Hello !
In the vehicle longitudinal system dynamics modelling, I give the state quantity - velocity a variation constraint, but the output result is not output according to the constraint, the following is the constraint procedure I wrote, could please help me to guide.
since you have not described the problem formulation and the excepted result in detail, I can only guess. Have you considered that the variable t, that is passed to the constraint functions, is the internal prediction time of the MPC (ranging from 0 to Thor) and not the global simulation time (ranging from 0 to Tsim)? This is also described in the GRAMPC manual, see equations (3.1) and the following text on page 5. If you need the global time, you should pass grampc->param->t0 via userparam to the constraint functions and compute t+t0.
Another thing: If I interpret your code correctly, you have a time-varying maximum bound for the vehicle velocity. Having many if-else-decisions within the problem functions can increase the computational time. If that is an issue, you should precompute the bound for each discretization step in the horizon (see grampc->rws->t) outside of grampc_run and pass them via userparam to the constraint functions. You could have a look at the reactor CSTR MHE example, where a similar approach is used to pass the measured states to the cost functions.
Regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,Andreas Völz
Thank you for replying to me in your busy schedule, since I just started learning this software, I didn't express the problem clearly to you yesterday, as you said.
For the vehicle longitudinal dynamics, I want to implement a dynamic over time constraint added to the state quantity-velocity. I understand what you said yesterday about t0 and t, but when I pass t0 through useparam to the constraint equation, there seems to be an error, and I see in this posting that you go about passing t0 this way.I understand that trajparam[0] is a fixed value. And not changing from moment to moment.
~~~
typeRNum trajparam = (typeRNum)userparam;
typeRNum t0 = trajparam[0];
typeRNum* coeff = trajparam + 1;
typeRNum xref = coeff[0] * (t0 + t) * (t0 + t) + coeff[1] * (t0 + t) + coeff[2];
~~~
Maybe my question is too stupid, because I don't know enough about this.
The second problem is that I tried to first define a dynamic curve in %% Userparameter definition and pass it to the constraint equation, the result is still a fixed value. I may have misunderstood , Could you please provide me with a simple template?
Best Regards,
xiaolou
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Furthermore, in your MPC-loop (e.g. in startMPC.m) you have to update the value of userparam(1) (that is trajparam[0] in your C code) in each MPC step, e.g. something like
grampc.userparam(1) = grampc.param.t0
Regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello Andreas Völz,
Thank you very much for your patient guidance, I studied the MHE example carefully and finally solved all the problems I encountered.
Thank you again and I sincerely hope all the best things will come your way !
Best regards,
xiaolou
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have a new question that I need your guidance on, after your guidance I can run my program in matlab very well and I can get good results too.Now I need to use simulink to simulate in real time with a model I have built, but I can't update the changing constraint parameters I gave in useparament in real time in simulink, is it caused by updating t0 in MPC_loop in Startmpc.
Best regards,
xiaolou
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
userparam is an input to the MPC-subsystem (S-function), which allows to update the user parameters in each simulation step. The current time step t0 is generated by a clock, converted to the required data type and forwarded to the input tk of the MPC-subsystem. If t0 is the first element of your userparam vector, you can add a Vector Concatenate Block that combines t0 from the clock and userparam(2:end) and forwards this to the MPC-subsystem and the sysfct. An alternative would be to create your own block (.m of S-function) that generates the userparam vector.
Regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello Andreas Völz ,
Thank you for your patient reply, I've thought about your comment and I still don't understand it particularly well: create my own block (.m of S-function) to generate the userparam vector. Does that mean I need to rewrite the S-function myself with .m? Or do I write a separate constraint and pass it to init-userparam by calling the function and create a module in simulink to call this constraint function. Since I am using v2.2, there is a separate userparam interface in simulink.
~~~%% Userparameter definition % e.g. system parameters or weights for the cost functionpSys=[852,9.8,0.02,1.223,0.7,2,15,25,15,20];% system parameterspCost=[0.0005,150];% weightstime=user.param.t0;dt=user.param.dt;t0=0:0.1:300;% The accelerate ,velocity and distance of back car a_b=0.*(t0<=40)+0.01*(t0-40).*(t0>40&t0<=50)+0.1.*(t0>50&t0<=70)+(0.1-0.01*(t0-70)).*(t0>70&t0<=80)+0.*(t0>80&t0<=110)+(0-0.01*(t0-110)).*(t0>110&t0<=120)...+(-0.1).*(t0>120&t0<=130)+(-0.1+0.01*(t0-130)).*(t0>130&t0<=140)+0.*(t0>140&t0<=175)+0.03*(t0-175).*(t0>175&t0<=180)+0.15.*(t0>180&t0<=200)...+(0.15-0.03*(t0-200)).*(t0>200&t0<=205)+0.*(t0>205&t0<=245)+(0-0.03*(t0-245)).*(t0>245&t0<=250)-0.15.*(t0>250&t0<=260)+(-0.15+0.03*(t0-260)).*(t0>260&t0<=265)+0.*(t0>265);v_b1=cumtrapz(t0,a_b)+18;userparam=[pSys,pCost,time,dt,v_b1];
~~This is the constraint function I have in initdata and then passed to the cost function via a pointer.~
Best regards,
xiaolou
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
the initData-function should be the same for startMPC and for Simulink. I thought your problem was how to update the t0-entry within userparam in each time step of the Simulink simulation. Now, I'm not an expert in Simulink, but I thought it should be possible to manipulate the userparam vector directly in Simulink using Mux, Demux, and/or Concatenate Vector blocks. Alternatively, you could write a small block that calls e.g. an m-function that updates the userparam vector. It should definitely not be necessary to modify the MPC S-function of GRAMPC to achieve your goal.
Regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello Andreas Völz,
Thank you for your patient guidance, I followed your method and tried several times and finally it worked properly.Because I used two methods when I added the constraints, although now only for one of the methods to achieve in simulink userparam changes with time, but fully able to support my current needs, thanks again for your guidance. and I sincerely hope all the best things will come your way !
Best regards
xiao lou
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
thanks for reporting that you finally came up with a solution. However, I doubt that your description is detailed enough to help other GRAMPC users who face a similar problem. I guess that it would be more helpful if GRAMPC would include some examples with more advanced usecases that new users can use as starting points.
Regards,
Andreas Völz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello !
In the vehicle longitudinal system dynamics modelling, I give the state quantity - velocity a variation constraint, but the output result is not output according to the constraint, the following is the constraint procedure I wrote, could please help me to guide.
Best Regards,
xiaolou
Last edit: xiaolou 2021-05-16
Hello xiaolou,
since you have not described the problem formulation and the excepted result in detail, I can only guess. Have you considered that the variable
t
, that is passed to the constraint functions, is the internal prediction time of the MPC (ranging from 0 to Thor) and not the global simulation time (ranging from 0 to Tsim)? This is also described in the GRAMPC manual, see equations (3.1) and the following text on page 5. If you need the global time, you should pass grampc->param->t0 via userparam to the constraint functions and compute t+t0.Another thing: If I interpret your code correctly, you have a time-varying maximum bound for the vehicle velocity. Having many if-else-decisions within the problem functions can increase the computational time. If that is an issue, you should precompute the bound for each discretization step in the horizon (see grampc->rws->t) outside of grampc_run and pass them via userparam to the constraint functions. You could have a look at the reactor CSTR MHE example, where a similar approach is used to pass the measured states to the cost functions.
Regards,
Andreas Völz
Hello,Andreas Völz
Thank you for replying to me in your busy schedule, since I just started learning this software, I didn't express the problem clearly to you yesterday, as you said.
For the vehicle longitudinal dynamics, I want to implement a dynamic over time constraint added to the state quantity-velocity. I understand what you said yesterday about t0 and t, but when I pass t0 through useparam to the constraint equation, there seems to be an error, and I see in this posting that you go about passing t0 this way.I understand that trajparam[0] is a fixed value. And not changing from moment to moment.
~~~
typeRNum trajparam = (typeRNum)userparam;
typeRNum t0 = trajparam[0];
typeRNum* coeff = trajparam + 1;
typeRNum xref = coeff[0] * (t0 + t) * (t0 + t) + coeff[1] * (t0 + t) + coeff[2];
~~~
Maybe my question is too stupid, because I don't know enough about this.
The second problem is that I tried to first define a dynamic curve in %% Userparameter definition and pass it to the constraint equation, the result is still a fixed value. I may have misunderstood , Could you please provide me with a simple template?
Best Regards,
xiaolou
Hello xiaolou,
the error in your code is that you cast userparam to a typeRNum (usually double) although it should be a pointer to typeRNum, see the code below:
Furthermore, in your MPC-loop (e.g. in startMPC.m) you have to update the value of userparam(1) (that is trajparam[0] in your C code) in each MPC step, e.g. something like
Regards,
Andreas Völz
Hello Andreas Völz,
Thank you very much for your patient guidance, I studied the MHE example carefully and finally solved all the problems I encountered.
Thank you again and I sincerely hope all the best things will come your way !
Best regards,
xiaolou
Hello xiaolou,
nice to hear that you could solve your problem. If you need further help in implementing or tuning the performance of your MPC, please ask.
Kind regards,
Andreas Völz
Hello Andreas Völz ,
I have a new question that I need your guidance on, after your guidance I can run my program in matlab very well and I can get good results too.Now I need to use simulink to simulate in real time with a model I have built, but I can't update the changing constraint parameters I gave in useparament in real time in simulink, is it caused by updating t0 in MPC_loop in Startmpc.
Best regards,
xiaolou
Hello xiaolou,
userparam is an input to the MPC-subsystem (S-function), which allows to update the user parameters in each simulation step. The current time step t0 is generated by a clock, converted to the required data type and forwarded to the input tk of the MPC-subsystem. If t0 is the first element of your userparam vector, you can add a Vector Concatenate Block that combines t0 from the clock and userparam(2:end) and forwards this to the MPC-subsystem and the sysfct. An alternative would be to create your own block (.m of S-function) that generates the userparam vector.
Regards,
Andreas Völz
Hello Andreas Völz ,
Thank you for your patient reply, I've thought about your comment and I still don't understand it particularly well: create my own block (.m of S-function) to generate the userparam vector. Does that mean I need to rewrite the S-function myself with .m? Or do I write a separate constraint and pass it to init-userparam by calling the function and create a module in simulink to call this constraint function. Since I am using v2.2, there is a separate userparam interface in simulink.
~~This is the constraint function I have in initdata and then passed to the cost function via a pointer.~
Best regards,
xiaolou
Hello xiaolou,
the initData-function should be the same for startMPC and for Simulink. I thought your problem was how to update the t0-entry within userparam in each time step of the Simulink simulation. Now, I'm not an expert in Simulink, but I thought it should be possible to manipulate the userparam vector directly in Simulink using Mux, Demux, and/or Concatenate Vector blocks. Alternatively, you could write a small block that calls e.g. an m-function that updates the userparam vector. It should definitely not be necessary to modify the MPC S-function of GRAMPC to achieve your goal.
Regards,
Andreas Völz
Hello Andreas Völz,
Thank you for your patient guidance, I followed your method and tried several times and finally it worked properly.Because I used two methods when I added the constraints, although now only for one of the methods to achieve in simulink userparam changes with time, but fully able to support my current needs, thanks again for your guidance. and I sincerely hope all the best things will come your way !
Best regards
xiao lou
Hello xiaolou,
thanks for reporting that you finally came up with a solution. However, I doubt that your description is detailed enough to help other GRAMPC users who face a similar problem. I guess that it would be more helpful if GRAMPC would include some examples with more advanced usecases that new users can use as starting points.
Regards,
Andreas Völz