rospy images publisher/subscriber fps optimization
I wrote publisher and subscriber scripts to transfer images over two pc. Aim of ImageSteeringPublisher.py is to publish frame from webcam and additional numerical data. Aim of ImageSteeringSubscriber.py is to receive this data, save frame to file and append additional numerical data to csv. Right now I am testing performance of my scripts, so publisher and subscriber are launch on the same pc(Ubuntu Bionic on virtual machine) over wired internet connection. When I set `rospy.Rate' to 30 i get about 29fps, but when I am increasing this parameter to 40-50 I still get the same number of fps. Is there any possibility to increase fps by modifying the above scripts? The only thing that comes to my mind is to run Image Subscriber.callback in async mode, but im not shure if async mode is set by default.
ImageSteeringPublisher.py
#!/usr/bin/env python
from __future__ import print_function
import roslib
roslib.load_manifest('learn_network')
import sys
import rospy
import cv2
from learn_network.msg import ImageSteering
from cv_bridge import CvBridge, CvBridgeError
from CameraController import CameraController
import random #torefactor
class ImagePublisher:
def __init__(self, topic_name):
self.publisher = rospy.Publisher(topic_name, ImageSteering, queue_size=1)
self.bridge = CvBridge()
self.rate_hz = 10
def publish(self, publisher_name, cameraController):
rospy.init_node(publisher_name, anonymous=True)
rate = rospy.Rate(self.rate_hz)
frame_number = 0
while not rospy.is_shutdown():
cv_image = cameraController.get_frame()
image_message = self.bridge.cv2_to_imgmsg(cv_image, encoding="passthrough")
image_steering = ImageSteering()
image_steering.frame_number = frame_number
image_steering.frame = image_message
image_steering.steering_angle = random.uniform(-2, 2) #here read steering motor angle
self.publisher.publish(image_steering)
frame_number += 1
rate.sleep()
def set_hz_rate(self, rate_hz):
self.rate_hz = rate_hz
if __name__ == '__main__':
try:
imagePublisher = ImagePublisher('image_topic')
imagePublisher.set_hz_rate(30)
cameraController = CameraController(0)
cameraController.set_height(120)
cameraController.set_width(160)
imagePublisher.publish('image_publisher_node', cameraController)
except rospy.ROSInterruptException:
ImageSteeringSubscriber.py
#!/usr/bin/env python
from __future__ import print_function
import roslib
roslib.load_manifest('learn_network')
import sys
import rospy
import cv2
from std_msgs.msg import String
from learn_network.msg import ImageSteering
from cv_bridge import CvBridge, CvBridgeError
from CameraController import CameraController
import random
import csv
import time
class ImageSubscriber:
def __init__(self, topic_name, data_directory):
self.subscriber = rospy.Subscriber(topic_name, ImageSteering ,self.callback)
self.bridge = CvBridge()
self.frames_directory = data_directory + 'Frames/'
self.csv = csv.writer(open(data_directory + "image_steering.csv","w"), delimiter=',',quoting=csv.QUOTE_ALL)
self.csv.writerow(["FrameNumber", "SteeringAngle"])
self.frame_number = 0
def __del__(self):
csv.close()
def subscribe(self, subscriber_name):
rospy.init_node(subscriber_name, anonymous=True)
rospy.spin()
def callback(self, image_steering):
try:
cv_image = self.bridge.imgmsg_to_cv2(image_steering.frame, "8UC3")
filename = str(image_steering.frame_number) + '.jpg'
cv2.imwrite(self.frames_directory + filename, cv_image)
self.csv.writerow([str(image_steering.frame_number), str(image_steering.steering_angle)])
#rospy.loginfo(filename + ' frame saved, steering ' + str(image_steering.steering_angle))
self.frame_number += 1
except CvBridgeError as e:
print(e)
if __name__ == '__main__':
try:
data_directory = '/home/fifi/ImageSteeringData/'
imageSubscriber = ImageSubscriber('image_topic', data_directory)
start_time = time.time()
imageSubscriber.subscribe('image_subscriber_node')
elapsed_time = time.time() - start_time
print('\n ' + str(imageSubscriber.frame_number/elapsed_time) + ' frames/s')
except rospy.ROSInterruptException:
pass
pass