鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    ROS2无法建立起odom->base_footprint之间的tf2变换

    已定时 已固定 已锁定 已移动
    机器人学
    nav2 ros2 nav2amcl ros2
    1
    1
    63
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • T
      td
      最后由 td 编辑

      使用里程计发布odom话题,并建立odom->base_footprint的之间tf2变换,代码如下:

      import rclpy
      from rclpy.node import Node
      from nav_msgs.msg import Odometry
      import tf2_ros
      from tf2_ros import TransformBroadcaster
      from geometry_msgs.msg import TransformStamped
      import math
       
      class OdometryPublisher(Node):
          def __init__(self):
              super().__init__('odom_tf')
              self.publisher = self.create_publisher(Odometry, 'odom', 10)
              self.timer = self.create_timer(0.1, self.publish_odometry)
              self.odom_frame_id = 'odom'
              self.child_frame_id = 'base_link'
              self.odom_broadcaster = TransformBroadcaster(self)
       
              # 初始化里程计变量
              self.x = 1.0
              self.y = -30.0
              self.theta = 1.0
      
              self.vx = 0.0  # 例子中使用的线速度
              self.vtheta = 0.0  # 例子中使用的角速度
       
          def publish_odometry(self):
              # 更新里程计信息
              self.x += self.vx * math.cos(self.theta)
              self.y += self.vx * math.sin(self.theta)
              self.theta += self.vtheta
       
              # 发布TransformStamped消息
              odom_trans = TransformStamped()
              odom_trans.header.stamp = self.get_clock().now().to_msg()
              odom_trans.header.frame_id = self.odom_frame_id
              odom_trans.child_frame_id = self.child_frame_id
              odom_trans.transform.translation.x = self.x
              odom_trans.transform.translation.y = self.y
              odom_trans.transform.rotation.w = math.cos(self.theta / 2)
              odom_trans.transform.rotation.z = math.sin(self.theta / 2)
              self.odom_broadcaster.sendTransform(odom_trans)
       
              # 发布Odometry消息
              odom_msg = Odometry()
              odom_msg.header.stamp = self.get_clock().now().to_msg()
              odom_msg.header.frame_id = self.odom_frame_id
              odom_msg.child_frame_id = self.child_frame_id
              odom_msg.pose.pose.position.x = self.x
              odom_msg.pose.pose.position.y = self.y
              odom_msg.pose.pose.orientation.w = math.cos(self.theta / 2)
              odom_msg.pose.pose.orientation.z = math.sin(self.theta / 2)
              odom_msg.twist.twist.linear.x = self.vx
              odom_msg.twist.twist.angular.z = self.vtheta
       
              self.publisher.publish(odom_msg)
       
      def main(args=None):
          rclpy.init(args=args)
          node = OdometryPublisher()
          rclpy.spin(node)
          rclpy.shutdown()
       
      if __name__ == '__main__':
          main()
      

      tf树也显示了连接:
      b42b957d-d3e3-4bc8-8254-effdcff8892f-图片.png
      但是无法建立map->odom之间的联系,而且在rviz2里面以odom为Fixed Frame,也没有雷达点云信息
      bd696441-5129-43b9-a0b9-cbdf52951323-截图 2025-06-17 15-33-24.png
      如果使用终端发布固定tf2变换,就可以建立odom与雷达之间的联系

      ros2 run tf2_ros static_transform_publisher 0 0 0 0 0 0 odom base_footprint
      

      4441e174-3360-4e49-b56d-a7da8a4d39ca-截图 2025-06-17 15-35-37.png
      而且也建立了map->odom之间的tf2变换,也可以进行导航,只不过机器人无法相对于map进行移动
      9df62140-5bf2-442e-9b8d-7007612c0e42-图片.png
      829fc4df-98e1-4852-b33e-5d061d72bae2-图片.png

      1 条回复 最后回复 回复 引用 0
      • 第一个帖子
        最后一个帖子
      皖ICP备16016415号-7
      Powered by NodeBB | 鱼香ROS