]> git.mxchange.org Git - flightgear.git/commitdiff
Updates to JSBSim and FDM interface.
authorcurt <curt>
Tue, 6 Nov 2001 22:33:05 +0000 (22:33 +0000)
committercurt <curt>
Tue, 6 Nov 2001 22:33:05 +0000 (22:33 +0000)
22 files changed:
src/FDM/ADA.cxx
src/FDM/Balloon.cxx
src/FDM/JSBSim.cxx
src/FDM/JSBSim.hxx
src/FDM/JSBSim/FGAircraft.cpp
src/FDM/JSBSim/FGAircraft.h
src/FDM/JSBSim/FGAtmosphere.h
src/FDM/JSBSim/FGForce.cpp
src/FDM/JSBSim/FGForce.h
src/FDM/JSBSim/FGLGear.h
src/FDM/JSBSim/FGPropeller.cpp
src/FDM/JSBSim/FGPropeller.h
src/FDM/JSBSim/FGPropulsion.cpp
src/FDM/JSBSim/FGPropulsion.h
src/FDM/JSBSim/FGState.cpp
src/FDM/JSBSim/FGTranslation.cpp
src/FDM/JSBSim/FGTranslation.h
src/FDM/JSBSim/FGTrimAxis.cpp
src/FDM/LaRCsim.cxx
src/FDM/MagicCarpet.cxx
src/FDM/flight.cxx
src/FDM/flight.hxx

