目录
【场景】仿真小车在Gazebo上进行Gmapping
步骤:
问题:
【填坑过程】
【知识储备】
【解决办法】
【修改尝试-0】
【结论-0】odom由一个发布者发布
【修改尝试-1】
【结论-1】odom信息由模型中的URDF决定
【修改尝试-2】
【结论-2】关闭Gazebo发布OdomTF可以避免让Gampping意外死掉,但是缺少了odom到base_footprint的连接
【修改尝试-3】
【结论-3】自添加odom到base_footprint的TF转换还是会让gmapping死掉
【踩坑分析-2】从成功例子入手
【修改尝试-4】
【场景】仿真小车在Gazebo上进行Gmapping
步骤:
运行roslaunch spark1_description spark_gmapping_slam_gazebo_rviz.launch
问题:
[ WARN] [1642146649.678388245, 0.303000000]: TF_REPEATED_DATA ignoring data with redundant timestamp for frame odom at time 0.353000 according to authority unknown_publisher
[spark_slam_gmapping-4] process has died [pid 27710, exit code -11, cmd /home/nx_ros/spark-slam-gazebo/devel/lib/gmapping/slam_gmapping __name:=spark_slam_gmapping __log:=/home/nx_ros/.ros/log/af99f9d2-750e-11ec-b97d-7f03d0e3bbcd/spark_slam_gmapping-4.log].
可见gmapping已死掉,在rviz上查看
rviz上显示no map received,应该是gmapping死掉的原因
使用rqt_tf_tree查看
rosrun rqt_tf_tree rqt_tf_tree
截取关键部分,同样看不见map的tf转换关系。
spark_gmapping_slam_gazebo_rviz.launch文件内容如下:
<?xml version="1.0"?>
<launch>
<!-- 设置launch文件的参数 -->
<!--<arg name="world_name" value="$(find spark1_description)/worlds/cloister.world"/> -->
<arg name="paused" default="false"/>
<arg name="use_sim_time" default="true"/>
<arg name="gui" default="true"/>
<arg name="headless" default="true"/>
<arg name="debug" default="false"/>
<arg name="model" default="$(find spark1_description)/urdf/spark1_description_gmapping.urdf"/>
<!--<arg name="configuration_basename" default="spark_lds_2d.lua"/>/-->
<!-- 运行gazebo仿真环境 -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<!--<arg name="world_name" value="$(arg world_name)" /> -->
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="$(arg paused)"/>
<arg name="use_sim_time" value="$(arg use_sim_time)"/>
<arg name="headless" value="$(arg headless)"/>
</include>
<!-- 运行joint_state_publisher节点,发布机器人的关节状态 -->
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node>
<!-- 运行robot_state_publisher节点,发布tf -->
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
</node>
<!--添加TF转换(map to odom)
<node pkg="tf" type="static_transform_publisher" name="map_to_odom" args="0 0 0 0 0 0 1 map odom 50" /> -->
<!--添加TF转换(odom to base_footprint)
<node pkg="tf" type="static_transform_publisher" name="odom_to_base_footprint" args="0 0 0 0 0 0 1 odom base_footprint 50" /> -->
<!-- 在gazebo中加载机器人模型-->
<param name="robot_description" command="$(find xacro)/xacro --inorder $(arg model)" />
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
args="-unpause -urdf -model marobot1 -param robot_description -x 0.0 -y 0.0"/>
<!-- Rviz -->
<arg name="rvizconfig" default="$(find spark1_description)/rviz/gr.rviz" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rvizconfig)" required="true" />
<!-- SLAM: gmapping -->
<include file="$(find spark1_description)/launch/spark_gmapping.launch" />
<!--创建新的终端,spark键盘控制 “wsad”分别代表“前后左右”-->
<node pkg="spark_teleop" type="keyboard_control.sh" name="kc_2d" />
<!--创建新的终端,确定是否保存地图
<node pkg="spark_teleop" type="cmd_save_map.sh" name="csm_2d" />-->
</launch>
其中模型文件关键部分如下:
<gazebo>
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<alwaysOn>true</alwaysOn>
<updateRate>50</updateRate>
<leftJoint>left_wheel_joint</leftJoint>
<rightJoint>right_wheel_joint</rightJoint>
<wheelSeparation>0.281</wheelSeparation>
<wheelDiameter>0.068</wheelDiameter>
<torque>0.1</torque>
<rosDebugLevel>na</rosDebugLevel>
<!-- -->
<publishOdomTF>true</publishOdomTF>
<odometryTopic>odom</odometryTopic>
<odometryFrame>odom</odometryFrame>
<publishWheelTF>false</publishWheelTF>
<wheelTorque>5</wheelTorque>
<publishTf>1</publishTf>
<wheelAcceleration>1</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic>
<robotBaseFrame>base_footprint</robotBaseFrame>
<publishWheelJointState>false</publishWheelJointState>
<legacyMode>true</legacyMode>
</plugin>
</gazebo>
【填坑过程】
以下,将作为填坑所做功夫,同时也为让思路更加清晰,文笔更加严谨。若填坑成功,会将成功方法置顶,相反,若无成功方法,即是仍在为此努力中。
【知识储备】
gmapping对硬件要求:
1.移动机器人可发布里程计信息,即topic---/odom
2.移动机器人可发布雷达信息,即topic---/scan
gmapping订阅的话题:
1.tf (tf/tfMessage)---用于雷达、底盘与里程计之间的坐标变换消息。
2.scan(sensor_msgs/LaserScan)---SLAM所需的雷达信息。
从上可以清晰知道gmapping获取此类信息的原因和用途。
关于gmapping的坐标转换(TF transform)
1.所需的的坐标转换
a)雷达坐标系→基坐标系:一般由 robot_state_publisher 或 static_transform_publisher 发布。
b)基坐标系→里程计坐标系(base_footprint→odom):一般由里程计节点发布。
2.发布的坐标转换
地图坐标系→里程计坐标系(map→odom):地图到里程计坐标系之间的变换。
关于gmapping更多信息可查看http://wiki.ros.org/gmapping
【解决办法】
首先保证启动仿真环境时,TF转换是正确的,而且gmapping获取的雷达话题也是正确的
URDF文件修改如下:
启动后用rqt_tf_tree查看
确保odom-->base_link,base-->virtual_lidar_link(发布/scan的关节)能够正确连接
用rostopic echo /scan,查看scan是否有数据.
问题综述,启动仿真环境和小车没有问题,一启动gmapping就挂掉,而且在报错信息上看不到有用信息,查看spark_gmapping.launch
一开始文件中关于启动gmapping节点如下
<node pkg="gmapping" type="slam_gmapping" name="spark_slam_gmapping" output="log">
output为log,也就不输出到终端,看不到相关信息
更改为输出到screen
<node pkg="gmapping" type="slam_gmapping" name="spark_slam_gmapping" output="screen">
如此,相关信息就会显示在终端上,再次按上述步骤启动
[ INFO] [1644392639.562246850, 6.522000000]: Laser is mounted upwards.
[spark_slam_gmapping-1] process has died [pid 28900, exit code -11, cmd /opt/ros/noetic/lib/gmapping/slam_gmapping scan:=/scan __name:=spark_slam_gmapping __log:=/home/nx_ros/.ros/log/03c0d4a0-897c-11ec-9bcf-e96662a23c5b/spark_slam_gmapping-1.log].
log file: /home/nx_ros/.ros/log/03c0d4a0-897c-11ec-9bcf-e96662a23c5b/spark_slam_gmapping-1*.log
出现Laser is mounted upwards.的信息,根据博客Gmapping报错 :[mapping-4] process has died 的可能解决原因与解决方法_wongHome的博客-CSDN博客
Gmapping 只适用于 单帧二维激光点数小于1440的点,如果单帧激光点数大于1440,那么就会出现[mapping-4] process has died
这样的问题。
所以把单帧二维激光点数配置为1440,就可以正常进行建图了。
将URDF文件中的virtual_lidar_link部分的samples修改成1200
保存后,重新启动,建图效果如下
出现有漂移的现象,影响不大
【修改尝试-0】
下面为踩坑记录,只当作记录,不需要继续看下去。
下面为踩坑记录,只当作记录,不需要继续看下去。
下面为踩坑记录,只当作记录,不需要继续看下去。
对于出错的[spark_slam_gmapping-4] ,由于从提示的信息看不出来是什么问题,先从warn部分看起
[ WARN] [1642146649.678388245, 0.303000000]: TF_REPEATED_DATA ignoring data with redundant timestamp for frame odom at time 0.353000 according to authority unknown_publisher
从字面猜测,可能是由于多个发布者重复发布/odom,再次启动launch文件
roslaunch spark1_description spark_gmapping_slam_gazebo_rviz.launch
另开终端,使用rostopic info 查看
rostopic info /odom
结果如下:
【结论-0】odom由一个发布者发布
【修改尝试-1】
【修改部分】从中可以看出是由gazebo发出,推测是模型URDF中决定,修改URDF文件odom部分
<publishOdomTF>true</publishOdomTF>
<odometryTopic>odom1</odometryTopic>
<odometryFrame>odom1</odometryFrame>
修改gmapping上订阅的odom名称,再次启动launch文件,修改rviz上的Fixed Frame,并由rostopic info 查看
同理由rqt_tf_tree查看,也同样获得和之前一样的结果,gmapping仍然死掉,区别仅仅在odom的名称上。
【结论-1】odom信息由模型中的URDF决定
【修改尝试-2】
【修改部分】当将 odom名称设回原来值,并将URDF文件中的<publishOdomTF>true</publishOdomTF>设为false后
<publishOdomTF>false</publishOdomTF>
再次启动,gmapping没有死掉,rviz中修改Fixed Frame,在gazebo中添加障碍物
仍出现no map received现象
报错信息为
[ WARN] [1642153099.373592268, 0.226000000]: TF_REPEATED_DATA ignoring data with redundant timestamp for frame odom at time 0.276000 according to authority unknown_publisher
[ WARN] [1642153121.976280751, 15.176000000]: MessageFilter [target=odom ]: Dropped 100.00% of messages so far. Please turn the [ros.gmapping.message_filter] rosconsole logger to DEBUG for more information.
使用rqt_tf_tree查看
可以看到odom与base_footprint的连接已断掉,但map已与odom相连,原因是因为URDF文件中将<publishOdomTF>设为false了,且gmapping正常运行中。
【结论-2】关闭Gazebo发布OdomTF可以避免让Gampping意外死掉,但是缺少了odom到base_footprint的连接
【修改尝试-3】
【修改部分】目前缺少了odom到base_footprint的TF转换,尝试在launch文件中添加相应的tf关系转换
在spark_gmapping_slam_gazebo_rviz.launch文件中添加以下信息
<!--添加TF转换(odom to base_footprint) -->
<node pkg="tf" type="static_transform_publisher" name="odom_to_base_footprint" args="0 0 0 0 0 0 1 odom base_footprint 50" />
其中所选范围即为新添加部分,运行查看效果
报错消息:
[ WARN] [1642212245.857175022, 0.226000000]: TF_REPEATED_DATA ignoring data with redundant timestamp for frame odom at time 0.276000 according to authority unknown_publisher
[spark_slam_gmapping-9] process has died [pid 13769, exit code -11, cmd /home/nx_ros/spark-slam-gazebo/devel/lib/gmapping/slam_gmapping __name:=spark_slam_gmapping __log:=/home/nx_ros/.ros/log/68a5e4e8-75a7-11ec-9515-adb2ca252e1d/spark_slam_gmapping-9.log].
用rqt_tf_tree查看
【结论-3】自添加odom到base_footprint的TF转换还是会让gmapping死掉
【踩坑分析-2】从成功例子入手
参照古月老师的slam教学例子(gmapping_slam)
启动成功后,用rqt_tf_tree查看
再去观察模型的URDF文件
<gazebo>
<plugin name="differential_drive_controller"
filename="libgazebo_ros_diff_drive.so">
<rosDebugLevel>Debug</rosDebugLevel>
<publishWheelTF>true</publishWheelTF>
<robotNamespace>/</robotNamespace>
<publishTf>1</publishTf>
<publishWheelJointState>true</publishWheelJointState>
<alwaysOn>true</alwaysOn>
<updateRate>100.0</updateRate>
<legacyMode>true</legacyMode>
<leftJoint>left_wheel_joint</leftJoint>
<rightJoint>right_wheel_joint</rightJoint>
<wheelSeparation>${wheel_joint_y*2}</wheelSeparation>
<wheelDiameter>${2*wheel_radius}</wheelDiameter>
<broadcastTF>1</broadcastTF>
<wheelTorque>30</wheelTorque>
<wheelAcceleration>1.8</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic>
<odometryFrame>odom</odometryFrame>
<odometryTopic>odom</odometryTopic>
<robotBaseFrame>base_footprint</robotBaseFrame>
</plugin>
</gazebo>
分析得知,古月老师的这份URDF文件,是将publishWheelTF,publishWheelJointState,设为true的,同时,publishOdomTF默认值也应为true
【修改尝试-4】
【修改部分】将我的机器人模型URDF中的publishWheelTF,publishWheelJointState和publishOdomTF设为true
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<alwaysOn>true</alwaysOn>
<updateRate>50</updateRate>
<leftJoint>left_wheel_joint</leftJoint>
<rightJoint>right_wheel_joint</rightJoint>
<wheelSeparation>0.281</wheelSeparation>
<wheelDiameter>0.068</wheelDiameter>
<torque>0.1</torque>
<rosDebugLevel>na</rosDebugLevel>
<!-- -->
<publishOdomTF>true</publishOdomTF>
<odometryTopic>odom</odometryTopic>
<odometryFrame>odom</odometryFrame>
<publishWheelTF>true</publishWheelTF>
<wheelTorque>5</wheelTorque>
<publishTf>1</publishTf>
<wheelAcceleration>1</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic>
<robotBaseFrame>base_footprint</robotBaseFrame>
<publishWheelJointState>true</publishWheelJointState>
<legacyMode>true</legacyMode>
</plugin>
</gazebo>
再次运行,出现以下错误
[ WARN] [1642386626.865860385, 0.895000000]: TF_REPEATED_DATA ignoring data with redundant timestamp for frame left_wheel_link at time 0.893000 according to authority unknown_publisher
[ WARN] [1642386626.865975309, 0.895000000]: TF_REPEATED_DATA ignoring data with redundant timestamp for frame right_wheel_link at time 0.893000 according to authority unknown_publisher
[spark_slam_gmapping-8] process has died [pid 6168, exit code -11, cmd /home/nx_ros/spark-slam-gazebo/devel/lib/gmapping/slam_gmapping __name:=spark_slam_gmapping __log:=/home/nx_ros/.ros/log/6ba24ef6-773d-11ec-ba9f-c313f8c7be2f/spark_slam_gmapping-8.log].
log file: /home/nx_ros/.ros/log/6ba24ef6-773d-11ec-ba9f-c313f8c7be2f/spark_slam_gmapping-8*.log
[ WARN] [1642386626.920107925, 0.934000000]: TF_REPEATED_DATA ignoring data with redundant timestamp for frame left_wheel_link at time 0.933000 according to authority unknown_publisher
[ WARN] [1642386626.920155923, 0.934000000]: TF_REPEATED_DATA ignoring data with redundant timestamp for frame right_wheel_link at time 0.933000 according to authority unknown_publisher
运行rqt_tf_tree查看
left_wheel_link和right_wheel_link会连接到base_footprint上
查看URDF文件中关于 left_wheel_link和right_wheel_link的部分
文件中父关节应为base_link
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)