Skip to content
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

feat: add node to limit trajectory velocity for apparent safety #690

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
431f1d1
Initial commit with barebone SafeVelocityAdjustorNode
maxime-clem Mar 22, 2022
6cb3ec0
Add debug topics, launch file, and config file
maxime-clem Mar 22, 2022
d01c9d3
Fix debug markers
maxime-clem Mar 23, 2022
9ab88d4
Fix dynamic parameters
maxime-clem Mar 23, 2022
af8ab05
Add proper collision detection and debug footprint
maxime-clem Mar 25, 2022
75d51f9
Add script to compare the original and adjusted velocity profiles
maxime-clem Mar 25, 2022
092fa11
Fix calculation of distance to obstacle
maxime-clem Mar 28, 2022
eb1e4bc
Add test for calculation collision distance
maxime-clem Mar 28, 2022
2722c3d
Add launch file to test the safe_velocity_adjustor with a bag
maxime-clem Mar 29, 2022
d2607e7
Cleanup code and add tests for forwardSimulatedVector
maxime-clem Mar 29, 2022
3bf0960
Simplify collision detection by not using a footprint polygon
maxime-clem Mar 30, 2022
1e656f0
Add filtering of the dynamic objects from the pointcloud
maxime-clem Mar 31, 2022
cb95908
[DEBUG] Print runtimes of expensive functions
maxime-clem Mar 31, 2022
00cfc4a
Add trajectory downsampling to boost performance + improve debug markers
maxime-clem Apr 1, 2022
893f76d
Modify velocity only from ego pose + distance parameter
maxime-clem Apr 5, 2022
2a63d11
Add 1st Eigen version of distanceToClosestCollision + benchmark
maxime-clem Apr 6, 2022
443d2e6
Switch to using contours from occupancy grid for collision checking
maxime-clem Apr 11, 2022
d399f61
Add buffer around dynamic obstacles to avoid false obstacle detection
maxime-clem Apr 12, 2022
fb1fdfe
Add parameter to limit the adjusted velocity
maxime-clem Apr 12, 2022
4bb4529
Use vehicle_info_util to get vehicle footprint
maxime-clem Apr 12, 2022
5cdc379
Calculate accurate distance to collision + add tests
maxime-clem Apr 12, 2022
9057796
Add parameter for the min velocity where a dynamic obstacle is ignored
maxime-clem Apr 13, 2022
4d62b50
Add README and some pictures to explain the node inner workings
maxime-clem Apr 13, 2022
0ad24e0
Update scenario_planning.launch.xml to run the new node
maxime-clem Apr 13, 2022
7036d26
Fix format of launch files
maxime-clem Apr 13, 2022
253beaa
Update launcher and rviz config used for debuging with bag
maxime-clem Apr 13, 2022
2325670
Cleanup debug publishing
maxime-clem Apr 14, 2022
05dfc53
Complete tests of collision_distance.hpp
maxime-clem Apr 14, 2022
584e14b
Add docstring + Small code cleanup
maxime-clem Apr 14, 2022
2ceb1c6
Improve test of occupancy_grid_utils
maxime-clem Apr 14, 2022
f235a9c
Fix bug when setting parameter callback before getting vehicle parame…
maxime-clem Apr 15, 2022
5f8a2f2
Rename safe_velocity_adjustor to apparent_safe_velocity_limiter
maxime-clem Apr 15, 2022
362cf55
Move declarations to cpp file (apparent_safe_velocity_limiter_node)
maxime-clem Apr 15, 2022
4dd7d6f
Move declarations to cpp file (occupancy_grid_utils)
maxime-clem Apr 15, 2022
bcb9cbd
Move declarations to cpp file (collision_distance)
maxime-clem Apr 15, 2022
a575c8c
Add exec of trajectory_visualizer.py in launch files
maxime-clem Apr 21, 2022
7040d3e
Mask trajectory footprint from the occupancy grid (might be expensive)
maxime-clem Apr 28, 2022
06c4dc9
Filter out the occupancy grid that is outside the envelope polygon
maxime-clem Apr 28, 2022
2e2099f
Add improved PolygonIterator using scan line algorithm
maxime-clem May 10, 2022
13d77b8
Use autoware_cmake for dependencies
maxime-clem May 12, 2022
d480b59
Improve performances of PolygonIterator
maxime-clem May 12, 2022
b0cf1cf
Lint scenario_planning.launch.xml
maxime-clem May 12, 2022
f9a0e64
Minor cleanup of PolygonIterator
maxime-clem May 14, 2022
84b2ea5
Use improved iterator + add benchmark (max/avg/med) to node
maxime-clem May 14, 2022
f7c912d
Minor code cleanup
maxime-clem May 16, 2022
448652f
Switch from set to vector/list in PolygonIterator
maxime-clem May 16, 2022
2efc874
Remove PolygonIterator and use implementation from grid_map_utils
maxime-clem May 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Minor cleanup of PolygonIterator
Signed-off-by: Maxime CLEMENT <maxime.clement@tier4.jp>
  • Loading branch information
