X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FAIModel%2FAIMultiplayer.cxx;h=a9635c5f7b5541902035b8ee508cd6fbda54f294;hb=38226af24ec01e8f0a20d7fd73ef838a69f6ef25;hp=c8c2a2cca62707fa2430577f97b069691453724d;hpb=5fe860750eb8b99401a64b6aca68cc7b3da5eac9;p=flightgear.git diff --git a/src/AIModel/AIMultiplayer.cxx b/src/AIModel/AIMultiplayer.cxx old mode 100755 new mode 100644 index c8c2a2cca..a9635c5f7 --- a/src/AIModel/AIMultiplayer.cxx +++ b/src/AIModel/AIMultiplayer.cxx @@ -19,7 +19,7 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifdef HAVE_CONFIG_H # include @@ -29,6 +29,8 @@ #include "AIMultiplayer.hxx" +#include + // #define SG_DEBUG SG_ALERT FGAIMultiplayer::FGAIMultiplayer() : FGAIBase(otMultiplayer) { @@ -37,19 +39,47 @@ FGAIMultiplayer::FGAIMultiplayer() : FGAIBase(otMultiplayer) { mTimeOffsetSet = false; mAllowExtrapolation = true; mLagAdjustSystemSpeed = 10; -} + mLastTimestamp = 0; + aip.getSceneGraph()->setNodeMask(~SG_NODEMASK_TERRAIN_BIT); + lastUpdateTime = 0; +} FGAIMultiplayer::~FGAIMultiplayer() { } -bool FGAIMultiplayer::init() { - return FGAIBase::init(); +bool FGAIMultiplayer::init(bool search_in_AI_path) { + props->setStringValue("sim/model/path", model_path.c_str()); + //refuel_node = fgGetNode("systems/refuel/contact", true); + isTanker = false; // do this until this property is + // passed over the net + + string str1 = _getCallsign(); + string str2 = "MOBIL"; + + string::size_type loc1= str1.find( str2, 0 ); + if ( (loc1 != string::npos && str2 != "") ){ + // cout << " string found " << str2 << " in " << str1 << endl; + isTanker = true; + // cout << "isTanker " << isTanker << " " << mCallSign <setBoolValue("model-installed", _installed); + return result; } void FGAIMultiplayer::bind() { FGAIBase::bind(); + props->tie("refuel/contact", SGRawValuePointer(&contact)); + props->tie("tanker", SGRawValuePointer(&isTanker)); + + props->tie("controls/invisible", + SGRawValuePointer(&invisible)); + #define AIMPROProp(type, name) \ SGRawValueMethods(*this, &FGAIMultiplayer::get##name) @@ -57,13 +87,14 @@ SGRawValueMethods(*this, &FGAIMultiplayer::get##name) SGRawValueMethods(*this, \ &FGAIMultiplayer::get##name, &FGAIMultiplayer::set##name) - props->tie("callsign", AIMPROProp(const char *, CallSign)); + //props->tie("callsign", AIMPROProp(const char *, CallSign)); props->tie("controls/allow-extrapolation", AIMPRWProp(bool, AllowExtrapolation)); props->tie("controls/lag-adjust-system-speed", AIMPRWProp(double, LagAdjustSystemSpeed)); + #undef AIMPROProp #undef AIMPRWProp } @@ -71,13 +102,19 @@ SGRawValueMethods(*this, \ void FGAIMultiplayer::unbind() { FGAIBase::unbind(); - props->untie("callsign"); + //props->untie("callsign"); props->untie("controls/allow-extrapolation"); props->untie("controls/lag-adjust-system-speed"); + props->untie("controls/invisible"); + props->untie("refuel/contact"); + props->untie("tanker"); + } void FGAIMultiplayer::update(double dt) { + using namespace simgear; + if (dt <= 0) return; @@ -111,7 +148,8 @@ void FGAIMultiplayer::update(double dt) mTimeOffset = curentPkgTime - curtime - lag; } else { double offset = curentPkgTime - curtime - lag; - if (!mAllowExtrapolation && offset + lag < mTimeOffset) { + if ((!mAllowExtrapolation && offset + lag < mTimeOffset) + || (offset - 10 > mTimeOffset)) { mTimeOffset = offset; SG_LOG(SG_GENERAL, SG_DEBUG, "Resetting time offset adjust system to " "avoid extrapolation: time offset = " << mTimeOffset); @@ -154,6 +192,7 @@ void FGAIMultiplayer::update(double dt) SGVec3d ecPos; SGQuatf ecOrient; + if (tInterp <= curentPkgTime) { // Ok, we need a time prevous to the last available packet, // that is good ... @@ -166,16 +205,46 @@ void FGAIMultiplayer::update(double dt) MotionInfo::iterator firstIt = mMotionInfo.begin(); ecPos = firstIt->second.position; ecOrient = firstIt->second.orientation; + speed = norm(firstIt->second.linearVel) * SG_METER_TO_NM * 3600.0; - std::vector::const_iterator firstPropIt; - std::vector::const_iterator firstPropItEnd; + std::vector::const_iterator firstPropIt; + std::vector::const_iterator firstPropItEnd; firstPropIt = firstIt->second.properties.begin(); firstPropItEnd = firstIt->second.properties.end(); while (firstPropIt != firstPropItEnd) { - float val = firstPropIt->value; - PropertyMap::iterator pIt = mPropertyMap.find(firstPropIt->id); + //cout << " Setting property..." << (*firstPropIt)->id; + PropertyMap::iterator pIt = mPropertyMap.find((*firstPropIt)->id); if (pIt != mPropertyMap.end()) - pIt->second->setFloatValue(val); + { + //cout << "Found " << pIt->second->getPath() << ":"; + switch ((*firstPropIt)->type) { + case props::INT: + case props::BOOL: + case props::LONG: + pIt->second->setIntValue((*firstPropIt)->int_value); + //cout << "Int: " << (*firstPropIt)->int_value << "\n"; + break; + case props::FLOAT: + case props::DOUBLE: + pIt->second->setFloatValue((*firstPropIt)->float_value); + //cout << "Flo: " << (*firstPropIt)->float_value << "\n"; + break; + case props::STRING: + case props::UNSPECIFIED: + pIt->second->setStringValue((*firstPropIt)->string_value); + //cout << "Str: " << (*firstPropIt)->string_value << "\n"; + break; + default: + // FIXME - currently defaults to float values + pIt->second->setFloatValue((*firstPropIt)->float_value); + //cout << "Unknown: " << (*firstPropIt)->float_value << "\n"; + break; + } + } + else + { + SG_LOG(SG_GENERAL, SG_DEBUG, "Unable to find property: " << (*firstPropIt)->id << "\n"); + } ++firstPropIt; } @@ -199,29 +268,72 @@ void FGAIMultiplayer::update(double dt) ecPos = ((1-tau)*prevIt->second.position + tau*nextIt->second.position); ecOrient = interpolate((float)tau, prevIt->second.orientation, nextIt->second.orientation); + speed = norm((1-tau)*prevIt->second.linearVel + + tau*nextIt->second.linearVel) * SG_METER_TO_NM * 3600.0; if (prevIt->second.properties.size() == nextIt->second.properties.size()) { - std::vector::const_iterator prevPropIt; - std::vector::const_iterator prevPropItEnd; - std::vector::const_iterator nextPropIt; - std::vector::const_iterator nextPropItEnd; + std::vector::const_iterator prevPropIt; + std::vector::const_iterator prevPropItEnd; + std::vector::const_iterator nextPropIt; + std::vector::const_iterator nextPropItEnd; prevPropIt = prevIt->second.properties.begin(); prevPropItEnd = prevIt->second.properties.end(); nextPropIt = nextIt->second.properties.begin(); nextPropItEnd = nextIt->second.properties.end(); while (prevPropIt != prevPropItEnd) { - float val = (1-tau)*prevPropIt->value + tau*nextPropIt->value; - PropertyMap::iterator pIt = mPropertyMap.find(prevPropIt->id); + PropertyMap::iterator pIt = mPropertyMap.find((*prevPropIt)->id); + //cout << " Setting property..." << (*prevPropIt)->id; + if (pIt != mPropertyMap.end()) - pIt->second->setFloatValue(val); + { + //cout << "Found " << pIt->second->getPath() << ":"; + + int ival; + float val; + switch ((*prevPropIt)->type) { + case props::INT: + case props::BOOL: + case props::LONG: + ival = (int) (0.5+(1-tau)*((double) (*prevPropIt)->int_value) + + tau*((double) (*nextPropIt)->int_value)); + pIt->second->setIntValue(ival); + //cout << "Int: " << ival << "\n"; + break; + case props::FLOAT: + case props::DOUBLE: + val = (1-tau)*(*prevPropIt)->float_value + + tau*(*nextPropIt)->float_value; + //cout << "Flo: " << val << "\n"; + pIt->second->setFloatValue(val); + break; + case props::STRING: + case props::UNSPECIFIED: + //cout << "Str: " << (*nextPropIt)->string_value << "\n"; + pIt->second->setStringValue((*nextPropIt)->string_value); + break; + default: + // FIXME - currently defaults to float values + val = (1-tau)*(*prevPropIt)->float_value + + tau*(*nextPropIt)->float_value; + //cout << "Unk: " << val << "\n"; + pIt->second->setFloatValue(val); + break; + } + } + else + { + SG_LOG(SG_GENERAL, SG_DEBUG, "Unable to find property: " << (*prevPropIt)->id << "\n"); + } + ++prevPropIt; ++nextPropIt; } } // Now throw away too old data - if (prevIt != mMotionInfo.begin()) { + if (prevIt != mMotionInfo.begin()) + { --prevIt; mMotionInfo.erase(mMotionInfo.begin(), prevIt); } @@ -229,7 +341,7 @@ void FGAIMultiplayer::update(double dt) } else { // Ok, we need to predict the future, so, take the best data we can have // and do some eom computation to guess that for now. - FGExternalMotionData motionInfo = it->second; + FGExternalMotionData& motionInfo = it->second; // The time to predict, limit to 5 seconds double t = tInterp - motionInfo.time; @@ -259,29 +371,71 @@ void FGAIMultiplayer::update(double dt) t -= h; } - std::vector::const_iterator firstPropIt; - std::vector::const_iterator firstPropItEnd; + std::vector::const_iterator firstPropIt; + std::vector::const_iterator firstPropItEnd; + speed = norm(linearVel) * SG_METER_TO_NM * 3600.0; firstPropIt = it->second.properties.begin(); firstPropItEnd = it->second.properties.end(); while (firstPropIt != firstPropItEnd) { - float val = firstPropIt->value; - PropertyMap::iterator pIt = mPropertyMap.find(firstPropIt->id); + PropertyMap::iterator pIt = mPropertyMap.find((*firstPropIt)->id); + //cout << " Setting property..." << (*firstPropIt)->id; + if (pIt != mPropertyMap.end()) - pIt->second->setFloatValue(val); + { + switch ((*firstPropIt)->type) { + case props::INT: + case props::BOOL: + case props::LONG: + pIt->second->setIntValue((*firstPropIt)->int_value); + //cout << "Int: " << (*firstPropIt)->int_value << "\n"; + break; + case props::FLOAT: + case props::DOUBLE: + pIt->second->setFloatValue((*firstPropIt)->float_value); + //cout << "Flo: " << (*firstPropIt)->float_value << "\n"; + break; + case props::STRING: + case props::UNSPECIFIED: + pIt->second->setStringValue((*firstPropIt)->string_value); + //cout << "Str: " << (*firstPropIt)->string_value << "\n"; + break; + default: + // FIXME - currently defaults to float values + pIt->second->setFloatValue((*firstPropIt)->float_value); + //cout << "Unk: " << (*firstPropIt)->float_value << "\n"; + break; + } + } + else + { + SG_LOG(SG_GENERAL, SG_DEBUG, "Unable to find property: " << (*firstPropIt)->id << "\n"); + } + ++firstPropIt; } } // extract the position - SGGeod geod = ecPos; - pos.setlat(geod.getLatitudeDeg()); - pos.setlon(geod.getLongitudeDeg()); - pos.setelev(geod.getElevationM()); - + pos = SGGeod::fromCart(ecPos); + double recent_alt_ft = altitude_ft; + altitude_ft = pos.getElevationFt(); + + // expose a valid vertical speed + if (lastUpdateTime != 0) + { + double dT = curtime - lastUpdateTime; + double Weighting=1; + if (dt < 1.0) + Weighting = dt; + // simple smoothing over 1 second + vs = (1.0-Weighting)*vs + Weighting * (altitude_ft - recent_alt_ft) / dT * 60; + } + lastUpdateTime = curtime; + // The quaternion rotating from the earth centered frame to the // horizontal local frame - SGQuatf qEc2Hl = SGQuatf::fromLonLatRad((float)geod.getLongitudeRad(), - (float)geod.getLatitudeRad()); + SGQuatf qEc2Hl = SGQuatf::fromLonLatRad((float)pos.getLongitudeRad(), + (float)pos.getLatitudeRad()); // The orientation wrt the horizontal local frame SGQuatf hlOr = conj(qEc2Hl)*ecOrient; float hDeg, pDeg, rDeg; @@ -291,25 +445,60 @@ void FGAIMultiplayer::update(double dt) pitch = pDeg; SG_LOG(SG_GENERAL, SG_DEBUG, "Multiplayer position and orientation: " - << geod << ", " << hlOr); + << ecPos << ", " << hlOr); //###########################// // do calculations for radar // //###########################// - UpdateRadar(manager); + double range_ft2 = UpdateRadar(manager); + + //************************************// + // Tanker code // + //************************************// + + + if ( isTanker) { + //cout << "IS tanker "; + if ( (range_ft2 < 250.0 * 250.0) && + (y_shift > 0.0) && + (elevation > 0.0) ){ + // refuel_node->setBoolValue(true); + //cout << "in contact" << endl; + contact = true; + } else { + // refuel_node->setBoolValue(false); + //cout << "not in contact" << endl; + contact = false; + } + } else { + //cout << "NOT tanker " << endl; + contact = false; + } Transform(); } void -FGAIMultiplayer::addMotionInfo(const FGExternalMotionData& motionInfo, +FGAIMultiplayer::addMotionInfo(FGExternalMotionData& motionInfo, long stamp) { mLastTimestamp = stamp; - // Drop packets arriving out of order - if (!mMotionInfo.empty() && motionInfo.time < mMotionInfo.rbegin()->first) - return; + + if (!mMotionInfo.empty()) { + double diff = motionInfo.time - mMotionInfo.rbegin()->first; + + // packet is very old -- MP has probably reset (incl. his timebase) + if (diff < -10.0) + mMotionInfo.clear(); + + // drop packets arriving out of order + else if (diff < 0.0) + return; + } mMotionInfo[motionInfo.time] = motionInfo; + // We just copied the property (pointer) list - they are ours now. Clear the + // properties list in given/returned object, so former owner won't deallocate them. + motionInfo.properties.clear(); } void @@ -318,4 +507,3 @@ FGAIMultiplayer::setDoubleProperty(const std::string& prop, double val) SGPropertyNode* pNode = props->getChild(prop.c_str(), true); pNode->setDoubleValue(val); } -