Coder Social home page Coder Social logo

mukundbala / nav-stack-from-scratch Goto Github PK

View Code? Open in Web Editor NEW
9.0 2.0 2.0 31.84 MB

A repository with implementations of common techniques and algorithms in robot path planning and navigation.

CMake 6.71% Python 1.86% C++ 88.83% Shell 0.92% MATLAB 1.63% C 0.06%
drone mapping navigation path-planning turtlebot3 astar-algorithm djikstra-algorithm theta-star

nav-stack-from-scratch's Introduction

Nav-Stack-From-Scratch

ROS Build

This repository contains from-scratch implementations of robotics motion planning, control and mapping algorithms/techniques. The goal was to understand these algorithms from 1st principles and implement them in an efficient, yet readable manner. This "full stack" approach has been vital in building an indepth understanding of how these algorithms work under the hood, while also vastly improving my skills as a robotics software engineer. This work allows for decoupled waypoint based missions for both robots and coupled missions where the drone's path is dependent on the Turtlebot's path

All algorithms are implemented and tested on C++17 on ROS Noetic using Gazebo for simulation.

If you are just browsing, see Sections (1-3). Build and usage instructions in Sections (4-6)

(1) Architecture

Figure 1: Software and Control Architecture

(2) Nav Stack in action

animated

Figure 2: TurtleBot3 Mapping and Navigation

animated

Figure 3: Linear TurtleBot3 Trajectories

animated

Figure 4: Cubic Hermite Spline TurtleBot3 Trajectories

animated

Figure 5: Quintic Hermite Spline TurtleBot3 Trajectories

animated

Figure 6: Hector Quadrotor Takeoff and Landing

animated

Figure 7: Hector Quadrotor Solo Waypoint Flight

animated

Figure 8: TurlteBot3 - Hector Co-Op Mission

animated

Figure 9: Spline-Based Prediction

animated

Figure 10: Without Spline-Based Prediction

(3) Algorithms/Techniques Implementations

(a) Differential Drive Simple Localization

[Found in loco_mapping package.]

This implementation uses the velocity motion model of a differential drive robot to track the pose using odometry (dead reckoning). This is fused with IMU with a weighted average filter. This is generally does not perform well due to wheel slip etc, but is reasonable for the flat ground in simulation.

(b) Occupancy Grid Mapping with Log Odds Binary Bayes Filter

[Found in loco_mapping package.]

This implementation uses lidar measurements to incrementally update the robot's belief of the occupancy state of each grid on the map. Brensenham's Line Algorithm combined with the inverse sensor model is heavily used accomplish this. The occupancy map is also inflated to permit point mass assumption and allow safe navigation.

(c) Mission Planner

[Found in mission_planner package.]

Mission Planner is a top level controller that loads waypoints from .yaml file. The completion of each waypoint is tracked, and the next waypoint is published only when the current waypoint is completed. This node shuts off all other nodes when all checkpoints have been achieved.

(d) tmsgs and hmsgs

[Found in tmsgs and hmsgs packages.]

Custom .msg and .srv files for communication for TurtleBot3 and Hector Quadrotor. Generally good practice is write these messages as separate topics. This should be followed for extensions with different robots.

(e) Global Planner

[Found in global_planner package]

Global Planner is a package that contains planning algorithms and the main global planner logic.

  • (e.1) Global Planner Logic

    The main global planner logic gets a new waypoint from mission planner, and uses the current position of the robot along with the current map state to compute a path. This path is published. Main logic is found in GlobalPlanner::run().

    The type of planner used is polymorphically selected at runtime from global_planner.yaml config files.

  • (e.2) GridPlannerCore

    This class is the base class grid planner pure interface that enforces plan(.), post_process_path(.) and generatePath(.) methods for its children. It also implements common functions and data structures that planners would need.

  • (e.3) OpenList

    The implementation of OpenList uses a min heap implemented using std::priority_queue, with 3 sorting modes that can be selected in the config files. Note that some planners require a certain cost mode to work. The OpenList data structure is implemented in GridPlannerCore.

  • (e.4) Grid Planners: Djikstra, Astar , ThetaStar

    3 Grid Based planners that inherit from GridPlannerCore have been implemented, and can be selected easily through config files.

  • (e.5) Fallback Planner

    Grid-based planners plan based on map states, where they avoid grids that are occupied/inflated and explore cells that are free. Due to imperfections in odometry, the robot can find itself on occupied/inflated cells or its goal may appear on these cells. This will cause the planner to always fail as these cells will be avoided. A Fallback Planner, implemented using Djikstra, finds the nearest free cell from a given non-free cell, which the main planner uses to plan its path.

(f) Commander

[Found in commander package]

