I'm trying to use the code generation tool to optimize my MPC. The code below is a simplified example of my MPC. When running the code generation and compiling the optimized result it seems to be no response in the control r. I tried to run the code, as it is, without code generation to see if there were response in the control r. The code run smoothly and worked perfectly. I guess there is something wrong with my LSQ implementation.
I updated ACADO to latest stable release and now it works. However I do not want to use the minimizeLSQEndTerm since it violates my constraints. I want to use
Function h;
h << sqrt((x-300)*(x-300) + (y-300)*(y-300))-300;
Matrix Q = eye(h.getDim());
Q *=10;
ocp.minimizeLSQ ( Q,h );
However, running this results in an error: "Only standard LSQ objective supported for code generation"
When using
Function h;
Function hN;
h << sqrt((x-300)*(x-300) + (y-300)*(y-300))-300;
h << r;
hN << sqrt((x-300)*(x-300) + (y-300)*(y-300)-300);
Matrix Q = eye(h.getDim());
Q *=10; Matrix QN = eye(hN.getDim()); QN *=10;
ocp.minimizeLSQ ( Q,h );
ocp.minimizeLSQEndTerm(QN, hN);
In the MPC problem it is not certain that the control objective is reached in one horizon. Thus specifying an end term would not be the perfect choice...
Any suggestions?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Espen,
I have few comments on your problem that hopefully may help you:
1- in your system model, I guess you can avoid using
f << dot(nu_x) == 0;
f << dot(nu_y) == 0;
because this means that these two variables are basically constants. That's why you are getting the 3rd and the 4th columns of (Differential variables:) as constants.
2- I believe that you are using a differential drive robot model in your problem formulation, and you use nu_x and nu_y as the velocities in x-direction and y-direction, respectively. So, why are you are putting them as just constants where in fact they are also control inputs. So, I would imagine your problem formulation to be something like:
// DEFINE THE VARIABLES:// ----------------------------------------------------------DifferentialStatex;DifferentialStatey;DifferentialStatenu_x;DifferentialStatenu_y;DifferentialStatepsi;Controlr;Controla_x;// acceleration in x-directionControla_y;// acceleration in y-direction// DEFINE THE MODEL EQUATIONS:// ----------------------------------------------------------DifferentialEquationf;f<<dot(x)==nu_x*cos(psi)-nu_y*sin(psi);f<<dot(y)==nu_x*sin(psi)+nu_y*cos(psi);f<<dot(nu_x)==a_x;f<<dot(nu_y)==a_y;f<<dot(psi)==r;
3- you are using a prediction horizon of length
OCP ocp( 0.0,20.0, 19 );
and based on that, your time step is basically (20/19 = 1.05 seconds). I guess this is a quite long update step for your system.
4- in case you want to eliminate the use of a terminal cost function, you can try
hN <<0;
You are simply putting zero in this function.
If you think that I am missing anything in my comments just ignore them.
Best Regards,
Mohamed
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you for your answer. I actually do not control the velocities nu_x and nu_y. Basically what I am doing is feeding waypoints (x,y) calculated by the MPC to a lower level autopilot in order to control an UAV. The UAV is flying by the (measured) velocities nu_x and nu_y (which for now are assumed to be constant). The only control is psi, which determines the UAV's heading. I have also included a to-axis gimbal system in the UAV where I control the gimbal's pan and tilt rates, which means that I have DifferentialState for pan and tilt angles together with Controls for pan and tilt rate. The only thing left in the implementation process is to make an optimized solution with the code generation tool. The issue, which I realized when running the optimized code is that the control r's constraint is violated (-0.1<=r<=0.1), which is not good at all. The UAV has a roll angle given by phi = 5*sin(-r). Since the maximal turn rate is given by the maximum roll angle of about 30 degrees, the solution (print of control r above) is not good at all.
The gimbal's camera is used to find objects with a camera vision tool, and the objects' coordinates are fed to the MPC. The MPC uses the objects' coordinates to calculate gimbal angles and waypoints.
I'll try your solution and hope for the best. Thanks! :-)
Last edit: Espen Skjong 2014-01-30
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The auto-generated .c file with initialization is given as:
#include "acado_common.h"#include "acado_auxiliary_functions.h"#include <stdio.h>#include <string.h>/*Someconvenientdefinitions.*/#define NX ACADO_NX /* Number of differential state variables. */#define NXA ACADO_NXA /* Number of algebraic variables. */#define NU ACADO_NU /* Number of control inputs. */#define NP ACADO_NP /* Number of parameters. */#define NY ACADO_NY /* Number of measurements/references on nodes 0..N - 1. */#define NYN ACADO_NYN /* Number of measurements/references on node N. */#define N ACADO_N /* Number of intervals in the horizon. */#define NUM_STEPS 10 /* Number of real-time iterations. */#define VERBOSE 1 /* Show iterations: 1, silent: 0. *//*Globalvariablesusedbythesolver.*/ACADOvariablesacadoVariables;ACADOworkspaceacadoWorkspace;/*Atemplatefortestingofthesolver.*/intmain(){/*Sometemporaryvariables.*/inti,iter;timert;/*Clearsolvermemory.*/memset(&acadoWorkspace,0,sizeof(acadoWorkspace));memset(&acadoVariables,0,sizeof(acadoVariables));/*Initializethesolver.*/initializeSolver();/*Initializethestatesandcontrols.*/for(i=0;i<NX*(N+1);++i)acadoVariables.x[i]=0.0;for(i=0;i<NU*N;++i)acadoVariables.u[i]=0.0;/*Initializethemeasurements/reference.*/for(i=0;i<NY*N;++i)acadoVariables.y[i]=0.0;for(i=0;i<NYN;++i)acadoVariables.yN[i]=0.0;/*MPC:initializethecurrentstatefeedback.*/#if ACADO_INITIAL_STATE_FIXEDfor(i=0;i<NX;++i)acadoVariables.x0[i]=0;acadoVariables.x0[0]=-0;//xacadoVariables.x0[1]=-10;//yacadoVariables.x0[2]=0;//nu_xacadoVariables.x0[3]=10;//nu_yacadoVariables.x0[4]=0;//psi#endifif(VERBOSE)printHeader();/*Preparefirststep*/preparationStep();/*Getthetimebeforestartoftheloop.*/tic(&t);/*The"real-time iterations"loop.*/for(iter=0;iter<NUM_STEPS;++iter){/*Performthefeedbackstep.*/feedbackStep();/*Applythenewcontrolimmediatelytotheprocess,firstNUcomponents.*/if(VERBOSE)printf("\tReal-Time Iteration %d: KKT Tolerance = %.3e\n\n",iter,getKKT());/*Optional:shifttheinitialization(lookatacado_common.h).*//*shiftStates(2,0,0);*//*shiftControls(0);*//*Prepareforthenextstep.*/preparationStep();}/*Readtheelapsedtime.*/real_tte=toc(&t);if(VERBOSE)printf("\n\nEnd of the RTI loop. \n\n\n");/*Eye-candy.*/if(!VERBOSE)printf("\n\n Average time of one real-time iteration: %.3g microseconds\n\n",1e6*te/NUM_STEPS);printDifferentialVariables();printControlVariables();return0;}
What I want is to make the UAV circle around a stationary point given by (300,300) with a circle radius of 300. The results from running the code is
Is there a magic trick that has to be performed to make the optimized code run as I want? Without optimization (not using the code generator) the MPC works like a charm, however faster computation cycles would be preferred.
Thanks in advance.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Espen,
I guess that the way the cost function (h) is defined in your problem formulation is misleading, i.e. if the definition of h is for the sake of a circular trajectory tracking, this is in fact not the right way to define it.
defining the reference is done basically by setting the values of
1) Check the manual
2) Examine the example in the tutorial section.
In short, you do not specify ||h - y||_Q^2 in the function h, but only function h. The actual reference is provided in the generated code, as Mohamed pointed out.
Check your ODE def once again. Are you sure you want to keep waypoints (references) as a part of the model?
Regards,
Milan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
I'm trying to use the code generation tool to optimize my MPC. The code below is a simplified example of my MPC. When running the code generation and compiling the optimized result it seems to be no response in the control r. I tried to run the code, as it is, without code generation to see if there were response in the control r. The code run smoothly and worked perfectly. I guess there is something wrong with my LSQ implementation.
}
The generated main file (with initial values) is given by
Does anyone see something wrong with my implementation and have a solution to my problem?
I tried to run the getting_started example (code generation) where the LSQ was implemented as
I don't get it...
Hi, which version of ACADO are you running? Cheers, Milan
I think it is Version 3, 29 June 2007.
Hi Milan,
I updated ACADO to latest stable release and now it works. However I do not want to use the minimizeLSQEndTerm since it violates my constraints. I want to use
However, running this results in an error: "Only standard LSQ objective supported for code generation"
When using
The control r violates it's boundaries given by
The output is then
In the MPC problem it is not certain that the control objective is reached in one horizon. Thus specifying an end term would not be the perfect choice...
Any suggestions?
Hi Espen,
I have few comments on your problem that hopefully may help you:
1- in your system model, I guess you can avoid using
because this means that these two variables are basically constants. That's why you are getting the 3rd and the 4th columns of (Differential variables:) as constants.
2- I believe that you are using a differential drive robot model in your problem formulation, and you use nu_x and nu_y as the velocities in x-direction and y-direction, respectively. So, why are you are putting them as just constants where in fact they are also control inputs. So, I would imagine your problem formulation to be something like:
3- you are using a prediction horizon of length
and based on that, your time step is basically (20/19 = 1.05 seconds). I guess this is a quite long update step for your system.
4- in case you want to eliminate the use of a terminal cost function, you can try
You are simply putting zero in this function.
If you think that I am missing anything in my comments just ignore them.
Best Regards,
Mohamed
Hi Mohamed,
Thank you for your answer. I actually do not control the velocities nu_x and nu_y. Basically what I am doing is feeding waypoints (x,y) calculated by the MPC to a lower level autopilot in order to control an UAV. The UAV is flying by the (measured) velocities nu_x and nu_y (which for now are assumed to be constant). The only control is psi, which determines the UAV's heading. I have also included a to-axis gimbal system in the UAV where I control the gimbal's pan and tilt rates, which means that I have DifferentialState for pan and tilt angles together with Controls for pan and tilt rate. The only thing left in the implementation process is to make an optimized solution with the code generation tool. The issue, which I realized when running the optimized code is that the control r's constraint is violated (-0.1<=r<=0.1), which is not good at all. The UAV has a roll angle given by phi = 5*sin(-r). Since the maximal turn rate is given by the maximum roll angle of about 30 degrees, the solution (print of control r above) is not good at all.
The gimbal's camera is used to find objects with a camera vision tool, and the objects' coordinates are fed to the MPC. The MPC uses the objects' coordinates to calculate gimbal angles and waypoints.
I'll try your solution and hope for the best. Thanks! :-)
Last edit: Espen Skjong 2014-01-30
It seems to be something wrong with the LSQ implementation. I'll give the full code example below:
The auto-generated .c file with initialization is given as:
What I want is to make the UAV circle around a stationary point given by (300,300) with a circle radius of 300. The results from running the code is
Is there a magic trick that has to be performed to make the optimized code run as I want? Without optimization (not using the code generator) the MPC works like a charm, however faster computation cycles would be preferred.
Thanks in advance.
Hi Espen,
I guess that the way the cost function (h) is defined in your problem formulation is misleading, i.e. if the definition of h is for the sake of a circular trajectory tracking, this is in fact not the right way to define it.
defining the reference is done basically by setting the values of
in the generated code.
You better look at this tutorial and it will show you how to do that.
http://acado.sourceforge.net/doc/html/db/daf/cgt_getting_started.html
Regards,
Mohamed
Hi,
Mohamed is right.
1) Check the manual
2) Examine the example in the tutorial section.
In short, you do not specify ||h - y||_Q^2 in the function h, but only function h. The actual reference is provided in the generated code, as Mohamed pointed out.
Check your ODE def once again. Are you sure you want to keep waypoints (references) as a part of the model?
Regards,
Milan