Skip to content

Commit 97de6f2

Browse files
Sushant-ChavanAlexeyMerzlyakovSteveMacenskiajtudelaCopilot
authored
Feature/vector object server (#5479)
* Add Vector Object server Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Meet review comments Signed-off-by: Alexey Merzlyakov <[email protected]> * Simplify shapes param configuring Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Rename getROSParameter() to getParameter() Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Return back getMaskData() to nav2_costmap_2d Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Add composition node support Signed-off-by: Alexey Merzlyakov <[email protected]> * Remove redundant methods Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Update nav2_map_server/src/vo_server/vector_object_server.cpp Co-authored-by: Steve Macenski <[email protected]> Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Avoid shapes clearing Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Optimize switchMapUpdate() method Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Switch to vector of shapes Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Minor fixes Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Meet review comments Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Move isPointInside algorithm to nav2_util Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Testcases covering new functionality Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Fix linting issues Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Adjust for Vector Objects demonstration Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Code clean-up * Corrected headers * Functions ordering * Comment fixes Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> * Additional code facelift * Correct licensing years * Fix Vector Object server dependencies * Funcion rename for better readability * Improve/fix comments Signed-off-by: Alexey Merzlyakov <[email protected]> * Minor fixing after rebase Signed-off-by: Alberto Tudela <[email protected]> * Rename vector object server Signed-off-by: Alberto Tudela <[email protected]> * Minor changes Signed-off-by: Alberto Tudela <[email protected]> * Update tests Signed-off-by: Alberto Tudela <[email protected]> * Merge branch 'main' into feature/vector_object_server Signed-off-by: Sushant Chavan <[email protected]> * Fix merge issues and pre-commit checks Signed-off-by: Sushant Chavan <[email protected]> * Change tf2_ros headers from `.h` to `.hpp` Signed-off-by: Sushant Chavan <[email protected]> * Fix race condition in pub-sub of VO map Signed-off-by: Sushant Chavan <[email protected]> * Cleanup Signed-off-by: Sushant Chavan <[email protected]> * Remove use of ament_target_dependencies Signed-off-by: Sushant Chavan <[email protected]> * Fix review comments Signed-off-by: Sushant Chavan <[email protected]> * Fix linter errors Signed-off-by: Sushant Chavan <[email protected]> * Fix exception handling Signed-off-by: Sushant Chavan <[email protected]> * Update nav2_map_server/include/nav2_map_server/vector_object_utils.hpp Co-authored-by: Copilot <[email protected]> Signed-off-by: Steve Macenski <[email protected]> * Update nav2_util/include/nav2_util/raytrace_line_2d.hpp Co-authored-by: Copilot <[email protected]> Signed-off-by: Steve Macenski <[email protected]> * Add error logs Signed-off-by: Sushant Chavan <[email protected]> * Fix cpplint Signed-off-by: Sushant Chavan <[email protected]> --------- Signed-off-by: Alexey Merzlyakov <[email protected]> Signed-off-by: Alberto Tudela <[email protected]> Signed-off-by: Sushant Chavan <[email protected]> Signed-off-by: Steve Macenski <[email protected]> Co-authored-by: Alexey Merzlyakov <[email protected]> Co-authored-by: Alexey Merzlyakov <[email protected]> Co-authored-by: Steve Macenski <[email protected]> Co-authored-by: Alberto Tudela <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 8aea1a8 commit 97de6f2

39 files changed

+4890
-368
lines changed

nav2_collision_monitor/include/nav2_collision_monitor/polygon.hpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,6 @@ class Polygon
239239
rcl_interfaces::msg::SetParametersResult dynamicParametersCallback(
240240
std::vector<rclcpp::Parameter> parameters);
241241

242-
/**
243-
* @brief Checks if point is inside polygon
244-
* @param point Given point to check
245-
* @return True if given point is inside polygon, otherwise false
246-
*/
247-
bool isPointInside(const Point & point) const;
248-
249242
/**
250243
* @brief Extracts Polygon points from a string with of the form [[x1,y1],[x2,y2],[x3,y3]...]
251244
* @param poly_string Input String containing the verteceis of the polygon

nav2_collision_monitor/src/polygon.cpp

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "tf2/transform_datatypes.hpp"
2323

2424
#include "nav2_ros_common/node_utils.hpp"
25+
#include "nav2_util/geometry_utils.hpp"
2526
#include "nav2_util/robot_utils.hpp"
2627
#include "nav2_util/array_parser.hpp"
2728

@@ -229,7 +230,7 @@ int Polygon::getPointsInside(const std::vector<Point> & points) const
229230
{
230231
int num = 0;
231232
for (const Point & point : points) {
232-
if (isPointInside(point)) {
233+
if (nav2_util::geometry_utils::isPointInsidePolygon(point.x, point.y, poly_)) {
233234
num++;
234235
}
235236
}
@@ -602,38 +603,6 @@ void Polygon::polygonCallback(geometry_msgs::msg::PolygonStamped::ConstSharedPtr
602603
updatePolygon(msg);
603604
}
604605

605-
inline bool Polygon::isPointInside(const Point & point) const
606-
{
607-
// Adaptation of Shimrat, Moshe. "Algorithm 112: position of point relative to polygon."
608-
// Communications of the ACM 5.8 (1962): 434.
609-
// Implementation of ray crossings algorithm for point in polygon task solving.
610-
// Y coordinate is fixed. Moving the ray on X+ axis starting from given point.
611-
// Odd number of intersections with polygon boundaries means the point is inside polygon.
612-
const int poly_size = poly_.size();
613-
int i, j; // Polygon vertex iterators
614-
bool res = false; // Final result, initialized with already inverted value
615-
616-
// Starting from the edge where the last point of polygon is connected to the first
617-
i = poly_size - 1;
618-
for (j = 0; j < poly_size; j++) {
619-
// Checking the edge only if given point is between edge boundaries by Y coordinates.
620-
// One of the condition should contain equality in order to exclude the edges
621-
// parallel to X+ ray.
622-
if ((point.y <= poly_[i].y) == (point.y > poly_[j].y)) {
623-
// Calculating the intersection coordinate of X+ ray
624-
const double x_inter = poly_[i].x +
625-
(point.y - poly_[i].y) * (poly_[j].x - poly_[i].x) /
626-
(poly_[j].y - poly_[i].y);
627-
// If intersection with checked edge is greater than point.x coordinate, inverting the result
628-
if (x_inter > point.x) {
629-
res = !res;
630-
}
631-
}
632-
i = j;
633-
}
634-
return res;
635-
}
636-
637606
bool Polygon::getPolygonFromString(
638607
std::string & poly_string,
639608
std::vector<Point> & polygon)

nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d.hpp

Lines changed: 0 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -461,105 +461,7 @@ class Costmap2D
461461
*/
462462
virtual void initMaps(unsigned int size_x, unsigned int size_y);
463463

464-
/**
465-
* @brief Raytrace a line and apply some action at each step
466-
* @param at The action to take... a functor
467-
* @param x0 The starting x coordinate
468-
* @param y0 The starting y coordinate
469-
* @param x1 The ending x coordinate
470-
* @param y1 The ending y coordinate
471-
* @param max_length The maximum desired length of the segment...
472-
* allows you to not go all the way to the endpoint
473-
* @param min_length The minimum desired length of the segment
474-
*/
475-
template<class ActionType>
476-
inline void raytraceLine(
477-
ActionType at, unsigned int x0, unsigned int y0, unsigned int x1,
478-
unsigned int y1,
479-
unsigned int max_length = UINT_MAX, unsigned int min_length = 0)
480-
{
481-
int dx_full = x1 - x0;
482-
int dy_full = y1 - y0;
483-
484-
// we need to chose how much to scale our dominant dimension,
485-
// based on the maximum length of the line
486-
double dist = std::hypot(dx_full, dy_full);
487-
if (dist < min_length) {
488-
return;
489-
}
490-
491-
unsigned int min_x0, min_y0;
492-
if (dist > 0.0) {
493-
// Adjust starting point and offset to start from min_length distance
494-
min_x0 = (unsigned int)(x0 + dx_full / dist * min_length);
495-
min_y0 = (unsigned int)(y0 + dy_full / dist * min_length);
496-
} else {
497-
// dist can be 0 if [x0, y0]==[x1, y1].
498-
// In this case only this cell should be processed.
499-
min_x0 = x0;
500-
min_y0 = y0;
501-
}
502-
unsigned int offset = min_y0 * size_x_ + min_x0;
503-
504-
int dx = x1 - min_x0;
505-
int dy = y1 - min_y0;
506-
507-
unsigned int abs_dx = abs(dx);
508-
unsigned int abs_dy = abs(dy);
509-
510-
int offset_dx = sign(dx);
511-
int offset_dy = sign(dy) * size_x_;
512-
513-
double scale = (dist == 0.0) ? 1.0 : std::min(1.0, max_length / dist);
514-
// if x is dominant
515-
if (abs_dx >= abs_dy) {
516-
int error_y = abs_dx / 2;
517-
518-
bresenham2D(
519-
at, abs_dx, abs_dy, error_y, offset_dx, offset_dy, offset, (unsigned int)(scale * abs_dx));
520-
return;
521-
}
522-
523-
// otherwise y is dominant
524-
int error_x = abs_dy / 2;
525-
526-
bresenham2D(
527-
at, abs_dy, abs_dx, error_x, offset_dy, offset_dx, offset, (unsigned int)(scale * abs_dy));
528-
}
529-
530464
private:
531-
/**
532-
* @brief A 2D implementation of Bresenham's raytracing algorithm...
533-
* applies an action at each step
534-
*/
535-
template<class ActionType>
536-
inline void bresenham2D(
537-
ActionType at, unsigned int abs_da, unsigned int abs_db, int error_b,
538-
int offset_a,
539-
int offset_b, unsigned int offset,
540-
unsigned int max_length)
541-
{
542-
unsigned int end = std::min(max_length, abs_da);
543-
for (unsigned int i = 0; i < end; ++i) {
544-
at(offset);
545-
offset += offset_a;
546-
error_b += abs_db;
547-
if ((unsigned int)error_b >= abs_da) {
548-
offset += offset_b;
549-
error_b -= abs_da;
550-
}
551-
}
552-
at(offset);
553-
}
554-
555-
/**
556-
* @brief get the sign of an int
557-
*/
558-
inline int sign(int x)
559-
{
560-
return x > 0 ? 1.0 : -1.0;
561-
}
562-
563465
mutex_t * access_;
564466

565467
protected:

nav2_costmap_2d/include/nav2_costmap_2d/costmap_filters/costmap_filter.hpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -185,20 +185,6 @@ class CostmapFilter : public Layer
185185
const std::string mask_frame,
186186
geometry_msgs::msg::Pose & mask_pose) const;
187187

