]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/YASim/Hitch.cpp
FGPUIDialog: fix reading from already free'd memory.
[flightgear.git] / src / FDM / YASim / Hitch.cpp
old mode 100755 (executable)
new mode 100644 (file)
index f1765e9..45f9bd9
@@ -1,18 +1,26 @@
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
 #include "Math.hpp"
 #include "BodyEnvironment.hpp"
 #include "RigidBody.hpp"
-#include <Main/fg_props.hxx>
 #include <string.h>
+#include <sstream>
 
 
 
 #include "Hitch.hpp"
+
+using std::vector;
+
 namespace yasim {
 Hitch::Hitch(const char *name)
 {
+    if (fgGetNode("/sim/hitches", true))
+        _node = fgGetNode("/sim/hitches", true)->getNode(name, true);
+    else _node = 0;
     int i;
-    strncpy(_name,name,128);
-    _name[127]=0;
     for(i=0; i<3; i++)
         _pos[i] = _force[i] = _winchPos[i] = _mp_lpos[i]=_towEndForce[i]=_mp_force[i]=0;
     for(i=0; i<2; i++)
@@ -61,97 +69,57 @@ Hitch::Hitch(const char *name)
     _mp_open_last_state=false;
     _timeLagCorrectedDist=0;
 
-    //tie the properties
-    char text[128];
-    sprintf(text,"/sim/hitches/%s", _name);
-    SGPropertyNode * node = fgGetNode(text, true);
-    node->tie("tow/length",SGRawValuePointer<float>(&_towLength));
-    node->tie("tow/elastic-constant",SGRawValuePointer<float>(&_towElasticConstant));
-    node->tie("tow/weight-per-m-kg-m",SGRawValuePointer<float>(&_towWeightPerM));
-    node->tie("tow/brake-force",SGRawValuePointer<float>(&_towBrakeForce));
-    node->tie("winch/max-speed-m-s",SGRawValuePointer<float>(&_winchMaxSpeed));
-    node->tie("winch/rel-speed",SGRawValuePointer<float>(&_winchRelSpeed));
-    node->tie("winch/initial-tow-length-m",SGRawValuePointer<float>(&_winchInitialTowLength));
-    node->tie("winch/min-tow-length-m",SGRawValuePointer<float>(&_winchMinTowLength));
-    node->tie("winch/max-tow-length-m",SGRawValuePointer<float>(&_winchMaxTowLength));
-    node->tie("winch/global-pos-x",SGRawValuePointer<double>(&_winchPos[0]));
-    node->tie("winch/global-pos-y",SGRawValuePointer<double>(&_winchPos[1]));
-    node->tie("winch/global-pos-z",SGRawValuePointer<double>(&_winchPos[2]));
-    node->tie("winch/max-power",SGRawValuePointer<float>(&_winchPower));
-    node->tie("winch/max-force",SGRawValuePointer<float>(&_winchMaxForce));
-    node->tie("winch/actual-force",SGRawValuePointer<float>(&_winchActualForce));
-    node->tie("tow/end-force-x",SGRawValuePointer<float>(&_reportTowEndForce[0]));
-    node->tie("tow/end-force-y",SGRawValuePointer<float>(&_reportTowEndForce[1]));
-    node->tie("tow/end-force-z",SGRawValuePointer<float>(&_reportTowEndForce[2]));
-    node->tie("force",SGRawValuePointer<float>(&_forceMagnitude));
-    node->tie("open",SGRawValuePointer<bool>(&_open));
-    node->tie("force-is-calculated-by-other",SGRawValuePointer<bool>(&_forceIsCalculatedByMaster));
-    node->tie("local-pos-x",SGRawValuePointer<float>(&_pos[0]));
-    node->tie("local-pos-y",SGRawValuePointer<float>(&_pos[1]));
-    node->tie("local-pos-z",SGRawValuePointer<float>(&_pos[2]));
-    node->tie("tow/dist",SGRawValuePointer<float>(&_dist));
-    node->tie("tow/dist-time-lag-corrected",SGRawValuePointer<float>(&_timeLagCorrectedDist));
-    node->tie("tow/connected-to-property-node",SGRawValuePointer<bool>(&_towEndIsConnectedToProperty));
-    node->tie("tow/connected-to-mp-node",SGRawValuePointer<bool>(&_nodeIsMultiplayer));
-    node->tie("tow/connected-to-ai-node",SGRawValuePointer<bool>(&_nodeIsAiAircraft));
-    node->tie("tow/connected-to-ai-or-mp-id",SGRawValuePointer<int>(&_nodeID));
-    node->tie("debug/hitch-height-above-ground",SGRawValuePointer<float>(&_height_above_ground));
-    node->tie("debug/tow-end-height-above-ground",SGRawValuePointer<float>(&_winch_height_above_ground));
-    node->tie("debug/tow-rel-lo-pos",SGRawValuePointer<float>(&_loPosFrac));
-    node->tie("debug/tow-lowest-pos-height",SGRawValuePointer<float>(&_lowest_tow_height));
-    node->tie("is-slave",SGRawValuePointer<bool>(&_isSlave));
-    node->tie("speed-in-tow-direction",SGRawValuePointer<float>(&_speed_in_tow_direction));
-    node->tie("mp-auto-connect-period",SGRawValuePointer<float>(&_mpAutoConnectPeriod));
-    node->tie("mp-time-lag",SGRawValuePointer<float>(&_mp_time_lag));
-    node->setStringValue("tow/node","");
-    node->setStringValue("tow/connected-to-ai-or-mp-callsign");
-    node->setBoolValue("broken",false);
+    if (_node)
+    {
+#define TIE(x,v) _tiedProperties.Tie(_node->getNode(x, true),v)
+        TIE("tow/length", SGRawValuePointer<float>(&_towLength));
+        TIE("tow/elastic-constant",SGRawValuePointer<float>(&_towElasticConstant));
+        TIE("tow/weight-per-m-kg-m",SGRawValuePointer<float>(&_towWeightPerM));
+        TIE("tow/brake-force",SGRawValuePointer<float>(&_towBrakeForce));
+        TIE("winch/max-speed-m-s",SGRawValuePointer<float>(&_winchMaxSpeed));
+        TIE("winch/rel-speed",SGRawValuePointer<float>(&_winchRelSpeed));
+        TIE("winch/initial-tow-length-m",SGRawValuePointer<float>(&_winchInitialTowLength));
+        TIE("winch/min-tow-length-m",SGRawValuePointer<float>(&_winchMinTowLength));
+        TIE("winch/max-tow-length-m",SGRawValuePointer<float>(&_winchMaxTowLength));
+        TIE("winch/global-pos-x",SGRawValuePointer<double>(&_winchPos[0]));
+        TIE("winch/global-pos-y",SGRawValuePointer<double>(&_winchPos[1]));
+        TIE("winch/global-pos-z",SGRawValuePointer<double>(&_winchPos[2]));
+        TIE("winch/max-power",SGRawValuePointer<float>(&_winchPower));
+        TIE("winch/max-force",SGRawValuePointer<float>(&_winchMaxForce));
+        TIE("winch/actual-force",SGRawValuePointer<float>(&_winchActualForce));
+        TIE("tow/end-force-x",SGRawValuePointer<float>(&_reportTowEndForce[0]));
+        TIE("tow/end-force-y",SGRawValuePointer<float>(&_reportTowEndForce[1]));
+        TIE("tow/end-force-z",SGRawValuePointer<float>(&_reportTowEndForce[2]));
+        TIE("force",SGRawValuePointer<float>(&_forceMagnitude));
+        TIE("open",SGRawValuePointer<bool>(&_open));
+        TIE("force-is-calculated-by-other",SGRawValuePointer<bool>(&_forceIsCalculatedByMaster));
+        TIE("local-pos-x",SGRawValuePointer<float>(&_pos[0]));
+        TIE("local-pos-y",SGRawValuePointer<float>(&_pos[1]));
+        TIE("local-pos-z",SGRawValuePointer<float>(&_pos[2]));
+        TIE("tow/dist",SGRawValuePointer<float>(&_dist));
+        TIE("tow/dist-time-lag-corrected",SGRawValuePointer<float>(&_timeLagCorrectedDist));
+        TIE("tow/connected-to-property-node",SGRawValuePointer<bool>(&_towEndIsConnectedToProperty));
+        TIE("tow/connected-to-mp-node",SGRawValuePointer<bool>(&_nodeIsMultiplayer));
+        TIE("tow/connected-to-ai-node",SGRawValuePointer<bool>(&_nodeIsAiAircraft));
+        TIE("tow/connected-to-ai-or-mp-id",SGRawValuePointer<int>(&_nodeID));
+        TIE("debug/hitch-height-above-ground",SGRawValuePointer<float>(&_height_above_ground));
+        TIE("debug/tow-end-height-above-ground",SGRawValuePointer<float>(&_winch_height_above_ground));
+        TIE("debug/tow-rel-lo-pos",SGRawValuePointer<float>(&_loPosFrac));
+        TIE("debug/tow-lowest-pos-height",SGRawValuePointer<float>(&_lowest_tow_height));
+        TIE("is-slave",SGRawValuePointer<bool>(&_isSlave));
+        TIE("speed-in-tow-direction",SGRawValuePointer<float>(&_speed_in_tow_direction));
+        TIE("mp-auto-connect-period",SGRawValuePointer<float>(&_mpAutoConnectPeriod));
+        TIE("mp-time-lag",SGRawValuePointer<float>(&_mp_time_lag));
+#undef TIE
+        _node->setStringValue("tow/node","");
+        _node->setStringValue("tow/connected-to-ai-or-mp-callsign");
+        _node->setBoolValue("broken",false);
+    }
 }
 
 Hitch::~Hitch()
 {
-    char text[128];
-    sprintf(text,"/sim/hitches/%s", _name);
-    SGPropertyNode * node = fgGetNode(text, true);
-    node->untie("tow/length");
-    node->untie("tow/elastic-constant");
-    node->untie("tow/weight-per-m-kg-m");
-    node->untie("tow/brake-force");
-    node->untie("winch/max-speed-m-s");
-    node->untie("winch/rel-speed");
-    node->untie("winch/initial-tow-length-m");
-    node->untie("winch/min-tow-length-m");
-    node->untie("winch/max-tow-length-m");
-    node->untie("winch/global-pos-x");
-    node->untie("winch/global-pos-y");
-    node->untie("winch/global-pos-z");
-    node->untie("winch/max-power");
-    node->untie("winch/max-force");
-    node->untie("winch/actual-force");
-    node->untie("tow/end-force-x");
-    node->untie("tow/end-force-y");
-    node->untie("tow/end-force-z");
-    node->untie("force");
-    node->untie("open");
-    node->untie("force-is-calculated-by-other");
-    node->untie("local-pos-x");
-    node->untie("local-pos-y");
-    node->untie("local-pos-z");
-    node->untie("tow/dist");
-    node->untie("tow/dist-time-lag-corrected");
-    node->untie("tow/connected-to-property-node");
-    node->untie("tow/connected-to-mp-node");
-    node->untie("tow/connected-to-ai-node");
-    node->untie("tow/connected-to-ai-or-mp-id");
-    node->untie("debug/hitch-height-above-ground");
-    node->untie("debug/tow-end-height-above-ground");
-    node->untie("debug/tow-rel-lo-pos");
-    node->untie("debug/tow-lowest-pos-height");
-    node->untie("is-slave");
-    node->untie("speed-in-tow-direction");
-    node->untie("mp-auto-connect-period");
-    node->untie("mp-time-lag");
-
+    _tiedProperties.Untie();
     delete _state;
 }
 
@@ -226,12 +194,12 @@ void Hitch::setForceIsCalculatedByOther(bool b)
     _forceIsCalculatedByMaster=b;
 }
 
