Services in ROS. Exercise 3.3**. Calculation of time

It is possible to work with time in many different ways.

rospy.Time.now()
http://wiki.ros.org/rospy/Overview/Time

Python library
https://docs.python.org/3/library/time.html
time.sleep()
or
time.time()

What and how you will use to calculate the time has passed?
P:S in this example we do not give duration msg, can it cause problems later by calculation?

Hi @236238,

rospy.Time.now() 

uses the rostime, which is usually given by Gazebo and represents the simulation time.

time.time()
is the system time, aka ‘real’ time.
For example, if your computer is not fast enough, Gazebo might take 2 ‘real’ seconds to simulate 1 second. If you were to measure this duration both ways, the rostime would show 1 second, the python time 2 seconds.

In general, any functionality in the simulation, as speed calculations, timers etc. you wanna do in rostime. Program functions that have nothing to do with the simulation, you should use the python time. For example you might want to figure out which step takes up most calculation time. If you pause the simulation, the rostime will halt, while the real time keeps on running.

2 Likes

Here is my code. I want to solve this task without time.sleep() but code does not work

    #!/usr/bin/env python
    import rospy
    from geometry_msgs.msg import Twist
    import time
  from my_custom_srv_msg.srv import MyCustomServiceMessage, MyCustomServiceMessageResponse
       def my_callback(request):
       print "Request Data==> duration="+str(request.duration)

        bb8_vel_publisher = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
        my_response = MyCustomServiceMessageResponse()
        val_move=Twist()
        now=time.time()

         while time.time()<request.duration+now 
            val_move.linear.x=0.2
            val_move.angular.z=0.2 
            rospy.loginfo("Moving BB8!")
            bb8_vel_publisher.publish(val_move)
            time.sleep(1)
            bb8_vel_publisher.publish(val_move)

        val_move.linear.x=0.0
        val_move.angular.z=0.0 
        rospy.loginfo("Moving BB8!")
        bb8_vel_publisher.publish(val_move)
        time.sleep(1)
        bb8_vel_publisher.publish(val_move)

     return  MyCustomServiceMessageResponse() # the service Response class, in this case EmptyResponse
        #return MyServi
    rospy.init_node('bb8_in_circle_custom') 
  my_service = rospy.Service('/move_bb8_in_circle_custom', MyCustomServiceMessage , my_callback) # create the Service called my_service with the defined callback
    rospy.spin() # maintain the service open.

First of all, when controlling a robot in simulation, you should really use rostime, not system time. Otherwise you will get completely different results depending on how fast the simulation runs. Also, you don’t need that while loop. it seems kinda weird and makes thing inaccurate. In addition, why do you publish the vel, wait 1 sec and publish it again? You could do it like this:

def my_callback(request):
       print "Request Data==> duration="+str(request.duration)

        bb8_vel_publisher = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
        my_response = MyCustomServiceMessageResponse()
        val_move=Twist()
       
        val_move.linear.x=0.2
        val_move.angular.z=0.2 
        rospy.loginfo("Moving BB8!")
        bb8_vel_publisher.publish(val_move)
        rospy.sleep(request.duration)

        val_move.linear.x=0
        val_move.angular.z=0
        rospy.loginfo("Stop BB8!")
        bb8_vel_publisher.publish(val_move)
        return my_response

could you show me solution with rostime?

I published two times, because it did not move.

Hi @236238,

I would suggest that you keep things simple here. I think the idea is that you want to move the robot for some given seconds and then stop it:

Please let me know if you need further clarifications.


By the way, welcome to the Community!

1 Like

In my example I used rostime, simply use this:

rospy.sleep(1)  #simulation time. Use pretty much for anything in ROS
#instead of 
time.sleep(1)   # system time

Another very useful tool when having loops that you want to run at a specific rate, is to do this:

while not rospy.is_shutdown:
    #do something
    rospy.Rate(10).sleep()

With this, ROS tries to run the loop at 10hz, so 10 times per second. It basically adjusts the sleep duration to fit the chosen rate. This is very useful. If you were to do rospy.sleep(0.1) at the end of the loop instead, it might be close to 10hz, however, if the code you are running in the loop takes longer, or worse, fluctuates, then the overall loop will run at anything but 10hz.