Intercept errors in the matrix inversion routine and report the faulty aircraft in the log.
This commit is contained in:
parent
3441c5ef3a
commit
83cad5797e
6 changed files with 24 additions and 8 deletions
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue