Hello all,
First, thank you to all the people involved with this tool and the forum which has already been a great resource to resolve many of my issues.
Unfortunately I have not yet been able to find the answer for this particular issue. To clarify the question from the title:
Does acados support dynamic expressions where a state is multiplied by the input (decision variable), and if so, how? I think that this question sums up the issues I am having, and I’m starting off with this general question in case there is a quick and simple answer, but I’ll elaborate on the details with a reduced example below (apologies, it is a little lengthy still):
-
I am using the
Matlab
interface ofacados
, but installed just before the recent overhaul which brought the syntax in line with the Python version. -
The exact problem I encounter is that I would like to control an algebraic state,
z1
, to a reference value. This state is defined asz1 = u * x1
, which is the multiplication of the system input,u
, and a system state,x1
. Unfortunately, I can’t get that to work. (I am using the implicit dynamics mode, more details in point 4 below) -
Where I believe my problem comes from: The projected trajectory of the algebraic state,
z1
, acquired from the solved ocp does not match the defined system behavior. The trajectory after solving the ocp, which is acquired viaocp.get('z')
, does not match the trajectory that I can calculate by multiplying the inputs and states,u * x1
, acquired fromocp.get('u')
andocp.get('x')
. This plot shows the difference between the two.
Given that this projected trajectory ofz1
is incorrect, it is no surprise to me that tracking this to a reference value will not work well either. This is what leads me to ask whether such dynamics are even supported, or whether I am still setting something up incorrectly. Some additional points:
- The trajectories from
ocp.get('x')
are correct, as I have verified them by applying the input trajectory to an external model. - When the system is in a more constant state the error is significantly reduced
- Reducing the sampling time also reduces the error
From here on I will describe how I set up the solver:
- How I set up the ocp: I am using the implicit dynamics mode to specify the system dynamics as follows (in this case I’m using as a reduced example an averaged model of a DC/DC buck converter, where
z1
denotes the input current):
f_impl = vertcat(- x1_dot + u * (p1/p2) - x2 * (1/p2), ...
x1 * (1/p3) - x2 * (1/(p4*p3)) - x2_dot,...
z1 - (u * x1));
Where the states/inputs/params are defined as:
% // States
% // Differential States (x vector)
x1 = SX.sym('x1'); % // inductor current
x2 = SX.sym('x2'); % // capacitor voltage output
x = vertcat(x1, x2); % // state vector
% //algebraic states (z vector)
z1 = SX.sym('z1');
z = vertcat(z1);
% ///inputs
u = SX.sym('u'); % duty cycle input
% //state derivatives (x dot vector)
x1_dot = SX.sym('x1_dot'); % derivative of inductor current
x2_dot = SX.sym('x2_dot'); % derivative of capacitor voltage
x_dot = vertcat(x1_dot, x2_dot); % state derivative vector
% //system parameters (constants so no need for expressions)
% //p1, p2, p3, p4
- I initially set up the ocp with the linear least squares cost type to track
z1
to a reference value. When this wasn’t working I set it up to trackx2
to a reference value instead for troubleshooting. This is the case in the plot shown above in point 3.
- I have also tried to exclude
z1
altogether and track theu * x1
using the non-linear least squares cost module. While this does tend to reach the reference value in a step response eventually, I believe it suffers from a similar issue of incorrect projections, but I have not been able to verify this as I don’t believe there is access to the actual cost of an optimized decision, is there?
- Model and ocp settings were largely taken from the example
\acados\examples\acados_matlab_octave\pendulum_dae
. At first I simply replaced the dynamic equation and states but in troubleshooting I have since then attempted most different integrator and solver settings with no luck.
Thank you to anyone who takes the time to read this, I hope you can shed some light on the situation!
(PS. I thought I had seen whole matlab script files in other posts but I haven’t been able to find those again and I haven’t yet figured out how to do it myself. If anyone would like the full script of the example I use here please let me know how to upload that )