From 01a80587736606125a728129709163f0ff437290 Mon Sep 17 00:00:00 2001 From: danielsanchezaran Date: Tue, 2 Jul 2024 15:58:24 +0900 Subject: [PATCH] feat(planning_evaluator): add lanelet info to the planning evaluator (#7781) add lanelet info to the planning evaluator Signed-off-by: Daniel Sanchez --- .../planning_evaluator_node.hpp | 29 +++++ .../launch/planning_evaluator.launch.xml | 6 + .../autoware_planning_evaluator/package.xml | 1 + .../src/planning_evaluator_node.cpp | 115 ++++++++++++++++++ 4 files changed, 151 insertions(+) diff --git a/evaluator/autoware_planning_evaluator/include/autoware/planning_evaluator/planning_evaluator_node.hpp b/evaluator/autoware_planning_evaluator/include/autoware/planning_evaluator/planning_evaluator_node.hpp index 0121425c15d1d..74523398c3a77 100644 --- a/evaluator/autoware_planning_evaluator/include/autoware/planning_evaluator/planning_evaluator_node.hpp +++ b/evaluator/autoware_planning_evaluator/include/autoware/planning_evaluator/planning_evaluator_node.hpp @@ -21,12 +21,17 @@ #include "tf2_ros/buffer.h" #include "tf2_ros/transform_listener.h" +#include +#include + #include "autoware_perception_msgs/msg/predicted_objects.hpp" #include "autoware_planning_msgs/msg/pose_with_uuid_stamped.hpp" #include "autoware_planning_msgs/msg/trajectory.hpp" #include "autoware_planning_msgs/msg/trajectory_point.hpp" #include "diagnostic_msgs/msg/diagnostic_array.hpp" +#include "geometry_msgs/msg/accel_with_covariance_stamped.hpp" #include "nav_msgs/msg/odometry.hpp" +#include #include #include @@ -43,6 +48,9 @@ using autoware_planning_msgs::msg::TrajectoryPoint; using diagnostic_msgs::msg::DiagnosticArray; using diagnostic_msgs::msg::DiagnosticStatus; using nav_msgs::msg::Odometry; +using LaneletMapBin = autoware_map_msgs::msg::LaneletMapBin; +using autoware_planning_msgs::msg::LaneletRoute; +using geometry_msgs::msg::AccelWithCovarianceStamped; /** * @brief Node for planning evaluation */ @@ -88,9 +96,22 @@ class PlanningEvaluatorNode : public rclcpp::Node DiagnosticStatus generateDiagnosticStatus( const Metric & metric, const Stat & metric_stat) const; + /** + * @brief publish current ego lane info + */ + DiagnosticStatus generateLaneletDiagnosticStatus(); + + /** + * @brief publish current ego kinematic state + */ + DiagnosticStatus generateKinematicStateDiagnosticStatus( + const AccelWithCovarianceStamped & accel_stamped); + private: static bool isFinite(const TrajectoryPoint & p); void publishModifiedGoalDeviationMetrics(); + // update Route Handler + void getRouteData(); // ROS rclcpp::Subscription::SharedPtr traj_sub_; @@ -98,10 +119,17 @@ class PlanningEvaluatorNode : public rclcpp::Node rclcpp::Subscription::SharedPtr objects_sub_; rclcpp::Subscription::SharedPtr modified_goal_sub_; rclcpp::Subscription::SharedPtr odom_sub_; + autoware::universe_utils::InterProcessPollingSubscriber route_subscriber_{ + this, "~/input/route", rclcpp::QoS{1}.transient_local()}; + autoware::universe_utils::InterProcessPollingSubscriber vector_map_subscriber_{ + this, "~/input/vector_map", rclcpp::QoS{1}.transient_local()}; + autoware::universe_utils::InterProcessPollingSubscriber accel_sub_{ + this, "~/input/acceleration"}; rclcpp::Publisher::SharedPtr metrics_pub_; std::shared_ptr transform_listener_{nullptr}; std::unique_ptr tf_buffer_; + autoware::route_handler::RouteHandler route_handler_; // Parameters std::string output_file_str_; @@ -116,6 +144,7 @@ class PlanningEvaluatorNode : public rclcpp::Node Odometry::ConstSharedPtr ego_state_ptr_; PoseWithUuidStamped::ConstSharedPtr modified_goal_ptr_; + std::optional prev_acc_stamped_{std::nullopt}; }; } // namespace planning_diagnostics diff --git a/evaluator/autoware_planning_evaluator/launch/planning_evaluator.launch.xml b/evaluator/autoware_planning_evaluator/launch/planning_evaluator.launch.xml index 2e358f6272379..70301ebe6275f 100644 --- a/evaluator/autoware_planning_evaluator/launch/planning_evaluator.launch.xml +++ b/evaluator/autoware_planning_evaluator/launch/planning_evaluator.launch.xml @@ -1,19 +1,25 @@ + + + + + + diff --git a/evaluator/autoware_planning_evaluator/package.xml b/evaluator/autoware_planning_evaluator/package.xml index 5bd500f200eac..3c3d4bd8bb595 100644 --- a/evaluator/autoware_planning_evaluator/package.xml +++ b/evaluator/autoware_planning_evaluator/package.xml @@ -16,6 +16,7 @@ autoware_motion_utils autoware_perception_msgs autoware_planning_msgs + autoware_route_handler autoware_universe_utils diagnostic_msgs eigen diff --git a/evaluator/autoware_planning_evaluator/src/planning_evaluator_node.cpp b/evaluator/autoware_planning_evaluator/src/planning_evaluator_node.cpp index 103e14c73f26d..5e959aed123af 100644 --- a/evaluator/autoware_planning_evaluator/src/planning_evaluator_node.cpp +++ b/evaluator/autoware_planning_evaluator/src/planning_evaluator_node.cpp @@ -14,6 +14,11 @@ #include "autoware/planning_evaluator/planning_evaluator_node.hpp" +#include +#include + +#include + #include "boost/lexical_cast.hpp" #include @@ -105,6 +110,97 @@ PlanningEvaluatorNode::~PlanningEvaluatorNode() } } +void PlanningEvaluatorNode::getRouteData() +{ + // route + { + const auto msg = route_subscriber_.takeNewData(); + if (msg) { + if (msg->segments.empty()) { + RCLCPP_ERROR(get_logger(), "input route is empty. ignored"); + } else { + route_handler_.setRoute(*msg); + } + } + } + + // map + { + const auto msg = vector_map_subscriber_.takeNewData(); + if (msg) { + route_handler_.setMap(*msg); + } + } +} + +DiagnosticStatus PlanningEvaluatorNode::generateLaneletDiagnosticStatus() +{ + const auto & ego_pose = ego_state_ptr_->pose.pose; + const auto current_lanelets = [&]() { + lanelet::ConstLanelet closest_route_lanelet; + route_handler_.getClosestLaneletWithinRoute(ego_pose, &closest_route_lanelet); + const auto shoulder_lanelets = route_handler_.getShoulderLaneletsAtPose(ego_pose); + lanelet::ConstLanelets closest_lanelets{closest_route_lanelet}; + closest_lanelets.insert( + closest_lanelets.end(), shoulder_lanelets.begin(), shoulder_lanelets.end()); + return closest_lanelets; + }(); + const auto arc_coordinates = lanelet::utils::getArcCoordinates(current_lanelets, ego_pose); + lanelet::ConstLanelet current_lane; + lanelet::utils::query::getClosestLanelet(current_lanelets, ego_pose, ¤t_lane); + + DiagnosticStatus status; + status.name = "ego_lane_info"; + status.level = status.OK; + diagnostic_msgs::msg::KeyValue key_value; + key_value.key = "lane_id"; + key_value.value = std::to_string(current_lane.id()); + status.values.push_back(key_value); + key_value.key = "s"; + key_value.value = std::to_string(arc_coordinates.length); + status.values.push_back(key_value); + key_value.key = "t"; + key_value.value = std::to_string(arc_coordinates.distance); + status.values.push_back(key_value); + return status; +} + +DiagnosticStatus PlanningEvaluatorNode::generateKinematicStateDiagnosticStatus( + const AccelWithCovarianceStamped & accel_stamped) +{ + DiagnosticStatus status; + status.name = "kinematic_state"; + status.level = status.OK; + diagnostic_msgs::msg::KeyValue key_value; + key_value.key = "vel"; + key_value.value = std::to_string(ego_state_ptr_->twist.twist.linear.x); + status.values.push_back(key_value); + key_value.key = "acc"; + const auto & acc = accel_stamped.accel.accel.linear.x; + key_value.value = std::to_string(acc); + status.values.push_back(key_value); + key_value.key = "jerk"; + const auto jerk = [&]() { + if (!prev_acc_stamped_.has_value()) { + prev_acc_stamped_ = accel_stamped; + return 0.0; + } + const auto t = static_cast(accel_stamped.header.stamp.sec) + + static_cast(accel_stamped.header.stamp.nanosec) * 1e-9; + const auto prev_t = static_cast(prev_acc_stamped_.value().header.stamp.sec) + + static_cast(prev_acc_stamped_.value().header.stamp.nanosec) * 1e-9; + const auto dt = t - prev_t; + if (dt < std::numeric_limits::epsilon()) return 0.0; + + const auto prev_acc = prev_acc_stamped_.value().accel.accel.linear.x; + prev_acc_stamped_ = accel_stamped; + return (acc - prev_acc) / dt; + }(); + key_value.value = std::to_string(jerk); + status.values.push_back(key_value); + return status; +} + DiagnosticStatus PlanningEvaluatorNode::generateDiagnosticStatus( const Metric & metric, const Stat & metric_stat) const { @@ -172,6 +268,25 @@ void PlanningEvaluatorNode::onOdometry(const Odometry::ConstSharedPtr odometry_m { ego_state_ptr_ = odometry_msg; metrics_calculator_.setEgoPose(odometry_msg->pose.pose); + { + DiagnosticArray metrics_msg; + metrics_msg.header.stamp = now(); + + getRouteData(); + if (route_handler_.isHandlerReady() && ego_state_ptr_) { + metrics_msg.status.push_back(generateLaneletDiagnosticStatus()); + } + + const auto acc = accel_sub_.takeData(); + + if (acc && ego_state_ptr_) { + metrics_msg.status.push_back(generateKinematicStateDiagnosticStatus(*acc)); + } + + if (!metrics_msg.status.empty()) { + metrics_pub_->publish(metrics_msg); + } + } if (modified_goal_ptr_) { publishModifiedGoalDeviationMetrics();