68#include "FGPropagate.h"
69#include "initialization/FGInitialCondition.h"
71#include "simgear/io/iostreams/sgstream.hxx"
72#include "FGInertial.h"
73#include "input_output/FGLog.h"
91 integrator_rotational_rate = eRectEuler;
92 integrator_translational_rate = eAdamsBashforth2;
93 integrator_rotational_position = eRectEuler;
94 integrator_translational_position = eAdamsBashforth3;
118 if (!FGModel::InitModel())
return false;
122 Inertial->SetAltitudeAGL(VState.
vLocation, 4.0);
129 integrator_rotational_rate = eRectEuler;
130 integrator_translational_rate = eAdamsBashforth2;
131 integrator_rotational_position = eRectEuler;
132 integrator_translational_position = eAdamsBashforth3;
149 Ti2ec = { cos(epa), sin(epa), 0.0,
150 -sin(epa), cos(epa), 0.0,
154 VState.vInertialPosition = Tec2i * VState.
vLocation;
156 UpdateLocationMatrices();
164 UpdateBodyMatrices();
170 vVel = Tb2l * VState.
vUVW;
173 RecomputeLocalTerrainVelocity();
179 VState.
vPQRi = VState.
vPQR + Ti2b * in.vOmegaPlanet;
181 CalculateInertialVelocity();
188void FGPropagate::InitializeDerivatives()
190 VState.dqPQRidot.assign(5, in.vPQRidot);
191 VState.dqUVWidot.assign(5, in.vUVWidot);
192 VState.dqInertialVelocity.assign(5, VState.vInertialVelocity);
193 VState.dqQtrndot.assign(5, VState.vQtrndot);
219 if (Holding)
return false;
221 double dt = in.DeltaT * rate;
226 Integrate(VState.
qAttitudeECI, VState.vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position);
227 Integrate(VState.
vPQRi, in.vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate);
228 Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
229 Integrate(VState.vInertialVelocity, in.vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate);
237 epa += in.vOmegaPlanet(eZ)*dt;
240 double cos_epa = cos(epa);
241 double sin_epa = sin(epa);
242 Ti2ec = { cos_epa, sin_epa, 0.0,
243 -sin_epa, cos_epa, 0.0,
248 VState.
vLocation = Ti2ec*VState.vInertialPosition;
252 UpdateLocationMatrices();
256 UpdateBodyMatrices();
263 RecomputeLocalTerrainVelocity();
265 VState.
vPQR = VState.
vPQRi - Ti2b * in.vOmegaPlanet;
274 vVel = Tb2l * VState.
vUVW;
277 ComputeOrbitalParameters();
288 VState.
vUVW.InitMatrix();
289 CalculateInertialVelocity();
290 VState.
vPQR.InitMatrix();
291 VState.
vPQRi = Ti2b * in.vOmegaPlanet;
293 InitializeDerivatives();
304void FGPropagate::CalculateQuatdot(
void)
317void FGPropagate::CalculateInertialVelocity(
void)
319 VState.vInertialVelocity = Tb2i * VState.
vUVW + (in.vOmegaPlanet * VState.vInertialPosition);
327void FGPropagate::CalculateUVW(
void)
329 VState.
vUVW = Ti2b * (VState.vInertialVelocity - (in.vOmegaPlanet * VState.vInertialPosition));
334void FGPropagate::Integrate( FGColumnVector3& Integrand,
335 FGColumnVector3& Val,
336 deque <FGColumnVector3>& ValDot,
338 eIntegrateType integration_type)
340 ValDot.push_front(Val);
343 switch(integration_type) {
344 case eRectEuler: Integrand += dt*ValDot[0];
346 case eTrapezoidal: Integrand += 0.5*dt*(ValDot[0] + ValDot[1]);
348 case eAdamsBashforth2: Integrand += dt*(1.5*ValDot[0] - 0.5*ValDot[1]);
350 case eAdamsBashforth3: Integrand += (1/12.0)*dt*(23.0*ValDot[0] - 16.0*ValDot[1] + 5.0*ValDot[2]);
352 case eAdamsBashforth4: Integrand += (1/24.0)*dt*(55.0*ValDot[0] - 59.0*ValDot[1] + 37.0*ValDot[2] - 9.0*ValDot[3]);
354 case eAdamsBashforth5: Integrand += dt*((1901./720.)*ValDot[0] - (1387./360.)*ValDot[1] + (109./30.)*ValDot[2] - (637./360.)*ValDot[3] + (251./720.)*ValDot[4]);
360 case eLocalLinearization:
363 err <<
"Can only use Buss (1 & 2) or local linearization integration methods in for rotational position!";
373void FGPropagate::Integrate( FGQuaternion& Integrand,
375 deque <FGQuaternion>& ValDot,
377 eIntegrateType integration_type)
379 ValDot.push_front(Val);
382 switch(integration_type) {
383 case eRectEuler: Integrand += dt*ValDot[0];
385 case eTrapezoidal: Integrand += 0.5*dt*(ValDot[0] + ValDot[1]);
387 case eAdamsBashforth2: Integrand += dt*(1.5*ValDot[0] - 0.5*ValDot[1]);
389 case eAdamsBashforth3: Integrand += (1/12.0)*dt*(23.0*ValDot[0] - 16.0*ValDot[1] + 5.0*ValDot[2]);
391 case eAdamsBashforth4: Integrand += (1/24.0)*dt*(55.0*ValDot[0] - 59.0*ValDot[1] + 37.0*ValDot[2] - 9.0*ValDot[3]);
393 case eAdamsBashforth5: Integrand += dt*((1901./720.)*ValDot[0] - (1387./360.)*ValDot[1] + (109./30.)*ValDot[2] - (637./360.)*ValDot[3] + (251./720.)*ValDot[4]);
401 Integrand = Integrand *
QExp(0.5 * dt * VState.
vPQRi);
409 FGColumnVector3 wi = VState.
vPQRi;
410 FGColumnVector3 wdoti = in.vPQRidot;
411 FGColumnVector3 omega = wi + 0.5*dt*wdoti + dt*dt/12.*wdoti*wi;
412 Integrand = Integrand *
QExp(0.5 * dt * omega);
415 case eLocalLinearization:
421 FGColumnVector3 wi = 0.5 * VState.
vPQRi;
422 FGColumnVector3 wdoti = 0.5 * in.vPQRidot;
424 double omegak = omegak2 > 1E-6 ? sqrt(omegak2) : 1E-6;
425 double rhok = 0.5 * dt * omegak;
426 double C1 = cos(rhok);
427 double C2 = 2.0 * sin(rhok) / omegak;
428 double C3 = 4.0 * (1.0 - C1) / (omegak*omegak);
429 double C4 = 4.0 * (dt - C2) / (omegak*omegak);
430 FGColumnVector3 Omega = C2*wi + C3*wdoti + C4*wi*wdoti;
438 Integrand = Integrand * q;
473 Integrand.Normalize();
478void FGPropagate::UpdateLocationMatrices(
void)
482 Ti2l = Tec2l * Ti2ec;
488void FGPropagate::UpdateBodyMatrices(
void)
494 Tec2b = Ti2b * Tec2i;
502void FGPropagate::ComputeOrbitalParameters(
void)
504 const FGColumnVector3 Z{0., 0., 1.};
505 FGColumnVector3 R = VState.vInertialPosition;
506 FGColumnVector3 angularMomentum = R * VState.vInertialVelocity;
507 h = angularMomentum.Magnitude();
508 Inclination = acos(angularMomentum(eZ)/h)*radtodeg;
510 if (abs(Inclination) > 1E-8) {
511 N = Z * angularMomentum;
512 RightAscension = atan2(N(eY), N(eX))*radtodeg;
516 RightAscension = 0.0;
518 PerigeeArgument = 0.0;
521 double vr =
DotProduct(R, VState.vInertialVelocity);
522 FGColumnVector3 eVector = (VState.vInertialVelocity*angularMomentum/in.GM - R);
523 Eccentricity = eVector.Magnitude();
524 if (Eccentricity > 1E-8) {
525 eVector /= Eccentricity;
526 if (abs(Inclination) > 1E-8) {
527 PerigeeArgument = acos(
DotProduct(N, eVector)) * radtodeg;
528 if (eVector(eZ) < 0) PerigeeArgument = 360. - PerigeeArgument;
533 eVector = {1., 0., 0.};
534 PerigeeArgument = 0.0;
538 if (vr < 0.0) TrueAnomaly = 360. - TrueAnomaly;
539 ApoapsisRadius = h*h / (in.GM * (1-Eccentricity));
540 PeriapsisRadius = h*h / (in.GM * (1+Eccentricity));
542 if (Eccentricity < 1.0) {
543 double semimajor = 0.5*(ApoapsisRadius + PeriapsisRadius);
544 OrbitalPeriod = 2.*M_PI*pow(semimajor, 1.5)/sqrt(in.GM);
552void FGPropagate::SetInertialOrientation(
const FGQuaternion& Qi)
556 UpdateBodyMatrices();
563void FGPropagate::SetInertialVelocity(
const FGColumnVector3& Vi) {
564 VState.vInertialVelocity = Vi;
566 vVel = Tb2l * VState.
vUVW;
571void FGPropagate::SetInertialRates(
const FGColumnVector3& vRates) {
572 VState.
vPQRi = Ti2b * vRates;
573 VState.
vPQR = VState.
vPQRi - Ti2b * in.vOmegaPlanet;
586void FGPropagate::SetAltitudeASL(
double altASL)
590 UpdateVehicleState();
595void FGPropagate::RecomputeLocalTerrainVelocity()
598 FGColumnVector3 normal;
599 Inertial->GetContactPoint(VState.
vLocation, contact, normal,
600 LocalTerrainVelocity, LocalTerrainAngularVelocity);
605double FGPropagate::GetTerrainElevation(
void)
const
607 FGColumnVector3 vDummy;
609 contact.SetEllipse(in.SemiMajor, in.SemiMinor);
610 Inertial->GetContactPoint(VState.
vLocation, contact, vDummy, vDummy, vDummy);
611 return contact.GetGeodAltitude();
616void FGPropagate::SetTerrainElevation(
double terrainElev)
618 Inertial->SetTerrainElevation(terrainElev);
627 Inertial->GetContactPoint(VState.
vLocation, contact, vDummy, vDummy, vDummy);
633double FGPropagate::GetDistanceAGL(
void)
const
635 return Inertial->GetAltitudeAGL(VState.
vLocation);
640double FGPropagate::GetDistanceAGLKm(
void)
const
642 return GetDistanceAGL()*0.0003048;
647void FGPropagate::SetDistanceAGL(
double tt)
649 Inertial->SetAltitudeAGL(VState.
vLocation, tt);
650 UpdateVehicleState();
655void FGPropagate::SetDistanceAGLKm(
double tt)
657 SetDistanceAGL(tt*3280.8399);
662void FGPropagate::SetVState(
const VehicleState& vstate)
666 UpdateLocationMatrices();
667 SetInertialOrientation(vstate.qAttitudeECI);
668 RecomputeLocalTerrainVelocity();
669 VState.
vUVW = vstate.vUVW;
670 vVel = Tb2l * VState.
vUVW;
671 VState.
vPQR = vstate.vPQR;
672 VState.
vPQRi = VState.
vPQR + Ti2b * in.vOmegaPlanet;
673 VState.vInertialPosition = vstate.vInertialPosition;
679void FGPropagate::UpdateVehicleState(
void)
681 RecomputeLocalTerrainVelocity();
682 VState.vInertialPosition = Tec2i * VState.
vLocation;
683 UpdateLocationMatrices();
684 UpdateBodyMatrices();
685 vVel = Tb2l * VState.
vUVW;
691void FGPropagate::SetLocation(
const FGLocation& l)
694 UpdateVehicleState();
706void FGPropagate::DumpState(
void)
710 out << LogFormat::BLUE
711 <<
"------------------------------------------------------------------" << LogFormat::RESET <<
"\n";
712 out << LogFormat::BOLD << fixed
713 <<
"State Report at sim time: " << FDMExec->
GetSimTime() <<
" seconds" << LogFormat::RESET <<
"\n";
714 out <<
" " << LogFormat::UNDERLINE_ON
715 <<
"Position" << LogFormat::UNDERLINE_OFF <<
"\n";
716 out <<
" ECI: " << VState.vInertialPosition.
Dump(
", ") <<
" (x,y,z, in ft)\n";
717 out <<
" ECEF: " << VState.
vLocation <<
" (x,y,z, in ft)\n";
720 <<
", " <<
GetAltitudeASL() <<
" (geodetic lat, lon, alt ASL in deg and ft)\n";
722 out <<
"\n " << LogFormat::UNDERLINE_ON
723 <<
"Orientation" << LogFormat::UNDERLINE_OFF <<
"\n";
727 out <<
"\n " << LogFormat::UNDERLINE_ON
728 <<
"Velocity" << LogFormat::UNDERLINE_OFF <<
"\n";
729 out <<
" ECI: " << VState.vInertialVelocity.
Dump(
", ") <<
" (x,y,z in ft/s)\n";
731 out <<
" Local: " <<
GetVel() <<
" (n,e,d in ft/sec)\n";
732 out <<
" Body: " <<
GetUVW() <<
" (u,v,w in ft/sec)\n";
734 out <<
"\n" <<
" " << LogFormat::UNDERLINE_ON
735 <<
"Body Rates (relative to given frame, expressed in body frame)" << LogFormat::UNDERLINE_OFF <<
"\n";
736 out <<
" ECI: " << (VState.
vPQRi * radtodeg).Dump(
", ") <<
" (p,q,r in deg/s)" <<
"\n";
737 out <<
" ECEF: " << (VState.
vPQR * radtodeg).Dump(
", ") <<
" (p,q,r in deg/s)" <<
"\n";
742void FGPropagate::WriteStateFile(
int num)
746 if (num == 0)
return;
750 if (path.isNull()) path = SGPath(
"initfile.");
751 else path.append(
"initfile.");
754 path.concat(to_string((
double)FDMExec->
GetSimTime())+
".xml");
759 if (outfile.is_open()) {
760 outfile <<
"<?xml version=\"1.0\"?>\n";
761 outfile <<
"<initialize name=\"reset00\">\n";
762 outfile <<
" <ubody unit=\"FT/SEC\"> " << VState.
vUVW(eU) <<
" </ubody> \n";
763 outfile <<
" <vbody unit=\"FT/SEC\"> " << VState.
vUVW(eV) <<
" </vbody> \n";
764 outfile <<
" <wbody unit=\"FT/SEC\"> " << VState.
vUVW(eW) <<
" </wbody> \n";
770 outfile <<
" <altitude unit=\"FT\"> " << GetDistanceAGL() <<
" </altitude>\n";
771 outfile <<
"</initialize>\n";
774 FGLogging log(LogLevel::ERROR);
775 log <<
"Could not open and/or write the state to the initial conditions file: "
781 if (outfile.is_open()) {
782 outfile <<
"<?xml version=\"1.0\"?>\n";
783 outfile <<
"<initialize name=\"IC File\" version=\"2.0\">\n";
785 outfile <<
" <position frame=\"ECEF\">\n";
788 outfile <<
" <altitudeMSL unit=\"FT\"> " <<
GetAltitudeASL() <<
" </altitudeMSL>\n";
789 outfile <<
" </position>\n";
791 outfile <<
" <orientation unit=\"DEG\" frame=\"LOCAL\">\n";
795 outfile <<
" </orientation>\n";
797 outfile <<
" <velocity unit=\"FT/SEC\" frame=\"LOCAL\">\n";
798 outfile <<
" <x> " <<
GetVel(eNorth) <<
" </x>\n";
799 outfile <<
" <y> " <<
GetVel(eEast) <<
" </y>\n";
800 outfile <<
" <z> " <<
GetVel(eDown) <<
" </z>\n";
801 outfile <<
" </velocity>\n";
803 outfile <<
" <attitude_rate unit=\"DEG/SEC\" frame=\"BODY\">\n";
804 outfile <<
" <roll> " << (VState.
vPQR*radtodeg)(eRoll) <<
" </roll>\n";
805 outfile <<
" <pitch> " << (VState.
vPQR*radtodeg)(ePitch) <<
" </pitch>\n";
806 outfile <<
" <yaw> " << (VState.
vPQR*radtodeg)(eYaw) <<
" </yaw>\n";
807 outfile <<
" </attitude_rate>\n";
809 outfile <<
"</initialize>\n";
812 FGLogging log(LogLevel::ERROR);
813 log <<
"Could not open and/or write the state to the initial conditions file: "
818 FGLogging log(LogLevel::ERROR);
819 log <<
"When writing a state file, the supplied value must be 1 or 2 for the version number of the resulting IC file\n";
825void FGPropagate::bind(
void)
857 &FGPropagate::SetAltitudeASL);
859 &FGPropagate::SetAltitudeASLmeters);
860 PropertyManager->Tie(
"position/lat-gc-rad",
this, &FGPropagate::GetLatitude,
861 &FGPropagate::SetLatitude);
862 PropertyManager->Tie(
"position/long-gc-rad",
this, &FGPropagate::GetLongitude,
863 &FGPropagate::SetLongitude);
864 PropertyManager->Tie(
"position/lat-gc-deg",
this, &FGPropagate::GetLatitudeDeg,
865 &FGPropagate::SetLatitudeDeg);
866 PropertyManager->Tie(
"position/long-gc-deg",
this, &FGPropagate::GetLongitudeDeg,
867 &FGPropagate::SetLongitudeDeg);
868 PropertyManager->Tie(
"position/lat-geod-rad",
this, &FGPropagate::GetGeodLatitudeRad);
869 PropertyManager->Tie(
"position/lat-geod-deg",
this, &FGPropagate::GetGeodLatitudeDeg);
870 PropertyManager->Tie(
"position/geod-alt-ft",
this, &FGPropagate::GetGeodeticAltitude);
871 PropertyManager->Tie(
"position/h-agl-ft",
this, &FGPropagate::GetDistanceAGL,
872 &FGPropagate::SetDistanceAGL);
873 PropertyManager->Tie(
"position/geod-alt-km",
this, &FGPropagate::GetGeodeticAltitudeKm);
874 PropertyManager->Tie(
"position/h-agl-km",
this, &FGPropagate::GetDistanceAGLKm,
875 &FGPropagate::SetDistanceAGLKm);
876 PropertyManager->Tie(
"position/radius-to-vehicle-ft",
this, &FGPropagate::GetRadius);
877 PropertyManager->Tie(
"position/terrain-elevation-asl-ft",
this, &FGPropagate::GetTerrainElevation,
878 &FGPropagate::SetTerrainElevation);
884 PropertyManager->Tie(
"position/ecef-x-ft",
this, eX, &FGPropagate::GetLocation);
885 PropertyManager->Tie(
"position/ecef-y-ft",
this, eY, &FGPropagate::GetLocation);
886 PropertyManager->Tie(
"position/ecef-z-ft",
this, eZ, &FGPropagate::GetLocation);
903 PropertyManager->Tie(
"orbital/specific-angular-momentum-ft2_sec", &h);
904 PropertyManager->Tie(
"orbital/inclination-deg", &Inclination);
905 PropertyManager->Tie(
"orbital/right-ascension-deg", &RightAscension);
906 PropertyManager->Tie(
"orbital/eccentricity", &Eccentricity);
907 PropertyManager->Tie(
"orbital/argument-of-perigee-deg", &PerigeeArgument);
908 PropertyManager->Tie(
"orbital/true-anomaly-deg", &TrueAnomaly);
909 PropertyManager->Tie(
"orbital/apoapsis-radius-ft", &ApoapsisRadius);
910 PropertyManager->Tie(
"orbital/periapsis-radius-ft", &PeriapsisRadius);
911 PropertyManager->Tie(
"orbital/period-sec", &OrbitalPeriod);
913 PropertyManager->Tie(
"simulation/integrator/rate/rotational", (
int*)&integrator_rotational_rate);
914 PropertyManager->Tie(
"simulation/integrator/rate/translational", (
int*)&integrator_translational_rate);
915 PropertyManager->Tie(
"simulation/integrator/position/rotational", (
int*)&integrator_rotational_position);
916 PropertyManager->Tie(
"simulation/integrator/position/translational", (
int*)&integrator_translational_position);
918 PropertyManager->Tie<
FGPropagate,
int>(
"simulation/write-state-file",
this,
919 nullptr, &FGPropagate::WriteStateFile);
941void FGPropagate::Debug(
int from)
943 if (debug_lvl <= 0)
return;
950 if (debug_lvl & 2 ) {
951 FGLogging log(LogLevel::DEBUG);
952 if (from == 0) log <<
"Instantiated: FGPropagate\n";
953 if (from == 1) log <<
"Destroyed: FGPropagate\n";
955 if (debug_lvl & 4 ) {
957 if (debug_lvl & 8 && from == 2) {
958 FGLogging log(LogLevel::DEBUG);
959 log <<
"\n" << LogFormat::BLUE << LogFormat::BOLD << left << fixed
960 <<
" Propagation Report (English units: ft, degrees) at simulation time " << FDMExec->
GetSimTime() <<
" seconds"
961 << LogFormat::RESET <<
"\n\n";
962 log << LogFormat::BOLD <<
" Earth Position Angle (deg): " << setw(8) << setprecision(3) << LogFormat::RESET
964 log << LogFormat::BOLD <<
" Body velocity (ft/sec): " << setw(8) << setprecision(3) << LogFormat::RESET << VState.
vUVW <<
"\n";
965 log << LogFormat::BOLD <<
" Local velocity (ft/sec): " << setw(8) << setprecision(3) << LogFormat::RESET << vVel <<
"\n";
966 log << LogFormat::BOLD <<
" Inertial velocity (ft/sec): " << setw(8) << setprecision(3) << LogFormat::RESET << VState.vInertialVelocity <<
"\n";
967 log << LogFormat::BOLD <<
" Inertial Position (ft): " << setw(10) << setprecision(3) << LogFormat::RESET << VState.vInertialPosition <<
"\n";
968 log << LogFormat::BOLD <<
" Latitude (deg): " << setw(8) << setprecision(3) << LogFormat::RESET << VState.
vLocation.
GetLatitudeDeg() <<
"\n";
969 log << LogFormat::BOLD <<
" Longitude (deg): " << setw(8) << setprecision(3) << LogFormat::RESET << VState.
vLocation.
GetLongitudeDeg() <<
"\n";
970 log << LogFormat::BOLD <<
" Altitude ASL (ft): " << setw(8) << setprecision(3) << LogFormat::RESET <<
GetAltitudeASL() <<
"\n";
973 log << LogFormat::BOLD <<
" Matrix ECEF to Body (Orientation of Body with respect to ECEF): \n"
974 << LogFormat::RESET << Tec2b.
Dump(
"\t",
" ");
975 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
979 log << LogFormat::BOLD <<
" Matrix Body to ECEF (Orientation of ECEF with respect to Body):\n"
980 << LogFormat::RESET << Tb2ec.
Dump(
"\t",
" ");
981 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
985 log << LogFormat::BOLD <<
" Matrix Local to Body (Orientation of Body with respect to Local):\n"
986 << LogFormat::RESET << Tl2b.
Dump(
"\t",
" ");
987 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
991 log << LogFormat::BOLD <<
" Matrix Body to Local (Orientation of Local with respect to Body):\n"
992 << LogFormat::RESET << Tb2l.
Dump(
"\t",
" ");
993 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
997 log << LogFormat::BOLD <<
" Matrix Local to ECEF (Orientation of ECEF with respect to Local):\n"
998 << LogFormat::RESET << Tl2ec.
Dump(
"\t",
" ");
999 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1003 log << LogFormat::BOLD <<
" Matrix ECEF to Local (Orientation of Local with respect to ECEF):\n"
1004 << LogFormat::RESET << Tec2l.
Dump(
"\t",
" ");
1005 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1009 log << LogFormat::BOLD <<
" Matrix ECEF to Inertial (Orientation of Inertial with respect to ECEF):\n"
1010 << LogFormat::RESET << Tec2i.Dump(
"\t",
" ");
1011 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1012 << setprecision(3) << LogFormat::RESET << (Tec2i.GetQuaternion().GetEuler()*radtodeg)
1015 log << LogFormat::BOLD <<
" Matrix Inertial to ECEF (Orientation of ECEF with respect to Inertial):\n"
1016 << LogFormat::RESET << Ti2ec.Dump(
"\t",
" ");
1017 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1018 << setprecision(3) << LogFormat::RESET << (Ti2ec.GetQuaternion().GetEuler()*radtodeg)
1021 log << LogFormat::BOLD <<
" Matrix Inertial to Body (Orientation of Body with respect to Inertial):\n"
1022 << LogFormat::RESET << Ti2b.
Dump(
"\t",
" ");
1023 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1027 log << LogFormat::BOLD <<
" Matrix Body to Inertial (Orientation of Inertial with respect to Body):\n"
1028 << LogFormat::RESET << Tb2i.
Dump(
"\t",
" ");
1029 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1033 log << LogFormat::BOLD <<
" Matrix Inertial to Local (Orientation of Local with respect to Inertial):\n"
1034 << LogFormat::RESET << Ti2l.
Dump(
"\t",
" ");
1035 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1039 log << LogFormat::BOLD <<
" Matrix Local to Inertial (Orientation of Inertial with respect to Local):\n"
1040 << LogFormat::RESET << Tl2i.Dump(
"\t",
" ");
1041 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1042 << setprecision(3) << LogFormat::RESET << (Tl2i.GetQuaternion().GetEuler()*radtodeg)
1045 if (debug_lvl & 16) {
1049 err <<
"Vehicle rotation rate is excessive (>1000 rad/sec): " << VState.
vPQR.
Magnitude() <<
"\n";
1054 err <<
"Vehicle velocity is excessive (>1e10 ft/sec): " << VState.
vUVW.
Magnitude() <<
"\n";
1057 if (fabs(GetDistanceAGL()) > 1e10) {
1059 err <<
"Vehicle altitude is excessive (>1e10 ft): " << GetDistanceAGL() <<
"\n";
1064 if (debug_lvl & 64) {
This class implements a 3 element column vector.
double Magnitude(void) const
Length of the vector.
std::string Dump(const std::string &delimeter) const
Prints the contents of the vector.
Encapsulates the JSBSim simulation executive.
const SGPath & GetOutputPath(void)
Retrieves the path to the output files.
bool IntegrationSuspended(void) const
Returns the simulation suspension state.
double GetSimTime(void) const
Returns the cumulative simulation time in seconds.
std::shared_ptr< FGInertial > GetInertial(void) const
Returns the FGInertial pointer.
Initializes the simulation run.
const FGColumnVector3 GetUVWFpsIC(void) const
Gets the initial body velocity.
const FGQuaternion & GetOrientation(void) const
Gets the initial orientation.
double GetEarthPositionAngleIC(void) const
Gets the initial Earth position angle.
const FGColumnVector3 GetPQRRadpsIC(void) const
Gets the initial body rotation rate.
const FGLocation & GetPosition(void) const
Gets the initial position.
static constexpr double Constrain(double min, double value, double max)
Constrain a value between a minimum and a maximum value.
FGLocation holds an arbitrary location in the Earth centered Earth fixed reference frame (ECEF).
void SetEllipse(double semimajor, double semiminor)
Sets the semimajor and semiminor axis lengths for this planet.
const FGMatrix33 & GetTl2ec(void) const
Transform matrix from local horizontal to earth centered frame.
double GetGeodLatitudeDeg(void) const
Get the GEODETIC latitude in degrees.
double GetRadius() const
Get the distance from the center of the earth in feet.
double GetSeaLevelRadius(void) const
Get the sea level radius in feet below the current location.
double GetLatitudeDeg() const
Get the GEOCENTRIC latitude in degrees.
void SetRadius(double radius)
Set the distance from the center of the earth.
double GetLongitudeDeg() const
Get the longitude.
FGMatrix33 Transposed(void) const
Transposed matrix.
std::string Dump(const std::string &delimeter) const
Prints the contents of the matrix.
FGQuaternion GetQuaternion(void) const
Returns the quaternion associated with this direction cosine (rotation) matrix.
Base class for all scheduled JSBSim models.
virtual bool Run(bool Holding)
Runs the model; called by the Executive.
double GetNEDVelocityMagnitude(void) const
Retrieves the total local NED velocity in ft/sec.
double GetInertialVelocityMagnitude(void) const
Retrieves the total inertial velocity in ft/sec.
double Gethdot(void) const
Returns the current altitude rate.
FGColumnVector3 GetEulerDeg(void) const
Retrieves the Euler angles (in degrees) that define the vehicle orientation.
const FGColumnVector3 & GetPQR(void) const
Retrieves the body angular rates vector, relative to the ECEF frame.
FGColumnVector3 GetECEFVelocity(void) const
Calculates and retrieves the velocity vector relative to the earth centered earth fixed (ECEF) frame.
double GetLocalTerrainRadius(void) const
Returns the "constant" LocalTerrainRadius.
bool Run(bool Holding)
Runs the state propagation model; called by the Executive Can pass in a value indicating if the execu...
double GetEarthPositionAngleDeg(void) const
Returns the Earth position angle in degrees.
double GetAltitudeASL(void) const
Returns the current altitude above sea level.
const FGColumnVector3 & GetPQRi(void) const
Retrieves the body angular rates vector, relative to the ECI (inertial) frame.
const FGColumnVector3 & GetEuler(void) const
Retrieves the Euler angles that define the vehicle orientation.
const FGColumnVector3 & GetUVW(void) const
Retrieves the body frame vehicle velocity vector.
~FGPropagate()
Destructor.
bool InitModel(void)
Initializes the FGPropagate class after instantiation and prior to first execution.
FGPropagate(FGFDMExec *Executive)
Constructor.
const FGColumnVector3 & GetInertialVelocity(void) const
Retrieves the inertial velocity vector in ft/sec.
const FGColumnVector3 & GetVel(void) const
Retrieves the velocity vector.
double GetEarthPositionAngle(void) const
Returns the Earth position angle.
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
double GetAltitudeASLmeters(void) const
Returns the current altitude above sea level.
const FGColumnVector3 & GetInertialPosition(void) const
Retrieves the inertial position vector.
Models the Quaternion representation of rotations.
void Normalize(void)
Normalize.
double GetEulerDeg(int i) const
Retrieves the Euler angles.
FGQuaternion GetQDot(const FGColumnVector3 &PQR) const
Quaternion derivative for given angular rates.
const FGColumnVector3 & GetEuler(void) const
Retrieves the Euler angles.
const FGMatrix33 & GetT(void) const
Transformation matrix.
Main namespace for the JSBSim Flight Dynamics Model.
double DotProduct(const FGColumnVector3 &v1, const FGColumnVector3 &v2)
Dot product of two vectors Compute and return the euclidean dot (or scalar) product of two vectors v1...
FGQuaternion QExp(const FGColumnVector3 &omega)
Quaternion exponential.
FGColumnVector3 vUVW
The velocity vector of the vehicle with respect to the ECEF frame, expressed in the body system.
FGQuaternion qAttitudeECI
The current orientation of the vehicle, that is, the orientation of the body frame relative to the in...
FGColumnVector3 vPQRi
The angular velocity vector for the vehicle body frame relative to the ECI frame, expressed in the bo...
FGColumnVector3 vPQR
The angular velocity vector for the vehicle relative to the ECEF frame, expressed in the body frame.
FGLocation vLocation
Represents the current location of the vehicle in Earth centered Earth fixed (ECEF) frame.
FGQuaternion qAttitudeLocal
The current orientation of the vehicle, that is, the orientation of the body frame relative to the lo...