The Local Planner receives a path from the Global Planner and generates a trajectory over the points on the path. It feeds targets on the trajectory to a PID controller to generate command velocities.

  • (f.1) Commander Logic

    The commander receives a path from Global Planner and generates a trajectory over this path. It tests the trajectory and triggers replanning by the Global Planner if the robot is too close to a target that is on a non-free cell. The Commander selects a target and feeds it to the PID Controller. Once a target is reached, it feeds the next target.

  • (f.2) Local Planner

    Trajectories are generated using C0 Continuous Linear Interpolation, C1 Continuous Cubic Hermite Spline or C2 Continuous Quintic Hermite Spline. Choice of local planner algorithm is polymorphically set based on config file params.

  • (f.3) PID Controller

    The PID Controller receives a target from the Local Planner and generates a command velocity using PID algorithm. The gains for the controller can be set in config params.

(g) Drone Commander

[Found in drone_commander package]

The Drone Commander contains a high level Finite State Machine (FNS) for mission control and a mid-level Trajectory Generator and PID Controller for motion planning. It allows the drone to fly coupled missions with the TurtleBot3 or solo waypoint based missions.

  • (g.1) FNS

    The FNS tracks the mission state of the Hector Drone and transitions to subsequent states to perform solo or coupled missions.

  • (g.2) Trajectory Generator

    Trajectories are generated using C0 Continuous Linear Interpolation, C1 Continuous Cubic Hermite Spline or C2 Continuous Quintic Hermite Spline. Choice of local planner algorithm is polymorphically set based on config file params.

  • (g.3) PID Controller

    The PID Controller receives a target from the Trajectory Generator and generates a command velocity using PID algorithm. The gains for the controller can be set in config params.

  • (g.4) Spline Based Prediction

    For coupled Hector-TurtleBot3 missions, we may require the Hector to fly to the movign TurtleBot3. Rather than generating trajectories to the Turtle's position, we use the spline of the TurtleBot to compute a point on the spline that both Hector and TurtleBot can reach at the same time. Repeating this prediction at every time step creates shorter and faster trajectories for the Hector.

(h) Drone Inertial Navigation System using EKF

The Drone Inertial Navigation System (INS) fuses GPS, IMU, Magnetometer, Barometer and Sonar measurements using an Extended Kalman Filter for pose estimation.

(4) How to build

##but first, some dependencies

sudo apt install python3-catkin-tools
sudo apt install ros-noetic-plotjuggler-ros

#ensure that you have ros-noetic installed: http://wiki.ros.org/noetic/Installation/Ubuntu

Clone workspace

cd ~
mkdir -p catkin_ws/src ##note that you dont have to use "catkin_ws"
cd ~catkin_ws/src
git clone [email protected]:mukundbala/Robot-Control-Planning-Navigation.git

Dependencies

1. Download the hector gazebo plugins and controllers here: 
**https://drive.google.com/drive/folders/1dpGfExLByJUMmeoGGoY88x6IGdUeHe9C?usp=sharing**

2. Move *hector* and *hector_quadrotor* folders into catkin_ws/src

Build workspace using catkin build

catkin build
source ~/catkin_ws/devel/setup.bash

(5) Robots and Simulation

(a) Overview

A Differential Drive Robot (TurtleBot3) and a Hector Quadrotor are simulated on Gazebo. There are options to spawn and control each robot individually, or run cooperative waypoint-based/coupled missions. Simulations, worlds, urdfs and simulation modes are all controlled by the robot_bringup package.

(b) robot_bringup package

In this package, utilities and files for launching, logging, visualization and simulation can be found. A brief overview is provided in this section. For this repository, this is the only package that will launch the simulation and the relevant nodes.

Directory Description
launch This directory contains launch files for simulations (bringup_robots.launch) and nodes (run_robots.launch)
logging Logging config files for plotjuggler
rviz Rviz config files
scripts Contains python teleoperation scripts for Hector Quadrotor and TurtleBot3, written as python nodes
src tf transform broadcaster for Turtlebot3
urdf Contains URDF descriptions of the robots used in this repository.
worlds Contains .world files of the simulation environment, spawn parameters (spawn location etc) and waypoint position in 2D or 3D

(c) supporting .sh files

This repository extensively uses bash scripts to load paramters and run programs to avoid the common hassle of "sourcing" the ROS workspace etc. Generally, it helps with data collection purposes where these .sh files can be run repeatedly with different parameters.