maxime-clem committed Jun 14, 2022
commit f9a0e645a2fcf8719731263a1a9907023ca17cc5
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,12 @@
#ifndef APPARENT_SAFE_VELOCITY_LIMITER__POLYGON_ITERATOR_HPP_
#define APPARENT_SAFE_VELOCITY_LIMITER__POLYGON_ITERATOR_HPP_

#include "grid_map_core/Polygon.hpp"
#include "grid_map_core/TypeDefs.hpp"
#include "grid_map_core/iterators/GridMapIterator.hpp"

#include <grid_map_core/GridMap.hpp>
#include <tier4_autoware_utils/system/stop_watch.hpp>
#include <grid_map_core/GridMapMath.hpp>
#include <grid_map_core/Polygon.hpp>

#include <algorithm>
#include <cmath>
#include <functional>
#include <iostream>
#include <limits>
#include <set>
#include <utility>
Expand All @@ -52,10 +47,13 @@ class PolygonIterator

const auto resolution = grid_map.getResolution();
const auto & map_pose = grid_map.getPosition();
const auto min_map_x = map_pose.x() - grid_map.getLength().x() / 2.0 + resolution / 2;
const auto max_map_x = map_pose.x() + grid_map.getLength().x() / 2.0 - resolution / 2;
const auto min_map_y = map_pose.y() - grid_map.getLength().y() / 2.0 + resolution / 2;
const auto max_map_y = map_pose.y() + grid_map.getLength().y() / 2.0 - resolution / 2;
const auto & map_size = grid_map.getSize();
// A cell is selected when its center point is inside the polygon
// Thus we restrict the range of x/y values to the center of the top left and bottom right cells
const auto min_x = map_pose.x() - grid_map.getLength().x() / 2.0 + resolution / 2;
const auto max_x = map_pose.x() + grid_map.getLength().x() / 2.0 - resolution / 2;
const auto min_y = map_pose.y() - grid_map.getLength().y() / 2.0 + resolution / 2;
const auto max_y = map_pose.y() + grid_map.getLength().y() / 2.0 - resolution / 2;

// We make line scan from left to right / up to down *in the index frame*.
// In the position frame, this corresponds to high to low Y values and high to low X values.
Expand All @@ -73,12 +71,6 @@ class PolygonIterator
}
};

tier4_autoware_utils::StopWatch<std::chrono::milliseconds> stopwatch;
double edges_d{};
double inter_d{};
double index_d{};