-const char *Hitch::getConnectedPropertyNode() const
+std::string Hitch::getConnectedPropertyNode() const
 {
     if (_towEndNode)
         return _towEndNode->getDisplayName();
     else
-        return 0;
+        return std::string("");
 }
 
 void Hitch::setConnectedPropertyNode(const char *nodename)
@@ -275,22 +243,15 @@ void Hitch::setWinchPositionAuto(bool doit)
 
     _state->posLocalToGlobal(lWinchPos,_winchPos);
     _towLength=_winchInitialTowLength;
-    SG_LOG(SG_GENERAL, SG_ALERT,"Set the winch pos to "<<_winchPos[0]<<","<<_winchPos[1]<<","<<_winchPos[2]<<endl);
+    fgSetString("/sim/messages/pilot", "Connected to winch!");
     _open=false;
 
-    char text[512];
-    sprintf(text,"/sim/hitches/%s", _name);
-    SGPropertyNode * node = fgGetNode(text, true);
-    node->setBoolValue("broken",false);
+    _node->setBoolValue("broken",false);
 
     //set the dist value (if not, the hitch would open in the next calcforce run
-    //float delta[3];
-    //Math::sub3(lWinchPos,_pos,delta);
-    //_dist=Math::mag3(delta);
-    _dist=Math::mag3(lWinchPos); //use the aircraft center as reference for distance calculation
-                                  //this position is transferred to the MP-Aircraft.
-                                  //With this trick, both player in aerotow get the same length
-    
+    float delta[3];
+    Math::sub3(lWinchPos,_pos,delta);
+    _dist=Math::mag3(delta);
 }
 
 void Hitch::findBestAIObject(bool doit,bool running_as_autoconnect)