index ae8e33ed31b92f30bf6bbaa2f4509223d5bb3b96..1dd27bae8d337a35f5bcbe092d8f5d9d8b0c5f86 100644 (file)
@@ -168,9 +168,10 @@ FGADA::~FGADA() {
 // for each subsequent iteration through the EOM
 void FGADA::init() {
 
-       // explicitly call the superclass's
-       // init() method first.
-    FGInterface::init();
+    //do init common to all FDM"s
+    common_init();
+    
+    //now do ADA-specific init.
 
     // cout << "FGADA::init()" << endl;
 
index 86e0f7156c3621874d0298eb55154b5f1ca3d739..4bde1049f443bc9d1c2c092cf81678081e45db0d 100644 (file)
@@ -75,9 +75,11 @@ FGBalloonSim::~FGBalloonSim() {
 // Initialize the BalloonSim flight model, dt is the time increment for
 // each subsequent iteration through the EOM
 void FGBalloonSim::init() {
-                               // explicitly call the superclass's
-                               // init method first.
-    FGInterface::init();
+               
+    //do init common to all the FDM's          
+    common_init();
+    
+    //now do init specific to the Balloon
 
     sgVec3 temp;
 
index e7ff9c2916c2ba5b0f5d192867bce2c5246a2742..ba30c9e4155232b55b58daeb46f70091b26f7f54 100644 (file)
@@ -66,17 +66,19 @@ FGJSBsim::FGJSBsim( double dt )
    
     fdmex = new FGFDMExec;
     
-    State        = fdmex->GetState();
-    Atmosphere   = fdmex->GetAtmosphere();
-    FCS          = fdmex->GetFCS();
-    MassBalance  = fdmex->GetMassBalance();
-    Propulsion   = fdmex->GetPropulsion();
-    Aircraft     = fdmex->GetAircraft();
-    Translation  = fdmex->GetTranslation();
-    Rotation     = fdmex->GetRotation();
-    Position     = fdmex->GetPosition();
-    Auxiliary    = fdmex->GetAuxiliary();
-    Aerodynamics = fdmex->GetAerodynamics();
+    State           = fdmex->GetState();
+    Atmosphere      = fdmex->GetAtmosphere();
+    FCS             = fdmex->GetFCS();
+    MassBalance     = fdmex->GetMassBalance();
+    Propulsion      = fdmex->GetPropulsion();
+    Aircraft        = fdmex->GetAircraft();
+    Translation     = fdmex->GetTranslation();
+    Rotation        = fdmex->GetRotation();
+    Position        = fdmex->GetPosition();
+    Auxiliary       = fdmex->GetAuxiliary();
+    Aerodynamics    = fdmex->GetAerodynamics();
+    GroundReactions = fdmex->GetGroundReactions();  
+  
     
     Atmosphere->UseInternal();
     
@@ -113,9 +115,9 @@ FGJSBsim::FGJSBsim( double dt )
         add_engine( FGEngInterface() );
     }  
     
-    if ( fdmex->GetGroundReactions()->GetNumGearUnits() <= 0 ) {
+    if ( GroundReactions->GetNumGearUnits() <= 0 ) {
         SG_LOG( SG_FLIGHT, SG_ALERT, "num gear units = "
-                << fdmex->GetGroundReactions()->GetNumGearUnits() );
+                << GroundReactions->GetNumGearUnits() );
         SG_LOG( SG_FLIGHT, SG_ALERT, "This is a very bad thing because with 0 gear units, the ground trimming");
          SG_LOG( SG_FLIGHT, SG_ALERT, "routine (coming up later in the code) will core dump.");
          SG_LOG( SG_FLIGHT, SG_ALERT, "Halting the sim now, and hoping a solution will present itself soon!");
@@ -123,6 +125,8 @@ FGJSBsim::FGJSBsim( double dt )
     }
         
     
+    init_gear();
+    
     fgSetDouble("/fdm/trim/pitch-trim", FCS->GetPitchTrimCmd());
     fgSetDouble("/fdm/trim/throttle",   FCS->GetThrottleCmd(0));
     fgSetDouble("/fdm/trim/aileron",    FCS->GetDaCmd());
@@ -137,6 +141,10 @@ FGJSBsim::FGJSBsim( double dt )
     throttle_trim = fgGetNode("/fdm/trim/throttle", true );
     aileron_trim = fgGetNode("/fdm/trim/aileron", true );
     rudder_trim = fgGetNode("/fdm/trim/rudder", true );
+    
+    
+    stall_warning = fgGetNode("/sim/aircraft/alarms/stall-warning",true);
+    stall_warning->setDoubleValue(0);
 }
 
 /******************************************************************************/
@@ -158,7 +166,7 @@ void FGJSBsim::init() {
    
     // Explicitly call the superclass's
     // init method first.
-    FGInterface::init();
+    common_init();
 
     fdmex->GetState()->Initialize(fgic);
     fdmex->RunIC(fgic); //loop JSBSim once w/o integrating
@@ -190,7 +198,9 @@ void FGJSBsim::init() {
                << Auxiliary->GetVcalibratedKTS() << " knots" );
     break;
     }
-
+    
+    stall_warning->setBoolValue(false);
+    
     SG_LOG( SG_FLIGHT, SG_INFO, "  Bank Angle: "
             <<  Rotation->Getphi()*RADTODEG << " deg" );
     SG_LOG( SG_FLIGHT, SG_INFO, "  Pitch Angle: "
@@ -208,6 +218,9 @@ void FGJSBsim::init() {
     SG_LOG( SG_FLIGHT, SG_INFO, "  set dt" );
 
     SG_LOG( SG_FLIGHT, SG_INFO, "Finished initializing JSBSim" );
+    
+
+   
 }
 
 /******************************************************************************/
@@ -224,51 +237,33 @@ bool FGJSBsim::update( int multiloop ) {
 
     trimmed->setBoolValue(false);
 
-    if ( needTrim && startup_trim->getBoolValue() ) {
-        cout << "num gear units = " << fdmex->GetGroundReactions()->GetNumGearUnits() << endl;
-        //fgic->SetSeaLevelRadiusFtIC( get_Sea_level_radius() );
-        //fgic->SetTerrainAltitudeFtIC( scenery.cur_elev * SG_METER_TO_FEET );
-
-        FGTrim *fgtrim;
-        if(fgic->GetVcalibratedKtsIC() < 10 ) {
-            fgic->SetVcalibratedKtsIC(0.0);
-            fgtrim=new FGTrim(fdmex,fgic,tGround);
-        } else {
-            fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
-        }
-        if(!fgtrim->DoTrim()) {
-            fgtrim->Report();
-            fgtrim->TrimStats();
-        } else {
-            trimmed->setBoolValue(true);
-        }
-        fgtrim->ReportState();
-        delete fgtrim;
-
-        needTrim=false;
-
-        pitch_trim->setDoubleValue( FCS->GetPitchTrimCmd() );
-        throttle_trim->setDoubleValue( FCS->GetThrottleCmd(0) );
-        aileron_trim->setDoubleValue( FCS->GetDaCmd() );
-        rudder_trim->setDoubleValue( FCS->GetDrCmd() );
-
-        globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
-        globals->get_controls()->set_elevator(FCS->GetDeCmd());
-        globals->get_controls()->set_throttle(FGControls::ALL_ENGINES,
-                                              FCS->GetThrottleCmd(0));
-
-        globals->get_controls()->set_aileron(FCS->GetDaCmd());
-        globals->get_controls()->set_rudder( FCS->GetDrCmd());
+    if ( needTrim ) {
+      if ( startup_trim->getBoolValue() ) {
+        do_trim();
+      } else {
+        fdmex->RunIC(fgic);  //apply any changes made through the set_ functions
+      }
+      needTrim = false;  
+    }    
     
-        SG_LOG( SG_FLIGHT, SG_INFO, "  Trim complete" );
-    }
-  
     for( i=0; i<get_num_engines(); i++ ) {
       FGEngInterface * e = get_engine(i);
       FGEngine * eng = Propulsion->GetEngine(i);
       FGThruster * thrust = Propulsion->GetThruster(i);
       eng->SetMagnetos( globals->get_controls()->get_magnetos(i) );
       eng->SetStarter( globals->get_controls()->get_starter(i) );
+      e->set_Throttle( globals->get_controls()->get_throttle(i) );
+    }
+
+
+    for ( i=0; i < multiloop; i++ ) {
+        fdmex->Run();
+    }
+
+    for( i=0; i<get_num_engines(); i++ ) {
+      FGEngInterface * e = get_engine(i);
+      FGEngine * eng = Propulsion->GetEngine(i);
+      FGThruster * thrust = Propulsion->GetThruster(i);
       e->set_Manifold_Pressure( eng->getManifoldPressure_inHg() );
       e->set_RPM( thrust->GetRPM() );
       e->set_EGT( eng->getExhaustGasTemp_degF() );
@@ -276,19 +271,15 @@ bool FGJSBsim::update( int multiloop ) {
       e->set_Oil_Temp( eng->getOilTemp_degF() );
       e->set_Running_Flag( eng->GetRunning() );
       e->set_Cranking_Flag( eng->GetCranking() );
-      e->set_Throttle( globals->get_controls()->get_throttle(i) );
     }
 
-    for ( i=0; i < multiloop; i++ ) {
-        fdmex->Run();
-    }
-
-    // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
-    // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
-
+    
+    update_gear();
+    
+    stall_warning->setDoubleValue( Aircraft->GetStallWarn() );
+    
     // translate JSBsim back to FG structure so that the
     // autopilot (and the rest of the sim can use the updated values
-
     copy_from_JSBsim();
     return true;
 }
@@ -350,25 +341,25 @@ bool FGJSBsim::copy_from_JSBsim() {
                       MassBalance->GetXYZcg(2),
                       MassBalance->GetXYZcg(3) );
 
-    _set_Accels_Body( Translation->GetUVWdot(1),
-                      Translation->GetUVWdot(2),
-                      Translation->GetUVWdot(3) );
+    _set_Accels_Body( Aircraft->GetBodyAccel()(1),
+                      Aircraft->GetBodyAccel()(2),
+                      Aircraft->GetBodyAccel()(3) );
 
-    _set_Accels_CG_Body( Translation->GetUVWdot(1),
-                         Translation->GetUVWdot(2),
-                         Translation->GetUVWdot(3) );
-
-    //_set_Accels_CG_Body_N ( Translation->GetNcg(1),
-    //                       Translation->GetNcg(2),
-    //                       Translation->GetNcg(3) );
+    //_set_Accels_CG_Body( Aircraft->GetBodyAccel()(1),
+    //                     Aircraft->GetBodyAccel()(2),
+    //                     Aircraft->GetBodyAccel()(3) );
     //
-    _set_Accels_Pilot_Body( Auxiliary->GetPilotAccel(1),
-                            Auxiliary->GetPilotAccel(2),
-                            Auxiliary->GetPilotAccel(3) );
+    _set_Accels_CG_Body_N ( Aircraft->GetNcg()(1),
+                            Aircraft->GetNcg()(2),
+                            Aircraft->GetNcg()(3) );
+    
+    _set_Accels_Pilot_Body( Auxiliary->GetPilotAccel()(1),
+                            Auxiliary->GetPilotAccel()(2),
+                            Auxiliary->GetPilotAccel()(3) );
 
-    //_set_Accels_Pilot_Body_N( Auxiliary->GetNpilot(1),
-    //                         Auxiliary->GetNpilot(2),
-    //                         Auxiliary->GetNpilot(3) );
+   // _set_Accels_Pilot_Body_N( Auxiliary->GetPilotAccel()(1)/32.1739,
+   //                           Auxiliary->GetNpilot(2)/32.1739,
+   //                           Auxiliary->GetNpilot(3)/32.1739 );
 
     _set_Nlf( Aerodynamics->GetNlf() );
 
@@ -437,19 +428,6 @@ bool FGJSBsim::copy_from_JSBsim() {
     return true;
 }
 
-void FGJSBsim::snap_shot(void) {
-    fgic->SetLatitudeRadIC(get_Lat_geocentric() );
-    fgic->SetLongitudeRadIC( get_Longitude() );
-    fgic->SetAltitudeFtIC( get_Altitude() );
-    fgic->SetTerrainAltitudeFtIC( get_Runway_altitude() );
-    fgic->SetVtrueFpsIC( get_V_rel_wind() );
-    fgic->SetPitchAngleRadIC( get_Theta() );
-    fgic->SetRollAngleRadIC( get_Phi() );
-    fgic->SetTrueHeadingRadIC( get_Psi() );
-    fgic->SetClimbRateFpsIC( get_Climb_Rate() );
-}
-
-
 bool FGJSBsim::ToggleDataLogging(void) {
     return fdmex->GetOutput()->Toggle();
 }
@@ -484,6 +462,7 @@ void FGJSBsim::set_Latitude(double lat) {
 
     sgGeodToGeoc( lat, alt * SG_FEET_TO_METER,
                  &sea_level_radius_meters, &lat_geoc );
+    
     _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET  );
     fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET  );
     fgic->SetLatitudeRadIC( lat_geoc );
@@ -617,7 +596,6 @@ void FGJSBsim::set_Density(double rho) {
     needTrim=true;
 }
   
-
 void FGJSBsim::set_Velocities_Local_Airmass (double wnorth, 
                          double weast, 
                          double wdown ) {
@@ -630,194 +608,70 @@ void FGJSBsim::set_Velocities_Local_Airmass (double wnorth,
         needTrim=true;
 }     
 
-
-//Positions
-void FGJSBsim::update_Latitude(double lat) {
-    double sea_level_radius_meters, lat_geoc;
-
-    SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::update_Latitude: " << lat );
-    SG_LOG(SG_FLIGHT,SG_INFO," cur alt =  " << get_Altitude() );
-
-    snap_shot();
-    sgGeodToGeoc( lat, get_Altitude(), &sea_level_radius_meters, &lat_geoc);
-    _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET  );
-    fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET  );
-    fgic->SetLatitudeRadIC( lat_geoc );
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-void FGJSBsim::update_Longitude(double lon) {
-
-    SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::update_Longitude: " << lon );
-    SG_LOG(SG_FLIGHT,SG_INFO," cur alt =  " << get_Altitude() );
-
-    snap_shot();
-    fgic->SetLongitudeRadIC(lon);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-void FGJSBsim::update_Altitude(double alt) {
-    double sea_level_radius_meters,lat_geoc;
-
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Altitude: " << alt );
-
-    snap_shot();
-    sgGeodToGeoc( get_Latitude(), alt , &sea_level_radius_meters, &lat_geoc);
-    _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET  );
-    fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
-    fgic->SetLatitudeRadIC( lat_geoc );
-    fgic->SetAltitudeFtIC(alt);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-void FGJSBsim::update_V_calibrated_kts(double vc) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_V_calibrated_kts: " <<  vc );
-
-    snap_shot();
-    fgic->SetVcalibratedKtsIC(vc);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-void FGJSBsim::update_Mach_number(double mach) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Mach_number: " <<  mach );
-
-    snap_shot();
-    fgic->SetMachIC(mach);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-void FGJSBsim::update_Velocities_Local( double north, double east, double down ){
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Velocities_Local: "
-       << north << ", " <<  east << ", " << down );
-
-    snap_shot();
-    fgic->SetVnorthFpsIC(north);
-    fgic->SetVeastFpsIC(east);
-    fgic->SetVdownFpsIC(down);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-void FGJSBsim::update_Velocities_Wind_Body( double u, double v, double w){
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Velocities_Wind_Body: "
-       << u << ", " <<  v << ", " <<  w );
-
-    snap_shot();
-    fgic->SetUBodyFpsIC(u);
-    fgic->SetVBodyFpsIC(v);
-    fgic->SetWBodyFpsIC(w);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-//Euler angles
-void FGJSBsim::update_Euler_Angles( double phi, double theta, double psi ) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Euler_Angles: "
-       << phi << ", " << theta << ", " << psi );
-
-    snap_shot();
-    fgic->SetPitchAngleRadIC(theta);
-    fgic->SetRollAngleRadIC(phi);
-    fgic->SetTrueHeadingRadIC(psi);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-//Flight Path
-void FGJSBsim::update_Climb_Rate( double roc) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Climb_Rate: " << roc );
-
-    snap_shot();
-    fgic->SetClimbRateFpsIC(roc);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-void FGJSBsim::update_Gamma_vert_rad( double gamma) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Gamma_vert_rad: " << gamma );
-
-    snap_shot();
-    fgic->SetFlightPathAngleRadIC(gamma);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
-}
-
-//Earth
-void FGJSBsim::update_Sea_level_radius(double slr) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Sea_level_radius: " << slr );
-
-    snap_shot();
-    fgic->SetSeaLevelRadiusFtIC(slr);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
+void FGJSBsim::init_gear(void ) {
+    
+    FGGearInterface *gear;
+    FGGroundReactions* gr=fdmex->GetGroundReactions();
+    int Ngear=GroundReactions->GetNumGearUnits();
+    for (int i=0;i<Ngear;i++) {
+      add_gear_unit( FGGearInterface() );
+      gear=get_gear_unit(i);
+      gear->SetX( gr->GetGearUnit(i)->GetBodyLocation()(1) );
+      gear->SetY( gr->GetGearUnit(i)->GetBodyLocation()(2) );
+      gear->SetZ( gr->GetGearUnit(i)->GetBodyLocation()(3) );
+      gear->SetWoW( gr->GetGearUnit(i)->GetWOW() );
+      if ( gr->GetGearUnit(i)->GetBrakeGroup() > 0 ) {
+        gear->SetBrake(true);
+      }
+      if ( gr->GetGearUp() ) {
+        gear->SetPosition( 0.0 );
+      }    
+    }  
 }
 
-void FGJSBsim::update_Runway_altitude(double ralt) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Runway_altitude: " << ralt );
-
-    snap_shot();
-    _set_Runway_altitude( ralt );
-    fgic->SetTerrainAltitudeFtIC( ralt );
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
-    needTrim=true;
+void FGJSBsim::update_gear(void) {
+    
+    FGGearInterface* gear;
+    FGGroundReactions* gr=fdmex->GetGroundReactions();
+    int Ngear=GroundReactions->GetNumGearUnits();
+    for (int i=0;i<Ngear;i++) {
+      gear=get_gear_unit(i);
+      gear->SetWoW( gr->GetGearUnit(i)->GetWOW() );
+      if ( gr->GetGearUp() ) {
+        gear->SetPosition( 0.0 );
+      }    
+    }  
 }
 
-void FGJSBsim::update_Static_pressure(double p) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Static_pressure: " << p );
-
-    snap_shot();
-    Atmosphere->SetExPressure(p);
-    if(Atmosphere->External() == true)
-    needTrim=true;
-}
+void FGJSBsim::do_trim(void) {
 
-void FGJSBsim::update_Static_temperature(double T) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Static_temperature: " << T );
-    
-    snap_shot();
-    Atmosphere->SetExTemperature(T);
-    if(Atmosphere->External() == true)
-    needTrim=true;
-}
+        FGTrim *fgtrim;
+        if(fgic->GetVcalibratedKtsIC() < 10 ) {
+            fgic->SetVcalibratedKtsIC(0.0);
+            fgtrim=new FGTrim(fdmex,fgic,tGround);
+        } else {
+            fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
+        }
+        if( !fgtrim->DoTrim() ) {
+            fgtrim->Report();
+            fgtrim->TrimStats();
+        } else {
+            trimmed->setBoolValue(true);
+        }
+        State->ReportState();
+        delete fgtrim;
+        pitch_trim->setDoubleValue( FCS->GetPitchTrimCmd() );
+        throttle_trim->setDoubleValue( FCS->GetThrottleCmd(0) );
+        aileron_trim->setDoubleValue( FCS->GetDaCmd() );
+        rudder_trim->setDoubleValue( FCS->GetDrCmd() );
 
-void FGJSBsim::update_Density(double rho) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Density: " << rho );
-    
-    snap_shot();
-    Atmosphere->SetExDensity(rho);
-    if(Atmosphere->External() == true)
-    needTrim=true;
-}
-  
+        globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
+        globals->get_controls()->set_elevator(FCS->GetDeCmd());
+        globals->get_controls()->set_throttle(FGControls::ALL_ENGINES,
+                                              FCS->GetThrottleCmd(0));
 
