1
0
Fork 0

YASim bugfix: XML processing failed if <control-speed> appeared before <control-input> in XML file.

This commit is contained in:
Henning Stahlke 2018-01-10 20:55:31 +01:00
parent 451f41fe0c
commit cbd5cb916f
3 changed files with 122 additions and 94 deletions

View file

@ -21,25 +21,70 @@
#include "ControlMap.hpp" #include "ControlMap.hpp"
namespace yasim { namespace yasim {
//! keep this list in sync with the enum Control in ControlMap.hpp !
static const std::vector<std::string> ControlNames = {
"THROTTLE",
"MIXTURE",
"CONDLEVER",
"STARTER",
"MAGNETOS",
"ADVANCE",
"REHEAT",
"PROP",
"BRAKE",
"STEER",
"EXTEND",
"HEXTEND",
"LEXTEND",
"LACCEL",
"INCIDENCE",
"FLAP0",
"FLAP1",
"SLAT",
"SPOILER",
"VECTOR",
"FLAP0EFFECTIVENESS",
"FLAP1EFFECTIVENESS",
"BOOST",
"CASTERING",
"PROPPITCH",
"PROPFEATHER",
"COLLECTIVE",
"CYCLICAIL",
"CYCLICELE",
"ROTORGEARENGINEON",
"TILTYAW",
"TILTPITCH",
"TILTROLL",
"ROTORBRAKE",
"ROTORENGINEMAXRELTORQUE",
"ROTORRELTARGET",
"ROTORBALANCE",
"REVERSE_THRUST",
"WASTEGATE",
"WINCHRELSPEED",
"HITCHOPEN",
"PLACEWINCH",
"FINDAITOW"
}; //! keep this list in sync with the enum Control in ControlMap.hpp !
ControlMap::~ControlMap() ControlMap::~ControlMap()
{ {
int i; for(int i=0; i<_inputs.size(); i++) {
for(i=0; i<_inputs.size(); i++) { Vector* v = (Vector*)_inputs.get(i);
Vector* v = (Vector*)_inputs.get(i); for(int j=0; j<v->size(); j++)
int j; delete (MapRec*)v->get(j);
for(j=0; j<v->size(); j++) delete v;
delete (MapRec*)v->get(j); }
delete v;
}
for(i=0; i<_outputs.size(); i++) for(int i=0; i<_outputs.size(); i++)
delete (OutRec*)_outputs.get(i); delete (OutRec*)_outputs.get(i);
for(i=0; i<_properties.size(); i++) { for(int i=0; i<_properties.size(); i++) {
PropHandle* p = (PropHandle*)_properties.get(i); PropHandle* p = (PropHandle*)_properties.get(i);
delete[] p->name; delete[] p->name;
delete p; delete p;
} }
} }
/** /**
@ -65,27 +110,9 @@ options: bits OPT_INVERT, OPT_SPLIT, OPT_SQUARE
*/ */
void* ControlMap::addMapping(const char* prop, Control control, ObjectID id, int options) void* ControlMap::addMapping(const char* prop, Control control, ObjectID id, int options)
{ {
int inputPropHandle = getInputPropertyHandle(prop);
// See if the output object already exists // See if the output object already exists
OutRec* out {nullptr}; OutRec* out {nullptr};
int i; out = getOutRec(id, control);
for(i = 0; i < _outputs.size(); i++) {
OutRec* o = (OutRec*)_outputs.get(i);
if(o->oid.object == id.object && o->oid.subObj == id.subObj
&& o->control == control)
{
out = o;
break;
}
}
// Create one if it doesn't
if(out == nullptr) {
out = new OutRec();
out->control = control;
out->oid = id;
_outputs.add(out);
}
// Make a new input record // Make a new input record
MapRec* map = new MapRec(); MapRec* map = new MapRec();
@ -98,11 +125,35 @@ void* ControlMap::addMapping(const char* prop, Control control, ObjectID id, int
map->src0 = map->dst0 = rangeMin(control); map->src0 = map->dst0 = rangeMin(control);
// And add it to the approproate vectors. // And add it to the approproate vectors.
int inputPropHandle = getInputPropertyHandle(prop);
Vector* maps = (Vector*)_inputs.get(inputPropHandle); Vector* maps = (Vector*)_inputs.get(inputPropHandle);
maps->add(map); maps->add(map);
return map; return map;
} }
ControlMap::OutRec* ControlMap::getOutRec(ObjectID id, Control control)
{
OutRec* out {nullptr};
for(int i = 0; i < _outputs.size(); i++) {
OutRec* o = (OutRec*)_outputs.get(i);
if(o->oid.object == id.object && o->oid.subObj == id.subObj
&& o->control == control)
{
out = o;
break;
}
}
// Create one if it doesn't
if(out == nullptr) {
out = new OutRec();
out->control = control;
out->oid = id;
out->id = _outputs.add(out);
}
return out;
}
void ControlMap::reset() void ControlMap::reset()
{ {
// Set all the values to zero // Set all the values to zero
@ -130,14 +181,7 @@ void ControlMap::setInput(int input, float val)
int ControlMap::getOutputHandle(ObjectID id, Control control) int ControlMap::getOutputHandle(ObjectID id, Control control)
{ {
for(int i = 0; i < _outputs.size(); i++) { return getOutRec(id, control)->id;
OutRec* o = (OutRec*)_outputs.get(i);
if(o->oid.object == id.object && o->oid.subObj == id.subObj
&& o->control == control)
return i;
}
fprintf(stderr, "ControlMap::getOutputHandle cannot find *%ld, control %d \nMissing <control-input ...> in XML?!", (long)id.object, control);
return -1;
} }
void ControlMap::setTransitionTime(int handle, float time) void ControlMap::setTransitionTime(int handle, float time)
@ -295,7 +339,7 @@ void ControlMap::applyControls(float dt)
case ROTORBRAKE: case ROTORBRAKE:
((Rotorgear*)obj)->setRotorBrake(lval); ((Rotorgear*)obj)->setRotorBrake(lval);
break; break;
case ROTORENGINEON: case ROTORGEARENGINEON:
((Rotorgear*)obj)->setEngineOn((int)lval); ((Rotorgear*)obj)->setEngineOn((int)lval);
break; break;
case ROTORENGINEMAXRELTORQUE: case ROTORENGINEMAXRELTORQUE:
@ -386,55 +430,26 @@ int ControlMap::getInputPropertyHandle(const char* name)
return p->handle; return p->handle;
} }
ControlMap::Control ControlMap::getControlByName(const std::string& name)
{
auto it = std::find(ControlNames.begin(), ControlNames.end(), name);
if (it == ControlNames.end()) {
SG_LOG(SG_FLIGHT,SG_ALERT,"Unrecognized control type '" << name
<< "' in YASim aircraft description.");
exit(1);
}
return static_cast<Control>(std::distance(ControlNames.begin(), it));
}
std::string ControlMap::getControlName(Control c)
{
return ControlNames.at(static_cast<int>(c));
}
ControlMap::Control ControlMap::parseControl(const char* name) ControlMap::Control ControlMap::parseControl(const char* name)
{ {
if(!strcmp(name, "THROTTLE")) return THROTTLE; std::string n(name);
if(!strcmp(name, "MIXTURE")) return MIXTURE; return getControlByName(n);
if(!strcmp(name, "CONDLEVER")) return CONDLEVER;
if(!strcmp(name, "STARTER")) return STARTER;
if(!strcmp(name, "MAGNETOS")) return MAGNETOS;
if(!strcmp(name, "ADVANCE")) return ADVANCE;
if(!strcmp(name, "REHEAT")) return REHEAT;
if(!strcmp(name, "BOOST")) return BOOST;
if(!strcmp(name, "VECTOR")) return VECTOR;
if(!strcmp(name, "PROP")) return PROP;
if(!strcmp(name, "BRAKE")) return BRAKE;
if(!strcmp(name, "STEER")) return STEER;
if(!strcmp(name, "EXTEND")) return EXTEND;
if(!strcmp(name, "HEXTEND")) return HEXTEND;
if(!strcmp(name, "LEXTEND")) return LEXTEND;
if(!strcmp(name, "LACCEL")) return LACCEL;
if(!strcmp(name, "INCIDENCE")) return INCIDENCE;
if(!strcmp(name, "FLAP0")) return FLAP0;
if(!strcmp(name, "FLAP0EFFECTIVENESS")) return FLAP0EFFECTIVENESS;
if(!strcmp(name, "FLAP1")) return FLAP1;
if(!strcmp(name, "FLAP1EFFECTIVENESS")) return FLAP1EFFECTIVENESS;
if(!strcmp(name, "SLAT")) return SLAT;
if(!strcmp(name, "SPOILER")) return SPOILER;
if(!strcmp(name, "CASTERING")) return CASTERING;
if(!strcmp(name, "PROPPITCH")) return PROPPITCH;
if(!strcmp(name, "PROPFEATHER")) return PROPFEATHER;
if(!strcmp(name, "COLLECTIVE")) return COLLECTIVE;
if(!strcmp(name, "CYCLICAIL")) return CYCLICAIL;
if(!strcmp(name, "CYCLICELE")) return CYCLICELE;
if(!strcmp(name, "TILTROLL")) return TILTROLL;
if(!strcmp(name, "TILTPITCH")) return TILTPITCH;
if(!strcmp(name, "TILTYAW")) return TILTYAW;
if(!strcmp(name, "ROTORGEARENGINEON")) return ROTORENGINEON;
if(!strcmp(name, "ROTORBRAKE")) return ROTORBRAKE;
if(!strcmp(name, "ROTORENGINEMAXRELTORQUE")) return ROTORENGINEMAXRELTORQUE;
if(!strcmp(name, "ROTORRELTARGET")) return ROTORRELTARGET;
if(!strcmp(name, "ROTORBALANCE")) return ROTORBALANCE;
if(!strcmp(name, "REVERSE_THRUST")) return REVERSE_THRUST;
if(!strcmp(name, "WASTEGATE")) return WASTEGATE;
if(!strcmp(name, "WINCHRELSPEED")) return WINCHRELSPEED;
if(!strcmp(name, "HITCHOPEN")) return HITCHOPEN;
if(!strcmp(name, "PLACEWINCH")) return PLACEWINCH;
if(!strcmp(name, "FINDAITOW")) return FINDAITOW;
SG_LOG(SG_FLIGHT,SG_ALERT,"Unrecognized control type '" << name
<< "' in YASim aircraft description.");
exit(1);
} }
ControlMap::ObjectID ControlMap::getObjectID(void* object, int subObj) ControlMap::ObjectID ControlMap::getObjectID(void* object, int subObj)

View file

@ -2,14 +2,19 @@
#define _CONTROL_MAP_HPP #define _CONTROL_MAP_HPP
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include "yasim-common.hpp"
#include "Vector.hpp" #include "Vector.hpp"
namespace yasim { namespace yasim {
class ControlMap { class ControlMap {
public: public:
~ControlMap(); ~ControlMap();
//! keep this enum in sync with the static vector ControlNames in ControlMap.cpp !
enum Control { enum Control {
THROTTLE, THROTTLE,
MIXTURE, MIXTURE,
@ -40,7 +45,7 @@ public:
COLLECTIVE, COLLECTIVE,
CYCLICAIL, CYCLICAIL,
CYCLICELE, CYCLICELE,
ROTORENGINEON, ROTORGEARENGINEON,
TILTYAW, TILTYAW,
TILTPITCH, TILTPITCH,
TILTROLL, TILTROLL,
@ -53,9 +58,10 @@ public:
WINCHRELSPEED, WINCHRELSPEED,
HITCHOPEN, HITCHOPEN,
PLACEWINCH, PLACEWINCH,
FINDAITOW FINDAITOW,
}; }; //! keep this enum in sync with the static vector ControlNames in ControlMap.cpp !
enum { enum {
OPT_SPLIT = 0x01, OPT_SPLIT = 0x01,
OPT_INVERT = 0x02, OPT_INVERT = 0x02,
@ -73,6 +79,8 @@ public:
// map control name to int (enum) // map control name to int (enum)
Control parseControl(const char* name); Control parseControl(const char* name);
Control getControlByName(const std::string& name);
std::string getControlName(Control c);
// create ID from object and optional sub index (e.g. for wing section) // create ID from object and optional sub index (e.g. for wing section)
ObjectID getObjectID(void* object, int subObj = 0); ObjectID getObjectID(void* object, int subObj = 0);
@ -103,7 +111,7 @@ public:
// Each output record is identified by both an object/type tuple // Each output record is identified by both an object/type tuple
// and a numeric handle. // and a numeric handle.
int getOutputHandle(ObjectID id, Control control); int getOutputHandle(ObjectID id, Control control);
// Sets the transition time for the control output to swing // Sets the transition time for the control output to swing
// through its full range. // through its full range.
void setTransitionTime(int handle, float time); void setTransitionTime(int handle, float time);
@ -120,7 +128,8 @@ public:
PropHandle* getProperty(const int i) { return ((PropHandle*)_properties.get(i)); } PropHandle* getProperty(const int i) { return ((PropHandle*)_properties.get(i)); }
private: private:
struct OutRec { struct OutRec {
int id {0};
Control control; Control control;
ObjectID oid; ObjectID oid;
Vector maps; Vector maps;
@ -149,6 +158,7 @@ private:
Vector _properties; Vector _properties;
void* addMapping(const char* prop, Control control, ObjectID id, int options = 0); void* addMapping(const char* prop, Control control, ObjectID id, int options = 0);
OutRec* getOutRec(ObjectID id, Control control);
}; };
}; // namespace yasim }; // namespace yasim

View file

@ -1,6 +1,9 @@
#ifndef _YASIM_COMMON_HPP #ifndef _YASIM_COMMON_HPP
#define _YASIM_COMMON_HPP #define _YASIM_COMMON_HPP
#include <string>
#include <vector>
#include <algorithm>
/* /*
common file for YASim wide constants and static helper functions common file for YASim wide constants and static helper functions
*/ */