188-
/**
189-
* @brief: Convert from world coordinates to mask coordinates.
190-
Similar to Costmap2D::worldToMap() method but works directly with OccupancyGrid-s.
191-
* @param filter_mask Filter mask on which to convert
192-
* @param wx The x world coordinate
193-
* @param wy The y world coordinate
194-
* @param mx Will be set to the associated mask x coordinate
195-
* @param my Will be set to the associated mask y coordinate
196-
* @return True if the conversion was successful (legal bounds) false otherwise
197-
*/
198-
bool worldToMask(
199-
nav_msgs::msg::OccupancyGrid::ConstSharedPtr filter_mask,
200-
double wx, double wy, unsigned int & mx, unsigned int & my) const;
201-
202188
/**
203189
* @brief Get the data of a cell in the filter mask
204190
* @param filter_mask Filter mask to get the data from

nav2_costmap_2d/plugins/costmap_filters/binary_filter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
#include "nav2_costmap_2d/costmap_filters/filter_values.hpp"
4646
#include "nav2_util/occ_grid_values.hpp"
47+
#include "nav2_util/occ_grid_utils.hpp"
4748

4849
namespace nav2_costmap_2d
4950
{
@@ -190,8 +191,8 @@ void BinaryFilter::process(
190191

191192
// Converting mask_pose robot position to filter_mask_ indexes (mask_robot_i, mask_robot_j)
192193
unsigned int mask_robot_i, mask_robot_j;
193-
if (!worldToMask(filter_mask_, mask_pose.position.x, mask_pose.position.y, mask_robot_i,
194-
mask_robot_j))
194+
if (!nav2_util::worldToMap(filter_mask_, mask_pose.position.x, mask_pose.position.y,
195+
mask_robot_i, mask_robot_j))
195196
{
196197
// Robot went out of mask range. Set "false" state by-default
197198
RCLCPP_WARN(

nav2_costmap_2d/plugins/costmap_filters/costmap_filter.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -193,29 +193,6 @@ bool CostmapFilter::transformPose(
193193
return true;
194194
}
195195

196-
bool CostmapFilter::worldToMask(
197-
nav_msgs::msg::OccupancyGrid::ConstSharedPtr filter_mask,
198-
double wx, double wy, unsigned int & mx, unsigned int & my) const
199-
{
200-
const double origin_x = filter_mask->info.origin.position.x;
201-
const double origin_y = filter_mask->info.origin.position.y;
202-
const double resolution = filter_mask->info.resolution;
203-
const unsigned int size_x = filter_mask->info.width;
204-
const unsigned int size_y = filter_mask->info.height;
205-
206-
if (wx < origin_x || wy < origin_y) {
207-
return false;
208-
}
209-
210-
mx = static_cast<unsigned int>((wx - origin_x) / resolution);
211-
my = static_cast<unsigned int>((wy - origin_y) / resolution);
212-
if (mx >= size_x || my >= size_y) {
213-
return false;
214-
}
215-
216-
return true;
217-
}
218-
219196
unsigned char CostmapFilter::getMaskCost(
220197
nav_msgs::msg::OccupancyGrid::ConstSharedPtr filter_mask,
221198
const unsigned int mx, const unsigned int & my) const

nav2_costmap_2d/plugins/costmap_filters/keepout_filter.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,17 @@
3535
* Author: Alexey Merzlyakov
3636
*********************************************************************/
3737

