目录
第5章 ROS常用开发工具
5.1 坐标变换工具介绍
5.1.1 通过命令行使用TF
1. 新打开一个终端,建立base_link到base_laser的坐标关系
ros2 run tf2_ros static_transform_publisher --x 0.1 --y 0.0 --z 0.2 --roll 0.0 --pitch 0.0 --yaw 0.0 --frame-id base_link --child-frame-id base_laser
2. 新打开一个终端,建立base_laser到wall_point的坐标关系
ros2 run tf2_ros static_transform_publisher --x 0.1 --y 0.0 --z 0.2 --roll 0.0 --pitch 0.0 --yaw 0.0 --frame-id base_laser --child-frame-id wall_point
3. 新打开一个终端,查询base_link到wall_point的坐标关系,会一直运行这个查询程序
ros2 run tf2_ros tf2_echo base_link wall_point
4. 安装3D旋转可视化
sudo apt install ros-humble-mrpt2 -y 无法定位软件包Unable to locate package ros-humble-mrpt2
使用 sudo apt install mrpt-apps 可以安装成功
5. 打开3d旋转可视化窗口
3d-rotation-converter
6. 查看TF树,导出至PDF文件中,需要同时运行1和2步的两个终端指令
ros2 run tf2_tools view_frames
5.1.2 对TF原理的简单探究
1. ros2 topic list查看话题
/parameter_events
/rosout
/tf_static
2. 查看话题tf_static,ros2 topic info /tf_static
Type: tf2_msgs/msg/TFMessage
Publisher count: 2
Subscription count: 0
3. 查看消息接口的定义,ros2 interface show tf2_msgs/msg/TFMessage
geometry_msgs/TransformStamped[] transforms
#
#
std_msgs/Header header 成员变量
builtin_interfaces/Time stamp 时间戳
int32 sec
uint32 nanosec
string frame_id 父坐标系名字
string child_frame_id 子坐标系名字
Transform transform
Vector3 translation
float64 x
float64 y
float64 z
Quaternion rotation
float64 x 0
float64 y 0
float64 z 0
float64 w 1
4. 订阅话题,ros2 topic echo /tf_static,显示话题内容
tf_static是静态坐标发布,tf是动态坐标发布
5.2 Python中的手眼坐标变换
5.2.1 通过Python发布静态TF
1. 安装两个库
sudo apt install ros-$ROS_DISTRO-tf-transformations
2.创建新的文件夹chapt5/chapt5_ws/src,在src下创建功能包
ros2 pkg create --build-type ament_python --dependencies rclpy geometry_msgs tf_ros tf_transformations --license Apache-2.0 demo_python_tf
3. 新建文件chapt5/chapt5_ws/src/demo_python_tf/demo_python_tf/static_tf_broadcast.py
import rclpy
from rclpy.node import Node
# 静态坐标发布器
from tf2_ros import StaticTransformBroadcaster
# 消息接口
from geometry_msgs.msg import TransformStamped
# 欧拉角转四元数
from tf_transformations import quaternion_from_euler
# 用于将角度转弧度
import math
class StaticTFBroadcaster(Node):
def __init__(self):
super().__init__('static_tf_broadcaster')
# 创建一个坐标发布器对象
self.static_broadcaster_ = StaticTransformBroadcaster(self)
self.publish_static_tf()
# 发布静态TF 从base_link到camera_link的坐标关系
def publish_static_tf(self):
# 创建一个消息接口对象
transform = TransformStamped()
# 对消息接口transform进行成员赋值
# 父坐标系名称
transform.header.frame_id = 'base_link'
# 子坐标系名称
transform.child_frame_id = 'camera_link'
# 时间
transform.header.stamp = self.get_clock().now().to_msg()
# 坐标关系
transform.transform.translation.x = 0.5
transform.transform.translation.y = 0.3
transform.transform.translation.z = 0.6
# 角度换算,欧拉角转四元数,返回一个元组q = x,y,z,w
q = quaternion_from_euler(math.radians(180),0,0)
transform.transform.rotation.x = q[0]
transform.transform.rotation.y = q[1]
transform.transform.rotation.z = q[2]
transform.transform.rotation.w = q[3]
# 发布静态坐标关系
self.static_broadcaster_.sendTransform(transform)
self.get_logger().info(f'发布静态坐标:{transform}')
def main():
rclpy.init()
node = StaticTFBroadcaster()
rclpy.spin(node)
rclpy.shutdown()
4. 修改setup.py
entry_points={
'console_scripts': [
'static_tf_broadcast = demo_python_tf