1
0
Fork 0

hla: Use hla derived classes part 2

This commit is contained in:
Mathias Froehlich 2012-11-11 16:29:56 +01:00
parent 518cd00094
commit 354a1b3a0b
2 changed files with 95 additions and 124 deletions

View file

@ -1,5 +1,5 @@
//
// Copyright (C) 2009 - 2010 Mathias Fröhlich <Mathias.Froehlich@web.de>
// Copyright (C) 2009 - 2012 Mathias Fröhlich <Mathias.Froehlich@web.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -368,7 +368,8 @@ public:
};
// Factory class that is used to create an apternative data element for the multiplayer property attribute
class MPPropertyVariantRecordDataElementFactory : public sg::HLAVariantArrayDataElement::AlternativeDataElementFactory {
class MPPropertyVariantRecordDataElementFactory :
public sg::HLAVariantArrayDataElement::AlternativeDataElementFactory {
public:
MPPropertyVariantRecordDataElementFactory(PropertyReferenceSet* propertyReferenceSet) :
_propertyReferenceSet(propertyReferenceSet)
@ -397,38 +398,17 @@ private:
SGSharedPtr<PropertyReferenceSet> _propertyReferenceSet;
};
class MPAttributeData {
class FGHLA::MultiplayerObjectInstance : public sg::HLAObjectInstance {
public:
MPAttributeData() :
MultiplayerObjectInstance(sg::HLAObjectClass* objectClass) :
sg::HLAObjectInstance(objectClass),
_propertyReferenceSet(new PropertyReferenceSet),
_mpProperties(new sg::HLAVariantArrayDataElement)
{
_mpProperties->setAlternativeDataElementFactory(new MPPropertyVariantRecordDataElementFactory(_propertyReferenceSet.get()));
}
void setLocation(sg::HLAAbstractLocation* location)
{ _location = location; }
sg::HLAAbstractLocation* getLocation()
{ return _location.get(); }
const sg::HLAAbstractLocation* getLocation() const
{ return _location.get(); }
void setModel(AbstractModel* model)
{ _model = model; }
AbstractModel* getModel()
{ return _model.get(); }
const AbstractModel* getModel() const
{ return _model.get(); }
void setSimTime(AbstractSimTime* simTime)
{ _simTime = simTime; }
AbstractSimTime* getSimTime()
{ return _simTime.get(); }
const AbstractSimTime* getSimTime() const
{ return _simTime.get(); }
sg::HLAVariantArrayDataElement* getMPProperties() const
{ return _mpProperties.get(); }
virtual ~MultiplayerObjectInstance()
{ }
SGSharedPtr<PropertyReferenceSet> _propertyReferenceSet;
SGSharedPtr<sg::HLAAbstractLocation> _location;
@ -437,98 +417,97 @@ public:
SGSharedPtr<sg::HLAVariantArrayDataElement> _mpProperties;
};
class MPUpdateCallback : public sg::HLAObjectInstance::UpdateCallback {
class FGHLA::MPUpdateCallback : public sg::HLAObjectInstance::UpdateCallback {
public:
virtual void updateAttributeValues(sg::HLAObjectInstance& objectInstance, const sg::RTIData& tag)
{
updateAttributeValues();
updateAttributeValues(static_cast<MultiplayerObjectInstance&>(objectInstance));
objectInstance.encodeAttributeValues();
objectInstance.sendAttributeValues(tag);
}
virtual void updateAttributeValues(sg::HLAObjectInstance& objectInstance, const SGTimeStamp& timeStamp, const sg::RTIData& tag)
{
updateAttributeValues();
updateAttributeValues(static_cast<MultiplayerObjectInstance&>(objectInstance));
objectInstance.encodeAttributeValues();
objectInstance.sendAttributeValues(timeStamp, tag);
}
void updateAttributeValues()
void updateAttributeValues(MultiplayerObjectInstance& objectInstance)
{
_attributeData._simTime->setTimeStamp(globals->get_sim_time_sec());
objectInstance._simTime->setTimeStamp(globals->get_sim_time_sec());
SGGeod position = _ifce.getPosition();
// The quaternion rotating from the earth centered frame to the
// horizontal local frame
SGQuatd qEc2Hl = SGQuatd::fromLonLat(position);
SGQuatd hlOr = SGQuatd::fromYawPitchRoll(_ifce.get_Psi(), _ifce.get_Theta(), _ifce.get_Phi());
_attributeData._location->setCartPosition(SGVec3d::fromGeod(position));
_attributeData._location->setCartOrientation(qEc2Hl*hlOr);
objectInstance._location->setCartPosition(SGVec3d::fromGeod(position));
objectInstance._location->setCartOrientation(qEc2Hl*hlOr);
// The angular velocitied in the body frame
double p = _ifce.get_P_body();
double q = _ifce.get_Q_body();
double r = _ifce.get_R_body();
_attributeData._location->setAngularBodyVelocity(SGVec3d(p, q, r));
objectInstance._location->setAngularBodyVelocity(SGVec3d(p, q, r));
// The body uvw velocities in the interface are wrt the wind instead
// of wrt the ec frame
double n = _ifce.get_V_north()*SG_FEET_TO_METER;
double e = _ifce.get_V_east()*SG_FEET_TO_METER;
double d = _ifce.get_V_down()*SG_FEET_TO_METER;
_attributeData._location->setLinearBodyVelocity(hlOr.transform(SGVec3d(n, e, d)));
objectInstance._location->setLinearBodyVelocity(hlOr.transform(SGVec3d(n, e, d)));
if (_attributeData._mpProperties.valid() && _attributeData._mpProperties->getNumElements() == 0) {
if (_attributeData._propertyReferenceSet.valid() && _attributeData._propertyReferenceSet->getRootNode()) {
const sg::HLADataType* elementDataType = _attributeData._mpProperties->getElementDataType();
if (objectInstance._mpProperties.valid() && objectInstance._mpProperties->getNumElements() == 0) {
if (objectInstance._propertyReferenceSet.valid() && objectInstance._propertyReferenceSet->getRootNode()) {
const sg::HLADataType* elementDataType = objectInstance._mpProperties->getElementDataType();
const sg::HLAVariantRecordDataType* variantRecordDataType = elementDataType->toVariantRecordDataType();
for (unsigned i = 0, count = 0; i < variantRecordDataType->getNumAlternatives(); ++i) {
std::string name = variantRecordDataType->getAlternativeSemantics(i);
SGPropertyNode* node = _attributeData._propertyReferenceSet->getRootNode()->getNode(name);
SGPropertyNode* node = objectInstance._propertyReferenceSet->getRootNode()->getNode(name);
if (!node)
continue;
_attributeData._mpProperties->getOrCreateElement(count++)->setAlternativeIndex(i);
objectInstance._mpProperties->getOrCreateElement(count++)->setAlternativeIndex(i);
}
}
}
}
MPAttributeData _attributeData;
FlightProperties _ifce;
};
class MPReflectCallback : public sg::HLAObjectInstance::ReflectCallback {
class FGHLA::MPReflectCallback : public sg::HLAObjectInstance::ReflectCallback {
public:
virtual void reflectAttributeValues(sg::HLAObjectInstance& objectInstance,
const sg::HLAIndexList& indexList, const sg::RTIData& tag)
{
objectInstance.reflectAttributeValues(indexList, tag);
reflectAttributeValues();
reflectAttributeValues(static_cast<MultiplayerObjectInstance&>(objectInstance));
}
virtual void reflectAttributeValues(sg::HLAObjectInstance& objectInstance, const sg::HLAIndexList& indexList,
const SGTimeStamp& timeStamp, const sg::RTIData& tag)
{
objectInstance.reflectAttributeValues(indexList, timeStamp, tag);
reflectAttributeValues();
reflectAttributeValues(static_cast<MultiplayerObjectInstance&>(objectInstance));
}
void reflectAttributeValues()
void reflectAttributeValues(MultiplayerObjectInstance& objectInstance)
{
// Puh, damn ordering problems with properties startup and so on
if (_aiMultiplayer.valid()) {
FGExternalMotionData motionInfo;
motionInfo.time = _attributeData._simTime->getTimeStamp();
motionInfo.time = objectInstance._simTime->getTimeStamp();
motionInfo.lag = 0;
motionInfo.position = _attributeData._location->getCartPosition();
motionInfo.orientation = toQuatf(_attributeData._location->getCartOrientation());
motionInfo.linearVel = toVec3f(_attributeData._location->getLinearBodyVelocity());
motionInfo.angularVel = toVec3f(_attributeData._location->getAngularBodyVelocity());
motionInfo.position = objectInstance._location->getCartPosition();
motionInfo.orientation = toQuatf(objectInstance._location->getCartOrientation());
motionInfo.linearVel = toVec3f(objectInstance._location->getLinearBodyVelocity());
motionInfo.angularVel = toVec3f(objectInstance._location->getAngularBodyVelocity());
motionInfo.linearAccel = SGVec3f::zeros();
motionInfo.angularAccel = SGVec3f::zeros();
_aiMultiplayer->addMotionInfo(motionInfo, SGTimeStamp::now().getSeconds());
} else {
std::string modelPath = _attributeData._model->getModelPath();
std::string modelPath = objectInstance._model->getModelPath();
if (modelPath.empty())
return;
FGAIManager *aiMgr;
@ -540,7 +519,7 @@ public:
_aiMultiplayer->setPath(modelPath.c_str());
aiMgr->attach(_aiMultiplayer.get());
_attributeData._propertyReferenceSet->setRootNode(_aiMultiplayer->getPropertyRoot());
objectInstance._propertyReferenceSet->setRootNode(_aiMultiplayer->getPropertyRoot());
}
}
@ -552,74 +531,38 @@ public:
_aiMultiplayer = 0;
}
MPAttributeData _attributeData;
SGSharedPtr<FGAIMultiplayer> _aiMultiplayer;
};
class FGHLA::MultiplayerObjectInstance : public sg::HLAObjectInstance {
public:
MultiplayerObjectInstance(sg::HLAObjectClass* objectClass) :
sg::HLAObjectInstance(objectClass)
{ }
virtual ~MultiplayerObjectInstance()
{ }
};
// A SimTime implementation that works with the simulation
// time in an attribute. Used when we cannot do real time management.
class AttributeSimTime : public AbstractSimTime {
public:
virtual double getTimeStamp() const
{ return _simTime; }
virtual void setTimeStamp(double simTime)
{ _simTime = simTime; }
sg::HLADataElement* getDataElement()
{ return _simTime.getDataElement(); }
private:
sg::HLADoubleData _simTime;
};
// A SimTime implementation that works with the simulation
// time in two attributes like the avation sim net fom works
class MSecAttributeSimTime : public AbstractSimTime {
public:
virtual double getTimeStamp() const
{
return _secSimTime + 1e-3*_msecSimTime;
}
virtual void setTimeStamp(double simTime)
{
double sec = floor(simTime);
_secSimTime = sec;
_msecSimTime = 1e3*(simTime - sec);
}
sg::HLADataElement* getSecDataElement()
{ return _secSimTime.getDataElement(); }
sg::HLADataElement* getMSecDataElement()
{ return _msecSimTime.getDataElement(); }
private:
sg::HLADoubleData _secSimTime;
sg::HLADoubleData _msecSimTime;
};
class SimTimeFactory : public SGReferenced {
public:
virtual ~SimTimeFactory() {}
virtual AbstractSimTime* createSimTime(sg::HLAObjectInstance&) const = 0;
};
// A SimTime implementation that works with the simulation
// time in an attribute. Used when we cannot do real time management.
class AttributeSimTimeFactory : public SimTimeFactory {
public:
class SimTime : public AbstractSimTime {
public:
virtual double getTimeStamp() const
{ return _simTime; }
virtual void setTimeStamp(double simTime)
{ _simTime = simTime; }
sg::HLADataElement* getDataElement()
{ return _simTime.getDataElement(); }
private:
sg::HLADoubleData _simTime;
};
virtual AbstractSimTime* createSimTime(sg::HLAObjectInstance& objectInstance) const
{
AttributeSimTime* attributeSimTime = new AttributeSimTime;
objectInstance.setAttributeDataElement(_simTimeIndex, attributeSimTime->getDataElement());
return attributeSimTime;
SimTime* simTime = new SimTime;
objectInstance.setAttributeDataElement(_simTimeIndex, simTime->getDataElement());
return simTime;
}
void setSimTimeIndex(const sg::HLADataElementIndex& simTimeIndex)
{ _simTimeIndex = simTimeIndex; }
@ -628,14 +571,39 @@ private:
sg::HLADataElementIndex _simTimeIndex;
};
// A SimTime implementation that works with the simulation
// time in two attributes like the avation sim net fom works
class MSecAttributeSimTimeFactory : public SimTimeFactory {
public:
class SimTime : public AbstractSimTime {
public:
virtual double getTimeStamp() const
{
return _secSimTime + 1e-3*_msecSimTime;
}
virtual void setTimeStamp(double simTime)
{
double sec = floor(simTime);
_secSimTime = sec;
_msecSimTime = 1e3*(simTime - sec);
}
sg::HLADataElement* getSecDataElement()
{ return _secSimTime.getDataElement(); }
sg::HLADataElement* getMSecDataElement()
{ return _msecSimTime.getDataElement(); }
private:
sg::HLADoubleData _secSimTime;
sg::HLADoubleData _msecSimTime;
};
virtual AbstractSimTime* createSimTime(sg::HLAObjectInstance& objectInstance) const
{
MSecAttributeSimTime* attributeSimTime = new MSecAttributeSimTime;
objectInstance.setAttributeDataElement(_secIndex, attributeSimTime->getSecDataElement());
objectInstance.setAttributeDataElement(_msecIndex, attributeSimTime->getMSecDataElement());
return attributeSimTime;
SimTime* simTime = new SimTime;
objectInstance.setAttributeDataElement(_secIndex, simTime->getSecDataElement());
objectInstance.setAttributeDataElement(_msecIndex, simTime->getMSecDataElement());
return simTime;
}
void setSecIndex(const sg::HLADataElementIndex& secIndex)
{ _secIndex = secIndex; }
@ -765,7 +733,7 @@ public:
HLAObjectClass::discoverInstance(objectInstance, tag);
MPReflectCallback* reflectCallback = new MPReflectCallback;
objectInstance.setReflectCallback(reflectCallback);
attachDataElements(objectInstance, reflectCallback->_attributeData, false);
attachDataElements(static_cast<MultiplayerObjectInstance&>(objectInstance), false);
}
virtual void removeInstance(sg::HLAObjectInstance& objectInstance, const sg::RTIData& tag)
{
@ -783,9 +751,10 @@ public:
HLAObjectClass::registerInstance(objectInstance);
MPUpdateCallback* updateCallback = new MPUpdateCallback;
objectInstance.setUpdateCallback(updateCallback);
attachDataElements(objectInstance, updateCallback->_attributeData, true);
updateCallback->_attributeData._model->setModelPath(fgGetString("/sim/model/path", "default"));
updateCallback->_attributeData._propertyReferenceSet->setRootNode(fgGetNode("/", true));
MultiplayerObjectInstance& mpObjectInstance = static_cast<MultiplayerObjectInstance&>(objectInstance);
attachDataElements(mpObjectInstance, true);
mpObjectInstance._model->setModelPath(fgGetString("/sim/model/path", "default"));
mpObjectInstance._propertyReferenceSet->setRootNode(fgGetNode("/", true));
}
virtual void deleteInstance(sg::HLAObjectInstance& objectInstance)
{
@ -827,22 +796,22 @@ public:
}
private:
void attachDataElements(sg::HLAObjectInstance& objectInstance, MPAttributeData& attributeData, bool outgoing)
void attachDataElements(MultiplayerObjectInstance& objectInstance, bool outgoing)
{
objectInstance.setAttributeDataElement(_mpPropertiesIndex, attributeData.getMPProperties());
objectInstance.setAttributeDataElement(_mpPropertiesIndex, objectInstance._mpProperties.get());
if (_locationFactory.valid())
attributeData.setLocation(_locationFactory->createLocation(objectInstance));
objectInstance._location = _locationFactory->createLocation(objectInstance);
if (_modelFactory.valid())
attributeData.setModel(_modelFactory->createModel(objectInstance));
objectInstance._model = _modelFactory->createModel(objectInstance);
if (_simTimeFactory.valid())
attributeData.setSimTime(_simTimeFactory->createSimTime(objectInstance));
objectInstance._simTime = _simTimeFactory->createSimTime(objectInstance);
if (outgoing)
attachPropertyDataElements(*attributeData._propertyReferenceSet,
attachPropertyDataElements(*objectInstance._propertyReferenceSet,
objectInstance, _outputProperties);
else
attachPropertyDataElements(*attributeData._propertyReferenceSet,
attachPropertyDataElements(*objectInstance._propertyReferenceSet,
objectInstance, _inputProperties);
}
typedef std::map<sg::HLADataElementIndex, std::string> IndexPropertyMap;

View file

@ -38,6 +38,8 @@ public:
private:
/// All the utility classes we need currently
class XMLConfigReader;
class MPUpdateCallback;
class MPReflectCallback;
class MultiplayerObjectInstance;
class MultiplayerObjectClass;
class Federate;