Skip to content

added: support box constraint in LinMPC and NonLinMPC#379

Open
franckgaga wants to merge 14 commits into
mainfrom
box_constraints
Open

added: support box constraint in LinMPC and NonLinMPC#379
franckgaga wants to merge 14 commits into
mainfrom
box_constraints

Conversation

@franckgaga

@franckgaga franckgaga commented Jun 18, 2026

Copy link
Copy Markdown
Member

Following discussion at #378, it is a good idea in terms of performances to treat constraints on the decision variable as box constraints, instead of linear inequality constraints, at least for NLP and interior point methods.

In this PR, these constraints:

  • limit on slack variable $\epsilon \ge 0$
  • limits on the input increments $\mathbf{\Delta u}$,
  • limits on the terminal state $\mathbf{\hat{x}}(k+H_p)$ for non-SingleShooting

are treated as box constraints. It applies to both LinMPC and NonLinMPC. Note that if there is a nonzero value in the associated softness parameters $\mathbf{c_{(\bullet)}}$ it is no longer a box constraint and the associated bound is treated as a linear inequality constraint, like before.

The default QP solver for LinMPC is OSQP.jl, and it does not support box constraint natively. It is still possible to define box constraints with the bridge mechanism of JuMP.jl. The new default optim argument for LinMPC is optim=JuMP.Model(OSQP.MathOptInterfaceOSQP.Optimizer, add_bridges=true). It should not affect the performances since JuMP will automatically convert them as linear equality constraints, as it was the case before this PR. It's possible that the performances with DAQP.jl will be improved however, since it supports box constraints natively.

Warning

Constructing LinMPC with optim=JuMP.Model(OSQP.MathOptInterfaceOSQP.Optimizer, add_bridges=false) will now throw an error. Please use add_bridges=true (it should not affect performances).

Let's see the benchmarks.

@codecov-commenter

codecov-commenter commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.60%. Comparing base (ed09542) to head (82f0ab8).
⚠️ Report is 8 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #379      +/-   ##
==========================================
+ Coverage   98.58%   98.60%   +0.02%     
==========================================
  Files          27       27              
  Lines        5512     5595      +83     
==========================================
+ Hits         5434     5517      +83     
  Misses         78       78              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown

Benchmark Results (Julia v1)

