【Autoware规控】mpc_follower模型预测控制节点
文章目录
- 1. 技术原理
- 2. 代码实现
1. 技术原理
MPC,即Model Predictive Control(模型预测控制),是一种基于动态模型的控制算法。MPC算法通过建立系统的数学模型,根据当前状态和一定时间内的预测,优化未来的控制输入,从而实现对系统的控制。
MPC算法主要分为以下几个步骤:
1. 建立数学模型:根据系统的物理特性,建立状态空间模型或者传递函数模型。
2. 预测状态:根据当前状态,利用建立的数学模型对未来一段时间内的状态进行预测。
3. 生成控制输入:根据预测的状态和控制目标,利用最优化算法生成控制输入。
4. 执行控制:根据生成的控制输入,执行控制。
5. 更新状态:根据执行的控制输入,更新系统状态,并进入下一次预测和控制循环。
基于模型预测控制的轨迹跟踪算法对未来轨迹的预测和处理多目标约束条件的能力较强。主要体现在:能够考虑系统的非线性和时变性,适用于各种复杂系统的控制;能够考虑多个控制目标,并在它们之间进行平衡和优化;能够对约束条件进行有效的处理,例如系统的输入和输出限制、状态变量的可行性等。
MPC算法可以用于实现车辆的路径跟踪和速度控制。具体地,利用车辆的动态模型,预测未来一段时间内的车辆状态(例如位置、速度、加速度等),并根据预测结果生成最优的车辆控制输入(例如方向盘转角、油门踏板位置、刹车踏板位置等),从而实现对车辆的精确控制。MPC算法还可以考虑车辆与周围环境的交互,例如与其他车辆、行人和路标的交互,从而实现更加安全和高效的自动驾驶。
2. 代码实现
在Autoware中,MPC算法主要实现在mpc_follower节点中。该节点接收/vehicle_status、/vehicle_cmd和/trajectory
等消息,其中/vehicle_status
消息包括车辆状态信息(例如位置、速度、方向等),/vehicle_cmd
消息包括车辆控制指令(例如方向盘转角、油门踏板位置、刹车踏板位置等),/trajectory
消息包括规划的车辆轨迹。通过对这些消息的处理,mpc_follower节点可以计算出最优的车辆控制指令,并将其发送给/vehicle_cmd
话题,从而实现对车辆的控制。
在实现MPC控制的过程中,需要定义车辆的动态模型、代价函数以及约束条件等。可以通过编辑mpc_param.yaml
文件来配置MPC控制的参数。
mpc_follower_core.h
#include <vector>
#include <iostream>
#include <limits>
#include <chrono>
#include <unistd.h>
#include <deque>#include <ros/ros.h>
#include <std_msgs/Float64.h>
#include <std_msgs/Float32.h>
#include <std_msgs/Float64MultiArray.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/TwistStamped.h>
#include <visualization_msgs/MarkerArray.h>
#include <visualization_msgs/Marker.h>
#include <tf2/utils.h>#include <eigen3/Eigen/Core>
#include <eigen3/Eigen/LU>#include <autoware_msgs/ControlCommandStamped.h>
#include <autoware_msgs/Lane.h>
#include <autoware_msgs/VehicleStatus.h>#include "mpc_follower/mpc_utils.h"
#include "mpc_follower/mpc_trajectory.h"
#include "mpc_follower/lowpass_filter.h"
#include "mpc_follower/vehicle_model/vehicle_model_bicycle_kinematics.h"
#include "mpc_follower/vehicle_model/vehicle_model_bicycle_dynamics.h"
#include "mpc_follower/vehicle_model/vehicle_model_bicycle_kinematics_no_delay.h"
#include "mpc_follower/qp_solver/qp_solver_unconstr.h"
#include "mpc_follower/qp_solver/qp_solver_unconstr_fast.h"
#include "mpc_follower/qp_solver/qp_solver_qpoases.h"/** * @class MPC-based waypoints follower class* @brief calculate control command to follow reference waypoints*/
class MPCFollower
{
public:/*** @brief constructor*/MPCFollower();/*** @brief destructor*/~MPCFollower();private:ros::NodeHandle nh_; //!< @brief ros node handleros::NodeHandle pnh_; //!< @brief private ros node handleros::Publisher pub_steer_vel_ctrl_cmd_; //!< @brief topic publisher for control commandros::Publisher pub_twist_cmd_; //!< @brief topic publisher for twist commandros::Subscriber sub_ref_path_; //!< @brief topic subscriber for reference waypointsros::Subscriber sub_pose_; //!< @brief subscriber for current poseros::Subscriber sub_vehicle_status_; //!< @brief subscriber for currrent vehicle statusros::Timer timer_control_; //!< @brief timer for control command computationMPCTrajectory ref_traj_; //!< @brief reference trajectory to be followedButterworth2dFilter lpf_steering_cmd_; //!< @brief lowpass filter for steering commandButterworth2dFilter lpf_lateral_error_; //!< @brief lowpass filter for lateral error to calculate derivatieButterworth2dFilter lpf_yaw_error_; //!< @brief lowpass filter for heading error to calculate derivatieautoware_msgs::Lane current_waypoints_; //!< @brief current waypoints to be followedstd::shared_ptr<VehicleModelInterface> vehicle_model_ptr_; //!< @brief vehicle model for MPCstd::string vehicle_model_type_; //!< @brief vehicle model type for MPCstd::shared_ptr<QPSolverInterface> qpsolver_ptr_; //!< @brief qp solver for MPCstd::string output_interface_; //!< @brief output command typestd::deque<double> input_buffer_; //!< @brief control input (mpc_output) buffer for delay time conpemsation/* parameters for control*/double ctrl_period_; //!< @brief control frequency [s]double steering_lpf_cutoff_hz_; //!< @brief cutoff frequency of lowpass filter for steering command [Hz]double admisible_position_error_; //!< @brief stop MPC calculation when lateral error is large than this value [m]double admisible_yaw_error_deg_; //!< @brief stop MPC calculation when heading error is large than this value [deg]double steer_lim_deg_; //!< @brief steering command limit [rad]double wheelbase_; //!< @brief vehicle wheelbase length [m] to convert steering angle to angular velocity/* parameters for path smoothing */bool enable_path_smoothing_; //< @brief flag for path smoothingbool enable_yaw_recalculation_; //< @brief flag for recalculation of yaw angle after resamplingint path_filter_moving_ave_num_; //< @brief param of moving average filter for path smoothingint path_smoothing_times_; //< @brief number of times of applying path smoothing filterint curvature_smoothing_num_; //< @brief point-to-point index distance used in curvature calculationdouble traj_resample_dist_; //< @brief path resampling interval [m]struct MPCParam{int prediction_horizon; //< @brief prediction horizon stepdouble prediction_sampling_time; //< @brief prediction horizon perioddouble weight_lat_error; //< @brief lateral error weight in matrix Qdouble weight_heading_error; //< @brief heading error weight in matrix Qdouble weight_heading_error_squared_vel_coeff; //< @brief heading error * velocity weight in matrix Qdouble weight_steering_input; //< @brief steering error weight in matrix Rdouble weight_steering_input_squared_vel_coeff; //< @brief steering error * velocity weight in matrix Rdouble weight_lat_jerk; //< @brief lateral jerk weight in matrix Rdouble weight_terminal_lat_error; //< @brief terminal lateral error weight in matrix Qdouble weight_terminal_heading_error; //< @brief terminal heading error weight in matrix Qdouble zero_ff_steer_deg; //< @brief threshold that feed-forward angle becomes zerodouble delay_compensation_time; //< @brief delay time for steering input to be compensated};MPCParam mpc_param_; // for mpc design parameterstruct VehicleStatus{std_msgs::Header header; //< @brief headergeometry_msgs::Pose pose; //< @brief vehicle posegeometry_msgs::Twist twist; //< @brief vehicle velocitydouble tire_angle_rad; //< @brief vehicle tire angle};VehicleStatus vehicle_status_; //< @brief vehicle statusdouble steer_cmd_prev_; //< @brief steering command calculated in previous perioddouble lateral_error_prev_; //< @brief previous lateral error for derivativedouble yaw_error_prev_; //< @brief previous lateral error for derivative/* flags */bool my_position_ok_; //< @brief flag for validity of current posebool my_velocity_ok_; //< @brief flag for validity of current velocitybool my_steering_ok_; //< @brief flag for validity of steering angle/*** @brief compute and publish control command for path follow with a constant control period*/void timerCallback(const ros::TimerEvent &);/*** @brief set current_waypoints_ with receved message*/void callbackRefPath(const autoware_msgs::Lane::ConstPtr &);/*** @brief set vehicle_status_.pose with receved message */void callbackPose(const geometry_msgs::PoseStamped::ConstPtr &);/*** @brief set vehicle_status_.twist and vehicle_status_.tire_angle_rad with receved message*/void callbackVehicleStatus(const autoware_msgs::VehicleStatus &msg);/*** @brief publish control command calculated by MPC* @param [in] vel_cmd velocity command [m/s] for vehicle control* @param [in] acc_cmd acceleration command [m/s2] for vehicle control* @param [in] steer_cmd steering angle command [rad] for vehicle control* @param [in] steer_vel_cmd steering angle speed [rad/s] for vehicle control*/void publishControlCommands(const double &vel_cmd, const double &acc_cmd,const double &steer_cmd, const double &steer_vel_cmd);/*** @brief publish control command as geometry_msgs/TwistStamped type* @param [in] vel_cmd velocity command [m/s] for vehicle control* @param [in] omega_cmd angular velocity command [rad/s] for vehicle control*/void publishTwist(const double &vel_cmd, const double &omega_cmd);/*** @brief publish control command as autoware_msgs/ControlCommand type* @param [in] vel_cmd velocity command [m/s] for vehicle control* @param [in] acc_cmd acceleration command [m/s2] for vehicle control* @param [in] steer_cmd steering angle command [rad] for vehicle control*/void publishCtrlCmd(const double &vel_cmd, const double &acc_cmd, const double &steer_cmd);/*** @brief calculate control command by MPC algorithm* @param [out] vel_cmd velocity command* @param [out] acc_cmd acceleration command* @param [out] steer_cmd steering command* @param [out] steer_vel_cmd steering rotation speed command*/bool calculateMPC(double &vel_cmd, double &acc_cmd, double &steer_cmd, double &steer_vel_cmd);/* debug */bool show_debug_info_; //!< @brief flag to display debug inforos::Publisher pub_debug_filtered_traj_; //!< @brief publisher for debug inforos::Publisher pub_debug_predicted_traj_; //!< @brief publisher for debug inforos::Publisher pub_debug_values_; //!< @brief publisher for debug inforos::Publisher pub_debug_mpc_calc_time_; //!< @brief publisher for debug inforos::Subscriber sub_estimate_twist_; //!< @brief subscriber for /estimate_twist for debuggeometry_msgs::TwistStamped estimate_twist_; //!< @brief received /estimate_twist for debug/*** @brief convert MPCTraj to visualizaton marker for visualization*/void convertTrajToMarker(const MPCTrajectory &traj, visualization_msgs::Marker &markers,std::string ns, double r, double g, double b, double z);/*** @brief callback for estimate twist for debug*/void callbackEstimateTwist(const geometry_msgs::TwistStamped &msg) { estimate_twist_ = msg; }
};
以上。
相关文章:

