全方位移动机器人 Stanley 轨迹跟踪 Gazebo 仿真

全方位移动机器人 Stanley 轨迹跟踪 Gazebo 仿真

本来打算今天出去跑一下 GPS,但是下雨,作罢

添加参考轨迹信息

以下三个功能包不需要修改:

  • mrobot:在 Rviz 和 Gazebo 中仿真机器人
  • cmd_to_mrobot:运动学解算,控制仿真机器人运动
  • mrobot_states_update:发布机器人状态信息

pure-pursuit 轨迹跟踪中只包含参考轨迹的 X、Y 信息,不包括参考航向角信息,而 stanley 轨迹跟踪需要参考航向角信息,因此修改 double_lane.cpp

主要有两种思路:

1、自定义参考轨迹消息,包括 ref_x,ref_y, ref_phi

float64[] ref_x
float64[] ref_y
float64[] ref_phi

但是参考轨迹要在 Rviz 中显示的话还是需要发布标准格式的消息,即 nav_msgs::Path

因此 double_lane 节点需要发布两个话题,一个给 stanley 控制器,一个给 Rviz,有点冗余


2、将参考航向角信息转化为 nav_msgs::Path 消息下的四元数格式

航向角相当于欧拉角中的偏航角(yaw),因此需要编写欧拉角到四元数的转换函数

array<float, 4> calEulerToQuaternion(const float roll, const float pitch, const float yaw) {array<float, 4> calQuaternion = {0.0f, 0.0f, 0.0f, 1.0f};  // 初始化四元数// 使用Eigen库来进行四元数计算Eigen::Quaternionf quat;quat = Eigen::AngleAxisf(roll, Eigen::Vector3f::UnitX()) *Eigen::AngleAxisf(pitch, Eigen::Vector3f::UnitY()) *Eigen::AngleAxisf(yaw, Eigen::Vector3f::UnitZ());calQuaternion[0] = quat.x();calQuaternion[1] = quat.y();calQuaternion[2] = quat.z();calQuaternion[3] = quat.w();return calQuaternion;
}

这里做了一个小 check,用calEulerToQuaternioncalQuaternionToEuler两个函数验证了转化的正确性

stanley 控制器实现

整体框架和 pure-pursuit 控制器很像,控制算法依然在 poseCallback 回调函数中实现

在参考路径回调函数 pointCallback 中添加参考航向角信息

void pointCallback(const nav_msgs::Path &msg)
{// 避免参考点重复赋值if (pointNum != 0){return;}// geometry_msgs/PoseStamped[] posespointNum = msg.poses.size();// 提前开辟内存r_x_.resize(pointNum);r_y_.resize(pointNum);r_phi_.resize(pointNum);for (int i = 0; i < pointNum; i++){r_x_[i] = msg.poses[i].pose.position.x;r_y_[i] = msg.poses[i].pose.position.y;array<float, 3> rpy = calQuaternionToEuler(msg.poses[i].pose.orientation.x, msg.poses[i].pose.orientation.y,msg.poses[i].pose.orientation.z, msg.poses[i].pose.orientation.w);r_phi_[i] = rpy[2];// cout << r_x_[i] << "\t" << r_y_[i] << "\t" << r_phi_[i] << endl;}
}

C++ 中 stanley 算法的实现和 MATLAB 中很像

