├── 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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
164 | * Phenix world
165 | ```
166 | ros2 launch neuronbot2_gazebo neuronbot2_world.launch.py world_model:=phenix_world.model
167 | ```
168 | 
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 | 
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 | 
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 | 
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 | 
246 | 2. Set Estimation
247 |
248 | Click "2D Pose Estimate", and set estimation to the approximate location of robot on the map.
249 |
250 | 
251 | 3. Set Goal
252 |
253 | Click "2D Nav Goal", and set goal to any free space on the map.
254 |
255 | 
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 | 
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
--------------------------------------------------------------------------------