From accff53dabd46f85abdfa5f29602c19315779bfc Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Tue, 9 Oct 2018 10:34:25 +0200 Subject: [PATCH 01/45] Created empty article page on embedded ROS2. --- articles/embedded.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 articles/embedded.md diff --git a/articles/embedded.md b/articles/embedded.md new file mode 100644 index 000000000..e322265f8 --- /dev/null +++ b/articles/embedded.md @@ -0,0 +1,18 @@ +--- +layout: default +title: Embedded ROS 2.0 +abstract: + This article captures requirements, design ideas and related works on a tiny ROS 2.0 stack for microcontrollers. +published: true +author: '[Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https://github.com/ralph-lange), ... add many more from Embedded ROS2 Interest Group' +--- + +{:toc} + +# {{ page.title }} + +
+{{ page.abstract }} +
+ +Original Author: {{ page.author }} From 893091bd40a1faaf6064da76dcb0d237ff7ffe6d Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Tue, 9 Oct 2018 10:43:52 +0200 Subject: [PATCH 02/45] Added draft for abstract by Ingo Luetkebohle (iluetkeb). --- articles/embedded.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/articles/embedded.md b/articles/embedded.md index e322265f8..ea133e4a1 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -16,3 +16,5 @@ author: '[Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https:// Original Author: {{ page.author }} + +While standard ROS2 can run on Linux-class embedded devices, smaller micro-controllers are still a challenge. For example, ARM Cortex-M3 and -M4 class micro-controllers are popular for motion control and sensor integration, but have little RAM and storage. Also, they are often running with small batteries, e.g. for environmental sensors, or small consumer robots, which requires efficient power management. micro-ROS aims to address these devices through a combination of specialized, but ROS2 interoperable, communication, as well as the use of small Real-Time Operating Systems (RTOSs). From cedde5a296763fb9862e51707efc7aa95a86f43c Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Wed, 10 Oct 2018 09:26:32 +0200 Subject: [PATCH 03/45] Very first structure of sections to fill. --- articles/embedded.md | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index ea133e4a1..daf2a16bd 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -17,4 +17,38 @@ author: '[Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https:// Original Author: {{ page.author }} -While standard ROS2 can run on Linux-class embedded devices, smaller micro-controllers are still a challenge. For example, ARM Cortex-M3 and -M4 class micro-controllers are popular for motion control and sensor integration, but have little RAM and storage. Also, they are often running with small batteries, e.g. for environmental sensors, or small consumer robots, which requires efficient power management. micro-ROS aims to address these devices through a combination of specialized, but ROS2 interoperable, communication, as well as the use of small Real-Time Operating Systems (RTOSs). +While standard ROS2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. Also, they are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, but ROS2 interoperable, communication, as well as the use of small Real-Time Operating Systems (RTOS). + +This article documents requirements, design ideas and related works on this undertaking. + + + +## Requirements + + + +* Link to OFERA requirements deliverable for details + + + +## Prior and on-going works + +### EU project OFERA + +https://github.com/microROS + + +### ROS2 library for OpenCR by ROBOTIS + +https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2 + + +### ROS1-based approaches + +* rosserial +* mROS + + +## First Design Ideas + +Our diagram ... From 60e33eaf84b7a9498760ac1f92524d48bc84fb34 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Wed, 10 Oct 2018 09:29:59 +0200 Subject: [PATCH 04/45] Added first ideas for requirements to list and discuss. --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index daf2a16bd..4c8490daf 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -25,7 +25,7 @@ This article documents requirements, design ideas and related works on this unde ## Requirements - +* Very basic requirements only: modularity, device classes to aim at, middleware interoperability, ... * Link to OFERA requirements deliverable for details From 700a63ee7946d78c0375b22c6d6895950084d20e Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Wed, 10 Oct 2018 09:30:50 +0200 Subject: [PATCH 05/45] Link to ofera.eu for detailed requirements document. --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 4c8490daf..ee3befc8e 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -27,7 +27,7 @@ This article documents requirements, design ideas and related works on this unde * Very basic requirements only: modularity, device classes to aim at, middleware interoperability, ... -* Link to OFERA requirements deliverable for details +For details also add link to OFERA requirements deliverable (on ofera.eu). From d28deabde27fa8d9da8e091efa33d9ada2ba6848 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Wed, 10 Oct 2018 16:18:42 +0200 Subject: [PATCH 06/45] Refined structure and added first descriptions to existing approaches. --- articles/embedded.md | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index ee3befc8e..6c401b24b 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -17,7 +17,7 @@ author: '[Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https:// Original Author: {{ page.author }} -While standard ROS2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. Also, they are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, but ROS2 interoperable, communication, as well as the use of small Real-Time Operating Systems (RTOS). +While standard ROS2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. Also, they are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, ROS2-interoperable stack as well as the use of small Real-Time Operating Systems (RTOS). This article documents requirements, design ideas and related works on this undertaking. @@ -25,9 +25,25 @@ This article documents requirements, design ideas and related works on this unde ## Requirements -* Very basic requirements only: modularity, device classes to aim at, middleware interoperability, ... +* **Seamless integration with ROS2** + * ... -For details also add link to OFERA requirements deliverable (on ofera.eu). +* **Portability of ROS2-based software** + * ... + +* **Support of a broad spectrum of device classes** + * ... + +* **Support of prevalent communication protocols** + * ... + +* **Modularity** + * ... + +* **MCU-specific base functionalities** + * ... + +In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). @@ -35,20 +51,29 @@ For details also add link to OFERA requirements deliverable (on ofera.eu). ### EU project OFERA -https://github.com/microROS +The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS2 rmw, rcl and rclcpp layers as-is on the micro-XRCE implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. + +* [ofera.eu](http://ofera.eu/) -- project website +* [github.com/microROS](https://github.com/microROS) -- first project results, including extensions for NuttX for various communication protocols and micro-XRCE +* [github.com/eProsima/Micro-XRCE-DDS](https://github.com/eProsima/Micro-XRCE-DDS) -- the implementation of XRCE-DSS standard by the project partner eProsima ### ROS2 library for OpenCR by ROBOTIS -https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2 +... *add description* ... + +* [github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2) ### ROS1-based approaches -* rosserial -* mROS +* [rosserial](http://wiki.ros.org/rosserial) -- well-known and widely used in the ROS community ... +* [mROS](https://github.com/tlk-emb/mROS/) -- a new work on bringing ROS1 concepts (including nodes and the ROS1 middleware) on stronger MCUs, cf. also + *Hideki Takase, Tomoya Mori, Kazuyoshi Takagi and Naofumi Takagi: 'Work-in-Progress: Design Concept of a Lightweight Runtime Environment for Robot Software Components onto Embedded Devices' in Proc. of ESWEEK, Torino, Italy, September 2018.* ## First Design Ideas -Our diagram ... +... *diagram from last OFERA meeting* ... + +... *possibly also the diagram with the API features and the vertical bars indicating the depth of implementation* ... From 3f834354a628f01e3ad0290980e5a19ce4a788e9 Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Thu, 11 Oct 2018 10:33:39 +0200 Subject: [PATCH 07/45] Added proposed architecture diagram. --- articles/embedded.md | 7 ++++--- img/embedded/micro-ROS_proposed_architecture.svg | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 img/embedded/micro-ROS_proposed_architecture.svg diff --git a/articles/embedded.md b/articles/embedded.md index 6c401b24b..5edc6ce14 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -51,7 +51,7 @@ In the EU project OFERA, we compiled a longer list of requirements to an embedde ### EU project OFERA -The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS2 rmw, rcl and rclcpp layers as-is on the micro-XRCE implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. +The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. * [ofera.eu](http://ofera.eu/) -- project website * [github.com/microROS](https://github.com/microROS) -- first project results, including extensions for NuttX for various communication protocols and micro-XRCE @@ -71,9 +71,10 @@ The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a * [mROS](https://github.com/tlk-emb/mROS/) -- a new work on bringing ROS1 concepts (including nodes and the ROS1 middleware) on stronger MCUs, cf. also *Hideki Takase, Tomoya Mori, Kazuyoshi Takagi and Naofumi Takagi: 'Work-in-Progress: Design Concept of a Lightweight Runtime Environment for Robot Software Components onto Embedded Devices' in Proc. of ESWEEK, Torino, Italy, September 2018.* - ## First Design Ideas -... *diagram from last OFERA meeting* ... +* This is our porposed architecture: + +![micro-ROS](/img/embedded/micro-ROS_proposed_architecture.svg) ... *possibly also the diagram with the API features and the vertical bars indicating the depth of implementation* ... diff --git a/img/embedded/micro-ROS_proposed_architecture.svg b/img/embedded/micro-ROS_proposed_architecture.svg new file mode 100644 index 000000000..e35d03f64 --- /dev/null +++ b/img/embedded/micro-ROS_proposed_architecture.svg @@ -0,0 +1,2 @@ + +
system modes
system modes
tf
tf
diagnostics
diagnostics
Lifecycle
Lifecycle
Graph
Graph
Executor
Executor
Timer
Timer
Logging
Logging
Subscriber
Subscriber
Parameter
Parameter
Server
Server
Client
Client
Publisher
Publisher
Clock
Clock
Node
Node
RCL
RCL
RMW
RMW
rmw n adapter
rmw n adapter
rmw adapter
rmw adapter
other transport n
other transport n
Micro XRCE-DDS
Micro XRCE-DDS
RTOS AL
[Not supported by viewer]
Peripheral AL
Peripheral AL
Power AL
Power AL
Scheduling AL
Scheduling AL
Peripheral adapter
Peripheral adapter
Power adapter
Power adapter
Scheduling adapter
Scheduling adapter
Clock AL
Clock AL
Clock adatpter
Clock adatpter
NuttX
NuttX
FreeRTOS
FreeRTOS
...
...
Baremetal
Baremetal
\ No newline at end of file From ca5f3535cd57644cd25e8f9535711b29c76c2ceb Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Thu, 11 Oct 2018 10:40:00 +0200 Subject: [PATCH 08/45] Changes svg for png format. --- articles/embedded.md | 2 +- .../micro-ROS_proposed_architecture.png | Bin 0 -> 32980 bytes .../micro-ROS_proposed_architecture.svg | 2 -- 3 files changed, 1 insertion(+), 3 deletions(-) create mode 100644 img/embedded/micro-ROS_proposed_architecture.png delete mode 100644 img/embedded/micro-ROS_proposed_architecture.svg diff --git a/articles/embedded.md b/articles/embedded.md index 5edc6ce14..d10af7562 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -75,6 +75,6 @@ The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a * This is our porposed architecture: -![micro-ROS](/img/embedded/micro-ROS_proposed_architecture.svg) +![micro-ROS](/img/embedded/micro-ROS_proposed_architecture.png) ... *possibly also the diagram with the API features and the vertical bars indicating the depth of implementation* ... diff --git a/img/embedded/micro-ROS_proposed_architecture.png b/img/embedded/micro-ROS_proposed_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..02341c3e93d9008bb8d0aedb99ef1d31cd45a19b GIT binary patch literal 32980 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

^% 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 rW{!+S`9uefX -
system modes
system modes
tf
tf
diagnostics
diagnostics
Lifecycle
Lifecycle
Graph
Graph
Executor
Executor
Timer
Timer
Logging
Logging
Subscriber
Subscriber
Parameter
Parameter
Server
Server
Client
Client
Publisher
Publisher
Clock
Clock
Node
Node
RCL
RCL
RMW
RMW
rmw n adapter
rmw n adapter
rmw adapter
rmw adapter
other transport n
other transport n
Micro XRCE-DDS
Micro XRCE-DDS
RTOS AL
[Not supported by viewer]
Peripheral AL
Peripheral AL
Power AL
Power AL
Scheduling AL
Scheduling AL
Peripheral adapter
Peripheral adapter
Power adapter
Power adapter
Scheduling adapter
Scheduling adapter
Clock AL
Clock AL
Clock adatpter
Clock adatpter
NuttX
NuttX
FreeRTOS
FreeRTOS
...
...
Baremetal
Baremetal
\ No newline at end of file From 1d4a7ae822ad4e988ac9ef15a473b3c866c3ab72 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Thu, 11 Oct 2018 17:57:22 +0200 Subject: [PATCH 09/45] First draft of the basic requirements. --- articles/embedded.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 6c401b24b..a529fa161 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -25,23 +25,19 @@ This article documents requirements, design ideas and related works on this unde ## Requirements -* **Seamless integration with ROS2** - * ... +* **Seamless integration with ROS2:** The embedded ROS2 stack shall integrate seamlessly with standard ROS2 stacks and nodes running on stronger microprocessors. For a standard ROS2 node, communication (topics, services) from and to software running on the embedded ROS2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle. -* **Portability of ROS2-based software** - * ... +* **Portability of ROS2-based software:** The embedded ROS2 stack shall resemble or directly use the ROS2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS2 nodes to MCUs. -* **Support of a broad spectrum of device classes** - * ... +* **Support of a broad spectrum of device classes and RTOS:** The embedded ROS2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. This implies suitable abstractions to be able to adapt the stack to specific hardware features/mechanisms as well as to replace modules or layers with optimized implementations. -* **Support of prevalent communication protocols** - * ... + Similarly, the stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs. -* **Modularity** - * ... +* **Support of prevalent communication technologies:** To cover the broad range of use-cases for MCUs in robotics, the embedded ROS2 stack shall be usable with the default ROS2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy -* **MCU-specific base functionalities** - * ... +* **High Modularity:** The embedded ROS2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. + +* **MCU-specific core functionalities and mechanisms:** Finally, the embedded ROS2 stack shall include novel core functionalities and mechanisms that are specific for MCUs. These include power management functionalities and mechanisms for static initialization and memory management. In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). @@ -68,6 +64,7 @@ The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ### ROS1-based approaches * [rosserial](http://wiki.ros.org/rosserial) -- well-known and widely used in the ROS community ... + * [mROS](https://github.com/tlk-emb/mROS/) -- a new work on bringing ROS1 concepts (including nodes and the ROS1 middleware) on stronger MCUs, cf. also *Hideki Takase, Tomoya Mori, Kazuyoshi Takagi and Naofumi Takagi: 'Work-in-Progress: Design Concept of a Lightweight Runtime Environment for Robot Software Components onto Embedded Devices' in Proc. of ESWEEK, Torino, Italy, September 2018.* From dc679e1dca1d76a6f829f28b8ec62324fce91c25 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Fri, 12 Oct 2018 16:40:52 +0200 Subject: [PATCH 10/45] Refined list of authors. --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 6431b1999..0b70047a1 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -4,7 +4,7 @@ title: Embedded ROS 2.0 abstract: This article captures requirements, design ideas and related works on a tiny ROS 2.0 stack for microcontrollers. published: true -author: '[Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https://github.com/ralph-lange), ... add many more from Embedded ROS2 Interest Group' +author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [Borja Outerelo](https://github.com/BorjaOuterelo), [Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https://github.com/ralph-lange), [Víctor Mayoral Vilches](https://github.com/vmayoral), ... and many more from Embedded ROS2 Interest Group. Please feel free to add your name.' --- {:toc} From bf0c260288b35625926cf1193f327af1aa1f4825 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Fri, 12 Oct 2018 16:53:06 +0200 Subject: [PATCH 11/45] Added link to micro-ROS webpage. --- articles/embedded.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 0b70047a1..63a2bbb36 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -25,6 +25,8 @@ This article documents requirements, design ideas and related works on this unde ## Requirements +In this section, we first describe basic requirements to the embedded ROS stack -- as a basis for discussion. This list shall be detailed by the feedback of the community. + * **Seamless integration with ROS2:** The embedded ROS2 stack shall integrate seamlessly with standard ROS2 stacks and nodes running on stronger microprocessors. For a standard ROS2 node, communication (topics, services) from and to software running on the embedded ROS2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle. * **Portability of ROS2-based software:** The embedded ROS2 stack shall resemble or directly use the ROS2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS2 nodes to MCUs. @@ -50,7 +52,8 @@ In the EU project OFERA, we compiled a longer list of requirements to an embedde The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. * [ofera.eu](http://ofera.eu/) -- project website -* [github.com/microROS](https://github.com/microROS) -- first project results, including extensions for NuttX for various communication protocols and micro-XRCE +* [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/) -- overview to the micro-ROS stack created in the project +* [github.com/microROS](https://github.com/microROS) -- repositories with first project results, including NuttX extensions for various communication protocols and micro-XRCE * [github.com/eProsima/Micro-XRCE-DDS](https://github.com/eProsima/Micro-XRCE-DDS) -- the implementation of XRCE-DSS standard by the project partner eProsima @@ -70,7 +73,7 @@ The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ## First Design Ideas -* This is our porposed architecture: +* This is our proposed architecture: ![micro-ROS](/img/embedded/micro-ROS_proposed_architecture.png) From d1472683c7f9db41011524a8618a7dd2007f39fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Fri, 12 Oct 2018 19:07:56 +0200 Subject: [PATCH 12/45] Minor rewording and ROS 2 instead of ROS2 --- articles/embedded.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 63a2bbb36..4827a1ac4 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -4,7 +4,7 @@ title: Embedded ROS 2.0 abstract: This article captures requirements, design ideas and related works on a tiny ROS 2.0 stack for microcontrollers. published: true -author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [Borja Outerelo](https://github.com/BorjaOuterelo), [Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https://github.com/ralph-lange), [Víctor Mayoral Vilches](https://github.com/vmayoral), ... and many more from Embedded ROS2 Interest Group. Please feel free to add your name.' +author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [Borja Outerelo](https://github.com/BorjaOuterelo), [Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https://github.com/ralph-lange), [Víctor Mayoral Vilches](https://github.com/vmayoral), ... and many more from Embedded ROS 2 Interest Group. Please feel free to add your name.' --- {:toc} @@ -17,31 +17,29 @@ author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [B Original Author: {{ page.author }} -While standard ROS2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. Also, they are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, ROS2-interoperable stack as well as the use of small Real-Time Operating Systems (RTOS). +While standard ROS 2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. ARM Cortex-L1 is widely used in many sensors due to its optimized power consumption capabilities and ultra low power modes. These microcontrollers are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, ROS 2-interoperable stack as well as the use of small Real-Time Operating Systems (RTOS). This article documents requirements, design ideas and related works on this undertaking. - - ## Requirements In this section, we first describe basic requirements to the embedded ROS stack -- as a basis for discussion. This list shall be detailed by the feedback of the community. -* **Seamless integration with ROS2:** The embedded ROS2 stack shall integrate seamlessly with standard ROS2 stacks and nodes running on stronger microprocessors. For a standard ROS2 node, communication (topics, services) from and to software running on the embedded ROS2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle. +* **Seamless integration with ROS 2:** The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on stronger microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle. -* **Portability of ROS2-based software:** The embedded ROS2 stack shall resemble or directly use the ROS2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS2 nodes to MCUs. +* **Portability of ROS 2-based software:** The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. -* **Support of a broad spectrum of device classes and RTOS:** The embedded ROS2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. This implies suitable abstractions to be able to adapt the stack to specific hardware features/mechanisms as well as to replace modules or layers with optimized implementations. +* **Support of a broad spectrum of device classes and RTOS:** The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. This implies suitable abstractions to be able to adapt the stack to specific hardware features/mechanisms as well as to replace modules or layers with optimized implementations. Similarly, the stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs. -* **Support of prevalent communication technologies:** To cover the broad range of use-cases for MCUs in robotics, the embedded ROS2 stack shall be usable with the default ROS2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy +* **Support of prevalent communication technologies:** To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy -* **High Modularity:** The embedded ROS2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. +* **High Modularity:** The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. -* **MCU-specific core functionalities and mechanisms:** Finally, the embedded ROS2 stack shall include novel core functionalities and mechanisms that are specific for MCUs. These include power management functionalities and mechanisms for static initialization and memory management. +* **MCU-specific core functionalities and mechanisms:** Finally, the embedded ROS 2 stack shall include novel core functionalities and mechanisms that are specific for MCUs. These include power management functionalities and mechanisms for static initialization and memory management. -In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). +In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). @@ -49,7 +47,7 @@ In the EU project OFERA, we compiled a longer list of requirements to an embedde ### EU project OFERA -The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. +The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. * [ofera.eu](http://ofera.eu/) -- project website * [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/) -- overview to the micro-ROS stack created in the project @@ -57,11 +55,11 @@ The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a * [github.com/eProsima/Micro-XRCE-DDS](https://github.com/eProsima/Micro-XRCE-DDS) -- the implementation of XRCE-DSS standard by the project partner eProsima -### ROS2 library for OpenCR by ROBOTIS +### ROS 2 library for OpenCR by ROBOTIS ... *add description* ... -* [github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2) +* [github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS 2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS 2](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS 2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS 2) ### ROS1-based approaches From 08b395d8c59b57b16b02b7a72fecffe6f9e7e088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Fri, 12 Oct 2018 19:14:56 +0200 Subject: [PATCH 13/45] Integrate consistently ROS 2 and ROS 1 approaches --- articles/embedded.md | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 4827a1ac4..df8faecb0 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -45,21 +45,10 @@ In the EU project OFERA, we compiled a longer list of requirements to an embedde ## Prior and on-going works -### EU project OFERA +### ROS2-based approaches +* [EU project OFERA](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [http://micro-ros.com](http://micro-ros.com). -The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. - -* [ofera.eu](http://ofera.eu/) -- project website -* [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/) -- overview to the micro-ROS stack created in the project -* [github.com/microROS](https://github.com/microROS) -- repositories with first project results, including NuttX extensions for various communication protocols and micro-XRCE -* [github.com/eProsima/Micro-XRCE-DDS](https://github.com/eProsima/Micro-XRCE-DDS) -- the implementation of XRCE-DSS standard by the project partner eProsima - - -### ROS 2 library for OpenCR by ROBOTIS - -... *add description* ... - -* [github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS 2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS 2](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS 2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS 2) +* [ROS 2 library for OpenCR by ROBOTIS](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2) ### ROS1-based approaches @@ -68,6 +57,9 @@ The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a * [mROS](https://github.com/tlk-emb/mROS/) -- a new work on bringing ROS1 concepts (including nodes and the ROS1 middleware) on stronger MCUs, cf. also *Hideki Takase, Tomoya Mori, Kazuyoshi Takagi and Naofumi Takagi: 'Work-in-Progress: Design Concept of a Lightweight Runtime Environment for Robot Software Components onto Embedded Devices' in Proc. of ESWEEK, Torino, Italy, September 2018.* +* [freeRTPS](TODO): TODO + +* [ros2_embedded_nuttx](TODO): TODO ## First Design Ideas From 2b9221118362f584287e5ae3174acde99acd9181 Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Mon, 15 Oct 2018 09:27:52 +0200 Subject: [PATCH 14/45] Updates architecture diagram. Fixes ARM processor name. --- articles/embedded.md | 2 +- .../micro-ROS_proposed_architecture.png | Bin 32980 -> 33968 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index df8faecb0..62889fbcd 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -17,7 +17,7 @@ author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [B Original Author: {{ page.author }} -While standard ROS 2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. ARM Cortex-L1 is widely used in many sensors due to its optimized power consumption capabilities and ultra low power modes. These microcontrollers are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, ROS 2-interoperable stack as well as the use of small Real-Time Operating Systems (RTOS). +While standard ROS 2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. ARM Cortex-M3 is widely used in many sensors due to its optimized power consumption capabilities and ultra low power modes. These microcontrollers are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, ROS 2-interoperable stack as well as the use of small Real-Time Operating Systems (RTOS). This article documents requirements, design ideas and related works on this undertaking. diff --git a/img/embedded/micro-ROS_proposed_architecture.png b/img/embedded/micro-ROS_proposed_architecture.png index 02341c3e93d9008bb8d0aedb99ef1d31cd45a19b..d2c669c5a0fe782b8ccf7264c157c4f66f05475e 100644 GIT binary patch literal 33968 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 IcK+u70citVSpWb4 literal 32980 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

^% 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 rW{!+S`9uefX Date: Mon, 15 Oct 2018 13:22:13 +0200 Subject: [PATCH 15/45] Fix my name --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 62889fbcd..9578c7ed4 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -4,7 +4,7 @@ title: Embedded ROS 2.0 abstract: This article captures requirements, design ideas and related works on a tiny ROS 2.0 stack for microcontrollers. published: true -author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [Borja Outerelo](https://github.com/BorjaOuterelo), [Ingo Luetkebohle](https://github.com/iluetkeb), [Ralph Lange](https://github.com/ralph-lange), [Víctor Mayoral Vilches](https://github.com/vmayoral), ... and many more from Embedded ROS 2 Interest Group. Please feel free to add your name.' +author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [Borja Outerelo](https://github.com/BorjaOuterelo), [Ingo Lütkebohle](https://github.com/iluetkeb), [Ralph Lange](https://github.com/ralph-lange), [Víctor Mayoral Vilches](https://github.com/vmayoral), ... and many more from Embedded ROS 2 Interest Group. Please feel free to add your name.' --- {:toc} From 3d6bc3507a59451c2c3837d200abe3729a04b674 Mon Sep 17 00:00:00 2001 From: "Luetkebohle Ingo (CR/AEX3)" Date: Mon, 15 Oct 2018 13:34:24 +0200 Subject: [PATCH 16/45] Reformat requirements as table. Call it "wishlist" instead of requirements. --- articles/embedded.md | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 9578c7ed4..a44b56a76 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -21,28 +21,23 @@ While standard ROS 2 can run on Linux-class embedded devices, smaller microcontr This article documents requirements, design ideas and related works on this undertaking. -## Requirements +## Wishlist -In this section, we first describe basic requirements to the embedded ROS stack -- as a basis for discussion. This list shall be detailed by the feedback of the community. +Ab initio, a number of things would be great to have. Feel free to add stuff ;-) -* **Seamless integration with ROS 2:** The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on stronger microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle. - -* **Portability of ROS 2-based software:** The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. - -* **Support of a broad spectrum of device classes and RTOS:** The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. This implies suitable abstractions to be able to adapt the stack to specific hardware features/mechanisms as well as to replace modules or layers with optimized implementations. - - Similarly, the stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs. - -* **Support of prevalent communication technologies:** To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy - -* **High Modularity:** The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. - -* **MCU-specific core functionalities and mechanisms:** Finally, the embedded ROS 2 stack shall include novel core functionalities and mechanisms that are specific for MCUs. These include power management functionalities and mechanisms for static initialization and memory management. +| Key | Title | Description | +|-----|-------|-------------| +| R-SEAMLESS | **Seamless integration with ROS 2** | The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on stronger microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle.| +| R-PORTABILITY | **Portability of ROS 2-based software** | The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. | +| R-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. This implies suitable abstractions to be able to adapt the stack to specific hardware features/mechanisms as well as to replace modules or layers with optimized implementations.| +| R-RTOS | **Support of a broad spectrum of RTOS(s)** | Similarly, the stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| +| R-MW | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy | +| R-MODULARITY | **High Modularity** | The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. +| R-MCU-SPEC | **MCU-specific core functionalities and mechanisms** | Finally, the embedded ROS 2 stack shall include novel core functionalities and mechanisms that are specific for MCUs. These include power management functionalities and mechanisms for static initialization and memory management.| In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). - ## Prior and on-going works ### ROS2-based approaches From 778a574fd4d9ae9b88b2382b0814dc63723727b1 Mon Sep 17 00:00:00 2001 From: "Luetkebohle Ingo (CR/AEX3)" Date: Mon, 15 Oct 2018 14:19:04 +0200 Subject: [PATCH 17/45] also mark the items as 'wish' (with a w), instead of 'r' for requirement --- articles/embedded.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index a44b56a76..a2fbf3e90 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -23,17 +23,18 @@ This article documents requirements, design ideas and related works on this unde ## Wishlist -Ab initio, a number of things would be great to have. Feel free to add stuff ;-) +A number of things that would be great to have, lets call it a wishlist... Feel free to add stuff ;-) | Key | Title | Description | |-----|-------|-------------| -| R-SEAMLESS | **Seamless integration with ROS 2** | The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on stronger microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle.| -| R-PORTABILITY | **Portability of ROS 2-based software** | The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. | -| R-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. This implies suitable abstractions to be able to adapt the stack to specific hardware features/mechanisms as well as to replace modules or layers with optimized implementations.| -| R-RTOS | **Support of a broad spectrum of RTOS(s)** | Similarly, the stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| -| R-MW | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy | -| R-MODULARITY | **High Modularity** | The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. -| R-MCU-SPEC | **MCU-specific core functionalities and mechanisms** | Finally, the embedded ROS 2 stack shall include novel core functionalities and mechanisms that are specific for MCUs. These include power management functionalities and mechanisms for static initialization and memory management.| +| W-SEAMLESS | **Seamless integration with ROS 2** | The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on stronger microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle.| +| W-PORTABILITY | **Portability of ROS 2-based software** | The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. | +| W-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. This implies suitable abstractions to be able to adapt the stack to specific hardware features/mechanisms as well as to replace modules or layers with optimized implementations.| +| W-RTOS | **Support of a broad spectrum of RTOS(s)** | Similarly, the stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| +| W-MW | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy | +| W-MODULARITY | **High Modularity** | The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. +| W-CONTROL | **Support control-oriented applications** | MCUs are great for control, and micro-ROS should be as well. This usually means hard real-time performance with low jitter and small response times. | +| W-MCU-SPEC | **MCU-specific core functionalities and mechanisms** | Finally, the embedded ROS 2 stack shall include novel core functionalities and mechanisms that are specific for MCUs. These include power management functionalities and mechanisms for static initialization and memory management.| In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). From 1f9efd9ef9f1ed57f6cf32bb19af2b8b5dd0ab9d Mon Sep 17 00:00:00 2001 From: "Luetkebohle Ingo (CR/AEX3)" Date: Mon, 15 Oct 2018 14:19:21 +0200 Subject: [PATCH 18/45] initial questions and actions --- articles/embedded.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/articles/embedded.md b/articles/embedded.md index a2fbf3e90..8decad55e 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -38,6 +38,37 @@ A number of things that would be great to have, lets call it a wishlist... Feel In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). +## Questions + +To determine how feasible that is, and to come up with the actual requirements and/or design, a few questions come to mind. I've cross-referenced them to the relevant wishlist items (most of the there's more than one -- this suggests areas where trade-offs may be required, or alternatives pursued). + +| Key | Related Wish | Question | +|-----|-------------|----------| +| Q-RTOS | W-RTOS, W-PORTABILITY | Which RTOS(s) do we use as the basis? | +| Q-BUILD | W-RTOS, W-PORTABILITY | How do we handle the RTOS(s) respective build-systems? | +| Q-LANG | W-PORTABILITY | Which language should be used, and at what spec level? | +| Q-API | W-PORTABILITY, W-MODULARITY | How should the API look in general?| +| Q-PERF | W-PORTABILITY, W-DEVICES, W-CONTROL | What are the performance implications of the API?| +| Q-MIDDLEWARE | W-MW | Which communication/middleware technology is used?| +| Q-MCU-SPEC | W-DEVICES, W-MCU-SPEC, W-CONTROL | Which MCU-specific features do we offer in the external API?| + +## Actions + +> *TODO: Maybe don't call this action, but "fact finding" or the like?* + +To answer these questions, both the OFERA EU project as well as several others have already undertaken or are planning exploratory work. + +*Meta-Note*: Please only add a short description here, linking to more detailed pages if necessary. + +| Key | Related Question | Action | Description | Links | +|-----|------------------|--------|-------------|-------| +| A-RTOS | Q-RTOS | RTOS Proof-of-Concept | Provide a proof-of-concept RTOS. In the OFERA project, we chose NuttX, because it is largely POSIX compatible and thus eases porting. There are also experiments based on RIOT and FreeRTOS | TODO | +| A-BUILD-META | Q-BUILD | Meta-Build | Explores a meta-build approach to transform ROS 2 CMakeLists.txt to RTOS-specific build instructions. | TODO | +| A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app in the NuttX build. |TODO | +| A-BUILD-ANDROID | Q-BUILD | Arduino Build | Robotis has explored building all the libraries using the Arduino IDE. This required some manual changes and thus does not scale, but can get you off the ground. | TODO | +| A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | TODO | +| A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | TODO | + ## Prior and on-going works From 0d98ce23098b2661524b342c3c373896084430ec Mon Sep 17 00:00:00 2001 From: "Luetkebohle Ingo (CR/AEX3)" Date: Tue, 16 Oct 2018 07:05:25 +0200 Subject: [PATCH 19/45] Do not use continuation words in the table. Split 'MCU-SPEC'. Fix ANDROID->ARDUINO --- articles/embedded.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 8decad55e..f7bca61db 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -29,12 +29,13 @@ A number of things that would be great to have, lets call it a wishlist... Feel |-----|-------|-------------| | W-SEAMLESS | **Seamless integration with ROS 2** | The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on stronger microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle.| | W-PORTABILITY | **Portability of ROS 2-based software** | The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. | -| W-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. This implies suitable abstractions to be able to adapt the stack to specific hardware features/mechanisms as well as to replace modules or layers with optimized implementations.| -| W-RTOS | **Support of a broad spectrum of RTOS(s)** | Similarly, the stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| +| W-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. | +| W-RTOS | **Support of a broad spectrum of RTOS(s)** | The stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| | W-MW | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy | -| W-MODULARITY | **High Modularity** | The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. +| W-MODULARITY | **High Modularity** | The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. | | W-CONTROL | **Support control-oriented applications** | MCUs are great for control, and micro-ROS should be as well. This usually means hard real-time performance with low jitter and small response times. | -| W-MCU-SPEC | **MCU-specific core functionalities and mechanisms** | Finally, the embedded ROS 2 stack shall include novel core functionalities and mechanisms that are specific for MCUs. These include power management functionalities and mechanisms for static initialization and memory management.| +| W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | +| W-STATIC | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). @@ -47,10 +48,9 @@ To determine how feasible that is, and to come up with the actual requirements a | Q-RTOS | W-RTOS, W-PORTABILITY | Which RTOS(s) do we use as the basis? | | Q-BUILD | W-RTOS, W-PORTABILITY | How do we handle the RTOS(s) respective build-systems? | | Q-LANG | W-PORTABILITY | Which language should be used, and at what spec level? | -| Q-API | W-PORTABILITY, W-MODULARITY | How should the API look in general?| -| Q-PERF | W-PORTABILITY, W-DEVICES, W-CONTROL | What are the performance implications of the API?| +| Q-API | W-PORTABILITY, W-MODULARITY, W-STATIC, W-POWER | How should the API look in general?| +| Q-PERF | W-PORTABILITY, W-DEVICES, W-CONTROL, W-STATIC | What are the performance implications of the API?| | Q-MIDDLEWARE | W-MW | Which communication/middleware technology is used?| -| Q-MCU-SPEC | W-DEVICES, W-MCU-SPEC, W-CONTROL | Which MCU-specific features do we offer in the external API?| ## Actions @@ -65,7 +65,7 @@ To answer these questions, both the OFERA EU project as well as several others h | A-RTOS | Q-RTOS | RTOS Proof-of-Concept | Provide a proof-of-concept RTOS. In the OFERA project, we chose NuttX, because it is largely POSIX compatible and thus eases porting. There are also experiments based on RIOT and FreeRTOS | TODO | | A-BUILD-META | Q-BUILD | Meta-Build | Explores a meta-build approach to transform ROS 2 CMakeLists.txt to RTOS-specific build instructions. | TODO | | A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app in the NuttX build. |TODO | -| A-BUILD-ANDROID | Q-BUILD | Arduino Build | Robotis has explored building all the libraries using the Arduino IDE. This required some manual changes and thus does not scale, but can get you off the ground. | TODO | +| A-BUILD-ARDUINO | Q-BUILD | Arduino Build | Robotis has explored building all the libraries using the Arduino IDE. This required some manual changes and thus does not scale, but can get you off the ground. | TODO | | A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | TODO | | A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | TODO | From 6270d68a2d4cff89a08f65b74ffaf9d1a44b9636 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Wed, 17 Oct 2018 09:46:13 +0200 Subject: [PATCH 20/45] Added details on other prior and on-going works. --- articles/embedded.md | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index f7bca61db..f7920746d 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -31,7 +31,7 @@ A number of things that would be great to have, lets call it a wishlist... Feel | W-PORTABILITY | **Portability of ROS 2-based software** | The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. | | W-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. | | W-RTOS | **Support of a broad spectrum of RTOS(s)** | The stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| -| W-MW | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy | +| W-COMM | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy | | W-MODULARITY | **High Modularity** | The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. | | W-CONTROL | **Support control-oriented applications** | MCUs are great for control, and micro-ROS should be as well. This usually means hard real-time performance with low jitter and small response times. | | W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | @@ -50,43 +50,41 @@ To determine how feasible that is, and to come up with the actual requirements a | Q-LANG | W-PORTABILITY | Which language should be used, and at what spec level? | | Q-API | W-PORTABILITY, W-MODULARITY, W-STATIC, W-POWER | How should the API look in general?| | Q-PERF | W-PORTABILITY, W-DEVICES, W-CONTROL, W-STATIC | What are the performance implications of the API?| -| Q-MIDDLEWARE | W-MW | Which communication/middleware technology is used?| +| Q-COMM | W-COMM | Which communication/middleware technology is used?| -## Actions +## Analyses and Experiments -> *TODO: Maybe don't call this action, but "fact finding" or the like?* - -To answer these questions, both the OFERA EU project as well as several others have already undertaken or are planning exploratory work. +To answer these questions, the OFERA EU project as well as several others have already undertaken or are planning exploratory work. *Meta-Note*: Please only add a short description here, linking to more detailed pages if necessary. -| Key | Related Question | Action | Description | Links | -|-----|------------------|--------|-------------|-------| -| A-RTOS | Q-RTOS | RTOS Proof-of-Concept | Provide a proof-of-concept RTOS. In the OFERA project, we chose NuttX, because it is largely POSIX compatible and thus eases porting. There are also experiments based on RIOT and FreeRTOS | TODO | -| A-BUILD-META | Q-BUILD | Meta-Build | Explores a meta-build approach to transform ROS 2 CMakeLists.txt to RTOS-specific build instructions. | TODO | -| A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app in the NuttX build. |TODO | -| A-BUILD-ARDUINO | Q-BUILD | Arduino Build | Robotis has explored building all the libraries using the Arduino IDE. This required some manual changes and thus does not scale, but can get you off the ground. | TODO | -| A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | TODO | -| A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | TODO | +| Key | Related Question | Action | Description | +|-----|------------------|--------|-------------| +| A-RTOS | Q-RTOS | RTOS Proof-of-Concept | Provide a proof-of-concept RTOS. In the OFERA project, we chose [NuttX](http://nuttx.org/), because it is largely POSIX compatible and thus eases porting. There are also experiments based on [RIOT](https://www.riot-os.org/) (cf. [github.com/astralien3000/riot-ros2](https://github.com/astralien3000/riot-ros2)) and FreeRTOS (cf. [github.com/ros2/ros2_embedded_freertos](https://github.com/ros2/ros2_embedded_freertos)) | +| A-BUILD-META | Q-BUILD | Meta-Build | Explores a meta-build approach to transform ROS 2 CMakeLists.txt to RTOS-specific build instructions. | +| A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app in the [NuttX build](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2). | +| A-BUILD-ARDUINO | Q-BUILD | Arduino Build | ROBOTIS has explored building all the libraries using the Arduino IDE, cf. [github.com/ROBOTIS-GIT/OpenCR](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps). This required some manual changes and thus does not scale, but can get you off the ground. | +| A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | +| A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | ## Prior and on-going works ### ROS2-based approaches -* [EU project OFERA](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [http://micro-ros.com](http://micro-ros.com). +* [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [micro-ros.com](http://micro-ros.com). + +* [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS2 publish/subscribe and clock API for the micro-XRCE (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. -* [ROS 2 library for OpenCR by ROBOTIS](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2) +* [**freeRTPS**](TODO): +* [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): ### ROS1-based approaches -* [rosserial](http://wiki.ros.org/rosserial) -- well-known and widely used in the ROS community ... +* [**rosserial**](http://wiki.ros.org/rosserial): Well-known and widely used in the ROS community. -* [mROS](https://github.com/tlk-emb/mROS/) -- a new work on bringing ROS1 concepts (including nodes and the ROS1 middleware) on stronger MCUs, cf. also +* [**mROS**](https://github.com/tlk-emb/mROS/): A new work on bringing ROS1 concepts (including nodes and the ROS1 middleware) on stronger MCUs, cf. *Hideki Takase, Tomoya Mori, Kazuyoshi Takagi and Naofumi Takagi: 'Work-in-Progress: Design Concept of a Lightweight Runtime Environment for Robot Software Components onto Embedded Devices' in Proc. of ESWEEK, Torino, Italy, September 2018.* -* [freeRTPS](TODO): TODO - -* [ros2_embedded_nuttx](TODO): TODO ## First Design Ideas From 177be060094e8fa2ec9661d5543a45c45567f16e Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Wed, 17 Oct 2018 12:07:51 +0200 Subject: [PATCH 21/45] Refs #2616. Fixes deliverable link. --- articles/embedded.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index f7bca61db..17969cd2b 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -37,7 +37,8 @@ A number of things that would be great to have, lets call it a wishlist... Feel | W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | | W-STATIC | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | -In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [ofera.eu/deliverables/D1.7_Requirements.pdf](http://ofera.eu/deliverables/D1.7_Requirements.pdf). +In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [OFERA deliverable D1.7_Requirements.pdf](http://ofera.eu/storage/deliverables/OFERA_D1.7_Requirements.pdf). + ## Questions From 2ee4c047ec5d18dcbeaa1a38bff558b0d5f11b5b Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Wed, 17 Oct 2018 13:27:35 +0200 Subject: [PATCH 22/45] Documented other existing/on-going ROS2-based approaches. --- articles/embedded.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index f7920746d..fdde7342a 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -73,11 +73,11 @@ To answer these questions, the OFERA EU project as well as several others have a ### ROS2-based approaches * [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [micro-ros.com](http://micro-ros.com). -* [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS2 publish/subscribe and clock API for the micro-XRCE (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. +* [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the micro-XRCE (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. -* [**freeRTPS**](TODO): +* [**freeRTPS**](https://github.com/ros2/freertps): A free, portable, minimalist implementation of the RTPS protocol for microcontrollers such as the STM32F7 developed at the OSRF. FreeRTPS shall allow to run ROS 2 with standard DDS as-is on stronger MCUs. -* [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): +* [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): Early port (in 2014) of ROS 2 alpha for the STM32F4Discovery board and the STM3240G eval board running the RTOS NuttX developed by Víctor Mayoral Vilches and Esteve Fernandez at the OSRF. ### ROS1-based approaches @@ -91,5 +91,3 @@ To answer these questions, the OFERA EU project as well as several others have a * This is our proposed architecture: ![micro-ROS](/img/embedded/micro-ROS_proposed_architecture.png) - -... *possibly also the diagram with the API features and the vertical bars indicating the depth of implementation* ... From 58c9a0a1443004c0c1d1fbdd129c893e5574d0f1 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Wed, 17 Oct 2018 17:27:12 +0200 Subject: [PATCH 23/45] Changed micro-XRCE-DSS to Micro XRCE-DDS --- articles/embedded.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index fdde7342a..4f4088241 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -71,9 +71,9 @@ To answer these questions, the OFERA EU project as well as several others have a ## Prior and on-going works ### ROS2-based approaches -* [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the micro-XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [micro-ros.com](http://micro-ros.com). +* [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the Micro XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [micro-ros.com](http://micro-ros.com). -* [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the micro-XRCE (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. +* [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. * [**freeRTPS**](https://github.com/ros2/freertps): A free, portable, minimalist implementation of the RTPS protocol for microcontrollers such as the STM32F7 developed at the OSRF. FreeRTPS shall allow to run ROS 2 with standard DDS as-is on stronger MCUs. From 910bc9f8bf7899e624948b21ece8a04b92b62a3d Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Wed, 17 Oct 2018 17:33:24 +0200 Subject: [PATCH 24/45] Notice on the fact that freeRTPS has obviously been discontinued in 2016. --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 4f4088241..00f7fc59e 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -75,7 +75,7 @@ To answer these questions, the OFERA EU project as well as several others have a * [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. -* [**freeRTPS**](https://github.com/ros2/freertps): A free, portable, minimalist implementation of the RTPS protocol for microcontrollers such as the STM32F7 developed at the OSRF. FreeRTPS shall allow to run ROS 2 with standard DDS as-is on stronger MCUs. +* [**freeRTPS**](https://github.com/ros2/freertps): A free, portable, minimalist implementation of the RTPS protocol for microcontrollers such as the STM32F7 developed at the OSRF. FreeRTPS shall allow to run ROS 2 with standard DDS as-is on stronger MCUs. This project has been discontinued in 2016. * [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): Early port (in 2014) of ROS 2 alpha for the STM32F4Discovery board and the STM3240G eval board running the RTOS NuttX developed by Víctor Mayoral Vilches and Esteve Fernandez at the OSRF. From d16ab73fd99a4d44981df047bed0f11e41b9b454 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Thu, 18 Oct 2018 13:34:52 +0200 Subject: [PATCH 25/45] Included figure features_with_dependencies.png in embedded ROS 2 article. --- articles/embedded.md | 10 +++++++--- img/embedded/features_with_dependencies.png | Bin 0 -> 29401 bytes 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 img/embedded/features_with_dependencies.png diff --git a/articles/embedded.md b/articles/embedded.md index 00f7fc59e..d48e52de7 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -86,8 +86,12 @@ To answer these questions, the OFERA EU project as well as several others have a * [**mROS**](https://github.com/tlk-emb/mROS/): A new work on bringing ROS1 concepts (including nodes and the ROS1 middleware) on stronger MCUs, cf. *Hideki Takase, Tomoya Mori, Kazuyoshi Takagi and Naofumi Takagi: 'Work-in-Progress: Design Concept of a Lightweight Runtime Environment for Robot Software Components onto Embedded Devices' in Proc. of ESWEEK, Torino, Italy, September 2018.* -## First Design Ideas +## Design Discussion -* This is our proposed architecture: +The following figure may serve as a starting point for the design discussion. It depicts the major layers from the real-time operating system to the application, in the style the ROS 2 standard stack. -![micro-ROS](/img/embedded/micro-ROS_proposed_architecture.png) +![micro-ROS](/img/embedded/features_with_dependencies.png) + +At the same time, the diagram illustrates the possible feature set of the client library -- ideally in a modular fashion so that different profiles can be derived from it. The vertical bar at each feature gives an indication of the dependencies with lower layers and thus on the portability to different RTOS and middlewares. + +In the OFERA project, a more detailed diagram has been developed, which can be found at [micro-ros.com](https://micro-ros.com/). diff --git a/img/embedded/features_with_dependencies.png b/img/embedded/features_with_dependencies.png new file mode 100644 index 0000000000000000000000000000000000000000..002a2e7d47dbe5998928f9b635dc6632345d28ea GIT binary patch literal 29401 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 literal 0 HcmV?d00001 From 9dd5336f10e874c5c619954a028a41583f6ea121 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Thu, 18 Oct 2018 15:25:05 +0200 Subject: [PATCH 26/45] Formulated labels more generic. --- img/embedded/features_with_dependencies.png | Bin 29401 -> 32506 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/img/embedded/features_with_dependencies.png b/img/embedded/features_with_dependencies.png index 002a2e7d47dbe5998928f9b635dc6632345d28ea..46399066ba83b3dfea8ab6657dfb0a219a144cff 100644 GIT binary patch literal 32506 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 literal 29401 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 From 02785a1d63779d957d5e90d7c829dbe1b2d4cae9 Mon Sep 17 00:00:00 2001 From: "Ralph Lange (CR/AEE1)" Date: Tue, 23 Oct 2018 09:53:21 +0200 Subject: [PATCH 27/45] Fixed micro-ROS urls. --- articles/embedded.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index d48e52de7..01ac9ebaf 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -71,7 +71,7 @@ To answer these questions, the OFERA EU project as well as several others have a ## Prior and on-going works ### ROS2-based approaches -* [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the Micro XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [micro-ros.com](http://micro-ros.com). +* [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the Micro XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/). * [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. @@ -94,4 +94,4 @@ The following figure may serve as a starting point for the design discussion. It At the same time, the diagram illustrates the possible feature set of the client library -- ideally in a modular fashion so that different profiles can be derived from it. The vertical bar at each feature gives an indication of the dependencies with lower layers and thus on the portability to different RTOS and middlewares. -In the OFERA project, a more detailed diagram has been developed, which can be found at [micro-ros.com](https://micro-ros.com/). +In the OFERA project, a more detailed diagram has been developed, which can be found at [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/). From 8c6f414ae8aaf6c19be8912cdbc993bce9843787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Tue, 23 Oct 2018 09:29:54 +0200 Subject: [PATCH 28/45] Minor rewording --- articles/embedded.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index c3aae9842..81de7f204 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -17,17 +17,17 @@ author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [B Original Author: {{ page.author }} -While standard ROS 2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. ARM Cortex-M3 is widely used in many sensors due to its optimized power consumption capabilities and ultra low power modes. These microcontrollers are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, ROS 2-interoperable stack as well as the use of small Real-Time Operating Systems (RTOS). +While standard ROS 2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. ARM Cortex-M3 is widely used in many sensors due to its optimized power consumption capabilities and ultra low power modes. These microcontrollers are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, ROS 2-interoperable stack as well as the use of Real-Time Operating Systems (RTOS). This article documents requirements, design ideas and related works on this undertaking. ## Wishlist -A number of things that would be great to have, lets call it a wishlist... Feel free to add stuff ;-) +A number of things that would be great to have, lets call it a wishlist. Feel free to add stuff ;-) | Key | Title | Description | |-----|-------|-------------| -| W-SEAMLESS | **Seamless integration with ROS 2** | The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on stronger microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle.| +| W-SEAMLESS | **Seamless integration with ROS 2** | The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on more powerful microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle.| | W-PORTABILITY | **Portability of ROS 2-based software** | The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. | | W-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. | | W-RTOS | **Support of a broad spectrum of RTOS(s)** | The stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| From b349d128b291bb6173cf1756dc96f07d0a3dac9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Tue, 23 Oct 2018 09:30:46 +0200 Subject: [PATCH 29/45] BLE is beyond our scope, I'd suggest to mention 6LoWPAN instead --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 81de7f204..edd5e8f83 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -31,7 +31,7 @@ A number of things that would be great to have, lets call it a wishlist. Feel fr | W-PORTABILITY | **Portability of ROS 2-based software** | The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. | | W-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. | | W-RTOS | **Support of a broad spectrum of RTOS(s)** | The stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| -| W-COMM | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like Bluetooth Low Energy | +| W-COMM | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like 6LoWPAN | | W-MODULARITY | **High Modularity** | The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. | | W-CONTROL | **Support control-oriented applications** | MCUs are great for control, and micro-ROS should be as well. This usually means hard real-time performance with low jitter and small response times. | | W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | From d6bd89a9118f6066c563bd826d6cb0f65571447d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Tue, 23 Oct 2018 09:49:24 +0200 Subject: [PATCH 30/45] Review wishlist, add boot and infomodel --- articles/embedded.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/articles/embedded.md b/articles/embedded.md index edd5e8f83..cbdb19ac2 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -36,6 +36,8 @@ A number of things that would be great to have, lets call it a wishlist. Feel fr | W-CONTROL | **Support control-oriented applications** | MCUs are great for control, and micro-ROS should be as well. This usually means hard real-time performance with low jitter and small response times. | | W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | | W-STATIC | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | +| W-BOOT | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | + In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [OFERA deliverable D1.7_Requirements.pdf](http://ofera.eu/storage/deliverables/OFERA_D1.7_Requirements.pdf). From 282ae351f1680491222b6a45bc122940a7d0a85a Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Sat, 20 Oct 2018 18:00:20 +0200 Subject: [PATCH 31/45] Refs #3569. Middleware notes: -Associates seamless integration with middleware questions. -Adds actions regarding middleware. -Fixes middleware and protocol names. --- articles/embedded.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index c3aae9842..10c87b9b3 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -51,7 +51,7 @@ To determine how feasible that is, and to come up with the actual requirements a | Q-LANG | W-PORTABILITY | Which language should be used, and at what spec level? | | Q-API | W-PORTABILITY, W-MODULARITY, W-STATIC, W-POWER | How should the API look in general?| | Q-PERF | W-PORTABILITY, W-DEVICES, W-CONTROL, W-STATIC | What are the performance implications of the API?| -| Q-COMM | W-COMM | Which communication/middleware technology is used?| +| Q-COMM | W-COMM, W-SEAMLESS| Which communication/middleware technology is used?| ## Analyses and Experiments @@ -67,7 +67,8 @@ To answer these questions, the OFERA EU project as well as several others have a | A-BUILD-ARDUINO | Q-BUILD | Arduino Build | ROBOTIS has explored building all the libraries using the Arduino IDE, cf. [github.com/ROBOTIS-GIT/OpenCR](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps). This required some manual changes and thus does not scale, but can get you off the ground. | | A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | | A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | - +| A-DDS-XRCE | Q-COMM | Use of DDS-XRCE standard protocol | This OMG standard defines the protocol used by microcontrollers to publish and subscribe data to a DDS Domain, standard in ROS 2. OFERA and ROBOTIS have proved that it is a suitable protocol to seamless communicate microcontrollers with ROS 2. | [DDS-XRCE](https://www.omg.org/spec/DDS-XRCE/) | +| A-Micro-XRCE-DDS | Q-COMM | Middleware usage | OFERA, Robotis and others have integrated Micro XRCE-DDS middleware as part of their solutions. This middleware provides an implementation of DDS-XRCE standard. Integrations have been done on top of different RTOSs, NuttX and FreeRTOS and using different underlying transports. | [Micro XRCE-DDS](https://github.com/eProsima/Micro-XRCE-DDS) | ## Prior and on-going works From 4511b35ba92720fc4781014b2709e215a9d18309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Tue, 23 Oct 2018 09:57:49 +0200 Subject: [PATCH 32/45] Minor addition in actions, review ROS 2 prior --- articles/embedded.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index cbdb19ac2..9ee24e05b 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -36,8 +36,8 @@ A number of things that would be great to have, lets call it a wishlist. Feel fr | W-CONTROL | **Support control-oriented applications** | MCUs are great for control, and micro-ROS should be as well. This usually means hard real-time performance with low jitter and small response times. | | W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | | W-STATIC | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | -| W-BOOT | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | - +| W-BOOT | **Quick boot times compared to native ROS 2 machines** | Microcontrollers provide with the capability of booting very quickly (typically, in the order of tenths of milliseconds or less). This enhance the existing landscape of ROS 2-native devices which in the best cases, require a few seconds to boot an embedded Linux.| +| W-INFOMODEL | **a common interface that facilitates interoperability across different vendors** | An information model for robot devices will facilitate interoperability among modules from different vendors of robot hardware and overall, it would facilitate the integration effort. Within the OFERA project we propose and use the [Hardware Robot Information Model (HRIM)](https://acutronicrobotics.com/modularity/hrim/).| In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [OFERA deliverable D1.7_Requirements.pdf](http://ofera.eu/storage/deliverables/OFERA_D1.7_Requirements.pdf). @@ -66,6 +66,7 @@ To answer these questions, the OFERA EU project as well as several others have a | A-RTOS | Q-RTOS | RTOS Proof-of-Concept | Provide a proof-of-concept RTOS. In the OFERA project, we chose [NuttX](http://nuttx.org/), because it is largely POSIX compatible and thus eases porting. There are also experiments based on [RIOT](https://www.riot-os.org/) (cf. [github.com/astralien3000/riot-ros2](https://github.com/astralien3000/riot-ros2)) and FreeRTOS (cf. [github.com/ros2/ros2_embedded_freertos](https://github.com/ros2/ros2_embedded_freertos)) | | A-BUILD-META | Q-BUILD | Meta-Build | Explores a meta-build approach to transform ROS 2 CMakeLists.txt to RTOS-specific build instructions. | | A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app in the [NuttX build](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2). | +| A-BUILD-NUTTX-LIB | Q-BUILD | NuttX-specific build as library | OFERA has integrated (parts of) micro-ROS directly as a library in the NuttX build. |TODO | | A-BUILD-ARDUINO | Q-BUILD | Arduino Build | ROBOTIS has explored building all the libraries using the Arduino IDE, cf. [github.com/ROBOTIS-GIT/OpenCR](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps). This required some manual changes and thus does not scale, but can get you off the ground. | | A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | | A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | @@ -76,6 +77,8 @@ To answer these questions, the OFERA EU project as well as several others have a ### ROS2-based approaches * [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the Micro XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/). +* [Hardware Robot Operating System (H-ROS)](https://acutronicrobotics.com/modularity/H-ROS/) is an a standardized software and hardware infrastructure to create modular robot hardware. H-ROS is actively being used within the OFERA EU project to benchmark and prototype the capabilities of the ROS 2 stack against the ROS 2 embedded stack. In addition, H-ROS implements selected components of the ROS 2.0 stack for microcontrollers. + * [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. * [**freeRTPS**](https://github.com/ros2/freertps): A free, portable, minimalist implementation of the RTPS protocol for microcontrollers such as the STM32F7 developed at the OSRF. FreeRTPS shall allow to run ROS 2 with standard DDS as-is on stronger MCUs. This project has been discontinued in 2016. From 684f0765a65ee4ec4a78b189a6e2a5b092ae9e2a Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Sat, 20 Oct 2018 21:55:59 +0200 Subject: [PATCH 33/45] Refs #3569. Extends on some ROS 2 based approaches. --- articles/embedded.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/articles/embedded.md b/articles/embedded.md index 10c87b9b3..403fb73ed 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -77,6 +77,11 @@ To answer these questions, the OFERA EU project as well as several others have a * [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. +* [XEL Network by ROBOTIS](https://xelnetwork.readthedocs.io): + Product which communicate with ROS 2 (DDS) through DDS-XRCE using Micro XRCE-DDS in the firmware of their CommXel board. + This CommXel board manages the rest of the boards conforming the XEL Network and interface them to a ROS 2 space. + The CommXel could use Ethernet or UART to communicate using DDS-XRCE. + * [**freeRTPS**](https://github.com/ros2/freertps): A free, portable, minimalist implementation of the RTPS protocol for microcontrollers such as the STM32F7 developed at the OSRF. FreeRTPS shall allow to run ROS 2 with standard DDS as-is on stronger MCUs. This project has been discontinued in 2016. * [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): Early port (in 2014) of ROS 2 alpha for the STM32F4Discovery board and the STM3240G eval board running the RTOS NuttX developed by Víctor Mayoral Vilches and Esteve Fernandez at the OSRF. From a474fc7bd0fae4b3a394aef39f7ade0d9d408a74 Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Mon, 22 Oct 2018 08:43:26 +0200 Subject: [PATCH 34/45] Refs #3569. Adds Renesas GR-ROSE platform. --- articles/embedded.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/articles/embedded.md b/articles/embedded.md index 403fb73ed..9e31afb4a 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -86,6 +86,11 @@ To answer these questions, the OFERA EU project as well as several others have a * [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): Early port (in 2014) of ROS 2 alpha for the STM32F4Discovery board and the STM3240G eval board running the RTOS NuttX developed by Víctor Mayoral Vilches and Esteve Fernandez at the OSRF. +* [Renesas GR-ROSE](http://gadget.renesas.com/ja/event/2018/pm_rose.html): + Renesas have integrated their GR-ROSE platform with ROS 2 using DDS-XRCE protocol. They use Micro XRCE-DDS implementation on top of FreeRTOS. + A sample can be found in their forums [renesas forum ](https://japan.renesasrulz.com/gr_user_forum_japanese/f/gr-rose/5201/ros-2-micro-rtps). + They have integrated Micro XRCE-DDS middleware as part of their [online web compiler](http://tool-cloud2.renesas.com/index.php) for the GR-ROSE platform. + ### ROS1-based approaches * [**rosserial**](http://wiki.ros.org/rosserial): Well-known and widely used in the ROS community. From 2f2106fb6405890a07a387bce86c954375adcc1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20L=C3=BCtkebohle?= Date: Tue, 23 Oct 2018 09:12:26 +0200 Subject: [PATCH 35/45] Update articles/embedded.md Co-Authored-By: BorjaOuterelo --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 9e31afb4a..88ef71e80 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -67,7 +67,7 @@ To answer these questions, the OFERA EU project as well as several others have a | A-BUILD-ARDUINO | Q-BUILD | Arduino Build | ROBOTIS has explored building all the libraries using the Arduino IDE, cf. [github.com/ROBOTIS-GIT/OpenCR](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps). This required some manual changes and thus does not scale, but can get you off the ground. | | A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | | A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | -| A-DDS-XRCE | Q-COMM | Use of DDS-XRCE standard protocol | This OMG standard defines the protocol used by microcontrollers to publish and subscribe data to a DDS Domain, standard in ROS 2. OFERA and ROBOTIS have proved that it is a suitable protocol to seamless communicate microcontrollers with ROS 2. | [DDS-XRCE](https://www.omg.org/spec/DDS-XRCE/) | +| A-DDS-XRCE | Q-COMM | Use of DDS-XRCE standard protocol | This OMG standard defines the protocol used by microcontrollers to publish and subscribe data to a DDS Domain, standard in ROS 2. OFERA and ROBOTIS have demonstrated that it is a suitable protocol to seamlessly communicate with microcontrollers. | [DDS-XRCE](https://www.omg.org/spec/DDS-XRCE/) | | A-Micro-XRCE-DDS | Q-COMM | Middleware usage | OFERA, Robotis and others have integrated Micro XRCE-DDS middleware as part of their solutions. This middleware provides an implementation of DDS-XRCE standard. Integrations have been done on top of different RTOSs, NuttX and FreeRTOS and using different underlying transports. | [Micro XRCE-DDS](https://github.com/eProsima/Micro-XRCE-DDS) | ## Prior and on-going works From 08d7cf33821f9dacc2053042688112b0e3db37e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Tue, 23 Oct 2018 10:13:07 +0200 Subject: [PATCH 36/45] Address @iluetkeb's request --- articles/embedded.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 9ee24e05b..53c7259c7 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -65,8 +65,7 @@ To answer these questions, the OFERA EU project as well as several others have a |-----|------------------|--------|-------------| | A-RTOS | Q-RTOS | RTOS Proof-of-Concept | Provide a proof-of-concept RTOS. In the OFERA project, we chose [NuttX](http://nuttx.org/), because it is largely POSIX compatible and thus eases porting. There are also experiments based on [RIOT](https://www.riot-os.org/) (cf. [github.com/astralien3000/riot-ros2](https://github.com/astralien3000/riot-ros2)) and FreeRTOS (cf. [github.com/ros2/ros2_embedded_freertos](https://github.com/ros2/ros2_embedded_freertos)) | | A-BUILD-META | Q-BUILD | Meta-Build | Explores a meta-build approach to transform ROS 2 CMakeLists.txt to RTOS-specific build instructions. | -| A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app in the [NuttX build](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2). | -| A-BUILD-NUTTX-LIB | Q-BUILD | NuttX-specific build as library | OFERA has integrated (parts of) micro-ROS directly as a library in the NuttX build. |TODO | +| A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app in the [NuttX build](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2) as well as a library. | | A-BUILD-ARDUINO | Q-BUILD | Arduino Build | ROBOTIS has explored building all the libraries using the Arduino IDE, cf. [github.com/ROBOTIS-GIT/OpenCR](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps). This required some manual changes and thus does not scale, but can get you off the ground. | | A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | | A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | From fcf4fcc32297891dfea7e3f3428f098f9c474c12 Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Tue, 23 Oct 2018 09:46:53 +0200 Subject: [PATCH 37/45] Refs #3569. Resolves pull requests comments: -Fixes some language misuse. -Splits sentences to single lines to improve diff readability. --- articles/embedded.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 88ef71e80..1cb2cb20d 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -87,7 +87,8 @@ To answer these questions, the OFERA EU project as well as several others have a * [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): Early port (in 2014) of ROS 2 alpha for the STM32F4Discovery board and the STM3240G eval board running the RTOS NuttX developed by Víctor Mayoral Vilches and Esteve Fernandez at the OSRF. * [Renesas GR-ROSE](http://gadget.renesas.com/ja/event/2018/pm_rose.html): - Renesas have integrated their GR-ROSE platform with ROS 2 using DDS-XRCE protocol. They use Micro XRCE-DDS implementation on top of FreeRTOS. + Renesas have integrated their GR-ROSE platform with ROS 2 using DDS-XRCE protocol. + They use Micro XRCE-DDS implementation on top of FreeRTOS. A sample can be found in their forums [renesas forum ](https://japan.renesasrulz.com/gr_user_forum_japanese/f/gr-rose/5201/ros-2-micro-rtps). They have integrated Micro XRCE-DDS middleware as part of their [online web compiler](http://tool-cloud2.renesas.com/index.php) for the GR-ROSE platform. From 39716604fc2aa9c03613e3e6deab2356d355e95c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20D=C4=85browski?= Date: Tue, 23 Oct 2018 12:30:07 +0200 Subject: [PATCH 38/45] Fix typo Co-Authored-By: vmayoral --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 53c7259c7..53a99a1d0 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -36,7 +36,7 @@ A number of things that would be great to have, lets call it a wishlist. Feel fr | W-CONTROL | **Support control-oriented applications** | MCUs are great for control, and micro-ROS should be as well. This usually means hard real-time performance with low jitter and small response times. | | W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | | W-STATIC | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | -| W-BOOT | **Quick boot times compared to native ROS 2 machines** | Microcontrollers provide with the capability of booting very quickly (typically, in the order of tenths of milliseconds or less). This enhance the existing landscape of ROS 2-native devices which in the best cases, require a few seconds to boot an embedded Linux.| +| W-BOOT | **Quick boot times compared to native ROS 2 machines** | Microcontrollers provide with the capability of booting very quickly (typically, in the order of tenths of milliseconds or less). This enhances the existing landscape of ROS 2-native devices which in the best cases, require a few seconds to boot an embedded Linux.| | W-INFOMODEL | **a common interface that facilitates interoperability across different vendors** | An information model for robot devices will facilitate interoperability among modules from different vendors of robot hardware and overall, it would facilitate the integration effort. Within the OFERA project we propose and use the [Hardware Robot Information Model (HRIM)](https://acutronicrobotics.com/modularity/hrim/).| In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [OFERA deliverable D1.7_Requirements.pdf](http://ofera.eu/storage/deliverables/OFERA_D1.7_Requirements.pdf). From 72a89d2440b1b48875be51b2ecd981349d413a07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20D=C4=85browski?= Date: Tue, 23 Oct 2018 12:30:47 +0200 Subject: [PATCH 39/45] Rephrasing in INFOMODEL. Co-Authored-By: vmayoral --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 53a99a1d0..e5800846c 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -37,7 +37,7 @@ A number of things that would be great to have, lets call it a wishlist. Feel fr | W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | | W-STATIC | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | | W-BOOT | **Quick boot times compared to native ROS 2 machines** | Microcontrollers provide with the capability of booting very quickly (typically, in the order of tenths of milliseconds or less). This enhances the existing landscape of ROS 2-native devices which in the best cases, require a few seconds to boot an embedded Linux.| -| W-INFOMODEL | **a common interface that facilitates interoperability across different vendors** | An information model for robot devices will facilitate interoperability among modules from different vendors of robot hardware and overall, it would facilitate the integration effort. Within the OFERA project we propose and use the [Hardware Robot Information Model (HRIM)](https://acutronicrobotics.com/modularity/hrim/).| +| W-INFOMODEL | **A common interface that facilitates interoperability across different vendors** | An information model for robot devices, adapted by vendors of robot modules, would lower costs of integration of robotic systems. Within the OFERA project we propose and use the [Hardware Robot Information Model (HRIM)](https://acutronicrobotics.com/modularity/hrim/).| In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [OFERA deliverable D1.7_Requirements.pdf](http://ofera.eu/storage/deliverables/OFERA_D1.7_Requirements.pdf). From de0fd3f2c98e3d9fbed06aaa4dcd8204b1a11c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Tue, 23 Oct 2018 17:39:33 +0200 Subject: [PATCH 40/45] Fix issue with URL --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index 53c7259c7..c677901b2 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -65,7 +65,7 @@ To answer these questions, the OFERA EU project as well as several others have a |-----|------------------|--------|-------------| | A-RTOS | Q-RTOS | RTOS Proof-of-Concept | Provide a proof-of-concept RTOS. In the OFERA project, we chose [NuttX](http://nuttx.org/), because it is largely POSIX compatible and thus eases porting. There are also experiments based on [RIOT](https://www.riot-os.org/) (cf. [github.com/astralien3000/riot-ros2](https://github.com/astralien3000/riot-ros2)) and FreeRTOS (cf. [github.com/ros2/ros2_embedded_freertos](https://github.com/ros2/ros2_embedded_freertos)) | | A-BUILD-META | Q-BUILD | Meta-Build | Explores a meta-build approach to transform ROS 2 CMakeLists.txt to RTOS-specific build instructions. | -| A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app in the [NuttX build](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ROS2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2) as well as a library. | +| A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app and as a library in the NuttX build. | | A-BUILD-ARDUINO | Q-BUILD | Arduino Build | ROBOTIS has explored building all the libraries using the Arduino IDE, cf. [github.com/ROBOTIS-GIT/OpenCR](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps). This required some manual changes and thus does not scale, but can get you off the ground. | | A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | | A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | From a36e9c85d9a1c3f21a871c2e882f6714070f6d62 Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Wed, 24 Oct 2018 09:33:10 +0200 Subject: [PATCH 41/45] Refs #3569. Makes the text consistent. --- articles/embedded.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 1cb2cb20d..3de5c63e0 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -77,7 +77,7 @@ To answer these questions, the OFERA EU project as well as several others have a * [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. -* [XEL Network by ROBOTIS](https://xelnetwork.readthedocs.io): +* [**XEL Network by ROBOTIS**](https://xelnetwork.readthedocs.io): Product which communicate with ROS 2 (DDS) through DDS-XRCE using Micro XRCE-DDS in the firmware of their CommXel board. This CommXel board manages the rest of the boards conforming the XEL Network and interface them to a ROS 2 space. The CommXel could use Ethernet or UART to communicate using DDS-XRCE. @@ -86,7 +86,7 @@ To answer these questions, the OFERA EU project as well as several others have a * [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): Early port (in 2014) of ROS 2 alpha for the STM32F4Discovery board and the STM3240G eval board running the RTOS NuttX developed by Víctor Mayoral Vilches and Esteve Fernandez at the OSRF. -* [Renesas GR-ROSE](http://gadget.renesas.com/ja/event/2018/pm_rose.html): +* [**Renesas GR-ROSE**](http://gadget.renesas.com/ja/event/2018/pm_rose.html): Renesas have integrated their GR-ROSE platform with ROS 2 using DDS-XRCE protocol. They use Micro XRCE-DDS implementation on top of FreeRTOS. A sample can be found in their forums [renesas forum ](https://japan.renesasrulz.com/gr_user_forum_japanese/f/gr-rose/5201/ros-2-micro-rtps). From 79b9a42410391b0662855f06a275d5c5bad32c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Wed, 24 Oct 2018 11:30:20 +0200 Subject: [PATCH 42/45] Bold H-ROS prior work to be consistent --- articles/embedded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/embedded.md b/articles/embedded.md index c02a60aa0..514a94bc5 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -77,7 +77,7 @@ To answer these questions, the OFERA EU project as well as several others have a ### ROS2-based approaches * [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the Micro XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/). -* [Hardware Robot Operating System (H-ROS)](https://acutronicrobotics.com/modularity/H-ROS/) is an a standardized software and hardware infrastructure to create modular robot hardware. H-ROS is actively being used within the OFERA EU project to benchmark and prototype the capabilities of the ROS 2 stack against the ROS 2 embedded stack. In addition, H-ROS implements selected components of the ROS 2.0 stack for microcontrollers. +* [**Hardware Robot Operating System (H-ROS)**](https://acutronicrobotics.com/modularity/H-ROS/) is an a standardized software and hardware infrastructure to create modular robot hardware. H-ROS is actively being used within the OFERA EU project to benchmark and prototype the capabilities of the ROS 2 stack against the ROS 2 embedded stack. In addition, H-ROS implements selected components of the ROS 2.0 stack for microcontrollers. * [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. From 9c08049c4a51064cb600ec5d2b84353f93f9170c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20L=C3=BCtkebohle?= Date: Sat, 27 Oct 2018 20:34:50 +0200 Subject: [PATCH 43/45] Update embedded.md Reformatted wishlist table into sections, to comply with OSRF's "short lines" requirement. --- articles/embedded.md | 96 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 15 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 514a94bc5..336255655 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -25,21 +25,87 @@ This article documents requirements, design ideas and related works on this unde A number of things that would be great to have, lets call it a wishlist. Feel free to add stuff ;-) -| Key | Title | Description | -|-----|-------|-------------| -| W-SEAMLESS | **Seamless integration with ROS 2** | The embedded ROS 2 stack shall integrate seamlessly with standard ROS 2 stacks and nodes running on more powerful microprocessors. For a standard ROS 2 node, communication (topics, services) from and to software running on the embedded ROS 2 stack should be transparent. The same should hold for other core concepts such as parameters, graph introspection, and run-time reconfiguration by the node lifecycle.| -| W-PORTABILITY | **Portability of ROS 2-based software** | The embedded ROS 2 stack shall resemble or directly use the ROS 2 API -- more precisely the rclcpp API -- to facilitate porting standard ROS 2 nodes to MCUs. | -| W-DEVICES | **Support of a broad spectrum of device classes** | The embedded ROS 2 stack shall support a broad range of MCU device classes, starting from a few tens kilobyte of RAM. | -| W-RTOS | **Support of a broad spectrum of RTOS(s)** | The stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, Zephyr) and provide abstractions with regard to the application software to facilitate porting application components to between RTOSs.| -| W-COMM | **Support of prevalent communication technologies** | To cover the broad range of use-cases for MCUs in robotics, the embedded ROS 2 stack shall be usable with the default ROS 2 middleware standard DDS, simple (custom) serial communication protocols just as common wireless technologies like 6LoWPAN | -| W-MODULARITY | **High Modularity** | The embedded ROS 2 stack shall be highly modular, not only to allow for adaptation to specific hardware features and different RTOS, but also to allow the integration with existing frameworks and to be able to create customized sub-stacks. For example, it shall be usable in the style of rosserial, thus bringing basically the message serialization to the MCU only. Similarly, it should be possible to derive a sub-stack that provides node graph features and publish/subscribe but no parameters and services, and so on. | -| W-CONTROL | **Support control-oriented applications** | MCUs are great for control, and micro-ROS should be as well. This usually means hard real-time performance with low jitter and small response times. | -| W-POWER | **Make low-power modes possible** | MCUs are often used in battery-powered applications, and/or in applications with a large amount of standby time. Therefore, the stack should make it easily possible to save power. | -| W-STATIC | **Use static initialization** | Static initialization is less error-prone, easier to analyze, and shifts memory usage from RAM to flash. It is a requirement for going to very small resource use. | -| W-BOOT | **Quick boot times compared to native ROS 2 machines** | Microcontrollers provide with the capability of booting very quickly (typically, in the order of tenths of milliseconds or less). This enhances the existing landscape of ROS 2-native devices which in the best cases, require a few seconds to boot an embedded Linux.| -| W-INFOMODEL | **A common interface that facilitates interoperability across different vendors** | An information model for robot devices, adapted by vendors of robot modules, would lower costs of integration of robotic systems. Within the OFERA project we propose and use the [Hardware Robot Information Model (HRIM)](https://acutronicrobotics.com/modularity/hrim/).| - -In the EU project OFERA, we compiled a longer list of requirements to an embedded ROS 2 stack, which might serve as a good basis for the discussion. Please see Section 5 in [OFERA deliverable D1.7_Requirements.pdf](http://ofera.eu/storage/deliverables/OFERA_D1.7_Requirements.pdf). +### W-SEAMLESS: *Seamless integration with ROS 2* + +The embedded ROS 2 stack shall integrate seamlessly with standard +ROS 2 stacks and nodes running on more powerful microprocessors. For +a standard ROS 2 node, communication (topics, services) from and to +software running on the embedded ROS 2 stack should be transparent. +The same should hold for other core concepts such as parameters, +graph introspection, and run-time reconfiguration by the node lifecycle. + +### W-PORTABILITY: *Portability of ROS 2-based software* + +The embedded ROS 2 stack shall resemble or directly use the ROS 2 API +-- more precisely the rclcpp API -- to facilitate porting standard +ROS 2 nodes to MCUs. + +### W-DEVICES *Support of a broad spectrum of device classes* + +The embedded ROS 2 stack shall support a broad range of MCU device +classes, starting from a few tens kilobyte of RAM. + +### W-RTOS: *Support of a broad spectrum of RTOS(s)* + +The stack shall be adaptable to different RTOS (e.g., NuttX, FreeRTOS, +Zephyr) and provide abstractions with regard to the application +software to facilitate porting application components to between RTOSs. + +### W-COMM: *Support of prevalent communication technologies* + +To cover the broad range of use-cases for MCUs in robotics, the embedded +ROS 2 stack shall be usable with the default ROS 2 middleware standard +DDS, simple (custom) serial communication protocols just as common +wireless technologies like 6LoWPAN + +### W-MODULARITY: *High Modularity* + +The embedded ROS 2 stack shall be highly modular, not only to allow for +adaptation to specific hardware features and different RTOS, but also to +allow the integration with existing frameworks and to be able to create +customized sub-stacks. For example, it shall be usable in the style of +rosserial, thus bringing basically the message serialization to the MCU +only. Similarly, it should be possible to derive a sub-stack that provides +node graph features and publish/subscribe but no parameters and services, +and so on. + +### W-CONTROL: *Support control-oriented applications* + +MCUs are great for control, and micro-ROS should be as well. This usually +means hard real-time performance with low jitter and small response times. + +### W-POWER *Make low-power modes possible* + +MCUs are often used in battery-powered applications, and/or in applications +with a large amount of standby time. Therefore, the stack should make it +easily possible to save power. + +### W-STATIC: *Use static initialization* + +Static initialization is less error-prone, easier to analyze, and shifts +memory usage from RAM to flash. It is a requirement for going to very small +resource use. + +### W-BOOT: *Quick boot times compared to native ROS 2 machines* + +Microcontrollers provide with the capability of booting very quickly +(typically, in the order of tenths of milliseconds or less). This enhances +the existing landscape of ROS 2-native devices which in the best cases, +require a few seconds to boot an embedded Linux. + +### W-INFOMODEL: *A common interface that facilitates interoperability across different vendors* + +An information model for robot devices, adapted by vendors of robot modules, +would lower costs of integration of robotic systems. Within the OFERA project +we propose and use the +[Hardware Robot Information Model (HRIM)](https://acutronicrobotics.com/modularity/hrim/).| + +### More Details / Ideas + +In the EU project OFERA, we compiled a longer list of requirements to an embedded +ROS 2 stack, which might serve as a good basis for the discussion. Please see +Section 5 in +[OFERA deliverable D1.7_Requirements.pdf](http://ofera.eu/storage/deliverables/OFERA_D1.7_Requirements.pdf). ## Questions From b3b2f66dad520814dffb69dae61282ac4926f537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20L=C3=BCtkebohle?= Date: Sat, 27 Oct 2018 20:43:22 +0200 Subject: [PATCH 44/45] Reformatted non-table parts to comply with short-line requirement. --- articles/embedded.md | 93 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 21 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 336255655..9d7c3c4e1 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -17,13 +17,24 @@ author: 'In alphabetic order: [Adam Dąbrowski](https://github.com/adamdbrw), [B Original Author: {{ page.author }} -While standard ROS 2 can run on Linux-class embedded devices, smaller microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 and -M4 class MCUs are popular for motion control and sensor integration, but have little RAM and storage. ARM Cortex-M3 is widely used in many sensors due to its optimized power consumption capabilities and ultra low power modes. These microcontrollers are often running with small batteries, e.g. for environmental sensors or small consumer robots, which requires efficient power management. We aim to address these devices through a combination of specialized, ROS 2-interoperable stack as well as the use of Real-Time Operating Systems (RTOS). - -This article documents requirements, design ideas and related works on this undertaking. +While standard ROS 2 can run on Linux-class embedded devices, smaller +microcontrollers (MCU) are still a challenge. For example, ARM Cortex-M3 +and -M4 class MCUs are popular for motion control and sensor integration, +but have little RAM and storage. ARM Cortex-M3 is widely used in many +sensors due to its optimized power consumption capabilities and ultra low +power modes. These microcontrollers are often running with small batteries, +e.g. for environmental sensors or small consumer robots, which requires +efficient power management. We aim to address these devices through a +combination of specialized, ROS 2-interoperable stack as well as the use +of Real-Time Operating Systems (RTOS). + +This article documents feature wishes, requirements, design ideas and +related work on this undertaking. ## Wishlist -A number of things that would be great to have, lets call it a wishlist. Feel free to add stuff ;-) +A number of things that would be great to have, lets call it a wishlist. +Feel free to add stuff ;-) ### W-SEAMLESS: *Seamless integration with ROS 2* @@ -141,40 +152,80 @@ To answer these questions, the OFERA EU project as well as several others have a ## Prior and on-going works ### ROS2-based approaches -* [**EU project OFERA**](http://ofera.eu/): The EU project OFERA (Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less than 100kB RAM. The project partners currently investigate of using the ROS 2 rmw, rcl and rclcpp layers as-is on the Micro XRCE-DDS implementation of the upcoming XRCE-DDS standard. In parallel, a more modular approach in the style of rosserial is investigated. In the project's use-cases, NuttX is considered as primary choice for the RTOS. Beyond the project page, additional details of the project results can be found at [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/). - -* [**Hardware Robot Operating System (H-ROS)**](https://acutronicrobotics.com/modularity/H-ROS/) is an a standardized software and hardware infrastructure to create modular robot hardware. H-ROS is actively being used within the OFERA EU project to benchmark and prototype the capabilities of the ROS 2 stack against the ROS 2 embedded stack. In addition, H-ROS implements selected components of the ROS 2.0 stack for microcontrollers. - -* [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): Tailored and optimized implementation of the ROS 2 publish/subscribe and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation of the upcoming XRCE-DDS middleware standard running on an STM32F7. +* [**EU project OFERA**](http://ofera.eu/): The EU project OFERA +(Open Framework for Embedded Robot Applications) aims at a ROS 2-compatible +stack for MCUs in the range of STM32F4 or STM32L1, i.e. with possibly less +than 100kB RAM. The project partners currently investigate of using the +ROS 2 rmw, rcl and rclcpp layers as-is on the Micro XRCE-DDS implementation +of the upcoming XRCE-DDS standard. In parallel, a more modular approach in +the style of rosserial is investigated. In the project's use-cases, NuttX +is considered as primary choice for the RTOS. Beyond the project page, +additional details of the project results can be found at +[microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/). + +* [**Hardware Robot Operating System (H-ROS)**](https://acutronicrobotics.com/modularity/H-ROS/) +is an a standardized software and hardware infrastructure to create modular +robot hardware. H-ROS is actively being used within the OFERA EU project to +benchmark and prototype the capabilities of the ROS 2 stack against the ROS 2 +embedded stack. In addition, H-ROS implements selected components of the ROS +2.0 stack for microcontrollers. + +* [**ROS 2 library for OpenCR by ROBOTIS**](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps/arduino/opencr_arduino/opencr/libraries/ROS2): +Tailored and optimized implementation of the ROS 2 publish/subscribe +and clock API for the Micro XRCE-DDS (formerly micro-RTPS) implementation +of the upcoming XRCE-DDS middleware standard running on an STM32F7. * [**XEL Network by ROBOTIS**](https://xelnetwork.readthedocs.io): - Product which communicate with ROS 2 (DDS) through DDS-XRCE using Micro XRCE-DDS in the firmware of their CommXel board. - This CommXel board manages the rest of the boards conforming the XEL Network and interface them to a ROS 2 space. + Product which communicate with ROS 2 (DDS) through DDS-XRCE using Micro + XRCE-DDS in the firmware of their CommXel board. + This CommXel board manages the rest of the boards conforming the XEL + Network and interface them to a ROS 2 space. The CommXel could use Ethernet or UART to communicate using DDS-XRCE. -* [**freeRTPS**](https://github.com/ros2/freertps): A free, portable, minimalist implementation of the RTPS protocol for microcontrollers such as the STM32F7 developed at the OSRF. FreeRTPS shall allow to run ROS 2 with standard DDS as-is on stronger MCUs. This project has been discontinued in 2016. +* [**freeRTPS**](https://github.com/ros2/freertps): A free, portable, +minimalist implementation of the RTPS protocol for microcontrollers such as +the STM32F7 developed at the OSRF. FreeRTPS shall allow to run ROS 2 with +standard DDS as-is on stronger MCUs. This project has been discontinued in 2016. -* [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): Early port (in 2014) of ROS 2 alpha for the STM32F4Discovery board and the STM3240G eval board running the RTOS NuttX developed by Víctor Mayoral Vilches and Esteve Fernandez at the OSRF. +* [**ros2_embedded_nuttx**](https://github.com/ros2/ros2_embedded_nuttx): +Early port (in 2014) of ROS 2 alpha for the STM32F4Discovery board and the +STM3240G eval board running the RTOS NuttX developed by Víctor Mayoral Vilches +and Esteve Fernandez at the OSRF. * [**Renesas GR-ROSE**](http://gadget.renesas.com/ja/event/2018/pm_rose.html): Renesas have integrated their GR-ROSE platform with ROS 2 using DDS-XRCE protocol. They use Micro XRCE-DDS implementation on top of FreeRTOS. - A sample can be found in their forums [renesas forum ](https://japan.renesasrulz.com/gr_user_forum_japanese/f/gr-rose/5201/ros-2-micro-rtps). - They have integrated Micro XRCE-DDS middleware as part of their [online web compiler](http://tool-cloud2.renesas.com/index.php) for the GR-ROSE platform. + A sample can be found in their forums + [renesas forum ](https://japan.renesasrulz.com/gr_user_forum_japanese/f/gr-rose/5201/ros-2-micro-rtps). + They have integrated Micro XRCE-DDS middleware as part of their + [online web compiler](http://tool-cloud2.renesas.com/index.php) for the GR-ROSE platform. ### ROS1-based approaches -* [**rosserial**](http://wiki.ros.org/rosserial): Well-known and widely used in the ROS community. +* [**rosserial**](http://wiki.ros.org/rosserial): Well-known and widely used +in the ROS community. -* [**mROS**](https://github.com/tlk-emb/mROS/): A new work on bringing ROS1 concepts (including nodes and the ROS1 middleware) on stronger MCUs, cf. - *Hideki Takase, Tomoya Mori, Kazuyoshi Takagi and Naofumi Takagi: 'Work-in-Progress: Design Concept of a Lightweight Runtime Environment for Robot Software Components onto Embedded Devices' in Proc. of ESWEEK, Torino, Italy, September 2018.* +* [**mROS**](https://github.com/tlk-emb/mROS/): A new + work on bringing ROS1 concepts (including nodes and the + ROS1 middleware) on stronger MCUs, cf. + *Hideki Takase, Tomoya Mori, Kazuyoshi Takagi and Naofumi Takagi: + 'Work-in-Progress: Design Concept of a Lightweight Runtime Environment + for Robot Software Components onto Embedded Devices' in + Proc. of ESWEEK, Torino, Italy, September 2018.* ## Design Discussion -The following figure may serve as a starting point for the design discussion. It depicts the major layers from the real-time operating system to the application, in the style the ROS 2 standard stack. +The following figure may serve as a starting point for the design discussion. +It depicts the major layers from the real-time operating system to the +application, in the style the ROS 2 standard stack. ![micro-ROS](/img/embedded/features_with_dependencies.png) -At the same time, the diagram illustrates the possible feature set of the client library -- ideally in a modular fashion so that different profiles can be derived from it. The vertical bar at each feature gives an indication of the dependencies with lower layers and thus on the portability to different RTOS and middlewares. +At the same time, the diagram illustrates the possible feature set of the +client library -- ideally in a modular fashion so that different profiles +can be derived from it. The vertical bar at each feature gives an indication +of the dependencies with lower layers and thus on the portability to +different RTOS and middlewares. -In the OFERA project, a more detailed diagram has been developed, which can be found at [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/). +In the OFERA project, a more detailed diagram has been developed, which can +be found at [microros.github.io/micro-ROS/](https://microros.github.io/micro-ROS/). From 7916600743150793eebcd4aa995b450efc76b2b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20L=C3=BCtkebohle?= Date: Sat, 27 Oct 2018 20:53:07 +0200 Subject: [PATCH 45/45] Final set of reformattings to achieve short lines. --- articles/embedded.md | 124 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 101 insertions(+), 23 deletions(-) diff --git a/articles/embedded.md b/articles/embedded.md index 9d7c3c4e1..2bc6ee81a 100644 --- a/articles/embedded.md +++ b/articles/embedded.md @@ -125,29 +125,107 @@ To determine how feasible that is, and to come up with the actual requirements a | Key | Related Wish | Question | |-----|-------------|----------| -| Q-RTOS | W-RTOS, W-PORTABILITY | Which RTOS(s) do we use as the basis? | -| Q-BUILD | W-RTOS, W-PORTABILITY | How do we handle the RTOS(s) respective build-systems? | -| Q-LANG | W-PORTABILITY | Which language should be used, and at what spec level? | -| Q-API | W-PORTABILITY, W-MODULARITY, W-STATIC, W-POWER | How should the API look in general?| -| Q-PERF | W-PORTABILITY, W-DEVICES, W-CONTROL, W-STATIC | What are the performance implications of the API?| -| Q-COMM | W-COMM, W-SEAMLESS| Which communication/middleware technology is used?| - -## Analyses and Experiments - -To answer these questions, the OFERA EU project as well as several others have already undertaken or are planning exploratory work. - -*Meta-Note*: Please only add a short description here, linking to more detailed pages if necessary. - -| Key | Related Question | Action | Description | -|-----|------------------|--------|-------------| -| A-RTOS | Q-RTOS | RTOS Proof-of-Concept | Provide a proof-of-concept RTOS. In the OFERA project, we chose [NuttX](http://nuttx.org/), because it is largely POSIX compatible and thus eases porting. There are also experiments based on [RIOT](https://www.riot-os.org/) (cf. [github.com/astralien3000/riot-ros2](https://github.com/astralien3000/riot-ros2)) and FreeRTOS (cf. [github.com/ros2/ros2_embedded_freertos](https://github.com/ros2/ros2_embedded_freertos)) | -| A-BUILD-META | Q-BUILD | Meta-Build | Explores a meta-build approach to transform ROS 2 CMakeLists.txt to RTOS-specific build instructions. | -| A-BUILD-NUTTX | Q-BUILD | NuttX-specific build | OFERA has integrated (parts of) micro-ROS directly as an app and as a library in the NuttX build. | -| A-BUILD-ARDUINO | Q-BUILD | Arduino Build | ROBOTIS has explored building all the libraries using the Arduino IDE, cf. [github.com/ROBOTIS-GIT/OpenCR](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps). This required some manual changes and thus does not scale, but can get you off the ground. | -| A-NUTTX-LIBCXX | Q-LANG | C++11/higher support for NuttX | Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. | -| A-PERF-RCLCPP-RESOURCE | Q-PERF | Determine resource use of rclcpp | | -| A-DDS-XRCE | Q-COMM | Use of DDS-XRCE standard protocol | This OMG standard defines the protocol used by microcontrollers to publish and subscribe data to a DDS Domain, standard in ROS 2. OFERA and ROBOTIS have demonstrated that it is a suitable protocol to seamlessly communicate with microcontrollers. | [DDS-XRCE](https://www.omg.org/spec/DDS-XRCE/) | -| A-Micro-XRCE-DDS | Q-COMM | Middleware usage | OFERA, Robotis and others have integrated Micro XRCE-DDS middleware as part of their solutions. This middleware provides an implementation of DDS-XRCE standard. Integrations have been done on top of different RTOSs, NuttX and FreeRTOS and using different underlying transports. | [Micro XRCE-DDS](https://github.com/eProsima/Micro-XRCE-DDS) | + +### Q-RTOS: *Which RTOS(s) do we use as the basis?* + +#### Related: W-RTOS, W-PORTABILITY + +### Q-BUILD: *How do we handle the RTOS(s) respective build-systems?* + +#### Related: W-RTOS, W-PORTABILITY + +### Q-LANG: *Which language(s) should be used, and at what spec level?* + +#### Related: W-PORTABILITY + +### Q-API: *How should the API look in general?* + +#### Related: W-PORTABILITY, W-MODULARITY, W-STATIC, W-POWER + +### Q-PERF: * What are the performance implications of the API?* + +#### Related: W-PORTABILITY, W-DEVICES, W-CONTROL, W-STATIC + +### Q-COMM: *Which communication/middleware technology is used?* + +#### Related: W-COMM, W-SEAMLESS + + +## Analyse and Experiment Actions + +To answer these questions, the OFERA EU project as well as several +others have already undertaken or are planning exploratory work. + +*Meta-Note*: Please only add a short description here, linking to +more detailed pages if necessary. + +### A-RTOS: *RTOS Proof-of-Concept* + +#### Questions: *Q-RTOS* + +Provide a proof-of-concept RTOS. In the OFERA project, we chose +[NuttX](http://nuttx.org/), because it is largely POSIX compatible +and thus eases porting. There are also experiments based on +[RIOT](https://www.riot-os.org/) (cf. +[github.com/astralien3000/riot-ros2](https://github.com/astralien3000/riot-ros2)) +and FreeRTOS (cf. +[github.com/ros2/ros2_embedded_freertos](https://github.com/ros2/ros2_embedded_freertos)) | + +### A-BUILD-META: *Meta-Build* + +#### Questions: Q-BUILD + +Explores a meta-build approach to transform ROS 2 CMakeLists.txt to +RTOS-specific build instructions. | + +### A-BUILD-NUTTX: *NuttX-specific build* + +#### Questions: Q-BUILD + +OFERA has integrated (parts of) micro-ROS directly as an app and +as a library in the NuttX build. + +### A-BUILD-ARDUINO: *Arduino Build* + +### Questions: Q-BUILD + +ROBOTIS has explored building all the libraries using the Arduino +IDE, cf. [github.com/ROBOTIS-GIT/OpenCR](https://github.com/ROBOTIS-GIT/OpenCR/tree/feature-ros2-micrortps). +This required some manual changes and thus does not scale, but +can get you off the ground. + +### A-NUTTX-LIBCXX: *C++11/higher support for NuttX* + +#### Questions: Q-LANG + +Build libxx from the LLVM project on NuttX, as a pre-requisite to building rclcpp. + +### A-PERF-RCLCPP-RESOURCE: *Determine resource use of rclcpp* + +#### Questions: Q-PERF + +There are doubts whether rclcpp can really fit tiny MCUs, but we'll only +know once we tried and measured it. + +### A-DDS-XRCE: *Use of DDS-XRCE standard protocol* + +#### Questions: Q-COMM + +This OMG standard defines a protocol for use by microcontrollers to +publish and subscribe data to a DDS Domain, standard in ROS 2. OFERA +and ROBOTIS have demonstrated that it is a suitable protocol to seamlessly +communicate with microcontrollers. See [DDS-XRCE](https://www.omg.org/spec/DDS-XRCE/) + +### A-Micro-XRCE-DDS: *Micro-XRCE Middleware usage* + +#### Questions: Q-COMM + +OFERA, Robotis and others have integrated Micro XRCE-DDS middleware as +part of their solutions. This middleware provides an implementation of +DDS-XRCE standard. Integrations have been done on top of different RTOSs, +NuttX and FreeRTOS and using different underlying transports. + +See [Micro XRCE-DDS](https://github.com/eProsima/Micro-XRCE-DDS) | ## Prior and on-going works