%==============================================================
% Calculate outputs
%==============================================================
function sys = mdlOutputs(t,x,u)global U; %store chi_tilde=[vel-vel_ref; delta - delta_ref]global cx;global cy;global phi_ref;pi = 3.1415926;ticfprintf('Update start, t=%6.3f\n',t);x = u(1);y = u(2);yaw_angle =u(3)*pi/180;%CarSim输出的Yaw angle为角度,角度转换为弧度v = u(4) / 3.6;gain_k = 5;L = 2.7;                                % [m] wheel base of vehicleN =  length(cx);Distance = zeros(N,1);x = x + L * cos(yaw_angle);y = y + L * sin(yaw_angle);for i = 1:NDistance(i) =  sqrt((cx(i)-x)^2 + (cy(i)-y)^2);end   %ind是最近点索引[value, location]= min(Distance);ind = location;%error是横向误差,根据实际位置与参考点的y值判断if y < cy(ind)error = value;elseerror = -value;endalpha = phi_ref(ind) - yaw_angle;if v < 1v = 1; endtheta = atan(gain_k * error/v);    delta = alpha + theta;
%     delta = delta * 180 / pi;U = delta;sys= U; % vel, steering, x, ytoc
% End of mdlOutputs.
// 计算发送给模型车的转角
void poseCallback(const geometry_msgs::PoseStamped &currentWaypoint)
{// 获取当前位姿auto currentPositionX = currentWaypoint.pose.position.x;auto currentPositionY = currentWaypoint.pose.position.y;auto currentPositionZ = 0.0;auto currentQuaternionX = currentWaypoint.pose.orientation.x;auto currentQuaternionY = currentWaypoint.pose.orientation.y;auto currentQuaternionZ = currentWaypoint.pose.orientation.z;auto currentQuaternionW = currentWaypoint.pose.orientation.w;std::array<float, 3> calRPY =calQuaternionToEuler(currentQuaternionX, currentQuaternionY,currentQuaternionZ, currentQuaternionW);float currentYaw = calRPY[2];cout << currentPositionX << "\t" << currentPositionY << "\t" << currentYaw << endl;// 计算前轴中心位置float front_x = currentPositionX + Ld * cos(currentYaw);float front_y = currentPositionY + Ld * sin(currentYaw);// 计算最近点距离及索引float cur_distance = 0.0;float min_distance = 1e9;for (int i = 0; i < pointNum; ++i){cur_distance = sqrt(pow(r_x_[i] - front_x, 2) + pow(r_y_[i] - front_y, 2));if (cur_distance < min_distance){min_distance = cur_distance;targetIndex = i;}}// 到达终点后结束控制,当两次以终点为目标点时结束if (targetIndex == pointNum - 1){++final_cnt;if (final_cnt >= 2){final_cnt = 2;}}// 计算横向误差,根据实际位置与参考点Y值判断float lateral_error = 0.0;if (currentPositionY < r_y_[targetIndex]){lateral_error = min_distance;}else{lateral_error = -min_distance;}// 计算航向偏差角和横向偏差角float alpha = r_phi_[targetIndex] - currentYaw;float theta = atan(Gain_K * lateral_error / currentVelocity);// cout << "targetIndex: " << targetIndex << endl;// cout << "ref_phi: " << r_phi_[targetIndex] << "\tcurrentYaw: " << currentYaw << endl;// cout << "currentVelocity: " << currentVelocity << "\tlateral_error: " << lateral_error << endl;// cout << "alpha: " << alpha << "\ttheta: " << theta << endl;// cout << "---------" << endl;// 发布小车运动指令及运动轨迹geometry_msgs::Twist vel_msg;vel_msg.linear.z = 1.0;if (targetIndex == pointNum - 1 && final_cnt >= 2){vel_msg.linear.x = 0;vel_msg.angular.z = 0;stanley_ctrl.publish(vel_msg);}else{float delta = alpha + theta;vel_msg.linear.x = 0.5;vel_msg.angular.z = delta;stanley_ctrl.publish(vel_msg);// 发布小车运动轨迹geometry_msgs::PoseStamped this_pose_stamped;this_pose_stamped.header.frame_id = "world";this_pose_stamped.header.stamp = ros::Time::now();this_pose_stamped.pose.position.x = currentPositionX;this_pose_stamped.pose.position.y = currentPositionY;this_pose_stamped.pose.orientation.x = currentQuaternionX;this_pose_stamped.pose.orientation.y = currentQuaternionY;this_pose_stamped.pose.orientation.z = currentQuaternionZ;this_pose_stamped.pose.orientation.w = currentQuaternionW;path.poses.push_back(this_pose_stamped);}actual_path.publish(path);
}

💡 添加对终点的处理,当第二次以终点为目标点时结束控制

跟踪效果分析

纵向速度 0.5m/s,增益参数 Gain_K = 2.0 时在开始跟踪后片刻立即跑飞

在这里插入图片描述

增益参数调整为 1.0 后勉强可以跟踪上参考轨迹

在这里插入图片描述

但横向跟踪误差和横摆角误差都很大,最大横向跟踪误差 0.4694m,最大横摆角误差 0.2868 rad,都是比较大的误差

💡 感觉这里误差均值的意义不大,因为正误差与负误差会抵消,还需结合论文判断

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

根据Stanley 轨迹跟踪算法研究(2)中 CarSim+Simulink 联合仿真结果可知:相同增益参数 Gain_K,速度越低越不稳定,前轮转角会存在越多的抖动;相同速度下,增益参数越大越不稳定,前轮转角会存在越多的抖动

