├── LICENSE ├── README.md ├── neuronbot2_bringup ├── CMakeLists.txt ├── cfg │ ├── camera.yaml │ ├── ekf.yaml │ └── hardware.yaml ├── include │ └── neuronbot2_bringup │ │ ├── data_holder.hpp │ │ ├── dataframe.hpp │ │ ├── neuron_serial.hpp │ │ ├── simple_dataframe.hpp │ │ └── simple_dataframe_master.hpp ├── launch │ └── bringup_launch.py ├── package.xml └── src │ ├── main.cpp │ ├── neuron_serial.cpp │ └── simple_dataframe_master.cpp ├── neuronbot2_description ├── CMakeLists.txt ├── meshes │ └── neuronbot2 │ │ ├── base_link.stl │ │ ├── laser_link.stl │ │ └── wheel_link.stl ├── package.xml ├── rviz │ └── urdf.rviz └── urdf │ ├── neuronbot2.urdf │ ├── neuronbot2_w_front_camera.urdf │ └── neuronbot2_w_top_camera.urdf ├── neuronbot2_gazebo ├── CMakeLists.txt ├── launch │ ├── neuronbot2_world.launch.py │ ├── robot_state_publisher.launch.py │ └── spawn_nb2.launch.py ├── models │ ├── mememan │ │ ├── model.config │ │ └── model.sdf │ ├── neuronbot2 │ │ ├── meshes │ │ │ └── neuronbot2 │ │ │ │ ├── base_link.stl │ │ │ │ ├── laser_link.stl │ │ │ │ └── wheel_link.stl │ │ ├── model.config │ │ └── model.sdf │ ├── neuronbot2_w_front_camera │ │ ├── meshes │ │ │ └── neuronbot2 │ │ │ │ ├── base_link.stl │ │ │ │ ├── laser_link.stl │ │ │ │ └── wheel_link.stl │ │ ├── model.config │ │ └── model.sdf │ ├── neuronbot2_w_top_camera │ │ ├── meshes │ │ │ └── neuronbot2 │ │ │ │ ├── base_link.stl │ │ │ │ ├── laser_link.stl │ │ │ │ └── wheel_link.stl │ │ ├── model.config │ │ └── model.sdf │ └── phenix │ │ ├── model.config │ │ └── model.sdf ├── package.xml └── worlds │ ├── mememan_world.model │ └── phenix_world.model ├── neuronbot2_nav ├── CMakeLists.txt ├── launch │ ├── bringup_launch.py │ ├── localization_launch.py │ ├── navigation_launch.py │ ├── rviz_view_launch.py │ └── slam_launch.py ├── map │ ├── F9.pgm │ ├── F9.yaml │ ├── mememan.pgm │ ├── mememan.yaml │ ├── phenix.pgm │ ├── phenix.yaml │ ├── training_room.pgm │ ├── training_room.yaml │ ├── wg.pgm │ └── wg.yaml ├── package.xml ├── param │ └── neuronbot_params.yaml └── rviz │ ├── nav2.rviz │ ├── nav2_default_view.rviz │ └── nav2_namespaced_view.rviz ├── neuronbot2_slam ├── CMakeLists.txt ├── README.md ├── config │ ├── cartographer.lua │ ├── cartographer_bag.lua │ └── slam_toolbox_params.yaml ├── launch │ ├── cartographer_launch.py │ ├── gmapping_launch.py │ └── slam_toolbox_launch.py ├── package.xml └── rviz │ └── slam.rviz ├── neuronbot2_tools ├── neuronbot2_init │ └── neuronbot2_init.sh └── neuronbot2_led │ ├── .gitignore │ ├── README.md │ ├── launch │ └── led_control_launch.py │ ├── neuronbot2_led │ ├── __init__.py │ └── led_control.py │ ├── package.xml │ ├── resource │ └── neuronbot2_led │ ├── setup.cfg │ └── setup.py └── readme_resource ├── 2d_nav_goal.png ├── 2d_setestimate.png ├── NueronBot2_sim.jpg ├── TF_tree.png ├── basedriver.png ├── basedriver_and_nav2.png ├── basedriver_and_slamtoolbox.png ├── bt_navigator_setUsingDedicatedThread.png ├── mememan_launch_nav.png ├── mememan_world.png ├── nav2_bt.gif ├── nav2_rosgraph.png ├── nav_estimate.gif ├── nav_set_goal.gif ├── nb2.png ├── nb2_opening_re.gif ├── nb2_robot.png ├── phenix_world.png ├── slam_move_base_8x.gif ├── slam_rviz.png ├── slam_teleop_8x.gif └── teleop.png /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 2021 ADLINK Technology 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NeuronBot2 in ROS 2 2 | 3 | 4 | ## Introduction 5 | NeuronBot2 is the newest version of NeuronBot made by Adlink, which fully supports ROS 1 and ROS 2. 6 | 7 | ### Features 8 | * Nice 9 | * Good 10 | * Awesome 11 | * Wonderful 12 | * Magnificent 13 | * Impressive 14 | * Intimidating 15 | * Stunning 16 | * Extraordinary 17 | * Superb 18 | 19 | 20 | This package includes the functions to bring up the robot, to make it SLAM, to navigate, and to simulate it with your own computer, testing the same functions mentioned before. 21 | 22 | Users are able to checkout to different branches of this package to run on ROS 1 and ROS 2, please check different branches. 23 | 24 | ## Installation 25 | 26 | 1. [Install ROS 2](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html) 27 | 2. Install ROS 2 development tools 28 | ``` 29 | sudo apt update && sudo apt install -y \ 30 | build-essential \ 31 | cmake \ 32 | git \ 33 | libbullet-dev \ 34 | python3-colcon-common-extensions \ 35 | python3-flake8 \ 36 | python3-pip \ 37 | python3-pytest-cov \ 38 | python3-rosdep \ 39 | python3-setuptools \ 40 | python3-vcstool \ 41 | openssh-server \ 42 | wget 43 | ``` 44 | 45 | 3. Git clone NeuronBot2 and other related sources 46 | ``` 47 | mkdir -p ~/neuronbot2_ros2_ws/src 48 | cd ~/neuronbot2_ros2_ws/ 49 | wget https://raw.githubusercontent.com/Adlink-ROS/neuronbot2_ros2.repos/humble/neuronbot2_ros2.repos 50 | vcs import src < neuronbot2_ros2.repos 51 | ``` 52 | 4. Install other dependencies 53 | ``` 54 | cd ~/neuronbot2_ros2_ws/ 55 | source /opt/ros/humble/setup.bash 56 | rosdep update 57 | rosdep install --from-paths src --ignore-src -r -y --rosdistro humble 58 | ``` 59 | 5. Initialze NeuronBot2 ttyUSB nodes, 60 | `neuronbot_init.sh` is needed to be run only once for the first setup. If you use NeuronBot2 for simulation only, not for the real robot, then you can skip this step. 61 | ``` 62 | cd ~/neuronbot2_ros2_ws/src/neuronbot2/neuronbot2_tools/neuronbot2_init/ 63 | sudo ./neuronbot2_init.sh 64 | ``` 65 | 66 | 6. Colcon build the package 67 | ``` 68 | cd ~/neuronbot2_ros2_ws/ 69 | source /opt/ros/humble/setup.bash 70 | colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release 71 | source ~/neuronbot2_ros2_ws/install/local_setup.bash 72 | ``` 73 | 74 | --- 75 | 76 | ## Bring up your NeuronBot2 77 | ![](readme_resource/nb2_opening_re.gif) 78 | 79 | Now, it's time to launch your NeuronBot2 and do a Robotic-Hello-World thing -- teleop it. 80 | 81 | If you are looking for the NeuronBot2 simulation, please jump to [Bring up in Simulation](https://github.com/Adlink-ROS/neuronbot2#bring-up-in-simulation). 82 | 83 | ### Launch NeuronBot2 84 | Open a new terminal (Ctrl + Alt + t). 85 | ``` 86 | source /opt/ros/humble/setup.bash 87 | source ~/neuronbot2_ros2_ws/install/local_setup.bash 88 | ros2 launch neuronbot2_bringup bringup_launch.py 89 | ``` 90 | ### Teleop NeuronBot2 91 | ``` 92 | source /opt/ros/humble/setup.bash 93 | ros2 run teleop_twist_keyboard teleop_twist_keyboard 94 | ``` 95 | Follow the hints and start to cruise your NeuronBot2. 96 | 97 | ![](readme_resource/teleop.png) 98 | ### SLAM your map 99 | 1. Launch SLAM as well as Rviz. 100 | 101 | ***We provide three slam methods.*** 102 | 103 | * Gmapping 104 | ``` 105 | ros2 launch neuronbot2_slam gmapping_launch.py open_rviz:=true 106 | ``` 107 | * Slam_toolbox 108 | ``` 109 | ros2 launch neuronbot2_slam slam_toolbox_launch.py open_rviz:=true 110 | ``` 111 | * Cartographer 112 | ``` 113 | ros2 launch neuronbot2_slam cartographer_launch.py open_rviz:=true 114 | ``` 115 | 2. Teleop NeuronBot2 to explore the world 116 | ``` 117 | # Run on the other terminal 118 | source /opt/ros/humble/setup.bash 119 | ros2 run teleop_twist_keyboard teleop_twist_keyboard 120 | ``` 121 | 3. Save the map 122 | ``` 123 | source /opt/ros/humble/setup.bash 124 | ros2 run nav2_map_server map_saver_cli -f / 125 | ``` 126 | 127 | The map is ready and SLAM can be turned off. 128 | ### Navigation 129 | 130 | * Try navigation on your own map. 131 | ``` 132 | ros2 launch neuronbot2_nav bringup_launch.py map:= open_rviz:=true 133 | ``` 134 | 1. Set Estimation 135 | 136 | ![](readme_resource/2d_setestimate.png) 137 | 138 | Click "2D Pose Estimate", and set estimation to the approximate location of robot on the map. 139 | 140 | 2. Set Goal 141 | 142 | ![](readme_resource/2d_nav_goal.png) 143 | 144 | Click "2D Nav Goal", and set goal to any free space on the map. 145 | 146 | 147 | --- 148 | ## Bring up in Simulation 149 | ![](readme_resource/NueronBot2_sim.jpg) 150 | ### Summon the NeuronBot2 into Gazebo 151 | 1. Specify the model path for Gazebo 152 | ``` 153 | source /opt/ros/humble/setup.bash 154 | source ~/neuronbot2_ros2_ws/install/local_setup.bash 155 | ``` 156 | 2. Launch Gazebo simulation. 157 | 158 | ***There are two worlds for users to explore.*** 159 | * Mememan world 160 | ``` 161 | ros2 launch neuronbot2_gazebo neuronbot2_world.launch.py world_model:=mememan_world.model 162 | ``` 163 | ![](./readme_resource/mememan_world.png) 164 | * Phenix world 165 | ``` 166 | ros2 launch neuronbot2_gazebo neuronbot2_world.launch.py world_model:=phenix_world.model 167 | ``` 168 | ![](readme_resource/phenix_world.png) 169 | 3. Teleop it in the world 170 | 171 | Users are able to control the NeuronBot2 with the following rosnode. Run it with the other terminal. 172 | ``` 173 | source /opt/ros/humble/local_setup.bash 174 | ros2 run teleop_twist_keyboard teleop_twist_keyboard 175 | ``` 176 | ![](readme_resource/teleop.png) 177 | 178 | ***p.s. To alleviate CPU consumption, close GAZEBO GUI by clicking x. This will not end the simulation server, which is running backend*** 179 | ### SLAM the world 180 | 1. Launch SLAM as well as Rviz while the Gazebo simulation is running. 181 | 182 | ***We provide three slam methods.*** 183 | 184 | * Gmapping 185 | ``` 186 | ros2 launch neuronbot2_slam gmapping_launch.py open_rviz:=true use_sim_time:=true 187 | ``` 188 | * Slam_toolbox 189 | ``` 190 | ros2 launch neuronbot2_slam slam_toolbox_launch.py open_rviz:=true use_sim_time:=true 191 | ``` 192 | * Cartographer 193 | ``` 194 | ros2 launch neuronbot2_slam cartographer_launch.py open_rviz:=true use_sim_time:=true 195 | ``` 196 | ![](readme_resource/slam_rviz.png) 197 | 2. Teleop NeuronBot2 to explore the world 198 | ``` 199 | # Run on the other terminal 200 | source /opt/ros/humble/setup.bash 201 | ros2 run teleop_twist_keyboard teleop_twist_keyboard 202 | ``` 203 | ![](readme_resource/slam_teleop_8x.gif) 204 | 3. Save the map 205 | ``` 206 | source /opt/ros/humble/setup.bash 207 | ros2 run nav2_map_server map_saver_cli -f / 208 | ``` 209 | 210 | Then, you shall turn off SLAM. 211 | ### Navigate to the desired location 212 | Once users obtain the map, pgm file, and yaml file, navigation is good to go. 213 | 214 | 1. Launch Navigation as well as Rviz while the Gazebo simulation is running. If you haven't finished SLAM to get the map files, no worries, you can use the default maps **mememan** and **phenix** we have built for you. 215 | 216 | * Bringup all navigation nodes with specific parameters 217 | ``` 218 | ros2 launch neuronbot2_nav bringup_launch.py map:=$HOME/neuronbot2_ros2_ws/src/neuronbot2/neuronbot2_nav/map/mememan.yaml open_rviz:=true use_sim_time:=true 219 | ``` 220 | 221 | * Try navigation on your own map. ***Put the .yaml and .pgm into " ~/neuronbot2_ros2_ws/src/neuronbot2/neuronbot2_nav/map/ "*** 222 | 223 | ``` 224 | ros2 launch neuronbot2_nav bringup_launch.py map:=.yaml open_rviz:=true use_sim_time:=true 225 | ``` 226 | * Supported parameters and its value for launch files 227 | 228 | **map**: phenix.yaml | mememan.yaml (default) 229 | 230 | **open_rviz**: true | false (default) 231 | 232 | **use_sim_time**: true | false (default) # if you run navigation in simulation, then use_sim_time must be set to true 233 | 234 | * You can also run localization and navigation in separate terminals. 235 | 236 | ``` 237 | # terminal 1 238 | ros2 launch neuronbot2_nav localization_launch.py use_sim_time:=true 239 | # terminal 2 240 | ros2 launch neuronbot2_nav navigation_launch.py use_sim_time:=true 241 | # terminal 3 242 | ros2 launch neuronbot2_nav rviz_view_launch.py use_sim_time:=true 243 | ``` 244 | 245 | ![](readme_resource/mememan_launch_nav.png) 246 | 2. Set Estimation 247 | 248 | Click "2D Pose Estimate", and set estimation to the approximate location of robot on the map. 249 | 250 | ![](readme_resource/nav_estimate.gif) 251 | 3. Set Goal 252 | 253 | Click "2D Nav Goal", and set goal to any free space on the map. 254 | 255 | ![](readme_resource/nav_set_goal.gif) 256 | 257 | ### Control with Behavior Tree 258 | To run this demo, users should execute Gazebo server and Navigation (with Rviz for visualization) first. 259 | 260 | 1. Open the other terminal and source the environment variables. 261 | ``` 262 | source /opt/ros/humble/setup.bash 263 | source ~/neuronbot2_ros2_ws/install/local_setup.bash 264 | ``` 265 | 2. Run Behavior Tree 266 | 267 | Please go to check this repos: https://github.com/Adlink-ROS/BT_ros2 268 | ![](readme_resource/nav2_bt.gif) 269 | -------------------------------------------------------------------------------- /neuronbot2_bringup/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Set minimum required version of cmake, project name and compile options 3 | ################################################################################ 4 | cmake_minimum_required(VERSION 3.5) 5 | project(neuronbot2_bringup) 6 | 7 | if(NOT CMAKE_CXX_STANDARD) 8 | set(CMAKE_CXX_STANDARD 14) 9 | endif() 10 | 11 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 12 | add_compile_options(-Wall -Wextra -Wpedantic) 13 | endif() 14 | 15 | ################################################################################ 16 | # Find ament packages and libraries for ament and system dependencies 17 | ################################################################################ 18 | find_package(ament_cmake REQUIRED) 19 | find_package(geometry_msgs REQUIRED) 20 | find_package(rclcpp REQUIRED) 21 | find_package(std_msgs REQUIRED) 22 | find_package(serial REQUIRED) 23 | find_package(tf2_geometry_msgs REQUIRED) 24 | find_package(tf2 REQUIRED) 25 | find_package(tf2_ros REQUIRED) 26 | find_package(nav_msgs REQUIRED) 27 | find_package(sensor_msgs REQUIRED) 28 | 29 | ################################################################################ 30 | # Build 31 | ################################################################################ 32 | include_directories( 33 | include include/ 34 | ) 35 | 36 | set(EXECUTABLE_NAME "neuronbot2_driver") 37 | 38 | add_executable(${EXECUTABLE_NAME} 39 | src/main.cpp 40 | src/simple_dataframe_master.cpp 41 | src/neuron_serial.cpp 42 | ) 43 | set(DEPENDENCIES 44 | "rclcpp" 45 | "std_msgs" 46 | "geometry_msgs" 47 | "tf2_geometry_msgs" 48 | "tf2" 49 | "tf2_ros" 50 | "nav_msgs" 51 | "serial" 52 | "sensor_msgs" 53 | ) 54 | 55 | ament_target_dependencies(${EXECUTABLE_NAME} ${DEPENDENCIES} 56 | ) 57 | ################################################################################ 58 | # Install 59 | ################################################################################ 60 | install(TARGETS ${EXECUTABLE_NAME} 61 | DESTINATION lib/${PROJECT_NAME}) 62 | 63 | install( 64 | DIRECTORY launch cfg 65 | DESTINATION share/${PROJECT_NAME} 66 | ) 67 | 68 | ament_package() 69 | -------------------------------------------------------------------------------- /neuronbot2_bringup/cfg/camera.yaml: -------------------------------------------------------------------------------- 1 | camera: 2 | ros__parameters: 3 | device_type: '' 4 | serial_no: '' 5 | usb_port_id: '' 6 | 7 | base_frame_id: 'camera_link' 8 | 9 | color_fps: 30.0 10 | color_height: 480 11 | color_width: 640 12 | 13 | depth_fps: 30.0 14 | depth_height: 720 15 | depth_width: 1280 16 | 17 | infra_height: 720 18 | infra_width: 1280 19 | 20 | gyro_fps: 0.0 21 | 22 | enable_color: true 23 | enable_depth: true 24 | enable_pointcloud: true 25 | enable_infra1: true 26 | enable_infra2: true 27 | enable_accel: false 28 | enable_gyro: false 29 | 30 | filters: '' 31 | 32 | pointcloud_texture_index: 0 33 | pointcloud_texture_stream: RS2_STREAM_COLOR 34 | 35 | stereo_module: 36 | emitter_enabled: 1 37 | 38 | unite_imu_method: '' 39 | 40 | rosbag_filename: '' 41 | 42 | -------------------------------------------------------------------------------- /neuronbot2_bringup/cfg/hardware.yaml: -------------------------------------------------------------------------------- 1 | rplidar: 2 | ros__parameters: 3 | serial_port: /dev/rplidar 4 | serial_baudrate: 115200 5 | frame_id: laser_frame 6 | inverted: False # set to True if RPLidar is upside down, 7 | angle_compensate: True 8 | scan_mode: Boost # Since firmware v1.24 => Standard: 2K samples with intensity, Express: 4K samples, Boost: 8K samples 9 | angle_min: 0.0 # start angle 10 | angle_max: 359.0 # end angle 11 | min_distance: 0.20 12 | 13 | robot_state_publisher: 14 | ros__parameters: 15 | use_sim_time: False 16 | 17 | joint_state_publisher: 18 | ros__parameters: 19 | publish_default_positions: True 20 | rate: 30 21 | 22 | 23 | -------------------------------------------------------------------------------- /neuronbot2_bringup/include/neuronbot2_bringup/data_holder.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DATA_HOLDER_HPP_ 2 | #define DATA_HOLDER_HPP_ 3 | 4 | #include 5 | 6 | namespace neuronbot2 7 | { 8 | #pragma pack(1) 9 | 10 | typedef int int32; 11 | typedef short int16; 12 | typedef unsigned short uint16; 13 | 14 | struct Robot_firmware{ 15 | char version[16]; // Firmware version 16 | char time[16]; // Building time 17 | }; 18 | 19 | struct Robot_parameter{ 20 | union{ 21 | char buff[64]; 22 | struct{ 23 | unsigned short wheel_diameter; // Diameter of wheel (mm) 24 | unsigned short wheel_track; // Differencial wheel system: distance between wheels. (mm) 25 | // 3 omni wheel system: diameter. (mm) 26 | // 4 omni wheel system: distance of front/back wheels + distance of left/right wheels. (mm) 27 | unsigned short encoder_resolution; // Resolution of the encoder 28 | unsigned char do_pid_interval; // pid interval (ms) 29 | unsigned short kp; // Proportional gain 30 | unsigned short ki; // Integral gain 31 | unsigned short kd; // differential gain 32 | unsigned short ko; // Open loop gain 33 | unsigned short cmd_last_time; // Sustained time of a command before stopping. (ms) 34 | unsigned short max_v_liner_x; // Maximun linear speed in x direction. (cm/s) 35 | unsigned short max_v_liner_y; // Maximun linear speed in y direction. (cm/s) 0 if differential. 36 | unsigned short max_v_angular_z; // Maximun angular speed in z direction. (0.01 rad/s) 37 | unsigned char imu_type; // Type of imu 38 | } params; 39 | }; 40 | }; 41 | 42 | struct Robot_velocity{ 43 | short v_liner_x; // Linear speed in x direction. >0: forward | <0: backward (cm/s) 44 | short v_liner_y; // Linear speed in y direction. 0 if differential.(cm/s) 45 | short v_angular_z; // Angular speed in z direction. >0: turn left | <0: turn right (0.01 rad/s) 46 | }; 47 | 48 | struct Robot_odom{ 49 | short v_liner_x; // Linear speed in x direction. >0: forward | <0: backward (cm/s) 50 | short v_liner_y; // Linear speed in y direction. 0 if differential.(cm/s) 51 | short v_angular_z; // Angular speed in z direction. >0: turn left | <0: turn right (0.01 rad/s) 52 | int32 x; // Odometry x (cm) (4 bytes) 53 | int32 y; // Odometry y (cm) (4 bytes) 54 | short yaw; // Odometry theta (0.01 rad) 55 | }; 56 | 57 | struct Robot_pid_data{ 58 | int32 input[4]; // Input of each wheel 59 | int32 output[4]; // Output of each wheel 60 | }; 61 | 62 | #pragma pack(0) 63 | 64 | class Data_holder{ 65 | public: 66 | static Data_holder* get(){ 67 | static Data_holder dh; 68 | return &dh; 69 | } 70 | 71 | void load_parameter(); 72 | 73 | void save_parameter(); 74 | 75 | private: 76 | Data_holder(){ 77 | memset(&firmware_info, 0, sizeof(struct Robot_firmware)); 78 | memset(¶meter, 0, sizeof(struct Robot_parameter)); 79 | memset(&velocity, 0, sizeof(struct Robot_velocity)); 80 | memset(&odom, 0, sizeof(struct Robot_odom)); 81 | memset(&pid_data, 0, sizeof(struct Robot_pid_data)); 82 | memset(&imu_data, 0, sizeof(imu_data)); 83 | } 84 | public: 85 | struct Robot_firmware firmware_info; 86 | struct Robot_parameter parameter; 87 | struct Robot_velocity velocity; 88 | struct Robot_odom odom; 89 | struct Robot_pid_data pid_data; 90 | 91 | float imu_data[9]; 92 | }; 93 | } // neuronbot2 94 | #endif // DATA_HOLDER_HPP_ -------------------------------------------------------------------------------- /neuronbot2_bringup/include/neuronbot2_bringup/dataframe.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PIBOT_DATA_FRAME_HPP_ 2 | #define PIBOT_DATA_FRAME_HPP_ 3 | 4 | namespace neuronbot2 5 | { 6 | enum MESSAGE_ID{ 7 | ID_GET_VERSION = 0, 8 | ID_SET_ROBOT_PARAMTER = 1, 9 | ID_GET_ROBOT_PARAMTER = 2, 10 | ID_INIT_ODOM = 3, 11 | ID_SET_VELOCITY = 4, 12 | ID_GET_ODOM = 5, 13 | ID_GET_PID_DATA = 6, 14 | ID_GET_IMU_DATA = 7, 15 | ID_MESSGAE_MAX 16 | }; 17 | 18 | class Notify{ 19 | public: 20 | virtual void update(const MESSAGE_ID id, void* data) = 0; 21 | }; 22 | 23 | 24 | class Dataframe{ 25 | public: 26 | virtual bool init()=0; 27 | // virtual void register_notify(const MESSAGE_ID id, Notify* _nf)=0; 28 | virtual bool data_recv(unsigned char c)=0; 29 | virtual bool data_parse()=0; 30 | virtual bool interact(const MESSAGE_ID id)=0; 31 | }; 32 | } // neuronbot2 33 | #endif // PIBOT_DATA_FRAME_HPP -------------------------------------------------------------------------------- /neuronbot2_bringup/include/neuronbot2_bringup/neuron_serial.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ADLINK Technology, Inc. 2 | // Developer: YU-WEN, CHEN (real.yuwen@gmail.com) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "neuronbot2_bringup/dataframe.hpp" 35 | #include "neuronbot2_bringup/simple_dataframe.hpp" 36 | #include "neuronbot2_bringup/data_holder.hpp" 37 | #include "neuronbot2_bringup/simple_dataframe_master.hpp" 38 | #include 39 | 40 | // TODO: namespace 41 | 42 | using namespace std::chrono_literals; 43 | using duration = std::chrono::nanoseconds; 44 | 45 | namespace neuronbot2 46 | { 47 | class NeuronSerial : public rclcpp::Node 48 | { 49 | public: 50 | NeuronSerial(); 51 | 52 | private: 53 | rclcpp::Node::SharedPtr node_handle_; 54 | double odom_freq; 55 | double imu_freq; 56 | double cmd_vel_timeout; 57 | 58 | std::string odom_frame_parent; 59 | std::string odom_frame_child; 60 | std::string imu_frame; 61 | 62 | // Switch 63 | bool publish_tf_; 64 | bool calibrate_imu_; 65 | bool cmd_vel_timeout_switch; 66 | 67 | // imu calibration bias 68 | float acc_x_bias; 69 | float acc_y_bias; 70 | float acc_z_bias; 71 | float vel_theta_bias; 72 | 73 | void parameter_init(); 74 | void read_firmware_info(); 75 | void keepalive_cb(); 76 | void on_cmd_vel(geometry_msgs::msg::Twist::SharedPtr msg); 77 | void on_motor_move(geometry_msgs::msg::Twist::SharedPtr msg); 78 | void update_odom(); 79 | void update_imu(); 80 | 81 | // Timer 82 | rclcpp::TimerBase::SharedPtr keepalive_timer; 83 | rclcpp::TimerBase::SharedPtr odom_read_timer; 84 | rclcpp::TimerBase::SharedPtr imu_read_timer; 85 | 86 | // Subscriber 87 | rclcpp::Subscription::SharedPtr cmd_vel_sub; 88 | 89 | // Publisher 90 | rclcpp::Publisher::SharedPtr cmd_vel_pub; 91 | rclcpp::Publisher::SharedPtr odom_pub; 92 | rclcpp::Publisher::SharedPtr imu_pub; 93 | rclcpp::Publisher::SharedPtr mag_pub; 94 | std::unique_ptr tf_broadcaster_; 95 | 96 | std::shared_ptr serial_; 97 | std::shared_ptr frame; 98 | std::shared_ptr rp; 99 | std::shared_ptr motor_cmd; 100 | Data_holder *dh; 101 | }; 102 | } // neuronbot2 -------------------------------------------------------------------------------- /neuronbot2_bringup/include/neuronbot2_bringup/simple_dataframe.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PIBOT_SIMPLE_DATAFRAME_HPP_ 2 | #define PIBOT_SIMPLE_DATAFRAME_HPP_ 3 | 4 | #include 5 | #include "dataframe.hpp" 6 | 7 | namespace neuronbot2 8 | { 9 | static const unsigned short MESSAGE_BUFFER_SIZE = 255; 10 | 11 | #define FIX_HEAD 0x5A 12 | 13 | struct Head{ 14 | unsigned char flag; // Head prefix: 0X5A 15 | unsigned char msg_id; // Message ID: determine the function and format of the message 16 | unsigned char length; // Length of the message 17 | }; 18 | 19 | 20 | struct Message{ 21 | struct Head head; 22 | unsigned char data[MESSAGE_BUFFER_SIZE]; 23 | unsigned char check; 24 | unsigned char recv_count; // Received bytes 25 | 26 | Message(){} 27 | Message(unsigned char msg_id, unsigned char* data=0,unsigned char len=0){ 28 | head.flag = FIX_HEAD; 29 | head.msg_id = msg_id; 30 | head.length = recv_count = len; 31 | check = 0; 32 | 33 | if (data != 0 && len !=0) 34 | memcpy(this->data, data, len); 35 | 36 | unsigned char* _send_buffer = (unsigned char*)this; 37 | 38 | unsigned int i = 0; 39 | for (i = 0; i < sizeof(head)+head.length; i++) 40 | check += _send_buffer[i]; 41 | 42 | _send_buffer[sizeof(head)+head.length] = check; 43 | } 44 | }; 45 | 46 | enum RECEIVE_STATE{ 47 | STATE_RECV_FIX=0, 48 | STATE_RECV_ID, 49 | STATE_RECV_LEN, 50 | STATE_RECV_DATA, 51 | STATE_RECV_CHECK 52 | }; 53 | } // neuronbot2 54 | #endif // PIBOT_SIMPLE_DATAFRAME_HPP_ -------------------------------------------------------------------------------- /neuronbot2_bringup/include/neuronbot2_bringup/simple_dataframe_master.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PIBOT_SIMPLE_DATAFRAME_MASTER_HPP_ 2 | #define PIBOT_SIMPLE_DATAFRAME_MASTER_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "data_holder.hpp" 8 | #include "simple_dataframe.hpp" 9 | #include "serial/serial.h" 10 | #include "rclcpp/rclcpp.hpp" 11 | 12 | namespace neuronbot2 13 | { 14 | class Simple_dataframe : public Dataframe{ 15 | public: 16 | Simple_dataframe(serial::Serial* _trans); 17 | ~Simple_dataframe(); 18 | 19 | bool init(); 20 | bool data_recv(unsigned char c); 21 | bool data_parse(); 22 | bool interact(const MESSAGE_ID id); 23 | 24 | private: 25 | bool recv_proc(); 26 | bool send_message(const MESSAGE_ID id); 27 | bool send_message(const MESSAGE_ID id, unsigned char* data, unsigned char len); 28 | bool send_message(Message* msg); 29 | 30 | Message active_rx_msg; 31 | RECEIVE_STATE recv_state; 32 | serial::Serial* trans; 33 | typedef std::vector Buffer; 34 | }; 35 | } // neuronbot2 36 | #endif // PIBOT_SIMPLE_DATAFRAME_MASTER_HPP_ -------------------------------------------------------------------------------- /neuronbot2_bringup/launch/bringup_launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | from ament_index_python.packages import get_package_share_directory 4 | from launch import LaunchDescription 5 | from launch.conditions import IfCondition 6 | from launch.conditions import UnlessCondition 7 | from launch.actions import DeclareLaunchArgument 8 | from launch.actions import IncludeLaunchDescription 9 | from launch.launch_description_sources import PythonLaunchDescriptionSource 10 | from launch.substitutions import ThisLaunchFileDir 11 | from launch.actions import ExecuteProcess 12 | from launch.substitutions import LaunchConfiguration, PythonExpression 13 | from launch_ros.actions import Node 14 | 15 | def generate_launch_description(): 16 | 17 | # Whether to open RealSense D435 18 | use_camera = LaunchConfiguration('use_camera', default='none') 19 | camera_config = Path(get_package_share_directory('neuronbot2_bringup'), 'cfg', 'camera.yaml') 20 | 21 | # Whether to use front or top camera 22 | urdf_file_name = 'neuronbot2.urdf' 23 | nb2_urdf = os.path.join( 24 | get_package_share_directory('neuronbot2_description'), 25 | 'urdf', 26 | urdf_file_name) 27 | 28 | urdf_file_name = 'neuronbot2_w_front_camera.urdf' 29 | nb2_w_front_camera_urdf = os.path.join( 30 | get_package_share_directory('neuronbot2_description'), 31 | 'urdf', 32 | urdf_file_name) 33 | 34 | urdf_file_name = 'neuronbot2_w_top_camera.urdf' 35 | nb2_w_top_camera_urdf = os.path.join( 36 | get_package_share_directory('neuronbot2_description'), 37 | 'urdf', 38 | urdf_file_name) 39 | 40 | hardware_config = Path(get_package_share_directory('neuronbot2_bringup'), 'cfg', 'hardware.yaml') 41 | 42 | # Whether to use EKF for multi-sensor fusion 43 | use_ekf = LaunchConfiguration('use_ekf', default='false') 44 | ekf_config = Path(get_package_share_directory('neuronbot2_bringup'), 'cfg', 'ekf.yaml') 45 | 46 | return LaunchDescription([ 47 | 48 | # if we don't use camera: 49 | Node( 50 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "none"'])), 51 | package='robot_state_publisher', 52 | executable='robot_state_publisher', 53 | name='robot_state_publisher', 54 | output='screen', 55 | arguments=[nb2_urdf], 56 | ), 57 | # else if we use front camera: 58 | Node( 59 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "front"'])), 60 | package='robot_state_publisher', 61 | executable='robot_state_publisher', 62 | name='robot_state_publisher', 63 | output='screen', 64 | arguments=[nb2_w_front_camera_urdf], 65 | ), 66 | # else if we use top camera: 67 | Node( 68 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "top"'])), 69 | package='robot_state_publisher', 70 | executable='robot_state_publisher', 71 | name='robot_state_publisher', 72 | output='screen', 73 | arguments=[nb2_w_top_camera_urdf], 74 | ), 75 | 76 | # open realsense D435 if use_camera != none 77 | Node( 78 | condition=IfCondition(PythonExpression(['"', use_camera, '" != "none"'])), 79 | package='realsense2_camera', 80 | executable='realsense2_camera_node', 81 | namespace='', 82 | output='screen', 83 | parameters=[camera_config], 84 | ), 85 | 86 | #Node( 87 | # package='joint_state_publisher', 88 | # executable='joint_state_publisher', 89 | # name='joint_state_publisher', 90 | # output='screen', 91 | # arguments=[str(urdf_path)], 92 | # parameters=[hardware_config] 93 | #), 94 | 95 | Node( 96 | package='rplidar_ros', 97 | executable='rplidar_node', 98 | name='rplidar', 99 | output='screen', 100 | parameters=[hardware_config], 101 | ), 102 | 103 | # If we use EKF: 104 | Node( 105 | condition=IfCondition(use_ekf), 106 | package='neuronbot2_bringup', 107 | executable='neuronbot2_driver', 108 | output='screen', 109 | parameters=[{ 110 | 'publish_tf': False, 111 | 'calibrate_imu' : True, 112 | 'odom_topic': 'raw_odom', 113 | 'odom_freq' : 50.0, 114 | 'imu_topic': 'raw_imu', 115 | 'imu_freq' : 100.0, 116 | 'cmd_vel_timeout' : 1.0 117 | }], 118 | ), 119 | Node( 120 | condition=IfCondition(use_ekf), 121 | package='robot_localization', 122 | executable='ekf_node', 123 | output='screen', 124 | parameters=[ekf_config], 125 | remappings=[("odometry/filtered", "odom")] 126 | ), 127 | # else if we don't use EKF: 128 | Node( 129 | condition=UnlessCondition(use_ekf), 130 | package='neuronbot2_bringup', 131 | executable='neuronbot2_driver', 132 | output='screen', 133 | parameters=[{ 134 | 'publish_tf': True, 135 | 'calibrate_imu' : False, 136 | 'odom_topic': 'odom', 137 | 'odom_freq' : 50.0, 138 | 'imu_topic': 'raw_imu', 139 | 'imu_freq' : 100.0, 140 | 'cmd_vel_timeout' : 1.0 141 | }], 142 | ), 143 | 144 | IncludeLaunchDescription( 145 | PythonLaunchDescriptionSource([ 146 | get_package_share_directory('neuronbot2_led'), '/led_control_launch.py' 147 | ]) 148 | ), 149 | 150 | ]) 151 | -------------------------------------------------------------------------------- /neuronbot2_bringup/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | neuronbot2_bringup 5 | 0.1.0 6 | 7 | ROS2 package for bringing up NeuronBot2 8 | 9 | Apache 2.0 10 | Ting Chang 11 | ament_cmake 12 | rclcpp 13 | std_msgs 14 | tf2 15 | tf2_ros 16 | serial 17 | sensor_msgs 18 | geometry_msgs 19 | tf2_geometry_msgs 20 | robot_state_publisher 21 | robot_localization 22 | teleop_twist_keyboard 23 | 24 | ament_cmake 25 | 26 | 27 | -------------------------------------------------------------------------------- /neuronbot2_bringup/src/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 ADLINK Technology, Inc. 2 | // Developer: YU-WEN, CHEN (real.yuwen@gmail.com) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #include 17 | 18 | #include "neuronbot2_bringup/neuron_serial.hpp" 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | //setvbuf(stdout, NULL, _IONBF, BUFSIZ); 23 | rclcpp::init(argc, argv); 24 | 25 | // Create an executor 26 | rclcpp::executors::SingleThreadedExecutor executor; 27 | 28 | // Create a node and add into the executor 29 | auto neuron_serial = std::make_shared(); 30 | executor.add_node(neuron_serial); 31 | 32 | // Spin the executor in a single thread 33 | executor.spin(); 34 | 35 | rclcpp::shutdown(); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /neuronbot2_bringup/src/simple_dataframe_master.cpp: -------------------------------------------------------------------------------- 1 | #include "neuronbot2_bringup/simple_dataframe_master.hpp" 2 | 3 | using namespace neuronbot2; 4 | 5 | Simple_dataframe::Simple_dataframe(serial::Serial* _trans) : trans(_trans) 6 | { 7 | recv_state = STATE_RECV_FIX; 8 | } 9 | 10 | Simple_dataframe::~Simple_dataframe(){ 11 | } 12 | 13 | bool Simple_dataframe::init(){ 14 | return interact(ID_INIT_ODOM); 15 | } 16 | 17 | bool Simple_dataframe::data_recv(unsigned char c){ 18 | switch (recv_state){ 19 | case STATE_RECV_FIX: 20 | if (c == FIX_HEAD){ 21 | memset(static_cast(&active_rx_msg), 0, sizeof(active_rx_msg)); 22 | active_rx_msg.head.flag = c; 23 | active_rx_msg.check += c; 24 | recv_state = STATE_RECV_ID; 25 | } 26 | else 27 | recv_state = STATE_RECV_FIX; 28 | break; 29 | case STATE_RECV_ID: 30 | if (c < ID_MESSGAE_MAX){ 31 | active_rx_msg.head.msg_id = c; 32 | active_rx_msg.check += c; 33 | recv_state = STATE_RECV_LEN; 34 | } 35 | else 36 | recv_state = STATE_RECV_FIX; 37 | break; 38 | case STATE_RECV_LEN: 39 | active_rx_msg.head.length =c; 40 | active_rx_msg.check += c; 41 | if (active_rx_msg.head.length==0) 42 | recv_state = STATE_RECV_CHECK; 43 | else 44 | recv_state = STATE_RECV_DATA; 45 | break; 46 | case STATE_RECV_DATA: 47 | active_rx_msg.data[active_rx_msg.recv_count++] = c; 48 | active_rx_msg.check += c; 49 | if (active_rx_msg.recv_count >=active_rx_msg.head.length) 50 | recv_state = STATE_RECV_CHECK; 51 | break; 52 | case STATE_RECV_CHECK: 53 | recv_state = STATE_RECV_FIX; 54 | if (active_rx_msg.check == c){ 55 | //printf("\r\n"); 56 | return true; 57 | } 58 | break; 59 | default: 60 | recv_state = STATE_RECV_FIX; 61 | } 62 | 63 | return false; 64 | } 65 | 66 | bool Simple_dataframe::data_parse(){ 67 | MESSAGE_ID id = (MESSAGE_ID)active_rx_msg.head.msg_id; 68 | Data_holder* dh = Data_holder::get(); 69 | 70 | switch (id){ 71 | case ID_GET_VERSION: 72 | memcpy(&dh->firmware_info, active_rx_msg.data, sizeof(dh->firmware_info)); 73 | break; 74 | case ID_SET_ROBOT_PARAMTER: 75 | break; 76 | case ID_GET_ROBOT_PARAMTER: 77 | memcpy(&dh->parameter, active_rx_msg.data, sizeof(dh->parameter)); 78 | break; 79 | case ID_INIT_ODOM: 80 | break; 81 | case ID_SET_VELOCITY: 82 | break; 83 | case ID_GET_ODOM: 84 | memcpy(&dh->odom, active_rx_msg.data, sizeof(dh->odom)); 85 | break; 86 | case ID_GET_PID_DATA: 87 | memcpy(&dh->pid_data, active_rx_msg.data, sizeof(dh->pid_data)); 88 | break; 89 | case ID_GET_IMU_DATA: 90 | memcpy(&dh->imu_data, active_rx_msg.data, sizeof(dh->imu_data)); 91 | break; 92 | default: 93 | break; 94 | } 95 | 96 | return true; 97 | } 98 | 99 | bool Simple_dataframe::send_message(const MESSAGE_ID id){ 100 | Message msg(id); 101 | 102 | send_message(&msg); 103 | 104 | return true; 105 | } 106 | 107 | bool Simple_dataframe::send_message(const MESSAGE_ID id, unsigned char* data, unsigned char len){ 108 | Message msg(id, data, len); 109 | 110 | send_message(&msg); 111 | 112 | return true; 113 | } 114 | 115 | bool Simple_dataframe::send_message(Message* msg){ 116 | if (trans == 0) 117 | return true; 118 | Buffer data((unsigned char*)msg, (unsigned char*)msg+sizeof(msg->head)+msg->head.length+1); 119 | trans->write(data); 120 | 121 | return true; 122 | } 123 | 124 | bool Simple_dataframe::interact(const MESSAGE_ID id){ 125 | Data_holder* dh = Data_holder::get(); 126 | 127 | switch (id){ 128 | case ID_GET_VERSION: 129 | send_message(id); 130 | break; 131 | case ID_SET_ROBOT_PARAMTER: 132 | send_message(id, (unsigned char*)&dh->parameter, sizeof(dh->parameter)); 133 | break; 134 | case ID_GET_ROBOT_PARAMTER: 135 | send_message(id); 136 | break; 137 | case ID_INIT_ODOM: 138 | send_message(id); 139 | break; 140 | case ID_SET_VELOCITY: 141 | send_message(id, (unsigned char*)&dh->velocity, sizeof(dh->velocity)); 142 | break; 143 | case ID_GET_ODOM: 144 | send_message(id); 145 | break; 146 | case ID_GET_PID_DATA: 147 | send_message(id); 148 | break; 149 | case ID_GET_IMU_DATA: 150 | send_message(id); 151 | break; 152 | default: 153 | break; 154 | } 155 | 156 | if (!recv_proc()) { 157 | fprintf(stderr, "serial cmd(%d) failure\n", id); 158 | return false; 159 | } 160 | 161 | return true; 162 | } 163 | 164 | bool Simple_dataframe::recv_proc(){ 165 | bool got=false; 166 | 167 | while(true){ 168 | std::vector inbuf; 169 | 170 | // read in the first function prefix ID 171 | while (inbuf.empty()) { 172 | auto n = trans->read(inbuf, 1); 173 | if (n == 0) { 174 | // time out 175 | fprintf(stderr, "serial read timeout\n"); 176 | return false; 177 | } 178 | } 179 | 180 | // read until the end of the message, which is determined by the function prefix ID 181 | for (unsigned i=0; i 2 | 3 | 4 | neuronbot2_description 5 | 0.1.0 6 | 3D models of the Neuronbot2 for simulation and visualization 7 | airuchen 8 | airuchen 9 | Apache 2.0 10 | 11 | ament_cmake 12 | urdf 13 | 14 | 15 | ament_cmake 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /neuronbot2_description/rviz/urdf.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz/Displays 3 | Help Height: 78 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: 7 | - /Global Options1 8 | - /Status1 9 | Splitter Ratio: 0.5 10 | Tree Height: 463 11 | - Class: rviz/Selection 12 | Name: Selection 13 | - Class: rviz/Tool Properties 14 | Expanded: 15 | - /2D Pose Estimate1 16 | - /2D Nav Goal1 17 | - /Publish Point1 18 | Name: Tool Properties 19 | Splitter Ratio: 0.588679016 20 | - Class: rviz/Views 21 | Expanded: 22 | - /Current View1 23 | Name: Views 24 | Splitter Ratio: 0.5 25 | - Class: rviz/Time 26 | Experimental: false 27 | Name: Time 28 | SyncMode: 0 29 | SyncSource: "" 30 | Visualization Manager: 31 | Class: "" 32 | Displays: 33 | - Alpha: 0.5 34 | Cell Size: 1 35 | Class: rviz/Grid 36 | Color: 160; 160; 164 37 | Enabled: true 38 | Line Style: 39 | Line Width: 0.0299999993 40 | Value: Lines 41 | Name: Grid 42 | Normal Cell Count: 0 43 | Offset: 44 | X: 0 45 | Y: 0 46 | Z: 0 47 | Plane: XY 48 | Plane Cell Count: 10 49 | Reference Frame: 50 | Value: true 51 | - Alpha: 1 52 | Class: rviz/RobotModel 53 | Collision Enabled: false 54 | Enabled: true 55 | Links: 56 | All Links Enabled: true 57 | Expand Joint Details: false 58 | Expand Link Details: false 59 | Expand Tree: false 60 | Link Tree Style: Links in Alphabetic Order 61 | base_link: 62 | Alpha: 1 63 | Show Axes: false 64 | Show Trail: false 65 | Value: true 66 | laser_link: 67 | Alpha: 1 68 | Show Axes: false 69 | Show Trail: false 70 | Value: true 71 | Name: RobotModel 72 | Robot Description: robot_description 73 | TF Prefix: "" 74 | Update Interval: 0 75 | Value: true 76 | Visual Enabled: true 77 | - Class: rviz/TF 78 | Enabled: true 79 | Frame Timeout: 15 80 | Frames: 81 | All Enabled: true 82 | base_link: 83 | Value: true 84 | laser_link: 85 | Value: true 86 | Marker Scale: 1 87 | Name: TF 88 | Show Arrows: true 89 | Show Axes: true 90 | Show Names: true 91 | Tree: 92 | base_link: 93 | laser_link: 94 | {} 95 | Update Interval: 0 96 | Value: true 97 | Enabled: true 98 | Global Options: 99 | Background Color: 48; 48; 48 100 | Fixed Frame: base_link 101 | Frame Rate: 30 102 | Name: root 103 | Tools: 104 | - Class: rviz/Interact 105 | Hide Inactive Objects: true 106 | - Class: rviz/MoveCamera 107 | - Class: rviz/Select 108 | - Class: rviz/FocusCamera 109 | - Class: rviz/Measure 110 | - Class: rviz/SetInitialPose 111 | Topic: /initialpose 112 | - Class: rviz/SetGoal 113 | Topic: /move_base_simple/goal 114 | - Class: rviz/PublishPoint 115 | Single click: true 116 | Topic: /clicked_point 117 | Value: true 118 | Views: 119 | Current: 120 | Class: rviz/Orbit 121 | Distance: 2.15671158 122 | Enable Stereo Rendering: 123 | Stereo Eye Separation: 0.0599999987 124 | Stereo Focal Distance: 1 125 | Swap Stereo Eyes: false 126 | Value: false 127 | Focal Point: 128 | X: 0 129 | Y: 0 130 | Z: 0 131 | Focal Shape Fixed Size: true 132 | Focal Shape Size: 0.0500000007 133 | Invert Z Axis: false 134 | Name: Current View 135 | Near Clip Distance: 0.00999999978 136 | Pitch: 0.145398423 137 | Target Frame: 138 | Value: Orbit (rviz) 139 | Yaw: 0.365398407 140 | Saved: ~ 141 | Window Geometry: 142 | Displays: 143 | collapsed: false 144 | Height: 744 145 | Hide Left Dock: false 146 | Hide Right Dock: false 147 | QMainWindow State: 000000ff00000000fd00000004000000000000016a0000025efc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000006400fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c00610079007301000000280000025e000000dd00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f0000025efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a0056006900650077007301000000280000025e000000b000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000005150000003efc0100000002fb0000000800540069006d00650100000000000005150000030000fffffffb0000000800540069006d00650100000000000004500000000000000000000002900000025e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 148 | Selection: 149 | collapsed: false 150 | Time: 151 | collapsed: false 152 | Tool Properties: 153 | collapsed: false 154 | Views: 155 | collapsed: false 156 | Width: 1301 157 | X: 65 158 | Y: 24 159 | -------------------------------------------------------------------------------- /neuronbot2_description/urdf/neuronbot2.urdf: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 26 | 28 | 35 | 36 | 37 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 63 | 65 | 72 | 73 | 74 | 77 | 78 | 80 | 81 | 82 | 83 | 84 | 87 | 88 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /neuronbot2_description/urdf/neuronbot2_w_front_camera.urdf: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 26 | 28 | 35 | 36 | 37 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 63 | 65 | 72 | 73 | 74 | 77 | 78 | 80 | 81 | 82 | 83 | 84 | 87 | 88 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /neuronbot2_description/urdf/neuronbot2_w_top_camera.urdf: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 26 | 28 | 35 | 36 | 37 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 63 | 65 | 72 | 73 | 74 | 77 | 78 | 80 | 81 | 82 | 83 | 84 | 87 | 88 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(neuronbot2_gazebo) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++14 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 14) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | find_package(gazebo_ros_pkgs REQUIRED) 21 | find_package(geometry_msgs REQUIRED) 22 | find_package(nav_msgs REQUIRED) 23 | find_package(rclcpp REQUIRED) 24 | find_package(sensor_msgs REQUIRED) 25 | find_package(tf2 REQUIRED) 26 | find_package(robot_state_publisher REQUIRED) 27 | 28 | if(BUILD_TESTING) 29 | find_package(ament_lint_auto REQUIRED) 30 | # the following line skips the linter which checks for copyrights 31 | # uncomment the line when a copyright and license is not present in all source files 32 | #set(ament_cmake_copyright_FOUND TRUE) 33 | # the following line skips cpplint (only works in a git repo) 34 | # uncomment the line when this package is not in a git repo 35 | #set(ament_cmake_cpplint_FOUND TRUE) 36 | ament_lint_auto_find_test_dependencies() 37 | endif() 38 | 39 | ## Install 40 | install(DIRECTORY launch worlds models 41 | DESTINATION share/${PROJECT_NAME}/ 42 | ) 43 | 44 | ament_package() 45 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/launch/neuronbot2_world.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ament_index_python.packages import get_package_share_directory 4 | from launch import LaunchDescription 5 | from launch.actions import IncludeLaunchDescription 6 | from launch.launch_description_sources import PythonLaunchDescriptionSource 7 | from launch.substitutions import LaunchConfiguration 8 | 9 | 10 | def generate_launch_description(): 11 | launch_file_dir = os.path.join(get_package_share_directory('neuronbot2_gazebo'), 'launch') 12 | pkg_gazebo_ros = get_package_share_directory('gazebo_ros') 13 | 14 | gazebo_model_path = os.path.join(get_package_share_directory('neuronbot2_gazebo'), 'models') 15 | if 'GAZEBO_MODEL_PATH' in os.environ: 16 | os.environ['GAZEBO_MODEL_PATH'] += ":" + gazebo_model_path 17 | else : 18 | os.environ['GAZEBO_MODEL_PATH'] = gazebo_model_path 19 | 20 | use_sim_time = LaunchConfiguration('use_sim_time', default='true') 21 | use_camera = LaunchConfiguration('use_camera', default='none') 22 | x_pose = LaunchConfiguration('x_pose', default='0.0') 23 | y_pose = LaunchConfiguration('y_pose', default='0.0') 24 | 25 | world = os.path.join( 26 | get_package_share_directory('neuronbot2_gazebo'), 27 | 'worlds', 28 | 'mememan_world.model' 29 | ) 30 | 31 | gzserver_cmd = IncludeLaunchDescription( 32 | PythonLaunchDescriptionSource( 33 | os.path.join(pkg_gazebo_ros, 'launch', 'gzserver.launch.py') 34 | ), 35 | launch_arguments={'world': world}.items() 36 | ) 37 | 38 | gzclient_cmd = IncludeLaunchDescription( 39 | PythonLaunchDescriptionSource( 40 | os.path.join(pkg_gazebo_ros, 'launch', 'gzclient.launch.py') 41 | ) 42 | ) 43 | 44 | robot_state_publisher_cmd = IncludeLaunchDescription( 45 | PythonLaunchDescriptionSource( 46 | os.path.join(launch_file_dir, 'robot_state_publisher.launch.py') 47 | ), 48 | launch_arguments={'use_sim_time': use_sim_time}.items() 49 | ) 50 | 51 | spawn_nb2_cmd = IncludeLaunchDescription( 52 | PythonLaunchDescriptionSource( 53 | os.path.join(launch_file_dir, 'spawn_nb2.launch.py') 54 | ), 55 | launch_arguments={ 56 | 'use_camera': use_camera, 57 | 'x_pose': x_pose, 58 | 'y_pose': y_pose 59 | }.items() 60 | ) 61 | 62 | ld = LaunchDescription() 63 | 64 | # Add the commands to the launch description 65 | ld.add_action(gzserver_cmd) 66 | ld.add_action(gzclient_cmd) 67 | ld.add_action(robot_state_publisher_cmd) 68 | ld.add_action(spawn_nb2_cmd) 69 | 70 | return ld -------------------------------------------------------------------------------- /neuronbot2_gazebo/launch/robot_state_publisher.launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ament_index_python.packages import get_package_share_directory 4 | from launch import LaunchDescription 5 | from launch.actions import DeclareLaunchArgument 6 | from launch.substitutions import LaunchConfiguration, PythonExpression 7 | from launch_ros.actions import Node 8 | from launch.conditions import IfCondition 9 | 10 | def generate_launch_description(): 11 | 12 | use_sim_time = LaunchConfiguration('use_sim_time', default='false') 13 | use_camera = LaunchConfiguration('use_camera', default='none') 14 | 15 | urdf_file_name = 'neuronbot2.urdf' 16 | nb2_urdf = os.path.join( 17 | get_package_share_directory('neuronbot2_description'), 18 | 'urdf', 19 | urdf_file_name) 20 | 21 | urdf_file_name = 'neuronbot2_w_front_camera.urdf' 22 | nb2_w_front_camera_urdf = os.path.join( 23 | get_package_share_directory('neuronbot2_description'), 24 | 'urdf', 25 | urdf_file_name) 26 | 27 | urdf_file_name = 'neuronbot2_w_top_camera.urdf' 28 | nb2_w_top_camera_urdf = os.path.join( 29 | get_package_share_directory('neuronbot2_description'), 30 | 'urdf', 31 | urdf_file_name) 32 | 33 | return LaunchDescription([ 34 | 35 | DeclareLaunchArgument( 36 | 'use_camera', 37 | default_value='none', 38 | description='Use camera?'), 39 | 40 | DeclareLaunchArgument( 41 | 'use_sim_time', 42 | default_value='false', 43 | description='Use simulation (Gazebo) clock if true'), 44 | 45 | # if we don't use camera: 46 | Node( 47 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "none"'])), 48 | package='robot_state_publisher', 49 | executable='robot_state_publisher', 50 | name='robot_state_publisher', 51 | output='screen', 52 | parameters=[{'use_sim_time': use_sim_time}], 53 | arguments=[nb2_urdf]), 54 | 55 | # else if we use front camera: 56 | Node( 57 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "front"'])), 58 | package='robot_state_publisher', 59 | executable='robot_state_publisher', 60 | name='robot_state_publisher', 61 | output='screen', 62 | parameters=[{'use_sim_time': use_sim_time}], 63 | arguments=[nb2_w_front_camera_urdf]), 64 | 65 | # else if we use top camera: 66 | Node( 67 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "top"'])), 68 | package='robot_state_publisher', 69 | executable='robot_state_publisher', 70 | name='robot_state_publisher', 71 | output='screen', 72 | parameters=[{'use_sim_time': use_sim_time}], 73 | arguments=[nb2_w_top_camera_urdf]), 74 | ]) 75 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/launch/spawn_nb2.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | 17 | from ament_index_python.packages import get_package_share_directory 18 | from launch import LaunchDescription 19 | from launch.actions import DeclareLaunchArgument 20 | from launch.conditions import IfCondition 21 | from launch.substitutions import LaunchConfiguration, PythonExpression 22 | from launch_ros.actions import Node 23 | 24 | def generate_launch_description(): 25 | NEURONBOT2_MODEL = 'nb2' 26 | model_path_prefix = os.path.join( 27 | get_package_share_directory('neuronbot2_gazebo'), 'models' 28 | ) 29 | 30 | # Launch configuration variables specific to simulation 31 | use_camera = LaunchConfiguration('use_camera', default='none') 32 | x_pose = LaunchConfiguration('x_pose', default='0.0') 33 | y_pose = LaunchConfiguration('y_pose', default='0.0') 34 | 35 | # Declare the launch arguments 36 | declare_camera_position_cmd = DeclareLaunchArgument( 37 | 'use_camera', 38 | default_value='none', 39 | description='Use camera?') 40 | 41 | declare_x_position_cmd = DeclareLaunchArgument( 42 | 'x_pose', default_value='0.0', 43 | description='Specify namespace of the robot') 44 | 45 | declare_y_position_cmd = DeclareLaunchArgument( 46 | 'y_pose', default_value='0.0', 47 | description='Specify namespace of the robot') 48 | 49 | # Spawn NB2 without camera 50 | spawn_nb2_wo_camera_cmd = Node( 51 | package='gazebo_ros', 52 | executable='spawn_entity.py', 53 | arguments=[ 54 | '-entity', NEURONBOT2_MODEL, 55 | '-file', os.path.join(model_path_prefix, 'neuronbot2', 'model.sdf'), 56 | '-timeout', '300', 57 | '-x', x_pose, 58 | '-y', y_pose, 59 | '-z', '0.01' 60 | ], 61 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "none"'])), 62 | output='screen', 63 | ) 64 | 65 | # Spawn NB2 with top camera 66 | spawn_nb2_w_top_camera_cmd = Node( 67 | package='gazebo_ros', 68 | executable='spawn_entity.py', 69 | arguments=[ 70 | '-entity', NEURONBOT2_MODEL, 71 | '-file', os.path.join(model_path_prefix, 'neuronbot2_w_top_camera', 'model.sdf'), 72 | '-timeout', '300', 73 | '-x', x_pose, 74 | '-y', y_pose, 75 | '-z', '0.01' 76 | ], 77 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "top"'])), 78 | output='screen', 79 | ) 80 | 81 | # Spawn NB2 with front camera 82 | spawn_nb2_w_front_camera_cmd = Node( 83 | package='gazebo_ros', 84 | executable='spawn_entity.py', 85 | arguments=[ 86 | '-entity', NEURONBOT2_MODEL, 87 | '-file', os.path.join(model_path_prefix, 'neuronbot2_w_front_camera', 'model.sdf'), 88 | '-timeout', '300', 89 | '-x', x_pose, 90 | '-y', y_pose, 91 | '-z', '0.01' 92 | ], 93 | condition=IfCondition(PythonExpression(['"', use_camera, '" == "front"'])), 94 | output='screen', 95 | ) 96 | 97 | ld = LaunchDescription() 98 | 99 | # Declare the launch options 100 | ld.add_action(declare_camera_position_cmd) 101 | ld.add_action(declare_x_position_cmd) 102 | ld.add_action(declare_y_position_cmd) 103 | 104 | # Add any conditioned actions 105 | ld.add_action(spawn_nb2_wo_camera_cmd) 106 | ld.add_action(spawn_nb2_w_top_camera_cmd) 107 | ld.add_action(spawn_nb2_w_front_camera_cmd) 108 | 109 | return ld -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/mememan/model.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | mememan 4 | 1.0 5 | model.sdf 6 | 7 | airuchen 8 | real.yuwen@gmail.com 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2/meshes/neuronbot2/base_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2/meshes/neuronbot2/base_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2/meshes/neuronbot2/laser_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2/meshes/neuronbot2/laser_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2/meshes/neuronbot2/wheel_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2/meshes/neuronbot2/wheel_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2/model.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | neuronbot2 4 | 1.0 5 | model.sdf 6 | 7 | airuchen 8 | real.yuwen@gmail.com 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2_w_front_camera/meshes/neuronbot2/base_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2_w_front_camera/meshes/neuronbot2/base_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2_w_front_camera/meshes/neuronbot2/laser_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2_w_front_camera/meshes/neuronbot2/laser_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2_w_front_camera/meshes/neuronbot2/wheel_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2_w_front_camera/meshes/neuronbot2/wheel_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2_w_front_camera/model.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | neuronbot2 4 | 1.0 5 | model.sdf 6 | 7 | airuchen 8 | real.yuwen@gmail.com 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2_w_top_camera/meshes/neuronbot2/base_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2_w_top_camera/meshes/neuronbot2/base_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2_w_top_camera/meshes/neuronbot2/laser_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2_w_top_camera/meshes/neuronbot2/laser_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2_w_top_camera/meshes/neuronbot2/wheel_link.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_gazebo/models/neuronbot2_w_top_camera/meshes/neuronbot2/wheel_link.stl -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/neuronbot2_w_top_camera/model.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | neuronbot2 4 | 1.0 5 | model.sdf 6 | 7 | airuchen 8 | real.yuwen@gmail.com 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/models/phenix/model.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | phenix 4 | 1.0 5 | model.sdf 6 | 7 | airuchen 8 | real.yuwen@gmail.com 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | neuronbot2_gazebo 5 | 0.1.0 6 | NeuronBot2 Gazebo simulation package 7 | airuchen 8 | airuchen 9 | Apache 2.0 10 | 11 | 12 | ament_cmake 13 | 14 | gazebo_ros_pkgs 15 | geometry_msgs 16 | nav_msgs 17 | rclcpp 18 | sensor_msgs 19 | tf2 20 | robot_state_publisher 21 | 22 | ament_lint_auto 23 | ament_lint_common 24 | 25 | 26 | ament_cmake 27 | 28 | 29 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/worlds/mememan_world.model: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | model://ground_plane 7 | 8 | 9 | 10 | model://sun 11 | 12 | 13 | 14 | false 15 | 16 | 17 | 18 | 19 | 0.319654 -0.235002 9.29441 0 1.5138 0.009599 20 | orbit 21 | perspective 22 | 23 | 24 | 25 | 26 | 1000.0 27 | 0.001 28 | 1 29 | 30 | 31 | quick 32 | 150 33 | 0 34 | 1.400000 35 | 1 36 | 37 | 38 | 0.00001 39 | 0.2 40 | 2000.000000 41 | 0.01000 42 | 43 | 44 | 45 | 46 | 47 | 1 48 | 49 | model://mememan 50 | 51 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /neuronbot2_gazebo/worlds/phenix_world.model: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | model://ground_plane 7 | 8 | 9 | 10 | model://sun 11 | 12 | 13 | 14 | false 15 | 16 | 17 | 18 | 19 | 0.319654 -0.235002 9.29441 0 1.5138 0.009599 20 | orbit 21 | perspective 22 | 23 | 24 | 25 | 26 | 1000.0 27 | 0.001 28 | 1 29 | 30 | 31 | quick 32 | 150 33 | 0 34 | 1.400000 35 | 1 36 | 37 | 38 | 0.00001 39 | 0.2 40 | 2000.000000 41 | 0.01000 42 | 43 | 44 | 45 | 46 | 47 | 1 48 | 49 | model://phenix 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /neuronbot2_nav/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(neuronbot2_nav) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++14 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 14) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | find_package(nav2_bringup REQUIRED) 21 | 22 | if(BUILD_TESTING) 23 | find_package(ament_lint_auto REQUIRED) 24 | # the following line skips the linter which checks for copyrights 25 | # uncomment the line when a copyright and license is not present in all source files 26 | #set(ament_cmake_copyright_FOUND TRUE) 27 | # the following line skips cpplint (only works in a git repo) 28 | # uncomment the line when this package is not in a git repo 29 | #set(ament_cmake_cpplint_FOUND TRUE) 30 | ament_lint_auto_find_test_dependencies() 31 | endif() 32 | 33 | ################################################################################ 34 | # Install 35 | ################################################################################ 36 | install( 37 | DIRECTORY launch map param rviz 38 | DESTINATION share/${PROJECT_NAME} 39 | ) 40 | 41 | ament_package() 42 | -------------------------------------------------------------------------------- /neuronbot2_nav/launch/bringup_launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 Intel Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | 17 | from ament_index_python.packages import get_package_share_directory 18 | 19 | from launch import LaunchDescription 20 | from launch.actions import (DeclareLaunchArgument, GroupAction, 21 | IncludeLaunchDescription, SetEnvironmentVariable) 22 | from launch.conditions import IfCondition 23 | from launch.launch_description_sources import PythonLaunchDescriptionSource 24 | from launch.substitutions import LaunchConfiguration, PythonExpression 25 | from launch_ros.actions import Node 26 | from launch_ros.actions import PushRosNamespace 27 | from nav2_common.launch import RewrittenYaml 28 | 29 | 30 | def generate_launch_description(): 31 | # Get the launch directory 32 | my_nav_dir = get_package_share_directory('neuronbot2_nav') 33 | my_launch_dir = os.path.join(my_nav_dir, 'launch') 34 | my_param_dir = os.path.join(my_nav_dir, 'param') 35 | my_param_file = 'neuronbot_params.yaml' 36 | my_map_dir = os.path.join(my_nav_dir, 'map') 37 | my_map_file = 'mememan.yaml' 38 | 39 | # Create the launch configuration variables 40 | namespace = LaunchConfiguration('namespace') 41 | use_namespace = LaunchConfiguration('use_namespace') 42 | slam = LaunchConfiguration('slam') 43 | map_yaml_file = LaunchConfiguration('map') 44 | use_sim_time = LaunchConfiguration('use_sim_time') 45 | params_file = LaunchConfiguration('params_file') 46 | autostart = LaunchConfiguration('autostart') 47 | use_composition = LaunchConfiguration('use_composition') 48 | use_respawn = LaunchConfiguration('use_respawn') 49 | open_rviz = LaunchConfiguration('open_rviz') 50 | 51 | # Map fully qualified names to relative ones so the node's namespace can be prepended. 52 | # In case of the transforms (tf), currently, there doesn't seem to be a better alternative 53 | # https://github.com/ros/geometry2/issues/32 54 | # https://github.com/ros/robot_state_publisher/pull/30 55 | # TODO(orduno) Substitute with `PushNodeRemapping` 56 | # https://github.com/ros2/launch_ros/issues/56 57 | remappings = [('/tf', 'tf'), 58 | ('/tf_static', 'tf_static')] 59 | 60 | # Create our own temporary YAML files that include substitutions 61 | param_substitutions = { 62 | 'use_sim_time': use_sim_time, 63 | 'yaml_filename': map_yaml_file} 64 | 65 | configured_params = RewrittenYaml( 66 | source_file=params_file, 67 | root_key=namespace, 68 | param_rewrites=param_substitutions, 69 | convert_types=True) 70 | 71 | stdout_linebuf_envvar = SetEnvironmentVariable( 72 | 'RCUTILS_LOGGING_BUFFERED_STREAM', '1') 73 | 74 | declare_namespace_cmd = DeclareLaunchArgument( 75 | 'namespace', 76 | default_value='', 77 | description='Top-level namespace') 78 | 79 | declare_use_namespace_cmd = DeclareLaunchArgument( 80 | 'use_namespace', 81 | default_value='false', 82 | description='Whether to apply a namespace to the navigation stack') 83 | 84 | declare_slam_cmd = DeclareLaunchArgument( 85 | 'slam', 86 | default_value='False', 87 | description='Whether run a SLAM') 88 | declare_map_yaml_cmd = DeclareLaunchArgument( 89 | 'map', 90 | default_value=os.path.join(my_map_dir, my_map_file), 91 | description='Full path to map yaml file to load') 92 | 93 | declare_use_sim_time_cmd = DeclareLaunchArgument( 94 | 'use_sim_time', 95 | default_value='false', 96 | description='Use simulation (Gazebo) clock if true') 97 | 98 | declare_params_file_cmd = DeclareLaunchArgument( 99 | 'params_file', 100 | default_value=os.path.join(my_param_dir, my_param_file), 101 | description='Full path to the ROS2 parameters file to use for all launched nodes') 102 | 103 | declare_autostart_cmd = DeclareLaunchArgument( 104 | 'autostart', default_value='true', 105 | description='Automatically startup the nav2 stack') 106 | 107 | declare_use_composition_cmd = DeclareLaunchArgument( 108 | 'use_composition', default_value='False', 109 | description='Whether to use composed bringup') 110 | 111 | declare_use_respawn_cmd = DeclareLaunchArgument( 112 | 'use_respawn', default_value='False', 113 | description='Whether to respawn if a node crashes. Applied when composition is disabled.') 114 | 115 | declare_open_rviz_cmd = DeclareLaunchArgument( 116 | 'open_rviz', 117 | default_value='false', 118 | description='Launch Rviz?') 119 | 120 | # Specify the actions 121 | bringup_cmd_group = GroupAction([ 122 | PushRosNamespace( 123 | condition=IfCondition(use_namespace), 124 | namespace=namespace), 125 | 126 | Node( 127 | condition=IfCondition(use_composition), 128 | name='nav2_container', 129 | package='rclcpp_components', 130 | executable='component_container_isolated', 131 | parameters=[configured_params, {'autostart': autostart}], 132 | remappings=remappings, 133 | output='screen'), 134 | 135 | IncludeLaunchDescription( 136 | PythonLaunchDescriptionSource(os.path.join(my_launch_dir, 'slam_launch.py')), 137 | condition=IfCondition(slam), 138 | launch_arguments={'namespace': namespace, 139 | 'use_sim_time': use_sim_time, 140 | 'autostart': autostart, 141 | 'use_respawn': use_respawn, 142 | 'params_file': params_file}.items()), 143 | 144 | IncludeLaunchDescription( 145 | PythonLaunchDescriptionSource(os.path.join(my_launch_dir, 146 | 'localization_launch.py')), 147 | condition=IfCondition(PythonExpression(['not ', slam])), 148 | launch_arguments={'namespace': namespace, 149 | 'map': map_yaml_file, 150 | 'use_sim_time': use_sim_time, 151 | 'autostart': autostart, 152 | 'params_file': params_file, 153 | 'use_composition': use_composition, 154 | 'use_respawn': use_respawn, 155 | 'container_name': 'nav2_container'}.items()), 156 | 157 | IncludeLaunchDescription( 158 | PythonLaunchDescriptionSource(os.path.join(my_launch_dir, 'navigation_launch.py')), 159 | launch_arguments={'namespace': namespace, 160 | 'use_sim_time': use_sim_time, 161 | 'autostart': autostart, 162 | 'params_file': params_file, 163 | 'use_composition': use_composition, 164 | 'use_respawn': use_respawn, 165 | 'container_name': 'nav2_container'}.items()), 166 | 167 | IncludeLaunchDescription( 168 | PythonLaunchDescriptionSource(os.path.join(my_launch_dir, 'rviz_view_launch.py')), 169 | launch_arguments={'use_sim_time': use_sim_time, 170 | 'open_rviz': open_rviz, 171 | 'map_subscribe_transient_local': 'true'}.items()), 172 | 173 | ]) 174 | 175 | # Create the launch description and populate 176 | ld = LaunchDescription() 177 | 178 | # Set environment variables 179 | ld.add_action(stdout_linebuf_envvar) 180 | 181 | # Declare the launch options 182 | ld.add_action(declare_namespace_cmd) 183 | ld.add_action(declare_use_namespace_cmd) 184 | ld.add_action(declare_slam_cmd) 185 | ld.add_action(declare_map_yaml_cmd) 186 | ld.add_action(declare_use_sim_time_cmd) 187 | ld.add_action(declare_params_file_cmd) 188 | ld.add_action(declare_autostart_cmd) 189 | ld.add_action(declare_use_composition_cmd) 190 | ld.add_action(declare_use_respawn_cmd) 191 | ld.add_action(declare_open_rviz_cmd) 192 | 193 | # Add the actions to launch all of the navigation nodes 194 | ld.add_action(bringup_cmd_group) 195 | 196 | return ld 197 | -------------------------------------------------------------------------------- /neuronbot2_nav/launch/localization_launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 Intel Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | 17 | from ament_index_python.packages import get_package_share_directory 18 | 19 | from launch import LaunchDescription 20 | from launch.actions import DeclareLaunchArgument, GroupAction, SetEnvironmentVariable 21 | from launch.conditions import IfCondition 22 | from launch.substitutions import LaunchConfiguration, PythonExpression 23 | from launch_ros.actions import LoadComposableNodes 24 | from launch_ros.actions import Node 25 | from launch_ros.descriptions import ComposableNode 26 | from nav2_common.launch import RewrittenYaml 27 | 28 | 29 | def generate_launch_description(): 30 | # Get the launch directory 31 | my_nav_dir = get_package_share_directory('neuronbot2_nav') 32 | my_param_dir = os.path.join(my_nav_dir, 'param') 33 | my_param_file = 'neuronbot_params.yaml' 34 | my_map_dir = os.path.join(my_nav_dir, 'map') 35 | my_map_file = 'mememan.yaml' 36 | 37 | namespace = LaunchConfiguration('namespace') 38 | map_yaml_file = LaunchConfiguration('map') 39 | use_sim_time = LaunchConfiguration('use_sim_time') 40 | autostart = LaunchConfiguration('autostart') 41 | params_file = LaunchConfiguration('params_file') 42 | use_composition = LaunchConfiguration('use_composition') 43 | container_name = LaunchConfiguration('container_name') 44 | use_respawn = LaunchConfiguration('use_respawn') 45 | 46 | lifecycle_nodes = ['map_server', 'amcl'] 47 | # Map fully qualified names to relative ones so the node's namespace can be prepended. 48 | # In case of the transforms (tf), currently, there doesn't seem to be a better alternative 49 | # https://github.com/ros/geometry2/issues/32 50 | # https://github.com/ros/robot_state_publisher/pull/30 51 | # TODO(orduno) Substitute with `PushNodeRemapping` 52 | # https://github.com/ros2/launch_ros/issues/56 53 | remappings = [('/tf', 'tf'), 54 | ('/tf_static', 'tf_static')] 55 | 56 | # Create our own temporary YAML files that include substitutions 57 | param_substitutions = { 58 | 'use_sim_time': use_sim_time, 59 | 'yaml_filename': map_yaml_file} 60 | 61 | configured_params = RewrittenYaml( 62 | source_file=params_file, 63 | root_key=namespace, 64 | param_rewrites=param_substitutions, 65 | convert_types=True) 66 | 67 | stdout_linebuf_envvar = SetEnvironmentVariable( 68 | 'RCUTILS_LOGGING_BUFFERED_STREAM', '1') 69 | 70 | declare_namespace_cmd = DeclareLaunchArgument( 71 | 'namespace', 72 | default_value='', 73 | description='Top-level namespace') 74 | 75 | declare_map_yaml_cmd = DeclareLaunchArgument( 76 | 'map', 77 | default_value=os.path.join(my_map_dir, my_map_file), 78 | description='[localize] Full path to map yaml file to load') 79 | 80 | declare_use_sim_time_cmd = DeclareLaunchArgument( 81 | 'use_sim_time', 82 | default_value='false', 83 | description='Use simulation (Gazebo) clock if true') 84 | 85 | declare_params_file_cmd = DeclareLaunchArgument( 86 | 'params_file', 87 | default_value=os.path.join(my_param_dir, my_param_file), 88 | description='Full path to the ROS2 parameters file to use') 89 | declare_autostart_cmd = DeclareLaunchArgument( 90 | 'autostart', default_value='true', 91 | description='Automatically startup the nav2 stack') 92 | 93 | declare_use_composition_cmd = DeclareLaunchArgument( 94 | 'use_composition', default_value='False', 95 | description='Use composed bringup if True') 96 | 97 | declare_container_name_cmd = DeclareLaunchArgument( 98 | 'container_name', default_value='nav2_container', 99 | description='the name of conatiner that nodes will load in if use composition') 100 | 101 | declare_use_respawn_cmd = DeclareLaunchArgument( 102 | 'use_respawn', default_value='False', 103 | description='Whether to respawn if a node crashes. Applied when composition is disabled.') 104 | 105 | load_nodes = GroupAction( 106 | condition=IfCondition(PythonExpression(['not ', use_composition])), 107 | actions=[ 108 | Node( 109 | package='nav2_map_server', 110 | executable='map_server', 111 | name='map_server', 112 | output='screen', 113 | respawn=use_respawn, 114 | respawn_delay=2.0, 115 | parameters=[configured_params], 116 | remappings=remappings), 117 | Node( 118 | package='nav2_amcl', 119 | executable='amcl', 120 | name='amcl', 121 | output='screen', 122 | respawn=use_respawn, 123 | respawn_delay=2.0, 124 | parameters=[configured_params], 125 | remappings=remappings), 126 | Node( 127 | package='nav2_lifecycle_manager', 128 | executable='lifecycle_manager', 129 | name='lifecycle_manager_localization', 130 | output='screen', 131 | parameters=[{'use_sim_time': use_sim_time}, 132 | {'autostart': autostart}, 133 | {'node_names': lifecycle_nodes}]) 134 | ] 135 | ) 136 | 137 | load_composable_nodes = LoadComposableNodes( 138 | condition=IfCondition(use_composition), 139 | target_container=container_name, 140 | composable_node_descriptions=[ 141 | ComposableNode( 142 | package='nav2_map_server', 143 | plugin='nav2_map_server::MapServer', 144 | name='map_server', 145 | parameters=[configured_params], 146 | remappings=remappings), 147 | ComposableNode( 148 | package='nav2_amcl', 149 | plugin='nav2_amcl::AmclNode', 150 | name='amcl', 151 | parameters=[configured_params], 152 | remappings=remappings), 153 | ComposableNode( 154 | package='nav2_lifecycle_manager', 155 | plugin='nav2_lifecycle_manager::LifecycleManager', 156 | name='lifecycle_manager_localization', 157 | parameters=[{'use_sim_time': use_sim_time, 158 | 'autostart': autostart, 159 | 'node_names': lifecycle_nodes}]), 160 | ], 161 | ) 162 | 163 | # Create the launch description and populate 164 | ld = LaunchDescription() 165 | 166 | # Set environment variables 167 | ld.add_action(stdout_linebuf_envvar) 168 | 169 | # Declare the launch options 170 | ld.add_action(declare_namespace_cmd) 171 | ld.add_action(declare_map_yaml_cmd) 172 | ld.add_action(declare_use_sim_time_cmd) 173 | ld.add_action(declare_params_file_cmd) 174 | ld.add_action(declare_autostart_cmd) 175 | ld.add_action(declare_use_composition_cmd) 176 | ld.add_action(declare_container_name_cmd) 177 | ld.add_action(declare_use_respawn_cmd) 178 | 179 | # Add the actions to launch all of the localiztion nodes 180 | ld.add_action(load_nodes) 181 | ld.add_action(load_composable_nodes) 182 | 183 | return ld 184 | -------------------------------------------------------------------------------- /neuronbot2_nav/launch/navigation_launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 Intel Corporation 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | 17 | from ament_index_python.packages import get_package_share_directory 18 | 19 | from launch import LaunchDescription 20 | from launch.actions import DeclareLaunchArgument, GroupAction, SetEnvironmentVariable 21 | from launch.conditions import IfCondition 22 | from launch.substitutions import LaunchConfiguration, PythonExpression 23 | from launch_ros.actions import LoadComposableNodes 24 | from launch_ros.actions import Node 25 | from launch_ros.descriptions import ComposableNode 26 | from nav2_common.launch import RewrittenYaml 27 | 28 | 29 | def generate_launch_description(): 30 | # Get the launch directory 31 | my_nav_dir = get_package_share_directory('neuronbot2_nav') 32 | my_param_dir = os.path.join(my_nav_dir, 'param') 33 | my_param_file = 'neuronbot_params.yaml' 34 | 35 | namespace = LaunchConfiguration('namespace') 36 | use_sim_time = LaunchConfiguration('use_sim_time') 37 | autostart = LaunchConfiguration('autostart') 38 | params_file = LaunchConfiguration('params_file') 39 | use_composition = LaunchConfiguration('use_composition') 40 | container_name = LaunchConfiguration('container_name') 41 | use_respawn = LaunchConfiguration('use_respawn') 42 | # map_subscribe_transient_local = LaunchConfiguration('map_subscribe_transient_local') 43 | 44 | lifecycle_nodes = ['controller_server', 45 | 'smoother_server', 46 | 'planner_server', 47 | 'behavior_server', 48 | 'bt_navigator', 49 | 'waypoint_follower'] 50 | 51 | # Map fully qualified names to relative ones so the node's namespace can be prepended. 52 | # In case of the transforms (tf), currently, there doesn't seem to be a better alternative 53 | # https://github.com/ros/geometry2/issues/32 54 | # https://github.com/ros/robot_state_publisher/pull/30 55 | # TODO(orduno) Substitute with `PushNodeRemapping` 56 | # https://github.com/ros2/launch_ros/issues/56 57 | remappings = [('/tf', 'tf'), 58 | ('/tf_static', 'tf_static')] 59 | 60 | # Create our own temporary YAML files that include substitutions 61 | param_substitutions = { 62 | 'use_sim_time': use_sim_time, 63 | 'autostart': autostart 64 | # ,'map_subscribe_transient_local': map_subscribe_transient_local 65 | } 66 | 67 | configured_params = RewrittenYaml( 68 | source_file=params_file, 69 | root_key=namespace, 70 | param_rewrites=param_substitutions, 71 | convert_types=True) 72 | 73 | stdout_linebuf_envvar = SetEnvironmentVariable( 74 | 'RCUTILS_LOGGING_BUFFERED_STREAM', '1') 75 | 76 | declare_namespace_cmd = DeclareLaunchArgument( 77 | 'namespace', 78 | default_value='', 79 | description='Top-level namespace') 80 | 81 | declare_use_sim_time_cmd = DeclareLaunchArgument( 82 | 'use_sim_time', 83 | default_value='false', 84 | description='Use simulation (Gazebo) clock if true') 85 | 86 | declare_params_file_cmd = DeclareLaunchArgument( 87 | 'params_file', 88 | default_value=os.path.join(my_param_dir, my_param_file), 89 | description='Full path to the ROS2 parameters file to use') 90 | 91 | declare_autostart_cmd = DeclareLaunchArgument( 92 | 'autostart', default_value='true', 93 | description='Automatically startup the nav2 stack') 94 | 95 | declare_use_composition_cmd = DeclareLaunchArgument( 96 | 'use_composition', default_value='False', 97 | description='Use composed bringup if True') 98 | 99 | declare_container_name_cmd = DeclareLaunchArgument( 100 | 'container_name', default_value='nav2_container', 101 | description='the name of conatiner that nodes will load in if use composition') 102 | 103 | declare_use_respawn_cmd = DeclareLaunchArgument( 104 | 'use_respawn', default_value='False', 105 | description='Whether to respawn if a node crashes. Applied when composition is disabled.') 106 | 107 | load_nodes = GroupAction( 108 | condition=IfCondition(PythonExpression(['not ', use_composition])), 109 | actions=[ 110 | Node( 111 | package='nav2_controller', 112 | executable='controller_server', 113 | output='screen', 114 | respawn=use_respawn, 115 | respawn_delay=2.0, 116 | parameters=[configured_params], 117 | remappings=remappings), 118 | Node( 119 | package='nav2_smoother', 120 | executable='smoother_server', 121 | name='smoother_server', 122 | output='screen', 123 | respawn=use_respawn, 124 | respawn_delay=2.0, 125 | parameters=[configured_params], 126 | remappings=remappings), 127 | Node( 128 | package='nav2_planner', 129 | executable='planner_server', 130 | name='planner_server', 131 | output='screen', 132 | respawn=use_respawn, 133 | respawn_delay=2.0, 134 | parameters=[configured_params], 135 | remappings=remappings), 136 | Node( 137 | package='nav2_behaviors', 138 | executable='behavior_server', 139 | name='behavior_server', 140 | output='screen', 141 | respawn=use_respawn, 142 | respawn_delay=2.0, 143 | parameters=[configured_params], 144 | remappings=remappings), 145 | Node( 146 | package='nav2_bt_navigator', 147 | executable='bt_navigator', 148 | name='bt_navigator', 149 | output='screen', 150 | respawn=use_respawn, 151 | respawn_delay=2.0, 152 | parameters=[configured_params], 153 | remappings=remappings), 154 | Node( 155 | package='nav2_waypoint_follower', 156 | executable='waypoint_follower', 157 | name='waypoint_follower', 158 | output='screen', 159 | respawn=use_respawn, 160 | respawn_delay=2.0, 161 | parameters=[configured_params], 162 | remappings=remappings), 163 | Node( 164 | package='nav2_lifecycle_manager', 165 | executable='lifecycle_manager', 166 | name='lifecycle_manager_navigation', 167 | output='screen', 168 | parameters=[{'use_sim_time': use_sim_time}, 169 | {'autostart': autostart}, 170 | {'node_names': lifecycle_nodes}]), 171 | ] 172 | ) 173 | 174 | load_composable_nodes = LoadComposableNodes( 175 | condition=IfCondition(use_composition), 176 | target_container=container_name, 177 | composable_node_descriptions=[ 178 | ComposableNode( 179 | package='nav2_controller', 180 | plugin='nav2_controller::ControllerServer', 181 | name='controller_server', 182 | parameters=[configured_params], 183 | remappings=remappings), 184 | ComposableNode( 185 | package='nav2_smoother', 186 | plugin='nav2_smoother::SmootherServer', 187 | name='smoother_server', 188 | parameters=[configured_params], 189 | remappings=remappings), 190 | ComposableNode( 191 | package='nav2_planner', 192 | plugin='nav2_planner::PlannerServer', 193 | name='planner_server', 194 | parameters=[configured_params], 195 | remappings=remappings), 196 | ComposableNode( 197 | package='nav2_behaviors', 198 | plugin='behavior_server::BehaviorServer', 199 | name='behavior_server', 200 | parameters=[configured_params], 201 | remappings=remappings), 202 | ComposableNode( 203 | package='nav2_bt_navigator', 204 | plugin='nav2_bt_navigator::BtNavigator', 205 | name='bt_navigator', 206 | parameters=[configured_params], 207 | remappings=remappings), 208 | ComposableNode( 209 | package='nav2_waypoint_follower', 210 | plugin='nav2_waypoint_follower::WaypointFollower', 211 | name='waypoint_follower', 212 | parameters=[configured_params], 213 | remappings=remappings), 214 | ComposableNode( 215 | package='nav2_lifecycle_manager', 216 | plugin='nav2_lifecycle_manager::LifecycleManager', 217 | name='lifecycle_manager_navigation', 218 | parameters=[{'use_sim_time': use_sim_time, 219 | 'autostart': autostart, 220 | 'node_names': lifecycle_nodes}]), 221 | ], 222 | ) 223 | 224 | # Create the launch description and populate 225 | ld = LaunchDescription() 226 | 227 | # Set environment variables 228 | ld.add_action(stdout_linebuf_envvar) 229 | 230 | # Declare the launch options 231 | ld.add_action(declare_namespace_cmd) 232 | ld.add_action(declare_use_sim_time_cmd) 233 | ld.add_action(declare_params_file_cmd) 234 | ld.add_action(declare_autostart_cmd) 235 | ld.add_action(declare_use_composition_cmd) 236 | ld.add_action(declare_container_name_cmd) 237 | ld.add_action(declare_use_respawn_cmd) 238 | 239 | # Add the actions to launch all of the navigation nodes 240 | ld.add_action(load_nodes) 241 | ld.add_action(load_composable_nodes) 242 | 243 | return ld 244 | -------------------------------------------------------------------------------- /neuronbot2_nav/launch/rviz_view_launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ament_index_python.packages import get_package_share_directory 4 | from launch import LaunchDescription 5 | from launch.conditions import IfCondition 6 | from launch.actions import DeclareLaunchArgument 7 | from launch.actions import IncludeLaunchDescription 8 | from launch.launch_description_sources import PythonLaunchDescriptionSource 9 | from launch.substitutions import LaunchConfiguration 10 | from launch_ros.actions import Node 11 | 12 | def generate_launch_description(): 13 | use_sim_time = LaunchConfiguration('use_sim_time', default='false') 14 | 15 | open_rviz = LaunchConfiguration('open_rviz', default='true') 16 | 17 | rviz_config_dir = os.path.join( 18 | get_package_share_directory('neuronbot2_nav'), 19 | 'rviz', 20 | 'nav2_default_view.rviz') 21 | 22 | return LaunchDescription([ 23 | 24 | DeclareLaunchArgument( 25 | 'use_sim_time', 26 | default_value='false', 27 | description='Use simulation (Gazebo) clock if true'), 28 | 29 | DeclareLaunchArgument( 30 | 'open_rviz', 31 | default_value='true', 32 | description='Launch Rviz?'), 33 | 34 | Node( 35 | package='rviz2', 36 | executable='rviz2', 37 | name='rviz2', 38 | arguments=['-d', rviz_config_dir], 39 | parameters=[{'use_sim_time': use_sim_time}], 40 | condition=IfCondition(LaunchConfiguration("open_rviz")) 41 | # output='log' 42 | ), 43 | ]) 44 | -------------------------------------------------------------------------------- /neuronbot2_nav/launch/slam_launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Samsung Research Russia 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | 17 | from ament_index_python.packages import get_package_share_directory 18 | 19 | from launch import LaunchDescription 20 | from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription 21 | from launch.conditions import IfCondition, UnlessCondition 22 | from launch.launch_description_sources import PythonLaunchDescriptionSource 23 | from launch.substitutions import LaunchConfiguration 24 | from launch_ros.actions import Node 25 | from nav2_common.launch import HasNodeParams, RewrittenYaml 26 | 27 | 28 | def generate_launch_description(): 29 | # Input parameters declaration 30 | namespace = LaunchConfiguration('namespace') 31 | params_file = LaunchConfiguration('params_file') 32 | use_sim_time = LaunchConfiguration('use_sim_time') 33 | autostart = LaunchConfiguration('autostart') 34 | use_respawn = LaunchConfiguration('use_respawn') 35 | 36 | # Variables 37 | lifecycle_nodes = ['map_saver'] 38 | 39 | # Getting directories and launch-files 40 | bringup_dir = get_package_share_directory('nav2_bringup') 41 | slam_toolbox_dir = get_package_share_directory('slam_toolbox') 42 | slam_launch_file = os.path.join(slam_toolbox_dir, 'launch', 'online_sync_launch.py') 43 | 44 | # Create our own temporary YAML files that include substitutions 45 | param_substitutions = { 46 | 'use_sim_time': use_sim_time} 47 | 48 | configured_params = RewrittenYaml( 49 | source_file=params_file, 50 | root_key=namespace, 51 | param_rewrites=param_substitutions, 52 | convert_types=True) 53 | 54 | # Declare the launch arguments 55 | declare_namespace_cmd = DeclareLaunchArgument( 56 | 'namespace', 57 | default_value='', 58 | description='Top-level namespace') 59 | 60 | declare_params_file_cmd = DeclareLaunchArgument( 61 | 'params_file', 62 | default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'), 63 | description='Full path to the ROS2 parameters file to use for all launched nodes') 64 | 65 | declare_use_sim_time_cmd = DeclareLaunchArgument( 66 | 'use_sim_time', 67 | default_value='True', 68 | description='Use simulation (Gazebo) clock if true') 69 | 70 | declare_autostart_cmd = DeclareLaunchArgument( 71 | 'autostart', default_value='True', 72 | description='Automatically startup the nav2 stack') 73 | 74 | declare_use_respawn_cmd = DeclareLaunchArgument( 75 | 'use_respawn', default_value='False', 76 | description='Whether to respawn if a node crashes. Applied when composition is disabled.') 77 | 78 | # Nodes launching commands 79 | 80 | start_map_saver_server_cmd = Node( 81 | package='nav2_map_server', 82 | executable='map_saver_server', 83 | output='screen', 84 | respawn=use_respawn, 85 | respawn_delay=2.0, 86 | parameters=[configured_params]) 87 | 88 | start_lifecycle_manager_cmd = Node( 89 | package='nav2_lifecycle_manager', 90 | executable='lifecycle_manager', 91 | name='lifecycle_manager_slam', 92 | output='screen', 93 | parameters=[{'use_sim_time': use_sim_time}, 94 | {'autostart': autostart}, 95 | {'node_names': lifecycle_nodes}]) 96 | 97 | # If the provided param file doesn't have slam_toolbox params, we must remove the 'params_file' 98 | # LaunchConfiguration, or it will be passed automatically to slam_toolbox and will not load 99 | # the default file 100 | has_slam_toolbox_params = HasNodeParams(source_file=params_file, 101 | node_name='slam_toolbox') 102 | 103 | start_slam_toolbox_cmd = IncludeLaunchDescription( 104 | PythonLaunchDescriptionSource(slam_launch_file), 105 | launch_arguments={'use_sim_time': use_sim_time}.items(), 106 | condition=UnlessCondition(has_slam_toolbox_params)) 107 | 108 | start_slam_toolbox_cmd_with_params = IncludeLaunchDescription( 109 | PythonLaunchDescriptionSource(slam_launch_file), 110 | launch_arguments={'use_sim_time': use_sim_time, 111 | 'slam_params_file': params_file}.items(), 112 | condition=IfCondition(has_slam_toolbox_params)) 113 | 114 | ld = LaunchDescription() 115 | 116 | # Declare the launch options 117 | ld.add_action(declare_namespace_cmd) 118 | ld.add_action(declare_params_file_cmd) 119 | ld.add_action(declare_use_sim_time_cmd) 120 | ld.add_action(declare_autostart_cmd) 121 | ld.add_action(declare_use_respawn_cmd) 122 | 123 | # Running Map Saver Server 124 | ld.add_action(start_map_saver_server_cmd) 125 | ld.add_action(start_lifecycle_manager_cmd) 126 | 127 | # Running SLAM Toolbox (Only one of them will be run) 128 | ld.add_action(start_slam_toolbox_cmd) 129 | ld.add_action(start_slam_toolbox_cmd_with_params) 130 | 131 | return ld -------------------------------------------------------------------------------- /neuronbot2_nav/map/F9.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_nav/map/F9.pgm -------------------------------------------------------------------------------- /neuronbot2_nav/map/F9.yaml: -------------------------------------------------------------------------------- 1 | image: F9.pgm 2 | mode: trinary 3 | resolution: 0.025 4 | origin: [-26.2, -27.8, 0] 5 | negate: 0 6 | occupied_thresh: 0.65 7 | free_thresh: 0.25 8 | -------------------------------------------------------------------------------- /neuronbot2_nav/map/mememan.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_nav/map/mememan.pgm -------------------------------------------------------------------------------- /neuronbot2_nav/map/mememan.yaml: -------------------------------------------------------------------------------- 1 | image: mememan.pgm 2 | resolution: 0.050000 3 | origin: [-12.200000, -13.800000, 0.000000] 4 | negate: 0 5 | occupied_thresh: 0.65 6 | free_thresh: 0.196 7 | 8 | -------------------------------------------------------------------------------- /neuronbot2_nav/map/phenix.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_nav/map/phenix.pgm -------------------------------------------------------------------------------- /neuronbot2_nav/map/phenix.yaml: -------------------------------------------------------------------------------- 1 | image: phenix.pgm 2 | mode: trinary 3 | resolution: 0.05 4 | origin: [-4.12, -16.4, 0] 5 | negate: 0 6 | occupied_thresh: 0.65 7 | free_thresh: 0.25 -------------------------------------------------------------------------------- /neuronbot2_nav/map/training_room.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_nav/map/training_room.pgm -------------------------------------------------------------------------------- /neuronbot2_nav/map/training_room.yaml: -------------------------------------------------------------------------------- 1 | image: training_room.pgm 2 | mode: trinary 3 | resolution: 0.05 4 | origin: [-7.84, -2.48, 0] 5 | negate: 0 6 | occupied_thresh: 0.65 7 | free_thresh: 0.25 -------------------------------------------------------------------------------- /neuronbot2_nav/map/wg.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_nav/map/wg.pgm -------------------------------------------------------------------------------- /neuronbot2_nav/map/wg.yaml: -------------------------------------------------------------------------------- 1 | image: wg.pgm 2 | mode: trinary 3 | resolution: 0.025 4 | origin: [-15, -26.2, 0] 5 | negate: 0 6 | occupied_thresh: 0.65 7 | free_thresh: 0.25 -------------------------------------------------------------------------------- /neuronbot2_nav/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | neuronbot2_nav 5 | 0.1.0 6 | ROS2 Navigation2 for NeuronBot2 7 | airuchen 8 | TODO: License declaration 9 | 10 | ament_cmake 11 | 12 | nav2_bringup 13 | 14 | ament_lint_auto 15 | ament_lint_common 16 | 17 | 18 | ament_cmake 19 | 20 | 21 | -------------------------------------------------------------------------------- /neuronbot2_nav/param/neuronbot_params.yaml: -------------------------------------------------------------------------------- 1 | amcl: 2 | ros__parameters: 3 | use_sim_time: False 4 | alpha1: 0.9 5 | alpha2: 0.1 6 | alpha3: 0.05 7 | alpha4: 0.01 8 | alpha5: 0.04 9 | base_frame_id: "base_footprint" 10 | beam_skip_distance: 0.5 11 | beam_skip_error_threshold: 0.9 12 | beam_skip_threshold: 0.3 13 | do_beamskip: false 14 | global_frame_id: "map" 15 | lambda_short: 0.1 16 | laser_likelihood_max_dist: 2.0 17 | laser_max_range: 100.0 18 | laser_min_range: -1.0 19 | laser_model_type: "likelihood_field" 20 | max_beams: 60 21 | max_particles: 2000 22 | min_particles: 500 23 | odom_frame_id: "odom" 24 | pf_err: 0.02 25 | pf_z: 0.85 26 | recovery_alpha_fast: 0.0 27 | recovery_alpha_slow: 0.0 28 | resample_interval: 2 29 | robot_model_type: "nav2_amcl::DifferentialMotionModel" 30 | save_pose_rate: 0.5 31 | sigma_hit: 0.02 32 | tf_broadcast: true 33 | transform_tolerance: 0.5 34 | update_min_a: 0.06 35 | update_min_d: 0.025 36 | z_hit: 0.7 37 | z_max: 0.001 38 | z_rand: 0.059 39 | z_short: 0.24 40 | scan_topic: scan 41 | 42 | # Initial Pose 43 | set_initial_pose: True 44 | initial_pose.x: 0.0 45 | initial_pose.y: 0.0 46 | initial_pose.z: 0.0 47 | initial_pose.yaw: 0.0 48 | 49 | amcl_map_client: 50 | ros__parameters: 51 | use_sim_time: False 52 | 53 | amcl_rclcpp_node: 54 | ros__parameters: 55 | use_sim_time: False 56 | 57 | bt_navigator: 58 | ros__parameters: 59 | use_sim_time: False 60 | global_frame: map 61 | robot_base_frame: base_footprint 62 | odom_topic: /odom 63 | bt_loop_duration: 10 64 | default_server_timeout: 20 65 | # 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults: 66 | # nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml 67 | # nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml 68 | # They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2. 69 | plugin_lib_names: 70 | - nav2_compute_path_to_pose_action_bt_node 71 | - nav2_compute_path_through_poses_action_bt_node 72 | - nav2_smooth_path_action_bt_node 73 | - nav2_follow_path_action_bt_node 74 | - nav2_spin_action_bt_node 75 | - nav2_wait_action_bt_node 76 | - nav2_back_up_action_bt_node 77 | - nav2_drive_on_heading_bt_node 78 | - nav2_clear_costmap_service_bt_node 79 | - nav2_is_stuck_condition_bt_node 80 | - nav2_goal_reached_condition_bt_node 81 | - nav2_goal_updated_condition_bt_node 82 | - nav2_globally_updated_goal_condition_bt_node 83 | - nav2_is_path_valid_condition_bt_node 84 | - nav2_initial_pose_received_condition_bt_node 85 | - nav2_reinitialize_global_localization_service_bt_node 86 | - nav2_rate_controller_bt_node 87 | - nav2_distance_controller_bt_node 88 | - nav2_speed_controller_bt_node 89 | - nav2_truncate_path_action_bt_node 90 | - nav2_truncate_path_local_action_bt_node 91 | - nav2_goal_updater_node_bt_node 92 | - nav2_recovery_node_bt_node 93 | - nav2_pipeline_sequence_bt_node 94 | - nav2_round_robin_node_bt_node 95 | - nav2_transform_available_condition_bt_node 96 | - nav2_time_expired_condition_bt_node 97 | - nav2_path_expiring_timer_condition 98 | - nav2_distance_traveled_condition_bt_node 99 | - nav2_single_trigger_bt_node 100 | # - nav2_goal_updated_controller_bt_node 101 | - nav2_is_battery_low_condition_bt_node 102 | - nav2_navigate_through_poses_action_bt_node 103 | - nav2_navigate_to_pose_action_bt_node 104 | - nav2_remove_passed_goals_action_bt_node 105 | - nav2_planner_selector_bt_node 106 | - nav2_controller_selector_bt_node 107 | - nav2_goal_checker_selector_bt_node 108 | - nav2_controller_cancel_bt_node 109 | - nav2_path_longer_on_approach_bt_node 110 | - nav2_wait_cancel_bt_node 111 | - nav2_spin_cancel_bt_node 112 | - nav2_back_up_cancel_bt_node 113 | - nav2_drive_on_heading_cancel_bt_node 114 | 115 | bt_navigator_rclcpp_node: 116 | ros__parameters: 117 | use_sim_time: False 118 | 119 | controller_server: 120 | ros__parameters: 121 | use_sim_time: False 122 | controller_frequency: 20.0 123 | min_x_velocity_threshold: 0.001 124 | min_y_velocity_threshold: 0.5 125 | min_theta_velocity_threshold: 0.001 126 | failure_tolerance: 0.3 127 | progress_checker_plugin: "progress_checker" 128 | goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker" 129 | controller_plugins: ["FollowPath"] 130 | 131 | # Progress checker parameters 132 | progress_checker: 133 | plugin: "nav2_controller::SimpleProgressChecker" 134 | required_movement_radius: 0.5 135 | movement_time_allowance: 10.0 136 | # Goal checker parameters 137 | #precise_goal_checker: 138 | # plugin: "nav2_controller::SimpleGoalChecker" 139 | # xy_goal_tolerance: 0.25 140 | # yaw_goal_tolerance: 0.25 141 | # stateful: True 142 | general_goal_checker: 143 | stateful: True 144 | plugin: "nav2_controller::SimpleGoalChecker" 145 | xy_goal_tolerance: 0.25 146 | yaw_goal_tolerance: 0.25 147 | # DWB parameters 148 | FollowPath: 149 | plugin: "dwb_core::DWBLocalPlanner" 150 | debug_trajectory_details: True 151 | min_vel_x: -1.0 152 | min_vel_y: 0.0 153 | max_vel_x: 1.0 154 | max_vel_y: 0.0 155 | max_vel_theta: 1.5 156 | min_speed_xy: 0.0 157 | max_speed_xy: 1.0 158 | min_speed_theta: 0.0 159 | # Add high threshold velocity for turtlebot 3 issue. 160 | # https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75 161 | acc_lim_x: 0.5 162 | acc_lim_y: 0.0 163 | acc_lim_theta: 1.0 164 | decel_lim_x: -0.5 165 | decel_lim_y: 0.0 166 | decel_lim_theta: -1.0 167 | vx_samples: 20 168 | vy_samples: 0 169 | vtheta_samples: 20 170 | sim_time: 1.7 171 | linear_granularity: 0.05 172 | angular_granularity: 0.025 173 | transform_tolerance: 0.2 174 | xy_goal_tolerance: 0.25 175 | trans_stopped_velocity: 0.25 176 | short_circuit_trajectory_evaluation: True 177 | stateful: True 178 | critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"] 179 | BaseObstacle.scale: 0.04 180 | PathAlign.scale: 50.0 181 | PathAlign.forward_point_distance: 0.1 182 | GoalAlign.scale: 10.0 183 | GoalAlign.forward_point_distance: 0.1 184 | PathDist.scale: 50.0 185 | GoalDist.scale: 10.0 186 | RotateToGoal.scale: 32.0 187 | RotateToGoal.slowing_factor: 5.0 188 | RotateToGoal.lookahead_time: -1.0 189 | 190 | controller_server_rclcpp_node: 191 | ros__parameters: 192 | use_sim_time: False 193 | 194 | local_costmap: 195 | local_costmap: 196 | ros__parameters: 197 | update_frequency: 5.0 198 | publish_frequency: 2.0 199 | global_frame: odom 200 | robot_base_frame: base_footprint 201 | use_sim_time: False 202 | rolling_window: true 203 | width: 3 204 | height: 3 205 | resolution: 0.05 206 | robot_radius: 0.20 207 | plugins: ["voxel_layer", "inflation_layer"] 208 | inflation_layer: 209 | plugin: "nav2_costmap_2d::InflationLayer" 210 | cost_scaling_factor: 3.0 211 | inflation_radius: 0.55 212 | voxel_layer: 213 | plugin: "nav2_costmap_2d::VoxelLayer" 214 | enabled: True 215 | publish_voxel_map: True 216 | origin_z: 0.0 217 | z_resolution: 0.05 218 | z_voxels: 16 219 | max_obstacle_height: 2.0 220 | mark_threshold: 0 221 | observation_sources: scan 222 | scan: 223 | topic: /scan 224 | max_obstacle_height: 2.0 225 | clearing: True 226 | marking: True 227 | data_type: "LaserScan" 228 | raytrace_max_range: 10.0 229 | raytrace_min_range: 0.0 230 | obstacle_max_range: 2.5 231 | obstacle_min_range: 0.0 232 | 233 | always_send_full_costmap: True 234 | local_costmap_client: 235 | ros__parameters: 236 | use_sim_time: False 237 | local_costmap_rclcpp_node: 238 | ros__parameters: 239 | use_sim_time: False 240 | 241 | global_costmap: 242 | global_costmap: 243 | ros__parameters: 244 | update_frequency: 1.0 245 | publish_frequency: 1.0 246 | global_frame: map 247 | robot_base_frame: base_footprint 248 | use_sim_time: False 249 | robot_radius: 0.20 250 | resolution: 0.05 251 | track_unknown_space: true 252 | plugins: ["static_layer", "obstacle_layer", "inflation_layer"] 253 | obstacle_layer: 254 | plugin: "nav2_costmap_2d::ObstacleLayer" 255 | enabled: True 256 | observation_sources: scan 257 | scan: 258 | topic: /scan 259 | max_obstacle_height: 2.0 260 | clearing: True 261 | marking: True 262 | data_type: "LaserScan" 263 | raytrace_max_range: 10.0 264 | raytrace_min_range: 0.0 265 | obstacle_max_range: 2.5 266 | obstacle_min_range: 0.0 267 | static_layer: 268 | plugin: "nav2_costmap_2d::StaticLayer" 269 | map_subscribe_transient_local: True 270 | inflation_layer: 271 | plugin: "nav2_costmap_2d::InflationLayer" 272 | cost_scaling_factor: 3.0 273 | inflation_radius: 0.55 274 | always_send_full_costmap: True 275 | global_costmap_client: 276 | ros__parameters: 277 | use_sim_time: False 278 | global_costmap_rclcpp_node: 279 | ros__parameters: 280 | use_sim_time: False 281 | 282 | map_server: 283 | ros__parameters: 284 | use_sim_time: False 285 | yaml_filename: "turtlebot3_world.yaml" 286 | 287 | map_saver: 288 | ros__parameters: 289 | use_sim_time: False 290 | save_map_timeout: 5.0 291 | free_thresh_default: 0.25 292 | occupied_thresh_default: 0.65 293 | map_subscribe_transient_local: True 294 | 295 | planner_server: 296 | ros__parameters: 297 | expected_planner_frequency: 20.0 298 | use_sim_time: False 299 | planner_plugins: ["GridBased"] 300 | GridBased: 301 | plugin: "nav2_navfn_planner/NavfnPlanner" 302 | tolerance: 0.5 303 | use_astar: false 304 | allow_unknown: true 305 | 306 | planner_server_rclcpp_node: 307 | ros__parameters: 308 | use_sim_time: False 309 | 310 | smoother_server: 311 | ros__parameters: 312 | use_sim_time: True 313 | smoother_plugins: ["simple_smoother"] 314 | simple_smoother: 315 | plugin: "nav2_smoother::SimpleSmoother" 316 | tolerance: 1.0e-10 317 | max_its: 1000 318 | do_refinement: True 319 | 320 | behavior_server: 321 | ros__parameters: 322 | costmap_topic: local_costmap/costmap_raw 323 | footprint_topic: local_costmap/published_footprint 324 | cycle_frequency: 10.0 325 | behavior_plugins: ["spin", "backup", "drive_on_heading", "wait"] 326 | spin: 327 | plugin: "nav2_behaviors/Spin" 328 | backup: 329 | plugin: "nav2_behaviors/BackUp" 330 | drive_on_heading: 331 | plugin: "nav2_behaviors/DriveOnHeading" 332 | wait: 333 | plugin: "nav2_behaviors/Wait" 334 | global_frame: odom 335 | robot_base_frame: base_footprint 336 | transform_tolerance: 0.1 337 | use_sim_time: False 338 | simulate_ahead_time: 2.0 339 | max_rotational_vel: 0.3 340 | min_rotational_vel: 0.05 341 | rotational_acc_lim: 0.3 342 | 343 | robot_state_publisher: 344 | ros__parameters: 345 | use_sim_time: False 346 | 347 | waypoint_follower: 348 | ros__parameters: 349 | loop_rate: 20 350 | stop_on_failure: false 351 | waypoint_task_executor_plugin: "wait_at_waypoint" 352 | wait_at_waypoint: 353 | plugin: "nav2_waypoint_follower::WaitAtWaypoint" 354 | enabled: True 355 | waypoint_pause_duration: 200 -------------------------------------------------------------------------------- /neuronbot2_nav/rviz/nav2_namespaced_view.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz_common/Displays 3 | Help Height: 195 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: 7 | - /Global Options1 8 | - /RobotModel1/Status1 9 | - /TF1/Frames1 10 | - /TF1/Tree1 11 | - /Global Planner1/Global Costmap1 12 | Splitter Ratio: 0.5833333134651184 13 | Tree Height: 464 14 | - Class: rviz_common/Selection 15 | Name: Selection 16 | - Class: rviz_common/Tool Properties 17 | Expanded: 18 | - /Publish Point1 19 | Name: Tool Properties 20 | Splitter Ratio: 0.5886790156364441 21 | - Class: rviz_common/Views 22 | Expanded: 23 | - /Current View1 24 | Name: Views 25 | Splitter Ratio: 0.5 26 | - Class: nav2_rviz_plugins/Navigation 2 27 | Name: Navigation 2 28 | Visualization Manager: 29 | Class: "" 30 | Displays: 31 | - Alpha: 0.5 32 | Cell Size: 1 33 | Class: rviz_default_plugins/Grid 34 | Color: 160; 160; 164 35 | Enabled: true 36 | Line Style: 37 | Line Width: 0.029999999329447746 38 | Value: Lines 39 | Name: Grid 40 | Normal Cell Count: 0 41 | Offset: 42 | X: 0 43 | Y: 0 44 | Z: 0 45 | Plane: XY 46 | Plane Cell Count: 10 47 | Reference Frame: 48 | Value: true 49 | - Alpha: 1 50 | Class: rviz_default_plugins/RobotModel 51 | Collision Enabled: false 52 | Description File: "" 53 | Description Source: Topic 54 | Description Topic: 55 | Depth: 5 56 | Durability Policy: Volatile 57 | History Policy: Keep Last 58 | Reliability Policy: Reliable 59 | Value: /robot_description 60 | Enabled: false 61 | Links: 62 | All Links Enabled: true 63 | Expand Joint Details: false 64 | Expand Link Details: false 65 | Expand Tree: false 66 | Link Tree Style: Links in Alphabetic Order 67 | Name: RobotModel 68 | TF Prefix: "" 69 | Update Interval: 0 70 | Value: true 71 | Visual Enabled: true 72 | - Class: rviz_default_plugins/TF 73 | Enabled: true 74 | Frame Timeout: 15 75 | Frames: 76 | All Enabled: false 77 | Marker Scale: 1 78 | Name: TF 79 | Show Arrows: true 80 | Show Axes: true 81 | Show Names: false 82 | Tree: 83 | {} 84 | Update Interval: 0 85 | Value: true 86 | - Alpha: 1 87 | Autocompute Intensity Bounds: true 88 | Autocompute Value Bounds: 89 | Max Value: 10 90 | Min Value: -10 91 | Value: true 92 | Axis: Z 93 | Channel Name: intensity 94 | Class: rviz_default_plugins/LaserScan 95 | Color: 255; 255; 255 96 | Color Transformer: Intensity 97 | Decay Time: 0 98 | Enabled: true 99 | Invert Rainbow: false 100 | Max Color: 255; 255; 255 101 | Max Intensity: 0 102 | Min Color: 0; 0; 0 103 | Min Intensity: 0 104 | Name: LaserScan 105 | Position Transformer: XYZ 106 | Selectable: true 107 | Size (Pixels): 3 108 | Size (m): 0.009999999776482582 109 | Style: Flat Squares 110 | Topic: 111 | Depth: 5 112 | Durability Policy: Volatile 113 | History Policy: Keep Last 114 | Reliability Policy: Best Effort 115 | Value: /scan 116 | Use Fixed Frame: true 117 | Use rainbow: true 118 | Value: true 119 | - Alpha: 1 120 | Autocompute Intensity Bounds: true 121 | Autocompute Value Bounds: 122 | Max Value: 10 123 | Min Value: -10 124 | Value: true 125 | Axis: Z 126 | Channel Name: intensity 127 | Class: rviz_default_plugins/PointCloud2 128 | Color: 255; 255; 255 129 | Color Transformer: "" 130 | Decay Time: 0 131 | Enabled: true 132 | Invert Rainbow: false 133 | Max Color: 255; 255; 255 134 | Max Intensity: 4096 135 | Min Color: 0; 0; 0 136 | Min Intensity: 0 137 | Name: Bumper Hit 138 | Position Transformer: "" 139 | Selectable: true 140 | Size (Pixels): 3 141 | Size (m): 0.07999999821186066 142 | Style: Spheres 143 | Topic: 144 | Depth: 5 145 | Durability Policy: Volatile 146 | History Policy: Keep Last 147 | Reliability Policy: Best Effort 148 | Value: /mobile_base/sensors/bumper_pointcloud 149 | Use Fixed Frame: true 150 | Use rainbow: true 151 | Value: true 152 | - Alpha: 1 153 | Class: rviz_default_plugins/Map 154 | Color Scheme: map 155 | Draw Behind: true 156 | Enabled: true 157 | Name: Map 158 | Topic: 159 | Depth: 1 160 | Durability Policy: Transient Local 161 | History Policy: Keep Last 162 | Reliability Policy: Reliable 163 | Value: /map 164 | Use Timestamp: false 165 | Value: true 166 | - Alpha: 1 167 | Arrow Length: 0.019999999552965164 168 | Axes Length: 0.30000001192092896 169 | Axes Radius: 0.009999999776482582 170 | Class: rviz_default_plugins/PoseArray 171 | Color: 0; 180; 0 172 | Enabled: true 173 | Head Length: 0.07000000029802322 174 | Head Radius: 0.029999999329447746 175 | Name: Amcl Particle Swarm 176 | Shaft Length: 0.23000000417232513 177 | Shaft Radius: 0.009999999776482582 178 | Shape: Arrow (Flat) 179 | Topic: 180 | Depth: 5 181 | Durability Policy: Volatile 182 | History Policy: Keep Last 183 | Reliability Policy: Best Effort 184 | Value: /particlecloud 185 | Value: true 186 | - Class: rviz_common/Group 187 | Displays: 188 | - Alpha: 0.30000001192092896 189 | Class: rviz_default_plugins/Map 190 | Color Scheme: costmap 191 | Draw Behind: false 192 | Enabled: true 193 | Name: Global Costmap 194 | Topic: 195 | Depth: 1 196 | Durability Policy: Transient Local 197 | History Policy: Keep Last 198 | Reliability Policy: Reliable 199 | Value: /global_costmap/costmap 200 | Use Timestamp: false 201 | Value: true 202 | - Alpha: 1 203 | Buffer Length: 1 204 | Class: rviz_default_plugins/Path 205 | Color: 255; 0; 0 206 | Enabled: true 207 | Head Diameter: 0.019999999552965164 208 | Head Length: 0.019999999552965164 209 | Length: 0.30000001192092896 210 | Line Style: Lines 211 | Line Width: 0.029999999329447746 212 | Name: Path 213 | Offset: 214 | X: 0 215 | Y: 0 216 | Z: 0 217 | Pose Color: 255; 85; 255 218 | Pose Style: Arrows 219 | Radius: 0.029999999329447746 220 | Shaft Diameter: 0.004999999888241291 221 | Shaft Length: 0.019999999552965164 222 | Topic: 223 | Depth: 5 224 | Durability Policy: Volatile 225 | History Policy: Keep Last 226 | Reliability Policy: Reliable 227 | Value: /plan 228 | Value: true 229 | - Alpha: 1 230 | Class: rviz_default_plugins/Polygon 231 | Color: 25; 255; 0 232 | Enabled: false 233 | Name: Polygon 234 | Topic: 235 | Depth: 5 236 | Durability Policy: Volatile 237 | History Policy: Keep Last 238 | Reliability Policy: Reliable 239 | Value: /global_costmap/published_footprint 240 | Value: false 241 | Enabled: true 242 | Name: Global Planner 243 | - Class: rviz_common/Group 244 | Displays: 245 | - Alpha: 0.699999988079071 246 | Class: rviz_default_plugins/Map 247 | Color Scheme: costmap 248 | Draw Behind: false 249 | Enabled: true 250 | Name: Local Costmap 251 | Topic: 252 | Depth: 1 253 | Durability Policy: Transient Local 254 | History Policy: Keep Last 255 | Reliability Policy: Reliable 256 | Value: /local_costmap/costmap 257 | Use Timestamp: false 258 | Value: true 259 | - Alpha: 1 260 | Buffer Length: 1 261 | Class: rviz_default_plugins/Path 262 | Color: 0; 12; 255 263 | Enabled: true 264 | Head Diameter: 0.30000001192092896 265 | Head Length: 0.20000000298023224 266 | Length: 0.30000001192092896 267 | Line Style: Lines 268 | Line Width: 0.029999999329447746 269 | Name: Local Plan 270 | Offset: 271 | X: 0 272 | Y: 0 273 | Z: 0 274 | Pose Color: 255; 85; 255 275 | Pose Style: None 276 | Radius: 0.029999999329447746 277 | Shaft Diameter: 0.10000000149011612 278 | Shaft Length: 0.10000000149011612 279 | Topic: 280 | Depth: 5 281 | Durability Policy: Volatile 282 | History Policy: Keep Last 283 | Reliability Policy: Reliable 284 | Value: /local_plan 285 | Value: true 286 | - Class: rviz_default_plugins/MarkerArray 287 | Enabled: false 288 | Name: Trajectories 289 | Namespaces: 290 | {} 291 | Topic: 292 | Depth: 5 293 | Durability Policy: Volatile 294 | History Policy: Keep Last 295 | Reliability Policy: Reliable 296 | Value: /marker 297 | Value: false 298 | - Alpha: 1 299 | Class: rviz_default_plugins/Polygon 300 | Color: 25; 255; 0 301 | Enabled: true 302 | Name: Polygon 303 | Topic: 304 | Depth: 5 305 | Durability Policy: Volatile 306 | History Policy: Keep Last 307 | Reliability Policy: Reliable 308 | Value: /local_costmap/published_footprint 309 | Value: true 310 | Enabled: true 311 | Name: Controller 312 | Enabled: true 313 | Global Options: 314 | Background Color: 48; 48; 48 315 | Fixed Frame: map 316 | Frame Rate: 30 317 | Name: root 318 | Tools: 319 | - Class: rviz_default_plugins/MoveCamera 320 | - Class: rviz_default_plugins/Select 321 | - Class: rviz_default_plugins/FocusCamera 322 | - Class: rviz_default_plugins/Measure 323 | Line color: 128; 128; 0 324 | - Class: rviz_default_plugins/SetInitialPose 325 | Topic: 326 | Depth: 5 327 | Durability Policy: Volatile 328 | History Policy: Keep Last 329 | Reliability Policy: Reliable 330 | Value: /initialpose 331 | - Class: nav2_rviz_plugins/GoalTool 332 | Transformation: 333 | Current: 334 | Class: rviz_default_plugins/TF 335 | Value: true 336 | Views: 337 | Current: 338 | Angle: -1.5700000524520874 339 | Class: rviz_default_plugins/TopDownOrtho 340 | Enable Stereo Rendering: 341 | Stereo Eye Separation: 0.05999999865889549 342 | Stereo Focal Distance: 1 343 | Swap Stereo Eyes: false 344 | Value: false 345 | Invert Z Axis: false 346 | Name: Current View 347 | Near Clip Distance: 0.009999999776482582 348 | Scale: 134.638427734375 349 | Target Frame: 350 | Value: TopDownOrtho (rviz_default_plugins) 351 | X: -0.032615214586257935 352 | Y: -0.0801941454410553 353 | Saved: ~ 354 | Window Geometry: 355 | Displays: 356 | collapsed: false 357 | Height: 914 358 | Hide Left Dock: false 359 | Hide Right Dock: true 360 | Navigation 2: 361 | collapsed: false 362 | QMainWindow State: 000000ff00000000fd00000004000000000000016a00000338fc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000002c4000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb00000018004e0061007600690067006100740069006f006e0020003201000003070000006e0000006200ffffff000000010000010f00000338fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d00000338000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d00650100000000000004500000000000000000000004990000033800000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 363 | Selection: 364 | collapsed: false 365 | Tool Properties: 366 | collapsed: false 367 | Views: 368 | collapsed: true 369 | Width: 1545 370 | X: 186 371 | Y: 117 372 | -------------------------------------------------------------------------------- /neuronbot2_slam/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(neuronbot2_slam) 3 | 4 | # Default to C99 5 | if(NOT CMAKE_C_STANDARD) 6 | set(CMAKE_C_STANDARD 99) 7 | endif() 8 | 9 | # Default to C++14 10 | if(NOT CMAKE_CXX_STANDARD) 11 | set(CMAKE_CXX_STANDARD 14) 12 | endif() 13 | 14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 15 | add_compile_options(-Wall -Wextra -Wpedantic) 16 | endif() 17 | 18 | # find dependencies 19 | find_package(ament_cmake REQUIRED) 20 | #find_package(cartographer_ros REQUIRED) 21 | 22 | if(BUILD_TESTING) 23 | find_package(ament_lint_auto REQUIRED) 24 | # the following line skips the linter which checks for copyrights 25 | # uncomment the line when a copyright and license is not present in all source files 26 | #set(ament_cmake_copyright_FOUND TRUE) 27 | # the following line skips cpplint (only works in a git repo) 28 | # uncomment the line when this package is not in a git repo 29 | #set(ament_cmake_cpplint_FOUND TRUE) 30 | ament_lint_auto_find_test_dependencies() 31 | endif() 32 | 33 | ################################################################################ 34 | # Install 35 | ################################################################################ 36 | install( 37 | DIRECTORY config launch rviz 38 | DESTINATION share/${PROJECT_NAME} 39 | ) 40 | 41 | ament_package() 42 | -------------------------------------------------------------------------------- /neuronbot2_slam/README.md: -------------------------------------------------------------------------------- 1 | This package is under construction with ROS-Foxy... 2 | -------------------------------------------------------------------------------- /neuronbot2_slam/config/cartographer.lua: -------------------------------------------------------------------------------- 1 | include "map_builder.lua" 2 | include "trajectory_builder.lua" 3 | 4 | options = { 5 | map_builder = MAP_BUILDER, 6 | trajectory_builder = TRAJECTORY_BUILDER, 7 | map_frame = "map", 8 | tracking_frame = "base_link", -- "imu_link", 9 | published_frame = "odom", -- "odom", 10 | odom_frame = "odom", -- "odom", 11 | provide_odom_frame = false, 12 | publish_frame_projected_to_2d = true, 13 | use_odometry = true, 14 | use_nav_sat = false, 15 | use_landmarks = false, 16 | num_laser_scans = 1, 17 | num_multi_echo_laser_scans = 0, 18 | num_subdivisions_per_laser_scan = 1, 19 | num_point_clouds = 0, 20 | lookup_transform_timeout_sec = 0.2, 21 | submap_publish_period_sec = 0.3, 22 | pose_publish_period_sec = 5e-3, 23 | trajectory_publish_period_sec = 30e-3, 24 | rangefinder_sampling_ratio = 1., 25 | odometry_sampling_ratio = 0.1, 26 | fixed_frame_pose_sampling_ratio = 1., 27 | imu_sampling_ratio = 1., 28 | landmarks_sampling_ratio = 1., 29 | } 30 | 31 | MAP_BUILDER.use_trajectory_builder_2d = true 32 | 33 | TRAJECTORY_BUILDER_2D.min_range = 0.15 34 | TRAJECTORY_BUILDER_2D.max_range = 5.0 35 | TRAJECTORY_BUILDER_2D.missing_data_ray_length = 3. 36 | TRAJECTORY_BUILDER_2D.use_imu_data = false 37 | TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true 38 | TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1) 39 | -- TEST 40 | TRAJECTORY_BUILDER_2D.ceres_scan_matcher.translation_weight = 2e2 41 | TRAJECTORY_BUILDER_2D.ceres_scan_matcher.ceres_solver_options.max_num_iterations = 20 42 | TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 1 43 | TRAJECTORY_BUILDER_2D.voxel_filter_size = 0.05 44 | TRAJECTORY_BUILDER_2D.submaps.num_range_data = 45 45 | MAP_BUILDER.num_background_threads = 4 46 | 47 | -- TEST 48 | POSE_GRAPH.constraint_builder.min_score = 0.65 49 | POSE_GRAPH.constraint_builder.global_localization_min_score = 0.7 50 | POSE_GRAPH.global_sampling_ratio = 0.001 51 | POSE_GRAPH.constraint_builder.sampling_ratio = 0.001 52 | 53 | POSE_GRAPH.optimize_every_n_nodes = 50 54 | 55 | 56 | return options 57 | -------------------------------------------------------------------------------- /neuronbot2_slam/config/cartographer_bag.lua: -------------------------------------------------------------------------------- 1 | include "map_builder.lua" 2 | include "trajectory_builder.lua" 3 | 4 | options = { 5 | map_builder = MAP_BUILDER, 6 | trajectory_builder = TRAJECTORY_BUILDER, 7 | map_frame = "map", 8 | tracking_frame = "imu_link", -- "imu_link", 9 | published_frame = "odom", -- "odom", 10 | odom_frame = "odom", -- "odom", 11 | provide_odom_frame = false, 12 | publish_frame_projected_to_2d = true, 13 | use_odometry = true, 14 | use_nav_sat = false, 15 | use_landmarks = false, 16 | num_laser_scans = 1, 17 | num_multi_echo_laser_scans = 0, 18 | num_subdivisions_per_laser_scan = 1, 19 | num_point_clouds = 0, 20 | lookup_transform_timeout_sec = 0.2, 21 | submap_publish_period_sec = 0.1, 22 | pose_publish_period_sec = 5e-3, 23 | trajectory_publish_period_sec = 30e-3, 24 | rangefinder_sampling_ratio = 1., 25 | odometry_sampling_ratio = 1., 26 | fixed_frame_pose_sampling_ratio = 1., 27 | imu_sampling_ratio = 1., 28 | landmarks_sampling_ratio = 1., 29 | } 30 | 31 | MAP_BUILDER.use_trajectory_builder_2d = true 32 | 33 | TRAJECTORY_BUILDER_2D.min_range = 0.15 34 | TRAJECTORY_BUILDER_2D.max_range = 3.0 35 | TRAJECTORY_BUILDER_2D.missing_data_ray_length = 3. 36 | TRAJECTORY_BUILDER_2D.use_imu_data = false 37 | TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = true 38 | TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = math.rad(0.1) 39 | -- TEST 40 | TRAJECTORY_BUILDER_2D.ceres_scan_matcher.translation_weight = 0.01 --2e2 41 | TRAJECTORY_BUILDER_2D.ceres_scan_matcher.ceres_solver_options.max_num_iterations = 20 42 | TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 1 43 | TRAJECTORY_BUILDER_2D.voxel_filter_size = 0.05 44 | TRAJECTORY_BUILDER_2D.submaps.num_range_data = 45 45 | MAP_BUILDER.num_background_threads = 4 46 | 47 | -- TEST 48 | POSE_GRAPH.constraint_builder.min_score = 0.65 49 | POSE_GRAPH.constraint_builder.global_localization_min_score = 0.7 50 | POSE_GRAPH.global_sampling_ratio = 0.001 51 | POSE_GRAPH.constraint_builder.sampling_ratio = 0.001 52 | 53 | POSE_GRAPH.optimize_every_n_nodes = 10 54 | 55 | 56 | return options 57 | -------------------------------------------------------------------------------- /neuronbot2_slam/config/slam_toolbox_params.yaml: -------------------------------------------------------------------------------- 1 | slam_toolbox: 2 | ros__parameters: 3 | 4 | # Plugin params 5 | solver_plugin: solver_plugins::CeresSolver # solver_plugins::G2oSolver, solver_plugins::SpaSolver, solver_plugins::CeresSolver 6 | ceres_linear_solver: SPARSE_NORMAL_CHOLESKY # ITERATIVE_SCHUR, SPARSE_SCHUR, SPARSE_NORMAL_CHOLESKY 7 | ceres_preconditioner: JACOBI # IDENTITY, JACOBI, SCHUR_JACOBI 8 | ceres_trust_strategy: DOGLEG # LEVENBERG_MARQUARDT, DOGLEG 9 | ceres_dogleg_type: SUBSPACE_DOGLEG # TRADITIONAL_DOGLEG, SUBSPACE_DOGLEG 10 | ceres_loss_function: HuberLoss # None, HuberLoss, CauchyLoss 11 | 12 | # ROS Parameters 13 | odom_frame: odom 14 | map_frame: map 15 | base_frame: base_footprint 16 | scan_topic: /scan 17 | mode: mapping # mapping, localization 18 | 19 | # if you'd like to immediately start continuing a map at a given pose 20 | # or at the dock, but they are mutually exclusive, if pose is given 21 | # will use pose 22 | #map_file_name: test_steve 23 | # map_start_pose: [0.0, 0.0, 0.0] 24 | #map_start_at_dock: true 25 | 26 | debug_logging: false 27 | throttle_scans: 1 28 | transform_publish_period: 0.01 #if 0 never publishes odometry 29 | map_update_interval: 1.0 30 | resolution: 0.04 31 | max_laser_range: 10.0 #for rastering images 32 | minimum_time_interval: 0.01 33 | transform_timeout: 0.1 34 | tf_buffer_duration: 10.0 35 | stack_size_to_use: 40000000 #// program needs a larger stack size to serialize large maps 36 | enable_interactive_mode: true 37 | 38 | # General Parameters 39 | use_scan_matching: true 40 | use_scan_barycenter: true 41 | minimum_travel_distance: 0.2 42 | minimum_travel_heading: 0.2 43 | scan_buffer_size: 25 44 | scan_buffer_maximum_scan_distance: 5.0 45 | link_match_minimum_response_fine: 0.1 46 | link_scan_maximum_distance: 0.5 47 | loop_search_maximum_distance: 3.0 48 | do_loop_closing: true 49 | loop_match_minimum_chain_size: 10 50 | loop_match_maximum_variance_coarse: 3.0 51 | loop_match_minimum_response_coarse: 0.35 52 | loop_match_minimum_response_fine: 0.45 53 | 54 | # Correlation Parameters - Correlation Parameters 55 | correlation_search_space_dimension: 2.7 56 | correlation_search_space_resolution: 0.0125 57 | correlation_search_space_smear_deviation: 0.01 58 | 59 | # Correlation Parameters - Loop Closure Parameters 60 | loop_search_space_dimension: 8.0 61 | loop_search_space_resolution: 0.05 62 | loop_search_space_smear_deviation: 0.03 63 | 64 | # Scan Matcher Parameters 65 | distance_variance_penalty: 0.5 66 | angle_variance_penalty: 0.01 67 | 68 | fine_search_angle_offset: 0.00349 69 | coarse_search_angle_offset: 0.349 70 | coarse_angle_resolution: 0.0349 71 | minimum_angle_penalty: 0.01 72 | minimum_distance_penalty: 0.5 73 | use_response_expansion: true 74 | -------------------------------------------------------------------------------- /neuronbot2_slam/launch/cartographer_launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | from ament_index_python.packages import get_package_share_directory 3 | from launch import LaunchDescription 4 | from launch.actions import SetEnvironmentVariable 5 | from launch_ros.actions import Node 6 | from launch.substitutions import LaunchConfiguration 7 | from launch.actions import DeclareLaunchArgument 8 | from launch.conditions import IfCondition 9 | 10 | 11 | def generate_launch_description(): 12 | use_sim_time = LaunchConfiguration('use_sim_time', default='False') 13 | cartographer_config_dir = LaunchConfiguration('cartographer_config_dir', 14 | default=os.path.join(get_package_share_directory('neuronbot2_slam') , 'config')) 15 | configuration_basename = LaunchConfiguration('configuration_basename', default='cartographer.lua') 16 | resolution = LaunchConfiguration('resolution', default='0.05') 17 | publish_period_sec = LaunchConfiguration('publish_period_sec', default='0.5') 18 | rviz_config_dir = os.path.join(get_package_share_directory('neuronbot2_slam'), 'rviz', 'slam.rviz') 19 | 20 | 21 | return LaunchDescription([ 22 | DeclareLaunchArgument( 23 | 'open_rviz', 24 | default_value='false', 25 | description='open rviz'), 26 | 27 | DeclareLaunchArgument( 28 | 'cartographer_config_dir', 29 | default_value=cartographer_config_dir, 30 | description='Full path to config file to load'), 31 | DeclareLaunchArgument( 32 | 'configuration_basename', 33 | default_value=configuration_basename, 34 | description='Name of lua file for cartographer'), 35 | DeclareLaunchArgument( 36 | 'use_sim_time', 37 | default_value='false', 38 | description='Use simulation (Gazebo) clock if true'), 39 | DeclareLaunchArgument( 40 | 'resolution', 41 | default_value=resolution, 42 | description='Resolution of a grid cell in the published occupancy grid'), 43 | DeclareLaunchArgument( 44 | 'publish_period_sec', 45 | default_value=publish_period_sec, 46 | description='OccupancyGrid publishing period'), 47 | 48 | 49 | Node( 50 | package='cartographer_ros', 51 | executable='cartographer_node', 52 | name='cartographer_node', 53 | output='screen', 54 | parameters=[{'use_sim_time': use_sim_time}], 55 | arguments=[ 56 | '-configuration_directory', cartographer_config_dir, 57 | '-configuration_basename', configuration_basename]), 58 | 59 | Node( 60 | package='cartographer_ros', 61 | executable='occupancy_grid_node', 62 | name='occupancy_grid_node', 63 | output='screen', 64 | parameters=[{'use_sim_time': use_sim_time}], 65 | arguments=['-resolution', resolution, '-publish_period_sec', publish_period_sec]), 66 | 67 | Node( 68 | package='rviz2', 69 | executable='rviz2', 70 | name='rviz2', 71 | arguments=['-d', rviz_config_dir], 72 | parameters=[{'use_sim_time': use_sim_time}], 73 | condition=IfCondition(LaunchConfiguration("open_rviz")), 74 | output='screen'), 75 | ]) 76 | -------------------------------------------------------------------------------- /neuronbot2_slam/launch/gmapping_launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | from ament_index_python.packages import get_package_share_directory 3 | from launch import LaunchDescription 4 | import launch_ros.actions 5 | from launch.actions import DeclareLaunchArgument 6 | from launch.substitutions import LaunchConfiguration 7 | from launch_ros.actions import Node 8 | from launch.conditions import IfCondition 9 | 10 | def generate_launch_description(): 11 | 12 | use_sim_time = LaunchConfiguration('use_sim_time', default='false') 13 | 14 | rviz_config_dir = os.path.join( 15 | get_package_share_directory('neuronbot2_slam'), 16 | 'rviz', 17 | 'slam.rviz') 18 | 19 | remappings = [('/tf', 'tf'), 20 | ('/tf_static', 'tf_static')] 21 | 22 | param_substitutions = { 23 | 'use_sim_time': use_sim_time, 24 | 'scan_topic': 'scan', 25 | 'base_frame': 'base_link', 26 | 'odom_frame': 'odom', 27 | 'map_frame': 'map', 28 | 'map_update_interval': 3.0, 29 | 'maxUrange': 10.0, 30 | 'sigma': 0.05, 31 | 'kernelSize': 1, 32 | 'lstep': 0.05, 33 | 'astep': 0.05, 34 | 'iterations': 5, 35 | 'lsigma': 0.075, 36 | 'ogain': 3.0, 37 | 'lskip': 0, 38 | 'srr': 0.1, 39 | 'srt': 0.2, 40 | 'str': 0.1, 41 | 'stt': 0.2, 42 | 'linearUpdate': 0.3, 43 | 'angularUpdate': 3.14, 44 | 'temporalUpdate': 5.0, 45 | 'resampleThreshold': 0.5, 46 | 'particles': 30, 47 | 'xmin': -15.0, 48 | 'ymin': -15.0, 49 | 'xmax': 15.0, 50 | 'ymax': 15.0, 51 | 'delta': 0.025, 52 | 'llsamplerange': 0.01, 53 | 'llsamplestep': 0.01, 54 | 'lasamplerange': 0.005, 55 | 'lasamplestep': 0.005, 56 | } 57 | return LaunchDescription([ 58 | DeclareLaunchArgument( 59 | 'open_rviz', 60 | default_value='false', 61 | description='open rviz'), 62 | 63 | launch_ros.actions.Node( 64 | package='slam_gmapping', 65 | executable='slam_gmapping', 66 | parameters=[param_substitutions], 67 | output='screen'), 68 | 69 | Node( 70 | package='rviz2', 71 | executable='rviz2', 72 | name='rviz2', 73 | arguments=['-d', rviz_config_dir], 74 | parameters=[{'use_sim_time': use_sim_time}], 75 | condition=IfCondition(LaunchConfiguration("open_rviz")), 76 | remappings=remappings 77 | ), 78 | ]) 79 | -------------------------------------------------------------------------------- /neuronbot2_slam/launch/slam_toolbox_launch.py: -------------------------------------------------------------------------------- 1 | import os 2 | from ament_index_python.packages import get_package_share_directory 3 | from launch import LaunchDescription 4 | from launch.actions import DeclareLaunchArgument 5 | import launch_ros.actions 6 | from launch.substitutions import LaunchConfiguration 7 | from launch_ros.actions import Node 8 | from launch.conditions import IfCondition 9 | 10 | def generate_launch_description(): 11 | use_sim_time = LaunchConfiguration('use_sim_time', default='false') 12 | rviz_config_dir = os.path.join( 13 | get_package_share_directory('neuronbot2_slam'), 14 | 'rviz', 15 | 'slam.rviz') 16 | 17 | return LaunchDescription([ 18 | DeclareLaunchArgument( 19 | 'open_rviz', 20 | default_value='false', 21 | description='open rviz'), 22 | 23 | launch_ros.actions.Node( 24 | parameters=[ 25 | {get_package_share_directory("neuronbot2_slam") + '/config/slam_toolbox_params.yaml'}, 26 | {'use_sim_time': use_sim_time} 27 | ], 28 | package='slam_toolbox', 29 | executable='async_slam_toolbox_node', 30 | name='slam_toolbox', 31 | output='screen' 32 | ), 33 | 34 | Node( 35 | package='rviz2', 36 | executable='rviz2', 37 | name='rviz2', 38 | arguments=['-d', rviz_config_dir], 39 | parameters=[{'use_sim_time': use_sim_time}], 40 | condition=IfCondition(LaunchConfiguration("open_rviz")) 41 | ), 42 | 43 | ]) 44 | -------------------------------------------------------------------------------- /neuronbot2_slam/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | neuronbot2_slam 5 | 0.1.0 6 | SLAM package for NeuronBot2 on ROS2 7 | airuchen 8 | Apache 2.0 9 | 10 | ament_cmake 11 | 12 | cartographer_ros 13 | slam_toolbox 14 | 15 | ament_lint_auto 16 | ament_lint_common 17 | 18 | 19 | ament_cmake 20 | 21 | 22 | -------------------------------------------------------------------------------- /neuronbot2_slam/rviz/slam.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz_common/Displays 3 | Help Height: 78 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: 7 | - /Global Options1 8 | - /TF1/Frames1 9 | - /LaserScan1/Topic1 10 | - /SLAM1 11 | - /RobotModel1/Description Topic1 12 | Splitter Ratio: 0.5794117450714111 13 | Tree Height: 787 14 | - Class: rviz_common/Selection 15 | Name: Selection 16 | - Class: rviz_common/Tool Properties 17 | Expanded: 18 | - /Publish Point1 19 | - /2D Pose Estimate1 20 | Name: Tool Properties 21 | Splitter Ratio: 0.5886790156364441 22 | - Class: rviz_common/Views 23 | Expanded: 24 | - /Current View1 25 | Name: Views 26 | Splitter Ratio: 0.5 27 | Visualization Manager: 28 | Class: "" 29 | Displays: 30 | - Alpha: 0.5 31 | Cell Size: 1 32 | Class: rviz_default_plugins/Grid 33 | Color: 160; 160; 164 34 | Enabled: true 35 | Line Style: 36 | Line Width: 0.029999999329447746 37 | Value: Lines 38 | Name: Grid 39 | Normal Cell Count: 0 40 | Offset: 41 | X: 0 42 | Y: 0 43 | Z: 0 44 | Plane: XY 45 | Plane Cell Count: 10 46 | Reference Frame: 47 | Value: true 48 | - Class: rviz_default_plugins/TF 49 | Enabled: true 50 | Frame Timeout: 15 51 | Frames: 52 | All Enabled: false 53 | base_footprint: 54 | Value: false 55 | base_link: 56 | Value: true 57 | imu_link: 58 | Value: false 59 | laser_frame: 60 | Value: false 61 | map: 62 | Value: true 63 | odom: 64 | Value: true 65 | wheel_left_link: 66 | Value: true 67 | wheel_right_link: 68 | Value: true 69 | Marker Scale: 1 70 | Name: TF 71 | Show Arrows: true 72 | Show Axes: true 73 | Show Names: true 74 | Tree: 75 | map: 76 | odom: 77 | base_footprint: 78 | base_link: 79 | imu_link: 80 | {} 81 | laser_frame: 82 | {} 83 | wheel_left_link: 84 | {} 85 | wheel_right_link: 86 | {} 87 | Update Interval: 0 88 | Value: true 89 | - Alpha: 1 90 | Autocompute Intensity Bounds: true 91 | Autocompute Value Bounds: 92 | Max Value: 10 93 | Min Value: -10 94 | Value: true 95 | Axis: Z 96 | Channel Name: intensity 97 | Class: rviz_default_plugins/LaserScan 98 | Color: 255; 255; 255 99 | Color Transformer: Intensity 100 | Decay Time: 0 101 | Enabled: true 102 | Invert Rainbow: false 103 | Max Color: 255; 255; 255 104 | Max Intensity: 0 105 | Min Color: 0; 0; 0 106 | Min Intensity: 0 107 | Name: LaserScan 108 | Position Transformer: XYZ 109 | Selectable: true 110 | Size (Pixels): 3 111 | Size (m): 0.019999999552965164 112 | Style: Flat Squares 113 | Topic: 114 | Depth: 5 115 | Durability Policy: Volatile 116 | Filter size: 10 117 | History Policy: Keep Last 118 | Reliability Policy: Best Effort 119 | Value: /scan 120 | Use Fixed Frame: true 121 | Use rainbow: true 122 | Value: true 123 | - Alpha: 0.699999988079071 124 | Class: rviz_default_plugins/Map 125 | Color Scheme: map 126 | Draw Behind: false 127 | Enabled: true 128 | Name: Map 129 | Topic: 130 | Depth: 5 131 | Durability Policy: Volatile 132 | Filter size: 10 133 | History Policy: Keep Last 134 | Reliability Policy: Reliable 135 | Value: /map 136 | Update Topic: 137 | Depth: 5 138 | Durability Policy: Volatile 139 | History Policy: Keep Last 140 | Reliability Policy: Reliable 141 | Value: /map_updates 142 | Use Timestamp: false 143 | Value: true 144 | - Class: rviz_common/Group 145 | Displays: 146 | - Alpha: 1 147 | Autocompute Intensity Bounds: true 148 | Autocompute Value Bounds: 149 | Max Value: 0.18203988671302795 150 | Min Value: 0.18195410072803497 151 | Value: true 152 | Axis: Z 153 | Channel Name: intensity 154 | Class: rviz_default_plugins/PointCloud2 155 | Color: 0; 255; 0 156 | Color Transformer: FlatColor 157 | Decay Time: 0 158 | Enabled: true 159 | Invert Rainbow: false 160 | Max Color: 255; 255; 255 161 | Max Intensity: 4096 162 | Min Color: 0; 0; 0 163 | Min Intensity: 0 164 | Name: scan_matched_points2 165 | Position Transformer: XYZ 166 | Selectable: true 167 | Size (Pixels): 3 168 | Size (m): 0.009999999776482582 169 | Style: Points 170 | Topic: 171 | Depth: 5 172 | Durability Policy: Volatile 173 | Filter size: 10 174 | History Policy: Keep Last 175 | Reliability Policy: Reliable 176 | Value: /scan_matched_points2 177 | Use Fixed Frame: true 178 | Use rainbow: true 179 | Value: true 180 | Enabled: false 181 | Name: SLAM 182 | - Alpha: 1 183 | Class: rviz_default_plugins/RobotModel 184 | Collision Enabled: false 185 | Description File: "" 186 | Description Source: Topic 187 | Description Topic: 188 | Depth: 5 189 | Durability Policy: Volatile 190 | History Policy: Keep Last 191 | Reliability Policy: Reliable 192 | Value: /robot_description 193 | Enabled: true 194 | Links: 195 | All Links Enabled: true 196 | Expand Joint Details: false 197 | Expand Link Details: false 198 | Expand Tree: false 199 | Link Tree Style: Links in Alphabetic Order 200 | base_footprint: 201 | Alpha: 1 202 | Show Axes: false 203 | Show Trail: false 204 | base_link: 205 | Alpha: 1 206 | Show Axes: false 207 | Show Trail: false 208 | Value: true 209 | imu_link: 210 | Alpha: 1 211 | Show Axes: false 212 | Show Trail: false 213 | laser_frame: 214 | Alpha: 1 215 | Show Axes: false 216 | Show Trail: false 217 | Value: true 218 | wheel_left_link: 219 | Alpha: 1 220 | Show Axes: false 221 | Show Trail: false 222 | Value: true 223 | wheel_right_link: 224 | Alpha: 1 225 | Show Axes: false 226 | Show Trail: false 227 | Value: true 228 | Mass Properties: 229 | Inertia: false 230 | Mass: false 231 | Name: RobotModel 232 | TF Prefix: "" 233 | Update Interval: 0 234 | Value: true 235 | Visual Enabled: true 236 | Enabled: true 237 | Global Options: 238 | Background Color: 48; 48; 48 239 | Fixed Frame: map 240 | Frame Rate: 30 241 | Name: root 242 | Tools: 243 | - Class: rviz_default_plugins/MoveCamera 244 | - Class: rviz_default_plugins/Select 245 | - Class: rviz_default_plugins/FocusCamera 246 | - Class: rviz_default_plugins/Measure 247 | Line color: 128; 128; 0 248 | - Class: rviz_default_plugins/SetGoal 249 | Topic: 250 | Depth: 5 251 | Durability Policy: Volatile 252 | History Policy: Keep Last 253 | Reliability Policy: Reliable 254 | Value: /move_base_simple/goal 255 | - Class: rviz_default_plugins/PublishPoint 256 | Single click: true 257 | Topic: 258 | Depth: 5 259 | Durability Policy: Volatile 260 | History Policy: Keep Last 261 | Reliability Policy: Reliable 262 | Value: /clicked_point 263 | - Class: rviz_default_plugins/SetInitialPose 264 | Covariance x: 0.25 265 | Covariance y: 0.25 266 | Covariance yaw: 0.06853891909122467 267 | Topic: 268 | Depth: 5 269 | Durability Policy: Volatile 270 | History Policy: Keep Last 271 | Reliability Policy: Reliable 272 | Value: initialpose 273 | Transformation: 274 | Current: 275 | Class: rviz_default_plugins/TF 276 | Value: true 277 | Views: 278 | Current: 279 | Angle: -1.5700000524520874 280 | Class: rviz_default_plugins/TopDownOrtho 281 | Enable Stereo Rendering: 282 | Stereo Eye Separation: 0.05999999865889549 283 | Stereo Focal Distance: 1 284 | Swap Stereo Eyes: false 285 | Value: false 286 | Invert Z Axis: false 287 | Name: Current View 288 | Near Clip Distance: 0.009999999776482582 289 | Scale: 78.41960144042969 290 | Target Frame: 291 | Value: TopDownOrtho (rviz_default_plugins) 292 | X: 2.0269784927368164 293 | Y: -0.391719788312912 294 | Saved: ~ 295 | Window Geometry: 296 | Displays: 297 | collapsed: false 298 | Height: 1016 299 | Hide Left Dock: false 300 | Hide Right Dock: false 301 | QMainWindow State: 000000ff00000000fd0000000400000000000001560000039efc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d0000039e000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d0061006700650100000375000000160000000000000000000000010000010f0000039efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000003d0000039e000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d00650100000000000004500000000000000000000004cf0000039e00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 302 | Selection: 303 | collapsed: false 304 | Tool Properties: 305 | collapsed: false 306 | Views: 307 | collapsed: false 308 | Width: 1856 309 | X: 64 310 | Y: 27 311 | -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_init/neuronbot2_init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # udev for NeuronBot2 TTY 4 | echo 'KERNEL=="ttyUSB*", KERNELS!="1-5", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", GROUP:="dialout", SYMLINK+="neuronbot2"' > /etc/udev/rules.d/neuronbot2.rules 5 | status=$? 6 | if [ $status -eq 0 ] 7 | then 8 | echo "Initialized NeuronBot successfully" 9 | else 10 | echo "Failed to initialize NeuronBot!" 11 | exit 1 12 | fi 13 | 14 | # udev for Arduino LED type 1 & 2 15 | echo 'KERNEL=="ttyUSB*", KERNELS=="1-5", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE:="0666", GROUP:="dialout", SYMLINK+="neuronbotLED"' > /etc/udev/rules.d/neuronbotLED.rules 16 | echo 'KERNEL=="ttyUSB*", KERNELS=="1-5", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", GROUP:="dialout", SYMLINK+="neuronbotLED"' >> /etc/udev/rules.d/neuronbotLED.rules 17 | status=$? 18 | if [ $status -eq 0 ] 19 | then 20 | echo "Initialized LED controller successfully" 21 | else 22 | echo "Failed to initialize LED controller!" 23 | exit 1 24 | fi 25 | 26 | # udev for RPLidar 27 | echo 'KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="0777", SYMLINK+="rplidar"' > /etc/udev/rules.d/rplidar.rules 28 | status=$? 29 | if [ $status -eq 0 ] 30 | then 31 | echo "Initialized RPLidar successfully" 32 | else 33 | echo "Failed to initialize RPLidar!" 34 | exit 1 35 | fi 36 | 37 | # Trgiier udev 38 | sudo udevadm control --reload 39 | sudo udevadm trigger 40 | status=$? 41 | if [ $status -eq 0 ] 42 | then 43 | echo "Udev restarted successfully." 44 | else 45 | echo "Failed to restart udev!" 46 | exit 1 47 | fi 48 | -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/README.md: -------------------------------------------------------------------------------- 1 | # NeuronBot2_LED 2 | 3 | ### Dependency 4 | ```sh 5 | pip install pyserial 6 | 7 | # if pip not found, use pip3 instead 8 | pip3 install pyserial 9 | ``` 10 | 11 | ### LED Example 12 | 13 | ```sh 14 | cd /src/neuronbot2/neuronbot2_tools/neuronbot2_led/neuronbot2_led 15 | ./led_control.py --port /dev/neuronbotLED --mode 6 16 | ``` 17 | 18 | You can look into `led_control.py` to see what else functions you can use to write your own program. 19 | Currently, we have implemented 10 modes listed as below code snippets: 20 | 21 | ```python 22 | if mode == 0: 23 | s.mode_clear(num) 24 | if mode == 1: 25 | s.mode_white(num) 26 | if mode == 2: 27 | s.mode_amber(num) 28 | if mode == 3: 29 | s.mode_red(num) 30 | if mode == 4: 31 | s.mode_green(num) 32 | if mode == 5: 33 | s.mode_blue(num) 34 | if mode == 6: 35 | s.mode_rainbow(num) 36 | if mode == 7: 37 | s.breath() 38 | if mode == 8: 39 | s.forward(num) 40 | s.backward(num) 41 | if mode == 9: 42 | s.blink_red() 43 | ``` 44 | 45 | ### Arduino Sketch 46 | 47 | NeuronBot2 LED relies on **Adafruit NeoPixel** library of Arduino. If you are interested in modifying the Arduino sketch, you can get and build LED (Arduino) source code from this GitHub repo: https://github.com/Adlink-ROS/neuronbot2_led 48 | -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/launch/led_control_launch.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from ament_index_python.packages import get_package_share_directory, get_resource, get_package_prefix 3 | from launch import LaunchDescription 4 | from launch.actions import ExecuteProcess 5 | 6 | def generate_launch_description(): 7 | 8 | ld = LaunchDescription() 9 | 10 | led_cmd = Path(get_package_prefix('neuronbot2_led'), 'lib', 'neuronbot2_led', 'led_control') 11 | 12 | led_process = ExecuteProcess(cmd=[str(led_cmd), '--port', '/dev/neuronbotLED', '--mode', '5', '--loop']) 13 | 14 | ld.add_action(led_process) 15 | 16 | return ld 17 | -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/neuronbot2_led/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_tools/neuronbot2_led/neuronbot2_led/__init__.py -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/neuronbot2_led/led_control.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import serial ## pip install pyserial 3 | import time 4 | import sys, getopt 5 | import atexit 6 | 7 | class Strip: 8 | def __init__(self, led_port, num): 9 | # led_port : port for the NeuronBot LED ttyUSB 10 | # baudrate : baud rate 11 | # num : the number of LED units 12 | baudrate=115200 13 | ser = serial.Serial(led_port, baudrate) 14 | if ser.isOpen(): 15 | self.serial=ser 16 | self.num=num 17 | a=self.serial.readline() 18 | self.read=a.decode("utf-8") 19 | print(self.read) 20 | else : 21 | print('NeuronBot LED port is not opened.') 22 | 23 | def setPixelColor(self,i,r,g,b): 24 | ## i : the serial number for a LED unit, starting from No.0 25 | ## r : the intensity of red light 26 | ## g : the intensity of green light 27 | ## b : the intensity of blue light 28 | 29 | i_bytes = bytes(str(i), encoding='utf8') 30 | self.serial.write(b'i'+i_bytes) 31 | r_bytes = bytes(str(r), encoding='utf8') 32 | self.serial.write(b'r'+r_bytes) 33 | g_bytes = bytes(str(g), encoding='utf8') 34 | self.serial.write(b'g'+g_bytes) 35 | b_bytes = bytes(str(b), encoding='utf8') 36 | self.serial.write(b'b'+b_bytes+b'\n') 37 | return 0 38 | 39 | def delay(self,delay_time): 40 | # time : minisecond (10^-3) 41 | time.sleep(delay_time*0.001) 42 | return 0 43 | 44 | def show(self): 45 | show_bytes = bytes(str("show"), encoding='utf8') 46 | self.serial.write(b'show\n') 47 | return 0 48 | 49 | def clear(self) : 50 | num=self.num 51 | for i in range(num) : 52 | self.setPixelColor(i,0,0,0) 53 | self.show() 54 | 55 | def close(self): 56 | self.serial.close() 57 | return 0 58 | 59 | 60 | def breath(self): 61 | max_valx_val=180 62 | v=0 63 | num=self.num 64 | slope=6 65 | wait=50 66 | self.clear() 67 | 68 | while v0 : 76 | v=v-slope 77 | for i in range(num): 78 | self.setPixelColor(i,v,v,v ) 79 | self.show() 80 | self.delay(wait) 81 | return 0 82 | 83 | def forward(self,number=5): 84 | # number : the number of lighting LED units 85 | max_val=180 86 | num=self.num 87 | wait=50 88 | gap=int(max_val/number) 89 | mid=int((number/2)+1) 90 | self.clear() 91 | t=int(1-mid) 92 | while t(0-mid) : 114 | for i in range(int(1+(number/2))): 115 | self.setPixelColor((t+i), (max_val-i*gap),(max_val-i*gap),0 ) 116 | self.setPixelColor((t-i), (max_val-i*gap),(max_val-i*gap),0) 117 | self.setPixelColor(t+(1+(number/2)), 0,0,0) 118 | self.show() 119 | self.delay(wait) 120 | t=t-1 121 | self.setPixelColor(0, 0,0,0) 122 | self.show() 123 | self.delay(wait) 124 | return 0 125 | 126 | def blink(self): 127 | wait=200 128 | num=self.num 129 | times=5 130 | self.clear() 131 | for t in range(times): 132 | for i in range(num): 133 | self.setPixelColor(i,50,0,50 ) 134 | self.show() 135 | self.delay(wait) 136 | self.clear() 137 | self.delay(wait) 138 | return 0 139 | 140 | def blink_red(self): 141 | wait=200 142 | num=self.num 143 | times=5 144 | self.clear() 145 | for t in range(times): 146 | for i in range(num): 147 | self.setPixelColor(i,50,0,0) 148 | self.show() 149 | self.delay(wait) 150 | self.clear() 151 | self.delay(wait) 152 | return 0 153 | 154 | def mode_clear(self, num): 155 | self.clear() 156 | self.delay(100) 157 | 158 | def mode_white(self, num): 159 | self.clear() 160 | self.delay(100) 161 | for i in range(num): 162 | self.setPixelColor(i,50,50,50) 163 | self.show() 164 | self.delay(100) 165 | 166 | def mode_amber(self, num): 167 | self.clear() 168 | self.delay(100) 169 | for i in range(num): 170 | self.setPixelColor(i,100,20,0) 171 | self.show() 172 | self.delay(100) 173 | 174 | def mode_red(self, num): 175 | self.clear() 176 | self.delay(100) 177 | for i in range(num): 178 | self.setPixelColor(i,50,0,0) 179 | self.show() 180 | self.delay(100) 181 | 182 | def mode_green(self, num): 183 | self.clear() 184 | self.delay(100) 185 | for i in range(num): 186 | self.setPixelColor(i,0,50,0) 187 | self.show() 188 | self.delay(100) 189 | 190 | def mode_blue(self, num): 191 | self.clear() 192 | self.delay(100) 193 | for i in range(num): 194 | self.setPixelColor(i,0,0,50) 195 | self.show() 196 | self.delay(100) 197 | 198 | def mode_rainbow(self, num): 199 | for j in range(256): 200 | for i in range(num): 201 | value = (i+j) & 255 202 | if value < 85: 203 | self.setPixelColor(i, value*3, 255-value*3, 0) 204 | elif value < 170: 205 | self.setPixelColor(i, 255-value*3, 0, value*3) 206 | else: 207 | self.setPixelColor(i, 0, value*3, 255-value*3) 208 | self.show() 209 | self.delay(20) 210 | 211 | def locate(self): 212 | # locate (led blinking) until receiving an interrupt signal! 213 | wait=300 214 | num=self.num 215 | self.clear() 216 | try: 217 | while (g_exit_flag is not True): 218 | for i in range(num): 219 | self.setPixelColor(i,0,0,50) 220 | self.show() 221 | self.delay(wait) 222 | self.clear() 223 | self.delay(wait) 224 | except KeyboardInterrupt: 225 | pass 226 | return 0 227 | 228 | def demo(self): 229 | self.clear() 230 | print("clear") 231 | self.delay(1000) 232 | self.setPixelColor(1,50,0,0) 233 | print("No.1 unit is red") 234 | self.show() 235 | self.delay(1000) 236 | self.setPixelColor(2,0,50,0) 237 | print("No.2 unit is green") 238 | self.show() 239 | self.delay(1000) 240 | self.setPixelColor(3,0,0,50) 241 | print("No.3 unit is blue") 242 | self.show() 243 | self.delay(1000) 244 | self.clear() 245 | print("clear") 246 | self.delay(1000) 247 | print("blink") 248 | self.blink() 249 | print("move from the end to the start") 250 | self.backward() 251 | self.delay(1000) 252 | print("move from the start to the end") 253 | self.forward() 254 | self.delay(1000) 255 | print("breath") 256 | self.breath() 257 | self.clear() 258 | self.close() 259 | print("close port") 260 | 261 | return 0 262 | 263 | def set_led(port, num, mode): 264 | s = Strip(port, num) 265 | if mode == 0: 266 | s.mode_clear(num) 267 | if mode == 1: 268 | s.mode_white(num) 269 | if mode == 2: 270 | s.mode_amber(num) 271 | if mode == 3: 272 | s.mode_red(num) 273 | if mode == 4: 274 | s.mode_green(num) 275 | if mode == 5: 276 | s.mode_blue(num) 277 | if mode == 6: 278 | s.mode_rainbow(num) 279 | if mode == 7: 280 | s.breath() 281 | if mode == 8: 282 | s.forward(num) 283 | s.backward(num) 284 | if mode == 9: 285 | s.blink_red() 286 | if mode == 10: 287 | s.locate() 288 | s.close() 289 | 290 | # restore_led works only when program exits 291 | @atexit.register 292 | def restore_led(): 293 | g_exit_flag = True 294 | port = '/dev/neuronbotLED' 295 | num = 10 296 | mode = 2 # restore to amber 297 | set_led(port, num, mode) 298 | 299 | g_exit_flag = False 300 | 301 | def main(): 302 | port = '/dev/neuronbotLED' 303 | num = 10 304 | mode = 5 305 | loop = False 306 | try: 307 | opts, args = getopt.getopt(sys.argv[1:],"hlp:n:m:",["port=", "num=", "mode=", "loop"]) 308 | except getopt.GetoptError: 309 | print ("python led_control.py -p -n -m ") 310 | sys.exit(2) 311 | for opt, arg in opts: 312 | if opt == '-h': 313 | print ("python led_control.py -p -n -m ") 314 | sys.exit() 315 | elif opt in ("-p", "--port"): 316 | port = arg 317 | elif opt in ("-n", "--num"): 318 | num = int(arg) 319 | elif opt in ("-m", "--mode"): 320 | mode = int(arg) 321 | elif opt in ("-l", "--loop"): 322 | loop = True 323 | 324 | if port=='' or num == '': 325 | print ("python led_control.py -p -n ") 326 | sys.exit() 327 | 328 | set_led(port, num, mode) 329 | 330 | try: 331 | while (loop): 332 | # loop until receiving signal interrupt 333 | time.sleep(2) 334 | except KeyboardInterrupt: 335 | pass 336 | 337 | if __name__ == "__main__": 338 | main() 339 | 340 | -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | neuronbot2_led 5 | 0.0.0 6 | TODO: Package description 7 | ros 8 | TODO: License declaration 9 | 10 | ament_copyright 11 | ament_flake8 12 | ament_pep257 13 | python3-pytest 14 | 15 | 16 | ament_python 17 | 18 | 19 | -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/resource/neuronbot2_led: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/neuronbot2_tools/neuronbot2_led/resource/neuronbot2_led -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/setup.cfg: -------------------------------------------------------------------------------- 1 | [develop] 2 | script-dir=$base/lib/neuronbot2_led 3 | [install] 4 | install-scripts=$base/lib/neuronbot2_led 5 | -------------------------------------------------------------------------------- /neuronbot2_tools/neuronbot2_led/setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from glob import glob 3 | from setuptools import setup 4 | 5 | package_name = 'neuronbot2_led' 6 | 7 | setup( 8 | name=package_name, 9 | version='1.0.0', 10 | packages=[package_name], 11 | data_files=[ 12 | ('share/ament_index/resource_index/packages', 13 | ['resource/' + package_name]), 14 | ('share/' + package_name, ['package.xml']), 15 | ('share/' + package_name, glob('launch/*launch.py')) 16 | ], 17 | install_requires=['setuptools'], 18 | zip_safe=True, 19 | maintainer='Ting Chang', 20 | maintainer_email='ting.chang@adlinktech.com', 21 | description='NeuronBot2 LED', 22 | license='Apache 2.0', 23 | entry_points={ 24 | 'console_scripts': [ 25 | 'led_control = neuronbot2_led.led_control:main' 26 | ], 27 | }, 28 | ) 29 | -------------------------------------------------------------------------------- /readme_resource/2d_nav_goal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/2d_nav_goal.png -------------------------------------------------------------------------------- /readme_resource/2d_setestimate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/2d_setestimate.png -------------------------------------------------------------------------------- /readme_resource/NueronBot2_sim.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/NueronBot2_sim.jpg -------------------------------------------------------------------------------- /readme_resource/TF_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/TF_tree.png -------------------------------------------------------------------------------- /readme_resource/basedriver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/basedriver.png -------------------------------------------------------------------------------- /readme_resource/basedriver_and_nav2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/basedriver_and_nav2.png -------------------------------------------------------------------------------- /readme_resource/basedriver_and_slamtoolbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/basedriver_and_slamtoolbox.png -------------------------------------------------------------------------------- /readme_resource/bt_navigator_setUsingDedicatedThread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/bt_navigator_setUsingDedicatedThread.png -------------------------------------------------------------------------------- /readme_resource/mememan_launch_nav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/mememan_launch_nav.png -------------------------------------------------------------------------------- /readme_resource/mememan_world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/mememan_world.png -------------------------------------------------------------------------------- /readme_resource/nav2_bt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/nav2_bt.gif -------------------------------------------------------------------------------- /readme_resource/nav2_rosgraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/nav2_rosgraph.png -------------------------------------------------------------------------------- /readme_resource/nav_estimate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/nav_estimate.gif -------------------------------------------------------------------------------- /readme_resource/nav_set_goal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/nav_set_goal.gif -------------------------------------------------------------------------------- /readme_resource/nb2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/nb2.png -------------------------------------------------------------------------------- /readme_resource/nb2_opening_re.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/nb2_opening_re.gif -------------------------------------------------------------------------------- /readme_resource/nb2_robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/nb2_robot.png -------------------------------------------------------------------------------- /readme_resource/phenix_world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/phenix_world.png -------------------------------------------------------------------------------- /readme_resource/slam_move_base_8x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/slam_move_base_8x.gif -------------------------------------------------------------------------------- /readme_resource/slam_rviz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/slam_rviz.png -------------------------------------------------------------------------------- /readme_resource/slam_teleop_8x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/slam_teleop_8x.gif -------------------------------------------------------------------------------- /readme_resource/teleop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adlink-ROS/neuronbot2/20dd836dcc266debed3114ecb37ba63eb184faa0/readme_resource/teleop.png --------------------------------------------------------------------------------