Previous: Create 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 a custom component.


.h file

class MyComponent : 
    public virtual openjaus::mobility_v1_0::services::GlobalPoseSensor, // [1]
    public openjaus::core::Base
public:
        MyComponent();
        virtual ~MyComponent();

        virtual openjaus::mobility_v1_0::ReportGlobalPose getReportGlobalPose(openjaus::mobility_v1_0::QueryGlobalPose *queryGlobalPose);  // [2]
        …
        virtual bool updateGlobalPose(openjaus::mobility_v1_0::SetGlobalPose *setGlobalPose);
        virtual bool updateGeomagneticProperty(openjaus::mobility_v1_0::SetGeomagneticProperty *setGeomagneticProperty); // [2]

protected:

private:
}


Notes:

[1] Notice that the openjaus::mobility::GlobalPoseSensor is inherited as public 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 and Service B) that inherit from the AccessControl service are used in the same component, then when a client takes control of the component using the AccessControl service, it has control of both Service A and Service B. For this to be properly handled in the OpenJAUS SDK, all services must be inherited as public virtual.


[2] 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.



.cpp file

MyComponent::MyComponent(std::string name) :
    // This initializer is not needed for proper operation but it is recommended for clarity.
    openjaus::mobility_v1_0::services::GlobalPoseSensor(), 
    openjaus::core::Base(name)
{

    // Add the Service Identification Data to the implements vector.
    // The implements vector contains the list of services supported by the component 
    // and may be used by other services, such as the Discovery service.
    this->implements->push_back(openjaus::mobility_v1_0::services::GlobalPoseSensor::create());

    // Service output messages can be registered with the Events service. 
    // The Events service allows a client to receive these messages at a periodic rate 
    // (PERIODIC_EVENT), when there is a data change (ON_CHANGE_EVENT) or 
    // both (ALL_EVENTS).  The periodic rate (Hz) is passed as the second parameter.
    Events::publish(openjaus::mobility_v1_0::ReportGlobalPose::ID, -1.0, openjaus::model::ALL_EVENTS);
}

MyComponent::~MyComponent()
{
}

openjaus::mobility_v1_0::ReportGlobalPose MyComponent::getReportGlobalPose(openjaus::mobility_v1_0::QueryGlobalPose *queryGlobalPose)
{
   openjaus::mobility_v1_0::ReportGlobalPose message; 

   // [3]

   return message;
}

…

bool MyComponent::updateGlobalPose(openjaus::mobility_v1_0::SetGlobalPose *setGlobalPose)
{
   // [4]

   return true; 
}


Notes:
[3] 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 incoming QueryXxx message will trigger the getReportXxx method call and the ReportXxx message will be automatically sent.


[4] Some methods return a boolean true or false and are usually used to trigger some internal action. In the above example, the SetGlobalPose message is intended to cause the globalPoseSensor service to update its current global position. The state machine handler will fall through the state machine calling methods that take a SetGlobalPose message until one of them returns true. Unless you are attempting to extend some existing functionality it is recommended that you always return true.



Previous: Create a Component