]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim.cxx
Sync with latest JSBSim CVS.
[flightgear.git] / src / FDM / JSBSim.cxx
index 301f60553ee0fb64144a4af3ef2ccc9c0b7628e5..ee28d6a633c53033708ee134625f50f607541532 100644 (file)
@@ -49,7 +49,6 @@
 #include <FDM/JSBSim/FGState.h>
 #include <FDM/JSBSim/FGTranslation.h>
 #include <FDM/JSBSim/FGAuxiliary.h>
-#include <FDM/JSBSim/FGDefs.h>
 #include <FDM/JSBSim/FGInitialCondition.h>
 #include <FDM/JSBSim/FGTrim.h>
 #include <FDM/JSBSim/FGAtmosphere.h>
@@ -64,20 +63,24 @@ FGJSBsim::FGJSBsim( double dt )
 {
     bool result;
    
-    fdmex=new FGFDMExec;
+    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();
+    GroundReactions = fdmex->GetGroundReactions();  
+  
+    
+    Atmosphere->UseInternal();
     
-    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();
-
     fgic=new FGInitialCondition(fdmex);
     needTrim=true;
   
@@ -93,13 +96,36 @@ FGJSBsim::FGJSBsim( double dt )
                                engine_path.str(),
                                fgGetString("/sim/aircraft") );
     
+    if (result) {
+      SG_LOG( SG_FLIGHT, SG_INFO, "  loaded aircraft.");
+    } else {
+      SG_LOG( SG_FLIGHT, SG_INFO,
+              "  aircraft does not exist (you may have mis-typed the name).");
+      throw(-1);
+    }
+
+    SG_LOG( SG_FLIGHT, SG_INFO, "" );
+    SG_LOG( SG_FLIGHT, SG_INFO, "" );
+    SG_LOG( SG_FLIGHT, SG_INFO, "After loading aircraft definition file ..." );
+
     int Neng = Propulsion->GetNumEngines();
-    SG_LOG(SG_FLIGHT,SG_INFO, "Neng: " << Neng );
-    
+    SG_LOG( SG_FLIGHT, SG_INFO, "num engines = " << Neng );
     for(int i=0;i<Neng;i++) {
         add_engine( FGEngInterface() );
     }  
     
