~ubuntu-branches/debian/sid/flightgear/sid

« back to all changes in this revision

Viewing changes to src/FDM/JSBSim/FGFDMExec.cpp

  • Committer: Package Import Robot
  • Author(s): Markus Wanner, Markus Wanner, Rebecca Palmer
  • Date: 2014-01-21 22:31:02 UTC
  • mfrom: (1.3.1) (15.1.2 experimental)
  • Revision ID: package-import@ubuntu.com-20140121223102-cjw7g9le25acd119
Tags: 3.0.0~git20140204+c99ea4-1
[ Markus Wanner ]
* Upload to unstable.
* Adjust B-D to allow building on kfreebsd-*. Closes: #724686.
* Add a lintian-overrides on autotools; we use cmake.
* Upstream corrected the fgfs manpage. Closes: #556362.
* Drop unnecessary man page for gl-info. Closes: #698308.
* Drop README.Linux: it's outdated to the point of uselessness.
  Closes: #574173.
* Add an upper limit of libsimgear-dev versions that flightgear can be
  built with. Closes: #738436.
* Drop the libsvn-dev dependency, neither flightgear nor simgear depend
  on libsvn, anymore. Closes: #682947.
* List icons in debian/install rather than copying around from rules.
* Update menu entry for flightgear, add one for fgcom; add .xpm icons.
  Closes: #713924.
* flightgear.desktop: add German translation
* Bump Standards-Version to 3.9.5; no changes needed.

[ Rebecca Palmer ]
* New upstream release.
* Install the icons (based on code by Saikrishna Arcot).  (Not a
  complete fix for LP908153 as it only sets the menu/Dash icon, not the
  running window's icon, but better than nothing).
* Disable screensaver while running. Closes: LP#793599. Add required
  libdbus-1-dev dependency.
* Remove outdated README.Debian.
* Terrasync now works after just ticking the box. Closes: #252899.
* Always set Terrasync directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
1
2
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3
 
3
4
 Module:       FGFDMExec.cpp
63
64
#include "models/FGInput.h"
64
65
#include "models/FGOutput.h"
65
66
#include "initialization/FGInitialCondition.h"
 
67
#include "initialization/FGSimplexTrim.h"
 
68
#include "initialization/FGLinearization.h"
66
69
#include "input_output/FGPropertyManager.h"
67
70
#include "input_output/FGScript.h"
 
71
#include "input_output/FGXMLFileRead.h"
 
72
#include "input_output/FGXMLElement.h"
68
73
 
69
74
using namespace std;
70
75
 
71
76
namespace JSBSim {
72
77
 
73
 
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.133 2012/04/14 18:10:43 bcoconni Exp $";
 
78
static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.150 2013/11/24 11:40:55 bcoconni Exp $";
74
79
static const char *IdHdr = ID_FDMEXEC;
75
80
 
76
81
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96
101
  holding = false;
97
102
  Terminate = false;
98
103
  StandAlone = false;
99
 
  firstPass = true;
100
104
 
101
105
  IncrementThenHolding = false;  // increment then hold is off by default
102
106
  TimeStepsUntilHold = -1;
132
136
  // Prepare FDMctr for the next child FDM id
133
137
  (*FDMctr)++;       // instance. "child" instances are loaded last.
134
138
 
135
 
  instance = Root->GetNode("/fdm/jsbsim",IdFDM,true);
 
139
  FGPropertyNode* instanceRoot = Root->GetNode("/fdm/jsbsim",IdFDM,true);
 
140
  instance = new FGPropertyManager(instanceRoot);
136
141
  Debug(0);
137
142
  // this is to catch errors in binding member functions to the property tree.
138
143
  try {
147
152
 
148
153
  Constructing = true;
149
154
  typedef int (FGFDMExec::*iPMF)(void) const;
 
155
  typedef double (FGFDMExec::*dPMF)(void) const;
150
156
//  typedef unsigned int (FGFDMExec::*uiPMF)(void) const;
151
157
//  instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis, false);
152
158
  instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim, false);
 
159
  instance->Tie("simulation/do_simplex_trim", this, (iPMF)0, &FGFDMExec::DoSimplexTrim);
 
160
  instance->Tie("simulation/do_linearization", this, (iPMF)0, &FGFDMExec::DoLinearization);
153
161
  instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions, false);
154
162
  instance->Tie("simulation/randomseed", this, (iPMF)0, &FGFDMExec::SRand, false);
155
163
  instance->Tie("simulation/terminate", (int *)&Terminate);
156
164
  instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime);
 
165
  instance->Tie("simulation/dt", this, &FGFDMExec::GetDeltaT);
157
166
  instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel);
158
167
  instance->Tie("simulation/frame", (int *)&Frame, false);
159
168
 
 
169
  // simplex trim properties
 
170
  instanceRoot->SetDouble("trim/solver/rtol",0.0001);
 
171
  instanceRoot->SetDouble("trim/solver/speed",2);
 
172
  instanceRoot->SetDouble("trim/solver/abstol",0.001);
 
173
  instanceRoot->SetDouble("trim/solver/iterMax",2000);
 
174
  instanceRoot->SetInt("trim/solver/debugLevel",0);
 
175
  instanceRoot->SetDouble("trim/solver/random",0);
 
176
  instanceRoot->SetBool("trim/solver/showSimplex",false);
 
177
  instanceRoot->SetBool("trim/solver/showConvergence",false);
 
178
  instanceRoot->SetBool("trim/solver/pause",false);
 
179
  instanceRoot->SetBool("trim/solver/variablePropPitch",false);
 
180
 
 
181
  instanceRoot->SetDouble("trim/solver/throttleGuess",0.50);
 
182
  instanceRoot->SetDouble("trim/solver/throttleMin",0.0);
 
183
  instanceRoot->SetDouble("trim/solver/throttleMax",1.0);
 
184
  instanceRoot->SetDouble("trim/solver/throttleStep",0.1);
 
185
 
 
186
  instanceRoot->SetDouble("trim/solver/aileronGuess",0);
 
187
  instanceRoot->SetDouble("trim/solver/aileronMin",-1.00);
 
188
  instanceRoot->SetDouble("trim/solver/aileronMax",1.00);
 
189
  instanceRoot->SetDouble("trim/solver/aileronStep",0.1);
 
190
 
 
191
  instanceRoot->SetDouble("trim/solver/rudderGuess",0);
 
192
  instanceRoot->SetDouble("trim/solver/rudderMin",-1.00);
 
193
  instanceRoot->SetDouble("trim/solver/rudderMax",1.00);
 
194
  instanceRoot->SetDouble("trim/solver/rudderStep",0.1);
 
195
 
 
196
  instanceRoot->SetDouble("trim/solver/elevatorGuess",-0.1);
 
197
  instanceRoot->SetDouble("trim/solver/elevatorMin",-1.0);
 
198
  instanceRoot->SetDouble("trim/solver/elevatorMax",1.0);
 
199
  instanceRoot->SetDouble("trim/solver/elevatorStep",0.1);
 
200
 
 
201
  instanceRoot->SetDouble("trim/solver/alphaGuess",0.05);
 
202
  instanceRoot->SetDouble("trim/solver/alphaMin",-0.1);
 
203
  instanceRoot->SetDouble("trim/solver/alphaMax",.18);
 
204
  instanceRoot->SetDouble("trim/solver/alphaStep",0.05);
 
205
 
 
206
  instanceRoot->SetDouble("trim/solver/betaGuess",0);
 
207
  instanceRoot->SetDouble("trim/solver/betaMin",-0.1);
 
208
  instanceRoot->SetDouble("trim/solver/betaMax",0.1);
 
209
  instanceRoot->SetDouble("trim/solver/betaStep",0.0001);
 
210
 
160
211
  Constructing = false;
161
212
}
162
213
 
168
219
    Unbind();
169
220
    DeAllocate();
170
221
 
 
222
    delete instance;
 
223
 
171
224
    if (IdFDM == 0) { // Meaning this is no child FDM
172
225
      if(Root != 0) {
173
226
         if(StandAlone)
213
266
  Models[eSystems]           = new FGFCS(this);
214
267
  Models[ePropulsion]        = new FGPropulsion(this);
215
268
  Models[eAerodynamics]      = new FGAerodynamics (this);
216
 
 
217
 
  GetGroundCallback()->SetSeaLevelRadius(((FGInertial*)Models[eInertial])->GetRefRadius());
218
 
 
219
269
  Models[eGroundReactions]   = new FGGroundReactions(this);
220
270
  Models[eExternalReactions] = new FGExternalReactions(this);
221
271
  Models[eBuoyantForces]     = new FGBuoyantForces(this);
222
272
  Models[eMassBalance]       = new FGMassBalance(this);
223
273
  Models[eAircraft]          = new FGAircraft(this);
224
274
  Models[eAccelerations]     = new FGAccelerations(this);
 
275
  Models[eOutput]            = new FGOutput(this);
225
276
 
226
277
  // Assign the Model shortcuts for internal executive use only.
227
278
  Propagate = (FGPropagate*)Models[ePropagate];
238
289
  MassBalance = (FGMassBalance*)Models[eMassBalance];
239
290
  Aircraft = (FGAircraft*)Models[eAircraft];
240
291
  Accelerations = (FGAccelerations*)Models[eAccelerations];
 
292
  Output = (FGOutput*)Models[eOutput];
241
293
 
242
294
  // Initialize planet (environment) constants
243
295
  LoadPlanetConstants();
 
296
  GetGroundCallback()->SetSeaLevelRadius(Inertial->GetRefRadius());
244
297
 
245
298
  // Initialize models
246
299
  for (unsigned int i = 0; i < Models.size(); i++) {
 
300
    // The Output model must not be initialized prior to IC loading
 
301
    if (i == eOutput) continue;
 
302
 
247
303
    LoadInputs(i);
248
304
    Models[i]->InitModel();
249
305
  }
263
319
  for (unsigned int i=0; i<eNumStandardModels; i++) delete Models[i];
264
320
  Models.clear();
265
321
 
266
 
  for (unsigned i=0; i<Outputs.size(); i++) delete Outputs[i];
267
 
  Outputs.clear();
268
 
 
269
322
  delete Script;
270
323
  delete IC;
271
324
  delete Trim;
297
350
    ChildFDMList[i]->Run();
298
351
  }
299
352
 
300
 
  if (firstPass && !IntegrationSuspended()) {
301
 
    // Outputs the initial conditions
302
 
    for (unsigned int i = 0; i < Outputs.size(); i++)
303
 
      Outputs[i]->Run(holding);
304
 
 
305
 
    firstPass = false;
306
 
  }
307
 
 
308
353
  IncrTime();
309
354
 
310
355
  // returns true if success, false if complete
371
416
    Auxiliary->in.RPBody       = MassBalance->StructuralToBody(Aircraft->GetXYZrp());
372
417
    Auxiliary->in.vFw          = Aerodynamics->GetvFw();
373
418
    Auxiliary->in.vLocation    = Propagate->GetLocation();
374
 
    Auxiliary->in.Latitude     = Propagate->GetLatitude();
375
 
    Auxiliary->in.Longitude    = Propagate->GetLongitude();
376
419
    Auxiliary->in.CosTht       = Propagate->GetCosEuler(eTht);
377
420
    Auxiliary->in.SinTht       = Propagate->GetSinEuler(eTht);
378
421
    Auxiliary->in.CosPhi       = Propagate->GetCosEuler(ePhi);
413
456
    Propulsion->in.PropFeather      = FCS->GetPropFeather();
414
457
    Propulsion->in.H_agl            = Propagate->GetDistanceAGL();
415
458
    Propulsion->in.PQR              = Propagate->GetPQR();
416
 
    Propulsion->in.vXYZcg           = MassBalance->GetXYZcg();
417
459
 
418
460
    break;
419
461
  case eAerodynamics:
475
517
    Aircraft->in.GroundMoment  = GroundReactions->GetMoments();
476
518
    Aircraft->in.ExternalMoment = ExternalReactions->GetMoments();
477
519
    Aircraft->in.BuoyantMoment = BuoyantForces->GetMoments();
478
 
    Aircraft->in.Weight        = MassBalance->GetWeight();
479
 
    Aircraft->in.Tl2b          = Propagate->GetTl2b();
480
520
    break;
481
521
  case eAccelerations:
482
522
    Accelerations->in.J        = MassBalance->GetJ();
513
553
{
514
554
  Propagate->in.vOmegaPlanet     = Inertial->GetOmegaPlanet();
515
555
  Accelerations->in.vOmegaPlanet = Inertial->GetOmegaPlanet();
516
 
  Propagate->in.RefRadius        = Inertial->GetRefRadius();
517
556
  Propagate->in.SemiMajor        = Inertial->GetSemimajor();
518
557
  Propagate->in.SemiMinor        = Inertial->GetSemiminor();
519
558
  Auxiliary->in.SLGravity        = Inertial->SLgravity();
533
572
  Auxiliary->in.Wingspan         = Aircraft->GetWingSpan();
534
573
  Auxiliary->in.Wingchord        = Aircraft->Getcbar();
535
574
  GroundReactions->in.vXYZcg     = MassBalance->GetXYZcg();
536
 
  Propulsion->in.vXYZcg          = MassBalance->GetXYZcg();
537
575
 
538
576
  LoadPlanetConstants();
539
577
}
543
581
 
544
582
bool FGFDMExec::RunIC(void)
545
583
{
 
584
  FGPropulsion* propulsion = (FGPropulsion*)Models[ePropulsion];
 
585
 
 
586
  Models[eOutput]->InitModel();
 
587
 
546
588
  SuspendIntegration(); // saves the integration rate, dt, then sets it to 0.0.
547
589
  Initialize(IC);
548
590
  Run();
549
591
  ResumeIntegration(); // Restores the integration rate to what it was.
550
592
 
 
593
  for (unsigned int i=0; i<IC->GetNumEnginesRunning(); i++)
 
594
    propulsion->InitRunning(IC->GetEngineRunning(i));
 
595
 
551
596
  return true;
552
597
}
553
598
 
575
620
 
576
621
void FGFDMExec::ResetToInitialConditions(int mode)
577
622
{
578
 
  if (mode == 1) {
579
 
    for (unsigned int i=0; i<Outputs.size(); i++) {
580
 
      Outputs[i]->SetStartNewFile(true);
581
 
    }
582
 
  }
 
623
  if (mode == 1) Output->SetStartNewOutput();
583
624
 
584
625
  ResetToInitialConditions();
585
626
}
590
631
{
591
632
  if (Constructing) return;
592
633
 
593
 
  vector <FGModel*>::iterator it;
594
 
  for (it = Models.begin(); it != Models.end(); ++it) (*it)->InitModel();
 
634
  for (unsigned int i = 0; i < Models.size(); i++) {
 
635
    // The Output model will be initialized during the RunIC() execution
 
636
    if (i == eOutput) continue;
 
637
 
 
638
    LoadInputs(i);
 
639
    Models[i]->InitModel();
 
640
  }
595
641
 
596
642
  RunIC();
 
643
 
597
644
  if (Script) Script->ResetEvents();
598
645
}
599
646
 
600
647
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601
648
 
602
 
bool FGFDMExec::SetOutputFileName(const string& fname)
603
 
{
604
 
  if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
605
 
  else return false;
606
 
  return true;
607
 
}
608
 
 
609
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610
 
 
611
 
string FGFDMExec::GetOutputFileName(void)
612
 
{
613
 
  if (Outputs.size() > 0) return Outputs[0]->GetOutputFileName();
614
 
  else return string("");
615
 
}
616
 
 
617
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
618
 
 
619
649
vector <string> FGFDMExec::EnumerateFDMs(void)
620
650
{
621
651
  vector <string> FDMList;
632
662
 
633
663
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634
664
 
635
 
bool FGFDMExec::LoadScript(const string& script, double deltaT)
 
665
bool FGFDMExec::LoadScript(const string& script, double deltaT, const string initfile)
636
666
{
637
667
  bool result;
638
668
 
639
669
  Script = new FGScript(this);
640
 
  result = Script->LoadScript(RootDir + script, deltaT);
 
670
  result = Script->LoadScript(RootDir + script, deltaT, initfile);
641
671
 
642
672
  return result;
643
673
}
681
711
  }
682
712
 
683
713
  int saved_debug_lvl = debug_lvl;
 
714
  FGXMLFileRead XMLFileRead;
 
715
  Element *document = XMLFileRead.LoadXMLDocument(aircraftCfgFileName); // "document" is a class member
684
716
 
685
 
  document = LoadXMLDocument(aircraftCfgFileName); // "document" is a class member
686
717
  if (document) {
687
718
    if (IsChild) debug_lvl = 0;
688
719
 
828
859
    }
829
860
 
830
861
    // Process the output element[s]. This element is OPTIONAL, and there may be more than one.
831
 
    unsigned int idx=0;
832
 
    typedef double (FGOutput::*iOPMF)(void) const;
833
 
    typedef int (FGFDMExec::*iOPV)(void) const;
834
862
    element = document->FindElement("output");
835
863
    while (element) {
836
 
      if (debug_lvl > 0) cout << endl << "  Output data set: " << idx << "  ";
837
 
      FGOutput* Output = new FGOutput(this);
838
 
      result = Output->Load(element);
 
864
      string output_file_name = aircraftCfgFileName;
 
865
 
 
866
      if (!element->GetAttributeValue("file").empty()) {
 
867
        output_file_name = RootDir + element->GetAttributeValue("file");
 
868
        result = ((FGOutput*)Models[eOutput])->SetDirectivesFile(output_file_name);
 
869
      }
 
870
      else
 
871
        result = ((FGOutput*)Models[eOutput])->Load(element);
 
872
 
839
873
      if (!result) {
840
 
        cerr << endl << "Aircraft output element has problems in file " << aircraftCfgFileName << endl;
841
 
        delete Output;
 
874
        cerr << endl << "Aircraft output element has problems in file " << output_file_name << endl;
842
875
        return result;
843
 
      } else {
844
 
        Output->InitModel();
845
 
        Schedule(Output);
846
 
        Outputs.push_back(Output);
847
 
        string outputProp = CreateIndexedPropertyName("simulation/output",idx);
848
 
        instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
849
 
        idx++;
850
876
      }
851
877
      element = document->FindNextElement("output");
852
878
    }
853
 
    if (idx)
854
 
      instance->Tie("simulation/force-output", this, (iOPV)0, &FGFDMExec::ForceOutput, false);
855
879
 
856
880
    // Lastly, process the child element. This element is OPTIONAL - and NOT YET SUPPORTED.
857
881
    element = document->FindElement("child");
872
896
    if (debug_lvl > 0) {
873
897
      LoadInputs(eMassBalance); // Update all input mass properties for the report.
874
898
      Models[eMassBalance]->Run(false);  // Update all mass properties for the report.
 
899
      LoadInputs(ePropulsion); // Update propulsion properties for the report.
 
900
      Models[ePropulsion]->Run(false);  // Update propulsion properties for the report.
 
901
      LoadInputs(eMassBalance); // Update all (one more time) input mass properties for the report.
 
902
      Models[eMassBalance]->Run(false);  // Update all (one more time) mass properties for the report.
875
903
      ((FGMassBalance*)Models[eMassBalance])->GetMassPropertiesReport();
876
904
 
877
905
      cout << endl << fgblue << highint
893
921
  if (result) {
894
922
    struct PropertyCatalogStructure masterPCS;
895
923
    masterPCS.base_string = "";
896
 
    masterPCS.node = (FGPropertyManager*)Root;
 
924
    masterPCS.node = Root->GetNode();
897
925
    BuildPropertyCatalog(&masterPCS);
898
926
  }
899
927
 
915
943
  int node_idx = 0;
916
944
 
917
945
  for (int i=0; i<pcs->node->nChildren(); i++) {
 
946
    string access="";
918
947
    pcsNew->base_string = pcs->base_string + "/" + pcs->node->getChild(i)->getName();
919
948
    node_idx = pcs->node->getChild(i)->getIndex();
920
949
    if (node_idx != 0) {
921
950
      pcsNew->base_string = CreateIndexedPropertyName(pcsNew->base_string, node_idx);
922
951
    }
923
952
    if (pcs->node->getChild(i)->nChildren() == 0) {
924
 
      if (pcsNew->base_string.substr(0,11) == string("/fdm/jsbsim")) {
 
953
      if (pcsNew->base_string.substr(0,12) == string("/fdm/jsbsim/")) {
925
954
        pcsNew->base_string = pcsNew->base_string.erase(0,12);
926
955
      }
927
 
      PropertyCatalog.push_back(pcsNew->base_string);
 
956
      if (pcs->node->getChild(i)->getAttribute(SGPropertyNode::READ)) access="R";
 
957
      if (pcs->node->getChild(i)->getAttribute(SGPropertyNode::WRITE)) access+="W";
 
958
      PropertyCatalog.push_back(pcsNew->base_string+" ("+access+")");
928
959
    } else {
929
 
      pcsNew->node = (FGPropertyManager*)pcs->node->getChild(i);
 
960
      pcsNew->node = (FGPropertyNode*)pcs->node->getChild(i);
930
961
      BuildPropertyCatalog(pcsNew);
931
962
    }
932
963
  }
1109
1140
 
1110
1141
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1111
1142
 
1112
 
void FGFDMExec::DisableOutput(void)
1113
 
{
1114
 
  for (unsigned i=0; i<Outputs.size(); i++) {
1115
 
    Outputs[i]->Disable();
1116
 
  }
1117
 
}
1118
 
 
1119
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1120
 
 
1121
 
void FGFDMExec::EnableOutput(void)
1122
 
{
1123
 
  for (unsigned i=0; i<Outputs.size(); i++) {
1124
 
    Outputs[i]->Enable();
1125
 
  }
1126
 
}
1127
 
 
1128
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1129
 
 
1130
1143
void FGFDMExec::CheckIncrementalHold(void)
1131
1144
{
1132
1145
  // Only check if increment then hold is on
1151
1164
 
1152
1165
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1153
1166
 
1154
 
void FGFDMExec::ForceOutput(int idx)
1155
 
{
1156
 
  if (idx >= (int)0 && idx < (int)Outputs.size()) Outputs[idx]->Print();
1157
 
}
1158
 
 
1159
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1160
 
 
1161
 
bool FGFDMExec::SetOutputDirectives(const string& fname)
1162
 
{
1163
 
  bool result;
1164
 
 
1165
 
  FGOutput* Output = new FGOutput(this);
1166
 
  Output->SetDirectivesFile(RootDir + fname);
1167
 
  result = Output->Load(0);
1168
 
 
1169
 
  if (result) {
1170
 
    Output->InitModel();
1171
 
    Schedule(Output);
1172
 
    Output->Run(holding);
1173
 
    Outputs.push_back(Output);
1174
 
    typedef double (FGOutput::*iOPMF)(void) const;
1175
 
    string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1);
1176
 
    instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
1177
 
  }
1178
 
  else
1179
 
    delete Output;
1180
 
 
1181
 
  return result;
1182
 
}
1183
 
 
1184
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1185
 
 
1186
1167
void FGFDMExec::DoTrim(int mode)
1187
1168
{
1188
1169
  double saved_time;
1202
1183
 
1203
1184
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1204
1185
 
 
1186
void FGFDMExec::DoSimplexTrim(int mode)
 
1187
{
 
1188
  double saved_time;
 
1189
  if (Constructing) return;
 
1190
  if (mode < 0 || mode > JSBSim::tNone) {
 
1191
      cerr << endl << "Illegal trimming mode!" << endl << endl;
 
1192
      return;
 
1193
  }
 
1194
  saved_time = sim_time;
 
1195
  FGSimplexTrim trim(this, (JSBSim::TrimMode)mode);
 
1196
  sim_time = saved_time;
 
1197
  Setsim_time(saved_time);
 
1198
  std::cout << "dT: " << dT << std::endl;
 
1199
}
 
1200
 
 
1201
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1202
 
 
1203
void FGFDMExec::DoLinearization(int mode)
 
1204
{
 
1205
  double saved_time;
 
1206
  if (Constructing) return;
 
1207
  saved_time = sim_time;
 
1208
  FGLinearization lin(this,mode);
 
1209
  sim_time = saved_time;
 
1210
  Setsim_time(saved_time);
 
1211
}
 
1212
 
 
1213
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
1214
 
1205
1215
void FGFDMExec::SRand(int sr)
1206
1216
{
1207
1217
  srand(sr);