FlightGear next
flight.hxx
Go to the documentation of this file.
1// flight.hxx -- define shared flight model parameters
2//
3// Written by Curtis Olson, started May 1997.
4//
5// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20//
21// $Id$
22
23
24#ifndef _FLIGHT_HXX
25#define _FLIGHT_HXX
26
27
28#ifndef __cplusplus
29# error This library requires C++
30#endif
31
32
33/* Required get_()
34
35 `FGInterface::get_Longitude ()'
36 `FGInterface::get_Latitude ()'
37 `FGInterface::get_Altitude ()'
38 `FGInterface::get_Phi ()'
39 `FGInterface::get_Theta ()'
40 `FGInterface::get_Psi ()'
41 `FGInterface::get_V_equiv_kts ()'
42
43 `FGInterface::get_V_north ()'
44 `FGInterface::get_V_east ()'
45 `FGInterface::get_V_down ()'
46
47 `FGInterface::get_P_Body ()'
48 `FGInterface::get_Q_Body ()'
49 `FGInterface::get_R_Body ()'
50
51 `FGInterface::get_Gamma_vert_rad ()'
52 `FGInterface::get_Climb_Rate ()'
53 `FGInterface::get_Alpha ()'
54 `FGInterface::get_Beta ()'
55
56 `FGInterface::get_Runway_altitude ()'
57
58 `FGInterface::get_Lon_geocentric ()'
59 `FGInterface::get_Lat_geocentric ()'
60 `FGInterface::get_Sea_level_radius ()'
61 `FGInterface::get_Earth_position_angle ()'
62
63 `FGInterface::get_Latitude_dot()'
64 `FGInterface::get_Longitude_dot()'
65 `FGInterface::get_Radius_dot()'
66
67 `FGInterface::get_Dx_cg ()'
68 `FGInterface::get_Dy_cg ()'
69 `FGInterface::get_Dz_cg ()'
70
71 `FGInterface::get_Radius_to_vehicle ()'
72
73 */
74
75
76#include <cmath>
77#include <functional>
78
79#include <simgear/compiler.h>
80#include <simgear/constants.h>
81#include <simgear/structure/subsystem_mgr.hxx>
82#include <simgear/props/tiedpropertylist.hxx>
83#include <FDM/groundcache.hxx>
86
87namespace simgear {
88class BVHMaterial;
89}
90
91class SGIOChannel;
92class FGAIAircraft;
93
105{
106public:
107 inline TrackComputer( double & track, double & path, const SGGeod & position ) :
108 _track( track ),
109 _path( path ),
110 _position( position ),
111 _prevPosition( position ) {
112 }
113
114 inline ~TrackComputer() {
115 if( _prevPosition == _position ) return;
116// _track = SGGeodesy::courseDeg( _prevPosition, _position );
117 double d = .0;
118 double distance = .0;
119 if( SGGeodesy::inverse( _prevPosition, _position, _track, d, distance ) ) {
120 d = _position.getElevationM() - _prevPosition.getElevationM();
121 _path = atan2( d, distance ) * SGD_RADIANS_TO_DEGREES;
122 }
123 }
124
125private:
126 double & _track;
127 double & _path;
128 const SGGeod & _position;
129 const SGGeod _prevPosition;
130};
131
132// This is based heavily on LaRCsim/ls_generic.h
133class FGInterface : public SGSubsystem
134{
135 // Has the init() method been called. This is used to delay
136 // initialization until scenery can be loaded and we know the true
137 // ground elevation.
138 bool inited;
139
140 // Have we bound to the property system
141 bool bound;
142
143 // periodic update management variable. This is a scheme to run
144 // the fdm with a fixed delta-t. We control how many iteration of
145 // the fdm to run with the fixed dt based on the elapsed time from
146 // the last update. This allows us to maintain sync with the real
147 // time clock, even though each frame could take a random amount
148 // of time. Since "dt" is unlikely to divide evenly into the
149 // elapse time, we keep track of the remainder and add it into the
150 // next elapsed time. This yields a small amount of temporal
151 // jitter ( < dt ) but in practice seems to work well.
152
158 struct FlightState
159 {
160 // CG position w.r.t. ref. point
161 SGVec3d d_cg_rp_body_v;
162
163 // Accelerations
164 SGVec3d v_dot_local_v;
165 SGVec3d v_dot_body_v;
166 SGVec3d a_cg_body_v;
167 SGVec3d a_pilot_body_v;
168 SGVec3d n_cg_body_v;
169 SGVec3d omega_dot_body_v;
170
171 // Velocities
172 SGVec3d v_local_v;
173 SGVec3d v_local_rel_ground_v; // V rel w.r.t. earth surface
174 SGVec3d v_local_airmass_v; // velocity of airmass (steady winds)
175 SGVec3d v_body_v; // ECEF velocities in body axis
176
177 SGVec3d omega_body_v; // Angular B rates
178 SGVec3d euler_rates_v;
179 SGVec3d geocentric_rates_v; // Geocentric linear velocities
180
181 // Positions
182 SGGeod geodetic_position_v;
183 SGVec3d cartesian_position_v;
184 SGGeoc geocentric_position_v;
185 SGVec3d euler_angles_v;
186
187 // Normal Load Factor
188 double nlf;
189
190 // Velocities
191 double v_rel_wind, v_true_kts;
192 double v_ground_speed, v_equiv_kts;
193 double v_calibrated_kts;
194
195 // Miscellaneious Quantities
196 double alpha, beta; // in radians
197 double gamma_vert_rad; // Flight path angles
198 double density, mach_number;
199 double static_pressure, total_pressure;
200 double dynamic_pressure;
201 double static_temperature, total_temperature;
202 double sea_level_radius, earth_position_angle;
203 double runway_altitude;
204 double climb_rate; // in feet per second
205 double altitude_agl;
206 double track;
207 double path;
208 };
209
210 FlightState _state;
211
212 simgear::TiedPropertyList _tiedProperties;
213
214 // the ground cache object itself.
215 FGGroundCache ground_cache;
216
217 GroundReactions _groundReactions;
218 AIWakeGroup wake_group;
219
220 void set_A_X_pilot(double x)
221 { _set_Accels_Pilot_Body(x, _state.a_pilot_body_v[1], _state.a_pilot_body_v[2]); }
222
223 void set_A_Y_pilot(double y)
224 { _set_Accels_Pilot_Body(_state.a_pilot_body_v[0], y, _state.a_pilot_body_v[2]); }
225
226 void set_A_Z_pilot(double z)
227 { _set_Accels_Pilot_Body(_state.a_pilot_body_v[0], _state.a_pilot_body_v[1], z); }
228
229protected:
230 int _calc_multiloop (double dt);
231
232
233 // deliberately not virtual so that
234 // FGInterface constructor will call
235 // the right version
236 void _setup();
237
238 void _busdump(void);
239 void _updatePositionM(const SGVec3d& cartPos);
240 void _updatePositionFt(const SGVec3d& cartPos) {
241 _updatePositionM(SG_FEET_TO_METER*cartPos);
242 }
243 void _updatePosition(const SGGeod& geod);
244 void _updatePosition(const SGGeoc& geoc);
245
246 void _updateGeodeticPosition( double lat, double lon, double alt );
247 void _updateGeocentricPosition( double lat_geoc, double lon, double alt );
248 void _update_ground_elev_at_pos( void );
249
250 inline void _set_CG_Position( double dx, double dy, double dz ) {
251 _state.d_cg_rp_body_v[0] = dx;
252 _state.d_cg_rp_body_v[1] = dy;
253 _state.d_cg_rp_body_v[2] = dz;
254 }
255 inline void _set_Accels_Local( double north, double east, double down ) {
256 _state.v_dot_local_v[0] = north;
257 _state.v_dot_local_v[1] = east;
258 _state.v_dot_local_v[2] = down;
259 }
260 inline void _set_Accels_Body( double u, double v, double w ) {
261 _state.v_dot_body_v[0] = u;
262 _state.v_dot_body_v[1] = v;
263 _state.v_dot_body_v[2] = w;
264 }
265 inline void _set_Accels_CG_Body( double x, double y, double z ) {
266 _state.a_cg_body_v[0] = x;
267 _state.a_cg_body_v[1] = y;
268 _state.a_cg_body_v[2] = z;
269 }
270 inline void _set_Accels_Pilot_Body( double x, double y, double z ) {
271 _state.a_pilot_body_v[0] = x;
272 _state.a_pilot_body_v[1] = y;
273 _state.a_pilot_body_v[2] = z;
274 }
275 inline void _set_Accels_CG_Body_N( double x, double y, double z ) {
276 _state.n_cg_body_v[0] = x;
277 _state.n_cg_body_v[1] = y;
278 _state.n_cg_body_v[2] = z;
279 }
280 void _set_Nlf(double n) { _state.nlf=n; }
281 inline void _set_Velocities_Local( double north, double east, double down ){
282 _state.v_local_v[0] = north;
283 _state.v_local_v[1] = east;
284 _state.v_local_v[2] = down;
285 }
286 inline void _set_Velocities_Ground(double north, double east, double down) {
287 _state.v_local_rel_ground_v[0] = north;
288 _state.v_local_rel_ground_v[1] = east;
289 _state.v_local_rel_ground_v[2] = down;
290 }
291 inline void _set_Velocities_Local_Airmass( double north, double east,
292 double down)
293 {
294 _state.v_local_airmass_v[0] = north;
295 _state.v_local_airmass_v[1] = east;
296 _state.v_local_airmass_v[2] = down;
297 }
298 inline void _set_Velocities_Body( double u, double v, double w) {
299 _state.v_body_v[0] = u;
300 _state.v_body_v[1] = v;
301 _state.v_body_v[2] = w;
302 }
303 inline void _set_V_rel_wind(double vt) { _state.v_rel_wind = vt; }
304 inline void _set_V_ground_speed( double v) { _state.v_ground_speed = v; }
305 inline void _set_V_equiv_kts( double kts ) { _state.v_equiv_kts = kts; }
306 inline void _set_V_calibrated_kts( double kts ) { _state.v_calibrated_kts = kts; }
307 inline void _set_Omega_Body( double p, double q, double r ) {
308 _state.omega_body_v[0] = p;
309 _state.omega_body_v[1] = q;
310 _state.omega_body_v[2] = r;
311 }
312 inline void _set_Euler_Rates( double phi, double theta, double psi ) {
313 _state.euler_rates_v[0] = phi;
314 _state.euler_rates_v[1] = theta;
315 _state.euler_rates_v[2] = psi;
316 }
317
318 void set_Phi_dot_degps(double x)
319 {
320 _state.euler_rates_v[0] = x * SGD_DEGREES_TO_RADIANS;
321 }
322
323 void set_Theta_dot_degps(double x)
324 {
325 _state.euler_rates_v[1] = x * SGD_DEGREES_TO_RADIANS;
326 }
327
328 void set_Psi_dot_degps(double x)
329 {
330 _state.euler_rates_v[2] = x * SGD_DEGREES_TO_RADIANS;
331 }
332
333 inline void _set_Geocentric_Rates( double lat, double lon, double rad ) {
334 _state.geocentric_rates_v[0] = lat;
335 _state.geocentric_rates_v[1] = lon;
336 _state.geocentric_rates_v[2] = rad;
337 }
338 inline void _set_Geocentric_Position( double lat, double lon, double rad ) {
339 _state.geocentric_position_v.setLatitudeRad(lat);
340 _state.geocentric_position_v.setLongitudeRad(lon);
341 _state.geocentric_position_v.setRadiusFt(rad);
342 }
343/* Don't call _set_L[at|ong]itude() directly, use _set_Geodetic_Position() instead.
344 These methods can't update the track.
345 *
346 inline void _set_Latitude(double lat) {
347 geodetic_position_v.setLatitudeRad(lat);
348 }
349 inline void _set_Longitude(double lon) {
350 geodetic_position_v.setLongitudeRad(lon);
351 }
352*/
353 inline void _set_Altitude(double altitude) {
354 _state.geodetic_position_v.setElevationFt(altitude);
355 }
356 inline void _set_Altitude_AGL(double agl) {
357 _state.altitude_agl = agl;
358 }
359 inline void _set_Geodetic_Position( double lat, double lon ) {
360 _set_Geodetic_Position( lat, lon, _state.geodetic_position_v.getElevationFt());
361 }
362 inline void _set_Geodetic_Position( double lat, double lon, double alt ) {
363 TrackComputer tracker( _state.track, _state.path, _state.geodetic_position_v );
364 _state.geodetic_position_v.setLatitudeRad(lat);
365 _state.geodetic_position_v.setLongitudeRad(lon);
366 _state.geodetic_position_v.setElevationFt(alt);
367 }
368 inline void _set_Euler_Angles( double phi, double theta, double psi ) {
369 _state.euler_angles_v[0] = phi;
370 _state.euler_angles_v[1] = theta;
371 _state.euler_angles_v[2] = psi;
372 }
373 // FIXME, for compatibility with JSBSim
374 inline void _set_T_Local_to_Body( int i, int j, double value) { }
375 inline void _set_Alpha( double a ) { _state.alpha = a; }
376 inline void _set_Beta( double b ) { _state.beta = b; }
377
378 inline void set_Alpha_deg( double a ) { _state.alpha = a * SGD_DEGREES_TO_RADIANS; }
379
380 inline void _set_Gamma_vert_rad( double gv ) { _state.gamma_vert_rad = gv; }
381 inline void _set_Density( double d ) { _state.density = d; }
382 inline void _set_Mach_number( double m ) { _state.mach_number = m; }
383 inline void _set_Static_pressure( double sp ) { _state.static_pressure = sp; }
384 inline void _set_Static_temperature( double t ) { _state.static_temperature = t; }
385 inline void _set_Total_temperature( double tat ) { _state.total_temperature = tat; } //JW
386 inline void _set_Sea_level_radius( double r ) { _state.sea_level_radius = r; }
387 inline void _set_Earth_position_angle(double a) {_state.earth_position_angle = a; }
388 inline void _set_Runway_altitude( double alt ) { _state.runway_altitude = alt; }
389 inline void _set_Climb_Rate(double rate) { _state.climb_rate = rate; }
390
391public:
392 FGInterface();
393 FGInterface( double dt );
394 virtual ~FGInterface();
395
396 // Subsystem API.
397 void bind() override;
398 void init() override;
399 void unbind() override;
400 void update(double dt) override;
401
402 virtual bool ToggleDataLogging(bool state) { return false; }
403 virtual bool ToggleDataLogging(void) { return false; }
404
405 bool readState(SGIOChannel* io);
406 bool writeState(SGIOChannel* io);
407
408 // Define the various supported flight models (many not yet implemented)
409 enum {
410 // Magic Carpet mode
412
413 // The NASA LaRCsim (Navion) flight model
415
416 // Jon S. Berndt's new FDM written from the ground up in C++
418
419 // Christian's hot air balloon simulation
421
422 // Aeronautical DEvelopment AGEncy, Bangalore India
424
425 // The following aren't implemented but are here to spark
426 // thoughts and discussions, and maybe even action.
432
433 // Driven externally via a serial port, net, file, etc.
435 };
436
437 // initialization
438 inline bool get_inited() const { return inited; }
439 inline void set_inited( bool value ) { inited = value; }
440
441 inline bool get_bound() const { return bound; }
442
443 //perform initializion that is common to all FDM's
444 void common_init();
445
446 // Makes possibly multiple calls of fn() with pairs of property paths that
447 // are associated in the FDM. Default implementation does nothing. Used by
448 // the Highlight subsystem.
449 virtual void property_associations(
450 std::function<void(const std::string& from, const std::string& to)> fn
451 );
452
453 // Positions
454 virtual void set_Latitude(double lat); // geocentric
455 virtual void set_Longitude(double lon);
456 virtual void set_Altitude(double alt); // triggers re-calc of AGL altitude
457 virtual void set_AltitudeAGL(double altagl); // and vice-versa
458 virtual void set_Latitude_deg (double lat) {
459 set_Latitude(lat * SGD_DEGREES_TO_RADIANS);
460 }
461 virtual void set_Longitude_deg (double lon) {
462 set_Longitude(lon * SGD_DEGREES_TO_RADIANS);
463 }
464
465 // Speeds -- setting any of these will trigger a re-calc of the rest
466 virtual void set_V_calibrated_kts(double vc);
467 virtual void set_Mach_number(double mach);
468 virtual void set_Velocities_Local( double north, double east, double down );
469 inline void set_V_north (double north) {
470 set_Velocities_Local(north, _state.v_local_v[1], _state.v_local_v[2]);
471 }
472 inline void set_V_east (double east) {
473 set_Velocities_Local(_state.v_local_v[0], east, _state.v_local_v[2]);
474 }
475 inline void set_V_down (double down) {
476 set_Velocities_Local(_state.v_local_v[0], _state.v_local_v[1], down);
477 }
478 virtual void set_Velocities_Body( double u, double v, double w);
479 virtual void set_uBody (double uBody) {
480 set_Velocities_Body(uBody, _state.v_body_v[1], _state.v_body_v[2]);
481 }
482 virtual void set_vBody (double vBody) {
483 set_Velocities_Body(_state.v_body_v[0], vBody, _state.v_body_v[2]);
484 }
485 virtual void set_wBody (double wBody) {
486 set_Velocities_Body(_state.v_body_v[0], _state.v_body_v[1], wBody);
487 }
488
489 // Euler angles
490 virtual void set_Euler_Angles( double phi, double theta, double psi );
491 virtual void set_Phi (double phi) {
493 }
494 virtual void set_Theta (double theta) {
495 set_Euler_Angles(get_Phi(), theta, get_Psi());
496 }
497 virtual void set_Psi (double psi) {
499 }
500 virtual void set_Phi_deg (double phi) {
501 set_Phi(phi * SGD_DEGREES_TO_RADIANS);
502 }
503 virtual void set_Theta_deg (double theta) {
504 set_Theta(theta * SGD_DEGREES_TO_RADIANS);
505 }
506 virtual void set_Psi_deg (double psi) {
507 set_Psi(psi * SGD_DEGREES_TO_RADIANS);
508 }
509
510 // Flight Path
511 virtual void set_Climb_Rate( double roc);
512 virtual void set_Gamma_vert_rad( double gamma);
513
514 // Earth
515
516 virtual void set_Static_pressure(double p);
517 virtual void set_Static_temperature(double T);
518 virtual void set_Density(double rho);
519
520 virtual void set_Velocities_Local_Airmass (double wnorth,
521 double weast,
522 double wdown );
523
524 // ========== Mass properties and geometry values ==========
525
526 // CG position w.r.t. ref. point
527 inline double get_Dx_cg() const { return _state.d_cg_rp_body_v[0]; }
528 inline double get_Dy_cg() const { return _state.d_cg_rp_body_v[1]; }
529 inline double get_Dz_cg() const { return _state.d_cg_rp_body_v[2]; }
530
531 // ========== Accelerations ==========
532
533 inline double get_V_dot_north() const { return _state.v_dot_local_v[0]; }
534 inline double get_V_dot_east() const { return _state.v_dot_local_v[1]; }
535 inline double get_V_dot_down() const { return _state.v_dot_local_v[2]; }
536
537 inline double get_U_dot_body() const { return _state.v_dot_body_v[0]; }
538 inline double get_V_dot_body() const { return _state.v_dot_body_v[1]; }
539 inline double get_W_dot_body() const { return _state.v_dot_body_v[2]; }
540
541 inline double get_A_X_cg() const { return _state.a_cg_body_v[0]; }
542 inline double get_A_Y_cg() const { return _state.a_cg_body_v[1]; }
543 inline double get_A_Z_cg() const { return _state.a_cg_body_v[2]; }
544
545 inline double get_A_X_pilot() const { return _state.a_pilot_body_v[0]; }
546 inline double get_A_Y_pilot() const { return _state.a_pilot_body_v[1]; }
547 inline double get_A_Z_pilot() const { return _state.a_pilot_body_v[2]; }
548
549 inline double get_N_X_cg() const { return _state.n_cg_body_v[0]; }
550 inline double get_N_Y_cg() const { return _state.n_cg_body_v[1]; }
551 inline double get_N_Z_cg() const { return _state.n_cg_body_v[2]; }
552
553 inline double get_Nlf(void) const { return _state.nlf; }
554
555 // ========== Velocities ==========
556
557 inline double get_V_north() const { return _state.v_local_v[0]; }
558 inline double get_V_east() const { return _state.v_local_v[1]; }
559 inline double get_V_down() const { return _state.v_local_v[2]; }
560 inline double get_uBody () const { return _state.v_body_v[0]; }
561 inline double get_vBody () const { return _state.v_body_v[1]; }
562 inline double get_wBody () const { return _state.v_body_v[2]; }
563
564 // Please dont comment these out. fdm=ada uses these (see
565 // cockpit.cxx) --->
566 inline double get_V_north_rel_ground() const {
567 return _state.v_local_rel_ground_v[0];
568 }
569 inline double get_V_east_rel_ground() const {
570 return _state.v_local_rel_ground_v[1];
571 }
572 inline double get_V_down_rel_ground() const {
573 return _state.v_local_rel_ground_v[2];
574 }
575 // <--- fdm=ada uses these (see cockpit.cxx)
576
577 inline double get_V_north_airmass() const { return _state.v_local_airmass_v[0]; }
578 inline double get_V_east_airmass() const { return _state.v_local_airmass_v[1]; }
579 inline double get_V_down_airmass() const { return _state.v_local_airmass_v[2]; }
580
581 inline double get_U_body() const { return _state.v_body_v[0]; }
582 inline double get_V_body() const { return _state.v_body_v[1]; }
583 inline double get_W_body() const { return _state.v_body_v[2]; }
584
585 inline double get_V_rel_wind() const { return _state.v_rel_wind; }
586
587 inline double get_V_true_kts() const { return _state.v_true_kts; }
588
589 inline double get_V_ground_speed() const { return _state.v_ground_speed; }
590 inline double get_V_ground_speed_kt() const { return _state.v_ground_speed * SG_FEET_TO_METER * 3600 * SG_METER_TO_NM; }
591 inline void set_V_ground_speed_kt(double ground_speed) { _state.v_ground_speed = ground_speed / ( SG_FEET_TO_METER * 3600 * SG_METER_TO_NM); }
592
593 inline double get_V_equiv_kts() const { return _state.v_equiv_kts; }
594
595 inline double get_V_calibrated_kts() const { return _state.v_calibrated_kts; }
596
597 inline double get_P_body() const { return _state.omega_body_v[0]; }
598 inline double get_Q_body() const { return _state.omega_body_v[1]; }
599 inline double get_R_body() const { return _state.omega_body_v[2]; }
600
601 inline double get_Phi_dot() const { return _state.euler_rates_v[0]; }
602 inline double get_Theta_dot() const { return _state.euler_rates_v[1]; }
603 inline double get_Psi_dot() const { return _state.euler_rates_v[2]; }
604 inline double get_Phi_dot_degps() const { return _state.euler_rates_v[0] * SGD_RADIANS_TO_DEGREES; }
605 inline double get_Theta_dot_degps() const { return _state.euler_rates_v[1] * SGD_RADIANS_TO_DEGREES; }
606 inline double get_Psi_dot_degps() const { return _state.euler_rates_v[2] * SGD_RADIANS_TO_DEGREES; }
607
608 inline double get_Latitude_dot() const { return _state.geocentric_rates_v[0]; }
609 inline double get_Longitude_dot() const { return _state.geocentric_rates_v[1]; }
610 inline double get_Radius_dot() const { return _state.geocentric_rates_v[2]; }
611
612 // ========== Positions ==========
613
614 inline double get_Lat_geocentric() const {
615 return _state.geocentric_position_v.getLatitudeRad();
616 }
617 inline double get_Lon_geocentric() const {
618 return _state.geocentric_position_v.getLongitudeRad();
619 }
620 inline double get_Radius_to_vehicle() const {
621 return _state.geocentric_position_v.getRadiusFt();
622 }
623
624 const SGGeod& getPosition() const { return _state.geodetic_position_v; }
625 const SGGeoc& getGeocPosition() const { return _state.geocentric_position_v; }
626 const SGVec3d& getCartPosition() const { return _state.cartesian_position_v; }
627
628 inline double get_Latitude() const {
629 return _state.geodetic_position_v.getLatitudeRad();
630 }
631 inline double get_Longitude() const {
632 return _state.geodetic_position_v.getLongitudeRad();
633 }
634 inline double get_Altitude() const {
635 return _state.geodetic_position_v.getElevationFt();
636 }
637 inline double get_Altitude_AGL(void) const { return _state.altitude_agl; }
638 inline double get_Track(void) const { return _state.track; }
639 inline double get_Path(void) const { return _state.path; }
640
641 inline double get_Latitude_deg () const {
642 return _state.geodetic_position_v.getLatitudeDeg();
643 }
644 inline double get_Longitude_deg () const {
645 return _state.geodetic_position_v.getLongitudeDeg();
646 }
647
648 inline double get_Phi() const { return _state.euler_angles_v[0]; }
649 inline double get_Theta() const { return _state.euler_angles_v[1]; }
650 inline double get_Psi() const { return _state.euler_angles_v[2]; }
651 inline double get_Phi_deg () const { return get_Phi() * SGD_RADIANS_TO_DEGREES; }
652 inline double get_Theta_deg () const { return get_Theta() * SGD_RADIANS_TO_DEGREES; }
653 inline double get_Psi_deg () const { return get_Psi() * SGD_RADIANS_TO_DEGREES; }
654
655
656 // ========== Miscellaneous quantities ==========
657
658 inline double get_Alpha() const { return _state.alpha; }
659 inline double get_Alpha_deg() const { return _state.alpha * SGD_RADIANS_TO_DEGREES; }
660 inline double get_Beta() const { return _state.beta; }
661 inline double get_Beta_deg() const { return _state.beta * SGD_RADIANS_TO_DEGREES; }
662 inline double get_Gamma_vert_rad() const { return _state.gamma_vert_rad; }
663
664 inline double get_Density() const { return _state.density; }
665 inline double get_Mach_number() const { return _state.mach_number; }
666
667 inline double get_Static_pressure() const { return _state.static_pressure; }
668 inline double get_Total_pressure() const { return _state.total_pressure; }
669 inline double get_Dynamic_pressure() const { return _state.dynamic_pressure; }
670
671 inline double get_Static_temperature() const { return _state.static_temperature; }
672 inline double get_Total_temperature() const { return _state.total_temperature; }
673
674 inline double get_Sea_level_radius() const { return _state.sea_level_radius; }
675 inline double get_Earth_position_angle() const {
676 return _state.earth_position_angle;
677 }
678
679 inline double get_Runway_altitude() const { return _state.runway_altitude; }
680 inline double get_Runway_altitude_m() const { return SG_FEET_TO_METER * _state.runway_altitude; }
681
682 inline double get_Climb_Rate() const { return _state.climb_rate; }
683
684 // Note that currently this is the "same" value runway altitude...
685 inline double get_ground_elev_ft() const { return _state.runway_altitude; }
686
687
689 // Ground handling routines
691
692 // Prepare the ground cache for the wgs84 position pt_*.
693 // That is take all vertices in the ball with radius rad around the
694 // position given by the pt_* and store them in a local scene graph.
695 bool prepare_ground_cache_m(double startSimTime, double endSimTime,
696 const double pt[3], double rad);
697 bool prepare_ground_cache_ft(double startSimTime, double endSimTime,
698 const double pt[3], double rad);
699
700
701 // Returns true if the cache is valid.
702 // Also the reference time, point and radius values where the cache
703 // is valid for are returned.
704 bool is_valid_m(double *ref_time, double pt[3], double *rad);
705 bool is_valid_ft(double *ref_time, double pt[3], double *rad);
706
707 // Return the nearest catapult to the given point
708 // pt in wgs84 coordinates.
709 double get_cat_m(double t, const double pt[3],
710 double end[2][3], double vel[2][3]);
711 double get_cat_ft(double t, const double pt[3],
712 double end[2][3], double vel[2][3]);
713
714
715 // Return the orientation and position matrix and the linear and angular
716 // velocity of that local coordinate systems origin for a given time and
717 // body id. The velocities are in the wgs84 frame at the bodys origin.
718 bool get_body_m(double t, simgear::BVHNode::Id id, double bodyToWorld[16],
719 double linearVel[3], double angularVel[3]);
720
721
722 // Return the altitude above ground below the wgs84 point pt
723 // Search for the nearest triangle to pt in downward direction.
724 // Return ground properties. The velocities are in the wgs84 frame at the
725 // contact point.
726 bool get_agl_m(double t, const double pt[3], double max_altoff,
727 double contact[3], double normal[3], double linearVel[3],
728 double angularVel[3], simgear::BVHMaterial const*& material,
729 simgear::BVHNode::Id& id);
730 bool get_agl_ft(double t, const double pt[3], double max_altoff,
731 double contact[3], double normal[3], double linearVel[3],
732 double angularVel[3], simgear::BVHMaterial const*& material,
733 simgear::BVHNode::Id& id);
734 double get_groundlevel_m(double lat, double lon, double alt);
735 double get_groundlevel_m(const SGGeod& geod);
736
737
738 // Return the nearest point in any direction to the point pt with a maximum
739 // distance maxDist. The velocities are in the wgs84 frame at the query
740 // position pt.
741 bool get_nearest_m(double t, const double pt[3], double maxDist,
742 double contact[3], double normal[3], double linearVel[3],
743 double angularVel[3], simgear::BVHMaterial const*& material,
744 simgear::BVHNode::Id& id);
745 bool get_nearest_ft(double t, const double pt[3], double maxDist,
746 double contact[3], double normal[3],double linearVel[3],
747 double angularVel[3], simgear::BVHMaterial const*& material,
748 simgear::BVHNode::Id& id);
749
750
751 // Return 1 if the hook intersects with a wire.
752 // That test is done by checking if the quad spanned by the points pt*
753 // intersects with the line representing the wire.
754 // If the wire is caught, the cache will trace this wires endpoints until
755 // the FDM calls release_wire().
756 bool caught_wire_m(double t, const double pt[4][3]);
757 bool caught_wire_ft(double t, const double pt[4][3]);
758
759 // Return the location and speed of the wire endpoints.
760 bool get_wire_ends_m(double t, double end[2][3], double vel[2][3]);
761 bool get_wire_ends_ft(double t, double end[2][3], double vel[2][3]);
762
763 // Tell the cache code that it does no longer need to care for
764 // the wire end position.
765 void release_wire(void);
766
767 // Ground reactions
768 bool updateGroundReactions(simgear::BVHMaterial const*& material) {
769 return _groundReactions.update(material);
770 }
771 inline void setHeading(float h) { _groundReactions.setHeading(h); }
772 inline void setPosition(double pt[3]) {
773 _groundReactions.setPosition(pt);
774 }
775 inline float getPressure() { return _groundReactions.getPressure(); }
776 inline float getBumpiness() { return _groundReactions.getBumpiness(); }
777 inline float getGroundDisplacement() {
778 return _groundReactions.getGroundDisplacement();
779 }
780 inline float getStaticFrictionFactor() {
781 return _groundReactions.getStaticFrictionFactor();
782 }
783 inline float getRolingFrictionFactor() {
784 return _groundReactions.getRolingFrictionFactor();
785 }
786 inline bool getSolid() { return _groundReactions.getSolid(); }
787
788
789 // Manages the AI wake computations.
790 void add_ai_wake(FGAIAircraft* ai) { wake_group.AddAI(ai); }
791 void reset_wake_group(void) { wake_group.gc(); }
792 const AIWakeGroup& get_wake_group(void) { return wake_group; }
793};
794
795#endif // _FLIGHT_HXX
double altitude
Definition ADA.cxx:46
double lat_geoc
Definition ADA.cxx:44
double sea_level_radius
Definition ADA.cxx:52
#define p(x)
#define i(x)
void init() override
Definition flight.cxx:126
void _updatePosition(const SGGeod &geod)
Definition flight.cxx:504
void _set_Altitude(double altitude)
Definition flight.hxx:353
double get_Psi() const
Definition flight.hxx:650
void _set_Mach_number(double m)
Definition flight.hxx:382
double get_V_east_airmass() const
Definition flight.hxx:578
void _set_Geodetic_Position(double lat, double lon)
Definition flight.hxx:359
double get_V_north_airmass() const
Definition flight.hxx:577
const SGGeod & getPosition() const
Definition flight.hxx:624
double get_V_dot_east() const
Definition flight.hxx:534
void set_Theta_dot_degps(double x)
Definition flight.hxx:323
void set_V_ground_speed_kt(double ground_speed)
Definition flight.hxx:591
double get_Lat_geocentric() const
Definition flight.hxx:614
double get_U_dot_body() const
Definition flight.hxx:537
double get_Longitude() const
Definition flight.hxx:631
virtual void set_Static_temperature(double T)
Definition flight.cxx:606
const SGVec3d & getCartPosition() const
Definition flight.hxx:626
double get_V_east() const
Definition flight.hxx:558
void _set_Geodetic_Position(double lat, double lon, double alt)
Definition flight.hxx:362
double get_vBody() const
Definition flight.hxx:561
double get_Latitude() const
Definition flight.hxx:628
void _set_Total_temperature(double tat)
Definition flight.hxx:385
void _update_ground_elev_at_pos(void)
Definition flight.cxx:540
bool getSolid()
Definition flight.hxx:786
virtual ~FGInterface()
Definition flight.cxx:60
void _set_Velocities_Local(double north, double east, double down)
Definition flight.hxx:281
float getStaticFrictionFactor()
Definition flight.hxx:780
bool get_nearest_m(double t, const double pt[3], double maxDist, double contact[3], double normal[3], double linearVel[3], double angularVel[3], simgear::BVHMaterial const *&material, simgear::BVHNode::Id &id)
Definition flight.cxx:795
virtual void set_Psi(double psi)
Definition flight.hxx:497
double get_V_north_rel_ground() const
Definition flight.hxx:566
bool writeState(SGIOChannel *io)
Definition flight.cxx:478
void set_V_east(double east)
Definition flight.hxx:472
void _set_Accels_Pilot_Body(double x, double y, double z)
Definition flight.hxx:270
double get_Phi_dot() const
Definition flight.hxx:601
double get_V_down() const
Definition flight.hxx:559
virtual void set_Latitude_deg(double lat)
Definition flight.hxx:458
virtual void set_Theta_deg(double theta)
Definition flight.hxx:503
float getBumpiness()
Definition flight.hxx:776
virtual void set_Velocities_Body(double u, double v, double w)
Definition flight.cxx:579
bool caught_wire_m(double t, const double pt[4][3])
Definition flight.cxx:895
void _set_Alpha(double a)
Definition flight.hxx:375
bool get_nearest_ft(double t, const double pt[3], double maxDist, double contact[3], double normal[3], double linearVel[3], double angularVel[3], simgear::BVHMaterial const *&material, simgear::BVHNode::Id &id)
Definition flight.cxx:814
virtual void set_Theta(double theta)
Definition flight.hxx:494
void _set_Velocities_Body(double u, double v, double w)
Definition flight.hxx:298
double get_Theta() const
Definition flight.hxx:649
double get_Alpha() const
Definition flight.hxx:658
void _set_Accels_Body(double u, double v, double w)
Definition flight.hxx:260
double get_W_dot_body() const
Definition flight.hxx:539
virtual void set_vBody(double vBody)
Definition flight.hxx:482
float getPressure()
Definition flight.hxx:775
double get_V_calibrated_kts() const
Definition flight.hxx:595
void unbind() override
Unbind any properties bound to this FDM.
Definition flight.cxx:442
void set_inited(bool value)
Definition flight.hxx:439
double get_Psi_deg() const
Definition flight.hxx:653
bool get_agl_ft(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double linearVel[3], double angularVel[3], simgear::BVHMaterial const *&material, simgear::BVHNode::Id &id)
Definition flight.cxx:769
virtual void set_wBody(double wBody)
Definition flight.hxx:485
double get_V_equiv_kts() const
Definition flight.hxx:593
bool get_wire_ends_ft(double t, double end[2][3], double vel[2][3])
Definition flight.cxx:928
void setHeading(float h)
Definition flight.hxx:771
float getGroundDisplacement()
Definition flight.hxx:777
bool is_valid_ft(double *ref_time, double pt[3], double *rad)
Definition flight.cxx:687
double get_V_dot_body() const
Definition flight.hxx:538
double get_V_body() const
Definition flight.hxx:582
double get_Static_temperature() const
Definition flight.hxx:671
double get_V_down_rel_ground() const
Definition flight.hxx:572
double get_V_ground_speed() const
Definition flight.hxx:589
void _set_Earth_position_angle(double a)
Definition flight.hxx:387
double get_V_true_kts() const
Definition flight.hxx:587
virtual void set_Phi_deg(double phi)
Definition flight.hxx:500
void _set_Climb_Rate(double rate)
Definition flight.hxx:389
void _set_CG_Position(double dx, double dy, double dz)
Definition flight.hxx:250
double get_Dz_cg() const
Definition flight.hxx:529
double get_cat_m(double t, const double pt[3], double end[2][3], double vel[2][3])
Definition flight.cxx:698
virtual void property_associations(std::function< void(const std::string &from, const std::string &to)> fn)
Definition flight.cxx:236
virtual void set_Latitude(double lat)
Definition flight.cxx:546
virtual void set_Climb_Rate(double roc)
Definition flight.cxx:597
double get_P_body() const
Definition flight.hxx:597
bool updateGroundReactions(simgear::BVHMaterial const *&material)
Definition flight.hxx:768
void bind() override
Bind getters and setters to properties.
Definition flight.cxx:254
double get_Gamma_vert_rad() const
Definition flight.hxx:662
void _set_Accels_Local(double north, double east, double down)
Definition flight.hxx:255
double get_A_X_cg() const
Definition flight.hxx:541
void set_Phi_dot_degps(double x)
Definition flight.hxx:318
void common_init()
Initialize the state of the FDM.
Definition flight.cxx:137
bool readState(SGIOChannel *io)
Definition flight.cxx:457
double get_Density() const
Definition flight.hxx:664
virtual bool ToggleDataLogging(bool state)
Definition flight.hxx:402
bool prepare_ground_cache_ft(double startSimTime, double endSimTime, const double pt[3], double rad)
Definition flight.cxx:669
virtual void set_Mach_number(double mach)
Definition flight.cxx:567
void _set_Accels_CG_Body_N(double x, double y, double z)
Definition flight.hxx:275
void _set_Runway_altitude(double alt)
Definition flight.hxx:388
double get_cat_ft(double t, const double pt[3], double end[2][3], double vel[2][3])
Definition flight.cxx:711
double get_Track(void) const
Definition flight.hxx:638
void _set_Static_pressure(double sp)
Definition flight.hxx:383
double get_Dynamic_pressure() const
Definition flight.hxx:669
virtual void set_Gamma_vert_rad(double gamma)
Definition flight.cxx:601
void set_V_down(double down)
Definition flight.hxx:475
void _set_Geocentric_Position(double lat, double lon, double rad)
Definition flight.hxx:338
double get_Beta_deg() const
Definition flight.hxx:661
float getRolingFrictionFactor()
Definition flight.hxx:783
const AIWakeGroup & get_wake_group(void)
Definition flight.hxx:792
double get_Longitude_dot() const
Definition flight.hxx:609
double get_Radius_to_vehicle() const
Definition flight.hxx:620
void _set_Velocities_Ground(double north, double east, double down)
Definition flight.hxx:286
void set_Alpha_deg(double a)
Definition flight.hxx:378
bool get_bound() const
Definition flight.hxx:441
double get_Mach_number() const
Definition flight.hxx:665
double get_A_Z_pilot() const
Definition flight.hxx:547
void _set_Static_temperature(double t)
Definition flight.hxx:384
void _set_Omega_Body(double p, double q, double r)
Definition flight.hxx:307
double get_Total_temperature() const
Definition flight.hxx:672
void release_wire(void)
Definition flight.cxx:941
virtual void set_V_calibrated_kts(double vc)
Definition flight.cxx:563
bool prepare_ground_cache_m(double startSimTime, double endSimTime, const double pt[3], double rad)
Definition flight.cxx:661
virtual void set_Phi(double phi)
Definition flight.hxx:491
virtual bool ToggleDataLogging(void)
Definition flight.hxx:403
double get_ground_elev_ft() const
Definition flight.hxx:685
void _set_Beta(double b)
Definition flight.hxx:376
double get_Runway_altitude_m() const
Definition flight.hxx:680
double get_A_Y_cg() const
Definition flight.hxx:542
double get_Theta_dot() const
Definition flight.hxx:602
double get_Beta() const
Definition flight.hxx:660
virtual void set_Altitude(double alt)
Definition flight.cxx:554
double get_Runway_altitude() const
Definition flight.hxx:679
void _set_Geocentric_Rates(double lat, double lon, double rad)
Definition flight.hxx:333
void _set_Nlf(double n)
Definition flight.hxx:280
bool get_agl_m(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double linearVel[3], double angularVel[3], simgear::BVHMaterial const *&material, simgear::BVHNode::Id &id)
Definition flight.cxx:746
double get_Earth_position_angle() const
Definition flight.hxx:675
double get_V_dot_down() const
Definition flight.hxx:535
void _set_Velocities_Local_Airmass(double north, double east, double down)
Definition flight.hxx:291
double get_V_rel_wind() const
Definition flight.hxx:585
virtual void set_Longitude_deg(double lon)
Definition flight.hxx:461
double get_uBody() const
Definition flight.hxx:560
double get_W_body() const
Definition flight.hxx:583
virtual void set_Density(double rho)
Definition flight.cxx:607
double get_Total_pressure() const
Definition flight.hxx:668
double get_Nlf(void) const
Definition flight.hxx:553
double get_Longitude_deg() const
Definition flight.hxx:644
double get_N_Z_cg() const
Definition flight.hxx:551
double get_Latitude_dot() const
Definition flight.hxx:608
bool is_valid_m(double *ref_time, double pt[3], double *rad)
Definition flight.cxx:679
double get_Phi() const
Definition flight.hxx:648
void _set_Accels_CG_Body(double x, double y, double z)
Definition flight.hxx:265
void _set_V_calibrated_kts(double kts)
Definition flight.hxx:306
double get_Path(void) const
Definition flight.hxx:639
double get_Latitude_deg() const
Definition flight.hxx:641
const SGGeoc & getGeocPosition() const
Definition flight.hxx:625
double get_V_north() const
Definition flight.hxx:557
void _setup()
Set default values for the state of the FDM.
Definition flight.cxx:85
bool get_wire_ends_m(double t, double end[2][3], double vel[2][3])
Definition flight.cxx:916
double get_A_X_pilot() const
Definition flight.hxx:545
void _set_Sea_level_radius(double r)
Definition flight.hxx:386
void _updateGeocentricPosition(double lat_geoc, double lon, double alt)
Definition flight.cxx:534
double get_V_dot_north() const
Definition flight.hxx:533
double get_A_Y_pilot() const
Definition flight.hxx:546
double get_Altitude() const
Definition flight.hxx:634
void _set_V_rel_wind(double vt)
Definition flight.hxx:303
void _updatePositionFt(const SGVec3d &cartPos)
Definition flight.hxx:240
void setPosition(double pt[3])
Definition flight.hxx:772
double get_A_Z_cg() const
Definition flight.hxx:543
void set_V_north(double north)
Definition flight.hxx:469
virtual void set_Static_pressure(double p)
Definition flight.cxx:605
bool caught_wire_ft(double t, const double pt[4][3])
Definition flight.cxx:905
void _set_Altitude_AGL(double agl)
Definition flight.hxx:356
virtual void set_Psi_deg(double psi)
Definition flight.hxx:506
void _set_T_Local_to_Body(int i, int j, double value)
Definition flight.hxx:374
virtual void set_Euler_Angles(double phi, double theta, double psi)
Definition flight.cxx:588
double get_N_X_cg() const
Definition flight.hxx:549
void update(double dt) override
Update the state of the FDM (i.e.
Definition flight.cxx:452
bool get_body_m(double t, simgear::BVHNode::Id id, double bodyToWorld[16], double linearVel[3], double angularVel[3])
Definition flight.cxx:726
void _updateGeodeticPosition(double lat, double lon, double alt)
Definition flight.cxx:528
double get_Psi_dot_degps() const
Definition flight.hxx:606
void _set_Euler_Rates(double phi, double theta, double psi)
Definition flight.hxx:312
double get_V_east_rel_ground() const
Definition flight.hxx:569
double get_N_Y_cg() const
Definition flight.hxx:550
double get_Phi_dot_degps() const
Definition flight.hxx:604
double get_Static_pressure() const
Definition flight.hxx:667
void _set_V_equiv_kts(double kts)
Definition flight.hxx:305
void _updatePositionM(const SGVec3d &cartPos)
Definition flight.cxx:493
int _calc_multiloop(double dt)
Definition flight.cxx:65
void add_ai_wake(FGAIAircraft *ai)
Definition flight.hxx:790
double get_Sea_level_radius() const
Definition flight.hxx:674
void reset_wake_group(void)
Definition flight.hxx:791
double get_Alpha_deg() const
Definition flight.hxx:659
void _set_V_ground_speed(double v)
Definition flight.hxx:304
void _set_Gamma_vert_rad(double gv)
Definition flight.hxx:380
virtual void set_uBody(double uBody)
Definition flight.hxx:479
virtual void set_Longitude(double lon)
Definition flight.cxx:550
double get_groundlevel_m(double lat, double lon, double alt)
Definition flight.cxx:834
double get_V_ground_speed_kt() const
Definition flight.hxx:590
double get_Lon_geocentric() const
Definition flight.hxx:617
double get_Climb_Rate() const
Definition flight.hxx:682
void _busdump(void)
Definition flight.cxx:618
virtual void set_Velocities_Local(double north, double east, double down)
Definition flight.cxx:571
double get_Radius_dot() const
Definition flight.hxx:610
double get_Altitude_AGL(void) const
Definition flight.hxx:637
double get_Q_body() const
Definition flight.hxx:598
virtual void set_Velocities_Local_Airmass(double wnorth, double weast, double wdown)
Definition flight.cxx:609
double get_Theta_dot_degps() const
Definition flight.hxx:605
virtual void set_AltitudeAGL(double altagl)
Definition flight.cxx:558
void _set_Euler_Angles(double phi, double theta, double psi)
Definition flight.hxx:368
double get_Phi_deg() const
Definition flight.hxx:651
double get_Psi_dot() const
Definition flight.hxx:603
void _set_Density(double d)
Definition flight.hxx:381
double get_Dx_cg() const
Definition flight.hxx:527
double get_wBody() const
Definition flight.hxx:562
double get_U_body() const
Definition flight.hxx:581
double get_V_down_airmass() const
Definition flight.hxx:579
double get_Dy_cg() const
Definition flight.hxx:528
bool get_inited() const
Definition flight.hxx:438
double get_R_body() const
Definition flight.hxx:599
void set_Psi_dot_degps(double x)
Definition flight.hxx:328
double get_Theta_deg() const
Definition flight.hxx:652
A little helper class to update the track if the position has changed.
Definition flight.hxx:105
TrackComputer(double &track, double &path, const SGGeod &position)
Definition flight.hxx:107