|
5 | 5 | from sensor_msgs.msg import Image # Image is the message type
|
6 | 6 | from cv_bridge import CvBridge, CvBridgeError # Package to convert between ROS and OpenCV Images
|
7 | 7 |
|
| 8 | +from functools import partial #std::bind for python |
| 9 | + |
8 | 10 | from threading import Thread
|
9 | 11 |
|
10 | 12 | class ImageSubscriber(Node):
|
11 |
| - def __init__(self, ros_topic_name, callback_): |
12 |
| - """ |
13 |
| - Class constructor to set up the node |
14 |
| - """ |
| 13 | + def __init__(self): |
15 | 14 | # Initiate the Node class's constructor and give it a name
|
16 |
| - super().__init__('image_subscriber') |
| 15 | + super().__init__('ImageSubscriber') |
| 16 | + |
| 17 | + self._callbacks = {} |
| 18 | + |
| 19 | + def subscribe(self, ros_topic_name, callback): |
| 20 | + self._callbacks[ros_topic_name] = callback |
| 21 | + subscriber_callback_bound = partial(self.subscriber_callback, ros_topic_name_=ros_topic_name) |
17 | 22 |
|
18 |
| - self.callback = callback_ |
19 |
| - # Create the subscriber. This subscriber will receive an Image |
20 |
| - # from the video_frames topic. The queue size is 10 messages. |
21 |
| - self.sub = self.create_subscription( |
22 |
| - Image, |
23 |
| - ros_topic_name, |
24 |
| - self.subscriber_callback, |
25 |
| - qos_profile_sensor_data) |
26 |
| - self.get_logger().info('Subscribed on ' + ros_topic_name) |
27 |
| - |
28 |
| - # Used to convert between ROS and OpenCV images |
29 |
| - self.br = CvBridge() |
30 |
| - |
31 |
| - def subscriber_callback(self, data): |
| 23 | + # Create the subscriber. This subscriber will receive an Image from the topic. The queue size is 10 messages. |
| 24 | + self.create_subscription( |
| 25 | + Image, |
| 26 | + ros_topic_name, |
| 27 | + subscriber_callback_bound, |
| 28 | + qos_profile_sensor_data) |
| 29 | + |
| 30 | + self.get_logger().info('Subscribed on ' + ros_topic_name) |
| 31 | + |
| 32 | + |
| 33 | + def subscriber_callback(self, data, ros_topic_name_): |
32 | 34 | try:
|
33 | 35 | # Convert ROS Image message to OpenCV/numpy image
|
34 | 36 | imageNumpy = CvBridge().imgmsg_to_cv2(data)
|
35 | 37 | self.get_logger().info('Received video frame dimensions {0}x{1}'.format(imageNumpy.shape[1], imageNumpy.shape[0]))
|
36 |
| - if (self.callback is not None): |
37 |
| - self.callback(imageNumpy) |
| 38 | + |
| 39 | + callback = self._callbacks.get(ros_topic_name_) |
| 40 | + if (callback is not None): |
| 41 | + callback(imageNumpy) |
38 | 42 | except CvBridgeError as exc:
|
39 | 43 | self.get_logger().error(exc)
|
40 | 44 |
|
41 | 45 | class ImageSubscriberWrapper:
|
42 |
| - def __init__(self, ros_topic_name, callback = None): |
| 46 | + |
| 47 | + def __init__(self): |
43 | 48 | rclpy.init()
|
44 |
| - self.node = ImageSubscriber(ros_topic_name, callback) |
| 49 | + self.node = ImageSubscriber() |
45 | 50 | self.thread = Thread(target=self._threadFunc)
|
46 | 51 | self.thread.start()
|
47 | 52 |
|
| 53 | + def subscribe(self, ros_topic_name, callback = None): |
| 54 | + self.node.subscribe(ros_topic_name, callback) |
| 55 | + |
48 | 56 | def _threadFunc(self):
|
49 | 57 | rclpy.spin(self.node)
|
50 | 58 | rclpy.shutdown()
|
|
0 commit comments