-void FGJSBsim::update_Velocities_Local_Airmass (double wnorth, 
-                         double weast, 
-                         double wdown ) {
-    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Velocities_Local_Airmass: " 
-       << wnorth << ", " << weast << ", " << wdown );
+        globals->get_controls()->set_aileron(FCS->GetDaCmd());
+        globals->get_controls()->set_rudder( FCS->GetDrCmd());
     
-    _set_Velocities_Local_Airmass( wnorth, weast, wdown );
-    snap_shot();
-    Atmosphere->SetWindNED(wnorth, weast, wdown );
-    if(Atmosphere->External() == true)
-        needTrim=true;
-}     
-
+        SG_LOG( SG_FLIGHT, SG_INFO, "  Trim complete" );
+}          
index c3ee3290510116372fffd1d583953f3a8e80dd42..b8097093fdcc88e94ea2c023020ca10f3729a5c9 100644 (file)
@@ -207,101 +207,7 @@ public:
                                       double wdown );
     /// @name Position Parameter Update
     //@{
-    /** Update geocentric latitude
-        @param lat latitude in radians measured from the 0 meridian where
-                        the westerly direction is positive and east is negative */
-    void update_Latitude(double lat);  // geocentric
-
-    /** Update longitude
-        @param lon longitude in radians measured from the equator where
-                        the northerly direction is positive and south is negative */
-    void update_Longitude(double lon);
-
-    /** Update altitude
-        Note: this triggers a recalculation of AGL altitude
-             @param alt altitude in feet */
-    void update_Altitude(double alt);        // triggers re-calc of AGL altitude
-    //@}
-
-    //void update_AltitudeAGL(double altagl); // and vice-versa
-
-    /// @name Velocity Parameter Update
-    //@{
-    /** Updates calibrated airspeed
-        Updateting this will trigger a recalc of the other velocity terms.
-             @param vc Calibrated airspeed in ft/sec */
-    void update_V_calibrated_kts(double vc);
-
-    /** Updates Mach number.
-        Updateting this will trigger a recalc of the other velocity terms.
-             @param mach Mach number */
-    void update_Mach_number(double mach);
-
-    /** Updates velocity in N-E-D coordinates.
-        Updateting this will trigger a recalc of the other velocity terms.
-             @param north velocity northward in ft/sec
-             @param east velocity eastward in ft/sec
-             @param down velocity downward in ft/sec */
-    void update_Velocities_Local( double north, double east, double down );
-
-    /** Updates aircraft velocity in stability frame.
-        Updateting this will trigger a recalc of the other velocity terms.
-             @param u X velocity in ft/sec
-             @param v Y velocity  in ft/sec
-             @param w Z velocity in ft/sec */
-    void update_Velocities_Wind_Body( double u, double v, double w);
-    //@}
-
-    /** Euler Angle Parameter Update
-        @param phi roll angle in radians
-             @param theta pitch angle in radians
-             @param psi heading angle in radians */
-    void update_Euler_Angles( double phi, double theta, double psi );
-
-    /// @name Flight Path Parameter Update
-    //@{
-    /** Updates rate of climb
-        @param roc Rate of climb in ft/sec */
-    void update_Climb_Rate( double roc);
-
-    /** Updates the flight path angle in radians
-        @param gamma flight path angle in radians. */
-    void update_Gamma_vert_rad( double gamma);
-    //@}
 
