Skip to content

Commit 12e196b

Browse files
author
Tony Najjar
authored
nav2_collision_monitor: collision detector (#3500) (Iron backport) (#3758)
* nav2_collision_monitor: collision detector (#3500) * fix
1 parent 3a1d41e commit 12e196b

17 files changed

+1491
-32
lines changed

.circleci/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ _commands:
3333
- restore_cache:
3434
name: Restore Cache << parameters.key >>
3535
keys:
36-
- "<< parameters.key >>-v14\
36+
- "<< parameters.key >>-v16\
3737
-{{ arch }}\
3838
-{{ .Branch }}\
3939
-{{ .Environment.CIRCLE_PR_NUMBER }}\
4040
-{{ checksum \"<< parameters.workspace >>/lockfile.txt\" }}"
41-
- "<< parameters.key >>-v14\
41+
- "<< parameters.key >>-v16\
4242
-{{ arch }}\
4343
-main\
4444
-<no value>\
@@ -58,7 +58,7 @@ _commands:
5858
steps:
5959
- save_cache:
6060
name: Save Cache << parameters.key >>
61-
key: "<< parameters.key >>-v14\
61+
key: "<< parameters.key >>-v16\
6262
-{{ arch }}\
6363
-{{ .Branch }}\
6464
-{{ .Environment.CIRCLE_PR_NUMBER }}\

nav2_collision_monitor/CMakeLists.txt

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ set(dependencies
3939
nav2_msgs
4040
)
4141

42-
set(executable_name collision_monitor)
43-
set(library_name ${executable_name}_core)
42+
set(monitor_executable_name collision_monitor)
43+
set(detector_executable_name collision_detector)
44+
set(monitor_library_name ${monitor_executable_name}_core)
45+
set(detector_library_name ${detector_executable_name}_core)
4446

45-
add_library(${library_name} SHARED
47+
add_library(${monitor_library_name} SHARED
4648
src/collision_monitor_node.cpp
4749
src/polygon.cpp
4850
src/circle.cpp
@@ -52,34 +54,59 @@ add_library(${library_name} SHARED
5254
src/range.cpp
5355
src/kinematics.cpp
5456
)
57+
add_library(${detector_library_name} SHARED
58+
src/collision_detector_node.cpp
59+
src/polygon.cpp
60+
src/circle.cpp
61+
src/source.cpp
62+
src/scan.cpp
63+
src/pointcloud.cpp
64+
src/range.cpp
65+
src/kinematics.cpp
66+
)
5567

56-
add_executable(${executable_name}
57-
src/main.cpp
68+
add_executable(${monitor_executable_name}
69+
src/collision_monitor_main.cpp
70+
)
71+
add_executable(${detector_executable_name}
72+
src/collision_detector_main.cpp
5873
)
5974

60-
ament_target_dependencies(${library_name}
75+
ament_target_dependencies(${monitor_library_name}
76+
${dependencies}
77+
)
78+
ament_target_dependencies(${detector_library_name}
6179
${dependencies}
6280
)
6381

64-
target_link_libraries(${executable_name}
65-
${library_name}
82+
target_link_libraries(${monitor_executable_name}
83+
${monitor_library_name}
84+
)
85+
target_link_libraries(${detector_executable_name}
86+
${detector_library_name}
87+
)
88+
89+
ament_target_dependencies(${monitor_executable_name}
90+
${dependencies}
6691
)
6792

68-
ament_target_dependencies(${executable_name}
93+
ament_target_dependencies(${detector_executable_name}
6994
${dependencies}
7095
)
7196

72-
rclcpp_components_register_nodes(${library_name} "nav2_collision_monitor::CollisionMonitor")
97+
rclcpp_components_register_nodes(${monitor_library_name} "nav2_collision_monitor::CollisionMonitor")
98+
99+
rclcpp_components_register_nodes(${detector_library_name} "nav2_collision_monitor::CollisionDetector")
73100

74101
### Install ###
75102

76-
install(TARGETS ${library_name}
103+
install(TARGETS ${monitor_library_name} ${detector_library_name}
77104
ARCHIVE DESTINATION lib
78105
LIBRARY DESTINATION lib
79106
RUNTIME DESTINATION bin
80107
)
81108

82-
install(TARGETS ${executable_name}
109+
install(TARGETS ${monitor_executable_name} ${detector_executable_name}
83110
RUNTIME DESTINATION lib/${PROJECT_NAME}
84111
)
85112

@@ -106,7 +133,7 @@ endif()
106133
### Ament stuff ###
107134

108135
ament_export_include_directories(include)
109-
ament_export_libraries(${library_name})
136+
ament_export_libraries(${monitor_library_name} ${detector_library_name})
110137
ament_export_dependencies(${dependencies})
111138

112139
ament_package()

nav2_collision_monitor/README.md

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Nav2 Collision Monitor
22

3+
## Collision Monitor
4+
35
The Collision Monitor is a node providing an additional level of robot safety.
46
It performs several collision avoidance related tasks using incoming data from the sensors, bypassing the costmap and trajectory planners, to monitor for and prevent potential collisions at the emergency-stop level.
57

@@ -12,7 +14,7 @@ The costmaps / trajectory planners will handle most situations, but this is to h
1214

1315
![polygons.png](doc/polygons.png)
1416

15-
## Features
17+
### Features
1618

1719
The Collision Monitor uses polygons relative the robot's base frame origin to define "zones".
1820
Data that fall into these zones trigger an operation depending on the model being used.
@@ -23,7 +25,6 @@ The following models of safety behaviors are employed by Collision Monitor:
2325

2426
* **Stop model**: Define a zone and a point threshold. If more that `N` obstacle points appear inside this area, stop the robot until the obstacles will disappear.
2527
* **Slowdown model**: Define a zone around the robot and slow the maximum speed for a `%S` percent, if more than `N` points will appear inside the area.
26-
* **Limit model**: Define a zone around the robot and clamp the maximum speed below a fixed value, if more than `N` points will appear inside the area.
2728
* **Approach model**: Using the current robot speed, estimate the time to collision to sensor data. If the time is less than `M` seconds (0.5, 2, 5, etc...), the robot will slow such that it is now at least `M` seconds to collision. The effect here would be to keep the robot always `M` seconds from any collision.
2829

2930
The zones around the robot can take the following shapes:
@@ -38,20 +39,19 @@ The data may be obtained from different data sources:
3839
* PointClouds (`sensor_msgs::msg::PointCloud2` messages)
3940
* IR/Sonars (`sensor_msgs::msg::Range` messages)
4041

41-
## Design
42+
### Design
4243

4344
The Collision Monitor is designed to operate below Nav2 as an independent safety node.
4445
This acts as a filter on the `cmd_vel` topic coming out of the Controller Server. If no such zone is triggered, then the Controller's `cmd_vel` is used. Else, it is scaled or set to stop as appropriate.
4546

4647
The following diagram is showing the high-level design of Collision Monitor module. All shapes (Polygons and Circles) are derived from base `Polygon` class, so without loss of generality we can call them as polygons. Subscribed footprint is also having the same properties as other polygons, but it is being obtained a footprint topic for the Approach Model.
4748
![HLD.png](doc/HLD.png)
48-
49-
## Configuration
49+
### Configuration
5050

5151
Detailed configuration parameters, their description and how to setup a Collision Monitor could be found at its [Configuration Guide](https://navigation.ros.org/configuration/packages/configuring-collision-monitor.html) and [Using Collision Monitor tutorial](https://navigation.ros.org/tutorials/docs/using_collision_monitor.html) pages.
5252

5353

54-
## Metrics
54+
### Metrics
5555

5656
Designed to be used in wide variety of robots (incl. moving fast) and have a high level of reliability, Collision Monitor node should operate at fast rates.
5757
Typical one frame processing time is ~4-5ms for laser scanner (with 360 points) and ~4-20ms for PointClouds (having 24K points).
@@ -66,3 +66,21 @@ The following notes could be made:
6666

6767
* Due to sheer speed, circle shapes are preferred for the approach behavior models if you can approximately model your robot as circular.
6868
* More points mean lower performance. Pointclouds could be culled or filtered before the Collision Monitor to improve performance.
69+
70+
71+
## Collision Detector
72+
73+
In some cases, the user may want to be informed about the detected obstacles without affecting the robot's velocity and instead take a different action within an external node. For example, the user may want to blink LEDs or sound an alarm when the robot is close to an obstacle. Another use case could be to detect data points in particular regions (e.g extremely close to the sensor) and warn of malfunctioning sensors. For this purpose, the Collision Detector node was introduced.
74+
75+
It works similarly to the Collision Monitor, but does not affect the robot's velocity. It will only inform that data from the configured sources has been detected within the configured polygons via message to the `collision_detector_state` topic.
76+
77+
### Features
78+
79+
Similarly to the Collision Monitor, the Collision Detector uses polygons relative the robot's base frame origin to define "zones".
80+
However, unlike the Collision Monitor that uses different behavior models, the Collision Detector does not use any of them and therefore the `action_type` should always be set to `none`. If set to anything else, it will implicitly be set to `none` and yield a warning.
81+
82+
The zones around the robot and the data sources are the same as for the Collision Monitor, with the exception of the footprint polygon, which is not supported by the Collision Detector.
83+
84+
### Configuration
85+
86+
Detailed configuration parameters, their description and how to setup a Collision Detector could be found at its [Configuration Guide](https://navigation.ros.org/configuration/packages/configuring-collision-detector.html).
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// Copyright (c) 2022 Samsung R&D Institute Russia
2+
// Copyright (c) 2023 Pixel Robotics GmbH
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
#ifndef NAV2_COLLISION_MONITOR__COLLISION_DETECTOR_NODE_HPP_
17+
#define NAV2_COLLISION_MONITOR__COLLISION_DETECTOR_NODE_HPP_
18+
19+
#include <string>
20+
#include <vector>
21+
#include <memory>
22+
23+
#include "rclcpp/rclcpp.hpp"
24+
25+
#include "tf2/time.h"
26+
#include "tf2_ros/buffer.h"
27+
#include "tf2_ros/transform_listener.h"
28+
29+
#include "nav2_util/lifecycle_node.hpp"
30+
#include "nav2_msgs/msg/collision_detector_state.hpp"
31+
32+
#include "nav2_collision_monitor/types.hpp"
33+
#include "nav2_collision_monitor/polygon.hpp"
34+
#include "nav2_collision_monitor/circle.hpp"
35+
#include "nav2_collision_monitor/source.hpp"
36+
#include "nav2_collision_monitor/scan.hpp"
37+
#include "nav2_collision_monitor/pointcloud.hpp"
38+
#include "nav2_collision_monitor/range.hpp"
39+
40+
namespace nav2_collision_monitor
41+
{
42+
43+
/**
44+
* @brief Collision Monitor ROS2 node
45+
*/
46+
class CollisionDetector : public nav2_util::LifecycleNode
47+
{
48+
public:
49+
/**
50+
* @brief Constructor for the nav2_collision_monitor::CollisionDetector
51+
* @param options Additional options to control creation of the node.
52+
*/
53+
explicit CollisionDetector(const rclcpp::NodeOptions & options = rclcpp::NodeOptions());
54+
/**
55+
* @brief Destructor for the nav2_collision_monitor::CollisionDetector
56+
*/
57+
~CollisionDetector();
58+
59+
protected:
60+
/**
61+
* @brief: Initializes and obtains ROS-parameters, creates main subscribers and publishers,
62+
* creates polygons and data sources objects
63+
* @param state Lifecycle Node's state
64+
* @return Success or Failure
65+
*/
66+
nav2_util::CallbackReturn on_configure(const rclcpp_lifecycle::State & state) override;
67+
/**
68+
* @brief: Activates LifecyclePublishers, polygons and main processor, creates bond connection
69+
* @param state Lifecycle Node's state
70+
* @return Success or Failure
71+
*/
72+
nav2_util::CallbackReturn on_activate(const rclcpp_lifecycle::State & state) override;
73+
/**
74+
* @brief: Deactivates LifecyclePublishers, polygons and main processor, destroys bond connection
75+
* @param state Lifecycle Node's state
76+
* @return Success or Failure
77+
*/
78+
nav2_util::CallbackReturn on_deactivate(const rclcpp_lifecycle::State & state) override;
79+
/**
80+
* @brief: Resets all subscribers/publishers, polygons/data sources arrays
81+
* @param state Lifecycle Node's state
82+
* @return Success or Failure
83+
*/
84+
nav2_util::CallbackReturn on_cleanup(const rclcpp_lifecycle::State & state) override;
85+
/**
86+
* @brief Called in shutdown state
87+
* @param state Lifecycle Node's state
88+
* @return Success or Failure
89+
*/
90+
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State & state) override;
91+
92+
protected:
93+
/**
94+
* @brief Supporting routine obtaining all ROS-parameters
95+
* @return True if all parameters were obtained or false in failure case
96+
*/
97+
bool getParameters();
98+
/**
99+
* @brief Supporting routine creating and configuring all polygons
100+
* @param base_frame_id Robot base frame ID
101+
* @param transform_tolerance Transform tolerance
102+
* @return True if all polygons were configured successfully or false in failure case
103+
*/
104+
bool configurePolygons(
105+
const std::string & base_frame_id,
106+
const tf2::Duration & transform_tolerance);
107+
/**
108+
* @brief Supporting routine creating and configuring all data sources
109+
* @param base_frame_id Robot base frame ID
110+
* @param odom_frame_id Odometry frame ID. Used as global frame to get
111+
* source->base time interpolated transform.
112+
* @param transform_tolerance Transform tolerance
113+
* @param source_timeout Maximum time interval in which data is considered valid
114+
* @param base_shift_correction Whether to correct source data towards to base frame movement,
115+
* considering the difference between current time and latest source time
116+
* @return True if all sources were configured successfully or false in failure case
117+
*/
118+
bool configureSources(
119+
const std::string & base_frame_id,
120+
const std::string & odom_frame_id,
121+
const tf2::Duration & transform_tolerance,
122+
const rclcpp::Duration & source_timeout,
123+
const bool base_shift_correction);
124+
125+
/**
126+
* @brief Main processing routine
127+
*/
128+
void process();
129+
130+
/**
131+
* @brief Polygons publishing routine. Made for visualization.
132+
*/
133+
void publishPolygons() const;
134+
135+
// ----- Variables -----
136+
137+
/// @brief TF buffer
138+
std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
139+
/// @brief TF listener
140+
std::shared_ptr<tf2_ros::TransformListener> tf_listener_;
141+
142+
/// @brief Polygons array
143+
std::vector<std::shared_ptr<Polygon>> polygons_;
144+
/// @brief Data sources array
145+
std::vector<std::shared_ptr<Source>> sources_;
146+
147+
/// @brief collision monitor state publisher
148+
rclcpp_lifecycle::LifecyclePublisher<nav2_msgs::msg::CollisionDetectorState>::SharedPtr
149+
state_pub_;
150+
/// @brief timer that runs actions
151+
rclcpp::TimerBase::SharedPtr timer_;
152+
153+
/// @brief main loop frequency
154+
double frequency_;
155+
}; // class CollisionDetector
156+
157+
} // namespace nav2_collision_monitor
158+
159+
#endif // NAV2_COLLISION_MONITOR__COLLISION_DETECTOR_NODE_HPP_

nav2_collision_monitor/include/nav2_collision_monitor/collision_monitor_node.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ class CollisionMonitor : public nav2_util::LifecycleNode
4747
{
4848
public:
4949
/**
50-
* @brief Constructor for the nav2_collision_safery::CollisionMonitor
50+
* @brief Constructor for the nav2_collision_monitor::CollisionMonitor
5151
* @param options Additional options to control creation of the node.
5252
*/
5353
explicit CollisionMonitor(const rclcpp::NodeOptions & options = rclcpp::NodeOptions());
5454
/**
55-
* @brief Destructor for the nav2_collision_safery::CollisionMonitor
55+
* @brief Destructor for the nav2_collision_monitor::CollisionMonitor
5656
*/
5757
~CollisionMonitor();
5858

@@ -126,7 +126,7 @@ class CollisionMonitor : public nav2_util::LifecycleNode
126126
* @brief Supporting routine creating and configuring all data sources
127127
* @param base_frame_id Robot base frame ID
128128
* @param odom_frame_id Odometry frame ID. Used as global frame to get
129-
* source->base time inerpolated transform.
129+
* source->base time interpolated transform.
130130
* @param transform_tolerance Transform tolerance
131131
* @param source_timeout Maximum time interval in which data is considered valid
132132
* @param base_shift_correction Whether to correct source data towards to base frame movement,

0 commit comments

Comments
 (0)