ROS 动态坐标变换

ROS 动态坐标变换

案例:实现小乌龟运动时,实时显示乌龟位姿与原点的相对关系,并能够在rviz中实时观察到两坐标的相对位置

实现思路:发布方订阅乌龟运动的位姿信息,建立乌龟(子级坐标系)与原点(父级坐标系)并发布相对关系,订阅方订阅到两坐标系并输出乌龟相对原点的动态变换坐标。

注意:这里的发布方订阅了内置节点乌龟运动的信息,其实是个嵌套实现

①发布方编码实现

#! /usr/bin/env python
import rospy
from turtlesim.msg import Pose
import tf2_ros
from geometry_msgs.msg import TransformStamped
import tf.transformations
"""
发布方实现:
订阅乌龟的位姿信息,转换成坐标系的相对关系并发布
准备:了解乌龟位姿的话题和消息类型:话题是turtle1/pose,类型turtlesim/Pose
流程:
1、导包
2、初始化ros节点
3、创建订阅对象
4、回调函数处理订阅到的消息(核心)
5、spin()
"""
def doPose(pose):
    #创建发布坐标系相对关系的对象
    pub = tf2_ros.TransformBroadcaster()
    #将Pose转换成坐标系相对关系的消息
    ts = TransformStamped()
    ts.header.frame_id = "world"
    ts.header.stamp = rospy.Time.now()
    ts.child_frame_id = "turtle1"
    #transform,坐标系子级坐标系相对于父级坐标系的偏移量
    ts.transform.translation.x = pose.x
    ts.transform.translation.y = pose.y
    ts.transform.translation.z = 0
    #ts下的rotation,通过四元数设置方向上的偏转角(一般需要一个欧拉角的转换过程)
    """
    乌龟是2D对象,不存在x向的翻滚,y向的俯仰,只有z向上的转向(偏航)
    欧拉角(0,0 ,pose.theta)
    """
    qtn = tf.transformations.quaternion_from_euler(0,0,pose.theta)
    ts.transform.rotation.x = qtn[0]
    ts.transform.rotation.y = qtn[1]
    ts.transform.rotation.z = qtn[2]
    ts.transform.rotation.w = qtn[3]
    #发布
    pub.sendTransform(ts)   

if __name__=="__main__":
    rospy.init_node("dynamic_pub")
    #创建订阅对象
    sub = rospy.Subscriber("/turtle1/pose",Pose,doPose,queue_size = 100)
    rospy.spin()

②订阅方编码实现

  这里要格外注意时间戳要置0,采用rospy.Time(),如果仍然采用rospy.Time.now获取当前,坐标转换会因为时间戳相差较大而无法完成转换从而抛出异常。

#! /usr/bin/env python
import rospy
import tf2_ros
from tf2_geometry_msgs import tf2_geometry_msgs
"""
订阅方实现:
订阅坐标变换消息,传入被转换的坐标点,调用转换算法实现坐标转换
1、导包(用到什么包导入什么包)
2、初始化ros节点
3、创建订阅对象
4、组织被转换的坐标点
5、转换逻辑编写(调用tf封装算法)
6、输出转换结果B
7、spin()/spinonce()
"""

if __name__=="__main__":

    #初始化ros节点
    rospy.init_node("static_tf_pub")
    #创建订阅对象
    buffer = tf2_ros.Buffer() #创建缓存对象
    sub = tf2_ros.TransformListener(buffer)#将缓存对象传入
    #组织被转换的坐标点
    ps = tf2_geometry_msgs.PointStamped()
    #时间戳 0 
    ps.header.stamp = rospy.Time()
    ps.header.frame_id = "turtle1"
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        try:
            #转换:buffer提供了对应的转换函数
            ps_out = buffer.transform(ps,"world")
            rospy.loginfo("转换后的坐标结果:(%.2f,%.2f,%.2f)当前参考的坐标系:%s",ps_out.point.x,ps_out.point.y,ps_out.point.z,ps_out.header.frame_id) 
        except:
            rospy.logwarn("错误提示:%s",Exception)
        rate.sleep()

③运行

  启动roscore,启动乌龟GUI节点和键盘控制节点,分别rosrun发布方和订阅方,打开rviz,可以看到键盘控制乌龟运动时,会实时输出乌龟相对原点坐标的位置信息和坐标的动态变化图

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ROS中,可以使用tf2库来发布动态坐标变换。下面是一个简单的Python示例,演示如何发布从“base_link”到“camera_link”的动态坐标变换: ```python #!/usr/bin/env python import rospy import tf2_ros import geometry_msgs.msg if __name__ == '__main__': rospy.init_node('dynamic_transform_publisher') tfBuffer = tf2_ros.Buffer() listener = tf2_ros.TransformListener(tfBuffer) broadcaster = tf2_ros.TransformBroadcaster() rate = rospy.Rate(10.0) while not rospy.is_shutdown(): try: trans = tfBuffer.lookup_transform('base_link', 'camera_link', rospy.Time()) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException): rate.sleep() continue t = geometry_msgs.msg.TransformStamped() t.header.stamp = rospy.Time.now() t.header.frame_id = 'base_link' t.child_frame_id = 'camera_link' t.transform.translation.x = trans.transform.translation.x t.transform.translation.y = trans.transform.translation.y t.transform.translation.z = trans.transform.translation.z t.transform.rotation.x = trans.transform.rotation.x t.transform.rotation.y = trans.transform.rotation.y t.transform.rotation.z = trans.transform.rotation.z t.transform.rotation.w = trans.transform.rotation.w broadcaster.sendTransform(t) rate.sleep() ``` 在这个例子中,我们创建了一个tf2_ros.TransformBroadcaster对象,并在while循环中不断发布“base_link”到“camera_link”的动态坐标变换。我们使用tf2_ros.Buffer和tf2_ros.TransformListener对象来获取当前的坐标变换。注意,在try-except块中,我们使用rospy.Time()作为时间戳,这将使ROS使用最新的可用坐标变换。 运行这个脚本后,可以使用rviz来查看发布的坐标变换。打开rviz后,点击“Add”按钮,选择“TF”,然后点击“OK”。在弹出的窗口中,将“Fixed Frame”设置为“base_link”,然后点击“Add”按钮,选择“TF”,并将“Child Frame”设置为“camera_link”。现在,您应该能够看到rviz中的“camera_link”相对于“base_link”的动态坐标变换

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芝士就是力量蛙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值