ROS学习笔记(十五)TF介绍(三)

TF介绍(三)

tf in python

tf中有C++接口,也有Python接口,tf在Python中的具体实现相对比较简单。

数据类型:

TF的相关数据类型,向量、点、四元数。矩阵的=都可以表示成类似于数组的形式(Tuple、List、Numpy Array表示)。
如:

t = (1.0,1.5,1.0)	#平移
q = [1,0,0,0]	#四元数
m = numpy.identity(3)	#旋转矩阵

t平移数据用Tuple表示的,也可以用List表示(t = [1.0,1.5,1.0]),也能用numpy.array(1.0,1.5,0)表示。数据类型没有特殊的对应,都是通用的,也就没有数据类型的转换。

TF库

tf.trabsformations

基本数学运算函数:

函数 注释
euler_matrix(ai,aj,ak,axes=‘sxyz’) 欧拉角到矩阵
euler_from_matrix(matrix,axes=‘sxyz’) 矩阵到欧拉角
euler_quaternion(quaternion,axes=‘sxyz’) 四元数到欧拉角
quaternion_from_euler(ai,aj,ak,axes=‘sxyz’) 欧拉角到四元数
quaternion_matrix(quaternion) 四元数到矩阵
quaternion_from_matrix() 矩阵到四元数

在使用函数库的时候,首先要import tf,tf.transformations给我们提供了基本的数学运算函数,使用较方便。

1. 定义空间点和空间向量

函数名称 函数功能
tf.transformations.random_quaternion(rand=None) 返回均匀随机单位四元数
tf.transformations.random_rotation_matrix(rand=None) 返回均匀随机单位旋转矩阵
tf.transformations.random_vector(size) 返回均匀随机单位向量
tf.transformations.translation_matrix(v) 通过向量来求旋转矩阵
tf.transformations.translation_from_matrix(m) 通过旋转矩阵来求向量

2. 定义四元数

函数名称 函数功能
tf.transformations.quaternion_about_axis(angle axis) 通过旋转轴和旋转角返回四元数
tf.transformations.quaternion_conjugate(quaternion) 返回四元数的共轭
tf.transformations.quaternion_from_euler() 从欧拉角和旋转轴,求四元数
tf.transformations_from_matrix(matrix) 从旋转矩阵中,返回四元数
tf.transformations.quaternion_multiply(quaternion1,quaternion2) 两个四元数相乘

文件位置:test/scripts/py_coordinate_transformation.py

#!/usr/bin/env python
#coding=utf-8

import rospy
import tf
import math

if __name__ == '__main__':
	rospy.init_node("py_coordinate_transformation")

	print '第1部分,定义空间点和空间向量'
	q = tf.transformations.random_quaternion(rand=None)
    print '定义均匀随机四元数:'
    print q

	m = tf.transformations.random_rotation_matrix(rand=None)
	print '定义均匀随机单位旋转矩阵:'
	print m
	
	v = tf.transformations.rand_vector(3)
	print '定义均匀随机单位向量:'
	print v
	
	v_m = tf.transformation.translation_matrix(v)
	print '通过向量来求旋转矩阵:'
	print v_m

	m_v = tf.transformation.translation_from_matrix(m)
	print '通过旋转矩阵来求向量:'
	print m_v
	
	print '第2部分,定义四元数'
	axis_q = tf.transformations.quaternion_about_axis(0.123,(1,0,0))
	print '通过旋转轴和旋转角返回四元数:'
	print axis_q
	
	n_q = tf.transformations.quaternion_conjugate(q)
	print '返回四元数q的共轭:'
	print n_q
	
	m_q = tf.transformations.quaternion_from_matrix(m)
	print '从旋转矩阵中,返回四元数:'
	print m_q

	qxq = tf.transformations.quaternion_multiply(q,n_q)
	print '两个四元数相乘'
	print  qxq   

TF类

tf.transformListener类

方法 作用
canTransform(self,target_frame,source_frame,time) frame是否相通
waitForTransform(self,target_frame,source_target,time,timeout) 阻塞直到frame相通
lookupTransform(self,target_frame,source_frame,time) 查看相对的tf,返回(trans,quat)

time参数使用rospy.Time(0),不是rospy::time::now()

方法 作用
chain(target_frame,source_frame,source_time,fixed_frame) frame的连接关系
frameExists(self,frame_id) frame是否存在
getFrameString(self) 返回所有tf的名称
fromTranslationRotation(translation,rotation) 根据平移和旋转返回4X4矩阵
transformPoint(target_frame,point_msg) 将PointStamped消息转换到新frame下
transformPose(target_frame,pose_msg) 将PoseStamped消息转换到新frame下
transformQuaternion(target_frame,quat_msg) 将QuaternionStamped…返回相同类型

