1 // Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 # include <simgear_config.h>
22 #include <simgear/compiler.h>
24 #include "HLAFederate.hxx"
28 #include "simgear/debug/logstream.hxx"
30 #include "RTIFederate.hxx"
31 #include "RTIFederateFactoryRegistry.hxx"
32 #include "RTI13FederateFactory.hxx"
33 #include "RTIInteractionClass.hxx"
34 #include "RTIObjectClass.hxx"
35 #include "HLADataElement.hxx"
36 #include "HLADataType.hxx"
37 #include "HLAOMTXmlVisitor.hxx"
41 HLAFederate::HLAFederate() :
43 _createFederationExecution(true),
44 _timeConstrained(false),
45 _timeRegulating(false),
46 _timeConstrainedByLocalClock(false),
49 // For now instantiate the current only available factory here explicitly
50 RTI13FederateFactory::instance();
53 HLAFederate::~HLAFederate()
57 // Remove the data type references from the data types.
58 // This is to remove the cycles from the data types that might happen if a data type references itself
59 for (DataTypeMap::iterator i = _dataTypeMap.begin(); i != _dataTypeMap.end(); ++i) {
60 i->second->releaseDataTypeReferences();
65 HLAFederate::getVersion() const
71 HLAFederate::setVersion(HLAFederate::Version version)
73 if (_rtiFederate.valid()) {
74 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
81 const std::list<std::string>&
82 HLAFederate::getConnectArguments() const
84 return _connectArguments;
88 HLAFederate::setConnectArguments(const std::list<std::string>& connectArguments)
90 if (_rtiFederate.valid()) {
91 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
94 _connectArguments = connectArguments;
99 HLAFederate::getCreateFederationExecution() const
101 return _createFederationExecution;
105 HLAFederate::setCreateFederationExecution(bool createFederationExecution)
107 _createFederationExecution = createFederationExecution;
112 HLAFederate::getFederationExecutionName() const
114 return _federationExecutionName;
118 HLAFederate::setFederationExecutionName(const std::string& federationExecutionName)
120 if (_rtiFederate.valid()) {
121 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
124 _federationExecutionName = federationExecutionName;
129 HLAFederate::getFederationObjectModel() const
131 return _federationObjectModel;
135 HLAFederate::setFederationObjectModel(const std::string& federationObjectModel)
137 if (_rtiFederate.valid()) {
138 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
141 _federationObjectModel = federationObjectModel;
146 HLAFederate::getFederateType() const
148 return _federateType;
152 HLAFederate::setFederateType(const std::string& federateType)
154 if (_rtiFederate.valid()) {
155 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
158 _federateType = federateType;
163 HLAFederate::getFederateName() const
165 return _federateName;
169 HLAFederate::setFederateName(const std::string& federateName)
171 if (_rtiFederate.valid()) {
172 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
175 _federateName = federateName;
180 HLAFederate::connect(Version version, const std::list<std::string>& stringList)
183 _connectArguments = stringList;
188 HLAFederate::connect()
190 if (_rtiFederate.valid()) {
191 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
195 SGSharedPtr<RTIFederateFactoryRegistry> registry = RTIFederateFactoryRegistry::instance();
197 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: RTIFederateFactoryRegistry is no longer available!");
203 _rtiFederate = registry->create("RTI13", _connectArguments);
206 _rtiFederate = registry->create("RTI1516", _connectArguments);
209 _rtiFederate = registry->create("RTI1516E", _connectArguments);
212 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
214 return _rtiFederate.valid();
218 HLAFederate::disconnect()
220 if (!_rtiFederate.valid()) {
221 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
230 HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
232 if (!_rtiFederate.valid()) {
233 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
237 RTIFederate::FederationManagementResult createResult;
238 createResult = _rtiFederate->createFederationExecution(federation, objectModel);
239 if (createResult == RTIFederate::FederationManagementFatal)
242 _federationExecutionName = federation;
243 _federationObjectModel = objectModel;
248 HLAFederate::destroyFederationExecution(const std::string& federation)
250 if (!_rtiFederate.valid()) {
251 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
255 RTIFederate::FederationManagementResult destroyResult;
256 destroyResult = _rtiFederate->destroyFederationExecution(federation);
257 if (destroyResult == RTIFederate::FederationManagementFatal)
264 HLAFederate::createFederationExecution()
266 if (!_rtiFederate.valid()) {
267 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
271 RTIFederate::FederationManagementResult createResult;
272 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
273 if (createResult != RTIFederate::FederationManagementSuccess)
280 HLAFederate::destroyFederationExecution()
282 if (!_rtiFederate.valid()) {
283 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
287 RTIFederate::FederationManagementResult destroyResult;
288 destroyResult = _rtiFederate->destroyFederationExecution(_federationExecutionName);
289 if (destroyResult != RTIFederate::FederationManagementSuccess)
296 HLAFederate::join(const std::string& federateType, const std::string& federation)
298 if (!_rtiFederate.valid()) {
299 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
303 RTIFederate::FederationManagementResult joinResult;
304 joinResult = _rtiFederate->join(federateType, federation);
305 if (joinResult == RTIFederate::FederationManagementFatal)
314 if (!_rtiFederate.valid()) {
315 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
319 RTIFederate::FederationManagementResult joinResult;
320 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
321 if (joinResult != RTIFederate::FederationManagementSuccess)
328 HLAFederate::resign()
330 if (!_rtiFederate.valid()) {
331 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
334 return _rtiFederate->resign();
338 HLAFederate::createJoinFederationExecution()
340 if (!_rtiFederate.valid()) {
341 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
347 RTIFederate::FederationManagementResult joinResult;
348 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
349 switch (joinResult) {
350 case RTIFederate::FederationManagementSuccess:
351 // Fast return on success
353 case RTIFederate::FederationManagementFatal:
354 // Abort on fatal errors
360 // If not already joinable, try to create the requested federation
361 RTIFederate::FederationManagementResult createResult;
362 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
363 switch (createResult) {
364 case RTIFederate::FederationManagementFatal:
365 // Abort on fatal errors
375 HLAFederate::resignDestroyFederationExecution()
377 if (!_rtiFederate.valid()) {
378 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
383 bool success = _rtiFederate->resign();
385 // and try to destroy, non fatal if still some federates joined
386 if (_rtiFederate->destroyFederationExecution(_federationExecutionName) == RTIFederate::FederationManagementFatal)
393 HLAFederate::getTimeConstrained() const
395 return _timeConstrained;
399 HLAFederate::setTimeConstrained(bool timeConstrained)
401 _timeConstrained = timeConstrained;
403 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
404 if (_timeConstrained && !_rtiFederate->getTimeConstrainedEnabled()) {
405 if (!enableTimeConstrained())
407 } else if (!_timeConstrained && _rtiFederate->getTimeConstrainedEnabled()) {
408 if (!disableTimeConstrained())
418 HLAFederate::getTimeConstrainedByLocalClock() const
420 return _timeConstrainedByLocalClock;
424 HLAFederate::setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock)
426 _timeConstrainedByLocalClock = timeConstrainedByLocalClock;
428 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
429 if (_timeConstrainedByLocalClock) {
430 if (!enableTimeConstrainedByLocalClock())
439 HLAFederate::getTimeRegulating() const
441 return _timeRegulating;
445 HLAFederate::setTimeRegulating(bool timeRegulating)
447 _timeRegulating = timeRegulating;
449 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
450 if (_timeRegulating && !_rtiFederate->getTimeRegulationEnabled()) {
451 if (!enableTimeRegulation())
453 } else if (!_timeRegulating && _rtiFederate->getTimeRegulationEnabled()) {
454 if (!disableTimeRegulation())
463 HLAFederate::setLeadTime(const SGTimeStamp& leadTime)
465 if (leadTime < SGTimeStamp::fromSec(0)) {
466 SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative lead time!");
470 _leadTime = leadTime;
472 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
473 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
474 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
483 HLAFederate::getLeadTime() const
489 HLAFederate::setTimeIncrement(const SGTimeStamp& timeIncrement)
491 if (timeIncrement < SGTimeStamp::fromSec(0)) {
492 SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative time increment!");
496 _timeIncrement = timeIncrement;
498 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
499 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
500 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
509 HLAFederate::getTimeIncrement() const
511 return _timeIncrement;
515 HLAFederate::enableTimeConstrained()
517 if (!_rtiFederate.valid()) {
518 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
522 if (!_rtiFederate->enableTimeConstrained()) {
523 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time constrained!");
527 while (!_rtiFederate->getTimeConstrainedEnabled()) {
528 _rtiFederate->processMessage();
535 HLAFederate::disableTimeConstrained()
537 if (!_rtiFederate.valid()) {
538 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
541 return _rtiFederate->disableTimeConstrained();
545 HLAFederate::enableTimeConstrainedByLocalClock()
547 // Compute the time offset from the system time to the simulation time
548 SGTimeStamp federateTime;
549 if (!queryFederateTime(federateTime)) {
550 SG_LOG(SG_NETWORK, SG_WARN, "Cannot get federate time!");
553 _localClockOffset = SGTimeStamp::now() - federateTime;
558 HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
560 if (!_rtiFederate.valid()) {
561 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
565 if (!_rtiFederate->enableTimeRegulation(lookahead)) {
566 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time regulation!");
570 while (!_rtiFederate->getTimeRegulationEnabled()) {
571 _rtiFederate->processMessage();
578 HLAFederate::enableTimeRegulation()
580 if (!enableTimeRegulation(SGTimeStamp::fromSec(0))) {
581 SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time regulation!");
584 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
585 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
592 HLAFederate::disableTimeRegulation()
594 if (!_rtiFederate.valid()) {
595 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
598 return _rtiFederate->disableTimeRegulation();
602 HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
604 if (!_rtiFederate.valid()) {
605 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
608 return _rtiFederate->modifyLookahead(timeStamp);
612 HLAFederate::timeAdvanceBy(const SGTimeStamp& timeIncrement)
614 if (!_rtiFederate.valid()) {
615 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
619 SGTimeStamp timeStamp;
620 if (!_rtiFederate->queryFederateTime(timeStamp)) {
621 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query federate time!");
625 if (!_rtiFederate->timeAdvanceRequest(timeStamp + timeIncrement)) {
626 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
630 return processMessages();
634 HLAFederate::timeAdvance(const SGTimeStamp& timeStamp)
636 if (!_rtiFederate.valid()) {
637 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
641 if (!_rtiFederate->timeAdvanceRequest(timeStamp)) {
642 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
646 return processMessages();
650 HLAFederate::timeAdvanceAvailable()
652 if (!_rtiFederate.valid()) {
653 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
657 SGTimeStamp timeStamp;
658 if (_rtiFederate->queryGALT(timeStamp)) {
659 if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) {
660 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
665 return processMessages();
669 HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
671 if (!_rtiFederate.valid()) {
672 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
675 return _rtiFederate->queryFederateTime(timeStamp);
679 HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
681 if (!_rtiFederate.valid()) {
682 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
685 return _rtiFederate->queryLookahead(timeStamp);
689 HLAFederate::processMessage()
691 if (!_rtiFederate.valid()) {
692 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
695 return _rtiFederate->processMessage();
699 HLAFederate::processMessage(const SGTimeStamp& timeout)
701 if (!_rtiFederate.valid()) {
702 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
705 return _rtiFederate->processMessages(timeout.toSecs(), 0);
709 HLAFederate::processMessages()
711 if (!_rtiFederate.valid()) {
712 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
716 while (_rtiFederate->getTimeAdvancePending()) {
717 _rtiFederate->processMessage();
720 if (_timeConstrainedByLocalClock) {
721 SGTimeStamp federateTime;
722 if (!_rtiFederate->queryFederateTime(federateTime)) {
723 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Error querying federate time!");
726 SGTimeStamp systemTime = federateTime + _localClockOffset;
728 double rest = (systemTime - SGTimeStamp::now()).toSecs();
731 _rtiFederate->processMessages(rest, rest);
735 // Now flush just what is left
736 while (_rtiFederate->processMessages(0, 0));
742 HLAFederate::tick(const double& minimum, const double& maximum)
744 if (!_rtiFederate.valid()) {
745 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
748 return _rtiFederate->processMessages(minimum, maximum);
752 HLAFederate::readObjectModelTemplate(const std::string& objectModel,
753 HLAFederate::ObjectModelFactory& objectModelFactory)
755 // The XML version of the federate object model.
756 // This one covers the generic attributes, parameters and data types.
757 HLAOMTXmlVisitor omtXmlVisitor;
759 readXML(objectModel, omtXmlVisitor);
760 } catch (const sg_throwable& e) {
761 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
765 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
769 omtXmlVisitor.setDataTypesToFederate(*this);
771 unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
772 for (unsigned i = 0; i < numObjectClasses; ++i) {
773 const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
774 std::string objectClassName = objectClass->getName();
776 SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
777 if (!hlaObjectClass.valid()) {
778 SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
782 bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
783 bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
785 // process the attributes
786 for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
787 const simgear::HLAOMTXmlVisitor::Attribute* attribute;
788 attribute = objectClass->getAttribute(j);
790 std::string attributeName = attribute->getName();
791 unsigned index = hlaObjectClass->addAttribute(attributeName);
794 SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
798 // the attributes datatype
799 SGSharedPtr<const HLADataType> dataType = getDataType(attribute->getDataType());
800 if (!dataType.valid()) {
801 SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
802 << attributeName << "\" in object class \"" << objectClassName << "\"!");
804 hlaObjectClass->setAttributeDataType(index, dataType);
805 hlaObjectClass->setAttributeUpdateType(index, attribute->getUpdateType());
806 if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
807 hlaObjectClass->setAttributeSubscriptionType(index, attribute->getSubscriptionType());
808 if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
809 hlaObjectClass->setAttributePublicationType(index, attribute->getPublicationType());
813 hlaObjectClass->publish();
815 hlaObjectClass->subscribe();
819 return resolveObjectModel();
823 HLAFederate::readRTI13ObjectModelTemplate(const std::string& objectModel)
825 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI13 not yet(!?) supported.");
830 HLAFederate::readRTI1516ObjectModelTemplate(const std::string& objectModel)
832 // The XML version of the federate object model.
833 // This one covers the generic attributes, parameters and data types.
834 HLAOMTXmlVisitor omtXmlVisitor;
836 readXML(objectModel, omtXmlVisitor);
837 } catch (const sg_throwable& e) {
838 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
842 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
846 omtXmlVisitor.setToFederate(*this);
848 return resolveObjectModel();
852 HLAFederate::readRTI1516EObjectModelTemplate(const std::string& objectModel)
854 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
859 HLAFederate::resolveObjectModel()
861 if (!_rtiFederate.valid()) {
862 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
866 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
867 RTIInteractionClass* rtiInteractionClass = _rtiFederate->createInteractionClass(i->second->getName(), i->second.get());
868 if (!rtiInteractionClass) {
869 SG_LOG(SG_NETWORK, SG_ALERT, "HLAFederate::_insertInteractionClass(): "
870 "No RTIInteractionClass found for \"" << i->second->getName() << "\"!");
873 i->second->_setRTIInteractionClass(rtiInteractionClass);
876 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
877 RTIObjectClass* rtiObjectClass = _rtiFederate->createObjectClass(i->second->getName(), i->second.get());
878 if (!rtiObjectClass) {
879 SG_LOG(SG_NETWORK, SG_ALERT, "HLAFederate::_insertObjectClass(): "
880 "No RTIObjectClass found for \"" << i->second->getName() << "\"!");
883 i->second->_setRTIObjectClass(rtiObjectClass);
890 HLAFederate::getDataType(const std::string& name) const
892 DataTypeMap::const_iterator i = _dataTypeMap.find(name);
893 if (i == _dataTypeMap.end())
895 return i->second.get();
899 HLAFederate::insertDataType(const std::string& name, const SGSharedPtr<HLADataType>& dataType)
901 if (!dataType.valid())
903 if (_dataTypeMap.find(name) != _dataTypeMap.end()) {
904 SG_LOG(SG_IO, SG_ALERT, "HLAFederate::insertDataType: data type with name \""
905 << name << "\" already known to federate!");
908 _dataTypeMap.insert(DataTypeMap::value_type(name, dataType));
913 HLAFederate::recomputeDataTypeAlignment()
915 // Finish alignment computations
919 for (DataTypeMap::iterator i = _dataTypeMap.begin(); i != _dataTypeMap.end(); ++i) {
920 if (i->second->recomputeAlignment())
927 HLAFederate::getInteractionClass(const std::string& name)
929 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
930 if (i == _interactionClassMap.end())
932 return i->second.get();
935 const HLAInteractionClass*
936 HLAFederate::getInteractionClass(const std::string& name) const
938 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
939 if (i == _interactionClassMap.end())
941 return i->second.get();
945 HLAFederate::createInteractionClass(const std::string& name)
947 return new HLAInteractionClass(name, this);
951 HLAFederate::getObjectClass(const std::string& name)
953 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
954 if (i == _objectClassMap.end())
956 return i->second.get();
959 const HLAObjectClass*
960 HLAFederate::getObjectClass(const std::string& name) const
962 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
963 if (i == _objectClassMap.end())
965 return i->second.get();
969 HLAFederate::createObjectClass(const std::string& name)
971 return new HLAObjectClass(name, this);
975 HLAFederate::getObjectInstance(const std::string& name)
977 ObjectInstanceMap::const_iterator i = _objectInstanceMap.find(name);
978 if (i == _objectInstanceMap.end())
980 return i->second.get();
983 const HLAObjectInstance*
984 HLAFederate::getObjectInstance(const std::string& name) const
986 ObjectInstanceMap::const_iterator i = _objectInstanceMap.find(name);
987 if (i == _objectInstanceMap.end())
989 return i->second.get();
993 HLAFederate::createObjectInstance(HLAObjectClass* objectClass, const std::string& name)
995 return new HLAObjectInstance(objectClass);
999 HLAFederate::setDone(bool done)
1005 HLAFederate::getDone() const
1011 HLAFederate::readObjectModel()
1013 // Depending on the actual version, try to find an apropriate
1014 // file format for the given file. The first one is always the
1015 // version native object model file format.
1016 switch (getVersion()) {
1018 if (readRTI13ObjectModelTemplate(getFederationObjectModel()))
1020 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1022 return readRTI1516EObjectModelTemplate(getFederationObjectModel());
1024 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1026 if (readRTI1516EObjectModelTemplate(getFederationObjectModel()))
1028 return readRTI13ObjectModelTemplate(getFederationObjectModel());
1030 if (readRTI1516EObjectModelTemplate(getFederationObjectModel()))
1032 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1034 return readRTI13ObjectModelTemplate(getFederationObjectModel());
1041 HLAFederate::subscribe()
1043 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
1044 if (!i->second->subscribe())
1048 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
1049 if (!i->second->subscribe())
1057 HLAFederate::publish()
1059 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
1060 if (!i->second->publish())
1064 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
1065 if (!i->second->publish())
1075 // We need to talk to the rti
1079 if (_createFederationExecution) {
1080 if (!createJoinFederationExecution())
1086 // Read the xml file containing the object model
1087 if (!readObjectModel()) {
1091 // start being time constrained if required
1092 if (_timeConstrained) {
1093 if (!enableTimeConstrained()) {
1098 // Now that we are potentially time constrained, we can subscribe.
1099 // This is to make sure we do not get any time stamped message
1100 // converted to a non time stamped message by the rti.
1105 // Before we publish anything start getting regulating if required
1106 if (_timeRegulating) {
1107 if (!enableTimeRegulation()) {
1112 // Note that starting from here, we need to be careful with things
1113 // requireing unbounded time. The rest of the federation might wait
1114 // for us to finish!
1116 // Compute the time offset from the system time to the simulation time
1117 if (_timeConstrainedByLocalClock) {
1118 if (!enableTimeConstrainedByLocalClock()) {
1119 SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time constrained by local clock!");
1125 // Publish what we want to write
1135 HLAFederate::update()
1137 return timeAdvanceBy(_timeIncrement);
1141 HLAFederate::shutdown()
1143 // On shutdown, just try all in order.
1144 // If something goes wrong, continue and try to get out here as good as possible.
1147 if (_createFederationExecution) {
1148 if (!resignDestroyFederationExecution())
1167 while (!getDone()) {
1181 HLAFederate::_clearRTI()
1183 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i)
1184 i->second->_clearRTIInteractionClass();
1185 for (ObjectInstanceMap::iterator i = _objectInstanceMap.begin(); i != _objectInstanceMap.end(); ++i)
1186 i->second->_clearRTIObjectInstance();
1187 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i)
1188 i->second->_clearRTIObjectClass();
1194 HLAFederate::_insertInteractionClass(const SGSharedPtr<HLAInteractionClass>& interactionClass)
1196 if (!interactionClass.valid())
1198 if (_interactionClassMap.find(interactionClass->getName()) != _interactionClassMap.end()) {
1199 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertInteractionClass: object instance with name \""
1200 << interactionClass->getName() << "\" already known to federate!");
1203 _interactionClassMap.insert(InteractionClassMap::value_type(interactionClass->getName(), interactionClass));
1208 HLAFederate::_insertObjectClass(const SGSharedPtr<HLAObjectClass>& objectClass)
1210 if (!objectClass.valid())
1212 if (_objectClassMap.find(objectClass->getName()) != _objectClassMap.end()) {
1213 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertObjectClass: object instance with name \""
1214 << objectClass->getName() << "\" already known to federate!");
1217 _objectClassMap.insert(ObjectClassMap::value_type(objectClass->getName(), objectClass));
1222 HLAFederate::_insertObjectInstance(const SGSharedPtr<HLAObjectInstance>& objectInstance)
1224 if (!objectInstance.valid())
1226 if (objectInstance->getName().empty()) {
1227 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertObjectInstance: trying to insert object instance with empty name!");
1230 if (_objectInstanceMap.find(objectInstance->getName()) != _objectInstanceMap.end()) {
1231 SG_LOG(SG_IO, SG_WARN, "HLA: _insertObjectInstance: object instance with name \""
1232 << objectInstance->getName() << "\" already known to federate!");
1235 _objectInstanceMap.insert(ObjectInstanceMap::value_type(objectInstance->getName(), objectInstance));
1240 HLAFederate::_eraseObjectInstance(const std::string& name)
1242 ObjectInstanceMap::iterator i = _objectInstanceMap.find(name);
1243 if (i == _objectInstanceMap.end()) {
1244 SG_LOG(SG_IO, SG_WARN, "HLA: _eraseObjectInstance: object instance with name \""
1245 << name << "\" not known to federate!");
1248 _objectInstanceMap.erase(i);
1251 } // namespace simgear