[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [certi-dev] CERTI-Devel Digest, Vol 64, Issue 1
From: |
Monday Morning |
Subject: |
Re: [certi-dev] CERTI-Devel Digest, Vol 64, Issue 1 |
Date: |
Thu, 11 Aug 2011 17:34:25 +0100 |
Eric, thank you for your prompt response.
>
> 1) Which version of CERTI are you using on which platform ?
The latest, on Win32 (XP) using supplied installer.
>
> 2) Which binding do you use
> C++ HLA 1.3
> C++ IEEE-1516
>
My include files are simply
#define RTI_USES_STD_FSTREAM
#include <RTI.hh>
#include <NullFederateAmbassador.hh>
#include <Enums.h>
Which I think means I am using C++ HLA 1.3. Ultimately I want to
support 1516, but my attempts to include any of those files were met
with hundreds of errors.
>
> Some generic answer:
> - 2 separate federate of the same federation shall not have the same name
I know this, and they never attempt to connect two federates of the
same name, except when one reconnects again after resigning.
>
> - If a federate did not resign currently CERTI does not resign it by
> some timeout mechanism
> even less destroy the federation, this is a implementation choice
> however I'll check HLA
> document in order to this what is told about that case.
This might be why all simulations I've seen using HLA have been
'flaky' at best. A federate might crash, and then all other
simulations will have out-dated objects.
With DIS, if things go badly wrong you only have to wait 12 seconds
and it all sorts itself out, normally quicker (12 second timeout for
DIS state PDU).
With DIS simulations I've seen regular applications crashing and
issuing of NaN for number fields (these really screw up filters). Both
of them can be normally fixed by restarting the application, but that
relies on the RTI refreshing the object list.
> This should be a bug I'll try to see if I can reproduce this.
> Do you get the very same error in this case?
I have written an example program, code included at the end.
> Did your application terminate and restart in this case or does it perform
>
> create/join/resign/destroy/create/join etc... in the same run?
It resigned, exits (RTIA is killed) and then restarts.
>
> > yet I still more often than not get the same problems when I try to restart
> > the
> > federation and rejoin.
>
> Is the rtig restarted as well in this case?
If other applications (federates) exist in the RTIG then it won't
restart and I have the problem. If it has restarted then things seem
to be fine, but that doesn't really solve the problem.
Here is my example program. Apologies if it is quite long but I have
tried to be as thorough as I can be. There are two applications built
for Win32, but they should work on Linux though this is not tested.
Possibly a header file may be needed.
Start RTIG
Start Application1
Start Application2 - creates two objects
..wait 5 seconds
Application2 resigns and exits
Restart Application2 and I get FederateNotExecutionMember when I try
to subscribeObjectClassAttributes, although the join has previously
succeeded.
Source files and FOM follow: (FOM modified from that included with
FlightGear). I can try and send the Visual Studio (7.1) project if
requested.
====================================================
Application1.cpp
====================================================
#include <cstdio>
#include <iostream>
#include <memory>
#ifdef WIN32
#include <windows.h> //for Sleep()
#endif
using std::auto_ptr;
#ifndef RTI_USES_STD_FSTREAM
#define RTI_USES_STD_FSTREAM
#endif
#include <RTI.hh>
#include <NullFederateAmbassador.hh>
#include <Enums.h>
RTI::ObjectClassHandle base_id;
RTI::ObjectClassHandle aircraft_id;
//This application does not know about submarine_id
RTI::ObjectHandle object_id;
//BaseEntity attrs:
RTI::AttributeHandle attr_location_id;
RTI::AttributeHandle attr_orientation_id;
RTI::AttributeHandle attr_velocity_id;
//Aircraft attrs:
RTI::AttributeHandle attr_afterburner_id;
class MyFederate: public NullFederateAmbassador
{
public:
MyFederate(){};
void discoverObjectInstance(RTI::ObjectHandle
theObject,RTI::ObjectClassHandle theObjectClass,const char
*theObjectName) throw (
RTI::CouldNotDiscover,RTI::ObjectClassNotKnown,RTI::FederateInternalError)
{
if (theObjectClass==base_id)
printf("Found BaseEntity (tag=%s) class=%i
id=%i\n",theObjectName,theObjectClass,theObject);
else if (theObjectClass==aircraft_id)
printf("Found Aircraft (tag=%s) class=%i
id=%i\n",theObjectName,theObjectClass,theObject);
else
printf("Unknown object found (tag=%s) class=%i
id=%i\n",theObjectName,theObjectClass,theObject);
}
void reflectAttributeValues(RTI::ObjectHandle theObject,const
RTI::AttributeHandleValuePairSet &theAttributes,const char *theTag)
throw (
RTI::ObjectNotKnown,RTI::AttributeNotKnown,RTI::FederateOwnsAttributes,RTI::FederateInternalError){}
void removeObjectInstance(RTI::ObjectHandle theObject, const
char
*tag) throw (RTI::ObjectNotKnown, RTI::FederateInternalError)
{
printf("Removing Object (tag=%s)
id=%i\n",tag,theObject);
}
void receiveInteraction(RTI::InteractionClassHandle
theInteraction,
const RTI::ParameterHandleValuePairSet &theData, const char *theTag)
throw (RTI::InteractionClassNotKnown,
RTI::InteractionParameterNotKnown, RTI::FederateInternalError){}
};
void Snooze(float secs)
{
#ifdef WIN32
Sleep((int)(secs*1000));
#else
sleep(secs);
#endif
}
RTI::RTIambassador *rtiAmb;
MyFederate *myfed;
int main()
{
try
{
rtiAmb=new RTI::RTIambassador();
myfed=new MyFederate();
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
Snooze(2.0f);
exit(1);
}
try
{
rtiAmb->createFederationExecution("Recon", "recon.fed");
}
catch(RTI::FederationExecutionAlreadyExists &e)
{
e._name; //ignore this 'exceptional circumstance' of the
federation
already existing...
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
Snooze(2.0f);
exit(1);
}
try
{
rtiAmb->joinFederationExecution("App1","Recon",myfed);
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
Snooze(2.0f);
exit(1);
}
base_id = rtiAmb->getObjectClassHandle("BaseEntity");
aircraft_id = rtiAmb->getObjectClassHandle("Aircraft");
//base entity attrs
std::auto_ptr<RTI::AttributeHandleSet>
attrs_base(RTI::AttributeHandleSetFactory::create(3));
attrs_base->add(attr_location_id =
rtiAmb->getAttributeHandle("WorldLocation", base_id));
attrs_base->add(attr_orientation_id =
rtiAmb->getAttributeHandle("Orientation", base_id));
attrs_base->add(attr_velocity_id =
rtiAmb->getAttributeHandle("VelocityVector", base_id));
rtiAmb->subscribeObjectClassAttributes(base_id, *attrs_base);
//aircraft entity attrs
std::auto_ptr<RTI::AttributeHandleSet>
attrs_ac(RTI::AttributeHandleSetFactory::create(1));
attrs_ac->add(attr_afterburner_id =
rtiAmb->getAttributeHandle("AfterburnerOn", aircraft_id));
rtiAmb->subscribeObjectClassAttributes(aircraft_id, *attrs_ac);
printf("Application1: Configured ok now running\n");
//now do nothing and wait
for(;;)
{
Snooze(1.0f);
try
{
rtiAmb->tick();
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
Snooze(2.0f);
exit(1);
}
}
}
====================================================
Application2.cpp
====================================================
#include <cstdio>
#include <iostream>
#include <memory>
#ifdef WIN32
#include <windows.h> //for Sleep()
#endif
using std::auto_ptr;
#ifndef RTI_USES_STD_FSTREAM
#define RTI_USES_STD_FSTREAM
#endif
#include <RTI.hh>
#include <NullFederateAmbassador.hh>
#include <Enums.h>
RTI::ObjectClassHandle base_id;
RTI::ObjectClassHandle aircraft_id;
RTI::ObjectClassHandle submarine_id; //I know about this, Application1 does
not
RTI::ObjectHandle object_ac_id;
RTI::ObjectHandle object_sub_id;
//BaseEntity attrs:
RTI::AttributeHandle attr_location_id;
RTI::AttributeHandle attr_orientation_id;
RTI::AttributeHandle attr_velocity_id;
//Aircraft attrs:
RTI::AttributeHandle attr_afterburner_id;
//Submarine attrs:
RTI::AttributeHandle attr_periscopeup_id;
class MyFederate: public NullFederateAmbassador
{
public:
MyFederate(){};
void discoverObjectInstance(RTI::ObjectHandle
theObject,RTI::ObjectClassHandle theObjectClass,const char
*theObjectName) throw (
RTI::CouldNotDiscover,RTI::ObjectClassNotKnown,RTI::FederateInternalError)
{}
void reflectAttributeValues(RTI::ObjectHandle theObject,const
RTI::AttributeHandleValuePairSet &theAttributes,const char *theTag)
throw (
RTI::ObjectNotKnown,RTI::AttributeNotKnown,RTI::FederateOwnsAttributes,RTI::FederateInternalError){}
void removeObjectInstance(RTI::ObjectHandle theObject, const
char
*tag) throw (RTI::ObjectNotKnown, RTI::FederateInternalError){}
void receiveInteraction(RTI::InteractionClassHandle
theInteraction,
const RTI::ParameterHandleValuePairSet &theData, const char *theTag)
throw (RTI::InteractionClassNotKnown,
RTI::InteractionParameterNotKnown, RTI::FederateInternalError){}
};
RTI::RTIambassador *rtiAmb;
MyFederate *myfed;
void Snooze(float secs)
{
#ifdef WIN32
Sleep((int)(secs*1000));
#else
sleep(secs);
#endif
}
int main()
{
try
{
rtiAmb=new RTI::RTIambassador();
myfed=new MyFederate();
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
exit(1);
}
try
{
rtiAmb->createFederationExecution("Recon", "recon.fed");
}
catch(RTI::FederationExecutionAlreadyExists &e)
{
e._name; //ignore this 'exceptional circumstance' of the
federation
already existing...
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
exit(1);
}
try
{
rtiAmb->joinFederationExecution("App2","Recon",myfed);
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
exit(1);
}
base_id = rtiAmb->getObjectClassHandle("BaseEntity");
aircraft_id = rtiAmb->getObjectClassHandle("Aircraft");
submarine_id = rtiAmb->getObjectClassHandle("Submarine");
//base entity attrs
std::auto_ptr<RTI::AttributeHandleSet>
attrs_base(RTI::AttributeHandleSetFactory::create(3));
attrs_base->add(attr_location_id =
rtiAmb->getAttributeHandle("WorldLocation", base_id));
attrs_base->add(attr_orientation_id =
rtiAmb->getAttributeHandle("Orientation", base_id));
attrs_base->add(attr_velocity_id =
rtiAmb->getAttributeHandle("VelocityVector", base_id));
rtiAmb->subscribeObjectClassAttributes(base_id, *attrs_base);
//aircraft entity attrs
std::auto_ptr<RTI::AttributeHandleSet>
attrs_ac(RTI::AttributeHandleSetFactory::create(1));
attrs_ac->add(attr_afterburner_id =
rtiAmb->getAttributeHandle("AfterburnerOn", aircraft_id));
try
{
//get error here when running for the second time
rtiAmb->subscribeObjectClassAttributes(aircraft_id, *attrs_ac);
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
exit(1);
}
//submarine entity attrs
std::auto_ptr<RTI::AttributeHandleSet>
attrs_sub(RTI::AttributeHandleSetFactory::create(1));
attrs_sub->add(attr_periscopeup_id =
rtiAmb->getAttributeHandle("PeriscopeUp", submarine_id));
rtiAmb->subscribeObjectClassAttributes(submarine_id, *attrs_sub);
//make an aircraft
std::auto_ptr<RTI::AttributeHandleSet>
attrs_myac(RTI::AttributeHandleSetFactory::create(4));
attrs_myac->add(attr_location_id);
attrs_myac->add(attr_orientation_id);
attrs_myac->add(attr_velocity_id);
attrs_myac->add(attr_afterburner_id);
rtiAmb->publishObjectClass(aircraft_id, *attrs_myac);
object_ac_id = rtiAmb->registerObjectInstance(aircraft_id, "Make
Aircraft");
puts("Made Aircraft");
//make a submarine
std::auto_ptr<RTI::AttributeHandleSet>
attrs_mysub(RTI::AttributeHandleSetFactory::create(4));
attrs_mysub->add(attr_location_id);
attrs_mysub->add(attr_orientation_id);
attrs_mysub->add(attr_velocity_id);
attrs_mysub->add(attr_periscopeup_id);
rtiAmb->publishObjectClass(submarine_id, *attrs_mysub);
object_sub_id = rtiAmb->registerObjectInstance(submarine_id, "Make
Submarine");
puts("Made Submarine");
printf("Application2: Configured ok now running\n5 dots: ");
fflush(stdout);
//now run for 5 seconds
for(int i=0;i<5;++i)
{
Snooze(1.0f);
printf(".");
fflush(stdout);
try
{
rtiAmb->tick();
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
Snooze(2.0f);
exit(1);
}
}
printf("\nApplication2: now exiting\n");
//now delete objects and resign
rtiAmb->unsubscribeObjectClass(object_ac_id);
rtiAmb->deleteObjectInstance(object_ac_id,"Delete Aircraft");
rtiAmb->unpublishObjectClass(object_ac_id);
rtiAmb->unsubscribeObjectClass(object_sub_id);
rtiAmb->deleteObjectInstance(object_sub_id,"Delete Submarine");
rtiAmb->unpublishObjectClass(object_sub_id);
rtiAmb->unsubscribeObjectClass(base_id);
rtiAmb->unsubscribeObjectClass(aircraft_id);
rtiAmb->unsubscribeObjectClass(submarine_id);
rtiAmb->resignFederationExecution(RTI::DELETE_OBJECTS_AND_RELEASE_ATTRIBUTES);
try
{
rtiAmb->destroyFederationExecution("Recon");//shouldn't work
because
Application1 is still running
}
catch(RTI::FederatesCurrentlyJoined &e)
{
e._name;
//ignore
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
Snooze(2.0f);
exit(1);
}
//we're done, exit
try
{
delete myfed;
delete rtiAmb;
}
catch(RTI::Exception &e)
{
printf("%s\n",e._name);
exit(1);
}
puts("Done");
Snooze(3.0f);
}
====================================================
recon.fed
====================================================
(Fed
(Federation Recon)
(FedVersion v1.3)
(Spaces
)
(Objects
(Class ObjectRoot
(Attribute privilegeToDelete reliable timestamp)
(Class RTIprivate)
(Class BaseEntity
(Attribute WorldLocation RELIABLE TIMESTAMP)
(Attribute Orientation RELIABLE TIMESTAMP)
(Attribute VelocityVector RELIABLE TIMESTAMP)
(Attribute AccelerationVector RELIABLE TIMESTAMP)
(Attribute AngularVelocityVector RELIABLE TIMESTAMP)
(Attribute VisualModel RELIABLE TIMESTAMP)
(Class PhysicalEntity
(Class Platform
(Class Aircraft
(attribute AfterburnerOn best_effort receive)
)
(Class Submarine
(attribute PeriscopeUp best_effort receive)
)
)
)
)
)
)
(Interactions
(Class InteractionRoot BEST_EFFORT RECEIVE
(Class RTIprivate BEST_EFFORT RECEIVE)
)
)
)
- Re: [certi-dev] CERTI-Devel Digest, Vol 64, Issue 1,
Monday Morning <=