小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
odom->base_footprint的TF转换没有成功
-
基础环境:
ubuntu 22.04
ros2-humble
gazebo-Fortress目的:
我使用gazebo仿真一个四轮小车,差速转向,发布TF的过程中发现odom->base_footprint的转换没有成功,调试了很久,查阅了很多资料,也没有找到具体原因,所以来社区请教。使用命令查看TF树:
查看topic
/clicked_point /clock /cmd_vel /entropy /front_mid_lidar/pc2 /front_mid_lidar/points /front_middle_camera/raw /goal_pose /imu /initialpose /joint_states /keyboard/keypress /map /map_metadata /odom /parameter_events /robot_description /rosout /scan /tf /tf_static
查看odom,tf的话题都有数据的输出:
/tf
transforms: - header: stamp: sec: 0 nanosec: 0 frame_id: map child_frame_id: odom transform: translation: x: 0.0 y: 0.0 z: 0.0 rotation: x: 0.0 y: 0.0 z: 0.0 w: 1.0 --- transforms: - header: stamp: sec: 0 nanosec: 0 frame_id: map child_frame_id: odom transform: translation: x: 0.0 y: 0.0 z: 0.0 rotation: x: 0.0 y: 0.0 z: 0.0 w: 1.0 --- transforms: - header: stamp: sec: 1731555131 nanosec: 253951340 frame_id: base_link child_frame_id: wheel_front_left transform: translation: x: 0.19999999999999998 y: 0.225 z: 0.1 rotation: x: 0.0 y: 0.0 z: 0.0 w: 1.0 - header: stamp: sec: 1731555131 nanosec: 253951340 frame_id: base_link child_frame_id: wheel_front_right transform: translation: x: 0.19999999999999998 y: -0.225 z: 0.1 rotation: x: 0.0 y: 0.0 z: 0.0 w: 1.0 - header: stamp: sec: 1731555131 nanosec: 253951340 frame_id: base_link child_frame_id: wheel_rear_left transform: translation: x: -0.19999999999999998 y: 0.225 z: 0.1 rotation: x: 0.0 y: 0.0 z: 0.0 w: 1.0 - header: stamp: sec: 1731555131 nanosec: 253951340 frame_id: base_link child_frame_id: wheel_rear_right transform: translation: x: -0.19999999999999998 y: -0.225 z: 0.1 rotation: x: 0.0 y: 0.0 z: 0.0 w: 1.0
查看odom
header: stamp: sec: 1336 nanosec: 800000000 frame_id: diff_vehicle_wheel_robot/odom child_frame_id: diff_vehicle_wheel_robot/base_footprint pose: pose: position: x: 6.147483913270831e-12 y: 5.126962272481519e-13 z: 0.0 orientation: x: 0.0 y: 0.0 z: 0.45940532564658004 w: 0.8882267428801949 covariance: - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 twist: twist: linear: x: 0.0 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: -1.3999999998001538 covariance: - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 ---
代码是launch文件启动,代码如下:
def generate_launch_description(): pkg_four_wheel_robot = get_package_share_directory('four_wheel_robot') gz_world_path = PathJoinSubstitution([pkg_four_wheel_robot, 'worlds']) gz_sim = IncludeLaunchDescription( PythonLaunchDescriptionSource(PathJoinSubstitution([pkg_four_wheel_robot, 'launch', 'gz_sim.launch.py'])), launch_arguments={ 'world': PathJoinSubstitution([gz_world_path, LaunchConfiguration('world')]), }.items(), ) # RViz2 rviz = Node( package='rviz2', executable='rviz2', arguments=['-d', os.path.join(pkg_four_wheel_robot, 'rviz', 'four_wheel_robot.rviz')], condition=IfCondition(LaunchConfiguration('rviz')) ) # Bridge bridge = Node( package='ros_gz_bridge', executable='parameter_bridge', arguments=['/clock@rosgraph_msgs/msg/Clock@ignition.msgs.Clock', '/imu@sensor_msgs/msg/Imu@ignition.msgs.IMU', '/front_mid_lidar/points@sensor_msgs/msg/LaserScan@gz.msgs.LaserScan', "/front_mid_lidar/pc2@sensor_msgs/msg/PointCloud2@gz.msgs.PointCloudPacked", '/front_middle_camera/raw@sensor_msgs/msg/Image@gz.msgs.Image', '/cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist', '/keyboard/keypress@std_msgs/msg/Int32@ignition.msgs.Int32', # "/odom@nav_msgs/msg/Odometry@gz.msgs.OdometryWithCovariance", "/odom@nav_msgs/msg/Odometry@gz.msgs.Odometry", "/tf@tf2_msgs/msg/TFMessage@gz.msgs.Pose_V", ], parameters=[{'qos_overrides./front_mid_lidar/points.subscriber.reliability': 'reliable', 'qos_overrides./front_middle_camera/raw.subscriber.reliability': 'reliable'}], output='screen' ) robot_state_pub = Node( package='robot_state_publisher', executable='robot_state_publisher', arguments=[os.path.join(pkg_four_wheel_robot, 'urdf', 'diff_vehicle_wheel_robot.sdf')], output='screen' ) joint_state_pub = Node( package="joint_state_publisher", executable="joint_state_publisher" ) return LaunchDescription([ DeclareLaunchArgument('rviz', default_value='true', description='Open RViz'), DeclareLaunchArgument('world', default_value='four_wheel_robot.world', description='World to load into Gazebo'), gz_sim, rviz, bridge, robot_state_pub, joint_state_pub ])
xacro文件写的小车的模型,差速配置如下:
<plugin filename="ignition-gazebo-diff-drive-system" name="ignition::gazebo::systems::DiffDrive"> <left_joint>wheel_front_left_joint</left_joint> <left_joint>wheel_rear_left_joint</left_joint> <right_joint>wheel_front_right_joint</right_joint> <right_joint>wheel_rear_right_joint</right_joint> <wheel_separation>0.45</wheel_separation> <wheel_radius>0.1</wheel_radius> <robot_namespace>/</robot_namespace> <topic>/cmd_vel</topic> <enable_odom>true</enable_odom> <odom_publish_frequency>10</odom_publish_frequency> <odom_frame>odom</odom_frame> <odom_topic>/odom</odom_topic> <base_frame>base_footprint</base_frame> <publish_tf>true</publish_tf> <tf_prefix>tf</tf_prefix> <broadcast_tf>1</broadcast_tf> <!-- <lidar_frame>lidar</lidar_frame> <lidar_frame>front_mid_lidar</lidar_frame> --> </plugin>
请问我应该如何更改代码?我查阅资料大家说odom->base_footprint是差速器插件自动转换的,所以没有尝试手动写代码进行转换,我还是比较想弄明白我的代码有什么问题?是哪里没有配置好?
再次感谢大家的指正!! -
在你的情况中,
odom
到base_footprint
的 TF 转换没有成功,这通常与几个因素有关:-
Diff Drive 插件配置:
- 确保你的 diff drive 插件配置正确,特别是
enable_odom
,odom_frame
,base_frame
,publish_tf
,broadcast_tf
等参数。 - 从你的配置来看,
enable_odom
是启用的,odom_frame
设置为odom
,base_frame
设置为base_footprint
,publish_tf
和broadcast_tf
也都是启用的。这些设置看起来是正确的。
- 确保你的 diff drive 插件配置正确,特别是
-
TF 树中的时间戳:
- 在你提供的
/tf
话题数据中,odom
到map
的转换时间戳为 0,这可能表示这个转换没有更新。确保 Gazebo 中的定位或 SLAM 节点(如 AMCL 或其他定位算法)正在发布有效的/odom
数据,并且时间戳是更新的。 - 同时,
base_link
到各个轮子(如wheel_front_left
)的转换有时间戳,这表明这些 TF 是由机器人状态发布者或其他节点正确发布的。
- 在你提供的
-
URDF/SDF 文件:
- 确保你的 URDF/SDF 文件中
base_footprint
和base_link
之间的关系定义正确。通常,base_footprint
是固定在base_link
下方的一个点,用于表示机器人的地面接触点。 - 检查是否有其他 TF 发布者在干扰或覆盖
odom
到base_footprint
的转换。
- 确保你的 URDF/SDF 文件中
-
机器人状态发布者:
robot_state_publisher
节点是否接收到正确的joint_states
?这个节点负责根据joint_states
和 URDF/SDF 文件构建 TF 树。- 确保
joint_state_publisher
节点正在运行,并且接收到了所有必要的关节状态信息。
-
调试步骤:
- 使用
ros2 topic echo /odom
查看odom
话题的详细内容,确保它包含了有效的位置和姿态信息。 - 使用
ros2 topic echo /joint_states
查看关节状态信息,确保所有必要的关节都在发布状态。 - 检查是否有任何日志或错误信息表明 TF 转换失败或存在冲突。
- 使用
-
代码和环境:
- 确保你的 ROS 2 环境(包括 Gazebo 插件和 ROS 2 桥接器)都是最新的,并且兼容你使用的 ROS 2 版本(Humble)。
-
重新启动和清理:
- 有时候,重新启动你的 ROS 2 节点和 Gazebo 实例可以解决一些不一致的问题。
- 确保在每次测试前彻底清理之前的会话和日志,以避免旧数据的干扰。
如果以上步骤都无法解决问题,你可能需要更深入地检查你的 Gazebo 仿真设置,或者考虑是否有其他软件或配置错误影响了 TF 的发布。希望这些步骤能帮助你找到问题的根源并解决它!
以上为生成回答,仅供参考~
-
-
使用命令:ros2 topic echo /joint_states 查看该话题数据如下:
header: stamp: sec: 1731556308 nanosec: 154098513 frame_id: '' name: - wheel_front_left_joint - wheel_front_right_joint - wheel_rear_left_joint - wheel_rear_right_joint position: - 0.0 - 0.0 - 0.0 - 0.0 velocity: [] effort: []
-
从您提供的
ros2 topic echo /joint_states
命令的输出数据中,我们可以看到/joint_states
话题包含了机器人关节的状态信息。以下是对该输出数据的详细解释:-
header:
- stamp: 时间戳,表示该数据消息被发布的时间。
- sec: 秒,从1970年1月1日(UTC)开始的秒数,这里是
1731556308
秒。 - nanosec: 纳秒,用于提供更精确的时间信息,这里是
154098513
纳秒。
- sec: 秒,从1970年1月1日(UTC)开始的秒数,这里是
- frame_id: 坐标系ID,这里为空字符串
''
,表示没有指定特定的参考坐标系。
- stamp: 时间戳,表示该数据消息被发布的时间。
-
name:
- 这是一个字符串列表,列出了当前发布状态的所有关节的名称。
- 关节名称包括:
wheel_front_left_joint
: 前左轮关节wheel_front_right_joint
: 前右轮关节wheel_rear_left_joint
: 后左轮关节wheel_rear_right_joint
: 后右轮关节
-
position:
- 这是一个浮点数列表,表示每个关节的位置(通常是角度或位移,取决于关节类型)。
- 所有关节的位置都是
0.0
,表明这些关节当前都处于其初始或参考位置。
-
velocity:
- 这是一个空的浮点数列表,表示没有提供关于关节速度的信息。
- 这可能是因为当前没有监测或发布关节速度数据。
-
effort:
- 这也是一个空的浮点数列表,表示没有提供关于关节所施加的努力(如扭矩或力)的信息。
- 同样,这可能是因为当前没有监测或发布这类数据。
总结:
/joint_states
话题提供了关于机器人四个轮子关节的位置信息。- 所有关节的位置均为
0.0
,且没有提供速度和努力的数据。 - 如果需要更多信息(如速度和努力),可能需要检查机器人系统是否配置为发布这些额外的状态信息。
以上为生成回答,仅供参考~
-
-
@小伊
我使用rviz2 打开TF topic发现有问题:
map->base_frontprint 和odom->baseprint 是没有的,具体截图如下:
-
由于我无法直接查看你提供的截图,我将基于你描述的问题提供一些可能的解决方案和检查步骤。你提到在RViz2中打开TF(Transform)topics时发现
map->base_frontprint
和odom->baseprint
这两个转换不存在。这里有几个可能的原因和解决方法:-
检查TF发布:
- 确认是否有节点正在发布
map->base_frontprint
和odom->baseprint
这两个转换。你可以使用ros2 topic list
查看所有发布的主题,然后使用ros2 topic echo /tf [message_type]
(通常message_type
是tf2_msgs/msg/TFMessage
)来查看TF消息的内容。 - 确认TF广播的帧名称是否正确。根据你提供的信息,可能存在拼写错误(例如
base_frontprint
可能应该是base_footprint
)。
- 确认是否有节点正在发布
-
检查节点和包:
- 确认是否有相关的节点(如定位节点、SLAM节点等)正在运行,并且这些节点负责发布TF转换。
- 检查是否有相关的ROS2包被正确安装和配置。
-
检查RViz2配置:
- 在RViz2中,确保你已经添加了TF显示项(通常是通过Add -> By display type -> TF)。
- 检查在RViz2的TF显示设置中,是否选择了正确的坐标系(Fixed Frame)。通常,这可以是
map
、odom
或base_link
等。
-
检查启动文件或配置文件:
- 如果你使用启动文件(如
.launch.py
或.launch.xml
),检查是否所有必要的节点都被正确启动。 - 检查是否有任何参数被错误设置,这可能影响到TF的发布。
- 如果你使用启动文件(如
-
查看日志和错误信息:
- 使用
ros2 node list
查看所有活动的节点。 - 使用
ros2 node info /node_name
查看特定节点的详细信息。 - 查看ROS2的日志输出(通常通过
ros2 console
或直接在终端中查看),查找可能的错误信息或警告。
- 使用
-
重启ROS2系统:
- 有时候,简单地重启ROS2系统(停止所有节点,然后重新启动它们)可以解决TF相关的问题。
-
确保时间同步:
- 在使用多节点和TF时,确保所有节点都使用相同的时间源(如ROS2的时间服务)。时间不同步可能导致TF问题。
如果上述步骤都不能解决问题,你可能需要更详细地检查你的系统配置或寻求来自ROS2社区或特定ROS2包的帮助。
以上为生成回答,仅供参考~
-