-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New jump nlp syntax, merge into main? #31
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #31 +/- ##
==========================================
+ Coverage 98.90% 98.98% +0.08%
==========================================
Files 23 23
Lines 2465 2466 +1
==========================================
+ Hits 2438 2441 +3
+ Misses 27 25 -2 ☔ View full report in Codecov by Sentry. |
I don't have any strong opinions on this, just a few comments
I've evaluated NLopt for MPC before and found it to be a poor fit. To solve challenging nonlinear MPC problems {large, long horizon, stiff dynamics, algebraic equations}, one usually require a multiple-shooting or direct-collocation transcription of the dynamics (as opposed to the single-shooting transcription used in this package so far). Such transcriptions result in large but sparse optimization problems, where the Lagrangian Hessian and the constraint Jacobian are both very sparse. NLopt does not support sparsity, and thus scales very poorly to large problems, whereas Ipopt is a sparse solver and handles it fine. If the intention with this package is to eventually support any such transcription methods, NLopt thus becomes irrelevant for all but very small problems. Unfortunately, the new JuMP nonlinear interface doesn't yet support vector-valued nonlinear functions, which means that it's very awkward to integrate continuous-time dynamics with anything other than very primitive integrators like forward Euler. Forward Euler is a horrendously bad integration method that should in principle never be used, even a simple RK4 is incredibly much better. However, in JuMP, one has to integrate each equation in the dynamics scalar-wise using RK4, rather than having the integrator coded up in a function since JuMP cannot represent this function from Direct collocation transcription could probably be implemented in JuMP since you do not suffer the increase in symbolic complexity from recursive application of the dynamics in the integrator, I haven't tried that but it should be relatively straightforward. |
I know, forward Euler is terrible 😢 . I used this method in the manual to keep the explanation as simple as possible. I wanted to put the focus on estimator and controller design, not model solving. I typically also used Runge-Kutta in the NMPC that I implemented on real systems. I could maybe add super-samples in the example (i.e. multi-step Euler), since we are near instability.
I know about direct collocation but I never dug deep in it. I will read on this tomorrow. I would be interested to add it in the package, in the short term if it's not too hard. I don't plan to add multiple shooting methods in the short term. I like the simplicity and elegance of the single shooting method. Easy to understand also means easy to troubleshoot. I understand that it scales poorly, but not everyone want to solve large problems. And its like linear algebra packages: sparse formulations are faster for large sparse problems, but they are also generally slower for small/medium problems, compared to dense formulation. The direct collocation method could maybe fill this gap in the package.
I'm not sure I fully understand this part. JuMP does not directly support functions with vector outputs, that's true (it is planned though), but there is a hacky workaroud. I do not work with scalars in the package, otherwise the user would not be able to change the prediction and control horizons. |
I generally prefer direct collocation over multiple shooting due to the simplicity with which one can
Multiple shooting and direct collocation are otherwise very similar, direct collocation includes all the intermediate stages in an integration step as variables, whereas multiple shooting only includes the initial condition for the shooting segment as variables. The complexity in their implementation is almost identical, with the exception that you need to handle the indexing of the intermediate stages for collocation. These intermediate states is also what makes it very cheap to evaluate functions of the state, since the state along the trajectory is treated as explicit variables rather than as computed from the input.
from the perspective of the user, calling |
New Idea: I could just support nonlinear continuous state-space models with a new syntax, and add |
That would also work. SeeToDee only contains 2 integrators at the moment, RK4 works with JuMP wile It's not quite a replacement for direct collocation though, since RK4 (and other explicit integrators) does not handle stiff equations |
By the way, have you ever found SL_SQP from NLopt outperform Ipopt? Even for very small problems, every time I've tried I've found SL_SQP to be suffering from convergence problems and taking 100x longer than Ipopt to find a good solution. I think that the problem might be that SLSQP does not make use second-order information, instead the keep a BFGS-like approximation to the Hessian. Ipopt through JuMP will use AD Hessians, which probably explains the difference. https://nlopt.readthedocs.io/en/latest/NLopt_Algorithms/#slsqp |
I only tested it on the pendulum example and, yes, it was about two times slower than Ipopt. It is safe to assume that the "exact" Hessian probably does help here. Btw, |
@baggepinnen so I made some quick test on some NLP solvers:
Seems like a good time to migrate to the new NLP syntax and merge into main. |
Your findings seem similar to mine 👍
🎉 😃 |
JuMP.jl
is introducing a new syntax for NLP, see https://jump.dev/JuMP.jl/stable/manual/nonlinear/ warning at the top.It is cleaner and marginally faster from my quick tests (the speed difference is negligible in fact). The drawback is that the optimizer support is partial right now.
Ipopt.jl
works well (the default forNonLinMPC
) butNLopt.jl
does not work. IMO, this meta-package include many interesting solvers for NMPC e.g. a SQP method called SLSQP.I finished the migration to the new syntax (both for
NonLinMPC
andMovingHorizonEstimator
). Come to think on it, maybe we should wait for at leastNLopt.jl
support before merging into main. What's your opinion ?