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()) {
double span = perfData->wingSpan();
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,
"Created mesh for " << ai->_getName() << " ID: #" << id);

View file

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

View file

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

View file

@ -25,13 +25,14 @@
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/SGVec3.hxx>
#include <simgear/debug/logstream.hxx>
#include "WakeMesh.hxx"
extern "C" {
#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)
{
double y1 = -0.5*span;
@ -59,7 +60,20 @@ WakeMesh::WakeMesh(double _span, double _chord)
}
// 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()

View file

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

View file

@ -367,7 +367,8 @@ FGJSBsim::FGJSBsim( double dt )
crashed = false;
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
FGTrim *fgtrim = new FGTrim(fdmex,tFull);