~ubuntu-branches/ubuntu/quantal/flightgear/quantal

« back to all changes in this revision

Viewing changes to src/FDM/JSBSim.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Ove Kaaven
  • Date: 2002-03-27 21:50:15 UTC
  • Revision ID: james.westby@ubuntu.com-20020327215015-0rvi3o8iml0a8s93
Tags: upstream-0.7.9
ImportĀ upstreamĀ versionĀ 0.7.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// JSBsim.cxx -- interface to the JSBsim flight model
 
2
//
 
3
// Written by Curtis Olson, started February 1999.
 
4
//
 
5
// Copyright (C) 1999  Curtis L. Olson  - curt@flightgear.org
 
6
//
 
7
// This program is free software; you can redistribute it and/or
 
8
// modify it under the terms of the GNU General Public License as
 
9
// published by the Free Software Foundation; either version 2 of the
 
10
// License, or (at your option) any later version.
 
11
//
 
12
// This program is distributed in the hope that it will be useful, but
 
13
// WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
// General Public License for more details.
 
16
//
 
17
// You should have received a copy of the GNU General Public License
 
18
// along with this program; if not, write to the Free Software
 
19
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
20
//
 
21
// $Id: JSBSim.cxx,v 1.88 2002/02/13 19:51:57 david Exp $
 
22
 
 
23
 
 
24
#include <simgear/compiler.h>
 
25
 
 
26
#ifdef SG_MATH_EXCEPTION_CLASH
 
27
#  include <math.h>
 
28
#endif
 
29
 
 
30
#include STL_STRING
 
31
 
 
32
#include <simgear/constants.h>
 
33
#include <simgear/debug/logstream.hxx>
 
34
#include <simgear/math/sg_geodesy.hxx>
 
35
#include <simgear/misc/sg_path.hxx>
 
36
 
 
37
#include <Scenery/scenery.hxx>
 
38
 
 
39
#include <Aircraft/aircraft.hxx>
 
40
#include <Controls/controls.hxx>
 
41
#include <Main/globals.hxx>
 
42
#include <Main/fg_props.hxx>
 
43
 
 
44
#include <FDM/JSBSim/FGFDMExec.h>
 
45
#include <FDM/JSBSim/FGAircraft.h>
 
46
#include <FDM/JSBSim/FGFCS.h>
 
47
#include <FDM/JSBSim/FGPosition.h>
 
48
#include <FDM/JSBSim/FGRotation.h>
 
49
#include <FDM/JSBSim/FGState.h>
 
50
#include <FDM/JSBSim/FGTranslation.h>
 
51
#include <FDM/JSBSim/FGAuxiliary.h>
 
52
#include <FDM/JSBSim/FGInitialCondition.h>
 
53
#include <FDM/JSBSim/FGTrim.h>
 
54
#include <FDM/JSBSim/FGAtmosphere.h>
 
55
#include <FDM/JSBSim/FGMassBalance.h>
 
56
#include <FDM/JSBSim/FGAerodynamics.h>
 
57
#include <FDM/JSBSim/FGLGear.h>
 
58
#include "JSBSim.hxx"
 
59
 
 
60
/******************************************************************************/
 
61
 
 
62
FGJSBsim::FGJSBsim( double dt ) 
 
63
  : FGInterface(dt)
 
