1
0
Fork 0
flightgear/src/FDM/YASim/ControlMap.cpp
curt 5b84ae51a5 Initial revision of Andy Ross's YASim code. This is (Y)et (A)nother Flight
Dynamics (Sim)ulator.  Basically, this is a rough, first cut of a "different
take" on FDM design.  It's intended to be very simple to use,
producing reasonable results for aircraft of all sorts and sizes,
while maintaining simulation plausibility even in odd flight
conditions like spins and aerobatics.  It's at the point now where one
can actually fly the planes around.
2001-12-01 06:22:24 +00:00

130 lines
3.1 KiB
C++

#include "Jet.hpp"
#include "Thruster.hpp"
#include "Gear.hpp"
#include "Wing.hpp"
#include "Math.hpp"
#include "ControlMap.hpp"
namespace yasim {
ControlMap::~ControlMap()
{
for(int i=0; i<_inputs.size(); i++) {
Vector* v = (Vector*)_inputs.get(i);
for(int j=0; j<v->size(); j++)
delete (MapRec*)v->get(j);
delete v;
}
for(int i=0; i<_outputs.size(); i++) {
OutRec* o = (OutRec*)_outputs.get(i);
delete[] o->values;
delete o;
}
}
int ControlMap::newInput()
{
Vector* v = new Vector();
return _inputs.add(v);
}
void ControlMap::addMapping(int input, int type, void* object, int options)
{
// See if the output object already exists
OutRec* out = 0;
for(int i=0; i<_outputs.size(); i++) {
OutRec* o = (OutRec*)_outputs.get(i);
if(o->object == object && o->type == type) {
out = o;
break;
}
}
// Create one if it doesn't
if(out == 0) {
out = new OutRec();
out->type = type;
out->object = object;
out->n = 0;
out->values = 0;
_outputs.add(out);
}
// Make space for the new input value
int idx = out->n++;
delete[] out->values;
out->values = new float[out->n];
// Add the new option tag
out->options.add((void*)options);
// Make a new input record
MapRec* map = new MapRec();
map->out = out;
map->idx = idx;
// And add it to the approproate vector.
Vector* maps = (Vector*)_inputs.get(input);
maps->add(map);
}
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->n; j++)
o->values[j] = 0;
}
}
void ControlMap::setInput(int input, float value)
{
Vector* maps = (Vector*)_inputs.get(input);
for(int i=0; i<maps->size(); i++) {
MapRec* map = (MapRec*)maps->get(i);
map->out->values[map->idx] = value;
}
}
void ControlMap::applyControls()
{
for(int outrec=0; outrec<_outputs.size(); outrec++) {
OutRec* o = (OutRec*)_outputs.get(outrec);
// Generate a summed value. Note the check for "split"
// control axes like ailerons.
float lval = 0, rval = 0;
for(int i=0; i<o->n; i++) {
float val = o->values[i];
int opt = (int)o->options.get(i);
if(opt & OPT_SQUARE)
val = val * Math::abs(val);
if(opt & OPT_INVERT)
val = -val;
lval += val;
if(opt & OPT_SPLIT)
rval -= val;
else
rval += val;
}
void* obj = o->object;
switch(o->type) {
case THROTTLE: ((Thruster*)obj)->setThrottle(lval); break;
case MIXTURE: ((Thruster*)obj)->setMixture(lval); break;
case PROP: ((Thruster*)obj)->setPropAdvance(lval); break;
case REHEAT: ((Jet*)obj)->setReheat(lval); break;
case BRAKE: ((Gear*)obj)->setBrake(lval); break;
case STEER: ((Gear*)obj)->setRotation(lval); break;
case EXTEND: ((Gear*)obj)->setExtension(lval); break;
case SLAT: ((Wing*)obj)->setSlat(lval); break;
case FLAP0: ((Wing*)obj)->setFlap0(lval, rval); break;
case FLAP1: ((Wing*)obj)->setFlap1(lval, rval); break;
case SPOILER: ((Wing*)obj)->setSpoiler(lval, rval); break;
}
}
}
}; // namespace yasim