ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

How to set to a ROS system a fixed communication frequency?

asked 2019-01-29 07:44:31 -0500

Spyros gravatar image

updated 2019-01-30 04:56:32 -0500

I have a ROS system with 2 nodes. The first node receives a string of data from a raspberry by using serial port and it uploads on in a topic. The second node subscribes to that topic, it gets the data and after some calculations it sends a string to a microcontroller using another serial port. The calculations include some equations that depend on time.

Let's say that I want to send the data to the microcontroller at a fixed frequency (66.67 Hz), but the calculations depend on data from all the system. How can I achieve that from the moment I run all the nodes the system is going to send the data to the microcontroller with this fixed frequency? Do I have to set the whole system under a common time frame? and if that is the case, how can I do it? I think that by setting only the rate to the second node to match that frequency will not solve my problem. After a small research I found that rospy.rostime might be helpful, but I didn't find any example on how to use it and what exactly can offer. I am new to ROS so I still try to find out how things work. I use ROS Kinetic, in Ubuntu 16.04 LTS and my nodes are in Python 2.7.12. Thank you in advance.


The code running on my Raspberry Pi is:

#!/usr/bin/env python
import random
import decimal
import time
import serial

ser = serial.Serial(

    port = '/dev/ttyAMA0',
    baudrate = 115200,
    parity = serial.PARITY_NONE,
    stopbits = serial.STOPBITS_ONE,
    bytesize = serial.EIGHTBITS,
    timeout = 1


counter = 0

while 1: # i while True:
    x = float(decimal.Decimal(random.randrange(0, 5010))/10)
    y = float(decimal.Decimal(random.randrange(0, 5010))/10)
    z = float(decimal.Decimal(random.randrange(0, 5010))/10)
    thita = float(decimal.Decimal(random.randrange(0, 5010))/10)
    u_x = float(decimal.Decimal(random.randrange(0, 5010))/10)
    u_y = float(decimal.Decimal(random.randrange(0, 5010))/10)
    string_buffer = str(x)+","+str(y)+","+str(z)+','+str(thita)+','+str(u_x)+','+str(u_y)+'/'+'\n'
    print string_buffer
    counter += 1


and the code of the first node (receiving from Pi and publishing on topic) is:


import rospy
import serial
import time
from std_msgs.msg import String

ser = serial.Serial('/dev/ttyS0', 115200)
print (

def camera_node():
    pub = rospy.Publisher('real_position', String, queue_size=10) # to$
    rospy.init_node('camera_node', anonymous=True)
    rate = rospy.Rate(1) #hz, mporei na thelei sygxronismo me ta ypolo$
    if ser.isOpen():
        print("in the loop")
        camera_str = ser.readline() #... auto p tha diavazei apo serial

if __name__ == '__main__':
        while not rospy.is_shutdown():
    except rospy.ROSInterruptException:
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2019-01-29 08:53:07 -0500

You can achieve what you want here by controlling the rate at which messages are published by the first node, assuming that the time taken by the second to process each messages is relatively constant. The message passing system is fundamentally event based, so only a publisher can set the rate, the subscriber simply runs at the rate messages are received (or slower if they can't be processed fast enough)

You say your first node receives a string from a raspberry pi, does the node have any control over 'when' it receives this string or is it pushed by the hardware? This is important because this is the node which needs to publish at exactly 66.7 Hz, so if it can control when it reads from the Pi it makes it easier to achieve this.

Your second node will then be subscribing to a topic which i published at 66.7 Hz, so it's callback (CPU allowing) will be running at the same rate. This node will then be able to write to the port at the correct frequency, although there will be a phase offset between the original read on node one and the write out on node two.

Hope this makes sense.

edit flag offensive delete link more


The only time control I have in the first node is the rate = rospy.Rate() which is set to be equal to the time.sleep() duration in raspberry pi's code loop.

Spyros gravatar image Spyros  ( 2019-01-29 09:43:07 -0500 )edit

Can you show us the source code for the first node and the code on the raspberry pi. We can't help you much more unless we see what's actually happening.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2019-01-29 11:32:43 -0500 )edit

@PeteBlackerThe3rd I updated my post with the source codes. The rospy.rate is set to 1 only for testing reasons.

Spyros gravatar image Spyros  ( 2019-01-30 04:57:57 -0500 )edit

Is there a reason why you're using a serial port to get the data off the pi? Since a pi is capable of running ROS itself it would seem much easier to network the pi and have a ROS node running on there, this would greatly simplify your system.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2019-01-30 06:20:49 -0500 )edit

If I get it correctly, the node running on the RPi will publish the data directly to the topic with the desired frequency. In that case, my first node (as it is now) will be no needed at all. Is this way going to solve my timing problem? Because if it is just an easier way to do the same thing...

Spyros gravatar image Spyros  ( 2019-02-01 12:43:26 -0500 )edit

... as I do now, I don't want to waste time to setup ROS in RPi. Also how these two nodes (1 on RPi and 1 on my pc) are going to communicate under the same ROS system?

Spyros gravatar image Spyros  ( 2019-02-01 12:46:27 -0500 )edit

ROS is a fundamentally distributed system as long as there is a network connection between the computers then nodes on any computer can communicate with any other node.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2019-02-01 14:34:19 -0500 )edit

Question Tools



Asked: 2019-01-29 07:44:31 -0500

Seen: 1,225 times

Last updated: Jan 30 '19