-    /// @name Earth Parameter Update
-    //@{
-    /** Updates the sea level radius in feet.
-        @param slr Sea Level Radius in feet */
-    void update_Sea_level_radius(double slr);
-
-    /** Updates the runway altitude in feet above sea level.
-        @param ralt Runway altitude in feet above sea level. */
-    void update_Runway_altitude(double ralt);
-    //@}
-
-    /// @name Atmospheric Parameter Update
-    //@{
-    /** Updates the atmospheric static pressure
-        @param p pressure in psf */
-    void update_Static_pressure(double p);
-
-    /** Updates the atmospheric temperature
-        @param T temperature in degrees rankine */
-    void update_Static_temperature(double T);
-
-    /** Updates the atmospheric density.
-        @param rho air density slugs/cubic foot */
-    void update_Density(double rho);
-
-    /** Updates the velocity of the local airmass for wind modeling.
-        @param wnorth velocity north in fps
-        @param weast velocity east in fps
-        @param wdown velocity down in fps*/
-    void update_Velocities_Local_Airmass (double wnorth,
-                                      double weast,
-                                      double wdown );
-    //@}
 
     /** Update the position based on inputs, positions, velocities, etc.
         @param multiloop number of times to loop through the FDM
@@ -309,6 +215,7 @@ public:
     bool update( int multiloop );
     bool ToggleDataLogging(bool state);
     bool ToggleDataLogging(void);
+    void do_trim(void);
 
 private:
     FGFDMExec *fdmex;
@@ -326,6 +233,7 @@ private:
     FGPosition*     Position;
     FGAuxiliary*    Auxiliary;
     FGAerodynamics* Aerodynamics;
+    FGGroundReactions *GroundReactions;
 
     int runcount;
     float trim_elev;
@@ -337,8 +245,11 @@ private:
     SGPropertyNode *throttle_trim;
     SGPropertyNode *aileron_trim;
     SGPropertyNode *rudder_trim;
+    SGPropertyNode *stall_warning;
+    
+    void init_gear(void);
+    void update_gear(void);
     
-    void snap_shot(void);
 };
 
 
index 0701474f36b173fbd8bdfa051df494f6c92777de..b5cfca1c0f67af4a22042a93e75907895d50325f 100644 (file)
@@ -104,13 +104,15 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
     vXYZrp(3),
     vXYZep(3),
     vDXYZcg(3),
-    vBodyAccel(3)
+    vBodyAccel(3),
+    vNcg(3)
 {
   Name = "FGAircraft";
   alphaclmin = alphaclmax = 0;
   HTailArea = VTailArea = HTailArm = VTailArm = 0.0;
   lbarh = lbarv = vbarh = vbarv = 0.0;
   WingIncidence=0;
+  impending_stall = 0;
 
   if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
 }
@@ -176,6 +178,16 @@ bool FGAircraft::Run(void)
     
     vBodyAccel = vForces/MassBalance->GetMass();
     
+    vNcg = vBodyAccel*INVGRAVITY;
+    
+    if (alphaclmax != 0) {
+      if (Translation->Getalpha() > 0.85*alphaclmax) {
+        impending_stall = 10*(Translation->Getalpha()/alphaclmax - 0.85);
+      } else {
+        impending_stall = 0;
+      }
+    }      
+    
     return false;
   } else {                               // skip Run() execution this time
     return true;
index 055373cc18301d069d87adf5e9ed43fba5b00b57..710401f36b21e469f6279f623c28c54c4756c257 100644 (file)
@@ -189,6 +189,7 @@ public:
   inline FGColumnVector3& GetMoments(void) { return vMoments; }
   inline FGColumnVector3& GetForces(void) { return vForces; }
   inline FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
+  inline FGColumnVector3& GetNcg   (void)    { return vNcg; }
   inline FGColumnVector3& GetXYZrp(void) { return vXYZrp; }
   inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
   inline float GetXYZrp(int idx) { return vXYZrp(idx); }
@@ -198,6 +199,8 @@ public:
 
   inline void SetAlphaCLMax(float tt) { alphaclmax=tt; }
   inline void SetAlphaCLMin(float tt) { alphaclmin=tt; }
+  
+  inline bool GetStallWarn(void) { return impending_stall; }
 
   /// Subsystem types for specifying which will be output in the FDM data logging
   enum  SubSystems {
@@ -224,10 +227,13 @@ private:
   FGColumnVector3 vEuler;
   FGColumnVector3 vDXYZcg;
   FGColumnVector3 vBodyAccel;
+  FGColumnVector3 vNcg;
+
   float WingArea, WingSpan, cbar, WingIncidence;
   float HTailArea, VTailArea, HTailArm, VTailArm;
   float lbarh,lbarv,vbarh,vbarv;
   float alphaclmax,alphaclmin;
+  float impending_stall;
   string CFGVersion;
   string AircraftName;
 
index 6b61ce0b5c3bab5707de38b01e9b73f63dbc7e0b..024969310c5d056fb9d6fa3e741ea854761fade3 100644 (file)
@@ -141,19 +141,19 @@ public:
   inline float GetWindPsi(void) { return psiw; }
   
 private:
-  float rho;
+  double rho;
 
   int lastIndex;
-  float h;
-  float htab[8];
-  float SLtemperature,SLdensity,SLpressure,SLsoundspeed;
-  float rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
-  float temperature,density,pressure,soundspeed;
+  double h;
+  double htab[8];
+  double SLtemperature,SLdensity,SLpressure,SLsoundspeed;
+  double rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
+  double temperature,density,pressure,soundspeed;
   bool useExternal;
-  float exTemperature,exDensity,exPressure;
+  double exTemperature,exDensity,exPressure;
   
   FGColumnVector3 vWindNED;
-  float psiw;
+  double psiw;
 
   void Calculate(float altitude);
   void Debug(void);
index 9c2945f1b5c8fe6ffd8073479373ef9ecf027372..00ac43a7a181b81dc1e4455c05ba022ef0b65e24 100644 (file)
@@ -63,12 +63,13 @@ FGForce::FGForce(FGFDMExec *FDMExec) :
     vXYZn(3),
     vDXYZ(3),
     mT(3,3),
+    vH(3),
     vSense(3),
     ttype(tNone)
 {
-  mT(1,1)=1; //identity matrix
-  mT(2,2)=1;
-  mT(3,3)=1;
+  mT(1,1) = 1; //identity matrix
+  mT(2,2) = 1;
+  mT(3,3) = 1;
   vSense.InitMatrix(1);
   if (debug_lvl & 2) cout << "Instantiated: FGForce" << endl;
 }
@@ -84,7 +85,7 @@ FGForce::~FGForce()
 
 FGColumnVector3& FGForce::GetBodyForces(void) {
 
-  vFb=Transform()*(vFn.multElementWise(vSense));
+  vFb = Transform()*(vFn.multElementWise(vSense));
 
   //find the distance from this vector's location to the cg
   //needs to be done like this to convert from structural to body coords
@@ -92,7 +93,9 @@ FGColumnVector3& FGForce::GetBodyForces(void) {
   vDXYZ(2) =  (vXYZn(2) - fdmex->GetMassBalance()->GetXYZcg(2))*INCHTOFT;  //cg and rp values are in inches
   vDXYZ(3) = -(vXYZn(3) - fdmex->GetMassBalance()->GetXYZcg(3))*INCHTOFT;
 
-  vM=vMn +vDXYZ*vFb;
+  // include rotational effects. vH will be set in descendent class such as
+  // FGPropeller, and in most other cases will be zero.
+  vM = vMn + vDXYZ*vFb + fdmex->GetRotation()->GetPQR()*vH;
 
   return vFb;
 }
index 58c48af4179efa94b58004495b1543732b90878a..c64d931491a5a43eec46a974c725e1fc3d2884bc 100644 (file)
@@ -256,6 +256,9 @@ public:
     vXYZn(2) = y;
     vXYZn(3) = z;
   }
+  inline void SetLocationX(float x) {vXYZn(1) = x;}
+  inline void SetLocationY(float y) {vXYZn(2) = y;}
+  inline void SetLocationZ(float z) {vXYZn(3) = z;}
   inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; }
   FGColumnVector3& GetLocation(void) { return vXYZn; }
 
@@ -282,6 +285,7 @@ public:
 protected:
   FGColumnVector3 vFn;
   FGColumnVector3 vMn;
+  FGColumnVector3 vH;
   FGFDMExec *fdmex;
   virtual void Debug(void);
 
index b6c7ab0ed40d95ed9d8ecc8f296a8c2de4229207..16331004d53a64d6c12f1ce76548f2bf6dfec124 100644 (file)
@@ -228,6 +228,9 @@ public:
   inline bool GetReport(void)    { return ReportEnable; }
   inline float GetSteerAngle(void) { return SteerAngle;}
   inline float GetstaticFCoeff(void) { return staticFCoeff;}
+  
+  inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
+  inline int GetSteerType(void)  { return (int)eSteerType; }
 
 private:
   FGColumnVector3 vXYZ;
index 36b7e0e930c87269bab1e772246b9154774ec58c..06c30b82da1c7431d32a13bebd51deaf76a6f94c 100644 (file)
@@ -50,7 +50,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
   string token;
   int rows, cols;
 
-  MaxPitch = MinPitch = 0.0;
+  MaxPitch = MinPitch = P_Factor = Sense = 0.0;
 
   Name = Prop_cfg->GetValue("NAME");
   Prop_cfg->GetNextConfigLine();
@@ -67,6 +67,10 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
       *Prop_cfg >> MinPitch;
     } else if (token == "MAXPITCH") {
       *Prop_cfg >> MaxPitch;
+    } else if (token == "P_FACTOR") {
+      *Prop_cfg >> P_Factor;
+    } else if (token == "SENSE") {
+      *Prop_cfg >> Sense;
     } else if (token == "EFFICIENCY") {
       *Prop_cfg >> rows >> cols;
       if (cols == 1) Efficiency = new FGTable(rows);
@@ -97,6 +101,14 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
     cout << "      Number of Blades  = " << numBlades << endl;
     cout << "      Minimum Pitch  = " << MinPitch << endl;
     cout << "      Maximum Pitch  = " << MaxPitch << endl;
+    if (P_Factor > 0.0) cout << "      P-Factor = " << P_Factor << endl;
+    if (Sense > 0.0) {
+      cout << "      Rotation Sense = CW (viewed from pilot looking forward)" << endl;
+    } else if (Sense < 0.0) {
+      cout << "      Rotation Sense = CCW (viewed from pilot looking forward)" << endl;
+    } else {
+      cout << "      Rotation Sense = indeterminate" << endl;
+    }
     cout << "      Efficiency: " <<  endl;
     Efficiency->Print();
     cout << "      Thrust Coefficient: " <<  endl;
@@ -141,6 +153,7 @@ float FGPropeller::Calculate(float PowerAvailable)
   float Vel = (fdmex->GetTranslation()->GetvAero())(1);
   float rho = fdmex->GetAtmosphere()->GetDensity();
   float RPS = RPM/60.0;
+  float alpha, beta;
 
   if (RPM > 0.10) {
     J = Vel / (Diameter * RPM / 60.0);
@@ -154,10 +167,25 @@ float FGPropeller::Calculate(float PowerAvailable)
     C_Thrust = cThrust->GetValue(J, Pitch);
   }
 
+  if (P_Factor > 0.0001) {
+    alpha = fdmex->GetTranslation()->Getalpha();
+    beta  = fdmex->GetTranslation()->Getbeta();
+    SetLocationY(P_Factor*alpha*fabs(Sense)/Sense);
+    SetLocationZ(P_Factor*beta*fabs(Sense)/Sense);
+  } else if (P_Factor < 0.000) {
+    cerr << "P-Factor value in config file must be greater than zero" << endl;
+  }
+
   Thrust = C_Thrust*RPS*RPS*Diameter*Diameter*Diameter*Diameter*rho;
   vFn(1) = Thrust;
   omega = RPS*2.0*M_PI;
 
+  // Must consider rotated axis for propeller (V-22, helicopter case)
+  // FIX THIS !!
+  vH(eX) = Ixx*omega*fabs(Sense)/Sense;
+  vH(eY) = 0.0;
+  vH(eZ) = 0.0;
+
   if (omega <= 5) omega = 1.0;
 
   Torque = PowerAvailable / omega;
index cd014c76fa47d034683ba8fd8fec0c183f5600a6..f133d79f55e395126c5aede6dc2d9a688efbbedd 100644 (file)
@@ -150,6 +150,8 @@ private:
   float Diameter;
   float MaxPitch;
   float MinPitch;
+  float P_Factor;
+  float Sense;
   float Pitch;
   float Torque;
   FGTable *Efficiency;
index 2434228e1b97a74113798ccc6fd25a6a1d437562..16be1ffdf21f79b940bb1acadd321671e6fefb29 100644 (file)
@@ -115,6 +115,8 @@ bool FGPropulsion::GetSteadyState(void) {
   float PowerAvailable;
   float currentThrust = 0, lastThrust=-1;
   dt = State->Getdt();
+  int steady_count,j=0;
+  bool steady=false;
 
   Forces->InitMatrix();
   Moments->InitMatrix();
@@ -123,10 +125,18 @@ bool FGPropulsion::GetSteadyState(void) {
     for (unsigned int i=0; i<numEngines; i++) {
       Engines[i]->SetTrimMode(true);
       Thrusters[i]->SetdeltaT(dt*rate);
-      while (pow(currentThrust - lastThrust, 2.0) > currentThrust*0.00010) {
+      steady=false;
+      while (!steady && j < 6000) {
         PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
         lastThrust = currentThrust;
         currentThrust = Thrusters[i]->Calculate(PowerAvailable);
+        if(fabs(lastThrust-currentThrust) < 0.0001) {
+          steady_count++;
+          if(steady_count > 120) { steady=true; }
+        } else {
+          steady_count=0;
+        }
+        j++;    
       }
       *Forces  += Thrusters[i]->GetBodyForces();  // sum body frame forces
       *Moments += Thrusters[i]->GetMoments();     // sum body frame moments
@@ -141,6 +151,33 @@ bool FGPropulsion::GetSteadyState(void) {
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+
+bool FGPropulsion::ICEngineStart(void) {
+  float PowerAvailable;
+  int j;
+  dt = State->Getdt();
+
+  Forces->InitMatrix();
+  Moments->InitMatrix();
+    
+  for (unsigned int i=0; i<numEngines; i++) {
+    Engines[i]->SetTrimMode(true);
+    Thrusters[i]->SetdeltaT(dt*rate);
+    j=0;
+    while (!Engines[i]->GetRunning() && j < 2000) {
+      PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
+      Thrusters[i]->Calculate(PowerAvailable);
+      j++;    
+    }
+    *Forces  += Thrusters[i]->GetBodyForces();  // sum body frame forces
+    *Moments += Thrusters[i]->GetMoments();     // sum body frame moments
+    Engines[i]->SetTrimMode(false);
+  }
+  return true;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
 bool FGPropulsion::Load(FGConfigFile* AC_cfg)
 {
   string token, fullpath;
index cc3d37115f46358120922d0df66853c6d2e3221e..4070128fc0e8047a9c350e52e4a7d0a86acf8dcd 100644 (file)
@@ -158,8 +158,13 @@ public:
   /** Returns the number of oxidizer tanks currently actively supplying oxidizer */
   inline int GetnumSelectedOxiTanks(void)  {return numSelectedOxiTanks;}
 