Time benchmarks
main 4751d5e... main / 4751d5e...
CASE STUDIES/PredictiveController/CSTR/LinMPC/With feedforward/DAQP/SingleShooting 4.95 ± 0.53 ms 5.13 ± 0.44 ms 0.965 ± 0.13
CASE STUDIES/PredictiveController/CSTR/LinMPC/With feedforward/OSQP/MultipleShooting 12.1 ± 0.79 ms 12.7 ± 0.79 ms 0.946 ± 0.085
CASE STUDIES/PredictiveController/CSTR/LinMPC/With feedforward/OSQP/SingleShooting 1.95 ± 0.1 ms 1.9 ± 0.1 ms 1.03 ± 0.077
CASE STUDIES/PredictiveController/CSTR/LinMPC/Without feedforward/DAQP/SingleShooting 4.88 ± 0.39 ms 5.15 ± 0.5 ms 0.948 ± 0.12
CASE STUDIES/PredictiveController/CSTR/LinMPC/Without feedforward/OSQP/MultipleShooting 8.34 ± 0.59 ms 9.07 ± 0.79 ms 0.919 ± 0.1
CASE STUDIES/PredictiveController/CSTR/LinMPC/Without feedforward/OSQP/SingleShooting 2.15 ± 0.11 ms 2.11 ± 0.097 ms 1.02 ± 0.069
CASE STUDIES/PredictiveController/Pendulum/LinMPC/Successive linearization/DAQP/SingleShooting 10.2 ± 1.8 ms 9.87 ± 1.5 ms 1.03 ± 0.24
CASE STUDIES/PredictiveController/Pendulum/LinMPC/Successive linearization/OSQP/MultipleShooting 0.138 ± 0.031 s 0.13 ± 0.028 s 1.06 ± 0.33
CASE STUDIES/PredictiveController/Pendulum/LinMPC/Successive linearization/OSQP/SingleShooting 15.3 ± 2.3 ms 15.4 ± 2.2 ms 0.994 ± 0.2
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/MultipleShooting 0.598 ± 0.002 s 0.541 ± 0.0025 s 1.1 ± 0.0063
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/MultipleShooting (Hessian) 0.816 ± 0.0052 s 1.37 ± 0.0034 s 0.594 ± 0.004
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/SingleShooting 1.4 ± 0.0033 s 1.58 ± 0.0032 s 0.885 ± 0.0028
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/TrapezoidalCollocation 0.624 ± 0.0035 s 1.04 ± 0.0031 s 0.6 ± 0.0038
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/TrapezoidalCollocation (Hessian) 0.627 ± 0.006 s 1.04 ± 0.0045 s 0.603 ± 0.0064
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/MultipleShooting 0.369 ± 0.0064 s 0.374 ± 0.0019 s 0.987 ± 0.018
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/MultipleShooting (Hessian) 0.442 ± 0.0057 s 0.439 ± 0.0014 s 1.01 ± 0.013
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/OrthogonalCollocation 0.554 ± 0.0042 s 0.542 ± 0.0012 s 1.02 ± 0.0081
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/OrthogonalCollocation (Hessian) 0.57 ± 0.012 s 0.55 ± 0.0023 s 1.04 ± 0.022
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/SingleShooting 0.526 ± 0.0015 s 0.539 ± 0.0024 s 0.975 ± 0.0051
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/SingleShooting (Hessian) 0.186 ± 0.001 s 0.188 ± 0.00068 s 0.988 ± 0.0064
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/TrapezoidalCollocation 0.342 ± 0.0022 s 0.339 ± 0.00074 s 1.01 ± 0.0068
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/TrapezoidalCollocation (Hessian) 0.345 ± 0.002 s 0.348 ± 0.0018 s 0.991 ± 0.0076
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/MadNLP/SingleShooting (Hessian) 0.0785 ± 0.00063 s 0.0819 ± 0.0014 s 0.959 ± 0.018
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Uno/MultipleShooting (Hessian) 0.187 ± 0.011 s 0.19 ± 0.01 s 0.986 ± 0.081
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/MultipleShooting 0.351 ± 0.0013 s 0.351 ± 0.0011 s 1 ± 0.0049
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/MultipleShooting (Hessian) 0.386 ± 0.0018 s 0.386 ± 0.0016 s 1 ± 0.0062
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/MultipleShooting (threaded) 0.376 ± 0.0027 s 0.373 ± 0.0042 s 1.01 ± 0.014
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/OrthogonalCollocation 0.607 ± 0.0018 s 0.614 ± 0.0034 s 0.99 ± 0.0062
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/OrthogonalCollocation (Hessian) 1.8 ± 0.02 s 1.82 ± 0.026 s 0.989 ± 0.018
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/SingleShooting 0.525 ± 0.0023 s 0.516 ± 0.0011 s 1.02 ± 0.005
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/SingleShooting (Hessian) 0.183 ± 0.0009 s 0.187 ± 0.0013 s 0.98 ± 0.0084
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/TrapezoidalCollocation 0.349 ± 0.0047 s 0.344 ± 0.0019 s 1.02 ± 0.015
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/TrapezoidalCollocation (Hessian) 0.299 ± 0.0013 s 0.306 ± 0.0033 s 0.978 ± 0.011
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/TrapezoidalCollocation (threaded) 0.365 ± 0.0031 s 0.374 ± 0.003 s 0.977 ± 0.012
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/MadNLP/MultipleShooting (Hessian) 0.26 ± 0.0081 s 0.26 ± 0.0016 s 0.999 ± 0.032
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/MadNLP/SingleShooting (Hessian) 0.0746 ± 0.00064 s 0.0762 ± 0.00069 s 0.979 ± 0.012
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Uno/MultipleShooting (Hessian) 0.168 ± 0.0025 s 0.167 ± 0.0014 s 1.01 ± 0.017
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Uno/OrthogonalCollocation (Hessian) 0.872 ± 0.016 s 0.88 ± 0.01 s 0.99 ± 0.022
CASE STUDIES/StateEstimator/CSTR/MovingHorizonEstimator/DAQP/Current form 0.0861 ± 0.0038 s 0.0854 ± 0.0065 s 1.01 ± 0.089
CASE STUDIES/StateEstimator/CSTR/MovingHorizonEstimator/DAQP/Prediction form 0.0641 ± 0.003 s 0.0642 ± 0.0074 s 0.999 ± 0.12
CASE STUDIES/StateEstimator/CSTR/MovingHorizonEstimator/OSQP/Current form 0.0811 ± 0.005 s 0.0851 ± 0.0048 s 0.953 ± 0.08
CASE STUDIES/StateEstimator/CSTR/MovingHorizonEstimator/OSQP/Prediction form 0.0599 ± 0.0085 s 0.0553 ± 0.0072 s 1.08 ± 0.21
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/Ipopt/Current form 0.0972 ± 0.00089 s 0.0993 ± 0.00042 s 0.979 ± 0.0098
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/Ipopt/Current form (Hessian) 0.0955 ± 0.00072 s 0.0965 ± 0.00059 s 0.989 ± 0.0096
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/Ipopt/Prediction form 0.0711 ± 0.00028 s 0.0717 ± 0.00053 s 0.992 ± 0.0083
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/Ipopt/Prediction form (Hessian) 0.0932 ± 0.00039 s 0.0955 ± 0.0005 s 0.976 ± 0.0065
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/MadNLP/Current form (Hessian) 0.0509 ± 0.0015 s 0.0503 ± 0.00041 s 1.01 ± 0.031
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/MadNLP/Prediction form (Hessian) 0.0455 ± 0.00053 s 0.0457 ± 0.00044 s 0.996 ± 0.015
UNIT TESTS/PredictiveController/ExplicitMPC/moveinput! 4.01 ± 0.21 μs 4.39 ± 0.23 μs 0.913 ± 0.068
UNIT TESTS/PredictiveController/LinMPC/getinfo! 0.0982 ± 0.002 ms 0.0992 ± 0.002 ms 0.99 ± 0.028
UNIT TESTS/PredictiveController/LinMPC/moveinput!/MultipleShooting 0.113 ± 0.0014 ms 0.146 ± 0.0098 ms 0.773 ± 0.053
UNIT TESTS/PredictiveController/LinMPC/moveinput!/SingleShooting 15.8 ± 0.4 μs 16.7 ± 0.36 μs 0.946 ± 0.031
UNIT TESTS/PredictiveController/NonLinMPC/getinfo!/LinModel 0.202 ± 0.012 ms 0.167 ± 0.017 ms 1.21 ± 0.14
UNIT TESTS/PredictiveController/NonLinMPC/getinfo!/NonLinModel 0.25 ± 0.028 ms 0.276 ± 0.027 ms 0.905 ± 0.13
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/LinModel/MultipleShooting 1.61 ± 0.26 ms 1.17 ± 0.25 ms 1.38 ± 0.36
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/LinModel/SingleShooting 1.05 ± 0.041 ms 0.481 ± 0.024 ms 2.17 ± 0.14
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/MultipleShooting 2.56 ± 0.76 ms 10.6 ± 0.23 ms 0.242 ± 0.072
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/MultipleShootingHessian 2.4 ± 0.089 ms 10.6 ± 0.19 ms 0.226 ± 0.0094
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/OrthogonalCollocation 2.39 ± 0.31 ms 10.2 ± 0.82 ms 0.234 ± 0.035
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/OrthogonalCollocationHessian 3.15 ± 0.15 ms 11 ± 0.63 ms 0.286 ± 0.021
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/SingleShooting 1.35 ± 0.041 ms 7.57 ± 0.7 ms 0.178 ± 0.017
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/SingleShootingHessian 1.34 ± 0.033 ms 7.05 ± 0.31 ms 0.19 ± 0.0095
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/TrapezoidalCollocation 1.73 ± 0.1 ms 7.38 ± 0.24 ms 0.234 ± 0.016
UNIT TESTS/SimModel/LinModel/evaloutput 0.14 ± 0 μs 0.14 ± 0 μs 1 ± 0
UNIT TESTS/SimModel/LinModel/updatestate! 0.19 ± 0.001 μs 0.19 ± 0.001 μs 1 ± 0.0074
UNIT TESTS/SimModel/NonLinModel/evaloutput 0.321 ± 0.001 μs 0.32 ± 0.01 μs 1 ± 0.032
UNIT TESTS/SimModel/NonLinModel/linearize! 1.8 ± 0.049 μs 2.11 ± 0.05 μs 0.853 ± 0.031
UNIT TESTS/SimModel/NonLinModel/updatestate! 0.371 ± 0.01 μs 0.38 ± 0.011 μs 0.976 ± 0.039
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/evaloutput/LinModel 0.491 ± 0.011 μs 0.491 ± 0.011 μs 1 ± 0.032
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/evaloutput/NonLinModel 1.67 ± 0.03 μs 1.66 ± 0.02 μs 1.01 ± 0.022
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/preparestate!/LinModel 0.23 ± 0.001 μs 0.24 ± 0.001 μs 0.958 ± 0.0058
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/preparestate!/NonLinModel 1.29 ± 0.01 μs 1.28 ± 0.01 μs 1.01 ± 0.011
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/updatestate!/LinModel 4.09 ± 0.06 μs 3.99 ± 0.07 μs 1.03 ± 0.023
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/updatestate!/NonLinModel 8.06 ± 0.071 μs 8.21 ± 0.08 μs 0.982 ± 0.013
UNIT TESTS/StateEstimator/InternalModel/evaloutput/LinModel 0.25 ± 0.001 μs 0.251 ± 0.01 μs 0.996 ± 0.04
UNIT TESTS/StateEstimator/InternalModel/evaloutput/NonLinModel 0.5 ± 0.01 μs 0.51 ± 0.01 μs 0.98 ± 0.027
UNIT TESTS/StateEstimator/InternalModel/preparestate!/LinModel 0.621 ± 0.01 μs 0.62 ± 0.02 μs 1 ± 0.036
UNIT TESTS/StateEstimator/InternalModel/preparestate!/NonLinModel 0.631 ± 0.01 μs 0.631 ± 0.01 μs 1 ± 0.022
UNIT TESTS/StateEstimator/InternalModel/updatestate!/LinModel 0.57 ± 0.02 μs 0.681 ± 0.02 μs 0.837 ± 0.038
UNIT TESTS/StateEstimator/InternalModel/updatestate!/NonLinModel 1.17 ± 0.02 μs 1.15 ± 0.011 μs 1.02 ± 0.02
UNIT TESTS/StateEstimator/KalmanFilter/evaloutput 0.241 ± 0.01 μs 0.431 ± 0.01 μs 0.559 ± 0.027
UNIT TESTS/StateEstimator/KalmanFilter/preparestate! 0.14 ± 0 μs 0.14 ± 0.001 μs 1 ± 0.0071
UNIT TESTS/StateEstimator/KalmanFilter/updatestate! 2.58 ± 0.05 μs 2.63 ± 0.05 μs 0.981 ± 0.027
UNIT TESTS/StateEstimator/Luenberger/evaloutput 0.23 ± 0.01 μs 0.22 ± 0.001 μs 1.05 ± 0.046
UNIT TESTS/StateEstimator/Luenberger/preparestate! 0.26 ± 0.001 μs 0.301 ± 0.021 μs 0.864 ± 0.06
UNIT TESTS/StateEstimator/Luenberger/updatestate! 0.361 ± 0.011 μs 0.361 ± 0.01 μs 1 ± 0.041
UNIT TESTS/StateEstimator/MovingHorizonEstimator/getinfo!/LinModel 0.29 ± 0.021 ms 0.284 ± 0.018 ms 1.02 ± 0.099
UNIT TESTS/StateEstimator/MovingHorizonEstimator/getinfo!/NonLinModel 0.368 ± 0.019 ms 0.358 ± 0.019 ms 1.03 ± 0.076
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/LinModel/Constant arr. cov. 0.0353 ± 0.0035 s 0.0332 ± 0.0028 s 1.06 ± 0.14
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/LinModel/Current form 0.0354 ± 0.002 s 16.2 ± 22 ms 2.18 ± 3
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/LinModel/Prediction form 0.43 ± 0.001 μs 0.43 ± 0.01 μs 1 ± 0.023
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/NonLinModel/Current form 0.323 ± 0.019 ms 0.315 ± 0.018 ms 1.02 ± 0.085
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/NonLinModel/Prediction form 1.32 ± 0.02 μs 1.32 ± 0.01 μs 1 ± 0.017
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/LinModel/Constant arr. cov. 13.1 ± 4 μs 13.4 ± 3.7 μs 0.975 ± 0.4
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/LinModel/Current form 0.0337 ± 0.01 ms 0.0393 ± 0.0058 ms 0.857 ± 0.28
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/LinModel/Prediction form 0.0333 ± 0.0018 s 31.4 ± 1.9 ms 1.06 ± 0.085
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/NonLinModel/Current form 18 ± 0.5 μs 18.3 ± 0.53 μs 0.983 ± 0.04
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/NonLinModel/Prediction form 0.339 ± 0.019 ms 0.331 ± 0.018 ms 1.03 ± 0.08
UNIT TESTS/StateEstimator/SteadyKalmanFilter/evaloutput 0.671 ± 0.01 μs 0.431 ± 0.011 μs 1.56 ± 0.046
UNIT TESTS/StateEstimator/SteadyKalmanFilter/preparestate! 0.251 ± 0.011 μs 0.26 ± 0.029 μs 0.965 ± 0.12
UNIT TESTS/StateEstimator/SteadyKalmanFilter/updatestate! 0.37 ± 0.019 μs 0.531 ± 0.011 μs 0.697 ± 0.039
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/evaloutput/LinModel 0.291 ± 0.01 μs 0.28 ± 0.01 μs 1.04 ± 0.052
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/evaloutput/NonLinModel 0.852 ± 0.01 μs 0.891 ± 0.011 μs 0.956 ± 0.016
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/preparestate!/LinModel 3.68 ± 0.069 μs 3.62 ± 0.051 μs 1.01 ± 0.024
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/preparestate!/NonLinModel 5.1 ± 0.05 μs 5.02 ± 0.051 μs 1.02 ± 0.014
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/updatestate!/LinModel 3.73 ± 0.06 μs 3.7 ± 0.06 μs 1.01 ± 0.023
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/updatestate!/NonLinModel 6.27 ± 0.08 μs 6.45 ± 0.14 μs 0.972 ± 0.025
time_to_load 6.04 ± 0.075 s 6.28 ± 0.015 s 0.962 ± 0.012
Memory benchmarks
main 4751d5e... main / 4751d5e...
CASE STUDIES/PredictiveController/CSTR/LinMPC/With feedforward/DAQP/SingleShooting 0.0469 M allocs: 1.85 MB 0.0489 M allocs: 1.86 MB 0.993
CASE STUDIES/PredictiveController/CSTR/LinMPC/With feedforward/OSQP/MultipleShooting 0.126 M allocs: 3.16 MB 0.126 M allocs: 3.16 MB 1
CASE STUDIES/PredictiveController/CSTR/LinMPC/With feedforward/OSQP/SingleShooting 12.9 k allocs: 0.361 MB 12.6 k allocs: 0.356 MB 1.01
CASE STUDIES/PredictiveController/CSTR/LinMPC/Without feedforward/DAQP/SingleShooting 0.0468 M allocs: 1.84 MB 0.0487 M allocs: 1.85 MB 0.993
CASE STUDIES/PredictiveController/CSTR/LinMPC/Without feedforward/OSQP/MultipleShooting 0.0882 M allocs: 2.23 MB 0.0879 M allocs: 2.23 MB 1
CASE STUDIES/PredictiveController/CSTR/LinMPC/Without feedforward/OSQP/SingleShooting 12.8 k allocs: 0.355 MB 12.5 k allocs: 0.35 MB 1.01
CASE STUDIES/PredictiveController/Pendulum/LinMPC/Successive linearization/DAQP/SingleShooting 0.119 M allocs: 6.37 MB 0.119 M allocs: 6.37 MB 1
CASE STUDIES/PredictiveController/Pendulum/LinMPC/Successive linearization/OSQP/MultipleShooting 4.76 M allocs: 0.257 GB 4.75 M allocs: 0.257 GB 1
CASE STUDIES/PredictiveController/Pendulum/LinMPC/Successive linearization/OSQP/SingleShooting 0.15 M allocs: 8.51 MB 0.148 M allocs: 8.22 MB 1.03
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/MultipleShooting 0.381 M allocs: 26.4 MB 0.369 M allocs: 25.5 MB 1.03
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/MultipleShooting (Hessian) 1.28 M allocs: 0.141 GB 2.2 M allocs: 0.244 GB 0.579
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/SingleShooting 0.233 M allocs: 0.0323 GB 0.306 M allocs: 0.0435 GB 0.743
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/TrapezoidalCollocation 1.28 M allocs: 0.124 GB 2.17 M allocs: 0.212 GB 0.585
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Custom constraints/Ipopt/TrapezoidalCollocation (Hessian) 1.28 M allocs: 0.124 GB 2.17 M allocs: 0.212 GB 0.585
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/MultipleShooting 0.316 M allocs: 22 MB 0.316 M allocs: 22 MB 1
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/MultipleShooting (Hessian) 0.741 M allocs: 0.0843 GB 0.741 M allocs: 0.0843 GB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/OrthogonalCollocation 1.33 M allocs: 0.119 GB 1.33 M allocs: 0.119 GB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/OrthogonalCollocation (Hessian) 1.33 M allocs: 0.119 GB 1.33 M allocs: 0.119 GB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/SingleShooting 0.0965 M allocs: 17.6 MB 0.0965 M allocs: 17.6 MB 1
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/SingleShooting (Hessian) 0.0812 M allocs: 16.8 MB 0.0812 M allocs: 16.9 MB 0.993
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/TrapezoidalCollocation 0.314 M allocs: 21.8 MB 0.314 M allocs: 21.9 MB 0.996
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Ipopt/TrapezoidalCollocation (Hessian) 0.757 M allocs: 0.0765 GB 0.757 M allocs: 0.0765 GB 1
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/MadNLP/SingleShooting (Hessian) 0.0926 M allocs: 19.8 MB 0.0926 M allocs: 20 MB 0.994
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Economic/Uno/MultipleShooting (Hessian) 0.311 M allocs: 0.0327 GB 0.311 M allocs: 0.0327 GB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/MultipleShooting 0.277 M allocs: 19 MB 0.277 M allocs: 19 MB 1
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/MultipleShooting (Hessian) 0.709 M allocs: 0.0738 GB 0.709 M allocs: 0.0739 GB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/MultipleShooting (threaded) 0.296 M allocs: 28 MB 0.296 M allocs: 28 MB 1
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/OrthogonalCollocation 1.43 M allocs: 0.128 GB 1.43 M allocs: 0.128 GB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/OrthogonalCollocation (Hessian) 5.12 M allocs: 0.601 GB 5.12 M allocs: 0.601 GB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/SingleShooting 0.0754 M allocs: 13.3 MB 0.0754 M allocs: 13.3 MB 1
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/SingleShooting (Hessian) 0.0808 M allocs: 16.8 MB 0.0808 M allocs: 16.9 MB 0.993
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/TrapezoidalCollocation 0.276 M allocs: 19 MB 0.276 M allocs: 19 MB 0.996
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/TrapezoidalCollocation (Hessian) 0.72 M allocs: 0.0656 GB 0.72 M allocs: 0.0656 GB 1
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Ipopt/TrapezoidalCollocation (threaded) 0.295 M allocs: 28 MB 0.295 M allocs: 28.1 MB 0.997
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/MadNLP/MultipleShooting (Hessian) 0.587 M allocs: 0.0728 GB 0.587 M allocs: 0.0728 GB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/MadNLP/SingleShooting (Hessian) 0.0927 M allocs: 19.9 MB 0.0927 M allocs: 20 MB 0.994
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Uno/MultipleShooting (Hessian) 0.307 M allocs: 30.3 MB 0.307 M allocs: 30.3 MB 0.999
CASE STUDIES/PredictiveController/Pendulum/NonLinMPC/Noneconomic/Uno/OrthogonalCollocation (Hessian) 2.13 M allocs: 0.243 GB 2.13 M allocs: 0.243 GB 0.999
CASE STUDIES/StateEstimator/CSTR/MovingHorizonEstimator/DAQP/Current form 1.25 M allocs: 0.213 GB 1.25 M allocs: 0.213 GB 1
CASE STUDIES/StateEstimator/CSTR/MovingHorizonEstimator/DAQP/Prediction form 1.16 M allocs: 0.136 GB 1.16 M allocs: 0.136 GB 1
CASE STUDIES/StateEstimator/CSTR/MovingHorizonEstimator/OSQP/Current form 1.13 M allocs: 0.21 GB 1.13 M allocs: 0.21 GB 1
CASE STUDIES/StateEstimator/CSTR/MovingHorizonEstimator/OSQP/Prediction form 1.07 M allocs: 0.134 GB 1.07 M allocs: 0.134 GB 1
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/Ipopt/Current form 0.0691 M allocs: 12.1 MB 0.0691 M allocs: 12.1 MB 1
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/Ipopt/Current form (Hessian) 0.0682 M allocs: 12 MB 0.0682 M allocs: 12 MB 1
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/Ipopt/Prediction form 0.0521 M allocs: 8.54 MB 0.0521 M allocs: 8.54 MB 1
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/Ipopt/Prediction form (Hessian) 0.0684 M allocs: 12.1 MB 0.0684 M allocs: 12.1 MB 1
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/MadNLP/Current form (Hessian) 0.0902 M allocs: 16 MB 0.0902 M allocs: 16 MB 1
CASE STUDIES/StateEstimator/Pendulum/MovingHorizonEstimator/MadNLP/Prediction form (Hessian) 0.0851 M allocs: 14.7 MB 0.0851 M allocs: 14.7 MB 1
UNIT TESTS/PredictiveController/ExplicitMPC/moveinput! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/PredictiveController/LinMPC/getinfo! 0.327 k allocs: 15.8 kB 0.326 k allocs: 15.6 kB 1.01
UNIT TESTS/PredictiveController/LinMPC/moveinput!/MultipleShooting 0.994 k allocs: 25.5 kB 1.62 k allocs: 0.0403 MB 0.618
UNIT TESTS/PredictiveController/LinMPC/moveinput!/SingleShooting 0.088 k allocs: 2.23 kB 0.114 k allocs: 2.98 kB 0.749
UNIT TESTS/PredictiveController/NonLinMPC/getinfo!/LinModel 0.482 k allocs: 0.0604 MB 0.408 k allocs: 0.0579 MB 1.04
UNIT TESTS/PredictiveController/NonLinMPC/getinfo!/NonLinModel 0.614 k allocs: 0.0785 MB 0.571 k allocs: 0.077 MB 1.02
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/LinModel/MultipleShooting 1.89 k allocs: 0.11 MB 1.79 k allocs: 0.105 MB 1.05
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/LinModel/SingleShooting 0.431 k allocs: 18.1 kB 0.254 k allocs: 10.1 kB 1.79
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/MultipleShooting 2.29 k allocs: 0.143 MB 4.76 k allocs: 0.368 MB 0.388
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/MultipleShootingHessian 2.88 k allocs: 0.198 MB 5.34 k allocs: 0.423 MB 0.468
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/OrthogonalCollocation 3.78 k allocs: 0.22 MB 9.58 k allocs: 0.609 MB 0.361
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/OrthogonalCollocationHessian 7.62 k allocs: 0.681 MB 0.0459 M allocs: 4.44 MB 0.154
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/SingleShooting 0.333 k allocs: 0.0473 MB 0.957 k allocs: 0.233 MB 0.203
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/SingleShootingHessian 0.333 k allocs: 0.0473 MB 0.957 k allocs: 0.233 MB 0.203
UNIT TESTS/PredictiveController/NonLinMPC/moveinput!/NonLinModel/TrapezoidalCollocation 1.45 k allocs: 0.0898 MB 3.42 k allocs: 0.241 MB 0.373
UNIT TESTS/SimModel/LinModel/evaloutput 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/SimModel/LinModel/updatestate! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/SimModel/NonLinModel/evaloutput 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/SimModel/NonLinModel/linearize! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/SimModel/NonLinModel/updatestate! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/evaloutput/LinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/evaloutput/NonLinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/preparestate!/LinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/preparestate!/NonLinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/updatestate!/LinModel 4 allocs: 0.0938 kB 4 allocs: 0.0938 kB 1
UNIT TESTS/StateEstimator/ExtendedKalmanFilter/updatestate!/NonLinModel 4 allocs: 0.0938 kB 4 allocs: 0.0938 kB 1
UNIT TESTS/StateEstimator/InternalModel/evaloutput/LinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/InternalModel/evaloutput/NonLinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/InternalModel/preparestate!/LinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/InternalModel/preparestate!/NonLinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/InternalModel/updatestate!/LinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/InternalModel/updatestate!/NonLinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/KalmanFilter/evaloutput 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/KalmanFilter/preparestate! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/KalmanFilter/updatestate! 4 allocs: 0.0938 kB 4 allocs: 0.0938 kB 1
UNIT TESTS/StateEstimator/Luenberger/evaloutput 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/Luenberger/preparestate! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/Luenberger/updatestate! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/MovingHorizonEstimator/getinfo!/LinModel 1.01 k allocs: 0.0405 MB 1.01 k allocs: 0.0405 MB 1
UNIT TESTS/StateEstimator/MovingHorizonEstimator/getinfo!/NonLinModel 1.27 k allocs: 0.167 MB 1.27 k allocs: 0.167 MB 1
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/LinModel/Constant arr. cov. 0.158 M allocs: 0.117 GB 0.158 M allocs: 0.116 GB 1.01
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/LinModel/Current form 0.158 M allocs: 0.115 GB 0.158 M allocs: 0.117 GB 0.988
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/LinModel/Prediction form 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/NonLinModel/Current form 0.977 k allocs: 25.3 kB 0.977 k allocs: 25.3 kB 1
UNIT TESTS/StateEstimator/MovingHorizonEstimator/preparestate!/NonLinModel/Prediction form 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/LinModel/Constant arr. cov. 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/LinModel/Current form 2 allocs: 0.0469 kB 2 allocs: 0.0469 kB 1
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/LinModel/Prediction form 7.08 k allocs: 0.451 MB 7.08 k allocs: 0.451 MB 1
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/NonLinModel/Current form 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/MovingHorizonEstimator/updatestate!/NonLinModel/Prediction form 0.977 k allocs: 25.3 kB 0.977 k allocs: 25.3 kB 1
UNIT TESTS/StateEstimator/SteadyKalmanFilter/evaloutput 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/SteadyKalmanFilter/preparestate! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/SteadyKalmanFilter/updatestate! 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/evaloutput/LinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/evaloutput/NonLinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/preparestate!/LinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/preparestate!/NonLinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/updatestate!/LinModel 0 allocs: 0 B 0 allocs: 0 B
UNIT TESTS/StateEstimator/UnscentedKalmanFilter/updatestate!/NonLinModel 0 allocs: 0 B 0 allocs: 0 B
time_to_load 0.149 k allocs: 11.2 kB 0.149 k allocs: 11.2 kB 1

