]> git.mxchange.org Git - flightgear.git/commitdiff
Move the mechanics of turning out of the derived classes into AIPlane. The user...
authordaveluff <daveluff>
Tue, 2 Mar 2004 10:43:16 +0000 (10:43 +0000)
committerdaveluff <daveluff>
Tue, 2 Mar 2004 10:43:16 +0000 (10:43 +0000)
src/ATC/AIGAVFRTraffic.cxx
src/ATC/AILocalTraffic.cxx
src/ATC/AIPlane.cxx
src/ATC/AIPlane.hxx

index 2078ef6dc1eca7e8123585c023b51e5fa2efc144..8449f236c35f8e01e27fbac8c89855e1737e4d2a 100644 (file)
@@ -84,7 +84,8 @@ bool FGAIGAVFRTraffic::Init(Point3D pt, string destID, const string& callsign) {
        _pos.setelev(_cruise_alt);
        // initially set waypoint as airport location
        _wp = _destPos;
-       _hdg = GetHeadingFromTo(_pos, _wp);
+       //_hdg = GetHeadingFromTo(_pos, _wp);
+       SetTrack(GetHeadingFromTo(_pos, _wp));
        _roll = 0.0;
        _pitch = 0.0;
        slope = 0.0;
@@ -201,7 +202,8 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                        _straightIn = true;
                                        _incoming = true;
                                        _wp = GetPatternApproachPos();
-                                       _hdg = GetHeadingFromTo(_pos, _wp);     // TODO - turn properly!
+                                       //_hdg = GetHeadingFromTo(_pos, _wp);   // TODO - turn properly!
+                                       SetTrack(GetHeadingFromTo(_pos, _wp));
                                        slope = atan((_wp.elev() - _pos.elev()) / dclGetHorizontalSeparation(_wp, _pos)) * DCL_RADIANS_TO_DEGREES;
                                        double thesh_offset = 0.0;
                                        Point3D opos = ortho.ConvertToLocal(_pos);
@@ -221,7 +223,7 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                        _downwindEntry = true;
                                        _incoming = true;
                                        _wp = GetPatternApproachPos();
-                                       _hdg = GetHeadingFromTo(_pos, _wp);     // TODO - turn properly!
+                                       SetTrack(GetHeadingFromTo(_pos, _wp));
                                        slope = atan((_wp.elev() - _pos.elev()) / dclGetHorizontalSeparation(_wp, _pos)) * DCL_RADIANS_TO_DEGREES;
                                        //cout << "slope = " << slope << '\n';
                                        pending_transmission = "Report ";
@@ -247,7 +249,7 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                if(_straightIn) {
                        //cout << "A " << flush;
                        if(fabs(orthopos.x()) < 10.0 && !_established) {
-                               _hdg = rwy.hdg;         // MEGA MEGA HACK - FIXME!!!!!!!
+                               SetTrack(rwy.hdg);
                                _established = true;
                                //cout << "Established at " << orthopos << '\n';
                        }
@@ -279,15 +281,8 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                        if(_entering) {
                                //cout << "C" << flush;
                                if(_turning) {
-                                       double tgt_hdg = rwy.hdg + 180.0;
-                                       while((tgt_hdg - _hdg) > 180.0) _hdg += 360.0;
-                                       while((_hdg - tgt_hdg) > 180.0) _hdg -= 360.0;
-                                       double turn_time = 60.0;
-                                       _hdg += (360.0 / turn_time) * dt * (tgt_hdg > _hdg ? 1.0 : -1.0);
-                                       Bank(25.0 * (tgt_hdg > _hdg ? 1.0 : -1.0));
-                                       if(fabs(_hdg - tgt_hdg) < 2.0) {
+                                       if(fabs(_hdg - (rwy.hdg + 180)) < 2.0) {        // TODO - use track instead of _hdg?
                                                //cout << "Going Local...\n";
-                                               _hdg = rwy.hdg + 180.0; // TODO - FIX THIS UGLY HACK!!!!!!!
                                                leg = DOWNWIND;
                                                _local = true;
                                                _aip.setVisible(true);  // HACK
@@ -300,6 +295,7 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                if(fabs(orthopos.x() - (patternDirection == 1 ? 1000 : -1000)) < (_e45 ? 175 : 550)) {  // Caution - hardwired turn clearances.
                                        //cout << "_turning...\n";
                                        _turning = true;
+                                       SetTrack(rwy.hdg + 180.0);
                                }       // TODO - need to check for other traffic in the pattern and enter much more integilently than that!!!
                        } else {
                                //cout << "D" << flush;
@@ -318,12 +314,14 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                                        slope = 0.0;
                                        ConditionalTransmit(30);
                                        if(_e45) {
-                                               _hdg = (patternDirection == 1 ? rwy.hdg - 135.0 : rwy.hdg + 135.0);
+                                               SetTrack(patternDirection == 1 ? rwy.hdg - 135.0 : rwy.hdg + 135.0);
                                        } else {
-                                               _hdg = (patternDirection == 1 ? rwy.hdg + 90.0 : rwy.hdg - 90.0);
+                                               SetTrack(patternDirection == 1 ? rwy.hdg + 90.0 : rwy.hdg - 90.0);
                                        }
-                                       if(_hdg < 0.0) _hdg += 360.0;
+                                       //if(_hdg < 0.0) _hdg += 360.0;
                                        _entering = true;
+                               } else {
+                                       SetTrack(GetHeadingFromTo(_pos, _wp));
                                }
                        }       
                }
@@ -332,8 +330,8 @@ void FGAIGAVFRTraffic::FlyPlane(double dt) {
                slope = 0.0;
        }
        // FIXME - lots of hackery in the next six lines!!!!
-       double track = _hdg;
-       double crab = 0.0;      
+       //double track = _hdg;
+       double crab = 0.0;      // This is a placeholder for when we take wind into account.    
        _hdg = track + crab;
        double vel = _cruise_ias;
        double dist = vel * 0.514444 * dt;
@@ -410,7 +408,6 @@ int FGAIGAVFRTraffic::GetQuadrangleAltitude(int dir, int des_alt) {
 // 3/ At and appropriate point on non-circuit side of rwy at take-off end for perpendicular entry to circuit overflying end-of-rwy.
 Point3D FGAIGAVFRTraffic::GetPatternApproachPos() {
        //cout << "\n\n";
-       //cout << "PPPPPPPPPPPPPPPPPPPPPPPppppppppppppppp\n";
        //cout << "Calculating pattern approach pos for " << plane.callsign << '\n';
        Point3D orthopos = ortho.ConvertToLocal(_pos);
        Point3D tmp;
index 0f71a83693c6f71e7d8e517e7a0143ae58080cfe..99a8aae8f4eeed50a26540c85cfaae5e23166690 100644 (file)
@@ -164,6 +164,10 @@ void FGAILocalTraffic::GetRwyDetails(string id) {
        //cout << "GetRwyDetails called" << endl;
        
        rwy.rwyID = tower->GetActiveRunway();
+       //cout << "id = " << id << '\n';
+       //cout << "Returned id is " << tower->get_ident() << '\n';
+       //cout << "Returned name is " << tower->get_name() << '\n';
+       //cout << "rwy.rwyID = " << rwy.rwyID << '\n';
        
        // Now we need to get the threshold position and rwy heading
        
@@ -201,7 +205,7 @@ void FGAILocalTraffic::GetRwyDetails(string id) {
                rwy.end1ortho = ortho.ConvertToLocal(rwy.threshold_pos);        // should come out as zero
                rwy.end2ortho = ortho.ConvertToLocal(takeoff_end);
        } else {
-               SG_LOG(SG_ATC, SG_ALERT, "Help  - can't get good runway in FGAILocalTraffic!!\n");
+               SG_LOG(SG_ATC, SG_ALERT, "Help  - can't get good runway at airport " << id << " in FGAILocalTraffic!!");
        }
 }
 
@@ -328,7 +332,7 @@ bool FGAILocalTraffic::Init(const string& callsign, string ICAO, OperatingState
                        leg = DOWNWIND;
                        elevInitGood = false;
                        inAir = true;
-                       track = rwy.hdg - (180 * patternDirection);     //should tend to bring track back into the 0->360 range
+                       SetTrack(rwy.hdg - (180 * patternDirection));
                        slope = 0.0;
                        _pitch = 0.0;
                        _roll = 0.0;
@@ -383,7 +387,7 @@ void FGAILocalTraffic::DownwindEntry() {
        leg = DOWNWIND;
        elevInitGood = false;
        inAir = true;
-       track = rwy.hdg - (180 * patternDirection);     //should tend to bring track back into the 0->360 range
+       SetTrack(rwy.hdg - (180 * patternDirection));
        slope = 0.0;
        _pitch = 0.0;
        _roll = 0.0;
@@ -399,7 +403,7 @@ void FGAILocalTraffic::StraightInEntry(bool des) {
        leg = FINAL;
        elevInitGood = false;
        inAir = true;
-       track = rwy.hdg;
+       SetTrack(rwy.hdg);
        transmitted = true;     // TODO - fix this hack.
        // TODO - set up the next 5 properly for a descent!
        slope = -5.5;
@@ -702,7 +706,7 @@ void FGAILocalTraffic::Update(double dt) {
        //fgSetDouble("/AI/Local1/ortho-y", (ortho.ConvertToLocal(_pos)).y());
        //fgSetDouble("/AI/Local1/elev", _pos.elev() * SG_METER_TO_FEET);
        
-       // And finally, call parent for transmission rendering
+       // And finally, call parent.
        FGAIPlane::Update(dt);
 }
 
@@ -800,6 +804,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                IAS = vel + (cos((_hdg - wind_from) * DCL_DEGREES_TO_RADIANS) * wind_speed);
                if(IAS >= 70) {
                        leg = CLIMBOUT;
+                       SetTrack(rwy.hdg);      // Hands over control of turning to AIPlane
                        _pitch = 10.0;
                        IAS = best_rate_of_climb_speed;
                        //slope = 7.0;  
@@ -808,7 +813,6 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                }
                break;
        case CLIMBOUT:
-               track = rwy.hdg;
                // Turn to crosswind if above 700ft AND if other traffic allows
                // (decided in FGTower and accessed through GetCrosswindConstraint(...)).
                // According to AIM, traffic should climb to within 300ft of pattern altitude before commencing crosswind turn.
@@ -843,16 +847,13 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                }               
                break;
        case TURN1:
-               track += (360.0 / turn_time) * dt * patternDirection;
-               Bank(25.0 * patternDirection);
+               SetTrack(rwy.hdg + (90.0 * patternDirection));
                if((track < (rwy.hdg - 89.0)) || (track > (rwy.hdg + 89.0))) {
                        leg = CROSSWIND;
                }
                break;
        case CROSSWIND:
                goAround = false;
-               LevelWings();
-               track = rwy.hdg + (90.0 * patternDirection);
                if((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET > 1000) {
                        slope = 0.0;
                        _pitch = 0.0;
@@ -873,8 +874,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                }
                break;
        case TURN2:
-               track += (360.0 / turn_time) * dt * patternDirection;
-               Bank(25.0 * patternDirection);
+               SetTrack(rwy.hdg - (180 * patternDirection));
                // just in case we didn't make height on crosswind
                if((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET > 1000) {
                        slope = 0.0;
@@ -884,12 +884,9 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                if((track < (rwy.hdg - 179.0)) || (track > (rwy.hdg + 179.0))) {
                        leg = DOWNWIND;
                        transmitted = false;
-                       //roll = 0.0;
                }
                break;
        case DOWNWIND:
-               LevelWings();
-               track = rwy.hdg - (180 * patternDirection);     //should tend to bring track back into the 0->360 range
                // just in case we didn't make height on crosswind
                if(((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET > 995) && ((_pos.elev() - rwy.threshold_pos.elev()) * SG_METER_TO_FEET < 1015)) {
                        slope = 0.0;
@@ -947,14 +944,12 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                }
                break;
        case TURN3:
-               track += (360.0 / turn_time) * dt * patternDirection;
-               Bank(25.0 * patternDirection);
+               SetTrack(rwy.hdg - (90 * patternDirection));
                if(fabs(rwy.hdg - track) < 91.0) {
                        leg = BASE;
                }
                break;
        case BASE:
-               LevelWings();
                if(!transmitted) {
                        // Base report should only be transmitted at uncontrolled airport - not towered.
                        if(!_controlled) TransmitPatternPositionReport();
@@ -977,8 +972,6 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                        IAS = 70.0;
                }
                
-               track = rwy.hdg - (90 * patternDirection);
-
                // Try and arrange to turn nicely onto final
                turn_circumference = IAS * 0.514444 * turn_time;        
                //Hmmm - this is an interesting one - ground vs airspeed in relation to turn radius
@@ -991,8 +984,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                }
                break;
        case TURN4:
-               track += (360.0 / turn_time) * dt * patternDirection;
-               Bank(25.0 * patternDirection);
+               SetTrack(rwy.hdg);
                if(fabs(track - rwy.hdg) < 0.6) {
                        leg = FINAL;
                        vel = nominal_final_speed;
@@ -1062,7 +1054,7 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                        }
                }
                // Try and track the extended centreline
-               track = rwy.hdg - (0.2 * orthopos.x());
+               SetTrack(rwy.hdg - (0.2 * orthopos.x()));
                //cout << "orthopos.x() = " << orthopos.x() << " hdg = " << hdg << '\n';
                if(_pos.elev() < (rwy.threshold_pos.elev()+20.0+wheelOffset)) {
                        DoGroundElev(); // Need to call it here expicitly on final since it's only called
@@ -1077,6 +1069,8 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
                                        _pitch = 0.0;
                                        leg = LANDING_ROLL;
                                        inAir = false;
+                                       LevelWings();
+                                       ClearTrack();   // Take over explicit track handling since AIPlane currently always banks when changing course 
                                }
                        }       // else need a fallback position based on arpt elev in case ground elev determination fails?
                } else {
index 23ebeda2ebbe265feb9e49a8e5909cd0f687eb4c..91434828db9c75eeaf63927b90dd7f5f85f68e13 100644 (file)
@@ -44,6 +44,10 @@ FGAIPlane::FGAIPlane() {
        playing = false;
        voiceOK = false;
        vPtr = NULL;
+       _tgtTrack = 0.0;
+       _trackSet = false;
+       _tgtRoll = 0.0;
+       _rollSuspended = false;
 }
 
 FGAIPlane::~FGAIPlane() {
@@ -113,20 +117,27 @@ void FGAIPlane::Update(double dt) {
                }
                _counter += dt;
        }
-}
-
-void FGAIPlane::Bank(double angle) {
-       // This *should* bank us smoothly to any angle
-       if(fabs(_roll - angle) > 0.6) {
-               _roll -= ((_roll - angle)/fabs(_roll - angle));  
+       
+       // Fly the plane if necessary
+       if(_trackSet) {
+               while((_tgtTrack - track) > 180.0) track += 360.0;
+               while((track - _tgtTrack) > 180.0) track -= 360.0;
+               double turn_time = 60.0;
+               track += (360.0 / turn_time) * dt * (_tgtTrack > track ? 1.0 : -1.0);
+               Bank(25.0 * (_tgtTrack > track ? 1.0 : -1.0));
+               if(fabs(track - _tgtTrack) < 2.0) {             // TODO - might need to optimise the delta there - it's on the large (safe) side atm.
+                       track = _tgtTrack;
+                       LevelWings();
+               }
        }
-}
-
-// Duplication of Bank(0.0) really - should I cut this?
-void FGAIPlane::LevelWings(void) {
-       // bring the plane back to level smoothly (this should work to come out of either bank)
-       if(fabs(_roll) > 0.6) {
-               _roll -= (_roll/fabs(_roll));
+       
+       if(!_rollSuspended) {
+               if(fabs(_roll - _tgtRoll) > 0.6) {
+                       // This *should* bank us smoothly to any angle
+                       _roll -= ((_roll - _tgtRoll)/fabs(_roll - _tgtRoll));
+               } else {
+                       _roll = _tgtRoll;
+               }
        }
 }
 
index e6da8ded4d7124211506b3e4c5055bc357a68888..466807ba43da724a16908f907501b3fc5845a226 100644 (file)
@@ -120,9 +120,12 @@ protected:
        
        // Transmit regardless of other dialog on the channel eg emergency
        void ImmediateTransmit(int callback_code = 0);
+       
+       inline void SetTrack(double t) { _tgtTrack = t; _trackSet = true; }
+       inline void ClearTrack() { _trackSet = false; }
 
-    void Bank(double angle);
-    void LevelWings(void);
+    inline void Bank(double r) { _tgtRoll = r; }
+    inline void LevelWings(void) { _tgtRoll = 0.0; }
        
        virtual void ProcessCallback(int code);
        
@@ -153,6 +156,12 @@ private:
        bool playing;           // Indicates a message in progress      
        bool voiceOK;           // Flag - true if at least one voice has loaded OK
        FGATCVoice* vPtr;
+       
+       // Navigation
+       double _tgtTrack;       // Track to be following if _trackSet is true
+       bool _trackSet;         // Set true if tgtTrack is to be followed
+       double _tgtRoll;
+       bool _rollSuspended;    // Set true when a derived class has suspended AIPlane's roll control
 };
 
 #endif  // _FG_AI_PLANE_HXX