@@ -298,14 +259,19 @@ void Hitch::findBestAIObject(bool doit,bool running_as_autoconnect)
     static bool lastState=false;
     if(!_state)
         return;
-    if (!doit)
+    if (!running_as_autoconnect)
     {
-        lastState=false;
-        return;
+        //if this function is binded to an input, it will be called every frame as long as the key is pressed.
+        //therefore wait for a key-release before running it again.
+        if (!doit)
+        {
+            lastState=false;
+            return;
+        }
+        if(lastState)
+            return;
+        lastState=true;
     }
-    if(lastState)
-        return;
-    lastState=true;
     double gpos[3];
     _state->posLocalToGlobal(_pos,gpos);
     double bestdist=_towLength*_towLength;//squared!
@@ -354,27 +320,30 @@ void Hitch::findBestAIObject(bool doit,bool running_as_autoconnect)
             bestdist=dist;
             _towEndNode=n;
             _towEndIsConnectedToProperty=true;
-            char text[512];
-            sprintf(text,"/sim/hitches/%s", _name);
-            SGPropertyNode * node = fgGetNode(text, true);
-            //node->setStringValue("tow/node",n->getPath());
-            node->setStringValue("tow/node",n->getDisplayName());
+            //_node->setStringValue("tow/node",n->getPath());
+            _node->setStringValue("tow/node",n->getDisplayName());
             _nodeID=n->getIntValue("id",0);