@franckgaga

franckgaga commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

Wow these terrible results haha ⁉️⁉️⁉️

I did something wrong for sure 😆

@franckgaga

franckgaga commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

Okay I ran some of the benchmark locally and many case studies did not converge anymore, that's why. There's presumably a nasty bug hidden somewhere.

I just modify them on `setconstraint!` calls
@franckgaga

franckgaga commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

Okay I have this MRE that converge to the best solution (at least a very good solution) on main, but a very bad solution in this branch:

using ModelPredictiveControl, ControlSystemsBase, JuMP, Ipopt, BenchmarkTools

function f!(ẋ, x, u, _ , p)
    g, L, K, m = p
    θ, ω = x[1], x[2]
    τ = u[1]
    ẋ[1] = ω
    ẋ[2] = -g/L*sin(θ) - K/m*ω + τ/m/L^2
end
h!(y, x, _ , _ ) = (y[1] = 180/π*x[1])
p = [9.8, 0.4, 1.2, 0.3]
nu = 1; nx = 2; ny = 1; Ts = 0.1
pendulum_model = NonLinModel(f!, h!, Ts, nu, nx, ny; p)
pendulum_p = p

h2!(y, x, _ , _ ) = (y[1] = 180/π*x[1]; y[2]=x[2])
nu, nx, ny = 1, 2, 2
pendulum_model2 = NonLinModel(f!, h2!, Ts, nu, nx, ny; p)
pendulum_p2 = p

