]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/YASim/FGFDM.cpp
Show YASim config error messages.
[flightgear.git] / src / FDM / YASim / FGFDM.cpp
index 0284adf257901c3d560034a078418bca304bdad2..8ce87f528df272617a8577f750870056bbac90b9 100644 (file)
@@ -16,7 +16,7 @@
 #include "TurbineEngine.hpp"
 #include "Rotor.hpp"
 #include "Rotorpart.hpp"
-#include "Rotorblade.hpp"
+#include "Hitch.hpp"
 
 #include "FGFDM.hpp"
 
@@ -132,8 +132,9 @@ void FGFDM::init()
         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);
@@ -159,12 +160,14 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts)
        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");
@@ -176,7 +179,22 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts)
        v[2] = attrf(a, "z");
        _airplane.setPilotPos(v);
     } else if(eq(name, "rotor")) {
-        _airplane.addRotor(parseRotor(a, name));
+        _airplane.getModel()->getRotorgear()->addRotor(parseRotor(a, name));
+    } else if(eq(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(eq(name, "wing")) {
        _airplane.setWing(parseWing(a, name));
     } else if(eq(name, "hstab")) {
@@ -231,6 +249,46 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts)
        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;
@@ -255,10 +313,17 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts)
             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();
@@ -302,7 +367,12 @@ void FGFDM::startElement(const char* name, const XMLAttributes &atts)
        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");
@@ -475,15 +545,17 @@ void FGFDM::setOutputProperties(float dt)
         p->prop->setFloatValue(val);
     }
 
-    for(i=0; i<_airplane.getNumRotors(); i++) {
-        Rotor*r=(Rotor*)_airplane.getRotor(i);
+    for(i=0; i<_airplane.getRotorgear()->getNumRotors(); i++) {
+        Rotor*r=(Rotor*)_airplane.getRotorgear()->getRotor(i);
         int j = 0;
         float f;
         char b[256];
         while((j = r->getValueforFGSet(j, b, &f)))
             if(b[0]) fgSetFloat(b,f);
-        
-        for(j=0; j < r->numRotorparts(); j++) {
+        j=0;
+        while((j = _airplane.getRotorgear()->getValueforFGSet(j, b, &f)))
+            if(b[0]) fgSetFloat(b,f);
+        for(j=0; j < r->numRotorparts(); j+=r->numRotorparts()>>2) {
             Rotorpart* s = (Rotorpart*)r->getRotorpart(j);
             char *b;
             int k;
@@ -492,18 +564,12 @@ void FGFDM::setOutputProperties(float dt)
                 if(b[0]) fgSetFloat(b, s->getAlpha(k));
             }
         }
-        for(j=0; j < r->numRotorblades(); j++) {
-            Rotorblade* s = (Rotorblade*)r->getRotorblade(j);
-            char *b;
-            int k;
-            for (k=0; k<2; k++) {
-                b = s->getAlphaoutput(k);
-                if(b[0]) fgSetFloat(b, s->getAlpha(k));
-            }
-        }
     }
 
-    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;
@@ -643,6 +709,7 @@ Rotor* FGFDM::parseRotor(XMLAttributes* a, const char* type)
     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);
@@ -652,13 +719,22 @@ Rotor* FGFDM::parseRotor(XMLAttributes* a, const char* type)
     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"))
@@ -670,16 +746,45 @@ Rotor* FGFDM::parseRotor(XMLAttributes* a, const char* type)
     if(a->hasAttribute("yawout"))   w->setAlphaoutput(5,a->getValue("yawout") );
     if(a->hasAttribute("rollout"))  w->setAlphaoutput(6,a->getValue("rollout") );
 
