forked from ros-planning/navigation
-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Timed Costmap #83
Draft
leoniegadner
wants to merge
25
commits into
devel
Choose a base branch
from
leonie/timed_costmap_converter
base: devel
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Timed Costmap #83
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
siferati
reviewed
Jun 22, 2023
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
F: Need to add documentation to every new function and attribute
F: CI seems to be failing
ChristofDubs
reviewed
Jul 4, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
See my bachelor thesis for a more detailed explanation.
🕐 Idea
The ROS Navigation Stack uses a costmap to represents the current state of the robot’s environment. However, this costmap treats the environment as static, disregarding movement of perceived obstacles. To allow the planner and controller to consider this movement information, we developed a timed costmap approach. The entire costmap is here augmented with a time dimension, by creating multiple costmaps, one for each timestep, instead of one. The planners can then find a path in this spatio-temporal map, allowing them to plan ahead in space and time resulting in more intuitive and overall safer navigation.
🕑 Implementation
Inside the LayeredCostmaps class we create a vector of costmaps
std::vector<costmap_2d::Costmap2D> timed_costmaps_
and get rid of the single Costmap2D objectcostmap_
. The Map UpdateupdateMap()
is then modified to update all costmaps. The update happens in two steps:To make use of this time dimension in the costmap, we also need layers with a timed logic!!! The most obvious idea for such a layer is a dynamic obstacle layer, which displaces moving obstacles along their trajectory given their velocity information. Two PoC's for timed layers can be found here:
Now that the time information is incorporated into the planner's and controller's search space, they also need to make use of it. In this first implementation only DWA was modified to work with the Timed Costmap and the global costmap is thus kept non-timed (
prediction_time = 0
).DWA generates trajectories by sampling different angular and linear velocities. The trajectories are scored with forward kinematic projection, using the parameters
sim_time
, which defines how far to simulate forward, andtime_granularity
, defining the time increment between two points on the trajectory. To calculate a trajectory’s ‘distance to obstacles’ score, DWA loops through the points on the trajectory and gets each point’s cost from the costmap. The timet
for each point on the trajectory is thus given byt = i*time_delta_
When the planner calls the
footprintCost()
function inside theObstacleCostFunction
class, we can then pass this time argument and use the costmap inside thetimed_costmaps_
that corresponds to the given timet
to get the footprint cost.🕒 Evalutation
Comparison of Approaches
To compare some of the different approaches I experimented with I wrote a short python script that sends the robot back and forth and creates 3 obstacles that cross its path. I then let the script run for 2 minutes for each configuration and 'measured' some metrics displayed in the table at the end. First I'll explain the configurations tested...
No dynamic obstacle handling
No explenation needed, we've all seen this one. If the obstacle does not avoid the robot, it will collide. 💥
Original Dynamic Obstacle Layer
A Dynamic Obstacle Layer Approach implemented here simply creates a 2D gaussian shape around the obstacles, extending them forward. For testing I used the original parameters.
Improved Dynamic Obstacle Layer
This approach was discussed in https://github.com/rapyuta-robotics/rr_navigation/pull/1407. The idea is to take the 2D Gaussian shape created in 2 but displace the center to the earliest point on the obstacles trajectory where the robot could collide with it (using the robot's current position and maximum speed). For this approach there are a lot of parameters that affect the performance and can be tuned to achieve different behaviors. For testing I ran it once with the original DOL parameters (IDOL0), once with a smaller gaussian shape (IDOL1) and once with a bigger one (IDOL2)
Timed Costmap
I tested this once with local costmap
prediction_time = 1.2
(Timed 1) and once withprediction_time = 2.0
(Timed 2) with DWAsim_time = 1.2s
(Timed 1) and once withsim_time = 2.0s
(Timed 2). The global costmapprediction_time = 0.0
. For this we are using the Timed Gradient Layer. Note, that we use this layer only in the local costmap, and don't add dynamic obstacles to the global costmap at all (not even at their current position!).Only Local
To test the effectiveness of the Timed Costmap, I also tested a configuration where we use the normal non-timed costmap but dynamic obstacles are added only to the local costmap and not to the global one. For this the same parameters as above where used (Only Local 1, Only Local 2).
In the table below you can see the results I got.
*Note that these are kinda subjective and I tend to be very biased in my judgement… 😇
In the video below, where I ran the Timed Costmap with
sim_time_ = 3
, you can see how the robot waits for the obstacles to pass or even moves out of the way when the obstacles are coming towards it, but doesn't slow down when the obstacles are moving out of its way.timed_costmap_3-2023-05-25_09.58.27.mp4
The behaviour of the three different approaches is visualised in the image below:
CPU
One big disadvantage of the Timed Costmap is the increased computation. The CPU usage is strongly affected by the parameters aswell as the order that the plugins are loaded in:
CPU usage with robot standing:
Prediction time = 0
→ CPU ~ 40%
Prediction time 1.2
Timestep 0.3
static_costmap: static
other plugins: obstacle (timed), obstacle_back, stvl, route, paint, semantic
→ CPU: ~45%
prediction_time: 1.2
timestep: 0.1
static_costmap: static, route, paint, semantic
other plugins: obstacle (timed), obstacle_back, stvl, inflation, dynamic
→ CPU ~53%
prediction_time: 1.2
timestep: 0.1
static_costmap: static, semantic,
other plugins: obstacle (timed), obstacle_back, stvl, route, paint, inflation, dynamic
→ CPU: ~60%
prediction_time: 1.2
timestep: 0.1
static_costmap: static
other plugins: obstacle (timed), obstacle_back, stvl, route, paint, semantic, inflation, dynamic
→ CPU: ~85%
...
🕓 Future Steps
To-Do:
Timed Costmap:
Timed Planners:
Timed Layers:
*might not be necessary, depends on perception component…