Hp, Hc, Mwt, Nwt, Cwt = 20, 2, [0.5], [2.5], Inf
umin, umax = [-1.5], [+1.5]

model2, p = pendulum_model2, pendulum_p2
plant2 = deepcopy(model2)
plant2.p[3] = 1.25*p[3]  # plant-model mismatch
σQ = [0.1, 1.0]; σR=[5.0]; nint_u=[1]; σQint_u=[0.1]
estim2 = UnscentedKalmanFilter(model2; σQ, σR, nint_u, σQint_u, i_ym=[1])
function JE(UE, ŶE, _ , p, _)
    Ts = p
    τ, ω = @views UE[1:end-1], ŶE[2:2:end-1]
    return Ts*dot(τ, ω)
end
p = Ts; Mwt2 = [Mwt; 0.0]; Ewt = 3.5e3
x_0 = [0, 0]; x̂_0 = [0, 0, 0]; ry = [180; 0]

function gc!(LHS, Ue, Ŷe, _, p, ϵ)
    Pmax = p
    i_τ, i_ω = 1, 2
    for i in eachindex(LHS)
        τ, ω = Ue[i_τ], Ŷe[i_ω]
        P = τ*ω
        LHS[i] = P - Pmax - ϵ
        i_τ += 1
        i_ω += 2
    end
    return nothing
