#include "TurbineEngine.hpp"
#include "Rotor.hpp"
#include "Rotorpart.hpp"
+#include "Hitch.hpp"
#include "FGFDM.hpp"
sprintf(buf, "/consumables/fuel/tank[%d]/density-ppg", i);
fgSetDouble(buf, density * (KG2LBS/CM2GALS));
- sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i);
- fgSetDouble(buf, _airplane.getFuel(i) * CM2GALS / density);
+// set in TankProperties class
+// sprintf(buf, "/consumables/fuel/tank[%d]/level-gal_us", i);
+// fgSetDouble(buf, _airplane.getFuel(i) * CM2GALS / density);
sprintf(buf, "/consumables/fuel/tank[%d]/capacity-gal_us", i);
fgSetDouble(buf, CM2GALS * _airplane.getTankCapacity(i)/density);
float spd = attrf(a, "speed") * KTS2MPS;
float alt = attrf(a, "alt", 0) * FT2M;
float aoa = attrf(a, "aoa", 0) * DEG2RAD;
- _airplane.setApproach(spd, alt, aoa, attrf(a, "fuel", 0.2));
+ float gla = attrf(a, "glide-angle", 0) * DEG2RAD;
+ _airplane.setApproach(spd, alt, aoa, attrf(a, "fuel", 0.2),gla);
_cruiseCurr = false;
} else if(eq(name, "cruise")) {
float spd = attrf(a, "speed") * KTS2MPS;
float alt = attrf(a, "alt") * FT2M;
- _airplane.setCruise(spd, alt, attrf(a, "fuel", 0.5));
+ float gla = attrf(a, "glide-angle", 0) * DEG2RAD;
+ _airplane.setCruise(spd, alt, attrf(a, "fuel", 0.5),gla);
_cruiseCurr = true;
} else if(eq(name, "solve-weight")) {
int idx = attri(a, "idx");
er->eng = j;
er->prefix = dup(buf);
_thrusters.add(er);
+ } else if(eq(name, "hitch")) {
+ Hitch* h = new Hitch(a->getValue("name"));
+ _currObj = h;
+ v[0] = attrf(a, "x");
+ v[1] = attrf(a, "y");
+ v[2] = attrf(a, "z");
+ h->setPosition(v);
+ if(a->hasAttribute("force-is-calculated-by-other")) h->setForceIsCalculatedByOther(attrb(a,"force-is-calculated-by-other"));
+ _airplane.addHitch(h);
+ } else if(eq(name, "tow")) {
+ Hitch* h = (Hitch*)_currObj;
+ if(a->hasAttribute("length"))
+ h->setTowLength(attrf(a, "length"));
+ if(a->hasAttribute("elastic-constant"))
+ h->setTowElasticConstant(attrf(a, "elastic-constant"));
+ if(a->hasAttribute("break-force"))
+ h->setTowBreakForce(attrf(a, "break-force"));
+ if(a->hasAttribute("weight-per-meter"))
+ h->setTowWeightPerM(attrf(a, "weight-per-meter"));
+ if(a->hasAttribute("mp-auto-connect-period"))
+ h->setMpAutoConnectPeriod(attrf(a, "mp-auto-connect-period"));
+ } else if(eq(name, "winch")) {
+ Hitch* h = (Hitch*)_currObj;
+ double pos[3];
+ pos[0] = attrd(a, "x",0);
+ pos[1] = attrd(a, "y",0);
+ pos[2] = attrd(a, "z",0);
+ h->setWinchPosition(pos);
+ if(a->hasAttribute("max-speed"))
+ h->setWinchMaxSpeed(attrf(a, "max-speed"));
+ if(a->hasAttribute("power"))
+ h->setWinchPower(attrf(a, "power") * 1000);
+ if(a->hasAttribute("max-force"))
+ h->setWinchMaxForce(attrf(a, "max-force"));
+ if(a->hasAttribute("initial-tow-length"))
+ h->setWinchInitialTowLength(attrf(a, "initial-tow-length"));
+ if(a->hasAttribute("max-tow-length"))
+ h->setWinchMaxTowLength(attrf(a, "max-tow-length"));
+ if(a->hasAttribute("min-tow-length"))
+ h->setWinchMinTowLength(attrf(a, "min-tow-length"));
} else if(eq(name, "gear")) {
Gear* g = new Gear();
_currObj = g;
v[i] *= attrf(a, "compression", 1);
g->setCompression(v);
g->setBrake(attrf(a, "skid", 0));
+ g->setInitialLoad(attrf(a, "initial-load", 0));
g->setStaticFriction(attrf(a, "sfric", 0.8));
g->setDynamicFriction(attrf(a, "dfric", 0.7));
g->setSpring(attrf(a, "spring", 1));
g->setDamping(attrf(a, "damp", 1));
+ if(a->hasAttribute("on-water")) g->setOnWater(attrb(a,"on-water"));
+ if(a->hasAttribute("on-solid")) g->setOnSolid(attrb(a,"on-solid"));
+ if(a->hasAttribute("ignored-by-solver")) g->setIgnoreWhileSolving(attrb(a,"ignored-by-solver"));
+ g->setSpringFactorNotPlaning(attrf(a, "spring-factor-not-planing", 1));
+ g->setSpeedPlaning(attrf(a, "speed-planing", 0) * KTS2MPS);
+ g->setReduceFrictionByExtension(attrf(a, "reduce-friction-by-extension", 0));
_airplane.addGear(g);
} else if(eq(name, "hook")) {
Hook* h = new Hook();
b[2] = attrf(a, "bz");
float taper = attrf(a, "taper", 1);
float mid = attrf(a, "midpoint", 0.5);
- _airplane.addFuselage(v, b, attrf(a, "width"), taper, mid);
+ float cx = attrf(a, "cx", 1);
+ float cy = attrf(a, "cy", 1);
+ float cz = attrf(a, "cz", 1);
+ float idrag = attrf(a, "idrag", 1);
+ _airplane.addFuselage(v, b, attrf(a, "width"), taper, mid,
+ cx, cy, cz, idrag);
} else if(eq(name, "tank")) {
v[0] = attrf(a, "x");
v[1] = attrf(a, "y");
}
}
- float fuelDensity = _airplane.getFuelDensity(0); // HACK
+ // Use the density of the first tank, or a dummy value if no tanks
+ float fuelDensity = 1.0;
+ if(_airplane.numTanks())
+ fuelDensity = _airplane.getFuelDensity(0);
for(i=0; i<_thrusters.size(); i++) {
EngRec* er = (EngRec*)_thrusters.get(i);
Thruster* t = er->eng;
w->setTranslift(attrf(a, "translift", 0.05));
w->setC2(attrf(a, "dragfactor", 1));
w->setStepspersecond(attrf(a, "stepspersecond", 120));
+ w->setPhiNull((attrf(a, "phi0", 0))*YASIM_PI/180);
w->setRPM(attrf(a, "rpm", 424));
w->setRelLenHinge(attrf(a, "rellenflaphinge", 0.07));
w->setAlpha0((attrf(a, "flap0", -5))*YASIM_PI/180);
w->setTeeterdamp(attrf(a,"teeterdamp",.0001));
w->setMaxteeterdamp(attrf(a,"maxteeterdamp",1000));
w->setRelLenTeeterHinge(attrf(a,"rellenteeterhinge",0.01));
- void setAlphamin(float f);
- void setAlphamax(float f);
- void setAlpha0factor(float f);
-
+ w->setBalance(attrf(a,"balance",1.0));
+ w->setMinTiltYaw(attrf(a,"mintiltyaw",0.0));
+ w->setMinTiltPitch(attrf(a,"mintiltpitch",0.0));
+ w->setMinTiltRoll(attrf(a,"mintiltroll",0.0));
+ w->setMaxTiltYaw(attrf(a,"maxtiltyaw",0.0));
+ w->setMaxTiltPitch(attrf(a,"maxtiltpitch",0.0));
+ w->setMaxTiltRoll(attrf(a,"maxtiltroll",0.0));
+ w->setTiltCenterX(attrf(a,"tiltcenterx",0.0));
+ w->setTiltCenterY(attrf(a,"tiltcentery",0.0));
+ w->setTiltCenterZ(attrf(a,"tiltcenterz",0.0));
+ w->setDownwashFactor(attrf(a, "downwashfactor", 1));
if(attrb(a,"ccw"))
w->setCcw(1);
-
+ if(attrb(a,"sharedflaphinge"))
+ w->setSharedFlapHinge(true);
+
if(a->hasAttribute("name"))
w->setName(a->getValue("name") );
if(a->hasAttribute("alphaout0"))
if(a->hasAttribute("compression"))
eng->setCompression(attrf(a, "compression"));
+ if(a->hasAttribute("min-throttle"))
+ eng->setMinThrottle(attrf(a, "min-throttle"));
+
if(a->hasAttribute("turbo-mul")) {
float mul = attrf(a, "turbo-mul");
float mp = attrf(a, "wastegate-mp", 1e6) * INHG2PA;
if(eq(name, "EXTEND")) return ControlMap::EXTEND;
if(eq(name, "HEXTEND")) return ControlMap::HEXTEND;
if(eq(name, "LEXTEND")) return ControlMap::LEXTEND;
+ if(eq(name, "LACCEL")) return ControlMap::LACCEL;
if(eq(name, "INCIDENCE")) return ControlMap::INCIDENCE;
if(eq(name, "FLAP0")) return ControlMap::FLAP0;
+ if(eq(name, "FLAP0EFFECTIVENESS")) return ControlMap::FLAP0EFFECTIVENESS;
if(eq(name, "FLAP1")) return ControlMap::FLAP1;
+ if(eq(name, "FLAP1EFFECTIVENESS")) return ControlMap::FLAP1EFFECTIVENESS;
if(eq(name, "SLAT")) return ControlMap::SLAT;
if(eq(name, "SPOILER")) return ControlMap::SPOILER;
if(eq(name, "CASTERING")) return ControlMap::CASTERING;
if(eq(name, "COLLECTIVE")) return ControlMap::COLLECTIVE;
if(eq(name, "CYCLICAIL")) return ControlMap::CYCLICAIL;
if(eq(name, "CYCLICELE")) return ControlMap::CYCLICELE;
+ if(eq(name, "TILTROLL")) return ControlMap::TILTROLL;
+ if(eq(name, "TILTPITCH")) return ControlMap::TILTPITCH;
+ if(eq(name, "TILTYAW")) return ControlMap::TILTYAW;
if(eq(name, "ROTORGEARENGINEON")) return ControlMap::ROTORENGINEON;
if(eq(name, "ROTORBRAKE")) return ControlMap::ROTORBRAKE;
+ if(eq(name, "ROTORENGINEMAXRELTORQUE"))
+ return ControlMap::ROTORENGINEMAXRELTORQUE;
+ if(eq(name, "ROTORRELTARGET")) return ControlMap::ROTORRELTARGET;
+ if(eq(name, "ROTORBALANCE")) return ControlMap::ROTORBALANCE;
if(eq(name, "REVERSE_THRUST")) return ControlMap::REVERSE_THRUST;
if(eq(name, "WASTEGATE")) return ControlMap::WASTEGATE;
+ if(eq(name, "WINCHRELSPEED")) return ControlMap::WINCHRELSPEED;
+ if(eq(name, "HITCHOPEN")) return ControlMap::HITCHOPEN;
+ if(eq(name, "PLACEWINCH")) return ControlMap::PLACEWINCH;
+ if(eq(name, "FINDAITOW")) return ControlMap::FINDAITOW;
+
SG_LOG(SG_FLIGHT,SG_ALERT,"Unrecognized control type '"
<< name << "' in YASim aircraft description.");
exit(1);
return s2;
}
-int FGFDM::attri(XMLAttributes* atts, char* attr)
+int FGFDM::attri(XMLAttributes* atts, const char* attr)
{
if(!atts->hasAttribute(attr)) {
SG_LOG(SG_FLIGHT,SG_ALERT,"Missing '" << attr <<
return attri(atts, attr, 0);
}
-int FGFDM::attri(XMLAttributes* atts, char* attr, int def)
+int FGFDM::attri(XMLAttributes* atts, const char* attr, int def)
{
const char* val = atts->getValue(attr);
if(val == 0) return def;
else return atol(val);
}
-float FGFDM::attrf(XMLAttributes* atts, char* attr)
+float FGFDM::attrf(XMLAttributes* atts, const char* attr)
{
if(!atts->hasAttribute(attr)) {
SG_LOG(SG_FLIGHT,SG_ALERT,"Missing '" << attr <<
return attrf(atts, attr, 0);
}
-float FGFDM::attrf(XMLAttributes* atts, char* attr, float def)
+float FGFDM::attrf(XMLAttributes* atts, const char* attr, float def)
{
const char* val = atts->getValue(attr);
if(val == 0) return def;
else return (float)atof(val);
}
+double FGFDM::attrd(XMLAttributes* atts, const char* attr)
+{
+ if(!atts->hasAttribute(attr)) {
+ SG_LOG(SG_FLIGHT,SG_ALERT,"Missing '" << attr <<
+ "' in YASim aircraft description");
+ exit(1);
+ }
+ return attrd(atts, attr, 0);
+}
+
+double FGFDM::attrd(XMLAttributes* atts, const char* attr, double def)
+{
+ const char* val = atts->getValue(attr);
+ if(val == 0) return def;
+ else return atof(val);
+}
+
// ACK: the dreaded ambiguous string boolean. Remind me to shoot Maik
// when I have a chance. :). Unless you have a parser that can check
// symbol constants (we don't), this kind of coding is just a Bad
// Unfortunately, this usage creeped into existing configuration files
// while I wasn't active, and it's going to be hard to remove. Issue
// a warning to nag people into changing their ways for now...
-bool FGFDM::attrb(XMLAttributes* atts, char* attr)
+bool FGFDM::attrb(XMLAttributes* atts, const char* attr)
{
const char* val = atts->getValue(attr);
if(val == 0) return false;