This example shows how to extend the RPR FOM from an existing RPR FOM Class Object (aircraft).
To extend the RPR FOM, you specify new objects and their attributes in a special FOM or FED file and add classes to your application to implement the new objects and attributes.
This example encompasses 2 separate example applications, an extendedRprFomTalk for publishing and an extendedRprFomListen for subscribing.
- Note
- Extending a FOM is not the same thing as creating a FOM Mapper. See the discussion at the end of this file.
Extending the RPR FOM
This example extends the Aircraft class in the RPR FOM. It adds a new class called F18, with an attribute called SpecialF18Attribute. This attribute is a variable length byte array that represents a string. The talk and listen applications are modified to implement the new object and attribute.
This example uses a special FOM called “example-extendF18”. There is an HLA1516 Evolved “_evolved.xml” version if the FOM, a 1516 .xml version, as well as a .fed version for HLA13.
The VR-Link.fed file is edited to add the new object as follows:
(class Aircraft (class F18 (attribute SpecialF18Attribute) ) )
To support this new attribute, we do the following things: 1) Extend the Entity State Repository by subclassing it. 2) Create Encoders/Decoders for this attribute by subclassing from existing encoders/decoders. 3) Tell the RPR FOM Mapper to use these attributes.
- Note
- Since the new class is subclassed from an existing class, we can take advantage of the existing classes for our state repository, publishers, and so on. If we were creating a new class from the base object level we would have to write additional code. See the Test Object Example which adds a new class from the baseObject level.
Why Extending a FOM is Not the Same Thing as Creating a FOM Mapper
Some VR-Link developers think that to add an object to the RPR FOM (extend the FOM) they have to create a FOM Mapper. This is not correct.
The purpose of a FOM Mapper is to map a FOM that VR-Link does not know about to the internal VR-Link object model. VR-Link already knows about the RPR FOM. The RPR FOM is mapped to the VR-Link object model through code internal to the VR-Link DLLs. There is no need to create a new FOM Mapper DLL, which would have to replace all of the internal FOM mapping, just to extend the RPR FOM.
To extend the RPR FOM, all you have to do is add your new class to the FED file and extend the VR-Link applications to work with the new object or attribute, as done in this example.
How to Run the Example
- Launch a extendedRprFomListen example from your VR-Link install's bin64 directory using the desired HLA protocol.
- Launch a extendedRprFomTalk example from your VR-Link install's bin64 directory using the same HLA protocol.
- Note that the talk will create an F18 using the new class, encoder, and decoder.
- Note that the listen will report the special F18 Attribute, a string "This is an F18".
- Enter 'q' in the Listen console to quit the listen application.
Example Code
Extended RPR FOM Talk Application
int main( int argc, char* argv[] )
{
try
{
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
appInit.setFederateType("Extended RPR FOM F18 publisher");
appInit.setRprFomVersion(2.0);
std::vector<DtString> fomModules;
fomModules.push_back("example-extendF18_evolved.xml");
appInit.setFomModules(fomModules);
#else
appInit.setRprFomVersion(2.0);
appInit.setFedFileName("example-extendF18.xml");
#endif
#else
appInit.setRprFomVersion(2.0);
appInit.setFedFileName("example-extendF18.fed");
#endif
appInit.parseCmdLine();
DtInfo <<
"adding new Encoders/Decoders for DtF18Entity" << std::endl;
DtInfo <<
"Registering the EntityClass Chooser" << std::endl;
while (simTime <= 10.0)
{
entityPub.tick();
simTime += dt;
}
}
return 0;
}
Extended RPR FOM Listen Application
#include <iostream>
{
std::cout << "Fire Interaction from "
}
int main( int argc, char* argv[] )
{
try
{
#if DtHLA_1516
#if DtHLA_1516_EVOLVED
appInit.setFederateType("Extended RPR FOM F18 subscriber");
appInit.setRprFomVersion(2.0);
std::vector<DtString> fomModules;
fomModules.push_back("example-extendF18_evolved.xml");
appInit.setFomModules(fomModules);
#else
appInit.setRprFomVersion(2.0);
appInit.setFedFileName("example-extendF18.xml");
#endif
#else
appInit.setRprFomVersion(2.0);
appInit.setFedFileName("example-extendF18.fed");
#endif
appInit.parseCmdLine();
DtInfo(
" Adding Encoders/Decoders for DtF18Entity\n");
int forever = 1;
while (forever)
{
break;
if (first)
{
std::cout << "special F18 Attribute: ("
}
}
}
return 0;
}
Extended RPR FOM Class, Encoder, and Decoder
#if DtHLA
#include <stdio.h>
{
public:
{ printf("\n===================\n"
"Constructing DtF18EntityStateRep\n"
"=====================\n"); }
private:
public:
protected:
};
{
public:
{
}
protected:
const RTI::AttributeHandleValuePairSet& attrs,
int pairSetIndex)
{
RTI::ULong length = attrs.getValueLength(pairSetIndex);
if (length == 0) return;
attrs.getValue(pairSetIndex, buffer, length);
buffer[length] = '\0';
}
};
{
public:
{
}
protected:
{
}
RTI::AttributeHandleValuePairSet* avList,
RTI::AttributeHandle attrHandle)
{
avList->add(attrHandle,
}
};
#define DtADD_ENCODER(className, derivedEnc) \
{ \
DtObjClassDesc* classDesc = exConn.fom()->objClassByName(#className); \
if (classDesc) \
{ \
exConn.fomMapper()->stateEncoderFactory()->addEncoder( \
classDesc->handle(), new derivedEnc(&exConn, classDesc)); \
} \
else \
{ \
DtWarn("Can't add encoder for object class %s: Not in FOM.\n", #className); \
} \
}
#define DtADD_DECODER(className, derivedDec) \
{ \
DtObjClassDesc* classDesc = exConn.fom()->objClassByName(#className); \
if (classDesc) \
{ \
exConn.fomMapper()->stateDecoderFactory()->addDecoder( \
classDesc->handle(), new derivedDec(&exConn, classDesc)); \
} \
else \
{ \
DtWarn("Can't add decoder for object class %s: Not in FOM.\n", #className); \
} \
}
void *usr)
{
printf("=========\n");
printf(" In Class Chooser, deciding which entity Type to publish\n");
printf("=========\n");
{
printf("Choosing F18 Type, we will use the new class!\n");
return "BaseEntity.PhysicalEntity.Platform.Aircraft.F18";
}
exConn, usr));
}
#endif