end
Cwt, Pmax, nc = 1e5, 3, Hp+1
x_0 = [0, 0]; x̂_0 = [0, 0, 0]; ry = [180; 0]

N = 35

optim = JuMP.Model(optimizer_with_attributes(Ipopt.Optimizer,"sb"=>"yes"), add_bridges=false)
transcription = MultipleShooting()
nmpc2_ipopt_ms = NonLinMPC(estim2; 
    Hp, Hc, Nwt=Nwt, Mwt=[0.5, 0], Cwt, gc!, nc, p=Pmax, optim, transcription
)
nmpc2_ipopt_ms = setconstraint!(nmpc2_ipopt_ms; umin, umax)
JuMP.unset_time_limit_sec(nmpc2_ipopt_ms.optim)

samples, evals, seconds = 100, 1, 15*60
# @btime(
#     sim!($nmpc2_ipopt_ms, $N, $ry; plant=$plant2, x_0=$x_0, x̂_0=$x̂_0, progress=false),
#     samples=samples, evals=evals, seconds=seconds, setup=GC.gc()
# )

unset_silent(nmpc2_ipopt_ms.optim)
initstate!(nmpc2_ipopt_ms, [0], [0])
setstate!(nmpc2_ipopt_ms, x̂_0)

preparestate!(nmpc2_ipopt_ms, [0])
u = moveinput!(nmpc2_ipopt_ms, ry)

We can see that the objective increases throughtout the iterrations:

This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

Number of nonzeros in equality constraint Jacobian...:      271
Number of nonzeros in inequality constraint Jacobian.:      180
Number of nonzeros in Lagrangian Hessian.............:        0

Total number of variables............................:       63
                     variables with only lower bounds:        1
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:       60
Total number of inequality constraints...............:       61
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:       61

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  3.2401000e+05 0.00e+00 1.00e+00   0.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  3.2403228e+05 3.69e-14 1.41e-02  -2.0 9.94e-03    -  9.96e-01 1.00e+00h  1
   2  3.2055122e+05 3.77e-06 1.36e-04  -5.3 5.28e-02    -  9.90e-01 1.00e+00f  1
   3  1.2932991e+05 2.49e+00 4.12e-02  -5.1 6.13e+00    -  9.89e-01 5.94e-01f  1
   4  1.4870286e+05 1.45e+00 1.23e+00  -4.9 1.93e+00    -  1.00e+00 2.29e-01f  1
   5  1.1307417e+05 1.28e+00 2.83e-01  -4.8 1.87e+00    -  1.00e+00 6.82e-01h  1
   6  2.1771590e+06 5.46e+00 3.32e+01  -2.9 7.85e+01    -  9.67e-01 1.32e-01f  1
   7  1.9320195e+06 6.39e+00 1.96e+02  -2.6 7.36e+00    -  1.18e-02 5.79e-01h  1
   8  1.9324280e+06 6.42e+00 9.16e+02  -2.6 5.58e+00    -  1.00e+00 5.48e-03h  1
   9  2.0054702e+06 6.31e+00 1.22e+03  -2.6 6.39e+00    -  5.13e-02 4.58e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  2.0056961e+06 6.31e+00 3.95e+03  -2.6 5.78e+00    -  1.62e-03 1.66e-04h  1
  11  2.3155204e+06 5.84e+00 2.94e+03  -2.6 9.30e+00    -  9.22e-04 9.04e-02f  1
  12  2.5187679e+06 5.70e+00 1.92e+03  -2.6 8.02e+00    -  1.95e-01 5.16e-02h  1
  13  2.5349819e+06 5.69e+00 3.02e+03  -2.6 1.21e+01    -  1.19e-02 2.35e-03h  1
  14  2.8620146e+06 5.40e+00 9.88e+03  -2.6 1.09e+01    -  1.20e-01 4.97e-02f  1
  15  8.2033055e+06 2.88e+00 3.36e+04  -2.6 1.04e+01    -  5.42e-02 4.53e-01h  1
  16  1.7043861e+07 1.41e-01 1.48e+03  -2.6 4.80e+00    -  9.69e-01 9.02e-01h  1
  17  1.6890133e+07 1.13e-01 3.63e+04  -2.6 4.71e-01    -  8.99e-01 2.00e-01h  1
  18  1.6336180e+07 9.55e-02 1.20e+04  -2.6 4.77e-01    -  3.81e-01 6.31e-01f  1
  19  1.7189242e+07 4.06e-03 4.47e+04  -2.6 3.54e-01    -  6.19e-02 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20  1.6972350e+07 7.39e-05 2.62e-03  -2.6 8.66e-02    -  9.94e-01 1.00e+00f  1
  21  1.6665026e+07 3.63e-03 4.91e+01  -3.9 3.51e-01    -  7.66e-01 4.49e-01f  1
  22  1.6653241e+07 7.44e-03 2.90e-02  -3.9 2.30e-01    -  1.00e+00 1.00e+00f  1
  23  1.6437398e+07 4.24e-02 2.06e+00  -3.9 5.56e-01    -  8.92e-01 1.00e+00f  1
  24  1.6255387e+07 8.97e-05 2.37e-02  -3.9 7.54e-02    -  3.40e-01 1.00e+00h  1
  25  1.6224119e+07 9.48e-05 1.29e-02  -3.9 3.15e+00    -  6.82e-01 4.03e-03f  2
  26  1.5845220e+07 1.26e-02 5.60e+01  -3.9 1.29e+00    -  2.73e-01 5.07e-01f  1
  27  1.4374217e+07 1.83e-01 9.21e+01  -3.9 1.13e+01    -  1.00e+00 3.53e-01f  1
  28  1.3948387e+07 1.71e-01 2.13e+02  -3.9 2.89e+00    -  1.00e+00 6.37e-02f  1
  29  1.2520204e+07 2.41e-03 4.76e+03  -3.9 6.61e-01    -  2.46e-02 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30  1.2501433e+07 2.71e-07 8.91e-03  -3.9 8.92e-03    -  1.00e+00 1.00e+00h  1
  31  1.2463733e+07 1.39e-05 2.43e-04  -3.9 1.52e-01    -  1.00e+00 1.94e-01f  2
  32  1.2406349e+07 1.85e-05 7.59e-05  -5.8 2.93e-02    -  1.00e+00 9.67e-01f  1
  33  1.2404926e+07 2.71e-08 2.81e-06  -5.8 1.16e-03    -  1.00e+00 1.00e+00h  1
  34  1.2404496e+07 2.24e-09 2.15e-04  -8.7 2.15e-04    -  1.00e+00 9.81e-01h  1
  35  1.2404470e+07 2.19e-10 2.41e-05  -8.7 2.41e-05    -  1.00e+00 9.38e-01h  1
  36  1.2404471e+07 8.88e-15 2.59e-07  -8.7 2.58e-07    -  1.00e+00 1.00e+00f  1
  37  1.2404470e+07 3.55e-15 2.88e-07 -12.3 2.88e-07    -  1.00e+00 1.00e+00f  1
  38  1.2404470e+07 1.78e-15 8.97e-11 -12.3 8.95e-11    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 38

                                   (scaled)                 (unscaled)
