【ROS1仿真】小车跟随--改善跟随的位置(路径规划、动态避障、激光slam、定位)

本文介绍如何通过ROS和TF框架,利用里程计数据和坐标系变换,实现对小车的精确目标跟随控制,通过四元数转偏航角并根据小车朝向调整跟随车辆的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

确保进行跟随的小车始终在身后

最终效果

ROS目标跟随改进版


代码改进

这里给出上一篇博客的链接:https://blog.youkuaiyun.com/m0_71523511/article/details/135610191

使用上一篇的launch文件创建机器人时,ros会自动创建一个坐标系相对关系发布节点:/tf,通过观察此节点发布的信息,可以通过监听里程计坐系:/map和小车底盘坐标系/robot2/base_footprint的坐标变换关系来实现想要的效果。直接上代码:

#include"ros/ros.h"
#include"tf2_ros/transform_listener.h"
#include"tf2_ros/buffer.h"
#include"nav_msgs/Odometry.h"
#include"geometry_msgs/PoseStamped.h"
#include"tf2_geometry_msgs/tf2_geometry_msgs.h"
#include"geometry_msgs/TransformStamped.h"
#include"geometry_msgs/Twist.h"


struct EulerAngles {
    double roll, pitch, yaw;
};

int main(int argc, char *argv[])
{
    ros::init(argc,argv,"test03_control_turtle2");
    ros::NodeHandle nh;
    tf2_ros::Buffer buffer;
    tf2_ros::TransformListener sub(buffer);

    ros::Publisher pub = nh.advertise<geometry_msgs::PoseStamped>("/robot1/move_base_simple/goal",100);

    ros::Rate rate(5);
    while (ros::ok())
    {
        try
        {
            geometry_msgs::TransformStamped son1toson2 = buffer.lookupTransform("map","robot2/base_footprint",ros::Time(0));
            ROS_INFO("son1xiangduiyuson2 : pianyiliang(%.2f,%.2f)",son1toson2.transform.translation.x,son1toson2.transform.translation.y);
            geometry_msgs::PoseStamped odometry;
            odometry.header.frame_id = "robot1/odom";
            
            EulerAngles angles;

            double sinr_cosp = 2 * (son1toson2.transform.rotation.w * son1toson2.transform.rotation.z + son1toson2.transform.rotation.y * son1toson2.transform.rotation.x);
            double cosr_cosp = 1 - 2 * (son1toson2.transform.rotation.z * son1toson2.transform.rotation.z + son1toson2.transform.rotation.y * son1toson2.transform.rotation.y);
            angles.yaw = std::atan2(sinr_cosp, cosr_cosp);

            if((angles.yaw >0) && (angles.yaw < 1.5))
            {
                odometry.pose.position.x = (son1toson2.transform.translation.x-0.35);
                odometry.pose.position.y = (son1toson2.transform.translation.y-0.35);
            }
            else if((angles.yaw >1.5) && (angles.yaw < 3.5))
            {
                odometry.pose.position.x = (son1toson2.transform.translation.x+0.35);
                odometry.pose.position.y = (son1toson2.transform.translation.y-0.35);
            }
            else if((angles.yaw >-1.5) && (angles.yaw < 0))
            {
                odometry.pose.position.x = (son1toson2.transform.translation.x-0.35);
                odometry.pose.position.y = (son1toson2.transform.translation.y+0.35);
            }
            else if((angles.yaw >-3) && (angles.yaw < -1.5))
            {
                odometry.pose.position.x = (son1toson2.transform.translation.x+0.35);
                odometry.pose.position.y = (son1toson2.transform.translation.y+0.35);
            }
            else
            {
                odometry.pose.position.x = (son1toson2.transform.translation.x-0.35);
                odometry.pose.position.y = (son1toson2.transform.translation.y-0.35);
            }
            odometry.pose.orientation.w = 1.0;
            ROS_INFO("stop_here = (%.2f,%.2f)",odometry.pose.position.x,odometry.pose.position.y);

            ROS_INFO("siyuanshu = (%.10f)",angles.yaw);
            pub.publish(odometry);
        }
        catch(const std::exception& e)
        {
            ROS_ERROR("Exception: %s", e.what());
        }

        rate.sleep();
        ros::spinOnce();
    }
    
    return 0;
}


