From 87149931dd2bcc9939d7e8cd53d214c988e3fb78 Mon Sep 17 00:00:00 2001 From: Henning Stahlke Date: Tue, 12 Dec 2017 08:14:30 +0100 Subject: [PATCH] YASim refactoring parser --- src/FDM/YASim/Airplane.cpp | 27 +++++++-------- src/FDM/YASim/Airplane.hpp | 10 ++++-- src/FDM/YASim/ControlMap.cpp | 52 ++++++++++++++-------------- src/FDM/YASim/ControlMap.hpp | 7 ++-- src/FDM/YASim/FGFDM.cpp | 66 ++++++++++++++++++++---------------- src/FDM/YASim/FGFDM.hpp | 3 +- 6 files changed, 87 insertions(+), 78 deletions(-) diff --git a/src/FDM/YASim/Airplane.cpp b/src/FDM/YASim/Airplane.cpp index 9510f65e8..0a4b128b6 100644 --- a/src/FDM/YASim/Airplane.cpp +++ b/src/FDM/YASim/Airplane.cpp @@ -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); diff --git a/src/FDM/YASim/Airplane.hpp b/src/FDM/YASim/Airplane.hpp index 0f22cfc22..7304e986c 100644 --- a/src/FDM/YASim/Airplane.hpp +++ b/src/FDM/YASim/Airplane.hpp @@ -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; } diff --git a/src/FDM/YASim/ControlMap.cpp b/src/FDM/YASim/ControlMap.cpp index db644691d..679d7aec5 100644 --- a/src/FDM/YASim/ControlMap.cpp +++ b/src/FDM/YASim/ControlMap.cpp @@ -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 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; diff --git a/src/FDM/YASim/ControlMap.hpp b/src/FDM/YASim/ControlMap.hpp index 94374ea2a..5c150c1e1 100644 --- a/src/FDM/YASim/ControlMap.hpp +++ b/src/FDM/YASim/ControlMap.hpp @@ -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 diff --git a/src/FDM/YASim/FGFDM.cpp b/src/FDM/YASim/FGFDM.cpp index 1a8c82c63..3c21a5ed7 100644 --- a/src/FDM/YASim/FGFDM.cpp +++ b/src/FDM/YASim/FGFDM.cpp @@ -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) diff --git a/src/FDM/YASim/FGFDM.hpp b/src/FDM/YASim/FGFDM.hpp index 845873d66..a546d1262 100644 --- a/src/FDM/YASim/FGFDM.hpp +++ b/src/FDM/YASim/FGFDM.hpp @@ -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};