YASim refactoring parser
This commit is contained in:
parent
7c55aa2c4a
commit
87149931dd
6 changed files with 87 additions and 78 deletions
|
@ -161,31 +161,30 @@ void Airplane::setCruise(float speed, float altitude, float fuel, float gla)
|
|||
|
||||
void Airplane::setElevatorControl(const char* prop)
|
||||
{
|
||||
_approachElevator.propHandle = getControlMap()->getPropertyHandle(prop);
|
||||
_approachElevator.propHandle = getControlMap()->getInputPropertyHandle(prop);
|
||||
_approachElevator.val = 0;
|
||||
_approachConfig.controls.add(&_approachElevator);
|
||||
}
|
||||
|
||||
void Airplane::addApproachControl(const char* prop, float val)
|
||||
void Airplane::addControlSetting(Configuration cfg, const char* prop, float val)
|
||||
{
|
||||
ControlSetting* c = new ControlSetting();
|
||||
c->propHandle = getControlMap()->getPropertyHandle(prop);
|
||||
c->propHandle = getControlMap()->getInputPropertyHandle(prop);
|
||||
c->val = val;
|
||||
_approachConfig.controls.add(c);
|
||||
switch (cfg) {
|
||||
case APPROACH:
|
||||
_approachConfig.controls.add(c);
|
||||
break;
|
||||
case CRUISE:
|
||||
_cruiseConfig.controls.add(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Airplane::addCruiseControl(const char* prop, float val)
|
||||
{
|
||||
ControlSetting* c = new ControlSetting();
|
||||
c->propHandle = getControlMap()->getPropertyHandle(prop);
|
||||
c->val = val;
|
||||
_cruiseConfig.controls.add(c);
|
||||
}
|
||||
|
||||
void Airplane::addSolutionWeight(bool approach, int idx, float wgt)
|
||||
void Airplane::addSolutionWeight(Configuration cfg, int idx, float wgt)
|
||||
{
|
||||
SolveWeight* w = new SolveWeight();
|
||||
w->approach = approach;
|
||||
w->approach = (cfg == APPROACH);
|
||||
w->idx = idx;
|
||||
w->wgt = wgt;
|
||||
_solveWeights.add(w);
|
||||
|
|
|
@ -24,6 +24,11 @@ public:
|
|||
Airplane();
|
||||
~Airplane();
|
||||
|
||||
enum Configuration {
|
||||
APPROACH,
|
||||
CRUISE,
|
||||
};
|
||||
|
||||
void iterate(float dt);
|
||||
void calcFuelWeights();
|
||||
|
||||
|
@ -60,10 +65,9 @@ public:
|
|||
void setCruise(float speed, float altitude, float fuel, float gla);
|
||||
|
||||
void setElevatorControl(const char* prop);
|
||||
void addApproachControl(const char* prop, float val);
|
||||
void addCruiseControl(const char* prop, float val);
|
||||
void addControlSetting(Configuration cfg, const char* prop, float val);
|
||||
|
||||
void addSolutionWeight(bool approach, int idx, float wgt);
|
||||
void addSolutionWeight(Configuration cfg, int idx, float wgt);
|
||||
|
||||
int numGear() const { return _gears.size(); }
|
||||
Gear* getGear(int g) { return ((GearRec*)_gears.get(g))->gear; }
|
||||
|
|
|
@ -50,13 +50,7 @@ options: bits OPT_INVERT, OPT_SPLIT, OPT_SQUARE
|
|||
*/
|
||||
void ControlMap::addMapping(const char* prop, Control control, ObjectID id, int options, float src0, float src1, float dst0, float dst1)
|
||||
{
|
||||
addMapping(prop, control, id, options);
|
||||
int inputPropHandle = getPropertyHandle(prop);
|
||||
|
||||
// The one we just added is last in the list (ugly, awful hack!)
|
||||
Vector* maps = (Vector*)_inputs.get(inputPropHandle);
|
||||
MapRec* m = (MapRec*)maps->get(maps->size() - 1);
|
||||
|
||||
MapRec* m = (MapRec*)addMapping(prop, control, id, options);
|
||||
m->src0 = src0;
|
||||
m->src1 = src1;
|
||||
m->dst0 = dst0;
|
||||
|
@ -69,12 +63,13 @@ control: identifier (see enum OutputType)
|
|||
object: object to which this input belongs to
|
||||
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 = getPropertyHandle(prop);
|
||||
int inputPropHandle = getInputPropertyHandle(prop);
|
||||
// See if the output object already exists
|
||||
OutRec* out {nullptr};
|
||||
for(int i = 0; i < _outputs.size(); i++) {
|
||||
int i;
|
||||
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)
|
||||
|
@ -105,6 +100,7 @@ void ControlMap::addMapping(const char* prop, Control control, ObjectID id, int
|
|||
// And add it to the approproate vectors.
|
||||
Vector* maps = (Vector*)_inputs.get(inputPropHandle);
|
||||
maps->add(map);
|
||||
return map;
|
||||
}
|
||||
|
||||
void ControlMap::reset()
|
||||
|
@ -138,9 +134,9 @@ int ControlMap::getOutputHandle(ObjectID id, Control control)
|
|||
OutRec* o = (OutRec*)_outputs.get(i);
|
||||
if(o->oid.object == id.object && o->oid.subObj == id.subObj
|
||||
&& o->control == control)
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
fprintf(stderr, "ControlMap::getOutputHandle cannot find *%ld, control %d \n", (long)id.object, control);
|
||||
fprintf(stderr, "ControlMap::getOutputHandle cannot find *%ld, control %d \nMissing <control-input ...> in XML?!", (long)id.object, control);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -330,6 +326,7 @@ void ControlMap::applyControls(float dt)
|
|||
((Hitch*)obj)->findBestAIObject(lval!=0);
|
||||
break;
|
||||
case PROP:
|
||||
break;
|
||||
case INCIDENCE:
|
||||
break;
|
||||
}
|
||||
|
@ -369,24 +366,24 @@ float ControlMap::rangeMax(Control control)
|
|||
}
|
||||
|
||||
/// register property name, return ID (int)
|
||||
int ControlMap::getPropertyHandle(const char* name)
|
||||
int ControlMap::getInputPropertyHandle(const char* name)
|
||||
{
|
||||
for(int i=0; i < _properties.size(); i++) {
|
||||
PropHandle* p = (PropHandle*)_properties.get(i);
|
||||
if(!strcmp(p->name, name))
|
||||
return p->handle;
|
||||
}
|
||||
for(int i=0; i < _properties.size(); i++) {
|
||||
PropHandle* p = (PropHandle*)_properties.get(i);
|
||||
if(!strcmp(p->name, name))
|
||||
return p->handle;
|
||||
}
|
||||
|
||||
// create new
|
||||
PropHandle* p = new PropHandle();
|
||||
p->name = strdup(name);
|
||||
|
||||
fgGetNode(p->name, true);
|
||||
// create new
|
||||
PropHandle* p = new PropHandle();
|
||||
p->name = strdup(name);
|
||||
|
||||
fgGetNode(p->name, true);
|
||||
|
||||
Vector* v = new Vector();
|
||||
p->handle = _inputs.add(v);
|
||||
_properties.add(p);
|
||||
return p->handle;
|
||||
Vector* v = new Vector();
|
||||
p->handle = _inputs.add(v);
|
||||
_properties.add(p);
|
||||
return p->handle;
|
||||
}
|
||||
|
||||
|
||||
|
@ -442,6 +439,7 @@ ControlMap::Control ControlMap::parseControl(const char* name)
|
|||
|
||||
ControlMap::ObjectID ControlMap::getObjectID(void* object, int subObj)
|
||||
{
|
||||
assert(object != nullptr);
|
||||
ObjectID o;
|
||||
o.object = object;
|
||||
o.subObj = subObj;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace yasim {
|
|||
class ControlMap {
|
||||
public:
|
||||
~ControlMap();
|
||||
|
||||
|
||||
enum Control {
|
||||
THROTTLE,
|
||||
MIXTURE,
|
||||
|
@ -77,7 +77,6 @@ public:
|
|||
ObjectID getObjectID(void* object, int subObj = 0);
|
||||
|
||||
// add input property for a control to an object
|
||||
void addMapping(const char* prop, Control control, ObjectID id, int options = 0);
|
||||
|
||||
// same with limits. Input values are clamped to [src0:src1] and then mapped to
|
||||
// [dst0:dst1] before being set on the objects control.
|
||||
|
@ -116,7 +115,7 @@ public:
|
|||
float getOutputR(int handle);
|
||||
|
||||
// register property name, return handle
|
||||
int getPropertyHandle(const char* name);
|
||||
int getInputPropertyHandle(const char* name);
|
||||
int numProperties() { return _properties.size(); }
|
||||
PropHandle* getProperty(const int i) { return ((PropHandle*)_properties.get(i)); }
|
||||
|
||||
|
@ -148,6 +147,8 @@ private:
|
|||
Vector _outputs;
|
||||
// control properties
|
||||
Vector _properties;
|
||||
|
||||
void* addMapping(const char* prop, Control control, ObjectID id, int options = 0);
|
||||
};
|
||||
|
||||
}; // namespace yasim
|
||||
|
|
|
@ -228,22 +228,7 @@ void FGFDM::startElement(const char* name, const XMLAttributes &a)
|
|||
else if(!strcmp(name, "solve-weight")) { parseSolveWeight(&a); }
|
||||
else if(!strcmp(name, "cockpit")) { parseCockpit(&a); }
|
||||
else if(!strcmp(name, "rotor")) { parseRotor(&a, name); }
|
||||
else if(!strcmp(name, "rotorgear")) {
|
||||
Rotorgear* r = _airplane.getModel()->getRotorgear();
|
||||
_currObj = r;
|
||||
#define p(x) if ((&a)->hasAttribute(#x)) r->setParameter((char *)#x,attrf(&a,#x) );
|
||||
#define p2(x,y) if ((&a)->hasAttribute(y)) r->setParameter((char *)#x,attrf(&a,y) );
|
||||
p2(max_power_engine,"max-power-engine")
|
||||
p2(engine_prop_factor,"engine-prop-factor")
|
||||
p(yasimdragfactor)
|
||||
p(yasimliftfactor)
|
||||
p2(max_power_rotor_brake,"max-power-rotor-brake")
|
||||
p2(rotorgear_friction,"rotorgear-friction")
|
||||
p2(engine_accel_limit,"engine-accel-limit")
|
||||
#undef p
|
||||
#undef p2
|
||||
r->setInUse();
|
||||
}
|
||||
else if(!strcmp(name, "rotorgear")) { parseRotorGear(&a); }
|
||||
else if(!strcmp(name, "wing") || !strcmp(name, "hstab") || !strcmp(name, "vstab") || !strcmp(name, "mstab")) {
|
||||
parseWing(&a, name, &_airplane);
|
||||
}
|
||||
|
@ -320,11 +305,11 @@ void FGFDM::parseApproachCruise(const XMLAttributes* a, const char* name)
|
|||
if (!strcmp(name, "approach")) {
|
||||
float aoa = attrf(a, "aoa", 0) * DEG2RAD;
|
||||
_airplane.setApproach(spd, alt, aoa, attrf(a, "fuel", 0.2), gla);
|
||||
_cruiseCurr = false;
|
||||
_airplaneCfg = Airplane::Configuration::APPROACH;
|
||||
}
|
||||
else {
|
||||
_airplane.setCruise(spd, alt, attrf(a, "fuel", 0.5),gla);
|
||||
_cruiseCurr = true;
|
||||
_airplaneCfg = Airplane::Configuration::CRUISE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,7 +324,7 @@ void FGFDM::parseSolveWeight(const XMLAttributes* a)
|
|||
SG_LOG(SG_FLIGHT,SG_ALERT,"YASim fatal: missing attribute, solve-weight needs one of {weight-lbs, weight-kg}");
|
||||
exit(1);
|
||||
}
|
||||
_airplane.addSolutionWeight(!_cruiseCurr, idx, f);
|
||||
_airplane.addSolutionWeight(_airplaneCfg, idx, f);
|
||||
}
|
||||
|
||||
void FGFDM::parseCockpit(const XMLAttributes* a)
|
||||
|
@ -594,10 +579,13 @@ void FGFDM::parseWing(const XMLAttributes* a, const char* type, Airplane* airpla
|
|||
|
||||
float dragFactor = attrf(a, "pdrag", 1);
|
||||
if (a->hasAttribute("effectiveness")) {
|
||||
/* FIXME:
|
||||
* check if all attibutes have "good" names and update parser AND documentation together
|
||||
* only after that issue warnings
|
||||
SG_LOG(SG_FLIGHT, SG_ALERT, "Warning: " <<
|
||||
"deprecated attribute 'effectiveness' in YASim configuration file. " <<
|
||||
"Use 'pdrag' instead to add parasitic drag.");
|
||||
|
||||
*/
|
||||
dragFactor = attrf(a, "effectiveness", 1);
|
||||
}
|
||||
w->setSectionDrag(_wingSection, dragFactor);
|
||||
|
@ -719,6 +707,24 @@ void FGFDM::parseRotor(const XMLAttributes* a, const char* type)
|
|||
_airplane.getModel()->getRotorgear()->addRotor(w);
|
||||
} //parseRotor
|
||||
|
||||
void FGFDM::parseRotorGear(const XMLAttributes* a)
|
||||
{
|
||||
Rotorgear* r = _airplane.getModel()->getRotorgear();
|
||||
_currObj = r;
|
||||
#define p(x) if (a->hasAttribute(#x)) r->setParameter((char *)#x,attrf(a,#x) );
|
||||
#define p2(x,y) if (a->hasAttribute(y)) r->setParameter((char *)#x,attrf(a,y) );
|
||||
p2(max_power_engine,"max-power-engine")
|
||||
p2(engine_prop_factor,"engine-prop-factor")
|
||||
p(yasimdragfactor)
|
||||
p(yasimliftfactor)
|
||||
p2(max_power_rotor_brake,"max-power-rotor-brake")
|
||||
p2(rotorgear_friction,"rotorgear-friction")
|
||||
p2(engine_accel_limit,"engine-accel-limit")
|
||||
#undef p
|
||||
#undef p2
|
||||
r->setInUse();
|
||||
}
|
||||
|
||||
void FGFDM::parsePistonEngine(const XMLAttributes* a)
|
||||
{
|
||||
float engP = attrf(a, "eng-power") * HP2W;
|
||||
|
@ -1138,12 +1144,7 @@ void FGFDM::parseControlSetting(const XMLAttributes* a)
|
|||
{
|
||||
// A cruise or approach control setting
|
||||
float value = attrf(a, "value", 0);
|
||||
if(_cruiseCurr) {
|
||||
_airplane.addCruiseControl(a->getValue("axis"), value);
|
||||
}
|
||||
else {
|
||||
_airplane.addApproachControl(a->getValue("axis"), value);
|
||||
}
|
||||
_airplane.addControlSetting(_airplaneCfg, a->getValue("axis"), value);
|
||||
}
|
||||
|
||||
void FGFDM::parseControlIn(const XMLAttributes* a)
|
||||
|
@ -1156,11 +1157,16 @@ void FGFDM::parseControlIn(const XMLAttributes* a)
|
|||
opt |= a->hasAttribute("split") ? ControlMap::OPT_SPLIT : 0;
|
||||
opt |= a->hasAttribute("invert") ? ControlMap::OPT_INVERT : 0;
|
||||
opt |= a->hasAttribute("square") ? ControlMap::OPT_SQUARE : 0;
|
||||
float src0, src1, dst0, dst1;
|
||||
src0 = dst0 = cm->rangeMin(control);
|
||||
src1 = dst1 = cm->rangeMax(control);
|
||||
if(a->hasAttribute("src0")) {
|
||||
cm->addMapping(a->getValue("axis"), control, oid, opt, attrf(a, "src0"), attrf(a, "src1"), attrf(a, "dst0"), attrf(a, "dst1"));
|
||||
} else {
|
||||
cm->addMapping(a->getValue("axis"), control, oid, opt);
|
||||
}
|
||||
src0 = attrf(a, "src0");
|
||||
src1 = attrf(a, "src1");
|
||||
dst0 = attrf(a, "dst0");
|
||||
dst1 = attrf(a, "dst1");
|
||||
}
|
||||
cm->addMapping(a->getValue("axis"), control, oid, opt, src0, src1, dst0, dst1);
|
||||
}
|
||||
|
||||
void FGFDM::parseControlOut(const XMLAttributes* a)
|
||||
|
|
|
@ -58,6 +58,7 @@ private:
|
|||
void setOutputProperties(float dt);
|
||||
|
||||
void parseRotor(const XMLAttributes* a, const char* name);
|
||||
void parseRotorGear(const XMLAttributes* a);
|
||||
void parseWing(const XMLAttributes* a, const char* name, Airplane* airplane);
|
||||
int parseOutput(const char* name);
|
||||
void parseWeight(const XMLAttributes* a);
|
||||
|
@ -113,7 +114,7 @@ private:
|
|||
|
||||
// Parsing temporaries
|
||||
void* _currObj {nullptr};
|
||||
bool _cruiseCurr {false};
|
||||
Airplane::Configuration _airplaneCfg;
|
||||
int _nextEngine {0};
|
||||
int _wingSection {0};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue