import cv2 import cv_bridge import erdos import numpy as np import rospy from sensor_msgs.msg import Image from pylot.perception.camera_frame import CameraFrame from pylot.perception.messages import FrameMessage CAMERA_FPS = 30 class Grasshopper3DriverOperator(erdos.Operator): """Subscribes to a ROS topic on which camera images are published. Args: camera_stream (:py:class:`erdos.WriteStream`): Stream on which the operator sends camera frames. camera_setup (:py:class:`pylot.drivers.sensor_setup.RGBCameraSetup`): Setup of the camera. topic_name (:obj:`str`): The name of the ROS topic on which to listen for camera frames. flags (absl.flags): Object to be used to access absl flags. """ def __init__(self, camera_stream, camera_setup, topic_name, flags): self._camera_stream = camera_stream self._camera_setup = camera_setup self._topic_name = topic_name self._flags = flags self._logger = erdos.utils.setup_logging(self.config.name, self.config.log_file_name) self._bridge = cv_bridge.CvBridge() self._modulo_to_send = CAMERA_FPS // self._flags.sensor_frequency self._counter = 0 self._msg_cnt = 0 @staticmethod def connect(): return [erdos.WriteStream()] @erdos.profile_method() def on_camera_frame(self, data): self._counter += 1 if self._counter % self._modulo_to_send != 0: return cv2_image = self._bridge.imgmsg_to_cv2(data, "bgr8") resized_image = cv2.resize( cv2.flip(cv2_image, -1), (self._flags.camera_image_width, self._flags.camera_image_height)) numpy_array = np.asarray(resized_image) timestamp = erdos.Timestamp(coordinates=[self._msg_cnt]) camera_frame = CameraFrame(numpy_array, 'BGR', self._camera_setup) self._camera_stream.send(FrameMessage(timestamp, camera_frame)) watermark_msg = erdos.WatermarkMessage(timestamp) self._camera_stream.send(watermark_msg) self._logger.debug('@{}: sent message'.format(timestamp)) self._msg_cnt += 1 def run(self): rospy.init_node(self.config.name, anonymous=True, disable_signals=True) rospy.Subscriber(self._topic_name, Image, self.on_camera_frame) rospy.spin()