0
$\begingroup$

Dear Robotics Community,

I have a simple problem. I working with ros2 foxy and have a simulator (not important for the question).

I want to set the ros clock from my simulator-loop such that I can use the simulation time for other nodes e.g. using ros - rate according to the simulator.

I thought i would be easy to just publish into the /clock topic, but actually, it did not work for me. Can somebody help me with and minimal example in python? Any other help is more than welcome.

Thank you for your help

$\endgroup$
1
  • $\begingroup$ The simulator is extremely important to the question; /clock is not a topic that comes up by default so it must be provided by the simulator and so it will determine how this topic is handled. Also, it's not clear why this is what you're trying to do (speeding up time for testing/training?) which is also relevant: other nodes in your system will likely ignore /clock. $\endgroup$
    – cst0
    Commented Jan 4 at 11:20

2 Answers 2

1
$\begingroup$

I solved my problem. I just used the wrong msg-type. I thought, the msg to be published into /clock should be of type "builtin_interfaces/msg/Time" but you need to use: "rosgraph_msgs/msg/Clock".

I attached to scripts as minimum example. One serves as "simulation loop" (clock_setter.py), which publishes the clock time, and the other has a rate, which should behave according to the published clock (try_rate_sim.py).

file: clock_setter.py

import rclpy
import time
from rclpy.node import Node
from rosgraph_msgs.msg import Clock


def main():
    rclpy.init()

    node = rclpy.create_node('sim_time_publisher')

    pub = node.create_publisher(Clock, '/clock', 1)

    sec = 0
    nanosec = 0

    start_time = time.time()

    while True:
        msg = Clock()
        msg.clock.sec = sec
        msg.clock.nanosec = nanosec

        pub.publish(msg)
        node.get_logger().info('Publishing: Sim-Time Message:  sec: {}, nanosec: {}'.format(sec, nanosec))
        time.sleep(1)
        current = time.time() - start_time
        sec += 0
        nanosec += int(0.001 * 10 ** 9)
        if nanosec >= (1 * 10 ** 9):
            sec += 1
            nanosec -= 1 * 10 ** 9


if __name__ == "__main__":
    main()

file: try_rate_sim.py

import rclpy
import threading

def main():
    rclpy.init()

    node = rclpy.create_node('simple_node')
    node.set_parameters([rclpy.parameter.Parameter("use_sim_time", rclpy.Parameter.Type.BOOL, True)])

    print(rclpy.time.Time())
    print(node.get_clock().now())

    # Spin in a separate thread
    thread = threading.Thread(target=rclpy.spin, args=(node,), daemon=True)
    thread.start()

    rate = node.create_rate(240.0)

    try:
        while rclpy.ok():
            print(f"rclpy.time.Time(): {rclpy.time.Time()}")
            print(f"node.get_clock().now(): {node.get_clock().now()}")
            rate.sleep()
    except KeyboardInterrupt:
        pass

    rclpy.shutdown()
    thread.join()

if __name__ == "__main__":
    main()

Thanks for your responses ! Any further critics of this code is more than welcome.

$\endgroup$
0
$\begingroup$

For ROS time to take effect on a Node you need to enable it with a parameter use_sim_time

https://docs.ros.org/en/iron/p/rclcpp/generated/classrclcpp_1_1TimeSource.html

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.