+    if ( GroundReactions->GetNumGearUnits() <= 0 ) {
+        SG_LOG( SG_FLIGHT, SG_ALERT, "num gear units = "
+                << 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!");
+         exit(-1);
+    }
+        
+    
+    init_gear();
+    
     fgSetDouble("/fdm/trim/pitch-trim", FCS->GetPitchTrimCmd());
     fgSetDouble("/fdm/trim/throttle",   FCS->GetThrottleCmd(0));
     fgSetDouble("/fdm/trim/aileron",    FCS->GetDaCmd());
@@ -114,13 +140,17 @@ 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);
 }
 
 /******************************************************************************/
 FGJSBsim::~FGJSBsim(void) {
-    if(fdmex != NULL) {
-        delete fdmex;
-        delete fgic;
+    if (fdmex != NULL) {
+        delete fdmex; fdmex=NULL;
+        delete fgic; fgic=NULL;
     }  
 }
 
@@ -130,17 +160,19 @@ FGJSBsim::~FGJSBsim(void) {
 // each subsequent iteration through the EOM
 
 void FGJSBsim::init() {
-                // Explicitly call the superclass's
-                // init method first.
-    FGInterface::init();
-
-    bool result;
-
+    
     SG_LOG( SG_FLIGHT, SG_INFO, "Starting and initializing JSBsim" );
+   
+    // Explicitly call the superclass's
+    // init method first.
+    common_init();
 
-    Atmosphere->UseInternal();
+    fdmex->GetState()->Initialize(fgic);
+    fdmex->RunIC(fgic); //loop JSBSim once w/o integrating
+    // fdmex->Run();       //loop JSBSim once
+    copy_from_JSBsim(); //update the bus
 
-    SG_LOG( SG_FLIGHT, SG_INFO, "  Initializing JSBSim with:" );
+    SG_LOG( SG_FLIGHT, SG_INFO, "  Initialized JSBSim with:" );
 
     switch(fgic->GetSpeedSet()) {
     case setned:
@@ -165,23 +197,29 @@ void FGJSBsim::init() {
                << Auxiliary->GetVcalibratedKTS() << " knots" );
     break;
     }
-
+    
+    stall_warning->setBoolValue(false);
+    
     SG_LOG( SG_FLIGHT, SG_INFO, "  Bank Angle: "
-            <<  Rotation->Getphi()*RADTODEG << " deg");
+            <<  Rotation->Getphi()*RADTODEG << " deg" );
     SG_LOG( SG_FLIGHT, SG_INFO, "  Pitch Angle: "
-            << Rotation->Gettht()*RADTODEG << " deg"  );
+            << Rotation->Gettht()*RADTODEG << " deg" );
     SG_LOG( SG_FLIGHT, SG_INFO, "  True Heading: "
-            << Rotation->Getpsi()*RADTODEG << " deg"  );
+            << Rotation->Getpsi()*RADTODEG << " deg" );
     SG_LOG( SG_FLIGHT, SG_INFO, "  Latitude: "
-            <<  Position->GetLatitude() << " deg" );
+            << Position->GetLatitude() << " deg" );
     SG_LOG( SG_FLIGHT, SG_INFO, "  Longitude: "
-            <<  Position->GetLongitude() << " deg"  );
-
+            << Position->GetLongitude() << " deg" );
+    SG_LOG( SG_FLIGHT, SG_INFO, "  Altitude: "
+           << Position->Geth() << " feet" );
     SG_LOG( SG_FLIGHT, SG_INFO, "  loaded initial conditions" );
 
     SG_LOG( SG_FLIGHT, SG_INFO, "  set dt" );
 
     SG_LOG( SG_FLIGHT, SG_INFO, "Finished initializing JSBSim" );
+    
+
+   
 }
 
 /******************************************************************************/
@@ -198,60 +236,71 @@ bool FGJSBsim::update( int multiloop ) {
 
     trimmed->setBoolValue(false);
 
-    if ( needTrim && startup_trim->getBoolValue() ) {
-
-        //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() );
-
-        controls.set_elevator_trim(FCS->GetPitchTrimCmd());
-        controls.set_elevator(FCS->GetDeCmd());
-        controls.set_throttle(FGControls::ALL_ENGINES,
-                              FCS->GetThrottleCmd(0));
-
-        controls.set_aileron(FCS->GetDaCmd());
-        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++ ) {
-      get_engine(i)->set_RPM( Propulsion->GetThruster(i)->GetRPM() );
-      get_engine(i)->set_Throttle( controls.get_throttle(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();
     }
 
-    // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
-    // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
+    struct FGJSBBase::Message* msg;
+    while (fdmex->ReadMessage()) {
+      msg = fdmex->ProcessMessage();
+      switch (msg->type) {
+      case FGJSBBase::Message::eText:
+        cout << msg->messageId << ": " << msg->text << endl;
+        break;
+      case FGJSBBase::Message::eBool:
+        cout << msg->messageId << ": " << msg->text << " " << msg->bVal << endl;
+        break;
+      case FGJSBBase::Message::eInteger:
+        cout << msg->messageId << ": " << msg->text << " " << msg->iVal << endl;
+        break;
+      case FGJSBBase::Message::eDouble:
+        cout << msg->messageId << ": " << msg->text << " " << msg->dVal << endl;
+        break;
+      default:
+        cerr << "Unrecognized message type." << endl;
+              break;
+      }
+    }
+
+    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() );
+      e->set_CHT( eng->getCylinderHeadTemp_degF() );
+      e->set_Oil_Temp( eng->getOilTemp_degF() );
+      e->set_Running_Flag( eng->GetRunning() );
+      e->set_Cranking_Flag( eng->GetCranking() );
+    }
 
+    
+    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;
 }
