基于ROS的无人车模型预测控制(MPC)C++实现

2023-11-04

基于ROS的无人车模型预测控制(MPC)C++实现

最近在做毕业设计的控制器部分,网上关于cpp实现模型预测控制的资料很少,基本都是Matlab/Simulink实现,顺手写一下学习过程。

1.建模方法

模型预测控制的基本原理本文不作赘述,可以参考:
DandD的模型预测控制轨迹跟踪的教学视频
Dr. CAN的模型预测控制原理教学视频

本文采用差速小车模型进行建模:
e ( k + 1 ) = A e ( k ) + B u ( k ) e(k+1)=Ae(k)+Bu(k) e(k+1)=Ae(k)+Bu(k)
其中:
e ( k ) = [ e x e y e ϕ ] e(k)=\begin{bmatrix} e_x \\ e_y\\ e_\phi \end{bmatrix} e(k)= exeyeϕ A = [ 1 0 − T V r sin ⁡ ϕ r 0 1 T V r cos ⁡ ϕ r 0 0 1 ] A=\begin{bmatrix} 1 & 0 & -TV_r\sin\phi_r\\ 0 & 1 & TV_r\cos\phi_r\\ 0 & 0 &1 \end{bmatrix} A= 100010TVrsinϕrTVrcosϕr1 B = [ T cos ⁡ ϕ r 0 T sin ⁡ ϕ r 0 0 T ] B=\begin{bmatrix} T\cos\phi_r & 0\\ T\sin\phi_r & 0\\ 0 & T \end{bmatrix} B= TcosϕrTsinϕr000T
其中 e x e_x ex e y e_y ey e ϕ e_\phi eϕ 为横向、纵向、偏航角方向的误差 , V r V_r Vr为参考纵向速度, T T T为采样时间, v v v为小车纵向速度, ω \omega ω为小车的横摆角速度。(阿克曼模型的车辆可以参考前面两个视频的建模方法,差别不大)

2.求解器选择及配置

这次选用的是Gurobi作为MPC中二次规划问题的求解器,优异的求解速度完全可以胜任MPC的底层求解任务,学生和老师还可以在官网申请免费的许可证。Gurobi的安装和配置以及C++接口配置请参考我的前两篇博客。

3.实现过程