-            node->setStringValue("tow/connected-to-ai-or-mp-callsign",n->getStringValue("callsign"));
+            _node->setStringValue("tow/connected-to-ai-or-mp-callsign",n->getStringValue("callsign"));
             _open=false;
             found = true;
         }
     }
     if (found)
     {
-        char text[512];
-        sprintf(text,"/sim/hitches/%s", _name);
-        SGPropertyNode * node = fgGetNode(text, true);
-        //if (!running_as_autoconnect)
-        SG_LOG(SG_GENERAL, SG_ALERT,"Found aircraft for aerotow: "
-                <<node->getStringValue("tow/connected-to-ai-or-mp-callsign")
-                <<", distance "<<Math::sqrt(bestdist)<<"m at " 
-                <<node->getStringValue("tow/node")<<endl);
+        if (!running_as_autoconnect)
+        {
+            std::stringstream message;
+            message<<_node->getStringValue("tow/connected-to-ai-or-mp-callsign")
+                    <<", I am on your hook, distance "<<Math::sqrt(bestdist)<<" meter.";
+            fgSetString("/sim/messages/pilot", message.str().c_str());
+        }
+        else
+        {
+            std::stringstream message;
+            message<<_node->getStringValue("tow/connected-to-ai-or-mp-callsign")
+                <<": I am on your hook, distance "<<Math::sqrt(bestdist)<<" meter.";
+            fgSetString("/sim/messages/ai-plane", message.str().c_str());
+        }
         if (running_as_autoconnect)
             _isSlave=true;
         //set the dist value to some value below the tow lentgh (if not, the hitch
@@ -384,7 +353,9 @@ void Hitch::findBestAIObject(bool doit,bool running_as_autoconnect)
     }
     else
         if (!running_as_autoconnect)
