6
6
Purpose: Integrate the EOM to determine instantaneous position
9
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
9
------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
11
11
This program is free software; you can redistribute it and/or modify it under
12
12
the terms of the GNU Lesser General Public License as published by the Free Software
82
85
last_vPQRdot.InitMatrix();
83
86
vPQRdot.InitMatrix();
88
last2_vQtrndot = FGQuaternion(0,0,0);
89
last_vQtrndot = FGQuaternion(0,0,0);
90
vQtrndot = FGQuaternion(0,0,0);
85
92
last2_vUVWdot.InitMatrix();
86
93
last_vUVWdot.InitMatrix();
87
94
vUVWdot.InitMatrix();
93
100
vOmegaLocal.InitMatrix();
95
102
integrator_rotational_rate = eAdamsBashforth2;
96
integrator_translational_rate = eAdamsBashforth2;
97
integrator_rotational_position = eTrapezoidal;
103
integrator_translational_rate = eTrapezoidal;
104
integrator_rotational_position = eAdamsBashforth2;
98
105
integrator_translational_position = eTrapezoidal;
115
122
if (!FGModel::InitModel()) return false;
117
SeaLevelRadius = Inertial->GetRefRadius(); // For initialization ONLY
118
RunwayRadius = SeaLevelRadius;
124
// For initialization ONLY:
125
SeaLevelRadius = LocalTerrainRadius = Inertial->GetRefRadius();
120
VState.vLocation.SetRadius( SeaLevelRadius + 4.0 ); // Todo Add terrain elevation?
127
VState.vLocation.SetRadius( LocalTerrainRadius + 4.0 );
121
128
VState.vLocation.SetEllipse(Inertial->GetSemimajor(), Inertial->GetSemiminor());
122
129
vOmega = FGColumnVector3( 0.0, 0.0, Inertial->omega() ); // Earth rotation vector
125
132
last_vPQRdot.InitMatrix();
126
133
vPQRdot.InitMatrix();
135
last2_vQtrndot = FGQuaternion(0,0,0);
136
last_vQtrndot = FGQuaternion(0,0,0);
137
vQtrndot = FGQuaternion(0,0,0);
128
139
last2_vUVWdot.InitMatrix();
129
140
last_vUVWdot.InitMatrix();
130
141
vUVWdot.InitMatrix();
136
147
vOmegaLocal.InitMatrix();
138
149
integrator_rotational_rate = eAdamsBashforth2;
139
integrator_translational_rate = eAdamsBashforth2;
140
integrator_rotational_position = eTrapezoidal;
150
integrator_translational_rate = eTrapezoidal;
151
integrator_rotational_position = eAdamsBashforth2;
141
152
integrator_translational_position = eTrapezoidal;
148
159
void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
150
SeaLevelRadius = FGIC->GetSeaLevelRadiusFtIC();
151
RunwayRadius = SeaLevelRadius;
161
SetSeaLevelRadius(FGIC->GetSeaLevelRadiusFtIC());
162
SetTerrainElevation(FGIC->GetTerrainElevationFtIC());
153
164
// Set the position lat/lon/radius
154
165
VState.vLocation.SetPosition( FGIC->GetLongitudeRadIC(),
155
166
FGIC->GetLatitudeRadIC(),
156
FGIC->GetAltitudeFtIC() + FGIC->GetSeaLevelRadiusFtIC() );
167
FGIC->GetAltitudeASLFtIC() + FGIC->GetSeaLevelRadiusFtIC() );
158
169
VehicleRadius = GetRadius();
159
170
radInv = 1.0/VehicleRadius;
179
190
// Finally, make sure that the quaternion stays normalized.
180
191
VState.vQtrn.Normalize();
182
// Recompute the RunwayRadius level.
183
RecomputeRunwayRadius();
193
// Recompute the LocalTerrainRadius.
194
RecomputeLocalTerrainRadius();
196
// These local copies of the transformation matrices are for use for
197
// initial conditions only.
199
Tl2b = GetTl2b(); // local to body frame transform
200
Tb2l = Tl2b.Transposed(); // body to local frame transform
201
Tl2ec = GetTl2ec(); // local to ECEF transform
202
Tec2l = Tl2ec.Transposed(); // ECEF to local frame transform
203
Tec2b = Tl2b * Tec2l; // ECEF to body frame transform
204
Tb2ec = Tec2b.Transposed(); // body to ECEF frame tranform
205
Ti2ec = GetTi2ec(); // ECI to ECEF transform
206
Tec2i = Ti2ec.Transposed(); // ECEF to ECI frame transform
207
Ti2b = Tec2b*Ti2ec; // ECI to body frame transform
208
Tb2i = Ti2b.Transposed(); // body to ECI frame transform
186
211
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208
233
if (FGModel::Run()) return true; // Fast return if we have nothing to do ...
209
234
if (FDMExec->Holding()) return false;
211
RecomputeRunwayRadius();
238
RecomputeLocalTerrainRadius();
213
240
// Calculate current aircraft radius from center of planet
417
446
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
419
void FGPropagate::RecomputeRunwayRadius(void)
448
void FGPropagate::RecomputeLocalTerrainRadius(void)
421
// Get the runway radius.
450
double t = State->Getsim_time();
452
// Get the LocalTerrain radius.
422
453
FGLocation contactloc;
423
454
FGColumnVector3 dv;
424
FGGroundCallback* gcb = FDMExec->GetGroundCallback();
425
double t = State->Getsim_time();
426
gcb->GetAGLevel(t, VState.vLocation, contactloc, dv, dv);
427
RunwayRadius = contactloc.GetRadius();
455
FDMExec->GetGroundCallback()->GetAGLevel(t, VState.vLocation, contactloc, dv, dv);
456
LocalTerrainRadius = contactloc.GetRadius();
430
459
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432
void FGPropagate::SetTerrainElevationASL(double tt)
461
void FGPropagate::SetTerrainElevation(double terrainElev)
434
FDMExec->GetGroundCallback()->SetTerrainGeoCentRadius(tt+SeaLevelRadius);
463
LocalTerrainRadius = terrainElev + SeaLevelRadius;
464
FDMExec->GetGroundCallback()->SetTerrainGeoCentRadius(LocalTerrainRadius);
437
467
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439
double FGPropagate::GetTerrainElevationASL(void) const
469
double FGPropagate::GetTerrainElevation(void) const
441
471
return FDMExec->GetGroundCallback()->GetTerrainGeoCentRadius()-SeaLevelRadius;
458
488
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
460
void FGPropagate::Seth(double tt)
490
void FGPropagate::SetAltitudeASL(double altASL)
462
VState.vLocation.SetRadius( tt + SeaLevelRadius );
492
VState.vLocation.SetRadius( altASL + SeaLevelRadius );
465
495
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
467
double FGPropagate::GetRunwayRadius(void) const
497
double FGPropagate::GetLocalTerrainRadius(void) const
499
return LocalTerrainRadius;
472
502
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474
504
double FGPropagate::GetDistanceAGL(void) const
476
return VState.vLocation.GetRadius() - RunwayRadius;
506
return VState.vLocation.GetRadius() - LocalTerrainRadius;
479
509
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481
511
void FGPropagate::SetDistanceAGL(double tt)
483
VState.vLocation.SetRadius( tt + RunwayRadius );
513
VState.vLocation.SetRadius( tt + LocalTerrainRadius );
486
516
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503
533
PropertyManager->Tie("velocities/q-rad_sec", this, eQ, (PMF)&FGPropagate::GetPQR);
504
534
PropertyManager->Tie("velocities/r-rad_sec", this, eR, (PMF)&FGPropagate::GetPQR);
536
PropertyManager->Tie("velocities/pi-rad_sec", this, eP, (PMF)&FGPropagate::GetPQRi);
537
PropertyManager->Tie("velocities/qi-rad_sec", this, eQ, (PMF)&FGPropagate::GetPQRi);
538
PropertyManager->Tie("velocities/ri-rad_sec", this, eR, (PMF)&FGPropagate::GetPQRi);
506
540
PropertyManager->Tie("velocities/eci-velocity-mag-fps", this, &FGPropagate::GetInertialVelocityMagnitude);
508
542
PropertyManager->Tie("accelerations/pdot-rad_sec2", this, eP, (PMF)&FGPropagate::GetPQRdot);
513
547
PropertyManager->Tie("accelerations/vdot-ft_sec2", this, eV, (PMF)&FGPropagate::GetUVWdot);
514
548
PropertyManager->Tie("accelerations/wdot-ft_sec2", this, eW, (PMF)&FGPropagate::GetUVWdot);
516
PropertyManager->Tie("position/h-sl-ft", this, &FGPropagate::Geth, &FGPropagate::Seth, true);
517
PropertyManager->Tie("position/h-sl-meters", this, &FGPropagate::Gethmeters, &FGPropagate::Sethmeters, true);
550
PropertyManager->Tie("position/h-sl-ft", this, &FGPropagate::GetAltitudeASL, &FGPropagate::SetAltitudeASL, true);
551
PropertyManager->Tie("position/h-sl-meters", this, &FGPropagate::GetAltitudeASLmeters, &FGPropagate::SetAltitudeASLmeters, true);
518
552
PropertyManager->Tie("position/lat-gc-rad", this, &FGPropagate::GetLatitude, &FGPropagate::SetLatitude);
519
553
PropertyManager->Tie("position/long-gc-rad", this, &FGPropagate::GetLongitude, &FGPropagate::SetLongitude);
520
554
PropertyManager->Tie("position/lat-gc-deg", this, &FGPropagate::GetLatitudeDeg, &FGPropagate::SetLatitudeDeg);
525
559
PropertyManager->Tie("position/h-agl-ft", this, &FGPropagate::GetDistanceAGL, &FGPropagate::SetDistanceAGL);
526
560
PropertyManager->Tie("position/radius-to-vehicle-ft", this, &FGPropagate::GetRadius);
527
561
PropertyManager->Tie("position/terrain-elevation-asl-ft", this,
528
&FGPropagate::GetTerrainElevationASL,
529
&FGPropagate::SetTerrainElevationASL, false);
562
&FGPropagate::GetTerrainElevation,
563
&FGPropagate::SetTerrainElevation, false);
531
PropertyManager->Tie("metrics/runway-radius", this, &FGPropagate::GetRunwayRadius);
565
PropertyManager->Tie("metrics/terrain-radius", this, &FGPropagate::GetLocalTerrainRadius);
533
567
PropertyManager->Tie("attitude/phi-rad", this, (int)ePhi, (PMF)&FGPropagate::GetEuler);
534
568
PropertyManager->Tie("attitude/theta-rad", this, (int)eTht, (PMF)&FGPropagate::GetEuler);