try{
        GRBEnv env = GRBEnv(true);  //初始化求解器
        env.start();    //激活求解器
        GRBModel model = GRBModel(env);   //建立求解模型
        GRBVar V[N_P+1],OMEGA[N_P+1];     //创建变量纵向速度 角速度
        for(int i=0; i<=N_P; i++){        //在模型中添加变量并设置约束
            std::ostringstream vname1, vname2;
            vname1<<"v"<<i;
            vname2<<"omega"<<i;
            V[i] = model.addVar(0,max_velocity,0.0,GRB_CONTINUOUS,vname1.str());
            OMEGA[i] = model.addVar(-max_palstance,max_palstance,0.0,GRB_CONTINUOUS,vname2.str());
        }
        std::vector<double> phi_r(N_P);
        phi_r = get_phi_reference();			//计算未来N_P个周期的参考偏航角
        GRBLinExpr X_ERROR[N_P+1];      //创建状态变量
        GRBLinExpr Y_ERROR[N_P+1];
        GRBLinExpr PHI_ERROR[N_P+1];
        X_ERROR[0] = error.x_e;
        Y_ERROR[0] = error.y_e;
        PHI_ERROR[0] = error.phi_e;
        for(int i=0; i<N_P ;i++){      //创建状态迭代方程
            X_ERROR[i+1]=X_ERROR[i]-T*V_R*sin(phi_r[i])*PHI_ERROR[i]+T*cos(phi_r[i])*V[i];
            Y_ERROR[i+1]=Y_ERROR[i]+T*V_R*cos(phi_r[i])*PHI_ERROR[i]+T*sin(phi_r[i])*V[i];
            PHI_ERROR[i+1]=PHI_ERROR[i]+T*OMEGA[i];
        }
        GRBQuadExpr obj = 0;    //创建优化目标值
        for(int i=0; i<=N_P; i++){
            obj+=K[0]*X_ERROR[i]*X_ERROR[i]+K[1]*Y_ERROR[i]*Y_ERROR[i]+K[2]*PHI_ERROR[i]*PHI_ERROR[i];  //优化误差目标值
            obj+=K[3]*(V[i]-V_R)*(V[i]-V_R)+K[4]*OMEGA[i]*OMEGA[i];
        }
        model.setObjective(obj,GRB_MINIMIZE);   //将优化目标值添加进模型
        model.optimize();   //求解
        result.velocity = V[0].get(GRB_DoubleAttr_X);   //MPC仅使用第一个输出量
        result.palstance = OMEGA[0].get(GRB_DoubleAttr_X);
    }   catch(GRBException e){
            std::cout<<"Error code:"<<e.getErrorCode()<<std::endl;
            std::cout<<e.getMessage()<<std::endl;
    }
        catch (...){
            std::cout << "Exception during optimization" << std::endl;
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于ROS的无人车模型预测控制(MPC)C++实现 的相关文章

  • 与 MinGW 的静态和动态/共享链接

    我想从一个简单的链接用法开始来解释我的问题 假设有一个图书馆z它可以编译为共享库 libz dll D libs z shared libz dll 或静态库 libz a D libs z static libz a 让我想要链接它 然后
  • 并行运行多个任务

    我有一个代理列表 每个代理都会访问不同的站点并从站点中提取所需的数据 目前它一次只做一个 但我希望同时运行 10 20 个任务 这样它就可以一次性从 20 个站点下载 而不是只下载一个 这是我目前正在做的事情 private async T
  • 如何以编程方式删除受信任的根证书颁发机构中的证书?

    我需要能够从组织中的每台电脑中删除特定的证书 是的 我可以逐个座位 但我要到周四才能完成 而且我没有人力逐个座位 是否有使用 C 的编程方式来执行此操作 我认为你不需要编写任何 C 看看certmgr exe del http msdn m
  • 获取列表框中视图中的项目

    我有一个 ListBox 其属性 VirtualizingStackPanel VirtualizationMode 设置为 回收 我正在绑定一个自定义集合 实现IList and IList
  • 如何在 Linux 上重新实现(或包装)系统调用函数?

    假设我想完全接管 open 系统调用 也许要包装实际的系统调用并执行一些日志记录 一种方法是使用 LD PRELOAD http scaryreasoner wordpress com 2007 11 17 using ld preload
  • 在 C# 中解析 JS Date.toIsoString

    我需要将 JS 日期存储为 ISO 8601 日期 我目前正在从格式为 2019 06 22T00 00 00 000Z 的表单中获取日期 正如 JS 的 toIsoString 方法所期望的那样 当这个日期传递到我的 API 控制器时 我
  • C# 结构默认值

    我有一个方法 它接受一个包含许多具有基本数据类型的字段的结构 我想传递大部分默认值 但需要进行一些调整 但我了解结构声明中的基本字段不能包含默认值声明 例如struct S int a 42 现在是这样的 OptionsStruct opt
  • 维护 VS Test Project 中单元测试方法之间的上下文

    我想按顺序运行以下单元测试 使用随机数字的名称 密码等创建新客户 检索刚刚创建的客户并断言其属性包含相同的随机数 对同一用户调用 ForgotPassword 函数 并使用相同的随机数作为用户名 清楚地看到 我需要生成一次随机数 并在 3
  • 加载 QPixmap 数据的更好方法

    更好的方法来做到这一点 没有QImage QImage image width height QImage Format RGB888 memcpy image bits m frameRGB gt data 0 height width
  • 公交车公共交通算法

    我正在开发一个可以查找公交路线的离线 C 应用程序 我可以提取时间表 巴士 路线数据 我正在寻找适用于基本数据的最简单的解决方案 可以使用什么算法来查找从巴士站 A 到巴士站 B 的路线 是否有适用于 C Java 的开源解决方案 数据库的
  • X 轴和 Z 轴上的 Quaternion.Slerp,无 Y 轴

    I am trying to rotate the Player about X Y and Z axis The Y axis should not move from last angle Example if I rotate 45
  • C# 可以为控制台应用程序部分类“程序”类吗?

    我想知道是否可以将为任何控制台应用程序创建的默认 程序 类更改为部分类 我想这样做是因为我想要更好的组织 而不是将所有方法都放在按区域分类的 1 个文件中 对我来说 将某些方法类别放在单独的文件中会更有意义 我对分部类的理解是 它是多个文件
  • 如何在Windows窗体中打开进程

    我想在我的 Windows 窗体应用程序中打开进程 例如 我希望当用户按下 Windows 窗体容器之一中的按钮时 mstsc exe 将打开 如果他按下按钮 它将在另一个容器上打开 IE DllImport user32 dll SetL
  • 从单应性估计 R/T

    我一直在尝试计算 2 个图像中的特征 然后将这些特征传递回CameraParams R没有运气 特征已成功计算并匹配 但是问题是将它们传递回R t 我明白你必须分解Homography为了使这一点成为可能 我已经使用如下方法完成了 http
  • 在 Visual Studio 2012 Express 中设置 C++ 调试环境

    我需要调试的应用程序需要设置环境变量 这在 Visual Studio 2012 中似乎非常复杂 我想做类似的事情 set path c foo c bar c windows c program files application set
  • 为什么我可以在另一个函数中定义一个函数?

    请参阅下面的代码 我在另一个函数中定义了一个函数 void test1 void void test2 void printf test2 n printf test1 n int main void test1 return 0 这个用法
  • 查找数组中的多个索引

    假设我有一个像这样的数组 string fruits watermelon apple apple kiwi pear banana 是否有一个内置函数可以让我查询 apple 的所有索引 例如 fruits FindAllIndex ap
  • 如何防止 Lotus Notes 用户转发或复制通过 System.Net.Mail 发送的邮件?

    我想使用 SMTP 客户端 uiing microsft net 以 C 作为编程语言发送电子邮件 但是对于通过SMTP客户端发送的电子邮件 我们是否可以添加 禁止转发 或 禁止复制 等安全功能 我不希望电子邮件的收件人转发或复制电子邮件的
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • 稀疏矩阵超定线性方程组c/c++库

    我需要一个库来解决 Ax b 系统 其中 A 是一个非对称稀疏矩阵 每行有 8 个条目 而且可能很大 我认为实现双共轭梯度的库应该没问题 但我找不到一个有效的库 我尝试过 iml 但 iml sparselib 包中缺少一些标头 有小费吗

随机推荐

  • 给两个四元数,如何生成一个四元数轨迹,让四元数转化成的旋转矩阵轨迹可微

    假设给定两个四元数 q1 和 q2 它们定义了从初始位置到结束位置的旋转 要生成四元数轨迹 可以考虑使用四元数球面线性插值 SLERP 具体步骤如下 1 标准化 q1 和 q2 确保它们都是单位四元数 2 计算 q1 和 q2 之间的夹角
  • 嵌入式系统之cyber-physical system

    嵌入式系统在生活中随处可见 之前的嵌入式做法一般都是在一些现成的板子上移植linux做一些剪切加一些传感器写一些设备驱动 都是随着时代的发展 嵌入式不再是之前大家认为的那种单片机原理 其实现在很多人都把搞单片机弄的那一套认为是嵌入式 当然业
  • ViewPager两种方式实现无限轮播

    给自己的忠告 虽然轮子很好用 但是使用轮子的前提是 如果不去封装一些复杂的功能 自己会用最基本的方法写一个 不然再好的轮子那也是别人的 当自己项目遇到和轮子不一样的地方 那就只能束手无策或者改人家的源码 当然能看懂轮子的封装思想自己学以致用
  • 为什么超过500万开发者选择了ASP.NET Core?

    目录 一 What ASP NET Core 二 Why ASP NET Core 三 为什么选择这项技术 四 ASP NET Core的优势具体可以梳理为以下几个方面 1 生成Web UI 和Web API的统一场景 2 Blazor 3
  • XX系统部署结构图

  • leetcode 26. 删除有序数组中的重复项

    给你一个 升序排列 的数组 nums 请你 原地 删除重复出现的元素 使每个元素 只出现一次 返回删除后数组的新长度 元素的 相对顺序 应该保持 一致 然后返回 nums 中唯一元素的个数 考虑 nums 的唯一元素的数量为 k 你需要做以
  • 扫码支付自动跳转(以上传一个压缩包到某种网盘或者可以下载的地址等让人付费解压为例)

    1 你有一个比较有用的资源A zip文件 2 做一个很简单的首页网页B并命名为解压码 html文件
  • FasterViT:基于分层注意力的快速视觉transformer

    文章目录 摘要 1 简介 2 相关工作 3 FasterViT 3 1 设计主体 3 2 架构设计 3 3 FasterViT组件 4 实验 4 1 训练设置 5 结果 5 1 图像分类 5 2 目标检测与实例分割 5 3 语义分割 6 消
  • Vue组件的边界情况

    01 root 访问组件的根实例 用的不多 基本上在vuex上进行数据操作 02 parent children 可以获得父组件或者子组件上边的数据 一般不建议使用 parent 因为如果获取这个值进行修改的话 也会更改父组件上边的数据
  • 图片颜色切换实现按钮控制暂停和开始

  • BES(恒玄) 提示音解析

    今天 继续讲解BES平台 UI 最后模块 提示音 提示音这一块比较繁琐 也很容易出问题 我们就 提示音实现机制 问题点 做个全面的讲解 BES 提示音分为两种 触发模式 第一种是打断的 第二种是mix类型的 首先 说下 BES单机模式下 提
  • Java 中的Object串行化(Serializable)

    假如你想保存一个对象 object 则这个对象所属类必须实现Serializable接口 当串行化一个对象时 Java会保存对象的完整的 对象图 即对该对象引用的其他对象 也进行串行化 当然 那些 其他对象 也要实现Serializable
  • web前端开发—Flex布局

    目录 Flex布局 1 思考 2 Flex布局 弹性布局 3 作用 4 设置方式 5 组成部分 6 主轴对齐方式 7 侧轴对齐方式 8 伸缩比 9 主轴方向 10 弹性盒子换行 Flex布局 目标 能够使用Flex布局模型灵活 快速的开发网
  • 初探webAssembly

    1 WebAssembly是什么 一种运行在现代网络浏览器中的新型代码 并且提供新的性能特性和效果 W3C WebAssembly Community Group开发的一项网络标准 对于浏览器而言 WebAssembly 提供了一条途径 让
  • Spring-boot中过滤器与拦截器

    1 过滤器 其实过滤器 Filter 跟Servlet很相似 都是java的一个组件 即请求发送到servlet之前 可以将其拦截和处理请求 也可以在serlvet结束工作之后 在响应发回之前处理响应 做一些事情 因此 可以理解为过滤器fi
  • powerdesigner 连接mysql提示“connection test failed”

    win10电脑 64位环境 powerdesigner 连接mysql提示 connection test failed 该如何解决 1 把64位的jdk换成32位的jdk 原的64的位不用卸载 2 PowerDesigner Tools
  • 蓝牙之六-A2dp代码调用流程

    上图描述的是蓝牙协议栈 通过该图 查看A2dp的代码在协议栈的调用流程 其分层架构如下 1 蓝牙的系统服务service通过JNI与bluedroid协议栈进行通信 协议栈分为两层 Bluetooth Embedded System BTE
  • .NET页面之间传值的几种方式总结

    1 QueryString 当页面上的form以get方式向页面发送请求数据时 web server将请求数据放入一名为QEURY STRING的环境变量中 QeueryString方法从这个变量中取出相应的值 先建立两个WebForm 分
  • FFmpeg通过摄像头实现对视频流进行解码并显示测试代码(新接口)

    在https blog csdn net fengbingchun article details 93975325 中给出了通过旧接口即FFmpeg中已废弃的接口实现通过摄像头获取视频流然后解码并显示的测试代码 这里通过使用FFmpeg中
  • 基于ROS的无人车模型预测控制(MPC)C++实现

    基于ROS的无人车模型预测控制 MPC C 实现 最近在做毕业设计的控制器部分 网上关于cpp实现模型预测控制的资料很少 基本都是Matlab Simulink实现 顺手写一下学习过程 1 建模方法 模型预测控制的基本原理本文不作赘述 可以