rclpy: Time
There are four separate ways that you may see time represented in ROS 2:
- Plain ol'
int
: representing a number of nanoseconds. float
: representing the fractional number of secondsrclpy.time.Time
- the preferred Pythonic interfacebuiltin_interfaces/msg/Time.msg
: the message representation.
Here's how you can convert them.
Converting this → to this ↓ |
int | float | rclpy | msg |
---|---|---|---|---|
int | - | int(t * 1e9) |
t.nanoseconds |
t.sec * 1e9 + t.nanosec |
float | t / 1e9 |
- | t.nanoseconds / 1e9 |
t.sec + t.nanosec / 1e9 |
rclpy | Time(nanoseconds=t) |
nano, sec = math.modf(t) Time(int(sec), int(nano * 1e9)) |
- | Time.from_msg(t) |
msg | Time(nanoseconds=t).to_msg() |
nano, sec = math.modf(t) builtin_interfaces.msg.Time(sec=int(sec), nanosec=int(nano * 1e9)) |
t.to_msg() |
- |
Important notes:
- You cannot do comparisons/math between mixed types or messages
- It is only mildly infuriating that
rclpy.time.Time
has the full wordnanoseconds
accessor and the message hasnanosec
.
Now
To get the equivalent of rospy.Time.now(), you now need a ROS 2 node:
import rclpy
from rclpy.node import Node
class MyNode(Node):
def some_func(self):
t = self.get_clock().now()
msg.header.stamp = t.to_msg()
Converting from Duration to messages is common:
Timers
Timers are created from the Node:
import rclpy
from rclpy.node import Node
class MyNode(Node):
def __init__(self):
super().__init__("my_node")
# Create a timer that fires every quarter second
timer_period = 0.25
self.timer = self.create_timer(timer_period, self.callback)
def callback(self):
self.get_logger().info("timer has fired")
Rates
Using Rate objects in ROS 2 is a bit more complex than in ROS 1. Due to implementation details, we need to spin() or the sleep() function will block. This is most easily accomplished using a thread: