diff --git a/src/FDM/AIWake/AIWakeGroup.cxx b/src/FDM/AIWake/AIWakeGroup.cxx index eb6451b2a..7dab53f8c 100644 --- a/src/FDM/AIWake/AIWakeGroup.cxx +++ b/src/FDM/AIWake/AIWakeGroup.cxx @@ -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); diff --git a/src/FDM/AIWake/AircraftMesh.cxx b/src/FDM/AIWake/AircraftMesh.cxx index 7bc9994b5..286f40820 100644 --- a/src/FDM/AIWake/AircraftMesh.cxx +++ b/src/FDM/AIWake/AircraftMesh.cxx @@ -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()); diff --git a/src/FDM/AIWake/AircraftMesh.hxx b/src/FDM/AIWake/AircraftMesh.hxx index 1cbf496d8..02932c5a9 100644 --- a/src/FDM/AIWake/AircraftMesh.hxx +++ b/src/FDM/AIWake/AircraftMesh.hxx @@ -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; }; diff --git a/src/FDM/AIWake/WakeMesh.cxx b/src/FDM/AIWake/WakeMesh.cxx index 57dd7c356..4259f4875 100644 --- a/src/FDM/AIWake/WakeMesh.cxx +++ b/src/FDM/AIWake/WakeMesh.cxx @@ -25,13 +25,14 @@ #include #include +#include #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() diff --git a/src/FDM/AIWake/WakeMesh.hxx b/src/FDM/AIWake/WakeMesh.hxx index 2c2a63708..e845ee2ba 100644 --- a/src/FDM/AIWake/WakeMesh.hxx +++ b/src/FDM/AIWake/WakeMesh.hxx @@ -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; diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index 27f277da0..2d6aec5d7 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -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);