【Autoware规控】mpc_follower模型预测控制节点
文章目录1. 技术原理2. 代码实现1. 技术原理 MPC,即Model Predictive Control(模型预测控制),是一种基于动态模型的控制算法。MPC算法通过建立系统的数学模型,根据当前状态和一定时间内的预测,优化未来的控…...

成果VR虚拟3D展厅让内容更丰富饱满
随着数字技术的不断发展和普及,数字化展厅成为了一种重要的展示形式。线上虚拟展厅作为数字化展示的一种新形式,采用虚拟现实技术,能够克服时空限制,打破传统展览业的展示模式,为用户提供更加丰富、立体、沉浸式的展览…...

【CE进阶】lua脚本使用
▒ 目录 ▒🛫 导读需求开发环境1️⃣ 脚本窗口Lua ScriptLua EngineAuto assemble2️⃣ 全局变量3️⃣ 进程当前打开的进程ID系统的进程列表系统的顶部窗口列表4️⃣ 线程5️⃣ 输入设备6️⃣ 屏幕7️⃣ 剪贴板🛬 文章小结📖 参考资料&#x…...

【vue2】近期bug收集与整理02
⭐【前言】 在使用vue2构建页面时候,博主遇到的问题难点以及最终的解决方案。 🥳博主:初映CY的前说(前端领域) 🤘本文核心:博主遇到的问题与解决思路 ⭐数据枚举文件的使用 同后端那边发送请求的时,请求返…...
2. 01背包问题
文章目录QuestionIdeasCodeQuestion 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi ,价值是 wi 。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入…...

