How to add Output Path Constraints?

Hi :wave:

I want to implement an MPC that controls a battery.
I am using the following equivalent cicuit model of the battery:

Here is the model of the underlying equations:
1. State of charge: \dot{z}(t) = -\eta(t)i(t)/Q
2. Current i_{R_1}: \dot{i_{R_1}}(t)= -\frac{1}{R_1C_1}i_{R_1}(t) + \frac{1}{R_1C_1}i(t)
3. terminal voltage: v(t) = \mathrm{OCV}(z(t)) - R_1i_{R_1}(t)- R_0i(t)
4. Battery power: P(t) = v(t) \cdot i(t)

I want to add a power tracking contraint, meaning that the battery power is equal to the demanded power, which is a parameter p.

For this I used the following nonlinear equality contraint:

% this is the mapping from SoC to open circuit voltage
Uocv = interpolant('UocvFcn','linear', {Bat.V_ocv2.SoCBrkPts}, round(Bat.V_ocv2.UocvVals, 2));

% terminal voltage equation, where model.x(1) is SoC, model.x(4) is iR1 and model.u(1) is ibat 
Vbat = Uocv(model.x(1)) - Bat.R1 * model.x(4) - Bat.R0 * model.u(1);

% battery power
Pbat = (Vbat * model.u(1)) / Bat.kW2W;

% This is the constraint
ocp.model.con_h_expr = Pbat - model.p(1);
ocp.constraints.lh = 0;
ocp.constraints.uh = 0;

For some reason the power tracking does not work, when I simulate the MPC with plant model in Simulink. Only tracking states x works, but when I add the input u to the nonlinear equality constrainz, the tracking is no longer working.

Is this the correct way of adding a nonlinear equality constraint? Is there another way of adding a constraint on the model ouput y?

I am using Matlab 2023b on Windows.

Thanks Jannis

Hi :waving_hand:

regarding your implemetation: you do not need to introduce the extra parameter. You can simply set the lower and upper bounds lh and uh. It is also possible to update these values stagewise after solver creation using the setter: constraints_set, see Python Interface — acados documentation

In general, additional equalities might be challenging. I would recommend to slack this constraint.

Do you get status 0, i.e. is the solve successful? If not could you provide the output of print_statictics?

Hi Katrin,

thank you for the response, I already use slack variables for the equality constraint.

When simulating I mostly get the solver status = 2.

In the beginning i get the follwong print_statistics:

iter	res_stat	res_eq		res_ineq	res_comp	qp_stat	qp_iter	alpha
0	5.423389e+01	2.124769e-05	1.500000e+01	0.000000e+00	0	0	0.000000e+00
1	1.048898e-03	3.333311e-01	4.187100e-01	4.575805e-02	0	4	1.000000e+00
2	2.174073e-05	1.093596e-01	0.000000e+00	2.792718e-03	0	3	1.000000e+00
3	7.416262e+04	3.898159e-01	1.535557e+01	8.148720e+07	2	50	1.000000e+00
4	2.956479e+03	7.622957e-02	2.431938e+00	9.788597e+03	0	48	1.000000e+00
5	1.934884e+03	7.432587e-02	2.084080e+00	1.557016e+03	0	38	1.000000e+00
6	5.788328e+02	7.548541e-02	9.193799e-01	4.812969e+02	0	23	1.000000e+00
7	1.728649e-02	5.467235e-02	2.795815e+00	5.978177e-01	0	4	1.000000e+00
8	3.783640e+05	3.900862e-01	1.525977e+01	5.805709e+07	2	50	1.000000e+00
9	1.599175e+03	9.915660e-02	3.375553e+00	1.846717e+04	0	43	1.000000e+00
10	2.469777e+03	7.121559e-02	5.196559e-01	1.738745e+03	0	47	1.000000e+00
11	1.252184e+03	9.418311e-02	1.444085e+00	9.519829e+02	0	42	1.000000e+00
12	6.858084e+00	9.979162e-02	8.483414e-01	9.406867e+00	0	7	1.000000e+00
13	5.275034e-03	5.467338e-02	9.322274e-01	1.403049e-01	0	6	1.000000e+00
14	1.369126e+05	3.903558e-01	1.532355e+01	3.733355e+07	2	50	1.000000e+00
15	2.795451e+03	9.728018e-02	3.231962e+00	1.795283e+04	0	49	1.000000e+00
16	1.764396e+03	7.319026e-02	1.841572e+00	2.476484e+03	0	38	1.000000e+00
17	3.885446e+02	7.639441e-02	7.665249e-01	3.231558e+02	0	20	1.000000e+00
18	1.728629e-02	5.467312e-02	2.494701e+00	5.435186e-01	0	4	1.000000e+00
19	3.136152e+05	3.899562e-01	1.530927e+01	5.454267e+07	2	50	1.000000e+00
20	3.136152e+05	3.899562e-01	1.530927e+01	5.454267e+07	0	46	1.000000e+00

At some point it changes to:

iter	res_stat	res_eq		res_ineq	res_comp	qp_stat	qp_iter	alpha
0	5.098942e-05	7.806839e-06	3.333232e-01	4.590597e+00	0	0	0.000000e+00
1	7.012896e-06	1.478578e-07	0.000000e+00	2.765003e-03	0	3	1.000000e+00

Thanks Jannis

Hi Jannis,

I would increase both the maximum number of iterations for the QP solver as well as the maximum number of SQP iterations.

Ist the constraint satisfied for those problems for which you get status 0? If not, you need to tune the slack weights a bit. Do you set a linear or a quadratic penalty term, or both?

Best, Katrin