From 1dd14f07b758e8a878c7bd3600f4b59d26cd6576 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Wed, 29 Apr 2020 08:51:52 +0200 Subject: [PATCH 1/7] Initial Zephyr emulator rework --- .../advanced/zephyr_emulator/index.md | 233 +----------------- 1 file changed, 10 insertions(+), 223 deletions(-) diff --git a/_docs/tutorials/advanced/zephyr_emulator/index.md b/_docs/tutorials/advanced/zephyr_emulator/index.md index 47158d46..b9a64653 100644 --- a/_docs/tutorials/advanced/zephyr_emulator/index.md +++ b/_docs/tutorials/advanced/zephyr_emulator/index.md @@ -3,7 +3,7 @@ title: Zephyr Emulator permalink: /docs/tutorials/advanced/zephyr_emulator/ --- -This tutorial aims to create a new micro-ROS application on with **[Zephyr RTOS](https://www.zephyrproject.org/)** emulator (also known as [Native POSIX](https://docs.zephyrproject.org/latest/boards/posix/native_posix/doc/index.html)). +This tutorial aims to create a new micro-ROS application on with **[Zephyr RTOS](https://www.zephyrproject.org/)** emulator (also known as [Native POSIX](https://docs.zephyrproject.org/latest/boards/posix/native_posix/doc/index.html)). This tutorial assumes that **[First micro-ROS Application on an RTOS](https://micro-ros.github.io/docs/tutorials/core/first_application_rtos/)** has been accomplished and user has basic knowledge about micro-ROS and ROS 2.
@@ -13,244 +13,31 @@ This tutorial aims to create a new micro-ROS application on with **[Zephyr RTOS] This tutorial requires no hardware beyond a Linux host computer. -## Adding a new micro-ROS app +## Building a Zephyr emulator application -First of all, make sure that you have a **ROS 2** installation. - -***TIP:** if you are familiar with Docker containers, this image may be useful: [ros:dashing](https://hub.docker.com/layers/ros/library/ros/dashing/images/sha256-b796c14ea663537129897769aa6c715a851ca08dffd4875ef2ecaa31a4dbd431?context=explore)* - -On the **ROS 2** installation open a command line and follow these steps: - -```bash -# Source the ROS 2 installation -source /opt/ros/$ROS_DISTRO/setup.bash - -# Create a workspace and download the micro-ROS tools -mkdir microros_ws -cd microros_ws -git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro-ros-build.git src/micro-ros-build - -# Update dependencies using rosdep -sudo apt update && sudo apt install python3-colcon-metadata -rosdep update -rosdep install --from-path src --ignore-src -y - -# Build micro-ROS tools and source them -colcon build -source install/local_setup.bash -``` - -Let's install the last version of CMake: - -```bash -sudo apt install wget -wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - -sudo apt install software-properties-common -sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' -sudo apt update -sudo apt install cmake -``` - -Now, let's create a firmware workspace that targets all the required code and tools for Zephyr emulator: +Once the micro-ROS build system is ready, let's create a new Zephyr firmware for host platform: ```bash # Create firmware step ros2 run micro_ros_setup create_firmware_ws.sh zephyr host ``` -Now you have all the required tools to compile micro-ROS and Zephyr. At this point, you must know that the micro-ROS build system is a four-step workflow: - - -1. **Create**: retrieves all the required packages for a specific RTOS and hardware platform. -2. **Configure**: configures the downloaded packages with options such as the micro-ROS application, the selected transport layer or the micro-ROS agent IP address (in network transports). -3. **Build**: generates a binary file ready for being loaded in the hardware. -4. **Flash**: load the micro-ROS software in the hardware. - -micro-ROS apps for Zephyr emulator are located at `firmware/zephyr_apps/apps`. In order to create a new application, create a new folder containing two files: the app code (inside a `src` folder) and the RMW configuration. You will also need some other Zephyr related files: a `CMakeLists.txt` to define the building process and a `prj.conf` where Zephyr is configured. You have these two files [here](https://github.com/micro-ROS/zephyr_apps/tree/dashing/apps/host_ping_pong), for now, it is ok to copy them. - -```bash -# Creating a new app -pushd firmware/zephyr_apps/apps -mkdir my_brand_new_app -cd my_brand_new_app -mkdir src -touch src/app.c app-colcon.meta - -# Copying CMakeLists.txt and prj.conf -wget https://raw.githubusercontent.com/micro-ROS/zephyr_apps/dashing/apps/host_ping_pong/CMakeLists.txt -wget https://raw.githubusercontent.com/micro-ROS/zephyr_apps/dashing/apps/host_ping_pong/prj.conf - -popd -``` - -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: -![pingpong](http://www.plantuml.com/plantuml/png/ZOwnIWGn48RxFCNFzSkoUG2vqce5jHEHi1dtWZkPa6GByNntavZY10yknMJu-ORlFwPiOjvvK-d3-M2YOR1uMKvHc93ZJafvoMML07d7h1NAE-DPWblg_na8vnwEx9OeZmzFOt1-BK7AzetJciPxCfRYVw1S0SbRLBEg1IpXPIvpUWLCmZpXIm6BS3addt7uQpu0ZQlxT1MK2r0g-7sfqbsbRrVfMrMwgbev3CDTlsqJGtJhATUmSMrMg5TKwaZUxfcttuMt7m00) +micro-ROS apps for Zephyr emulator are located at `firmware/zephyr_apps/apps`. In order to create a new application, create a new folder containing two files: the app code (inside a `src` folder) and the RMW configuration. You will also need some other Zephyr related files: a `CMakeLists.txt` to define the building process and a `prj.conf` where Zephyr is configured. There is a sample proyect [here](https://github.com/micro-ROS/zephyr_apps/tree/dashing/apps/host_ping_pong), for now, it is ok to copy them. -To start creating this app, lets configure the RMW with the required static memory. You can read more about RMW and Micro XRCE-DDS Configuration [here](/docs/tutorials/core/microxrcedds_rmw_configuration/). The `app-colcon.meta` should look like: +Make sure your app's `CMakeLists.txt` is compatible with `native_posix`: ``` -{ - "names": { - "rmw_microxrcedds": { - "cmake-args": [ - "-DRMW_UXRCE_MAX_NODES=1", - "-DRMW_UXRCE_MAX_PUBLISHERS=2", - "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=2", - "-DRMW_UXRCE_MAX_SERVICES=0", - "-DRMW_UXRCE_MAX_CLIENTS=0", - "-DRMW_UXRCE_MAX_HISTORY=4", - ] - } - } -} -``` - -Meanwhile `src/app.c` should look like the following code: - -```c -#include -#include -#include -#include "rosidl_generator_c/string_functions.h" -#include - -#include - -#include -#include -#include - -#include - -#define STRING_BUFFER_LEN 100 - -// App main function -void main(void) -{ - //Init RCL options - rcl_init_options_t options = rcl_get_zero_initialized_init_options(); - rcl_init_options_init(&options, rcl_get_default_allocator()); - - // Init RCL context - rcl_context_t context = rcl_get_zero_initialized_context(); - rcl_init(0, NULL, &options, &context); - - // Create a node - rcl_node_options_t node_ops = rcl_node_get_default_options(); - rcl_node_t node = rcl_get_zero_initialized_node(); - rcl_node_init(&node, "pingpong_node", "", &context, &node_ops); - - // Create a reliable ping publisher - rcl_publisher_options_t ping_publisher_ops = rcl_publisher_get_default_options(); - rcl_publisher_t ping_publisher = rcl_get_zero_initialized_publisher(); - rcl_publisher_init(&ping_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/ping", &ping_publisher_ops); - - // Create a best effort pong publisher - rcl_publisher_options_t pong_publisher_ops = rcl_publisher_get_default_options(); - pong_publisher_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; - rcl_publisher_t pong_publisher = rcl_get_zero_initialized_publisher(); - rcl_publisher_init(&pong_publisher, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/pong", &pong_publisher_ops); - - // Create a best effort pong subscriber - rcl_subscription_options_t pong_subscription_ops = rcl_subscription_get_default_options(); - pong_subscription_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; - rcl_subscription_t pong_subscription = rcl_get_zero_initialized_subscription(); - rcl_subscription_init(&pong_subscription, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/pong", &pong_subscription_ops); - - // Create a best effort ping subscriber - rcl_subscription_options_t ping_subscription_ops = rcl_subscription_get_default_options(); - ping_subscription_ops.qos.reliability = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT; - rcl_subscription_t ping_subscription = rcl_get_zero_initialized_subscription(); - rcl_subscription_init(&ping_subscription, &node, ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Header), "/microROS/ping", &ping_subscription_ops); - - // Create a wait set - rcl_wait_set_t wait_set = rcl_get_zero_initialized_wait_set(); - rcl_wait_set_init(&wait_set, 2, 0, 0, 0, 0, 0, &context, rcl_get_default_allocator()); - - // Create and allocate the pingpong publication message - std_msgs__msg__Header msg; - char msg_buffer[STRING_BUFFER_LEN]; - msg.frame_id.data = msg_buffer; - msg.frame_id.capacity = STRING_BUFFER_LEN; - - // Create and allocate the pingpong subscription message - std_msgs__msg__Header rcv_msg; - char rcv_buffer[STRING_BUFFER_LEN]; - rcv_msg.frame_id.data = rcv_buffer; - rcv_msg.frame_id.capacity = STRING_BUFFER_LEN; - - // Set device id and sequence number; - int device_id = rand(); - int seq_no; - - int pong_count = 0; - struct timespec ts; - rcl_ret_t rc; - - uint32_t iterations = 0; - - do { - // Clear and set the waitset - rcl_wait_set_clear(&wait_set); - - size_t index_pong_subscription; - rcl_wait_set_add_subscription(&wait_set, &pong_subscription, &index_pong_subscription); - - size_t index_ping_subscription; - rcl_wait_set_add_subscription(&wait_set, &ping_subscription, &index_ping_subscription); - - // Run session for 100 ms - rcl_wait(&wait_set, RCL_MS_TO_NS(100)); - - // Check if some pong message is received - if (wait_set.subscriptions[index_pong_subscription]) { - rc = rcl_take(wait_set.subscriptions[index_pong_subscription], &rcv_msg, NULL, NULL); - if(rc == RCL_RET_OK && strcmp(msg.frame_id.data,rcv_msg.frame_id.data) == 0) { - pong_count++; - printf("Pong for seq %s (%d)\n", rcv_msg.frame_id.data, pong_count); - } - } - - // Check if some ping message is received and pong it - if (wait_set.subscriptions[index_ping_subscription]) { - rc = rcl_take(wait_set.subscriptions[index_ping_subscription], &rcv_msg, NULL, NULL); - - // Dont pong my own pings - if(rc == RCL_RET_OK && strcmp(msg.frame_id.data,rcv_msg.frame_id.data) != 0){ - printf("Ping received with seq %s. Answering.\n", rcv_msg.frame_id.data); - rcl_publish(&pong_publisher, (const void*)&rcv_msg, NULL); - } - } - - // Check if it is time to send a ping - if (iterations++ % 50 == 0) { - // Generate a new random sequence number - seq_no = rand(); - sprintf(msg.frame_id.data, "%d_%d", seq_no, device_id); - msg.frame_id.size = strlen(msg.frame_id.data); - - // Fill the message timestamp - clock_gettime(CLOCK_REALTIME, &ts); - msg.stamp.sec = ts.tv_sec; - msg.stamp.nanosec = ts.tv_nsec; - - // Reset the pong count and publish the ping message - pong_count = 0; - rcl_publish(&ping_publisher, (const void*)&msg, NULL); - printf("Ping send seq %s\n", msg.frame_id.data); - } - - usleep(10000); - } while (true); -} +... +set(COMPATIBLE_BOARDS native_posix) +.... ``` -Once the new folder is created, let's configure our new app with a UDP transport that looks for the agent on the port UDP/8888 at localhost: +Once the app folder is created, let's configure our new app with a UDP transport that looks for the agent on the port UDP/8888 at localhost: ```bash # Configure step -ros2 run micro_ros_setup configure_firmware.sh my_brand_new_app --transport udp --ip 127.0.0.1 --port 8888 +ros2 run micro_ros_setup configure_firmware.sh host_ping_pong --transport udp --ip 127.0.0.1 --port 8888 ``` When the configuring step ends, just build the firmware: From 3685c22939f491e1a6648439c2c9d521dd0c5403 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Wed, 29 Apr 2020 08:53:49 +0200 Subject: [PATCH 2/7] Fix --- _docs/tutorials/advanced/zephyr_emulator/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/_docs/tutorials/advanced/zephyr_emulator/index.md b/_docs/tutorials/advanced/zephyr_emulator/index.md index b9a64653..a737810c 100644 --- a/_docs/tutorials/advanced/zephyr_emulator/index.md +++ b/_docs/tutorials/advanced/zephyr_emulator/index.md @@ -3,7 +3,9 @@ title: Zephyr Emulator permalink: /docs/tutorials/advanced/zephyr_emulator/ --- -This tutorial aims to create a new micro-ROS application on with **[Zephyr RTOS](https://www.zephyrproject.org/)** emulator (also known as [Native POSIX](https://docs.zephyrproject.org/latest/boards/posix/native_posix/doc/index.html)). This tutorial assumes that **[First micro-ROS Application on an RTOS](https://micro-ros.github.io/docs/tutorials/core/first_application_rtos/)** has been accomplished and user has basic knowledge about micro-ROS and ROS 2. +This tutorial aims to create a new micro-ROS application on with **[Zephyr RTOS](https://www.zephyrproject.org/)** emulator (also known as [Native POSIX](https://docs.zephyrproject.org/latest/boards/posix/native_posix/doc/index.html)). + +This tutorial assumes that **[First micro-ROS Application on an RTOS](https://micro-ros.github.io/docs/tutorials/core/first_application_rtos/)** has been accomplished and user has basic knowledge about micro-ROS and ROS 2. The target app in this tutorial is the same ping pong app explained that tutorial
From a186ee4776468deb90e2b9635416507da3a13005 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Thu, 30 Apr 2020 15:47:18 +0200 Subject: [PATCH 3/7] Update _docs/tutorials/advanced/zephyr_emulator/index.md Co-authored-by: FranFin <58737168+FranFin@users.noreply.github.com> --- _docs/tutorials/advanced/zephyr_emulator/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/tutorials/advanced/zephyr_emulator/index.md b/_docs/tutorials/advanced/zephyr_emulator/index.md index a737810c..0f4a914a 100644 --- a/_docs/tutorials/advanced/zephyr_emulator/index.md +++ b/_docs/tutorials/advanced/zephyr_emulator/index.md @@ -3,7 +3,7 @@ title: Zephyr Emulator permalink: /docs/tutorials/advanced/zephyr_emulator/ --- -This tutorial aims to create a new micro-ROS application on with **[Zephyr RTOS](https://www.zephyrproject.org/)** emulator (also known as [Native POSIX](https://docs.zephyrproject.org/latest/boards/posix/native_posix/doc/index.html)). +This tutorial aims at creating a new micro-ROS application on with **[Zephyr RTOS](https://www.zephyrproject.org/)** emulator (also known as [Native POSIX](https://docs.zephyrproject.org/latest/boards/posix/native_posix/doc/index.html)). This tutorial assumes that **[First micro-ROS Application on an RTOS](https://micro-ros.github.io/docs/tutorials/core/first_application_rtos/)** has been accomplished and user has basic knowledge about micro-ROS and ROS 2. The target app in this tutorial is the same ping pong app explained that tutorial From c0d0b35971c60a36d6918b96df584d85eee9c6ea Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Thu, 30 Apr 2020 15:47:24 +0200 Subject: [PATCH 4/7] Update _docs/tutorials/advanced/zephyr_emulator/index.md Co-authored-by: FranFin <58737168+FranFin@users.noreply.github.com> --- _docs/tutorials/advanced/zephyr_emulator/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_docs/tutorials/advanced/zephyr_emulator/index.md b/_docs/tutorials/advanced/zephyr_emulator/index.md index 0f4a914a..3b91609b 100644 --- a/_docs/tutorials/advanced/zephyr_emulator/index.md +++ b/_docs/tutorials/advanced/zephyr_emulator/index.md @@ -17,7 +17,7 @@ This tutorial requires no hardware beyond a Linux host computer. ## Building a Zephyr emulator application -Once the micro-ROS build system is ready, let's create a new Zephyr firmware for host platform: +Once the micro-ROS build system is ready, let's create a new Zephyr firmware for the host platform: ```bash # Create firmware step From 1258b34fee3aa6f90b816b45105dcc41fcf32c36 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Thu, 30 Apr 2020 15:47:30 +0200 Subject: [PATCH 5/7] Update _docs/tutorials/advanced/zephyr_emulator/index.md Co-authored-by: FranFin <58737168+FranFin@users.noreply.github.com> --- _docs/tutorials/advanced/zephyr_emulator/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_docs/tutorials/advanced/zephyr_emulator/index.md b/_docs/tutorials/advanced/zephyr_emulator/index.md index 3b91609b..74cdb03c 100644 --- a/_docs/tutorials/advanced/zephyr_emulator/index.md +++ b/_docs/tutorials/advanced/zephyr_emulator/index.md @@ -5,7 +5,8 @@ permalink: /docs/tutorials/advanced/zephyr_emulator/ This tutorial aims at creating a new micro-ROS application on with **[Zephyr RTOS](https://www.zephyrproject.org/)** emulator (also known as [Native POSIX](https://docs.zephyrproject.org/latest/boards/posix/native_posix/doc/index.html)). -This tutorial assumes that **[First micro-ROS Application on an RTOS](https://micro-ros.github.io/docs/tutorials/core/first_application_rtos/)** has been accomplished and user has basic knowledge about micro-ROS and ROS 2. The target app in this tutorial is the same ping pong app explained that tutorial +To follow this tutorial, it is assumed that the user is already familiar with the **[First micro-ROS Application on an RTOS](https://micro-ros.github.io/docs/tutorials/core/first_application_rtos/)** tutorial. The target app in this tutorial is the same ping pong app. +Another requirement is that the user has a basic knowledge of micro-ROS and ROS 2.
From 616d2f0ff30d4f6028aa53a0a1433e7cea7ba902 Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Thu, 30 Apr 2020 15:53:44 +0200 Subject: [PATCH 6/7] Updates --- .../advanced/zephyr_emulator/index.md | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/_docs/tutorials/advanced/zephyr_emulator/index.md b/_docs/tutorials/advanced/zephyr_emulator/index.md index 74cdb03c..562f9bc5 100644 --- a/_docs/tutorials/advanced/zephyr_emulator/index.md +++ b/_docs/tutorials/advanced/zephyr_emulator/index.md @@ -25,15 +25,28 @@ Once the micro-ROS build system is ready, let's create a new Zephyr firmware for ros2 run micro_ros_setup create_firmware_ws.sh zephyr host ``` - micro-ROS apps for Zephyr emulator are located at `firmware/zephyr_apps/apps`. In order to create a new application, create a new folder containing two files: the app code (inside a `src` folder) and the RMW configuration. You will also need some other Zephyr related files: a `CMakeLists.txt` to define the building process and a `prj.conf` where Zephyr is configured. There is a sample proyect [here](https://github.com/micro-ROS/zephyr_apps/tree/dashing/apps/host_ping_pong), for now, it is ok to copy them. -Make sure your app's `CMakeLists.txt` is compatible with `native_posix`: +```bash +# Creating a new app +pushd firmware/zephyr_apps/apps +mkdir host_ping_pong +cd host_ping_pong +mkdir src + +# Contents of app.c are here: https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/src/main.c +touch src/app.c -``` -... -set(COMPATIBLE_BOARDS native_posix) -.... +# Contents of app-colcon.meta are here: https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/app-colcon.meta +touch app-colcon.meta + +# Contents of app-colcon.meta are here: https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/CMakeLists.txt +touch CMakeLists.txt + +# Contents of app-colcon.meta are here: https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/prj.conf +touch prj.conf + +popd ``` Once the app folder is created, let's configure our new app with a UDP transport that looks for the agent on the port UDP/8888 at localhost: From 1e1043053366f545239331f7c47912eea51cfd0b Mon Sep 17 00:00:00 2001 From: Pablo Garrido Date: Thu, 30 Apr 2020 16:10:41 +0200 Subject: [PATCH 7/7] Update links --- _docs/tutorials/advanced/zephyr_emulator/index.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/_docs/tutorials/advanced/zephyr_emulator/index.md b/_docs/tutorials/advanced/zephyr_emulator/index.md index 562f9bc5..c73bcf05 100644 --- a/_docs/tutorials/advanced/zephyr_emulator/index.md +++ b/_docs/tutorials/advanced/zephyr_emulator/index.md @@ -34,21 +34,16 @@ mkdir host_ping_pong cd host_ping_pong mkdir src -# Contents of app.c are here: https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/src/main.c touch src/app.c - -# Contents of app-colcon.meta are here: https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/app-colcon.meta touch app-colcon.meta - -# Contents of app-colcon.meta are here: https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/CMakeLists.txt touch CMakeLists.txt - -# Contents of app-colcon.meta are here: https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/prj.conf touch prj.conf popd ``` +The contents of the files can be found here: [app.c](https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/src/main.c), [app-colcon.meta](https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/app-colcon.meta), [CMakeLists.txt](https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/CMakeLists.txt) and [prj.conf](https://github.com/micro-ROS/zephyr_apps/blob/dashing/apps/host_ping_pong/prj.conf). + Once the app folder is created, let's configure our new app with a UDP transport that looks for the agent on the port UDP/8888 at localhost: ```bash