Creating Your First Component
In the OpenJAUS SDK, a JAUS component is represented as a class and the desired JAUS services are added to a component via inheritance. When a service is added to a component all the functionality from the parent services are also added.
Introduction
Base Component Classes
The OpenJAUS SDK provides a few base component classes that provide all the core functionality needed to quickly start communicating between JAUS components and should be used as a starting point for creating your own custom component. These classes are:
openjaus::components::EventsBase
openjaus::components::Base
openjaus::components::Managed
openjaus::components::EventsBase
The EventsBase
component class includes the following services:
urn:jaus:jss:core:Transport
urn:jaus:jss:core:Events
urn:jaus:jss:core:Discovery
urn:jaus:jss:core:Liveness
The Discovery
and Liveness
services can be enabled or disabled via the OpenJAUS configuration file.
It also includes the following custom OpenJAUS services:
urn:openjaus:core:DiscoveryClient
- A Discovery service client that will find other JAUS components on the network. The frequency for running the Discovery process can be controlled via the OpenJAUS configuration file.
urn:openjaus:core:Configuration
- A non-standard, custom service that configure the JAUS ID of the component based on the settings specified in the OpenJAUS configuration file.
openjaus::components::Base
The Base
component class includes all the services in the EventsBase
component and adds the following services:
urn:jaus:jss:core:AccessControl
urn:jaus:jss:core:Time
The Time
service can be enabled or disabled via the OpenJAUS configuration file.
openjaus::components::Managed
The Managed
component class includes all the services in the Base
component and adds the following services:
urn:jaus:jss:core:Management
Which Base Component Class should I use?
The base component class that should be used when creating your own component will depend on the inheritance chain for the services you want to add to your component.
-
If want to add a service that inherits from the
Management
service, then you should inherit from theopenjaus::components::Managed
component class.- Example: the
PrimitiveDriver
service (urn:jaus:jss:mobility:PrimitiveDriver
)
- Example: the
-
If you want to add a service that inherits from the
AccessControl
service but not theManagement
service, then you should inherit from theopenjaus::components::Base
component class.- Example: the
GlobalPoseSensor
service (urn:jaus:jss:mobility:GlobalPoseSensor
)
- Example: the
-
If you want to add a services that inhertis from the
Events
service but not theAccessControl
orManagement
services, then you should inherit from theopenjaus::components::EventsBase
component class.- Example: the
PanTiltJointPositionSensor
service (urn:jaus:jss:manipulator:PanTiltJointPositionSensor
)
- Example: the
-
If you are adding multiple services, then you should inherit the from the component class includes all the services you need.
- Example: if adding both the
PrimitiveDriver
andGlobalPoseSensor
services then you should inherit from theopenjaus::components::Managed
component class.
- Example: if adding both the
Most components will either start from the openjaus::components::Base
or openjaus::components::Managed
component classes.
Note
Avoid adding unnecessary services to your component and pick the appropriate base component class to start from. You should avoid always starting from the openjaus::components::Managed
component class if the Management
service is not needed as it could lead to unintended side effects.
Creating a Custom Component
The following code snippets show how to create a custom component class.
Note
A component name is required by the Base component class and is used for two things:
- As part of the Discovery service to identify the Component on the JAUS network
- In the OpenJAUS configuration file to identify Component specific configuration parameters
Warning
Use of the openjaus::components::EventsBase()
, openjaus::components::Base()
, openjaus::components::Managed()
s constructors that do not take a name parameter is deprecated and will be removed in the future.
Adding Services to a Component
Services are added to a component using inheritance. This adds support to the component’s message and protocol behavior (also called the state machine) handlers such that the service's input messages will be properly processed and the necessary protocol behavior transitions will be executed.
See AS5710A for a better understanding of messages, internal events, and protocol behavior transitions.
Note
The terms service protocol behavior and service state machine are often used interchangeably.
In the following code snippet, we add the GlobalPoseSensor
service to the custom component created previously.
Note
- Notice that the
openjaus::mobility::GlobalPoseSensor
class is inherited aspublic virtual
. In JAUS, if two services that have a shared parent service are used together in the same component, the shared parent service is the same service instance. For example, if two services (Service A
andService B
) both inherit from theAccessControl
service and are used together in the same component, then when a client takes control of the component using theAccessControl
service, it has control of bothService A
andService B
. For this to be properly handled in the OpenJAUS SDK, all service classes must be inherited as `public virtual. - We need to override/reimplement all the methods inherited from the
GlobalPoseSensor
class. If these methods are not overridden/reimplemented then the service will do nothing when the associated messages are received.
Note
-
Some methods (usually named as
getXXX
) return a JAUS message. The message needs to be populated correctly based on the details provided in the AS-4 standard documents. These methods are usually called when a message needs to be sent in response to some incoming message. For example, an incomingQueryXXX
message will trigger thegetReportXXX
method call and theReportXXX
message will be automatically sent. -
Some methods return a
boolean
true
orfalse
and are usually used to trigger some internal action. In the above example, theSetGlobalPose
message is intended to cause theGlobalPoseSensor
service to update its current global position. The state machine handler will move through the state machine calling methods that take aSetGlobalPose
message until one of them returnstrue
. It is recommended that you always returntrue
unless you are attempting to extend some existing functionality.