+  /** Loops the engines/thrusters until thrust output steady (used for trimming) */
   bool GetSteadyState(void);
-
+  
+  /** starts the engines in IC mode (dt=0).  All engine-specific setup must
+      be done before calling this (i.e. magnetos, starter engage, etc.) */
+  bool ICEngineStart(void);
+  
   string GetPropulsionStrings(void);
   string GetPropulsionValues(void);
 
index 19bb8edc7055e3ae5b8429165750a6eb758c6343..84ef65274ba14d05e00efb72c5a6e474b6cfb9e9 100644 (file)
@@ -739,7 +739,7 @@ void FGState::ReportState(void) {
                     GetParameter(FG_RUDDER_POS)*RADTODEG );
   cout << out;                  
   snprintf(out,80, "    Throttle: %5.2f%c\n",
-                    FCS->GetThrottlePos(0),'%' );
+                    FCS->GetThrottlePos(0)*100,'%' );
   cout << out;
   
   snprintf(out,80, "    Wind Components: %5.2f kts head wind, %5.2f kts cross wind\n",
index 2e7cfca2b8f524775bf5cb7d2052827bcf4ccfac..871c8a3f57b3f2ea50ecc1e1ba6d1b7cf9ac2bca 100644 (file)
@@ -80,7 +80,6 @@ CLASS IMPLEMENTATION
 FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
     vUVW(3),
     vUVWdot(3),
-    vNcg(3),
     vlastUVWdot(3),
     mVel(3,3),
     vAero(3)
@@ -120,9 +119,7 @@ bool FGTranslation::Run(void)
     mVel(3,2) =  vUVW(eU);
     mVel(3,3) =  0.0;
 
-    vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetForces()/MassBalance->GetMass();
-
-    vNcg = vUVWdot*INVGRAVITY;
+    vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetBodyAccel();
 
     vUVW += Tc * (vlastUVWdot + vUVWdot);
     vAero = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
index 43c69b6ffe44185a7a33dcc01175ff8478e8bf0e..21dbd2aeba839a31a0d6943ff4add7031ed8dbba 100644 (file)
@@ -91,8 +91,6 @@ public:
   inline float            GetUVW   (int idx) { return vUVW(idx); }
   inline FGColumnVector3& GetUVWdot(void)    { return vUVWdot; }
   inline float            GetUVWdot(int idx) { return vUVWdot(idx); }
-  inline FGColumnVector3& GetNcg   (void)    { return vNcg; }
-  inline float            GetNcg   (int idx) { return vNcg(idx); }
   inline FGColumnVector3& GetvAero (void)    { return vAero; }
   inline float            GetvAero (int idx) { return vAero(idx); }
 
@@ -121,7 +119,6 @@ public:
 private:
   FGColumnVector3 vUVW;
   FGColumnVector3 vUVWdot;
-  FGColumnVector3 vNcg;
   FGColumnVector3 vlastUVWdot;
   FGMatrix33       mVel;
   FGColumnVector3 vAero;
index 221a8ce30af8972daca4bcaf1fd2fab867c9f7a2..d59977b0b91b8503116b4fe9979d5894194921a9 100644 (file)
@@ -150,9 +150,9 @@ FGTrimAxis::~FGTrimAxis()
 
 void FGTrimAxis::getState(void) {
   switch(state) {
-  case tUdot: state_value=fdmex->GetTranslation()->GetUVWdot(1); break;
-  case tVdot: state_value=fdmex->GetTranslation()->GetUVWdot(2); break;
-  case tWdot: state_value=fdmex->GetTranslation()->GetUVWdot(3); break;
+  case tUdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(1); break;
+  case tVdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(2); break;
+  case tWdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(3); break;
   case tQdot: state_value=fdmex->GetRotation()->GetPQRdot(2);break;
   case tPdot: state_value=fdmex->GetRotation()->GetPQRdot(1); break;
   case tRdot: state_value=fdmex->GetRotation()->GetPQRdot(3); break;
@@ -397,7 +397,10 @@ void FGTrimAxis::setThrottlesPct(void) {
       tMin=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMin();
       tMax=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMax();
       //cout << "setThrottlespct: " << i << ", " << control_min << ", " << control_max << ", " << control_value;
-      fdmex -> GetFCS() -> SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
+      fdmex->GetFCS()->SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
+      //cout << "setThrottlespct: " << fdmex->GetFCS()->GetThrottleCmd(i) << endl;
+      fdmex->RunIC(fgic); //apply throttle change
+      fdmex->GetPropulsion()->GetSteadyState();
   }
 }
 
index f6343d676d39b1e619ff18765896c22b380689e1..fedef5a210c2a3823aabab8102e6e7187a7882ce 100644 (file)
@@ -88,10 +88,10 @@ FGLaRCsim::~FGLaRCsim(void) {
 // Initialize the LaRCsim flight model, dt is the time increment for
 // each subsequent iteration through the EOM
 void FGLaRCsim::init() {
+   //do init common to all FDM's
+   common_init();
 
-               // Explicitly call the superclass's
-                               // init method first.
-    FGInterface::init();
+   //now do any specific to LaRCsim
 }
 
 
index b78d764743ca12d9a8af0518bb47d2b25b0a8159..624ae51e20311ee740f4f9e15cd3f6e509f92b13 100644 (file)
@@ -44,9 +44,7 @@ FGMagicCarpet::~FGMagicCarpet() {
 // Initialize the Magic Carpet flight model, dt is the time increment
 // for each subsequent iteration through the EOM
 void FGMagicCarpet::init() {
-                               // explicitly call the superclass's
-                               // init method first
-    FGInterface::init();
+    common_init();
 }
 
 
index 2adf802dbe05543ff4ffc6e3d03a133eca1c335b..673faaf048399b6f3324f1c9ce6f9b7808649118 100644 (file)
@@ -71,6 +71,14 @@ FGEngInterface::FGEngInterface() {
 FGEngInterface::~FGEngInterface(void) {
 }
 
+FGGearInterface::FGGearInterface(void) {
+    x=y=z=0.0;
+    brake=rolls=WoW=false;
+    position=1.0;
+}    
+
+FGGearInterface::~FGGearInterface() {
+}
 
 // Constructor
 FGInterface::FGInterface() {
@@ -167,86 +175,101 @@ FGInterface::_setup ()
     altitude_agl=0;
 }
 
+void
+FGInterface::init () {}
 
 /**
  * Initialize the state of the FDM.
  *
  * Subclasses of FGInterface may do their own, additional initialization,
- * but normally they should invoke this method explicitly first as
- * FGInterface::init() to make sure the basic structures are set up
- * properly.
+ * but there is some that is common to all.  Normally, they should call
+ * this before they begin their own init to make sure the basic structures 
+ * are set up properly.
  */
 void
-FGInterface::init ()
+FGInterface::common_init ()
 {
-  SG_LOG(SG_FLIGHT, SG_INFO, "Start initializing FGInterface");
-
-  inited = true;
-
-  stamp();
-  set_remainder(0);
-
-                               // Set initial position
-  SG_LOG(SG_FLIGHT, SG_INFO, "...initializing position...");
-  set_Longitude(fgGetDouble("/position/longitude-deg") * SGD_DEGREES_TO_RADIANS);
-  set_Latitude(fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS);
-  double ground_elev_m = scenery.get_cur_elev() + 1;
-  double ground_elev_ft = ground_elev_m * METERS_TO_FEET;
-  if (fgGetBool("/sim/startup/onground") ||
-      fgGetDouble("/position/altitude-ft") < ground_elev_ft)
-    fgSetDouble("/position/altitude-ft", ground_elev_ft);
-  set_Altitude(fgGetDouble("/position/altitude-ft"));
-
-                               // Set ground elevation
-  SG_LOG(SG_FLIGHT, SG_INFO,
-        "...initializing ground elevation to "
-        << ground_elev_ft << "ft...");
-  fgFDMSetGroundElevation("jsb", ground_elev_m);
-
-                               // Set sea-level radius
-  SG_LOG(SG_FLIGHT, SG_INFO, "...initializing sea-level radius...");
-  SG_LOG(SG_FLIGHT, SG_INFO, " lat = " << fgGetDouble("/position/latitude-deg")
-        << " alt = " << fgGetDouble("/position/altitude-ft") );
-  double sea_level_radius_meters;
-  double lat_geoc;
-  sgGeodToGeoc(fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS,
-              fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER,
-              &sea_level_radius_meters, &lat_geoc);
-  set_Sea_level_radius(sea_level_radius_meters * SG_METER_TO_FEET);
-
-                               // Set initial velocities
-  SG_LOG(SG_FLIGHT, SG_INFO, "...initializing velocities...");
-  if (!fgHasNode("/sim/startup/speed-set")) {
-    set_V_calibrated_kts(0.0);
-  } else {
-    const string speedset = fgGetString("/sim/startup/speed-set");
-    if (speedset == "knots" || speedset == "KNOTS") {
-      set_V_calibrated_kts(fgGetDouble("/velocities/airspeed-kt"));
-    } else if (speedset == "mach" || speedset == "MACH") {
-      set_Mach_number(fgGetDouble("/velocities/mach"));
-    } else if (speedset == "UVW" || speedset == "uvw") {
-      set_Velocities_Wind_Body(fgGetDouble("/velocities/uBody-fps"),
-                              fgGetDouble("/velocities/vBody-fps"),
-                              fgGetDouble("/velocities/wBody-fps"));
-    } else if (speedset == "NED" || speedset == "ned") {
-      set_Velocities_Local(fgGetDouble("/velocities/speed-north-fps"),
-                          fgGetDouble("/velocities/speed-east-fps"),
-                          fgGetDouble("/velocities/speed-down-fps"));
+    SG_LOG( SG_FLIGHT, SG_INFO, "Start common FDM init" );
+
+    set_inited( true );
+
+    stamp();
+    set_remainder( 0 );
+
+    // Set initial position
+    SG_LOG( SG_FLIGHT, SG_INFO, "...initializing position..." );
+    set_Longitude( fgGetDouble("/position/longitude-deg")
+                   * SGD_DEGREES_TO_RADIANS );
+    set_Latitude( fgGetDouble("/position/latitude-deg")
+                  * SGD_DEGREES_TO_RADIANS );
+    double ground_elev_m = scenery.get_cur_elev();
+    double ground_elev_ft = ground_elev_m * METERS_TO_FEET;
+    if ( fgGetBool("/sim/startup/onground")
+         || fgGetDouble("/position/altitude-ft") < ground_elev_ft ) {
+        fgSetDouble("/position/altitude-ft", ground_elev_ft);
+    }
+    set_Altitude( fgGetDouble("/position/altitude-ft") );
+
+    // Set ground elevation
+    SG_LOG( SG_FLIGHT, SG_INFO,
+            "...initializing ground elevation to " << ground_elev_ft
+            << "ft..." );
+    SG_LOG( SG_FLIGHT, SG_INFO, "common_init(): set ground elevation "
+            << ground_elev_ft ); 
+    base_fdm_state.set_Runway_altitude( ground_elev_ft );
+    set_Runway_altitude( ground_elev_ft );
+
+    // Set sea-level radius
+    SG_LOG( SG_FLIGHT, SG_INFO, "...initializing sea-level radius..." );
+    SG_LOG( SG_FLIGHT, SG_INFO, " lat = "
+            << fgGetDouble("/position/latitude-deg")
+            << " alt = " << fgGetDouble("/position/altitude-ft") );
+    double sea_level_radius_meters;
+    double lat_geoc;
+    sgGeodToGeoc( fgGetDouble("/position/latitude-deg")
+                    * SGD_DEGREES_TO_RADIANS,
+                  fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER,
+                  &sea_level_radius_meters, &lat_geoc );
+    set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
+
+    // Set initial velocities
+    SG_LOG( SG_FLIGHT, SG_INFO, "...initializing velocities..." );
+    if ( !fgHasNode("/sim/startup/speed-set") ) {
+        set_V_calibrated_kts(0.0);
     } else {
-      SG_LOG(SG_FLIGHT, SG_ALERT,
-            "Unrecognized value for /sim/startup/speed-set: " << speedset);
-      set_V_calibrated_kts(0.0);
+        const string speedset = fgGetString("/sim/startup/speed-set");
+        if ( speedset == "knots" || speedset == "KNOTS" ) {
+            set_V_calibrated_kts( fgGetDouble("/velocities/airspeed-kt") );
+        } else if ( speedset == "mach" || speedset == "MACH" ) {
+            set_Mach_number( fgGetDouble("/velocities/mach") );
+        } else if ( speedset == "UVW" || speedset == "uvw" ) {
+            set_Velocities_Wind_Body(
+                                     fgGetDouble("/velocities/uBody-fps"),
+                                     fgGetDouble("/velocities/vBody-fps"),
+                                     fgGetDouble("/velocities/wBody-fps") );
+        } else if ( speedset == "NED" || speedset == "ned" ) {
+            set_Velocities_Local(
+                                 fgGetDouble("/velocities/speed-north-fps"),
+                                 fgGetDouble("/velocities/speed-east-fps"),
+                                 fgGetDouble("/velocities/speed-down-fps") );
+        } else {
+            SG_LOG( SG_FLIGHT, SG_ALERT,
+                    "Unrecognized value for /sim/startup/speed-set: "
+                    << speedset);
+            set_V_calibrated_kts( 0.0 );
+        }
     }
-  }
 
-                               // Set initial Euler angles
-  SG_LOG(SG_FLIGHT, SG_INFO, "...initializing Euler angles...");
-  set_Euler_Angles
-    (fgGetDouble("/orientation/roll-deg") * SGD_DEGREES_TO_RADIANS,
-     fgGetDouble("/orientation/pitch-deg") * SGD_DEGREES_TO_RADIANS,
-     fgGetDouble("/orientation/heading-deg") * SGD_DEGREES_TO_RADIANS);
+    // Set initial Euler angles
+    SG_LOG( SG_FLIGHT, SG_INFO, "...initializing Euler angles..." );
+    set_Euler_Angles( fgGetDouble("/orientation/roll-deg")
+                        * SGD_DEGREES_TO_RADIANS,
+                      fgGetDouble("/orientation/pitch-deg")
+                        * SGD_DEGREES_TO_RADIANS,
+                      fgGetDouble("/orientation/heading-deg")
+                        * SGD_DEGREES_TO_RADIANS );
 
-  SG_LOG(SG_FLIGHT, SG_INFO, "End initializing FGInterface");
+    SG_LOG( SG_FLIGHT, SG_INFO, "End common FDM init" );
 }
 
 
@@ -524,15 +547,6 @@ void fgFDMForceAltitude(const string &model, double alt_meters) {
 }
 
 
-// Set the local ground elevation
-void fgFDMSetGroundElevation(const string &model, double ground_meters) {
-    SG_LOG( SG_FLIGHT,SG_INFO, "fgFDMSetGroundElevation: "
-           << ground_meters*SG_METER_TO_FEET ); 
-    base_fdm_state.set_Runway_altitude( ground_meters * SG_METER_TO_FEET );
-    cur_fdm_state->set_Runway_altitude( ground_meters * SG_METER_TO_FEET );
-}
-
-
 // Positions
 void FGInterface::set_Latitude(double lat) { 
     geodetic_position_v[0] = lat;
@@ -723,4 +737,3 @@ void FGInterface::_busdump(void) {
 void fgToggleFDMdataLogging(void) {
   cur_fdm_state->ToggleDataLogging();
 }
-
index e23a28c75e03bb2b93217752a2e2fd5995fc8423..f37ada9eee24bdafe4f377f66af0cdf066ef93f8 100644 (file)
@@ -177,6 +177,43 @@ public:
 
 typedef vector < FGEngInterface > engine_list;
 
+class FGGearInterface {
+   private:
+   
+     string name;
+     float x,y,z;     // >0 forward of cg, >0 right, >0 down
+     bool brake;      // true if this gear unit has a brake mechanism
+     bool rolls;      // true if this gear unit has a wheel
+     bool WoW;        // true if this gear unit is touching the ground
+     float position;  // 0 if retracted, 1 if extended
+   
+   public:
+     FGGearInterface(void);
+     ~FGGearInterface(void);
+     inline string GetName(void)     { return name; }
+     inline void SetName(string nm)  { name=nm; }
+     inline float GetX(void)         { return x; }
+     inline void SetX(float xloc)    { x=xloc;   }
+     inline float GetY(void)         { return y; }
+     inline void SetY(float yloc)    { y=yloc;   }
+     inline float GetZ(void)         { return z; }
+     inline void SetZ(float zloc)    { z=zloc;   }
+     inline bool GetBrake(void)      { return brake; }
+     inline void SetBrake(bool brk) { brake=brk; }
+     
+     // no good way to implement these right now
+     //inline bool GetRolls(void)      { return rolls; }
+     //inline SetRolls(bool rl)        { rolls=rl; }
+     
+     inline bool GetWoW(void)        { return WoW; }        
+     inline void SetWoW(bool wow)         { WoW=wow;    }     
+     inline float GetPosition(void)  { return position; }
+     inline void SetPosition(float pos) { position=pos; }
+};
+
+typedef vector < FGGearInterface > gear_list;       
+           
+
 
 // This is based heavily on LaRCsim/ls_generic.h
 class FGInterface : public FGSubsystem {
@@ -302,6 +339,9 @@ private:
 
     // Engine list
     engine_list engines;
+    
+    //gear list
+    gear_list gear;
 
     // SGTimeStamp valid_stamp;          // time this record is valid
     // SGTimeStamp next_stamp;           // time this record is valid
@@ -521,6 +561,9 @@ public:
 
     inline bool get_bound() const { return bound; }
 
+    //perform initializion that is common to all FDM's
+    void common_init();
+
     // time and update management values
     inline double get_delta_t() const { return delta_t; }
     inline void set_delta_t( double dt ) { delta_t = dt; }
@@ -1179,6 +1222,19 @@ public:
     inline void add_engine( FGEngInterface e ) {
        engines.push_back( e );
     }
+    
+    //gear
+    inline int get_num_gear() const {
+      return gear.size();
+    }
+    
+    inline FGGearInterface* get_gear_unit( int i ) {
+       return &gear[i];
+    }
+    
+    inline void add_gear_unit( FGGearInterface fgi ) {
+       gear.push_back( fgi );
+    }        
 };
 
 
@@ -1195,9 +1251,6 @@ extern FGInterface * cur_fdm_state;
 // Set the altitude (force)
 void fgFDMForceAltitude(const string &model, double alt_meters);
 
-// Set the local ground elevation
-void fgFDMSetGroundElevation(const string &model, double alt_meters);
-
 // Toggle data logging on/off
 void fgToggleFDMdataLogging(void);