通过代码不难看出,这里的实现就是将检测到的坐标系变换中的四元数转为了偏航角,通过偏航角就可以知道小车此时的朝向,通过测试最终写成四段if多条件判断语句,小车朝向不同,那么第二辆进行跟随的小车它的落点也就不同,这样就可以实现进行跟随的小车始终跟随在前面一辆下车的后面。
如果想要更精细的落点可以增加判断的语句。

### ROS中使用Gazebo进行路径规划仿真ROS环境中利用Gazebo进行路径规划仿真涉及多个方面的工作,包括但不限于环境搭建、模型创建以及算法实现。对于希望基于Solidworks设计的复杂机器人结构来进行更真实的模拟实验的研究者来说,可以遵循特定流程完成这一目标。 #### 安装必要的软件包 为了能够在ROS环境下顺利运行Gazebo并执行路径规划任务,需先安装一系列依赖项。这通常包含了`ros-noetic-gazebo-ros-pkgs`和`ros-noetic-navigation`等核心组件[^1]。 #### 导入Solidworks生成的URDF文件至Gazebo 针对从Solidworks导出的URDF格式描述文件,确保其兼容性至关重要。通过调整链接(link)与关节(joint)定义部分的内容,使得最终形成的机器人表示能够被Gazebo正确解析。此外,还需注意材质(materials)属性设置以增强视觉效果的真实度。 ```bash # 假设已存在名为my_robot.urdf.xacro 的XACRO 文件 roslaunch gazebo_ros empty_world.launch world_name:=/path/to/world.world & sleep 5 # 等待启动完毕 rosrun xacro xacro /path/to/my_robot.urdf.xacro -o /tmp/my_robot.urdf rosparam set robot_description $(cat /tmp/my_robot.urdf) rosrun spawn_model spawn_urdf_model.py my_robot /tmp/my_robot.urdf ``` 上述命令序列展示了如何加载自定义世界场景,并将由Solidworks转换而来的URDF模型实例化到该虚拟空间内。 #### 配置导航堆栈参数 一旦确认物理形态无误之后,则可着手准备用于指导移动平台自主行动所需的各项配置资料。此过程主要围绕着编辑launch文件展开工作,其中会涉及到指定地图(map),设定初始位姿(pose), 并指明所选用的具体运动控制策略(controller)[^2]。 ```xml <!-- wpb_stage_slam.launch --> <launch> <!-- 启动SLAM节点 --> <include file="$(find wpr_simulation)/launch/wpb_stage_hector_mapping.launch"/> <!-- 发布TF变换关系 --> <node pkg="tf" type="static_transform_publisher" name="base_to_laser" args="0 0 0.2 0 0 0 base_link laser_frame 100"/> </launch> <!-- wpb_demo_nav.launch --> <launch> <!-- 加载全局成本图 --> <arg name="map_file" default="$(find wpr_simulation)/maps/map.yaml"/> <node pkg="map_server" type="map_server" name="map_server" args="$(arg map_file)" output="screen"> ... </node> <!-- 初始化AMCL定位服务 --> <include file="$(find amcl)/examples/amcl_omni_example.xml"/> <!-- 设置局部及全局路径规划--> <param name="/move_base/global_costmap/static_map" value="true"/> <param name="/move_base/local_costmap/static_map" value="false"/> <rosparam command="load" file="$(find wpr_simulation)/config/costmap_common_params.yaml" ns="costmap_common"/> <rosparam command="load" file="$(find wpr_simulation)/config/base_local_planner_params.yaml" ns="local_costmap"/> <rosparam command="load" file="$(find wpr_simulation)/config/dwa_local_planner_params.yaml" ns="DWAPlannerROS"/> </launch> ``` 以上XML片段摘录了两个典型的Launch脚本示例,分别负责处理建图(mapping)阶段的任务分配以及后续导航(navigation)期间的各项初始化操作。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值