考虑移动机器人纵向速度仅为 0.5m/s,速度较低,因此增益参数Gain_K应取小值,同时依然存在 Gazebo 关节控制器 PID 参数调教的问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/177611.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最佳实践-使用Github Actions来构建跨平台容器镜像

公众号「架构成长指南」&#xff0c;专注于生产实践、云原生、分布式系统、大数据技术分享。 前言 最近在写K8s的相关系列文章&#xff0c;因为有涉及到镜像构建&#xff0c;发现在Mac m1的Arm架构下构建的部分镜像&#xff0c;没法在X86架构下使用&#xff0c;不兼容。 尝试…

Xocde 升级15 或者 iOS17报错:

错误&#xff1a; Assertion failed: (false && "compact unwind compressed function offset doesnt fit in 24 bits"), function operator(), file Layout.cpp, line 5758. 翻译&#xff1a; 断言失败&#xff1a;&#xff08;false&&“压缩展开…

【仿真】ruckig在线轨迹生成器示例

该场景说明了使用 CoppeliaSim 中提供的 Ruckig 在线轨迹生成功能的各种方法&#xff1a; 1. 在线程脚本内使用单个阻塞函数&#xff08;红色&#xff09; 2. 在线程脚本中使用多个非阻塞函数&#xff08;黄色&#xff09; 3. 在非线程脚本中使用多个非阻塞函数&#xff08;…

基于闪电搜索算法优化概率神经网络PNN的分类预测 - 附代码

基于闪电搜索算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于闪电搜索算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于闪电搜索优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

PyG(torch_geometric)的MessagePassing详解

1. 提出MessagePassing的目的 MessagePassing是图神经网络&#xff08;Graph Neural Networks&#xff0c;GNNs&#xff09;的一个基础组件&#xff0c;它被设计用来处理图形数据的问题。在图形数据中&#xff0c;数据点&#xff08;节点&#xff09;之间的关系&#xff08;边…

【工具流】WSL2安装

一些废话 最近看到了PKU出品的cs自学指南&#xff0c;想要跟着里面的自学路径学国外的优质课程&#xff0c;无奈大多数pre教程里面都是直接Linux环境下的操作&#xff0c;并且我在CSwiki看到了那个熟悉的上学期学了一点的missing-semester课。 上学期自学missing-semester的时候…

Windows系统Mysql数据库、文件夹自动备份

一、批处理bat文件编写 批处理命令如下&#xff0c;使用时需要将相关参数修改为实际参数 echo off color 0a chcp 65001::数据库备份文件及模型文件备份的根路径 SET BACKUP_DIRZ:\backup ::**************************************配置MySQL数据库备份相关参数*************…

谷歌提出AGI的6大原则,和5大能力等级

随着ChatGPT等大模型的出现,AGI概念正在从哲学层面快速转向实际应用落地&#xff0c;并且ChatGPT已经展示出了初级AGI的功能&#xff08;如AutoGPT&#xff09;,有不少专家认为&#xff0c;AGI时代可能在10年内到来。 因此&#xff0c;需要一个明确的技术框架来讨论和衡量不同…

深度学习+opencv+python实现车道线检测 - 自动驾驶 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络3.1卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV56 数据集处理7 模型训练8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &am…

学好Python-新手小白如何做?

新手小白如何学好Python?有哪些参考方法吗?这是一个老生常谈的话题了。今天为大家带来两位前辈的分享&#xff0c;他们给出了非常实用的方法和思路&#xff0c;希望对你有所帮助。 1、多练&#xff0c;两个字&#xff1a;多练 如果真的要说方法可以参考如下&#xff1a; ①…

Acrobat Pro DC 2023 中文版

Acrobat Pro DC 2023是PDF编辑和管理软件&#xff0c;具有以下优点&#xff1a; 更好的安全性&#xff1a;Acrobat Pro DC 2023采用了新的安全功能&#xff0c;包括加密、数字签名等&#xff0c;可以更好地保护PDF文件的安全性。 更高的速度和性能&#xff1a;Acrobat Pro DC …

19C进入数据库出现问号

问题情况如图所示&#xff1a; 解决方法&#xff1a; su - oracle echo "NLS_LANGAMERICAN_AMERICA.ZHS16GBK;export NLS_LANG" >> ~/.bash_profilesource ~/.bash_profileofile