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.
18 #include "HLAFederate.hxx"
22 #include "simgear/debug/logstream.hxx"
24 #include "RTIFederate.hxx"
25 #include "RTIFederateFactoryRegistry.hxx"
26 #include "RTI13FederateFactory.hxx"
27 #include "RTIInteractionClass.hxx"
28 #include "RTIObjectClass.hxx"
29 #include "HLADataElement.hxx"
30 #include "HLADataType.hxx"
31 #include "HLAOMTXmlVisitor.hxx"
35 HLAFederate::HLAFederate() :
37 _createFederationExecution(true),
38 _timeConstrained(false),
39 _timeRegulating(false),
40 _timeConstrainedByLocalClock(false),
43 // For now instantiate the current only available factory here explicitly
44 RTI13FederateFactory::instance();
47 HLAFederate::~HLAFederate()
51 // Remove the data type references from the data types.
52 // This is to remove the cycles from the data types that might happen if a data type references itself
53 for (DataTypeMap::iterator i = _dataTypeMap.begin(); i != _dataTypeMap.end(); ++i) {
54 i->second->releaseDataTypeReferences();
59 HLAFederate::getVersion() const
65 HLAFederate::setVersion(HLAFederate::Version version)
67 if (_rtiFederate.valid()) {
68 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
75 const std::list<std::string>&
76 HLAFederate::getConnectArguments() const
78 return _connectArguments;
82 HLAFederate::setConnectArguments(const std::list<std::string>& connectArguments)
84 if (_rtiFederate.valid()) {
85 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
88 _connectArguments = connectArguments;
93 HLAFederate::getCreateFederationExecution() const
95 return _createFederationExecution;
99 HLAFederate::setCreateFederationExecution(bool createFederationExecution)
101 _createFederationExecution = createFederationExecution;
106 HLAFederate::getFederationExecutionName() const
108 return _federationExecutionName;
112 HLAFederate::setFederationExecutionName(const std::string& federationExecutionName)
114 if (_rtiFederate.valid()) {
115 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
118 _federationExecutionName = federationExecutionName;
123 HLAFederate::getFederationObjectModel() const
125 return _federationObjectModel;
129 HLAFederate::setFederationObjectModel(const std::string& federationObjectModel)
131 if (_rtiFederate.valid()) {
132 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
135 _federationObjectModel = federationObjectModel;
140 HLAFederate::getFederateType() const
142 return _federateType;
146 HLAFederate::setFederateType(const std::string& federateType)
148 if (_rtiFederate.valid()) {
149 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
152 _federateType = federateType;
157 HLAFederate::getFederateName() const
159 return _federateName;
163 HLAFederate::setFederateName(const std::string& federateName)
165 if (_rtiFederate.valid()) {
166 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
169 _federateName = federateName;
174 HLAFederate::connect(Version version, const std::list<std::string>& stringList)
177 _connectArguments = stringList;
182 HLAFederate::connect()
184 if (_rtiFederate.valid()) {
185 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
189 SGSharedPtr<RTIFederateFactoryRegistry> registry = RTIFederateFactoryRegistry::instance();
191 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: RTIFederateFactoryRegistry is no longer available!");
197 _rtiFederate = registry->create("RTI13", _connectArguments);
200 _rtiFederate = registry->create("RTI1516", _connectArguments);
203 _rtiFederate = registry->create("RTI1516E", _connectArguments);
206 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
208 return _rtiFederate.valid();
212 HLAFederate::disconnect()
214 if (!_rtiFederate.valid()) {
215 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
224 HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
226 if (!_rtiFederate.valid()) {
227 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
231 RTIFederate::FederationManagementResult createResult;
232 createResult = _rtiFederate->createFederationExecution(federation, objectModel);
233 if (createResult == RTIFederate::FederationManagementFatal)
236 _federationExecutionName = federation;
237 _federationObjectModel = objectModel;
242 HLAFederate::destroyFederationExecution(const std::string& federation)
244 if (!_rtiFederate.valid()) {
245 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
249 RTIFederate::FederationManagementResult destroyResult;
250 destroyResult = _rtiFederate->destroyFederationExecution(federation);
251 if (destroyResult == RTIFederate::FederationManagementFatal)
258 HLAFederate::createFederationExecution()
260 if (!_rtiFederate.valid()) {
261 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
265 RTIFederate::FederationManagementResult createResult;
266 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
267 if (createResult != RTIFederate::FederationManagementSuccess)
274 HLAFederate::destroyFederationExecution()
276 if (!_rtiFederate.valid()) {
277 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
281 RTIFederate::FederationManagementResult destroyResult;
282 destroyResult = _rtiFederate->destroyFederationExecution(_federationExecutionName);
283 if (destroyResult != RTIFederate::FederationManagementSuccess)
290 HLAFederate::join(const std::string& federateType, const std::string& federation)
292 if (!_rtiFederate.valid()) {
293 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
297 RTIFederate::FederationManagementResult joinResult;
298 joinResult = _rtiFederate->join(federateType, federation);
299 if (joinResult == RTIFederate::FederationManagementFatal)
308 if (!_rtiFederate.valid()) {
309 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
313 RTIFederate::FederationManagementResult joinResult;
314 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
315 if (joinResult != RTIFederate::FederationManagementSuccess)
322 HLAFederate::resign()
324 if (!_rtiFederate.valid()) {
325 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
328 return _rtiFederate->resign();
332 HLAFederate::createJoinFederationExecution()
334 if (!_rtiFederate.valid()) {
335 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
341 RTIFederate::FederationManagementResult joinResult;
342 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
343 switch (joinResult) {
344 case RTIFederate::FederationManagementSuccess:
345 // Fast return on success
347 case RTIFederate::FederationManagementFatal:
348 // Abort on fatal errors
354 // If not already joinable, try to create the requested federation
355 RTIFederate::FederationManagementResult createResult;
356 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
357 switch (createResult) {
358 case RTIFederate::FederationManagementFatal:
359 // Abort on fatal errors
369 HLAFederate::resignDestroyFederationExecution()
371 if (!_rtiFederate.valid()) {
372 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
377 bool success = _rtiFederate->resign();
379 // and try to destroy, non fatal if still some federates joined
380 if (_rtiFederate->destroyFederationExecution(_federationExecutionName) == RTIFederate::FederationManagementFatal)
387 HLAFederate::getTimeConstrained() const
389 return _timeConstrained;
393 HLAFederate::setTimeConstrained(bool timeConstrained)
395 _timeConstrained = timeConstrained;
397 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
398 if (_timeConstrained && !_rtiFederate->getTimeConstrainedEnabled()) {
399 if (!enableTimeConstrained())
401 } else if (!_timeConstrained && _rtiFederate->getTimeConstrainedEnabled()) {
402 if (!disableTimeConstrained())
412 HLAFederate::getTimeConstrainedByLocalClock() const
414 return _timeConstrainedByLocalClock;
418 HLAFederate::setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock)
420 _timeConstrainedByLocalClock = timeConstrainedByLocalClock;
422 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
423 if (_timeConstrainedByLocalClock) {
424 if (!enableTimeConstrainedByLocalClock())
433 HLAFederate::getTimeRegulating() const
435 return _timeRegulating;
439 HLAFederate::setTimeRegulating(bool timeRegulating)
441 _timeRegulating = timeRegulating;
443 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
444 if (_timeRegulating && !_rtiFederate->getTimeRegulationEnabled()) {
445 if (!enableTimeRegulation())
447 } else if (!_timeRegulating && _rtiFederate->getTimeRegulationEnabled()) {
448 if (!disableTimeRegulation())
457 HLAFederate::setLeadTime(const SGTimeStamp& leadTime)
459 if (leadTime < SGTimeStamp::fromSec(0)) {
460 SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative lead time!");
464 _leadTime = leadTime;
466 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
467 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
468 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
477 HLAFederate::getLeadTime() const
483 HLAFederate::setTimeIncrement(const SGTimeStamp& timeIncrement)
485 if (timeIncrement < SGTimeStamp::fromSec(0)) {
486 SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative time increment!");
490 _timeIncrement = timeIncrement;
492 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
493 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
494 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
503 HLAFederate::getTimeIncrement() const
505 return _timeIncrement;
509 HLAFederate::enableTimeConstrained()
511 if (!_rtiFederate.valid()) {
512 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
516 if (!_rtiFederate->enableTimeConstrained()) {
517 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time constrained!");
521 while (!_rtiFederate->getTimeConstrainedEnabled()) {
522 _rtiFederate->processMessage();
529 HLAFederate::disableTimeConstrained()
531 if (!_rtiFederate.valid()) {
532 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
535 return _rtiFederate->disableTimeConstrained();
539 HLAFederate::enableTimeConstrainedByLocalClock()
541 // Compute the time offset from the system time to the simulation time
542 SGTimeStamp federateTime;
543 if (!queryFederateTime(federateTime)) {
544 SG_LOG(SG_NETWORK, SG_WARN, "Cannot get federate time!");
547 _localClockOffset = SGTimeStamp::now() - federateTime;
552 HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
554 if (!_rtiFederate.valid()) {
555 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
559 if (!_rtiFederate->enableTimeRegulation(lookahead)) {
560 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time regulation!");
564 while (!_rtiFederate->getTimeRegulationEnabled()) {
565 _rtiFederate->processMessage();
572 HLAFederate::enableTimeRegulation()
574 if (!enableTimeRegulation(SGTimeStamp::fromSec(0))) {
575 SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time regulation!");
578 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
579 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
586 HLAFederate::disableTimeRegulation()
588 if (!_rtiFederate.valid()) {
589 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
592 return _rtiFederate->disableTimeRegulation();
596 HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
598 if (!_rtiFederate.valid()) {
599 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
602 return _rtiFederate->modifyLookahead(timeStamp);
606 HLAFederate::timeAdvanceBy(const SGTimeStamp& timeIncrement)
608 if (!_rtiFederate.valid()) {
609 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
613 SGTimeStamp timeStamp;
614 if (!_rtiFederate->queryFederateTime(timeStamp)) {
615 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query federate time!");
619 if (!_rtiFederate->timeAdvanceRequest(timeStamp + timeIncrement)) {
620 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
624 return processMessages();
628 HLAFederate::timeAdvance(const SGTimeStamp& timeStamp)
630 if (!_rtiFederate.valid()) {
631 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
635 if (!_rtiFederate->timeAdvanceRequest(timeStamp)) {
636 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
640 return processMessages();
644 HLAFederate::timeAdvanceAvailable()
646 if (!_rtiFederate.valid()) {
647 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
651 SGTimeStamp timeStamp;
652 if (!_rtiFederate->queryGALT(timeStamp)) {
653 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query GALT!");
657 if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) {
658 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
662 return processMessages();
666 HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
668 if (!_rtiFederate.valid()) {
669 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
672 return _rtiFederate->queryFederateTime(timeStamp);
676 HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
678 if (!_rtiFederate.valid()) {
679 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
682 return _rtiFederate->queryLookahead(timeStamp);
686 HLAFederate::processMessage()
688 if (!_rtiFederate.valid()) {
689 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
692 return _rtiFederate->processMessage();
696 HLAFederate::processMessage(const SGTimeStamp& timeout)
698 if (!_rtiFederate.valid()) {
699 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
702 return _rtiFederate->processMessages(timeout.toSecs(), 0);
706 HLAFederate::processMessages()
708 if (!_rtiFederate.valid()) {
709 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
713 while (_rtiFederate->getTimeAdvancePending()) {
714 _rtiFederate->processMessage();
717 if (_timeConstrainedByLocalClock) {
718 SGTimeStamp federateTime;
719 if (!_rtiFederate->queryFederateTime(federateTime)) {
720 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Error querying federate time!");
723 SGTimeStamp systemTime = federateTime + _localClockOffset;
725 double rest = (systemTime - SGTimeStamp::now()).toSecs();
728 _rtiFederate->processMessages(rest, rest);
732 // Now flush just what is left
733 while (_rtiFederate->processMessages(0, 0));
739 HLAFederate::tick(const double& minimum, const double& maximum)
741 if (!_rtiFederate.valid()) {
742 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
745 return _rtiFederate->processMessages(minimum, maximum);
749 HLAFederate::readObjectModelTemplate(const std::string& objectModel,
750 HLAFederate::ObjectModelFactory& objectModelFactory)
752 // The XML version of the federate object model.
753 // This one covers the generic attributes, parameters and data types.
754 HLAOMTXmlVisitor omtXmlVisitor;
756 readXML(objectModel, omtXmlVisitor);
757 } catch (const sg_throwable& e) {
758 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
762 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
766 omtXmlVisitor.setDataTypesToFederate(*this);
768 unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
769 for (unsigned i = 0; i < numObjectClasses; ++i) {
770 const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
771 std::string objectClassName = objectClass->getName();
773 SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
774 if (!hlaObjectClass.valid()) {
775 SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
779 bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
780 bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
782 // process the attributes
783 for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
784 const simgear::HLAOMTXmlVisitor::Attribute* attribute;
785 attribute = objectClass->getAttribute(j);
787 std::string attributeName = attribute->getName();
788 unsigned index = hlaObjectClass->addAttribute(attributeName);
791 SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
795 // the attributes datatype
796 SGSharedPtr<const HLADataType> dataType = getDataType(attribute->getDataType());
797 if (!dataType.valid()) {
798 SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
799 << attributeName << "\" in object class \"" << objectClassName << "\"!");
801 hlaObjectClass->setAttributeDataType(index, dataType);
802 hlaObjectClass->setAttributeUpdateType(index, attribute->getUpdateType());
803 if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
804 hlaObjectClass->setAttributeSubscriptionType(index, attribute->getSubscriptionType());
805 if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
806 hlaObjectClass->setAttributePublicationType(index, attribute->getPublicationType());
810 hlaObjectClass->publish();
812 hlaObjectClass->subscribe();
816 return resolveObjectModel();
820 HLAFederate::readRTI13ObjectModelTemplate(const std::string& objectModel)
822 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI13 not yet(!?) supported.");
827 HLAFederate::readRTI1516ObjectModelTemplate(const std::string& objectModel)
829 // The XML version of the federate object model.
830 // This one covers the generic attributes, parameters and data types.
831 HLAOMTXmlVisitor omtXmlVisitor;
833 readXML(objectModel, omtXmlVisitor);
834 } catch (const sg_throwable& e) {
835 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
839 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
843 omtXmlVisitor.setToFederate(*this);
845 return resolveObjectModel();
849 HLAFederate::readRTI1516EObjectModelTemplate(const std::string& objectModel)
851 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
856 HLAFederate::resolveObjectModel()
858 if (!_rtiFederate.valid()) {
859 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
863 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
864 RTIInteractionClass* rtiInteractionClass = _rtiFederate->createInteractionClass(i->second->getName(), i->second.get());
865 if (!rtiInteractionClass) {
866 SG_LOG(SG_NETWORK, SG_ALERT, "HLAFederate::_insertInteractionClass(): "
867 "No RTIInteractionClass found for \"" << i->second->getName() << "\"!");
870 i->second->_setRTIInteractionClass(rtiInteractionClass);
873 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
874 RTIObjectClass* rtiObjectClass = _rtiFederate->createObjectClass(i->second->getName(), i->second.get());
875 if (!rtiObjectClass) {
876 SG_LOG(SG_NETWORK, SG_ALERT, "HLAFederate::_insertObjectClass(): "
877 "No RTIObjectClass found for \"" << i->second->getName() << "\"!");
880 i->second->_setRTIObjectClass(rtiObjectClass);
887 HLAFederate::getDataType(const std::string& name) const
889 DataTypeMap::const_iterator i = _dataTypeMap.find(name);
890 if (i == _dataTypeMap.end())
892 return i->second.get();
896 HLAFederate::insertDataType(const std::string& name, const SGSharedPtr<HLADataType>& dataType)
898 if (!dataType.valid())
900 if (_dataTypeMap.find(name) != _dataTypeMap.end()) {
901 SG_LOG(SG_IO, SG_ALERT, "HLAFederate::insertDataType: data type with name \""
902 << name << "\" already known to federate!");
905 _dataTypeMap.insert(DataTypeMap::value_type(name, dataType));
910 HLAFederate::recomputeDataTypeAlignment()
912 // Finish alignment computations
916 for (DataTypeMap::iterator i = _dataTypeMap.begin(); i != _dataTypeMap.end(); ++i) {
917 if (i->second->recomputeAlignment())
924 HLAFederate::getInteractionClass(const std::string& name)
926 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
927 if (i == _interactionClassMap.end())
929 return i->second.get();
932 const HLAInteractionClass*
933 HLAFederate::getInteractionClass(const std::string& name) const
935 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
936 if (i == _interactionClassMap.end())
938 return i->second.get();
942 HLAFederate::createInteractionClass(const std::string& name)
944 return new HLAInteractionClass(name, this);
948 HLAFederate::getObjectClass(const std::string& name)
950 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
951 if (i == _objectClassMap.end())
953 return i->second.get();
956 const HLAObjectClass*
957 HLAFederate::getObjectClass(const std::string& name) const
959 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
960 if (i == _objectClassMap.end())
962 return i->second.get();
966 HLAFederate::createObjectClass(const std::string& name)
968 return new HLAObjectClass(name, this);
972 HLAFederate::getObjectInstance(const std::string& name)
974 ObjectInstanceMap::const_iterator i = _objectInstanceMap.find(name);
975 if (i == _objectInstanceMap.end())
977 return i->second.get();
980 const HLAObjectInstance*
981 HLAFederate::getObjectInstance(const std::string& name) const
983 ObjectInstanceMap::const_iterator i = _objectInstanceMap.find(name);
984 if (i == _objectInstanceMap.end())
986 return i->second.get();
990 HLAFederate::createObjectInstance(HLAObjectClass* objectClass, const std::string& name)
992 return new HLAObjectInstance(objectClass);
996 HLAFederate::setDone(bool done)
1002 HLAFederate::getDone() const
1008 HLAFederate::readObjectModel()
1010 // Depending on the actual version, try to find an apropriate
1011 // file format for the given file. The first one is always the
1012 // version native object model file format.
1013 switch (getVersion()) {
1015 if (readRTI13ObjectModelTemplate(getFederationObjectModel()))
1017 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1019 return readRTI1516EObjectModelTemplate(getFederationObjectModel());
1021 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1023 if (readRTI1516EObjectModelTemplate(getFederationObjectModel()))
1025 return readRTI13ObjectModelTemplate(getFederationObjectModel());
1027 if (readRTI1516EObjectModelTemplate(getFederationObjectModel()))
1029 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1031 return readRTI13ObjectModelTemplate(getFederationObjectModel());
1038 HLAFederate::subscribe()
1040 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
1041 if (!i->second->subscribe())
1045 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
1046 if (!i->second->subscribe())
1054 HLAFederate::publish()
1056 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
1057 if (!i->second->publish())
1061 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
1062 if (!i->second->publish())
1072 // We need to talk to the rti
1076 if (_createFederationExecution) {
1077 if (!createJoinFederationExecution())
1083 // Read the xml file containing the object model
1084 if (!readObjectModel()) {
1088 // start being time constrained if required
1089 if (_timeConstrained) {
1090 if (!enableTimeConstrained()) {
1095 // Now that we are potentially time constrained, we can subscribe.
1096 // This is to make sure we do not get any time stamped message
1097 // converted to a non time stamped message by the rti.
1102 // Before we publish anything start getting regulating if required
1103 if (_timeRegulating) {
1104 if (!enableTimeRegulation()) {
1109 // Note that starting from here, we need to be careful with things
1110 // requireing unbounded time. The rest of the federation might wait
1111 // for us to finish!
1113 // Compute the time offset from the system time to the simulation time
1114 if (_timeConstrainedByLocalClock) {
1115 if (!enableTimeConstrainedByLocalClock()) {
1116 SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time constrained by local clock!");
1122 // Publish what we want to write
1132 HLAFederate::update()
1134 return timeAdvanceBy(_timeIncrement);
1138 HLAFederate::shutdown()
1140 // On shutdown, just try all in order.
1141 // If something goes wrong, continue and try to get out here as good as possible.
1144 if (_createFederationExecution) {
1145 if (!resignDestroyFederationExecution())
1164 while (!getDone()) {
1178 HLAFederate::_clearRTI()
1180 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i)
1181 i->second->_clearRTIInteractionClass();
1182 for (ObjectInstanceMap::iterator i = _objectInstanceMap.begin(); i != _objectInstanceMap.end(); ++i)
1183 i->second->_clearRTIObjectInstance();
1184 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i)
1185 i->second->_clearRTIObjectClass();
1191 HLAFederate::_insertInteractionClass(const SGSharedPtr<HLAInteractionClass>& interactionClass)
1193 if (!interactionClass.valid())
1195 if (_interactionClassMap.find(interactionClass->getName()) != _interactionClassMap.end()) {
1196 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertInteractionClass: object instance with name \""
1197 << interactionClass->getName() << "\" already known to federate!");
1200 _interactionClassMap.insert(InteractionClassMap::value_type(interactionClass->getName(), interactionClass));
1205 HLAFederate::_insertObjectClass(const SGSharedPtr<HLAObjectClass>& objectClass)
1207 if (!objectClass.valid())
1209 if (_objectClassMap.find(objectClass->getName()) != _objectClassMap.end()) {
1210 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertObjectClass: object instance with name \""
1211 << objectClass->getName() << "\" already known to federate!");
1214 _objectClassMap.insert(ObjectClassMap::value_type(objectClass->getName(), objectClass));
1219 HLAFederate::_insertObjectInstance(const SGSharedPtr<HLAObjectInstance>& objectInstance)
1221 if (!objectInstance.valid())
1223 if (objectInstance->getName().empty()) {
1224 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertObjectInstance: trying to insert object instance with empty name!");
1227 if (_objectInstanceMap.find(objectInstance->getName()) != _objectInstanceMap.end()) {
1228 SG_LOG(SG_IO, SG_WARN, "HLA: _insertObjectInstance: object instance with name \""
1229 << objectInstance->getName() << "\" already known to federate!");
1232 _objectInstanceMap.insert(ObjectInstanceMap::value_type(objectInstance->getName(), objectInstance));
1237 HLAFederate::_eraseObjectInstance(const std::string& name)
1239 ObjectInstanceMap::iterator i = _objectInstanceMap.find(name);
1240 if (i == _objectInstanceMap.end()) {
1241 SG_LOG(SG_IO, SG_WARN, "HLA: _eraseObjectInstance: object instance with name \""
1242 << name << "\" not known to federate!");
1245 _objectInstanceMap.erase(i);
1248 } // namespace simgear