a robot performing mapping and autonomous navigation in a real time manner using ROS2 humble with gazebo classic for simulation and rviz2 for visulation on Ubuntu 22.04
- make sure you have installed gazebo classic not gazebo ignition as it has a bug of creating the topic
/cmd_vel
when using its plugins in the robot - make sure you have installed rviz2 for visualization of the map
- make sure to install the project dependencies by running the command
rosdep install -i --from-path src --rosdistro humble -y
when standing in the directory called workspace
Package | Usage |
---|---|
nav2 | given a goal for a robot, the nav2 will try to navigate that robot to the goal wanted using cost map (mostly the goal will be x, y and yaw) |
gazebo_ros | launching gazebo classic for simulation od the world and the robot inside it |
rviz2 | for visualization of the generated map and cost map from the robot |
explore_lite | sets the goal for nav2 and it's responsible for autonomous navigation by setting some interest points in the fourentier and tell nav2 to explore each one and decide which one is more interesting to explore where it will favor the lower cost points (given from cost map) unless the higher cost points gave an indication of the possibility of exploring unknonw areas |
slam_toolbox | generate map for a robot using pose estimation and scan matching given initial pose |
- make sure to run the following for every terminal you intend to open to deal with ROS2
source /opt/ros/humble/setup.bash
export ROS_DOMAIN_ID=95
export ROS_LOCALHOST_ONLY=1
source /usr/share/colcon_cd/function/colcon_cd.sh
export _colcon_cd_root=/opt/ros/humble/
source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash
or in another words make sure you followed ROS2 installation tutorial
- to run the project, go to the directory workspace and run
./run_project.sh
in your shell
demo.mp4
- spawn mutliple robots by modifying robot urdf files & launch files to create a namespace for each robot to avoid conflicts of multiple robots publishing to the topic.
- use the package
map_merge
for merging the maps generated by these different robots into 1 map to be visualized.
- Turtlebot4 had a bug of crashing the simulation when spawning more than 1 robot (for more details, refer to this issue), even though that error can be solved by:
edit the file called 'create3.urdf.xacro' which in my case was to be found in '/opt/ros/humble/share/irobot_create_description/urdf/'
1. remove the sensors-system plugin.
<gazebo>
<plugin filename="libignition-gazebo-sensors-system.so" name="ignition::gazebo::systems::Sensors">
<render_engine>ogre</render_engine>
</plugin>
</gazebo>
2. remove the contact-system plugin.
<gazebo>
<plugin filename="libignition-gazebo-contact-system.so" name="ignition::gazebo::systems::Contact"></plugin>
</gazebo>
as both have to be included in the **world file** only once.
but it seems there is a hard limit of around ~120 nodes created by turtlebot4 so I couldn't spawn more than 3. (I mean I could by editing the source of turtlebot4 and remove unneeded nodes but it would be too much work)
-
Gazebo ignition (fortress) for some reasone didn't create the topic
/cmd_vel
for my robot through which I can control the robot, I used the pluginlibignition-gazebo-diff-drive-system.so
but it only created topics for feedback like/tf
,/odometry
so I had to downgrade to Gazebo Classic but migrating fromurdf
files tosdf
files made the plugin work but i think it would require too much work since unlikeurdf
files, thesdf
are static not dynamic so every robot will have to have its ownsdf
which will cause too much code redundancy. so I had to rewrite my world file again for Gazebo Classic. -
couldn't make Turtlebot3 be spawned in Gazebo Ignition (Fortress) as it's defaulted to Gazebo Classic and it would require too much work to it work with Gazebo Ignition (Fortress).
the directory workspace:
├── LICENSE # contains licence details
├── README.md # the current readme file
└── workspace # main workspace where we shall run our ros commands
├── build # contains build files for the packages in the `src` directory (not important)
├── install # contains executable files and shared files for the packages in the `src` directory (not important)
├── log # contains some `log` files during execution
├── run_project.sh # the file through which you can run our project
├── src # conatins the packages of the workspace
└── temp_Commands # just a notepad for different useful ROS2 commands
the directory src (refer to 'Packages & Usages' above) :
├── explore # package used for setting the goal for nav2
├── map_merge # merging maps generated from different robots
├── slam_robots # perform mapping and locatalization of the robot
├── turtlebot3 # Turtlebot3 Packages (not used) (a part of failure attempt)
└── turtlebot4 # Turtlebot4 Packages (not used) (a part of failure attempt)
the main project files slam_robots:
├── CMakeLists.txt # build instruction for cmake tool, places for installing shared files and so on (all related to cmake tool).
├── config # conatins configuration files for project
│ ├── gazebo_params.yaml # define some paramters for gazebo simulation for some synchronization
│ └── mapper_params_online_async.yaml # define paramters for slam_toolbox
├── generated_map # a folder to save the generated maps in but currently it doesn't contain anything
├── include # was supposed to have some header files for node src code (part of failure attempt)
│ └── SLAM_Robots # empty directory (part of failure attempt)
├── launch # contains launch files
│ ├── launch_sim.launch.py # main working launch file
│ ├── robot_launch.launch.py # used to launch 1 robot file from its urdf file
│ ├── slam_robots_main_trial2.launch.py # launch multiple robots for my_robot_v2 (part of failure attempt)
│ ├── slam_robots_main_trial.launch.py # launch multiple of my my_robot_v1 by creating bridges (part of failure attempt)
│ └── slam_robots_main_turtlebot4_trial.launch.py # launch multiple turtlebot4 (part of failure attempt)
├── package.xml # file to describe the packages and helpful in downloading dependencies
├── robot # main folder that contains robot design files
│ ├── camera.xacro # contains plugins for rgp camare
│ ├── depth_camera.xacro # contains plugins for rgpd camare
│ ├── face.xacro # extra face design that has shape of smily face
│ ├── gazebo_control.xacro # contains diffdrive plugin for feedback and moving robot
│ ├── image_system_comarison.png # temp image for explanation a small concept in ROS2
│ ├── inertial_macros.xacro # a micro file related to inertia used in robot_core.xacro
│ ├── lidar.xacro # contains information related to lidar plugin
│ ├── robot_core.xacro # contains chassis design
│ ├── robot.urdf.xacro # main robot design files
│ ├── ros2_control.xacro # contains some controllers (not used)
│ └── rviz # contains some of rviz2 ready configurations (look at 'final_config', the rest are attempts)
│ ├── drive_bot.rviz
│ ├── final_config.rviz
│ ├── robot_depth_camera.rviz
│ ├── robot_lidar_visualize.rviz
│ ├── slam_robot_mapping.rviz
│ ├── test.rviz
│ └── view_robot.rviz
├── src # conatins a failure attemp file to deal with incoming message from gazebo ignition using bridge
│ └── gazebo_middleware.cpp
└── worlds # contains design files for our world
├── models # contains model files for gazebo ignition
│ ├── freeCad_dae # sdf basic models, freecad output
│ │ ├── chair.dae
│ │ ├── chair.sdf
│ │ ├── computer_table.dae
│ │ ├── computer_table.sdf
│ │ ├── corridor.dae
│ │ ├── corridor.sdf
│ │ ├── lecture_theater_platform.dae
│ │ ├── lecture_theater_platform.sdf
│ │ ├── smart_board.dae
│ │ ├── smart_board.sdf
│ │ ├── stadium.dae
│ │ ├── stadium.sdf
│ │ ├── table.dae
│ │ ├── table.sdf
│ │ ├── wall.dae
│ │ ├── wall.sdf
│ │ ├── wall_with_window.dae
│ │ └── wall_with_window.sdf
│ ├── freeCad design files # freecad design files
│ │ ├── chair.FCStd
│ │ ├── chair.FCStd1
│ │ ├── computer_table.FCStd
│ │ ├── computer_table.FCStd1
│ │ ├── corridor.FCStd
│ │ ├── corridor.FCStd1
│ │ ├── lecture_theater_platform.FCStd
│ │ ├── lecture_theater_platform.FCStd1
│ │ ├── smart_board.FCStd
│ │ ├── smart_board.FCStd1
│ │ ├── stadium.FCStd
│ │ ├── stadium.FCStd1
│ │ ├── table.FCStd
│ │ ├── table.FCStd1
│ │ ├── wall.FCStd
│ │ ├── wall.FCStd1
│ │ ├── wall_with_window.FCStd
│ │ └── wall_with_window.FCStd1
│ ├── fuel_models # ready made models
│ │ ├── Casual_female
│ │ │ ├── materials
│ │ │ │ └── textures
│ │ │ │ ├── brown_eye.png
│ │ │ │ ├── casual_female.png
│ │ │ │ ├── eyebrow002.png
│ │ │ │ ├── eyelashes01.png
│ │ │ │ ├── female_casualsuit01_diffuse.png
│ │ │ │ ├── female_casualsuit01_normal.png
│ │ │ │ ├── female_casualsuit02_diffuse.png
│ │ │ │ ├── female_casualsuit02_normal.png
│ │ │ │ ├── ponytail01_diffuse.png
│ │ │ │ ├── shoes05_diffuse.png
│ │ │ │ ├── tongue01_diffuse.png
│ │ │ │ └── young_lightskinned_female_diffuse.png
│ │ │ ├── meshes
│ │ │ │ └── casual_female.dae
│ │ │ ├── model.config
│ │ │ ├── model.sdf
│ │ │ └── thumbnails
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ └── 5.png
│ │ ├── Standing_person
│ │ │ ├── materials
│ │ │ │ └── textures
│ │ │ │ ├── eyebrow001.png
│ │ │ │ ├── eyebrow001-unmodified.png
│ │ │ │ ├── green_eye.png
│ │ │ │ ├── jeans01_normals.png
│ │ │ │ ├── jeans_basic_diffuse.png
│ │ │ │ ├── male02_diffuse_black.png
│ │ │ │ ├── male02_diffuse_black-unmodified.png
│ │ │ │ ├── teeth.png
│ │ │ │ ├── tshirt02_normals.png
│ │ │ │ ├── tshirt02_texture.png
│ │ │ │ └── young_lightskinned_male_diffuse.png
│ │ │ ├── meshes
│ │ │ │ └── standing.dae
│ │ │ ├── model.config
│ │ │ ├── model.sdf
│ │ │ └── thumbnails
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ └── 5.png
│ │ └── Walking_person
│ │ ├── materials
│ │ │ └── textures
│ │ │ ├── eyebrow001.png
│ │ │ ├── eyebrow001-unmodified.png
│ │ │ ├── green_eye.png
│ │ │ ├── jeans01_normals.png
│ │ │ ├── jeans_basic_diffuse.png
│ │ │ ├── male02_diffuse_black.png
│ │ │ ├── male02_diffuse_black-unmodified.png
│ │ │ ├── teeth.png
│ │ │ ├── tshirt02_normals.png
│ │ │ ├── tshirt02_texture.png
│ │ │ └── young_lightskinned_male_diffuse.png
│ │ ├── meshes
│ │ │ └── walking.dae
│ │ ├── model.config
│ │ ├── model.sdf
│ │ └── thumbnails
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ └── 5.png
│ ├── robots # failure attempt
│ │ ├── robot10.sdf
│ │ ├── robot1.sdf
│ │ ├── robot2.sdf
│ │ ├── robot3.sdf
│ │ ├── robot4.sdf
│ │ ├── robot5.sdf
│ │ ├── robot6.sdf
│ │ ├── robot7.sdf
│ │ ├── robot8.sdf
│ │ └── robot9.sdf
│ └── sub_worlds
│ ├── first_year.sdf
│ ├── fourth_year.sdf
│ ├── lab1.sdf
│ ├── lab2.sdf
│ ├── lab3.sdf
│ ├── lab4.sdf
│ ├── library.sdf
│ ├── maincorridor.sdf
│ ├── robots.sdf
│ ├── second_year.sdf
│ └── third_year.sdf
├── models_classic # contains model files for gazebo classic
│ ├── basic_models
│ │ ├── chair
│ │ │ ├── chair.dae
│ │ │ ├── model.config
│ │ │ └── model.sdf
│ │ ├── computer_table
│ │ │ ├── computer_table.dae
│ │ │ ├── model.config
│ │ │ └── model.sdf
│ │ ├── corridor
│ │ │ ├── corridor.dae
│ │ │ ├── model.config
│ │ │ └── model.sdf
│ │ ├── lecture_theater_platform
│ │ │ ├── lecture_theater_platform.dae
│ │ │ ├── model.config
│ │ │ └── model.sdf
│ │ ├── smart_board
│ │ │ ├── model.config
│ │ │ ├── model.sdf
│ │ │ └── smart_board.dae
│ │ ├── stadium
│ │ │ ├── model.config
│ │ │ ├── model.sdf
│ │ │ └── stadium.dae
│ │ ├── table
│ │ │ ├── model.config
│ │ │ ├── model.sdf
│ │ │ └── table.dae
│ │ ├── wall
│ │ │ ├── model.config
│ │ │ ├── model.sdf
│ │ │ └── wall.dae
│ │ └── wall_with_window
│ │ ├── model.config
│ │ ├── model.sdf
│ │ └── wall_with_window.dae
│ ├── freeCad_dae
│ ├── freeCad design files
│ │ ├── chair.FCStd
│ │ ├── chair.FCStd1
│ │ ├── computer_table.FCStd
│ │ ├── computer_table.FCStd1
│ │ ├── corridor.FCStd
│ │ ├── corridor.FCStd1
│ │ ├── lecture_theater_platform.FCStd
│ │ ├── lecture_theater_platform.FCStd1
│ │ ├── smart_board.FCStd
│ │ ├── smart_board.FCStd1
│ │ ├── stadium.FCStd
│ │ ├── stadium.FCStd1
│ │ ├── table.FCStd
│ │ ├── table.FCStd1
│ │ ├── wall.FCStd
│ │ ├── wall.FCStd1
│ │ ├── wall_with_window.FCStd
│ │ └── wall_with_window.FCStd1
│ ├── fuel_models
│ │ ├── Casual_female
│ │ │ ├── materials
│ │ │ │ └── textures
│ │ │ │ ├── brown_eye.png
│ │ │ │ ├── casual_female.png
│ │ │ │ ├── eyebrow002.png
│ │ │ │ ├── eyelashes01.png
│ │ │ │ ├── female_casualsuit01_diffuse.png
│ │ │ │ ├── female_casualsuit01_normal.png
│ │ │ │ ├── female_casualsuit02_diffuse.png
│ │ │ │ ├── female_casualsuit02_normal.png
│ │ │ │ ├── ponytail01_diffuse.png
│ │ │ │ ├── shoes05_diffuse.png
│ │ │ │ ├── tongue01_diffuse.png
│ │ │ │ └── young_lightskinned_female_diffuse.png
│ │ │ ├── meshes
│ │ │ │ └── casual_female.dae
│ │ │ ├── model.config
│ │ │ ├── model.sdf
│ │ │ └── thumbnails
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ └── 5.png
│ │ ├── Standing_person
│ │ │ ├── materials
│ │ │ │ └── textures
│ │ │ │ ├── eyebrow001.png
│ │ │ │ ├── eyebrow001-unmodified.png
│ │ │ │ ├── green_eye.png
│ │ │ │ ├── jeans01_normals.png
│ │ │ │ ├── jeans_basic_diffuse.png
│ │ │ │ ├── male02_diffuse_black.png
│ │ │ │ ├── male02_diffuse_black-unmodified.png
│ │ │ │ ├── teeth.png
│ │ │ │ ├── tshirt02_normals.png
│ │ │ │ ├── tshirt02_texture.png
│ │ │ │ └── young_lightskinned_male_diffuse.png
│ │ │ ├── meshes
│ │ │ │ └── standing.dae
│ │ │ ├── model.config
│ │ │ ├── model.sdf
│ │ │ └── thumbnails
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ └── 5.png
│ │ └── Walking_person
│ │ ├── materials
│ │ │ └── textures
│ │ │ ├── eyebrow001.png
│ │ │ ├── eyebrow001-unmodified.png
│ │ │ ├── green_eye.png
│ │ │ ├── jeans01_normals.png
│ │ │ ├── jeans_basic_diffuse.png
│ │ │ ├── male02_diffuse_black.png
│ │ │ ├── male02_diffuse_black-unmodified.png
│ │ │ ├── teeth.png
│ │ │ ├── tshirt02_normals.png
│ │ │ ├── tshirt02_texture.png
│ │ │ └── young_lightskinned_male_diffuse.png
│ │ ├── meshes
│ │ │ └── walking.dae
│ │ ├── model.config
│ │ ├── model.sdf
│ │ └── thumbnails
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ └── 5.png
│ ├── robots
│ │ ├── robot10.sdf
│ │ ├── robot1.sdf
│ │ ├── robot2.sdf
│ │ ├── robot3.sdf
│ │ ├── robot4.sdf
│ │ ├── robot5.sdf
│ │ ├── robot6.sdf
│ │ ├── robot7.sdf
│ │ ├── robot8.sdf
│ │ └── robot9.sdf
│ └── sub_worlds
│ ├── first_year
│ │ ├── model.config
│ │ └── model.sdf
│ ├── fourth_year
│ │ ├── model.config
│ │ └── model.sdf
│ ├── lab1
│ │ ├── model.config
│ │ └── model.sdf
│ ├── lab2
│ │ ├── model.config
│ │ └── model.sdf
│ ├── lab3
│ │ ├── model.config
│ │ └── model.sdf
│ ├── lab4
│ │ ├── model.config
│ │ └── model.sdf
│ ├── library
│ │ ├── model.config
│ │ └── model.sdf
│ ├── maincorridor
│ │ ├── model.config
│ │ └── model.sdf
│ ├── robots.sdf
│ ├── second_year
│ │ ├── model.config
│ │ └── model.sdf
│ └── third_year
│ ├── model.config
│ └── model.sdf
├── world_classic.sdf # world file for gazebo classic
└── world.sdf # world file for gazebo ignition