64
{
 
65
    bool result;
 
66
   
 
67
    fdmex = new FGFDMExec;
 
68
    
 
69
    State           = fdmex->GetState();
 
70
    Atmosphere      = fdmex->GetAtmosphere();
 
71
    FCS             = fdmex->GetFCS();
 
72
    MassBalance     = fdmex->GetMassBalance();
 
73
    Propulsion      = fdmex->GetPropulsion();
 
74
    Aircraft        = fdmex->GetAircraft();
 
75
    Translation     = fdmex->GetTranslation();
 
76
    Rotation        = fdmex->GetRotation();
 
77
    Position        = fdmex->GetPosition();
 
78
    Auxiliary       = fdmex->GetAuxiliary();
 
79
    Aerodynamics    = fdmex->GetAerodynamics();
 
80
    GroundReactions = fdmex->GetGroundReactions();  
 
81
  
 
82
    
 
83
    Atmosphere->UseInternal();
 
84
    
 
85
    fgic=new FGInitialCondition(fdmex);
 
86
    needTrim=true;
 
87
  
 
88
    SGPath aircraft_path( globals->get_fg_root() );
 
89
    aircraft_path.append( "Aircraft" );
 
90
 
 
91
    SGPath engine_path( globals->get_fg_root() );
 
92
    engine_path.append( "Engine" );
 
93
    set_delta_t( dt );
 
94
    State->Setdt( dt );
 
95
 
 
96
    result = fdmex->LoadModel( aircraft_path.str(),
 
97
                               engine_path.str(),
 
98
                               fgGetString("/sim/aero") );
 
99
    
 
100
    if (result) {
 
101
      SG_LOG( SG_FLIGHT, SG_INFO, "  loaded aero.");
 
102
    } else {
 
103
      SG_LOG( SG_FLIGHT, SG_INFO,
 
104
              "  aero does not exist (you may have mis-typed the name).");
 
105
      throw(-1);
 
106
    }
 
107
 
 
108
    SG_LOG( SG_FLIGHT, SG_INFO, "" );
 
109
    SG_LOG( SG_FLIGHT, SG_INFO, "" );
 
110
    SG_LOG( SG_FLIGHT, SG_INFO, "After loading aero definition file ..." );
 
111
 
 
112
    int Neng = Propulsion->GetNumEngines();
 
113
    SG_LOG( SG_FLIGHT, SG_INFO, "num engines = " << Neng );
 
114
    
 
115
    if ( GroundReactions->GetNumGearUnits() <= 0 ) {
 
116
        SG_LOG( SG_FLIGHT, SG_ALERT, "num gear units = "
 
117
                << GroundReactions->GetNumGearUnits() );
 
118
        SG_LOG( SG_FLIGHT, SG_ALERT, "This is a very bad thing because with 0 gear units, the ground trimming");
 
119
         SG_LOG( SG_FLIGHT, SG_ALERT, "routine (coming up later in the code) will core dump.");
 
120
         SG_LOG( SG_FLIGHT, SG_ALERT, "Halting the sim now, and hoping a solution will present itself soon!");
 
121
         exit(-1);
 
122
    }
 
123
        
 
124
    
 
125
    init_gear();
 
126
 
 
127
                                // Set initial fuel levels if provided.
 
128
    for (unsigned int i = 0; i < Propulsion->GetNumTanks(); i++) {
 
129
      SGPropertyNode * node = fgGetNode("/consumables/fuel/tank", i, true);
 
130
      if (node->getChild("level-gal_us", 0, false) != 0)
 
131
        Propulsion->GetTank(i)
 
132
          ->SetContents(node->getDoubleValue("level-gal_us") * 6.6);
 
133
    }
 
134
    
 
135
    fgSetDouble("/fdm/trim/pitch-trim", FCS->GetPitchTrimCmd());
 
136
    fgSetDouble("/fdm/trim/throttle",   FCS->GetThrottleCmd(0));
 
137
    fgSetDouble("/fdm/trim/aileron",    FCS->GetDaCmd());
 
138
    fgSetDouble("/fdm/trim/rudder",     FCS->GetDrCmd());
 
139
 
 
140
    startup_trim = fgGetNode("/sim/startup/trim", true);
 
141
 
 
142
    trimmed = fgGetNode("/fdm/trim/trimmed", true);
 
143
    trimmed->setBoolValue(false);
 
144
 
 
145
    pitch_trim = fgGetNode("/fdm/trim/pitch-trim", true );
 
146
    throttle_trim = fgGetNode("/fdm/trim/throttle", true );
 
147
    aileron_trim = fgGetNode("/fdm/trim/aileron", true );
 
148
    rudder_trim = fgGetNode("/fdm/trim/rudder", true );
 
149
    
 
150
    
 
151
    stall_warning = fgGetNode("/sim/aero/alarms/stall-warning",true);
 
152
    stall_warning->setDoubleValue(0);
 
153
}
 
154
 
 
155
/******************************************************************************/
 
156
FGJSBsim::~FGJSBsim(void) {
 
157
    if (fdmex != NULL) {
 
158
        delete fdmex; fdmex=NULL;
 
159
        delete fgic; fgic=NULL;
 
160
    }  
 
161
}
 
162
 
 
163
/******************************************************************************/
 
164
 
 
165
// Initialize the JSBsim flight model, dt is the time increment for
 
166
// each subsequent iteration through the EOM
 
