33 from __future__
import print_function
43 from geometry_msgs.msg
import TransformStamped
48 The following euler conversion functions are from https://github.com/matthew-brett/transforms3d 49 which adapted it from transformations.py, it is needed here until transforms3d is available 52 They are for internal use only. 56 _EPS = numpy.finfo(float).eps * 4.0
59 _NEXT_AXIS = [1, 2, 0, 1]
64 'sxyz': (0, 0, 0, 0),
'sxyx': (0, 0, 1, 0),
'sxzy': (0, 1, 0, 0),
65 'sxzx': (0, 1, 1, 0),
'syzx': (1, 0, 0, 0),
'syzy': (1, 0, 1, 0),
66 'syxz': (1, 1, 0, 0),
'syxy': (1, 1, 1, 0),
'szxy': (2, 0, 0, 0),
67 'szxz': (2, 0, 1, 0),
'szyx': (2, 1, 0, 0),
'szyz': (2, 1, 1, 0),
68 'rzyx': (0, 0, 0, 1),
'rxyx': (0, 0, 1, 1),
'ryzx': (0, 1, 0, 1),
69 'rxzx': (0, 1, 1, 1),
'rxzy': (1, 0, 0, 1),
'ryzy': (1, 0, 1, 1),
70 'rzxy': (1, 1, 0, 1),
'ryxy': (1, 1, 1, 1),
'ryxz': (2, 0, 0, 1),
71 'rzxz': (2, 0, 1, 1),
'rxyz': (2, 1, 0, 1),
'rzyz': (2, 1, 1, 1)}
74 """temporaray import from https://github.com/matthew-brett/transforms3d/blob/master/transforms3d/_gohlketransforms.py for internal use only""" 76 firstaxis, parity, repetition, frame = _AXES2TUPLE[axes.lower()]
77 except (AttributeError, KeyError):
79 firstaxis, parity, repetition, frame = axes
82 j = _NEXT_AXIS[i+parity]
83 k = _NEXT_AXIS[i-parity+1]
85 M = numpy.array(matrix, dtype=numpy.float64, copy=
False)[:3, :3]
87 sy = math.sqrt(M[i, j]*M[i, j] + M[i, k]*M[i, k])
89 ax = math.atan2( M[i, j], M[i, k])
90 ay = math.atan2( sy, M[i, i])
91 az = math.atan2( M[j, i], -M[k, i])
93 ax = math.atan2(-M[j, k], M[j, j])
94 ay = math.atan2( sy, M[i, i])
97 cy = math.sqrt(M[i, i]*M[i, i] + M[j, i]*M[j, i])
99 ax = math.atan2( M[k, j], M[k, k])
100 ay = math.atan2(-M[k, i], cy)
101 az = math.atan2( M[j, i], M[i, i])
103 ax = math.atan2(-M[j, k], M[j, j])
104 ay = math.atan2(-M[k, i], cy)
108 ax, ay, az = -ax, -ay, -az
114 """temporaray import from https://github.com/matthew-brett/transforms3d/blob/master/transforms3d/_gohlketransforms.py for internal use only""" 115 q = numpy.array(quaternion, dtype=numpy.float64, copy=
True)
118 return numpy.identity(4)
119 q *= math.sqrt(2.0 / n)
120 q = numpy.outer(q, q)
122 [1.0-q[2, 2]-q[3, 3], q[1, 2]-q[3, 0], q[1, 3]+q[2, 0], 0.0],
123 [ q[1, 2]+q[3, 0], 1.0-q[1, 1]-q[3, 3], q[2, 3]-q[1, 0], 0.0],
124 [ q[1, 3]-q[2, 0], q[2, 3]+q[1, 0], 1.0-q[1, 1]-q[2, 2], 0.0],
125 [ 0.0, 0.0, 0.0, 1.0]])
128 """temporaray import from https://github.com/matthew-brett/transforms3d/blob/master/transforms3d/_gohlketransforms.py for internal use only""" 154 rospy.signal_shutdown(
"tf echo finished")
157 cur_time = rospy.Time.now()
161 lookup_time = rospy.Time(self.
args.time)
162 elif self.
args.offset:
164 lookup_time = cur_time + rospy.Duration(self.
args.offset)
167 lookup_time = rospy.Time()
171 self.
args.target_frame,
174 msg =
"At time {}, (current time {}) ".format(lookup_time.to_sec(), cur_time.to_sec())
175 rospy.logerr(msg + str(ex))
178 msg =
"(current time {}) ".format(cur_time.to_sec())
179 rospy.logerr(msg + str(ex))
185 msg =
"At time {}, (current time {})".format(ts.header.stamp.to_sec(), cur_time.to_sec())
186 xyz = ts.transform.translation
187 msg +=
"\n- Translation: [{:.{p}f}, {:.{p}f}, {:.{p}f}]\n".format(xyz.x, xyz.y, xyz.z, p=self.
args.precision)
188 quat = ts.transform.rotation
189 msg +=
"- Rotation: in Quaternion [{:.{p}f}, {:.{p}f}, {:.{p}f}, {:.{p}f}]\n".format(quat.x, quat.y, quat.z, quat.w, p=self.
args.precision)
193 msg +=
" in RPY (radian) " 194 msg +=
"[{:.{p}f}, {:.{p}f}, {:.{p}f}]\n".format(euler[0], euler[1], euler[2], p=self.
args.precision)
195 msg +=
" in RPY (degree) " 196 msg +=
"[{:.{p}f}, {:.{p}f}, {:.{p}f}]".format(math.degrees(euler[0]),
197 math.degrees(euler[1]),
198 math.degrees(euler[2]), p=self.
args.precision)
204 raise argparse.ArgumentTypeError(
"{} must be > 0.0".format(x))
210 raise argparse.ArgumentTypeError(
"{} must be > 0".format(x))
213 if __name__ ==
'__main__':
214 rospy.init_node(
"echo")
216 other_args = rospy.myargv(argv=sys.argv)
219 precision = rospy.get_param(
'~precision')
220 rospy.loginfo(
"Precision default value was overriden, new value: %d", precision)
224 parser = argparse.ArgumentParser()
225 parser.add_argument(
"source_frame")
226 parser.add_argument(
"target_frame")
227 parser.add_argument(
"-r",
"--rate",
228 help=
"update rate, must be > 0.0",
231 parser.add_argument(
"-c",
"--cache_time",
232 help=
"length of tf buffer cache in seconds",
234 parser.add_argument(
"-o",
"--offset",
235 help=
"offset the lookup from current time, ignored if using -t",
237 parser.add_argument(
"-t",
"--time",
238 help=
"fixed time to do the lookup",
240 parser.add_argument(
"-l",
"--limit",
241 help=
"lookup fixed number of times",
243 parser.add_argument(
"-p",
"--precision",
244 help=
"output precision",
247 args = parser.parse_args(other_args[1:])
def _euler_from_quaternion_msg(quaternion)
def _euler_from_matrix(matrix, axes='sxyz')
def _quaternion_matrix(quaternion)
def _euler_from_quaternion(quaternion, axes='sxyz')