Skip to content

Commit 8ce0ead

Browse files
AlexeyMerzlyakovJoshua Wallace
authored andcommitted
Fix velocities comparison for rotation at place case (ros-navigation#3177)
* Fix velocities comparison for rotation at place case * Meet review item * Remove unnecessary header * Change the comment
1 parent f424310 commit 8ce0ead

File tree

2 files changed

+122
-11
lines changed

2 files changed

+122
-11
lines changed

nav2_collision_monitor/include/nav2_collision_monitor/types.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ struct Velocity
2727

2828
inline bool operator<(const Velocity & second) const
2929
{
30-
const double first_vel = x * x + y * y;
31-
const double second_vel = second.x * second.x + second.y * second.y;
30+
const double first_vel = x * x + y * y + tw * tw;
31+
const double second_vel = second.x * second.x + second.y * second.y + second.tw * second.tw;
32+
// This comparison includes rotations in place, where linear velocities are equal to zero
3233
return first_vel < second_vel;
3334
}
3435

nav2_collision_monitor/test/collision_monitor_node_test.cpp

Lines changed: 119 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "sensor_msgs/msg/range.hpp"
3131
#include "sensor_msgs/point_cloud2_iterator.hpp"
3232
#include "geometry_msgs/msg/twist.hpp"
33+
#include "geometry_msgs/msg/polygon_stamped.hpp"
3334

3435
#include "tf2_ros/transform_broadcaster.h"
3536

@@ -38,13 +39,14 @@
3839

3940
using namespace std::chrono_literals;
4041

41-
static constexpr double EPSILON = std::numeric_limits<float>::epsilon();
42+
static constexpr double EPSILON = 1e-5;
4243

4344
static const char BASE_FRAME_ID[]{"base_link"};
4445
static const char SOURCE_FRAME_ID[]{"base_source"};
4546
static const char ODOM_FRAME_ID[]{"odom"};
4647
static const char CMD_VEL_IN_TOPIC[]{"cmd_vel_in"};
4748
static const char CMD_VEL_OUT_TOPIC[]{"cmd_vel_out"};
49+
static const char FOOTPRINT_TOPIC[]{"footprint"};
4850
static const char SCAN_NAME[]{"Scan"};
4951
static const char POINTCLOUD_NAME[]{"PointCloud"};
5052
static const char RANGE_NAME[]{"Range"};
@@ -132,6 +134,9 @@ class Tester : public ::testing::Test
132134
// Setting TF chains
133135
void sendTransforms(const rclcpp::Time & stamp);
134136

137+
// Publish robot footprint
138+
void publishFootprint(const double radius, const rclcpp::Time & stamp);
139+
135140
// Main topic/data working routines
136141
void publishScan(const double dist, const rclcpp::Time & stamp);
137142
void publishPointCloud(const double dist, const rclcpp::Time & stamp);
@@ -149,6 +154,9 @@ class Tester : public ::testing::Test
149154
// CollisionMonitor node
150155
std::shared_ptr<CollisionMonitorWrapper> cm_;
151156

157+
// Footprint publisher
158+
rclcpp::Publisher<geometry_msgs::msg::PolygonStamped>::SharedPtr footprint_pub_;
159+
152160
// Data source publishers
153161
rclcpp::Publisher<sensor_msgs::msg::LaserScan>::SharedPtr scan_pub_;
154162
rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr pointcloud_pub_;
@@ -165,6 +173,9 @@ Tester::Tester()
165173
{
166174
cm_ = std::make_shared<CollisionMonitorWrapper>();
167175

176+
footprint_pub_ = cm_->create_publisher<geometry_msgs::msg::PolygonStamped>(
177+
FOOTPRINT_TOPIC, rclcpp::QoS(rclcpp::KeepLast(1)).transient_local().reliable());
178+
168179
scan_pub_ = cm_->create_publisher<sensor_msgs::msg::LaserScan>(
169180
SCAN_NAME, rclcpp::QoS(rclcpp::KeepLast(1)).transient_local().reliable());
170181
pointcloud_pub_ = cm_->create_publisher<sensor_msgs::msg::PointCloud2>(
@@ -181,6 +192,8 @@ Tester::Tester()
181192

182193
Tester::~Tester()
183194
{
195+
footprint_pub_.reset();
196+
184197
scan_pub_.reset();
185198
pointcloud_pub_.reset();
186199
range_pub_.reset();
@@ -236,12 +249,19 @@ void Tester::addPolygon(
236249
cm_->set_parameter(
237250
rclcpp::Parameter(polygon_name + ".type", "polygon"));
238251

239-
const std::vector<double> points {
240-
size, size, size, -size, -size, -size, -size, size};
241-
cm_->declare_parameter(
242-
polygon_name + ".points", rclcpp::ParameterValue(points));
243-
cm_->set_parameter(
244-
rclcpp::Parameter(polygon_name + ".points", points));
252+
if (at != "approach") {
253+
const std::vector<double> points {
254+
size, size, size, -size, -size, -size, -size, size};
255+
cm_->declare_parameter(
256+
polygon_name + ".points", rclcpp::ParameterValue(points));
257+
cm_->set_parameter(
258+
rclcpp::Parameter(polygon_name + ".points", points));
259+
} else { // at == "approach"
260+
cm_->declare_parameter(
261+
polygon_name + ".footprint_topic", rclcpp::ParameterValue(FOOTPRINT_TOPIC));
262+
cm_->set_parameter(
263+
rclcpp::Parameter(polygon_name + ".footprint_topic", FOOTPRINT_TOPIC));
264+
}
245265
} else if (type == CIRCLE) {
246266
cm_->declare_parameter(
247267
polygon_name + ".type", rclcpp::ParameterValue("circle"));
@@ -379,6 +399,31 @@ void Tester::sendTransforms(const rclcpp::Time & stamp)
379399
}
380400
}
381401

402+
void Tester::publishFootprint(const double radius, const rclcpp::Time & stamp)
403+
{
404+
std::unique_ptr<geometry_msgs::msg::PolygonStamped> msg =
405+
std::make_unique<geometry_msgs::msg::PolygonStamped>();
406+
407+
msg->header.frame_id = BASE_FRAME_ID;
408+
msg->header.stamp = stamp;
409+
410+
geometry_msgs::msg::Point32 p;
411+
p.x = radius;
412+
p.y = radius;
413+
msg->polygon.points.push_back(p);
414+
p.x = radius;
415+
p.y = -radius;
416+
msg->polygon.points.push_back(p);
417+
p.x = -radius;
418+
p.y = -radius;
419+
msg->polygon.points.push_back(p);
420+
p.x = -radius;
421+
p.y = radius;
422+
msg->polygon.points.push_back(p);
423+
424+
footprint_pub_->publish(std::move(msg));
425+
}
426+
382427
void Tester::publishScan(const double dist, const rclcpp::Time & stamp)
383428
{
384429
std::unique_ptr<sensor_msgs::msg::LaserScan> msg =
@@ -544,7 +589,7 @@ TEST_F(Tester, testProcessStopSlowdown)
544589
ASSERT_NEAR(cmd_vel_out_->linear.y, 0.0, EPSILON);
545590
ASSERT_NEAR(cmd_vel_out_->angular.z, 0.0, EPSILON);
546591

547-
// 4. Restorint back normal operation
592+
// 4. Restoring back normal operation
548593
publishScan(3.0, curr_time);
549594
ASSERT_TRUE(waitData(3.0, 500ms, curr_time));
550595
publishCmdVel(0.5, 0.2, 0.1);
@@ -606,7 +651,7 @@ TEST_F(Tester, testProcessApproach)
606651
ASSERT_NEAR(cmd_vel_out_->linear.y, 0.0, EPSILON);
607652
ASSERT_NEAR(cmd_vel_out_->angular.z, 0.0, EPSILON);
608653

609-
// 4. Restorint back normal operation
654+
// 4. Restoring back normal operation
610655
publishScan(3.0, curr_time);
611656
ASSERT_TRUE(waitData(3.0, 500ms, curr_time));
612657
publishCmdVel(0.5, 0.2, 0.0);
@@ -619,6 +664,71 @@ TEST_F(Tester, testProcessApproach)
619664
cm_->stop();
620665
}
621666

667+
TEST_F(Tester, testProcessApproachRotation)
668+
{
669+
rclcpp::Time curr_time = cm_->now();
670+
671+
// Set Collision Monitor parameters.
672+
// Making one circle footprint for approach.
673+
setCommonParameters();
674+
addPolygon("Approach", POLYGON, 1.0, "approach");
675+
addSource(RANGE_NAME, RANGE);
676+
setVectors({"Approach"}, {RANGE_NAME});
677+
678+
// Start Collision Monitor node
679+
cm_->start();
680+
681+
// Publish robot footprint
682+
publishFootprint(1.0, curr_time);
683+
684+
// Share TF
685+
sendTransforms(curr_time);
686+
687+
// 1. Obstacle is far away from robot
688+
publishRange(2.0, curr_time);
689+
ASSERT_TRUE(waitData(2.0, 500ms, curr_time));
690+
publishCmdVel(0.0, 0.0, M_PI / 4);
691+
ASSERT_TRUE(waitCmdVel(500ms));
692+
ASSERT_NEAR(cmd_vel_out_->linear.x, 0.0, EPSILON);
693+
ASSERT_NEAR(cmd_vel_out_->linear.y, 0.0, EPSILON);
694+
ASSERT_NEAR(cmd_vel_out_->angular.z, M_PI / 4, EPSILON);
695+
696+
// 2. Approaching rotation to obstacle ( M_PI / 4 - M_PI / 20 ahead from robot)
697+
publishRange(1.4, curr_time);
698+
ASSERT_TRUE(waitData(1.4, 500ms, curr_time));
699+
publishCmdVel(0.0, 0.0, M_PI / 4);
700+
ASSERT_TRUE(waitCmdVel(500ms));
701+
ASSERT_NEAR(
702+
cmd_vel_out_->linear.x, 0.0, EPSILON);
703+
ASSERT_NEAR(
704+
cmd_vel_out_->linear.y, 0.0, EPSILON);
705+
ASSERT_NEAR(
706+
cmd_vel_out_->angular.z,
707+
M_PI / 5,
708+
(M_PI / 4) * (SIMULATION_TIME_STEP / TIME_BEFORE_COLLISION));
709+
710+
// 3. Obstacle is inside robot footprint
711+
publishRange(0.5, curr_time);
712+
ASSERT_TRUE(waitData(0.5, 500ms, curr_time));
713+
publishCmdVel(0.0, 0.0, M_PI / 4);
714+
ASSERT_TRUE(waitCmdVel(500ms));
715+
ASSERT_NEAR(cmd_vel_out_->linear.x, 0.0, EPSILON);
716+
ASSERT_NEAR(cmd_vel_out_->linear.y, 0.0, EPSILON);
717+
ASSERT_NEAR(cmd_vel_out_->angular.z, 0.0, EPSILON);
718+
719+
// 4. Restoring back normal operation
720+
publishRange(2.5, curr_time);
721+
ASSERT_TRUE(waitData(2.5, 500ms, curr_time));
722+
publishCmdVel(0.0, 0.0, M_PI / 4);
723+
ASSERT_TRUE(waitCmdVel(500ms));
724+
ASSERT_NEAR(cmd_vel_out_->linear.x, 0.0, EPSILON);
725+
ASSERT_NEAR(cmd_vel_out_->linear.y, 0.0, EPSILON);
726+
ASSERT_NEAR(cmd_vel_out_->angular.z, M_PI / 4, EPSILON);
727+
728+
// Stop Collision Monitor node
729+
cm_->stop();
730+
}
731+
622732
TEST_F(Tester, testCrossOver)
623733
{
624734
rclcpp::Time curr_time = cm_->now();

0 commit comments

Comments
 (0)