]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIShip.cxx
Walk the AImodels property tree only once at init, rather than at update. Should...
[flightgear.git] / src / AIModel / AIShip.cxx
index 76b470d6d00b8e1a19c68837b3fad34fe7dbe7d7..b27b21d965dff8fd484489a362e05a9b6926b5b8 100644 (file)
@@ -43,7 +43,7 @@
 
 FGAIShip::FGAIShip(object_type ot) :
 FGAIBase(ot),
-_limit(40),
+_limit(100),
 _elevation_m(0),
 _elevation_ft(0),
 _tow_angle(0),
@@ -52,6 +52,7 @@ _next_run(0),
 _lead_angle(0),
 _xtrack_error(0),
 _tunnel(false),
+_initial_tunnel(false),
 _curr_alt(0),
 _prev_alt(0),
 _until_time(""),
@@ -68,7 +69,8 @@ _old_range(0),
 _range_rate(0),
 _roll_constant(0.001),
 _hdg_constant(0.01),
-_roll_factor(-0.0083335)
+_roll_factor(-0.0083335),
+_restart(false)
 
 {
         invisible = false;
@@ -89,6 +91,7 @@ void FGAIShip::readFromScenario(SGPropertyNode* scFileNode) {
     setRadius(scFileNode->getDoubleValue("turn-radius-ft", 2000));
     std::string flightplan = scFileNode->getStringValue("flightplan");
     setRepeat(scFileNode->getBoolValue("repeat", false));
+    setRestart(scFileNode->getBoolValue("restart", false));
     setStartTime(scFileNode->getStringValue("time", ""));
     setLeadAngleGain(scFileNode->getDoubleValue("lead-angle-gain", 1.5));
     setLeadAngleLimit(scFileNode->getDoubleValue("lead-angle-limit-deg", 15));
@@ -96,6 +99,7 @@ void FGAIShip::readFromScenario(SGPropertyNode* scFileNode) {
     setRudderConstant(scFileNode->getDoubleValue("rudder-constant", 0.5));
     setFixedTurnRadius(scFileNode->getDoubleValue("fixed-turn-radius-ft", 500));
     setSpeedConstant(scFileNode->getDoubleValue("speed-constant", 0.5));
+    setSMPath(scFileNode->getStringValue("submodel-path", ""));
 
     if (!flightplan.empty()) {
         SG_LOG(SG_GENERAL, SG_ALERT, "getting flightplan: " << _name );
@@ -196,6 +200,10 @@ void FGAIShip::bind() {
         SGRawValuePointer<double>(&_proportion));
     props->tie("controls/fixed-turn-radius-ft",
         SGRawValuePointer<double>(&_fixed_turn_radius));
+    props->tie("controls/restart",
+        SGRawValuePointer<bool>(&_restart));
+    props->tie("velocities/speed-kts",
+                SGRawValuePointer<double>(&speed));
 }
 
 void FGAIShip::unbind() {
@@ -231,6 +239,8 @@ void FGAIShip::unbind() {
     props->untie("controls/constants/lead-angle/proportion");
     props->untie("controls/fixed-turn-radius-ft");
     props->untie("controls/constants/speed");
+    props->untie("controls/restart");
+    props->untie("velocities/speed-kts");
 
 }
 void FGAIShip::update(double dt) {
@@ -241,12 +251,12 @@ void FGAIShip::update(double dt) {
     // Update the velocity information stored in those nodes.
     // Transform that one to the horizontal local coordinate system.
     SGQuatd ec2hl = SGQuatd::fromLonLat(pos);
-    // The orientation of the carrier wrt the horizontal local frame
+    // The orientation of the ship wrt the horizontal local frame
     SGQuatd hl2body = SGQuatd::fromYawPitchRollDeg(hdg, pitch, roll);
     // and postrotate the orientation of the AIModel wrt the horizontal
     // local frame
     SGQuatd ec2body = ec2hl*hl2body;
-    // The cartesian position of the carrier in the wgs84 world
+    // The cartesian position of the ship in the wgs84 world
     SGVec3d cartPos = SGVec3d::fromGeod(pos);
 
     // The simulation time this transform is meant for
@@ -304,8 +314,7 @@ void FGAIShip::Run(double dt) {
     }
 
     // do not allow unreasonable speeds
-    if (speed > _limit)
-        speed = _limit;
+    SG_CLAMP_RANGE(speed, -_limit * 0.75, _limit);
 
     // convert speed to degrees per second
     speed_north_deg_sec = cos(hdg / SGD_RADIANS_TO_DEGREES)
@@ -332,17 +341,26 @@ void FGAIShip::Run(double dt) {
 
 
     //we assume that at slow speed ships will manoeuvre using engines/bow thruster
-    if (fabs(speed)<=5)
-        _sp_turn_radius_ft = _fixed_turn_radius;
-    else {
-        // adjust turn radius for speed. The equation is very approximate.
-        // we need to allow for negative speeds
-        if (type == "ship")
-            _sp_turn_radius_ft = 10 * pow ((fabs(speed) - 15), 2) + turn_radius_ft;
-        else
-            _sp_turn_radius_ft = turn_radius_ft;
+       if(type == "ship" || type == "carrier" || type == "escort"){
+
+               if (fabs(speed)<=5)
+                       _sp_turn_radius_ft = _fixed_turn_radius;
+               else {
+                       // adjust turn radius for speed. The equation is very approximate.
+                       // we need to allow for negative speeds
+                       _sp_turn_radius_ft = 10 * pow ((fabs(speed) - 15), 2) + turn_radius_ft;
+               }
+
+       } else {
+               
+               if (fabs(speed) <= 40)
+           _sp_turn_radius_ft = _fixed_turn_radius;
+               else {
+                       // adjust turn radius for speed. 
+                       _sp_turn_radius_ft = turn_radius_ft;
+               }
+       }
 
-    }
 
     if (_rudder <= -0.25 || _rudder >= 0.25) {
         // adjust turn radius for _rudder angle. The equation is even more approximate.
@@ -404,7 +422,7 @@ void FGAIShip::Run(double dt) {
     }
 
     // set the _rudder limit by speed
-    if (type == "ship"){
+    if (type == "ship" || type == "carrier" || type == "escort"){
 
         if (speed <= 40)
             rudder_limit = (-0.825 * speed) + 35;
@@ -456,13 +474,6 @@ void FGAIShip::ClimbTo(double altitude) {
 }
 
 void FGAIShip::TurnTo(double heading) {
-    //double relbrg_corr = _relbrg;
-
-    //if ( relbrg_corr > 5)
-    //    relbrg_corr = 5;
-    //else if( relbrg_corr < -5)
-    //    relbrg_corr = -5;
-
     tgt_heading = heading - _lead_angle + _tow_angle;
     SG_NORMALIZE_RANGE(tgt_heading, 0.0, 360.0);
     _hdg_lock = true;
@@ -511,6 +522,10 @@ void FGAIShip::setRepeat(bool r) {
     _repeat = r;
 }
 
+void FGAIShip::setRestart(bool r) {
+    _restart = r;
+}
+
 void FGAIShip::setMissed(bool m) {
     _missed = m;
     props->setBoolValue("waypoint/missed", _missed);
@@ -548,6 +563,15 @@ void FGAIShip::setFixedTurnRadius(double ftr) {
     _fixed_turn_radius = ftr;
 }
 
+void FGAIShip::setInitialTunnel(bool t) {
+    _initial_tunnel = t;
+    setTunnel(_initial_tunnel);
+}
+
+void FGAIShip::setTunnel(bool t) {
+    _tunnel = t;
+}
+
 void FGAIShip::setWPNames() {
 
     if (prev != 0)
@@ -614,7 +638,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
     if (_dt_count < _next_run && _start_sec < time_sec)
         return;
 
-    _next_run = 1.0 + (0.5 * sg_random());
+    _next_run = 0.05 + (0.025 * sg_random());
 
     double until_time_sec = 0;
     _missed = false;
@@ -657,7 +681,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
         if (_next_name == "TUNNEL"){
             _tunnel = !_tunnel;
 
-            //SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: " << _name << " TUNNEL ");
+            SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: " << _name << " " << sp_turn_radius_nm );
 
             fp->IncrementWaypoint(false);
             next = fp->getNextWaypoint();
@@ -674,7 +698,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
         }else if(_next_name == "END" || fp->getNextWaypoint() == 0) {
 
             if (_repeat) {
-                SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: "<< _name << "Flightplan restarting ");
+                SG_LOG(SG_GENERAL, SG_INFO, "AIShip: "<< _name << " Flightplan repeating ");
                 fp->restart();
                 prev = curr;
                 curr = fp->getCurrentWaypoint();
@@ -687,6 +711,10 @@ void FGAIShip::ProcessFlightPlan(double dt) {
                 _missed_count = 0;
                 _lead_angle = 0;
                 AccelTo(prev->speed);
+            } else if (_restart){
+                SG_LOG(SG_GENERAL, SG_INFO, "AIShip: " << _name << " Flightplan restarting ");
+                _missed_count = 0;
+                initFlightPlan();
             } else {
                 SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: " << _name << " Flightplan dying ");
                 setDie(true);
@@ -728,7 +756,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
             _until_time = next->time;
             setUntilTime(next->time);
             if (until_time_sec > time_sec) {
-                SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: " << _name << " "
+                SG_LOG(SG_GENERAL, SG_INFO, "AIShip: " << _name << " "
                     << curr->name << " waiting until: "
                     << _until_time << " " << until_time_sec << " now " << time_sec );
                 setSpeed(0);
@@ -736,7 +764,7 @@ void FGAIShip::ProcessFlightPlan(double dt) {
                 _waiting = true;
                 return;
             } else {
-                SG_LOG(SG_GENERAL, SG_DEBUG, "AIShip: "
+                SG_LOG(SG_GENERAL, SG_INFO, "AIShip: "
                     << _name << " wait until done: getting new waypoints ");
                 setUntilTime("");
                 fp->IncrementWaypoint(false);
@@ -802,6 +830,7 @@ bool FGAIShip::initFlightPlan() {
 
     bool init = false;
     _start_sec = 0;
+    _tunnel = _initial_tunnel;
 
     fp->restart();
     fp->IncrementWaypoint(false);
@@ -859,7 +888,7 @@ bool FGAIShip::initFlightPlan() {
     _missed_count = 0;
     _new_waypoint = true;
 
-    SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: " << _name << " done initialising waypoints ");
+    SG_LOG(SG_GENERAL, SG_ALERT, "AIShip: " << _name << " done initialising waypoints " << _tunnel);
     if (prev)
         init = true;
 
@@ -1068,15 +1097,17 @@ void FGAIShip::setXTrackError() {
     double brg = getCourse(pos.getLatitudeDeg(), pos.getLongitudeDeg(),
         curr->latitude, curr->longitude);
     double xtrack_error_nm = sin((course - brg)* SG_DEGREES_TO_RADIANS) * _wp_range;
+    double factor = -0.0045 * speed + 1;
+    double limit = _lead_angle_limit * factor;
 
     if (_wp_range > 0){
         _lead_angle = atan2(xtrack_error_nm,(_wp_range * _proportion)) * SG_RADIANS_TO_DEGREES;
     } else
         _lead_angle = 0;
 
-    _lead_angle *= _lead_angle_gain;
+    _lead_angle *= _lead_angle_gain * factor;
     _xtrack_error = xtrack_error_nm * 6076.1155;
 
-    SG_CLAMP_RANGE(_lead_angle, -_lead_angle_limit, _lead_angle_limit);
+    SG_CLAMP_RANGE(_lead_angle, -limit, limit);
 
 }