]> git.mxchange.org Git - flightgear.git/blob - src/AIModel/AIAircraft.cxx
Tidy up the code a bit
[flightgear.git] / src / AIModel / AIAircraft.cxx
1 // FGAIAircraft - FGAIBase-derived class creates an AI airplane
2 //
3 // Written by David Culp, started October 2003.
4 //
5 // Copyright (C) 2003  David P. Culp - davidculp2@comcast.net
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include <simgear/math/point3d.hxx>
26 #include <Main/fg_props.hxx>
27 #include <Main/globals.hxx>
28 #include <Scenery/scenery.hxx>
29 #include <string>
30 #include <math.h>
31
32 SG_USING_STD(string);
33
34 #include "AIAircraft.hxx"
35
36
37 const FGAIAircraft::PERF_STRUCT FGAIAircraft::settings[] = {
38     // light aircraft
39     {2.0, 2.0,  450.0, 1000.0,  70.0,  80.0, 100.0,  80.0,  60.0},
40     // ww2_fighter
41     {4.0, 2.0, 3000.0, 1500.0, 110.0, 180.0, 250.0, 200.0, 100.0},
42     // jet_transport
43     {5.0, 2.0, 3000.0, 1500.0, 140.0, 300.0, 430.0, 300.0, 130.0},
44     // jet_fighter
45     {7.0, 3.0, 4000.0, 2000.0, 150.0, 350.0, 500.0, 350.0, 150.0}
46 };
47
48
49 FGAIAircraft::FGAIAircraft() {
50
51    // set heading and altitude locks
52    hdg_lock = false;
53    alt_lock = false;
54 }
55
56
57 FGAIAircraft::~FGAIAircraft() {
58 }
59
60
61 bool FGAIAircraft::init() {
62    return FGAIBase::init();
63 }
64
65
66 void FGAIAircraft::update(double dt) {
67
68    Run(dt);
69    Transform();
70    FGAIBase::update(dt);
71 }
72
73 void FGAIAircraft::SetPerformance(const PERF_STRUCT *ps) {
74    
75    performance = ps;
76
77
78
79 void FGAIAircraft::Run(double dt) {
80
81    FGAIAircraft::dt = dt;
82         
83    double turn_radius_ft;
84    double turn_circum_ft;
85    double speed_north_deg_sec;
86    double speed_east_deg_sec;
87    double ft_per_deg_lon;
88    double ft_per_deg_lat;
89    double dist_covered_ft;
90    double alpha;
91
92    // get size of a degree at this latitude
93    ft_per_deg_lat = 366468.96 - 3717.12 * cos(pos.lat() / 57.2958 );
94    ft_per_deg_lon = 365228.16 * cos(pos.lat() / 57.2958);
95
96    // adjust speed
97    double speed_diff = tgt_speed - speed;
98    if (fabs(speed_diff) > 0.2) {
99      if (speed_diff > 0.0) speed += performance->accel * dt;
100      if (speed_diff < 0.0) speed -= performance->decel * dt;
101    } 
102    
103    // convert speed to degrees per second
104    speed_north_deg_sec = cos( hdg / 57.29577951 ) * speed * 1.686 / ft_per_deg_lat;
105    speed_east_deg_sec  = sin( hdg / 57.29577951 ) * speed * 1.686 / ft_per_deg_lon;
106
107    // set new position
108    pos.setlat( pos.lat() + speed_north_deg_sec * dt);
109    pos.setlon( pos.lon() + speed_east_deg_sec * dt); 
110
111    // adjust heading based on current bank angle
112    if (roll != 0.0) {
113      turn_radius_ft = 0.088362 * speed * speed / tan( fabs(roll) / 57.2958 );
114      turn_circum_ft = 6.2831853 * turn_radius_ft;
115      dist_covered_ft = speed * 1.686 * dt; 
116      alpha = dist_covered_ft / turn_circum_ft * 360.0;
117      hdg += alpha * sign( roll );
118      if ( hdg > 360.0 ) hdg -= 360.0;
119      if ( hdg < 0.0) hdg += 360.0;
120    }
121
122    // adjust target bank angle if heading lock engaged
123    if (hdg_lock) {
124      double bank_sense = 0.0;
125      double diff = fabs(hdg - tgt_heading);
126      if (diff > 180) diff = fabs(diff - 360);
127      double sum = hdg + diff;
128      if (sum > 360.0) sum -= 360.0;
129      if (fabs(sum - tgt_heading) < 1.0) { 
130        bank_sense = 1.0;
131      } else {
132        bank_sense = -1.0;
133      } 
134      if (diff < 30) tgt_roll = diff * bank_sense; 
135    }
136
137    // adjust bank angle
138    double bank_diff = tgt_roll - roll;
139    if (fabs(bank_diff) > 0.2) {
140      if (bank_diff > 0.0) roll += 5.0 * dt;
141      if (bank_diff < 0.0) roll -= 5.0 * dt;
142    }
143
144    // adjust altitude (meters) based on current vertical speed (fpm)
145    altitude += vs * 0.0166667 * dt * 0.3048;  
146
147    // find target vertical speed if altitude lock engaged
148    if (alt_lock) {
149      double altitude_ft = altitude * 3.28084;
150      if (altitude_ft < tgt_altitude) {
151       tgt_vs = tgt_altitude - altitude_ft;
152       if (tgt_vs > performance->climb_rate) tgt_vs = performance->climb_rate;
153      } else {
154       tgt_vs = tgt_altitude - altitude_ft;
155       if (tgt_vs  < (-performance->descent_rate)) tgt_vs = -performance->descent_rate;
156      }
157    }
158
159    // adjust vertical speed
160    double vs_diff = tgt_vs - vs;
161    if (fabs(vs_diff) > 1.0) {
162      if (vs_diff > 0.0) {
163        vs += 400.0 * dt;
164        if (vs > tgt_vs) vs = tgt_vs;
165      } else {
166        vs -= 300.0 * dt;
167        if (vs < tgt_vs) vs = tgt_vs;
168      }
169    }   
170    
171    // match pitch angle to vertical speed
172    pitch = vs * 0.005;
173
174 }
175
176
177 void FGAIAircraft::AccelTo(double speed) {
178    tgt_speed = speed;
179 }
180
181
182 void FGAIAircraft::PitchTo(double angle) {
183    tgt_pitch = angle;
184    alt_lock = false;
185 }
186
187
188 void FGAIAircraft::RollTo(double angle) {
189    tgt_roll = angle;
190    hdg_lock = false; 
191 }
192
193
194 void FGAIAircraft::YawTo(double angle) {
195    tgt_yaw = angle;
196 }
197
198
199 void FGAIAircraft::ClimbTo(double altitude) {
200    tgt_altitude = altitude;
201    alt_lock = true;
202 }
203
204
205 void FGAIAircraft::TurnTo(double heading) {
206    tgt_heading = heading;
207    hdg_lock = true;
208 }
209
210
211 double FGAIAircraft::sign(double x) {
212
213   if ( x < 0.0 ) { return -1.0; }
214   else { return 1.0; }
215 }