1
0
Fork 0

Sync'ed JSBSim

- Trim reports, FGOutputFG and sockets messages now respond to the debug level
- Channels : fix for incorrect time steps caused by execrate
- Improved configuration error detection in FGSwitch with respect to late bound
- Fixed the ordre in which the components of the p-factor moment are reported in CSV output files.
This commit is contained in:
Bertrand Coconnier 2018-07-20 23:38:33 +02:00
parent af380e0d8c
commit ec004d8c6b
13 changed files with 134 additions and 144 deletions

View file

@ -1142,6 +1142,8 @@ void FGFDMExec::DoTrim(int mode)
FGTrim trim(this, (JSBSim::TrimMode)mode);
bool success = trim.DoTrim();
if (debug_lvl > 0)
trim.Report();
if (!success)

View file

@ -122,6 +122,26 @@ FGOutputFG::FGOutputFG(FGFDMExec* fdmex) :
FGOutputSocket(fdmex)
{
memset(&fgSockBuf, 0x0, sizeof(fgSockBuf));
if (fdmex->GetDebugLevel() > 0) {
// Engine status
if (Propulsion->GetNumEngines() > FGNetFDM::FG_MAX_ENGINES)
cerr << "This vehicle has " << Propulsion->GetNumEngines() << " engines, but the current " << endl
<< "version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_ENGINES << " engines." << endl
<< "Only the first " << FGNetFDM::FG_MAX_ENGINES << " engines will be used." << endl;
// Consumables
if (Propulsion->GetNumTanks() > FGNetFDM::FG_MAX_TANKS)
cerr << "This vehicle has " << Propulsion->GetNumTanks() << " tanks, but the current " << endl
<< "version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_TANKS << " tanks." << endl
<< "Only the first " << FGNetFDM::FG_MAX_TANKS << " tanks will be used." << endl;
// Gear status
if (GroundReactions->GetNumGearUnits() > FGNetFDM::FG_MAX_WHEELS)
cerr << "This vehicle has " << GroundReactions->GetNumGearUnits() << " bogeys, but the current " << endl
<< "version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_WHEELS << " bogeys." << endl
<< "Only the first " << FGNetFDM::FG_MAX_WHEELS << " bogeys will be used." << endl;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -169,12 +189,6 @@ void FGOutputFG::SocketDataFill(FGNetFDM* net)
net->stall_warning = 0.0; // 0.0 - 1.0 indicating the amount of stall
net->slip_deg = (float)(Auxiliary->Getbeta(inDegrees)); // slip ball deflection, deg
// Engine status
if (Propulsion->GetNumEngines() > FGNetFDM::FG_MAX_ENGINES && FDMExec->GetSimTime() == 0.0)
cerr << "This vehicle has " << Propulsion->GetNumEngines() << " engines, but the current " << endl
<< "version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_ENGINES << " engines." << endl
<< "Only the first " << FGNetFDM::FG_MAX_ENGINES << " engines will be used." << endl;
net->num_engines = min(FGNetFDM::FG_MAX_ENGINES,Propulsion->GetNumEngines()); // Number of valid engines
for (i=0; i<net->num_engines; i++) {
@ -210,24 +224,12 @@ void FGOutputFG::SocketDataFill(FGNetFDM* net)
}
}
// Consumables
if (Propulsion->GetNumTanks() > FGNetFDM::FG_MAX_TANKS && FDMExec->GetSimTime() == 0.0)
cerr << "This vehicle has " << Propulsion->GetNumTanks() << " tanks, but the current " << endl
<< "version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_TANKS << " tanks." << endl
<< "Only the first " << FGNetFDM::FG_MAX_TANKS << " tanks will be used." << endl;
net->num_tanks = min(FGNetFDM::FG_MAX_TANKS, Propulsion->GetNumTanks()); // Max number of fuel tanks
for (i=0; i<net->num_tanks; i++) {
net->fuel_quantity[i] = (float)(((FGTank *)Propulsion->GetTank(i))->GetContents());
}
// Gear status
if (GroundReactions->GetNumGearUnits() > FGNetFDM::FG_MAX_WHEELS && FDMExec->GetSimTime() == 0.0)
cerr << "This vehicle has " << GroundReactions->GetNumGearUnits() << " bogeys, but the current " << endl
<< "version of FlightGear's FGNetFDM only supports " << FGNetFDM::FG_MAX_WHEELS << " bogeys." << endl
<< "Only the first " << FGNetFDM::FG_MAX_WHEELS << " bogeys will be used." << endl;
net->num_wheels = min(FGNetFDM::FG_MAX_WHEELS, GroundReactions->GetNumGearUnits());
for (i=0; i<net->num_wheels; i++) {

View file

@ -62,15 +62,17 @@ CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#if defined(_MSC_VER) || defined(__MINGW32__)
static bool LoadWinSockDLL(void)
static bool LoadWinSockDLL(int debug_lvl)
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData)) {
cout << "Winsock DLL not initialized ..." << endl;
cerr << "Winsock DLL not initialized ..." << endl;
return false;
}
if (debug_lvl > 0)
cout << "Winsock DLL loaded ..." << endl;
return true;
}
#endif
@ -82,28 +84,34 @@ FGfdmSocket::FGfdmSocket(const string& address, int port, int protocol)
connected = false;
#if defined(_MSC_VER) || defined(__MINGW32__)
if (!LoadWinSockDLL()) return;
if (!LoadWinSockDLL(debug_lvl)) return;
#endif
if (!is_number(address)) {
if ((host = gethostbyname(address.c_str())) == NULL) {
cout << "Could not get host net address by name..." << endl;
host = gethostbyname(address.c_str());
if (host == NULL) {
cerr << "Could not get host net address by name..." << endl;
return;
}
} else {
unsigned long ip;
ip = inet_addr(address.c_str());
if ((host = gethostbyaddr((char*)&ip, sizeof(ip), PF_INET)) == NULL) {
cout << "Could not get host net address by number..." << endl;
unsigned long ip = inet_addr(address.c_str());
host = gethostbyaddr((char*)&ip, sizeof(ip), PF_INET);
if (host == NULL) {
cerr << "Could not get host net address by number..." << endl;
return;
}
}
if (host != NULL) {
if (protocol == ptUDP) { //use udp protocol
sckt = socket(AF_INET, SOCK_DGRAM, 0);
if (debug_lvl > 0)
cout << "Creating UDP socket on port " << port << endl;
}
else { //use tcp protocol
sckt = socket(AF_INET, SOCK_STREAM, 0);
if (debug_lvl > 0)
cout << "Creating TCP socket on port " << port << endl;
}
@ -112,18 +120,17 @@ FGfdmSocket::FGfdmSocket(const string& address, int port, int protocol)
scktName.sin_family = AF_INET;
scktName.sin_port = htons(port);
memcpy(&scktName.sin_addr, host->h_addr_list[0], host->h_length);
int len = sizeof(struct sockaddr_in);
if (connect(sckt, (struct sockaddr*)&scktName, len) == 0) { // successful
if (debug_lvl > 0)
cout << "Successfully connected to socket for output ..." << endl;
connected = true;
} else { // unsuccessful
cout << "Could not connect to socket for output ..." << endl;
}
} else { // unsuccessful
cout << "Could not create socket for FDM output, error = " << errno << endl;
}
} else // unsuccessful
cerr << "Could not connect to socket for output ..." << endl;
} else // unsuccessful
cerr << "Could not create socket for FDM output, error = " << errno << endl;
}
Debug(0);
}
@ -137,7 +144,7 @@ FGfdmSocket::FGfdmSocket(int port, int protocol)
string ProtocolName;
#if defined(_MSC_VER) || defined(__MINGW32__)
if (!LoadWinSockDLL()) return;
if (!LoadWinSockDLL(debug_lvl)) return;
#endif
if (Protocol == ptUDP) { //use udp protocol
@ -154,18 +161,25 @@ FGfdmSocket::FGfdmSocket(int port, int protocol)
ProtocolName = "TCP";
sckt = socket(AF_INET, SOCK_STREAM, 0);
}
cout << "Creating input " << ProtocolName << " socket on port " << port << endl;
if (debug_lvl > 0)
cout << "Creating input " << ProtocolName << " socket on port " << port
<< endl;
if (sckt != -1) {
memset(&scktName, 0, sizeof(struct sockaddr_in));
scktName.sin_family = AF_INET;
scktName.sin_port = htons(port);
if (Protocol == ptUDP)
scktName.sin_addr.s_addr = htonl(INADDR_ANY);
int len = sizeof(struct sockaddr_in);
if (bind(sckt, (struct sockaddr*)&scktName, len) != -1) {
cout << "Successfully bound to " << ProtocolName << " input socket on port "
<< port << endl <<endl;
if (debug_lvl > 0)
cout << "Successfully bound to " << ProtocolName
<< " input socket on port " << port << endl << endl;
if (Protocol == ptTCP) {
unsigned long NoBlock = true;
if (listen(sckt, 5) >= 0) { // successful listen()
@ -177,74 +191,22 @@ FGfdmSocket::FGfdmSocket(int port, int protocol)
sckt_in = accept(sckt, (struct sockaddr*)&scktName, (socklen_t*)&len);
#endif
connected = true;
} else {
} else
cerr << "Could not listen ..." << endl;
}
} else
connected = true;
} else { // unsuccessful
cout << "Could not bind to " << ProtocolName << " input socket, error = "
} else // unsuccessful
cerr << "Could not bind to " << ProtocolName << " input socket, error = "
<< errno << endl;
}
} else { // unsuccessful
cout << "Could not create " << ProtocolName << " socket for input, error = "
} else // unsuccessful
cerr << "Could not create " << ProtocolName << " socket for input, error = "
<< errno << endl;
}
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGfdmSocket::FGfdmSocket(const string& address, int port) // assumes TCP
{
sckt = sckt_in = 0;
connected = false;
Protocol = ptTCP;
#if defined(_MSC_VER) || defined(__MINGW32__)
if (!LoadWinSockDLL()) return;
#endif
cout << "... Socket Configuration Sanity Check ..." << endl;
cout << "Host name... " << address << ", Port... " << port << "." << endl;
cout << "Host name... (char) " << address.c_str() << "." << endl;
if (!is_number(address)) {
if ((host = gethostbyname(address.c_str())) == NULL) {
cout << "Could not get host net address by name..." << endl;
}
} else {
if ((host = gethostbyaddr(address.c_str(), address.size(), PF_INET)) == NULL) {
cout << "Could not get host net address by number..." << endl;
}
}
if (host != NULL) {
cout << "Got host net address..." << endl;
sckt = socket(AF_INET, SOCK_STREAM, 0);
if (sckt >= 0) { // successful
memset(&scktName, 0, sizeof(struct sockaddr_in));
scktName.sin_family = AF_INET;
scktName.sin_port = htons(port);
memcpy(&scktName.sin_addr, host->h_addr_list[0], host->h_length);
int len = sizeof(struct sockaddr_in);
if (connect(sckt, (struct sockaddr*)&scktName, len) == 0) { // successful
cout << "Successfully connected to socket for output ..." << endl;
connected = true;
} else { // unsuccessful
cout << "Could not connect to socket for output ..." << endl;
}
} else { // unsuccessful
cout << "Could not create socket for FDM output, error = " << errno << endl;
}
}
Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGfdmSocket::~FGfdmSocket()
{
if (sckt) shutdown(sckt,2);
@ -391,6 +353,16 @@ void FGfdmSocket::Send(const char *data, int length)
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGfdmSocket::WaitUntilReadable(void)
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(sckt_in, &fds);
select(sckt_in+1, &fds, NULL, NULL, NULL);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -83,7 +83,8 @@ CLASS DECLARATION
class FGfdmSocket : public FGJSBBase
{
public:
FGfdmSocket(const std::string&, int);
FGfdmSocket(const std::string& address, int port)
: FGfdmSocket(address, port, ptTCP) {}
FGfdmSocket(const std::string&, int, int);
FGfdmSocket(int, int);
~FGfdmSocket();
@ -100,6 +101,7 @@ public:
void Clear(const std::string& s);
void Close(void);
bool GetConnectStatus(void) {return connected;}
void WaitUntilReadable(void);
enum ProtocolType {ptUDP, ptTCP};

View file

@ -149,14 +149,14 @@ bool FGAuxiliary::Run(bool Holding)
vAeroPQR = in.vPQR - in.TurbPQR;
vAeroUVW = in.vUVW - in.Tl2b * in.TotalWindNED;
Vt = vAeroUVW.Magnitude();
alpha = beta = adot = bdot = 0;
double AeroU2 = vAeroUVW(eU)*vAeroUVW(eU);
double AeroV2 = vAeroUVW(eV)*vAeroUVW(eV);
double AeroW2 = vAeroUVW(eW)*vAeroUVW(eW);
double mUW = AeroU2 + AeroW2;
double Vt2 = Vt*Vt;
double Vt2 = mUW + AeroV2;
Vt = sqrt(Vt2);
if ( Vt > 0.001 ) {
if (vAeroUVW(eW) != 0.0)
@ -206,11 +206,9 @@ bool FGAuxiliary::Run(bool Holding)
if (abs(Mach) > 0.0) {
vcas = VcalibratedFromMach(Mach, in.Pressure, in.PressureSL, in.DensitySL);
veas = sqrt(2 * qbar / in.DensitySL);
vtrue = 1116.43559 * Mach * sqrt(in.Temperature / 518.67);
}
else {
vcas = veas = vtrue = 0.0;
}
else
vcas = veas = 0.0;
vPilotAccel.InitMatrix();
vNcg = in.vBodyAccel/in.SLGravity;

View file

@ -131,9 +131,9 @@ public:
/** Returns equivalent airspeed in knots. */
double GetVequivalentKTS(void) const { return veas*fpstokts; }
/** Returns the true airspeed in feet per second. */
double GetVtrueFPS() const { return vtrue; }
double GetVtrueFPS() const { return Vt; }
/** Returns the true airspeed in knots. */
double GetVtrueKTS() const { return vtrue * fpstokts; }
double GetVtrueKTS() const { return Vt * fpstokts; }
/** Returns the total pressure.
Total pressure is freestream total pressure for
@ -290,7 +290,7 @@ public:
} in;
private:
double vcas, veas, vtrue;
double vcas, veas;
double pt, tat, tatc; // Don't add a getter for pt!
FGMatrix33 mTw2b;

View file

@ -503,9 +503,10 @@ bool FGFCS::Load(Element* document)
string sOnOffProperty = channel_element->GetAttributeValue("execute");
string sChannelName = channel_element->GetAttributeValue("name");
int Rate = 0;
if (!channel_element->GetAttributeValue("execrate").empty())
Rate = channel_element->GetAttributeValueAsNumber("execrate");
ChannelRate = channel_element->GetAttributeValueAsNumber("execrate");
else
ChannelRate = 1;
if (sOnOffProperty.length() > 0) {
FGPropertyNode* OnOffPropertyNode = PropertyManager->GetNode(sOnOffProperty);
@ -516,10 +517,10 @@ bool FGFCS::Load(Element* document)
<< "understood. The simulation will abort" << reset << endl;
throw("Bad system definition");
} else
newChannel = new FGFCSChannel(this, sChannelName, Rate,
newChannel = new FGFCSChannel(this, sChannelName, ChannelRate,
OnOffPropertyNode);
} else
newChannel = new FGFCSChannel(this, sChannelName, Rate);
newChannel = new FGFCSChannel(this, sChannelName, ChannelRate);
SystemChannels.push_back(newChannel);

View file

@ -92,7 +92,6 @@ public:
/// Adds a component to a channel
void Add(FGFCSComponent* comp) {
FCSComponents.push_back(comp);
comp->SetDtForFrameCount(ExecRate);
}
/// Returns the number of components in the channel.
size_t GetNumComponents() {return FCSComponents.size();}

View file

@ -63,7 +63,7 @@ FGFCSComponent::FGFCSComponent(FGFCS* _fcs, Element* element) : fcs(_fcs)
clipMinSign = clipMaxSign = 1.0;
IsOutput = clip = false;
string input,init, clip_string;
dt = fcs->GetDt();
dt = fcs->GetChannelDeltaT();
PropertyManager = fcs->GetPropertyManager();
if (element->GetName() == string("lag_filter")) {
@ -250,13 +250,6 @@ void FGFCSComponent::SetOutput(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCSComponent::SetDtForFrameCount(int FrameCount)
{
dt = fcs->GetDt() * FrameCount;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCSComponent::Delay(void)
{
output_array[index] = Output;

View file

@ -94,7 +94,6 @@ public:
virtual bool Run(void) { return true; }
virtual void SetOutput(void);
void SetDtForFrameCount(int FrameCount);
double GetOutput (void) const {return Output;}
std::string GetName(void) const {return Name;}
std::string GetType(void) const { return Type; }

View file

@ -135,6 +135,13 @@ bool FGSwitch::Run(void )
bool pass = false;
double default_output=0.0;
// To detect errors early, make sure all conditions and values can be
// evaluated in the first time step.
if (!initialized) {
initialized = true;
VerifyProperties();
}
for (unsigned int i=0; i<tests.size(); i++) {
if (tests[i]->Default) {
default_output = tests[i]->GetValue();
@ -157,6 +164,18 @@ bool FGSwitch::Run(void )
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGSwitch::VerifyProperties(void)
{
for (unsigned int i=0; i<tests.size(); i++) {
if (!tests[i]->Default) {
tests[i]->condition->Evaluate();
}
tests[i]->GetValue();
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -193,7 +193,9 @@ private:
};
std::vector <test*> tests;
bool initialized = false;
void VerifyProperties(void);
void Debug(int from);
};
}

View file

@ -363,12 +363,13 @@ double FGPropeller::GetPowerRequired(void)
FGColumnVector3 FGPropeller::GetPFactor() const
{
double px=0.0, py, pz;
// These are moments in lbf per ft : the lever arm along Z generates a moment
// along the pitch direction.
double p_pitch = Thrust * Sense * (GetActingLocationZ() - GetLocationZ()) / 12.0;
// The lever arm along Y generates a moment along the yaw direction.
double p_yaw = Thrust * Sense * (GetActingLocationY() - GetLocationY()) / 12.0;
py = Thrust * Sense * (GetActingLocationY() - GetLocationY()) / 12.0;
pz = Thrust * Sense * (GetActingLocationZ() - GetLocationZ()) / 12.0;
return FGColumnVector3(px, py, pz);
return FGColumnVector3(0.0, p_pitch, p_yaw);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%