candi4 / ACADO

How to use ACADO
1 stars 0 forks source link

what is the difference of defining two types of DifferentialState? #2

Open yaofulan opened 2 months ago

yaofulan commented 2 months ago

Hi, in your code, I see two types of DifferentialState, one is to define x, y, theta, and another includes the x_dot, y_dot, theta_dot, I wonder which one achieves better performance and why to add x_dot, y_dot, theta_dot? Thank you!

candi4 commented 2 months ago

ACADO solves optimal control problems, which need system dynamics. In the code, the system dynamics is a differential equation. dot means time differential, e.g., theta_dot is an angular velocity.

yaofulan commented 2 months ago

ACADO solves optimal control problems, which need system dynamics. In the code, the system dynamics is a differential equation. dot means time differential i.e. theta_dot is an angular velocity.

I am really excited to receive your reply. Yes, I understand what you mentioned. You misunderstood my point. What I want to ask is that in this repo, some code generation defines the state with only x, y, and theta, while others additionally include their derivatives. Which one did you ultimately choose and which performance better? Additionally, I would like to ask why we manually define the state update function update_RK4 and the MPC solver function runAcado. In the ACADO tutorial, state and control updates can be set using acado_shiftStates(2, 0, 0); and acado_shiftControls(0);

candi4 commented 2 months ago

Now I understand your question. Could you show me the code that doesn't have x_dot, y_dot, and theta_dot in my repo? I want to make sure which code you're looking at.

RK4 is simple enough to write the code, so I didn't use ACADO's. acado_shiftStates and acado_shiftControls merely shift the values; they do not solve optimal control problems.

yaofulan commented 2 months ago

Now I understand your question. Could you show me the code that doesn't have x_dot, y_dot, and theta_dot in my repo? I want to make sure which code you're looking at.

RK4 is simple enough to write the code, so I didn't use ACADO's. acado_shiftStates and acado_shiftControls merely shift the values; they do not solve optimal control problems.

of course, here is the code"https://github.com/candi4/ACADO/blob/main/example/planar_drone_ACADO/prob2_codegen.cpp".

Additionally, we call "acado_preparationStep" and "acado_feedbackStep" to solve the ocp. "acado_shiftStates" and "acado_shiftControls" merely shift the values, so the states and controls can be shifted by call them, why do you manually difine the "planar_drone_dnm" and "update_RK4" to get the next state, it can be solved by calling "acado_shiftStates, acado_shiftControls". Thank you!

yaofulan commented 2 months ago

I would like to ask you another question and hope to get your help. When I call the custom-generated MPC solver, I set up a loop to solve multiple times due to insufficient precision, aiming to reduce the KKT (the smaller the KKT, the closer to convergence). During different loop iterations, acado_getKKT() does decrease, but the control input u remains the same. Do you know the specific reason for this? Below is the code and the output, I would greatly appreciate it if you could help me!

real_t* u; for (i = 0; i < 3; i++) { acado_preparationStep(); status = acado_feedbackStep(); u = acado_getVariablesU(); // Why is the control input the same in different iterations, while the output of acado_getKKT() is different? cout << u[0] << " " << u[1] << " " << u[2] << " " << u[3] << " " << u[4] << " " << u[5] << "i: " << i << endl; printf("\tReal-Time Iteration %d: KKT Tolerance = %.3e\n\n", iter, acado_getKKT()); cout << endl; }

the output: -0.0224341 0.113729 -0.0049196 0.254814 0.126724 -0.18046 i: 0 KKT Tolerance = 2.247e+01 -0.0224341 0.113729 -0.0049196 0.254814 0.126724 -0.18046 i: 1 KKT Tolerance = 5.753e-15 -0.0224341 0.113729 -0.0049196 0.254814 0.126724 -0.18046 i: 2 KKT Tolerance = 1.149e-15

candi4 commented 2 months ago

https://github.com/candi4/ACADO/blob/bfdb0d6a4ac20415deed1a5c81a783f7a5349699/example/planar_drone_ACADO/prob2_codegen.cpp#L46-L48 https://github.com/candi4/ACADO/blob/bfdb0d6a4ac20415deed1a5c81a783f7a5349699/example/planar_drone_ACADO/planar_drone_codegen.cpp#L52-L57 The system dynamics of the second code has the second derivatives of x, y, and theta. So I defined x_dot, y_dot, and theta_dot. I didn't check if dot(dot(x)) works.

Additionally, we call "acado_preparationStep" and "acado_feedbackStep" to solve the ocp. "acado_shiftStates" and "acado_shiftControls" merely shift the values, so the states and controls can be shifted by call them, why do you manually difine the "planar_drone_dnm" and "update_RK4" to get the next state, it can be solved by calling "acado_shiftStates, acado_shiftControls". Thank you!

I just wrote the code using ACADO functions as minimally as possible because I'm not familiar with ACADO. Thank you for letting me know acado_preparationStep and acado_feedbackStep.

yaofulan commented 2 months ago

Thank you! I am new to ACADO too, still struggling.

candi4 commented 2 months ago

real_t* u; for (i = 0; i < 3; i++) { acado_preparationStep(); status = acado_feedbackStep(); u = acado_getVariablesU(); // Why is the control input the same in different iterations, while the output of acado_getKKT() is different? cout << u[0] << " " << u[1] << " " << u[2] << " " << u[3] << " " << u[4] << " " << u[5] << "i: " << i << endl; printf("\tReal-Time Iteration %d: KKT Tolerance = %.3e\n\n", iter, acado_getKKT()); cout << endl; }

I think there is no function for updating input. acado_getVariablesU is just for getting the input value, not updating. Therefore the value of u doesn't change.

/** Get pointer to the matrix with control variables. */
real_t* acado_getVariablesU( );

https://github.com/uzh-rpg/rpg_mpc/blob/33263db209105f716e204acc6481834fbd9bc778/model/quadrotor_mpc_codegen/acado_auxiliary_functions.h#L35-L36

yaofulan commented 2 months ago

real_t* u; for (i = 0; i < 3; i++) { acado_preparationStep(); status = acado_feedbackStep(); u = acado_getVariablesU(); // Why is the control input the same in different iterations, while the output of acado_getKKT() is different? cout << u[0] << " " << u[1] << " " << u[2] << " " << u[3] << " " << u[4] << " " << u[5] << "i: " << i << endl; printf("\tReal-Time Iteration %d: KKT Tolerance = %.3e\n\n", iter, acado_getKKT()); cout << endl; }

I think there is no function for updating input. acado_getVariablesU is just for getting the input value, not updating. Therefore the value of u doesn't change.

/** Get pointer to the matrix with control variables. */
real_t* acado_getVariablesU( );

https://github.com/uzh-rpg/rpg_mpc/blob/33263db209105f716e204acc6481834fbd9bc778/model/quadrotor_mpc_codegen/acado_auxiliary_functions.h#L35-L36

Thank you, I will have a try to update it! Thank you for your time, Thank you! Wishing you success in your studies and progress in your career!