167
 
 
168
void FGJSBsim::init() {
 
169
    
 
170
    SG_LOG( SG_FLIGHT, SG_INFO, "Starting and initializing JSBsim" );
 
171
   
 
172
    // Explicitly call the superclass's
 
173
    // init method first.
 
174
    common_init();
 
175
    copy_to_JSBsim();
 
176
 
 
177
    fdmex->GetState()->Initialize(fgic);
 
178
    fdmex->RunIC(fgic); //loop JSBSim once w/o integrating
 
179
    // fdmex->Run();       //loop JSBSim once
 
180
    copy_from_JSBsim(); //update the bus
 
181
 
 
182
    SG_LOG( SG_FLIGHT, SG_INFO, "  Initialized JSBSim with:" );
 
183
 
 
184
    switch(fgic->GetSpeedSet()) {
 
185
    case setned:
 
186
        SG_LOG(SG_FLIGHT,SG_INFO, "  Vn,Ve,Vd= "
 
187
               << Position->GetVn() << ", "
 
188
               << Position->GetVe() << ", "
 
189
               << Position->GetVd() << " ft/s");
 
190
    break;
 
191
    case setuvw:
 
192
        SG_LOG(SG_FLIGHT,SG_INFO, "  U,V,W= "
 
193
               << Translation->GetUVW(1) << ", "
 
194
               << Translation->GetUVW(2) << ", "
 
195
               << Translation->GetUVW(3) << " ft/s");
 
196
    break;
 
197
    case setmach:
 
198
        SG_LOG(SG_FLIGHT,SG_INFO, "  Mach: "
 
199
               << Translation->GetMach() );
 
200
    break;
 
201
    case setvc:
 
202
    default:
 
203
        SG_LOG(SG_FLIGHT,SG_INFO, "  Indicated Airspeed: "
 
204
               << Auxiliary->GetVcalibratedKTS() << " knots" );
 
205
    break;
 
206
    }
 
207
    
 
208
    stall_warning->setDoubleValue(0);
 
209
    
 
210
    SG_LOG( SG_FLIGHT, SG_INFO, "  Bank Angle: "
 
211
            <<  Rotation->Getphi()*RADTODEG << " deg" );
 
212
    SG_LOG( SG_FLIGHT, SG_INFO, "  Pitch Angle: "
 
213
            << Rotation->Gettht()*RADTODEG << " deg" );
 
214
    SG_LOG( SG_FLIGHT, SG_INFO, "  True Heading: "
 
215
            << Rotation->Getpsi()*RADTODEG << " deg" );
 
216
    SG_LOG( SG_FLIGHT, SG_INFO, "  Latitude: "
 
217
            << Position->GetLatitude() << " deg" );
 
218
    SG_LOG( SG_FLIGHT, SG_INFO, "  Longitude: "
 
219
            << Position->GetLongitude() << " deg" );
 
220
    SG_LOG( SG_FLIGHT, SG_INFO, "  Altitude: "
 
221
        << Position->Geth() << " feet" );
 
222
    SG_LOG( SG_FLIGHT, SG_INFO, "  loaded initial conditions" );
 
223
 
 
224
    SG_LOG( SG_FLIGHT, SG_INFO, "  set dt" );
 
225
 
 
226
    SG_LOG( SG_FLIGHT, SG_INFO, "Finished initializing JSBSim" );
 
227
    
 
228
    SG_LOG( SG_FLIGHT, SG_INFO, "FGControls::get_gear_down()= " << 
 
229
                                  globals->get_controls()->get_gear_down() );
 
230
    
 
231
 
 
232
   
 
233
}
 
234
 
 
235
/******************************************************************************/
 
236
 
 
237
// Run an iteration of the EOM (equations of motion)
 
238
 
 
239
void
 
240
FGJSBsim::update( int multiloop ) {
 
241
 
 
242
    int i;
 
243
 
 
244
    // double save_alt = 0.0;
 
245
 
 
246
    copy_to_JSBsim();
 
247
 
 
248
    trimmed->setBoolValue(false);
 
249
 
 
250
    if ( needTrim ) {
 
251
      if ( startup_trim->getBoolValue() ) {
 
252
        do_trim();
 
253
      } else {
 
254
        fdmex->RunIC(fgic);  //apply any changes made through the set_ functions
 
255
      }
 
256
      needTrim = false;  
 
257
    }    
 
258
    
 
259
    for ( i=0; i < multiloop; i++ ) {
 
260
        fdmex->Run();
 
261
    }
 
262
 
 
263
    FGJSBBase::Message* msg;
 
264
    while (fdmex->ReadMessage()) {
 
265
      msg = fdmex->ProcessMessage();
 
266
      switch (msg->type) {
 
267
      case FGJSBBase::Message::eText:
 
268
        SG_LOG( SG_FLIGHT, SG_INFO, msg->messageId << ": " << msg->text );
 
269
        break;
 
270
      case FGJSBBase::Message::eBool:
 
271
        SG_LOG( SG_FLIGHT, SG_INFO, msg->messageId << ": " << msg->text << " " << msg->bVal );
 
272
        break;
 
273
      case FGJSBBase::Message::eInteger:
 
274
        SG_LOG( SG_FLIGHT, SG_INFO, msg->messageId << ": " << msg->text << " " << msg->iVal );
 
275
        break;
 
276
      case FGJSBBase::Message::eDouble:
 
277
        SG_LOG( SG_FLIGHT, SG_INFO, msg->messageId << ": " << msg->text << " " << msg->dVal );
 
278
        break;
 
279
      default:
 
280
        SG_LOG( SG_FLIGHT, SG_INFO, "Unrecognized message type." );
 
281
        break;
 
282
      }
 
283
    }
 
284
 
 
285
    // translate JSBsim back to FG structure so that the
 
286
    // autopilot (and the rest of the sim can use the updated values
 
287
    copy_from_JSBsim();
 
288
}
 
