从0制作自己的ros导航小车
系列文章:
①【从0制作自己的ros导航小车:介绍及准备】
②【从0制作自己的ros导航小车:下位机篇】01、工程准备_标准库移植freertos
③【从0制作自己的ros导航小车:下位机篇】02、电机驱动、转速读取、PID控制
④【从0制作自己的ros导航小车:下位机篇】03、mpu6050偏航角获取
⑤【从0制作自己的ros导航小车:上、下位机通信篇】上、下位机串口DMA通信
⑥【从0制作自己的ros导航小车:上位机篇】01、里程计与坐标变换发布
⑦【从0制作自己的ros导航小车:上位机篇】02、ros1多机通讯与坐标变换可视化
⑧【从0制作自己的ros导航小车:上位机篇】03、添加urdf模型(发布各传感器与小车基坐标系之间的静态坐标变换)
⑨【从0制作自己的ros导航小车:上位机篇】04、使用gmapping建图
⑩【从0制作自己的ros导航小车:上位机篇】05、导航!
前言
上一篇已经可以在rviz中看到小车的位姿和里程计了,但是只有坐标系不太好看,本篇博客为小车添加urdf模型。小车各部件之间的坐标系位置关系是固定的,所以可以有两种策略发布这种静态坐标变换:①直接在launch文件中使用tf2节点发布各部件与base_footprint之间的静态坐标变换;②编写urdf文件,在launch文件中包含urdf文件,此时会自动发布各部件之间的静态坐标变化。
为了可视化方便,本文使用第二种方法(只是弄个很简单的模型,可以自己写,使用xacro)
不懂为什么要坐标变换的看这里:
只有经过坐标变换,传感器的数据才会在同一个坐标系下显示出来,比如:当前系统只发布了base_footprint到odom的坐标变换,此时在rviz中选择odom坐标系就可以看到base_footprint和odom,如果此时运行雷达,发布了雷达话题/scan和雷达坐标系laser,那此时在rviz中如果选择odom,那就看不到雷达数据,如果改成laser坐标系,那就可以看到雷达数据,所以此时只需要发布一个laser到base_footprint的静态坐标变换,就可以在odom坐标系下同时看到base_footprint和laser。此时的tf树关系是:odom→base_footprint→laser。
一、编写URDF文件
进入工作空间新建功能包:
cd src
catkin_create_pkg my_description urdf xacro
cd ..
catkin_make
进入新建的功能包中新建urdf文件
进入urdf目录新建car.urdf
car.urdf:
<?xml version="1.0"?>
<robot name="my_robot_description">
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="0.001" />
</geometry>
</visual>
</link>
<link name="base_link">
<visual>
<geometry>
<box size="0.25 .16 .05"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0.0"/>
<material name="gree">
<color rgba="0 0 .8 1"/>
</material>
</visual>
</link>
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link"/>
<origin xyz="0 0 0.055" />
</joint>
<link name="left_front_wheel">
<visual>
<geometry>
<cylinder length=".02" radius="0.05"/>
</geometry>
<material name="red">
<color rgba="1 0 0 1"/>
</material>
</visual>
</link>
<joint name="left_front_wheel_joint" type="continuous">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="right_front_wheel"/>
<origin rpy="1.57075 0 0" xyz="0.12 0.1 0"/>
<limit effort="100" velocity="100"/>
<joint_properties damping="0.0" friction="0.0"/>
</joint>
<link name="right_front_wheel">
<visual>
<geometry>
<cylinder length=".02" radius="0.05"/>
</geometry>
<material name="red">
<color rgba="1 0 0 1"/>
</material>
</visual>
</link>
<joint name="right_front_wheel_joint" type="continuous">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="left_front_wheel"/>
<origin rpy="1.57075 0 0" xyz="0.12 -0.1 0"/>
<limit effort="100" velocity="100"/>
<joint_properties damping="0.0" friction="0.0"/>
</joint>
<link name="right_back_wheel">
<visual>
<geometry>
<cylinder length=".02" radius="0.05"/>
</geometry>
<material name="red">
<color rgba="1 0 0 1"/>
</material>
</visual>
</link>
<joint name="right_back_wheel_joint" type="continuous">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="right_back_wheel"/>
<origin rpy="1.57075 0 0" xyz="-0.12 -0.1 0"/>
<limit effort="100" velocity="100"/>
<joint_properties damping="0.0" friction="0.0"/>
</joint>
<link name="left_back_wheel">
<visual>
<geometry>
<cylinder length=".02" radius="0.05"/>
</geometry>
<material name="red">
<color rgba="0.8 0.5 0.5 1"/>
</material>
</visual>
</link>
<joint name="left_back_wheel_joint" type="continuous">
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="left_back_wheel"/>
<origin rpy="1.57075 0 0" xyz="-0.12 0.1 0"/>
<limit effort="100" velocity="100"/>
<joint_properties damping="0.0" friction="0.0"/>
</joint>
<link name="laser">
<visual>
<geometry>
<box size=".02 .03 .05"/>
</geometry>
<material name="white">
<color rgba="0 0 0 1"/>
</material>
</visual>
</link>
<joint name="lasertobaselink" type="fixed">
<parent link="base_link"/>
<child link="laser"/>
<origin xyz="0.0 0.0 0.025"/>
</joint>
</robot>
二、可视化模型并结合里程计数据测试
回到串口的功能包中新建launch目录,在launch目录下新建start_car.launch:
<launch>
<!-- 将 urdf 文件内容设置进参数服务器 -->
<param name="robot_description" textfile="$(find my_description)/urdf/car.urdf" />
<!-- 启动里程计与坐标变换发布节点 -->
<node pkg="uart_tf" type="uartandtf" name="uart_and_tf" output="screen"/>
<!-- 启动机器人状态和关节状态发布节点 -->
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" />
</launch>
此时打开虚拟机的rviz,坐标系选择odom,然后添加robotmodel和tf,可以看到小车模型,并且此模型会随着现实中小车的运动而运动。
此时的tf树如下图所示,使用rqt查看:
这里最左边的laser是雷达坐标系,现在还没到使用雷达的时候,先写好,之后就不用改了。