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!");
82 HLAFederate::setVersion(const std::string& version)
84 if (version == "RTI13")
85 return setVersion(RTI13);
86 else if (version == "RTI1516")
87 return setVersion(RTI1516);
88 else if (version == "RTI1516E")
89 return setVersion(RTI1516E);
91 /// at some time think about routing these down to the factory
92 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Unknown version string in HLAFederate::setVersion!");
97 const std::list<std::string>&
98 HLAFederate::getConnectArguments() const
100 return _connectArguments;
104 HLAFederate::setConnectArguments(const std::list<std::string>& connectArguments)
106 if (_rtiFederate.valid()) {
107 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
110 _connectArguments = connectArguments;
115 HLAFederate::getCreateFederationExecution() const
117 return _createFederationExecution;
121 HLAFederate::setCreateFederationExecution(bool createFederationExecution)
123 _createFederationExecution = createFederationExecution;
128 HLAFederate::getFederationExecutionName() const
130 return _federationExecutionName;
134 HLAFederate::setFederationExecutionName(const std::string& federationExecutionName)
136 if (_rtiFederate.valid()) {
137 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
140 _federationExecutionName = federationExecutionName;
145 HLAFederate::getFederationObjectModel() const
147 return _federationObjectModel;
151 HLAFederate::setFederationObjectModel(const std::string& federationObjectModel)
153 if (_rtiFederate.valid()) {
154 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
157 _federationObjectModel = federationObjectModel;
162 HLAFederate::getFederateType() const
164 return _federateType;
168 HLAFederate::setFederateType(const std::string& federateType)
170 if (_rtiFederate.valid()) {
171 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
174 _federateType = federateType;
179 HLAFederate::getFederateName() const
181 return _federateName;
185 HLAFederate::setFederateName(const std::string& federateName)
187 if (_rtiFederate.valid()) {
188 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
191 _federateName = federateName;
196 HLAFederate::connect(Version version, const std::list<std::string>& stringList)
199 _connectArguments = stringList;
204 HLAFederate::connect()
206 if (_rtiFederate.valid()) {
207 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
211 SGSharedPtr<RTIFederateFactoryRegistry> registry = RTIFederateFactoryRegistry::instance();
213 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: RTIFederateFactoryRegistry is no longer available!");
219 _rtiFederate = registry->create("RTI13", _connectArguments);
222 _rtiFederate = registry->create("RTI1516", _connectArguments);
225 _rtiFederate = registry->create("RTI1516E", _connectArguments);
228 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
230 return _rtiFederate.valid();
234 HLAFederate::disconnect()
236 if (!_rtiFederate.valid()) {
237 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
246 HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
248 if (!_rtiFederate.valid()) {
249 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
253 RTIFederate::FederationManagementResult createResult;
254 createResult = _rtiFederate->createFederationExecution(federation, objectModel);
255 if (createResult == RTIFederate::FederationManagementFatal)
258 _federationExecutionName = federation;
259 _federationObjectModel = objectModel;
264 HLAFederate::destroyFederationExecution(const std::string& federation)
266 if (!_rtiFederate.valid()) {
267 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
271 RTIFederate::FederationManagementResult destroyResult;
272 destroyResult = _rtiFederate->destroyFederationExecution(federation);
273 if (destroyResult == RTIFederate::FederationManagementFatal)
280 HLAFederate::createFederationExecution()
282 if (!_rtiFederate.valid()) {
283 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
287 RTIFederate::FederationManagementResult createResult;
288 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
289 if (createResult != RTIFederate::FederationManagementSuccess)
296 HLAFederate::destroyFederationExecution()
298 if (!_rtiFederate.valid()) {
299 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
303 RTIFederate::FederationManagementResult destroyResult;
304 destroyResult = _rtiFederate->destroyFederationExecution(_federationExecutionName);
305 if (destroyResult != RTIFederate::FederationManagementSuccess)
312 HLAFederate::join(const std::string& federateType, const std::string& federation)
314 if (!_rtiFederate.valid()) {
315 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
319 RTIFederate::FederationManagementResult joinResult;
320 joinResult = _rtiFederate->join(federateType, federation);
321 if (joinResult == RTIFederate::FederationManagementFatal)
330 if (!_rtiFederate.valid()) {
331 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
335 RTIFederate::FederationManagementResult joinResult;
336 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
337 if (joinResult != RTIFederate::FederationManagementSuccess)
344 HLAFederate::resign()
346 if (!_rtiFederate.valid()) {
347 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
350 return _rtiFederate->resign();
354 HLAFederate::createJoinFederationExecution()
356 if (!_rtiFederate.valid()) {
357 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
363 RTIFederate::FederationManagementResult joinResult;
364 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
365 switch (joinResult) {
366 case RTIFederate::FederationManagementSuccess:
367 // Fast return on success
369 case RTIFederate::FederationManagementFatal:
370 // Abort on fatal errors
376 // If not already joinable, try to create the requested federation
377 RTIFederate::FederationManagementResult createResult;
378 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
379 switch (createResult) {
380 case RTIFederate::FederationManagementFatal:
381 // Abort on fatal errors
391 HLAFederate::resignDestroyFederationExecution()
393 if (!_rtiFederate.valid()) {
394 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
399 bool success = _rtiFederate->resign();
401 // and try to destroy, non fatal if still some federates joined
402 if (_rtiFederate->destroyFederationExecution(_federationExecutionName) == RTIFederate::FederationManagementFatal)
409 HLAFederate::getTimeConstrained() const
411 return _timeConstrained;
415 HLAFederate::setTimeConstrained(bool timeConstrained)
417 _timeConstrained = timeConstrained;
419 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
420 if (_timeConstrained && !_rtiFederate->getTimeConstrainedEnabled()) {
421 if (!enableTimeConstrained())
423 } else if (!_timeConstrained && _rtiFederate->getTimeConstrainedEnabled()) {
424 if (!disableTimeConstrained())
434 HLAFederate::getTimeConstrainedByLocalClock() const
436 return _timeConstrainedByLocalClock;
440 HLAFederate::setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock)
442 _timeConstrainedByLocalClock = timeConstrainedByLocalClock;
444 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
445 if (_timeConstrainedByLocalClock) {
446 if (!enableTimeConstrainedByLocalClock())
455 HLAFederate::getTimeRegulating() const
457 return _timeRegulating;
461 HLAFederate::setTimeRegulating(bool timeRegulating)
463 _timeRegulating = timeRegulating;
465 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
466 if (_timeRegulating && !_rtiFederate->getTimeRegulationEnabled()) {
467 if (!enableTimeRegulation())
469 } else if (!_timeRegulating && _rtiFederate->getTimeRegulationEnabled()) {
470 if (!disableTimeRegulation())
479 HLAFederate::setLeadTime(const SGTimeStamp& leadTime)
481 if (leadTime < SGTimeStamp::fromSec(0)) {
482 SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative lead time!");
486 _leadTime = leadTime;
488 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
489 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
490 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
499 HLAFederate::getLeadTime() const
505 HLAFederate::setTimeIncrement(const SGTimeStamp& timeIncrement)
507 if (timeIncrement < SGTimeStamp::fromSec(0)) {
508 SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative time increment!");
512 _timeIncrement = timeIncrement;
514 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
515 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
516 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
525 HLAFederate::getTimeIncrement() const
527 return _timeIncrement;
531 HLAFederate::enableTimeConstrained()
533 if (!_rtiFederate.valid()) {
534 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
538 if (!_rtiFederate->enableTimeConstrained()) {
539 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time constrained!");
543 while (!_rtiFederate->getTimeConstrainedEnabled()) {
544 _rtiFederate->processMessage();
551 HLAFederate::disableTimeConstrained()
553 if (!_rtiFederate.valid()) {
554 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
557 return _rtiFederate->disableTimeConstrained();
561 HLAFederate::enableTimeConstrainedByLocalClock()
563 // Compute the time offset from the system time to the simulation time
564 SGTimeStamp federateTime;
565 if (!queryFederateTime(federateTime)) {
566 SG_LOG(SG_NETWORK, SG_WARN, "Cannot get federate time!");
569 _localClockOffset = SGTimeStamp::now() - federateTime;
574 HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
576 if (!_rtiFederate.valid()) {
577 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
581 if (!_rtiFederate->enableTimeRegulation(lookahead)) {
582 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time regulation!");
586 while (!_rtiFederate->getTimeRegulationEnabled()) {
587 _rtiFederate->processMessage();
594 HLAFederate::enableTimeRegulation()
596 if (!enableTimeRegulation(SGTimeStamp::fromSec(0))) {
597 SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time regulation!");
600 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
601 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
608 HLAFederate::disableTimeRegulation()
610 if (!_rtiFederate.valid()) {
611 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
614 return _rtiFederate->disableTimeRegulation();
618 HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
620 if (!_rtiFederate.valid()) {
621 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
624 return _rtiFederate->modifyLookahead(timeStamp);
628 HLAFederate::timeAdvanceBy(const SGTimeStamp& timeIncrement)
630 if (!_rtiFederate.valid()) {
631 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
635 SGTimeStamp timeStamp;
636 if (!_rtiFederate->queryFederateTime(timeStamp)) {
637 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query federate time!");
641 if (!_rtiFederate->timeAdvanceRequest(timeStamp + timeIncrement)) {
642 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
646 return processMessages();
650 HLAFederate::timeAdvance(const SGTimeStamp& timeStamp)
652 if (!_rtiFederate.valid()) {
653 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
657 if (!_rtiFederate->timeAdvanceRequest(timeStamp)) {
658 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
662 return processMessages();
666 HLAFederate::timeAdvanceAvailable()
668 if (!_rtiFederate.valid()) {
669 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
673 SGTimeStamp timeStamp;
674 if (_rtiFederate->queryGALT(timeStamp)) {
675 if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) {
676 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
681 return processMessages();
685 HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
687 if (!_rtiFederate.valid()) {
688 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
691 return _rtiFederate->queryFederateTime(timeStamp);
695 HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
697 if (!_rtiFederate.valid()) {
698 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
701 return _rtiFederate->queryLookahead(timeStamp);
705 HLAFederate::processMessage()
707 if (!_rtiFederate.valid()) {
708 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
711 return _rtiFederate->processMessage();
715 HLAFederate::processMessage(const SGTimeStamp& timeout)
717 if (!_rtiFederate.valid()) {
718 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
721 return _rtiFederate->processMessages(timeout.toSecs(), 0);
725 HLAFederate::processMessages()
727 if (!_rtiFederate.valid()) {
728 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
732 while (_rtiFederate->getTimeAdvancePending()) {
733 _rtiFederate->processMessage();
736 if (_timeConstrainedByLocalClock) {
737 SGTimeStamp federateTime;
738 if (!_rtiFederate->queryFederateTime(federateTime)) {
739 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Error querying federate time!");
742 SGTimeStamp systemTime = federateTime + _localClockOffset;
744 double rest = (systemTime - SGTimeStamp::now()).toSecs();
747 _rtiFederate->processMessages(rest, rest);
751 // Now flush just what is left
752 while (_rtiFederate->processMessages(0, 0));
758 HLAFederate::readObjectModelTemplate(const std::string& objectModel,
759 HLAFederate::ObjectModelFactory& objectModelFactory)
761 // The XML version of the federate object model.
762 // This one covers the generic attributes, parameters and data types.
763 HLAOMTXmlVisitor omtXmlVisitor;
765 readXML(objectModel, omtXmlVisitor);
766 } catch (const sg_throwable& e) {
767 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
771 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
775 omtXmlVisitor.setDataTypesToFederate(*this);
777 unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
778 for (unsigned i = 0; i < numObjectClasses; ++i) {
779 const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
780 std::string objectClassName = objectClass->getName();
782 SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
783 if (!hlaObjectClass.valid()) {
784 SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
788 bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
789 bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
791 // process the attributes
792 for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
793 const simgear::HLAOMTXmlVisitor::Attribute* attribute;
794 attribute = objectClass->getAttribute(j);
796 std::string attributeName = attribute->getName();
797 unsigned index = hlaObjectClass->addAttribute(attributeName);
800 SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
804 // the attributes datatype
805 SGSharedPtr<const HLADataType> dataType = getDataType(attribute->getDataType());
806 if (!dataType.valid()) {
807 SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
808 << attributeName << "\" in object class \"" << objectClassName << "\"!");
810 hlaObjectClass->setAttributeDataType(index, dataType);
811 hlaObjectClass->setAttributeUpdateType(index, attribute->getUpdateType());
812 if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
813 hlaObjectClass->setAttributeSubscriptionType(index, attribute->getSubscriptionType());
814 if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
815 hlaObjectClass->setAttributePublicationType(index, attribute->getPublicationType());
819 hlaObjectClass->publish();
821 hlaObjectClass->subscribe();
825 return resolveObjectModel();
829 HLAFederate::readRTI13ObjectModelTemplate(const std::string& objectModel)
831 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI13 not yet(!?) supported.");
836 HLAFederate::readRTI1516ObjectModelTemplate(const std::string& objectModel)
838 // The XML version of the federate object model.
839 // This one covers the generic attributes, parameters and data types.
840 HLAOMTXmlVisitor omtXmlVisitor;
842 readXML(objectModel, omtXmlVisitor);
843 } catch (const sg_throwable& e) {
844 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
848 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
852 omtXmlVisitor.setToFederate(*this);
854 return resolveObjectModel();
858 HLAFederate::readRTI1516EObjectModelTemplate(const std::string& objectModel)
860 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
865 HLAFederate::resolveObjectModel()
867 if (!_rtiFederate.valid()) {
868 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
872 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
873 RTIInteractionClass* rtiInteractionClass = _rtiFederate->createInteractionClass(i->second->getName(), i->second.get());
874 if (!rtiInteractionClass) {
875 SG_LOG(SG_NETWORK, SG_ALERT, "HLAFederate::_insertInteractionClass(): "
876 "No RTIInteractionClass found for \"" << i->second->getName() << "\"!");
879 i->second->_setRTIInteractionClass(rtiInteractionClass);
882 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
883 RTIObjectClass* rtiObjectClass = _rtiFederate->createObjectClass(i->second->getName(), i->second.get());
884 if (!rtiObjectClass) {
885 SG_LOG(SG_NETWORK, SG_ALERT, "HLAFederate::_insertObjectClass(): "
886 "No RTIObjectClass found for \"" << i->second->getName() << "\"!");
889 i->second->_setRTIObjectClass(rtiObjectClass);
896 HLAFederate::getDataType(const std::string& name) const
898 DataTypeMap::const_iterator i = _dataTypeMap.find(name);
899 if (i == _dataTypeMap.end())
901 return i->second.get();
905 HLAFederate::insertDataType(const std::string& name, const SGSharedPtr<HLADataType>& dataType)
907 if (!dataType.valid())
909 if (_dataTypeMap.find(name) != _dataTypeMap.end()) {
910 SG_LOG(SG_IO, SG_ALERT, "HLAFederate::insertDataType: data type with name \""
911 << name << "\" already known to federate!");
914 _dataTypeMap.insert(DataTypeMap::value_type(name, dataType));
919 HLAFederate::recomputeDataTypeAlignment()
921 // Finish alignment computations
925 for (DataTypeMap::iterator i = _dataTypeMap.begin(); i != _dataTypeMap.end(); ++i) {
926 if (i->second->recomputeAlignment())
933 HLAFederate::getInteractionClass(const std::string& name)
935 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
936 if (i == _interactionClassMap.end())
938 return i->second.get();
941 const HLAInteractionClass*
942 HLAFederate::getInteractionClass(const std::string& name) const
944 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
945 if (i == _interactionClassMap.end())
947 return i->second.get();
951 HLAFederate::createInteractionClass(const std::string& name)
953 return new HLAInteractionClass(name, this);
957 HLAFederate::getObjectClass(const std::string& name)
959 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
960 if (i == _objectClassMap.end())
962 return i->second.get();
965 const HLAObjectClass*
966 HLAFederate::getObjectClass(const std::string& name) const
968 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
969 if (i == _objectClassMap.end())
971 return i->second.get();
975 HLAFederate::createObjectClass(const std::string& name)
977 return new HLAObjectClass(name, this);
981 HLAFederate::getObjectInstance(const std::string& name)
983 ObjectInstanceMap::const_iterator i = _objectInstanceMap.find(name);
984 if (i == _objectInstanceMap.end())
986 return i->second.get();
989 const HLAObjectInstance*
990 HLAFederate::getObjectInstance(const std::string& name) const
992 ObjectInstanceMap::const_iterator i = _objectInstanceMap.find(name);
993 if (i == _objectInstanceMap.end())
995 return i->second.get();
999 HLAFederate::createObjectInstance(HLAObjectClass* objectClass, const std::string& name)
1001 return new HLAObjectInstance(objectClass);
1005 HLAFederate::setDone(bool done)
1011 HLAFederate::getDone() const
1017 HLAFederate::readObjectModel()
1019 // Depending on the actual version, try to find an apropriate
1020 // file format for the given file. The first one is always the
1021 // version native object model file format.
1022 switch (getVersion()) {
1024 if (readRTI13ObjectModelTemplate(getFederationObjectModel()))
1026 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1028 return readRTI1516EObjectModelTemplate(getFederationObjectModel());
1030 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1032 if (readRTI1516EObjectModelTemplate(getFederationObjectModel()))
1034 return readRTI13ObjectModelTemplate(getFederationObjectModel());
1036 if (readRTI1516EObjectModelTemplate(getFederationObjectModel()))
1038 if (readRTI1516ObjectModelTemplate(getFederationObjectModel()))
1040 return readRTI13ObjectModelTemplate(getFederationObjectModel());
1047 HLAFederate::subscribe()
1049 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
1050 if (!i->second->subscribe())
1054 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
1055 if (!i->second->subscribe())
1063 HLAFederate::publish()
1065 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i) {
1066 if (!i->second->publish())
1070 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i) {
1071 if (!i->second->publish())
1081 // We need to talk to the rti
1085 if (_createFederationExecution) {
1086 if (!createJoinFederationExecution())
1092 // Read the xml file containing the object model
1093 if (!readObjectModel()) {
1097 // start being time constrained if required
1098 if (_timeConstrained) {
1099 if (!enableTimeConstrained()) {
1104 // Now that we are potentially time constrained, we can subscribe.
1105 // This is to make sure we do not get any time stamped message
1106 // converted to a non time stamped message by the rti.
1111 // Before we publish anything start getting regulating if required
1112 if (_timeRegulating) {
1113 if (!enableTimeRegulation()) {
1118 // Note that starting from here, we need to be careful with things
1119 // requireing unbounded time. The rest of the federation might wait
1120 // for us to finish!
1122 // Compute the time offset from the system time to the simulation time
1123 if (_timeConstrainedByLocalClock) {
1124 if (!enableTimeConstrainedByLocalClock()) {
1125 SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time constrained by local clock!");
1131 // Publish what we want to write
1141 HLAFederate::update()
1143 return timeAdvanceBy(_timeIncrement);
1147 HLAFederate::shutdown()
1149 // On shutdown, just try all in order.
1150 // If something goes wrong, continue and try to get out here as good as possible.
1153 if (_createFederationExecution) {
1154 if (!resignDestroyFederationExecution())
1173 while (!getDone()) {
1187 HLAFederate::_clearRTI()
1189 for (InteractionClassMap::iterator i = _interactionClassMap.begin(); i != _interactionClassMap.end(); ++i)
1190 i->second->_clearRTIInteractionClass();
1191 for (ObjectInstanceMap::iterator i = _objectInstanceMap.begin(); i != _objectInstanceMap.end(); ++i)
1192 i->second->_clearRTIObjectInstance();
1193 for (ObjectClassMap::iterator i = _objectClassMap.begin(); i != _objectClassMap.end(); ++i)
1194 i->second->_clearRTIObjectClass();
1200 HLAFederate::_insertInteractionClass(const SGSharedPtr<HLAInteractionClass>& interactionClass)
1202 if (!interactionClass.valid())
1204 if (_interactionClassMap.find(interactionClass->getName()) != _interactionClassMap.end()) {
1205 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertInteractionClass: object instance with name \""
1206 << interactionClass->getName() << "\" already known to federate!");
1209 _interactionClassMap.insert(InteractionClassMap::value_type(interactionClass->getName(), interactionClass));
1214 HLAFederate::_insertObjectClass(const SGSharedPtr<HLAObjectClass>& objectClass)
1216 if (!objectClass.valid())
1218 if (_objectClassMap.find(objectClass->getName()) != _objectClassMap.end()) {
1219 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertObjectClass: object instance with name \""
1220 << objectClass->getName() << "\" already known to federate!");
1223 _objectClassMap.insert(ObjectClassMap::value_type(objectClass->getName(), objectClass));
1228 HLAFederate::_insertObjectInstance(const SGSharedPtr<HLAObjectInstance>& objectInstance)
1230 if (!objectInstance.valid())
1232 if (objectInstance->getName().empty()) {
1233 SG_LOG(SG_IO, SG_ALERT, "HLA: _insertObjectInstance: trying to insert object instance with empty name!");
1236 if (_objectInstanceMap.find(objectInstance->getName()) != _objectInstanceMap.end()) {
1237 SG_LOG(SG_IO, SG_WARN, "HLA: _insertObjectInstance: object instance with name \""
1238 << objectInstance->getName() << "\" already known to federate!");
1241 _objectInstanceMap.insert(ObjectInstanceMap::value_type(objectInstance->getName(), objectInstance));
1246 HLAFederate::_eraseObjectInstance(const std::string& name)
1248 ObjectInstanceMap::iterator i = _objectInstanceMap.find(name);
1249 if (i == _objectInstanceMap.end()) {
1250 SG_LOG(SG_IO, SG_WARN, "HLA: _eraseObjectInstance: object instance with name \""
1251 << name << "\" not known to federate!");
1254 _objectInstanceMap.erase(i);
1257 } // namespace simgear