289
 
 
290
/******************************************************************************/
 
291
 
 
292
// Convert from the FGInterface struct to the JSBsim generic_ struct
 
293
 
 
294
bool FGJSBsim::copy_to_JSBsim() {
 
295
    unsigned int i;
 
296
 
 
297
    // copy control positions into the JSBsim structure
 
298
 
 
299
    FCS->SetDaCmd( globals->get_controls()->get_aileron());
 
300
    FCS->SetRollTrimCmd( globals->get_controls()->get_aileron_trim() );
 
301
    FCS->SetDeCmd( globals->get_controls()->get_elevator());
 
302
    FCS->SetPitchTrimCmd( globals->get_controls()->get_elevator_trim() );
 
303
    FCS->SetDrCmd( -globals->get_controls()->get_rudder() );
 
304
    FCS->SetYawTrimCmd( -globals->get_controls()->get_rudder_trim() );
 
305
    FCS->SetDfCmd(  globals->get_controls()->get_flaps() );
 
306
    FCS->SetDsbCmd( 0.0 ); //speedbrakes
 
307
    FCS->SetDspCmd( 0.0 ); //spoilers
 
308
    FCS->SetLBrake( globals->get_controls()->get_brake( 0 ) );
 
309
    FCS->SetRBrake( globals->get_controls()->get_brake( 1 ) );
 
310
    FCS->SetCBrake( globals->get_controls()->get_brake( 2 ) );
 
311
    FCS->SetGearCmd( globals->get_controls()->get_gear_down());
 
312
    for (i = 0; i < Propulsion->GetNumEngines(); i++) {
 
313
      FGEngine * eng = Propulsion->GetEngine(i);
 
314
      SGPropertyNode * node = fgGetNode("engines/engine", i, true);
 
315
      FCS->SetThrottleCmd(i, globals->get_controls()->get_throttle(i));
 
316
      FCS->SetMixtureCmd(i, globals->get_controls()->get_mixture(i));
 
317
      FCS->SetPropAdvanceCmd(i, globals->get_controls()->get_prop_advance(i));
 
318
      Propulsion->GetThruster(i)->SetRPM(node->getDoubleValue("rpm"));
 
319
      eng->SetMagnetos( globals->get_controls()->get_magnetos(i) );
 
320
      eng->SetStarter( globals->get_controls()->get_starter(i) );
 
321
    }
 
322
 
 
323
    Position->SetSeaLevelRadius( get_Sea_level_radius() );
 
324
    Position->SetRunwayRadius( scenery.get_cur_elev()*SG_METER_TO_FEET
 
325
                               + get_Sea_level_radius() );
 
326
 
 
327
    Atmosphere->SetExTemperature(get_Static_temperature());
 
328
    Atmosphere->SetExPressure(get_Static_pressure());
 
329
    Atmosphere->SetExDensity(get_Density());
 
330
    Atmosphere->SetWindNED(get_V_north_airmass(),
 
331
                           get_V_east_airmass(),
 
332
                           get_V_down_airmass());
 
333
//    SG_LOG(SG_FLIGHT,SG_INFO, "Wind NED: "
 
334
//                  << get_V_north_airmass() << ", "
 
335
//                  << get_V_east_airmass()  << ", "
 
336
//                  << get_V_down_airmass() );
 
337
 
 
338
    for (i = 0; i < Propulsion->GetNumTanks(); i++) {
 
339
      SGPropertyNode * node = fgGetNode("/consumables/fuel/tank", i, true);
 
340
      FGTank * tank = Propulsion->GetTank(i);
 
341
      tank->SetContents(node->getDoubleValue("level-gal_us") * 6.6);
 
342
//       tank->SetContents(node->getDoubleValue("level-lb"));
 
343
    }
 
344
 
 
345
    return true;
 
346
}
 