Objective...............:   1.2404469932044904e-01    1.2404469932044903e+07
Dual infeasibility......:   8.9661412978295787e-11    8.9661412978295791e-03
Constraint violation....:   9.1623033856588404e-20    1.7763568394002505e-15
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   5.0101162578586281e-13    5.0101162578586282e-05
Overall NLP error.......:   6.4974345416931383e-11    8.9661412978295791e-03


Number of objective function evaluations             = 44
Number of objective gradient evaluations             = 39
Number of equality constraint evaluations            = 44
Number of inequality constraint evaluations          = 44
Number of equality constraint Jacobian evaluations   = 39
Number of inequality constraint Jacobian evaluations = 39
Number of Lagrangian Hessian evaluations             = 0
Total seconds in IPOPT                               = 28.387

EXIT: Optimal Solution Found.
1-element Vector{Float64}:
 -1.5000000149650201

The results on main is way better:


This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.2.

Number of nonzeros in equality constraint Jacobian...:      271
Number of nonzeros in inequality constraint Jacobian.:      181
Number of nonzeros in Lagrangian Hessian.............:        0

Total number of variables............................:       63
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:       60
Total number of inequality constraints...............:       62
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:       62

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  3.2400000e+05 0.00e+00 2.20e-03   0.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  3.2399304e+05 3.58e-14 2.13e-03  -8.0 1.00e-02    -  1.00e+00 9.90e-01h  1
   2  3.2525985e+05 8.45e-06 1.09e-04  -9.5 2.39e-01    -  1.00e+00 1.00e+00h  1
   3  3.1650137e+05 3.15e-05 3.85e-03  -6.3 1.21e-01    -  9.90e-01 1.00e+00h  1
   4  2.9849888e+05 1.14e-03 2.22e-01  -7.4 5.31e-01    -  1.00e+00 4.85e-01h  1
   5  2.8580059e+05 2.49e-03 8.67e+00  -7.6 2.35e+00    -  1.00e+00 8.57e-02h  1
   6  1.3045575e+05 2.43e+00 8.87e-01  -7.5 1.04e+01    -  9.85e-01 2.95e-01h  1
   7  1.2954931e+05 1.95e+00 1.96e+00  -5.6 7.44e+00    -  1.00e+00 1.38e-01h  1
   8  1.0191055e+05 2.06e+00 1.05e+00  -5.5 2.58e+00    -  1.00e+00 3.28e-01h  1
   9  1.0072735e+05 2.05e+00 1.41e+00  -5.8 2.41e+00    -  2.21e-01 1.67e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  9.5195578e+04 1.96e+00 1.96e+00  -5.2 2.39e+00    -  1.00e+00 1.04e-01h  1
  11  1.4464578e+05 8.68e-01 3.08e-04  -4.7 1.23e+00    -  1.00e+00 1.00e+00h  1
  12  1.3198381e+05 2.80e-01 1.82e-01  -5.8 7.12e-01    -  1.00e+00 8.09e-01h  1
  13  1.2831229e+05 2.20e-02 7.10e-05  -6.5 4.13e-01    -  1.00e+00 1.00e+00h  1
  14  1.2812679e+05 7.51e-04 1.68e-06  -7.5 3.91e-02    -  1.00e+00 1.00e+00h  1
  15  1.2810475e+05 2.47e-05 2.53e-08  -9.6 1.56e-03    -  1.00e+00 9.69e-01h  1
  16  1.2810408e+05 3.11e-09 4.20e-09 -12.3 5.89e-05    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 16

                                   (scaled)                 (unscaled)