@@ -263,21 +312,23 @@ bool FGJSBsim::update( int multiloop ) {
 bool FGJSBsim::copy_to_JSBsim() {
     // copy control positions into the JSBsim structure
 
-    FCS->SetDaCmd( controls.get_aileron());
-    FCS->SetDeCmd( controls.get_elevator());
-    FCS->SetPitchTrimCmd(controls.get_elevator_trim());
-    FCS->SetDrCmd( -controls.get_rudder());
-    FCS->SetDfCmd(  controls.get_flaps() );
+    FCS->SetDaCmd( globals->get_controls()->get_aileron());
+    FCS->SetDeCmd( globals->get_controls()->get_elevator());
+    FCS->SetPitchTrimCmd(globals->get_controls()->get_elevator_trim());
+    FCS->SetDrCmd( -globals->get_controls()->get_rudder());
+    FCS->SetDfCmd(  globals->get_controls()->get_flaps() );
     FCS->SetDsbCmd( 0.0 ); //speedbrakes
     FCS->SetDspCmd( 0.0 ); //spoilers
-    FCS->SetThrottleCmd( FGControls::ALL_ENGINES,
-                         controls.get_throttle( 0 ));
-    FCS->SetLBrake( controls.get_brake( 0 ) );
-    FCS->SetRBrake( controls.get_brake( 1 ) );
-    FCS->SetCBrake( controls.get_brake( 2 ) );
+    FCS->SetLBrake( globals->get_controls()->get_brake( 0 ) );
+    FCS->SetRBrake( globals->get_controls()->get_brake( 1 ) );
+    FCS->SetCBrake( globals->get_controls()->get_brake( 2 ) );
+    for (int i = 0; i < get_num_engines(); i++) {
+      FCS->SetThrottleCmd(i, globals->get_controls()->get_throttle(i));
+      FCS->SetMixtureCmd(i, globals->get_controls()->get_mixture(i));
+    }
 
     Position->SetSeaLevelRadius( get_Sea_level_radius() );
-    Position->SetRunwayRadius( scenery.cur_elev*SG_METER_TO_FEET
+    Position->SetRunwayRadius( scenery.get_cur_elev()*SG_METER_TO_FEET
                                + get_Sea_level_radius() );
 
     Atmosphere->SetExTemperature(get_Static_temperature());
@@ -311,25 +362,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_CG_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_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() );
 
@@ -372,6 +423,8 @@ bool FGJSBsim::copy_from_JSBsim() {
                      Position->GetLongitude(),
                      Position->Geth() );
 
+    _set_Altitude_AGL( Position->GetDistanceAGL() );
+
     _set_Euler_Angles( Rotation->Getphi(),
                        Rotation->Gettht(),
                        Rotation->Getpsi() );
@@ -396,19 +449,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();
 }
@@ -427,17 +467,26 @@ bool FGJSBsim::ToggleDataLogging(bool state) {
 
 //Positions
 void FGJSBsim::set_Latitude(double lat) {
-    double sea_level_radius_meters,lat_geoc;
+    static const SGPropertyNode *altitude
+       = fgGetNode("/position/altitude-ft");
+    double alt;
+    if ( altitude->getDoubleValue() > -9990 ) {
+       alt = altitude->getDoubleValue();
+    } else {
+       alt = 0.0;
+    }
+
+    double sea_level_radius_meters, lat_geoc;
 
     SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Latitude: " << lat );
+    SG_LOG(SG_FLIGHT,SG_INFO," cur alt (ft) =  " << alt );
 
-    snap_shot();
-    sgGeodToGeoc( lat, get_Altitude() , &sea_level_radius_meters, &lat_geoc);
+    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 );
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
     needTrim=true;
 }
 
@@ -445,46 +494,39 @@ void FGJSBsim::set_Longitude(double lon) {
 
     SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Longitude: " << lon );
 
-    snap_shot();
-    fgic->SetLongitudeRadIC(lon);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
+    fgic->SetLongitudeRadIC( lon );
     needTrim=true;
 }
 
 void FGJSBsim::set_Altitude(double alt) {
+    static const SGPropertyNode *latitude
+       = fgGetNode("/position/latitude-deg");
+
     double sea_level_radius_meters,lat_geoc;
 
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Altitude: " << alt );
+    SG_LOG(SG_FLIGHT,SG_INFO, "  lat (deg) = " << latitude->getDoubleValue() );
 
-    snap_shot();
-    sgGeodToGeoc( get_Latitude(), alt , &sea_level_radius_meters, &lat_geoc);
+    sgGeodToGeoc( latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, 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::set_V_calibrated_kts(double vc) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_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::set_Mach_number(double mach) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Mach_number: " <<  mach );
 
-    snap_shot();
     fgic->SetMachIC(mach);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
     needTrim=true;
 }
 
@@ -492,12 +534,9 @@ void FGJSBsim::set_Velocities_Local( double north, double east, double down ){
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_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;
 }
 
@@ -505,12 +544,9 @@ void FGJSBsim::set_Velocities_Wind_Body( double u, double v, double w){
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_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;
 }
 
@@ -519,12 +555,9 @@ void FGJSBsim::set_Euler_Angles( double phi, double theta, double psi ) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_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;
 }
 
@@ -532,20 +565,14 @@ void FGJSBsim::set_Euler_Angles( double phi, double theta, double psi ) {
 void FGJSBsim::set_Climb_Rate( double roc) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Climb_Rate: " << roc );
 
-    snap_shot();
     fgic->SetClimbRateFpsIC(roc);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
     needTrim=true;
 }
 
 void FGJSBsim::set_Gamma_vert_rad( double gamma) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Gamma_vert_rad: " << gamma );
 
-    snap_shot();
     fgic->SetFlightPathAngleRadIC(gamma);
-    fdmex->RunIC(fgic); //loop JSBSim once
-    copy_from_JSBsim(); //update the bus
     needTrim=true;
 }
 
