nmpc圆形轨迹跟踪C代码
时间: 2023-08-06 17:19:39 浏览: 82
C 代码 使用蒙特卡罗方法估计函数的积分 在 2D 圆形环形的内部annulus_monte_carlo.rar
以下是一个基于NMPC(非线性模型预测控制)的圆形轨迹跟踪的C代码示例:
```c
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "qpOASES.h"
#define NX 4 // 状态变量数
#define NU 2 // 控制变量数
#define N 20 // 预测步数
#define DT 0.1 // 时间间隔
using namespace Eigen;
USING_NAMESPACE_QPOASES
int main()
{
// 系统模型
Matrix<double, NX, NX> A;
A << 1, 0, DT, 0,
0, 1, 0, DT,
0, 0, 1, 0,
0, 0, 0, 1;
Matrix<double, NX, NU> B;
B << 0, 0,
0, 0,
DT, 0,
0, DT;
Matrix<double, NX, 1> x0; // 初始状态
x0 << 0, 0, 0, 0;
// 目标轨迹(圆形)
double r = 1.0; // 圆半径
double omega = 0.5; // 角速度
Matrix<double, N+1, 2> ref_traj;
for (int i = 0; i <= N; i++) {
double t = i * DT;
ref_traj(i, 0) = r * cos(omega * t);
ref_traj(i, 1) = r * sin(omega * t);
}
// NMPC控制器参数
double Q[NX] = {1, 1, 0, 0}; // 状态权重
double R[NU] = {0.1, 0.1}; // 控制权重
double QN[NX] = {10, 10, 0, 0}; // 终端状态权重
double x_lb[NX] = {-10, -10, -10, -10}; // 状态下限
double x_ub[NX] = {10, 10, 10, 10}; // 状态上限
double u_lb[NU] = {-5, -5}; // 控制下限
double u_ub[NU] = {5, 5}; // 控制上限
// QP求解器
SQProblem qp(NX, NU);
Options options;
options.printLevel = PL_NONE;
qp.setOptions(options);
// NMPC主循环
Matrix<double, NX, 1> x = x0;
for (int i = 0; i < N; i++) {
// 构造目标函数和约束
real_t H[NU*N*NU*N], g[NU*N], A[NX*N*NU*N], lb[NX*N*NU*N], ub[NX*N*NU*N];
for (int j = 0; j < N; j++) {
// 目标函数
for (int k = 0; k < NU; k++) {
for (int l = 0; l < NU; l++) {
if (j == N-1) // 终端权重
H[(j*NU+k)*NU+l] = QN[k*NU+l];
else
H[(j*NU+k)*NU+l] = R[k*NU+l];
}
g[j*NU+k] = 0;
if (j == N-1) // 终端状态目标
g[j*NU+k] -= QN[k] * ref_traj(j+1,k);
}
for (int k = 0; k < NX; k++) {
if (j == N-1) // 终端权重
H[(j*NU+k+NU*N)*(NU*N+1)/2-1] = QN[k];
else
H[(j*NU+k+NU*N)*(NU*N+1)/2-1] = 0;
}
// 约束
for (int k = 0; k < NU; k++) {
lb[j*NU+k] = u_lb[k];
ub[j*NU+k] = u_ub[k];
}
for (int k = 0; k < NX; k++) {
for (int l = 0; l < NU; l++) {
A[(j*NX+k)*NU+l] = 0;
for (int m = 0; m < NX; m++) {
if (j == N-1 && m == k) // 终端权重
A[(j*NX+k)*NU+l] += QN[m] * A(m,k);
else
A[(j*NX+k)*NU+l] += Q[m] * A(m,k);
}
for (int m = 0; m < NU; m++) {
if (l == m)
A[(j*NX+k)*NU+l] += R[m] * B(k,m);
}
}
lb[N*NU+j*NX+k] = x_lb[k] - x(k); // 状态约束
ub[N*NU+j*NX+k] = x_ub[k] - x(k);
if (j == N-1) // 终端状态目标
lb[N*NU+j*NX+k] = ub[N*NU+j*NX+k] = ref_traj(j+1,k);
else
lb[N*NU+j*NX+k] = ub[N*NU+j*NX+k] = 0;
}
}
// 求解QP
real_t xOpt[NU*N];
qp.init(H, g, A, NULL, NULL, lb, ub, N, 1);
int nWSR = 1000;
qp.hotstart(NULL, xOpt, NULL, NULL, NULL, NULL, NULL, &nWSR);
// 执行控制
Matrix<double, NU, 1> u(xOpt[0], xOpt[1]);
x = A * x + B * u;
printf("x = %.3f, %.3f, %.3f, %.3f, u = %.3f, %.3f\n",
x(0), x(1), x(2), x(3), u(0), u(1));
}
return 0;
}
```
该代码使用qpOASES库实现了NMPC控制器。其中,状态变量包括车辆位置和速度,控制变量为车辆加速度和转向角速度。系统模型为匀速直线行驶,圆形轨迹为目标轨迹。通过构造目标函数和约束,求解QP问题得到最优控制输入,执行控制并更新状态。
阅读全文