This is my implementation of a complete 2D navigation package, including global planner, local planner, and motion controller (path follower).
I developed the above 3 modules, corresponding to the folders:
- /global_planner
- /local_planner
- /stage_robot_controller
This folder contains the launch file for RVIZ, Gmapping, Stage_ros, Gazebo_ros:
- /launch_stage_gmapping_rviz
Required input messages:
- nav_msgs/OccupancyGrid
- nav_msgs/Odometry
- sensor_msgs/LaserScan
Output message:
- /cmd_vel, geometry_msgs/Twist
Two simulators are used for demonstration purpose:
-
- It uses a bmp image to build the world. I draw my map using this bitmap tool pixilart .
- It creates a differential-drive robot with 2D lidar.
-
Gazebo with turtlebot .
- The map is turtlebot_house.
- The turtlebot robot is a differential-drive robot with 2D lidar. It also has RGBD cameras though not used in this project.
Robot exploring the map to reach the goal:
![gazebo turtle gazebo turtle](https://github.com/hanmmmmm/Navigation_package_for_DifferentialDrive/raw/main/gifs/nav_gazebo_turtle_house_one.gif)
For slam, I am using the standard Gmapping for demonstration.
This is the workflow within the system (using stage_ros simulator).
![local local gif](https://github.com/hanmmmmm/navigation_package_V1/raw/main/gifs/nav_rqt.gif)
- geometry_msgs: Twist, PoseStamped
- sensor_msgs: LaserScan
- nav_msgs: OccupancyGrid, MapMetaData, Odometry, Path
- ros/ros.h
- vector, array, queue, string
- atomic, thread
- iostream, chrono, stdexcept, iomanip
- set, map, unordered_map
- limits, algorithm, math.h
Place the needed folders in a ros workspace, e.g. catkin_ws/src/
, and run catkin_make
at catkin_ws
- Add algos from random-tree family, and compare with the A* family here.
- Add MPC Model-predictive-controller.
- Add Reed-shepp curve feature.
The line of green arrows is the path, from current location to the goal location.
This example is using A* algorithm to find the path.
Each path-finding takes <1~20 ms. The more obstacles between robot and goal, the longer time it takes to find the valid path.
But this node is set to update the global path about 2~3 Hz even though it could do much faster, since global path doesn't need to be updated too frequently.
Here I am dragging the robot in Stage simulator by hand.
![set goal goal gif](https://github.com/hanmmmmm/navigation_package_V1/raw/main/gifs/nav_global_path.gif)
The green arrows are global path, and the red ones are local path.
This example is using Hybrid-A* to find the local path. The local goal is the last glocal path-point covered inside the local search area (The white square area around the robot base_link).
This is also a full working demo actually, since the robot is moving following the cmd_vel message generated by my controller module.
![local local gif](https://github.com/hanmmmmm/navigation_package_V1/raw/main/gifs/nav_local_path.gif)
Several new goals are added while the robot is moving. The paths are updated to guide the robot.
The controller module use odometry and local_path to generate the disired linear & angular velocity for the robot to follow the local_path.
In the planning module, the unkown region (dark green) is treated the same as clear region (bright white). Becasue the global planning is consantly updating the global path, a new path will be found if the existing path pass through a new-found obstacle.
The current path follower is Pure pursuit.
1. Stage sim
![local local gif](https://github.com/hanmmmmm/navigation_package_V1/raw/main/gifs/nav_demo_1.gif)
2. Gazebo
![local local gif](https://github.com/hanmmmmm/navigation_package_V1/raw/main/gifs/nav_gazebo_turtle.gif)