347
 
 
348
/******************************************************************************/
 
349
 
 
350
// Convert from the JSBsim generic_ struct to the FGInterface struct
 
351
 
 
352
bool FGJSBsim::copy_from_JSBsim() {
 
353
    unsigned int i, j;
 
354
 
 
355
    _set_Inertias( MassBalance->GetMass(),
 
356
                   MassBalance->GetIxx(),
 
357
                   MassBalance->GetIyy(),
 
358
                   MassBalance->GetIzz(),
 
359
                   MassBalance->GetIxz() );
 
360
 
 
361
    _set_CG_Position( MassBalance->GetXYZcg(1),
 
362
                      MassBalance->GetXYZcg(2),
 
363
                      MassBalance->GetXYZcg(3) );
 
364
 
 
365
    _set_Accels_Body( Aircraft->GetBodyAccel()(1),
 
366
                      Aircraft->GetBodyAccel()(2),
 
367
                      Aircraft->GetBodyAccel()(3) );
 
368
 
 
369
    //_set_Accels_CG_Body( Aircraft->GetBodyAccel()(1),
 
370
    //                     Aircraft->GetBodyAccel()(2),
 
371
    //                     Aircraft->GetBodyAccel()(3) );
 
372
    //
 
373
    _set_Accels_CG_Body_N ( Aircraft->GetNcg()(1),
 
374
                            Aircraft->GetNcg()(2),
 
375
                            Aircraft->GetNcg()(3) );
 
376
    
 
377
    _set_Accels_Pilot_Body( Auxiliary->GetPilotAccel()(1),
 
378
                            Auxiliary->GetPilotAccel()(2),
 
379
                            Auxiliary->GetPilotAccel()(3) );
 
380
 
 
381
   // _set_Accels_Pilot_Body_N( Auxiliary->GetPilotAccel()(1)/32.1739,
 
382
   //                           Auxiliary->GetNpilot(2)/32.1739,
 
383
   //                           Auxiliary->GetNpilot(3)/32.1739 );
 
384
 
 
385
    _set_Nlf( Aircraft->GetNlf() );
 
386
 
 
387
    // Velocities
 
388
 
 
389
    _set_Velocities_Local( Position->GetVn(),
 
390
                           Position->GetVe(),
 
391
                           Position->GetVd() );
 
392
 
 
393
    _set_Velocities_Wind_Body( Translation->GetUVW(1),
 
394
                               Translation->GetUVW(2),
 
395
                               Translation->GetUVW(3) );
 
396
 
 
397
    _set_V_rel_wind( Translation->GetVt() );
 
398
 
 
399
    _set_V_equiv_kts( Auxiliary->GetVequivalentKTS() );
 
400
 
 
401
    // _set_V_calibrated( Auxiliary->GetVcalibratedFPS() );
 
402
 
 
403
    _set_V_calibrated_kts( Auxiliary->GetVcalibratedKTS() );
 
404
 
 
405
    _set_V_ground_speed( Position->GetVground() );
 
406
 
 
407
    _set_Omega_Body( Rotation->GetPQR(1),
 
408
                     Rotation->GetPQR(2),
 
409
                     Rotation->GetPQR(3) );
 
410
 
 
411
    _set_Euler_Rates( Rotation->GetEulerRates(1),
 
412
                      Rotation->GetEulerRates(2),
 
413
                      Rotation->GetEulerRates(3) );
 
414
 
 
415
    _set_Geocentric_Rates(Position->GetLatitudeDot(),
 
416
                          Position->GetLongitudeDot(),
 
417
                          Position->Gethdot() );
 
418
 
 
419
    _set_Mach_number( Translation->GetMach() );
 
420
 
 
421
    // Positions
 
422
    _updateGeocentricPosition( Position->GetLatitude(),
 
423
                               Position->GetLongitude(),
 
424
                               Position->Geth() );
 
425
 
 
426
    _set_Altitude_AGL( Position->GetDistanceAGL() );
 
427
 
 
428
    _set_Euler_Angles( Rotation->Getphi(),
 
429
                       Rotation->Gettht(),
 
430
                       Rotation->Getpsi() );
 
431
 
 
432
    _set_Alpha( Translation->Getalpha() );
 
433
    _set_Beta( Translation->Getbeta() );
 
434
 
 
435
 
 
436
    _set_Gamma_vert_rad( Position->GetGamma() );
 
437
    // set_Gamma_horiz_rad( Gamma_horiz_rad );
 
438
 
 
439
    _set_Earth_position_angle( Auxiliary->GetEarthPositionAngle() );
 
440
 
 
441
    _set_Climb_Rate( Position->Gethdot() );
 
442
 
 
443
 
 
444
    for ( i = 1; i <= 3; i++ ) {
 
445
        for ( j = 1; j <= 3; j++ ) {
 
446
            _set_T_Local_to_Body( i, j, State->GetTl2b(i,j) );
 
447
        }
 
448
    }
 
449
 
 
450
                                // Copy the engine values from JSBSim.
 
451
    for( i=0; i < Propulsion->GetNumEngines(); i++ ) {
 
452
      SGPropertyNode * node = fgGetNode("engines/engine", i, true);
 
453
      FGEngine * eng = Propulsion->GetEngine(i);
 
454
      FGThruster * thrust = Propulsion->GetThruster(i);
 
455
 
 
456
      node->setDoubleValue("mp-osi", eng->getManifoldPressure_inHg());
 
457
      node->setDoubleValue("rpm", thrust->GetRPM());
 
458
      node->setDoubleValue("egt-degf", eng->getExhaustGasTemp_degF());
 
459
      node->setDoubleValue("fuel-flow-gph", eng->getFuelFlow_gph());
 
460
      node->setDoubleValue("cht-degf", eng->getCylinderHeadTemp_degF());
 
461
      node->setDoubleValue("oil-temperature-degf", eng->getOilTemp_degF());
 
462
      node->setDoubleValue("oil-pressure-psi", eng->getOilPressure_psi());
 
463
      node->setBoolValue("running", eng->GetRunning());
 
464
      node->setBoolValue("cranking", eng->GetCranking());
 
465
    }
 
466
 
 
467
    static const SGPropertyNode *fuel_freeze
 
468
        = fgGetNode("/sim/freeze/fuel");
 
469
 
 
470
                                // Copy the fuel levels from JSBSim if fuel
 
471
                                // freeze not enabled.
 
472
    if ( ! fuel_freeze->getBoolValue() ) {
 
473
        for (i = 0; i < Propulsion->GetNumTanks(); i++) {
 
474
            SGPropertyNode * node
 
475
                = fgGetNode("/consumables/fuel/tank", i, true);
 
476
            double contents = Propulsion->GetTank(i)->GetContents();
 
477
            node->setDoubleValue("level-gal_us", contents/6.6);
 
478
            // node->setDoubleValue("level-lb", contents);
 
479
        }
 
480
    }
 
481
 
 
482
    update_gear();
 
483
    
 
484
    stall_warning->setDoubleValue( Aircraft->GetStallWarn() );
 
485
    
 
486
    return true;
 
487
}
 