【Docker】CAdvisor+InfluxDB+Granfana容器监控
文章目录原生命令 docker stats容器监控3剑客CIGCAdvisorInfluxDBGranfanacompose容器编排,一套带走新建目录新建3件套组合的 docker-compose.yml检查配置,有问题才有输出 docker-compose config -q启动docker-compose文件 docker-compose up -d测试浏览…...

k8s 部署nginx 实现集群统一配置,自动更新nginx.conf配置文件 总结
k8s 部署nginx 实现集群统一配置,自动更新nginx.conf配置文件 总结 大纲 1 nginx镜像选择2 创建configmap保存nginx配置文件3 使用inotify监控配置文件变化4 Dockerfile创建5 调整镜像原地址使用阿里云6 创建deploy部署文件部署nginx7 测试使用nginx配置文件同步&…...

动态内存管理(上)——“C”
各位CSDN的uu们你们好呀,今天,小雅兰的内容是动态内存管理噢,下面,让我们进入动态内存管理的世界吧 为什么存在动态内存分配 动态内存函数的介绍 malloc free calloc realloc 常见的动态内存错误 为什么存在动态内存分配 我们已…...

GPT-4发布,这类人才告急,大厂月薪10W+疯抢
ChatGPT最近彻底火出圈,各行各业都在争相报道,甚至连很多官媒都下场“跟风”。ChatGPT的瓜还没吃完,平地一声雷,GPT-4又重磅发布! 很多小伙伴瑟瑟发抖:“AI会不会跟自己抢饭碗啊?” 关于“如何…...

