1
0
Fork 0

YASIM add initialization

use Math::clamp in ControlMap
This commit is contained in:
Henning Stahlke 2017-12-01 13:03:36 +01:00
parent b2000e1cca
commit c63ded1c44
4 changed files with 62 additions and 68 deletions

View file

@ -66,9 +66,8 @@ void ControlMap::addMapping(int input, Control control, void* object, int option
void ControlMap::addMapping(int input, Control control, void* object, int options)
{
// See if the output object already exists
OutRec* out = 0;
int i;
for(i=0; i<_outputs.size(); i++) {
OutRec* out {nullptr};
for(int i = 0; i < _outputs.size(); i++) {
OutRec* o = (OutRec*)_outputs.get(i);
if(o->object == object && o->control == control) {
out = o;
@ -77,7 +76,7 @@ void ControlMap::addMapping(int input, Control control, void* object, int option
}
// Create one if it doesn't
if(out == 0) {
if(out == nullptr) {
out = new OutRec();
out->control = control;
out->object = object;
@ -102,29 +101,25 @@ void ControlMap::addMapping(int input, Control control, void* object, int option
void ControlMap::reset()
{
// Set all the values to zero
for(int i=0; i<_outputs.size(); i++) {
OutRec* o = (OutRec*)_outputs.get(i);
for(int j=0; j<o->maps.size(); j++)
((MapRec*)(o->maps.get(j)))->val = 0;
for(int i = 0; i < _outputs.size(); i++) {
OutRec* o = (OutRec*)_outputs.get(i);
for(int j = 0; j < o->maps.size(); j++) {
((MapRec*)(o->maps.get(j)))->val = 0;
}
}
}
void ControlMap::setInput(int input, float val)
{
Vector* maps = (Vector*)_inputs.get(input);
for(int i=0; i<maps->size(); i++) {
MapRec* m = (MapRec*)maps->get(i);
float val2 = val;
// Do the scaling operation. Clamp to [src0:src1], rescale to
// [0:1] within that range, then map to [dst0:dst1].
if(val2 < m->src0) val2 = m->src0;
if(val2 > m->src1) val2 = m->src1;
val2 = (val2 - m->src0) / (m->src1 - m->src0);
val2 = m->dst0 + val2 * (m->dst1 - m->dst0);
m->val = val2;
for(int i = 0; i < maps->size(); i++) {
MapRec* m = (MapRec*)maps->get(i);
float val2 = val;
// Do the scaling operation. Clamp to [src0:src1], rescale to
// [0:1] within that range, then map to [dst0:dst1].
val2 = Math::clamp(val2, m->src0, m->src1);
val2 = (val2 - m->src0) / (m->src1 - m->src0);
m->val = m->dst0 + val2 * (m->dst1 - m->dst0);
}
}

View file

@ -116,15 +116,15 @@ public:
private:
struct OutRec {
Control control;
void* object;
Control control;
void* object {nullptr};
Vector maps;
float oldL {0};
float oldR {0};
float time {0};
};
struct MapRec {
OutRec* out;
OutRec* out {nullptr};
int idx {0};
int opt {0};
float val {0};

View file

@ -35,10 +35,6 @@ namespace yasim {
FGFDM::FGFDM()
{
_vehicle_radius = 0.0f;
_nextEngine = 0;
// Map /controls/flight/elevator to the approach elevator control. This
// should probably be settable, but there are very few aircraft
// who trim their approaches using things other than elevator.
@ -534,7 +530,7 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts)
} else if(eq(name, "weight")) {
parseWeight(a);
} else if(eq(name, "stall")) {
Wing* w = (Wing*)_currObj;
Wing* w = (Wing*)_currObj;
StallParams sp;
sp.aoa = attrf(a, "aoa") * DEG2RAD;
sp.width = attrf(a, "width", 2) * DEG2RAD;
@ -583,38 +579,34 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts)
_airplane.addCruiseControl(cm->propertyHandle(axis), value);
else
_airplane.addApproachControl(cm->propertyHandle(axis), value);
} else if(eq(name, "control-input")) {
ControlMap* cm = _airplane.getControlMap();
// A mapping of input property to a control
int axis = cm->propertyHandle(a->getValue("axis"));
ControlMap::Control control = cm->parseControl(a->getValue("control"));
int opt = 0;
opt |= a->hasAttribute("split") ? ControlMap::OPT_SPLIT : 0;
opt |= a->hasAttribute("invert") ? ControlMap::OPT_INVERT : 0;
opt |= a->hasAttribute("square") ? ControlMap::OPT_SQUARE : 0;
if(a->hasAttribute("src0")) {
cm->addMapping(axis, control, _currObj, opt,
attrf(a, "src0"), attrf(a, "src1"),
attrf(a, "dst0"), attrf(a, "dst1"));
} else {
cm->addMapping(axis, control, _currObj, opt);
}
} else if(eq(name, "control-output")) {
} else if(eq(name, "control-input")) {
ControlMap* cm = _airplane.getControlMap();
// A mapping of input property to a control
int propHandle = cm->propertyHandle(a->getValue("axis"));
ControlMap::Control control = cm->parseControl(a->getValue("control"));
int opt = 0;
opt |= a->hasAttribute("split") ? ControlMap::OPT_SPLIT : 0;
opt |= a->hasAttribute("invert") ? ControlMap::OPT_INVERT : 0;
opt |= a->hasAttribute("square") ? ControlMap::OPT_SQUARE : 0;
if(a->hasAttribute("src0")) {
cm->addMapping(propHandle, control, _currObj, opt, attrf(a, "src0"), attrf(a, "src1"), attrf(a, "dst0"), attrf(a, "dst1"));
} else {
cm->addMapping(propHandle, control, _currObj, opt);
}
} else if(eq(name, "control-output")) {
// A property output for a control on the current object
ControlMap* cm = _airplane.getControlMap();
ControlMap::Control control = cm->parseControl(a->getValue("control"));
int handle = cm->getOutputHandle(_currObj, control);
PropOut* p = new PropOut();
p->prop = fgGetNode(a->getValue("prop"), true);
p->handle = handle;
p->control = control;
p->left = !(a->hasAttribute("side") &&
eq("right", a->getValue("side")));
p->min = attrf(a, "min", cm->rangeMin(control));
p->max = attrf(a, "max", cm->rangeMax(control));
_controlProps.add(p);
PropOut* p = new PropOut();
p->prop = fgGetNode(a->getValue("prop"), true);
p->handle = cm->getOutputHandle(_currObj, control);
p->control = control;
p->left = !(a->hasAttribute("side") &&
eq("right", a->getValue("side")));
p->min = attrf(a, "min", cm->rangeMin(control));
p->max = attrf(a, "max", cm->rangeMax(control));
_controlProps.add(p);
} else if(eq(name, "control-speed")) {
ControlMap* cm = _airplane.getControlMap();
@ -854,10 +846,10 @@ Wing* FGFDM::parseWing(XMLAttributes* a, const char* type, Version * version)
// The 70% is a magic number that sorta kinda seems to match known
// throttle settings to approach speed.
w->setInducedDrag(0.7*attrf(a, "idrag", 1));
float effect = attrf(a, "effectiveness", 1);
w->multiplyDragCoefficient(effect);
_currObj = w;
return w;
}

View file

@ -32,12 +32,19 @@ public:
float getVehicleRadius(void) const { return _vehicle_radius; }
private:
struct EngRec { char* prefix; Thruster* eng; };
struct WeightRec { char* prop; float size; int handle; };
struct PropOut {
SGPropertyNode* prop;
struct EngRec {
char* prefix {nullptr};
Thruster* eng {nullptr};
};
struct WeightRec {
char* prop {nullptr};
float size {0};
int handle {0};
ControlMap::Control control;
};
struct PropOut {
SGPropertyNode* prop {nullptr};
int handle {0};
ControlMap::Control control;
bool left {false};
float min {0};
float max {0};
@ -79,12 +86,12 @@ private:
Vector _controlProps;
// Radius of the vehicle, for intersection testing.
float _vehicle_radius;
float _vehicle_radius {0};
// Parsing temporaries
void* _currObj;
bool _cruiseCurr;
int _nextEngine;
void* _currObj {nullptr};
bool _cruiseCurr {false};
int _nextEngine {0};
class FuelProps
{