文件位置:test/scripts/py_tf_listerner.py

#!/usr/bin/env python
#coding=utf-8

import ros
import tf
import math

if __name__ == '__main__':
	rospy.init_node("py_tf_listener")
	listener = tf.transdormListener()	#TransformListener创建后就开始接收tf广播信息,最多可以缓存10s
	rate = rospy.Rate(1.0)
	
	print '1. 阻塞直到frame相通'  
	listener.waitForTransform('/base_link','/link1',rospy.Time(0),rospy.Duration(4))	#rospy.Time(0)不表示0时刻的tf,是指最近的一帧
	while not rospy.is_shutdown():
		try:
			 print '2. 监听对应的tf,返回平移和旋转'  
			 (trans,rot) = listener.lookupTransform('/base_link','/link1',rospy.Time(0))
		except(tf.lookupException,tf.ConnectivityException,tf.ExtrapolationException):
		continue
		rospy.loginfo('距离原点的位置:x=%f,y=%f,z=%f\n旋转四元数:w=%f,x=%f,y=%f,z=%f',trans[0],trans[1],trans[2],rot[0],rot[1],rot[2],rot[3])
		print '3. 判断两个frame是否相通'
		if listener.canTransform('/link1','base_link',rospy.Time(0)):
			print 'true'
		else:
			print 'false'
		rate.sleep()

tf.TransformBroadcaster类

成员函数有两个:

sendTransform(translation,rotation,time,child,parent)	#向/tf发布消息
sendTransformMessage(transform)	#向/tf发布消息

sendTransform()参数为平移、旋转、时间戳,从父到子的frame流,再发向/tf的topic。
sendTransformMessage(),是发送transform已经封装好了的Message给/tf。
这两种不同的发送方式功能一致。

文件位置:test/scripts/py_tf_broadcaster.py

#!/usr/bin/env python
#coding=utf-8

import rospy
import tf
import math

if __name__ == '__main__':
	rospy.init_node('py_tf_broadcaster')
	 print 'tf.transformBroadcaster类'
	 print '第1种发布方式:sendTransform(translation,rotation,time,child,parent)'
	 br = tf.transformBroadcaster()
	 x = 1.0
	 y=2.0
     z=3.0  
     roll=0 
     pitch=0
     yaw=1.57
     rate = rospy.Rate(1)
     while not rospy.is_shutdown():
     	yaw += 0.1
     	br.sendTransform((x,y,z),tf.transformations.quaternion_from_euler(roll,pitch,yaw),rospy.Time(0),'base_link','link1')
     	rate.sleep()
     	

文件位置:test/scripts/py_tf_broadcaster02.py

#!/usr/bin/env python
#coding=utf-8

import rospy
import geometry_msgs.msg
import tf
import math

if __name__ == '__main__':
	rospy.init_node('py_tf_broadcaster')
	print 'tf.transformBroadcaster类'
	print '第2种发布方式:sendTransformMessage(transform)'
	br = tf.TransformBroadcaster()
	t = geometry_msgs.msg.TransformStamped()
	t.header.frame_id = 'base_link'
	t.header.stamp = rospy.Time(0)
	t.child_frame_id = 'link1';
	t.transform.translation.x = 1
	t.transform.translation.y = 2
	t.transform.translation.z = 3
	t.transform.rotation.w = 1
	t.transform.rotation.x = 0
	t.transform.rotation.y = 0
	t.transform.rotation.z = 0
	rate = rospy.Rate(1)
	while not rtospy.is_shutdown():
		br.sendTransformMessage(t)
		rate.sleep()

TF相关工具命令

1.根据当前tf树创建一个PDF图

rosrun tf view_frames

首先订阅/tf,订阅5秒,根据这段时间接收道德tf信息,绘制成一张tf tree,再创建一个PDF图
2. 查看当前tf树

rosrun rqt_tf_tree rqt_tf_tree

查询tf tree,与上一个命令区别是该命令动态查询当前tf tree,当前的任何变化都能当即看到,如何时断开连接,捕捉到这些然后通过rqt插件显示出来。
3. 查看两个frame之间的变换关系

rosrun tf tf_echo[reference_frame][target_frame]

你可能感兴趣的:(ROS学习笔记,python,linux,人工智能)