Objective...............:   1.2810408484187311e-03    1.2810408484187310e+05
Dual infeasibility......:   4.1966114646936961e-09    4.1966114646936958e-01
Constraint violation....:   1.6049625022104373e-13    3.1116478005355219e-09
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   5.0384975200402182e-13    5.0384975200402179e-05
Overall NLP error.......:   4.1966114646936961e-09    4.1966114646936958e-01


Number of objective function evaluations             = 17
Number of objective gradient evaluations             = 17
Number of equality constraint evaluations            = 17
Number of inequality constraint evaluations          = 17
Number of equality constraint Jacobian evaluations   = 17
Number of inequality constraint Jacobian evaluations = 17
Number of Lagrangian Hessian evaluations             = 0
Total seconds in IPOPT                               = 23.984

EXIT: Optimal Solution Found.
1-element Vector{Float64}:
 1.2717046667926974

I'm not sure what's happening. I will continue my investigations. Any clue @cvanaret on why the iterations could suddenly increase like this ?

edit : There is only one box constraint here, the slack $\epsilon \ge 0$, for constraint softening. This decision variable tends to take very small values since there is a $(10^5) \epsilon^2$ term in the objective function.

edit 2: It converges to the good solution if I set hessian=true in the NonLinMPC constructor, that is, provide an exact Hessian instead of the builtin LBFGS solver of Ipopt. Maybe it's not a bug on my side. Maybe the builtin LBFGS has difficulties when it's a bound constraint instead of an inequality constraint because it no longer appears in the Jacobian and Hessian? I will try Uno to see what's happening.

@cvanaret

Copy link
Copy Markdown

@franckgaga I'll try to run Ipopt on your instance to look at what's happening.
A few thoughts:

  • when the bound constraint $\varepsilon \ge 0$ is handled as a linear constraint, Ipopt introduces a slack $s$ such that $\varepsilon - s = 0$ and $s \ge 0$, and initializes $s$ with its own strategy (probably something like $10^{-2}$). In the model with explicit bound constraints, you perhaps set an initial value for $\varepsilon$ (I couldn't tell)?
  • Ipopt implements a fraction-to-boundary rule to maintain positivity of $\varepsilon$ or $s$, which has the other effect that the linearized constraints may not be satisfied by the scaled step. Hence the coupling between $\varepsilon$ and $s$ is temporarily lost during some iterations, which allows more freedom.
  • the linear constraints have no curvature contribution to the Lagrangian Hessian.

@franckgaga

franckgaga commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

Okay thanks for the tips !

Some progress here: changing the weight $C$ of the slack $\epsilon$ from 1e5 to 1e4 solve the issue here. And based on this new weight, the performances are slightly improved on this branch compared to main. My interpretation is the problem is badly scaled (which is kind of inevitable with this approach to constraint softening) and it affects the robustness of the builtin LBFGS solver. Reducing $C$ make it a bit less "ill-conditioned".

I will run the benchmark with this new Cwt value (note that it only affects the "Custom Constraint" entries, that is, the worst results right now).

edit : to answer your question, yes $\epsilon$ is initialized at 0, that is exactly on the bound.

This is necessary if there is a change on the state operating point, for the hard terminal constraints and `MultipleShooting` transcription.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants