JSBSim-Team / jsbsim

An open source flight dynamics & control software library
GNU Lesser General Public License v2.1
1.22k stars 420 forks source link

Linearization and simplex trim from console executable and xml script #989

Closed vtpasquale closed 5 months ago

vtpasquale commented 5 months ago

I'm submitting a ...

Describe the issue

What is the current behavior?

When running:

JSBSim --script=737_cruise_steady_turn_simplex

The run fails with the following console error:

FATAL ERROR: JSBSim terminated with an exception.
The message was: No property, "simulation/do_simplex_trim" is defined.

Simple trim can be used instead of simplex trim by changing <set name="simulation/do_simplex_trim" value="1"/> to <set name="simulation/do_simple_trim" value="1"/> in 737_cruise_steady_turn_simplex.xml.

In that case, when running

JSBSim --script=737_cruise_steady_turn_simplex

The run fails with the following console error:

FATAL ERROR: JSBSim terminated with an exception.
The message was: No property, "simulation/do_linearization" is defined.

What is the expected behavior?

What is the motivation / use case for changing the behavior?

Please tell us about your environment:

Other information

agodemar commented 5 months ago

@vtpasquale thank you for reaching out and for the detailed feature request. Please have a look at this discussion: Update FGTrimAnalysis wrt latest JSBSim Release #988, where a user is working on something similar.

vtpasquale commented 5 months ago

Thanks for the quick response, @agodemar . It's interesting to see the parallel work. The trim feature ('simulation/do_simple_trim') being used by @rishi1906 is currently accessible from the console executable and with xml scripts. That specific trim feature has been working OK for me. I don't believe resolution of #988 will simultaneously resolve my request.

I'm most interested in the Linearization feature becoming available through the console executable and xml scripts, as it was previously. That feature is currently accessible through Python.

I think the alternative simplex trim capability is also currently available through Python. I don’t currently need the simplex trim capability, since the standard trim capability is working OK for me, but it might make sense to add console executable access to the simplex trim capability at the same time as the Linearization feature (since console executable access was removed simultaneously for both features).

vtpasquale commented 5 months ago

I think the required changes may be quite small. You can see the diff of my attempt here: https://github.com/JSBSim-Team/jsbsim/compare/master...vtpasquale:jsbsim:dev

The build is failing

/home/aricciar/projects/jsbsimFork/jsbsim/src/FGFDMExec.cpp: In constructor ‘JSBSim::FGFDMExec::FGFDMExec(JSBSim::FGPropertyManager*, std::shared_ptr<unsigned int>)’:
/home/aricciar/projects/jsbsimFork/jsbsim/src/FGFDMExec.cpp:164:16: error: no matching function for call to ‘JSBSim::FGPropertyManager::Tie(const char [28], JSBSim::FGFDMExec*, void (JSBSim::FGFDMExec::*)(int))’
  164 |   instance->Tie("simulation/do_linearization", this, &FGFDMExec::DoLinearization);
      |   ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/aricciar/projects/jsbsimFork/jsbsim/src/input_output/FGPropertyReader.h:44,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/math/FGModelFunctions.h:40,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/models/FGModel.h:44,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/models/FGPropagate.h:43,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/FGFDMExec.h:46,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/FGFDMExec.cpp:47:

I added a &FGFDMExec::DoLinearization function (modified from earlier versions), but I think there may be an issue with the input arguments lining up with what FGPropertyManager::Tie is specifying, and my inexperience is showing.

seanmcleod commented 5 months ago

You're close, use the same setup as you have for do_simplex_trim, i.e.

instance->Tie("simulation/do_linearization", this, (iPMF)0, &FGFDMExec::DoLinearization);

Basically you left out the argument for the getter.

The setter is optional, but the getter isn't.

    template <class T, class V> void
    Tie (const std::string &name, T * obj, V (T::*getter)() const,
         void (T::*setter)(V) = nullptr)
vtpasquale commented 5 months ago

Thanks, @seanmcleod. I made some updates: https://github.com/JSBSim-Team/jsbsim/compare/master...vtpasquale:jsbsim:dev

But I'm still getting a similar error:

/home/aricciar/projects/jsbsimFork/jsbsim/src/FGFDMExec.cpp: In constructor ‘JSBSim::FGFDMExec::FGFDMExec(JSBSim::FGPropertyManager*, std::shared_ptr<unsigned int>)’:
/home/aricciar/projects/jsbsimFork/jsbsim/src/FGFDMExec.cpp:164:16: error: no matching function for call to ‘JSBSim::FGPropertyManager::Tie(const char [28], JSBSim::FGFDMExec*, int (JSBSim::FGFDMExec::*)() const, void (JSBSim::FGFDMExec::*)())’
  164 |   instance->Tie("simulation/do_linearization", this, (iPMF)0, &FGFDMExec::DoLinearization);
      |   ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/aricciar/projects/jsbsimFork/jsbsim/src/input_output/FGPropertyReader.h:44,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/math/FGModelFunctions.h:40,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/models/FGModel.h:44,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/models/FGPropagate.h:43,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/FGFDMExec.h:46,
                 from /home/aricciar/projects/jsbsimFork/jsbsim/src/FGFDMExec.cpp:47:

Any suggestions?

seanmcleod commented 5 months ago

I made some updates

Too many updates? :wink:

I see you also changed the setter to take no/void arguments?

There are no compile issues with your DoSimplexTrim(int) right?

seanmcleod commented 5 months ago

To start off I suggest keeping it simpler. Comment out the simplex trim stuff. You had mentioned your primary goal was the linearization.

So you need:

instance->Tie("simulation/do_linearization", this, (iPMF)0, &FGFDMExec::DoLinearization);

void FGFDMExec::DoLinearization(int)
{
...
}

And confirm whether you can get that to compile and link.

seanmcleod commented 5 months ago

I did a quick test and was able to compile and link without any issues.

instance->Tie("simulation/do_linearization", this, (iPMF)0, &FGFDMExec::DoLinearization);

void FGFDMExec::DoLinearization(int)
{
  FGLinearization lin(this);
  lin.WriteScicoslab();
}
vtpasquale commented 5 months ago

Nice! I'll give that a shot. Was that without the simplex trim code included?

I had not tried commenting out this line: // instance->Tie("simulation/do_linearization", this, (iPMF)0, &FGFDMExec::DoLinearization);

The previous error is passed over when that line is commented out (I'll try updating the function as you did instead). I get to linking errors, but after starting to chase those down it was seeming like the simplex trim option is not maintained and will be a harder fix.

seanmcleod commented 5 months ago

Correct, I haven't done anything to try and add in the simplex trim code.

The only other line I added to FGFDMExec.cpp was:

#include "initialization/FGLinearization.h"
vtpasquale commented 5 months ago

Awesome! That complies for me and let's me generate the _lin.sc file with the linearized matrices using the desired workflow. I'll run some check cases to confirm the matrices match what I expect.

This is the test xml script

This is the latest https://github.com/JSBSim-Team/jsbsim/compare/master...vtpasquale:jsbsim:dev

One thing: JSBSim is locking up and not completing the simulation following the linearization. That's probably fine for the linearization workflow (mission accomplished), but I don't think that is the expected or desired behavior. Would you expect the typical simulation to continue after the linearized matrices are exported?

seanmcleod commented 5 months ago

Yep, I wouldn't expect the linearization to crash or hang JSBSim.

vtpasquale commented 5 months ago

This is happening because both FGFDMExec.dTand FGFDMExec.saved_dT are being set to 0.0 during the Linearization process.

It's like void FGFDMExec::SuspendIntegration(void) {saved_dT = dT; dT = 0.0;}is called twice in a row.FGLinearization is interacting FGStateSpace, and FGStateSpace adjusts dT quite a bit during assembly - it's hard to pinpoint the exact culprit. I'll have to revisit later.

This workaround allows the simulation to proceed:

void FGFDMExec::DoLinearization(int)
{
  double dt0 = this->GetDeltaT();
  FGLinearization lin(this);
  lin.WriteScicoslab();
  this->Setdt(dt0);
}
agodemar commented 5 months ago

@vtpasquale if your tests give reasonable results it would be great if you could:

I'm sure many users will benefit from this feature, which somehow has been buried in the codebase so far.

vtpasquale commented 5 months ago

Thanks for the suggestion, @agodemar. I just submitted pull request #991.

vtpasquale commented 5 months ago

Linearization from console executable and xml script feature is merged via #991. I appreciate the team's helpful and fast inputs on this.

I thought enabling simplex trim at the same time as linearization might be easy, but it turned out to be more involved. The standard trim capability is working OK for me, so I'll close this issue.