488
 
 
489
bool FGJSBsim::ToggleDataLogging(void) {
 
490
    return fdmex->GetOutput()->Toggle();
 
491
}
 
492
 
 
493
 
 
494
bool FGJSBsim::ToggleDataLogging(bool state) {
 
495
    if (state) {
 
496
      fdmex->GetOutput()->Enable();
 
497
      return true;
 
498
    } else {
 
499
      fdmex->GetOutput()->Disable();
 
500
      return false;
 
501
    }
 
502
}
 
503
 
 
504
 
 
505
//Positions
 
506
void FGJSBsim::set_Latitude(double lat) {
 
507
    static const SGPropertyNode *altitude = fgGetNode("/position/altitude-ft");
 
508
    double alt;
 
509
    if ( altitude->getDoubleValue() > -9990 ) {
 
510
      alt = altitude->getDoubleValue();
 
511
    } else {
 
512
      alt = 0.0;
 
513
    }
 
514
 
 
515
    double sea_level_radius_meters, lat_geoc;
 
516
 
 
517
    SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Latitude: " << lat );
 
518
    SG_LOG(SG_FLIGHT,SG_INFO," cur alt (ft) =  " << alt );
 
519
 
 
520
    sgGeodToGeoc( lat, alt * SG_FEET_TO_METER, &sea_level_radius_meters, &lat_geoc );
 
521
    
 
522
    _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET  );
 
523
    fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET  );
 
524
    fgic->SetLatitudeRadIC( lat_geoc );
 
525
    needTrim=true;
 
526
}
 