-            SG_LOG(SG_GENERAL, SG_ALERT,"Found no aircraft for aerotow!"<<endl);
+        {
+            fgSetString("/sim/messages/atc", "Sorry, no aircraft for aerotow!");
+        }
 }
 
 void Hitch::setWinchInitialTowLength(float length)
@@ -431,8 +402,10 @@ void Hitch::calcForce(Ground *g_cb, RigidBody* body, State* s)
     *_state=*s;
     s->posGlobalToLocal(_winchPos,lWinchPos);
     Math::sub3(lWinchPos,_pos,delta);
-    //_dist=Math::mag3(delta);
-    _dist=Math::mag3(lWinchPos); //use the aircraft center as reference for distance calculation
+    if(!_towEndIsConnectedToProperty)
+        _dist=Math::mag3(delta);
+    else
+        _dist=Math::mag3(lWinchPos); //use the aircraft center as reference for distance calculation
                                   //this position is transferred to the MP-Aircraft.
                                   //With this trick, both player in aerotow get the same length
     Math::unit3(delta,deltaN);
@@ -467,10 +440,7 @@ void Hitch::calcForce(Ground *g_cb, RigidBody* body, State* s)
     {
         _forceMagnitude=0;
         _open=true;
-        char text[128];
-        sprintf(text,"/sim/hitches/%s", _name);
-        SGPropertyNode * node = fgGetNode(text, true);
-        node->setBoolValue("broken",true);
+        _node->setBoolValue("broken",true);
         _force[0]=_force[1]=_force[2]=0;
         _towEndForce[0]=_towEndForce[1]=_towEndForce[2]=0;
         _reportTowEndForce[0]=_reportTowEndForce[1]=_reportTowEndForce[2]=0;
@@ -561,10 +531,7 @@ void Hitch::calcForce(Ground *g_cb, RigidBody* body, State* s)
     {
         _forceMagnitude=0;
         _open=true;
-        char text[128];
-        sprintf(text,"/sim/hitches/%s", _name);
-        SGPropertyNode * node = fgGetNode(text, true);
-        node->setBoolValue("broken",true);
+        _node->setBoolValue("broken",true);
         _force[0]=_force[1]=_force[2]=0;
         _towEndForce[0]=_towEndForce[1]=_towEndForce[2]=0;
     }
@@ -588,16 +555,21 @@ void Hitch::integrate (float dt)
         {
             if (_dist>_towLength*1.00001)
             {
-                SG_LOG(SG_GENERAL, SG_ALERT,"Could not lock Hinch (tow length is insufficient) on hitch '"<<_name<<"' !"<<endl);
+                std::stringstream message;
+                message<<"Could not lock hitch (tow length is insufficient) on hitch "
+                       <<_node->getName()<<" "<<_node->getIndex()<<"!";
+                fgSetString("/sim/messages/pilot", message.str().c_str());
                 _open=true;
                 return;
             }
-            char text[512];
-            sprintf(text,"/sim/hitches/%s", _name);
-            SGPropertyNode * node = fgGetNode(text, true);
-            node->setBoolValue("broken",false);
+            _node->setBoolValue("broken",false);
         }
-        SG_LOG(SG_GENERAL, SG_ALERT,(_open?"Opened hitch (or broken tow) '":"Locked hitch '")<<_name<<"' !"<<endl);
+        std::stringstream message;
+        if (_node->getBoolValue("broken",false)&&_open)
+            message<<"Oh no, the tow is broken";
+        else
+            message<<(_open?"Opened hitch ":"Locked hitch ")<<_node->getName()<<" "<<_node->getIndex()<<"!";
+        fgSetString("/sim/messages/pilot", message.str().c_str());
         _oldOpen=_open;
     }
 
