1
0
Fork 0

Intercept errors in the matrix inversion routine and report the faulty aircraft in the log.

This commit is contained in:
Bertrand Coconnier 2022-04-16 13:45:10 +02:00
parent 3441c5ef3a
commit 83cad5797e
6 changed files with 24 additions and 8 deletions

View file

@ -47,7 +47,8 @@ void AIWakeGroup::AddAI(FGAIAircraft* ai)
if (_aiWakeData.find(id) == _aiWakeData.end()) { if (_aiWakeData.find(id) == _aiWakeData.end()) {
double span = perfData->wingSpan(); double span = perfData->wingSpan();
double chord = perfData->wingChord(); double chord = perfData->wingChord();
_aiWakeData[id] = AIWakeData(new WakeMesh(span, chord)); _aiWakeData[id] = AIWakeData(new WakeMesh(span, chord,
std::string("AI:") + ai->_getName()));
SG_LOG(SG_FLIGHT, SG_DEV_ALERT, SG_LOG(SG_FLIGHT, SG_DEV_ALERT,
"Created mesh for " << ai->_getName() << " ID: #" << id); "Created mesh for " << ai->_getName() << " ID: #" << id);

View file

@ -37,8 +37,8 @@ extern "C" {
#include "../LaRCsim/ls_matrix.h" #include "../LaRCsim/ls_matrix.h"
} }
AircraftMesh::AircraftMesh(double _span, double _chord) AircraftMesh::AircraftMesh(double _span, double _chord, const std::string& name)
: WakeMesh(_span, _chord) : WakeMesh(_span, _chord, name)
{ {
collPt.resize(nelm, SGVec3d::zeros()); collPt.resize(nelm, SGVec3d::zeros());
midPt.resize(nelm, SGVec3d::zeros()); midPt.resize(nelm, SGVec3d::zeros());

View file

@ -32,7 +32,7 @@ class AIWakeGroup;
class AircraftMesh : public WakeMesh { class AircraftMesh : public WakeMesh {
public: public:
AircraftMesh(double _span, double _chord); AircraftMesh(double _span, double _chord, const std::string& name);
void setPosition(const SGVec3d& pos, const SGQuatd& orient); void setPosition(const SGVec3d& pos, const SGQuatd& orient);
SGVec3d GetForce(const AIWakeGroup& wg, const SGVec3d& vel, double rho); SGVec3d GetForce(const AIWakeGroup& wg, const SGVec3d& vel, double rho);
const SGVec3d& GetMoment(void) const { return moment; }; const SGVec3d& GetMoment(void) const { return moment; };

View file

@ -25,13 +25,14 @@
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/SGVec3.hxx> #include <simgear/math/SGVec3.hxx>
#include <simgear/debug/logstream.hxx>
#include "WakeMesh.hxx" #include "WakeMesh.hxx"
extern "C" { extern "C" {
#include "../LaRCsim/ls_matrix.h" #include "../LaRCsim/ls_matrix.h"
} }
WakeMesh::WakeMesh(double _span, double _chord) WakeMesh::WakeMesh(double _span, double _chord, const std::string& aircraft_name)
: nelm(10), span(_span), chord(_chord) : nelm(10), span(_span), chord(_chord)
{ {
double y1 = -0.5*span; double y1 = -0.5*span;
@ -59,7 +60,20 @@ WakeMesh::WakeMesh(double _span, double _chord)
} }
// Compute the inverse matrix with the Gauss-Jordan algorithm // Compute the inverse matrix with the Gauss-Jordan algorithm
nr_gaussj(influenceMtx, nelm, 0, 0); int ret = nr_gaussj(influenceMtx, nelm, nullptr, 0);
if (ret) {
// Something went wrong with the matrix inversion.
// 1. Nullify the influence matrix to disable the current aircraft wake.
for (int i=0; i < nelm; ++i) {
for (int j=0; j < nelm; ++j)
influenceMtx[i+1][j+1] = 0.0;
}
// 2. Report the issue in the log.
SG_LOG(SG_FLIGHT, SG_WARN,
"Failed to build wake mesh. " << aircraft_name << " ( span:"
<< _span << ", chord:" << _chord << ") wake will be ignored.");
}
} }
WakeMesh::~WakeMesh() WakeMesh::~WakeMesh()

View file

@ -30,7 +30,7 @@ namespace FGTestApi { namespace PrivateAccessor { namespace FDM { class Accessor
class WakeMesh : public SGReferenced { class WakeMesh : public SGReferenced {
public: public:
WakeMesh(double _span, double _chord); WakeMesh(double _span, double _chord, const std::string& aircraft_name);
virtual ~WakeMesh(); virtual ~WakeMesh();
double computeAoA(double vel, double rho, double weight); double computeAoA(double vel, double rho, double weight);
SGVec3d getInducedVelocityAt(const SGVec3d& at) const; SGVec3d getInducedVelocityAt(const SGVec3d& at) const;

View file

@ -367,7 +367,8 @@ FGJSBsim::FGJSBsim( double dt )
crashed = false; crashed = false;
mesh = new AircraftMesh(fgGetDouble("/fdm/jsbsim/metrics/bw-ft"), mesh = new AircraftMesh(fgGetDouble("/fdm/jsbsim/metrics/bw-ft"),
fgGetDouble("/fdm/jsbsim/metrics/cbarw-ft")); fgGetDouble("/fdm/jsbsim/metrics/cbarw-ft"),
fdmex->GetModelName());
// Trim once to initialize all output parameters // Trim once to initialize all output parameters
FGTrim *fgtrim = new FGTrim(fdmex,tFull); FGTrim *fgtrim = new FGTrim(fdmex,tFull);