527
 
 
528
void FGJSBsim::set_Longitude(double lon) {
 
529
 
 
530
    SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Longitude: " << lon );
 
531
 
 
532
    fgic->SetLongitudeRadIC( lon );
 
533
    needTrim=true;
 
534
}
 
535
 
 
536
void FGJSBsim::set_Altitude(double alt) {
 
537
    static const SGPropertyNode *latitude = fgGetNode("/position/latitude-deg");
 
538
 
 
539
    double sea_level_radius_meters,lat_geoc;
 
540
 
 
541
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Altitude: " << alt );
 
542
    SG_LOG(SG_FLIGHT,SG_INFO, "  lat (deg) = " << latitude->getDoubleValue() );
 
543
 
 
544
    sgGeodToGeoc( latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, alt,
 
545
      &sea_level_radius_meters, &lat_geoc);
 
546
    _set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET  );
 
547
    fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
 
548
    fgic->SetLatitudeRadIC( lat_geoc );
 
549
    fgic->SetAltitudeFtIC(alt);
 
550
    needTrim=true;
 
551
}
 
552
 
 
553
void FGJSBsim::set_V_calibrated_kts(double vc) {
 
554
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_V_calibrated_kts: " <<  vc );
 
555
 
 
556
    fgic->SetVcalibratedKtsIC(vc);
 
557
    needTrim=true;
 
558
}
 
559
 
 
560
void FGJSBsim::set_Mach_number(double mach) {
 
561
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Mach_number: " <<  mach );
 
562
 
 
563
    fgic->SetMachIC(mach);
 
564
    needTrim=true;
 
565
}
 
566
 
 
567
void FGJSBsim::set_Velocities_Local( double north, double east, double down ){
 
568
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Velocities_Local: "
 
569
       << north << ", " <<  east << ", " << down );
 
570
 
 
571
    fgic->SetVnorthFpsIC(north);
 
572
    fgic->SetVeastFpsIC(east);
 
573
    fgic->SetVdownFpsIC(down);
 
574
    needTrim=true;
 
575
}
 
576
 
 
577
void FGJSBsim::set_Velocities_Wind_Body( double u, double v, double w){
 
578
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Velocities_Wind_Body: "
 
579
       << u << ", " <<  v << ", " <<  w );
 
580
 
 
581
    fgic->SetUBodyFpsIC(u);
 
582
    fgic->SetVBodyFpsIC(v);
 
583
    fgic->SetWBodyFpsIC(w);
 
584
    needTrim=true;
 
585
}
 
586
 
 
587
//Euler angles
 
588
void FGJSBsim::set_Euler_Angles( double phi, double theta, double psi ) {
 
589
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Euler_Angles: "
 
590
       << phi << ", " << theta << ", " << psi );
 
591
 
 
592
    fgic->SetPitchAngleRadIC(theta);
 
593
    fgic->SetRollAngleRadIC(phi);
 
594
    fgic->SetTrueHeadingRadIC(psi);
 
595
    needTrim=true;
 
596
}
 
597
 
 
598
//Flight Path
 
599
void FGJSBsim::set_Climb_Rate( double roc) {
 
600
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Climb_Rate: " << roc );
 
601
 
 
602
    fgic->SetClimbRateFpsIC(roc);
 
603
    needTrim=true;
 
604
}
 
605
 
 
606
void FGJSBsim::set_Gamma_vert_rad( double gamma) {
 
607
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Gamma_vert_rad: " << gamma );
 
608
 
 
609
    fgic->SetFlightPathAngleRadIC(gamma);
 
610
    needTrim=true;
 
611
}
 
612
 
 
613
//Earth
 
614
void FGJSBsim::set_Sea_level_radius(double slr) {
 
615
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Sea_level_radius: " << slr );
 
616
 
 
617
    fgic->SetSeaLevelRadiusFtIC(slr);
 
618
    needTrim=true;
 
619
}
 
620
 
 
621
void FGJSBsim::set_Runway_altitude(double ralt) {
 
622
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Runway_altitude: " << ralt );
 
623
 
 
624
    _set_Runway_altitude( ralt );
 
625
    fgic->SetTerrainAltitudeFtIC( ralt );
 
626
    needTrim=true;
 
627
}
 
628
 
 
629
void FGJSBsim::set_Static_pressure(double p) {
 
630
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Static_pressure: " << p );
 
631
 
 
632
    Atmosphere->SetExPressure(p);
 
633
    if(Atmosphere->External() == true)
 
634
    needTrim=true;
 
635
}
 
