Skip to content

Commit f125f50

Browse files
committed
First micro-ROS app on Linux reviewed.
1 parent 37608e9 commit f125f50

1 file changed

Lines changed: 86 additions & 79 deletions

File tree

  • _docs/tutorials/core/first_application_linux

_docs/tutorials/core/first_application_linux/index.md

Lines changed: 86 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,22 @@ This tutorial teaches you how to create a first micro-ROS application on Linux f
77

88
## Installing ROS 2 and the micro-ROS build system
99

10-
First of all, let's take a Ubuntu 18.04 LTS computer and install **ROS 2 Dashing Diademata**:
10+
First of all, install **ROS 2 Dashing Diademata** on your Ubuntu 18.04 LTS computer.
11+
To do so from binaries, via Debian packages, follow the instructions detailed
12+
[here](https://index.ros.org/doc/ros2/Installation/Dashing/Linux-Install-Debians/) instead.
13+
Alternatively, you can use a docker container with a fresh ROS 2 Dashing installation. The minimum docker that serves
14+
the purpose is the image run by the command:
1115

12-
```
13-
sudo locale-gen en_US en_US.UTF-8
14-
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
15-
export LANG=en_US.UTF-8
16-
17-
sudo apt update && sudo apt install curl gnupg2 lsb-release
18-
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
19-
20-
sudo sh -c 'echo "deb http://packages.ros.org/ros2/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list'
21-
sudo apt update
22-
sudo apt install ros-dashing-desktop
16+
```bash
17+
docker pull ros:dashing-ros-base
2318
```
2419

25-
Once you have a **ROS 2** installation in the computer, follow these steps to install the micro-ROS build system:
26-
2720
```bash
2821
# Source the ROS 2 installation
29-
source /opt/ros/$ROS_DISTRO/setup.bash
22+
source /opt/ros/dashing/setup.bash
3023

3124
# Create a workspace and download the micro-ROS tools
32-
mkdir microros_ws
25+
mkdir microros_ws
3326
cd microros_ws
3427
git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro-ros-build.git src/micro-ros-build
3528

@@ -44,7 +37,7 @@ source install/local_setup.bash
4437

4538
***TIP:** if you are familiar with Docker containers, this image may be useful: [micro-ros:base](https://github.com/micro-ROS/docker/blob/dashing/base/Dockerfile)*
4639

47-
These instructions will setup a workspace with a ready-to-use micro-ROS build system. This build system is in charge of downloading the required cross-compilation tools and building the apps for the required platforms.
40+
These instructions will setup a workspace with a ready-to-use micro-ROS build system. This build system is in charge of downloading the required cross-compilation tools and building the apps for the required platforms.
4841

4942
The build system's workflow is a four-step procedure:
5043

@@ -63,87 +56,87 @@ Once the build system is installed, let's create a firmware workspace that targe
6356
ros2 run micro_ros_setup create_firmware_ws.sh host
6457
```
6558

66-
micro-ROS apps for Linux are located at `src/uros/micro-ROS-demos/rcl/`. In order to create a new application, create a new folder containing two files: the app code and the CMake file. You can check the complete content of these file [here](https://github.com/micro-ROS/micro-ROS-demos/tree/dashing/rcl/ping_pong).
59+
This step is in charge, among other things, of creating a set of micro-ROS apps for Linux, that are located at
60+
`src/uros/micro-ROS-demos/rcl`. Each app is represented by a folder containing two files: a `.c` file with the app code
61+
and the CMake file. The former contains the logic of the application, whereas the latter contains the script to
62+
compile it.
6763

68-
```bash
69-
# Creating a new app
70-
pushd src/uros/micro-ROS-demos/rcl/
71-
mkdir ping_pong
72-
cd ping_pong
73-
touch app.c CMakeLists.txt
74-
popd
75-
```
76-
77-
Don't forget to register your app in `src/uros/micro-ROS-demos/rcl/CMakeLists.txt` by adding the following line:
64+
For the user to create its custom application, a folder `<my_app>` will need to be registered in this location,
65+
containing the two files just described. Also, any such new application folder needs to be registered in
66+
`src/uros/micro-ROS-demos/rcl/CMakeLists.txt` by adding the following line:
7867

7968
```
80-
export_executable(ping_pong)
69+
export_executable(<my_app>)
8170
```
8271

83-
For this example we are going to create a ping pong app where a node sends a ping package with a unique identifier using a publisher and the same package is received by a pong subscriber. The node will also answer to pings received from other nodes with a pong message:
72+
In this tutorial, we will focus on the out-of-the-box `ping_pong` application located at
73+
`src/uros/micro-ROS-demos/rcl/ping_pong`.
74+
You can check the complete content of this app
75+
[here](https://github.com/micro-ROS/micro-ROS-demos/tree/dashing/rcl/ping_pong).
76+
77+
This example showcases a micro-ROS node with two publisher-subscriber pairs associated with a `ping` and a `pong`
78+
topics, respectively.
79+
The node sends a `ping` package with a unique identifier, using a `ping` publisher.
80+
If the `ping` subscriber receives a `ping` from an external node, the `pong` publisher responds to the incoming `ping`
81+
with a `pong`. To test that this logic is correctly functioning, we implement communication with a ROS 2 node that:
82+
83+
* Listens to the topics published by the `ping` subscriber.
84+
* Publishes a `fake_ping` package, that is received by the micro-ROS `ping` subscriber.
85+
As a consequence, the `pong` publisher on the micro-ROS application will publish a `pong`, to signal that it received
86+
the `fake_ping` correctly.
87+
88+
The diagram below clarifies the communication flow between these entities:
8489

8590
![pingpong](http://www.plantuml.com/plantuml/png/ZOwnIWGn48RxFCNFzSkoUG2vqce5jHEHi1dtWZkPa6GByNntavZY10yknMJu-ORlFwPiOjvvK-d3-M2YOR1uMKvHc93ZJafvoMML07d7h1NAE-DPWblg_na8vnwEx9OeZmzFOt1-BK7AzetJciPxCfRYVw1S0SbRLBEg1IpXPIvpUWLCmZpXIm6BS3addt7uQpu0ZQlxT1MK2r0g-7sfqbsbRrVfMrMwgbev3CDTlsqJGtJhATUmSMrMg5TKwaZUxfcttuMt7m00)
8691

87-
The app logic of this demo is contained in [`app.c`](https://github.com/micro-ROS/micro-ROS-demos/blob/dashing/rcl/ping_pong/main.c). A thorough review of this file can show how to create a micro-ROS publisher or subscriber, as shown below.
88-
89-
**For more in depth learning about RCL and RCLC programming [check this section](https://micro-ros.github.io/docs/tutorials/core/programming_rcl_rclc/).**
90-
```c
91-
...
92-
// Create a reliable ping publisher
93-
rcl_publisher_options_t ping_publisher_ops = rcl_publisher_get_default_options();
94-
rcl_publisher_t ping_publisher = rcl_get_zero_initialized_publisher();
95-
rcl_publisher_init(&ping_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/ping", &ping_publisher_ops);
96-
...
97-
98-
...
99-
// Create a best effort pong subscriber
100-
rcl_subscription_options_t pong_subscription_ops = rcl_subscription_get_default_options();
101-
pong_subscription_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT;
102-
rcl_subscription_t pong_subscription = rcl_get_zero_initialized_subscription();
103-
rcl_subscription_init(&pong_subscription, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/pong", &pong_subscription_ops);
104-
...
105-
...
106-
// Check if some pong message is received
107-
if (wait_set.subscriptions[index_pong_subscription]) {
108-
rc = rcl_take(wait_set.subscriptions[index_pong_subscription], &rcv_msg, NULL, NULL);
109-
if(rc == RCL_RET_OK) {
110-
// Subscription app logic
111-
}
112-
}
113-
114-
...
115-
// Reset the pong count and publish the ping message
116-
rcl_publish(&ping_publisher, (const void*)&msg, NULL);
117-
...
92+
The app logic of this demo is contained in
93+
[`app.c`](https://github.com/micro-ROS/micro-ROS-demos/blob/dashing/rcl/ping_pong/main.c).
94+
A thorough review of this file is illustrative of how to create a micro-ROS publisher or subscriber.
95+
96+
Once the app has been created, the build step is in order.
97+
Notice that, with respect to the four-steps workflow delined above, we would expect a configuration step to happen
98+
before building the app. However, given that we are compiling micro-ROS in the host machine rather than in a board,
99+
the cross-compilation implemented by this configure step is not required in this case.
100+
We can then proceed to build the firmware and source the local installation:
101+
102+
```bash
103+
# Build step
104+
ros2 run micro_ros_setup build_firmware.sh
105+
source install/local_setup.bash
118106
```
119107

120-
## Running the micro-ROS app
108+
## Create the micro-ROS agent
121109

122-
The micro-ROS app is ready to be built and connected to a micro-ROS-Agent to start talking with the rest of the ROS 2 world.
110+
The micro-ROS app is now ready to be connected to a micro-ROS agent to start talking with the rest of the ROS 2
111+
world.
123112

124-
First of all, create a micro-ROS agent:
113+
To do that, let's first of all create a micro-ROS agent:
125114

126115
```bash
127116
# Download micro-ROS-Agent packages
128117
ros2 run micro_ros_setup create_agent_ws.sh
129118
```
130119

131-
When the all client and agent packages are ready, just build them all:
120+
Now, let's build the agent packages and, when this is done, source the installation:
132121

133122
```bash
134123
# Build step
135-
ros2 run micro_ros_setup build_firmware.sh
124+
colcon build
136125
source install/local_setup.bash
137126
```
138127

139-
Then run the agent:
128+
## Running the micro-ROS app
129+
130+
At this point, you have both the client and the agent correctly installed in your host machine.
131+
132+
To start micro-ROS, first run the agent:
140133

141134
```bash
142135
# Run a micro-ROS agent
143136
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888
144137
```
145138

146-
Then run the app in another command line (remember sourcing ROS 2 and micro-ROS installation):
139+
And then, in another command line, run the micro-ROS node (remember sourcing the ROS 2 and micro-ROS installations):
147140

148141
```bash
149142
source /opt/ros/$ROS_DISTRO/setup.bash
@@ -153,7 +146,12 @@ source install/local_setup.bash
153146
ros2 run micro_ros_demos_rcl ping_pong
154147
```
155148

156-
And finally, let's check that everything is working in another command line. We are going to listen to ping topic to check whether the Ping Pong node is publishing its own pings:
149+
## Testing the micro-ROS app
150+
151+
Now, we want to check that everything is working.
152+
153+
Open another command line. We are going to listen to the `ping` topic
154+
with ROS 2 to check whether the micro-ROS Ping Pong node is correctly publishing the expected pings:
157155

158156
```bash
159157
source /opt/ros/$ROS_DISTRO/setup.bash
@@ -178,7 +176,11 @@ frame_id: '730417256_1085377743'
178176
---
179177
```
180178

181-
On another command line, let's subscribe to the pong topic
179+
At this point, we know that our app is publishing pings.
180+
Let's check if it also answers to someone else's pings, publishing a pong as an answer.
181+
182+
So, first of all, let's subscribe with ROS 2 to the `pong` topic
183+
(notice that initially we don't expect to receive any pong, since none has been sent yet):
182184

183185
```bash
184186
source /opt/ros/$ROS_DISTRO/setup.bash
@@ -187,7 +189,7 @@ source /opt/ros/$ROS_DISTRO/setup.bash
187189
ros2 topic echo /microROS/pong
188190
```
189191

190-
At this point, we know that our app is publishing pings. Let's check if it also answers to someone else pings in a new command line:
192+
And now, let's publish a `fake_ping` with ROS 2 from yet another command line:
191193

192194
```bash
193195
source /opt/ros/$ROS_DISTRO/setup.bash
@@ -196,7 +198,8 @@ source /opt/ros/$ROS_DISTRO/setup.bash
196198
ros2 topic pub --once /microROS/ping std_msgs/msg/Header '{frame_id: "fake_ping"}'
197199
```
198200

199-
Now, we should see on the ping subscriber our fake ping along with the board pings:
201+
Now, we should see this `fake_ping` both in the `ping` subscriber console (the second that we opened),
202+
along with the micro-ROS pings:
200203

201204
```
202205
user@user:~$ ros2 topic echo /microROS/ping
@@ -217,7 +220,9 @@ frame_id: '2084670932_1085377743'
217220
---
218221
```
219222

220-
And in the pong subscriber, we should see the board's answer to our fake ping:
223+
Also, we expect that, because of having received the `fake_ping`, the micro-ROS `pong` publisher will answer with a
224+
`pong`. As a consequence, in the `pong` subscriber console (the third that we opened),
225+
we should see the micro-ROS app answer to our `fake_ping`:
221226

222227
```
223228
user@user:~$ ros2 topic echo /microROS/pong
@@ -228,18 +233,20 @@ frame_id: fake_ping
228233
---
229234
```
230235

231-
232236
## Multiple Ping Pong nodes
233237

234-
One of the advantages of having an Linux micro-ROS app is that you don't need to buy a bunch of hardware in order to test some multi-node micro-ROS apps. So, with the same micro-ROS agent of the last section, let's open four different command lines and run the following on each:
238+
One of the advantages of having an Linux micro-ROS app is that you don't need to buy a bunch of hardware in order to
239+
test some multi-node micro-ROS apps.
240+
So, with the same micro-ROS agent of the last section, let's open four different command lines and run the following on
241+
each:
235242

236243
```bash
237244
cd microros_ws
238245

239246
source /opt/ros/$ROS_DISTRO/setup.bash
240247
source install/local_setup.bash
241248

242-
ros2 run micro_ros_demos_rcl my_brand_new_app
249+
ros2 run micro_ros_demos_rcl ping_pong
243250
```
244251

245252
As soon as all micro-ROS nodes are up and connected to the micro-ROS agent you will see them interacting:
@@ -248,9 +255,9 @@ As soon as all micro-ROS nodes are up and connected to the micro-ROS agent you w
248255
user@user$ ros2 run micro_ros_demos_rcl my_brand_new_app
249256
UDP mode => ip: 127.0.0.1 - port: 8888
250257
Ping send seq 1711620172_1742614911 <---- This micro-ROS node sends a ping with ping ID "1711620172" and node ID "1742614911"
251-
Pong for seq 1711620172_1742614911 (1) <---- The first mate pongs my ping
252-
Pong for seq 1711620172_1742614911 (2) <---- The second mate pongs my ping
253-
Pong for seq 1711620172_1742614911 (3) <---- The third mate pongs my ping
258+
Pong for seq 1711620172_1742614911 (1) <---- The first mate pongs my ping
259+
Pong for seq 1711620172_1742614911 (2) <---- The second mate pongs my ping
260+
Pong for seq 1711620172_1742614911 (3) <---- The third mate pongs my ping
254261
Ping received with seq 1845948271_546591567. Answering. <---- A ping is received from a mate identified as "546591567", let's pong it.
255262
Ping received with seq 232977719_1681483056. Answering. <---- A ping is received from a mate identified as "1681483056", let's pong it.
256263
Ping received with seq 1134264528_1107823050. Answering. <---- A ping is received from a mate identified as "1107823050", let's pong it.

0 commit comments

Comments
 (0)