# 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 seconds * [`rclpy.time.Time`](https://github.com/ros2/rclpy/blob/rolling/rclpy/rclpy/time.py) - the preferred Pythonic interface * [`builtin_interfaces/msg/Time.msg`](https://github.com/ros2/rcl_interfaces/blob/master/builtin_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 word `nanoseconds` accessor and the message has `nanosec`. ## Now To get the equivalent of rospy.Time.now(), you now need a ROS 2 node: ```python 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: ```python import rclpy from rclpy.duration import Duration msg.duration = Duration(seconds=1).to_msg() ``` ## Timers Timers are created from the Node: ```python 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: ```python import threading # Run spin in a thread, make thread daemon so we don't have to join it to exit thread = threading.Thread(target=rclpy.spin, args=(node, ), daemon=True) thread.start() rate = node.create_rate(10) while rclpy.ok(): print('This prints at 10hz') rate.sleep() ```