├── .gitignore ├── LICENSE ├── README.md ├── ROBOT_INSTALLATION.md ├── docker ├── .cyclonedds.xml ├── .env ├── .fastrtps.xml ├── Dockerfile ├── docker-compose.yaml ├── entrypoint.sh ├── install_sensors.bash └── sim.yaml ├── docs ├── linorobot2.gif ├── linorobot2_launchfiles.png └── microcontroller_architecture.png ├── install_linorobot2.bash ├── linorobot2 ├── CMakeLists.txt └── package.xml ├── linorobot2_base ├── CMakeLists.txt ├── config │ └── ekf.yaml └── package.xml ├── linorobot2_bringup ├── CMakeLists.txt ├── config │ ├── box_laser_filter.yaml │ ├── fake_laser.yaml │ ├── joy.yaml │ └── zed_common.yaml ├── launch │ ├── bringup.launch.py │ ├── custom_robot.launch.py │ ├── default_robot.launch.py │ ├── depth.launch.py │ ├── extra.launch.py │ ├── joy_teleop.launch.py │ ├── lasers.launch.py │ └── sensors.launch.py └── package.xml ├── linorobot2_description ├── CMakeLists.txt ├── launch │ └── description.launch.py ├── package.xml ├── rviz │ └── description.rviz └── urdf │ ├── 2wd_properties.urdf.xacro │ ├── 4wd_properties.urdf.xacro │ ├── controllers │ ├── diff_drive.urdf.xacro │ ├── omni_drive.urdf.xacro │ └── skid_steer.urdf.xacro │ ├── mecanum_properties.urdf.xacro │ ├── mech │ ├── base.urdf.xacro │ ├── caster_wheel.urdf.xacro │ ├── mecanum_wheel.urdf.xacro │ └── wheel.urdf.xacro │ ├── robots │ ├── 2wd.urdf.xacro │ ├── 4wd.urdf.xacro │ ├── mecanum.urdf.xacro │ ├── turtlebot.urdf.xacro │ └── vattenkar.urdf.xacro │ └── sensors │ ├── camera.urdf.xacro │ ├── depth_sensor.urdf.xacro │ ├── generic_laser.urdf.xacro │ ├── imu.urdf.xacro │ └── laser.urdf.xacro ├── linorobot2_gazebo ├── CMakeLists.txt ├── env-hooks │ └── linorobot2_gazebo.sh.in ├── launch │ └── gazebo.launch.py ├── package.xml ├── rviz │ └── view_urdf.rviz ├── scripts │ ├── __init__.py │ ├── command_timeout.py │ └── map2gazebo.py └── worlds │ ├── gas_station.world │ └── playground.world ├── linorobot2_navigation ├── CMakeLists.txt ├── config │ ├── navigation.yaml │ ├── navigation_sim.yaml │ └── slam.yaml ├── launch │ ├── navigation.launch.py │ └── slam.launch.py ├── maps │ ├── map.pgm │ ├── map.yaml │ ├── playground.pgm │ └── playground.yaml ├── package.xml └── rviz │ ├── linorobot2_navigation.rviz │ ├── linorobot2_navigation_minimal.rviz │ └── linorobot2_slam.rviz └── update_microros.bash /.gitignore: -------------------------------------------------------------------------------- 1 | log 2 | build 3 | install -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /ROBOT_INSTALLATION.md: -------------------------------------------------------------------------------- 1 | ## Manual installation of linorobot2 package on robot computer 2 | 3 | ### 1. Install micro-ROS and its dependencies 4 | 5 | #### 1.1 Source your ROS2 distro and workspace 6 | If it's your first time using ROS2 and haven't created your ROS2 workspace yet, you can check out [ROS2 Creating a Workspace](https://docs.ros.org/en/galactic/Tutorials/Workspace/Creating-A-Workspace.html) tutorial. 7 | 8 | source /opt/ros//setup.bash 9 | cd 10 | colcon build 11 | source install/setup.bash 12 | 13 | #### 1.2 Install LIDAR ROS2 drivers: 14 | YDLIDAR: 15 | 16 | cd /tmp 17 | git clone https://github.com/YDLIDAR/YDLidar-SDK.git 18 | cd YDLidar-SDK/build 19 | cmake .. 20 | make 21 | sudo make install 22 | cd 23 | git clone https://github.com/YDLIDAR/ydlidar_ros2_driver src/ydlidar_ros2_driver 24 | chmod 0777 src/ydlidar_ros2_driver/startup/* 25 | sudo sh src/ydlidar_ros2_driver/startup/initenv.sh 26 | colcon build --symlink-install 27 | source /install/setup.bash 28 | 29 | XV11: 30 | 31 | cd 32 | git clone https://github.com/mjstn/xv_11_driver src/xv_11_driver 33 | colcon build 34 | source /install/setup.bash 35 | 36 | LD06 LD19 STL27L: 37 | 38 | cd 39 | git clone https://github.com/hippo5329/ldlidar_stl_ros2.git src/ldlidar_stl_ros2 40 | colcon build 41 | source /install/setup.bash 42 | cd /tmp 43 | wget https://raw.githubusercontent.com/linorobot/ldlidar/ros2/ldlidar.rules 44 | sudo cp ldlidar.rules /etc/udev/rules.d 45 | 46 | RPLIDAR (A1 A2 A3 C1 S1 S2 S3): 47 | 48 | cd 49 | git clone https://github.com/Slamtec/sllidar_ros2.git 50 | colcon build 51 | source /install/setup.bash 52 | sudo cp sllidar_ros2/scripts/rplidar.rules /etc/udev/rules.d 53 | 54 | #### 1.3 Install depth sensor drivers: 55 | Intel RealSense: 56 | 57 | sudo apt install ros-$ROS_DISTRO-realsense2-camera 58 | 59 | Zed Camera: 60 | 61 | cd /tmp 62 | wget https://download.stereolabs.com/zedsdk/3.5/jp45/jetsons -O zed_sdk #use Jetson SDK 63 | #wget https://download.stereolabs.com/zedsdk/3.5/cu111/ubuntu20 -O zed_sdk #use this for x86 machine with NVIDIA GPU 64 | chmod +x zed_sdk 65 | ./zed_sdk -- silent 66 | cd 67 | git clone https://github.com/stereolabs/zed-ros2-wrapper src/zed-ros2-wrapper 68 | git clone https://github.com/ros-perception/image_common -b $ROS_DISTRO src/image_common 69 | rosdep install --from-paths src --ignore-src -r -y 70 | colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release 71 | source /install/setup.bash 72 | 73 | OAK-D Camera: 74 | 75 | sudo apt install ros-$ROS_DISTRO-depthai-ros 76 | 77 | #### 1.4 Download and install micro-ROS: 78 | 79 | cd 80 | git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro_ros_setup src/micro_ros_setup 81 | sudo apt install python3-vcstool build-essential 82 | sudo apt update && rosdep update 83 | rosdep install --from-path src --ignore-src -y 84 | colcon build 85 | source install/setup.bash 86 | 87 | #### 1.5 Setup micro-ROS agent: 88 | 89 | ros2 run micro_ros_setup create_agent_ws.sh 90 | ros2 run micro_ros_setup build_agent.sh 91 | source install/setup.bash 92 | 93 | * You can ignore `1 package had stderr output: microxrcedds_agent` after building your workspace. 94 | 95 | ### 2. Download linorobot2 and its dependencies: 96 | 97 | #### 2.1 Download linorobot2: 98 | 99 | cd 100 | git clone -b $ROS_DISTRO https://github.com/linorobot/linorobot2 src/linorobot2 101 | 102 | #### 2.2 Ignore Gazebo Packages on robot computer (optional) 103 | 104 | If you're installing this on the robot's computer or you don't need to run Gazebo at all, you can skip linorobot2_gazebo package by creating a COLCON_IGNORE file: 105 | 106 | cd src/linorobot2/linorobot2_gazebo 107 | touch COLCON_IGNORE 108 | 109 | #### 2.3 Install linorobot2 package: 110 | 111 | cd 112 | rosdep update && rosdep install --from-path src --ignore-src -y --skip-keys microxrcedds_agent 113 | colcon build 114 | source install/setup.bash 115 | 116 | * microxrcedds_agent dependency checks are skipped to prevent this [issue](https://github.com/micro-ROS/micro_ros_setup/issues/138) of finding its keys. This means that you have to always add `--skip-keys microxrcedds_agent` whenever you have to run `rosdep install` on the ROS2 workspace where you installed linorobot2. 117 | 118 | ## ENV Variables 119 | ### 1. Robot Type 120 | Set LINOROBOT2_BASE env variable to the type of robot base that you want to use. This is not required if you're using a custom URDF. Available env variables are *2wd*, *4wd*, and *mecanum*. For example: 121 | 122 | echo "export LINOROBOT2_BASE=2wd" >> ~/.bashrc 123 | 124 | ### 2. Sensors 125 | #### 2.1 Depth Sensor (Optional) 126 | The Nav2 config file has been configured to support [Voxel Layer](https://navigation.ros.org/configuration/packages/costmap-plugins/voxel.html) for marking 3D obstacles in the Local Costmap using a depth sensor. To enable one of the tested depth sensor's launch files in bringup.launch.py, export the depth sensor you're using to `LINOROBOT2_DEPTH_SENSOR` env variable. 127 | 128 | Tested sensors are: 129 | - `realsense` - [Intel RealSense](https://www.intelrealsense.com/stereo-depth/) D435, D435i 130 | - `astra` - [Orbec Astra](https://orbbec3d.com/product-astra-pro/) 131 | - `zed` - [Zed](https://www.stereolabs.com/zed) 132 | - `zed2` - [Zed 2](https://www.stereolabs.com/zed-2) 133 | - `zed2i` - [Zed 2i](https://www.stereolabs.com/zed-2i) 134 | - `zedm` - [Zed Mini](https://www.stereolabs.com/zed-mini) 135 | 136 | For example: 137 | 138 | echo "export LINOROBOT2_DEPTH_SENSOR=realsense" >> ~/.bashrc 139 | 140 | #### 2.2 Laser Sensor (Optional) 141 | The launch files of the tested laser sensors have already been added in bringup.launch.py. You can enable one of these sensors by exporting the laser sensor you're using to `LINOROBOT2_LASER_SENSOR` env variable. 142 | 143 | Tested Laser Sensors: 144 | - `rplidar` - [RP LIDAR A1](https://www.slamtec.com/en/Lidar/A1) 145 | - `ldlidar` - [LD06 LIDAR](https://www.inno-maker.com/product/lidar-ld06/) 146 | - `ld06` - [LD06 LIDAR](https://www.ldrobot.com/ProductDetails?sensor_name=STL-06P) 147 | - `ld19` - [LD19/LD300 LIDAR](https://www.ldrobot.com/ProductDetails?sensor_name=STL-19P) 148 | - `stl27l` - [STL27L LIDAR](https://www.ldrobot.com/ProductDetails?sensor_name=STL-27L) 149 | - `ydlidar` - [YDLIDAR](https://www.ydlidar.com/lidars.html) 150 | - `realsense` - [Intel RealSense](https://www.intelrealsense.com/stereo-depth/) D435, D435i 151 | - `astra` - [Orbec Astra](https://orbbec3d.com/product-astra-pro/) 152 | - `zed` - [Zed](https://www.stereolabs.com/zed) 153 | - `zed2` - [Zed 2](https://www.stereolabs.com/zed-2) 154 | - `zed2i` - [Zed 2i](https://www.stereolabs.com/zed-2i) 155 | - `zedm` - [Zed Mini](https://www.stereolabs.com/zed-mini) 156 | 157 | For example: 158 | 159 | echo "export LINOROBOT2_LASER_SENSOR=rplidar" >> ~/.bashrc 160 | 161 | If you export a depth sensor to `LINOROBOT2_LASER_SENSOR`, the launch file will run [depthimage_to_laserscan](https://github.com/ros-perception/depthimage_to_laserscan) to convert the depth sensor's depth image to laser. 162 | 163 | ### 3. Save changes 164 | Source your `~/.bashrc` to apply the changes you made: 165 | 166 | source ~/.bashrc 167 | 168 | ## Miscellaneous 169 | 170 | ### 1. Creating Jetson Nano Image 171 | 172 | - Create the custom image on your host machine by following this [tutorial](https://pythops.com/post/create-your-own-image-for-jetson-nano-board.html). Prepare an SD card and use the helper scripts found in the [repository](https://github.com/pythops/jetson-nano-image) mentioned in the tutorial to build and flash the custom image to the SD card. 173 | 174 | - Before going through the tutorial, you can change the user name and password by modifying this [file](https://github.com/pythops/jetson-nano-image/blob/master/ansible/roles/jetson/defaults/main.yaml#L5-L7). 175 | 176 | - If you encounter this problem: `Extend the fs... e2fsck: No such file or directory while trying to open /dev/sdcp1 177 | ` after flashing the image, you can check out this [issue](https://github.com/pythops/jetson-nano-image/issues/43) to resolve the problem. 178 | 179 | - On your jetson nano, install the Nvidia Libraries: 180 | 181 | sudo apt install -y cuda-toolkit-10-2 libcudnn8 libcudnn8-dev 182 | 183 | ### 2. Running a launch file during boot-up. 184 | 185 | This is a short tutorial on how to make your bringup launch files run during startup. 186 | 187 | ### 2.1 Create your env.sh 188 | 189 | sudo touch /etc/ros/env.sh 190 | sudo nano /etc/ros/env.sh 191 | 192 | and paste the following: 193 | 194 | #!/bin/sh 195 | 196 | export LINOROBOT2_BASE= 197 | export LINOROBOT2_LASER_SENSOR= #(optional) 198 | 199 | ### 2.2 Create systemd service 200 | 201 | sudo touch /etc/systemd/system/robot-boot.service 202 | sudo nano /etc/systemd/system/robot-boot.service 203 | 204 | and paste the following: 205 | 206 | [Unit] 207 | After=NetworkManager.service time-sync.target 208 | 209 | [Service] 210 | Type=simple 211 | User= 212 | ExecStart=/bin/sh -c ". /opt/ros//setup.sh;. /etc/ros/env.sh;. /home///install/setup.sh; ros2 launch linorobot2_bringup bringup.launch.py joy:=true" 213 | 214 | [Install] 215 | WantedBy=multi-user.target 216 | 217 | Remember to replace: 218 | - `user` with your machine's user name (`echo $USER`) 219 | - `your_ros_distro` with the ros2 distro (`echo $ROS_DISTRO`) your machine is running on 220 | - `your_ws` with the location of the ros2 ws where you installed linorobot2 221 | 222 | ### 2.3 Enable the service 223 | 224 | sudo systemctl enable robot-boot.service 225 | 226 | You can check if the service you just created is correct by: 227 | 228 | sudo systemctl start robot-boot.service 229 | sudo systemctl status robot-boot.service 230 | 231 | * You should see the ros2 logs that you usually see when running bringup.launch.py. Once successful, you can now reboot your machine. bringup.launch.py should start running once the machine finished booting up. 232 | 233 | ### 2.4 Removing the service 234 | 235 | systemctl stop robot-boot.service 236 | systemctl disable robot-boot.service 237 | sudo rm /etc/systemd/system/robot-boot.service 238 | 239 | 240 | Source: https://blog.roverrobotics.com/how-to-run-ros-on-startup-bootup/ 241 | -------------------------------------------------------------------------------- /docker/.cyclonedds.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | false 9 | 10 | 11 | auto 12 | 13 | 14 | 15 | 120 16 | 17 | 18 | -------------------------------------------------------------------------------- /docker/.env: -------------------------------------------------------------------------------- 1 | # Robot type. Available variables: 2wd 4wd mecanum 2 | ROBOT_BASE=2wd 3 | 4 | # 2D laser scanner to be used. Available variables: ldlidar rplidar ydlidar xv11 5 | LASER_SENSOR= 6 | 7 | # Depth sensor to be used. Available variables: realsense zed zedm zed2 zed2i 8 | DEPTH_SENSOR= 9 | 10 | # Type of installation. Available variables: 11 | # simulation - Install Gazebo and plugins 12 | # hardware - Install with microros 13 | DEPLOY=hardware 14 | 15 | # Default ROS_DOMAIN_ID 16 | ROS_DOMAIN_ID=0 17 | 18 | # Launch custom robot launch file. DO NOT SET THIS unless you're using a custom launch file. 19 | CUSTOM_ROBOT=false 20 | 21 | # Launch extra launch file 22 | LAUNCH_EXTRA=false 23 | 24 | # Odometry topic 25 | ODOM_TOPIC=/odom 26 | 27 | # Base Serial Port 28 | BASE_SERIAL_PORT=/dev/ttyACM0 29 | 30 | # Launch Joystick 31 | LAUNCH_JOYSTICK=false 32 | 33 | # Use GPU if GPU is installed 34 | # nvidia To enable 35 | # leave blank to disable 36 | RUNTIME= 37 | 38 | UBUNTU_VER=22.04 39 | USE_ROS_DISTRO=humble 40 | 41 | RMW=cyclonedds 42 | # RMW=fastrtps 43 | -------------------------------------------------------------------------------- /docker/.fastrtps.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | custom_udpv4_transport 7 | UDPv4 8 | 9 | 10 | 11 | 12 | false 13 | 14 | custom_udpv4_transport 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG USE_ROS_DISTRO= 2 | ARG UBUNTU_VER= 3 | ARG RUNTIME= 4 | ARG DEPLOY= 5 | ARG RMW= 6 | 7 | FROM --platform=$BUILDPLATFORM ros:${USE_ROS_DISTRO}-ros-base AS ros2 8 | SHELL ["/bin/bash", "-c"] 9 | ENV DEBIAN_FRONTEND=noninteractive 10 | 11 | # Install language 12 | RUN apt-get update && apt-get install -y \ 13 | locales \ 14 | && locale-gen en_US.UTF-8 \ 15 | && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 \ 16 | && rm -rf /var/lib/apt/lists/* 17 | ENV LANG en_US.UTF-8 18 | 19 | # Install timezone 20 | RUN ln -fs /usr/share/zoneinfo/UTC /etc/localtime \ 21 | && export DEBIAN_FRONTEND=noninteractive \ 22 | && apt-get update \ 23 | && apt-get install -y tzdata \ 24 | && dpkg-reconfigure --frontend noninteractive tzdata \ 25 | && rm -rf /var/lib/apt/lists/* 26 | 27 | RUN apt-get update && apt-get -y upgrade \ 28 | && rm -rf /var/lib/apt/lists/* 29 | 30 | # Install common programs 31 | RUN apt-get update && apt-get install -y --no-install-recommends \ 32 | gnupg2 \ 33 | lsb-release \ 34 | software-properties-common \ 35 | wget \ 36 | curl \ 37 | python3-pip \ 38 | && rm -rf /var/lib/apt/lists/* 39 | 40 | FROM nvidia/cuda:12.1.0-runtime-ubuntu${UBUNTU_VER} AS ros2nvidia 41 | SHELL ["/bin/bash", "-c"] 42 | ENV DEBIAN_FRONTEND=noninteractive 43 | 44 | # Install language 45 | RUN apt-get update && apt-get install -y \ 46 | locales \ 47 | && locale-gen en_US.UTF-8 \ 48 | && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 \ 49 | && rm -rf /var/lib/apt/lists/* 50 | ENV LANG en_US.UTF-8 51 | 52 | # Install timezone 53 | RUN ln -fs /usr/share/zoneinfo/UTC /etc/localtime \ 54 | && export DEBIAN_FRONTEND=noninteractive \ 55 | && apt-get update \ 56 | && apt-get install -y tzdata \ 57 | && dpkg-reconfigure --frontend noninteractive tzdata \ 58 | && rm -rf /var/lib/apt/lists/* 59 | 60 | RUN apt-get update && apt-get -y upgrade \ 61 | && rm -rf /var/lib/apt/lists/* 62 | 63 | # Install common programs 64 | RUN apt-get update && apt-get install -y --no-install-recommends \ 65 | gnupg2 \ 66 | lsb-release \ 67 | software-properties-common \ 68 | wget \ 69 | curl \ 70 | python3-pip \ 71 | libegl1-mesa \ 72 | libglu1-mesa \ 73 | libxv1 \ 74 | libxtst6 \ 75 | && rm -rf /var/lib/apt/lists/* 76 | 77 | # Install VirtualGL 78 | ARG VIRTUALGL_VER="3.1" 79 | RUN wget -O /tmp/virtualgl.deb https://zenlayer.dl.sourceforge.net/project/virtualgl/${VIRTUALGL_VER}/virtualgl_${VIRTUALGL_VER}_amd64.deb 80 | RUN dpkg -i /tmp/virtualgl.deb 81 | 82 | # Install glvnd 83 | # Reference: https://github.com/athackst/dockerfiles/blob/main/ros2/humble-cuda.Dockerfile 84 | RUN apt-get update && apt-get install -y --no-install-recommends \ 85 | libglvnd0 \ 86 | libgl1 \ 87 | libglx0 \ 88 | libegl1 \ 89 | libxext6 \ 90 | libx11-6 \ 91 | && rm -rf /var/lib/apt/lists/* 92 | 93 | # Install ROS2 94 | ARG USE_ROS_DISTRO= 95 | RUN add-apt-repository universe \ 96 | && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ 97 | && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null \ 98 | && apt-get update && apt-get install -y --no-install-recommends \ 99 | ros-${USE_ROS_DISTRO}-ros-base \ 100 | python3-argcomplete \ 101 | && rm -rf /var/lib/apt/lists/* 102 | 103 | RUN apt-get update && apt-get install -y --no-install-recommends \ 104 | ros-dev-tools \ 105 | ros-${USE_ROS_DISTRO}-ament-* \ 106 | && rm -rf /var/lib/apt/lists/* 107 | 108 | RUN source /opt/ros/${USE_ROS_DISTRO}/setup.bash 109 | RUN rosdep init 110 | ENV ROS_DISTRO=${USE_ROS_DISTRO} 111 | ENV NVIDIA_VISIBLE_DEVICES=all 112 | ENV NVIDIA_DRIVER_CAPABILITIES=graphics,utility,compute 113 | ENV QT_X11_NO_MITSHM=1 114 | 115 | FROM ros2${RUNTIME} AS common 116 | SHELL ["/bin/bash", "-c"] 117 | 118 | ARG RMW= 119 | RUN if [ "${RMW}" == "cyclonedds" ]; then \ 120 | apt-get update && apt-get install -y --no-install-recommends \ 121 | ros-${ROS_DISTRO}-rmw-cyclonedds-cpp \ 122 | && rm -rf /var/lib/apt/lists/* ; \ 123 | fi 124 | 125 | COPY docker/.${RMW}.xml /root 126 | ENV RMW_IMPLEMENTATION=rmw_${RMW}_cpp 127 | ENV CYCLONEDDS_URI=/root/.cyclonedds.xml 128 | ENV FASTRTPS_DEFAULT_PROFILES_FILE=/root/.fastrtps.xml 129 | 130 | RUN mkdir -p /root/linorobot2_ws/src/linorobot2 131 | RUN mkdir -p /root/preinstall/base \ 132 | /root/preinstall/description \ 133 | /root/preinstall/navigation 134 | 135 | COPY ./linorobot2_base/package.xml /root/preinstall/base 136 | COPY ./linorobot2_description/package.xml /root/preinstall/description 137 | COPY ./linorobot2_navigation/package.xml /root/preinstall/navigation 138 | 139 | RUN apt-get update \ 140 | && rosdep update --rosdistro=${ROS_DISTRO} \ 141 | && rosdep install --rosdistro=${ROS_DISTRO} --from-paths /root/preinstall -iry --os=ubuntu:$(lsb_release -sc) \ 142 | && rm -rf /var/lib/apt/lists/* 143 | 144 | COPY docker/entrypoint.sh /root 145 | ARG RUNTIME= 146 | RUN if [ ${RUNTIME} == "nvidia" ]; then \ 147 | sed -i 's/\$\@/vglrun +v -d \/dev\/dri\/card0 \$@/' /root/entrypoint.sh; \ 148 | fi 149 | RUN sed -i "s/rosdistro/${ROS_DISTRO}/" /root/entrypoint.sh 150 | RUN chmod +x /root/entrypoint.sh 151 | 152 | FROM common AS hardware 153 | SHELL ["/bin/bash", "-c"] 154 | 155 | RUN mkdir -p /root/preinstall/bringup 156 | COPY ./linorobot2_bringup/package.xml /root/preinstall/bringup 157 | 158 | RUN apt-get update \ 159 | && rosdep update --rosdistro=${ROS_DISTRO} \ 160 | && rosdep install --rosdistro=${ROS_DISTRO} --from-paths /root/preinstall -iry --os=ubuntu:$(lsb_release -sc) \ 161 | && rm -rf /var/lib/apt/lists/* 162 | 163 | ARG ROBOT_BASE=2wd 164 | ARG LASER_SENSOR= 165 | ARG DEPTH_SENSOR= 166 | COPY ./docker/install_sensors.bash /root 167 | RUN /bin/bash /root/install_sensors.bash $ROBOT_BASE $LASER_SENSOR $DEPTH_SENSOR $ROS_DISTRO 168 | 169 | RUN apt-get update && apt-get install -y --no-install-recommends \ 170 | python3-vcstool \ 171 | build-essential \ 172 | && rm -rf /var/lib/apt/lists/* 173 | 174 | WORKDIR /root/linorobot2_ws 175 | RUN git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup 176 | RUN apt-get update \ 177 | && rosdep update --rosdistro=${ROS_DISTRO} \ 178 | && rosdep install --rosdistro=${ROS_DISTRO} --from-paths src -iry --os=ubuntu:$(lsb_release -sc) --skip-keys micro_ros_agent \ 179 | && rm -rf /var/lib/apt/lists/* 180 | 181 | RUN source /opt/ros/$ROS_DISTRO/setup.bash \ 182 | && colcon build --packages-select micro_ros_setup 183 | 184 | RUN source /opt/ros/$ROS_DISTRO/setup.bash \ 185 | && source /root/linorobot2_ws/install/setup.bash \ 186 | && ros2 run micro_ros_setup create_agent_ws.sh 187 | 188 | RUN source /opt/ros/$ROS_DISTRO/setup.bash \ 189 | && source /root/linorobot2_ws/install/setup.bash \ 190 | && ros2 run micro_ros_setup build_agent.sh 191 | 192 | RUN source /opt/ros/$ROS_DISTRO/setup.bash \ 193 | && colcon build 194 | 195 | FROM common AS simulation 196 | SHELL ["/bin/bash", "-c"] 197 | 198 | RUN git clone https://github.com/osrf/gazebo_models.git /root/.gazebo/models 199 | RUN rm -rf /root/.gazebo/models/.git 200 | 201 | RUN mkdir -p /root/preinstall/gazebo 202 | COPY ./linorobot2_gazebo/package.xml /root/preinstall/gazebo 203 | RUN apt-get update \ 204 | && rosdep update --rosdistro=${ROS_DISTRO} \ 205 | && rosdep install --rosdistro=${ROS_DISTRO} --from-paths /root/preinstall -iry --os=ubuntu:$(lsb_release -sc) \ 206 | && rm -rf /var/lib/apt/lists/* 207 | 208 | FROM ${DEPLOY} AS base 209 | SHELL ["/bin/bash", "-c"] 210 | 211 | COPY . /root/linorobot2_ws/src/linorobot2 212 | 213 | ARG DEPLOY= 214 | RUN if [ ${DEPLOY} == "hardware" ]; then \ 215 | touch /root/linorobot2_ws/src/linorobot2/linorobot2_gazebo/COLCON_IGNORE; \ 216 | elif [ ${DEPLOY} == "simulation" ]; then \ 217 | touch /root/linorobot2_ws/src/linorobot2/linorobot2_bringup/COLCON_IGNORE; \ 218 | fi 219 | 220 | WORKDIR /root/linorobot2_ws 221 | RUN source /opt/ros/$ROS_DISTRO/setup.bash \ 222 | && colcon build 223 | 224 | ENTRYPOINT ["/root/entrypoint.sh"] 225 | -------------------------------------------------------------------------------- /docker/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | base: 3 | image: linorobot2-${DEPLOY}:${USE_ROS_DISTRO} 4 | build: 5 | context: ../ 6 | dockerfile: docker/Dockerfile 7 | args: 8 | - RUNTIME=${RUNTIME} 9 | - DEPLOY=${DEPLOY} 10 | - UBUNTU_VER=${UBUNTU_VER} 11 | - USE_ROS_DISTRO=${USE_ROS_DISTRO} 12 | - ROBOT_BASE=${ROBOT_BASE} 13 | - LASER_SENSOR=${LASER_SENSOR} 14 | - DEPTH_SENSOR=${DEPTH_SENSOR} 15 | - RMW=${RMW} 16 | target: base 17 | 18 | dev: 19 | runtime: ${RUNTIME} 20 | image: linorobot2-${DEPLOY}:${USE_ROS_DISTRO} 21 | hostname: linorobot2-${USE_ROS_DISTRO} 22 | stdin_open: true 23 | tty: true 24 | network_mode: host 25 | ipc: host 26 | privileged: true 27 | environment: 28 | - ROS_DOMAIN_ID=${ROS_DOMAIN_ID} 29 | - LINOROBOT2_BASE=${ROBOT_BASE} 30 | - LINOROBOT2_LASER_SENSOR=${LASER_SENSOR} 31 | - LINOROBOT2_DEPTH_SENSOR=${DEPTH_SENSOR} 32 | - DISPLAY=${DISPLAY} 33 | - QT_X11_NO_MITSHM=1 34 | - WORLD=${WORLD:-playground} 35 | volumes: 36 | - /tmp/.X11-unix:/tmp/.X11-unix:rw 37 | - $HOME/.Xauthority:/root/.Xauthority 38 | - ../linorobot2_navigation/maps:/root/linorobot2_ws/src/linorobot2/linorobot2_navigation/maps:rw) 39 | 40 | gazebo: 41 | container_name: gazebo 42 | extends: dev 43 | command: ros2 launch linorobot2_gazebo gazebo.launch.py world:=/root/linorobot2_ws/install/linorobot2_gazebo/share/linorobot2_gazebo/worlds/${WORLD:-playground}.world 44 | devices: 45 | - /dev:/dev 46 | 47 | bringup: 48 | container_name: bringup 49 | extends: dev 50 | command: > 51 | ros2 launch linorobot2_bringup bringup.launch.py 52 | custom_robot:=${CUSTOM_ROBOT} 53 | extra:=${LAUNCH_EXTRA} 54 | odom_topic:=${ODOM_TOPIC} 55 | base_serial_port:=${BASE_SERIAL_PORT} 56 | joy:=${LAUNCH_JOYSTICK} 57 | devices: 58 | - /dev:/dev 59 | 60 | slam: 61 | container_name: slam 62 | extends: dev 63 | command: > 64 | ros2 launch linorobot2_navigation slam.launch.py 65 | rviz:=false 66 | 67 | slam-sim: 68 | container_name: slam-sim 69 | extends: dev 70 | command: > 71 | ros2 launch linorobot2_navigation slam.launch.py 72 | rviz:=true 73 | sim:=true 74 | 75 | navigate: 76 | container_name: navigate 77 | extends: dev 78 | command: > 79 | ros2 launch linorobot2_navigation navigation.launch.py 80 | map:=/root/linorobot2_ws/src/linorobot2/linorobot2_navigation/maps/${WORLD:-playground}.yaml 81 | rviz:=false 82 | sim:=false 83 | 84 | navigate-sim: 85 | container_name: navigate-sim 86 | extends: dev 87 | command: > 88 | ros2 launch linorobot2_navigation navigation.launch.py 89 | map:=/root/linorobot2_ws/src/linorobot2/linorobot2_navigation/maps/${WORLD:-playground}.yaml 90 | rviz:=true 91 | sim:=true 92 | 93 | save-map: 94 | container_name: save-map 95 | extends: dev 96 | command: > 97 | ros2 run nav2_map_server map_saver_cli 98 | -f /root/linorobot2_ws/src/linorobot2/linorobot2_navigation/maps/map 99 | --fmt png 100 | --ros-args -p save_map_timeout:=10000. 101 | 102 | rviz-nav: 103 | container_name: rviz-nav 104 | extends: dev 105 | command: rviz2 -d /root/linorobot2_ws/src/linorobot2/linorobot2_navigation/rviz/linorobot2_navigation.rviz 106 | 107 | rviz: 108 | container_name: rviz 109 | extends: dev 110 | command: rviz2 111 | 112 | debug: 113 | container_name: debug 114 | extends: dev 115 | command: sleep infinity 116 | volumes: 117 | - ../.:/root/linorobot2_ws/src/linorobot2 118 | 119 | webtop: 120 | image: lscr.io/linuxserver/webtop:latest 121 | container_name: webtop 122 | security_opt: 123 | - seccomp:unconfined 124 | environment: 125 | - PUID=1000 126 | - PGID=1000 127 | - TZ=Etc/UTC 128 | - SUBFOLDER=/ 129 | - TITLE=Webtop 130 | - DISPLAY=:200 131 | network_mode: host 132 | volumes: 133 | - /path/to/data:/config 134 | - /var/run/docker.sock:/var/run/docker.sock 135 | - /tmp/.X11-unix:/tmp/.X11-unix:rw 136 | - $HOME/.Xauthority:/root/.Xauthority 137 | devices: 138 | - /dev/dri:/dev/dri 139 | shm_size: "1gb" 140 | restart: unless-stopped 141 | 142 | kasmvnc: 143 | runtime: ${RUNTIME} 144 | container_name: kasmvnc 145 | image: ghcr.io/linuxserver/baseimage-kasmvnc:alpine318 146 | privileged: true 147 | network_mode: host 148 | volumes: 149 | - /tmp/.X11-unix:/tmp/.X11-unix:rw 150 | - $HOME/.Xauthority:/root/.Xauthority 151 | environment: 152 | - DISPLAY=:200 153 | devices: 154 | - /dev/dri:/dev/dri 155 | -------------------------------------------------------------------------------- /docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source /opt/ros/rosdistro/setup.bash 4 | source /root/linorobot2_ws/install/setup.bash 5 | 6 | $@ -------------------------------------------------------------------------------- /docker/install_sensors.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | set -e 17 | 18 | BASE=$1 19 | LASER_SENSOR=$2 20 | DEPTH_SENSOR=$3 21 | ARCH="$(uname -m)" 22 | ROSDISTRO=$4 23 | 24 | WORKSPACE="/root/linorobot2_ws" 25 | 26 | ROBOT_TYPE_ARRAY=(2wd 4wd mecanum) 27 | DEPTH_SENSOR_ARRAY=(realsense zed zedm zed2 zed2i oakd oakdlite oakdpro) 28 | LASER_SENSOR_ARRAY=(ydlidar xv11 ld06 ld19 stl27l a1 a2 a3 c1 s1 s2 s3 ldlidar) 29 | LASER_SENSOR_ARRAY+=(${DEPTH_SENSOR_ARRAY[@]}) 30 | 31 | if [ -z "$LASER_SENSOR" ] 32 | then 33 | LASER_SENSOR="" 34 | fi 35 | 36 | if [ -z "$DEPTH_SENSOR" ] 37 | then 38 | DEPTH_SENSOR="" 39 | fi 40 | 41 | function install_cuda_jetson { 42 | wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/sbsa/cuda-ubuntu2004.pin 43 | sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600 44 | wget http://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda-repo-ubuntu2004-11-4-local_11.4.2-470.57.02-1_arm64.deb 45 | sudo dpkg -i cuda-repo-ubuntu2004-11-4-local_11.4.2-470.57.02-1_arm64.deb 46 | sudo apt-key add /var/cuda-repo-ubuntu2004-11-4-local/7fa2af80.pub #verify this 47 | sudo apt-get update 48 | sudo apt-get -y install cuda 49 | # Errors were encountered while processing: 50 | # /tmp/apt-dpkg-install-TvUCLd/14-libnvidia-compute-470_470.57.02-0ubuntu1_arm64.deb 51 | # /tmp/apt-dpkg-install-TvUCLd/18-libnvidia-gl-470_470.57.02-0ubuntu1_arm64.deb 52 | # E: Sub-process /usr/bin/dpkg returned an error code (1) 53 | } 54 | 55 | function install_xv11 { 56 | cd $WORKSPACE 57 | git clone https://github.com/mjstn/xv_11_driver src/xv_11_driver 58 | colcon build 59 | source $WORKSPACE/install/setup.bash 60 | } 61 | 62 | function install_ydlidar { 63 | cd /tmp 64 | git clone https://github.com/YDLIDAR/YDLidar-SDK.git 65 | mkdir YDLidar-SDK/build 66 | cd YDLidar-SDK/build 67 | cmake .. 68 | make 69 | sudo make install 70 | cd $WORKSPACE 71 | git clone https://github.com/YDLIDAR/ydlidar_ros2_driver src/ydlidar_ros2_driver 72 | chmod 0777 src/ydlidar_ros2_driver/startup/* 73 | colcon build --symlink-install 74 | source $WORKSPACE/install/setup.bash 75 | } 76 | 77 | function install_ldlidar { 78 | cd $WORKSPACE 79 | git clone https://github.com/linorobot/ldlidar src/ldlidar 80 | colcon build 81 | source $WORKSPACE/install/setup.bash 82 | } 83 | 84 | function install_ldlidar_stl_ros2 { 85 | cd $WORKSPACE 86 | git clone https://github.com/hippo5329/ldlidar_stl_ros2.git src/ldlidar_stl_ros2 87 | colcon build 88 | source $WORKSPACE/install/setup.bash 89 | } 90 | 91 | function install_ld06 { 92 | install_ldlidar_stl_ros2 93 | } 94 | 95 | function install_ld19 { 96 | install_ldlidar_stl_ros2 97 | } 98 | 99 | function install_stl27l { 100 | install_ldlidar_stl_ros2 101 | } 102 | 103 | function install_sllidar_ros2 { 104 | cd $WORKSPACE 105 | git clone https://github.com/Slamtec/sllidar_ros2.git src/sllidar_ros2 106 | colcon build 107 | source $WORKSPACE/install/setup.bash 108 | } 109 | 110 | function install_a1 { 111 | install_sllidar_ros2 112 | } 113 | 114 | function install_a2 { 115 | install_sllidar_ros2 116 | } 117 | 118 | function install_a3 { 119 | install_sllidar_ros2 120 | } 121 | 122 | function install_c1 { 123 | install_sllidar_ros2 124 | } 125 | 126 | function install_s1 { 127 | install_sllidar_ros2 128 | } 129 | 130 | function install_s2 { 131 | install_sllidar_ros2 132 | } 133 | 134 | function install_s3 { 135 | install_sllidar_ros2 136 | } 137 | 138 | function install_realsense { 139 | sudo apt-get install -y ros-$ROS_DISTRO-realsense2-camera 140 | cd /tmp 141 | wget https://raw.githubusercontent.com/IntelRealSense/librealsense/master/config/99-realsense-libusb.rules 142 | } 143 | 144 | function install_astra { 145 | cd $WORKSPACE 146 | sudo apt-get install -y libuvc-dev libopenni2-dev 147 | git clone https://github.com/linorobot/ros_astra_camera src/ros_astra_camera 148 | colcon build 149 | source $WORKSPACE/install/setup.bash 150 | } 151 | 152 | function install_zed { 153 | cd /tmp 154 | if [[ -f /etc/nv_tegra_release ]] 155 | then 156 | #TODO ADD CUDA INSTALLATION HERE 157 | wget https://download.stereolabs.com/zedsdk/3.5/jp45/jetsons -O zed_sdk 158 | elif lspci | grep VGA | grep -o NVIDIA 159 | then 160 | wget https://download.stereolabs.com/zedsdk/3.5/cu111/ubuntu20 -O zed_sdk 161 | else 162 | echo "Linux Machine not supported by Zed Camera" 163 | exit 1 164 | fi 165 | 166 | chmod +x zed_sdk 167 | ./zed_sdk -- silent 168 | cd $WORKSPACE 169 | 170 | git clone https://github.com/stereolabs/zed-ros2-wrapper src/zed-ros2-wrapper 171 | git clone https://github.com/ros-perception/image_common -b $ROS_DISTRO src/image_common #https://github.com/stereolabs/zed-ros2-wrapper#image-transport-and-topic-subscriptions 172 | rosdep install --from-paths src --ignore-src -r -y 173 | colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release 174 | # colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release --cmake-args=-DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-11.4 175 | source $WORKSPACE/install/setup.bash 176 | source ~/.bashrc 177 | } 178 | 179 | function install_zedm { 180 | install_zed 181 | } 182 | 183 | function install_zed2 { 184 | install_zed 185 | } 186 | 187 | function install_zed2i { 188 | install_zed 189 | } 190 | 191 | function install_oakd { 192 | echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules 193 | sudo udevadm control --reload-rules && sudo udevadm trigger 194 | sudo apt-get install ros-$ROS_DISTRO-depthai-ros 195 | } 196 | 197 | function install_oakdlite { 198 | install_oakd 199 | } 200 | 201 | function install_oakdpro { 202 | install_oakd 203 | } 204 | 205 | echo 206 | echo "INSTALLING SENSORS NOW ..." 207 | echo 208 | 209 | source /opt/ros/$ROS_DISTRO/setup.bash 210 | sudo apt-get update 211 | if (printf '%s\n' "${LASER_SENSOR_ARRAY[@]}" | grep -xq $LASER_SENSOR) 212 | then 213 | install_$LASER_SENSOR 214 | fi 215 | 216 | if (printf '%s\n' "${DEPTH_SENSOR_ARRAY[@]}" | grep -xq $DEPTH_SENSOR) 217 | then 218 | install_$DEPTH_SENSOR 219 | fi 220 | 221 | -------------------------------------------------------------------------------- /docker/sim.yaml: -------------------------------------------------------------------------------- 1 | name: linorobot2-sim-demo 2 | on_project_start: export DISPLAY=:200 3 | on_project_exit: 4 | - docker compose down 5 | tmux_options: -f $HOME/.config/tmuxinator/eztmux/.tmux.conf 6 | windows: 7 | - main: 8 | panes: 9 | - docker compose up webtop 10 | - docker compose up gazebo 11 | - docker compose up navigate-sim 12 | 13 | - # This is not limited to this line only 14 | - # You can add as much panes as you want. 15 | -------------------------------------------------------------------------------- /docs/linorobot2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linorobot/linorobot2/6b7ae2ebd5e3782560363dca136c3a92864f5a46/docs/linorobot2.gif -------------------------------------------------------------------------------- /docs/linorobot2_launchfiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linorobot/linorobot2/6b7ae2ebd5e3782560363dca136c3a92864f5a46/docs/linorobot2_launchfiles.png -------------------------------------------------------------------------------- /docs/microcontroller_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linorobot/linorobot2/6b7ae2ebd5e3782560363dca136c3a92864f5a46/docs/microcontroller_architecture.png -------------------------------------------------------------------------------- /install_linorobot2.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | set -e 17 | 18 | ROSDISTRO="$(printenv ROS_DISTRO)" 19 | BASE=$1 20 | LASER_SENSOR=$2 21 | DEPTH_SENSOR=$3 22 | ARCH="$(uname -m)" 23 | WORKSPACE="$HOME/linorobot2_ws" 24 | 25 | ROBOT_TYPE_ARRAY=(2wd 4wd mecanum) 26 | DEPTH_SENSOR_ARRAY=(realsense zed zedm zed2 zed2i oakd oakdlite oakdpro) 27 | LASER_SENSOR_ARRAY=(ydlidar xv11 ld06 ld19 stl27l a1 a2 a3 c1 s1 s2 s3) 28 | LASER_SENSOR_ARRAY+=(${DEPTH_SENSOR_ARRAY[@]}) 29 | 30 | if [ -z "$LASER_SENSOR" ] 31 | then 32 | LASER_SENSOR="" 33 | fi 34 | 35 | if [ -z "$DEPTH_SENSOR" ] 36 | then 37 | DEPTH_SENSOR="" 38 | fi 39 | 40 | function install_cuda_jetson { 41 | wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/sbsa/cuda-ubuntu2004.pin 42 | sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600 43 | wget http://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda-repo-ubuntu2004-11-4-local_11.4.2-470.57.02-1_arm64.deb 44 | sudo dpkg -i cuda-repo-ubuntu2004-11-4-local_11.4.2-470.57.02-1_arm64.deb 45 | sudo apt-key add /var/cuda-repo-ubuntu2004-11-4-local/7fa2af80.pub #verify this 46 | sudo apt-get update 47 | sudo apt-get -y install cuda 48 | # Errors were encountered while processing: 49 | # /tmp/apt-dpkg-install-TvUCLd/14-libnvidia-compute-470_470.57.02-0ubuntu1_arm64.deb 50 | # /tmp/apt-dpkg-install-TvUCLd/18-libnvidia-gl-470_470.57.02-0ubuntu1_arm64.deb 51 | # E: Sub-process /usr/bin/dpkg returned an error code (1) 52 | } 53 | 54 | function install_xv11 { 55 | cd $WORKSPACE 56 | git clone https://github.com/mjstn/xv_11_driver src/xv_11_driver 57 | colcon build 58 | source $WORKSPACE/install/setup.bash 59 | } 60 | 61 | function install_ydlidar { 62 | cd /tmp 63 | git clone https://github.com/YDLIDAR/YDLidar-SDK.git 64 | mkdir YDLidar-SDK/build 65 | cd YDLidar-SDK/build 66 | cmake .. 67 | make 68 | sudo make install 69 | cd $WORKSPACE 70 | git clone https://github.com/YDLIDAR/ydlidar_ros2_driver src/ydlidar_ros2_driver 71 | chmod 0777 src/ydlidar_ros2_driver/startup/* 72 | sudo echo 'KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="0666", GROUP:="dialout", SYMLINK+="ydlidar"' >/etc/udev/rules.d/ydlidar.rules 73 | sudo echo 'KERNEL=="ttyACM*", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE:="0666", GROUP:="dialout", SYMLINK+="ydlidar"' >/etc/udev/rules.d/ydlidar-V2.rules 74 | sudo echo 'KERNEL=="ttyUSB*", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE:="0666", GROUP:="dialout", SYMLINK+="ydlidar"' >/etc/udev/rules.d/ydlidar-2303.rules 75 | colcon build --symlink-install 76 | source $WORKSPACE/install/setup.bash 77 | } 78 | 79 | function install_ldlidar_stl_ros2 { 80 | cd $WORKSPACE 81 | git clone https://github.com/hippo5329/ldlidar_stl_ros2.git src/ldlidar_stl_ros2 82 | colcon build 83 | source $WORKSPACE/install/setup.bash 84 | cd /tmp 85 | wget https://raw.githubusercontent.com/linorobot/ldlidar/ros2/ldlidar.rules 86 | sudo cp ldlidar.rules /etc/udev/rules.d 87 | } 88 | 89 | function install_ld06 { 90 | install_ldlidar_stl_ros2 91 | } 92 | 93 | function install_ld19 { 94 | install_ldlidar_stl_ros2 95 | } 96 | 97 | function install_stl27l { 98 | install_ldlidar_stl_ros2 99 | } 100 | 101 | function install_sllidar_ros2 { 102 | cd $WORKSPACE 103 | git clone https://github.com/Slamtec/sllidar_ros2.git 104 | colcon build 105 | source $WORKSPACE/install/setup.bash 106 | sudo cp sllidar_ros2/scripts/rplidar.rules /etc/udev/rules.d 107 | } 108 | 109 | function install_a1 { 110 | install_sllidar_ros2 111 | } 112 | 113 | function install_a2 { 114 | install_sllidar_ros2 115 | } 116 | 117 | function install_a3 { 118 | install_sllidar_ros2 119 | } 120 | 121 | function install_c1 { 122 | install_sllidar_ros2 123 | } 124 | 125 | function install_s1 { 126 | install_sllidar_ros2 127 | } 128 | 129 | function install_s2 { 130 | install_sllidar_ros2 131 | } 132 | 133 | function install_s3 { 134 | install_sllidar_ros2 135 | } 136 | 137 | function install_realsense { 138 | sudo apt install -y ros-$ROS_DISTRO-realsense2-camera 139 | cd /tmp 140 | wget https://raw.githubusercontent.com/IntelRealSense/librealsense/master/config/99-realsense-libusb.rules 141 | sudo cp 99-realsense-libusb.rules /etc/udev/rules.d 142 | } 143 | 144 | function install_astra { 145 | cd $WORKSPACE 146 | sudo apt install -y libuvc-dev libopenni2-dev 147 | git clone https://github.com/linorobot/ros_astra_camera src/ros_astra_camera 148 | sudo cp src/ros_astra_camera/56-orbbec-usb.rules /etc/udev/rules.d/ 149 | colcon build 150 | source $WORKSPACE/install/setup.bash 151 | } 152 | 153 | function install_zed { 154 | cd /tmp 155 | if [[ -f /etc/nv_tegra_release ]] 156 | then 157 | #TODO ADD CUDA INSTALLATION HERE 158 | wget https://download.stereolabs.com/zedsdk/3.5/jp45/jetsons -O zed_sdk 159 | elif lspci | grep VGA | grep -o NVIDIA 160 | then 161 | wget https://download.stereolabs.com/zedsdk/3.5/cu111/ubuntu20 -O zed_sdk 162 | else 163 | echo "Linux Machine not supported by Zed Camera" 164 | exit 1 165 | fi 166 | 167 | chmod +x zed_sdk 168 | ./zed_sdk -- silent 169 | cd $WORKSPACE 170 | 171 | git clone https://github.com/stereolabs/zed-ros2-wrapper src/zed-ros2-wrapper 172 | git clone https://github.com/ros-perception/image_common -b $ROS_DISTRO src/image_common #https://github.com/stereolabs/zed-ros2-wrapper#image-transport-and-topic-subscriptions 173 | rosdep install --from-paths src --ignore-src -r -y 174 | colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release 175 | # colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release --cmake-args=-DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-11.4 176 | source $WORKSPACE/install/setup.bash 177 | source ~/.bashrc 178 | } 179 | 180 | function install_zedm { 181 | install_zed 182 | } 183 | 184 | function install_zed2 { 185 | install_zed 186 | } 187 | 188 | function install_zed2i { 189 | install_zed 190 | } 191 | 192 | function install_oakd { 193 | echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules 194 | sudo udevadm control --reload-rules && sudo udevadm trigger 195 | sudo apt install ros-$ROS_DISTRO-depthai-ros 196 | } 197 | 198 | function install_oakdlite { 199 | install_oakd 200 | } 201 | 202 | function install_oakdpro { 203 | install_oakd 204 | } 205 | 206 | if [[ "$ROSDISTRO" == "" || "$ROSDISTRO" == "" ]] 207 | then 208 | echo "No ROS2 distro detected" 209 | echo "Try running $ source /opt/ros//setup.bash and try again." 210 | exit 1 211 | fi 212 | 213 | if [ "$*" == "" ] 214 | then 215 | echo "No arguments provided" 216 | echo 217 | echo "Example: $ bash install_linorobot2.bash 2wd a1" 218 | echo "Example: $ bash install_linorobot2.bash 2wd a1 realsense" 219 | echo "Example: $ bash install_linorobot2.bash 2wd - realsense" 220 | echo "Example: $ bash install_linorobot2.bash 2wd" 221 | 222 | echo 223 | exit 1 224 | fi 225 | 226 | if [[ "$BASE" != "ci" ]] && !(printf '%s\n' "${ROBOT_TYPE_ARRAY[@]}" | grep -xq $BASE) 227 | then 228 | echo "Invalid linorobot base: $1" 229 | echo 230 | echo "Valid Options:" 231 | for key in "${!ROBOT_TYPE_ARRAY[@]}"; do echo "${ROBOT_TYPE_ARRAY[$key]}"; done 232 | echo 233 | exit 1 234 | fi 235 | 236 | if [[ "$BASE" != "ci" && "$LASER_SENSOR" != "" && "$LASER_SENSOR" != "-" ]] && !(printf '%s\n' "${LASER_SENSOR_ARRAY[@]}" | grep -xq $LASER_SENSOR) 237 | then 238 | echo "Invalid linorobot2 laser sensor: $LASER_SENSOR" 239 | echo 240 | echo "Valid Options:" 241 | for key in "${!LASER_SENSOR_ARRAY[@]}"; do echo "${LASER_SENSOR_ARRAY[$key]}"; done 242 | echo 243 | exit 1 244 | fi 245 | 246 | if [[ "$BASE" != "ci" && "$DEPTH_SENSOR" != "" ]] && !(printf '%s\n' "${DEPTH_SENSOR_ARRAY[@]}" | grep -xq $DEPTH_SENSOR) 247 | then 248 | echo "Invalid linorobot2 depth sensor: $DEPTH_SENSOR" 249 | echo 250 | echo "Valid Options:" 251 | for key in "${!DEPTH_SENSOR_ARRAY[@]}"; do echo "${DEPTH_SENSOR_ARRAY[$key]}"; done 252 | echo 253 | exit 1 254 | fi 255 | 256 | if [[ "$BASE" != "ci" ]] 257 | then 258 | echo 259 | echo "You are installing linorobot2 on your robot computer." 260 | echo 261 | echo "===========SUMMARY============" 262 | echo "ROBOT TYPE : $BASE" 263 | echo "LASER SENSOR : $LASER_SENSOR" 264 | echo "DEPTH SENSOR : $DEPTH_SENSOR" 265 | echo 266 | echo "This installer will edit your ~/.bashrc." 267 | echo "Create a linorobot2_ws on your $HOME directory." 268 | echo "Install linorobot2 ROS2 dependencies." 269 | echo "Install udev rules on /etc/udev/rules.d folder." 270 | echo -n "Enter [y] to continue. " 271 | read reply 272 | if [[ "$reply" != "y" && "$reply" != "Y" ]] 273 | then 274 | echo "Exiting now." 275 | exit 1 276 | fi 277 | fi 278 | 279 | echo 280 | echo "INSTALLING NOW...." 281 | echo 282 | 283 | #### 1.1 Source your ROS2 distro and workspace 284 | cd $HOME 285 | mkdir -p $WORKSPACE/src 286 | source /opt/ros/$ROS_DISTRO/setup.bash 287 | cd $WORKSPACE 288 | colcon build 289 | source $WORKSPACE/install/setup.bash 290 | 291 | #### 1.2/1.3 Install LIDAR/Depth Sensor ROS2 drivers: 292 | if (printf '%s\n' "${LASER_SENSOR_ARRAY[@]}" | grep -xq $LASER_SENSOR) 293 | then 294 | install_$LASER_SENSOR 295 | fi 296 | 297 | if (printf '%s\n' "${DEPTH_SENSOR_ARRAY[@]}" | grep -xq $DEPTH_SENSOR) 298 | then 299 | install_$DEPTH_SENSOR 300 | fi 301 | 302 | if [[ "$BASE" == "ci" ]] 303 | then 304 | for key in "${!LASER_SENSOR_ARRAY[@]}"; do install_${LASER_SENSOR_ARRAY[$key]}; done 305 | fi 306 | 307 | #### 1.4 Download and install micro-ROS: 308 | cd $WORKSPACE 309 | git clone -b $ROS_DISTRO https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup 310 | sudo apt install -y python3-vcstool build-essential 311 | sudo apt update && rosdep update 312 | rosdep install --from-path src --ignore-src -y 313 | colcon build 314 | source $WORKSPACE/install/setup.bash 315 | 316 | #### 1.5 Setup micro-ROS agent: 317 | ros2 run micro_ros_setup create_agent_ws.sh 318 | ros2 run micro_ros_setup build_agent.sh 319 | source $WORKSPACE/install/setup.bash 320 | 321 | #### 2.1 Download linorobot2: 322 | cd $WORKSPACE 323 | git clone -b $ROS_DISTRO https://github.com/linorobot/linorobot2 src/linorobot2 324 | 325 | #### 2.2 Ignore Gazebo Packages on robot computer (optional) 326 | cd $WORKSPACE/src/linorobot2/linorobot2_gazebo 327 | touch COLCON_IGNORE 328 | 329 | #### 2.3 Install linorobot2 package: 330 | cd $WORKSPACE 331 | rosdep update && rosdep install --from-path src --ignore-src -y --skip-keys microxrcedds_agent 332 | colcon build 333 | source $WORKSPACE/install/setup.bash 334 | 335 | ## ENV Variables 336 | if [[ "$BASE" != "ci" ]] 337 | then 338 | ### 1. Robot Type 339 | echo "export LINOROBOT2_BASE=$BASE" >> ~/.bashrc 340 | ### 2. Sensors 341 | if [[ "$LASER_SENSOR" != "-" || "$LASER_SENSOR" != "" ]] 342 | then 343 | echo "export LINOROBOT2_LASER_SENSOR=$LASER_SENSOR" >> ~/.bashrc 344 | fi 345 | 346 | if [[ "$DEPTH_SENSOR" != "-" || "$DEPTH_SENSOR" != "" ]] 347 | then 348 | echo "export LINOROBOT2_DEPTH_SENSOR=$DEPTH_SENSOR" >> ~/.bashrc 349 | fi 350 | echo 351 | echo "Do you want to add sourcing of linorobot2_ws on your ~/.bashrc?" 352 | echo -n "Yes [y] or No [n]: " 353 | read reply 354 | if [[ "$reply" == "y" || "$reply" == "Y" ]] 355 | then 356 | echo "source \$HOME/linorobot2_ws/install/setup.bash" >> ~/.bashrc 357 | else 358 | echo 359 | echo "Remember to run $ source ~/linorobot2_ws/install/setup.bash every time you open a terminal." 360 | fi 361 | fi 362 | 363 | echo 364 | echo "INSTALLATION DONE." 365 | echo 366 | echo "Restart your robot computer now." 367 | -------------------------------------------------------------------------------- /linorobot2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(linorobot2) 3 | find_package(ament_cmake REQUIRED) 4 | ament_package() -------------------------------------------------------------------------------- /linorobot2/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | linorobot2 5 | 0.0.0 6 | Linorobot ROS2 Package 7 | Juan Miguel Jimeno 8 | Apache 2.0 9 | linorobot.org 10 | https://github.com/linorobot/linorobot2 11 | https://github.com/linorobot/linorobot2/issues 12 | ament_cmake 13 | 14 | ament_cmake 15 | 16 | -------------------------------------------------------------------------------- /linorobot2_base/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(linorobot2_base) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | 6 | install( 7 | DIRECTORY config 8 | DESTINATION share/${PROJECT_NAME} 9 | ) 10 | 11 | ament_package() 12 | -------------------------------------------------------------------------------- /linorobot2_base/config/ekf.yaml: -------------------------------------------------------------------------------- 1 | ekf_filter_node: 2 | ros__parameters: 3 | frequency: 50.0 4 | two_d_mode: true 5 | publish_tf: true 6 | 7 | map_frame: map 8 | odom_frame: odom 9 | base_link_frame: base_footprint 10 | world_frame: odom 11 | 12 | #x , y , z, 13 | #roll , pitch , yaw, 14 | #vx , vy , vz, 15 | #vroll , vpitch, vyaw, 16 | #ax , ay , az 17 | odom0: odom/unfiltered 18 | odom0_config: [false, false, false, 19 | false, false, false, 20 | true, true, false, 21 | false, false, true, 22 | false, false, false] 23 | 24 | imu0: imu/data 25 | imu0_config: [false, false, false, 26 | false, false, false, 27 | false, false, false, 28 | false, false, true, 29 | false, false, false] 30 | -------------------------------------------------------------------------------- /linorobot2_base/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | linorobot2_base 5 | 0.0.0 6 | Linorobot2 Base Package 7 | Juan Miguel Jimeno 8 | Apache 2.0 9 | linorobot.org 10 | https://github.com/linorobot/linorobot2 11 | https://github.com/linorobot/linorobot2/issues 12 | ament_cmake 13 | 14 | ament_cmake 15 | 16 | 17 | -------------------------------------------------------------------------------- /linorobot2_bringup/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(linorobot2_bringup) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | 6 | install( 7 | DIRECTORY launch config 8 | DESTINATION share/${PROJECT_NAME} 9 | ) 10 | 11 | ament_package() 12 | -------------------------------------------------------------------------------- /linorobot2_bringup/config/box_laser_filter.yaml: -------------------------------------------------------------------------------- 1 | scan_to_scan_filter_chain: 2 | ros__parameters: 3 | filter1: 4 | name: box_filter 5 | type: laser_filters/LaserScanBoxFilter 6 | params: 7 | box_frame: base_laser 8 | max_x: 12. 9 | max_y: 12. 10 | max_z: 0.5 11 | min_x: 0.0 12 | min_y: -12. 13 | min_z: -0.5 14 | 15 | invert: true # activate to remove all points outside of the box -------------------------------------------------------------------------------- /linorobot2_bringup/config/fake_laser.yaml: -------------------------------------------------------------------------------- 1 | depthimage_to_laserscan: 2 | ros__parameters: 3 | scan_time: 0.033 4 | range_min: 0.45 5 | range_max: 10.0 6 | scan_height: 1 7 | output_frame: camera_link -------------------------------------------------------------------------------- /linorobot2_bringup/config/joy.yaml: -------------------------------------------------------------------------------- 1 | teleop_twist_joy_node: 2 | ros__parameters: 3 | 4 | axis_linear: 5 | x: 1 6 | y: 0 7 | 8 | scale_linear: 9 | x: 0.5 10 | y: 0.5 11 | 12 | axis_angular: 13 | yaw: 3 14 | 15 | scale_angular: 16 | yaw: 1.0 -------------------------------------------------------------------------------- /linorobot2_bringup/config/zed_common.yaml: -------------------------------------------------------------------------------- 1 | # config/common_yaml 2 | # Common parameters to Stereolabs ZED and ZED mini cameras 3 | # 4 | # Note: the parameter svo_file is passed as exe argumet 5 | --- 6 | 7 | /**: 8 | ros__parameters: 9 | general: 10 | svo_file: '' 11 | svo_loop: false # Enable loop mode when using an SVO as input source 12 | svo_realtime: false # if true SVO will be played trying to respect the original framerate eventually skipping frames, otherwise every frame will be processed respecting the `pub_frame_rate` setting 13 | camera_timeout_sec: 5 14 | camera_max_reconnect: 5 15 | camera_flip: false 16 | zed_id: 0 17 | serial_number: 0 18 | resolution: 2 # '0': HD2K, '1': HD1080, '2': HD720, '3': VGA 19 | sdk_verbose: true 20 | grab_frame_rate: 30 # ZED SDK internal grabbing rate 21 | pub_frame_rate: 15.0 # [DYNAMIC] - frequency of publishing of visual images and depth images 22 | gpu_id: -1 23 | 24 | video: 25 | extrinsic_in_camera_frame: false # if `false` extrinsic parameter in `camera_info` will use ROS native frame (X FORWARD, Z UP) instead of the camera frame (Z FORWARD, Y DOWN) [`true` use old behavior as for version < v3.1] 26 | img_downsample_factor: 0.5 # Resample factor for image data matrices [0.01,1.0] The SDK works with native data sizes, but publishes rescaled matrices 27 | brightness: 4 # [DYNAMIC] 28 | contrast: 4 # [DYNAMIC] 29 | hue: 0 # [DYNAMIC] 30 | saturation: 4 # [DYNAMIC] 31 | sharpness: 4 # [DYNAMIC] 32 | gamma: 8 # [DYNAMIC] - Requires SDK >=v3.1 33 | auto_exposure_gain: true # [DYNAMIC] 34 | exposure: 80 # [DYNAMIC] 35 | gain: 80 # [DYNAMIC] 36 | auto_whitebalance: true # [DYNAMIC] 37 | whitebalance_temperature: 42 # [DYNAMIC] - [28,65] works only if `auto_whitebalance` is false 38 | qos_history: 1 # '1': KEEP_LAST - '2': KEEP_ALL 39 | qos_depth: 1 # Queue size if using KEEP_LAST 40 | qos_reliability: 1 # '1': RELIABLE - '2': BEST_EFFORT - 41 | qos_durability: 2 # '1': TRANSIENT_LOCAL - '2': VOLATILE 42 | 43 | depth: 44 | quality: 1 # '0': NONE, '1': PERFORMANCE, '2': QUALITY, '3': ULTRA - Note: if '0' all the modules that requires depth extraction are disabled by default (Pos. Tracking, Obj. Detection, Mapping, ...) 45 | sensing_mode: 0 # '0': STANDARD, '1': FILL 46 | depth_stabilization: true # Forces positional tracking to start if 'true' 47 | openni_depth_mode: false # 'false': 32bit float [meters], 'true': 16bit unsigned int [millimeters] 48 | depth_downsample_factor: 0.5 # Resample factor for depth data matrices [0.01,1.0] The SDK works with native data sizes, but publishes rescaled matrices (depth map, point cloud, ...) 49 | point_cloud_freq: 10.0 # [DYNAMIC] - frequency of the pointcloud publishing (equal or less to `grab_frame_rate` value) 50 | depth_confidence: 50 # [DYNAMIC] 51 | depth_texture_conf: 100 # [DYNAMIC] 52 | qos_history: 1 # '1': KEEP_LAST - '2': KEEP_ALL 53 | qos_depth: 1 # Queue size if using KEEP_LAST 54 | qos_reliability: 1 # '1': RELIABLE - '2': BEST_EFFORT - 55 | qos_durability: 2 # '1': TRANSIENT_LOCAL - '2': VOLATILE 56 | 57 | pos_tracking: 58 | pos_tracking_enabled: false # True to enable positional tracking from start 59 | publish_tf: false # publish `odom -> base_link` TF 60 | publish_map_tf: false # publish `map -> odom` TF 61 | base_frame: 'base_link' # use the same name as in the URDF file 62 | map_frame: 'map' 63 | odometry_frame: 'odom' 64 | area_memory_db_path: '' 65 | area_memory: true # Enable to detect loop closure 66 | floor_alignment: false # Enable to automatically calculate camera/floor offset 67 | initial_base_pose: [0.0,0.0,0.0, 0.0,0.0,0.0] # Initial position of the `base_frame` -> [X, Y, Z, R, P, Y] 68 | init_odom_with_first_valid_pose: true # Enable to initialize the odometry with the first valid pose 69 | path_pub_rate: 2.0 # [DYNAMIC] - Camera trajectory publishing frequency 70 | path_max_count: -1 # use '-1' for unlimited path size 71 | two_d_mode: false # Force navigation on a plane. If true the Z value will be fixed to "fixed_z_value", roll and pitch to zero 72 | fixed_z_value: 0.00 # Value to be used for Z coordinate if `two_d_mode` is true 73 | qos_history: 1 # '1': KEEP_LAST - '2': KEEP_ALL 74 | qos_depth: 1 # Queue size if using KEEP_LAST 75 | qos_reliability: 1 # '1': RELIABLE - '2': BEST_EFFORT - 76 | qos_durability: 2 # '1': TRANSIENT_LOCAL - '2': VOLATILE 77 | 78 | mapping: 79 | mapping_enabled: false # True to enable mapping and fused point cloud pubblication 80 | resolution: 0.1 # maps resolution in meters [0.01f, 0.2f] 81 | max_mapping_range: 20.0 # maximum depth range while mapping in meters (-1 for automatic calculation) [2.0, 20.0] 82 | fused_pointcloud_freq: 0.5 # frequency of the publishing of the fused colored point cloud 83 | qos_history: 1 # '1': KEEP_LAST - '2': KEEP_ALL 84 | qos_depth: 1 # Queue size if using KEEP_LAST 85 | qos_reliability: 1 # '1': RELIABLE - '2': BEST_EFFORT - 86 | qos_durability: 2 # '1': TRANSIENT_LOCAL - '2': VOLATILE 87 | 88 | debug: 89 | debug_general: false 90 | debug_sensors: false -------------------------------------------------------------------------------- /linorobot2_bringup/launch/bringup.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 16 | from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription 17 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution, PythonExpression 18 | from launch.launch_description_sources import PythonLaunchDescriptionSource 19 | from launch_ros.actions import Node 20 | from launch_ros.substitutions import FindPackageShare 21 | from launch.conditions import IfCondition, UnlessCondition 22 | 23 | 24 | def generate_launch_description(): 25 | sensors_launch_path = PathJoinSubstitution( 26 | [FindPackageShare('linorobot2_bringup'), 'launch', 'sensors.launch.py'] 27 | ) 28 | 29 | joy_launch_path = PathJoinSubstitution( 30 | [FindPackageShare('linorobot2_bringup'), 'launch', 'joy_teleop.launch.py'] 31 | ) 32 | 33 | description_launch_path = PathJoinSubstitution( 34 | [FindPackageShare('linorobot2_description'), 'launch', 'description.launch.py'] 35 | ) 36 | 37 | ekf_config_path = PathJoinSubstitution( 38 | [FindPackageShare("linorobot2_base"), "config", "ekf.yaml"] 39 | ) 40 | 41 | default_robot_launch_path = PathJoinSubstitution( 42 | [FindPackageShare('linorobot2_bringup'), 'launch', 'default_robot.launch.py'] 43 | ) 44 | 45 | custom_robot_launch_path = PathJoinSubstitution( 46 | [FindPackageShare('linorobot2_bringup'), 'launch', 'custom_robot.launch.py'] 47 | ) 48 | 49 | extra_launch_path = PathJoinSubstitution( 50 | [FindPackageShare('linorobot2_bringup'), 'launch', 'extra.launch.py'] 51 | ) 52 | 53 | return LaunchDescription([ 54 | DeclareLaunchArgument( 55 | name='custom_robot', 56 | default_value='false', 57 | description='Use custom robot' 58 | ), 59 | 60 | DeclareLaunchArgument( 61 | name='extra', 62 | default_value='false', 63 | description='Launch extra launch file' 64 | ), 65 | 66 | DeclareLaunchArgument( 67 | name='base_serial_port', 68 | default_value='/dev/ttyACM0', 69 | description='Linorobot Base Serial Port' 70 | ), 71 | 72 | DeclareLaunchArgument( 73 | name='micro_ros_transport', 74 | default_value='serial', 75 | description='micro-ROS transport' 76 | ), 77 | 78 | DeclareLaunchArgument( 79 | name='micro_ros_port', 80 | default_value='8888', 81 | description='micro-ROS udp/tcp port number' 82 | ), 83 | 84 | DeclareLaunchArgument( 85 | name='odom_topic', 86 | default_value='/odom', 87 | description='EKF out odometry topic' 88 | ), 89 | 90 | DeclareLaunchArgument( 91 | name='madgwick', 92 | default_value='false', 93 | description='Use madgwick to fuse imu and magnetometer' 94 | ), 95 | 96 | DeclareLaunchArgument( 97 | name='orientation_stddev', 98 | default_value='0.003162278', 99 | description='Madgwick orientation stddev' 100 | ), 101 | 102 | DeclareLaunchArgument( 103 | name='joy', 104 | default_value='false', 105 | description='Use Joystick' 106 | ), 107 | 108 | Node( 109 | condition=IfCondition(LaunchConfiguration("madgwick")), 110 | package='imu_filter_madgwick', 111 | executable='imu_filter_madgwick_node', 112 | name='madgwick_filter_node', 113 | output='screen', 114 | parameters=[{ 115 | 'orientation_stddev' : LaunchConfiguration('orientation_stddev'), 116 | 'publish_tf' : False 117 | }] 118 | ), 119 | 120 | Node( 121 | package='robot_localization', 122 | executable='ekf_node', 123 | name='ekf_filter_node', 124 | output='screen', 125 | parameters=[ 126 | ekf_config_path 127 | ], 128 | remappings=[("odometry/filtered", LaunchConfiguration("odom_topic"))] 129 | ), 130 | 131 | IncludeLaunchDescription( 132 | PythonLaunchDescriptionSource(default_robot_launch_path), 133 | condition=UnlessCondition(LaunchConfiguration("custom_robot")), 134 | launch_arguments={ 135 | 'base_serial_port': LaunchConfiguration("base_serial_port") 136 | }.items() 137 | ), 138 | 139 | IncludeLaunchDescription( 140 | PythonLaunchDescriptionSource(extra_launch_path), 141 | condition=IfCondition(LaunchConfiguration("extra")), 142 | ), 143 | 144 | IncludeLaunchDescription( 145 | PythonLaunchDescriptionSource(custom_robot_launch_path), 146 | condition=IfCondition(LaunchConfiguration("custom_robot")), 147 | ) 148 | ]) 149 | -------------------------------------------------------------------------------- /linorobot2_bringup/launch/custom_robot.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 16 | from launch.actions import IncludeLaunchDescription 17 | from launch.substitutions import PathJoinSubstitution 18 | from launch.launch_description_sources import PythonLaunchDescriptionSource 19 | from launch_ros.actions import Node 20 | from launch_ros.substitutions import FindPackageShare 21 | 22 | 23 | def generate_launch_description(): 24 | sensors_launch_path = PathJoinSubstitution( 25 | [FindPackageShare('linorobot2_bringup'), 'launch', 'sensors.launch.py'] 26 | ) 27 | 28 | description_launch_path = PathJoinSubstitution( 29 | [FindPackageShare('linorobot2_description'), 'launch', 'description.launch.py'] 30 | ) 31 | 32 | return LaunchDescription([ 33 | #run robot driver 34 | #https://github.com/linorobot/sphero_rvr 35 | Node( 36 | package='sphero_rvr', 37 | executable='sphero_node', 38 | name='sphero_node', 39 | output='screen' 40 | ), 41 | #https://github.com/christianrauch/raspicam2_node 42 | Node( 43 | package='raspicam2', 44 | executable='raspicam2_node', 45 | name='raspicam2', 46 | output='screen' 47 | ), 48 | #you can load your custom urdf launcher here 49 | #for demo's sake we'll use the default description launch file 50 | IncludeLaunchDescription( 51 | PythonLaunchDescriptionSource(description_launch_path) 52 | ), 53 | #hardware/sensor specific launch files 54 | #for demo's sake we'll use the default description launch file 55 | IncludeLaunchDescription( 56 | PythonLaunchDescriptionSource(sensors_launch_path), 57 | ) 58 | ]) -------------------------------------------------------------------------------- /linorobot2_bringup/launch/default_robot.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 16 | from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription 17 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution, PythonExpression 18 | from launch.launch_description_sources import PythonLaunchDescriptionSource 19 | from launch_ros.actions import Node 20 | from launch_ros.substitutions import FindPackageShare 21 | from launch.conditions import IfCondition, LaunchConfigurationEquals, LaunchConfigurationNotEquals 22 | 23 | 24 | def generate_launch_description(): 25 | sensors_launch_path = PathJoinSubstitution( 26 | [FindPackageShare('linorobot2_bringup'), 'launch', 'sensors.launch.py'] 27 | ) 28 | 29 | description_launch_path = PathJoinSubstitution( 30 | [FindPackageShare('linorobot2_description'), 'launch', 'description.launch.py'] 31 | ) 32 | 33 | return LaunchDescription([ 34 | DeclareLaunchArgument( 35 | name='base_serial_port', 36 | default_value='/dev/ttyACM0', 37 | description='Linorobot Base Serial Port' 38 | ), 39 | 40 | DeclareLaunchArgument( 41 | name='micro_ros_baudrate', 42 | default_value='115200', 43 | description='micro-ROS baudrate' 44 | ), 45 | 46 | DeclareLaunchArgument( 47 | name='micro_ros_transport', 48 | default_value='serial', 49 | description='micro-ROS transport' 50 | ), 51 | 52 | DeclareLaunchArgument( 53 | name='micro_ros_port', 54 | default_value='8888', 55 | description='micro-ROS udp/tcp port number' 56 | ), 57 | 58 | Node( 59 | condition=LaunchConfigurationEquals('micro_ros_transport', 'serial'), 60 | package='micro_ros_agent', 61 | executable='micro_ros_agent', 62 | name='micro_ros_agent', 63 | output='screen', 64 | arguments=['serial', '--dev', LaunchConfiguration("base_serial_port"), '--baudrate', LaunchConfiguration("micro_ros_baudrate")] 65 | ), 66 | 67 | Node( 68 | condition=LaunchConfigurationEquals('micro_ros_transport', 'udp4'), 69 | package='micro_ros_agent', 70 | executable='micro_ros_agent', 71 | name='micro_ros_agent', 72 | output='screen', 73 | arguments=[LaunchConfiguration('micro_ros_transport'), '--port', LaunchConfiguration('micro_ros_port')] 74 | ), 75 | 76 | IncludeLaunchDescription( 77 | PythonLaunchDescriptionSource(description_launch_path) 78 | ), 79 | IncludeLaunchDescription( 80 | PythonLaunchDescriptionSource(sensors_launch_path), 81 | ) 82 | ]) -------------------------------------------------------------------------------- /linorobot2_bringup/launch/depth.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 17 | from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription 18 | from launch.substitutions import PathJoinSubstitution, PythonExpression, LaunchConfiguration 19 | from launch.launch_description_sources import PythonLaunchDescriptionSource 20 | from launch_ros.substitutions import FindPackageShare 21 | from launch.conditions import IfCondition, LaunchConfigurationEquals 22 | from launch_ros.actions import Node 23 | 24 | 25 | def generate_launch_description(): 26 | zed_sensors = ['zed', 'zed2', 'zed2i', 'zedm'] 27 | zed_common_config_path = PathJoinSubstitution( 28 | [FindPackageShare('linorobot2_bringup'), 'config', 'zed_common.yaml'] 29 | ) 30 | 31 | oakd_sensors = ['oakd', 'oakdlite', 'oakdpro'] 32 | to_oakd_vars = { 33 | "oakd": "OAK-D", 34 | "oakdlite": "OAK-D-LITE", 35 | "oakdpro": "OAK-D-PRO" 36 | } 37 | return LaunchDescription([ 38 | DeclareLaunchArgument( 39 | name='sensor', 40 | default_value='realsense', 41 | description='Sensor to launch' 42 | ), 43 | 44 | IncludeLaunchDescription( 45 | PythonLaunchDescriptionSource(PathJoinSubstitution( 46 | [FindPackageShare('realsense2_camera'), 'launch', 'rs_launch.py'] 47 | )), 48 | condition=LaunchConfigurationEquals('sensor', 'realsense'), 49 | launch_arguments={ 50 | 'pointcloud.enable': 'true', 51 | 'ordered_pc': 'true', 52 | 'initial_reset': 'true' 53 | }.items() 54 | ), 55 | 56 | IncludeLaunchDescription( 57 | PythonLaunchDescriptionSource(PathJoinSubstitution( 58 | [FindPackageShare('zed_wrapper'), 'launch/include', 'zed_camera.launch.py'] 59 | )), 60 | condition=IfCondition(PythonExpression(['"', LaunchConfiguration('sensor'), '" in "', str(zed_sensors), '"'])), 61 | launch_arguments={ 62 | 'camera_model': LaunchConfiguration('sensor'), 63 | 'config_common_path': zed_common_config_path, 64 | 'camera_name': '', 65 | 'node_name': 'zed', 66 | 'publish_urdf': 'true', 67 | 'base_frame': 'camera_link' 68 | }.items() 69 | ), 70 | 71 | IncludeLaunchDescription( 72 | PythonLaunchDescriptionSource(PathJoinSubstitution( 73 | [FindPackageShare('depthai_examples'), 'launch', 'stereo.launch.py'] 74 | )), 75 | condition=IfCondition(PythonExpression(['"', LaunchConfiguration('sensor'), '" in "', str(oakd_sensors), '"'])), 76 | launch_arguments={ 77 | 'camera_model': to_oakd_vars.get(LaunchConfiguration('sensor'), None), 78 | }.items() 79 | ), 80 | ]) 81 | 82 | -------------------------------------------------------------------------------- /linorobot2_bringup/launch/extra.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 16 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 17 | from launch_ros.substitutions import FindPackageShare 18 | from launch_ros.actions import Node, SetRemap 19 | from launch.actions import IncludeLaunchDescription, GroupAction 20 | from launch.launch_description_sources import PythonLaunchDescriptionSource 21 | 22 | 23 | def generate_launch_description(): 24 | 25 | laser_filter_config_path = PathJoinSubstitution( 26 | [FindPackageShare('linorobot2_bringup'), 'config', 'box_laser_filter.yaml'] 27 | ) 28 | 29 | laser_launch_path = PathJoinSubstitution( 30 | [FindPackageShare('linorobot2_bringup'), 'launch', 'lasers.launch.py'] 31 | ) 32 | 33 | return LaunchDescription([ 34 | Node( 35 | package='ldlidar', 36 | executable='ldlidar', 37 | name='ldlidar', 38 | output='screen', 39 | parameters=[ 40 | {'serial_port': '/dev/ttyUSB1'}, 41 | {'topic_name': '/base/scan/unfiltered'}, 42 | {'lidar_frame': 'base_laser'}, 43 | {'range_threshold': 0.005} 44 | ] 45 | ), 46 | Node( 47 | package="laser_filters", 48 | executable="scan_to_scan_filter_chain", 49 | parameters=[ 50 | laser_filter_config_path 51 | ], 52 | remappings=[ 53 | ('/scan', '/base/scan/unfiltered'), 54 | ('/scan_filtered', '/base/scan') 55 | ] 56 | ) 57 | ]) 58 | 59 | -------------------------------------------------------------------------------- /linorobot2_bringup/launch/joy_teleop.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 17 | from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription 18 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 19 | from launch.launch_description_sources import PythonLaunchDescriptionSource 20 | from launch_ros.substitutions import FindPackageShare 21 | from launch_ros.actions import Node 22 | 23 | 24 | def generate_launch_description(): 25 | joy_config_path = PathJoinSubstitution( 26 | [FindPackageShare("linorobot2_bringup"), "config", "joy.yaml"] 27 | ) 28 | 29 | return LaunchDescription([ 30 | Node( 31 | package='joy_linux', 32 | executable='joy_linux_node', 33 | name='joy_linux_node', 34 | output='screen', 35 | ), 36 | 37 | Node( 38 | package='teleop_twist_joy', 39 | executable='teleop_node', 40 | name='teleop_twist_joy_node', 41 | output='screen', 42 | parameters=[joy_config_path] 43 | ) 44 | ]) -------------------------------------------------------------------------------- /linorobot2_bringup/launch/lasers.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 16 | from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, OpaqueFunction 17 | from launch.launch_description_sources import PythonLaunchDescriptionSource 18 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 19 | from launch_ros.substitutions import FindPackageShare 20 | from launch.conditions import LaunchConfigurationEquals 21 | from launch_ros.actions import Node 22 | 23 | 24 | def launch_rplidar(context, *args, **kwargs): 25 | lidar_str = context.perform_substitution(LaunchConfiguration('sensor')) 26 | rplidar_sensors = [ 27 | 'a1', 28 | 'a2', 29 | 'a3', 30 | 'c1', 31 | 's1', 32 | 's2', 33 | 's3', 34 | ] 35 | 36 | if lidar_str in rplidar_sensors: 37 | launch_file = f'sllidar_{lidar_str}_launch.py' 38 | return [IncludeLaunchDescription( 39 | PythonLaunchDescriptionSource(PathJoinSubstitution( 40 | [FindPackageShare('sllidar_ros2'), 'launch', launch_file] 41 | )), 42 | launch_arguments={ 43 | 'serial_port': '/dev/rplidar', 44 | 'frame_id': LaunchConfiguration('frame_id'), 45 | }.items() 46 | )] 47 | else: 48 | return [] 49 | 50 | def generate_launch_description(): 51 | lidar_options =[ 52 | 'rplidar', 53 | 'ldlidar', 54 | 'ld06', 55 | 'ld19', 56 | 'stl27l', 57 | 'ydlidar', 58 | 'xv11', 59 | 'a1', 60 | 'a2', 61 | 'a3', 62 | 'c1', 63 | 's1', 64 | 's2', 65 | 's3', 66 | ] 67 | 68 | return LaunchDescription([ 69 | DeclareLaunchArgument( 70 | name='sensor', 71 | default_value='ydlidar', 72 | description='Sensor to launch', 73 | choices=lidar_options 74 | ), 75 | 76 | DeclareLaunchArgument( 77 | name='topic_name', 78 | default_value='scan', 79 | description='Laser Topic Name' 80 | ), 81 | 82 | DeclareLaunchArgument( 83 | name='frame_id', 84 | default_value='laser', 85 | description='Laser Frame ID' 86 | ), 87 | 88 | DeclareLaunchArgument( 89 | name='lidar_transport', 90 | default_value='serial', 91 | description='Lidar transport: serial, udp_server, udp_client, tcp_server, tcp_client' 92 | ), 93 | 94 | DeclareLaunchArgument( 95 | name='lidar_serial_port', 96 | default_value='/dev/ttyUSB0', 97 | description='Lidar serial port device name' 98 | ), 99 | 100 | DeclareLaunchArgument( 101 | name='lidar_server_ip', 102 | default_value='0.0.0.0', 103 | description='Lidar server ip' 104 | ), 105 | 106 | DeclareLaunchArgument( 107 | name='lidar_server_port', 108 | default_value='8889', 109 | description='Lidar server port number' 110 | ), 111 | 112 | Node( 113 | condition=LaunchConfigurationEquals('sensor', 'ydlidar'), 114 | package='ydlidar_ros2_driver', 115 | executable='ydlidar_ros2_driver_node', 116 | name='ydlidar_ros2_driver_node', 117 | output='screen', 118 | emulate_tty=True, 119 | remappings=[('scan', LaunchConfiguration('topic_name'))], 120 | parameters=[{ 121 | 'port': '/dev/ydlidar', 122 | 'frame_id': LaunchConfiguration('frame_id'), 123 | 'ignore_array': '', 124 | 'baudrate': 128000, 125 | 'lidar_type': 1, 126 | 'device_type': 6, 127 | 'sample_rate': 5, 128 | 'abnormal_check_count': 4, 129 | 'fixed_resolution': True, 130 | 'reversion': False, 131 | 'inverted': True, 132 | 'auto_reconnect': True, 133 | 'isSingleChannel': False, 134 | 'intensity': False, 135 | 'support_motor_dtr': True, 136 | 'angle_max': 180.0, 137 | 'angle_min': -180.0, 138 | 'range_max': 10.0, 139 | 'range_min': 0.12, 140 | 'frequency': 5.0, 141 | 'invalid_range_is_inf': False 142 | }] 143 | ), 144 | 145 | # Node( 146 | # condition=LaunchConfigurationEquals('sensor', 'rplidar'), 147 | # name='rplidar_composition', 148 | # package='rplidar_ros', 149 | # executable='rplidar_composition', 150 | # output='screen', 151 | # remappings=[('scan', LaunchConfiguration('topic_name'))], 152 | # parameters=[{ 153 | # 'serial_port': '/dev/ttyUSB0', 154 | # 'serial_baudrate': 115200, # A1 / A2 155 | # 'frame_id': LaunchConfiguration('frame_id'), 156 | # 'inverted': False, 157 | # 'angle_compensate': True, 158 | # }], 159 | # ), 160 | 161 | Node( 162 | condition=LaunchConfigurationEquals('sensor', 'xv11'), 163 | name='xv_11_driver', 164 | package='xv_11_driver', 165 | executable='xv_11_driver', 166 | output='screen', 167 | remappings=[('scan', LaunchConfiguration('topic_name'))], 168 | parameters=[{ 169 | 'port': '/dev/ttyACM0', 170 | 'baud_rate': 115200, 171 | 'frame_id': LaunchConfiguration('frame_id'), 172 | 'firmware_version': 2 173 | }], 174 | ), 175 | 176 | Node( 177 | condition=LaunchConfigurationEquals('sensor', 'ldlidar'), 178 | package='ldlidar', 179 | executable='ldlidar', 180 | name='ldlidar', 181 | output='screen', 182 | parameters=[ 183 | {'serial_port': '/dev/ttyUSB0'}, 184 | {'topic_name': LaunchConfiguration('topic_name')}, 185 | {'lidar_frame': LaunchConfiguration('frame_id')}, 186 | {'range_threshold': 0.005} 187 | ] 188 | ), 189 | 190 | Node( 191 | condition=LaunchConfigurationEquals('sensor', 'ld06'), 192 | package='ldlidar_stl_ros2', 193 | executable='ldlidar_stl_ros2_node', 194 | name='ld06', 195 | output='screen', 196 | parameters=[ 197 | {'product_name': 'LDLiDAR_LD06'}, 198 | {'topic_name': LaunchConfiguration('topic_name')}, 199 | {'frame_id': LaunchConfiguration('frame_id')}, 200 | {'comm_mode': LaunchConfiguration('lidar_transport')}, 201 | {'port_name': LaunchConfiguration('lidar_serial_port')}, 202 | {'port_baudrate': 230400}, 203 | {'server_ip': LaunchConfiguration('lidar_server_ip')}, 204 | {'server_port': LaunchConfiguration('lidar_server_port')}, 205 | {'laser_scan_dir': True}, 206 | {'bins': 456}, 207 | {'enable_angle_crop_func': False}, 208 | {'angle_crop_min': 135.0}, 209 | {'angle_crop_max': 225.0} 210 | ] 211 | ), 212 | 213 | Node( 214 | condition=LaunchConfigurationEquals('sensor', 'ld19'), 215 | package='ldlidar_stl_ros2', 216 | executable='ldlidar_stl_ros2_node', 217 | name='ld19', 218 | output='screen', 219 | parameters=[ 220 | {'product_name': 'LDLiDAR_LD19'}, 221 | {'topic_name': LaunchConfiguration('topic_name')}, 222 | {'frame_id': LaunchConfiguration('frame_id')}, 223 | {'comm_mode': LaunchConfiguration('lidar_transport')}, 224 | {'port_name': LaunchConfiguration('lidar_serial_port')}, 225 | {'port_baudrate': 230400}, 226 | {'server_ip': LaunchConfiguration('lidar_server_ip')}, 227 | {'server_port': LaunchConfiguration('lidar_server_port')}, 228 | {'laser_scan_dir': True}, 229 | {'bins': 456}, 230 | {'enable_angle_crop_func': False}, 231 | {'angle_crop_min': 135.0}, 232 | {'angle_crop_max': 225.0} 233 | ] 234 | ), 235 | 236 | Node( 237 | condition=LaunchConfigurationEquals('sensor', 'stl27l'), 238 | package='ldlidar_stl_ros2', 239 | executable='ldlidar_stl_ros2_node', 240 | name='stl27l', 241 | output='screen', 242 | parameters=[ 243 | {'product_name': 'LDLiDAR_STL27L'}, 244 | {'topic_name': LaunchConfiguration('topic_name')}, 245 | {'frame_id': LaunchConfiguration('frame_id')}, 246 | {'comm_mode': LaunchConfiguration('lidar_transport')}, 247 | {'port_name': LaunchConfiguration('lidar_serial_port')}, 248 | {'port_baudrate': 921600}, 249 | {'server_ip': LaunchConfiguration('lidar_server_ip')}, 250 | {'server_port': LaunchConfiguration('lidar_server_port')}, 251 | {'laser_scan_dir': True}, 252 | {'bins': 2160}, 253 | {'enable_angle_crop_func': False}, 254 | {'angle_crop_min': 135.0}, 255 | {'angle_crop_max': 225.0} 256 | ] 257 | ), 258 | OpaqueFunction(function=launch_rplidar) 259 | ]) 260 | 261 | -------------------------------------------------------------------------------- /linorobot2_bringup/launch/sensors.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 17 | from launch.actions import IncludeLaunchDescription, GroupAction 18 | from launch.substitutions import PathJoinSubstitution, PythonExpression 19 | from launch.launch_description_sources import PythonLaunchDescriptionSource 20 | from launch_ros.substitutions import FindPackageShare 21 | from launch.conditions import IfCondition 22 | from launch_ros.actions import Node, SetRemap 23 | 24 | 25 | def generate_launch_description(): 26 | laser_sensor_name = os.getenv('LINOROBOT2_LASER_SENSOR', '') 27 | depth_sensor_name = os.getenv('LINOROBOT2_DEPTH_SENSOR', '') 28 | 29 | fake_laser_config_path = PathJoinSubstitution( 30 | [FindPackageShare('linorobot2_bringup'), 'config', 'fake_laser.yaml'] 31 | ) 32 | 33 | #indices 34 | #0 - depth topic (str) 35 | #1 - depth info topic (str) 36 | depth_topics = { 37 | '': ['', '', '', {}, '', ''], 38 | 'realsense': ['/camera/depth/image_rect_raw', '/camera/depth/camera_info'], 39 | 'astra': ['/depth/rgb/ir', '/camera_info'], 40 | 'zed': ['/zed/depth/depth_registered', '/zed/depth/camera_info'], 41 | 'zed2': ['/zed/depth/depth_registered', '/zed/depth/camera_info'], 42 | 'zed2i': ['/zed/depth/depth_registered', '/zed/depth/camera_info'], 43 | 'zedm': ['/zed/depth/depth_registered', '/zed/depth/camera_info'], 44 | 'oakd': ['/right/image_rect', '/right/camera_info'], 45 | 'oakdlite': ['/right/image_rect', '/right/camera_info'], 46 | 'oakdpro': ['/right/image_rect', '/right/camera_info'], 47 | } 48 | 49 | point_cloud_topics = { 50 | '': '', 51 | 'realsense': '/camera/depth/color/points', 52 | 'astra': '/camera/depth/points', 53 | 'zed': '/zed/point_cloud/cloud_registered', 54 | 'zed2': '/zed/point_cloud/cloud_registered', 55 | 'zed2i': '/zed/point_cloud/cloud_registered', 56 | 'zedm': '/zed/point_cloud/cloud_registered', 57 | 'oakd': '/stereo/points', 58 | 'oakdlite': '/stereo/points', 59 | 'oakdpro': '/stereo/points', 60 | } 61 | 62 | laser_launch_path = PathJoinSubstitution( 63 | [FindPackageShare('linorobot2_bringup'), 'launch', 'lasers.launch.py'] 64 | ) 65 | 66 | depth_launch_path = PathJoinSubstitution( 67 | [FindPackageShare('linorobot2_bringup'), 'launch', 'depth.launch.py'] 68 | ) 69 | 70 | return LaunchDescription([ 71 | GroupAction( 72 | actions=[ 73 | SetRemap(src=point_cloud_topics[depth_sensor_name], dst='/camera/depth/color/points'), 74 | IncludeLaunchDescription( 75 | PythonLaunchDescriptionSource(depth_launch_path), 76 | condition=IfCondition(PythonExpression(['"" != "', depth_sensor_name, '"'])), 77 | launch_arguments={'sensor': depth_sensor_name}.items() 78 | ) 79 | ] 80 | ), 81 | IncludeLaunchDescription( 82 | PythonLaunchDescriptionSource(laser_launch_path), 83 | condition=IfCondition(PythonExpression(['"" != "', laser_sensor_name, '"'])), 84 | launch_arguments={ 85 | 'sensor': laser_sensor_name 86 | }.items() 87 | ), 88 | Node( 89 | condition=IfCondition(PythonExpression(['"" != "', laser_sensor_name, '" and ', '"', laser_sensor_name, '" in "', str(list(depth_topics.keys())[1:]), '"'])), 90 | package='depthimage_to_laserscan', 91 | executable='depthimage_to_laserscan_node', 92 | remappings=[('depth', depth_topics[depth_sensor_name][0]), 93 | ('depth_camera_info', depth_topics[depth_sensor_name][1])], 94 | parameters=[fake_laser_config_path] 95 | ) 96 | ]) 97 | 98 | -------------------------------------------------------------------------------- /linorobot2_bringup/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | linorobot2_bringup 5 | 0.0.0 6 | Linorobot2 Bringup Files 7 | Juan Miguel Jimeno 8 | Apache 2.0 9 | linorobot.org 10 | https://github.com/linorobot/linorobot2 11 | https://github.com/linorobot/linorobot2/issues 12 | ament_cmake 13 | imu_tools 14 | robot_localization 15 | joy_linux 16 | teleop_twist_joy 17 | teleop_twist_keyboard 18 | micro_ros_agent 19 | depthimage_to_laserscan 20 | laser_filters 21 | rqt_image_view 22 | image_proc 23 | depth_image_proc 24 | 25 | ament_cmake 26 | 27 | 28 | -------------------------------------------------------------------------------- /linorobot2_description/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(linorobot2_description) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(urdf REQUIRED) 6 | 7 | install( 8 | DIRECTORY launch urdf rviz 9 | DESTINATION share/${PROJECT_NAME} 10 | ) 11 | 12 | ament_package() 13 | -------------------------------------------------------------------------------- /linorobot2_description/launch/description.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 17 | from launch.actions import DeclareLaunchArgument 18 | from launch.substitutions import LaunchConfiguration, Command, PathJoinSubstitution, EnvironmentVariable 19 | from launch.conditions import IfCondition 20 | from launch_ros.actions import Node 21 | from launch_ros.substitutions import FindPackageShare 22 | 23 | 24 | def generate_launch_description(): 25 | robot_base = os.getenv('LINOROBOT2_BASE') 26 | 27 | urdf_path = PathJoinSubstitution( 28 | [FindPackageShare("linorobot2_description"), "urdf/robots", f"{robot_base}.urdf.xacro"] 29 | ) 30 | 31 | rviz_config_path = PathJoinSubstitution( 32 | [FindPackageShare('linorobot2_description'), 'rviz', 'description.rviz'] 33 | ) 34 | 35 | return LaunchDescription([ 36 | DeclareLaunchArgument( 37 | name='urdf', 38 | default_value=urdf_path, 39 | description='URDF path' 40 | ), 41 | 42 | DeclareLaunchArgument( 43 | name='publish_joints', 44 | default_value='true', 45 | description='Launch joint_states_publisher' 46 | ), 47 | 48 | DeclareLaunchArgument( 49 | name='rviz', 50 | default_value='false', 51 | description='Run rviz' 52 | ), 53 | 54 | DeclareLaunchArgument( 55 | name='use_sim_time', 56 | default_value='false', 57 | description='Use simulation time' 58 | ), 59 | 60 | Node( 61 | package='joint_state_publisher', 62 | executable='joint_state_publisher', 63 | name='joint_state_publisher', 64 | condition=IfCondition(LaunchConfiguration("publish_joints")), 65 | parameters=[ 66 | {'use_sim_time': LaunchConfiguration('use_sim_time')} 67 | ] 68 | ), 69 | 70 | Node( 71 | package='robot_state_publisher', 72 | executable='robot_state_publisher', 73 | name='robot_state_publisher', 74 | output='screen', 75 | parameters=[ 76 | { 77 | 'use_sim_time': LaunchConfiguration('use_sim_time'), 78 | 'robot_description': Command(['xacro ', LaunchConfiguration('urdf')]) 79 | } 80 | ] 81 | ), 82 | 83 | Node( 84 | package='rviz2', 85 | executable='rviz2', 86 | name='rviz2', 87 | output='screen', 88 | arguments=['-d', rviz_config_path], 89 | condition=IfCondition(LaunchConfiguration("rviz")), 90 | parameters=[{'use_sim_time': LaunchConfiguration('use_sim_time')}] 91 | ) 92 | ]) 93 | 94 | #sources: 95 | #https://navigation.ros.org/setup_guides/index.html# 96 | #https://answers.ros.org/question/374976/ros2-launch-gazebolaunchpy-from-my-own-launch-file/ 97 | #https://github.com/ros2/rclcpp/issues/940 -------------------------------------------------------------------------------- /linorobot2_description/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | linorobot2_description 5 | 0.0.0 6 | Linorobot2 Description Package 7 | Juan Miguel Jimeno 8 | Apache 2.0 9 | linorobot.org 10 | https://github.com/linorobot/linorobot2 11 | https://github.com/linorobot/linorobot2/issues 12 | ament_cmake 13 | joint_state_publisher 14 | robot_state_publisher 15 | rviz2 16 | xacro 17 | 18 | ament_cmake 19 | 20 | 21 | -------------------------------------------------------------------------------- /linorobot2_description/rviz/description.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz_common/Displays 3 | Help Height: 78 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: ~ 7 | Splitter Ratio: 0.5 8 | Tree Height: 907 9 | Visualization Manager: 10 | Class: "" 11 | Displays: 12 | - Alpha: 0.5 13 | Cell Size: 1 14 | Class: rviz_default_plugins/Grid 15 | Color: 160; 160; 164 16 | Enabled: true 17 | Line Style: 18 | Line Width: 0.029999999329447746 19 | Value: Lines 20 | Name: Grid 21 | Normal Cell Count: 0 22 | Offset: 23 | X: 0 24 | Y: 0 25 | Z: 0 26 | Plane: XY 27 | Plane Cell Count: 10 28 | Reference Frame: 29 | Value: true 30 | - Alpha: 0.8999999761581421 31 | Class: rviz_default_plugins/RobotModel 32 | Collision Enabled: false 33 | Description File: "" 34 | Description Source: Topic 35 | Description Topic: 36 | Depth: 5 37 | Durability Policy: Volatile 38 | History Policy: Keep Last 39 | Reliability Policy: Reliable 40 | Value: /robot_description 41 | Enabled: true 42 | Links: 43 | All Links Enabled: true 44 | Expand Joint Details: false 45 | Expand Link Details: false 46 | Expand Tree: false 47 | Link Tree Style: Links in Alphabetic Order 48 | base_footprint: 49 | Alpha: 1 50 | Show Axes: false 51 | Show Trail: false 52 | base_link: 53 | Alpha: 1 54 | Show Axes: false 55 | Show Trail: false 56 | Value: true 57 | camera_link: 58 | Alpha: 1 59 | Show Axes: false 60 | Show Trail: false 61 | Value: true 62 | front_left_wheel_link: 63 | Alpha: 1 64 | Show Axes: false 65 | Show Trail: false 66 | Value: true 67 | front_right_wheel_link: 68 | Alpha: 1 69 | Show Axes: false 70 | Show Trail: false 71 | Value: true 72 | imu_link: 73 | Alpha: 1 74 | Show Axes: false 75 | Show Trail: false 76 | laser: 77 | Alpha: 1 78 | Show Axes: false 79 | Show Trail: false 80 | Value: true 81 | rear_left_wheel_link: 82 | Alpha: 1 83 | Show Axes: false 84 | Show Trail: false 85 | Value: true 86 | rear_right_wheel_link: 87 | Alpha: 1 88 | Show Axes: false 89 | Show Trail: false 90 | Value: true 91 | Name: RobotModel 92 | TF Prefix: "" 93 | Update Interval: 0 94 | Value: true 95 | Visual Enabled: true 96 | - Class: rviz_default_plugins/TF 97 | Enabled: true 98 | Frame Timeout: 15 99 | Frames: 100 | All Enabled: true 101 | base_footprint: 102 | Value: true 103 | base_link: 104 | Value: true 105 | camera_link: 106 | Value: true 107 | front_left_wheel_link: 108 | Value: true 109 | front_right_wheel_link: 110 | Value: true 111 | imu_link: 112 | Value: true 113 | laser: 114 | Value: true 115 | rear_left_wheel_link: 116 | Value: true 117 | rear_right_wheel_link: 118 | Value: true 119 | Marker Scale: 0.10000000149011612 120 | Name: TF 121 | Show Arrows: true 122 | Show Axes: true 123 | Show Names: true 124 | Tree: 125 | base_footprint: 126 | base_link: 127 | camera_link: 128 | {} 129 | front_left_wheel_link: 130 | {} 131 | front_right_wheel_link: 132 | {} 133 | imu_link: 134 | {} 135 | laser: 136 | {} 137 | rear_left_wheel_link: 138 | {} 139 | rear_right_wheel_link: 140 | {} 141 | Update Interval: 0 142 | Value: true 143 | - Class: rviz_default_plugins/Axes 144 | Enabled: true 145 | Length: 1 146 | Name: Axes 147 | Radius: 0.0010000000474974513 148 | Reference Frame: 149 | Value: true 150 | Enabled: true 151 | Global Options: 152 | Background Color: 238; 238; 236 153 | Fixed Frame: base_footprint 154 | Frame Rate: 30 155 | Name: root 156 | Tools: 157 | - Class: rviz_default_plugins/Interact 158 | Hide Inactive Objects: true 159 | - Class: rviz_default_plugins/MoveCamera 160 | - Class: rviz_default_plugins/Select 161 | - Class: rviz_default_plugins/FocusCamera 162 | - Class: rviz_default_plugins/Measure 163 | Line color: 128; 128; 0 164 | Transformation: 165 | Current: 166 | Class: rviz_default_plugins/TF 167 | Value: true 168 | Views: 169 | Current: 170 | Class: rviz_default_plugins/Orbit 171 | Distance: 0.6006462574005127 172 | Enable Stereo Rendering: 173 | Stereo Eye Separation: 0.05999999865889549 174 | Stereo Focal Distance: 1 175 | Swap Stereo Eyes: false 176 | Value: false 177 | Focal Point: 178 | X: 0 179 | Y: 0 180 | Z: 0 181 | Focal Shape Fixed Size: true 182 | Focal Shape Size: 0.05000000074505806 183 | Invert Z Axis: false 184 | Name: Current View 185 | Near Clip Distance: 0.009999999776482582 186 | Pitch: 0.4653983414173126 187 | Target Frame: 188 | Value: Orbit (rviz) 189 | Yaw: 0.7553982138633728 190 | Saved: ~ 191 | Window Geometry: 192 | Displays: 193 | collapsed: false 194 | Height: 1136 195 | Hide Left Dock: false 196 | Hide Right Dock: false 197 | QMainWindow State: 000000ff00000000fd00000001000000000000015600000416fc0200000001fb000000100044006900730070006c006100790073010000003d00000416000000c900ffffff000005f40000041600000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 198 | Width: 1872 199 | X: 48 200 | Y: 27 201 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/2wd_properties.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/4wd_properties.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/controllers/diff_drive.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | odom:=odom/unfiltered 7 | 8 | 100 9 | left_wheel_joint 10 | right_wheel_joint 11 | ${wheel_separation} 12 | ${wheel_radius * 2} 13 | 1.0 14 | base_footprint 15 | true 16 | false 17 | true 18 | odom 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/controllers/omni_drive.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | odom:=odom/unfiltered 7 | 8 | cmd_vel 9 | odom/unfiltered 10 | odom 11 | 20.0 12 | base_footprint 13 | true 14 | false 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/controllers/skid_steer.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | odom:=odom/unfiltered 7 | 8 | 9 | 2 10 | front_left_wheel_joint 11 | front_right_wheel_joint 12 | rear_left_wheel_joint 13 | rear_right_wheel_joint 14 | 15 | ${wheel_separation} 16 | ${wheel_separation} 17 | ${wheel_radius * 2} 18 | ${wheel_radius * 2} 19 | 20 | 100 21 | 1.0 22 | base_footprint 23 | true 24 | false 25 | true 26 | odom 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/mecanum_properties.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/mech/base.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 0.8392 0.6314 0.0 1.0 38 | 0.8392 0.6314 0.0 1.0 39 | 0.99 0.99 0.99 1.0 40 | 0.0 0.0 0.0 0.0 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/mech/caster_wheel.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 0.01 42 | 0.01 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/mech/mecanum_wheel.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 0.01 32 | 0.01 33 | 34 | 35 | 36 | 37 | 38 | 0.1764 0.4588 0.8509 1.0 39 | 0.1764 0.4588 0.8509 1.0 40 | 0.1764 0.4588 0.8509 1.0 41 | 0.0 0.0 0.0 0.0 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/mech/wheel.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 0.1764 0.4588 0.8509 1.0 33 | 0.1764 0.4588 0.8509 1.0 34 | 0.1764 0.4588 0.8509 1.0 35 | 0.0 0.0 0.0 0.0 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/robots/2wd.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 22 | 23 | 32 | 33 | 42 | 43 | 44 | 51 | 52 | 53 | 54 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 77 | 78 | 79 | 80 | 85 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/robots/4wd.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 21 | 22 | 31 | 32 | 41 | 50 | 51 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 75 | 76 | 77 | 78 | 83 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/robots/mecanum.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 21 | 22 | 31 | 32 | 41 | 50 | 51 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/robots/turtlebot.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 | 43 | 52 | 53 | 62 | 63 | 64 | 71 | 72 | 73 | 74 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 98 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/robots/vattenkar.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 46 | 47 | 56 | 57 | 66 | 67 | 68 | 75 | 76 | 77 | 78 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 106 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/sensors/camera.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 0.051 0.047 0.416 1.0 35 | 0.051 0.047 0.416 1.0 36 | 0.051 0.047 0.416 1.0 37 | 0.051 0.047 0.416 1.0 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | true 59 | 30.0 60 | 61 | 1.50098 62 | 63 | 640 64 | 480 65 | R8G8B8 66 | 67 | 68 | 69 | 70 | ${name}/image_raw:=${topic_name} 71 | 72 | 0.07 73 | ${name}_optical_link 74 | 0.00000001 75 | 0.00000001 76 | 0.00000001 77 | 0.00000001 78 | 0.00000001 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/sensors/depth_sensor.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 0.416 0.051 0.047 1.0 36 | 0.416 0.051 0.047 1.0 37 | 0.416 0.051 0.047 1.0 38 | 0.416 0.051 0.047 1.0 39 | 40 | 41 | rgb(213,28,40) 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | true 60 | 30.0 61 | 62 | 1.50098 63 | 64 | 640 65 | 480 66 | R8G8B8 67 | 68 | 69 | 70 | 71 | /camera/camera_info:=/camera/color/camera_info 72 | /camera/image_raw:=/camera/color/image_raw 73 | /camera/points:=/camera/depth/color/points 74 | /camera/depth/image_raw:=/camera/depth/image_rect_raw 75 | 76 | 77 | 78 | best_effort 79 | 80 | 81 | 82 | 83 | 0.015 84 | 3.0 85 | 0.07 86 | camera_depth_link 87 | 0.00000001 88 | 0.00000001 89 | 0.00000001 90 | 0.00000001 91 | 0.00000001 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/sensors/generic_laser.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 18 | 19 | 20 | 21 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/sensors/imu.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | true 13 | 14 | true 15 | 20 16 | true 17 | __default_topic__ 18 | 19 | 20 | ~/out:=imu/data 21 | 22 | imu/data 23 | imu_link 24 | 10.0 25 | 0.0 26 | 0 0 0 27 | 0 0 0 28 | imu_link 29 | false 30 | 31 | 0 0 0 0 0 0 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /linorobot2_description/urdf/sensors/laser.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 0.003 0.639 0.223 1.0 34 | 0.003 0.639 0.223 1.0 35 | 0.003 0.639 0.223 1.0 36 | 0.0 0.0 0.0 0.0 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | true 50 | ${update_rate} 51 | 0 0 0 0 0 0 52 | false 53 | 54 | 55 | 56 | ${ray_count} 57 | 1 58 | ${min_angle} 59 | ${max_angle} 60 | 61 | 62 | 63 | ${min_range} 64 | ${max_range} 65 | 0.01 66 | 67 | 68 | 69 | 70 | ~/out:=${topic_name} 71 | 72 | sensor_msgs/LaserScan 73 | true 74 | ${update_rate} 75 | ${topic_name} 76 | ${frame_id} 77 | sensor_msgs/LaserScan 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /linorobot2_gazebo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(linorobot2_gazebo) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(ament_cmake_python REQUIRED) 6 | find_package(rclpy REQUIRED) 7 | 8 | execute_process( 9 | COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/scripts/map2gazebo.py 10 | --map_dir ${CMAKE_CURRENT_SOURCE_DIR}/../linorobot2_navigation/maps 11 | --model_dir ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/models 12 | --world_dir ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/worlds 13 | RESULT_VARIABLE SCRIPT_RESULT 14 | OUTPUT_VARIABLE SCRIPT_OUTPUT 15 | ) 16 | 17 | if(NOT SCRIPT_RESULT EQUAL 0) 18 | message(WARNING "Python script execution failed with error code: ${SCRIPT_RESULT}") 19 | message(WARNING "Script output: ${SCRIPT_OUTPUT}") 20 | endif() 21 | 22 | install( 23 | DIRECTORY launch rviz worlds 24 | DESTINATION share/${PROJECT_NAME} 25 | ) 26 | 27 | install(PROGRAMS 28 | scripts/command_timeout.py 29 | DESTINATION lib/${PROJECT_NAME} 30 | ) 31 | 32 | ament_environment_hooks("${CMAKE_CURRENT_SOURCE_DIR}/env-hooks/linorobot2_gazebo.sh.in") 33 | ament_package() -------------------------------------------------------------------------------- /linorobot2_gazebo/env-hooks/linorobot2_gazebo.sh.in: -------------------------------------------------------------------------------- 1 | ament_prepend_unique_value GAZEBO_MODEL_PATH "$COLCON_CURRENT_PREFIX/share/linorobot2_gazebo/models" 2 | -------------------------------------------------------------------------------- /linorobot2_gazebo/launch/gazebo.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 17 | from launch.actions import DeclareLaunchArgument, ExecuteProcess, IncludeLaunchDescription 18 | from launch.substitutions import LaunchConfiguration, Command, PathJoinSubstitution 19 | from launch.launch_description_sources import PythonLaunchDescriptionSource 20 | from launch_ros.actions import Node 21 | from launch_ros.substitutions import FindPackageShare 22 | from launch_ros.actions import ComposableNodeContainer 23 | from launch_ros.descriptions import ComposableNode 24 | 25 | 26 | def generate_launch_description(): 27 | use_sim_time = True 28 | 29 | ekf_config_path = PathJoinSubstitution( 30 | [FindPackageShare("linorobot2_base"), "config", "ekf.yaml"] 31 | ) 32 | 33 | world_path = PathJoinSubstitution( 34 | [FindPackageShare("linorobot2_gazebo"), "worlds", "playground.world"] 35 | ) 36 | 37 | robot_base = os.getenv('LINOROBOT2_BASE') 38 | urdf_path = PathJoinSubstitution( 39 | [FindPackageShare("linorobot2_description"), "urdf/robots", f"{robot_base}.urdf.xacro"] 40 | ) 41 | 42 | description_launch_path = PathJoinSubstitution( 43 | [FindPackageShare('linorobot2_description'), 'launch', 'description.launch.py'] 44 | ) 45 | 46 | return LaunchDescription([ 47 | DeclareLaunchArgument( 48 | name='urdf', 49 | default_value=urdf_path, 50 | description='URDF path' 51 | ), 52 | 53 | DeclareLaunchArgument( 54 | name='odom_topic', 55 | default_value='/odom', 56 | description='EKF out odometry topic' 57 | ), 58 | 59 | DeclareLaunchArgument( 60 | name='world', 61 | default_value=world_path, 62 | description='Gazebo world' 63 | ), 64 | 65 | DeclareLaunchArgument( 66 | name='spawn_x', 67 | default_value='0.0', 68 | description='Robot spawn position in X axis' 69 | ), 70 | 71 | DeclareLaunchArgument( 72 | name='spawn_y', 73 | default_value='0.0', 74 | description='Robot spawn position in Y axis' 75 | ), 76 | 77 | DeclareLaunchArgument( 78 | name='spawn_z', 79 | default_value='0.0', 80 | description='Robot spawn position in Z axis' 81 | ), 82 | 83 | DeclareLaunchArgument( 84 | name='spawn_yaw', 85 | default_value='0.0', 86 | description='Robot spawn heading' 87 | ), 88 | 89 | ExecuteProcess( 90 | cmd=['gazebo', '--verbose', '-s', 'libgazebo_ros_factory.so', '-s', 'libgazebo_ros_init.so', LaunchConfiguration('world')], 91 | output='screen' 92 | ), 93 | 94 | Node( 95 | package='gazebo_ros', 96 | executable='spawn_entity.py', 97 | name='urdf_spawner', 98 | output='screen', 99 | arguments=[ 100 | '-topic', 'robot_description', 101 | '-entity', 'linorobot2', 102 | '-x', LaunchConfiguration('spawn_x'), 103 | '-y', LaunchConfiguration('spawn_y'), 104 | '-z', LaunchConfiguration('spawn_z'), 105 | '-Y', LaunchConfiguration('spawn_yaw'), 106 | ] 107 | ), 108 | 109 | Node( 110 | package='linorobot2_gazebo', 111 | executable='command_timeout.py', 112 | name='command_timeout' 113 | ), 114 | 115 | Node( 116 | package='robot_localization', 117 | executable='ekf_node', 118 | name='ekf_filter_node', 119 | output='screen', 120 | parameters=[ 121 | {'use_sim_time': use_sim_time}, 122 | ekf_config_path 123 | ], 124 | remappings=[("odometry/filtered", LaunchConfiguration("odom_topic"))] 125 | ), 126 | 127 | IncludeLaunchDescription( 128 | PythonLaunchDescriptionSource(description_launch_path), 129 | launch_arguments={ 130 | 'use_sim_time': str(use_sim_time), 131 | 'publish_joints': 'false', 132 | 'urdf': LaunchConfiguration('urdf') 133 | }.items() 134 | ) 135 | ]) 136 | 137 | #sources: 138 | #https://navigation.ros.org/setup_guides/index.html# 139 | #https://answers.ros.org/question/374976/ros2-launch-gazebolaunchpy-from-my-own-launch-file/ 140 | #https://github.com/ros2/rclcpp/issues/940 141 | -------------------------------------------------------------------------------- /linorobot2_gazebo/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | linorobot2_gazebo 5 | 0.0.0 6 | Linorobot2 Gazebo Package 7 | Juan Miguel Jimeno 8 | Apache 2.0 9 | linorobot.org 10 | https://github.com/linorobot/linorobot2 11 | https://github.com/linorobot/linorobot2/issues 12 | ament_cmake 13 | ament_cmake_python 14 | robot_localization 15 | gazebo_ros_pkgs 16 | rclpy 17 | geometry_msgs 18 | image_proc 19 | depth_image_proc 20 | python-trimesh-pip 21 | python3-numpy 22 | python3-pycollada 23 | python3-scipy 24 | python3-networkx 25 | python3-opencv-contrib-python 26 | python3-matplotlib 27 | 28 | ament_cmake 29 | 30 | 31 | -------------------------------------------------------------------------------- /linorobot2_gazebo/rviz/view_urdf.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz_common/Displays 3 | Help Height: 78 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: ~ 7 | Splitter Ratio: 0.5 8 | Tree Height: 605 9 | Visualization Manager: 10 | Class: "" 11 | Displays: 12 | - Alpha: 0.5 13 | Cell Size: 1 14 | Class: rviz_default_plugins/Grid 15 | Color: 160; 160; 164 16 | Enabled: true 17 | Line Style: 18 | Line Width: 0.029999999329447746 19 | Value: Lines 20 | Name: Grid 21 | Normal Cell Count: 0 22 | Offset: 23 | X: 0 24 | Y: 0 25 | Z: 0 26 | Plane: XY 27 | Plane Cell Count: 10 28 | Reference Frame: 29 | Value: true 30 | - Alpha: 0.6000000238418579 31 | Class: rviz_default_plugins/RobotModel 32 | Collision Enabled: false 33 | Description File: "" 34 | Description Source: Topic 35 | Description Topic: 36 | Depth: 5 37 | Durability Policy: Volatile 38 | History Policy: Keep Last 39 | Reliability Policy: Reliable 40 | Value: /robot_description 41 | Enabled: true 42 | Links: 43 | All Links Enabled: true 44 | Expand Joint Details: false 45 | Expand Link Details: false 46 | Expand Tree: false 47 | Link Tree Style: Links in Alphabetic Order 48 | base_footprint: 49 | Alpha: 1 50 | Show Axes: false 51 | Show Trail: false 52 | base_link: 53 | Alpha: 1 54 | Show Axes: false 55 | Show Trail: false 56 | Value: true 57 | left_wheel_link: 58 | Alpha: 1 59 | Show Axes: false 60 | Show Trail: false 61 | Value: true 62 | right_wheel_link: 63 | Alpha: 1 64 | Show Axes: false 65 | Show Trail: false 66 | Value: true 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: true 77 | base_footprint: 78 | Value: true 79 | base_link: 80 | Value: true 81 | left_wheel_link: 82 | Value: true 83 | right_wheel_link: 84 | Value: true 85 | Marker Scale: 0.10000000149011612 86 | Name: TF 87 | Show Arrows: true 88 | Show Axes: true 89 | Show Names: true 90 | Tree: 91 | base_footprint: 92 | base_link: 93 | left_wheel_link: 94 | {} 95 | right_wheel_link: 96 | {} 97 | Update Interval: 0 98 | Value: true 99 | - Class: rviz_default_plugins/Axes 100 | Enabled: true 101 | Length: 1 102 | Name: Axes 103 | Radius: 0.0010000000474974513 104 | Reference Frame: 105 | Value: true 106 | Enabled: true 107 | Global Options: 108 | Background Color: 48; 48; 48 109 | Fixed Frame: base_footprint 110 | Frame Rate: 30 111 | Name: root 112 | Tools: 113 | - Class: rviz_default_plugins/Interact 114 | Hide Inactive Objects: true 115 | - Class: rviz_default_plugins/MoveCamera 116 | - Class: rviz_default_plugins/Select 117 | - Class: rviz_default_plugins/FocusCamera 118 | - Class: rviz_default_plugins/Measure 119 | Line color: 128; 128; 0 120 | Transformation: 121 | Current: 122 | Class: rviz_default_plugins/TF 123 | Value: true 124 | Views: 125 | Current: 126 | Class: rviz_default_plugins/Orbit 127 | Distance: 0.6006462574005127 128 | Enable Stereo Rendering: 129 | Stereo Eye Separation: 0.05999999865889549 130 | Stereo Focal Distance: 1 131 | Swap Stereo Eyes: false 132 | Value: false 133 | Focal Point: 134 | X: 0 135 | Y: 0 136 | Z: 0 137 | Focal Shape Fixed Size: true 138 | Focal Shape Size: 0.05000000074505806 139 | Invert Z Axis: false 140 | Name: Current View 141 | Near Clip Distance: 0.009999999776482582 142 | Pitch: 0.44039836525917053 143 | Target Frame: 144 | Value: Orbit (rviz) 145 | Yaw: 0.7753981947898865 146 | Saved: ~ 147 | Window Geometry: 148 | Displays: 149 | collapsed: false 150 | Height: 834 151 | Hide Left Dock: false 152 | Hide Right Dock: false 153 | QMainWindow State: 000000ff00000000fd000000010000000000000156000002e8fc0200000001fb000000100044006900730070006c006100790073010000003d000002e8000000c900ffffff000002e8000002e800000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 154 | Width: 1092 155 | X: 675 156 | Y: 38 157 | -------------------------------------------------------------------------------- /linorobot2_gazebo/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linorobot/linorobot2/6b7ae2ebd5e3782560363dca136c3a92864f5a46/linorobot2_gazebo/scripts/__init__.py -------------------------------------------------------------------------------- /linorobot2_gazebo/scripts/command_timeout.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | import rclpy 17 | from rclpy.node import Node 18 | from std_msgs.msg import String 19 | from geometry_msgs.msg import Twist 20 | 21 | class CommandTimeout(Node): 22 | def __init__(self): 23 | super().__init__('command_timeout') 24 | self.prev_cmd_time_ = self.get_clock().now() 25 | self.zero_cmd_sent_ = True 26 | self.twist_publisher_ = self.create_publisher(Twist, 'cmd_vel', 10) 27 | 28 | brake_timer = self.create_timer(0.2, self.brake_timer_callback) 29 | 30 | twist_subscription = self.create_subscription( 31 | Twist, 32 | 'cmd_vel', 33 | self.twist_callback, 34 | 10) 35 | twist_subscription 36 | 37 | def brake_timer_callback(self): 38 | now = self.get_clock().now() 39 | dt = (now - self.prev_cmd_time_).nanoseconds 40 | 41 | #5Hz 42 | if dt >= 2e+8 and not self.zero_cmd_sent_: 43 | self.zero_cmd_sent_ = True 44 | twist_msg = Twist() 45 | twist_msg.linear.x = 0.0 46 | twist_msg.linear.y = 0.0 47 | twist_msg.angular.z = 0.0 48 | self.twist_publisher_.publish(twist_msg) 49 | 50 | def twist_callback(self, msg): 51 | if msg.linear.x == 0 and msg.linear.y == 0 and msg.angular.z == 0: 52 | return 53 | 54 | self.zero_cmd_sent_ = False 55 | self.prev_cmd_time_ = self.get_clock().now() 56 | 57 | def main(args=None): 58 | rclpy.init(args=args) 59 | 60 | command_timeout = CommandTimeout() 61 | rclpy.spin(command_timeout) 62 | command_timeout.destroy_node() 63 | rclpy.shutdown() 64 | 65 | if __name__ == '__main__': 66 | main() -------------------------------------------------------------------------------- /linorobot2_gazebo/worlds/gas_station.world: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 0 0 10 0 -0 0 6 | 0.8 0.8 0.8 1 7 | 0.2 0.2 0.2 1 8 | 9 | 1000 10 | 0.9 11 | 0.01 12 | 0.001 13 | 14 | -0.5 0.1 -0.9 15 | 16 | 0 17 | 0 18 | 0 19 | 20 | 21 | 22 | 1 23 | 24 | 25 | 26 | 27 | 0 0 1 28 | 100 100 29 | 30 | 31 | 32 | 33 | 65535 34 | 35 | 36 | 37 | 38 | 100 39 | 50 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 10 48 | 49 | 50 | 0 51 | 52 | 53 | 0 0 1 54 | 100 100 55 | 56 | 57 | 58 | 62 | 63 | 64 | 0 65 | 0 66 | 0 67 | 68 | 69 | 0 0 -9.8 70 | 6e-06 2.3e-05 -4.2e-05 71 | 72 | 73 | 0.001 74 | 1 75 | 1000 76 | 77 | 78 | 0.4 0.4 0.4 1 79 | 0.7 0.7 0.7 1 80 | 1 81 | 82 | 83 | 84 | EARTH_WGS84 85 | 0 86 | 0 87 | 0 88 | 0 89 | 90 | 91 | 1 92 | 93 | 0 0 0 0 -0 0 94 | 95 | 96 | 97 | model://gas_station/meshes/gas_station.dae 98 | 99 | 100 | 10 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | model://gas_station/meshes/gas_station.dae 118 | 119 | 120 | 121 | 126 | 127 | GasStation_Normal.png 128 | 129 | 130 | 131 | 0 132 | 0 133 | 0 134 | 135 | 0.389891 12.2183 0 0 -0 0 136 | 137 | 138 | 0 139 | 0 140 | 0 141 | 0 142 | 143 | 0.389891 12.2183 0 0 -0 0 144 | 1 1 1 145 | 146 | 0.389891 12.2183 0 0 -0 0 147 | 0 0 0 0 -0 0 148 | 0 0 0 0 -0 0 149 | 0 0 0 0 -0 0 150 | 151 | 152 | 153 | 0 0 0 0 -0 0 154 | 1 1 1 155 | 156 | 0 0 0 0 -0 0 157 | 0 0 0 0 -0 0 158 | 0 0 0 0 -0 0 159 | 0 0 0 0 -0 0 160 | 161 | 162 | 163 | 0 0 10 0 -0 0 164 | 165 | 166 | 167 | 168 | 4.51677 -2.40887 2.01663 -0 0.383643 2.5202 169 | orbit 170 | perspective 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /linorobot2_navigation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(linorobot2_navigation) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | 6 | install( 7 | DIRECTORY launch rviz config maps 8 | DESTINATION share/${PROJECT_NAME} 9 | ) 10 | 11 | ament_package() 12 | -------------------------------------------------------------------------------- /linorobot2_navigation/config/slam.yaml: -------------------------------------------------------------------------------- 1 | slam_toolbox: 2 | ros__parameters: 3 | 4 | # Plugin params 5 | solver_plugin: solver_plugins::CeresSolver 6 | ceres_linear_solver: SPARSE_NORMAL_CHOLESKY 7 | ceres_preconditioner: SCHUR_JACOBI 8 | ceres_trust_strategy: LEVENBERG_MARQUARDT 9 | ceres_dogleg_type: TRADITIONAL_DOGLEG 10 | ceres_loss_function: None 11 | 12 | # ROS Parameters 13 | odom_frame: odom 14 | map_frame: map 15 | base_frame: base_footprint 16 | scan_topic: /scan 17 | mode: 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: true 27 | throttle_scans: 1 28 | transform_publish_period: 0.02 #if 0 never publishes odometry 29 | map_update_interval: 5.0 30 | resolution: 0.05 31 | max_laser_range: 10.0 #for rastering images 32 | minimum_time_interval: 0.5 33 | transform_timeout: 0.2 34 | tf_buffer_duration: 30. 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.5 42 | minimum_travel_heading: 0.5 43 | scan_buffer_size: 10 44 | scan_buffer_maximum_scan_distance: 10.0 45 | link_match_minimum_response_fine: 0.1 46 | link_scan_maximum_distance: 1.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: 0.5 56 | correlation_search_space_resolution: 0.01 57 | correlation_search_space_smear_deviation: 0.1 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: 1.0 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.9 72 | minimum_distance_penalty: 0.5 73 | use_response_expansion: true 74 | -------------------------------------------------------------------------------- /linorobot2_navigation/launch/navigation.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 17 | from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription 18 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 19 | from launch.launch_description_sources import PythonLaunchDescriptionSource 20 | from launch.conditions import IfCondition 21 | from launch_ros.substitutions import FindPackageShare 22 | from launch_ros.actions import Node 23 | from launch.conditions import IfCondition, UnlessCondition 24 | 25 | 26 | MAP_NAME='playground' #change to the name of your own map here 27 | 28 | def generate_launch_description(): 29 | depth_sensor = os.getenv('LINOROBOT2_DEPTH_SENSOR', '') 30 | 31 | nav2_launch_path = PathJoinSubstitution( 32 | [FindPackageShare('nav2_bringup'), 'launch', 'bringup_launch.py'] 33 | ) 34 | 35 | rviz_config_path = PathJoinSubstitution( 36 | [FindPackageShare('linorobot2_navigation'), 'rviz', 'linorobot2_navigation.rviz'] 37 | ) 38 | 39 | default_map_path = PathJoinSubstitution( 40 | [FindPackageShare('linorobot2_navigation'), 'maps', f'{MAP_NAME}.yaml'] 41 | ) 42 | 43 | nav2_config_path = PathJoinSubstitution( 44 | [FindPackageShare('linorobot2_navigation'), 'config', 'navigation.yaml'] 45 | ) 46 | 47 | nav2_sim_config_path = PathJoinSubstitution( 48 | [FindPackageShare('linorobot2_navigation'), 'config', 'navigation_sim.yaml'] 49 | ) 50 | 51 | 52 | return LaunchDescription([ 53 | DeclareLaunchArgument( 54 | name='sim', 55 | default_value='false', 56 | description='Enable use_sime_time to true' 57 | ), 58 | 59 | DeclareLaunchArgument( 60 | name='rviz', 61 | default_value='false', 62 | description='Run rviz' 63 | ), 64 | 65 | DeclareLaunchArgument( 66 | name='map', 67 | default_value=default_map_path, 68 | description='Navigation map path' 69 | ), 70 | 71 | IncludeLaunchDescription( 72 | PythonLaunchDescriptionSource(nav2_launch_path), 73 | condition=UnlessCondition(LaunchConfiguration("sim")), 74 | launch_arguments={ 75 | 'map': LaunchConfiguration("map"), 76 | 'use_sim_time': LaunchConfiguration("sim"), 77 | 'params_file': nav2_config_path 78 | }.items() 79 | ), 80 | 81 | IncludeLaunchDescription( 82 | PythonLaunchDescriptionSource(nav2_launch_path), 83 | condition=IfCondition(LaunchConfiguration("sim")), 84 | launch_arguments={ 85 | 'map': LaunchConfiguration("map"), 86 | 'use_sim_time': LaunchConfiguration("sim"), 87 | 'params_file': nav2_sim_config_path 88 | }.items() 89 | ), 90 | 91 | Node( 92 | package='rviz2', 93 | executable='rviz2', 94 | name='rviz2', 95 | output='screen', 96 | arguments=['-d', rviz_config_path], 97 | condition=IfCondition(LaunchConfiguration("rviz")), 98 | parameters=[{'use_sim_time': LaunchConfiguration("sim")}] 99 | ) 100 | ]) -------------------------------------------------------------------------------- /linorobot2_navigation/launch/slam.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Juan Miguel Jimeno 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 | from launch import LaunchDescription 17 | from launch import LaunchContext 18 | from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription 19 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 20 | from launch.launch_description_sources import PythonLaunchDescriptionSource 21 | from launch.conditions import IfCondition 22 | from launch.substitutions import EnvironmentVariable 23 | from launch_ros.substitutions import FindPackageShare 24 | from launch_ros.actions import Node 25 | 26 | 27 | def generate_launch_description(): 28 | slam_launch_path = PathJoinSubstitution( 29 | [FindPackageShare('slam_toolbox'), 'launch', 'online_async_launch.py'] 30 | ) 31 | 32 | slam_config_path = PathJoinSubstitution( 33 | [FindPackageShare('linorobot2_navigation'), 'config', 'slam.yaml'] 34 | ) 35 | 36 | navigation_launch_path = PathJoinSubstitution( 37 | [FindPackageShare('nav2_bringup'), 'launch', 'navigation_launch.py'] 38 | ) 39 | 40 | nav2_config_path = PathJoinSubstitution( 41 | [FindPackageShare('linorobot2_navigation'), 'config', 'navigation.yaml'] 42 | ) 43 | 44 | rviz_config_path = PathJoinSubstitution( 45 | [FindPackageShare('linorobot2_navigation'), 'rviz', 'linorobot2_slam.rviz'] 46 | ) 47 | 48 | lc = LaunchContext() 49 | ros_distro = EnvironmentVariable('ROS_DISTRO') 50 | slam_param_name = 'slam_params_file' 51 | if ros_distro.perform(lc) == 'foxy': 52 | slam_param_name = 'params_file' 53 | 54 | return LaunchDescription([ 55 | DeclareLaunchArgument( 56 | name='sim', 57 | default_value='false', 58 | description='Enable use_sime_time to true' 59 | ), 60 | 61 | DeclareLaunchArgument( 62 | name='rviz', 63 | default_value='false', 64 | description='Run rviz' 65 | ), 66 | 67 | IncludeLaunchDescription( 68 | PythonLaunchDescriptionSource(navigation_launch_path), 69 | launch_arguments={ 70 | 'use_sim_time': LaunchConfiguration("sim"), 71 | 'params_file': nav2_config_path 72 | }.items() 73 | ), 74 | 75 | IncludeLaunchDescription( 76 | PythonLaunchDescriptionSource(slam_launch_path), 77 | launch_arguments={ 78 | 'use_sim_time': LaunchConfiguration("sim"), 79 | slam_param_name: slam_config_path 80 | }.items() 81 | ), 82 | 83 | Node( 84 | package='rviz2', 85 | executable='rviz2', 86 | name='rviz2', 87 | output='screen', 88 | arguments=['-d', rviz_config_path], 89 | condition=IfCondition(LaunchConfiguration("rviz")), 90 | parameters=[{'use_sim_time': LaunchConfiguration("sim")}] 91 | ) 92 | ]) 93 | -------------------------------------------------------------------------------- /linorobot2_navigation/maps/map.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linorobot/linorobot2/6b7ae2ebd5e3782560363dca136c3a92864f5a46/linorobot2_navigation/maps/map.pgm -------------------------------------------------------------------------------- /linorobot2_navigation/maps/map.yaml: -------------------------------------------------------------------------------- 1 | image: map.pgm 2 | resolution: 0.050000 3 | origin: [-50.000000, -50.000000, 0.000000] 4 | negate: 0 5 | occupied_thresh: 0.65 6 | free_thresh: 0.196 7 | -------------------------------------------------------------------------------- /linorobot2_navigation/maps/playground.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linorobot/linorobot2/6b7ae2ebd5e3782560363dca136c3a92864f5a46/linorobot2_navigation/maps/playground.pgm -------------------------------------------------------------------------------- /linorobot2_navigation/maps/playground.yaml: -------------------------------------------------------------------------------- 1 | image: playground.pgm 2 | mode: trinary 3 | resolution: 0.05 4 | origin: [-10.3, -10.5, 0] 5 | negate: 0 6 | occupied_thresh: 0.65 7 | free_thresh: 0.25 8 | -------------------------------------------------------------------------------- /linorobot2_navigation/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | linorobot2_navigation 5 | 0.0.0 6 | Linorobot2 Navigation Package 7 | Juan Miguel Jimeno 8 | Apache 2.0 9 | linorobot.org 10 | https://github.com/linorobot/linorobot2 11 | https://github.com/linorobot/linorobot2/issues 12 | ament_cmake 13 | nav2_bringup 14 | 15 | ament_cmake 16 | nav2_bringup 17 | slam_toolbox 18 | 19 | 20 | -------------------------------------------------------------------------------- /linorobot2_navigation/rviz/linorobot2_navigation_minimal.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz_common/Displays 3 | Help Height: 0 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: 7 | - /TF1/Frames1 8 | - /TF1/Tree1 9 | Splitter Ratio: 0.5833333134651184 10 | Tree Height: 502 11 | - Class: rviz_common/Selection 12 | Name: Selection 13 | - Class: rviz_common/Tool Properties 14 | Expanded: 15 | - /Publish Point1 16 | Name: Tool Properties 17 | Splitter Ratio: 0.5886790156364441 18 | - Class: rviz_common/Views 19 | Expanded: 20 | - /Current View1 21 | Name: Views 22 | Splitter Ratio: 0.5 23 | - Class: nav2_rviz_plugins/Navigation 2 24 | Name: Navigation 2 25 | Visualization Manager: 26 | Class: "" 27 | Displays: 28 | - Alpha: 0.30000001192092896 29 | Cell Size: 1 30 | Class: rviz_default_plugins/Grid 31 | Color: 32; 74; 135 32 | Enabled: true 33 | Line Style: 34 | Line Width: 0.029999999329447746 35 | Value: Lines 36 | Name: Grid 37 | Normal Cell Count: 0 38 | Offset: 39 | X: 0 40 | Y: 0 41 | Z: 0 42 | Plane: XY 43 | Plane Cell Count: 1000 44 | Reference Frame: 45 | Value: true 46 | - Alpha: 1 47 | Class: rviz_default_plugins/RobotModel 48 | Collision Enabled: false 49 | Description File: "" 50 | Description Source: Topic 51 | Description Topic: 52 | Depth: 5 53 | Durability Policy: Volatile 54 | History Policy: Keep Last 55 | Reliability Policy: Reliable 56 | Value: /robot_description 57 | Enabled: false 58 | Links: 59 | All Links Enabled: true 60 | Expand Joint Details: false 61 | Expand Link Details: false 62 | Expand Tree: false 63 | Link Tree Style: "" 64 | Name: RobotModel 65 | TF Prefix: "" 66 | Update Interval: 0 67 | Value: false 68 | Visual Enabled: true 69 | - Class: rviz_default_plugins/TF 70 | Enabled: true 71 | Frame Timeout: 15 72 | Frames: 73 | All Enabled: false 74 | base_footprint: 75 | Value: true 76 | base_link: 77 | Value: false 78 | camera_color_frame: 79 | Value: true 80 | camera_color_optical_frame: 81 | Value: true 82 | camera_depth_frame: 83 | Value: true 84 | camera_depth_link: 85 | Value: true 86 | camera_depth_optical_frame: 87 | Value: true 88 | camera_link: 89 | Value: false 90 | front_caster_wheel_link: 91 | Value: true 92 | imu_link: 93 | Value: false 94 | laser: 95 | Value: false 96 | left_wheel_link: 97 | Value: true 98 | odom: 99 | Value: false 100 | rear_caster_wheel_link: 101 | Value: true 102 | right_wheel_link: 103 | Value: true 104 | Marker Scale: 2 105 | Name: TF 106 | Show Arrows: true 107 | Show Axes: true 108 | Show Names: false 109 | Tree: 110 | {} 111 | Update Interval: 0 112 | Value: true 113 | - Alpha: 1 114 | Autocompute Intensity Bounds: true 115 | Autocompute Value Bounds: 116 | Max Value: 3.290379285812378 117 | Min Value: -10.208759307861328 118 | Value: true 119 | Axis: X 120 | Channel Name: intensity 121 | Class: rviz_default_plugins/LaserScan 122 | Color: 255; 255; 255 123 | Color Transformer: AxisColor 124 | Decay Time: 0 125 | Enabled: true 126 | Invert Rainbow: false 127 | Max Color: 255; 255; 255 128 | Max Intensity: 0 129 | Min Color: 0; 0; 0 130 | Min Intensity: 0 131 | Name: LaserScan 132 | Position Transformer: XYZ 133 | Selectable: true 134 | Size (Pixels): 3 135 | Size (m): 0.10000000149011612 136 | Style: Flat Squares 137 | Topic: 138 | Depth: 5 139 | Durability Policy: Volatile 140 | History Policy: Keep Last 141 | Reliability Policy: Best Effort 142 | Value: /scan 143 | Use Fixed Frame: true 144 | Use rainbow: true 145 | Value: true 146 | - Alpha: 1 147 | Class: rviz_default_plugins/Map 148 | Color Scheme: map 149 | Draw Behind: true 150 | Enabled: true 151 | Name: Map 152 | Topic: 153 | Depth: 1 154 | Durability Policy: Transient Local 155 | History Policy: Keep Last 156 | Reliability Policy: Reliable 157 | Value: /map 158 | Update Topic: 159 | Depth: 5 160 | Durability Policy: Volatile 161 | History Policy: Keep Last 162 | Reliability Policy: Reliable 163 | Value: /map_updates 164 | Use Timestamp: false 165 | Value: true 166 | - Alpha: 0.20000000298023224 167 | Arrow Length: 0.10000000149011612 168 | Axes Length: 0.30000001192092896 169 | Axes Radius: 0.009999999776482582 170 | Class: rviz_default_plugins/PoseArray 171 | Color: 173; 127; 168 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 | Enabled: true 187 | Global Options: 188 | Background Color: 255; 255; 255 189 | Fixed Frame: map 190 | Frame Rate: 30 191 | Name: root 192 | Tools: 193 | - Class: rviz_default_plugins/MoveCamera 194 | - Class: rviz_default_plugins/Select 195 | - Class: rviz_default_plugins/FocusCamera 196 | - Class: rviz_default_plugins/Measure 197 | Line color: 128; 128; 0 198 | - Class: rviz_default_plugins/SetInitialPose 199 | Topic: 200 | Depth: 5 201 | Durability Policy: Volatile 202 | History Policy: Keep Last 203 | Reliability Policy: Reliable 204 | Value: /initialpose 205 | - Class: rviz_default_plugins/PublishPoint 206 | Single click: true 207 | Topic: 208 | Depth: 5 209 | Durability Policy: Volatile 210 | History Policy: Keep Last 211 | Reliability Policy: Reliable 212 | Value: /clicked_point 213 | - Class: nav2_rviz_plugins/GoalTool 214 | Transformation: 215 | Current: 216 | Class: rviz_default_plugins/TF 217 | Value: true 218 | Views: 219 | Current: 220 | Angle: 0 221 | Class: rviz_default_plugins/TopDownOrtho 222 | Enable Stereo Rendering: 223 | Stereo Eye Separation: 0.05999999865889549 224 | Stereo Focal Distance: 1 225 | Swap Stereo Eyes: false 226 | Value: false 227 | Invert Z Axis: false 228 | Name: Current View 229 | Near Clip Distance: 0.009999999776482582 230 | Scale: 71.72926330566406 231 | Target Frame: base_link 232 | Value: TopDownOrtho (rviz_default_plugins) 233 | X: 0.4037398099899292 234 | Y: 0.7326793670654297 235 | Saved: ~ 236 | Window Geometry: 237 | Displays: 238 | collapsed: false 239 | Height: 842 240 | Hide Left Dock: false 241 | Hide Right Dock: true 242 | Navigation 2: 243 | collapsed: false 244 | QMainWindow State: 000000ff00000000fd000000040000000000000156000002f0fc020000000afb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d00000233000000c900fffffffb00000018004e0061007600690067006100740069006f006e002000320100000276000000b7000000b700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000001e005200650061006c00730065006e0073006500430061006d00650072006100000002c6000000c1000000000000000000000001000001c60000034afc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d0000034a000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000750000000b7fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d0065010000000000000450000000000000000000000420000002f000000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 245 | Selection: 246 | collapsed: false 247 | Tool Properties: 248 | collapsed: false 249 | Views: 250 | collapsed: true 251 | Width: 1404 252 | X: 423 253 | Y: 153 254 | -------------------------------------------------------------------------------- /linorobot2_navigation/rviz/linorobot2_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 | - /RobotModel1/Description Topic1 9 | Splitter Ratio: 0.5 10 | Tree Height: 613 11 | - Class: rviz_common/Selection 12 | Name: Selection 13 | - Class: rviz_common/Tool Properties 14 | Expanded: 15 | - /2D Goal Pose1 16 | - /Publish Point1 17 | Name: Tool Properties 18 | Splitter Ratio: 0.5886790156364441 19 | - Class: rviz_common/Views 20 | Expanded: 21 | - /Current View1 22 | Name: Views 23 | Splitter Ratio: 0.5 24 | Visualization Manager: 25 | Class: "" 26 | Displays: 27 | - Alpha: 0.30000001192092896 28 | Cell Size: 1 29 | Class: rviz_default_plugins/Grid 30 | Color: 32; 74; 135 31 | Enabled: true 32 | Line Style: 33 | Line Width: 0.029999999329447746 34 | Value: Lines 35 | Name: Grid 36 | Normal Cell Count: 0 37 | Offset: 38 | X: 0 39 | Y: 0 40 | Z: 0 41 | Plane: XY 42 | Plane Cell Count: 1000 43 | Reference Frame: 44 | Value: true 45 | - Class: rviz_default_plugins/TF 46 | Enabled: true 47 | Frame Timeout: 15 48 | Frames: 49 | All Enabled: true 50 | base_footprint: 51 | Value: true 52 | base_link: 53 | Value: true 54 | camera_link: 55 | Value: true 56 | front_left_wheel_link: 57 | Value: true 58 | front_right_wheel_link: 59 | Value: true 60 | imu_link: 61 | Value: true 62 | laser: 63 | Value: true 64 | map: 65 | Value: true 66 | odom: 67 | Value: true 68 | rear_left_wheel_link: 69 | Value: true 70 | rear_right_wheel_link: 71 | Value: true 72 | Marker Scale: 0.5 73 | Name: TF 74 | Show Arrows: true 75 | Show Axes: true 76 | Show Names: true 77 | Tree: 78 | map: 79 | odom: 80 | base_footprint: 81 | base_link: 82 | camera_link: 83 | {} 84 | imu_link: 85 | {} 86 | laser: 87 | {} 88 | front_left_wheel_link: 89 | {} 90 | front_right_wheel_link: 91 | {} 92 | rear_left_wheel_link: 93 | {} 94 | rear_right_wheel_link: 95 | {} 96 | Update Interval: 0 97 | Value: true 98 | - Alpha: 1 99 | Class: rviz_default_plugins/RobotModel 100 | Collision Enabled: false 101 | Description File: "" 102 | Description Source: Topic 103 | Description Topic: 104 | Depth: 5 105 | Durability Policy: Volatile 106 | History Policy: Keep Last 107 | Reliability Policy: Reliable 108 | Value: /robot_description 109 | Enabled: true 110 | Links: 111 | All Links Enabled: true 112 | Expand Joint Details: false 113 | Expand Link Details: false 114 | Expand Tree: false 115 | Link Tree Style: Links in Alphabetic Order 116 | base_footprint: 117 | Alpha: 1 118 | Show Axes: false 119 | Show Trail: false 120 | base_link: 121 | Alpha: 1 122 | Show Axes: false 123 | Show Trail: false 124 | Value: true 125 | camera_link: 126 | Alpha: 1 127 | Show Axes: false 128 | Show Trail: false 129 | Value: true 130 | front_left_wheel_link: 131 | Alpha: 1 132 | Show Axes: false 133 | Show Trail: false 134 | Value: true 135 | front_right_wheel_link: 136 | Alpha: 1 137 | Show Axes: false 138 | Show Trail: false 139 | Value: true 140 | imu_link: 141 | Alpha: 1 142 | Show Axes: false 143 | Show Trail: false 144 | laser: 145 | Alpha: 1 146 | Show Axes: false 147 | Show Trail: false 148 | Value: true 149 | rear_left_wheel_link: 150 | Alpha: 1 151 | Show Axes: false 152 | Show Trail: false 153 | Value: true 154 | rear_right_wheel_link: 155 | Alpha: 1 156 | Show Axes: false 157 | Show Trail: false 158 | Value: true 159 | Name: RobotModel 160 | TF Prefix: "" 161 | Update Interval: 0 162 | Value: true 163 | Visual Enabled: true 164 | - Alpha: 0.4000000059604645 165 | Class: rviz_default_plugins/Map 166 | Color Scheme: map 167 | Draw Behind: false 168 | Enabled: true 169 | Name: Map 170 | Topic: 171 | Depth: 5 172 | Durability Policy: Volatile 173 | History Policy: Keep Last 174 | Reliability Policy: Reliable 175 | Value: /map 176 | Update Topic: 177 | Depth: 5 178 | Durability Policy: Volatile 179 | History Policy: Keep Last 180 | Reliability Policy: Reliable 181 | Value: /map_updates 182 | Use Timestamp: false 183 | Value: true 184 | - Alpha: 1 185 | Autocompute Intensity Bounds: true 186 | Autocompute Value Bounds: 187 | Max Value: 10.362611770629883 188 | Min Value: -0.29685065150260925 189 | Value: true 190 | Axis: X 191 | Channel Name: intensity 192 | Class: rviz_default_plugins/LaserScan 193 | Color: 255; 255; 255 194 | Color Transformer: AxisColor 195 | Decay Time: 0 196 | Enabled: true 197 | Invert Rainbow: false 198 | Max Color: 255; 255; 255 199 | Max Intensity: 0 200 | Min Color: 0; 0; 0 201 | Min Intensity: 0 202 | Name: LaserScan 203 | Position Transformer: XYZ 204 | Selectable: true 205 | Size (Pixels): 3 206 | Size (m): 0.10000000149011612 207 | Style: Flat Squares 208 | Topic: 209 | Depth: 5 210 | Durability Policy: Volatile 211 | History Policy: Keep Last 212 | Reliability Policy: Reliable 213 | Value: /scan 214 | Use Fixed Frame: true 215 | Use rainbow: true 216 | Value: true 217 | Enabled: true 218 | Global Options: 219 | Background Color: 117; 135; 133 220 | Fixed Frame: map 221 | Frame Rate: 30 222 | Name: root 223 | Tools: 224 | - Class: rviz_default_plugins/Interact 225 | Hide Inactive Objects: true 226 | - Class: rviz_default_plugins/MoveCamera 227 | - Class: rviz_default_plugins/Select 228 | - Class: rviz_default_plugins/FocusCamera 229 | - Class: rviz_default_plugins/Measure 230 | Line color: 128; 128; 0 231 | - Class: rviz_default_plugins/SetInitialPose 232 | Topic: 233 | Depth: 5 234 | Durability Policy: Volatile 235 | History Policy: Keep Last 236 | Reliability Policy: Reliable 237 | Value: /initialpose 238 | - Class: rviz_default_plugins/SetGoal 239 | Topic: 240 | Depth: 5 241 | Durability Policy: Volatile 242 | History Policy: Keep Last 243 | Reliability Policy: Reliable 244 | Value: /goal_pose 245 | - Class: rviz_default_plugins/PublishPoint 246 | Single click: true 247 | Topic: 248 | Depth: 5 249 | Durability Policy: Volatile 250 | History Policy: Keep Last 251 | Reliability Policy: Reliable 252 | Value: /clicked_point 253 | Transformation: 254 | Current: 255 | Class: rviz_default_plugins/TF 256 | Value: true 257 | Views: 258 | Current: 259 | Angle: 0 260 | Class: rviz_default_plugins/TopDownOrtho 261 | Enable Stereo Rendering: 262 | Stereo Eye Separation: 0.05999999865889549 263 | Stereo Focal Distance: 1 264 | Swap Stereo Eyes: false 265 | Value: false 266 | Invert Z Axis: false 267 | Name: Current View 268 | Near Clip Distance: 0.009999999776482582 269 | Scale: 32.17724609375 270 | Target Frame: base_link 271 | Value: TopDownOrtho (rviz_default_plugins) 272 | X: -1.7143195867538452 273 | Y: 1.3631300926208496 274 | Saved: ~ 275 | Window Geometry: 276 | Displays: 277 | collapsed: false 278 | Height: 842 279 | Hide Left Dock: false 280 | Hide Right Dock: true 281 | QMainWindow State: 000000ff00000000fd000000040000000000000156000002f0fc0200000009fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000003d000002f0000000c900fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000001e005200650061006c00730065006e0073006500430061006d0065007200610000000000ffffffff0000000000000000000000010000023e00000416fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d00000416000000a400fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004420000003efc0100000002fb0000000800540069006d00650100000000000004420000000000000000fb0000000800540069006d0065010000000000000450000000000000000000000420000002f000000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 282 | Selection: 283 | collapsed: false 284 | Tool Properties: 285 | collapsed: false 286 | Views: 287 | collapsed: true 288 | Width: 1404 289 | X: 263 290 | Y: 213 291 | -------------------------------------------------------------------------------- /update_microros.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | cd ../uros/micro-ROS-Agent/ 6 | git pull 7 | cd ../../../ 8 | . install/setup.bash 9 | ros2 run micro_ros_setup create_agent_ws.sh 10 | ros2 run micro_ros_setup build_agent.sh 11 | . install/setup.bash 12 | 13 | --------------------------------------------------------------------------------