stopwatch.tic("edges");
std::multiset<Edge, Comp> edges;
const auto & vertices = polygon_.getVertices();
for (auto vertex = vertices.cbegin(); std::next(vertex) != vertices.cend(); ++vertex) {
Expand All @@ -89,19 +81,15 @@ class PolygonIterator
edges.insert(edge);
}
}
edges_d += stopwatch.toc("edges");
// get min/max x edge values
const auto max_x = edges.cbegin()->first.x();
const auto min_x = std::prev(edges.cend())->second.x();
const auto max_vertex_x = edges.cbegin()->first.x();
const auto min_vertex_x = std::prev(edges.cend())->second.x();
// get min/max x values truncated to grid cell centers
const auto max_line_x = std::clamp(
min_map_x + resolution * static_cast<int>((max_x - min_map_x) / resolution), min_map_x,
max_map_x);
min_x + resolution * static_cast<int>((max_vertex_x - min_x) / resolution), min_x, max_x);
const auto min_line_x = std::clamp(
min_map_x + resolution * static_cast<int>((min_x - min_map_x) / resolution), min_map_x,
max_map_x);
min_x + resolution * static_cast<int>((min_vertex_x - min_x) / resolution), min_x, max_x);
// calculate for each line the y value intersecting with the polygon in decreasing order
stopwatch.tic("inter");
std::vector<std::multiset<double, std::greater<>>> y_intersections_per_line;
const auto nb_x_lines = static_cast<size_t>((max_line_x - min_line_x) / resolution) + 1;
y_intersections_per_line.reserve(nb_x_lines);
Expand All @@ -125,38 +113,33 @@ class PolygonIterator
}
y_intersections_per_line.push_back(y_intersections);
}
inter_d += stopwatch.toc("inter");
// calculate map indexes between pairs of intersections Y values on each X line
grid_map::Position pos;
grid_map::Index idx;
stopwatch.tic("index");
polygon_indexes_.reserve(
nb_x_lines * static_cast<size_t>((max_map_y - min_map_y) / resolution + 1));
polygon_indexes_.reserve(nb_x_lines * static_cast<size_t>((max_y - min_y) / resolution + 1));
const auto & start_idx = grid_map.getStartIndex();
// TODO(Maxime CLEMENT): from_row can be 1 less than real value due to float precision issue
const auto from_row = static_cast<size_t>((max_x - max_line_x) / resolution);
for (size_t i = 0; i < y_intersections_per_line.size(); ++i) {
const auto y_intersections = y_intersections_per_line[i];
pos.x() = max_line_x - static_cast<double>(i) * resolution;
grid_map.getIndex(pos, idx);
auto row = static_cast<int>(start_idx(0) + from_row + i);
grid_map::wrapIndexToRange(row, map_size(0));
// query the index of the row at it may be shifted in the gridmap
for (auto y_iter = y_intersections.cbegin(); y_iter != y_intersections.cend(); ++y_iter) {
const auto from_y = std::clamp(*y_iter, min_map_y, max_map_y + resolution);
const auto from_col =
static_cast<int>(std::abs(max_map_y + resolution - from_y) / resolution);
const auto from_y = std::clamp(*y_iter, min_y, max_y + resolution);
const auto from_col = static_cast<int>(std::abs(max_y + resolution - from_y) / resolution);

++y_iter;
const auto to_y = std::clamp(*y_iter, min_map_y, max_map_y);
const auto to_col = static_cast<int>(std::abs(max_map_y - to_y) / resolution);
// special case where both intersection points are outside of the map
if (
(from_y >= max_map_y && to_y >= max_map_y) || (from_y <= min_map_y && to_y <= min_map_y))
continue;
const auto to_y = std::clamp(*y_iter, min_y, max_y);
const auto to_col = static_cast<int>(std::abs(max_y - to_y) / resolution);
// TODO(Maxime CLEMENT): remove pairs outside of map directly when finding intersection
// points special case where both intersection points are outside of the map
if ((from_y >= max_y && to_y >= max_y) || (from_y <= min_y && to_y <= min_y)) continue;
for (auto col = from_col; col <= to_col; ++col) {
polygon_indexes_.emplace_back(idx(0), col);
auto wrapped_col = start_idx(1) + col;
grid_map::wrapIndexToRange(wrapped_col, map_size(1));
polygon_indexes_.emplace_back(row, wrapped_col);
}
}
}
index_d += stopwatch.toc("index");
std::cout << "Edges: " << edges_d << std::endl;
std::cout << "Inter: " << inter_d << std::endl;
std::cout << "Index: " << index_d << std::endl;
}

bool operator!=(const PolygonIterator & other) const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,14 +301,16 @@ TEST(PolygonIterator, BenchCompare)

for (double resolution = 0.01; resolution <= 1.00; resolution *= 10) {
map.setGeometry(Length(10.0, 10.0), resolution, Position(0.0, 0.0)); // bufferSize(8, 5)
for (auto seed = 0; seed < 1000; ++seed) {
const auto move = grid_map::Position(2.0, 2.0);
map.move(move);
for (auto seed = 0; seed < 100; ++seed) {
std::cout << seed << std::endl;
std::random_device r;
std::default_random_engine engine(seed);
std::uniform_real_distribution uniform_dist(-2.50, 2.50);
Polygon polygon;
for (const auto & vertex : base_polygon.getVertices()) {
polygon.addVertex(vertex + Position(uniform_dist(engine), uniform_dist(engine)));
polygon.addVertex(vertex + Position(uniform_dist(engine), uniform_dist(engine)) + move);
}
stopwatch.tic("ctor");
apparent_safe_velocity_limiter::PolygonIterator iterator(map, polygon);
Expand All @@ -320,7 +322,7 @@ TEST(PolygonIterator, BenchCompare)
while (!iterator.isPastEnd() && !iterator_gridmap.isPastEnd()) {
// std::cout << (*iterator).transpose() << " " << (*iterator_gridmap).transpose() <<
// std::endl;
EXPECT_EQ((*iterator).x(), (*iterator_gridmap).x());
ASSERT_EQ((*iterator).x(), (*iterator_gridmap).x());
EXPECT_EQ((*iterator).y(), (*iterator_gridmap).y());
stopwatch.tic("iter");
++iterator;
Expand Down