diff --git a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/config/traffic_light.param.yaml b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/config/traffic_light.param.yaml index 23746a61b6043..6aac965227efb 100644 --- a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/config/traffic_light.param.yaml +++ b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/config/traffic_light.param.yaml @@ -7,3 +7,9 @@ yellow_lamp_period: 2.75 enable_pass_judge: true enable_rtc: false # If set to true, the scene modules require approval from the rtc (request to cooperate) function. If set to false, the modules can be executed without requiring rtc approval + + v2i: + use_rest_time: false + last_time_allowed_to_pass: 2.0 # relative time against at the time of turn to red + velocity_threshold: 0.5 # change the decision logic whether the current velocity is faster or not + required_time_to_departure: 3.0 # prevent low speed pass diff --git a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/package.xml b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/package.xml index 4bc7a15cddc48..cb0291a793c52 100644 --- a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/package.xml +++ b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/package.xml @@ -31,6 +31,7 @@ autoware_universe_utils eigen geometry_msgs + jpn_signal_v2i_msgs pluginlib rclcpp tf2 diff --git a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/manager.cpp b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/manager.cpp index 9a402f31af0e4..9edfc4c060950 100644 --- a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/manager.cpp +++ b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/manager.cpp @@ -17,14 +17,17 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include namespace autoware::behavior_velocity_planner { using autoware::universe_utils::getOrDeclareParameter; @@ -42,8 +45,22 @@ TrafficLightModuleManager::TrafficLightModuleManager(rclcpp::Node & node) planner_param_.enable_pass_judge = getOrDeclareParameter(node, ns + ".enable_pass_judge"); planner_param_.yellow_lamp_period = getOrDeclareParameter(node, ns + ".yellow_lamp_period"); + planner_param_.v2i_use_rest_time = getOrDeclareParameter(node, ns + ".v2i.use_rest_time"); + planner_param_.v2i_last_time_allowed_to_pass = + getOrDeclareParameter(node, ns + ".v2i.last_time_allowed_to_pass"); + planner_param_.v2i_velocity_threshold = + getOrDeclareParameter(node, ns + ".v2i.velocity_threshold"); + planner_param_.v2i_required_time_to_departure = + getOrDeclareParameter(node, ns + ".v2i.required_time_to_departure"); pub_tl_state_ = node.create_publisher( "~/output/traffic_signal", 1); + + if (planner_param_.v2i_use_rest_time) { + RCLCPP_INFO(logger_, "V2I is enabled"); + v2i_subscriber_ = autoware::universe_utils::InterProcessPollingSubscriber< + jpn_signal_v2i_msgs::msg::TrafficLightInfo>:: + create_subscription(&node, "/v2i/external/v2i_traffic_light_info", 1); + } } void TrafficLightModuleManager::modifyPathVelocity(tier4_planning_msgs::msg::PathWithLaneId * path) @@ -57,6 +74,8 @@ void TrafficLightModuleManager::modifyPathVelocity(tier4_planning_msgs::msg::Pat velocity_factor_array.header.frame_id = "map"; velocity_factor_array.header.stamp = clock_->now(); + if (planner_param_.v2i_use_rest_time) updateV2IRestTimeInfo(); + nearest_ref_stop_path_point_index_ = static_cast(path->points.size() - 1); for (const auto & scene_module : scene_modules_) { std::shared_ptr traffic_light_scene_module( @@ -115,6 +134,9 @@ void TrafficLightModuleManager::launchNewModules( registerModule(std::make_shared( lane_id, *(traffic_light_reg_elem.first), traffic_light_reg_elem.second, planner_param_, logger_.get_child("traffic_light_module"), clock_, time_keeper_, + std::bind( + &TrafficLightModuleManager::getV2IRestTimeToRedSignal, this, + traffic_light_reg_elem.first->id()), planning_factor_interface_)); generateUUID(lane_id); updateRTCStatus( @@ -175,6 +197,37 @@ bool TrafficLightModuleManager::hasSameTrafficLight( return false; } +void TrafficLightModuleManager::updateV2IRestTimeInfo() +{ + if (!v2i_subscriber_) { + return; + } + auto msg = v2i_subscriber_->takeData(); + if (!msg) { + return; + } + + std::vector traffic_light_ids; + traffic_light_id_to_rest_time_map_.clear(); + for (const auto & car_light : msg->car_lights) { + for (const auto & state : car_light.states) { + traffic_light_id_to_rest_time_map_[state.traffic_light_group_id] = + car_light.min_rest_time_to_red; + traffic_light_ids.push_back(state.traffic_light_group_id); + } + } +} + +std::optional TrafficLightModuleManager::getV2IRestTimeToRedSignal( + const lanelet::Id & id) const +{ + const auto rest_time_to_red_signal = traffic_light_id_to_rest_time_map_.find(id); + if (rest_time_to_red_signal == traffic_light_id_to_rest_time_map_.end()) { + return std::nullopt; + } + return rest_time_to_red_signal->second; +} + } // namespace autoware::behavior_velocity_planner #include diff --git a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/manager.hpp b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/manager.hpp index 5ac32d1107880..242fb2f9468aa 100644 --- a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/manager.hpp +++ b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/manager.hpp @@ -20,11 +20,14 @@ #include #include #include +#include #include +#include #include #include +#include #include #include @@ -55,6 +58,15 @@ class TrafficLightModuleManager : public SceneModuleManagerInterfaceWithRTC const lanelet::TrafficLightConstPtr element, const lanelet::TrafficLightConstPtr registered_element) const; + void updateV2IRestTimeInfo(); + + std::optional getV2IRestTimeToRedSignal(const lanelet::Id & id) const; + + // V2I + autoware::universe_utils::InterProcessPollingSubscriber< + jpn_signal_v2i_msgs::msg::TrafficLightInfo>::SharedPtr v2i_subscriber_; + std::map traffic_light_id_to_rest_time_map_; + // Debug rclcpp::Publisher::SharedPtr pub_tl_state_; diff --git a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/scene.cpp b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/scene.cpp index b051d5ff7eb76..dc7363096f770 100644 --- a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/scene.cpp +++ b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/scene.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -26,6 +27,7 @@ #include #include +#include #ifdef ROS_DISTRO_GALACTIC #include @@ -45,6 +47,7 @@ TrafficLightModule::TrafficLightModule( lanelet::ConstLanelet lane, const PlannerParam & planner_param, const rclcpp::Logger logger, const rclcpp::Clock::SharedPtr clock, const std::shared_ptr time_keeper, + const std::function(void)> & get_rest_time_to_red_signal, const std::shared_ptr planning_factor_interface) : SceneModuleInterfaceWithRTC(lane_id, logger, clock, time_keeper, planning_factor_interface), lane_id_(lane_id), @@ -52,7 +55,8 @@ TrafficLightModule::TrafficLightModule( lane_(lane), state_(State::APPROACH), debug_data_(), - is_prev_state_stop_(false) + is_prev_state_stop_(false), + get_rest_time_to_red_signal_(get_rest_time_to_red_signal) { velocity_factor_.init(PlanningBehavior::TRAFFIC_SIGNAL); planner_param_ = planner_param; @@ -107,6 +111,33 @@ bool TrafficLightModule::modifyPathVelocity(PathWithLaneId * path) first_ref_stop_path_point_index_ = stop_line.value().first; + // Use V2I if available + if (planner_param_.v2i_use_rest_time) { + std::optional rest_time_to_red_signal = get_rest_time_to_red_signal_(); + if (rest_time_to_red_signal.has_value()) { + const double rest_time_allowed_to_go_ahead = + rest_time_to_red_signal.value() - planner_param_.v2i_last_time_allowed_to_pass; + const double ego_v = planner_data_->current_velocity->twist.linear.x; + + // Determine whether to stop based on velocity and time constraints + bool should_stop = + (ego_v >= planner_param_.v2i_velocity_threshold && + ego_v * rest_time_allowed_to_go_ahead <= signed_arc_length_to_stop_point) || + (ego_v < planner_param_.v2i_velocity_threshold && + rest_time_allowed_to_go_ahead < planner_param_.v2i_required_time_to_departure); + + // RTC + setSafe(!should_stop); + if (isActivated()) { + return true; + } + *path = insertStopPose(input_path, stop_line.value().first, stop_line.value().second); + return true; + } + RCLCPP_WARN( + logger_, "Failed to get V2I rest time to red signal. traffic_light_lane_id: %ld", lane_id_); + } + // Check if stop is coming. const bool is_stop_signal = isStopSignal(); diff --git a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/scene.hpp b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/scene.hpp index c30cbbdfc1477..69891ffd5a0be 100644 --- a/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/scene.hpp +++ b/planning/behavior_velocity_planner/autoware_behavior_velocity_traffic_light_module/src/scene.hpp @@ -15,6 +15,7 @@ #ifndef SCENE_HPP_ #define SCENE_HPP_ +#include #include #include #include @@ -63,6 +64,11 @@ class TrafficLightModule : public SceneModuleInterfaceWithRTC double yellow_lamp_period; double stop_time_hysteresis; bool enable_pass_judge; + // V2I Parameter + bool v2i_use_rest_time; + double v2i_last_time_allowed_to_pass; + double v2i_velocity_threshold; + double v2i_required_time_to_departure; }; public: @@ -71,6 +77,7 @@ class TrafficLightModule : public SceneModuleInterfaceWithRTC lanelet::ConstLanelet lane, const PlannerParam & planner_param, const rclcpp::Logger logger, const rclcpp::Clock::SharedPtr clock, const std::shared_ptr time_keeper, + const std::function(void)> & get_rest_time_to_red_signal, const std::shared_ptr planning_factor_interface); bool modifyPathVelocity(PathWithLaneId * path) override; @@ -130,6 +137,9 @@ class TrafficLightModule : public SceneModuleInterfaceWithRTC // Traffic Light State TrafficSignal looking_tl_state_; + + // V2I + std::function(void)> get_rest_time_to_red_signal_; }; } // namespace autoware::behavior_velocity_planner