1 // Copyright (C) 2009 - 2010 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 "RTI13Federate.hxx"
21 #include "RTIFederate.hxx"
22 #include "RTIInteractionClass.hxx"
23 #include "RTIObjectClass.hxx"
24 #include "HLADataElement.hxx"
25 #include "HLADataType.hxx"
26 #include "HLAOMTXmlVisitor.hxx"
30 HLAFederate::HLAFederate()
34 HLAFederate::~HLAFederate()
39 HLAFederate::getVersion() const
45 HLAFederate::setVersion(HLAFederate::Version version)
47 if (_rtiFederate.valid()) {
48 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
55 const std::list<std::string>&
56 HLAFederate::getConnectArguments() const
58 return _connectArguments;
62 HLAFederate::setConnectArguments(const std::list<std::string>& connectArguments)
64 if (_rtiFederate.valid()) {
65 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
68 _connectArguments = connectArguments;
73 HLAFederate::getFederationExecutionName() const
75 return _federationExecutionName;
79 HLAFederate::setFederationExecutionName(const std::string& federationExecutionName)
81 if (_rtiFederate.valid()) {
82 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
85 _federationExecutionName = federationExecutionName;
90 HLAFederate::getFederationObjectModel() const
92 return _federationObjectModel;
96 HLAFederate::setFederationObjectModel(const std::string& federationObjectModel)
98 if (_rtiFederate.valid()) {
99 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
102 _federationObjectModel = federationObjectModel;
107 HLAFederate::getFederateType() const
109 return _federateType;
113 HLAFederate::setFederateType(const std::string& federateType)
115 if (_rtiFederate.valid()) {
116 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
119 _federateType = federateType;
124 HLAFederate::getFederateName() const
126 return _federateName;
130 HLAFederate::setFederateName(const std::string& federateName)
132 if (_rtiFederate.valid()) {
133 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Ignoring HLAFederate parameter setting on already connected federate!");
136 _federateName = federateName;
141 HLAFederate::connect(Version version, const std::list<std::string>& stringList)
143 if (_rtiFederate.valid()) {
144 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
149 _rtiFederate = new RTI13Federate(stringList);
151 _connectArguments = stringList;
154 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
155 // _rtiFederate = new RTI1516Federate(stringList);
158 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
159 // _rtiFederate = new RTI1516eFederate(stringList);
162 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
164 return _rtiFederate.valid();
168 HLAFederate::connect()
170 if (_rtiFederate.valid()) {
171 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
176 _rtiFederate = new RTI13Federate(_connectArguments);
179 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
180 // _rtiFederate = new RTI1516Federate(_connectArguments);
183 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
184 // _rtiFederate = new RTI1516eFederate(_connectArguments);
187 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
189 return _rtiFederate.valid();
193 HLAFederate::disconnect()
195 if (!_rtiFederate.valid()) {
196 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
204 HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
206 if (!_rtiFederate.valid()) {
207 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
211 RTIFederate::FederationManagementResult createResult;
212 createResult = _rtiFederate->createFederationExecution(federation, objectModel);
213 if (createResult == RTIFederate::FederationManagementFatal)
216 _federationExecutionName = federation;
217 _federationObjectModel = objectModel;
222 HLAFederate::destroyFederationExecution(const std::string& federation)
224 if (!_rtiFederate.valid()) {
225 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
229 RTIFederate::FederationManagementResult destroyResult;
230 destroyResult = _rtiFederate->destroyFederationExecution(federation);
231 if (destroyResult == RTIFederate::FederationManagementFatal)
238 HLAFederate::createFederationExecution()
240 if (!_rtiFederate.valid()) {
241 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
245 RTIFederate::FederationManagementResult createResult;
246 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
247 if (createResult != RTIFederate::FederationManagementSuccess)
254 HLAFederate::destroyFederationExecution()
256 if (!_rtiFederate.valid()) {
257 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
261 RTIFederate::FederationManagementResult destroyResult;
262 destroyResult = _rtiFederate->destroyFederationExecution(_federationExecutionName);
263 if (destroyResult != RTIFederate::FederationManagementSuccess)
270 HLAFederate::join(const std::string& federateType, const std::string& federation)
272 if (!_rtiFederate.valid()) {
273 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
277 RTIFederate::FederationManagementResult joinResult;
278 joinResult = _rtiFederate->join(federateType, federation);
279 if (joinResult == RTIFederate::FederationManagementFatal)
288 if (!_rtiFederate.valid()) {
289 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
293 RTIFederate::FederationManagementResult joinResult;
294 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
295 if (joinResult != RTIFederate::FederationManagementSuccess)
302 HLAFederate::resign()
304 if (!_rtiFederate.valid()) {
305 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
308 return _rtiFederate->resign();
312 HLAFederate::createJoinFederationExecution()
314 if (!_rtiFederate.valid()) {
315 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
321 RTIFederate::FederationManagementResult joinResult;
322 joinResult = _rtiFederate->join(_federateType, _federationExecutionName);
323 switch (joinResult) {
324 case RTIFederate::FederationManagementSuccess:
325 // Fast return on success
327 case RTIFederate::FederationManagementFatal:
328 // Abort on fatal errors
334 // If not already joinable, try to create the requested federation
335 RTIFederate::FederationManagementResult createResult;
336 createResult = _rtiFederate->createFederationExecution(_federationExecutionName, _federationObjectModel);
337 switch (createResult) {
338 case RTIFederate::FederationManagementFatal:
339 // Abort on fatal errors
349 HLAFederate::resignDestroyFederationExecution()
351 if (!_rtiFederate.valid()) {
352 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
357 bool success = _rtiFederate->resign();
359 // and try to destroy, non fatal if still some federates joined
360 if (_rtiFederate->destroyFederationExecution(_federationExecutionName) == RTIFederate::FederationManagementFatal)
367 HLAFederate::enableTimeConstrained()
369 if (!_rtiFederate.valid()) {
370 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
373 return _rtiFederate->enableTimeConstrained();
377 HLAFederate::disableTimeConstrained()
379 if (!_rtiFederate.valid()) {
380 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
383 return _rtiFederate->disableTimeConstrained();
387 HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
389 if (!_rtiFederate.valid()) {
390 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
393 return _rtiFederate->enableTimeRegulation(lookahead);
397 HLAFederate::disableTimeRegulation()
399 if (!_rtiFederate.valid()) {
400 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
403 return _rtiFederate->disableTimeRegulation();
407 HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
409 if (!_rtiFederate.valid()) {
410 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
413 return _rtiFederate->timeAdvanceRequestBy(dt);
417 HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
419 if (!_rtiFederate.valid()) {
420 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
423 return _rtiFederate->timeAdvanceRequest(dt);
427 HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
429 if (!_rtiFederate.valid()) {
430 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
433 return _rtiFederate->queryFederateTime(timeStamp);
437 HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
439 if (!_rtiFederate.valid()) {
440 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
443 return _rtiFederate->modifyLookahead(timeStamp);
447 HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
449 if (!_rtiFederate.valid()) {
450 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
453 return _rtiFederate->queryLookahead(timeStamp);
459 if (!_rtiFederate.valid()) {
460 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
463 return _rtiFederate->tick();
467 HLAFederate::tick(const double& minimum, const double& maximum)
469 if (!_rtiFederate.valid()) {
470 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
473 return _rtiFederate->tick(minimum, maximum);
477 HLAFederate::readObjectModelTemplate(const std::string& objectModel,
478 HLAFederate::ObjectModelFactory& objectModelFactory)
480 if (!_rtiFederate.valid()) {
481 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
485 // The XML version of the federate object model.
486 // This one covers the generic attributes, parameters and data types.
487 HLAOMTXmlVisitor omtXmlVisitor;
489 readXML(objectModel, omtXmlVisitor);
490 } catch (const sg_throwable& e) {
491 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
495 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
499 unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
500 for (unsigned i = 0; i < numObjectClasses; ++i) {
501 const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
502 std::string objectClassName = objectClass->getName();
504 SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
505 if (!hlaObjectClass.valid()) {
506 SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
510 bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
511 bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
513 std::set<unsigned> subscriptions;
514 std::set<unsigned> publications;
516 // process the attributes
517 for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
518 const simgear::HLAOMTXmlVisitor::Attribute* attribute;
519 attribute = objectClass->getAttribute(j);
521 std::string attributeName = attribute->getName();
522 unsigned index = hlaObjectClass->getAttributeIndex(attributeName);
525 SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
529 SGSharedPtr<HLADataType> dataType;
530 dataType = omtXmlVisitor.getAttributeDataType(objectClassName, attributeName);
531 if (!dataType.valid()) {
532 SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
533 << attributeName << "\" in object class \"" << objectClassName << "\"!");
535 hlaObjectClass->setAttributeDataType(index, dataType);
537 HLAUpdateType updateType = HLAUndefinedUpdate;
538 if (attribute->_updateType == "Periodic")
539 updateType = HLAPeriodicUpdate;
540 else if (attribute->_updateType == "Static")
541 updateType = HLAStaticUpdate;
542 else if (attribute->_updateType == "Conditional")
543 updateType = HLAConditionalUpdate;
544 hlaObjectClass->setAttributeUpdateType(index, updateType);
546 if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
547 subscriptions.insert(index);
548 if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
549 publications.insert(index);
553 hlaObjectClass->publish(publications);
555 hlaObjectClass->subscribe(subscriptions, true);
557 _objectClassMap[objectClassName] = hlaObjectClass;
564 HLAFederate::getObjectClass(const std::string& name)
566 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
567 if (i == _objectClassMap.end())
569 return i->second.get();
572 const HLAObjectClass*
573 HLAFederate::getObjectClass(const std::string& name) const
575 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
576 if (i == _objectClassMap.end())
578 return i->second.get();
582 HLAFederate::getInteractionClass(const std::string& name)
584 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
585 if (i == _interactionClassMap.end())
587 return i->second.get();
590 const HLAInteractionClass*
591 HLAFederate::getInteractionClass(const std::string& name) const
593 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
594 if (i == _interactionClassMap.end())
596 return i->second.get();
599 } // namespace simgear