-    w->setPitchA(attrf(a, "pitch_a", 10));
-    w->setPitchB(attrf(a, "pitch_b", 10));
-    w->setForceAtPitchA(attrf(a, "forceatpitch_a", 3000));
-    w->setPowerAtPitch0(attrf(a, "poweratpitch_0", 300));
-    w->setPowerAtPitchB(attrf(a, "poweratpitch_b", 3000));
+    w->setPitchA(attrf(a, "pitch-a", 10));
+    w->setPitchB(attrf(a, "pitch-b", 10));
+    w->setForceAtPitchA(attrf(a, "forceatpitch-a", 3000));
+    w->setPowerAtPitch0(attrf(a, "poweratpitch-0", 300));
+    w->setPowerAtPitchB(attrf(a, "poweratpitch-b", 3000));
     if(attrb(a,"notorque"))
        w->setNotorque(1); 
-    if(attrb(a,"simblades"))
-       w->setSimBlades(1); 
 
+#define p(x) if (a->hasAttribute(#x)) w->setParameter((char *)#x,attrf(a,#x) );
+#define p2(x,y) if (a->hasAttribute(y)) w->setParameter((char *)#x,attrf(a,y) );
+    p2(translift_ve,"translift-ve")
+    p2(translift_maxfactor,"translift-maxfactor")
+    p2(ground_effect_constant,"ground-effect-constant")
+    p2(vortex_state_lift_factor,"vortex-state-lift-factor")
+    p2(vortex_state_c1,"vortex-state-c1")
+    p2(vortex_state_c2,"vortex-state-c2")
+    p2(vortex_state_c3,"vortex-state_c3")
+    p2(vortex_state_e1,"vortex-state-e1")
+    p2(vortex_state_e2,"vortex-state-e2")
+    p(twist)
+    p2(number_of_segments,"number-of-segments")
+    p2(number_of_parts,"number-of-parts")
+    p2(rel_len_where_incidence_is_measured,"rel-len-where-incidence-is-measured")
+    p(chord)
+    p(taper)
+    p2(airfoil_incidence_no_lift,"airfoil-incidence-no-lift")
+    p2(rel_len_blade_start,"rel-len-blade-start")
+    p2(incidence_stall_zero_speed,"incidence-stall-zero-speed")
+    p2(incidence_stall_half_sonic_speed,"incidence-stall-half-sonic-speed")
+    p2(lift_factor_stall,"lift-factor-stall")
+    p2(stall_change_over,"stall-change-over")
+    p2(drag_factor_stall,"drag-factor-stall")
+    p2(airfoil_lift_coefficient,"airfoil-lift-coefficient")
+    p2(airfoil_drag_coefficient0,"airfoil-drag-coefficient0")
+    p2(airfoil_drag_coefficient1,"airfoil-drag-coefficient1")
+    p2(cyclic_factor,"cyclic-factor")
+    p2(rotor_correction_factor,"rotor-correction-factor")
+#undef p
+#undef p2
     _currObj = w;
     return w;
 }
@@ -697,6 +802,9 @@ void FGFDM::parsePistonEngine(XMLAttributes* a)
     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;
@@ -842,9 +950,12 @@ int FGFDM::parseOutput(const char* name)
     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;
@@ -853,9 +964,22 @@ int FGFDM::parseOutput(const char* name)
     if(eq(name, "COLLECTIVE")) return ControlMap::COLLECTIVE;
     if(eq(name, "CYCLICAIL")) return ControlMap::CYCLICAIL;
     if(eq(name, "CYCLICELE")) return ControlMap::CYCLICELE;
-    if(eq(name, "ROTORENGINEON")) return ControlMap::ROTORENGINEON;
+    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);
@@ -896,7 +1020,7 @@ char* FGFDM::dup(const char* s)
     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 <<
@@ -906,14 +1030,14 @@ int FGFDM::attri(XMLAttributes* atts, char* 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 <<
@@ -923,13 +1047,30 @@ float FGFDM::attrf(XMLAttributes* atts, char* 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
@@ -941,7 +1082,7 @@ float FGFDM::attrf(XMLAttributes* atts, char* attr, float def)
 // 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;