1
0
Fork 0

Start using or own types for vectors and matrices for sharter and more readable code. Fix some sign issues

This commit is contained in:
Erik Hofman 2020-09-04 10:58:18 +02:00
parent ce1e85f656
commit e8fe8345bf
2 changed files with 164 additions and 141 deletions

View file

@ -2,7 +2,7 @@
//
// Written by Erik Hofman, started November 2016
//
// Copyright (C) 2016,2017 Erik Hofman <erik@ehofman.com>
// Copyright (C) 2016-2020 by Erik Hofman <erik@ehofman.com>
//
//
// This program is free software; you can redistribute it and/or
@ -121,7 +121,7 @@ FGAISim::FGAISim(double dt) :
// the aircraft on it's wheels.
for (int i=0; i<no_gears; ++i) {
// convert from structural frame to body frame
gear_pos[i] = simd4_t<float,3>(-cg[X] - gear_pos[i][X],
gear_pos[i] = aiVec3(-cg[X] - gear_pos[i][X],
-cg[Y] + gear_pos[i][Y],
cg[Z] - gear_pos[i][Z])*INCHES_TO_FEET;
if (gear_pos[i][Z] < agl) agl = gear_pos[i][Z];
@ -134,11 +134,11 @@ FGAISim::FGAISim(double dt) :
Cg_damp[no_gears] = 2000.0f;
no_gears++;
simd4x4_t<float,4> mcg;
aiMtx4 mcg;
simd4x4::unit(mcg);
simd4x4::translate(mcg, cg);
mI = simd4x4_t<float,4>( I[XX], 0.0f, -I[XZ], 0.0f,
mI = aiMtx4( I[XX], 0.0f, -I[XZ], 0.0f,
0.0f, I[YY], 0.0f, 0.0f,
-I[XZ], 0.0f, I[ZZ], 0.0f,
0.0f, 0.0f, 0.0f, 0.0f);
@ -194,26 +194,28 @@ FGAISim::update(double ddt)
/* Earth-to-Body-Axis Transformation Matrix */
/* matrices to compensate for pitch, roll and heading */
simd4_t<float,3> vector = euler;
aiVec3 vector = euler;
float angle = simd4::normalize(vector);
simd4x4_t<float,4> mNed2Body = simd4x4::rotation_matrix(angle, vector);
simd4x4_t<float,4> mBody2Ned = simd4x4::transpose(mNed2Body);
simd4_t<float,3> gravity_body = mNed2Body*gravity_ned;
aiMtx4 mNed2Body = simd4x4::rotation_matrix(angle, vector);
aiMtx4 mBody2Ned = simd4x4::transpose(mNed2Body);
aiVec3 gravity_body = mNed2Body*gravity_ned;
/* Air-Relative velocity vector */
vUVWaero = vUVW + mNed2Body*wind_ned;
update_velocity( simd4::magnitude( simd4_t<float,2>(vUVWaero) ) );
simd4_t<float,3> WindAxis = AOA;
float alpha = (vUVWaero[W] == 0) ? 0 : std::atan2(vUVWaero[W], vUVWaero[U]);
aiVec3 WindAxis = AOA;
float alpha = std::atan2(vUVWaero[W], vUVWaero[U]);
set_alpha_rad( _MINMAX(alpha, -0.0873f, 0.349f) ); // -5 to 20 degrees
float beta = (velocity == 0) ? 0 : std::asin(vUVWaero[V]/velocity);
set_beta_rad( _MINMAX(beta, -0.2618f, 0.2618f) ); // -15 to 15 degrees
AOAdot = (AOA - WindAxis)*inv_dt;
printf("velocity: %f, vUVWaero: %3.2f, %3.2f, %3.2f, mach: %3.2f\n", velocity, vUVWaero[0], vUVWaero[1], vUVWaero[2], mach);
printf("agl: %5.4f, alpha: %5.4f, beta: %5.4f, adot: %5.4f, bdot: %5.4f\n", agl, AOA[ALPHA], AOA[BETA], AOAdot[ALPHA], AOAdot[BETA]);
#if 0
printf("velocity: %f, vUVWaero: %3.2f, %3.2f, %3.2f, mach: %3.2f\n", velocity, vUVWaero[0], vUVWaero[1], vUVWaero[2], mach);
printf("agl: %5.4f, alpha: %5.4f, beta: %5.4f, adot: %5.4f, bdot: %5.4f\n", agl, AOA[ALPHA], AOA[BETA], AOAdot[ALPHA], AOAdot[BETA]);
#endif
/* Force and Moment Coefficients */
/* Sum all Drag, Side, Lift, Roll, Pitch, Yaw and Thrust coefficients */
@ -230,80 +232,86 @@ printf("agl: %5.4f, alpha: %5.4f, beta: %5.4f, adot: %5.4f, bdot: %5.4f\n", agl,
* Clmn[ROLL] = (Clp*p + Clr*r)*b_2U;
* Clmn[YAW] = (Cnp*p + Cnr*r)*b_2U;
*/
simd4_t<float,4> Ccbar2U = (xCq*q + xCadot*adot)*cbar_2U;
simd4_t<float,4> Cb2U = (xCp*p + xCr*r )*b_2U;
aiVec4 Ccbar2U = (xCq*q + xCadot*adot)*cbar_2U;
aiVec4 Cb2U = (xCp*p + xCr*r )*b_2U;
simd4_t<float,4> CDYL(0.0f, Cb2U[SIDE], Ccbar2U[LIFT]);
simd4_t<float,4> Clmn(Cb2U[ROLL], Ccbar2U[PITCH], Cb2U[YAW]);
for (int i=0; i<4; ++i) {
CDYL += simd4_t<float,4>(xCDYLT.m4x4()[i]);
Clmn += simd4_t<float,4>(xClmnT.m4x4()[i]);
aiVec4 CDYL(0.0f, Cb2U[SIDE], Ccbar2U[LIFT]);
aiVec4 Clmn(Cb2U[ROLL], Ccbar2U[PITCH], Cb2U[YAW]);
int i = 3;
do {
CDYL += static_cast<aiVec4>(xCDYLT.m4x4()[i]);
Clmn += static_cast<aiVec4>(xClmnT.m4x4()[i]);
}
while(i--);
float CL = CDYL[LIFT];
CDYL += simd4_t<float,3>(CDi*CL*CL, 0.0f, 0.0f);
CDYL += aiVec3(CDi*CL*CL, 0.0f, 0.0f);
printf("CDYL: %7.2f, %7.2f, %7.2f\n", CDYL[DRAG], CDYL[SIDE], CDYL[LIFT]);
#if 0
printf(" CLa: %6.3f, CLadot: %6.3f, CLq: %6.3f\n", xCDYLT.ptr()[ALPHA][LIFT],CLadot*adot,CLq*q);
printf(" CDa: %6.3f, CDb: %6.3f, CDi: %6.3f\n", xCDYLT.ptr()[ALPHA][DRAG],xCDYLT.ptr()[BETA][DRAG],CDi*CL*CL);
printf(" CYb: %6.3f, CYp: %6.3f, CYr: %6.3f\n", xCDYLT.ptr()[BETA][SIDE],CYp*p,CYr*r);
printf(" Cma: %6.3f, Cmadot: %6.3f, Cmq: %6.3f\n", xClmnT.ptr()[ALPHA][PITCH],Cmadot*adot,Cmq*q);
printf(" Clb: %6.3f, Clp: %6.3f, Clr: %6.3f\n", xClmnT.ptr()[BETA][ROLL],Clp*p,Clr*r);
printf(" Cnb: %6.3f, Cnp: %6.3f, Cnr: %6.3f\n", xClmnT.ptr()[BETA][YAW],Cnp*p,Cnr*r);
printf(" CLa: %6.3f, CLadot: %6.3f, CLq: %6.3f\n", xCDYLT.ptr()[ALPHA][LIFT],CLadot*adot,CLq*q);
printf(" CDa: %6.3f, CDb: %6.3f, CDi: %6.3f\n", xCDYLT.ptr()[ALPHA][DRAG],xCDYLT.ptr()[BETA][DRAG],CDi*CL*CL);
printf(" CYb: %6.3f, CYp: %6.3f, CYr: %6.3f\n", xCDYLT.ptr()[BETA][SIDE],CYp*p,CYr*r);
printf(" Cma: %6.3f, Cmadot: %6.3f, Cmq: %6.3f\n", xClmnT.ptr()[ALPHA][PITCH],Cmadot*adot,Cmq*q);
printf(" Clb: %6.3f, Clp: %6.3f, Clr: %6.3f\n", xClmnT.ptr()[BETA][ROLL],Clp*p,Clr*r);
printf(" Cnb: %6.3f, Cnp: %6.3f, Cnr: %6.3f\n", xClmnT.ptr()[BETA][YAW],Cnp*p,Cnr*r);
printf(" Cmde: %6.3f\n", xClmnT.ptr()[ELEVATOR][PITCH]);
printf(" CYdr: %6.3f, Cldr: %6.3f, Cndr: %6.3f\n", xCDYLT.ptr()[RUDDER][SIDE], xClmnT.ptr()[RUDDER][ROLL], xClmnT.ptr()[RUDDER][YAW]);
printf(" Clda: %6.3f, CYda: %6.3f\n", xClmnT.ptr()[AILERON][ROLL], xClmnT.ptr()[AILERON][YAW]);
printf(" Cldf: %6.3f, CDdf: %6.3f, Cmdf: %6.3f\n", xCDYLT.ptr()[FLAPS][LIFT], xCDYLT.ptr()[FLAPS][DRAG], xClmnT.ptr()[FLAPS][PITCH]);
printf(" Cmde: %6.3f\n", xClmnT.ptr()[ELEVATOR][PITCH]);
printf(" CYdr: %6.3f, Cldr: %6.3f, Cndr: %6.3f\n", xCDYLT.ptr()[RUDDER][SIDE], xClmnT.ptr()[RUDDER][ROLL], xClmnT.ptr()[RUDDER][YAW]);
printf(" Clda: %6.3f, CYda: %6.3f\n", xClmnT.ptr()[AILERON][ROLL], xClmnT.ptr()[AILERON][YAW]);
printf(" Cldf: %6.3f, CDdf: %6.3f, Cmdf: %6.3f\n", xCDYLT.ptr()[FLAPS][LIFT], xCDYLT.ptr()[FLAPS][DRAG], xClmnT.ptr()[FLAPS][PITCH]);
#endif
/* State Accelerations (convert coefficients to forces and moments) */
simd4_t<float,3> FDYL = CDYL*Coef2Force;
simd4_t<float,3> Mlmn = Clmn*Coef2Moment;
aiVec3 FDYL = CDYL*Coef2Force;
aiVec3 Mlmn = Clmn*Coef2Moment;
/* convert from wind axes to body axes */
vector = AOA;
angle = simd4::normalize(vector);
simd4x4_t<float,4> mWindBody = simd4x4::rotation_matrix(angle, vector);
simd4_t<float,3> FXYZ = mWindBody*FDYL;
aiMtx4 mWindBody = simd4x4::rotation_matrix(angle, vector);
aiVec3 FXYZ = mWindBody*FDYL;
/* Thrust */
for (int i=0; i<no_engines; ++i) {
FXYZ += FT[i]*th + FTM[i]*mach;
// Mlmn += MT*th;
// Mlmn += MT[i]*th;
printf("FDYL: %7.2f, %7.2f, %7.2f\n", FDYL[DRAG], FDYL[SIDE], FDYL[LIFT]);
printf("FT: %10.2f, %7.2f, MT: %7.2f\n", FT[i][X]*th, FTM[i][X]*mach, MT[i][X]*th);
#if 0
printf("FDYL: %7.2f, %7.2f, %7.2f\n", FDYL[DRAG], FDYL[SIDE], FDYL[LIFT]);
printf("FT: %10.2f, %7.2f, MT: %7.2f\n", FT[i][X]*th, FTM[i][X]*mach, MT[i][X]*th);
#endif
}
/* gear forces */
WoW = false;
if (agl < 100.0f) {
int WoW_main = 0;
simd4_t<float,3> cg_agl_neu(0.0f, 0.0f, agl);
aiVec3 cg_agl_neu(0.0f, 0.0f, agl);
for (int i=0; i<no_gears; ++i) {
simd4_t<float,3> gear_ned = mBody2Ned*gear_pos[i];
simd4_t<float,3> lg_ground_neu = gear_ned + cg_agl_neu;
aiVec3 gear_ned = mBody2Ned*gear_pos[i];
aiVec3 lg_ground_neu = gear_ned + cg_agl_neu;
if (lg_ground_neu[Z] < 0.0f) { // weight on wheel
simd4_t<float,3> lg_vrot = simd4::cross(vPQR, gear_pos[i]);
simd4_t<float,3> lg_cg_vned = mBody2Ned*lg_vrot;
simd4_t<float,3> lg_vned = NEDdot + lg_cg_vned;
aiVec3 lg_vrot = simd4::cross(vPQR, gear_pos[i]);
aiVec3 lg_cg_vned = mBody2Ned*lg_vrot;
aiVec3 lg_vned = NEDdot + lg_cg_vned;
float Fn;
Fn = Cg_spring[i]*lg_ground_neu[Z] - Cg_damp[i]*lg_vned[Z];
if (Fn > 0.0f) Fn = 0.0f;
simd4_t<float,3> Fn_lg(0.0f, 0.0f, Fn);
simd4_t<float,3> mu_body(-0.02f-0.7f*br, 0.8f, 0.0f);
simd4_t<float,3> FLGear = mNed2Body*Fn_lg + vUVWaero*mu_body;
// simd4_t<float,3> MLGear = simd4::cross(gear_pos[i], FLGear);
#if 0
printf("FLGear[%i]: %10.2f %10.2f %10.2f\n",i,FLGear[0], FLGear[1], FLGear[2]);
printf("MLGear[%i]: %10.2f %10.2f %10.2f\n",i,MLGear[0], MLGear[1], MLGear[2]);
#endif
aiVec3 Fn_lg(0.0f, 0.0f, Fn);
aiVec3 mu_body(-0.02f-0.7f*br, 0.8f, 0.0f);
aiVec3 FLGear = mNed2Body*Fn_lg + vUVWaero*mu_body;
FXYZ += FLGear;
aiVec3 MLGear = simd4::cross(gear_pos[i], FLGear);
// Mlmn += MLGear;
#if 0
printf("FLGear[%i]: %10.2f %10.2f %10.2f\n",i,FLGear[0], FLGear[1], FLGear[2]);
printf("MLGear[%i]: %10.2f %10.2f %10.2f\n",i,MLGear[0], MLGear[1], MLGear[2]);
#endif
if (i<3) WoW_main++;
}
WoW = (WoW_main == 3);
@ -312,8 +320,10 @@ printf("MLGear[%i]: %10.2f %10.2f %10.2f\n",i,MLGear[0], MLGear[1], MLGear[2]);
/* local body accelrations */
aXYZ = FXYZ*inv_m + gravity_body;
printf("aXYZ: %7.2f, %7.2f, %7.2f\n", aXYZ[X]/m, aXYZ[Y]/m, aXYZ[Z]/m);
printf("Mlmn: %7.2f, %7.2f, %7.2f\n", Mlmn[ROLL], Mlmn[PITCH], Mlmn[YAW]);
#if 0
printf("aXYZ: %7.2f, %7.2f, %7.2f\n", aXYZ[X]/m, aXYZ[Y]/m, aXYZ[Z]/m);
printf("Mlmn: %7.2f, %7.2f, %7.2f\n", Mlmn[ROLL], Mlmn[PITCH], Mlmn[YAW]);
#endif
/* Dynamic Equations */
@ -324,17 +334,20 @@ printf("Mlmn: %7.2f, %7.2f, %7.2f\n", Mlmn[ROLL], Mlmn[PITCH], Mlmn[YAW]);
/* body-axis rotational accelerations: rolling, pitching, yawing */
vPQRdot = mIinv*(Mlmn - vPQR*(mI*vPQR));
vPQR += vPQRdot*dt;
printf("PQRdot: %7.2f, %7.2f, %7.2f\n", vPQRdot[P], vPQRdot[Q], vPQRdot[R]);
printf("PQR: %7.2f, %7.2f, %7.2f\n", vPQR[P], vPQR[Q], vPQR[R]);
printf("UVWdot: %7.2f, %7.2f, %7.2f\n", vUVWdot[U], vUVWdot[V], vUVWdot[W]);
printf("UVW: %7.2f, %7.2f, %7.2f\n", vUVW[U], vUVW[V], vUVW[W]);
#if 0
printf("PQRdot: %7.2f, %7.2f, %7.2f\n", vPQRdot[P], vPQRdot[Q], vPQRdot[R]);
printf("PQR: %7.2f, %7.2f, %7.2f\n", vPQR[P], vPQR[Q], vPQR[R]);
printf("UVWdot: %7.2f, %7.2f, %7.2f\n", vUVWdot[U], vUVWdot[V], vUVWdot[W]);
printf("UVW: %7.2f, %7.2f, %7.2f\n", vUVW[U], vUVW[V], vUVW[W]);
#endif
/* position of center of mass wrt earth: north, east, down */
NEDdot = mBody2Ned*vUVW;
simd4_t<float,3> NEDdist = NEDdot*dt;
printf("NEDdot: %7.2f, %7.2f, %7.2f\n", NEDdot[0], NEDdot[1], NEDdot[2]);
printf("NEDdist: %7.2f, %7.2f, %7.2f\n", NEDdist[0], NEDdist[1], NEDdist[2]);
aiVec3 NEDdist = NEDdot*dt;
#if 0
printf("NEDdot: %7.2f, %7.2f, %7.2f\n", NEDdot[0], NEDdot[1], NEDdot[2]);
printf("NEDdist: %7.2f, %7.2f, %7.2f\n", NEDdist[0], NEDdist[1], NEDdist[2]);
#endif
#ifdef ENABLE_SP_FDM
double dist = simd4::magnitude( simd4_t<float,2>(NEDdist) );
@ -354,7 +367,9 @@ printf("NEDdist: %7.2f, %7.2f, %7.2f\n", NEDdist[0], NEDdist[1], NEDdist[2]);
location_geod[Z] -= NEDdist[Z];
set_altitude_agl_ft(location_geod[DOWN]);
#endif
printf("GEOD: %7.2f, %7.2f, %7.2f\n", location_geod[0], location_geod[1], location_geod[2]);
#if 0
printf("GEOD: %7.2f, %7.2f, %7.2f\n", location_geod[0], location_geod[1], location_geod[2]);
#endif
/* angle of body wrt earth: phi (pitch), theta (roll), psi (heading) */
float sin_p = std::sin(euler[PHI]);
@ -368,7 +383,9 @@ printf("GEOD: %7.2f, %7.2f, %7.2f\n", location_geod[0], location_geod[1], loc
// euler_dot[PHI] = p + (q*sin_p + r*cos_p)*sin_t/cos_t;
euler_dot[PHI] = p + euler_dot[PSI]*sin_t;
euler += euler_dot*dt;
printf("euler: %7.2f, %7.2f, %7.2f\n", euler[PHI], euler[THETA], euler[PSI]);
#if 0
printf("euler: %7.2f, %7.2f, %7.2f\n", euler[PHI], euler[THETA], euler[PSI]);
#endif
#ifdef ENABLE_SP_FDM
copy_from_AISim();
@ -507,11 +524,11 @@ FGAISim::update_velocity(float v)
float Sbqbar = Sqbar*b;
float Sqbarcbar = Sqbar*cbar;
/* Drag, Side, Lift */
Coef2Force = simd4_t<float,3>(Sqbar);
/* Drag, Side, Lift, Thrust */
Coef2Force = aiVec3(Sqbar);
/* Roll, Pitch, Yaw */
Coef2Moment = simd4_t<float,3>(Sbqbar, Sqbarcbar, Sbqbar, Sbqbar);
/* Roll, Pitch, Yaw, Thrust */
Coef2Moment = aiVec3(Sbqbar, Sqbarcbar, Sbqbar, Sbqbar);
/* linear interpolation for speed of sound */
float vs = ifract*vsound[idx] + fract*vsound[idx+1];
@ -524,28 +541,28 @@ FGAISim::update_velocity(float v)
}
simd4x4_t<float,4>
FGAISim::matrix_inverse(simd4x4_t<float,4> mtx)
FGAISim::matrix_inverse(aiMtx4 mtx)
{
simd4x4_t<float,4> dst;
simd4_t<float,4> v1, v2;
aiMtx4 dst;
aiVec4 v1, v2;
dst = simd4x4::transpose(mtx);
v1 = simd4_t<float,4>(mtx.m4x4()[3]);
v2 = simd4_t<float,4>(mtx.m4x4()[0]);
v1 = static_cast<aiVec4>(mtx.m4x4()[3]);
v2 = static_cast<aiVec4>(mtx.m4x4()[0]);
dst.ptr()[3][0] = -simd4::dot(v1, v2);
v2 = simd4_t<float,4>(mtx.m4x4()[1]);
v2 = static_cast<aiVec4>(mtx.m4x4()[1]);
dst.ptr()[3][1] = -simd4::dot(v1, v2);
v2 = simd4_t<float,4>(mtx.m4x4()[2]);
v2 = static_cast<aiVec4>(mtx.m4x4()[2]);
dst.ptr()[3][2] = -simd4::dot(v1, v2);
return dst;
}
simd4x4_t<float,4>
FGAISim::invert_inertia(simd4x4_t<float,4> mtx)
FGAISim::invert_inertia(aiMtx4 mtx)
{
float Ixx, Iyy, Izz, Ixz;
float k1, k3, k4, k6;
@ -565,10 +582,10 @@ FGAISim::invert_inertia(simd4x4_t<float,4> mtx)
k4 = (Izz*Ixx - Ixz*Ixz)*denom;
k6 = Ixx*Iyy*denom;
return simd4x4_t<float,4>( k1, 0.0f, k3, 0.0f,
0.0f, k4, 0.0f, 0.0f,
k3, 0.0f, k6, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f );
return aiMtx4( k1, 0.0f, k3, 0.0f,
0.0f, k4, 0.0f, 0.0f,
k3, 0.0f, k6, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f );
}
@ -623,7 +640,7 @@ FGAISim::load(std::string path)
/* thuster / propulsion */
// (FWD,RIGHT,DOWN)
simd4_t<float,3> dir(1.0f,0.0f,0.0f);
aiVec3 dir(1.0f,0.0f,0.0f);
no_engines = 1;
CTmax = 0.057f/144;
@ -642,7 +659,7 @@ FGAISim::load(std::string path)
/* aerodynamic coefficients */
CLmin = 0.307f;
CLa = 5.13f;
CLa = 4.72f;
CLadot = 1.70f;
CLq = 3.90f;
CLdf_n = 0.705f*df_max;
@ -658,23 +675,23 @@ FGAISim::load(std::string path)
CYr = 0.262f;
CYdr_n = 0.091f*dr_max;
Clb = -0.057f;
Clp = -0.613f;
Clr = 0.079f;
Clda_n = 0.170f*da_max;
Cldr_n = 0.01f*dr_max;
Clb = -0.322; // -0.057f;
Clp = -0.4840; // -0.613f;
Clr = 2.0f; // 0.079f;
Clda_n = 0.229f*da_max; // 0.170f*da_max;
Cldr_n = 0.0147f*dr_max; // 0.01f*dr_max;
Cma = -1.0f;
Cmadot = -4.42f;
Cmq = -10.5f;
Cmde_n = -1.05f*de_max;
Cmdf_n = -0.059f*df_max;
Cma = -1.8f; // -1.0f;
Cmadot = -7.27f; // -4.42f;
Cmq = -12.4f; // -10.5f;
Cmde_n = -1.122f*de_max; // -1.05f*de_max;
Cmdf_n = -0.2177f*df_max; // -0.059f*df_max;
Cnb = 0.0630f;
Cnp = -0.0028f;
Cnr = -0.0681f;
Cnda_n = -0.0100f*da_max;
Cndr_n = -0.0398f*dr_max;
Cnb = -0.0587f; // -0.0630f;
Cnp = -0.0278f; // -0.0028f;
Cnr = -0.0937f; // -0.0681f;
Cnda_n = -0.0053f*da_max; // -0.0100f*da_max;
Cndr_n = -0.043f*dr_max; // -0.0398f*dr_max;
return true;
}

View file

@ -2,7 +2,7 @@
//
// Written by Erik Hofman, started November 2016
//
// Copyright (C) 2016,2017 Erik Hofman <erik@ehofman.com>
// Copyright (C) 2016-2020 by Erik Hofman <erik@ehofman.com>
//
//
// This program is free software; you can redistribute it and/or
@ -71,6 +71,12 @@ private:
enum { P=0, Q=1, R=2 };
enum { U=0, V=1, W=2 };
using aiVec3d = simd4_t<double,3>;
using aiVec3 = simd4_t<float,3>;
using aiVec4 = simd4_t<float,4>;
using aiMtx4 = simd4x4_t<float,4>;
public:
FGAISim(double dt);
~FGAISim();
@ -107,56 +113,56 @@ public:
}
inline void set_flaps_norm(float f) {
xCDYLT.ptr()[FLAPS][LIFT] = -CLdf_n*f;
xCDYLT.ptr()[FLAPS][DRAG] = CDdf_n*std::abs(f);
xCDYLT.ptr()[FLAPS][DRAG] = -CDdf_n*std::abs(f);
xClmnT.ptr()[FLAPS][PITCH] = Cmdf_n*f;
}
inline void set_throttle_norm(float f) { th = f; }
inline void set_brake_norm(float f) { br = f; }
/* (initial) state, local frame */
inline void set_location_geod(const simd4_t<double,3>& p) {
inline void set_location_geod(aiVec3d& p) {
location_geod = p;
}
inline void set_location_geod(double lat, double lon, double alt) {
location_geod = simd4_t<double,3>(lat, lon, alt);
location_geod = aiVec3d(lat, lon, alt);
}
inline void set_altitude_asl_ft(float f) { location_geod[ALTITUDE] = f; };
inline void set_altitude_agl_ft(float f) { agl = f; }
inline void set_euler_angles_rad(const simd4_t<float,3>& e) {
inline void set_euler_angles_rad(const aiVec3& e) {
euler = e;
}
inline void set_euler_angles_rad(float phi, float theta, float psi) {
euler = simd4_t<float,3>(phi, theta, psi);
euler = aiVec3(phi, theta, psi);
}
inline void set_pitch_rad(float f) { euler[PHI] = f; }
inline void set_roll_rad(float f) { euler[THETA] = f; }
inline void set_heading_rad(float f) { euler[PSI] = f; }
void set_velocity_fps(const simd4_t<float,3>& v) { vUVW = v; }
void set_velocity_fps(const aiVec3& v) { vUVW = v; }
void set_velocity_fps(float u, float v, float w) {
vUVW = simd4_t<float,3>(u, v, w);
vUVW = aiVec3(u, v, w);
}
void set_velocity_fps(float u) {
vUVW = simd4_t<float,3>(u, 0.0f, 0.0f);
vUVW = aiVec3(u, 0.0f, 0.0f);
}
inline void set_wind_ned_fps(const simd4_t<float,3>& w) { wind_ned = w; }
inline void set_wind_ned_fps(const aiVec3& w) { wind_ned = w; }
inline void set_wind_ned_fps(float n, float e, float d) {
wind_ned = simd4_t<float,3>(n, e, d);
wind_ned = aiVec3(n, e, d);
}
inline void set_alpha_rad(float f) {
xCDYLT.ptr()[ALPHA][DRAG] = CDa*std::abs(f);
xCDYLT.ptr()[ALPHA][LIFT] = -CLa*f;
xCDYLT.ptr()[ALPHA][DRAG] = -CDa*std::abs(f);
xClmnT.ptr()[ALPHA][PITCH] = Cma*f;
AOA[ALPHA] = f;
}
inline void set_beta_rad(float f) {
xCDYLT.ptr()[BETA][DRAG] = CDb*std::abs(f);
xCDYLT.ptr()[BETA][DRAG] = -CDb*std::abs(f);
xCDYLT.ptr()[BETA][SIDE] = CYb*f;
xClmnT.ptr()[BETA][ROLL] = Clb*f;
xClmnT.ptr()[BETA][YAW] = Cnb*f;
xClmnT.ptr()[BETA][YAW] = -Cnb*f;
AOA[BETA] = f;
}
inline float get_alpha_rad() {
@ -168,26 +174,26 @@ public:
private:
void update_velocity(float v);
simd4x4_t<float,4> matrix_inverse(simd4x4_t<float,4> mtx);
simd4x4_t<float,4> invert_inertia(simd4x4_t<float,4> mtx);
aiMtx4 matrix_inverse(aiMtx4 mtx);
aiMtx4 invert_inertia(aiMtx4 mtx);
/* aircraft normalized controls */
float th; /* throttle command */
float br = 0.0f; /* brake command */
/* aircraft state */
simd4_t<double,3> location_geod; /* lat, lon, altitude */
simd4_t<float,3> aXYZ; /* local body accelrations */
simd4_t<float,3> NEDdot; /* North, East, Down velocity */
simd4_t<float,3> vUVW; /* fwd, side, down velocity */
simd4_t<float,3> vUVWdot; /* fwd, side, down accel. */
simd4_t<float,3> vPQR; /* roll, pitch, yaw rate */
simd4_t<float,3> vPQRdot; /* roll, pitch, yaw accel. */
simd4_t<float,3> AOA; /* alpha, beta */
simd4_t<float,3> AOAdot; /* adot, bdot */
simd4_t<float,3> euler; /* phi, theta, psi */
simd4_t<float,3> euler_dot; /* change in phi, theta, psi */
simd4_t<float,3> wind_ned; /* wind north, east, down */
aiVec3d location_geod; /* lat, lon, altitude */
aiVec3 aXYZ; /* local body accelrations */
aiVec3 NEDdot; /* North, East, Down velocity */
aiVec3 vUVW; /* fwd, side, down velocity */
aiVec3 vUVWdot; /* fwd, side, down accel. */
aiVec3 vPQR; /* roll, pitch, yaw rate */
aiVec3 vPQRdot; /* roll, pitch, yaw accel. */
aiVec3 AOA; /* alpha, beta */
aiVec3 AOAdot; /* adot, bdot */
aiVec3 euler; /* phi, theta, psi */
aiVec3 euler_dot; /* change in phi, theta, psi */
aiVec3 wind_ned; /* wind north, east, down */
/* ---------------------------------------------------------------- */
/* This should reduce the time spent in update() since controls */
@ -195,32 +201,32 @@ private:
/* run 20 to 60 times (or more) per second */
/* cache */
simd4_t<float,3> vUVWaero; /* airmass relative to the body */
simd4_t<float,3> FT[AISIM_MAX]; /* thrust force */
simd4_t<float,3> FTM[AISIM_MAX]; /* thrust due to mach force */
simd4_t<float,3> MT[AISIM_MAX]; /* thrust moment */
simd4_t<float,3> b_2U, cbar_2U;
simd4_t<float,3> inv_m;
aiVec3 vUVWaero; /* airmass relative to the body */
aiVec3 FT[AISIM_MAX]; /* thrust force */
aiVec3 FTM[AISIM_MAX]; /* thrust due to mach force */
aiVec3 MT[AISIM_MAX]; /* thrust moment */
aiVec3 b_2U, cbar_2U;
aiVec3 inv_m;
float velocity = 0.0f;
float mach = 0.0f;
float agl = 0.0f;
bool WoW = true;
/* dynamic coefficients (already multiplied with their value) */
simd4_t<float,3> xCq, xCadot, xCp, xCr;
simd4x4_t<float,4> xCDYLT;
simd4x4_t<float,4> xClmnT;
simd4_t<float,4> Coef2Force;
simd4_t<float,4> Coef2Moment;
aiVec3 xCq, xCadot, xCp, xCr;
aiMtx4 xCDYLT;
aiMtx4 xClmnT;
aiVec4 Coef2Force;
aiVec4 Coef2Moment;
/* ---------------------------------------------------------------- */
/* aircraft static data */
int no_engines = 0;
int no_gears = 0;
simd4x4_t<float,4> mI, mIinv; /* inertia matrix */
simd4_t<float,3> gear_pos[AISIM_MAX]; /* pos in structural frame */
simd4_t<float,3> cg; /* center of gravity */
simd4_t<float,4> I; /* inertia */
aiMtx4 mI, mIinv; /* inertia matrix */
aiVec3 gear_pos[AISIM_MAX]; /* pos in structural frame */
aiVec3 cg; /* center of gravity */
aiVec4 I; /* inertia */
float S = 0.0f; /* wing area */
float cbar = 0.0f; /* mean average chord */
float b = 0.0f; /* wing span */
@ -239,7 +245,7 @@ private:
/* environment data */
static float density[101], vsound[101];
simd4_t<float,3> gravity_ned;
aiVec3 gravity_ned;
float rho = 0.0f;
float qbar = 0.0f;
float sigma = 0.0f;