NMPC圆形轨迹跟踪C代码
时间: 2023-08-06 16:20:30 浏览: 160
以下是一个简单的NMPC控制器,用于将小车跟踪一个圆形轨迹。其中,小车的状态变量为x和y,控制变量为v和theta(车速和车头方向角度),轨迹参数为圆心坐标xc和yc,及半径r。该控制器使用了CasADi库来进行数学建模和求解。
```c
#include <casadi/casadi.hpp>
#include <iostream>
using namespace casadi;
int main()
{
// Define symbolic variables
SX x = SX::sym("x");
SX y = SX::sym("y");
SX v = SX::sym("v");
SX theta = SX::sym("theta");
// Define model and constraints
Function f = Function("f", {x, y, v, theta}, {v*cos(theta), v*sin(theta), 0, 0});
Function h = Function("h", {x, y}, {pow(x - xc, 2) + pow(y - yc, 2) - pow(r, 2)});
// Define optimization variables
SX xc = SX::sym("xc");
SX yc = SX::sym("yc");
SX r = SX::sym("r");
SX dt = SX::sym("dt");
SX p = SX::vertcat({xc, yc, r, dt});
SX u = SX::vertcat({v, theta});
SX n_states = 4;
SX n_controls = 2;
SX n_params = 4;
// Define cost function
SX L = pow(v, 2) + pow(theta, 2);
Function lag = Function("lag", {x, y, v, theta, xc, yc, r}, {L});
// Define NMPC problem
SXDict nlp = {{"x", SX::vertcat({x, y, v, theta})},
{"p", p},
{"f", f(x, y, v, theta)},
{"g", h(x, y)},
{"u", u},
{"lbg", 0},
{"ubg", 0},
{"lbx", SX::vertcat({-Inf, -Inf, 0, -Inf})},
{"ubx", SX::vertcat({Inf, Inf, Inf, Inf})},
{"p_min", SX::vertcat({-Inf, -Inf, 0, 0.1})},
{"p_max", SX::vertcat({Inf, Inf, Inf, 0.5})}
};
// Define solver and options
std::map<std::string, std::string> options;
options["ipopt.print_level"] = "0";
options["ipopt.max_iter"] = "100";
options["ipopt.tol"] = "1e-6";
options["ipopt.warm_start_init_point"] = "yes";
options["ipopt.warm_start_bound_push"] = "1e-8";
options["ipopt.warm_start_bound_frac"] = "1e-8";
options["ipopt.warm_start_slack_bound_frac"] = "1e-8";
options["ipopt.warm_start_slack_bound_push"] = "1e-8";
options["ipopt.mu_init"] = "1e-6";
options["ipopt.mu_strategy"] = "adaptive";
options["ipopt.hessian_approximation"] = "limited-memory";
options["ipopt.linear_solver"] = "ma57";
options["print_time"] = "0";
std::vector<SX> w0, lbw, ubw, lbg, ubg, p_min, p_max;
lbw = {0, 0, 0, -pi};
ubw = {0, 0, 1, pi};
w0 = {0, 0, 0.2, 0};
lbg = {0};
ubg = {0};
p_min = {-1, -1, 0, 0.1};
p_max = {1, 1, 1, 0.5};
// Create solver instance
Function nlp_fcn = Function("nlp_fcn", nlp);
nlpsol_solver nlpsol("nlpsol", "ipopt", nlp_fcn, options);
nlpsol.setInput("x0", w0);
nlpsol.setInput("lbx", lbw);
nlpsol.setInput("ubx", ubw);
nlpsol.setInput("lbg", lbg);
nlpsol.setInput("ubg", ubg);
nlpsol.setInput("p_min", p_min);
nlpsol.setInput("p_max", p_max);
// Loop over time steps
double t = 0;
double T = 10;
double dt_val = 0.1;
while (t < T) {
// Solve NMPC
nlpsol.setInput("x0", w0);
nlpsol.setInput("p", {xc_val, yc_val, r_val, dt_val});
nlpsol.evaluate();
std::vector<double> w_opt = nlpsol.getOutput("x").asVector();
std::vector<double> u_opt = {w_opt[2], w_opt[3]};
// Simulate system
std::vector<double> x_val = {w0[0], w0[1], w_opt[0], w_opt[1]};
std::vector<double> xdot_val = f(x_val, u_opt).asVector();
std::vector<double> x_next = {x_val[0] + xdot_val[0]*dt_val,
x_val[1] + xdot_val[1]*dt_val,
xdot_val[2],
xdot_val[3]};
// Update variables and time
w0 = {x_next[0], x_next[1], u_opt[0], u_opt[1]};
t += dt_val;
}
return 0;
}
```
此代码实现的是一个基于NMPC的控制器,用于将小车跟踪圆形轨迹。其中,控制器将小车当前状态和轨迹参数作为输入,然后基于数学模型求解控制变量,即车速和车头方向角度。该控制器的优化问题由一个非线性规划(NLP)问题描述,可以使用IPOPT求解器求解。通过在时间上循环执行此代码,可以实现小车沿圆形轨迹运动的目的。
阅读全文