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"
20 #include "simgear/debug/logstream.hxx"
22 #include "RTIFederate.hxx"
23 #include "RTIFederateFactoryRegistry.hxx"
24 #include "RTI13FederateFactory.hxx"
25 #include "RTIInteractionClass.hxx"
26 #include "RTIObjectClass.hxx"
27 #include "HLADataElement.hxx"
28 #include "HLADataType.hxx"
29 #include "HLAOMTXmlVisitor.hxx"
33 HLAFederate::HLAFederate() :
35 _createFederationExecution(true),
36 _timeConstrained(false),
37 _timeRegulating(false),
38 _timeConstrainedByLocalClock(false),
41 // For now instantiate the current only available factory here explicitly
42 RTI13FederateFactory::instance();
45 HLAFederate::~HLAFederate()
50 HLAFederate::getVersion() const
56 HLAFederate::setVersion(HLAFederate::Version version)
58 if (_rtiFederate.valid()) {
59 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
66 const std::list<std::string>&
67 HLAFederate::getConnectArguments() const
69 return _connectArguments;
73 HLAFederate::setConnectArguments(const std::list<std::string>& connectArguments)
75 if (_rtiFederate.valid()) {
76 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
79 _connectArguments = connectArguments;
84 HLAFederate::getCreateFederationExecution() const
86 return _createFederationExecution;
90 HLAFederate::setCreateFederationExecution(bool createFederationExecution)
92 _createFederationExecution = createFederationExecution;
97 HLAFederate::getFederationExecutionName() const
99 return _federationExecutionName;
103 HLAFederate::setFederationExecutionName(const std::string& federationExecutionName)
105 if (_rtiFederate.valid()) {
106 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
109 _federationExecutionName = federationExecutionName;
114 HLAFederate::getFederationObjectModel() const
116 return _federationObjectModel;
120 HLAFederate::setFederationObjectModel(const std::string& federationObjectModel)
122 if (_rtiFederate.valid()) {
123 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
126 _federationObjectModel = federationObjectModel;
131 HLAFederate::getFederateType() const
133 return _federateType;
137 HLAFederate::setFederateType(const std::string& federateType)
139 if (_rtiFederate.valid()) {
140 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
143 _federateType = federateType;
148 HLAFederate::getFederateName() const
150 return _federateName;
154 HLAFederate::setFederateName(const std::string& federateName)
156 if (_rtiFederate.valid()) {
157 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
160 _federateName = federateName;
165 HLAFederate::connect(Version version, const std::list<std::string>& stringList)
168 _connectArguments = stringList;
173 HLAFederate::connect()
175 if (_rtiFederate.valid()) {
176 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
180 SGSharedPtr<RTIFederateFactoryRegistry> registry = RTIFederateFactoryRegistry::instance();
182 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: RTIFederateFactoryRegistry is no longer available!");
188 _rtiFederate = registry->create("RTI13", _connectArguments);
191 _rtiFederate = registry->create("RTI1516", _connectArguments);
194 _rtiFederate = registry->create("RTI1516E", _connectArguments);
197 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
199 return _rtiFederate.valid();
203 HLAFederate::disconnect()
205 if (!_rtiFederate.valid()) {
206 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
214 HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
216 if (!_rtiFederate.valid()) {
217 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
221 RTIFederate::FederationManagementResult createResult;
222 createResult = _rtiFederate->createFederationExecution(federation, objectModel);
223 if (createResult == RTIFederate::FederationManagementFatal)
226 _federationExecutionName = federation;
227 _federationObjectModel = objectModel;
232 HLAFederate::destroyFederationExecution(const std::string& federation)
234 if (!_rtiFederate.valid()) {
235 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
239 RTIFederate::FederationManagementResult destroyResult;
240 destroyResult = _rtiFederate->destroyFederationExecution(federation);
241 if (destroyResult == RTIFederate::FederationManagementFatal)
248 HLAFederate::createFederationExecution()
250 if (!_rtiFederate.valid()) {
251 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
255 RTIFederate::FederationManagementResult createResult;
256 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
257 if (createResult != RTIFederate::FederationManagementSuccess)
264 HLAFederate::destroyFederationExecution()
266 if (!_rtiFederate.valid()) {
267 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
271 RTIFederate::FederationManagementResult destroyResult;
272 destroyResult = _rtiFederate->destroyFederationExecution(_federationExecutionName);
273 if (destroyResult != RTIFederate::FederationManagementSuccess)
280 HLAFederate::join(const std::string& federateType, const std::string& federation)
282 if (!_rtiFederate.valid()) {
283 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
287 RTIFederate::FederationManagementResult joinResult;
288 joinResult = _rtiFederate->join(federateType, federation);
289 if (joinResult == RTIFederate::FederationManagementFatal)
298 if (!_rtiFederate.valid()) {
299 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
303 RTIFederate::FederationManagementResult joinResult;
304 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
305 if (joinResult != RTIFederate::FederationManagementSuccess)
312 HLAFederate::resign()
314 if (!_rtiFederate.valid()) {
315 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
318 return _rtiFederate->resign();
322 HLAFederate::createJoinFederationExecution()
324 if (!_rtiFederate.valid()) {
325 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
331 RTIFederate::FederationManagementResult joinResult;
332 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
333 switch (joinResult) {
334 case RTIFederate::FederationManagementSuccess:
335 // Fast return on success
337 case RTIFederate::FederationManagementFatal:
338 // Abort on fatal errors
344 // If not already joinable, try to create the requested federation
345 RTIFederate::FederationManagementResult createResult;
346 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
347 switch (createResult) {
348 case RTIFederate::FederationManagementFatal:
349 // Abort on fatal errors
359 HLAFederate::resignDestroyFederationExecution()
361 if (!_rtiFederate.valid()) {
362 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
367 bool success = _rtiFederate->resign();
369 // and try to destroy, non fatal if still some federates joined
370 if (_rtiFederate->destroyFederationExecution(_federationExecutionName) == RTIFederate::FederationManagementFatal)
377 HLAFederate::getTimeConstrained() const
379 return _timeConstrained;
383 HLAFederate::setTimeConstrained(bool timeConstrained)
385 _timeConstrained = timeConstrained;
387 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
388 if (_timeConstrained && !_rtiFederate->getTimeConstrainedEnabled()) {
389 if (!enableTimeConstrained())
391 } else if (!_timeConstrained && _rtiFederate->getTimeConstrainedEnabled()) {
392 if (!disableTimeConstrained())
402 HLAFederate::getTimeConstrainedByLocalClock() const
404 return _timeConstrainedByLocalClock;
408 HLAFederate::setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock)
410 _timeConstrainedByLocalClock = timeConstrainedByLocalClock;
412 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
413 if (_timeConstrainedByLocalClock) {
414 if (!enableTimeConstrainedByLocalClock())
423 HLAFederate::getTimeRegulating() const
425 return _timeRegulating;
429 HLAFederate::setTimeRegulating(bool timeRegulating)
431 _timeRegulating = timeRegulating;
433 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
434 if (_timeRegulating && !_rtiFederate->getTimeRegulationEnabled()) {
435 if (!enableTimeRegulation())
437 } else if (!_timeRegulating && _rtiFederate->getTimeRegulationEnabled()) {
438 if (!disableTimeRegulation())
447 HLAFederate::setLeadTime(const SGTimeStamp& leadTime)
449 if (leadTime < SGTimeStamp::fromSec(0)) {
450 SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative lead time!");
454 _leadTime = leadTime;
456 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
457 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
458 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
467 HLAFederate::getLeadTime() const
473 HLAFederate::setTimeIncrement(const SGTimeStamp& timeIncrement)
475 if (timeIncrement < SGTimeStamp::fromSec(0)) {
476 SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative time increment!");
480 _timeIncrement = timeIncrement;
482 if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
483 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
484 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
493 HLAFederate::getTimeIncrement() const
495 return _timeIncrement;
499 HLAFederate::enableTimeConstrained()
501 if (!_rtiFederate.valid()) {
502 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
506 if (!_rtiFederate->enableTimeConstrained()) {
507 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time constrained!");
511 while (!_rtiFederate->getTimeConstrainedEnabled()) {
512 _rtiFederate->processMessage();
519 HLAFederate::disableTimeConstrained()
521 if (!_rtiFederate.valid()) {
522 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
525 return _rtiFederate->disableTimeConstrained();
529 HLAFederate::enableTimeConstrainedByLocalClock()
531 // Compute the time offset from the system time to the simulation time
532 SGTimeStamp federateTime;
533 if (!queryFederateTime(federateTime)) {
534 SG_LOG(SG_NETWORK, SG_WARN, "Cannot get federate time!");
537 _localClockOffset = SGTimeStamp::now() - federateTime;
542 HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
544 if (!_rtiFederate.valid()) {
545 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
549 if (!_rtiFederate->enableTimeRegulation(lookahead)) {
550 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time regulation!");
554 while (!_rtiFederate->getTimeRegulationEnabled()) {
555 _rtiFederate->processMessage();
562 HLAFederate::enableTimeRegulation()
564 if (!enableTimeRegulation(SGTimeStamp::fromSec(0))) {
565 SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time regulation!");
568 if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
569 SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
576 HLAFederate::disableTimeRegulation()
578 if (!_rtiFederate.valid()) {
579 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
582 return _rtiFederate->disableTimeRegulation();
586 HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
588 if (!_rtiFederate.valid()) {
589 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
592 return _rtiFederate->modifyLookahead(timeStamp);
596 HLAFederate::timeAdvanceBy(const SGTimeStamp& timeIncrement)
598 if (!_rtiFederate.valid()) {
599 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
603 SGTimeStamp timeStamp;
604 if (!_rtiFederate->queryFederateTime(timeStamp)) {
605 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query federate time!");
609 if (!_rtiFederate->timeAdvanceRequest(timeStamp + timeIncrement)) {
610 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
614 return processMessages();
618 HLAFederate::timeAdvance(const SGTimeStamp& timeStamp)
620 if (!_rtiFederate.valid()) {
621 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
625 if (!_rtiFederate->timeAdvanceRequest(timeStamp)) {
626 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
630 return processMessages();
634 HLAFederate::timeAdvanceAvailable()
636 if (!_rtiFederate.valid()) {
637 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
641 SGTimeStamp timeStamp;
642 if (!_rtiFederate->queryGALT(timeStamp)) {
643 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query GALT!");
647 if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) {
648 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
652 return processMessages();
656 HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
658 if (!_rtiFederate.valid()) {
659 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
662 return _rtiFederate->queryFederateTime(timeStamp);
666 HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
668 if (!_rtiFederate.valid()) {
669 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
672 return _rtiFederate->queryLookahead(timeStamp);
676 HLAFederate::processMessage()
678 if (!_rtiFederate.valid()) {
679 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
682 return _rtiFederate->processMessage();
686 HLAFederate::processMessage(const SGTimeStamp& timeout)
688 if (!_rtiFederate.valid()) {
689 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
692 return _rtiFederate->processMessages(timeout.toSecs(), 0);
696 HLAFederate::processMessages()
698 if (!_rtiFederate.valid()) {
699 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
703 while (_rtiFederate->getTimeAdvancePending()) {
704 _rtiFederate->processMessage();
707 if (_timeConstrainedByLocalClock) {
708 SGTimeStamp federateTime;
709 if (!_rtiFederate->queryFederateTime(federateTime)) {
710 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Error querying federate time!");
713 SGTimeStamp systemTime = federateTime + _localClockOffset;
715 double rest = (systemTime - SGTimeStamp::now()).toSecs();
718 _rtiFederate->processMessages(rest, rest);
722 // Now flush just what is left
723 while (_rtiFederate->processMessages(0, 0));
729 HLAFederate::tick(const double& minimum, const double& maximum)
731 if (!_rtiFederate.valid()) {
732 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
735 return _rtiFederate->processMessages(minimum, maximum);
739 HLAFederate::readObjectModelTemplate(const std::string& objectModel,
740 HLAFederate::ObjectModelFactory& objectModelFactory)
742 if (!_rtiFederate.valid()) {
743 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
747 // The XML version of the federate object model.
748 // This one covers the generic attributes, parameters and data types.
749 HLAOMTXmlVisitor omtXmlVisitor;
751 readXML(objectModel, omtXmlVisitor);
752 } catch (const sg_throwable& e) {
753 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
757 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
761 unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
762 for (unsigned i = 0; i < numObjectClasses; ++i) {
763 const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
764 std::string objectClassName = objectClass->getName();
766 SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
767 if (!hlaObjectClass.valid()) {
768 SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
772 bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
773 bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
775 std::set<unsigned> subscriptions;
776 std::set<unsigned> publications;
778 // process the attributes
779 for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
780 const simgear::HLAOMTXmlVisitor::Attribute* attribute;
781 attribute = objectClass->getAttribute(j);
783 std::string attributeName = attribute->getName();
784 unsigned index = hlaObjectClass->getAttributeIndex(attributeName);
787 SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
791 SGSharedPtr<HLADataType> dataType;
792 dataType = omtXmlVisitor.getAttributeDataType(objectClassName, attributeName);
793 if (!dataType.valid()) {
794 SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
795 << attributeName << "\" in object class \"" << objectClassName << "\"!");
797 hlaObjectClass->setAttributeDataType(index, dataType);
799 HLAUpdateType updateType = HLAUndefinedUpdate;
800 if (attribute->_updateType == "Periodic")
801 updateType = HLAPeriodicUpdate;
802 else if (attribute->_updateType == "Static")
803 updateType = HLAStaticUpdate;
804 else if (attribute->_updateType == "Conditional")
805 updateType = HLAConditionalUpdate;
806 hlaObjectClass->setAttributeUpdateType(index, updateType);
808 if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
809 subscriptions.insert(index);
810 if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
811 publications.insert(index);
815 hlaObjectClass->publish(publications);
817 hlaObjectClass->subscribe(subscriptions, true);
819 _objectClassMap[objectClassName] = hlaObjectClass;
826 HLAFederate::readRTI13ObjectModelTemplate(const std::string& objectModel)
828 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI13 not yet(!?) supported.");
833 HLAFederate::readRTI1516ObjectModelTemplate(const std::string& objectModel)
835 ObjectModelFactory objectModelFactory;
836 return readObjectModelTemplate(objectModel, objectModelFactory);
840 HLAFederate::readRTI1516EObjectModelTemplate(const std::string& objectModel)
842 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
847 HLAFederate::getObjectClass(const std::string& name)
849 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
850 if (i == _objectClassMap.end())
852 return i->second.get();
855 const HLAObjectClass*
856 HLAFederate::getObjectClass(const std::string& name) const
858 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
859 if (i == _objectClassMap.end())
861 return i->second.get();
865 HLAFederate::createObjectClass(const std::string& name)
867 return new HLAObjectClass(name, *this);
871 HLAFederate::getInteractionClass(const std::string& name)
873 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
874 if (i == _interactionClassMap.end())
876 return i->second.get();
879 const HLAInteractionClass*
880 HLAFederate::getInteractionClass(const std::string& name) const
882 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
883 if (i == _interactionClassMap.end())
885 return i->second.get();
889 HLAFederate::setDone(bool done)
895 HLAFederate::getDone() const
901 HLAFederate::readObjectModel()
903 /// Currently empty, but is called at the right time so that
904 /// the object model is present when it is needed
905 // switch (getVersion()) {
907 // return readRTI13ObjectModelTemplate(getFederationObjectModel());
909 // return readRTI1516ObjectModelTemplate(getFederationObjectModel());
911 // return readRTI1516EObjectModelTemplate(getFederationObjectModel());
917 HLAFederate::subscribe()
919 /// Currently empty, but is called at the right time
924 HLAFederate::publish()
926 /// Currently empty, but is called at the right time
933 // We need to talk to the rti
937 if (_createFederationExecution) {
938 if (!createJoinFederationExecution())
944 // Read the xml file containing the object model
945 if (!readObjectModel()) {
949 // start being time constrained if required
950 if (_timeConstrained) {
951 if (!enableTimeConstrained()) {
956 // Now that we are potentially time constrained, we can subscribe.
957 // This is to make sure we do not get any time stamped message
958 // converted to a non time stamped message by the rti.
963 // Before we publish anything start getting regulating if required
964 if (_timeRegulating) {
965 if (!enableTimeRegulation()) {
970 // Note that starting from here, we need to be careful with things
971 // requireing unbounded time. The rest of the federation might wait
974 // Compute the time offset from the system time to the simulation time
975 if (_timeConstrainedByLocalClock) {
976 if (!enableTimeConstrainedByLocalClock()) {
977 SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time constrained by local clock!");
983 // Publish what we want to write
993 HLAFederate::update()
995 return timeAdvanceBy(_timeIncrement);
999 HLAFederate::shutdown()
1001 // On shutdown, just try all in order.
1002 // If something goes wrong, continue and try to get out here as good as possible.
1005 if (_createFederationExecution) {
1006 if (!resignDestroyFederationExecution())
1025 while (!getDone()) {
1038 } // namespace simgear