FlightGear next
AIWingman.cxx
Go to the documentation of this file.
1// FGAIWingman - FGAIBllistic-derived class creates an AI Wingman
2//
3// Written by Vivian Meazza, started February 2008.
4// - vivian.meazza at lineone.net
5//
6// This program is free software; you can redistribute it and/or
7// modify it under the terms of the GNU General Public License as
8// published by the Free Software Foundation; either version 2 of the
9// License, or (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include <simgear/sg_inlines.h>
25
26#include <Main/fg_props.hxx>
27
28#include "AIWingman.hxx"
29
31_formate_to_ac(true),
32_break(false),
33_join(false),
34_break_angle(-90),
35_coeff_hdg(5.0),
36_coeff_pch(5.0),
37_coeff_bnk(5.0),
38_coeff_spd(2.0)
39
40{
41 invisible = false;
42 _parent="";
43 tgt_heading = 250;
44
45}
46
47void FGAIWingman::readFromScenario(SGPropertyNode* scFileNode) {
48 if (!scFileNode)
49 return;
50
52
53 setAzimuth(scFileNode->getDoubleValue("azimuth", 0.0));
54 setElevation(scFileNode->getDoubleValue("elevation", 0.0));
55 setLife(scFileNode->getDoubleValue("life", -1));
56 setNoRoll(scFileNode->getBoolValue("no-roll", false));
57 setName(scFileNode->getStringValue("name", "Wingman"));
58 setParentName(scFileNode->getStringValue("parent", ""));
59 setSubID(scFileNode->getIntValue("SubID", 0));
60 setXoffset(scFileNode->getDoubleValue("x-offset", 0.0));
61 setYoffset(scFileNode->getDoubleValue("y-offset", 0.0));
62 setZoffset(scFileNode->getDoubleValue("z-offset", 0.0));
63 setPitchoffset(scFileNode->getDoubleValue("pitch-offset", 0.0));
64 setRolloffset(scFileNode->getDoubleValue("roll-offset", 0.0));
65 setYawoffset(scFileNode->getDoubleValue("yaw-offset", 0.0));
66 setGroundOffset(scFileNode->getDoubleValue("ground-offset", 0.0));
67 setFormate(scFileNode->getBoolValue("formate", true));
68 setMaxSpeed(scFileNode->getDoubleValue("max-speed-kts", 300.0));
69 setCoeffHdg(scFileNode->getDoubleValue("coefficients/heading", 5.0));
70 setCoeffPch(scFileNode->getDoubleValue("coefficients/pitch", 5.0));
71 setCoeffBnk(scFileNode->getDoubleValue("coefficients/bank", 4.0));
72 setCoeffSpd(scFileNode->getDoubleValue("coefficients/speed", 2.0));
73
74
75}
76
79
80 props->untie("controls/slave-to-ac");
81
82 tie("id", SGRawValueMethods<FGAIBase,int>(*this,
84 tie("subID", SGRawValueMethods<FGAIBase,int>(*this,
86 tie("position/altitude-ft",
87 SGRawValueMethods<FGAIBase,double>(*this,
90 tie("position/latitude-deg",
91 SGRawValueMethods<FGAIBase,double>(*this,
94 tie("position/longitude-deg",
95 SGRawValueMethods<FGAIBase,double>(*this,
98
99 tie("controls/break", SGRawValuePointer<bool>(&_break));
100 tie("controls/join", SGRawValuePointer<bool>(&_join));
101
102 tie("controls/formate-to-ac",
103 SGRawValueMethods<FGAIWingman,bool>
104 (*this, &FGAIWingman::getFormate, &FGAIWingman::setFormate));
105 tie("controls/tgt-heading-deg",
106 SGRawValueMethods<FGAIWingman,double>
107 (*this, &FGAIWingman::getTgtHdg, &FGAIWingman::setTgtHdg));
108 tie("controls/tgt-speed-kt",
109 SGRawValueMethods<FGAIWingman,double>
110 (*this, &FGAIWingman::getTgtSpd, &FGAIWingman::setTgtSpd));
111 tie("controls/break-deg-rel",
112 SGRawValueMethods<FGAIWingman,double>
113 (*this, &FGAIWingman::getBrkAng, &FGAIWingman::setBrkAng));
114 tie("controls/coefficients/heading",
115 SGRawValuePointer<double>(&_coeff_hdg));
116 tie("controls/coefficients/pitch",
117 SGRawValuePointer<double>(&_coeff_pch));
118 tie("controls/coefficients/bank",
119 SGRawValuePointer<double>(&_coeff_bnk));
120 tie("controls/coefficients/speed",
121 SGRawValuePointer<double>(&_coeff_spd));
122
123 tie("orientation/pitch-deg", SGRawValuePointer<double>(&pitch));
124 tie("orientation/roll-deg", SGRawValuePointer<double>(&roll));
125 tie("orientation/true-heading-deg", SGRawValuePointer<double>(&hdg));
126
127 tie("submodels/serviceable", SGRawValuePointer<bool>(&serviceable));
128
129 tie("load/rel-brg-to-user-deg",
130 SGRawValueMethods<FGAIBallistic,double>
132 tie("load/elev-to-user-deg",
133 SGRawValueMethods<FGAIBallistic,double>
135
136 tie("velocities/vertical-speed-fps",
137 SGRawValueMethods<FGAIBase,double>(*this, &FGAIBase::_getVS_fps, &FGAIBase::_setVS_fps));
138 tie("velocities/true-airspeed-kt",
139 SGRawValuePointer<double>(&speed));
140 tie("velocities/speed-east-fps",
141 SGRawValuePointer<double>(&_speed_east_fps));
142 tie("velocities/speed-north-fps",
143 SGRawValuePointer<double>(&_speed_north_fps));
144
145 tie("position/x-offset",
146 SGRawValueMethods<FGAIBase,double>(*this, &FGAIBase::_getXOffset, &FGAIBase::setXoffset));
147 tie("position/y-offset",
148 SGRawValueMethods<FGAIBase,double>(*this, &FGAIBase::_getYOffset, &FGAIBase::setYoffset));
149 tie("position/z-offset",
150 SGRawValueMethods<FGAIBase,double>(*this, &FGAIBase::_getZOffset, &FGAIBase::setZoffset));
151 tie("position/tgt-x-offset",
152 SGRawValueMethods<FGAIBallistic,double>(*this, &FGAIBallistic::getTgtXOffset, &FGAIBallistic::setTgtXOffset));
153 tie("position/tgt-y-offset",
154 SGRawValueMethods<FGAIBallistic,double>(*this, &FGAIBallistic::getTgtYOffset, &FGAIBallistic::setTgtYOffset));
155 tie("position/tgt-z-offset",
156 SGRawValueMethods<FGAIBallistic,double>(*this, &FGAIBallistic::getTgtZOffset, &FGAIBallistic::setTgtZOffset));
157}
158
160{
161 if (!FGAIBallistic::init(searchOrder))
162 return false;
163 reinit();
164 return true;
165}
166
168 invisible = false;
169
173
174 hdg = _azimuth;
176 roll = _rotation;
177 _ht_agl_ft = 1e10;
178
179 if(_parent != ""){
181 }
182
184
185 props->setStringValue("submodels/path", _path.c_str());
186 user_WoW_node = fgGetNode("gear/gear[1]/wow", true);
187
189}
190
191void FGAIWingman::update(double dt) {
192
193// FGAIBallistic::update(dt);
194
195 if (_formate_to_ac){
196 formateToAC(dt);
197 Transform();
198 setBrkHdg(_break_angle);
199 }else if (_break) {
203 tgt_roll = roll;
205 Break(dt);
206 Transform();
207 } else {
208 Join(dt);
209 Transform();
210 }
211
212}
213
214double FGAIWingman::calcDistanceM(SGGeod pos1, SGGeod pos2) const {
215 //calculate the distance load to hitch
216 SGVec3d cartPos1 = SGVec3d::fromGeod(pos1);
217 SGVec3d cartPos2 = SGVec3d::fromGeod(pos2);
218
219 SGVec3d diff = cartPos1 - cartPos2;
220 double distance = norm(diff);
221 return distance;
222}
223
224double FGAIWingman::calcAngle(double range, SGGeod pos1, SGGeod pos2){
225
226 double angle = 0;
227 double distance = calcDistanceM(pos1, pos2);
228 double daltM = pos1.getElevationM() - pos2.getElevationM();
229
230 if (fabs(distance) < SGLimits<float>::min()) {
231 angle = 0;
232 } else {
233 double sAngle = daltM/range;
234 sAngle = SGMiscd::min(1, SGMiscd::max(-1, sAngle));
235 angle = SGMiscd::rad2deg(asin(sAngle));
236 }
237
238 return angle;
239}
240
241void FGAIWingman::formateToAC(double dt){
242
243 double p_hdg, p_pch, p_rll, p_agl, p_ht, p_wow = 0;
244
245 setTgtOffsets(dt, 25);
246
247 if (_pnode != 0) {
248 setParentPos();
249 p_hdg = _p_hdg_node->getDoubleValue();
250 p_pch = _p_pch_node->getDoubleValue();
251 p_rll = _p_rll_node->getDoubleValue();
252 p_ht = _p_alt_node->getDoubleValue();
253 setOffsetPos(_parentpos, p_hdg, p_pch, p_rll);
254 setSpeed(_p_spd_node->getDoubleValue());
255 }else {
256 p_hdg = manager->get_user_heading();
257 p_pch = manager->get_user_pitch();
258 p_rll = manager->get_user_roll();
259 p_ht = globals->get_aircraft_position().getElevationFt();
260 setOffsetPos(globals->get_aircraft_position(), p_hdg,p_pch, p_rll);
261 setSpeed(manager->get_user_speed());
262 }
263
264 // elapsed time has a random initialisation so that each
265 // wingman moves differently
266 _elapsed_time += dt;
267
268 // we derive a sine based factor to give us smoothly
269 // varying error between -1 and 1
270 double factor = sin(SGMiscd::deg2rad(_elapsed_time * 10));
271 double r_angle = 5 * factor;
272 double p_angle = 2.5 * factor;
273 double h_angle = 5 * factor;
274 double h_feet = 3 * factor;
275
276 p_agl = manager->get_user_agl();
277 p_wow = user_WoW_node->getDoubleValue();
278
279 if(p_agl <= 10 || p_wow == 1) {
280 _height = p_ht;
281 } else if (p_agl <= 150 ) {
282 setHt(p_ht, dt, 1.0);
283 } else if (p_agl <= 250) {
284 setHt(_offsetpos.getElevationFt() + h_feet, dt, 0.75);
285 } else{
286 setHt(_offsetpos.getElevationFt() + h_feet, dt, 0.5);
287 }
288
289 pos.setElevationFt(_height);
290 pos.setLatitudeDeg(_offsetpos.getLatitudeDeg());
291 pos.setLongitudeDeg(_offsetpos.getLongitudeDeg());
292
293 // these calculations are unreliable at slow speeds
294 // and we don't want random movement on the ground
295 if(speed >= 10 && p_wow != 1) {
296 setHdg(p_hdg + h_angle, dt, 0.9);
297 setPch(p_pch + p_angle + _pitch_offset, dt, 0.9);
298
299 if (roll <= 115 && roll >= -115)
300 setBnk(p_rll + r_angle + _roll_offset, dt, 0.5);
301 else
302 roll = p_rll + r_angle + _roll_offset;
303
304 } else {
305 setHdg(p_hdg, dt, 0.9);
306 setPch(p_pch + _pitch_offset, dt, 0.9);
307 setBnk(p_rll + _roll_offset, dt, 0.9);
308 }
309
311}// end formateToAC
312
313void FGAIWingman::Break(double dt) {
314
315 Run(dt);
316
317 //calculate the turn direction: 1 = right, -1 = left
318 double rel_brg = calcRelBearingDeg(tgt_heading, hdg);
319 int turn = SGMiscd::sign(rel_brg);
320
321 // set heading and pitch
322 setHdg(tgt_heading, dt, _coeff_hdg);
323 setPch(0, dt, _coeff_pch);
324
325 if (fabs(tgt_heading - hdg) >= 10)
326 setBnk(45 * turn , dt, _coeff_bnk);
327 else
328 setBnk(0, dt, _coeff_bnk);
329
330} // end Break
331
332void FGAIWingman::Join(double dt) {
333
334 double range, bearing, az2;
335 double parent_hdg, parent_spd = 0;
336 double p_hdg, p_pch, p_rll = 0;
337
338 setTgtOffsets(dt, 25);
339
340 if (_pnode != 0) {
341 setParentPos();
342 p_hdg = _p_hdg_node->getDoubleValue();
343 p_pch = _p_pch_node->getDoubleValue();
344 p_rll = _p_rll_node->getDoubleValue();
345 setOffsetPos(_parentpos, p_hdg, p_pch, p_rll);
346 parent_hdg = _p_hdg_node->getDoubleValue();
347 parent_spd = _p_spd_node->getDoubleValue();
348 }else {
349 p_hdg = manager->get_user_heading();
350 p_pch = manager->get_user_pitch();
351 p_rll = manager->get_user_roll();
352 setOffsetPos(globals->get_aircraft_position(), p_hdg, p_pch, p_rll);
353 parent_hdg = manager->get_user_heading();
354 parent_spd = manager->get_user_speed();
355 }
356
357 setSpeed(parent_spd);
358
359 double distance = calcDistanceM(pos, _offsetpos);
360 double daltM = _offsetpos.getElevationM() - pos.getElevationM();
361 double limit = 10;
362 double hdg_l_lim = parent_hdg - limit;
363 SG_NORMALIZE_RANGE(hdg_l_lim, 0.0, 360.0);
364 double hdg_r_lim = parent_hdg + limit;
365 SG_NORMALIZE_RANGE(hdg_r_lim, 0.0, 360.0);
366
367 if (distance <= 2 && fabs(daltM) <= 2 &&
368 (hdg >= hdg_l_lim || hdg <= hdg_r_lim)){
369 _height = _offsetpos.getElevationFt();
370 _formate_to_ac = true;
371 _join = false;
372
373 SG_LOG(SG_AI, SG_ALERT, _name << " joined " << " RANGE " << distance
374 << " SPEED " << speed );
375
376 return;
377 }
378
379 geo_inverse_wgs_84(pos, _offsetpos, &bearing, &az2, &range);
380
381 double rel_brg = calcRelBearingDeg(bearing, hdg);
382 double recip_brg = calcRecipBearingDeg(bearing);
383 double angle = calcAngle(distance,_offsetpos, pos);
384 //double approx_angle = atan2(daltM, range);
385 double frm_spd = 50; // formation speed
386 double join_rnge = 1000.0;
387// double recip_parent_hdg = calcRecipBearingDeg(parent_hdg);
388 int turn = SGMiscd::sign(rel_brg);// turn direction: 1 = right, -1 = left
389
390 if (range <= join_rnge && (hdg >= hdg_l_lim || hdg <= hdg_r_lim)){
391
392 //these are the rules governing joining
393
394 if ((rel_brg <= -175 || rel_brg >= 175) && range <=10 ){
395 // station is behind us - back up a bit
396 setSpeed(parent_spd - ((frm_spd/join_rnge) * range));
397 setHdg(recip_brg, dt, _coeff_hdg);
398 setPch(angle, dt, _coeff_pch);
399 //cout << _name << " backing up HEADING " << hdg
400 // << " RANGE " << range;
401 } else if (rel_brg >= -5 && rel_brg <= 5) {
402 // station is in front of us - slow down
403 setSpeed(parent_spd + ((frm_spd/100) * range));
404 //SGMiscd::clip
405 setHdg(bearing, dt, 1.5);
406 setPch(angle, dt, _coeff_pch);
407 //cout << _name << " slowing HEADING " << hdg
408 // << " RANGE " << range <<endl;
409 } else if ( range <=10 ){
410 // station is to one side - equal speed and turn towards
411 setSpd(parent_spd , dt, 2.0);
413 setHdg(parent_hdg + (5 * turn), dt, _coeff_hdg);
414 //cout << _name << " equal speed HEADING " << hdg
415 // << " RANGE " << range<< endl;
416 } else {
417 // we missed it - equal speed and turn to recip
418 setSpd(parent_spd , dt, 2.0);
420 setHdg(recip_brg, dt, _coeff_hdg);
421 //cout << _name << " WHOOPS!! missed join HEADING " << hdg
422 // << " RANGE " << range<< endl;
423 }
424
425 } else if (range <= join_rnge) {
426 // we missed it - equal speed and turn to recip
427 setSpd(parent_spd , dt, 2.0);
429 setHdg(recip_brg , dt, _coeff_hdg);
430 //cout << _name << " WHOOPS!! missed approach HEADING " << hdg
431 // << " " << recip_brg
432 // /*<< " " << recip_parent_hdg*/
433 // << " RANGE " << range<< endl;
434 } else if (range > join_rnge && range <= 2000 ){
435 //approach phase
436 //cout << _name << " approach HEADING " << hdg
437 // << " RANGE " << range<< endl;
438 setSpd(parent_spd + frm_spd, dt, 2.0);
440 setHdg(bearing, dt, _coeff_hdg);
441 setPch(angle, dt, _coeff_pch);
442 } else {
443 //hurry up
444 //cout << _name << " hurry up HEADING " << hdg
445 // << " RANGE " << range<< endl;
446 setSpd(_max_speed -10, dt, 2.0);
448 setHdg(bearing, dt, _coeff_hdg);
449 setPch(angle, dt, _coeff_pch);
450 }
451
452 Run(dt);
453
454 // set roll
455
456 if (fabs(bearing - hdg) >= 10)
457 setBnk(45 * turn , dt, _coeff_bnk);
458 else
459 setBnk(0, dt, _coeff_bnk);
460
461} // end Join
462
463void FGAIWingman::Run(double dt) {
464
465 // don't let speed become negative
466 SG_CLAMP_RANGE(speed, 100.0, _max_speed);
467
468 double speed_fps = speed * SG_KT_TO_FPS;
469
470 // calculate vertical and horizontal speed components
471 if (speed == 0.0) {
472 hs = vs_fps = 0.0;
473 } else {
474 vs_fps = sin( pitch * SG_DEGREES_TO_RADIANS ) * speed_fps;
475 hs = cos( pitch * SG_DEGREES_TO_RADIANS ) * speed_fps;
476 }
477
478 //cout << "vs hs " << vs << " " << hs << endl;
479
480 //resolve horizontal speed into north and east components:
481 double speed_north_fps = cos(hdg / SG_RADIANS_TO_DEGREES) * hs;
482 double speed_east_fps = sin(hdg / SG_RADIANS_TO_DEGREES) * hs;
483
484 // convert horizontal speed (fps) to degrees per second
485 double speed_north_deg_sec = speed_north_fps / ft_per_deg_lat;
486 double speed_east_deg_sec = speed_east_fps / ft_per_deg_lon;
487
488 //get wind components
489 _wind_from_north = manager->get_wind_from_north();
490 _wind_from_east = manager->get_wind_from_east();
491
492 // convert wind speed (fps) to degrees lat/lon per second
493 double wind_speed_from_north_deg_sec = _wind_from_north / ft_per_deg_lat;
494 double wind_speed_from_east_deg_sec = _wind_from_east / ft_per_deg_lon;
495
496 //recombine the horizontal velocity components
497 hs = sqrt(((speed_north_fps) * (speed_north_fps))
498 + ((speed_east_fps)* (speed_east_fps )));
499
500 if (hs <= 0.00001)
501 hs = 0;
502
503 if (vs_fps <= 0.00001 && vs_fps >= -0.00001)
504 vs_fps = 0;
505
506 //cout << "lat " << pos.getLatitudeDeg()<< endl;
507 // set new position
508 pos.setLatitudeDeg( pos.getLatitudeDeg()
509 + (speed_north_deg_sec - wind_speed_from_north_deg_sec) * dt );
510 pos.setLongitudeDeg( pos.getLongitudeDeg()
511 + (speed_east_deg_sec - wind_speed_from_east_deg_sec ) * dt );
512 pos.setElevationFt(pos.getElevationFt() + vs_fps * dt);
513
514 //cout << _name << " run hs " << hs << " vs " << vs << endl;
515
516 // recalculate total speed
517 if ( vs_fps == 0 && hs == 0)
518 speed = 0;
519 else
520 speed = sqrt( vs_fps * vs_fps + hs * hs) / SG_KT_TO_FPS;
521
522 // recalculate elevation and azimuth (velocity vectors)
523 pitch = atan2( vs_fps, hs ) * SG_RADIANS_TO_DEGREES;
524 hdg = atan2((speed_east_fps),(speed_north_fps))* SG_RADIANS_TO_DEGREES;
525
526 // rationalise heading
527 SG_NORMALIZE_RANGE(hdg, 0.0, 360.0);
528
529}// end Run
530
531// end AIWingman
bool init(ModelSearchOrder searchOrder) override
void setTgtXOffset(double x)
void setTgtZOffset(double z)
void setOffsetVelocity(double dt, SGGeod pos)
double getTgtYOffset() const
SGPropertyNode_ptr _p_rll_node
double _speed_east_fps
void setNoRoll(bool nr)
void setParentNodes(const SGPropertyNode_ptr)
SGPropertyNode_ptr _p_spd_node
double getTgtXOffset() const
void setBnk(double r, double dt, double c)
void setSpd(double s, double dt, double c)
double _wind_from_north
double _wind_from_east
double _speed_north_fps
int setHdg(double az, double dt, double c)
void setTgtYOffset(double y)
void setLife(double seconds)
void setOffsetPos(SGGeod pos, double heading, double pitch, double roll)
void setPch(double e, double dt, double c)
double getElevHitchToUser() const
void setSubID(int i)
void setHt(double h, double dt, double c)
double getTgtZOffset() const
double getRelBrgHitchToUser() const
void reinit() override
SGPropertyNode_ptr _p_pch_node
void setTgtOffsets(double dt, double c)
void setAzimuth(double az)
void setElevation(double el)
void setGroundOffset(double g)
SGPropertyNode_ptr _p_hdg_node
SGPropertyNode_ptr _p_alt_node
SGPropertyNode_ptr _pnode
FGAIBallistic(object_type ot=object_type::otBallistic)
void bind() override
std::string _parent
Definition AIBase.hxx:191
void setSpeed(double speed_KTAS)
Definition AIBase.hxx:404
void setName(const std::string &n)
Definition AIBase.hxx:491
void setMaxSpeed(double kts)
Definition AIBase.hxx:542
double speed_fps
Definition AIBase.hxx:217
double tgt_pitch
Definition AIBase.hxx:233
double tgt_heading
Definition AIBase.hxx:229
double altitude_ft
Definition AIBase.hxx:218
double _getZOffset() const
Definition AIBase.cxx:1124
bool serviceable
Definition AIBase.hxx:258
SGGeod pos
Definition AIBase.hxx:212
virtual void readFromScenario(SGPropertyNode *scFileNode)
Definition AIBase.cxx:249
double _getElevationFt() const
Definition AIBase.cxx:1002
double _getYOffset() const
Definition AIBase.cxx:1120
void setParentName(const std::string &p)
Definition AIBase.hxx:486
double _getLatitude() const
Definition AIBase.cxx:998
void _setAltitude(double _alt)
Definition AIBase.cxx:1044
void setYoffset(double y_offset)
Definition AIBase.hxx:461
std::string _name
Definition AIBase.hxx:190
int getID() const
Definition AIBase.cxx:1092
bool invisible
Definition AIBase.hxx:256
int _getSubID() const
Definition AIBase.cxx:1096
double _pitch_offset
Definition AIBase.hxx:178
SGPropertyNode_ptr _selected_ac
Definition AIBase.hxx:204
double _x_offset
Definition AIBase.hxx:174
virtual void update(double dt)
Definition AIBase.cxx:294
double speed
Definition AIBase.hxx:216
double bearing
Definition AIBase.hxx:239
double _getXOffset() const
Definition AIBase.cxx:1116
void setZoffset(double z_offset)
Definition AIBase.hxx:466
double range
Definition AIBase.hxx:241
double _getLongitude() const
Definition AIBase.cxx:994
void _setLatitude(double latitude)
Definition AIBase.cxx:945
bool setParentNode()
Definition AIBase.cxx:953
double vs_fps
Definition AIBase.hxx:219
double hdg
Definition AIBase.hxx:213
void Transform()
Definition AIBase.cxx:518
double _max_speed
Definition AIBase.hxx:182
double tgt_speed
Definition AIBase.hxx:231
double _z_offset
Definition AIBase.hxx:176
double pitch
Definition AIBase.hxx:215
std::string _path
Definition AIBase.hxx:187
double ft_per_deg_lon
Definition AIBase.hxx:225
double speed_east_deg_sec
Definition AIBase.hxx:221
ModelSearchOrder
Definition AIBase.hxx:63
double calcRecipBearingDeg(double bearing)
Definition AIBase.hxx:535
double _y_offset
Definition AIBase.hxx:175
double calcRelBearingDeg(double bearing, double heading)
Definition AIBase.hxx:521
double ft_per_deg_lat
Definition AIBase.hxx:226
void setXoffset(double x_offset)
Definition AIBase.hxx:456
void setYawoffset(double z_offset)
Definition AIBase.hxx:481
double tgt_altitude_ft
Definition AIBase.hxx:230
void _setVS_fps(double _vs)
Definition AIBase.cxx:1022
void _setLongitude(double longitude)
Definition AIBase.cxx:941
double speed_north_deg_sec
Definition AIBase.hxx:220
double _getVS_fps() const
Definition AIBase.cxx:1010
double tgt_roll
Definition AIBase.hxx:232
double _roll_offset
Definition AIBase.hxx:179
double roll
Definition AIBase.hxx:214
void tie(const char *aRelPath, const SGRawValue< T > &aRawValue)
Tied-properties helper, record nodes which are tied for easy un-tie-ing.
Definition AIBase.hxx:198
SGPropertyNode_ptr props
Definition AIBase.hxx:205
FGAIManager * manager
Definition AIBase.hxx:209
void setPitchoffset(double x_offset)
Definition AIBase.hxx:471
void setRolloffset(double y_offset)
Definition AIBase.hxx:476
void update(double dt) override
void bind() override
Definition AIWingman.cxx:77
bool init(ModelSearchOrder searchOrder) override
void reinit() override
void readFromScenario(SGPropertyNode *scFileNode) override
Definition AIWingman.cxx:47
SGGeod get_aircraft_position() const
Definition globals.cxx:611
FGGlobals * globals
Definition globals.cxx:142
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
Definition proptest.cpp:27