38+
#include "nav2_costmap_2d/costmap_filters/keepout_filter.hpp"
39+
3840
#include <string>
3941
#include <memory>
4042
#include <algorithm>
4143
#include "tf2/convert.hpp"
4244
#include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
4345

44-
#include "nav2_costmap_2d/costmap_filters/keepout_filter.hpp"
4546
#include "nav2_costmap_2d/costmap_filters/filter_values.hpp"
4647
#include "nav2_util/geometry_utils.hpp"
48+
#include "nav2_util/occ_grid_utils.hpp"
4749

4850
namespace nav2_costmap_2d
4951
{
@@ -200,8 +202,8 @@ void KeepoutFilter::updateBounds(
200202
geometry_msgs::msg::Pose mask_pose;
201203
if (transformPose(global_frame_, pose, filter_mask_->header.frame_id, mask_pose)) {
202204
unsigned int mask_robot_i, mask_robot_j;
203-
if (worldToMask(filter_mask_, mask_pose.position.x, mask_pose.position.y, mask_robot_i,
204-
mask_robot_j))
205+
if (nav2_util::worldToMap(filter_mask_, mask_pose.position.x, mask_pose.position.y,
206+
mask_robot_i, mask_robot_j))
205207
{
206208
auto data = getMaskCost(filter_mask_, mask_robot_i, mask_robot_j);
207209
is_pose_lethal_ = (data == INSCRIBED_INFLATED_OBSTACLE || data == LETHAL_OBSTACLE);
@@ -366,7 +368,7 @@ void KeepoutFilter::process(
366368
msk_wy = gl_wy;
367369
}
368370
// Get mask coordinates corresponding to (i, j) point at filter_mask_
369-
if (worldToMask(filter_mask_, msk_wx, msk_wy, mx, my)) {
371+
if (nav2_util::worldToMap(filter_mask_, msk_wx, msk_wy, mx, my)) {
370372
data = getMaskCost(filter_mask_, mx, my);
371373
// Update if mask_ data is valid and greater than existing master_grid's one
372374
if (data == NO_INFORMATION) {

nav2_costmap_2d/plugins/costmap_filters/speed_filter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <string>
4444

4545
#include "nav2_costmap_2d/costmap_filters/filter_values.hpp"
46+
#include "nav2_util/occ_grid_utils.hpp"
4647

4748
namespace nav2_costmap_2d
4849
{
@@ -198,8 +199,8 @@ void SpeedFilter::process(
198199

199200
// Converting mask_pose robot position to filter_mask_ indexes (mask_robot_i, mask_robot_j)
200201
unsigned int mask_robot_i, mask_robot_j;
201-
if (!worldToMask(filter_mask_, mask_pose.position.x, mask_pose.position.y, mask_robot_i,
202-
mask_robot_j))
202+
if (!nav2_util::worldToMap(filter_mask_, mask_pose.position.x, mask_pose.position.y,
203+
mask_robot_i, mask_robot_j))
203204
{
204205
return;
205206
}

nav2_costmap_2d/plugins/obstacle_layer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@
4545

4646
#include "pluginlib/class_list_macros.hpp"
4747
#include "sensor_msgs/point_cloud2_iterator.hpp"
48+
#include "nav2_util/raytrace_line_2d.hpp"
4849
#include "nav2_costmap_2d/costmap_math.hpp"
50+
#include "nav2_ros_common/node_utils.hpp"
4951
#include "rclcpp/version.h"
5052

5153
PLUGINLIB_EXPORT_CLASS(nav2_costmap_2d::ObstacleLayer, nav2_costmap_2d::Layer)
@@ -768,7 +770,8 @@ ObstacleLayer::raytraceFreespace(
768770
unsigned int cell_raytrace_min_range = cellDistance(clearing_observation.raytrace_min_range_);
769771
MarkCell marker(costmap_, FREE_SPACE);
770772
// and finally... we can execute our trace to clear obstacles along that line
771-
raytraceLine(marker, x0, y0, x1, y1, cell_raytrace_max_range, cell_raytrace_min_range);
773+
nav2_util::raytraceLine(
774+
marker, x0, y0, x1, y1, size_x_, cell_raytrace_max_range, cell_raytrace_min_range);
772775

773776
updateRaytraceBounds(
774777
ox, oy, wx, wy, clearing_observation.raytrace_max_range_,

nav2_costmap_2d/src/costmap_2d.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <vector>
4444
#include "nav2_costmap_2d/cost_values.hpp"
4545
#include "nav2_util/occ_grid_values.hpp"
46+
#include "nav2_util/raytrace_line_2d.hpp"
4647

4748
namespace nav2_costmap_2d
4849
{
@@ -462,14 +463,15 @@ void Costmap2D::polygonOutlineCells(
462463
{
463464
PolygonOutlineCells cell_gatherer(*this, costmap_, polygon_cells);
464465
for (unsigned int i = 0; i < polygon.size() - 1; ++i) {
465-
raytraceLine(cell_gatherer, polygon[i].x, polygon[i].y, polygon[i + 1].x, polygon[i + 1].y);
466+
nav2_util::raytraceLine(
467+
cell_gatherer, polygon[i].x, polygon[i].y, polygon[i + 1].x, polygon[i + 1].y, size_x_);
466468
}
467469
if (!polygon.empty()) {
468470
unsigned int last_index = polygon.size() - 1;
469471
// we also need to close the polygon by going from the last point to the first
470-
raytraceLine(
472+
nav2_util::raytraceLine(
471473
cell_gatherer, polygon[last_index].x, polygon[last_index].y, polygon[0].x,
472-
polygon[0].y);
474+
polygon[0].y, size_x_);
473475
}
474476
}
475477

0 commit comments

Comments
 (0)