Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions nav2_collision_monitor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ find_package(nav2_common REQUIRED)
find_package(nav2_util REQUIRED)
find_package(nav2_costmap_2d REQUIRED)
find_package(nav2_msgs REQUIRED)
find_package(visualization_msgs REQUIRED)

### Header ###

Expand All @@ -37,6 +38,7 @@ set(dependencies
nav2_util
nav2_costmap_2d
nav2_msgs
visualization_msgs
)

set(monitor_executable_name collision_monitor)
Expand All @@ -51,6 +53,7 @@ add_library(${monitor_library_name} SHARED
src/source.cpp
src/scan.cpp
src/pointcloud.cpp
src/polygon_source.cpp
src/range.cpp
src/kinematics.cpp
)
Expand All @@ -61,6 +64,7 @@ add_library(${detector_library_name} SHARED
src/source.cpp
src/scan.cpp
src/pointcloud.cpp
src/polygon_source.cpp
src/range.cpp
src/kinematics.cpp
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include "nav2_util/lifecycle_node.hpp"
#include "nav2_msgs/msg/collision_detector_state.hpp"
#include "visualization_msgs/msg/marker_array.hpp"

#include "nav2_collision_monitor/types.hpp"
#include "nav2_collision_monitor/polygon.hpp"
Expand All @@ -36,6 +37,7 @@
#include "nav2_collision_monitor/scan.hpp"
#include "nav2_collision_monitor/pointcloud.hpp"
#include "nav2_collision_monitor/range.hpp"
#include "nav2_collision_monitor/polygon_source.hpp"

namespace nav2_collision_monitor
{
Expand Down Expand Up @@ -147,6 +149,9 @@ class CollisionDetector : public nav2_util::LifecycleNode
/// @brief collision monitor state publisher
rclcpp_lifecycle::LifecyclePublisher<nav2_msgs::msg::CollisionDetectorState>::SharedPtr
state_pub_;
/// @brief Collision points marker publisher
rclcpp_lifecycle::LifecyclePublisher<visualization_msgs::msg::MarkerArray>::SharedPtr
collision_points_marker_pub_;
/// @brief timer that runs actions
rclcpp::TimerBase::SharedPtr timer_;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include "visualization_msgs/msg/marker_array.hpp"

#include "tf2/time.h"
#include "tf2_ros/buffer.h"
Expand All @@ -36,6 +37,7 @@
#include "nav2_collision_monitor/scan.hpp"
#include "nav2_collision_monitor/pointcloud.hpp"
#include "nav2_collision_monitor/range.hpp"
#include "nav2_collision_monitor/polygon_source.hpp"

namespace nav2_collision_monitor
{
Expand Down Expand Up @@ -107,6 +109,7 @@ class CollisionMonitor : public nav2_util::LifecycleNode
* @param cmd_vel_in_topic Output name of cmd_vel_in topic
* @param cmd_vel_out_topic Output name of cmd_vel_out topic
* is required.
* @param state_topic topic name for publishing collision monitor state
* @return True if all parameters were obtained or false in failure case
*/
bool getParameters(
Expand Down Expand Up @@ -210,6 +213,10 @@ class CollisionMonitor : public nav2_util::LifecycleNode
rclcpp_lifecycle::LifecyclePublisher<nav2_msgs::msg::CollisionMonitorState>::SharedPtr
state_pub_;

/// @brief Collision points marker publisher
rclcpp_lifecycle::LifecyclePublisher<visualization_msgs::msg::MarkerArray>::SharedPtr
collision_points_marker_pub_;

/// @brief Whether main routine is active
bool process_active_;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright (c) 2023 Pixel Robotics GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef NAV2_COLLISION_MONITOR__POLYGON_SOURCE_HPP_
#define NAV2_COLLISION_MONITOR__POLYGON_SOURCE_HPP_

#include <memory>
#include <vector>
#include <string>

#include "nav2_msgs/msg/polygons_array.hpp"

#include "nav2_collision_monitor/source.hpp"

namespace nav2_collision_monitor
{

/**
* @brief Implementation for polygon source
*/
class PolygonSource : public Source
{
public:
/**
* @brief PolygonSource constructor
* @param node Collision Monitor node pointer
* @param source_name Name of data source
* @param tf_buffer Shared pointer to a TF buffer
* @param base_frame_id Robot base frame ID. The output data will be transformed into this frame.
* @param global_frame_id Global frame ID for correct transform calculation
* @param transform_tolerance Transform tolerance
* @param source_timeout Maximum time interval in which data is considered valid
* @param base_shift_correction Whether to correct source data towards to base frame movement,
* considering the difference between current time and latest source time
*/
PolygonSource(
const nav2_util::LifecycleNode::WeakPtr & node,
const std::string & source_name,
const std::shared_ptr<tf2_ros::Buffer> tf_buffer,
const std::string & base_frame_id,
const std::string & global_frame_id,
const tf2::Duration & transform_tolerance,
const rclcpp::Duration & source_timeout,
const bool base_shift_correction);
/**
* @brief PolygonSource destructor
*/
~PolygonSource();

/**
* @brief Data source configuration routine. Obtains ROS-parameters
* and creates subscriber.
*/
void configure();

/**
* @brief Adds latest data from polygon source to the data array.
* @param curr_time Current node time for data interpolation
* @param data Array where the data from source to be added.
* Added data is transformed to base_frame_id_ coordinate system at curr_time.
*/
void getData(
const rclcpp::Time & curr_time,
std::vector<Point> & data) const;

void convertPolygonStampedToPoints(
const geometry_msgs::msg::PolygonStamped & polygon,
std::vector<Point> & data) const;

protected:
/**
* @brief Getting sensor-specific ROS-parameters
* @param source_topic Output name of source subscription topic
*/
void getParameters(std::string & source_topic);

/**
* @brief PolygonSource data callback
* @param msg Shared pointer to PolygonSource message
*/
void dataCallback(nav2_msgs::msg::PolygonsArray::ConstSharedPtr msg);

// ----- Variables -----

/// @brief PolygonSource data subscriber
rclcpp::Subscription<nav2_msgs::msg::PolygonsArray>::SharedPtr data_sub_;

/// @brief Latest data obtained
nav2_msgs::msg::PolygonsArray::ConstSharedPtr data_;

/// @brief distance between sampled points on polygon edges
double sampling_distance_;
}; // class PolygonSource

} // namespace nav2_collision_monitor

#endif // NAV2_COLLISION_MONITOR__POLYGON_SOURCE_HPP_
1 change: 1 addition & 0 deletions nav2_collision_monitor/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<depend>nav2_util</depend>
<depend>nav2_costmap_2d</depend>
<depend>nav2_msgs</depend>
<depend>visualization_msgs</depend>

<test_depend>ament_cmake_gtest</test_depend>
<test_depend>ament_lint_common</test_depend>
Expand Down
40 changes: 40 additions & 0 deletions nav2_collision_monitor/src/collision_detector_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ CollisionDetector::on_configure(const rclcpp_lifecycle::State & /*state*/)
state_pub_ = this->create_publisher<nav2_msgs::msg::CollisionDetectorState>(
"collision_detector_state", rclcpp::SystemDefaultsQoS());

collision_points_marker_pub_ = this->create_publisher<visualization_msgs::msg::MarkerArray>(
"~/collision_points_marker", 1);

// Obtaining ROS parameters
if (!getParameters()) {
return nav2_util::CallbackReturn::FAILURE;
Expand All @@ -70,6 +73,7 @@ CollisionDetector::on_activate(const rclcpp_lifecycle::State & /*state*/)

// Activating lifecycle publisher
state_pub_->on_activate();
collision_points_marker_pub_->on_activate();

// Activating polygons
for (std::shared_ptr<Polygon> polygon : polygons_) {
Expand Down Expand Up @@ -97,6 +101,7 @@ CollisionDetector::on_deactivate(const rclcpp_lifecycle::State & /*state*/)

// Deactivating lifecycle publishers
state_pub_->on_deactivate();
collision_points_marker_pub_->on_deactivate();

// Deactivating polygons
for (std::shared_ptr<Polygon> polygon : polygons_) {
Expand All @@ -115,6 +120,7 @@ CollisionDetector::on_cleanup(const rclcpp_lifecycle::State & /*state*/)
RCLCPP_INFO(get_logger(), "Cleaning up");

state_pub_.reset();
collision_points_marker_pub_.reset();

polygons_.clear();
sources_.clear();
Expand Down Expand Up @@ -278,6 +284,13 @@ bool CollisionDetector::configureSources(
r->configure();

sources_.push_back(r);
} else if (source_type == "polygon") {
std::shared_ptr<PolygonSource> ps = std::make_shared<PolygonSource>(
node, source_name, tf_buffer_, base_frame_id, odom_frame_id,
transform_tolerance, source_timeout, base_shift_correction);
ps->configure();

sources_.push_back(ps);
} else { // Error if something else
RCLCPP_ERROR(
get_logger(),
Expand Down Expand Up @@ -309,6 +322,33 @@ void CollisionDetector::process()
}
}

if (collision_points_marker_pub_->get_subscription_count() > 0) {
// visualize collision points with markers
auto marker_array = std::make_unique<visualization_msgs::msg::MarkerArray>();
visualization_msgs::msg::Marker marker;
marker.header.frame_id = get_parameter("base_frame_id").as_string();
marker.header.stamp = rclcpp::Time(0, 0);
marker.ns = "collision_points";
marker.id = 0;
marker.type = visualization_msgs::msg::Marker::POINTS;
marker.action = visualization_msgs::msg::Marker::ADD;
marker.scale.x = 0.02;
marker.scale.y = 0.02;
marker.color.r = 1.0;
marker.color.a = 1.0;
marker.lifetime = rclcpp::Duration(0, 0);

for (const auto & point : collision_points) {
geometry_msgs::msg::Point p;
p.x = point.x;
p.y = point.y;
p.z = 0.0;
marker.points.push_back(p);
}
marker_array->markers.push_back(marker);
collision_points_marker_pub_->publish(std::move(marker_array));
}

std::unique_ptr<nav2_msgs::msg::CollisionDetectorState> state_msg =
std::make_unique<nav2_msgs::msg::CollisionDetectorState>();

Expand Down
41 changes: 41 additions & 0 deletions nav2_collision_monitor/src/collision_monitor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,15 @@ CollisionMonitor::on_configure(const rclcpp_lifecycle::State & /*state*/)
std::bind(&CollisionMonitor::cmdVelInCallback, this, std::placeholders::_1));
cmd_vel_out_pub_ = this->create_publisher<geometry_msgs::msg::Twist>(
cmd_vel_out_topic, 1);

if (!state_topic.empty()) {
state_pub_ = this->create_publisher<nav2_msgs::msg::CollisionMonitorState>(
state_topic, 1);
}

collision_points_marker_pub_ = this->create_publisher<visualization_msgs::msg::MarkerArray>(
"~/collision_points_marker", 1);

return nav2_util::CallbackReturn::SUCCESS;
}

Expand All @@ -86,6 +90,7 @@ CollisionMonitor::on_activate(const rclcpp_lifecycle::State & /*state*/)
if (state_pub_) {
state_pub_->on_activate();
}
collision_points_marker_pub_->on_activate();

// Activating polygons
for (std::shared_ptr<Polygon> polygon : polygons_) {
Expand Down Expand Up @@ -126,6 +131,7 @@ CollisionMonitor::on_deactivate(const rclcpp_lifecycle::State & /*state*/)
if (state_pub_) {
state_pub_->on_deactivate();
}
collision_points_marker_pub_->on_deactivate();

// Destroying bond connection
destroyBond();
Expand All @@ -141,6 +147,7 @@ CollisionMonitor::on_cleanup(const rclcpp_lifecycle::State & /*state*/)
cmd_vel_in_sub_.reset();
cmd_vel_out_pub_.reset();
state_pub_.reset();
collision_points_marker_pub_.reset();

polygons_.clear();
sources_.clear();
Expand Down Expand Up @@ -342,6 +349,13 @@ bool CollisionMonitor::configureSources(
r->configure();

sources_.push_back(r);
} else if (source_type == "polygon") {
std::shared_ptr<PolygonSource> ps = std::make_shared<PolygonSource>(
node, source_name, tf_buffer_, base_frame_id, odom_frame_id,
transform_tolerance, source_timeout, base_shift_correction);
ps->configure();

sources_.push_back(ps);
} else { // Error if something else
RCLCPP_ERROR(
get_logger(),
Expand Down Expand Up @@ -378,6 +392,33 @@ void CollisionMonitor::process(const Velocity & cmd_vel_in)
}
}

if (collision_points_marker_pub_->get_subscription_count() > 0) {
// visualize collision points with markers
auto marker_array = std::make_unique<visualization_msgs::msg::MarkerArray>();
visualization_msgs::msg::Marker marker;
marker.header.frame_id = get_parameter("base_frame_id").as_string();
marker.header.stamp = rclcpp::Time(0, 0);
marker.ns = "collision_points";
marker.id = 0;
marker.type = visualization_msgs::msg::Marker::POINTS;
marker.action = visualization_msgs::msg::Marker::ADD;
marker.scale.x = 0.02;
marker.scale.y = 0.02;
marker.color.r = 1.0;
marker.color.a = 1.0;
marker.lifetime = rclcpp::Duration(0, 0);

for (const auto & point : collision_points) {
geometry_msgs::msg::Point p;
p.x = point.x;
p.y = point.y;
p.z = 0.0;
marker.points.push_back(p);
}
marker_array->markers.push_back(marker);
collision_points_marker_pub_->publish(std::move(marker_array));
}

// By default - there is no action
Action robot_action{DO_NOTHING, cmd_vel_in, ""};
// Polygon causing robot action (if any)
Expand Down
3 changes: 2 additions & 1 deletion nav2_collision_monitor/src/pointcloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <functional>

#include "sensor_msgs/point_cloud2_iterator.hpp"
#include "tf2/transform_datatypes.h"

#include "nav2_util/node_utils.hpp"
#include "nav2_util/robot_utils.hpp"
Expand Down Expand Up @@ -111,7 +112,7 @@ void PointCloud::getData(
return;
}

tf2::Transform tf_transform;
tf2::Stamped<tf2::Transform> tf_transform;
if (base_shift_correction_) {
// Obtaining the transform to get data from source frame and time where it was received
// to the base frame and current time
Expand Down
Loading