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::getFederateType() const
41 if (!_rtiFederate.valid()) {
42 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
45 return _rtiFederate->getFederateType();
49 HLAFederate::getFederationName() const
51 if (!_rtiFederate.valid()) {
52 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
55 return _rtiFederate->getFederationName();
59 HLAFederate::connect(Version version, const std::list<std::string>& stringList)
61 if (_rtiFederate.valid()) {
62 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Trying to connect to already connected federate!");
67 _rtiFederate = new RTI13Federate(stringList);
70 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported.");
71 // _rtiFederate = new RTI1516Federate(stringList);
74 SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported.");
75 // _rtiFederate = new RTI1516eFederate(stringList);
78 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Unknown rti version in connect!");
80 return _rtiFederate.valid();
84 HLAFederate::disconnect()
86 if (!_rtiFederate.valid()) {
87 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
95 HLAFederate::createFederationExecution(const std::string& federation, const std::string& objectModel)
97 if (!_rtiFederate.valid()) {
98 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
101 return _rtiFederate->createFederationExecution(federation, objectModel);
105 HLAFederate::destroyFederationExecution(const std::string& federation)
107 if (!_rtiFederate.valid()) {
108 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
111 return _rtiFederate->destroyFederationExecution(federation);
115 HLAFederate::join(const std::string& federateType, const std::string& federation)
117 if (!_rtiFederate.valid()) {
118 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
121 return _rtiFederate->join(federateType, federation);
125 HLAFederate::resign()
127 if (!_rtiFederate.valid()) {
128 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
131 return _rtiFederate->resign();
135 HLAFederate::enableTimeConstrained()
137 if (!_rtiFederate.valid()) {
138 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
141 return _rtiFederate->enableTimeConstrained();
145 HLAFederate::disableTimeConstrained()
147 if (!_rtiFederate.valid()) {
148 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
151 return _rtiFederate->disableTimeConstrained();
155 HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
157 if (!_rtiFederate.valid()) {
158 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
161 return _rtiFederate->enableTimeRegulation(lookahead);
165 HLAFederate::disableTimeRegulation()
167 if (!_rtiFederate.valid()) {
168 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
171 return _rtiFederate->disableTimeRegulation();
175 HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
177 if (!_rtiFederate.valid()) {
178 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
181 return _rtiFederate->timeAdvanceRequestBy(dt);
185 HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
187 if (!_rtiFederate.valid()) {
188 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
191 return _rtiFederate->timeAdvanceRequest(dt);
195 HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
197 if (!_rtiFederate.valid()) {
198 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
201 return _rtiFederate->queryFederateTime(timeStamp);
205 HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
207 if (!_rtiFederate.valid()) {
208 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
211 return _rtiFederate->modifyLookahead(timeStamp);
215 HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
217 if (!_rtiFederate.valid()) {
218 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
221 return _rtiFederate->queryLookahead(timeStamp);
227 if (!_rtiFederate.valid()) {
228 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
231 return _rtiFederate->tick();
235 HLAFederate::tick(const double& minimum, const double& maximum)
237 if (!_rtiFederate.valid()) {
238 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
241 return _rtiFederate->tick(minimum, maximum);
245 HLAFederate::readObjectModelTemplate(const std::string& objectModel,
246 HLAFederate::ObjectModelFactory& objectModelFactory)
248 if (!_rtiFederate.valid()) {
249 SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
253 // The XML version of the federate object model.
254 // This one covers the generic attributes, parameters and data types.
255 HLAOMTXmlVisitor omtXmlVisitor;
257 readXML(objectModel, omtXmlVisitor);
258 } catch (const sg_throwable& e) {
259 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file: "
263 SG_LOG(SG_IO, SG_ALERT, "Could not open HLA XML object model file");
267 unsigned numObjectClasses = omtXmlVisitor.getNumObjectClasses();
268 for (unsigned i = 0; i < numObjectClasses; ++i) {
269 const HLAOMTXmlVisitor::ObjectClass* objectClass = omtXmlVisitor.getObjectClass(i);
270 std::string objectClassName = objectClass->getName();
272 SGSharedPtr<HLAObjectClass> hlaObjectClass = objectModelFactory.createObjectClass(objectClassName, *this);
273 if (!hlaObjectClass.valid()) {
274 SG_LOG(SG_IO, SG_INFO, "Ignoring object class \"" << objectClassName << "\".");
278 bool publish = objectModelFactory.publishObjectClass(objectClassName, objectClass->getSharing());
279 bool subscribe = objectModelFactory.subscribeObjectClass(objectClassName, objectClass->getSharing());
281 std::set<unsigned> subscriptions;
282 std::set<unsigned> publications;
284 // process the attributes
285 for (unsigned j = 0; j < objectClass->getNumAttributes(); ++j) {
286 const simgear::HLAOMTXmlVisitor::Attribute* attribute;
287 attribute = objectClass->getAttribute(j);
289 std::string attributeName = attribute->getName();
290 unsigned index = hlaObjectClass->getAttributeIndex(attributeName);
293 SG_LOG(SG_IO, SG_WARN, "RTI does not know the \"" << attributeName << "\" attribute!");
297 SGSharedPtr<HLADataType> dataType;
298 dataType = omtXmlVisitor.getAttributeDataType(objectClassName, attributeName);
299 if (!dataType.valid()) {
300 SG_LOG(SG_IO, SG_WARN, "Could not find data type for attribute \""
301 << attributeName << "\" in object class \"" << objectClassName << "\"!");
303 hlaObjectClass->setAttributeDataType(index, dataType);
305 HLAUpdateType updateType = HLAUndefinedUpdate;
306 if (attribute->_updateType == "Periodic")
307 updateType = HLAPeriodicUpdate;
308 else if (attribute->_updateType == "Static")
309 updateType = HLAStaticUpdate;
310 else if (attribute->_updateType == "Conditional")
311 updateType = HLAConditionalUpdate;
312 hlaObjectClass->setAttributeUpdateType(index, updateType);
314 if (subscribe && objectModelFactory.subscribeAttribute(objectClassName, attributeName, attribute->_sharing))
315 subscriptions.insert(index);
316 if (publish && objectModelFactory.publishAttribute(objectClassName, attributeName, attribute->_sharing))
317 publications.insert(index);
321 hlaObjectClass->publish(publications);
323 hlaObjectClass->subscribe(subscriptions, true);
325 _objectClassMap[objectClassName] = hlaObjectClass;
332 HLAFederate::getObjectClass(const std::string& name)
334 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
335 if (i == _objectClassMap.end())
337 return i->second.get();
340 const HLAObjectClass*
341 HLAFederate::getObjectClass(const std::string& name) const
343 ObjectClassMap::const_iterator i = _objectClassMap.find(name);
344 if (i == _objectClassMap.end())
346 return i->second.get();
350 HLAFederate::getInteractionClass(const std::string& name)
352 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
353 if (i == _interactionClassMap.end())
355 return i->second.get();
358 const HLAInteractionClass*
359 HLAFederate::getInteractionClass(const std::string& name) const
361 InteractionClassMap::const_iterator i = _interactionClassMap.find(name);
362 if (i == _interactionClassMap.end())
364 return i->second.get();
367 } // namespace simgear