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"
93 integrator_rotational_rate = eRectEuler;
94 integrator_translational_rate = eAdamsBashforth2;
95 integrator_rotational_position = eRectEuler;
96 integrator_translational_position = eAdamsBashforth3;
120 if (!FGModel::InitModel())
return false;
124 Inertial->SetAltitudeAGL(VState.
vLocation, 4.0);
131 integrator_rotational_rate = eRectEuler;
132 integrator_translational_rate = eAdamsBashforth2;
133 integrator_rotational_position = eRectEuler;
134 integrator_translational_position = eAdamsBashforth3;
151 Ti2ec = { cos(epa), sin(epa), 0.0,
152 -sin(epa), cos(epa), 0.0,
156 VState.vInertialPosition = Tec2i * VState.
vLocation;
158 UpdateLocationMatrices();
166 UpdateBodyMatrices();
172 vVel = Tb2l * VState.
vUVW;
175 RecomputeLocalTerrainVelocity();
181 VState.
vPQRi = VState.
vPQR + Ti2b * in.vOmegaPlanet;
183 CalculateInertialVelocity();
190void FGPropagate::InitializeDerivatives()
192 VState.dqPQRidot.assign(5, in.vPQRidot);
193 VState.dqUVWidot.assign(5, in.vUVWidot);
194 VState.dqInertialVelocity.assign(5, VState.vInertialVelocity);
195 VState.dqQtrndot.assign(5, VState.vQtrndot);
221 if (Holding)
return false;
223 double dt = in.DeltaT * rate;
228 Integrate(VState.
qAttitudeECI, VState.vQtrndot, VState.dqQtrndot, dt, integrator_rotational_position);
229 Integrate(VState.
vPQRi, in.vPQRidot, VState.dqPQRidot, dt, integrator_rotational_rate);
230 Integrate(VState.vInertialPosition, VState.vInertialVelocity, VState.dqInertialVelocity, dt, integrator_translational_position);
231 Integrate(VState.vInertialVelocity, in.vUVWidot, VState.dqUVWidot, dt, integrator_translational_rate);
239 epa += in.vOmegaPlanet(eZ)*dt;
242 double cos_epa = cos(epa);
243 double sin_epa = sin(epa);
244 Ti2ec = { cos_epa, sin_epa, 0.0,
245 -sin_epa, cos_epa, 0.0,
250 VState.
vLocation = Ti2ec*VState.vInertialPosition;
254 UpdateLocationMatrices();
258 UpdateBodyMatrices();
265 RecomputeLocalTerrainVelocity();
267 VState.
vPQR = VState.
vPQRi - Ti2b * in.vOmegaPlanet;
276 vVel = Tb2l * VState.
vUVW;
279 ComputeOrbitalParameters();
290 VState.
vUVW.InitMatrix();
291 CalculateInertialVelocity();
292 VState.
vPQR.InitMatrix();
293 VState.
vPQRi = Ti2b * in.vOmegaPlanet;
295 InitializeDerivatives();
306void FGPropagate::CalculateQuatdot(
void)
319void FGPropagate::CalculateInertialVelocity(
void)
321 VState.vInertialVelocity = Tb2i * VState.
vUVW + (in.vOmegaPlanet * VState.vInertialPosition);
329void FGPropagate::CalculateUVW(
void)
331 VState.
vUVW = Ti2b * (VState.vInertialVelocity - (in.vOmegaPlanet * VState.vInertialPosition));
336void FGPropagate::Integrate( FGColumnVector3& Integrand,
337 FGColumnVector3& Val,
338 deque <FGColumnVector3>& ValDot,
340 eIntegrateType integration_type)
342 ValDot.push_front(Val);
345 switch(integration_type) {
346 case eRectEuler: Integrand += dt*ValDot[0];
348 case eTrapezoidal: Integrand += 0.5*dt*(ValDot[0] + ValDot[1]);
350 case eAdamsBashforth2: Integrand += dt*(1.5*ValDot[0] - 0.5*ValDot[1]);
352 case eAdamsBashforth3: Integrand += (1/12.0)*dt*(23.0*ValDot[0] - 16.0*ValDot[1] + 5.0*ValDot[2]);
354 case eAdamsBashforth4: Integrand += (1/24.0)*dt*(55.0*ValDot[0] - 59.0*ValDot[1] + 37.0*ValDot[2] - 9.0*ValDot[3]);
356 case eAdamsBashforth5: Integrand += dt*((1901./720.)*ValDot[0] - (1387./360.)*ValDot[1] + (109./30.)*ValDot[2] - (637./360.)*ValDot[3] + (251./720.)*ValDot[4]);
362 case eLocalLinearization:
365 err <<
"Can only use Buss (1 & 2) or local linearization integration methods in for rotational position!";
375void FGPropagate::Integrate( FGQuaternion& Integrand,
377 deque <FGQuaternion>& ValDot,
379 eIntegrateType integration_type)
381 ValDot.push_front(Val);
384 switch(integration_type) {
385 case eRectEuler: Integrand += dt*ValDot[0];
387 case eTrapezoidal: Integrand += 0.5*dt*(ValDot[0] + ValDot[1]);
389 case eAdamsBashforth2: Integrand += dt*(1.5*ValDot[0] - 0.5*ValDot[1]);
391 case eAdamsBashforth3: Integrand += (1/12.0)*dt*(23.0*ValDot[0] - 16.0*ValDot[1] + 5.0*ValDot[2]);
393 case eAdamsBashforth4: Integrand += (1/24.0)*dt*(55.0*ValDot[0] - 59.0*ValDot[1] + 37.0*ValDot[2] - 9.0*ValDot[3]);
395 case eAdamsBashforth5: Integrand += dt*((1901./720.)*ValDot[0] - (1387./360.)*ValDot[1] + (109./30.)*ValDot[2] - (637./360.)*ValDot[3] + (251./720.)*ValDot[4]);
403 Integrand = Integrand *
QExp(0.5 * dt * VState.
vPQRi);
411 FGColumnVector3 wi = VState.
vPQRi;
412 FGColumnVector3 wdoti = in.vPQRidot;
413 FGColumnVector3 omega = wi + 0.5*dt*wdoti + dt*dt/12.*wdoti*wi;
414 Integrand = Integrand *
QExp(0.5 * dt * omega);
417 case eLocalLinearization:
423 FGColumnVector3 wi = 0.5 * VState.
vPQRi;
424 FGColumnVector3 wdoti = 0.5 * in.vPQRidot;
426 double omegak = omegak2 > 1E-6 ? sqrt(omegak2) : 1E-6;
427 double rhok = 0.5 * dt * omegak;
428 double C1 = cos(rhok);
429 double C2 = 2.0 * sin(rhok) / omegak;
430 double C3 = 4.0 * (1.0 - C1) / (omegak*omegak);
431 double C4 = 4.0 * (dt - C2) / (omegak*omegak);
432 FGColumnVector3 Omega = C2*wi + C3*wdoti + C4*wi*wdoti;
440 Integrand = Integrand * q;
475 Integrand.Normalize();
480void FGPropagate::UpdateLocationMatrices(
void)
484 Ti2l = Tec2l * Ti2ec;
490void FGPropagate::UpdateBodyMatrices(
void)
496 Tec2b = Ti2b * Tec2i;
504void FGPropagate::ComputeOrbitalParameters(
void)
506 const FGColumnVector3 Z{0., 0., 1.};
507 FGColumnVector3 R = VState.vInertialPosition;
508 FGColumnVector3 angularMomentum = R * VState.vInertialVelocity;
509 h = angularMomentum.Magnitude();
510 Inclination = acos(angularMomentum(eZ)/h)*radtodeg;
512 if (abs(Inclination) > 1E-8) {
513 N = Z * angularMomentum;
514 RightAscension = atan2(N(eY), N(eX))*radtodeg;
518 RightAscension = 0.0;
520 PerigeeArgument = 0.0;
523 double vr =
DotProduct(R, VState.vInertialVelocity);
524 FGColumnVector3 eVector = (VState.vInertialVelocity*angularMomentum/in.GM - R);
525 Eccentricity = eVector.Magnitude();
526 if (Eccentricity > 1E-8) {
527 eVector /= Eccentricity;
528 if (abs(Inclination) > 1E-8) {
529 PerigeeArgument = acos(
DotProduct(N, eVector)) * radtodeg;
530 if (eVector(eZ) < 0) PerigeeArgument = 360. - PerigeeArgument;
535 eVector = {1., 0., 0.};
536 PerigeeArgument = 0.0;
540 if (vr < 0.0) TrueAnomaly = 360. - TrueAnomaly;
541 ApoapsisRadius = h*h / (in.GM * (1-Eccentricity));
542 PeriapsisRadius = h*h / (in.GM * (1+Eccentricity));
544 if (Eccentricity < 1.0) {
545 double semimajor = 0.5*(ApoapsisRadius + PeriapsisRadius);
546 OrbitalPeriod = 2.*M_PI*pow(semimajor, 1.5)/sqrt(in.GM);
554void FGPropagate::SetInertialOrientation(
const FGQuaternion& Qi)
558 UpdateBodyMatrices();
565void FGPropagate::SetInertialVelocity(
const FGColumnVector3& Vi) {
566 VState.vInertialVelocity = Vi;
568 vVel = Tb2l * VState.
vUVW;
573void FGPropagate::SetInertialRates(
const FGColumnVector3& vRates) {
574 VState.
vPQRi = Ti2b * vRates;
575 VState.
vPQR = VState.
vPQRi - Ti2b * in.vOmegaPlanet;
588void FGPropagate::SetAltitudeASL(
double altASL)
592 UpdateVehicleState();
597void FGPropagate::RecomputeLocalTerrainVelocity()
600 FGColumnVector3 normal;
601 Inertial->GetContactPoint(VState.
vLocation, contact, normal,
602 LocalTerrainVelocity, LocalTerrainAngularVelocity);
607double FGPropagate::GetTerrainElevation(
void)
const
609 FGColumnVector3 vDummy;
611 contact.SetEllipse(in.SemiMajor, in.SemiMinor);
612 Inertial->GetContactPoint(VState.
vLocation, contact, vDummy, vDummy, vDummy);
613 return contact.GetGeodAltitude();
618void FGPropagate::SetTerrainElevation(
double terrainElev)
620 Inertial->SetTerrainElevation(terrainElev);
629 Inertial->GetContactPoint(VState.
vLocation, contact, vDummy, vDummy, vDummy);
635double FGPropagate::GetDistanceAGL(
void)
const
637 return Inertial->GetAltitudeAGL(VState.
vLocation);
642double FGPropagate::GetDistanceAGLKm(
void)
const
644 return GetDistanceAGL()*0.0003048;
649void FGPropagate::SetDistanceAGL(
double tt)
651 Inertial->SetAltitudeAGL(VState.
vLocation, tt);
652 UpdateVehicleState();
657void FGPropagate::SetDistanceAGLKm(
double tt)
659 SetDistanceAGL(tt*3280.8399);
664void FGPropagate::SetVState(
const VehicleState& vstate)
668 UpdateLocationMatrices();
669 SetInertialOrientation(vstate.qAttitudeECI);
670 RecomputeLocalTerrainVelocity();
671 VState.
vUVW = vstate.vUVW;
672 vVel = Tb2l * VState.
vUVW;
673 VState.
vPQR = vstate.vPQR;
674 VState.
vPQRi = VState.
vPQR + Ti2b * in.vOmegaPlanet;
675 VState.vInertialPosition = vstate.vInertialPosition;
681void FGPropagate::UpdateVehicleState(
void)
683 RecomputeLocalTerrainVelocity();
684 VState.vInertialPosition = Tec2i * VState.
vLocation;
685 UpdateLocationMatrices();
686 UpdateBodyMatrices();
687 vVel = Tb2l * VState.
vUVW;
693void FGPropagate::SetLocation(
const FGLocation& l)
696 UpdateVehicleState();
708void FGPropagate::DumpState(
void)
712 out << LogFormat::BLUE
713 <<
"------------------------------------------------------------------" << LogFormat::RESET <<
"\n";
714 out << LogFormat::BOLD << fixed
715 <<
"State Report at sim time: " << FDMExec->
GetSimTime() <<
" seconds" << LogFormat::RESET <<
"\n";
716 out <<
" " << LogFormat::UNDERLINE_ON
717 <<
"Position" << LogFormat::UNDERLINE_OFF <<
"\n";
718 out <<
" ECI: " << VState.vInertialPosition.
Dump(
", ") <<
" (x,y,z, in ft)\n";
719 out <<
" ECEF: " << VState.
vLocation <<
" (x,y,z, in ft)\n";
722 <<
", " <<
GetAltitudeASL() <<
" (geodetic lat, lon, alt ASL in deg and ft)\n";
724 out <<
"\n " << LogFormat::UNDERLINE_ON
725 <<
"Orientation" << LogFormat::UNDERLINE_OFF <<
"\n";
729 out <<
"\n " << LogFormat::UNDERLINE_ON
730 <<
"Velocity" << LogFormat::UNDERLINE_OFF <<
"\n";
731 out <<
" ECI: " << VState.vInertialVelocity.
Dump(
", ") <<
" (x,y,z in ft/s)\n";
733 out <<
" Local: " <<
GetVel() <<
" (n,e,d in ft/sec)\n";
734 out <<
" Body: " <<
GetUVW() <<
" (u,v,w in ft/sec)\n";
736 out <<
"\n" <<
" " << LogFormat::UNDERLINE_ON
737 <<
"Body Rates (relative to given frame, expressed in body frame)" << LogFormat::UNDERLINE_OFF <<
"\n";
738 out <<
" ECI: " << (VState.
vPQRi * radtodeg).Dump(
", ") <<
" (p,q,r in deg/s)" <<
"\n";
739 out <<
" ECEF: " << (VState.
vPQR * radtodeg).Dump(
", ") <<
" (p,q,r in deg/s)" <<
"\n";
744void FGPropagate::WriteStateFile(
int num)
748 if (num == 0)
return;
752 if (path.isNull()) path = SGPath(
"initfile.");
753 else path.append(
"initfile.");
756 path.concat(to_string((
double)FDMExec->
GetSimTime())+
".xml");
761 if (outfile.is_open()) {
762 outfile <<
"<?xml version=\"1.0\"?>\n";
763 outfile <<
"<initialize name=\"reset00\">\n";
764 outfile <<
" <ubody unit=\"FT/SEC\"> " << VState.
vUVW(eU) <<
" </ubody> \n";
765 outfile <<
" <vbody unit=\"FT/SEC\"> " << VState.
vUVW(eV) <<
" </vbody> \n";
766 outfile <<
" <wbody unit=\"FT/SEC\"> " << VState.
vUVW(eW) <<
" </wbody> \n";
772 outfile <<
" <altitude unit=\"FT\"> " << GetDistanceAGL() <<
" </altitude>\n";
773 outfile <<
"</initialize>\n";
776 FGLogging log(LogLevel::ERROR);
777 log <<
"Could not open and/or write the state to the initial conditions file: "
783 if (outfile.is_open()) {
784 outfile <<
"<?xml version=\"1.0\"?>\n";
785 outfile <<
"<initialize name=\"IC File\" version=\"2.0\">\n";
787 outfile <<
" <position frame=\"ECEF\">\n";
790 outfile <<
" <altitudeMSL unit=\"FT\"> " <<
GetAltitudeASL() <<
" </altitudeMSL>\n";
791 outfile <<
" </position>\n";
793 outfile <<
" <orientation unit=\"DEG\" frame=\"LOCAL\">\n";
797 outfile <<
" </orientation>\n";
799 outfile <<
" <velocity unit=\"FT/SEC\" frame=\"LOCAL\">\n";
800 outfile <<
" <x> " <<
GetVel(eNorth) <<
" </x>\n";
801 outfile <<
" <y> " <<
GetVel(eEast) <<
" </y>\n";
802 outfile <<
" <z> " <<
GetVel(eDown) <<
" </z>\n";
803 outfile <<
" </velocity>\n";
805 outfile <<
" <attitude_rate unit=\"DEG/SEC\" frame=\"BODY\">\n";
806 outfile <<
" <roll> " << (VState.
vPQR*radtodeg)(eRoll) <<
" </roll>\n";
807 outfile <<
" <pitch> " << (VState.
vPQR*radtodeg)(ePitch) <<
" </pitch>\n";
808 outfile <<
" <yaw> " << (VState.
vPQR*radtodeg)(eYaw) <<
" </yaw>\n";
809 outfile <<
" </attitude_rate>\n";
811 outfile <<
"</initialize>\n";
814 FGLogging log(LogLevel::ERROR);
815 log <<
"Could not open and/or write the state to the initial conditions file: "
820 FGLogging log(LogLevel::ERROR);
821 log <<
"When writing a state file, the supplied value must be 1 or 2 for the version number of the resulting IC file\n";
827void FGPropagate::bind(
void)
859 &FGPropagate::SetAltitudeASL);
861 &FGPropagate::SetAltitudeASLmeters);
862 PropertyManager->Tie(
"position/lat-gc-rad",
this, &FGPropagate::GetLatitude,
863 &FGPropagate::SetLatitude);
864 PropertyManager->Tie(
"position/long-gc-rad",
this, &FGPropagate::GetLongitude,
865 &FGPropagate::SetLongitude);
866 PropertyManager->Tie(
"position/lat-gc-deg",
this, &FGPropagate::GetLatitudeDeg,
867 &FGPropagate::SetLatitudeDeg);
868 PropertyManager->Tie(
"position/long-gc-deg",
this, &FGPropagate::GetLongitudeDeg,
869 &FGPropagate::SetLongitudeDeg);
870 PropertyManager->Tie(
"position/lat-geod-rad",
this, &FGPropagate::GetGeodLatitudeRad);
871 PropertyManager->Tie(
"position/lat-geod-deg",
this, &FGPropagate::GetGeodLatitudeDeg);
872 PropertyManager->Tie(
"position/geod-alt-ft",
this, &FGPropagate::GetGeodeticAltitude);
873 PropertyManager->Tie(
"position/h-agl-ft",
this, &FGPropagate::GetDistanceAGL,
874 &FGPropagate::SetDistanceAGL);
875 PropertyManager->Tie(
"position/geod-alt-km",
this, &FGPropagate::GetGeodeticAltitudeKm);
876 PropertyManager->Tie(
"position/h-agl-km",
this, &FGPropagate::GetDistanceAGLKm,
877 &FGPropagate::SetDistanceAGLKm);
878 PropertyManager->Tie(
"position/radius-to-vehicle-ft",
this, &FGPropagate::GetRadius);
879 PropertyManager->Tie(
"position/terrain-elevation-asl-ft",
this, &FGPropagate::GetTerrainElevation,
880 &FGPropagate::SetTerrainElevation);
886 PropertyManager->Tie(
"position/ecef-x-ft",
this, eX, &FGPropagate::GetLocation);
887 PropertyManager->Tie(
"position/ecef-y-ft",
this, eY, &FGPropagate::GetLocation);
888 PropertyManager->Tie(
"position/ecef-z-ft",
this, eZ, &FGPropagate::GetLocation);
905 PropertyManager->Tie(
"orbital/specific-angular-momentum-ft2_sec", &h);
906 PropertyManager->Tie(
"orbital/inclination-deg", &Inclination);
907 PropertyManager->Tie(
"orbital/right-ascension-deg", &RightAscension);
908 PropertyManager->Tie(
"orbital/eccentricity", &Eccentricity);
909 PropertyManager->Tie(
"orbital/argument-of-perigee-deg", &PerigeeArgument);
910 PropertyManager->Tie(
"orbital/true-anomaly-deg", &TrueAnomaly);
911 PropertyManager->Tie(
"orbital/apoapsis-radius-ft", &ApoapsisRadius);
912 PropertyManager->Tie(
"orbital/periapsis-radius-ft", &PeriapsisRadius);
913 PropertyManager->Tie(
"orbital/period-sec", &OrbitalPeriod);
915 PropertyManager->Tie(
"simulation/integrator/rate/rotational", (
int*)&integrator_rotational_rate);
916 PropertyManager->Tie(
"simulation/integrator/rate/translational", (
int*)&integrator_translational_rate);
917 PropertyManager->Tie(
"simulation/integrator/position/rotational", (
int*)&integrator_rotational_position);
918 PropertyManager->Tie(
"simulation/integrator/position/translational", (
int*)&integrator_translational_position);
920 PropertyManager->Tie<
FGPropagate,
int>(
"simulation/write-state-file",
this,
921 nullptr, &FGPropagate::WriteStateFile);
943void FGPropagate::Debug(
int from)
945 if (debug_lvl <= 0)
return;
952 if (debug_lvl & 2 ) {
953 FGLogging log(LogLevel::DEBUG);
954 if (from == 0) log <<
"Instantiated: FGPropagate\n";
955 if (from == 1) log <<
"Destroyed: FGPropagate\n";
957 if (debug_lvl & 4 ) {
959 if (debug_lvl & 8 && from == 2) {
960 FGLogging log(LogLevel::DEBUG);
961 log <<
"\n" << LogFormat::BLUE << LogFormat::BOLD << left << fixed
962 <<
" Propagation Report (English units: ft, degrees) at simulation time " << FDMExec->
GetSimTime() <<
" seconds"
963 << LogFormat::RESET <<
"\n\n";
964 log << LogFormat::BOLD <<
" Earth Position Angle (deg): " << setw(8) << setprecision(3) << LogFormat::RESET
966 log << LogFormat::BOLD <<
" Body velocity (ft/sec): " << setw(8) << setprecision(3) << LogFormat::RESET << VState.
vUVW <<
"\n";
967 log << LogFormat::BOLD <<
" Local velocity (ft/sec): " << setw(8) << setprecision(3) << LogFormat::RESET << vVel <<
"\n";
968 log << LogFormat::BOLD <<
" Inertial velocity (ft/sec): " << setw(8) << setprecision(3) << LogFormat::RESET << VState.vInertialVelocity <<
"\n";
969 log << LogFormat::BOLD <<
" Inertial Position (ft): " << setw(10) << setprecision(3) << LogFormat::RESET << VState.vInertialPosition <<
"\n";
970 log << LogFormat::BOLD <<
" Latitude (deg): " << setw(8) << setprecision(3) << LogFormat::RESET << VState.
vLocation.
GetLatitudeDeg() <<
"\n";
971 log << LogFormat::BOLD <<
" Longitude (deg): " << setw(8) << setprecision(3) << LogFormat::RESET << VState.
vLocation.
GetLongitudeDeg() <<
"\n";
972 log << LogFormat::BOLD <<
" Altitude ASL (ft): " << setw(8) << setprecision(3) << LogFormat::RESET <<
GetAltitudeASL() <<
"\n";
975 log << LogFormat::BOLD <<
" Matrix ECEF to Body (Orientation of Body with respect to ECEF): \n"
976 << LogFormat::RESET << Tec2b.
Dump(
"\t",
" ");
977 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
981 log << LogFormat::BOLD <<
" Matrix Body to ECEF (Orientation of ECEF with respect to Body):\n"
982 << LogFormat::RESET << Tb2ec.
Dump(
"\t",
" ");
983 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
987 log << LogFormat::BOLD <<
" Matrix Local to Body (Orientation of Body with respect to Local):\n"
988 << LogFormat::RESET << Tl2b.
Dump(
"\t",
" ");
989 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
993 log << LogFormat::BOLD <<
" Matrix Body to Local (Orientation of Local with respect to Body):\n"
994 << LogFormat::RESET << Tb2l.
Dump(
"\t",
" ");
995 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
999 log << LogFormat::BOLD <<
" Matrix Local to ECEF (Orientation of ECEF with respect to Local):\n"
1000 << LogFormat::RESET << Tl2ec.
Dump(
"\t",
" ");
1001 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1005 log << LogFormat::BOLD <<
" Matrix ECEF to Local (Orientation of Local with respect to ECEF):\n"
1006 << LogFormat::RESET << Tec2l.
Dump(
"\t",
" ");
1007 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1011 log << LogFormat::BOLD <<
" Matrix ECEF to Inertial (Orientation of Inertial with respect to ECEF):\n"
1012 << LogFormat::RESET << Tec2i.Dump(
"\t",
" ");
1013 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1014 << setprecision(3) << LogFormat::RESET << (Tec2i.GetQuaternion().GetEuler()*radtodeg)
1017 log << LogFormat::BOLD <<
" Matrix Inertial to ECEF (Orientation of ECEF with respect to Inertial):\n"
1018 << LogFormat::RESET << Ti2ec.Dump(
"\t",
" ");
1019 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1020 << setprecision(3) << LogFormat::RESET << (Ti2ec.GetQuaternion().GetEuler()*radtodeg)
1023 log << LogFormat::BOLD <<
" Matrix Inertial to Body (Orientation of Body with respect to Inertial):\n"
1024 << LogFormat::RESET << Ti2b.
Dump(
"\t",
" ");
1025 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1029 log << LogFormat::BOLD <<
" Matrix Body to Inertial (Orientation of Inertial with respect to Body):\n"
1030 << LogFormat::RESET << Tb2i.
Dump(
"\t",
" ");
1031 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1035 log << LogFormat::BOLD <<
" Matrix Inertial to Local (Orientation of Local with respect to Inertial):\n"
1036 << LogFormat::RESET << Ti2l.
Dump(
"\t",
" ");
1037 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1041 log << LogFormat::BOLD <<
" Matrix Local to Inertial (Orientation of Inertial with respect to Local):\n"
1042 << LogFormat::RESET << Tl2i.Dump(
"\t",
" ");
1043 log << LogFormat::BOLD <<
"\n Associated Euler angles (deg): " << setw(8)
1044 << setprecision(3) << LogFormat::RESET << (Tl2i.GetQuaternion().GetEuler()*radtodeg)
1047 if (debug_lvl & 16) {
1051 err <<
"Vehicle rotation rate is excessive (>1000 rad/sec): " << VState.
vPQR.
Magnitude() <<
"\n";
1056 err <<
"Vehicle velocity is excessive (>1e10 ft/sec): " << VState.
vUVW.
Magnitude() <<
"\n";
1059 if (fabs(GetDistanceAGL()) > 1e10) {
1061 err <<
"Vehicle altitude is excessive (>1e10 ft): " << GetDistanceAGL() <<
"\n";
1066 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...