Waiting for TransformListener with ROS2 and Python?
I'm trying to build code that listens to transforms between two frames. About 50% of the time that I run the following code I get an error:
"tf2.LookupException: "front_bumper" passed to lookupTransform argument target_frame does not exist."
As far as I can tell, passing in any value for Duration has no effect despite what I believe the C++ documentation suggests.
What is the right way to wait for the transform to show up? Am I better off trying to do this in C++?
Environment is Ubuntu 20.04.1 LTS & ROS2 Foxy
#! /usr/bin/env python
from math import sin, cos, pi
import threading
import rclpy
import time
from rclpy.duration import Duration
from rclpy.node import Node
from rclpy.qos import QoSProfile
from geometry_msgs.msg import Quaternion
from sensor_msgs.msg import JointState
from tf2_ros import TransformBroadcaster, TransformListener, TransformStamped, Buffer
class StatePublisher(Node):
def __init__(self):
rclpy.init()
super().__init__('state_publisher')
self.nodeName = self.get_name()
self.get_logger().info("{0} started".format(self.nodeName))
tfBuffer = Buffer()
listener = TransformListener(tfBuffer, self)
try:
while rclpy.ok():
rclpy.spin_once(self)
now = self.get_clock().now()
dur = Duration()
dur.sec = 40
dur.nsec = 0
trans = tfBuffer.lookup_transform('front_bumper', 'base_link', now, dur )
self.get_logger().info("\n")
self.get_logger().info("Translation:")
self.get_logger().info( "x:" + str( trans.transform.translation.x ) )
self.get_logger().info( "y:" + str( trans.transform.translation.y ) )
self.get_logger().info( "z:" + str( trans.transform.translation.z ) )
self.get_logger().info("Rotation (in quaternion):")
self.get_logger().info( "w:" + str( trans.transform.rotation.w ) )
self.get_logger().info( "x:" + str( trans.transform.rotation.x ) )
self.get_logger().info( "y:" + str( trans.transform.rotation.y ) )
self.get_logger().info( "z:" + str( trans.transform.rotation.z ) )
time.sleep(1)
except KeyboardInterrupt:
pass
def main():
node = StatePublisher()
if __name__ == '__main__':
main()
~