@@ -553,28 +580,21 @@ void FGJSBsim::set_Gamma_vert_rad( double gamma) {
 void FGJSBsim::set_Sea_level_radius(double slr) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_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::set_Runway_altitude(double ralt) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_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::set_Static_pressure(double p) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Static_pressure: " << p );
 
-    snap_shot();
     Atmosphere->SetExPressure(p);
     if(Atmosphere->External() == true)
     needTrim=true;
@@ -583,7 +603,6 @@ void FGJSBsim::set_Static_pressure(double p) {
 void FGJSBsim::set_Static_temperature(double T) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Static_temperature: " << T );
     
-    snap_shot();
     Atmosphere->SetExTemperature(T);
     if(Atmosphere->External() == true)
     needTrim=true;
@@ -593,13 +612,11 @@ void FGJSBsim::set_Static_temperature(double T) {
 void FGJSBsim::set_Density(double rho) {
     SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Density: " << rho );
     
-    snap_shot();
     Atmosphere->SetExDensity(rho);
     if(Atmosphere->External() == true)
     needTrim=true;
 }
   
-
 void FGJSBsim::set_Velocities_Local_Airmass (double wnorth, 
                          double weast, 
                          double wdown ) {
@@ -607,9 +624,75 @@ void FGJSBsim::set_Velocities_Local_Airmass (double wnorth,
        << wnorth << ", " << weast << ", " << wdown );
     
     _set_Velocities_Local_Airmass( wnorth, weast, wdown );
-    snap_shot();
     Atmosphere->SetWindNED(wnorth, weast, wdown );
     if(Atmosphere->External() == true)
         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_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::do_trim(void) {
+
+        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() );
+
+        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());
+    
+        SG_LOG( SG_FLIGHT, SG_INFO, "  Trim complete" );
+}