Merge branch 'next' of git.gitorious.org:fg/simgear into next
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
@@ -27,7 +27,13 @@
|
||||
|
||||
namespace simgear {
|
||||
|
||||
HLAFederate::HLAFederate()
|
||||
HLAFederate::HLAFederate() :
|
||||
_version(RTI13),
|
||||
_createFederationExecution(true),
|
||||
_timeConstrained(false),
|
||||
_timeRegulating(false),
|
||||
_timeConstrainedByLocalClock(false),
|
||||
_done(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -69,6 +75,19 @@ HLAFederate::setConnectArguments(const std::list<std::string>& connectArguments)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getCreateFederationExecution() const
|
||||
{
|
||||
return _createFederationExecution;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setCreateFederationExecution(bool createFederationExecution)
|
||||
{
|
||||
_createFederationExecution = createFederationExecution;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
HLAFederate::getFederationExecutionName() const
|
||||
{
|
||||
@@ -363,6 +382,128 @@ HLAFederate::resignDestroyFederationExecution()
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getTimeConstrained() const
|
||||
{
|
||||
return _timeConstrained;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setTimeConstrained(bool timeConstrained)
|
||||
{
|
||||
_timeConstrained = timeConstrained;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (_timeConstrained && !_rtiFederate->getTimeConstrainedEnabled()) {
|
||||
if (!enableTimeConstrained())
|
||||
return false;
|
||||
} else if (!_timeConstrained && _rtiFederate->getTimeConstrainedEnabled()) {
|
||||
if (!disableTimeConstrained())
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getTimeConstrainedByLocalClock() const
|
||||
{
|
||||
return _timeConstrainedByLocalClock;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock)
|
||||
{
|
||||
_timeConstrainedByLocalClock = timeConstrainedByLocalClock;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (_timeConstrainedByLocalClock) {
|
||||
if (!enableTimeConstrainedByLocalClock())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getTimeRegulating() const
|
||||
{
|
||||
return _timeRegulating;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setTimeRegulating(bool timeRegulating)
|
||||
{
|
||||
_timeRegulating = timeRegulating;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (_timeRegulating && !_rtiFederate->getTimeRegulationEnabled()) {
|
||||
if (!enableTimeRegulation())
|
||||
return false;
|
||||
} else if (!_timeRegulating && _rtiFederate->getTimeRegulationEnabled()) {
|
||||
if (!disableTimeRegulation())
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setLeadTime(const SGTimeStamp& leadTime)
|
||||
{
|
||||
if (leadTime < SGTimeStamp::fromSec(0)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative lead time!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_leadTime = leadTime;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const SGTimeStamp&
|
||||
HLAFederate::getLeadTime() const
|
||||
{
|
||||
return _leadTime;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::setTimeIncrement(const SGTimeStamp& timeIncrement)
|
||||
{
|
||||
if (timeIncrement < SGTimeStamp::fromSec(0)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Ignoring negative time increment!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_timeIncrement = timeIncrement;
|
||||
|
||||
if (_rtiFederate.valid() && _rtiFederate->getJoined()) {
|
||||
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const SGTimeStamp&
|
||||
HLAFederate::getTimeIncrement() const
|
||||
{
|
||||
return _timeIncrement;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeConstrained()
|
||||
{
|
||||
@@ -370,7 +511,17 @@ HLAFederate::enableTimeConstrained()
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->enableTimeConstrained();
|
||||
|
||||
if (!_rtiFederate->enableTimeConstrained()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time constrained!");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!_rtiFederate->getTimeConstrainedEnabled()) {
|
||||
_rtiFederate->processMessage();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -383,6 +534,19 @@ HLAFederate::disableTimeConstrained()
|
||||
return _rtiFederate->disableTimeConstrained();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeConstrainedByLocalClock()
|
||||
{
|
||||
// Compute the time offset from the system time to the simulation time
|
||||
SGTimeStamp federateTime;
|
||||
if (!queryFederateTime(federateTime)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot get federate time!");
|
||||
return false;
|
||||
}
|
||||
_localClockOffset = SGTimeStamp::now() - federateTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
|
||||
{
|
||||
@@ -390,7 +554,31 @@ HLAFederate::enableTimeRegulation(const SGTimeStamp& lookahead)
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->enableTimeRegulation(lookahead);
|
||||
|
||||
if (!_rtiFederate->enableTimeRegulation(lookahead)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not enable time regulation!");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!_rtiFederate->getTimeRegulationEnabled()) {
|
||||
_rtiFederate->processMessage();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::enableTimeRegulation()
|
||||
{
|
||||
if (!enableTimeRegulation(SGTimeStamp::fromSec(0))) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time regulation!");
|
||||
return false;
|
||||
}
|
||||
if (!modifyLookahead(_leadTime + SGTimeStamp::fromSec(_timeIncrement.toSecs()*0.9))) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot modify lookahead!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -404,23 +592,73 @@ HLAFederate::disableTimeRegulation()
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvanceRequestBy(const SGTimeStamp& dt)
|
||||
HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->timeAdvanceRequestBy(dt);
|
||||
return _rtiFederate->modifyLookahead(timeStamp);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvanceRequest(const SGTimeStamp& dt)
|
||||
HLAFederate::timeAdvanceBy(const SGTimeStamp& timeIncrement)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->timeAdvanceRequest(dt);
|
||||
|
||||
SGTimeStamp timeStamp;
|
||||
if (!_rtiFederate->queryFederateTime(timeStamp)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query federate time!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtiFederate->timeAdvanceRequest(timeStamp + timeIncrement)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return processMessages();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvance(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtiFederate->timeAdvanceRequest(timeStamp)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return processMessages();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::timeAdvanceAvailable()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
SGTimeStamp timeStamp;
|
||||
if (!_rtiFederate->queryGALT(timeStamp)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Could not query GALT!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_rtiFederate->timeAdvanceRequestAvailable(timeStamp)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Time advance request failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return processMessages();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -433,16 +671,6 @@ HLAFederate::queryFederateTime(SGTimeStamp& timeStamp)
|
||||
return _rtiFederate->queryFederateTime(timeStamp);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->modifyLookahead(timeStamp);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
|
||||
{
|
||||
@@ -454,13 +682,56 @@ HLAFederate::queryLookahead(SGTimeStamp& timeStamp)
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::tick()
|
||||
HLAFederate::processMessage()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->tick();
|
||||
return _rtiFederate->processMessage();
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::processMessage(const SGTimeStamp& timeout)
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->processMessages(timeout.toSecs(), 0);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::processMessages()
|
||||
{
|
||||
if (!_rtiFederate.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (_rtiFederate->getTimeAdvancePending()) {
|
||||
_rtiFederate->processMessage();
|
||||
}
|
||||
|
||||
if (_timeConstrainedByLocalClock) {
|
||||
SGTimeStamp federateTime;
|
||||
if (!_rtiFederate->queryFederateTime(federateTime)) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Error querying federate time!");
|
||||
return false;
|
||||
}
|
||||
SGTimeStamp systemTime = federateTime + _localClockOffset;
|
||||
for (;;) {
|
||||
double rest = (systemTime - SGTimeStamp::now()).toSecs();
|
||||
if (rest < 0)
|
||||
break;
|
||||
_rtiFederate->processMessages(rest, rest);
|
||||
}
|
||||
}
|
||||
|
||||
// Now flush just what is left
|
||||
while (_rtiFederate->processMessages(0, 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -470,7 +741,7 @@ HLAFederate::tick(const double& minimum, const double& maximum)
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "HLA: Accessing unconnected federate!");
|
||||
return false;
|
||||
}
|
||||
return _rtiFederate->tick(minimum, maximum);
|
||||
return _rtiFederate->processMessages(minimum, maximum);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -596,4 +867,146 @@ HLAFederate::getInteractionClass(const std::string& name) const
|
||||
return i->second.get();
|
||||
}
|
||||
|
||||
void
|
||||
HLAFederate::setDone(bool done)
|
||||
{
|
||||
_done = done;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::getDone() const
|
||||
{
|
||||
return _done;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::readObjectModel()
|
||||
{
|
||||
/// Currently empty, but is called at the right time so that
|
||||
/// the object model is present when it is needed
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::subscribe()
|
||||
{
|
||||
/// Currently empty, but is called at the right time
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::publish()
|
||||
{
|
||||
/// Currently empty, but is called at the right time
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::init()
|
||||
{
|
||||
// We need to talk to the rti
|
||||
if (!connect())
|
||||
return false;
|
||||
// Join ...
|
||||
if (_createFederationExecution) {
|
||||
if (!createJoinFederationExecution())
|
||||
return false;
|
||||
} else {
|
||||
if (!join())
|
||||
return false;
|
||||
}
|
||||
// Read the xml file containing the object model
|
||||
if (!readObjectModel()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
// start being time constrained if required
|
||||
if (_timeConstrained) {
|
||||
if (!enableTimeConstrained()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Now that we are potentially time constrained, we can subscribe.
|
||||
// This is to make sure we do not get any time stamped message
|
||||
// converted to a non time stamped message by the rti.
|
||||
if (!subscribe()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
// Before we publish anything start getting regulating if required
|
||||
if (_timeRegulating) {
|
||||
if (!enableTimeRegulation()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Note that starting from here, we need to be careful with things
|
||||
// requireing unbounded time. The rest of the federation might wait
|
||||
// for us to finish!
|
||||
|
||||
// Compute the time offset from the system time to the simulation time
|
||||
if (_timeConstrainedByLocalClock) {
|
||||
if (!enableTimeConstrainedByLocalClock()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "Cannot enable time constrained by local clock!");
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Publish what we want to write
|
||||
if (!publish()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::update()
|
||||
{
|
||||
return timeAdvanceBy(_timeIncrement);
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::shutdown()
|
||||
{
|
||||
// On shutdown, just try all in order.
|
||||
// If something goes wrong, continue and try to get out here as good as possible.
|
||||
bool ret = true;
|
||||
|
||||
if (_createFederationExecution) {
|
||||
if (!resignDestroyFederationExecution())
|
||||
ret = false;
|
||||
} else {
|
||||
if (!resign())
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (!disconnect())
|
||||
ret = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
HLAFederate::exec()
|
||||
{
|
||||
if (!init())
|
||||
return false;
|
||||
|
||||
while (!getDone()) {
|
||||
if (!update()) {
|
||||
shutdown();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!shutdown())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace simgear
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
@@ -41,21 +41,31 @@ public:
|
||||
RTI1516E
|
||||
};
|
||||
|
||||
/// The rti version backend to connect
|
||||
Version getVersion() const;
|
||||
bool setVersion(HLAFederate::Version version);
|
||||
|
||||
/// The rti backends connect arguments, depends on the version
|
||||
const std::list<std::string>& getConnectArguments() const;
|
||||
bool setConnectArguments(const std::list<std::string>& connectArguments);
|
||||
|
||||
/// If true try to create on join and try to destroy on resign
|
||||
bool getCreateFederationExecution() const;
|
||||
bool setCreateFederationExecution(bool createFederationExecution);
|
||||
|
||||
/// The federation execution name to use on create, join and destroy
|
||||
const std::string& getFederationExecutionName() const;
|
||||
bool setFederationExecutionName(const std::string& federationExecutionName);
|
||||
|
||||
/// The federation object model name to use on create and possibly join
|
||||
const std::string& getFederationObjectModel() const;
|
||||
bool setFederationObjectModel(const std::string& federationObjectModel);
|
||||
|
||||
/// The federate type used on join
|
||||
const std::string& getFederateType() const;
|
||||
bool setFederateType(const std::string& federateType);
|
||||
|
||||
/// The federate name possibly used on join
|
||||
const std::string& getFederateName() const;
|
||||
bool setFederateName(const std::string& federateName);
|
||||
|
||||
@@ -82,21 +92,76 @@ public:
|
||||
bool resignDestroyFederationExecution();
|
||||
|
||||
|
||||
/// Time management
|
||||
|
||||
/// If set to true, time constrained mode is entered on init
|
||||
bool getTimeConstrained() const;
|
||||
bool setTimeConstrained(bool timeConstrained);
|
||||
|
||||
/// If set to true, time advance is constrained by the local system clock
|
||||
bool getTimeConstrainedByLocalClock() const;
|
||||
bool setTimeConstrainedByLocalClock(bool timeConstrainedByLocalClock);
|
||||
|
||||
/// If set to true, time regulation mode is entered on init
|
||||
bool getTimeRegulating() const;
|
||||
bool setTimeRegulating(bool timeRegulating);
|
||||
|
||||
/// If set to a non zero value, this federate leads the federations
|
||||
/// locical time advance by this amount of time.
|
||||
const SGTimeStamp& getLeadTime() const;
|
||||
bool setLeadTime(const SGTimeStamp& leadTime);
|
||||
|
||||
/// The time increment for use in the default update method.
|
||||
const SGTimeStamp& getTimeIncrement() const;
|
||||
bool setTimeIncrement(const SGTimeStamp& timeIncrement);
|
||||
|
||||
/// Actually enable time constrained mode.
|
||||
/// This method blocks until time constrained mode is enabled.
|
||||
bool enableTimeConstrained();
|
||||
/// Actually disable time constrained mode.
|
||||
bool disableTimeConstrained();
|
||||
|
||||
/// Actually enable time constrained by local clock mode.
|
||||
bool enableTimeConstrainedByLocalClock();
|
||||
|
||||
/// Actually enable time regulation mode.
|
||||
/// This method blocks until time regulation mode is enabled.
|
||||
bool enableTimeRegulation(const SGTimeStamp& lookahead);
|
||||
bool enableTimeRegulation();
|
||||
/// Actually disable time regulation mode.
|
||||
bool disableTimeRegulation();
|
||||
/// Actually modify the lookahead time.
|
||||
bool modifyLookahead(const SGTimeStamp& lookahead);
|
||||
|
||||
bool timeAdvanceRequestBy(const SGTimeStamp& dt);
|
||||
bool timeAdvanceRequest(const SGTimeStamp& dt);
|
||||
/// Advance the logical time by the given time increment.
|
||||
/// Depending on the time constrained mode, this might
|
||||
/// block until the time advance is granted.
|
||||
bool timeAdvanceBy(const SGTimeStamp& timeIncrement);
|
||||
/// Advance the logical time to the given time.
|
||||
/// Depending on the time constrained mode, this might
|
||||
/// block until the time advance is granted.
|
||||
bool timeAdvance(const SGTimeStamp& timeStamp);
|
||||
/// Advance the logical time as far as time advances are available.
|
||||
/// This call should not block and advance the logical time
|
||||
/// as far as currently possible.
|
||||
bool timeAdvanceAvailable();
|
||||
|
||||
/// Get the current federates time
|
||||
bool queryFederateTime(SGTimeStamp& timeStamp);
|
||||
bool modifyLookahead(const SGTimeStamp& timeStamp);
|
||||
/// Get the current federates lookahead
|
||||
bool queryLookahead(SGTimeStamp& timeStamp);
|
||||
|
||||
/// Process messages
|
||||
bool tick();
|
||||
/// Process one messsage
|
||||
bool processMessage();
|
||||
/// Process one message but do not wait longer than the relative timeout.
|
||||
bool processMessage(const SGTimeStamp& timeout);
|
||||
/// Process messages until the federate can proceed with the
|
||||
/// next simulation step. That is flush all pending messages and
|
||||
/// depending on the time constrained mode process messages until
|
||||
/// a pending time advance is granted.
|
||||
bool processMessages();
|
||||
|
||||
/// Legacy tick call
|
||||
bool tick(const double& minimum, const double& maximum);
|
||||
|
||||
class ObjectModelFactory {
|
||||
@@ -127,17 +192,59 @@ public:
|
||||
HLAInteractionClass* getInteractionClass(const std::string& name);
|
||||
const HLAInteractionClass* getInteractionClass(const std::string& name) const;
|
||||
|
||||
/// Tells the main exec loop to continue or not.
|
||||
void setDone(bool done);
|
||||
bool getDone() const;
|
||||
|
||||
virtual bool readObjectModel();
|
||||
|
||||
virtual bool subscribe();
|
||||
virtual bool publish();
|
||||
|
||||
virtual bool init();
|
||||
virtual bool update();
|
||||
virtual bool shutdown();
|
||||
|
||||
virtual bool exec();
|
||||
|
||||
private:
|
||||
HLAFederate(const HLAFederate&);
|
||||
HLAFederate& operator=(const HLAFederate&);
|
||||
|
||||
/// The underlying interface to the rti implementation
|
||||
SGSharedPtr<RTIFederate> _rtiFederate;
|
||||
|
||||
/// Parameters required to connect to an rti
|
||||
Version _version;
|
||||
std::list<std::string> _connectArguments;
|
||||
|
||||
/// Parameters for the federation execution
|
||||
std::string _federationExecutionName;
|
||||
std::string _federationObjectModel;
|
||||
bool _createFederationExecution;
|
||||
|
||||
/// Parameters for the federate
|
||||
std::string _federateType;
|
||||
std::string _federateName;
|
||||
|
||||
/// Time management related parameters
|
||||
/// If true, the federate is expected to enter time constrained mode
|
||||
bool _timeConstrained;
|
||||
/// If true, the federate is expected to enter time regulating mode
|
||||
bool _timeRegulating;
|
||||
/// The amount of time this federate leads the others.
|
||||
SGTimeStamp _leadTime;
|
||||
/// The regular time increment we do on calling update()
|
||||
SGTimeStamp _timeIncrement;
|
||||
/// The reference system time at initialization time.
|
||||
/// Is used to implement being time constrained on the
|
||||
/// local system time.
|
||||
bool _timeConstrainedByLocalClock;
|
||||
SGTimeStamp _localClockOffset;
|
||||
|
||||
/// If true the exec method returns.
|
||||
bool _done;
|
||||
|
||||
typedef std::map<std::string, SGSharedPtr<HLAObjectClass> > ObjectClassMap;
|
||||
ObjectClassMap _objectClassMap;
|
||||
|
||||
|
||||
@@ -579,7 +579,6 @@ private:
|
||||
|
||||
RTI13Federate::RTI13Federate(const std::list<std::string>& stringList) :
|
||||
_joined(false),
|
||||
_tickTimeout(10),
|
||||
_ambassador(new RTI13Ambassador),
|
||||
_federateAmbassador(new FederateAmbassador)
|
||||
{
|
||||
@@ -702,6 +701,12 @@ RTI13Federate::resign()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::getJoined() const
|
||||
{
|
||||
return _joined;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag)
|
||||
{
|
||||
@@ -728,13 +733,9 @@ RTI13Federate::registerFederationSynchronizationPoint(const std::string& label,
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::waitForFederationSynchronizationPointAnnounced(const std::string& label)
|
||||
RTI13Federate::getFederationSynchronizationPointAnnounced(const std::string& label)
|
||||
{
|
||||
while (!_federateAmbassador->getFederationSynchronizationPointAnnounced(label)) {
|
||||
_ambassador->tick(_tickTimeout, 0);
|
||||
_federateAmbassador->processQueues();
|
||||
}
|
||||
return true;
|
||||
return _federateAmbassador->getFederationSynchronizationPointAnnounced(label);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -766,13 +767,9 @@ RTI13Federate::synchronizationPointAchieved(const std::string& label)
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::waitForFederationSynchronized(const std::string& label)
|
||||
RTI13Federate::getFederationSynchronized(const std::string& label)
|
||||
{
|
||||
while (!_federateAmbassador->getFederationSynchronized(label)) {
|
||||
_ambassador->tick(_tickTimeout, 0);
|
||||
_federateAmbassador->processQueues();
|
||||
}
|
||||
return true;
|
||||
return _federateAmbassador->getFederationSynchronized(label);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -816,11 +813,6 @@ RTI13Federate::enableTimeConstrained()
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!_federateAmbassador->_timeConstrainedEnabled) {
|
||||
_ambassador->tick(_tickTimeout, 0);
|
||||
_federateAmbassador->processQueues();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -863,6 +855,12 @@ RTI13Federate::disableTimeConstrained()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::getTimeConstrainedEnabled()
|
||||
{
|
||||
return _federateAmbassador->_timeConstrainedEnabled;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::enableTimeRegulation(const SGTimeStamp& lookahead)
|
||||
{
|
||||
@@ -910,11 +908,6 @@ RTI13Federate::enableTimeRegulation(const SGTimeStamp& lookahead)
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!_federateAmbassador->_timeRegulationEnabled) {
|
||||
_ambassador->tick(_tickTimeout, 0);
|
||||
_federateAmbassador->processQueues();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -958,19 +951,44 @@ RTI13Federate::disableTimeRegulation()
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::timeAdvanceRequestBy(const SGTimeStamp& dt)
|
||||
RTI13Federate::modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead.");
|
||||
return false;
|
||||
}
|
||||
|
||||
SGTimeStamp fedTime = _federateAmbassador->_federateTime + dt;
|
||||
return timeAdvanceRequest(fedTime);
|
||||
try {
|
||||
_ambassador->modifyLookahead(timeStamp);
|
||||
} catch (RTI::InvalidLookahead& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::FederateNotExecutionMember& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::ConcurrentAccessAttempted& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::SaveInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::RestoreInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::RTIinternalError& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::timeAdvanceRequest(const SGTimeStamp& fedTime)
|
||||
RTI13Federate::getTimeRegulationEnabled()
|
||||
{
|
||||
return _federateAmbassador->_timeRegulationEnabled;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::timeAdvanceRequest(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
|
||||
@@ -978,7 +996,7 @@ RTI13Federate::timeAdvanceRequest(const SGTimeStamp& fedTime)
|
||||
}
|
||||
|
||||
try {
|
||||
_ambassador->timeAdvanceRequest(fedTime);
|
||||
_ambassador->timeAdvanceRequest(timeStamp);
|
||||
_federateAmbassador->_timeAdvancePending = true;
|
||||
} catch (RTI::InvalidFederationTime& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
@@ -1012,14 +1030,61 @@ RTI13Federate::timeAdvanceRequest(const SGTimeStamp& fedTime)
|
||||
return false;
|
||||
}
|
||||
|
||||
while (_federateAmbassador->_timeAdvancePending) {
|
||||
_ambassador->tick(_tickTimeout, 0);
|
||||
_federateAmbassador->processQueues();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::timeAdvanceRequestAvailable(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
_ambassador->timeAdvanceRequestAvailable(timeStamp);
|
||||
_federateAmbassador->_timeAdvancePending = true;
|
||||
} catch (RTI::InvalidFederationTime& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::FederationTimeAlreadyPassed& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::TimeAdvanceAlreadyInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::EnableTimeRegulationPending& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::EnableTimeConstrainedPending& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::FederateNotExecutionMember& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::ConcurrentAccessAttempted& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::SaveInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::RestoreInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::RTIinternalError& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::getTimeAdvancePending()
|
||||
{
|
||||
return _federateAmbassador->_timeAdvancePending;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::queryFederateTime(SGTimeStamp& timeStamp)
|
||||
{
|
||||
@@ -1049,37 +1114,6 @@ RTI13Federate::queryFederateTime(SGTimeStamp& timeStamp)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::modifyLookahead(const SGTimeStamp& timeStamp)
|
||||
{
|
||||
if (!_ambassador.valid()) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead.");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
_ambassador->modifyLookahead(timeStamp);
|
||||
} catch (RTI::InvalidLookahead& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::FederateNotExecutionMember& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::ConcurrentAccessAttempted& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::SaveInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::RestoreInProgress& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
} catch (RTI::RTIinternalError& e) {
|
||||
SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::queryLookahead(SGTimeStamp& timeStamp)
|
||||
{
|
||||
@@ -1168,7 +1202,7 @@ RTI13Federate::queryLITS(SGTimeStamp& timeStamp)
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::tick()
|
||||
RTI13Federate::processMessage()
|
||||
{
|
||||
bool result = _ambassador->tick();
|
||||
_federateAmbassador->processQueues();
|
||||
@@ -1176,10 +1210,17 @@ RTI13Federate::tick()
|
||||
}
|
||||
|
||||
bool
|
||||
RTI13Federate::tick(const double& minimum, const double& maximum)
|
||||
RTI13Federate::processMessages(const double& minimum, const double& maximum)
|
||||
{
|
||||
bool result = _ambassador->tick(minimum, maximum);
|
||||
bool result = _ambassador->tick(minimum, 0);
|
||||
_federateAmbassador->processQueues();
|
||||
if (!result)
|
||||
return false;
|
||||
SGTimeStamp timeStamp = SGTimeStamp::now() + SGTimeStamp::fromSec(maximum);
|
||||
do {
|
||||
result = _ambassador->tick(0, 0);
|
||||
_federateAmbassador->processQueues();
|
||||
} while (result && SGTimeStamp::now() <= timeStamp);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,33 +45,36 @@ public:
|
||||
/// Join with federateName the federation execution federation
|
||||
virtual FederationManagementResult join(const std::string& federateType, const std::string& federation);
|
||||
virtual bool resign();
|
||||
virtual bool getJoined() const;
|
||||
|
||||
/// Synchronization Point handling
|
||||
virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag);
|
||||
virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label);
|
||||
virtual bool getFederationSynchronizationPointAnnounced(const std::string& label);
|
||||
virtual bool synchronizationPointAchieved(const std::string& label);
|
||||
virtual bool waitForFederationSynchronized(const std::string& label);
|
||||
virtual bool getFederationSynchronized(const std::string& label);
|
||||
|
||||
/// Time management
|
||||
virtual bool enableTimeConstrained();
|
||||
virtual bool disableTimeConstrained();
|
||||
virtual bool getTimeConstrainedEnabled();
|
||||
|
||||
virtual bool enableTimeRegulation(const SGTimeStamp& lookahead);
|
||||
virtual bool disableTimeRegulation();
|
||||
virtual bool modifyLookahead(const SGTimeStamp& timeStamp);
|
||||
virtual bool getTimeRegulationEnabled();
|
||||
|
||||
virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt);
|
||||
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime);
|
||||
virtual bool timeAdvanceRequest(const SGTimeStamp& timeStamp);
|
||||
virtual bool timeAdvanceRequestAvailable(const SGTimeStamp& timeStamp);
|
||||
virtual bool getTimeAdvancePending();
|
||||
|
||||
virtual bool queryFederateTime(SGTimeStamp& timeStamp);
|
||||
virtual bool modifyLookahead(const SGTimeStamp& timeStamp);
|
||||
virtual bool queryLookahead(SGTimeStamp& timeStamp);
|
||||
|
||||
virtual bool queryGALT(SGTimeStamp& timeStamp);
|
||||
virtual bool queryLITS(SGTimeStamp& timeStamp);
|
||||
|
||||
/// Process messages
|
||||
virtual bool tick();
|
||||
virtual bool tick(const double& minimum, const double& maximum);
|
||||
virtual bool processMessage();
|
||||
virtual bool processMessages(const double& minimum, const double& maximum);
|
||||
|
||||
virtual RTI13ObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass);
|
||||
|
||||
@@ -86,10 +89,6 @@ private:
|
||||
RTI::FederateHandle _federateHandle;
|
||||
bool _joined;
|
||||
|
||||
/// The timeout for the single callback tick function in
|
||||
/// syncronous operations that need to wait for a callback
|
||||
double _tickTimeout;
|
||||
|
||||
/// RTI connection
|
||||
SGSharedPtr<RTI13Ambassador> _ambassador;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
@@ -46,33 +46,36 @@ public:
|
||||
/// Join with federateName the federation execution federation
|
||||
virtual FederationManagementResult join(const std::string& federateType, const std::string& federation) = 0;
|
||||
virtual bool resign() = 0;
|
||||
virtual bool getJoined() const = 0;
|
||||
|
||||
/// Synchronization Point handling
|
||||
virtual bool registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag) = 0;
|
||||
virtual bool waitForFederationSynchronizationPointAnnounced(const std::string& label) = 0;
|
||||
virtual bool getFederationSynchronizationPointAnnounced(const std::string& label) = 0;
|
||||
virtual bool synchronizationPointAchieved(const std::string& label) = 0;
|
||||
virtual bool waitForFederationSynchronized(const std::string& label) = 0;
|
||||
virtual bool getFederationSynchronized(const std::string& label) = 0;
|
||||
|
||||
/// Time management
|
||||
virtual bool enableTimeConstrained() = 0;
|
||||
virtual bool disableTimeConstrained() = 0;
|
||||
virtual bool getTimeConstrainedEnabled() = 0;
|
||||
|
||||
virtual bool enableTimeRegulation(const SGTimeStamp& lookahead) = 0;
|
||||
virtual bool disableTimeRegulation() = 0;
|
||||
virtual bool modifyLookahead(const SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool getTimeRegulationEnabled() = 0;
|
||||
|
||||
virtual bool timeAdvanceRequestBy(const SGTimeStamp& dt) = 0;
|
||||
virtual bool timeAdvanceRequest(const SGTimeStamp& fedTime) = 0;
|
||||
virtual bool timeAdvanceRequestAvailable(const SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool getTimeAdvancePending() = 0;
|
||||
|
||||
virtual bool queryFederateTime(SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool modifyLookahead(const SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool queryLookahead(SGTimeStamp& timeStamp) = 0;
|
||||
|
||||
virtual bool queryGALT(SGTimeStamp& timeStamp) = 0;
|
||||
virtual bool queryLITS(SGTimeStamp& timeStamp) = 0;
|
||||
|
||||
/// Process messages
|
||||
virtual bool tick() = 0;
|
||||
virtual bool tick(const double& minimum, const double& maximum) = 0;
|
||||
virtual bool processMessage() = 0;
|
||||
virtual bool processMessages(const double& minimum, const double& maximum) = 0;
|
||||
|
||||
virtual RTIObjectClass* createObjectClass(const std::string& name, HLAObjectClass* hlaObjectClass) = 0;
|
||||
// virtual RTIInteractionClass* createInteractionClass(const std::string& name) = 0;
|
||||
|
||||
Reference in New Issue
Block a user