Bash File Description
bringup.sh Handles the boring stuff like sourcing workspace. More importantly, it loads (or sources in bash terms) simulation parameters and launches the bringup_robots.launch file
run.sh Handles the boring stuff like sourcing workspace. Resets Gazebo simulation so that we can immediately restart simulation without shutting off everything. Launch all relevant nodes according to the simulation mode using run_robots.launch file.Safely shuts down the simulation by directly publishing 0 velocities to robots
params.sh Contains 2 very important field: WORLD and TASK. WORLD refers to the chosen world in robot_bringup package, while TASK refers to the simulation mode (more on this later)
teleop_turtle.sh Launches TurtleBot3 teleoperation node. Directly publishes to /cmd_vel topic. You minimally need to bringup the simulation to use this.
teleop_hector.sh Launches Hector Quadrotor teleoperation node. Directly publishes to /cmd_vel topic. You minimally need to bringup the simulation to use this.
drone_logger.sh Logging bash file that launches plotjuggler. Nothing too important here.
================================

(6) Simulation Modes

Mode 1: Solo Turtlebot

This mode allows only the Turtlebot to be spawned in a world. Waypoints can be set and the Turtlebot will map the environment and travel to each of the waypoints in sequence.

Mode 2: Solo Hector Quadrotor

This mode is primarily meant to test out Hector's Finite State Machine and Trajectory Generation. This mode allows waypoint based flight for the Hector. Only the hector will be spawned in this mode. This mode was used to tune the PID gains of the Hector

Mode 3: Coupled Co-op Flights

During Co-op flights, the Hector will chase after the Turtle and fly to its position. The Hector then flies to the final goal of the Turtle before flying back to the Takeoff Point. A naive approach might be to simply get the Turtle's position and fly to it. However, this can create unnecessarily long flight paths.

Alternately, we can fly to where the Turtle is going to be in the future. This is done by getting the published trajectory of the turtle. These trajectories can be Linear, Cubic or Quintic splines. The commonality is that targets in these trajectories are generated over a fixed dt. We can exploit this to find a point on the trajectory from the Turtle's current target where both the Turtle and the Hector will reach at around the same time.

(7) How to Use

Adding World Files and goals for different modes

  1. Go to robot_bringup/worlds
  • Each world file that is added has its own directory,<world_name>. This directory contains a <world_name>.sh file,<world_name>_tgoals.yaml,<world_name>_hgoals.yaml file and a <world_name>.world file.

  • The configuration for these files according to the chosen mode are explained below

    • For Mode 1: Solo Turtlebot

      • <world_name>.sh file
        ## spawning coordinates for Turtlebot
        export TURTLE_X=-2.0 
        export TURTLE_Y=-0.5
        
        ## map limits for turtlebot
        export TURTLE_MIN_X=-8.0
        export TURTLE_MIN_Y=-13.0
        export TURTLE_MAX_X=7.0
        export TURTLE_MAX_Y=3.0
      • <world_name>_tgoals.yaml file
        goals: 
        - [3.0 , -4.0]
        - [-1.0 , -5.0]
        - [-3.5 , -8.5]
      • <world_name>.world follows the usual .world file format
    • For Mode 2: Solo Hector Quadrotor

      • <world_name>.sh file
        ## spawning coordinates for Hector Quadrotor
        export HECTOR_X=0.0
        export HECTOR_Y=0.0
        export HECTOR_Z=0.178
      • <world_name>_hgoals.yaml file
        goals: 
        - [1.0, 1.0, 2.0]
        - [5.0 , 5.0 , 2.0]
        - [1.0 , 1.0 , 2.0]
    • For Mode 3 (3a and 3b): Co-Op Hector + Turtlebot

      • <world_name>.sh file
        export TURTLE_X=-2.0
        export TURTLE_Y=-0.5
        export TURTLE_MIN_X=-8.0
        export TURTLE_MIN_Y=-13.0
        export TURTLE_MAX_X=7.0
        export TURTLE_MAX_Y=3.0
        export HECTOR_X=2.0
        export HECTOR_Y=2.0
        export HECTOR_Z=0.178
      • <world_name>_tgoals.yaml file
        goals: 
        - [3.0 , -4.0]
        - [-1.0 , -5.0]
        - [-3.5 , -8.5]
      • <world_name>_hgoals.yaml contain the goals for the Hector Quadrotor
        • mode3a (Coupled Navigation)
          goals: 
        • mode3b (Decoupled Navigation)
          goals: 
          - [1.0, 1.0, 2.0]
          - [5.0 , 5.0 , 2.0]
          - [1.0 , 1.0 , 2.0]
  1. In this directory (robot_bringup/worlds), create a directory with the worldname that you want, such that robot_bringup/worlds/<world_name>. World name can be pretty much anything, but make sure this <world_name> is used for all files inside the directory.

  2. Depending on which mode you want the world to be used in, add in the relevant fields detailed in Step 1

  3. It is recommended that for different modes, you create different <world_name> folders even if the same .world file is being used.

Mode 1: Solo Turtlebot

This mode will spawn a Turtlebot in a world, and it will navigate from its spawn location to each of the goal locations that were set.

  1. Follow the instructions in the Adding World Files section. Make sure you follow the fields for Mode 1
  2. Go to params.sh and add in the <world_name> in the WORLD field and "mode1" to the TASK field.
  3. Run catkin build if you made any changes to the code
  4. Open 2 terminals. Make sure you runs source devel/setup.bash in each terminal
  5. In the first terminal, run ./bringup.sh
  6. Once Gazebo and Rviz have launched, run ./run.sh in the second terminal
  7. The Turtlebot will begin its mission

Figure 11: Mode 1

Mode 2: Solo Hector Quadrotor

This mode will spawn a Hector Quadrotor in a world, and it will navigate from its spawn location to each of the goal locations that were set.

  1. Follow the instructions in the Adding World Files section. Make sure you follow the fields for Mode 2
  2. Go to params.sh and add in the <world_name> in the WORLD field and "mode2" to the TASK field.
  3. Go to drone_commander/config/drone_commander.yaml and set co_op=false. This is to trigger the solo flight Finite State Machine to run.
  4. Run catkin build if you made any changes to the code
  5. Open 2 terminals. Make sure you runs source devel/setup.bash in each terminal
  6. In the first terminal, run ./bringup.sh
  7. Once Gazebo and Rviz have launched, run ./run.sh in the second terminal
  8. The Quadrotor will begin its mission

Figure 12: Mode 2

Mode 3: Co-op Turtlebot + Hector Quadrotor

This mode spawn both the Hector and Turtlebot in the world. There are 2 "sub modes" in this mode, mode3a and mode3b that have different co-op behaviors

In Mode 3a, Hector's navigation is entirely coupled with the Turtlebot. The Hector will Takeoff, then fly to the Turtle's position, then fly to the Turtle's final goal. It will then fly back to its Takeoff position. This pattern (Takeoff - Turtle - TurtleFinalWaypoint - Takeoff - ....) will continue UNTIL the Turtle has reached its final goal. It will then complete its current cycle, fly back to the Takeoff point, and Land.

In Mode 3b, the Hector's navigation is decoupled from the Turtlebot. The Hector will load in separate goals from <world_name>_hgoals.yaml and follow that instead. Its behavior will be identical to the behavior in Mode2.

The only difference in settings for mode3a and mode3b is in setting the co_op field in drone_commander/config/drone_commander.yaml to true or false.

Mode 3a: Coupled Mission

  1. Follow the instructions in the Adding World Files section. Make sure you follow the fields for Mode 3.
  2. Go to params.sh and add in the <world_name> in the WORLD field and "mode3" to the TASK field.
  3. Go to drone_commander/config/drone_commander.yaml and set co_op=true. The State Machine will run a follow turtle sequence to fulfill the cycles
  4. Run catkin build if you made any changes to the code
  5. Open 2 terminals. Make sure you runs source devel/setup.bash in each terminal
  6. In the first terminal, run ./bringup.sh
  7. Once Gazebo and Rviz have launched, run ./run.sh in the second terminal
  8. The Quadrotor and Turtlebot will begin their respective missions

Mode 3b: Decoupled Mission

  1. Follow the instructions in the Adding World Files section. Make sure you follow the fields for Mode 3.
  2. Go to params.sh and add in the <world_name> in the WORLD field and "mode3" to the TASK field.
  3. Go to drone_commander/config/drone_commander.yaml and set co_op=false. The State Machine will run a waypoint follower sequence and fly independently of the Turtle
  4. Run catkin build if you made any changes to the code
  5. Open 2 terminals. Make sure you runs source devel/setup.bash in each terminal
  6. In the first terminal, run ./bringup.sh
  7. Once Gazebo and Rviz have launched, run ./run.sh in the second terminal
  8. The Quadrotor and Turtlebot will begin their respective missions

Figure 13: Mode 3

nav-stack-from-scratch's People

Contributors

kartheegeyan avatar mukundbala avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

nav-stack-from-scratch's Issues

Danger Close implementation for trajectory logic needs improvement

The local planner logic implements an improvement that checks the trajectory from the current target onwards rather than the entire trajectory. Even if the trajectory is unsafe, the idea to to continue along the trajectory to explore new locations on the map. Improvement is needed in dealing with velocity generation when danger close is active.

Better estimate of average speed of hector

Can possibly implement a better estimation of average speed to estimate the turtleposition. First step would be to keep a running average of the hector speeds that are published.

Upgrade GlobalPlanner

  1. Make the global planner general such that it accepts different kinds of planners.
  2. Implement Djisktra, Astar, ThetaStar
  3. OpenList heap implementation
  4. GlobalPlanner as a service call

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.