MySQL数据库实现主主同步
前言 MySQL主主同步实际上是在主从同步的基础上将从数据库也提升成主数据库,让它们可以互相读写数据库,从数据库变成主数据库;主从相互授权连接,读取对方binlog日志并更新到本地数据库的过程,只要对方数据改变,自己就…...
JavaScript传参的6种方式
JavaScript传参的方式1. 传递基本类型参数2. 传递对象类型参数3. 使用解构赋值传递参数4. 使用展开运算符传递参数5. 使用可选参数6. 使用剩余参数JavaScript是一门非常灵活的语言,其参数传递方式也同样灵活。在本篇文章中,会详细介绍JavaScript中的参数…...

蓝桥之统计子矩阵
样例说明 满足条件的子矩阵一共有 19 , 包含: 大小为 11 的有 10 个。 大小为 12 的有 3 个。 大小为13 的有 2 个。 大小为 14 的有 1 个。 大小为 21 的有 3 个。 前缀和二维数组 前缀和暴力搜索 import java.util.*; public class Main{private static int ans0;pub…...
Java的基础面试题
一.java基础1.JDK和JRE有什么区别?JDK是java开发工具包,JRE是java运行时环境(包括Java基础类库,java虚拟机)2.和equals的区别是什么?比较的是两者的地址值,equals比较的是两者的内容是否一样3.两…...

J1939故障码诊断说明
1:1939整体协议说明 这里主要说明1939不同的协议,对应不同的网络分层 注意了,这里只进行文档解析说明,具体查看去搜素协议的关键字进行理解 2:DMx和FMI 说明 想知道每个代号的具体含义,可以去 saeJ1939…...

XCPC第十三站,贪心问题
一.区间选点 我们采取这样的策略来选点:step(1)将区间按照右端点的大小从小到大排序;step(2)从前往后依次枚举每个区间,如果当前区间中已经包含点,直接pass,否则选当前区…...

一文让你吃透 Vue3中的组件间通讯 【一篇通】
文章目录前情回顾前言1. 父组件 > 子组件通讯传递2. 子组件 > 父组件通讯传递3. 爷孙组件,后代组件通讯数据总结前情回顾 在本专栏前一章节中,我为大家带来了 Vue3 新特性变化上手指南 的归纳梳理,主要介绍了 Vue3 的 Proxy 响应式原理…...
EVE遭遇大规模DDOS攻击,玩家和官方都傻眼了
如果你恰好是一名《星战前夜》(EVE)的国际服玩家(虽然这个几率很小),又恰好因为疫情一直待在家里,那你就真是倒霉透顶了。因为从1月底开始,EVE的服务器就一直受到大规模的DDOS攻击,而…...

【数据结构】二叉树及相关习题详解
新年新气象! 祝大家兔年 财源滚滚! 万事胜意! 文章目录前言1. 树的一些基础概念1.1 树的一些基本概念1.2 树的一些重要概念2. 二叉树的一些基本概念2.1 二叉树的结构2.2 两种特殊的二叉树3. 二叉树的性质4. 二叉树的存储5. 二叉树的基本操作5.1 构造一棵二叉树5.2 二叉树的遍历…...

锂电池充电的同时也能放电吗?
大家应该都有这样经历,我们的手机在充电的同时也能边使用,有的同学就会说了,这是因为手机电池在充电的同时也在放电。如果这样想我们可能就把锂电池类比了一个蓄水池,以为它在进水的同时也能出水,其实这个比喻是错误的…...

通信工程考研英语复试专有名词翻译
中文英文频分多址Frequency Division Multiple Access码分多址Code Division Multiple Access时分多址Time Division Multiple Access移动通信mobile communication人工智能artificial intelligence水声通信Middle-Range Uwa Communication正交频分复用Orthogonal frequency di…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...