Skip to content

Commit ecc19f0

Browse files
committed
get rid of deprecated rclcpp::spin_some()
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
1 parent e59410c commit ecc19f0

File tree

3 files changed

+52
-47
lines changed

3 files changed

+52
-47
lines changed

README.md

Lines changed: 46 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Tutorial Level: Beginner
3737
Take a look at [my_publisher.cpp](image_transport_tutorials/src/my_publisher.cpp).
3838

3939
### The code explained
40-
Now, let's break down the code piece by piece.
40+
Now, let's break down the code piece by piece.
4141
For lines not explained here, review [Writing a Simple Publisher and Subscriber (C++)](https://docs.ros.org/en/galactic/Tutorials/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html).
4242

4343
```
@@ -54,15 +54,15 @@ rclcpp::Node::SharedPtr node = rclcpp::Node::make_shared("image_publisher", opti
5454
image_transport::ImageTransport it(node);
5555
```
5656

57-
We create an `ImageTransport` instance, initializing it with our node.
57+
We create an `ImageTransport` instance, initializing it with our node.
5858
We use methods of `ImageTransport` to create image publishers and subscribers, much as we use methods of `Node` to create generic ROS publishers and subscribers.
5959

6060
```
6161
image_transport::Publisher pub = it.advertise("camera/image", 1);
6262
```
6363

64-
Advertise that we are going to be publishing images on the base topic `camera/image`.
65-
Depending on whether more plugins are built, additional (per-plugin) topics derived from the base topic may also be advertised.
64+
Advertise that we are going to be publishing images on the base topic `camera/image`.
65+
Depending on whether more plugins are built, additional (per-plugin) topics derived from the base topic may also be advertised.
6666
The second argument is the size of our publishing queue.
6767

6868
`advertise()` returns an `image_transport::Publisher` object, which serves two purposes:
@@ -80,32 +80,34 @@ We load a user-specified (on the command line) color image from disk using OpenC
8080

8181
```
8282
rclcpp::WallRate loop_rate(5);
83+
rclcpp::executors::SingleThreadedExecutor executor;
84+
executor.add_node(node);
8385
while (rclcpp::ok()) {
8486
pub.publish(msg);
85-
rclcpp::spin_some(node);
87+
executor.spin_some();
8688
loop_rate.sleep();
8789
}
8890
```
8991

9092
We broadcast the image to anyone connected to one of our topics, exactly as we would have using an `rclcpp::Publisher`.
9193

9294
### Adding video stream from a webcam
93-
The example above requires a path to an image file to be added as a command line parameter.
94-
This image will be converted and sent as a message to an image subscriber.
95-
In most cases, however, this is not a very practical example as you are often required to handle streaming data.
96-
(For example: multiple webcams mounted on a robot record the scene around it and you have to pass the image data to some other node for further analysis).
95+
The example above requires a path to an image file to be added as a command line parameter.
96+
This image will be converted and sent as a message to an image subscriber.
97+
In most cases, however, this is not a very practical example as you are often required to handle streaming data.
98+
(For example: multiple webcams mounted on a robot record the scene around it and you have to pass the image data to some other node for further analysis).
9799

98-
The publisher example can be modified quite easily to make it work with a video device supported by `cv::VideoCapture` (in case it is not, you have to handle it accordingly).
100+
The publisher example can be modified quite easily to make it work with a video device supported by `cv::VideoCapture` (in case it is not, you have to handle it accordingly).
99101
Take a look at [publisher_from_video.cpp](image_transport_tutorials/src/publisher_from_video.cpp) to see how a video device can be passed in as a command line argument and used as the image source.
100102

101-
If you have a single device, you do not need to do the whole routine with passing a command line argument.
102-
In this case, you can hard-code the index/address of the device and directly pass it to the video capturing structure in OpenCV (example: `cv::VideoCapture(0)` if `/dev/video0` is used).
103-
Multiple checks are also included here to make sure that the publisher does not break if the camera is shut down.
103+
If you have a single device, you do not need to do the whole routine with passing a command line argument.
104+
In this case, you can hard-code the index/address of the device and directly pass it to the video capturing structure in OpenCV (example: `cv::VideoCapture(0)` if `/dev/video0` is used).
105+
Multiple checks are also included here to make sure that the publisher does not break if the camera is shut down.
104106
If the retrieved frame from the video device is not empty, it will then be converted to a ROS message which will be published by the publisher.
105107

106108
## Writing a Simple Image Subscriber (C++) <a name="cpp_simple_image_sub"/>
107-
Description: This tutorial shows how to create a subscriber node that will display an image on the screen.
108-
By using the `image_transport` subscriber to subscribe to images, any image transport can be used at runtime.
109+
Description: This tutorial shows how to create a subscriber node that will display an image on the screen.
110+
By using the `image_transport` subscriber to subscribe to images, any image transport can be used at runtime.
109111
To learn how to actually use a specific image transport, see the next tutorial.
110112

111113
Tutorial Level: Beginner
@@ -129,8 +131,8 @@ These headers will allow us to subscribe to image messages, display images using
129131
void imageCallback(const sensor_msgs::msg::Image::ConstSharedPtr & msg)
130132
```
131133

132-
This is the callback function that will be called when a new image has arrived on the `camera/image` topic.
133-
Although the image may have been sent in some arbitrary transport-specific message type, notice that the callback need only handle the normal `sensor_msgs/msg/Image` type.
134+
This is the callback function that will be called when a new image has arrived on the `camera/image` topic.
135+
Although the image may have been sent in some arbitrary transport-specific message type, notice that the callback need only handle the normal `sensor_msgs/msg/Image` type.
134136
All image encoding/decoding is handled automatically for you.
135137

136138
```
@@ -142,7 +144,7 @@ try {
142144
RCLCPP_ERROR(logger, "Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
143145
```
144146

145-
The body of the callback.
147+
The body of the callback.
146148
We convert the ROS image message into an OpenCV image with BGR pixel encoding, then show it in a display window.
147149

148150
```
@@ -156,13 +158,13 @@ We create an `ImageTransport` instance, initializing it with our node.
156158
image_transport::Subscriber sub = it.subscribe("camera/image", 1, imageCallback);
157159
```
158160

159-
Subscribe to the `camera/image` base topic.
160-
The actual ROS topic subscribed to depends on which transport is used.
161-
In the default case, "raw" transport, the topic is `camera/image` with type `sensor_msgs/msg/Image`.
162-
ROS will call the `imageCallback` function whenever a new image arrives.
161+
Subscribe to the `camera/image` base topic.
162+
The actual ROS topic subscribed to depends on which transport is used.
163+
In the default case, "raw" transport, the topic is `camera/image` with type `sensor_msgs/msg/Image`.
164+
ROS will call the `imageCallback` function whenever a new image arrives.
163165
The 2nd argument is the queue size.
164166

165-
`subscribe()` returns an `image_transport::Subscriber` object that you must hold on to until you want to unsubscribe.
167+
`subscribe()` returns an `image_transport::Subscriber` object that you must hold on to until you want to unsubscribe.
166168
When the Subscriber object is destructed, it will automatically unsubscribe from the `camera/image` base topic.
167169

168170
In just a few lines of code, we have written a ROS image viewer that can handle images in both raw and a variety of compressed forms.
@@ -173,7 +175,7 @@ Description: This tutorial discusses running the simple image publisher and subs
173175
Tutorial Level: Beginner
174176

175177
### Running the publisher
176-
In a previous tutorial we made a publisher node called `my_publisher`.
178+
In a previous tutorial we made a publisher node called `my_publisher`.
177179
Now run the node with an image file as the command-line argument:
178180

179181
```
@@ -186,7 +188,7 @@ To check that your node is running properly, list the topics being published:
186188
$ ros2 topic list
187189
```
188190

189-
You should see `/camera/image` in the output.
191+
You should see `/camera/image` in the output.
190192
You can also get more information about the topic:
191193

192194
```
@@ -211,8 +213,8 @@ $ ros2 run image_transport_tutorials my_subscriber
211213
You should see a window pop up with the image you gave to the publisher.
212214

213215
### Finding available transports
214-
`image_transport` searches your ROS installation for transport plugins at runtime and dynamically loads all that are built.
215-
This affords you great flexibility in adding additional transports, but makes it unclear which are available on your system.
216+
`image_transport` searches your ROS installation for transport plugins at runtime and dynamically loads all that are built.
217+
This affords you great flexibility in adding additional transports, but makes it unclear which are available on your system.
216218
`image_transport` provides a `list_transports` executable for this purpose:
217219

218220
```
@@ -229,21 +231,21 @@ Details:
229231
----------
230232
"image_transport/raw"
231233
- Provided by package: image_transport
232-
- Publisher:
234+
- Publisher:
233235
This is the default publisher. It publishes the Image as-is on the base topic.
234-
235-
- Subscriber:
236+
237+
- Subscriber:
236238
This is the default pass-through subscriber for topics of type sensor_msgs/Image.
237239
```
238240

239-
This the expected output for an otherwise new ROS installation after completing the previous tutorials.
241+
This the expected output for an otherwise new ROS installation after completing the previous tutorials.
240242
Depending on your setup, you may already have "theora" or other transports available.
241243

242244
### Adding new transports
243-
Our nodes are currently communicating raw `sensor_msgs/msg/Image` messages, so we are not gaining anything over using `rclcpp::Publisher` and `rclcpp::Subscriber`.
245+
Our nodes are currently communicating raw `sensor_msgs/msg/Image` messages, so we are not gaining anything over using `rclcpp::Publisher` and `rclcpp::Subscriber`.
244246
Let's change that by introducing a new transport.
245247

246-
The `compressed_image_transport` package provides plugins for the "compressed" transport, which sends images over the wire in either JPEG- or PNG-compressed form.
248+
The `compressed_image_transport` package provides plugins for the "compressed" transport, which sends images over the wire in either JPEG- or PNG-compressed form.
247249
Notice that `compressed_image_transport` is not a dependency of your package; `image_transport` will automatically discover all transport plugins built in your ROS system.
248250

249251
The easiest way to add the "compressed" transport is to install the package:
@@ -261,8 +263,8 @@ $ sudo apt-get install ros-iron-image-transport-plugins
261263
But you can also build from source.
262264

263265
### Changing the transport used
264-
Now let's start up a new subscriber, this one using compressed transport.
265-
The key is that `image_transport` subscribers check the parameter `_image_transport` for the name of a transport to use in place of "raw".
266+
Now let's start up a new subscriber, this one using compressed transport.
267+
The key is that `image_transport` subscribers check the parameter `_image_transport` for the name of a transport to use in place of "raw".
266268
Let's set this parameter and start a subscriber node with name "compressed_listener":
267269

268270
```
@@ -274,23 +276,23 @@ You should see an identical image window pop up.
274276
`compressed_listener` is listening to a separate topic carrying JPEG-compressed versions of the same images published on `/camera/image`.
275277

276278
### Changing transport-specific behavior
277-
For a particular transport, we may want to tweak settings such as compression level, bit rate, etc.
278-
Transport plugins can expose such settings through ROS parameters.
279+
For a particular transport, we may want to tweak settings such as compression level, bit rate, etc.
280+
Transport plugins can expose such settings through ROS parameters.
279281
For example, `/camera/image/compressed` allows you to change the compression format and quality on the fly; see the package documentation for full details.
280282

281-
For now let's adjust the JPEG quality.
282-
By default, the "compressed" transport uses JPEG compression at 80% quality.
283+
For now let's adjust the JPEG quality.
284+
By default, the "compressed" transport uses JPEG compression at 80% quality.
283285
Let's change it to 15%.
284286
We can use the GUI, `rqt_reconfigure`, to change the quality:
285287

286288
```
287289
$ ros2 run rqt_reconfigure rqt_reconfigure
288290
```
289291

290-
Now pick `/image_publisher` in the drop-down menu and move the `jpeg_quality` slider down to 15%.
292+
Now pick `/image_publisher` in the drop-down menu and move the `jpeg_quality` slider down to 15%.
291293
Do you see the compression artifacts in your second view window?
292294

293-
The `rqt_reconfigure` GUI has updated the ROS parameter `/image_publisher/jpeg_quality`.
295+
The `rqt_reconfigure` GUI has updated the ROS parameter `/image_publisher/jpeg_quality`.
294296
You can verify this by running:
295297

296298
```
@@ -308,7 +310,7 @@ Tutorial Level: Beginner
308310
Take a look at [my_publisher.py](image_transport_tutorials_py/image_transport_tutorials_py/my_publisher.py).
309311

310312
To publish images using `image_transport_py`, you create an `ImageTransport` object and use it to advertise an image topic. The first parameter for `ImageTransport` is the image transport
311-
node's name which needs to be unique in the namespace.
313+
node's name which needs to be unique in the namespace.
312314

313315
Steps:
314316

@@ -351,8 +353,8 @@ from image_transport_py import ImageTransport
351353

352354
## Writing a Simple Image Subscriber (Python) <a name="py_simple_image_sub"/>
353355

354-
Description: This tutorial shows how to create a subscriber node that will receive the contents of the published
355-
image. By using the `image_transport` subscriber to subscribe to images, any image transport can be used at runtime.
356+
Description: This tutorial shows how to create a subscriber node that will receive the contents of the published
357+
image. By using the `image_transport` subscriber to subscribe to images, any image transport can be used at runtime.
356358

357359
Tutorial Level: Beginner
358360

@@ -395,4 +397,3 @@ class MySubscriber(Node):
395397

396398
By default, `image_transport` uses the `raw` transport. You can specify a different transport by passing `image_transport` parameter to `ImageTransport`. Alternatively,
397399
you can use your own ROS2 parameter file for the imagetransport node via `launch_params_filepath` parameter.
398-

image_transport_tutorials/src/my_publisher.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ int main(int argc, char ** argv)
3131
sensor_msgs::msg::Image::SharedPtr msg = cv_bridge::CvImage(hdr, "bgr8", image).toImageMsg();
3232

3333
rclcpp::WallRate loop_rate(5);
34+
rclcpp::executors::SingleThreadedExecutor executor;
35+
executor.add_node(node);
3436
while (rclcpp::ok()) {
3537
pub.publish(msg);
36-
rclcpp::spin_some(node);
38+
executor.spin_some();
3739
loop_rate.sleep();
3840
}
3941
}

image_transport_tutorials/src/publisher_from_video.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ int main(int argc, char ** argv)
5454
sensor_msgs::msg::Image::SharedPtr msg;
5555

5656
rclcpp::WallRate loop_rate(5);
57+
rclcpp::executors::SingleThreadedExecutor executor;
58+
executor.add_node(node);
5759
while (rclcpp::ok()) {
5860
cap >> frame;
5961
// Check if grabbed frame is actually full with some content
@@ -63,7 +65,7 @@ int main(int argc, char ** argv)
6365
cv::waitKey(1);
6466
}
6567

66-
rclcpp::spin_some(node);
68+
executor.spin_some();
6769
loop_rate.sleep();
6870
}
6971

0 commit comments

Comments
 (0)