ROS学习六、TF坐标系转换(2)

ROS学习六、TF坐标系转换(2)

tf消息

tf树通过Topic进行建立与维护。tf树的建立是从第一个父坐标系开始,根据父子frame之间的位姿消息,逐渐添加子叶(子frame),然后再根据消息进行父子frame间位姿的维护更新。tf树中每一对父子frame都依靠话题来传递位姿信息,这个话题就是 /tf

/tf话题包含了tf tree中所有父子坐标系之间的位姿变换关系消息,而父子坐标系之间的位姿又是通过一个Broadcaster节点发布的,典型的Broadcaster节点例如/robot_state_publisher,/joint_state_publisher等。

ROS提供了geometry_msg/Transformgeometry_msg/TransformStamped消息类型来表示frame之间的相对位姿关系:

# geometry_msg/TransformStamped
std_msgs/Header header
string child_frame_id
geometry_msgs/Transform transform
# ---------------------------------
# geometry_msg/Transform
geometry_msgs/Vector3 translation
geometry_msgs/Quaternion rotation

而/tf话题上的消息类型则是tf2_msgs/TFMessage

# tf2_msgs/TFMessage
geometry_msgs/TransformStamped[] transforms

可以看出,/tf上发布的消息是frame间位姿变换消息的数组,实际上就是由各父子frame间的位姿变换关系组成。

tf转换

在tf树中,如果两个frame之间是连通的,那么就可以通过数学运算(矩阵乘法)获得frame之间的位姿变换关系。

ROS中给出了通过代码进行tf转换的消息发布与接收方法,可以通过roscpp或rospy通过tf2_ros类来实现:

#  Broadcasting Transforms
tf2_ros::TransformBroadcaster
tf2_ros::TransformBroadcaster::sendTransform()

tf2_ros::StaticTransformBroadcaster
tf2_ros::StaticTransformBroadcaster::sendTransform()

# Using published Transforms
tf2_ros::Buffer
tf2_ros::TransformListener
tf2_ros::Buffer::canTransform()
tf2_ros::Buffer::lookupTransform()

# Using eigen to transform
tf2::eigenToTransform()
tf2::transformToEigen()
tf2::fromMsg()
tf2::toMsg()
tf2::doTransform()

总结

ROS中,可以采用TF(实际上是TF2)来实现各坐标系(frame)之间的位姿变换。

tf2中,BufferCore类作为坐标系位姿变换的底层实现,而tf2_ros::BufferInterface封装了tf2::BufferCore作为接口,然后再使用tf2_ros::Buffer、tf2_ros::BufferClient与tf2_ros::BufferServer进一步实现了该接口。

tf2_ros中,类TransformBroadcaster作为/tf话题的publisher,类TransformListener作为/tf话题的subscriber,/tf话题下的消息包含了所有父子frame之间的位姿变换。

tf2_ros还提供了canTransform和lookupTransform,可以通过这两个函数从/tf话题中得知任意两个frame间能否转换以及获得位姿转换矩阵。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS中,使用TF库来处理坐标系变换。首先,在你的ROS包中创建一个订阅器(Subscriber)来订阅TF话题,并在回调函数中将TF消息转换为Pose消息。 以下是一个示例代码: ```cpp #include <ros/ros.h> #include <tf/transform_listener.h> #include <geometry_msgs/PoseStamped.h> void tfCallback(const tf::tfMessage::ConstPtr& tfMsg) { // 创建一个TransformListener对象 tf::TransformListener listener; // 获取两个坐标系之间的变换 tf::StampedTransform transform; try{ listener.lookupTransform("map", "base_link", ros::Time(0), transform); } catch (tf::TransformException ex){ ROS_ERROR("%s",ex.what()); return; } // 将变换转换为Pose消息 geometry_msgs::PoseStamped poseMsg; poseMsg.header.stamp = ros::Time::now(); poseMsg.header.frame_id = "map"; poseMsg.pose.position.x = transform.getOrigin().x(); poseMsg.pose.position.y = transform.getOrigin().y(); poseMsg.pose.position.z = transform.getOrigin().z(); poseMsg.pose.orientation.x = transform.getRotation().x(); poseMsg.pose.orientation.y = transform.getRotation().y(); poseMsg.pose.orientation.z = transform.getRotation().z(); poseMsg.pose.orientation.w = transform.getRotation().w(); // 发布Pose消息 // ... } int main(int argc, char** argv) { ros::init(argc, argv, "tf_to_pose"); ros::NodeHandle nh; // 创建一个订阅器来订阅TF话题 ros::Subscriber sub = nh.subscribe("/tf", 10, tfCallback); // 创建一个发布器来发布Pose消息 // ... ros::spin(); return 0; } ``` 在回调函数中,我们首先创建了一个TransformListener对象,然后调用`lookupTransform()`方法获取两个坐标系之间的变换。注意,`lookupTransform()`方法的第一个参数是目标坐标系,第二个参数是源坐标系。在这个例子中,我们将获取从`base_link`坐标系到`map`坐标系的变换。 一旦我们获取了变换,我们就可以将其转换为Pose消息,并发布出去。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值