@@ -162,6 +162,7 @@ class Tester : public ::testing::Test
162162 void setPolygonVelocityVectors (
163163 const std::string & polygon_name,
164164 const std::vector<std::string> & polygons);
165+ void setGlobalHeightParams (const std::string & source_name, const double min_height);
165166
166167 // Setting TF chains
167168 void sendTransforms (const rclcpp::Time & stamp);
@@ -172,6 +173,9 @@ class Tester : public ::testing::Test
172173 // Main topic/data working routines
173174 void publishScan (const double dist, const rclcpp::Time & stamp);
174175 void publishPointCloud (const double dist, const rclcpp::Time & stamp);
176+ void publishPointCloudWithHeight (
177+ const double dist, const double height,
178+ const rclcpp::Time & stamp);
175179 void publishRange (const double dist, const rclcpp::Time & stamp);
176180 void publishPolygon (const double dist, const rclcpp::Time & stamp);
177181 void publishCmdVel (const double x, const double y, const double tw);
@@ -491,6 +495,8 @@ void Tester::addSource(
491495 source_name + " .max_height" , rclcpp::ParameterValue (1.0 ));
492496 cm_->set_parameter (
493497 rclcpp::Parameter (source_name + " .max_height" , 1.0 ));
498+ cm_->declare_parameter (
499+ source_name + " .use_global_height" , rclcpp::ParameterValue (false ));
494500 } else if (type == RANGE) {
495501 cm_->declare_parameter (
496502 source_name + " .type" , rclcpp::ParameterValue (" range" ));
@@ -547,6 +553,12 @@ void Tester::setPolygonVelocityVectors(
547553 cm_->set_parameter (rclcpp::Parameter (polygon_name + " .velocity_polygons" , polygons));
548554}
549555
556+ void Tester::setGlobalHeightParams (const std::string & source_name, const double min_height)
557+ {
558+ cm_->set_parameter (rclcpp::Parameter (source_name + " .use_global_height" , true ));
559+ cm_->set_parameter (rclcpp::Parameter (source_name + " .min_height" , min_height));
560+ }
561+
550562void Tester::sendTransforms (const rclcpp::Time & stamp)
551563{
552564 std::shared_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster =
@@ -654,6 +666,45 @@ void Tester::publishPointCloud(const double dist, const rclcpp::Time & stamp)
654666 pointcloud_pub_->publish (std::move (msg));
655667}
656668
669+ void Tester::publishPointCloudWithHeight (
670+ const double dist, const double height,
671+ const rclcpp::Time & stamp)
672+ {
673+ std::unique_ptr<sensor_msgs::msg::PointCloud2> msg =
674+ std::make_unique<sensor_msgs::msg::PointCloud2>();
675+ sensor_msgs::PointCloud2Modifier modifier (*msg);
676+
677+ msg->header .frame_id = SOURCE_FRAME_ID;
678+ msg->header .stamp = stamp;
679+
680+ modifier.setPointCloud2Fields (
681+ 4 , " x" , 1 , sensor_msgs::msg::PointField::FLOAT32,
682+ " y" , 1 , sensor_msgs::msg::PointField::FLOAT32,
683+ " z" , 1 , sensor_msgs::msg::PointField::FLOAT32,
684+ " height" , 1 , sensor_msgs::msg::PointField::FLOAT32);
685+ modifier.resize (2 );
686+
687+ sensor_msgs::PointCloud2Iterator<float > iter_x (*msg, " x" );
688+ sensor_msgs::PointCloud2Iterator<float > iter_y (*msg, " y" );
689+ sensor_msgs::PointCloud2Iterator<float > iter_z (*msg, " z" );
690+ sensor_msgs::PointCloud2Iterator<float > iter_height (*msg, " height" );
691+
692+ // Point 0: (dist, 0.01, 0.2, height)
693+ *iter_x = dist;
694+ *iter_y = 0.01 ;
695+ *iter_z = 0.2 ;
696+ *iter_height = height;
697+ ++iter_x; ++iter_y; ++iter_z; ++iter_height;
698+
699+ // Point 1: (dist, -0.01, 0.2, height)
700+ *iter_x = dist;
701+ *iter_y = -0.01 ;
702+ *iter_z = 0.2 ;
703+ *iter_height = height;
704+
705+ pointcloud_pub_->publish (std::move (msg));
706+ }
707+
657708void Tester::publishRange (const double dist, const rclcpp::Time & stamp)
658709{
659710 std::unique_ptr<sensor_msgs::msg::Range> msg =
@@ -1656,6 +1707,64 @@ TEST_F(Tester, testVelocityPolygonStop)
16561707 cm_->stop ();
16571708}
16581709
1710+ TEST_F (Tester, testVelocityPolygonStopGlobalHeight)
1711+ {
1712+ // Set Collision Monitor parameters.
1713+ // Add velocity polygon with 2 sub polygon:
1714+ // 1. Forward: 0 -> 0.5 m/s
1715+ // 2. Backward: 0 -> -0.5 m/s
1716+ setCommonParameters ();
1717+ addPolygon (" VelocityPolygon" , VELOCITY_POLYGON, 1.0 , " stop" );
1718+ addPolygonVelocitySubPolygon (" VelocityPolygon" , " Forward" , 0.0 , 0.5 , 0.0 , 1.0 , 4.0 );
1719+ addPolygonVelocitySubPolygon (" VelocityPolygon" , " Backward" , -0.5 , 0.0 , 0.0 , 1.0 , 2.0 );
1720+ setPolygonVelocityVectors (" VelocityPolygon" , {" Forward" , " Backward" });
1721+ addSource (POINTCLOUD_NAME, POINTCLOUD);
1722+ setGlobalHeightParams (POINTCLOUD_NAME, 0.5 );
1723+ setVectors ({" VelocityPolygon" }, {POINTCLOUD_NAME});
1724+
1725+ cm_->set_parameter (
1726+ rclcpp::Parameter (" source_timeout" , 2.0 ));
1727+
1728+ rclcpp::Time curr_time = cm_->now ();
1729+ // Start Collision Monitor node
1730+ cm_->start ();
1731+ // Check that robot stops when source is enabled
1732+ sendTransforms (curr_time);
1733+
1734+ // 1. Obstacle is in Forward velocity polygon and below global height
1735+ publishPointCloudWithHeight (3.0 , 0.4 , curr_time);
1736+ ASSERT_FALSE (waitData (std::hypot (3.0 , 0.01 ), 500ms, curr_time));
1737+ publishCmdVel (0.4 , 0.0 , 0.1 );
1738+ ASSERT_TRUE (waitCmdVel (500ms));
1739+ ASSERT_NEAR (cmd_vel_out_->linear .x , 0.4 , EPSILON);
1740+ ASSERT_NEAR (cmd_vel_out_->linear .y , 0.0 , EPSILON);
1741+ ASSERT_NEAR (cmd_vel_out_->angular .z , 0.1 , EPSILON);
1742+
1743+ // 2. Obstacle is in Forward velocity polygon and above global height
1744+ publishPointCloudWithHeight (3.0 , 0.6 , curr_time);
1745+ ASSERT_TRUE (waitData (std::hypot (3.0 , 0.01 ), 500ms, curr_time));
1746+ publishCmdVel (0.4 , 0.0 , 0.1 );
1747+ ASSERT_TRUE (waitCmdVel (500ms));
1748+ ASSERT_NEAR (cmd_vel_out_->linear .x , 0.0 , EPSILON);
1749+ ASSERT_NEAR (cmd_vel_out_->linear .y , 0.0 , EPSILON);
1750+ ASSERT_NEAR (cmd_vel_out_->angular .z , 0.0 , EPSILON);
1751+ ASSERT_TRUE (waitActionState (500ms));
1752+ ASSERT_EQ (action_state_->action_type , STOP);
1753+ ASSERT_EQ (action_state_->polygon_name , " VelocityPolygon" );
1754+
1755+ // 3. Pointcloud without height field, invalid source.
1756+ publishPointCloud (2.5 , curr_time);
1757+ ASSERT_FALSE (waitData (std::hypot (2.5 , 0.01 ), 100ms, curr_time));
1758+ publishCmdVel (3.0 , 3.0 , 3.0 );
1759+ ASSERT_FALSE (waitCmdVel (500ms));
1760+ ASSERT_TRUE (waitActionState (500ms));
1761+ ASSERT_EQ (action_state_->action_type , STOP);
1762+ ASSERT_EQ (action_state_->polygon_name , " invalid source" );
1763+
1764+ // Stop Collision Monitor node
1765+ cm_->stop ();
1766+ }
1767+
16591768TEST_F (Tester, testSourceAssociatedToPolygon)
16601769{
16611770 // Set Collision Monitor parameters:
0 commit comments