├── .github └── ISSUE_TEMPLATE │ └── general-issue.md ├── .gitignore ├── 3rd-party-licenses.txt ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md ├── assets ├── diagrams │ └── architecture.puml └── images │ ├── board.png │ ├── crazyflie_icon.jpg │ ├── disco_l475_iot1.jpg │ ├── ros2_icon.png │ ├── rqt.png │ └── zephyr_logo.png ├── docker-compose.yml └── dockerfile ├── agent ├── Dockerfile └── entrypoint.sh ├── builder ├── Dockerfile └── entrypoint.sh └── rqt ├── Dockerfile ├── entrypoint.sh └── src ├── default.perspective └── demo_sensors.perspective /.github/ISSUE_TEMPLATE/general-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: General issue 3 | about: General issue template for micro-ROS 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Issue template 11 | 12 | - Hardware description: 13 | - RTOS: 14 | - Installation type: 15 | - Version or commit hash: 16 | 17 | #### Steps to reproduce the issue 18 | 19 | 20 | #### Expected behavior 21 | 22 | #### Actual behavior 23 | 24 | #### Additional information 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dockerfile/.env/variables.env 2 | -------------------------------------------------------------------------------- /3rd-party-licenses.txt: -------------------------------------------------------------------------------- 1 | Third Party Licenses 2 | ==================== 3 | 4 | This repository does not directly contain 3rd party source code. 5 | 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Want to contribute? Great! You can do so through the standard GitHub pull 4 | request model. For large contributions we do encourage you to file a ticket in 5 | the GitHub issues tracking system prior to any code development to coordinate 6 | with the system_modes development team early in the process. Coordinating up 7 | front helps to avoid frustration later on. 8 | 9 | Your contribution must be licensed under the Apache-2.0 license, the license 10 | used by this project. 11 | 12 | ## Add / retain copyright notices 13 | 14 | Include a copyright notice and license in each new file to be contributed, 15 | consistent with the style used by this project. If your contribution contains 16 | code under the copyright of a third party, document its origin, license, and 17 | copyright holders. 18 | 19 | ## Sign your work 20 | 21 | This project tracks patch provenance and licensing using a modified Developer 22 | Certificate of Origin (DCO; from [OSDL][DCO]) and Signed-off-by tags initially 23 | developed by the Linux kernel project. 24 | 25 | ``` 26 | system_modes Developer's Certificate of Origin. Version 1.0 27 | 28 | By making a contribution to this project, I certify that: 29 | 30 | (a) The contribution was created in whole or in part by me and I 31 | have the right to submit it under the "Apache License, Version 2.0" 32 | ("Apache-2.0"); or 33 | 34 | (b) The contribution is based upon previous work that is covered by 35 | an appropriate open source license and I have the right under 36 | that license to submit that work with modifications, whether 37 | created in whole or in part by me, under the Apache-2.0 license; 38 | or 39 | 40 | (c) The contribution was provided directly to me by some other 41 | person who certified (a) or (b) and I have not modified it. 42 | 43 | (d) I understand and agree that this project and the contribution 44 | are public and that a record of the contribution (including all 45 | metadata and personal information I submit with it, including my 46 | sign-off) is maintained indefinitely and may be redistributed 47 | consistent with this project and the requirements of the Apache-2.0 48 | license or any open source license(s) involved, where they are 49 | relevant. 50 | 51 | (e) I am granting the contribution to this project under the terms of 52 | Apache-2.0. 53 | 54 | http://www.apache.org/licenses/LICENSE-2.0 55 | ``` 56 | 57 | With the sign-off in a commit message you certify that you authored the patch 58 | or otherwise have the right to submit it under an open source license. The 59 | procedure is simple: To certify above system_modes Developer's Certificate of 60 | Origin 1.0 for your contribution just append a line 61 | 62 | Signed-off-by: Random J Developer 63 | 64 | to every commit message using your real name or your pseudonym and a valid 65 | email address. 66 | 67 | If you have set your `user.name` and `user.email` git configs you can 68 | automatically sign the commit by running the git-commit command with the `-s` 69 | option. There may be multiple sign-offs if more than one developer was 70 | involved in authoring the contribution. 71 | 72 | For a more detailed description of this procedure, please see 73 | [SubmittingPatches][] which was extracted from the Linux kernel project, and 74 | which is stored in an external repository. 75 | 76 | ### Individual vs. Corporate Contributors 77 | 78 | Often employers or academic institution have ownership over code that is 79 | written in certain circumstances, so please do due diligence to ensure that 80 | you have the right to submit the code. 81 | 82 | If you are a developer who is authorized to contribute to system_modes on 83 | behalf of your employer, then please use your corporate email address in the 84 | Signed-off-by tag. Otherwise please use a personal email address. 85 | 86 | ## Maintain Copyright holder / Contributor list 87 | 88 | Each contributor is responsible for identifying themselves in the 89 | [NOTICE](NOTICE) file, the project's list of copyright holders and authors. 90 | Please add the respective information corresponding to the Signed-off-by tag 91 | as part of your first pull request. 92 | 93 | If you are a developer who is authorized to contribute to system_modes on 94 | behalf of your employer, then add your company / organization to the list of 95 | copyright holders in the [NOTICE](NOTICE) file. As author of a corporate 96 | contribution you can also add your name and corporate email address as in the 97 | Signed-off-by tag. 98 | 99 | If your contribution is covered by this project's DCO's clause "(c) The 100 | contribution was provided directly to me by some other person who certified 101 | (a) or (b) and I have not modified it", please add the appropriate copyright 102 | holder(s) to the [NOTICE](NOTICE) file as part of your contribution. 103 | 104 | 105 | [DCO]: http://web.archive.org/web/20070306195036/http://osdlab.org/newsroom/press_releases/2004/2004_05_24_dco.html 106 | 107 | [SubmittingPatches]: https://github.com/wking/signed-off-by/blob/7d71be37194df05c349157a2161c7534feaf86a4/Documentation/SubmittingPatches 108 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | 2 | # This is the official list of copyright holders and authors. 3 | # 4 | # Often employers or academic institutions have ownership over code that is 5 | # written in certain circumstances, so please do due diligence to ensure that 6 | # you have the right to submit the code. 7 | # 8 | # When adding J Random Contributor's name to this file, either J's name on its 9 | # own or J's name associated with J's organization's name should be added, 10 | # depending on whether J's employer (or academic institution) has ownership 11 | # over code that is written for this project. 12 | # 13 | # How to add names to this file: 14 | # Individual's name . 15 | # 16 | # If Individual's organization is copyright holder of her contributions add the 17 | # organization's name, optionally also the contributor's name: 18 | # 19 | # Organization's name 20 | # Individual's name 21 | # 22 | # Please keep the list sorted. 23 | 24 | eProsima 25 | Jose Antonio Moral 26 | Pablo Garrido 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # micro-ROS Sensors Demo 2 | 3 | This demo illustrates micro-ROS capabilities in combination with the [STM32L4 Discovery kit IoT node](https://www.st.com/en/evaluation-tools/b-l475e-iot01a.html) node and [Zephyr RTOS](https://www.zephyrproject.org/). 4 | micro-ROS integration with common ROS 2 tools such as [RQt](http://wiki.ros.org/rqt) are shown in this demo case of use. The used board is an ST development board with a complete set of sensors and communication peripherals:  3-axis inertial units (IMU), environmental sensors (temperature, humidity, and pressure), a time of flight laser ranging sensor, NFC, low-power radio and 802.11 devices. 5 | 6 | The vast majority of these peripherals are out-of-the-box supported by Zephyr RTOS. So, by using the micro-ROS + Zephyr port, this demo case will put some of these sensors' measurements to the ROS 2 world. Concretely, the 3-axis accelerometer data will be published on `/sensors/imu` ROS 2 topic as a three-position array of 32 bits floating-point data. The range measurement of the time of flight laser sensor will be published on `/sensors/tof` ROS 2 topic. 7 | 8 | Finally, in order to test communications from the ROS 2 world to the embedded board running micro-ROS, the board is subscribed to a simple boolean topic on `/sensors/led` that will turn a LED on and off. 9 | 10 | This demo is also focused on the micro-ROS's middleware layer where eProsima Micro XRCE-DDS is the default implementation. This software, base on the [DDS-XRCE](https://www.omg.org/spec/DDS-XRCE/About-DDS-XRCE/) wire protocol, offers to micro-ROS client-server communication with the following characteristics: 11 | 12 | * Multi-transport protocol support (UDP, TCP and Serial). 13 | * Peer-to-peer communication. 14 | * Server discovery. 15 | * Best-effort and reliable communication. 16 | * Message fragmentation. 17 | 18 | This demo aims to be an entry point for further IoT development using the STM32L4 Discovery kit IoT node, Zephyr and micro-ROS. It will also show the ease of use of the micro-ROS development environment for a ROS 2 developer. 19 | ![](http://www.plantuml.com/plantuml/proxy?cache=no&src=https://raw.githubusercontent.com/micro-ROS/micro-ROS_sensors_demo/master/assets/diagrams/architecture.puml) 20 | 21 | ## Hardware 22 | 23 | The following is a list of the hardware needed to reproduce this demo: 24 | 25 | * 1 x [STM32L4 Discovery kit IoT node](https://www.st.com/en/evaluation-tools/b-l475e-iot01a.html) 26 | * 1 x MicroUSB to USB cable. 27 | 28 | ## How to build and flash the firmware? 29 | 30 | 1. Run the builder Docker: 31 | ```bash 32 | docker-compose run stiot_builder 33 | ``` 34 | This demo aims to be an entry point for further IoT development using STM32L4 Discovery kit IoT node, Zephyr and micro-ROS. It will also show the ease of use of the micro-ROS development environment for a ROS 2 developer. 35 | 36 | 2. Configure and build the micro-ROS firmware inside the Docker: 37 | ```bash 38 | ros2 run micro_ros_setup configure_firmware.sh sensors_publisher --transport serial-usb 39 | ros2 run micro_ros_setup build_firmware.sh 40 | ``` 41 | 42 | 3. Connect the board using the STLink USB port and make sure the board is supplied by `5V_ST_LINK` in the bottom supply jumpers. 43 | 4. Flash the micro-ROS firmware: 44 | ```bash 45 | ros2 run micro_ros_setup flash_firmware.sh 46 | ``` 47 | 48 | ## How to use? 49 | 50 | To start the application just two steps are needed: 51 | 52 | 1. Connect host USB to your computer. You can disconnect the STLink USB port and modify the board supply jumper on the bottom layer to `5V_USB_FS`. 53 | 54 | 2. Remember to enable X11 sharing for all hosts with: `xhost +` 55 | 56 | 3. Up the Docker Compose: 57 | 58 | ```bash 59 | docker-compose up -d 60 | ``` 61 | 62 | To stop the application just down the Docker Compose: 63 | 64 | ```bash 65 | docker-compose down 66 | ``` 67 | 68 | ## Purpose of the Project 69 | 70 | This software is not ready for production use. It has neither been developed nor 71 | tested for a specific use case. However, the license conditions of the 72 | applicable Open Source licenses allow you to adapt the software to your needs. 73 | Before using it in a safety relevant setting, make sure that the software 74 | fulfills your requirements and adjust it according to any applicable safety 75 | standards, e.g., ISO 26262. 76 | 77 | ## License 78 | 79 | This repository is open-sourced under the Apache-2.0 license. See the [LICENSE](LICENSE) file for details. 80 | 81 | For a list of other open-source components included in this repository, 82 | see the file [3rd-party-licenses.txt](3rd-party-licenses.txt). 83 | 84 | ## Known Issues/Limitations 85 | 86 | There are no known limitations. 87 | -------------------------------------------------------------------------------- /assets/diagrams/architecture.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | 3 | skinparam monochrome true 4 | 5 | node as ros2 { 6 | interface "/sensors/imu" as imu 7 | interface "/sensors/tof" as tof 8 | interface "/sensors/led" as led 9 | } 10 | 11 | ' node as st_disco 12 | 13 | ' node as st_disco {} 14 | 15 | [] as st_disco 16 | 17 | [] as rqt 18 | 19 | ' [] as rqt 20 | 21 | ' [translator.py\n\n ] as translator 22 | 23 | note top of ros2 24 | | Topic | Type | 25 | | /sensors/imu | Point32 | 26 | | /sensors/tof | Float32 | 27 | | /sensors/led | Bool | 28 | end note 29 | 30 | st_disco -up-> imu 31 | st_disco -up-> tof 32 | st_disco <.up. led 33 | 34 | rqt <-up- imu 35 | rqt <-up- tof 36 | rqt .up.> led 37 | 38 | @endutml -------------------------------------------------------------------------------- /assets/images/board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micro-ROS/micro-ROS_sensors_demo/7fd84a2664fbfcc8aaccd4c483b3e87114272673/assets/images/board.png -------------------------------------------------------------------------------- /assets/images/crazyflie_icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micro-ROS/micro-ROS_sensors_demo/7fd84a2664fbfcc8aaccd4c483b3e87114272673/assets/images/crazyflie_icon.jpg -------------------------------------------------------------------------------- /assets/images/disco_l475_iot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micro-ROS/micro-ROS_sensors_demo/7fd84a2664fbfcc8aaccd4c483b3e87114272673/assets/images/disco_l475_iot1.jpg -------------------------------------------------------------------------------- /assets/images/ros2_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micro-ROS/micro-ROS_sensors_demo/7fd84a2664fbfcc8aaccd4c483b3e87114272673/assets/images/ros2_icon.png -------------------------------------------------------------------------------- /assets/images/rqt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micro-ROS/micro-ROS_sensors_demo/7fd84a2664fbfcc8aaccd4c483b3e87114272673/assets/images/rqt.png -------------------------------------------------------------------------------- /assets/images/zephyr_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/micro-ROS/micro-ROS_sensors_demo/7fd84a2664fbfcc8aaccd4c483b3e87114272673/assets/images/zephyr_logo.png -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | stiot_builder: 4 | build: ./dockerfile/builder 5 | # image: pablogs9/microrossensorsdemo_stiot_builder:latest 6 | volumes: 7 | - /dev/bus/usb:/dev/bus/usb 8 | privileged: true 9 | stiot_agent: 10 | build: ./dockerfile/agent 11 | volumes: 12 | - /dev:/dev 13 | network_mode: "host" 14 | privileged: true 15 | stiot_rqt: 16 | build: ./dockerfile/rqt 17 | volumes: 18 | - /tmp/.X11-unix:/tmp/.X11-unix 19 | privileged: true 20 | environment: 21 | DISPLAY: unix:0 22 | network_mode: "host" 23 | -------------------------------------------------------------------------------- /dockerfile/agent/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microros/micro-ros-agent:foxy 2 | 3 | COPY ./entrypoint.sh / 4 | 5 | ENTRYPOINT ["/entrypoint.sh"] 6 | CMD ["bash"] 7 | -------------------------------------------------------------------------------- /dockerfile/agent/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source "/opt/ros/$ROS_DISTRO/setup.bash" 5 | source "/uros_ws/install/setup.bash" 6 | 7 | DEV=/dev/serial/by-id/usb-ZEPHYR_Zephyr_ST_Discovery_4E345008004C0049-if00 8 | 9 | while true; do 10 | while [ ! -e "$DEV" ]; do 11 | sleep 1 12 | echo "Waiting for device" 13 | done 14 | 15 | echo "Serial detected. Running agent." 16 | 17 | ros2 run micro_ros_agent micro_ros_agent serial --dev $DEV -v6 & 18 | export APP_PID=$! 19 | 20 | while [ -e "$DEV" ]; do 21 | sleep 1 22 | done 23 | 24 | echo "Serial disconnected. Running agent." 25 | 26 | kill -9 $APP_PID 27 | done 28 | 29 | -------------------------------------------------------------------------------- /dockerfile/builder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microros/base:foxy 2 | 3 | RUN . /opt/ros/$ROS_DISTRO/setup.sh \ 4 | && . ./install/setup.sh \ 5 | && apt update \ 6 | && ros2 run micro_ros_setup create_firmware_ws.sh zephyr discovery_l475_iot1 \ 7 | && rm -rf /var/lib/apt/lists/* 8 | 9 | COPY ./entrypoint.sh / 10 | 11 | ENTRYPOINT ["/entrypoint.sh"] 12 | CMD ["bash"] 13 | -------------------------------------------------------------------------------- /dockerfile/builder/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source "/opt/ros/$ROS_DISTRO/setup.bash" 5 | source "/uros_ws/install/setup.bash" 6 | 7 | exec "$@" -------------------------------------------------------------------------------- /dockerfile/rqt/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ros:foxy 2 | 3 | RUN apt update \ 4 | && DEBIAN_FRONTEND=noninteractive apt install -y ros-foxy-desktop \ 5 | && rm -rf /var/lib/apt/lists/* 6 | 7 | WORKDIR / 8 | COPY ./src ./src 9 | 10 | COPY ./entrypoint.sh / 11 | ENTRYPOINT ["/entrypoint.sh"] 12 | CMD ["bash"] 13 | -------------------------------------------------------------------------------- /dockerfile/rqt/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | source "/opt/ros/$ROS_DISTRO/setup.bash" 5 | 6 | while true; do 7 | if ros2 topic list | grep "sensors/imu" > /dev/null; then 8 | break 9 | fi 10 | done 11 | 12 | exec rqt --perspective-file /src/demo_sensors.perspective -------------------------------------------------------------------------------- /dockerfile/rqt/src/default.perspective: -------------------------------------------------------------------------------- 1 | { 2 | "keys": {}, 3 | "groups": { 4 | "mainwindow": { 5 | "keys": { 6 | "geometry": { 7 | "repr(QByteArray.hex)": "QtCore.QByteArray(b'01d9d0cb00020000000004270000045300000b630000086f000004270000046f00000b630000086f00000000000000000780')", 8 | "type": "repr(QByteArray.hex)", 9 | "pretty-print": " ' S c o ' o c o " 10 | }, 11 | "state": { 12 | "repr(QByteArray.hex)": "QtCore.QByteArray(b'000000ff00000000fd00000001000000030000073d000003d5fc0100000004fc00000000000003e20000013f00fffffffc0200000002fb00000042007200710074005f0070006c006f0074005f005f0050006c006f0074005f005f0031005f005f00440061007400610050006c006f00740057006900640067006500740100000016000001e80000009200fffffffb00000042007200710074005f0070006c006f0074005f005f0050006c006f0074005f005f0032005f005f00440061007400610050006c006f00740057006900640067006500740100000204000001e70000009200fffffffb00000044007200710074005f00670072006100700068005f005f0052006f007300470072006100700068005f005f0031005f005f0052006f0073004700720061007000680055006901000002a1000002590000000000000000fb0000006a007200710074005f0072006f0062006f0074005f007300740065006500720069006e0067005f005f0052006f0062006f0074005300740065006500720069006e0067005f005f0031005f005f0052006f0062006f0074005300740065006500720069006e00670055006901000002fe000001410000000000000000fb00000058007200710074005f007000750062006c00690073006800650072005f005f005000750062006c00690073006800650072005f005f0031005f005f005000750062006c0069007300680065007200570069006400670065007401000003e8000003550000023d00ffffff0000073d0000000000000004000000040000000800000008fc00000001000000030000000100000036004d0069006e0069006d0069007a006500640044006f0063006b00570069006400670065007400730054006f006f006c0062006100720000000000ffffffff0000000000000000')", 13 | "type": "repr(QByteArray.hex)", 14 | "pretty-print": " ? Y A U = = " 15 | } 16 | }, 17 | "groups": { 18 | "toolbar_areas": { 19 | "keys": { 20 | "MinimizedDockWidgetsToolbar": { 21 | "repr": "8", 22 | "type": "repr" 23 | } 24 | }, 25 | "groups": {} 26 | } 27 | } 28 | }, 29 | "pluginmanager": { 30 | "keys": { 31 | "running-plugins": { 32 | "repr": "{'rqt_plot/Plot': [1, 2], 'rqt_publisher/Publisher': [1]}", 33 | "type": "repr" 34 | } 35 | }, 36 | "groups": { 37 | "plugin__rqt_graph__RosGraph__1": { 38 | "keys": {}, 39 | "groups": { 40 | "dock_widget__RosGraphUi": { 41 | "keys": { 42 | "dock_widget_title": { 43 | "repr": "'Node Graph'", 44 | "type": "repr" 45 | }, 46 | "dockable": { 47 | "repr": "'true'", 48 | "type": "repr" 49 | }, 50 | "parent": { 51 | "repr": "None", 52 | "type": "repr" 53 | } 54 | }, 55 | "groups": {} 56 | }, 57 | "plugin": { 58 | "keys": { 59 | "actionlib_check_box_state": { 60 | "repr": "'true'", 61 | "type": "repr" 62 | }, 63 | "auto_fit_graph_check_box_state": { 64 | "repr": "'true'", 65 | "type": "repr" 66 | }, 67 | "dead_sinks_check_box_state": { 68 | "repr": "'true'", 69 | "type": "repr" 70 | }, 71 | "filter_line_edit_text": { 72 | "repr": "'/'", 73 | "type": "repr" 74 | }, 75 | "graph_type_combo_box_index": { 76 | "repr": "'2'", 77 | "type": "repr" 78 | }, 79 | "group_image_check_box_state": { 80 | "repr": "'true'", 81 | "type": "repr" 82 | }, 83 | "group_tf_check_box_state": { 84 | "repr": "'true'", 85 | "type": "repr" 86 | }, 87 | "hide_dynamic_reconfigure_check_box_state": { 88 | "repr": "'true'", 89 | "type": "repr" 90 | }, 91 | "hide_tf_nodes_check_box_state": { 92 | "repr": "'true'", 93 | "type": "repr" 94 | }, 95 | "highlight_connections_check_box_state": { 96 | "repr": "'true'", 97 | "type": "repr" 98 | }, 99 | "leaf_topics_check_box_state": { 100 | "repr": "'true'", 101 | "type": "repr" 102 | }, 103 | "namespace_cluster_spin_box_value": { 104 | "repr": "'0'", 105 | "type": "repr" 106 | }, 107 | "quiet_check_box_state": { 108 | "repr": "'true'", 109 | "type": "repr" 110 | }, 111 | "topic_filter_line_edit_text": { 112 | "repr": "'/'", 113 | "type": "repr" 114 | }, 115 | "unreachable_check_box_state": { 116 | "repr": "'true'", 117 | "type": "repr" 118 | } 119 | }, 120 | "groups": {} 121 | } 122 | } 123 | }, 124 | "plugin__rqt_plot__Plot__1": { 125 | "keys": {}, 126 | "groups": { 127 | "dock_widget__DataPlotWidget": { 128 | "keys": { 129 | "dock_widget_title": { 130 | "repr": "'MatPlot'", 131 | "type": "repr" 132 | }, 133 | "dockable": { 134 | "repr": "True", 135 | "type": "repr" 136 | }, 137 | "parent": { 138 | "repr": "None", 139 | "type": "repr" 140 | } 141 | }, 142 | "groups": {} 143 | }, 144 | "plugin": { 145 | "keys": { 146 | "autoscroll": { 147 | "repr": "True", 148 | "type": "repr" 149 | }, 150 | "plot_type": { 151 | "repr": "1", 152 | "type": "repr" 153 | }, 154 | "topics": { 155 | "repr": "['/sensors/imu//x', '/sensors/imu//y', '/sensors/imu//z']", 156 | "type": "repr" 157 | }, 158 | "x_limits": { 159 | "repr": "[-31.726714372634888, 68.27328562736511]", 160 | "type": "repr" 161 | }, 162 | "y_limits": { 163 | "repr": "[-3.0, 10.017000198364258]", 164 | "type": "repr" 165 | } 166 | }, 167 | "groups": {} 168 | } 169 | } 170 | }, 171 | "plugin__rqt_plot__Plot__2": { 172 | "keys": {}, 173 | "groups": { 174 | "dock_widget__DataPlotWidget": { 175 | "keys": { 176 | "dock_widget_title": { 177 | "repr": "'MatPlot (2)'", 178 | "type": "repr" 179 | }, 180 | "dockable": { 181 | "repr": "True", 182 | "type": "repr" 183 | }, 184 | "parent": { 185 | "repr": "None", 186 | "type": "repr" 187 | } 188 | }, 189 | "groups": {} 190 | }, 191 | "plugin": { 192 | "keys": { 193 | "autoscroll": { 194 | "repr": "True", 195 | "type": "repr" 196 | }, 197 | "plot_type": { 198 | "repr": "1", 199 | "type": "repr" 200 | }, 201 | "topics": { 202 | "repr": "'/sensors/tof///data'", 203 | "type": "repr" 204 | }, 205 | "x_limits": { 206 | "repr": "[-60.67521262168884, 39.32478737831116]", 207 | "type": "repr" 208 | }, 209 | "y_limits": { 210 | "repr": "[0.0, 8.1899995803833]", 211 | "type": "repr" 212 | } 213 | }, 214 | "groups": {} 215 | } 216 | } 217 | }, 218 | "plugin__rqt_publisher__Publisher__1": { 219 | "keys": {}, 220 | "groups": { 221 | "dock_widget__PublisherWidget": { 222 | "keys": { 223 | "dock_widget_title": { 224 | "repr": "'Message Publisher'", 225 | "type": "repr" 226 | }, 227 | "dockable": { 228 | "repr": "True", 229 | "type": "repr" 230 | }, 231 | "parent": { 232 | "repr": "None", 233 | "type": "repr" 234 | } 235 | }, 236 | "groups": {} 237 | }, 238 | "plugin": { 239 | "keys": { 240 | "publishers": { 241 | "repr": "\"[{'topic_name': '/sensors/led', 'type_name': 'std_msgs/msg/Bool', 'rate': 1.0, 'enabled': False, 'publisher_id': 0, 'counter': 123, 'expressions': {'/sensors/led/data': 'i%2==0'}}]\"", 242 | "type": "repr" 243 | } 244 | }, 245 | "groups": {} 246 | } 247 | } 248 | }, 249 | "plugin__rqt_robot_steering__RobotSteering__1": { 250 | "keys": {}, 251 | "groups": { 252 | "plugin": { 253 | "keys": { 254 | "topic": { 255 | "repr": "'/cmd_vel'", 256 | "type": "repr" 257 | }, 258 | "vw_max": { 259 | "repr": "'3'", 260 | "type": "repr" 261 | }, 262 | "vw_min": { 263 | "repr": "'-3'", 264 | "type": "repr" 265 | }, 266 | "vx_max": { 267 | "repr": "'1'", 268 | "type": "repr" 269 | }, 270 | "vx_min": { 271 | "repr": "'-1'", 272 | "type": "repr" 273 | } 274 | }, 275 | "groups": {} 276 | } 277 | } 278 | } 279 | } 280 | } 281 | } 282 | } -------------------------------------------------------------------------------- /dockerfile/rqt/src/demo_sensors.perspective: -------------------------------------------------------------------------------- 1 | { 2 | "keys": {}, 3 | "groups": { 4 | "mainwindow": { 5 | "keys": { 6 | "geometry": { 7 | "repr(QByteArray.hex)": "QtCore.QByteArray(b'01d9d0cb00020000000004270000045300000b630000086f000004270000046f00000b630000086f00000000000000000780')", 8 | "type": "repr(QByteArray.hex)", 9 | "pretty-print": " ' S c o ' o c o " 10 | }, 11 | "state": { 12 | "repr(QByteArray.hex)": "QtCore.QByteArray(b'000000ff00000000fd00000001000000030000073d000003d5fc0100000004fc00000000000003e20000013f00fffffffc0200000002fb00000042007200710074005f0070006c006f0074005f005f0050006c006f0074005f005f0031005f005f00440061007400610050006c006f00740057006900640067006500740100000016000001e80000009200fffffffb00000042007200710074005f0070006c006f0074005f005f0050006c006f0074005f005f0032005f005f00440061007400610050006c006f00740057006900640067006500740100000204000001e70000009200fffffffb00000044007200710074005f00670072006100700068005f005f0052006f007300470072006100700068005f005f0031005f005f0052006f0073004700720061007000680055006901000002a1000002590000000000000000fb0000006a007200710074005f0072006f0062006f0074005f007300740065006500720069006e0067005f005f0052006f0062006f0074005300740065006500720069006e0067005f005f0031005f005f0052006f0062006f0074005300740065006500720069006e00670055006901000002fe000001410000000000000000fb00000058007200710074005f007000750062006c00690073006800650072005f005f005000750062006c00690073006800650072005f005f0031005f005f005000750062006c0069007300680065007200570069006400670065007401000003e8000003550000023d00ffffff0000073d0000000000000004000000040000000800000008fc00000001000000030000000100000036004d0069006e0069006d0069007a006500640044006f0063006b00570069006400670065007400730054006f006f006c0062006100720000000000ffffffff0000000000000000')", 13 | "type": "repr(QByteArray.hex)", 14 | "pretty-print": " ? Y A U = = " 15 | } 16 | }, 17 | "groups": { 18 | "toolbar_areas": { 19 | "keys": { 20 | "MinimizedDockWidgetsToolbar": { 21 | "repr": "8", 22 | "type": "repr" 23 | } 24 | }, 25 | "groups": {} 26 | } 27 | } 28 | }, 29 | "pluginmanager": { 30 | "keys": { 31 | "running-plugins": { 32 | "repr": "{'rqt_plot/Plot': [1, 2], 'rqt_publisher/Publisher': [1]}", 33 | "type": "repr" 34 | } 35 | }, 36 | "groups": { 37 | "plugin__rqt_graph__RosGraph__1": { 38 | "keys": {}, 39 | "groups": { 40 | "dock_widget__RosGraphUi": { 41 | "keys": { 42 | "dock_widget_title": { 43 | "repr": "'Node Graph'", 44 | "type": "repr" 45 | }, 46 | "dockable": { 47 | "repr": "'true'", 48 | "type": "repr" 49 | }, 50 | "parent": { 51 | "repr": "None", 52 | "type": "repr" 53 | } 54 | }, 55 | "groups": {} 56 | }, 57 | "plugin": { 58 | "keys": { 59 | "actionlib_check_box_state": { 60 | "repr": "'true'", 61 | "type": "repr" 62 | }, 63 | "auto_fit_graph_check_box_state": { 64 | "repr": "'true'", 65 | "type": "repr" 66 | }, 67 | "dead_sinks_check_box_state": { 68 | "repr": "'true'", 69 | "type": "repr" 70 | }, 71 | "filter_line_edit_text": { 72 | "repr": "'/'", 73 | "type": "repr" 74 | }, 75 | "graph_type_combo_box_index": { 76 | "repr": "'2'", 77 | "type": "repr" 78 | }, 79 | "group_image_check_box_state": { 80 | "repr": "'true'", 81 | "type": "repr" 82 | }, 83 | "group_tf_check_box_state": { 84 | "repr": "'true'", 85 | "type": "repr" 86 | }, 87 | "hide_dynamic_reconfigure_check_box_state": { 88 | "repr": "'true'", 89 | "type": "repr" 90 | }, 91 | "hide_tf_nodes_check_box_state": { 92 | "repr": "'true'", 93 | "type": "repr" 94 | }, 95 | "highlight_connections_check_box_state": { 96 | "repr": "'true'", 97 | "type": "repr" 98 | }, 99 | "leaf_topics_check_box_state": { 100 | "repr": "'true'", 101 | "type": "repr" 102 | }, 103 | "namespace_cluster_spin_box_value": { 104 | "repr": "'0'", 105 | "type": "repr" 106 | }, 107 | "quiet_check_box_state": { 108 | "repr": "'true'", 109 | "type": "repr" 110 | }, 111 | "topic_filter_line_edit_text": { 112 | "repr": "'/'", 113 | "type": "repr" 114 | }, 115 | "unreachable_check_box_state": { 116 | "repr": "'true'", 117 | "type": "repr" 118 | } 119 | }, 120 | "groups": {} 121 | } 122 | } 123 | }, 124 | "plugin__rqt_plot__Plot__1": { 125 | "keys": {}, 126 | "groups": { 127 | "dock_widget__DataPlotWidget": { 128 | "keys": { 129 | "dock_widget_title": { 130 | "repr": "'MatPlot'", 131 | "type": "repr" 132 | }, 133 | "dockable": { 134 | "repr": "True", 135 | "type": "repr" 136 | }, 137 | "parent": { 138 | "repr": "None", 139 | "type": "repr" 140 | } 141 | }, 142 | "groups": {} 143 | }, 144 | "plugin": { 145 | "keys": { 146 | "autoscroll": { 147 | "repr": "True", 148 | "type": "repr" 149 | }, 150 | "plot_type": { 151 | "repr": "1", 152 | "type": "repr" 153 | }, 154 | "topics": { 155 | "repr": "['/sensors/imu//x', '/sensors/imu//y', '/sensors/imu//z']", 156 | "type": "repr" 157 | }, 158 | "x_limits": { 159 | "repr": "[-41.007572412490845, 58.992427587509155]", 160 | "type": "repr" 161 | }, 162 | "y_limits": { 163 | "repr": "[-3.0, 11.739999771118164]", 164 | "type": "repr" 165 | } 166 | }, 167 | "groups": {} 168 | } 169 | } 170 | }, 171 | "plugin__rqt_plot__Plot__2": { 172 | "keys": {}, 173 | "groups": { 174 | "dock_widget__DataPlotWidget": { 175 | "keys": { 176 | "dock_widget_title": { 177 | "repr": "'MatPlot (2)'", 178 | "type": "repr" 179 | }, 180 | "dockable": { 181 | "repr": "True", 182 | "type": "repr" 183 | }, 184 | "parent": { 185 | "repr": "None", 186 | "type": "repr" 187 | } 188 | }, 189 | "groups": {} 190 | }, 191 | "plugin": { 192 | "keys": { 193 | "autoscroll": { 194 | "repr": "True", 195 | "type": "repr" 196 | }, 197 | "plot_type": { 198 | "repr": "1", 199 | "type": "repr" 200 | }, 201 | "topics": { 202 | "repr": "'/sensors/tof///data'", 203 | "type": "repr" 204 | }, 205 | "x_limits": { 206 | "repr": "[-40.98789978027344, 59.01210021972656]", 207 | "type": "repr" 208 | }, 209 | "y_limits": { 210 | "repr": "[0.0, 8.1899995803833]", 211 | "type": "repr" 212 | } 213 | }, 214 | "groups": {} 215 | } 216 | } 217 | }, 218 | "plugin__rqt_publisher__Publisher__1": { 219 | "keys": {}, 220 | "groups": { 221 | "dock_widget__PublisherWidget": { 222 | "keys": { 223 | "dock_widget_title": { 224 | "repr": "'Message Publisher'", 225 | "type": "repr" 226 | }, 227 | "dockable": { 228 | "repr": "True", 229 | "type": "repr" 230 | }, 231 | "parent": { 232 | "repr": "None", 233 | "type": "repr" 234 | } 235 | }, 236 | "groups": {} 237 | }, 238 | "plugin": { 239 | "keys": { 240 | "publishers": { 241 | "repr": "\"[{'topic_name': '/sensors/led', 'type_name': 'std_msgs/msg/Bool', 'rate': 1.0, 'enabled': False, 'publisher_id': 0, 'counter': 37, 'expressions': {'/sensors/led/data': 'i%2==0'}}]\"", 242 | "type": "repr" 243 | } 244 | }, 245 | "groups": {} 246 | } 247 | } 248 | }, 249 | "plugin__rqt_robot_steering__RobotSteering__1": { 250 | "keys": {}, 251 | "groups": { 252 | "plugin": { 253 | "keys": { 254 | "topic": { 255 | "repr": "'/cmd_vel'", 256 | "type": "repr" 257 | }, 258 | "vw_max": { 259 | "repr": "'3'", 260 | "type": "repr" 261 | }, 262 | "vw_min": { 263 | "repr": "'-3'", 264 | "type": "repr" 265 | }, 266 | "vx_max": { 267 | "repr": "'1'", 268 | "type": "repr" 269 | }, 270 | "vx_min": { 271 | "repr": "'-1'", 272 | "type": "repr" 273 | } 274 | }, 275 | "groups": {} 276 | } 277 | } 278 | } 279 | } 280 | } 281 | } 282 | } --------------------------------------------------------------------------------