rospy setting StampedTransform attributes simultaneously

asked 2017-07-05 16:10:23 -0500

jwhendy gravatar image

I'm going through the tf2 tutorials and can't help but think this looks pretty verbose:

br = tf2_ros.TransformBroadcaster()
t = geometry_msgs.msg.TransformStamped()

t.header.stamp = rospy.Time.now()
t.header.frame_id = "world"
t.child_frame_id = turtlename

t.transform.translation.x = msg.x
t.transform.translation.y = msg.y
t.transform.translation.z = 0.0
q = tf.transformations.quaternion_from_euler(0, 0, msg.theta)
t.transform.rotation.x = q[0]
t.transform.rotation.y = q[1]
t.transform.rotation.z = q[2]
t.transform.rotation.w = q[3]

br.sendTransform(t)

Is this this the best/preferred way to set this? I tried fiddling around but didn't get very far... I wondered if a dict could be passed, or perhaps __setattr__ could be used (seemed to only want to take one value at a time).

Having finished the tf tutorials, I also notice that the "old way" appears to be constructing the coordinate info on the fly and just sending it vs. storing it just to send (I see no other use of t).

br.sendTransform((msg.x, msg.y, 0),
                 tf.transformations.quaternion_from_euler(0, 0, msg.theta),
                 rospy.Time.now(),
                 turtlename,
                 "world")

This didn't work for tf2, but in investigating the TransformStamped msg, it's composed of several others. Just to illustrate a different way, I composed elements of t separately with their component messages. I'm not sure if the verbosity is any less, but I do like how it deals with q, as it's a little more transparent about what's going on vs. just accessing the indices by number:

t = geometry_msgs.msg.TransformStamped()                                  
t.header = std_msgs.msg.Header(stamp=rospy.Time.now(),
                               frame_id='world')

t.child_frame_id = turtlename

t.transform.translation = geometry_msgs.msg.Vector3(x=msg.x,
                                                    y=msg.y,
                                                    z=0)

qx, qy, qz, qw = tf.transformations.quaternion_from_euler(0, 0, msg.theta)
t.transform.rotation = geometry_msgs.msg.Quaternion(x=qx,
                                                    y=qy,
                                                    z=qz,
                                                    w=qw)

Are there better, more elegant ways to define a message for this purpose, or is the original tf2 tutorial method sort of "what everyone does in ROS"?

edit retag flag offensive close merge delete

Comments

IIRC, the initializing constructor for messages in rospy didn't exist until fairly recently. I think the tutorial was written before it was available.

Ed Venator gravatar image Ed Venator  ( 2017-07-07 23:35:12 -0500 )edit

Can you point me toward the constructor or an example based on the above? It sounds like this would facilitate what I'm asking, but I've not heard of it. Googling, I get this promising issue, but it's old and without recent activity.

jwhendy gravatar image jwhendy  ( 2017-07-09 19:13:33 -0500 )edit