56#include "FGAccelerations.h"
58#include "input_output/FGLog.h"
72 Name =
"FGAccelerations";
75 vPQRidot.InitMatrix();
76 vUVWidot.InitMatrix();
78 vBodyAccel.InitMatrix();
95 if (!FGModel::InitModel())
return false;
97 vPQRidot.InitMatrix();
98 vUVWidot.InitMatrix();
100 vBodyAccel.InitMatrix();
113 if (Holding)
return false;
119 CalculateFrictionForces(in.
DeltaT * rate);
139void FGAccelerations::CalculatePQRdot(
void)
158 vPQRdot.InitMatrix();
184void FGAccelerations::CalculateUVWdot(
void)
186 if (FDMExec->
GetHoldDown() && !FDMExec->GetTrimStatus())
187 vBodyAccel.InitMatrix();
200 vUVWdot.InitMatrix();
214 vUVWdot.InitMatrix();
215 vPQRdot.InitMatrix();
233void FGAccelerations::CalculateFrictionForces(
double dt)
236 size_t n = multipliers.size();
238 vFrictionForces.InitMatrix();
239 vFrictionMoments.InitMatrix();
244 vector<double> a(n*n);
245 vector<double> rhs(n);
248 for (
unsigned int i=0; i < n; i++) {
254 for (
unsigned int j=0; j < i; j++)
257 for (
unsigned int j=i; j < n; j++) {
258 U = multipliers[j]->ForceJacobian;
259 r = multipliers[j]->LeverArm;
267 FGColumnVector3 vdot = vUVWdot;
272 FGColumnVector3 wdot = vPQRdot;
280 for (
unsigned int i=0; i < n; i++) {
282 FGColumnVector3 U = multipliers[i]->ForceJacobian;
283 FGColumnVector3 r = multipliers[i]->LeverArm;
287 for (
unsigned int j=0; j < n; j++)
292 for (
int iter=0; iter < 50; iter++) {
295 for (
unsigned int i=0; i < n; i++) {
296 double lambda0 = multipliers[i]->value;
297 double dlambda = rhs[i];
299 for (
unsigned int j=0; j < n; j++)
300 dlambda -= a[i*n+j]*multipliers[j]->value;
302 multipliers[i]->value =
Constrain(multipliers[i]->Min, lambda0+dlambda, multipliers[i]->Max);
303 dlambda = multipliers[i]->value - lambda0;
305 norm += fabs(dlambda);
308 if (norm < 1E-5)
break;
313 for (
unsigned int i=0; i< n; i++) {
314 double lambda = multipliers[i]->value;
315 FGColumnVector3 U = multipliers[i]->ForceJacobian;
316 FGColumnVector3 r = multipliers[i]->LeverArm;
318 FGColumnVector3 F = lambda * U;
319 vFrictionForces += F;
320 vFrictionMoments += r * F;
323 FGColumnVector3 accel = vFrictionForces / in.
Mass;
324 FGColumnVector3 omegadot = in.
Jinv * vFrictionMoments;
328 vUVWidot += in.
Tb2i * accel;
330 vPQRidot += omegadot;
340 CalculateFrictionForces(0.);
345void FGAccelerations::bind(
void)
363 PropertyManager->Tie(
"accelerations/gravity-ft_sec2",
this, &FGAccelerations::GetGravAccelMagnitude);
364 PropertyManager->Tie(
"simulation/gravitational-torque", &gravTorque);
365 PropertyManager->Tie(
"forces/fbx-weight-lbs",
this, eX, &FGAccelerations::GetWeight);
366 PropertyManager->Tie(
"forces/fby-weight-lbs",
this, eY, &FGAccelerations::GetWeight);
367 PropertyManager->Tie(
"forces/fbz-weight-lbs",
this, eZ, &FGAccelerations::GetWeight);
369 PropertyManager->Tie(
"forces/fbx-total-lbs",
this, eX, &FGAccelerations::GetForces);
370 PropertyManager->Tie(
"forces/fby-total-lbs",
this, eY, &FGAccelerations::GetForces);
371 PropertyManager->Tie(
"forces/fbz-total-lbs",
this, eZ, &FGAccelerations::GetForces);
372 PropertyManager->Tie(
"moments/l-total-lbsft",
this, eL, &FGAccelerations::GetMoments);
373 PropertyManager->Tie(
"moments/m-total-lbsft",
this, eM, &FGAccelerations::GetMoments);
374 PropertyManager->Tie(
"moments/n-total-lbsft",
this, eN, &FGAccelerations::GetMoments);
376 PropertyManager->Tie(
"moments/l-gear-lbsft",
this, eL, &FGAccelerations::GetGroundMoments);
377 PropertyManager->Tie(
"moments/m-gear-lbsft",
this, eM, &FGAccelerations::GetGroundMoments);
378 PropertyManager->Tie(
"moments/n-gear-lbsft",
this, eN, &FGAccelerations::GetGroundMoments);
379 PropertyManager->Tie(
"forces/fbx-gear-lbs",
this, eX, &FGAccelerations::GetGroundForces);
380 PropertyManager->Tie(
"forces/fby-gear-lbs",
this, eY, &FGAccelerations::GetGroundForces);
381 PropertyManager->Tie(
"forces/fbz-gear-lbs",
this, eZ, &FGAccelerations::GetGroundForces);
403void FGAccelerations::Debug(
int from)
405 if (debug_lvl <= 0)
return;
412 if (debug_lvl & 2 ) {
413 FGLogging log(LogLevel::DEBUG);
414 if (from == 0) log <<
"Instantiated: FGAccelerations\n";
415 if (from == 1) log <<
"Destroyed: FGAccelerations\n";
417 if (debug_lvl & 4 ) {
419 if (debug_lvl & 8 && from == 2) {
421 if (debug_lvl & 16) {
423 if (debug_lvl & 64) {
void InitializeDerivatives(void)
Initializes the FGAccelerations class prior to a new execution.
const FGColumnVector3 & GetUVWidot(void) const
Retrieves the body axis acceleration in the ECI frame.
const FGColumnVector3 & GetUVWdot(void) const
Retrieves the body axis acceleration.
FGAccelerations(FGFDMExec *Executive)
Constructor.
~FGAccelerations()
Destructor.
bool Run(bool Holding) override
Runs the state propagation model; called by the Executive Can pass in a value indicating if the execu...
bool InitModel(void) override
Initializes the FGAccelerations class after instantiation and prior to first execution.
const FGColumnVector3 & GetPQRdot(void) const
Retrieves the body axis angular acceleration vector.
const FGColumnVector3 & GetPQRidot(void) const
Retrieves the axis angular acceleration vector in the ECI frame.
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
This class implements a 3 element column vector.
double Magnitude(void) const
Length of the vector.
Encapsulates the JSBSim simulation executive.
bool GetHoldDown(void) const
Gets the value of the property forces/hold-down.
static constexpr double Constrain(double min, double value, double max)
Constrain a value between a minimum and a maximum value.
Base class for all scheduled JSBSim models.
virtual bool Run(bool Holding)
Runs the model; called by the Executive.
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...