@@ -616,14 +588,11 @@ void Hitch::integrate (float dt)
     //check, if tow end can be modified by property, if yes: update
     if(_towEndIsConnectedToProperty)
     {
-        char text[128];
-        sprintf(text,"/sim/hitches/%s", _name);
-        SGPropertyNode * node = fgGetNode(text, true);
-        if (node)
+        if (_node)
         {
-            //_towEndNode=fgGetNode(node->getStringValue("tow/node"), false);
+            //_towEndNode=fgGetNode(_node->getStringValue("tow/node"), false);
             char towNode[256];
-            strncpy(towNode,node->getStringValue("tow/node"),256);
+            strncpy(towNode,_node->getStringValue("tow/node"),256);
             towNode[255]=0;
             _towEndNode=fgGetNode("ai/models")->getNode(towNode, false);
             //AI and multiplayer objects seem to change node?
@@ -632,7 +601,7 @@ void Hitch::integrate (float dt)
             {
                 char MPcallsign[256]="";
                 const char *MPc;
-                MPc=node->getStringValue("tow/connected-to-ai-or-mp-callsign");
+                MPc=_node->getStringValue("tow/connected-to-ai-or-mp-callsign");
                 if (MPc)
                 {
                     strncpy(MPcallsign,MPc,256);
@@ -654,8 +623,8 @@ void Hitch::integrate (float dt)
                                     if (strcmp(n->getStringValue("callsign"),MPcallsign)==0)//found
                                     {
                                         _towEndNode=n;
-                                        //node->setStringValue("tow/node",n->getPath());
-                                        node->setStringValue("tow/node",n->getDisplayName());
+                                        //_node->setStringValue("tow/node",n->getPath());
+                                        _node->setStringValue("tow/node",n->getDisplayName());
                                     }
                             }
                         }
@@ -701,12 +670,11 @@ void Hitch::integrate (float dt)
                         {
                             if(mp_open)
                             {
-                                _open=true;
-                                char text[512];
-                                sprintf(text,"/sim/hitches/%s", _name);
-                                SGPropertyNode * node = fgGetNode(text, true);
-                                node->getStringValue("tow/node","");
-                                SG_LOG(SG_GENERAL, SG_ALERT,"'"<<node->getStringValue("tow/node","")<<"' has opened hitch!"<<endl);
+                                _oldOpen=_open=true;
+                                std::stringstream message;
+                                message<<_node->getStringValue("tow/connected-to-ai-or-mp-callsign")
+                                    <<": I have released the tow!";
+                                fgSetString("/sim/messages/ai-plane", message.str().c_str());
                             }
                         }
                     }
@@ -736,13 +704,8 @@ void Hitch::integrate (float dt)
             }
         }
     }
-    //set the _reported_tow_end_force (smoothed)
-    //smooth it a bit and store it
-    float sc=10.*dt; //100ms
-    float tmp[3];
-    Math::mul3(sc,_towEndForce,tmp);
-    Math::mul3(1.-sc,_reportTowEndForce,_reportTowEndForce);
-    Math::add3(tmp,_reportTowEndForce,_reportTowEndForce);
+    //set the _reported_tow_end_force
+    Math::set3(_towEndForce,_reportTowEndForce);
 
     if (_open) return;
     if (_winchRelSpeed==0) return;
@@ -775,4 +738,4 @@ void Hitch::integrate (float dt)
 
 
 
-}; // namespace yasim
\ No newline at end of file
+}; // namespace yasim