YASim bugfix: XML processing failed if <control-speed> appeared before <control-input> in XML file.
This commit is contained in:
parent
451f41fe0c
commit
cbd5cb916f
3 changed files with 122 additions and 94 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue