diff --git a/common/component_interface_tools/CMakeLists.txt b/common/component_interface_tools/CMakeLists.txt
new file mode 100644
index 0000000000000..a5ebc29463bec
--- /dev/null
+++ b/common/component_interface_tools/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.14)
+project(component_interface_tools)
+
+find_package(autoware_cmake REQUIRED)
+autoware_package()
+ament_auto_add_executable(service_log_checker src/service_log_checker.cpp)
+ament_auto_package(INSTALL_TO_SHARE launch)
diff --git a/common/component_interface_tools/launch/service_log_checker.launch.xml b/common/component_interface_tools/launch/service_log_checker.launch.xml
new file mode 100644
index 0000000000000..f3099b3238096
--- /dev/null
+++ b/common/component_interface_tools/launch/service_log_checker.launch.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/common/component_interface_tools/package.xml b/common/component_interface_tools/package.xml
new file mode 100644
index 0000000000000..a1eba3cb41e09
--- /dev/null
+++ b/common/component_interface_tools/package.xml
@@ -0,0 +1,28 @@
+
+
+
+ component_interface_tools
+ 0.1.0
+ The component_interface_tools package
+ Takagi, Isamu
+ yabuta
+ Kah Hooi Tan
+ Apache License 2.0
+
+ ament_cmake_auto
+
+ autoware_cmake
+
+ diagnostic_updater
+ fmt
+ rclcpp
+ tier4_system_msgs
+ yaml_cpp_vendor
+
+ ament_lint_auto
+ autoware_lint_common
+
+
+ ament_cmake
+
+
diff --git a/common/component_interface_tools/src/service_log_checker.cpp b/common/component_interface_tools/src/service_log_checker.cpp
new file mode 100644
index 0000000000000..ce89573356412
--- /dev/null
+++ b/common/component_interface_tools/src/service_log_checker.cpp
@@ -0,0 +1,110 @@
+// Copyright 2022 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 "service_log_checker.hpp"
+
+#include
+
+#include
+#include
+
+#define FMT_HEADER_ONLY
+#include
+
+ServiceLogChecker::ServiceLogChecker() : Node("service_log_checker"), diagnostics_(this)
+{
+ sub_ = create_subscription(
+ "/service_log", 50, std::bind(&ServiceLogChecker::on_service_log, this, std::placeholders::_1));
+
+ diagnostics_.setHardwareID(get_name());
+ diagnostics_.add("response_status", this, &ServiceLogChecker::update_diagnostics);
+}
+
+void ServiceLogChecker::on_service_log(const ServiceLog::ConstSharedPtr msg)
+{
+ try {
+ // Ignore service request.
+ if (msg->type == ServiceLog::CLIENT_REQUEST || msg->type == ServiceLog::SERVER_REQUEST) {
+ return;
+ }
+
+ // Ignore service errors.
+ if (msg->type == ServiceLog::ERROR_UNREADY) {
+ return set_error(*msg, "not ready");
+ }
+ if (msg->type == ServiceLog::ERROR_TIMEOUT) {
+ return set_error(*msg, "timeout");
+ }
+
+ // Ignore version API because it doesn't have response status.
+ if (msg->name == "/api/interface/version") {
+ return;
+ }
+
+ // Parse response data.
+ const auto status = YAML::Load(msg->yaml)["status"];
+ if (!status) {
+ return set_error(*msg, "no response status");
+ }
+
+ // Check response status.
+ const auto success = status["success"].as();
+ if (!success) {
+ const auto message = status["message"].as();
+ const auto code = status["code"].as();
+ return set_error(*msg, fmt::format("status code {} '{}'", code, message));
+ }
+ } catch (const YAML::Exception & error) {
+ return set_error(*msg, fmt::format("invalid data: '{}'", error.what()));
+ }
+
+ set_success(*msg);
+}
+
+void ServiceLogChecker::set_success(const ServiceLog & msg)
+{
+ errors_.erase(fmt::format("{} ({})", msg.name, msg.node));
+}
+
+void ServiceLogChecker::set_error(const ServiceLog & msg, const std::string & log)
+{
+ errors_[fmt::format("{} ({})", msg.name, msg.node)] = log;
+ RCLCPP_ERROR_STREAM(get_logger(), fmt::format("{}: {} ({})", msg.name, log, msg.node));
+}
+
+void ServiceLogChecker::update_diagnostics(diagnostic_updater::DiagnosticStatusWrapper & stat)
+{
+ using diagnostic_msgs::msg::DiagnosticStatus;
+
+ for (const auto & error : errors_) {
+ stat.add(error.first, error.second);
+ }
+
+ if (errors_.empty()) {
+ stat.summary(DiagnosticStatus::OK, "OK");
+ } else {
+ stat.summary(DiagnosticStatus::ERROR, "ERROR");
+ }
+}
+
+int main(int argc, char ** argv)
+{
+ rclcpp::init(argc, argv);
+ rclcpp::executors::SingleThreadedExecutor executor;
+ auto node = std::make_shared();
+ executor.add_node(node);
+ executor.spin();
+ executor.remove_node(node);
+ rclcpp::shutdown();
+}
diff --git a/common/component_interface_tools/src/service_log_checker.hpp b/common/component_interface_tools/src/service_log_checker.hpp
new file mode 100644
index 0000000000000..32c7f02e757c6
--- /dev/null
+++ b/common/component_interface_tools/src/service_log_checker.hpp
@@ -0,0 +1,42 @@
+// Copyright 2022 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 SERVICE_LOG_CHECKER_HPP_
+#define SERVICE_LOG_CHECKER_HPP_
+
+#include
+#include
+
+#include
+
+#include
+#include
+
+class ServiceLogChecker : public rclcpp::Node
+{
+public:
+ ServiceLogChecker();
+
+private:
+ using ServiceLog = tier4_system_msgs::msg::ServiceLog;
+ rclcpp::Subscription::SharedPtr sub_;
+ diagnostic_updater::Updater diagnostics_;
+ void on_service_log(const ServiceLog::ConstSharedPtr msg);
+ void set_success(const ServiceLog & msg);
+ void set_error(const ServiceLog & msg, const std::string & log);
+ void update_diagnostics(diagnostic_updater::DiagnosticStatusWrapper & stat);
+ std::unordered_map errors_;
+};
+
+#endif // SERVICE_LOG_CHECKER_HPP_
diff --git a/common/component_interface_utils/CMakeLists.txt b/common/component_interface_utils/CMakeLists.txt
index d753b4e92d218..d4f6343e381c7 100644
--- a/common/component_interface_utils/CMakeLists.txt
+++ b/common/component_interface_utils/CMakeLists.txt
@@ -3,5 +3,4 @@ project(component_interface_utils)
find_package(autoware_cmake REQUIRED)
autoware_package()
-ament_export_dependencies(tier4_system_msgs)
ament_auto_package()
diff --git a/common/component_interface_utils/package.xml b/common/component_interface_utils/package.xml
index 78620dab76cfe..90602a65bd1b0 100644
--- a/common/component_interface_utils/package.xml
+++ b/common/component_interface_utils/package.xml
@@ -13,6 +13,7 @@
ament_cmake_auto
autoware_cmake
+ tier4_system_msgs
autoware_adapi_v1_msgs
rclcpp
diff --git a/common/tier4_autoware_utils/include/tier4_autoware_utils/ros/uuid_helper.hpp b/common/tier4_autoware_utils/include/tier4_autoware_utils/ros/uuid_helper.hpp
new file mode 100644
index 0000000000000..5b2f197c18827
--- /dev/null
+++ b/common/tier4_autoware_utils/include/tier4_autoware_utils/ros/uuid_helper.hpp
@@ -0,0 +1,34 @@
+// Copyright 2022 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 TIER4_AUTOWARE_UTILS__ROS__UUID_HELPER_HPP_
+#define TIER4_AUTOWARE_UTILS__ROS__UUID_HELPER_HPP_
+
+#include
+
+#include
+
+namespace tier4_autoware_utils
+{
+inline std::string toHexString(const unique_identifier_msgs::msg::UUID & id)
+{
+ std::stringstream ss;
+ for (auto i = 0; i < 16; ++i) {
+ ss << std::hex << std::setfill('0') << std::setw(2) << +id.uuid[i];
+ }
+ return ss.str();
+}
+} // namespace tier4_autoware_utils
+
+#endif // TIER4_AUTOWARE_UTILS__ROS__UUID_HELPER_HPP_
diff --git a/common/tier4_autoware_utils/include/tier4_autoware_utils/tier4_autoware_utils.hpp b/common/tier4_autoware_utils/include/tier4_autoware_utils/tier4_autoware_utils.hpp
index 35b4c7b836b46..b1cb540ee7a77 100644
--- a/common/tier4_autoware_utils/include/tier4_autoware_utils/tier4_autoware_utils.hpp
+++ b/common/tier4_autoware_utils/include/tier4_autoware_utils/tier4_autoware_utils.hpp
@@ -33,6 +33,7 @@
#include "tier4_autoware_utils/ros/self_pose_listener.hpp"
#include "tier4_autoware_utils/ros/transform_listener.hpp"
#include "tier4_autoware_utils/ros/update_param.hpp"
+#include "tier4_autoware_utils/ros/uuid_helper.hpp"
#include "tier4_autoware_utils/ros/wait_for_param.hpp"
#include "tier4_autoware_utils/system/stop_watch.hpp"
diff --git a/common/tier4_autoware_utils/package.xml b/common/tier4_autoware_utils/package.xml
index 1e9acb6101935..9e648c49e067b 100644
--- a/common/tier4_autoware_utils/package.xml
+++ b/common/tier4_autoware_utils/package.xml
@@ -6,6 +6,8 @@
The tier4_autoware_utils package
Takamasa Horibe
Kenji Miyake
+ Takayuki Murooka
+ Yutaka Shimizu
Apache License 2.0
ament_cmake_auto
@@ -23,6 +25,7 @@
tf2
tf2_geometry_msgs
tier4_debug_msgs
+ unique_identifier_msgs
visualization_msgs
ament_cmake_ros
diff --git a/control/operation_mode_transition_manager/config/operation_mode_transition_manager.param.yaml b/control/operation_mode_transition_manager/config/operation_mode_transition_manager.param.yaml
index a0ddef6e363cc..a86443f5cabdb 100644
--- a/control/operation_mode_transition_manager/config/operation_mode_transition_manager.param.yaml
+++ b/control/operation_mode_transition_manager/config/operation_mode_transition_manager.param.yaml
@@ -3,6 +3,8 @@
transition_timeout: 10.0
frequency_hz: 10.0
check_engage_condition: false # set false if you do not want to care about the engage condition.
+ nearest_dist_deviation_threshold: 3.0 # [m] for finding nearest index
+ nearest_yaw_deviation_threshold: 1.57 # [rad] for finding nearest index
engage_acceptable_limits:
allow_autonomous_in_stopped: true # no check if the velocity is zero, always allowed.
dist_threshold: 1.5
diff --git a/control/operation_mode_transition_manager/src/state.cpp b/control/operation_mode_transition_manager/src/state.cpp
index 775083908cdfd..8980f665d916d 100644
--- a/control/operation_mode_transition_manager/src/state.cpp
+++ b/control/operation_mode_transition_manager/src/state.cpp
@@ -43,6 +43,10 @@ AutonomousMode::AutonomousMode(rclcpp::Node * node)
"trajectory", 1, [this](const Trajectory::SharedPtr msg) { trajectory_ = *msg; });
check_engage_condition_ = node->declare_parameter("check_engage_condition");
+ nearest_dist_deviation_threshold_ =
+ node->declare_parameter("nearest_dist_deviation_threshold");
+ nearest_yaw_deviation_threshold_ =
+ node->declare_parameter("nearest_yaw_deviation_threshold");
// params for mode change available
{
@@ -86,9 +90,6 @@ bool AutonomousMode::isModeChangeCompleted()
return true;
}
- constexpr auto dist_max = 5.0;
- constexpr auto yaw_max = M_PI_4;
-
const auto current_speed = kinematics_.twist.twist.linear.x;
const auto & param = engage_acceptable_param_;
@@ -107,8 +108,9 @@ bool AutonomousMode::isModeChangeCompleted()
return unstable();
}
- const auto closest_idx =
- findNearestIndex(trajectory_.points, kinematics_.pose.pose, dist_max, yaw_max);
+ const auto closest_idx = findNearestIndex(
+ trajectory_.points, kinematics_.pose.pose, nearest_dist_deviation_threshold_,
+ nearest_yaw_deviation_threshold_);
if (!closest_idx) {
RCLCPP_INFO(logger_, "Not stable yet: closest point not found");
return unstable();
@@ -199,9 +201,6 @@ bool AutonomousMode::isModeChangeAvailable()
return true;
}
- constexpr auto dist_max = 100.0;
- constexpr auto yaw_max = M_PI_4;
-
const auto current_speed = kinematics_.twist.twist.linear.x;
const auto target_control_speed = control_cmd_.longitudinal.speed;
const auto & param = engage_acceptable_param_;
@@ -213,8 +212,9 @@ bool AutonomousMode::isModeChangeAvailable()
return false;
}
- const auto closest_idx =
- findNearestIndex(trajectory_.points, kinematics_.pose.pose, dist_max, yaw_max);
+ const auto closest_idx = findNearestIndex(
+ trajectory_.points, kinematics_.pose.pose, nearest_dist_deviation_threshold_,
+ nearest_yaw_deviation_threshold_);
if (!closest_idx) {
RCLCPP_INFO(logger_, "Engage unavailable: closest point not found");
debug_info_ = DebugInfo{}; // all false
diff --git a/control/operation_mode_transition_manager/src/state.hpp b/control/operation_mode_transition_manager/src/state.hpp
index dc72d57aed231..9d384857bbe3d 100644
--- a/control/operation_mode_transition_manager/src/state.hpp
+++ b/control/operation_mode_transition_manager/src/state.hpp
@@ -72,7 +72,9 @@ class AutonomousMode : public ModeChangeBase
rclcpp::Logger logger_;
rclcpp::Clock::SharedPtr clock_;
- bool check_engage_condition_ = true; // if false, the vehicle is engaged without any checks.
+ bool check_engage_condition_ = true; // if false, the vehicle is engaged without any checks.
+ double nearest_dist_deviation_threshold_; // [m] for finding nearest index
+ double nearest_yaw_deviation_threshold_; // [rad] for finding nearest index
EngageAcceptableParam engage_acceptable_param_;
StableCheckParam stable_check_param_;
AckermannControlCommand control_cmd_;
diff --git a/control/trajectory_follower/design/mpc_lateral_controller-design.md b/control/trajectory_follower/design/mpc_lateral_controller-design.md
index ee79cc88f206b..0883d160cb89b 100644
--- a/control/trajectory_follower/design/mpc_lateral_controller-design.md
+++ b/control/trajectory_follower/design/mpc_lateral_controller-design.md
@@ -93,6 +93,7 @@ AutonomouStuff Lexus RX 450h for under 40 km/h driving.
| path_smoothing_times | int | number of times of applying path smoothing filter | 1 |
| curvature_smoothing_num_ref_steer | double | index distance of points used in curvature calculation for reference steer command: p(i-num), p(i), p(i+num). larger num makes less noisy values. | 35 |
| curvature_smoothing_num_traj | double | index distance of points used in curvature calculation for trajectory: p(i-num), p(i), p(i+num). larger num makes less noisy values. | 1 |
+| extend_trajectory_for_end_yaw_control | bool | trajectory extending flag for end yaw control. | true |
| steering_lpf_cutoff_hz | double | cutoff frequency of lowpass filter for steering output command [hz] | 3.0 |
| admissible_position_error | double | stop vehicle when following position error is larger than this value [m]. | 5.0 |
| admissible_yaw_error_rad | double | stop vehicle when following yaw angle error is larger than this value [rad]. | 1.57 |
diff --git a/control/trajectory_follower/include/trajectory_follower/mpc.hpp b/control/trajectory_follower/include/trajectory_follower/mpc.hpp
index 8ae6dc5449fc3..c64c231144b80 100644
--- a/control/trajectory_follower/include/trajectory_follower/mpc.hpp
+++ b/control/trajectory_follower/include/trajectory_follower/mpc.hpp
@@ -400,7 +400,7 @@ class TRAJECTORY_FOLLOWER_PUBLIC MPC
const autoware_auto_planning_msgs::msg::Trajectory & trajectory_msg,
const double traj_resample_dist, const bool enable_path_smoothing,
const int path_filter_moving_ave_num, const int curvature_smoothing_num_traj,
- const int curvature_smoothing_num_ref_steer);
+ const int curvature_smoothing_num_ref_steer, const bool extend_trajectory_for_end_yaw_control);
/**
* @brief set the vehicle model of this MPC
*/
diff --git a/control/trajectory_follower/include/trajectory_follower/mpc_lateral_controller.hpp b/control/trajectory_follower/include/trajectory_follower/mpc_lateral_controller.hpp
index d38312505fed7..8ed6d44b85258 100644
--- a/control/trajectory_follower/include/trajectory_follower/mpc_lateral_controller.hpp
+++ b/control/trajectory_follower/include/trajectory_follower/mpc_lateral_controller.hpp
@@ -97,6 +97,9 @@ class TRAJECTORY_FOLLOWER_PUBLIC MpcLateralController : public LateralController
//!< @brief path resampling interval [m]
double m_traj_resample_dist;
+ //!< @brief flag of traj extending for terminal yaw
+ bool m_extend_trajectory_for_end_yaw_control;
+
/* parameters for stop state */
double m_stop_state_entry_ego_speed;
double m_stop_state_entry_target_speed;
diff --git a/control/trajectory_follower/include/trajectory_follower/mpc_utils.hpp b/control/trajectory_follower/include/trajectory_follower/mpc_utils.hpp
index 9f394ff9baa6f..f9f58deadd6bb 100644
--- a/control/trajectory_follower/include/trajectory_follower/mpc_utils.hpp
+++ b/control/trajectory_follower/include/trajectory_follower/mpc_utils.hpp
@@ -179,6 +179,21 @@ TRAJECTORY_FOLLOWER_PUBLIC bool calcNearestPoseInterp(
// */
TRAJECTORY_FOLLOWER_PUBLIC double calcStopDistance(
const autoware_auto_planning_msgs::msg::Trajectory & current_trajectory, const int origin);
+
+/**
+ * @brief extend terminal points
+ * Note: The current MPC does not properly take into account the attitude angle at the end of the
+ * path. By extending the end of the path in the attitude direction, the MPC can consider the
+ * attitude angle well, resulting in improved control performance. If the trajectory is
+ * well-defined considering the end point attitude angle, this feature is not necessary.
+ * @param [in] terminal yaw
+ * @param [in] extend interval
+ * @param [in] flag of forward shift
+ * @param [out] extended trajectory
+ */
+void extendTrajectoryInYawDirection(
+ const double yaw, const double interval, const bool is_forward_shift, MPCTrajectory & traj);
+
} // namespace MPCUtils
} // namespace trajectory_follower
} // namespace control
diff --git a/control/trajectory_follower/src/mpc.cpp b/control/trajectory_follower/src/mpc.cpp
index 050727c40a50d..ed6472700e14a 100644
--- a/control/trajectory_follower/src/mpc.cpp
+++ b/control/trajectory_follower/src/mpc.cpp
@@ -180,7 +180,7 @@ void MPC::setReferenceTrajectory(
const autoware_auto_planning_msgs::msg::Trajectory & trajectory_msg,
const double traj_resample_dist, const bool enable_path_smoothing,
const int path_filter_moving_ave_num, const int curvature_smoothing_num_traj,
- const int curvature_smoothing_num_ref_steer)
+ const int curvature_smoothing_num_ref_steer, const bool extend_trajectory_for_end_yaw_control)
{
trajectory_follower::MPCTrajectory mpc_traj_raw; // received raw trajectory
trajectory_follower::MPCTrajectory mpc_traj_resampled; // resampled trajectory
@@ -217,6 +217,17 @@ void MPC::setReferenceTrajectory(
}
}
+ /* extend terminal points
+ * Note: The current MPC does not properly take into account the attitude angle at the end of the
+ * path. By extending the end of the path in the attitude direction, the MPC can consider the
+ * attitude angle well, resulting in improved control performance. If the trajectory is
+ * well-defined considering the end point attitude angle, this feature is not necessary.
+ */
+ if (extend_trajectory_for_end_yaw_control) {
+ trajectory_follower::MPCUtils::extendTrajectoryInYawDirection(
+ mpc_traj_raw.yaw.back(), traj_resample_dist, m_is_forward_shift, mpc_traj_smoothed);
+ }
+
/* calculate yaw angle */
trajectory_follower::MPCUtils::calcTrajectoryYawFromXY(&mpc_traj_smoothed, m_is_forward_shift);
trajectory_follower::MPCUtils::convertEulerAngleToMonotonic(&mpc_traj_smoothed.yaw);
diff --git a/control/trajectory_follower/src/mpc_lateral_controller.cpp b/control/trajectory_follower/src/mpc_lateral_controller.cpp
index aaefa696d6494..b2e0ac18753a5 100644
--- a/control/trajectory_follower/src/mpc_lateral_controller.cpp
+++ b/control/trajectory_follower/src/mpc_lateral_controller.cpp
@@ -65,6 +65,8 @@ MpcLateralController::MpcLateralController(rclcpp::Node & node) : node_{&node}
m_mpc.m_admissible_yaw_error_rad = node_->declare_parameter("admissible_yaw_error_rad");
m_mpc.m_use_steer_prediction = node_->declare_parameter("use_steer_prediction");
m_mpc.m_param.steer_tau = node_->declare_parameter("vehicle_model_steer_tau");
+ m_extend_trajectory_for_end_yaw_control =
+ node_->declare_parameter("extend_trajectory_for_end_yaw_control");
/* stop state parameters */
m_stop_state_entry_ego_speed = node_->declare_parameter("stop_state_entry_ego_speed");
@@ -302,7 +304,8 @@ void MpcLateralController::setTrajectory(
m_mpc.setReferenceTrajectory(
*msg, m_traj_resample_dist, m_enable_path_smoothing, m_path_filter_moving_ave_num,
- m_curvature_smoothing_num_traj, m_curvature_smoothing_num_ref_steer);
+ m_curvature_smoothing_num_traj, m_curvature_smoothing_num_ref_steer,
+ m_extend_trajectory_for_end_yaw_control);
// update trajectory buffer to check the trajectory shape change.
m_trajectory_buffer.push_back(*m_current_trajectory_ptr);
diff --git a/control/trajectory_follower/src/mpc_utils.cpp b/control/trajectory_follower/src/mpc_utils.cpp
index e4270909cdf21..6e5b31d340e6b 100644
--- a/control/trajectory_follower/src/mpc_utils.cpp
+++ b/control/trajectory_follower/src/mpc_utils.cpp
@@ -265,10 +265,9 @@ bool calcMPCTrajectoryTime(MPCTrajectory & traj)
traj.relative_time.clear();
traj.relative_time.push_back(t);
for (size_t i = 0; i < traj.x.size() - 1; ++i) {
- const double dx = traj.x.at(i + 1) - traj.x.at(i);
- const double dy = traj.y.at(i + 1) - traj.y.at(i);
- const double dz = traj.z.at(i + 1) - traj.z.at(i);
- const double dist = std::sqrt(dx * dx + dy * dy + dz * dz);
+ const double dist = std::hypot(
+ traj.x.at(i + 1) - traj.x.at(i), traj.y.at(i + 1) - traj.y.at(i),
+ traj.z.at(i + 1) - traj.z.at(i));
const double v = std::max(std::fabs(traj.vx.at(i)), 0.1);
t += (dist / v);
traj.relative_time.push_back(t);
@@ -404,6 +403,31 @@ double calcStopDistance(
return stop_dist;
}
+void extendTrajectoryInYawDirection(
+ const double yaw, const double interval, const bool is_forward_shift, MPCTrajectory & traj)
+{
+ // set terminal yaw
+ traj.yaw.back() = yaw;
+
+ // get terminal pose
+ autoware_auto_planning_msgs::msg::Trajectory autoware_traj;
+ autoware::motion::control::trajectory_follower::MPCUtils::convertToAutowareTrajectory(
+ traj, autoware_traj);
+ auto extended_pose = autoware_traj.points.back().pose;
+
+ constexpr double extend_dist = 10.0;
+ constexpr double extend_vel = 10.0;
+ const double x_offset = is_forward_shift ? interval : -interval;
+ const double dt = interval / extend_vel;
+ const size_t num_extended_point = static_cast(extend_dist / interval);
+ for (size_t i = 0; i < num_extended_point; ++i) {
+ extended_pose = tier4_autoware_utils::calcOffsetPose(extended_pose, x_offset, 0.0, 0.0);
+ traj.push_back(
+ extended_pose.position.x, extended_pose.position.y, extended_pose.position.z, traj.yaw.back(),
+ extend_vel, traj.k.back(), traj.smooth_k.back(), traj.relative_time.back() + dt);
+ }
+}
+
} // namespace MPCUtils
} // namespace trajectory_follower
} // namespace control
diff --git a/control/trajectory_follower/test/test_mpc.cpp b/control/trajectory_follower/test/test_mpc.cpp
index 909133dcd65bd..6aa767289c1fd 100644
--- a/control/trajectory_follower/test/test_mpc.cpp
+++ b/control/trajectory_follower/test/test_mpc.cpp
@@ -84,6 +84,7 @@ class MPCTest : public ::testing::Test
int curvature_smoothing_num_ref_steer = 35;
bool enable_path_smoothing = true;
bool use_steer_prediction = true;
+ bool extend_trajectory_for_end_yaw_control = true;
void SetUp() override
{
@@ -175,7 +176,8 @@ class MPCTest : public ::testing::Test
// Init trajectory
mpc.setReferenceTrajectory(
dummy_straight_trajectory, traj_resample_dist, enable_path_smoothing,
- path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer);
+ path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer,
+ extend_trajectory_for_end_yaw_control);
}
}; // class MPCTest
@@ -233,7 +235,8 @@ TEST_F(MPCTest, InitializeAndCalculateRightTurn)
initializeMPC(mpc);
mpc.setReferenceTrajectory(
dummy_right_turn_trajectory, traj_resample_dist, enable_path_smoothing,
- path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer);
+ path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer,
+ extend_trajectory_for_end_yaw_control);
// Calculate MPC
AckermannLateralCommand ctrl_cmd;
@@ -251,7 +254,8 @@ TEST_F(MPCTest, OsqpCalculate)
initializeMPC(mpc);
mpc.setReferenceTrajectory(
dummy_straight_trajectory, traj_resample_dist, enable_path_smoothing,
- path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer);
+ path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer,
+ extend_trajectory_for_end_yaw_control);
const std::string vehicle_model_type = "kinematics";
std::shared_ptr vehicle_model_ptr =
@@ -282,7 +286,8 @@ TEST_F(MPCTest, OsqpCalculateRightTurn)
initializeMPC(mpc);
mpc.setReferenceTrajectory(
dummy_right_turn_trajectory, traj_resample_dist, enable_path_smoothing,
- path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer);
+ path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer,
+ extend_trajectory_for_end_yaw_control);
const std::string vehicle_model_type = "kinematics";
std::shared_ptr vehicle_model_ptr =
@@ -327,7 +332,8 @@ TEST_F(MPCTest, KinematicsNoDelayCalculate)
// Init trajectory
mpc.setReferenceTrajectory(
dummy_straight_trajectory, traj_resample_dist, enable_path_smoothing,
- path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer);
+ path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer,
+ extend_trajectory_for_end_yaw_control);
// Calculate MPC
AckermannLateralCommand ctrl_cmd;
Trajectory pred_traj;
@@ -344,7 +350,8 @@ TEST_F(MPCTest, KinematicsNoDelayCalculateRightTurn)
initializeMPC(mpc);
mpc.setReferenceTrajectory(
dummy_right_turn_trajectory, traj_resample_dist, enable_path_smoothing,
- path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer);
+ path_filter_moving_ave_num, curvature_smoothing_num_traj, curvature_smoothing_num_ref_steer,
+ extend_trajectory_for_end_yaw_control);
const std::string vehicle_model_type = "kinematics_no_delay";
std::shared_ptr vehicle_model_ptr =
diff --git a/control/trajectory_follower_nodes/param/lateral_controller_defaults.param.yaml b/control/trajectory_follower_nodes/param/lateral_controller_defaults.param.yaml
index a6d98fa682d74..92d15da9e49e6 100644
--- a/control/trajectory_follower_nodes/param/lateral_controller_defaults.param.yaml
+++ b/control/trajectory_follower_nodes/param/lateral_controller_defaults.param.yaml
@@ -12,6 +12,9 @@
curvature_smoothing_num_traj: 15 # point-to-point index distance used in curvature calculation (for trajectory): curvature is calculated from three points p(i-num), p(i), p(i+num)
curvature_smoothing_num_ref_steer: 15 # point-to-point index distance used in curvature calculation (for steer command reference): curvature is calculated from three points p(i-num), p(i), p(i+num)
+ # -- trajectory extending --
+ extend_trajectory_for_end_yaw_control: true # flag of trajectory extending for terminal yaw control
+
# -- mpc optimization --
qp_solver_type: "osqp" # optimization solver option (unconstraint_fast or osqp)
mpc_prediction_horizon: 50 # prediction horizon step
diff --git a/launch/tier4_control_launch/config/trajectory_follower/lateral_controller.param.yaml b/launch/tier4_control_launch/config/trajectory_follower/lateral_controller.param.yaml
index 76b5da140bfaa..f3819f155edfe 100644
--- a/launch/tier4_control_launch/config/trajectory_follower/lateral_controller.param.yaml
+++ b/launch/tier4_control_launch/config/trajectory_follower/lateral_controller.param.yaml
@@ -13,6 +13,9 @@
curvature_smoothing_num_traj: 15 # point-to-point index distance used in curvature calculation (for trajectory): curvature is calculated from three points p(i-num), p(i), p(i+num)
curvature_smoothing_num_ref_steer: 15 # point-to-point index distance used in curvature calculation (for steer command reference): curvature is calculated from three points p(i-num), p(i), p(i+num)
+ # -- trajectory extending --
+ extend_trajectory_for_end_yaw_control: true # flag of trajectory extending for terminal yaw control
+
# -- mpc optimization --
qp_solver_type: "osqp" # optimization solver option (unconstraint_fast or osqp)
mpc_prediction_horizon: 50 # prediction horizon step
diff --git a/launch/tier4_map_launch/config/pointcloud_map_loader.param.yaml b/launch/tier4_map_launch/config/pointcloud_map_loader.param.yaml
index fa94afbf12a0b..8f3ccbff00360 100644
--- a/launch/tier4_map_launch/config/pointcloud_map_loader.param.yaml
+++ b/launch/tier4_map_launch/config/pointcloud_map_loader.param.yaml
@@ -3,6 +3,7 @@
enable_whole_load: true
enable_downsampled_whole_load: false
enable_partial_load: false
+ enable_differential_load: false
# only used when downsample_whole_load enabled
leaf_size: 3.0 # downsample leaf size [m]
diff --git a/launch/tier4_planning_launch/config/scenario_planning/lane_driving/behavior_planning/behavior_path_planner/behavior_path_planner.param.yaml b/launch/tier4_planning_launch/config/scenario_planning/lane_driving/behavior_planning/behavior_path_planner/behavior_path_planner.param.yaml
index 6ed118001fa6a..5edecdde26a11 100644
--- a/launch/tier4_planning_launch/config/scenario_planning/lane_driving/behavior_planning/behavior_path_planner/behavior_path_planner.param.yaml
+++ b/launch/tier4_planning_launch/config/scenario_planning/lane_driving/behavior_planning/behavior_path_planner/behavior_path_planner.param.yaml
@@ -7,11 +7,6 @@
backward_length_buffer_for_end_of_pull_out: 5.0
minimum_lane_change_length: 12.0
minimum_pull_over_length: 16.0
- drivable_area_resolution: 0.1
- drivable_lane_forward_length: 50.0
- drivable_lane_backward_length: 5.0
- drivable_lane_margin: 3.0
- drivable_area_margin: 6.0
refine_goal_search_radius_range: 7.5
turn_signal_intersection_search_distance: 30.0
turn_signal_intersection_angle_threshold_deg: 15.0
diff --git a/launch/tier4_planning_launch/config/scenario_planning/lane_driving/motion_planning/obstacle_cruise_planner/obstacle_cruise_planner.param.yaml b/launch/tier4_planning_launch/config/scenario_planning/lane_driving/motion_planning/obstacle_cruise_planner/obstacle_cruise_planner.param.yaml
index 520637abed775..dfc2b2e6ddb44 100644
--- a/launch/tier4_planning_launch/config/scenario_planning/lane_driving/motion_planning/obstacle_cruise_planner/obstacle_cruise_planner.param.yaml
+++ b/launch/tier4_planning_launch/config/scenario_planning/lane_driving/motion_planning/obstacle_cruise_planner/obstacle_cruise_planner.param.yaml
@@ -3,15 +3,18 @@
common:
planning_algorithm: "pid_base" # currently supported algorithm is "pid_base"
- is_showing_debug_info: true
+ is_showing_debug_info: false
+ disable_stop_planning: false # true
# longitudinal info
- idling_time: 1.5 # idling time to detect front vehicle starting deceleration [s]
+ idling_time: 2.0 # idling time to detect front vehicle starting deceleration [s]
min_ego_accel_for_rss: -1.0 # ego's acceleration to calculate RSS distance [m/ss]
min_object_accel_for_rss: -1.0 # front obstacle's acceleration to calculate RSS distance [m/ss]
safe_distance_margin : 6.0 # This is also used as a stop margin [m]
terminal_safe_distance_margin : 3.0 # Stop margin at the goal. This value cannot exceed safe distance margin. [m]
+ lpf_gain_for_accel: 0.2 # gain of low pass filter for ego acceleration [-]
+
nearest_dist_deviation_threshold: 3.0 # [m] for finding nearest index
nearest_yaw_deviation_threshold: 1.57 # [rad] for finding nearest index
min_behavior_stop_margin: 3.0 # [m]
@@ -25,7 +28,7 @@
bus: true
trailer: true
motorcycle: true
- bicycle: false
+ bicycle: true
pedestrian: false
stop_obstacle_type:
@@ -62,7 +65,7 @@
stop_obstacle_hold_time_threshold : 1.0 # maximum time for holding closest stop obstacle
ignored_outside_obstacle_type:
- unknown: false
+ unknown: true
car: false
truck: false
bus: false
@@ -72,21 +75,41 @@
pedestrian: true
pid_based_planner:
- # use_predicted_obstacle_pose: false
+ use_velocity_limit_based_planner: true
+ error_function_type: quadratic # choose from linear, quadratic
- # PID gains to keep safe distance with the front vehicle
- kp: 2.5
- ki: 0.0
- kd: 2.3
+ velocity_limit_based_planner:
+ # PID gains to keep safe distance with the front vehicle
+ kp: 10.0
+ ki: 0.0
+ kd: 2.0
- min_accel_during_cruise: -2.0 # minimum acceleration during cruise to slow down [m/ss]
+ output_ratio_during_accel: 0.6 # target acceleration is multiplied with this value while ego accelerates to catch up the front vehicle [-]
+ vel_to_acc_weight: 12.0 # target acceleration is calculated by (target_velocity - current_velocity) * vel_to_acc_weight [-]
+
+ enable_jerk_limit_to_output_acc: false
- output_ratio_during_accel: 0.6 # target acceleration is multiplied with this value while ego accelerates to catch up the front vehicle [-]
- vel_to_acc_weight: 3.0 # target acceleration is calculated by (target_velocity - current_velocity) * vel_to_acc_weight [-]
+ disable_target_acceleration: true
+ velocity_insertion_based_planner:
+ kp_acc: 6.0
+ ki_acc: 0.0
+ kd_acc: 2.0
+
+ kp_jerk: 20.0
+ ki_jerk: 0.0
+ kd_jerk: 0.0
+
+ output_acc_ratio_during_accel: 0.6 # target acceleration is multiplied with this value while ego accelerates to catch up the front vehicle [-]
+ output_jerk_ratio_during_accel: 1.0 # target acceleration is multiplied with this value while ego accelerates to catch up the front vehicle [-]
+
+ enable_jerk_limit_to_output_acc: true
+
+ min_accel_during_cruise: -2.0 # minimum acceleration during cruise to slow down [m/ss]
min_cruise_target_vel: 0.0 # minimum target velocity during slow down [m/s]
+ time_to_evaluate_rss: 0.0
- lpf_cruise_gain: 0.2
+ lpf_normalized_error_cruise_dist_gain: 0.2
optimization_based_planner:
dense_resampling_time_interval: 0.2
diff --git a/launch/tier4_system_launch/config/system_error_monitor/system_error_monitor.param.yaml b/launch/tier4_system_launch/config/system_error_monitor/system_error_monitor.param.yaml
index b9de5cc4f2e13..71dc2ac600685 100644
--- a/launch/tier4_system_launch/config/system_error_monitor/system_error_monitor.param.yaml
+++ b/launch/tier4_system_launch/config/system_error_monitor/system_error_monitor.param.yaml
@@ -36,6 +36,7 @@
/autoware/system/node_alive_monitoring: default
/autoware/system/emergency_stop_operation: default
+ /autoware/system/service_log_checker: { sf_at: "warn", lf_at: "none", spf_at: "none" }
/autoware/system/resource_monitoring: { sf_at: "warn", lf_at: "none", spf_at: "none" }
/autoware/vehicle/node_alive_monitoring: default
@@ -46,5 +47,6 @@
/autoware/system/node_alive_monitoring: default
/autoware/system/emergency_stop_operation: default
+ /autoware/system/service_log_checker: { sf_at: "warn", lf_at: "none", spf_at: "none" }
/autoware/vehicle/node_alive_monitoring: default
diff --git a/launch/tier4_system_launch/config/system_error_monitor/system_error_monitor.planning_simulation.param.yaml b/launch/tier4_system_launch/config/system_error_monitor/system_error_monitor.planning_simulation.param.yaml
index bf40c334f6498..9708456df4fe7 100644
--- a/launch/tier4_system_launch/config/system_error_monitor/system_error_monitor.planning_simulation.param.yaml
+++ b/launch/tier4_system_launch/config/system_error_monitor/system_error_monitor.planning_simulation.param.yaml
@@ -36,6 +36,7 @@
/autoware/system/node_alive_monitoring: default
/autoware/system/emergency_stop_operation: default
+ /autoware/system/service_log_checker: { sf_at: "warn", lf_at: "none", spf_at: "none" }
# /autoware/system/resource_monitoring: { sf_at: "warn", lf_at: "error", spf_at: "none" }
/autoware/vehicle/node_alive_monitoring: default
@@ -46,5 +47,6 @@
/autoware/system/node_alive_monitoring: default
/autoware/system/emergency_stop_operation: default
+ /autoware/system/service_log_checker: { sf_at: "warn", lf_at: "none", spf_at: "none" }
/autoware/vehicle/node_alive_monitoring: default
diff --git a/launch/tier4_system_launch/launch/system.launch.xml b/launch/tier4_system_launch/launch/system.launch.xml
index ff3ebae90e847..2400b8b449a6a 100644
--- a/launch/tier4_system_launch/launch/system.launch.xml
+++ b/launch/tier4_system_launch/launch/system.launch.xml
@@ -25,6 +25,11 @@
+
+
+
+
+
diff --git a/localization/pose_initializer/config/pose_initializer.param.yaml b/localization/pose_initializer/config/pose_initializer.param.yaml
index e94f86c8d6c7e..86b0382527201 100644
--- a/localization/pose_initializer/config/pose_initializer.param.yaml
+++ b/localization/pose_initializer/config/pose_initializer.param.yaml
@@ -22,3 +22,7 @@
0.0, 0.0, 0.0, 0.0, 0.01, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.2,
]
+
+ # use partial map loading for large maps
+ # Note: You also need to enable partial_map_loading interface in pointcloud_map_loader to use this functionality
+ enable_partial_map_load: false
diff --git a/localization/pose_initializer/docs/map_height_fitter.md b/localization/pose_initializer/docs/map_height_fitter.md
index ee7fdfb44264d..2715ab7f91ac3 100644
--- a/localization/pose_initializer/docs/map_height_fitter.md
+++ b/localization/pose_initializer/docs/map_height_fitter.md
@@ -7,8 +7,21 @@ Use this service as preprocessing for `pose_initializer` when using a initial po
This service replaces the Z value of the input pose with the lowest point of the map point cloud within a cylinder of XY-radius.
If no point is found in this range, returns the input pose without changes.
+Note that this package supports partial map loading interface, which is disabled by default. The interface is intended to be enabled when
+the pointcloud map is too large to handle. By using the interface, the node will request for a partial map around the requested position
+instead of loading whole map by subscription interface. To use this interface,
+
+1. Set `enable_partial_map_load` in this node to `true`
+2. Set `enable_partial_load` in `pointcloud_map_loader` to `true`
+
## Interfaces
+### Parameters
+
+| Name | Type | Description | |
+| ------------------------- | ---- | ------------------------------------------------------------------------------------- | ----- |
+| `enable_partial_map_load` | bool | If true, use partial map load interface. If false, use topic subscription interaface. | false |
+
### Services
| Name | Type | Description |
@@ -20,3 +33,9 @@ If no point is found in this range, returns the input pose without changes.
| Name | Type | Description |
| --------------------- | ----------------------------- | -------------- |
| `/map/pointcloud_map` | sensor_msgs::msg::PointCloud2 | pointcloud map |
+
+### Clients
+
+| Name | Type | Description |
+| --------------------------------- | ----------------------------------------------- | -------------------------------------------- |
+| `/map/get_partial_pointcloud_map` | autoware_map_msgs::srv::GetPartialPointCloudMap | client for requesting partial pointcloud map |
diff --git a/localization/pose_initializer/launch/pose_initializer.launch.xml b/localization/pose_initializer/launch/pose_initializer.launch.xml
index 732457dfaac54..9a29fdd60fe02 100644
--- a/localization/pose_initializer/launch/pose_initializer.launch.xml
+++ b/localization/pose_initializer/launch/pose_initializer.launch.xml
@@ -5,8 +5,10 @@
-
+
+
+
diff --git a/localization/pose_initializer/package.xml b/localization/pose_initializer/package.xml
index 2f39f74efa09c..48d3a203b8deb 100644
--- a/localization/pose_initializer/package.xml
+++ b/localization/pose_initializer/package.xml
@@ -14,6 +14,7 @@
autoware_cmake
+ autoware_map_msgs
component_interface_specs
component_interface_utils
geometry_msgs
diff --git a/localization/pose_initializer/src/map_height_fitter/map_height_fitter_core.cpp b/localization/pose_initializer/src/map_height_fitter/map_height_fitter_core.cpp
index 0e2bded754f61..44a9360d65d68 100644
--- a/localization/pose_initializer/src/map_height_fitter/map_height_fitter_core.cpp
+++ b/localization/pose_initializer/src/map_height_fitter/map_height_fitter_core.cpp
@@ -23,17 +23,33 @@
#endif
#include
+#include
MapHeightFitter::MapHeightFitter() : Node("map_height_fitter"), tf2_listener_(tf2_buffer_)
{
+ enable_partial_map_load_ = declare_parameter("enable_partial_map_load", false);
+
const auto durable_qos = rclcpp::QoS(1).transient_local();
using std::placeholders::_1;
using std::placeholders::_2;
- sub_map_ = create_subscription(
- "pointcloud_map", durable_qos, std::bind(&MapHeightFitter::on_map, this, _1));
srv_fit_ = create_service(
"fit_map_height", std::bind(&MapHeightFitter::on_fit, this, _1, _2));
+
+ if (!enable_partial_map_load_) {
+ sub_map_ = create_subscription(
+ "pointcloud_map", durable_qos, std::bind(&MapHeightFitter::on_map, this, _1));
+ } else {
+ callback_group_service_ = create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
+ cli_get_partial_pcd_ = create_client(
+ "client_partial_map_load", rmw_qos_profile_default, callback_group_service_);
+ while (!cli_get_partial_pcd_->wait_for_service(std::chrono::seconds(1)) && rclcpp::ok()) {
+ RCLCPP_INFO(
+ this->get_logger(),
+ "Cannot find partial map loading interface. Please check the setting in "
+ "pointcloud_map_loader to see if the interface is enabled.");
+ }
+ }
}
void MapHeightFitter::on_map(const sensor_msgs::msg::PointCloud2::ConstSharedPtr msg)
@@ -72,15 +88,62 @@ double MapHeightFitter::get_ground_height(const tf2::Vector3 & point) const
return std::isfinite(height) ? height : point.getZ();
}
+void MapHeightFitter::get_partial_point_cloud_map(const geometry_msgs::msg::Point & point)
+{
+ if (!cli_get_partial_pcd_) {
+ throw std::runtime_error{"Partial map loading in pointcloud_map_loader is not enabled"};
+ }
+ const auto req = std::make_shared();
+ req->area.center = point;
+ req->area.radius = 50;
+
+ RCLCPP_INFO(this->get_logger(), "Send request to map_loader");
+ auto res{cli_get_partial_pcd_->async_send_request(
+ req, [](rclcpp::Client::SharedFuture) {})};
+
+ std::future_status status = res.wait_for(std::chrono::seconds(0));
+ while (status != std::future_status::ready) {
+ RCLCPP_INFO(this->get_logger(), "waiting response");
+ if (!rclcpp::ok()) {
+ return;
+ }
+ status = res.wait_for(std::chrono::seconds(1));
+ }
+
+ RCLCPP_INFO(
+ this->get_logger(), "Loaded partial pcd map from map_loader (grid size: %d)",
+ static_cast(res.get()->new_pointcloud_with_ids.size()));
+
+ sensor_msgs::msg::PointCloud2 pcd_msg;
+ for (const auto & pcd_with_id : res.get()->new_pointcloud_with_ids) {
+ if (pcd_msg.width == 0) {
+ pcd_msg = pcd_with_id.pointcloud;
+ } else {
+ pcd_msg.width += pcd_with_id.pointcloud.width;
+ pcd_msg.row_step += pcd_with_id.pointcloud.row_step;
+ pcd_msg.data.insert(
+ pcd_msg.data.end(), pcd_with_id.pointcloud.data.begin(), pcd_with_id.pointcloud.data.end());
+ }
+ }
+
+ map_frame_ = res.get()->header.frame_id;
+ map_cloud_ = pcl::PointCloud::Ptr(new pcl::PointCloud);
+ pcl::fromROSMsg(pcd_msg, *map_cloud_);
+}
+
void MapHeightFitter::on_fit(
const RequestHeightFitting::Request::SharedPtr req,
- const RequestHeightFitting::Response::SharedPtr res) const
+ const RequestHeightFitting::Response::SharedPtr res)
{
const auto & position = req->pose_with_covariance.pose.pose.position;
tf2::Vector3 point(position.x, position.y, position.z);
std::string req_frame = req->pose_with_covariance.header.frame_id;
res->success = false;
+ if (enable_partial_map_load_) {
+ get_partial_point_cloud_map(req->pose_with_covariance.pose.pose.position);
+ }
+
if (map_cloud_) {
try {
const auto stamped = tf2_buffer_.lookupTransform(map_frame_, req_frame, tf2::TimePointZero);
diff --git a/localization/pose_initializer/src/map_height_fitter/map_height_fitter_core.hpp b/localization/pose_initializer/src/map_height_fitter/map_height_fitter_core.hpp
index 8845b77a78095..5efa97989b95f 100644
--- a/localization/pose_initializer/src/map_height_fitter/map_height_fitter_core.hpp
+++ b/localization/pose_initializer/src/map_height_fitter/map_height_fitter_core.hpp
@@ -17,6 +17,7 @@
#include
+#include
#include
#include
#include
@@ -40,12 +41,17 @@ class MapHeightFitter : public rclcpp::Node
std::string map_frame_;
pcl::PointCloud::Ptr map_cloud_;
rclcpp::Subscription::SharedPtr sub_map_;
+ rclcpp::Client::SharedPtr cli_get_partial_pcd_;
rclcpp::Service::SharedPtr srv_fit_;
+ bool enable_partial_map_load_;
+ rclcpp::CallbackGroup::SharedPtr callback_group_service_;
+
void on_map(const sensor_msgs::msg::PointCloud2::ConstSharedPtr msg);
+ void get_partial_point_cloud_map(const geometry_msgs::msg::Point & point);
void on_fit(
const RequestHeightFitting::Request::SharedPtr req,
- const RequestHeightFitting::Response::SharedPtr res) const;
+ const RequestHeightFitting::Response::SharedPtr res);
double get_ground_height(const tf2::Vector3 & point) const;
};
diff --git a/localization/pose_initializer/src/map_height_fitter/map_height_fitter_node.cpp b/localization/pose_initializer/src/map_height_fitter/map_height_fitter_node.cpp
index 296a50e0cd3ab..ca4e75671243f 100644
--- a/localization/pose_initializer/src/map_height_fitter/map_height_fitter_node.cpp
+++ b/localization/pose_initializer/src/map_height_fitter/map_height_fitter_node.cpp
@@ -19,7 +19,7 @@
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
- rclcpp::executors::SingleThreadedExecutor executor;
+ rclcpp::executors::MultiThreadedExecutor executor;
auto node = std::make_shared();
executor.add_node(node);
executor.spin();
diff --git a/map/map_loader/CMakeLists.txt b/map/map_loader/CMakeLists.txt
index 6bfcffde71d60..4c3b418239a5c 100644
--- a/map/map_loader/CMakeLists.txt
+++ b/map/map_loader/CMakeLists.txt
@@ -10,6 +10,7 @@ ament_auto_add_library(pointcloud_map_loader_node SHARED
src/pointcloud_map_loader/pointcloud_map_loader_node.cpp
src/pointcloud_map_loader/pointcloud_map_loader_module.cpp
src/pointcloud_map_loader/partial_map_loader_module.cpp
+ src/pointcloud_map_loader/differential_map_loader_module.cpp
src/pointcloud_map_loader/utils.cpp
)
target_link_libraries(pointcloud_map_loader_node ${PCL_LIBRARIES})
diff --git a/map/map_loader/README.md b/map/map_loader/README.md
index 1683fd472e74a..c8f5bed19bb3d 100644
--- a/map/map_loader/README.md
+++ b/map/map_loader/README.md
@@ -12,6 +12,7 @@ Currently, it supports the following two types:
- Publish raw pointcloud map
- Publish downsampled pointcloud map
- Send partial pointcloud map loading via ROS 2 service
+- Send differential pointcloud map loading via ROS 2 service
#### Publish raw pointcloud map (ROS 2 topic)
@@ -28,6 +29,13 @@ Here, we assume that the pointcloud maps are divided into grids.
Given a query from a client node, the node sends a set of pointcloud maps that overlaps with the queried area.
Please see [the description of `GetPartialPointCloudMap.srv`](https://github.com/autowarefoundation/autoware_msgs/tree/main/autoware_map_msgs#getpartialpointcloudmapsrv) for details.
+#### Send differential pointcloud map (ROS 2 service)
+
+Here, we assume that the pointcloud maps are divided into grids.
+
+Given a query and set of map IDs, the node sends a set of pointcloud maps that overlap with the queried area and are not included in the set of map IDs.
+Please see [the description of `GetDifferentialPointCloudMap.srv`](https://github.com/autowarefoundation/autoware_msgs/tree/main/autoware_map_msgs#getdifferentialpointcloudmapsrv) for details.
+
### Parameters
| Name | Type | Description | Default value |
@@ -35,6 +43,7 @@ Please see [the description of `GetPartialPointCloudMap.srv`](https://github.com
| enable_whole_load | bool | A flag to enable raw pointcloud map publishing | true |
| enable_downsampled_whole_load | bool | A flag to enable downsampled pointcloud map publishing | false |
| enable_partial_load | bool | A flag to enable partial pointcloud map server | false |
+| enable_differential_load | bool | A flag to enable differential pointcloud map server | false |
| leaf_size | float | Downsampling leaf size (only used when enable_downsampled_whole_load is set true) | 3.0 |
### Interfaces
@@ -42,6 +51,7 @@ Please see [the description of `GetPartialPointCloudMap.srv`](https://github.com
- `output/pointcloud_map` (sensor_msgs/msg/PointCloud2) : Raw pointcloud map
- `output/debug/downsampled_pointcloud_map` (sensor_msgs/msg/PointCloud2) : Downsampled pointcloud map
- `service/get_partial_pcd_map` (autoware_map_msgs/srv/GetPartialPointCloudMap) : Partial pointcloud map
+- `service/get_differential_pcd_map` (autoware_map_msgs/srv/GetDifferentialPointCloudMap) : Differential pointcloud map
---
diff --git a/map/map_loader/config/pointcloud_map_loader.param.yaml b/map/map_loader/config/pointcloud_map_loader.param.yaml
index fa94afbf12a0b..8f3ccbff00360 100644
--- a/map/map_loader/config/pointcloud_map_loader.param.yaml
+++ b/map/map_loader/config/pointcloud_map_loader.param.yaml
@@ -3,6 +3,7 @@
enable_whole_load: true
enable_downsampled_whole_load: false
enable_partial_load: false
+ enable_differential_load: false
# only used when downsample_whole_load enabled
leaf_size: 3.0 # downsample leaf size [m]
diff --git a/map/map_loader/src/pointcloud_map_loader/differential_map_loader_module.cpp b/map/map_loader/src/pointcloud_map_loader/differential_map_loader_module.cpp
new file mode 100644
index 0000000000000..b42b919edb59d
--- /dev/null
+++ b/map/map_loader/src/pointcloud_map_loader/differential_map_loader_module.cpp
@@ -0,0 +1,85 @@
+// Copyright 2022 The Autoware Contributors
+//
+// 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 "differential_map_loader_module.hpp"
+
+DifferentialMapLoaderModule::DifferentialMapLoaderModule(
+ rclcpp::Node * node, const std::map & pcd_file_metadata_dict)
+: logger_(node->get_logger()), all_pcd_file_metadata_dict_(pcd_file_metadata_dict)
+{
+ get_differential_pcd_maps_service_ = node->create_service(
+ "service/get_differential_pcd_map",
+ std::bind(
+ &DifferentialMapLoaderModule::onServiceGetDifferentialPointCloudMap, this,
+ std::placeholders::_1, std::placeholders::_2));
+}
+
+void DifferentialMapLoaderModule::differentialAreaLoad(
+ const autoware_map_msgs::msg::AreaInfo area, const std::vector & cached_ids,
+ GetDifferentialPointCloudMap::Response::SharedPtr & response) const
+{
+ // iterate over all the available pcd map grids
+ std::vector should_remove(static_cast(cached_ids.size()), true);
+ for (const auto & ele : all_pcd_file_metadata_dict_) {
+ std::string path = ele.first;
+ PCDFileMetadata metadata = ele.second;
+
+ // assume that the map ID = map path (for now)
+ std::string map_id = path;
+
+ // skip if the pcd file is not within the queried area
+ if (!isGridWithinQueriedArea(area, metadata)) continue;
+
+ auto id_in_cached_list = std::find(cached_ids.begin(), cached_ids.end(), map_id);
+ if (id_in_cached_list != cached_ids.end()) {
+ int index = id_in_cached_list - cached_ids.begin();
+ should_remove[index] = false;
+ } else {
+ autoware_map_msgs::msg::PointCloudMapCellWithID pointcloud_map_cell_with_id =
+ loadPointCloudMapCellWithID(path, map_id);
+ response->new_pointcloud_with_ids.push_back(pointcloud_map_cell_with_id);
+ }
+ }
+
+ for (int i = 0; i < static_cast(cached_ids.size()); ++i) {
+ if (should_remove[i]) {
+ response->ids_to_remove.push_back(cached_ids[i]);
+ }
+ }
+}
+
+bool DifferentialMapLoaderModule::onServiceGetDifferentialPointCloudMap(
+ GetDifferentialPointCloudMap::Request::SharedPtr req,
+ GetDifferentialPointCloudMap::Response::SharedPtr res)
+{
+ auto area = req->area;
+ std::vector cached_ids = req->cached_ids;
+ differentialAreaLoad(area, cached_ids, res);
+ res->header.frame_id = "map";
+ return true;
+}
+
+autoware_map_msgs::msg::PointCloudMapCellWithID
+DifferentialMapLoaderModule::loadPointCloudMapCellWithID(
+ const std::string path, const std::string map_id) const
+{
+ sensor_msgs::msg::PointCloud2 pcd;
+ if (pcl::io::loadPCDFile(path, pcd) == -1) {
+ RCLCPP_ERROR_STREAM(logger_, "PCD load failed: " << path);
+ }
+ autoware_map_msgs::msg::PointCloudMapCellWithID pointcloud_map_cell_with_id;
+ pointcloud_map_cell_with_id.pointcloud = pcd;
+ pointcloud_map_cell_with_id.cell_id = map_id;
+ return pointcloud_map_cell_with_id;
+}
diff --git a/map/map_loader/src/pointcloud_map_loader/differential_map_loader_module.hpp b/map/map_loader/src/pointcloud_map_loader/differential_map_loader_module.hpp
new file mode 100644
index 0000000000000..5d6188c0b1a1f
--- /dev/null
+++ b/map/map_loader/src/pointcloud_map_loader/differential_map_loader_module.hpp
@@ -0,0 +1,59 @@
+// Copyright 2022 The Autoware Contributors
+//
+// 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 POINTCLOUD_MAP_LOADER__DIFFERENTIAL_MAP_LOADER_MODULE_HPP_
+#define POINTCLOUD_MAP_LOADER__DIFFERENTIAL_MAP_LOADER_MODULE_HPP_
+
+#include "utils.hpp"
+
+#include
+
+#include "autoware_map_msgs/srv/get_differential_point_cloud_map.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include