636
 
 
637
void FGJSBsim::set_Static_temperature(double T) {
 
638
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Static_temperature: " << T );
 
639
    
 
640
    Atmosphere->SetExTemperature(T);
 
641
    if(Atmosphere->External() == true)
 
642
    needTrim=true;
 
643
}
 
644
 
 
645
 
 
646
void FGJSBsim::set_Density(double rho) {
 
647
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Density: " << rho );
 
648
    
 
649
    Atmosphere->SetExDensity(rho);
 
650
    if(Atmosphere->External() == true)
 
651
    needTrim=true;
 
652
}
 
653
  
 
654
void FGJSBsim::set_Velocities_Local_Airmass (double wnorth, 
 
655
                         double weast, 
 
656
                         double wdown ) {
 
657
    SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::set_Velocities_Local_Airmass: " 
 
658
       << wnorth << ", " << weast << ", " << wdown );
 
659
    
 
660
    _set_Velocities_Local_Airmass( wnorth, weast, wdown );
 
661
    Atmosphere->SetWindNED(wnorth, weast, wdown );
 
662
    if(Atmosphere->External() == true)
 
663
        needTrim=true;
 
664
}     
 
665
 
 
666
void FGJSBsim::init_gear(void ) {
 
667
    
 
668
    FGGroundReactions* gr=fdmex->GetGroundReactions();
 
669
    int Ngear=GroundReactions->GetNumGearUnits();
 
670
    for (int i=0;i<Ngear;i++) {
 
671
      SGPropertyNode * node = fgGetNode("gear/gear", i, true);
 
672
      node->setDoubleValue("xoffset-in",
 
673
                           gr->GetGearUnit(i)->GetBodyLocation()(1));
 
674
      node->setDoubleValue("yoffset-in",
 
675
                           gr->GetGearUnit(i)->GetBodyLocation()(2));
 
676
      node->setDoubleValue("zoffset-in",
 
677
                           gr->GetGearUnit(i)->GetBodyLocation()(3));
 
678
      node->setBoolValue("wow", gr->GetGearUnit(i)->GetWOW());
 
679
      node->setBoolValue("has-brake", gr->GetGearUnit(i)->GetBrakeGroup() > 0);
 
680
      node->setDoubleValue("position", FCS->GetGearPos());
 
681
    }  
 
682
}
 
683
 
 
684
void FGJSBsim::update_gear(void) {
 
685
    
 
686
    FGGroundReactions* gr=fdmex->GetGroundReactions();
 
687
    int Ngear=GroundReactions->GetNumGearUnits();
 
688
    for (int i=0;i<Ngear;i++) {
 
689
      SGPropertyNode * node = fgGetNode("gear/gear", i, true);
 
690
      node->getChild("wow", 0, true)
 
691
        ->setBoolValue(gr->GetGearUnit(i)->GetWOW());
 
692
      node->getChild("position", 0, true)
 
693
        ->setDoubleValue(FCS->GetGearPos());
 
694
    }  
 
695
}
 
696
 
 
697
void FGJSBsim::do_trim(void) {
 
698
 
 
699
        FGTrim *fgtrim;
 
700
        if(fgic->GetVcalibratedKtsIC() < 10 ) {
 
701
            fgic->SetVcalibratedKtsIC(0.0);
 
702
            fgtrim=new FGTrim(fdmex,fgic,tGround);
 
703
        } else {
 
704
            fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
 
705
        }
 
706
        if( !fgtrim->DoTrim() ) {
 
707
            fgtrim->Report();
 
708
            fgtrim->TrimStats();
 
709
        } else {
 
710
            trimmed->setBoolValue(true);
 
711
        }
 
712
        State->ReportState();
 
713
        delete fgtrim;
 
714
        pitch_trim->setDoubleValue( FCS->GetPitchTrimCmd() );
 
715
        throttle_trim->setDoubleValue( FCS->GetThrottleCmd(0) );
 
716
        aileron_trim->setDoubleValue( FCS->GetDaCmd() );
 
717
        rudder_trim->setDoubleValue( FCS->GetDrCmd() );
 
718
 
 
719
        globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
 
720
        globals->get_controls()->set_elevator(FCS->GetDeCmd());
 
721
        globals->get_controls()->set_throttle(FGControls::ALL_ENGINES,
 
722
                                              FCS->GetThrottleCmd(0));
 
723
 
 
724
        globals->get_controls()->set_aileron(FCS->GetDaCmd());
 
725
        globals->get_controls()->set_rudder( FCS->GetDrCmd());
 
726
    
 
727
        SG_LOG( SG_FLIGHT, SG_INFO, "  Trim complete" );
 
728
}