From 6ff47cf181fb1c2ee3f226f06f56e4fde9d32cd0 Mon Sep 17 00:00:00 2001
From: SakodaShintaro
Date: Tue, 9 Jan 2024 09:36:15 +0900
Subject: [PATCH 001/154] refactor(ndt_scan_matcher): removed
tf2_listener_module (#6008)
Removed tf2_listener_module
Signed-off-by: Shintaro SAKODA
---
localization/localization_util/CMakeLists.txt | 1 -
.../localization_util/tf2_listener_module.hpp | 43 -------------
.../src/tf2_listener_module.cpp | 60 -------------------
.../ndt_scan_matcher/map_update_module.hpp | 1 -
.../ndt_scan_matcher_core.hpp | 6 +-
.../src/ndt_scan_matcher_core.cpp | 50 ++++++++++++----
6 files changed, 43 insertions(+), 118 deletions(-)
delete mode 100644 localization/localization_util/include/localization_util/tf2_listener_module.hpp
delete mode 100644 localization/localization_util/src/tf2_listener_module.cpp
diff --git a/localization/localization_util/CMakeLists.txt b/localization/localization_util/CMakeLists.txt
index ade446020d101..fe65077d89649 100644
--- a/localization/localization_util/CMakeLists.txt
+++ b/localization/localization_util/CMakeLists.txt
@@ -6,7 +6,6 @@ autoware_package()
ament_auto_add_library(localization_util SHARED
src/util_func.cpp
- src/tf2_listener_module.cpp
src/smart_pose_buffer.cpp
)
diff --git a/localization/localization_util/include/localization_util/tf2_listener_module.hpp b/localization/localization_util/include/localization_util/tf2_listener_module.hpp
deleted file mode 100644
index b332f9effe0e0..0000000000000
--- a/localization/localization_util/include/localization_util/tf2_listener_module.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2015-2019 Autoware Foundation
-//
-// 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 LOCALIZATION_UTIL__TF2_LISTENER_MODULE_HPP_
-#define LOCALIZATION_UTIL__TF2_LISTENER_MODULE_HPP_
-
-#include
-
-#include
-#include
-#include
-
-#include
-
-class Tf2ListenerModule
-{
- using TransformStamped = geometry_msgs::msg::TransformStamped;
-
-public:
- explicit Tf2ListenerModule(rclcpp::Node * node);
- bool get_transform(
- const builtin_interfaces::msg::Time & timestamp, const std::string & target_frame,
- const std::string & source_frame,
- const geometry_msgs::msg::TransformStamped::SharedPtr & transform_stamped_ptr) const;
-
-private:
- rclcpp::Logger logger_;
- tf2_ros::Buffer tf2_buffer_;
- tf2_ros::TransformListener tf2_listener_;
-};
-
-#endif // LOCALIZATION_UTIL__TF2_LISTENER_MODULE_HPP_
diff --git a/localization/localization_util/src/tf2_listener_module.cpp b/localization/localization_util/src/tf2_listener_module.cpp
deleted file mode 100644
index 8a19ceec9f30d..0000000000000
--- a/localization/localization_util/src/tf2_listener_module.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2015-2019 Autoware Foundation
-//
-// 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.
-
-#include "localization_util/tf2_listener_module.hpp"
-
-#include
-
-geometry_msgs::msg::TransformStamped identity_transform_stamped(
- const builtin_interfaces::msg::Time & timestamp, const std::string & header_frame_id,
- const std::string & child_frame_id)
-{
- geometry_msgs::msg::TransformStamped transform;
- transform.header.stamp = timestamp;
- transform.header.frame_id = header_frame_id;
- transform.child_frame_id = child_frame_id;
- transform.transform.rotation = tier4_autoware_utils::createQuaternion(0.0, 0.0, 0.0, 1.0);
- transform.transform.translation = tier4_autoware_utils::createTranslation(0.0, 0.0, 0.0);
- return transform;
-}
-
-Tf2ListenerModule::Tf2ListenerModule(rclcpp::Node * node)
-: logger_(node->get_logger()), tf2_buffer_(node->get_clock()), tf2_listener_(tf2_buffer_)
-{
-}
-
-bool Tf2ListenerModule::get_transform(
- const builtin_interfaces::msg::Time & timestamp, const std::string & target_frame,
- const std::string & source_frame, const TransformStamped::SharedPtr & transform_stamped_ptr) const
-{
- const TransformStamped identity =
- identity_transform_stamped(timestamp, target_frame, source_frame);
-
- if (target_frame == source_frame) {
- *transform_stamped_ptr = identity;
- return true;
- }
-
- try {
- *transform_stamped_ptr =
- tf2_buffer_.lookupTransform(target_frame, source_frame, tf2::TimePointZero);
- } catch (tf2::TransformException & ex) {
- RCLCPP_WARN(logger_, "%s", ex.what());
- RCLCPP_ERROR(logger_, "Please publish TF %s to %s", target_frame.c_str(), source_frame.c_str());
-
- *transform_stamped_ptr = identity;
- return false;
- }
- return true;
-}
diff --git a/localization/ndt_scan_matcher/include/ndt_scan_matcher/map_update_module.hpp b/localization/ndt_scan_matcher/include/ndt_scan_matcher/map_update_module.hpp
index 5457a6c310f5d..8b192b0186b42 100644
--- a/localization/ndt_scan_matcher/include/ndt_scan_matcher/map_update_module.hpp
+++ b/localization/ndt_scan_matcher/include/ndt_scan_matcher/map_update_module.hpp
@@ -15,7 +15,6 @@
#ifndef NDT_SCAN_MATCHER__MAP_UPDATE_MODULE_HPP_
#define NDT_SCAN_MATCHER__MAP_UPDATE_MODULE_HPP_
-#include "localization_util/tf2_listener_module.hpp"
#include "localization_util/util_func.hpp"
#include "ndt_scan_matcher/particle.hpp"
diff --git a/localization/ndt_scan_matcher/include/ndt_scan_matcher/ndt_scan_matcher_core.hpp b/localization/ndt_scan_matcher/include/ndt_scan_matcher/ndt_scan_matcher_core.hpp
index 6a5c61041f0da..b8792c20c323e 100644
--- a/localization/ndt_scan_matcher/include/ndt_scan_matcher/ndt_scan_matcher_core.hpp
+++ b/localization/ndt_scan_matcher/include/ndt_scan_matcher/ndt_scan_matcher_core.hpp
@@ -18,7 +18,6 @@
#define FMT_HEADER_ONLY
#include "localization_util/smart_pose_buffer.hpp"
-#include "localization_util/tf2_listener_module.hpp"
#include "ndt_scan_matcher/map_module.hpp"
#include "ndt_scan_matcher/map_update_module.hpp"
@@ -41,6 +40,8 @@
#include
#include
#include
+#include
+#include
#ifdef ROS_DISTRO_GALACTIC
#include
@@ -176,6 +177,8 @@ class NDTScanMatcher : public rclcpp::Node
rclcpp::Service::SharedPtr service_trigger_node_;
tf2_ros::TransformBroadcaster tf2_broadcaster_;
+ tf2_ros::Buffer tf2_buffer_;
+ tf2_ros::TransformListener tf2_listener_;
rclcpp::CallbackGroup::SharedPtr timer_callback_group_;
@@ -213,7 +216,6 @@ class NDTScanMatcher : public rclcpp::Node
std::unique_ptr regularization_pose_buffer_;
std::atomic is_activated_;
- std::shared_ptr tf2_listener_module_;
std::unique_ptr map_module_;
std::unique_ptr map_update_module_;
std::unique_ptr logger_configure_;
diff --git a/localization/ndt_scan_matcher/src/ndt_scan_matcher_core.cpp b/localization/ndt_scan_matcher/src/ndt_scan_matcher_core.cpp
index 7f6fe605c42b0..7108dca20d8d7 100644
--- a/localization/ndt_scan_matcher/src/ndt_scan_matcher_core.cpp
+++ b/localization/ndt_scan_matcher/src/ndt_scan_matcher_core.cpp
@@ -68,6 +68,8 @@ Eigen::Matrix2d find_rotation_matrix_aligning_covariance_to_principal_axes(
NDTScanMatcher::NDTScanMatcher()
: Node("ndt_scan_matcher"),
tf2_broadcaster_(*this),
+ tf2_buffer_(this->get_clock()),
+ tf2_listener_(tf2_buffer_),
ndt_ptr_(new NormalDistributionsTransform),
state_ptr_(new std::map),
output_pose_covariance_({}),
@@ -262,8 +264,6 @@ NDTScanMatcher::NDTScanMatcher()
&NDTScanMatcher::service_trigger_node, this, std::placeholders::_1, std::placeholders::_2),
rclcpp::ServicesQoS().get_rmw_qos_profile(), sensor_callback_group);
- tf2_listener_module_ = std::make_shared(this);
-
use_dynamic_map_loading_ = this->declare_parameter("use_dynamic_map_loading");
if (use_dynamic_map_loading_) {
map_update_module_ = std::make_unique(this, &ndt_ptr_mtx_, ndt_ptr_);
@@ -574,11 +574,25 @@ void NDTScanMatcher::transform_sensor_measurement(
const pcl::shared_ptr> & sensor_points_input_ptr,
pcl::shared_ptr> & sensor_points_output_ptr)
{
- auto tf_target_to_source_ptr = std::make_shared();
- tf2_listener_module_->get_transform(
- this->now(), target_frame, source_frame, tf_target_to_source_ptr);
+ if (source_frame == target_frame) {
+ sensor_points_output_ptr = sensor_points_input_ptr;
+ return;
+ }
+
+ geometry_msgs::msg::TransformStamped transform;
+ try {
+ transform = tf2_buffer_.lookupTransform(target_frame, source_frame, tf2::TimePointZero);
+ } catch (tf2::TransformException & ex) {
+ RCLCPP_WARN(this->get_logger(), "%s", ex.what());
+ RCLCPP_WARN(
+ this->get_logger(), "Please publish TF %s to %s", target_frame.c_str(), source_frame.c_str());
+ // Since there is no clear error handling policy, temporarily return as is.
+ sensor_points_output_ptr = sensor_points_input_ptr;
+ return;
+ }
+
const geometry_msgs::msg::PoseStamped target_to_source_pose_stamped =
- tier4_autoware_utils::transform2pose(*tf_target_to_source_ptr);
+ tier4_autoware_utils::transform2pose(transform);
const Eigen::Matrix4f base_to_sensor_matrix =
pose_to_matrix4f(target_to_source_pose_stamped.pose);
tier4_autoware_utils::transformPointCloud(
@@ -863,13 +877,27 @@ void NDTScanMatcher::service_ndt_align(
tier4_localization_msgs::srv::PoseWithCovarianceStamped::Response::SharedPtr res)
{
// get TF from pose_frame to map_frame
- auto tf_pose_to_map_ptr = std::make_shared();
- tf2_listener_module_->get_transform(
- get_clock()->now(), map_frame_, req->pose_with_covariance.header.frame_id, tf_pose_to_map_ptr);
+ const std::string & target_frame = map_frame_;
+ const std::string & source_frame = req->pose_with_covariance.header.frame_id;
+
+ geometry_msgs::msg::TransformStamped transform_s2t;
+ try {
+ transform_s2t = tf2_buffer_.lookupTransform(target_frame, source_frame, tf2::TimePointZero);
+ } catch (tf2::TransformException & ex) {
+ // Note: Up to AWSIMv1.1.0, there is a known bug where the GNSS frame_id is incorrectly set to
+ // "gnss_link" instead of "map". The ndt_align is designed to return identity when this issue
+ // occurs. However, in the future, converting to a non-existent frame_id should be prohibited.
+ RCLCPP_WARN(this->get_logger(), "%s", ex.what());
+ RCLCPP_WARN(
+ this->get_logger(), "Please publish TF %s to %s", target_frame.c_str(), source_frame.c_str());
+ transform_s2t.header.stamp = get_clock()->now();
+ transform_s2t.header.frame_id = target_frame;
+ transform_s2t.child_frame_id = source_frame;
+ transform_s2t.transform = tf2::toMsg(tf2::Transform::getIdentity());
+ }
// transform pose_frame to map_frame
- const auto initial_pose_msg_in_map_frame =
- transform(req->pose_with_covariance, *tf_pose_to_map_ptr);
+ const auto initial_pose_msg_in_map_frame = transform(req->pose_with_covariance, transform_s2t);
if (use_dynamic_map_loading_) {
map_update_module_->update_map(initial_pose_msg_in_map_frame.pose.pose.position);
}
From 1ab746f82f568883b726184bf21ac50d6422d24b Mon Sep 17 00:00:00 2001
From: Kento Yabuuchi
Date: Tue, 9 Jan 2024 09:49:43 +0900
Subject: [PATCH 002/154] docs(ekf_localizer): improve readme and explain
confusing process (#5834)
* update ekf_localizer/README.md
Signed-off-by: Kento Yabuuchi
* add comment to explain
Signed-off-by: Kento Yabuuchi
* style(pre-commit): autofix
* update readme
Signed-off-by: Kento Yabuuchi
* rename pi
Signed-off-by: Kento Yabuuchi
* style(pre-commit): autofix
* fix typo
Signed-off-by: Kento Yabuuchi
---------
Signed-off-by: Kento Yabuuchi
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
---
localization/ekf_localizer/README.md | 76 +++++--------------
localization/ekf_localizer/src/ekf_module.cpp | 10 ++-
2 files changed, 29 insertions(+), 57 deletions(-)
diff --git a/localization/ekf_localizer/README.md b/localization/ekf_localizer/README.md
index bda1c84a2747c..87cc510c5fe14 100644
--- a/localization/ekf_localizer/README.md
+++ b/localization/ekf_localizer/README.md
@@ -32,71 +32,33 @@ This package includes the following features:
-## Launch
-
-The `ekf_localizer` starts with the default parameters with the following command.
-
-```sh
-roslaunch ekf_localizer ekf_localizer.launch
-```
-
-The parameters and input topic names can be set in the `ekf_localizer.launch` file.
-
## Node
### Subscribed Topics
-- measured_pose_with_covariance (geometry_msgs/PoseWithCovarianceStamped)
-
- Input pose source with the measurement covariance matrix.
-
-- measured_twist_with_covariance (geometry_msgs/TwistWithCovarianceStamped)
-
- Input twist source with the measurement covariance matrix.
-
-- initialpose (geometry_msgs/PoseWithCovarianceStamped)
-
- Initial pose for EKF. The estimated pose is initialized with zeros at the start. It is initialized with this message whenever published.
+| Name | Type | Description |
+| -------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
+| `measured_pose_with_covariance` | `geometry_msgs::msg::PoseWithCovarianceStamped` | Input pose source with the measurement covariance matrix. |
+| `measured_twist_with_covariance` | `geometry_msgs::msg::TwistWithCovarianceStamped` | Input twist source with the measurement covariance matrix. |
+| `initialpose` | `geometry_msgs::msg::PoseWithCovarianceStamped` | Initial pose for EKF. The estimated pose is initialized with zeros at the start. It is initialized with this message whenever published. |
### Published Topics
-- ekf_odom (nav_msgs/Odometry)
-
- Estimated odometry.
-
-- ekf_pose (geometry_msgs/PoseStamped)
-
- Estimated pose.
-
-- ekf_pose_with_covariance (geometry_msgs/PoseWithCovarianceStamped)
-
- Estimated pose with covariance.
-
-- ekf_biased_pose (geometry_msgs/PoseStamped)
-
- Estimated pose including the yaw bias
-
-- ekf_biased_pose_with_covariance (geometry_msgs/PoseWithCovarianceStamped)
-
- Estimated pose with covariance including the yaw bias
-
-- ekf_twist (geometry_msgs/TwistStamped)
-
- Estimated twist.
-
-- ekf_twist_with_covariance (geometry_msgs/TwistWithCovarianceStamped)
-
- The estimated twist with covariance.
-
-- diagnostics (diagnostic_msgs/DiagnosticArray)
-
- The diagnostic information.
+| Name | Type | Description |
+| --------------------------------- | ------------------------------------------------ | ----------------------------------------------------- |
+| `ekf_odom` | `nav_msgs::msg::Odometry` | Estimated odometry. |
+| `ekf_pose` | `geometry_msgs::msg::PoseStamped` | Estimated pose. |
+| `ekf_pose_with_covariance` | `geometry_msgs::msg::PoseWithCovarianceStamped` | Estimated pose with covariance. |
+| `ekf_biased_pose` | `geometry_msgs::msg::PoseStamped` | Estimated pose including the yaw bias |
+| `ekf_biased_pose_with_covariance` | `geometry_msgs::msg::PoseWithCovarianceStamped` | Estimated pose with covariance including the yaw bias |
+| `ekf_twist` | `geometry_msgs::msg::TwistStamped` | Estimated twist. |
+| `ekf_twist_with_covariance` | `geometry_msgs::msg::TwistWithCovarianceStamped` | The estimated twist with covariance. |
+| `diagnostics` | `diagnostics_msgs::msg::DiagnosticArray` | The diagnostic information. |
### Published TF
- base_link
-
- TF from "map" coordinate to estimated pose.
+ TF from `map` coordinate to estimated pose.
## Functions
@@ -205,7 +167,9 @@ Increasing the number will improve the smoothness of the estimation, but may hav
-where `b_k` is the yawbias.
+where, $\theta_k$ represents the vehicle's heading angle, including the mounting angle bias.
+$b_k$ is a correction term for the yaw bias, and it is modeled so that $(\theta_k+b_k)$ becomes the heading angle of the base_link.
+The pose_estimator is expected to publish the base_link in the map coordinate system. However, the yaw angle may be offset due to calibration errors. This model compensates this error and improves estimation accuracy.
### time delay model
@@ -240,7 +204,7 @@ Note that, although the dimension gets larger since the analytical expansion can
## Known issues
-- In the presence of multiple inputs with yaw estimation, yaw bias `b_k` in the current EKF state would not make any sense, since it is intended to capture the extrinsic parameter's calibration error of a sensor. Thus, future work includes introducing yaw bias for each sensor with yaw estimation.
+- If multiple pose_estimators are used, the input to the EKF will include multiple yaw biases corresponding to each source. However, the current EKF assumes the existence of only one yaw bias. Therefore, yaw bias `b_k` in the current EKF state would not make any sense and cannot correctly handle these multiple yaw biases. Thus, future work includes introducing yaw bias for each sensor with yaw estimation.
## reference
diff --git a/localization/ekf_localizer/src/ekf_module.cpp b/localization/ekf_localizer/src/ekf_module.cpp
index 573472fe2dabf..8977d82f34138 100644
--- a/localization/ekf_localizer/src/ekf_module.cpp
+++ b/localization/ekf_localizer/src/ekf_module.cpp
@@ -87,9 +87,15 @@ geometry_msgs::msg::PoseStamped EKFModule::getCurrentPose(
{
const double x = kalman_filter_.getXelement(IDX::X);
const double y = kalman_filter_.getXelement(IDX::Y);
+ /*
+ getXelement(IDX::YAW) is surely `biased_yaw`.
+ Please note how `yaw` and `yaw_bias` are used in the state transition model and
+ how the observed pose is handled in the measurement pose update.
+ */
const double biased_yaw = kalman_filter_.getXelement(IDX::YAW);
const double yaw_bias = kalman_filter_.getXelement(IDX::YAWB);
const double yaw = biased_yaw + yaw_bias;
+
Pose current_ekf_pose;
current_ekf_pose.header.frame_id = params_.pose_frame_id;
current_ekf_pose.header.stamp = current_time;
@@ -224,7 +230,9 @@ bool EKFModule::measurementUpdatePose(
return false;
}
- /* Set yaw */
+ /* Since the kalman filter cannot handle the rotation angle directly,
+ offset the yaw angle so that the difference from the yaw angle that ekf holds internally is less
+ than 2 pi. */
double yaw = tf2::getYaw(pose.pose.pose.orientation);
const double ekf_yaw = kalman_filter_.getXelement(delay_step * dim_x_ + IDX::YAW);
const double yaw_error = normalizeYaw(yaw - ekf_yaw); // normalize the error not to exceed 2 pi
From a96c71cd86499eb85e24a80f9b5dbc005b11ce8b Mon Sep 17 00:00:00 2001
From: Takayuki Murooka
Date: Tue, 9 Jan 2024 11:10:00 +0900
Subject: [PATCH 003/154] refactor(dynamic_avoidance): separate dynamic
avoidance module (#6019)
* refactor(dynamic_avoidance): separate dynamic avoidance module
Signed-off-by: Takayuki Murooka
* move figures
Signed-off-by: Takayuki Murooka
* update .pages
Signed-off-by: Takayuki Murooka
---------
Signed-off-by: Takayuki Murooka
---
planning/.pages | 2 +-
.../CMakeLists.txt | 25 ++++
.../README.md} | 6 +-
.../config}/dynamic_avoidance.param.yaml | 0
.../drivable_area_extraction_width.drawio.svg | 0
.../image}/opposite_directional_object.svg | 0
.../image}/same_directional_object.svg | 0
.../manager.hpp | 8 +-
.../scene.hpp} | 9 +-
.../package.xml | 42 ++++++
.../plugins.xml | 2 +-
.../src}/manager.cpp | 2 +-
.../src/scene.cpp} | 2 +-
...t_behavior_path_planner_node_interface.cpp | 123 ++++++++++++++++++
planning/behavior_path_planner/CMakeLists.txt | 4 -
planning/behavior_path_planner/README.md | 2 +-
...t_behavior_path_planner_node_interface.cpp | 15 +--
17 files changed, 211 insertions(+), 31 deletions(-)
create mode 100644 planning/behavior_path_dynamic_avoidance_module/CMakeLists.txt
rename planning/{behavior_path_planner/docs/behavior_path_planner_dynamic_avoidance_design.md => behavior_path_dynamic_avoidance_module/README.md} (94%)
rename planning/{behavior_path_planner/config/dynamic_avoidance => behavior_path_dynamic_avoidance_module/config}/dynamic_avoidance.param.yaml (100%)
rename planning/{behavior_path_planner/image/dynamic_avoidance => behavior_path_dynamic_avoidance_module/image}/drivable_area_extraction_width.drawio.svg (100%)
rename planning/{behavior_path_planner/image/dynamic_avoidance => behavior_path_dynamic_avoidance_module/image}/opposite_directional_object.svg (100%)
rename planning/{behavior_path_planner/image/dynamic_avoidance => behavior_path_dynamic_avoidance_module/image}/same_directional_object.svg (100%)
rename planning/{behavior_path_planner/include/behavior_path_planner/scene_module/dynamic_avoidance => behavior_path_dynamic_avoidance_module/include/behavior_path_dynamic_avoidance_module}/manager.hpp (82%)
rename planning/{behavior_path_planner/include/behavior_path_planner/scene_module/dynamic_avoidance/dynamic_avoidance_module.hpp => behavior_path_dynamic_avoidance_module/include/behavior_path_dynamic_avoidance_module/scene.hpp} (97%)
create mode 100644 planning/behavior_path_dynamic_avoidance_module/package.xml
rename planning/{behavior_path_planner => behavior_path_dynamic_avoidance_module}/plugins.xml (72%)
rename planning/{behavior_path_planner/src/scene_module/dynamic_avoidance => behavior_path_dynamic_avoidance_module/src}/manager.cpp (99%)
rename planning/{behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp => behavior_path_dynamic_avoidance_module/src/scene.cpp} (99%)
create mode 100644 planning/behavior_path_dynamic_avoidance_module/test/test_behavior_path_planner_node_interface.cpp
diff --git a/planning/.pages b/planning/.pages
index c41a1cc8c6603..e244f1d1ea25d 100644
--- a/planning/.pages
+++ b/planning/.pages
@@ -12,7 +12,7 @@ nav:
- 'Scene Module':
- 'Avoidance': planning/behavior_path_avoidance_module
- 'Avoidance by Lane Change': planning/behavior_path_avoidance_by_lane_change_module
- - 'Dynamic Avoidance': planning/behavior_path_planner/docs/behavior_path_planner_dynamic_avoidance_design
+ - 'Dynamic Avoidance': planning/behavior_path_dynamic_avoidance_module
- 'Goal Planner': planning/behavior_path_goal_planner_module
- 'Lane Change': planning/behavior_path_lane_change_module
- 'Side Shift': planning/behavior_path_side_shift_module
diff --git a/planning/behavior_path_dynamic_avoidance_module/CMakeLists.txt b/planning/behavior_path_dynamic_avoidance_module/CMakeLists.txt
new file mode 100644
index 0000000000000..98874b8923324
--- /dev/null
+++ b/planning/behavior_path_dynamic_avoidance_module/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.14)
+project(behavior_path_dynamic_avoidance_module)
+
+find_package(autoware_cmake REQUIRED)
+autoware_package()
+pluginlib_export_plugin_description_file(behavior_path_planner plugins.xml)
+
+ament_auto_add_library(${PROJECT_NAME} SHARED
+ src/scene.cpp
+ src/manager.cpp
+)
+
+if(BUILD_TESTING)
+ ament_add_ros_isolated_gmock(test_${PROJECT_NAME}
+ test/test_behavior_path_planner_node_interface.cpp
+ )
+
+ target_link_libraries(test_${PROJECT_NAME}
+ ${PROJECT_NAME}
+ )
+
+ target_include_directories(test_${PROJECT_NAME} PRIVATE src)
+endif()
+
+ament_auto_package(INSTALL_TO_SHARE config)
diff --git a/planning/behavior_path_planner/docs/behavior_path_planner_dynamic_avoidance_design.md b/planning/behavior_path_dynamic_avoidance_module/README.md
similarity index 94%
rename from planning/behavior_path_planner/docs/behavior_path_planner_dynamic_avoidance_design.md
rename to planning/behavior_path_dynamic_avoidance_module/README.md
index f303937bd0f78..5e8be9136886c 100644
--- a/planning/behavior_path_planner/docs/behavior_path_planner_dynamic_avoidance_design.md
+++ b/planning/behavior_path_dynamic_avoidance_module/README.md
@@ -32,16 +32,16 @@ First, a maximum lateral offset to avoid is calculated as follows.
The polygon's width to extract from the drivable area is the obstacle width and double `drivable_area_generation.lat_offset_from_obstacle`.
We can limit the lateral shift offset by `drivable_area_generation.max_lat_offset_to_avoid`.
-
+
Then, extracting the same directional and opposite directional obstacles from the drivable area will work as follows considering TTC (time to collision).
Regarding the same directional obstacles, obstacles whose TTC is negative will be ignored (e.g. The obstacle is in front of the ego, and the obstacle's velocity is larger than the ego's velocity.).
Same directional obstacles
-
+
Opposite directional obstacles
-
+
## Parameters
diff --git a/planning/behavior_path_planner/config/dynamic_avoidance/dynamic_avoidance.param.yaml b/planning/behavior_path_dynamic_avoidance_module/config/dynamic_avoidance.param.yaml
similarity index 100%
rename from planning/behavior_path_planner/config/dynamic_avoidance/dynamic_avoidance.param.yaml
rename to planning/behavior_path_dynamic_avoidance_module/config/dynamic_avoidance.param.yaml
diff --git a/planning/behavior_path_planner/image/dynamic_avoidance/drivable_area_extraction_width.drawio.svg b/planning/behavior_path_dynamic_avoidance_module/image/drivable_area_extraction_width.drawio.svg
similarity index 100%
rename from planning/behavior_path_planner/image/dynamic_avoidance/drivable_area_extraction_width.drawio.svg
rename to planning/behavior_path_dynamic_avoidance_module/image/drivable_area_extraction_width.drawio.svg
diff --git a/planning/behavior_path_planner/image/dynamic_avoidance/opposite_directional_object.svg b/planning/behavior_path_dynamic_avoidance_module/image/opposite_directional_object.svg
similarity index 100%
rename from planning/behavior_path_planner/image/dynamic_avoidance/opposite_directional_object.svg
rename to planning/behavior_path_dynamic_avoidance_module/image/opposite_directional_object.svg
diff --git a/planning/behavior_path_planner/image/dynamic_avoidance/same_directional_object.svg b/planning/behavior_path_dynamic_avoidance_module/image/same_directional_object.svg
similarity index 100%
rename from planning/behavior_path_planner/image/dynamic_avoidance/same_directional_object.svg
rename to planning/behavior_path_dynamic_avoidance_module/image/same_directional_object.svg
diff --git a/planning/behavior_path_planner/include/behavior_path_planner/scene_module/dynamic_avoidance/manager.hpp b/planning/behavior_path_dynamic_avoidance_module/include/behavior_path_dynamic_avoidance_module/manager.hpp
similarity index 82%
rename from planning/behavior_path_planner/include/behavior_path_planner/scene_module/dynamic_avoidance/manager.hpp
rename to planning/behavior_path_dynamic_avoidance_module/include/behavior_path_dynamic_avoidance_module/manager.hpp
index 9e08f309a78b3..c2c17c4e55c1e 100644
--- a/planning/behavior_path_planner/include/behavior_path_planner/scene_module/dynamic_avoidance/manager.hpp
+++ b/planning/behavior_path_dynamic_avoidance_module/include/behavior_path_dynamic_avoidance_module/manager.hpp
@@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef BEHAVIOR_PATH_PLANNER__SCENE_MODULE__DYNAMIC_AVOIDANCE__MANAGER_HPP_
-#define BEHAVIOR_PATH_PLANNER__SCENE_MODULE__DYNAMIC_AVOIDANCE__MANAGER_HPP_
+#ifndef BEHAVIOR_PATH_DYNAMIC_AVOIDANCE_MODULE__MANAGER_HPP_
+#define BEHAVIOR_PATH_DYNAMIC_AVOIDANCE_MODULE__MANAGER_HPP_
-#include "behavior_path_planner/scene_module/dynamic_avoidance/dynamic_avoidance_module.hpp"
+#include "behavior_path_dynamic_avoidance_module/scene.hpp"
#include "behavior_path_planner_common/interface/scene_module_manager_interface.hpp"
#include
@@ -52,4 +52,4 @@ class DynamicAvoidanceModuleManager : public SceneModuleManagerInterface
} // namespace behavior_path_planner
-#endif // BEHAVIOR_PATH_PLANNER__SCENE_MODULE__DYNAMIC_AVOIDANCE__MANAGER_HPP_
+#endif // BEHAVIOR_PATH_DYNAMIC_AVOIDANCE_MODULE__MANAGER_HPP_
diff --git a/planning/behavior_path_planner/include/behavior_path_planner/scene_module/dynamic_avoidance/dynamic_avoidance_module.hpp b/planning/behavior_path_dynamic_avoidance_module/include/behavior_path_dynamic_avoidance_module/scene.hpp
similarity index 97%
rename from planning/behavior_path_planner/include/behavior_path_planner/scene_module/dynamic_avoidance/dynamic_avoidance_module.hpp
rename to planning/behavior_path_dynamic_avoidance_module/include/behavior_path_dynamic_avoidance_module/scene.hpp
index 50f5b61e15169..d2f9cd95066d9 100644
--- a/planning/behavior_path_planner/include/behavior_path_planner/scene_module/dynamic_avoidance/dynamic_avoidance_module.hpp
+++ b/planning/behavior_path_dynamic_avoidance_module/include/behavior_path_dynamic_avoidance_module/scene.hpp
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef BEHAVIOR_PATH_PLANNER__SCENE_MODULE__DYNAMIC_AVOIDANCE__DYNAMIC_AVOIDANCE_MODULE_HPP_
-#define BEHAVIOR_PATH_PLANNER__SCENE_MODULE__DYNAMIC_AVOIDANCE__DYNAMIC_AVOIDANCE_MODULE_HPP_
+#ifndef BEHAVIOR_PATH_DYNAMIC_AVOIDANCE_MODULE__SCENE_HPP_
+#define BEHAVIOR_PATH_DYNAMIC_AVOIDANCE_MODULE__SCENE_HPP_
#include "behavior_path_planner_common/interface/scene_module_interface.hpp"
@@ -23,9 +23,6 @@
#include
#include
#include
-#include
-#include
-#include
#include
#include
@@ -413,4 +410,4 @@ class DynamicAvoidanceModule : public SceneModuleInterface
};
} // namespace behavior_path_planner
-#endif // BEHAVIOR_PATH_PLANNER__SCENE_MODULE__DYNAMIC_AVOIDANCE__DYNAMIC_AVOIDANCE_MODULE_HPP_
+#endif // BEHAVIOR_PATH_DYNAMIC_AVOIDANCE_MODULE__SCENE_HPP_
diff --git a/planning/behavior_path_dynamic_avoidance_module/package.xml b/planning/behavior_path_dynamic_avoidance_module/package.xml
new file mode 100644
index 0000000000000..11792a15b2cd2
--- /dev/null
+++ b/planning/behavior_path_dynamic_avoidance_module/package.xml
@@ -0,0 +1,42 @@
+
+
+
+ behavior_path_dynamic_avoidance_module
+ 0.1.0
+ The behavior_path_dynamic_avoidance_module package
+
+ Takayuki Murooka
+ Yuki Takagi
+ Satoshi Ota
+ Kosuke Takeuchi
+
+ Apache License 2.0
+
+ ament_cmake_auto
+ autoware_cmake
+ eigen3_cmake_module
+
+ autoware_auto_perception_msgs
+ autoware_auto_planning_msgs
+ autoware_auto_vehicle_msgs
+ behavior_path_planner
+ behavior_path_planner_common
+ geometry_msgs
+ lanelet2_core
+ lanelet2_extension
+ motion_utils
+ object_recognition_utils
+ pluginlib
+ rclcpp
+ signal_processing
+ tier4_autoware_utils
+ visualization_msgs
+
+ ament_cmake_ros
+ ament_lint_auto
+ autoware_lint_common
+
+
+ ament_cmake
+
+
diff --git a/planning/behavior_path_planner/plugins.xml b/planning/behavior_path_dynamic_avoidance_module/plugins.xml
similarity index 72%
rename from planning/behavior_path_planner/plugins.xml
rename to planning/behavior_path_dynamic_avoidance_module/plugins.xml
index a16f3dd7bddee..fd2e1bc4137b7 100644
--- a/planning/behavior_path_planner/plugins.xml
+++ b/planning/behavior_path_dynamic_avoidance_module/plugins.xml
@@ -1,3 +1,3 @@
-
+
diff --git a/planning/behavior_path_planner/src/scene_module/dynamic_avoidance/manager.cpp b/planning/behavior_path_dynamic_avoidance_module/src/manager.cpp
similarity index 99%
rename from planning/behavior_path_planner/src/scene_module/dynamic_avoidance/manager.cpp
rename to planning/behavior_path_dynamic_avoidance_module/src/manager.cpp
index f39727246d722..569c6a17b5b32 100644
--- a/planning/behavior_path_planner/src/scene_module/dynamic_avoidance/manager.cpp
+++ b/planning/behavior_path_dynamic_avoidance_module/src/manager.cpp
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "behavior_path_planner/scene_module/dynamic_avoidance/manager.hpp"
+#include "behavior_path_dynamic_avoidance_module/manager.hpp"
#include "tier4_autoware_utils/ros/update_param.hpp"
diff --git a/planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp b/planning/behavior_path_dynamic_avoidance_module/src/scene.cpp
similarity index 99%
rename from planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp
rename to planning/behavior_path_dynamic_avoidance_module/src/scene.cpp
index 01635d7a6cb70..ca58bbf0adcaa 100644
--- a/planning/behavior_path_planner/src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp
+++ b/planning/behavior_path_dynamic_avoidance_module/src/scene.cpp
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "behavior_path_planner/scene_module/dynamic_avoidance/dynamic_avoidance_module.hpp"
+#include "behavior_path_dynamic_avoidance_module/scene.hpp"
#include "behavior_path_planner_common/utils/drivable_area_expansion/static_drivable_area.hpp"
#include "behavior_path_planner_common/utils/utils.hpp"
diff --git a/planning/behavior_path_dynamic_avoidance_module/test/test_behavior_path_planner_node_interface.cpp b/planning/behavior_path_dynamic_avoidance_module/test/test_behavior_path_planner_node_interface.cpp
new file mode 100644
index 0000000000000..16b4ffbc688ae
--- /dev/null
+++ b/planning/behavior_path_dynamic_avoidance_module/test/test_behavior_path_planner_node_interface.cpp
@@ -0,0 +1,123 @@
+// Copyright 2023 TIER IV, Inc.
+//
+// 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.
+
+#include "behavior_path_planner/behavior_path_planner_node.hpp"
+
+#include
+#include
+#include
+
+#include
+
+using behavior_path_planner::BehaviorPathPlannerNode;
+using planning_test_utils::PlanningInterfaceTestManager;
+
+std::shared_ptr generateTestManager()
+{
+ auto test_manager = std::make_shared();
+
+ // set subscriber with topic name: behavior_path_planner → test_node_
+ test_manager->setPathWithLaneIdSubscriber("behavior_path_planner/output/path");
+
+ // set behavior_path_planner's input topic name(this topic is changed to test node)
+ test_manager->setRouteInputTopicName("behavior_path_planner/input/route");
+
+ test_manager->setInitialPoseTopicName("behavior_path_planner/input/odometry");
+
+ return test_manager;
+}
+
+std::shared_ptr generateNode()
+{
+ auto node_options = rclcpp::NodeOptions{};
+ const auto planning_test_utils_dir =
+ ament_index_cpp::get_package_share_directory("planning_test_utils");
+ const auto behavior_path_planner_dir =
+ ament_index_cpp::get_package_share_directory("behavior_path_planner");
+
+ std::vector module_names;
+ module_names.emplace_back("behavior_path_planner::DynamicAvoidanceModuleManager");
+
+ std::vector params;
+ params.emplace_back("launch_modules", module_names);
+ node_options.parameter_overrides(params);
+
+ test_utils::updateNodeOptions(
+ node_options,
+ {planning_test_utils_dir + "/config/test_common.param.yaml",
+ planning_test_utils_dir + "/config/test_nearest_search.param.yaml",
+ planning_test_utils_dir + "/config/test_vehicle_info.param.yaml",
+ behavior_path_planner_dir + "/config/behavior_path_planner.param.yaml",
+ behavior_path_planner_dir + "/config/drivable_area_expansion.param.yaml",
+ behavior_path_planner_dir + "/config/scene_module_manager.param.yaml",
+ ament_index_cpp::get_package_share_directory("behavior_path_dynamic_avoidance_module") +
+ "/config/dynamic_avoidance.param.yaml"});
+
+ return std::make_shared(node_options);
+}
+
+void publishMandatoryTopics(
+ std::shared_ptr test_manager,
+ std::shared_ptr test_target_node)
+{
+ // publish necessary topics from test_manager
+ test_manager->publishInitialPose(test_target_node, "behavior_path_planner/input/odometry");
+ test_manager->publishAcceleration(test_target_node, "behavior_path_planner/input/accel");
+ test_manager->publishPredictedObjects(test_target_node, "behavior_path_planner/input/perception");
+ test_manager->publishOccupancyGrid(
+ test_target_node, "behavior_path_planner/input/occupancy_grid_map");
+ test_manager->publishLaneDrivingScenario(
+ test_target_node, "behavior_path_planner/input/scenario");
+ test_manager->publishMap(test_target_node, "behavior_path_planner/input/vector_map");
+ test_manager->publishCostMap(test_target_node, "behavior_path_planner/input/costmap");
+ test_manager->publishOperationModeState(test_target_node, "system/operation_mode/state");
+ test_manager->publishLateralOffset(
+ test_target_node, "behavior_path_planner/input/lateral_offset");
+}
+
+TEST(PlanningModuleInterfaceTest, NodeTestWithExceptionRoute)
+{
+ rclcpp::init(0, nullptr);
+ auto test_manager = generateTestManager();
+ auto test_target_node = generateNode();
+
+ publishMandatoryTopics(test_manager, test_target_node);
+
+ // test for normal trajectory
+ ASSERT_NO_THROW_WITH_ERROR_MSG(test_manager->testWithBehaviorNominalRoute(test_target_node));
+ EXPECT_GE(test_manager->getReceivedTopicNum(), 1);
+
+ // test with empty route
+ ASSERT_NO_THROW_WITH_ERROR_MSG(test_manager->testWithAbnormalRoute(test_target_node));
+ rclcpp::shutdown();
+}
+
+TEST(PlanningModuleInterfaceTest, NodeTestWithOffTrackEgoPose)
+{
+ rclcpp::init(0, nullptr);
+
+ auto test_manager = generateTestManager();
+ auto test_target_node = generateNode();
+ publishMandatoryTopics(test_manager, test_target_node);
+
+ // test for normal trajectory
+ ASSERT_NO_THROW_WITH_ERROR_MSG(test_manager->testWithBehaviorNominalRoute(test_target_node));
+
+ // make sure behavior_path_planner is running
+ EXPECT_GE(test_manager->getReceivedTopicNum(), 1);
+
+ ASSERT_NO_THROW_WITH_ERROR_MSG(test_manager->testRouteWithInvalidEgoPose(test_target_node));
+
+ rclcpp::shutdown();
+}
diff --git a/planning/behavior_path_planner/CMakeLists.txt b/planning/behavior_path_planner/CMakeLists.txt
index f3727f35a492f..54b4bf122da00 100644
--- a/planning/behavior_path_planner/CMakeLists.txt
+++ b/planning/behavior_path_planner/CMakeLists.txt
@@ -7,13 +7,9 @@ autoware_package()
find_package(OpenCV REQUIRED)
find_package(magic_enum CONFIG REQUIRED)
-pluginlib_export_plugin_description_file(${PROJECT_NAME} plugins.xml)
-
ament_auto_add_library(${PROJECT_NAME}_lib SHARED
src/planner_manager.cpp
src/behavior_path_planner_node.cpp
- src/scene_module/dynamic_avoidance/dynamic_avoidance_module.cpp
- src/scene_module/dynamic_avoidance/manager.cpp
)
target_include_directories(${PROJECT_NAME}_lib SYSTEM PUBLIC
diff --git a/planning/behavior_path_planner/README.md b/planning/behavior_path_planner/README.md
index 6f462e17248f0..03f8c8d2a5696 100644
--- a/planning/behavior_path_planner/README.md
+++ b/planning/behavior_path_planner/README.md
@@ -28,7 +28,7 @@ Behavior Path Planner has following scene modules
| :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------- |
| Lane Following | this module generates reference path from lanelet centerline. | LINK |
| Avoidance | this module generates avoidance path when there is objects that should be avoid. | [LINK](../behavior_path_avoidance_module/README.md) |
-| Dynamic Avoidance | WIP | LINK |
+| Dynamic Avoidance | WIP | [LINK](../behavior_path_dynamic_avoidance_module/README.md) |
| Avoidance By Lane Change | this module generates lane change path when there is objects that should be avoid. | [LINK](../behavior_path_avoidance_by_lane_change_module/README.md) |
| Lane Change | this module is performed when it is necessary and a collision check with other vehicles is cleared. | [LINK](../behavior_path_lane_change_module/README.md) |
| External Lane Change | WIP | LINK |
diff --git a/planning/behavior_path_planner/test/test_behavior_path_planner_node_interface.cpp b/planning/behavior_path_planner/test/test_behavior_path_planner_node_interface.cpp
index 28ee6d31e80dc..7ba934e873a8d 100644
--- a/planning/behavior_path_planner/test/test_behavior_path_planner_node_interface.cpp
+++ b/planning/behavior_path_planner/test/test_behavior_path_planner_node_interface.cpp
@@ -50,21 +50,18 @@ std::shared_ptr generateNode()
ament_index_cpp::get_package_share_directory("behavior_path_planner");
std::vector module_names;
- module_names.emplace_back("behavior_path_planner::DynamicAvoidanceModuleManager");
std::vector params;
params.emplace_back("launch_modules", module_names);
node_options.parameter_overrides(params);
test_utils::updateNodeOptions(
- node_options,
- {planning_test_utils_dir + "/config/test_common.param.yaml",
- planning_test_utils_dir + "/config/test_nearest_search.param.yaml",
- planning_test_utils_dir + "/config/test_vehicle_info.param.yaml",
- behavior_path_planner_dir + "/config/behavior_path_planner.param.yaml",
- behavior_path_planner_dir + "/config/drivable_area_expansion.param.yaml",
- behavior_path_planner_dir + "/config/scene_module_manager.param.yaml",
- behavior_path_planner_dir + "/config/dynamic_avoidance/dynamic_avoidance.param.yaml"});
+ node_options, {planning_test_utils_dir + "/config/test_common.param.yaml",
+ planning_test_utils_dir + "/config/test_nearest_search.param.yaml",
+ planning_test_utils_dir + "/config/test_vehicle_info.param.yaml",
+ behavior_path_planner_dir + "/config/behavior_path_planner.param.yaml",
+ behavior_path_planner_dir + "/config/drivable_area_expansion.param.yaml",
+ behavior_path_planner_dir + "/config/scene_module_manager.param.yaml"});
return std::make_shared(node_options);
}
From 4a419f834f6aa5b1239ccbba07ac251a30a935be Mon Sep 17 00:00:00 2001
From: Yoshi Ri
Date: Tue, 9 Jan 2024 11:11:13 +0900
Subject: [PATCH 004/154] feat(probabilistic_occupancy_grid_map): add grid map
fusion node (#5993)
* add synchronized ogm fusion node
Signed-off-by: yoshiri
* add launch test for grid map fusion node
Signed-off-by: yoshiri
* fix test cases input msg error
Signed-off-by: yoshiri
* change default fusion parameter
Signed-off-by: yoshiri
* rename parameter for ogm fusion
Signed-off-by: yoshiri
* feat: add multi_lidar_ogm generation method
Signed-off-by: yoshiri
* enable ogm creation launcher in tier4_perception_launch to call multi_lidar ogm creation
Signed-off-by: yoshiri
* fix: change ogm fusion node pub policy to reliable
Signed-off-by: yoshiri
* chore: remove files outof scope with divied PR
Signed-off-by: yoshiri
---------
Signed-off-by: yoshiri
---
...robabilistic_occupancy_grid_map.launch.xml | 16 +-
.../CMakeLists.txt | 27 ++
.../README.md | 17 +
...nchronized_grid_map_fusion_node.param.yaml | 20 +
.../synchronized_grid_map_fusion.drawio.svg | 290 +++++++++++
.../include/cost_value.hpp | 33 +-
.../fusion/single_frame_fusion_policy.hpp | 66 +++
.../synchronized_grid_map_fusion_node.hpp | 127 +++++
...grid_map_log_odds_bayes_filter_updater.hpp | 48 ++
.../include/utils/utils.hpp | 3 +
...nized_occupancy_grid_map_fusion.launch.xml | 10 +
.../src/fusion/single_frame_fusion_policy.cpp | 322 ++++++++++++
.../synchronized_grid_map_fusion_node.cpp | 458 ++++++++++++++++++
...grid_map_log_odds_bayes_filter_updater.cpp | 69 +++
.../src/utils/utils.cpp | 16 +
.../synchronized_grid_map_fusion.md | 168 +++++++
.../test/cost_value_test.cpp | 47 ++
.../test/fusion_policy_test.cpp | 75 +++
.../test_synchronized_grid_map_fusion_node.py | 255 ++++++++++
19 files changed, 2064 insertions(+), 3 deletions(-)
create mode 100644 perception/probabilistic_occupancy_grid_map/config/synchronized_grid_map_fusion_node.param.yaml
create mode 100644 perception/probabilistic_occupancy_grid_map/image/synchronized_grid_map_fusion.drawio.svg
create mode 100644 perception/probabilistic_occupancy_grid_map/include/fusion/single_frame_fusion_policy.hpp
create mode 100644 perception/probabilistic_occupancy_grid_map/include/fusion/synchronized_grid_map_fusion_node.hpp
create mode 100644 perception/probabilistic_occupancy_grid_map/include/updater/occupancy_grid_map_log_odds_bayes_filter_updater.hpp
create mode 100644 perception/probabilistic_occupancy_grid_map/launch/synchronized_occupancy_grid_map_fusion.launch.xml
create mode 100644 perception/probabilistic_occupancy_grid_map/src/fusion/single_frame_fusion_policy.cpp
create mode 100644 perception/probabilistic_occupancy_grid_map/src/fusion/synchronized_grid_map_fusion_node.cpp
create mode 100644 perception/probabilistic_occupancy_grid_map/src/updater/occupancy_grid_map_log_odds_bayes_filter_updater.cpp
create mode 100644 perception/probabilistic_occupancy_grid_map/synchronized_grid_map_fusion.md
create mode 100644 perception/probabilistic_occupancy_grid_map/test/cost_value_test.cpp
create mode 100644 perception/probabilistic_occupancy_grid_map/test/fusion_policy_test.cpp
create mode 100644 perception/probabilistic_occupancy_grid_map/test/test_synchronized_grid_map_fusion_node.py
diff --git a/launch/tier4_perception_launch/launch/occupancy_grid_map/probabilistic_occupancy_grid_map.launch.xml b/launch/tier4_perception_launch/launch/occupancy_grid_map/probabilistic_occupancy_grid_map.launch.xml
index 751eeea66c7b6..281a52a85af71 100644
--- a/launch/tier4_perception_launch/launch/occupancy_grid_map/probabilistic_occupancy_grid_map.launch.xml
+++ b/launch/tier4_perception_launch/launch/occupancy_grid_map/probabilistic_occupancy_grid_map.launch.xml
@@ -8,7 +8,7 @@
-
+
@@ -48,4 +48,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/perception/probabilistic_occupancy_grid_map/CMakeLists.txt b/perception/probabilistic_occupancy_grid_map/CMakeLists.txt
index 035845772ce53..928532f928e38 100644
--- a/perception/probabilistic_occupancy_grid_map/CMakeLists.txt
+++ b/perception/probabilistic_occupancy_grid_map/CMakeLists.txt
@@ -55,6 +55,24 @@ rclcpp_components_register_node(laserscan_based_occupancy_grid_map
EXECUTABLE laserscan_based_occupancy_grid_map_node
)
+# GridMapFusionNode
+ament_auto_add_library(synchronized_grid_map_fusion SHARED
+ src/fusion/synchronized_grid_map_fusion_node.cpp
+ src/fusion/single_frame_fusion_policy.cpp
+ src/pointcloud_based_occupancy_grid_map/occupancy_grid_map_fixed.cpp
+ src/updater/occupancy_grid_map_log_odds_bayes_filter_updater.cpp
+ src/utils/utils.cpp
+)
+
+target_link_libraries(synchronized_grid_map_fusion
+ ${PCL_LIBRARIES}
+)
+
+rclcpp_components_register_node(synchronized_grid_map_fusion
+ PLUGIN "synchronized_grid_map_fusion::GridMapFusionNode"
+ EXECUTABLE synchronized_grid_map_fusion_node
+)
+
ament_auto_package(
INSTALL_TO_SHARE
launch
@@ -66,13 +84,22 @@ if(BUILD_TESTING)
# launch_testing
find_package(launch_testing_ament_cmake REQUIRED)
add_launch_test(test/test_pointcloud_based_method.py)
+ add_launch_test(test/test_synchronized_grid_map_fusion_node.py)
# gtest
ament_add_gtest(test_utils
test/test_utils.cpp
)
+ ament_add_gtest(costmap_unit_tests
+ test/cost_value_test.cpp)
+ ament_add_gtest(fusion_policy_unit_tests
+ test/fusion_policy_test.cpp
+ src/fusion/single_frame_fusion_policy.cpp
+ )
target_link_libraries(test_utils
${PCL_LIBRARIES}
${PROJECT_NAME}_common
)
+ target_include_directories(costmap_unit_tests PRIVATE "include")
+ target_include_directories(fusion_policy_unit_tests PRIVATE "include")
endif()
diff --git a/perception/probabilistic_occupancy_grid_map/README.md b/perception/probabilistic_occupancy_grid_map/README.md
index 962bcdc6f154f..084c55d80d629 100644
--- a/perception/probabilistic_occupancy_grid_map/README.md
+++ b/perception/probabilistic_occupancy_grid_map/README.md
@@ -9,6 +9,7 @@ This package outputs the probability of having an obstacle as occupancy grid map
- [Pointcloud based occupancy grid map](pointcloud-based-occupancy-grid-map.md)
- [Laserscan based occupancy grid map](laserscan-based-occupancy-grid-map.md)
+- [Grid map fusion](synchronized_grid_map_fusion.md)
## Settings
@@ -70,3 +71,19 @@ Additional argument is shown below:
| `container_name` | `occupancy_grid_map_container` | |
| `input_obstacle_pointcloud` | `false` | only for laserscan based method. If true, the node subscribe obstacle pointcloud |
| `input_obstacle_and_raw_pointcloud` | `true` | only for laserscan based method. If true, the node subscribe both obstacle and raw pointcloud |
+
+### Test
+
+This package provides unit tests using `gtest`.
+You can run the test by the following command.
+
+```bash
+colcon test --packages-select probabilistic_occupancy_grid_map --event-handlers console_direct+
+```
+
+Test contains the following.
+
+- Unit test for cost value conversion function
+- Unit test for utility functions
+- Unit test for occupancy grid map fusion functions
+- Input/Output test for pointcloud based occupancy grid map
diff --git a/perception/probabilistic_occupancy_grid_map/config/synchronized_grid_map_fusion_node.param.yaml b/perception/probabilistic_occupancy_grid_map/config/synchronized_grid_map_fusion_node.param.yaml
new file mode 100644
index 0000000000000..f8a2dc2fbc7de
--- /dev/null
+++ b/perception/probabilistic_occupancy_grid_map/config/synchronized_grid_map_fusion_node.param.yaml
@@ -0,0 +1,20 @@
+/**:
+ ros__parameters:
+ # 1. fusion parameters
+ fusion_input_ogm_topics: ["topic1", "topic2"]
+ input_ogm_reliabilities: [0.8, 0.2]
+ fusion_method: "overwrite" # choose from ["overwrite", "log-odds", "dempster-shafer"]
+
+ # 2. synchronization settings
+ match_threshold_sec: 0.01 # 10ms
+ timeout_sec: 0.1 # 100ms
+ input_offset_sec: [0.0, 0.0] # no offset
+
+ # 3. settings for fused fusion map
+ # remember resolution and map size should be same with input maps
+ map_frame_: "map"
+ base_link_frame_: "base_link"
+ grid_map_origin_frame_: "base_link"
+ fusion_map_length_x: 100.0
+ fusion_map_length_y: 100.0
+ fusion_map_resolution: 0.5
diff --git a/perception/probabilistic_occupancy_grid_map/image/synchronized_grid_map_fusion.drawio.svg b/perception/probabilistic_occupancy_grid_map/image/synchronized_grid_map_fusion.drawio.svg
new file mode 100644
index 0000000000000..6bf5ed98e4edf
--- /dev/null
+++ b/perception/probabilistic_occupancy_grid_map/image/synchronized_grid_map_fusion.drawio.svg
@@ -0,0 +1,290 @@
+
diff --git a/perception/probabilistic_occupancy_grid_map/include/cost_value.hpp b/perception/probabilistic_occupancy_grid_map/include/cost_value.hpp
index e9667ccf65577..e0f18cedcdff1 100644
--- a/perception/probabilistic_occupancy_grid_map/include/cost_value.hpp
+++ b/perception/probabilistic_occupancy_grid_map/include/cost_value.hpp
@@ -59,19 +59,48 @@ static const unsigned char NO_INFORMATION = 128; // 0.5 * 255
static const unsigned char LETHAL_OBSTACLE = 255;
static const unsigned char FREE_SPACE = 0;
+static const unsigned char OCCUPIED_THRESHOLD = 180;
+static const unsigned char FREE_THRESHOLD = 50;
+
struct CostTranslationTable
{
CostTranslationTable()
{
for (int i = 0; i < 256; i++) {
- const auto value = static_cast(static_cast(i) * 100.f / 255.f);
- data[i] = std::max(std::min(value, static_cast(99)), static_cast(1));
+ const auto value =
+ static_cast(static_cast(i) * 100.f / 255.f); // 0-255 to 0-100
+ data[i] =
+ std::max(std::min(value, static_cast(99)), static_cast(1)); // 0-100 to 1-99
}
}
char operator[](unsigned char n) const { return data[n]; }
char data[256];
};
+struct InverseCostTranslationTable
+{
+ InverseCostTranslationTable()
+ {
+ // 0-100 to 0-255
+ for (int i = 0; i < 100; i++) {
+ data[i] = static_cast(i * 255 / 99);
+ }
+ }
+ unsigned char operator[](char n) const
+ {
+ if (n > 99) {
+ return data[99];
+ } else if (n < 1) {
+ return data[1];
+ } else {
+ const unsigned char u_n = static_cast(n);
+ return data[u_n];
+ }
+ }
+ unsigned char data[100];
+};
+
static const CostTranslationTable cost_translation_table;
+static const InverseCostTranslationTable inverse_cost_translation_table;
} // namespace occupancy_cost_value
#endif // COST_VALUE_HPP_
diff --git a/perception/probabilistic_occupancy_grid_map/include/fusion/single_frame_fusion_policy.hpp b/perception/probabilistic_occupancy_grid_map/include/fusion/single_frame_fusion_policy.hpp
new file mode 100644
index 0000000000000..13829b4910d96
--- /dev/null
+++ b/perception/probabilistic_occupancy_grid_map/include/fusion/single_frame_fusion_policy.hpp
@@ -0,0 +1,66 @@
+// Copyright 2023 TIER IV, Inc.
+//
+// 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 FUSION__SINGLE_FRAME_FUSION_POLICY_HPP_
+#define FUSION__SINGLE_FRAME_FUSION_POLICY_HPP_
+
+#include "cost_value.hpp"
+
+#include
+#include
+#include
+#include
+
+/*min and max prob threshold to prevent log-odds to diverge*/
+#define EPSILON_PROB 0.03
+
+namespace fusion_policy
+{
+enum class FusionMethod { OVERWRITE, LOG_ODDS, DEMPSTER_SHAFER };
+
+unsigned char convertProbabilityToChar(const double & probability);
+double convertCharToProbability(const unsigned char & occupancy);
+std::vector convertProbabilityToChar(const std::vector & probabilities);
+std::vector convertCharToProbability(const std::vector & occupancies);
+
+namespace overwrite_fusion
+{
+enum State : unsigned char { UNKNOWN = 0U, FREE = 1U, OCCUPIED = 2U };
+State getApproximateState(const unsigned char & occupancy);
+unsigned char overwriteFusion(const std::vector & occupancies);
+} // namespace overwrite_fusion
+
+namespace log_odds_fusion
+{
+double logOddsFusion(const std::vector & probabilities);
+double logOddsFusion(
+ const std::vector & probabilities, const std::vector & weights);
+} // namespace log_odds_fusion
+
+namespace dempster_shafer_fusion
+{
+struct dempsterShaferOccupancy;
+double dempsterShaferFusion(const std::vector & probability);
+double dempsterShaferFusion(
+ const std::vector & probability, const std::vector & reliability);
+} // namespace dempster_shafer_fusion
+
+unsigned char singleFrameOccupancyFusion(
+ const std::vector & occupancy, FusionMethod method);
+unsigned char singleFrameOccupancyFusion(
+ const std::vector & occupancy, FusionMethod method,
+ const std::vector & reliability);
+} // namespace fusion_policy
+
+#endif // FUSION__SINGLE_FRAME_FUSION_POLICY_HPP_
diff --git a/perception/probabilistic_occupancy_grid_map/include/fusion/synchronized_grid_map_fusion_node.hpp b/perception/probabilistic_occupancy_grid_map/include/fusion/synchronized_grid_map_fusion_node.hpp
new file mode 100644
index 0000000000000..6bea5b2a16f72
--- /dev/null
+++ b/perception/probabilistic_occupancy_grid_map/include/fusion/synchronized_grid_map_fusion_node.hpp
@@ -0,0 +1,127 @@
+// Copyright 2023 Tier IV, Inc.
+//
+// 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 FUSION__SYNCHRONIZED_GRID_MAP_FUSION_NODE_HPP_
+#define FUSION__SYNCHRONIZED_GRID_MAP_FUSION_NODE_HPP_
+
+#include "fusion/single_frame_fusion_policy.hpp"
+#include "pointcloud_based_occupancy_grid_map/occupancy_grid_map_fixed.hpp"
+#include "updater/occupancy_grid_map_log_odds_bayes_filter_updater.hpp"
+#include "updater/occupancy_grid_map_updater_interface.hpp"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include