Skip to content

Commit ca832ea

Browse files
committed
feat(behavior_velocity): add the option to keep the last valid observation (autowarefoundation#6036)
* feat(behavior_velocity): add the option to keep the last valid observation Signed-off-by: Mamoru Sobue <mamoru.sobue@tier4.jp> * keep_last_observation is false by default and intersection/traffic_light is explicily true Signed-off-by: Mamoru Sobue <mamoru.sobue@tier4.jp> * for intersection Signed-off-by: Mamoru Sobue <mamoru.sobue@tier4.jp> --------- Signed-off-by: Mamoru Sobue <mamoru.sobue@tier4.jp>
1 parent 6135260 commit ca832ea

File tree

6 files changed

+60
-32
lines changed

6 files changed

+60
-32
lines changed

planning/behavior_velocity_crosswalk_module/src/scene_crosswalk.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -1035,19 +1035,20 @@ bool CrosswalkModule::isRedSignalForPedestrians() const
10351035
crosswalk_.regulatoryElementsAs<const lanelet::TrafficLight>();
10361036

10371037
for (const auto & traffic_lights_reg_elem : traffic_lights_reg_elems) {
1038-
const auto traffic_signal_stamped =
1038+
const auto traffic_signal_stamped_opt =
10391039
planner_data_->getTrafficSignal(traffic_lights_reg_elem->id());
1040-
if (!traffic_signal_stamped) {
1040+
if (!traffic_signal_stamped_opt) {
10411041
continue;
10421042
}
1043+
const auto traffic_signal_stamped = traffic_signal_stamped_opt.value();
10431044

10441045
if (
10451046
planner_param_.traffic_light_state_timeout <
1046-
(clock_->now() - traffic_signal_stamped->stamp).seconds()) {
1047+
(clock_->now() - traffic_signal_stamped.stamp).seconds()) {
10471048
continue;
10481049
}
10491050

1050-
const auto & lights = traffic_signal_stamped->signal.elements;
1051+
const auto & lights = traffic_signal_stamped.signal.elements;
10511052
if (lights.empty()) {
10521053
continue;
10531054
}

planning/behavior_velocity_intersection_module/src/scene_intersection.cpp

+14-17
Original file line numberDiff line numberDiff line change
@@ -940,12 +940,11 @@ bool IntersectionModule::modifyPathVelocity(PathWithLaneId * path, StopReason *
940940
return true;
941941
}
942942

943-
static bool isGreenSolidOn(
944-
lanelet::ConstLanelet lane, const std::map<int, TrafficSignalStamped> & tl_infos)
943+
bool IntersectionModule::isGreenSolidOn(lanelet::ConstLanelet lane)
945944
{
946945
using TrafficSignalElement = autoware_perception_msgs::msg::TrafficSignalElement;
947946

948-
std::optional<int> tl_id = std::nullopt;
947+
std::optional<lanelet::Id> tl_id = std::nullopt;
949948
for (auto && tl_reg_elem : lane.regulatoryElementsAs<lanelet::TrafficLight>()) {
950949
tl_id = tl_reg_elem->id();
951950
break;
@@ -954,12 +953,13 @@ static bool isGreenSolidOn(
954953
// this lane has no traffic light
955954
return false;
956955
}
957-
const auto tl_info_it = tl_infos.find(tl_id.value());
958-
if (tl_info_it == tl_infos.end()) {
956+
const auto tl_info_opt = planner_data_->getTrafficSignal(
957+
tl_id.value(), true /* traffic light module keeps last observation*/);
958+
if (!tl_info_opt) {
959959
// the info of this traffic light is not available
960960
return false;
961961
}
962-
const auto & tl_info = tl_info_it->second;
962+
const auto & tl_info = tl_info_opt.value();
963963
for (auto && tl_light : tl_info.signal.elements) {
964964
if (
965965
tl_light.color == TrafficSignalElement::GREEN &&
@@ -1004,8 +1004,7 @@ IntersectionModule::DecisionResult IntersectionModule::modifyPathVelocityDetail(
10041004

10051005
// at the very first time of regisTration of this module, the path may not be conflicting with the
10061006
// attention area, so update() is called to update the internal data as well as traffic light info
1007-
const auto traffic_prioritized_level =
1008-
getTrafficPrioritizedLevel(assigned_lanelet, planner_data_->traffic_light_id_map);
1007+
const auto traffic_prioritized_level = getTrafficPrioritizedLevel(assigned_lanelet);
10091008
const bool is_prioritized =
10101009
traffic_prioritized_level == TrafficPrioritizedLevel::FULLY_PRIORITIZED;
10111010
intersection_lanelets.update(
@@ -1300,8 +1299,7 @@ IntersectionModule::DecisionResult IntersectionModule::modifyPathVelocityDetail(
13001299
// If there are any vehicles on the attention area when ego entered the intersection on green
13011300
// light, do pseudo collision detection because the vehicles are very slow and no collisions may
13021301
// be detected. check if ego vehicle entered assigned lanelet
1303-
const bool is_green_solid_on =
1304-
isGreenSolidOn(assigned_lanelet, planner_data_->traffic_light_id_map);
1302+
const bool is_green_solid_on = isGreenSolidOn(assigned_lanelet);
13051303
if (is_green_solid_on) {
13061304
if (!initial_green_light_observed_time_) {
13071305
const auto assigned_lane_begin_point = assigned_lanelet.centerline().front();
@@ -1458,12 +1456,11 @@ IntersectionModule::DecisionResult IntersectionModule::modifyPathVelocityDetail(
14581456
}
14591457
}
14601458

1461-
TrafficPrioritizedLevel IntersectionModule::getTrafficPrioritizedLevel(
1462-
lanelet::ConstLanelet lane, const std::map<int, TrafficSignalStamped> & tl_infos)
1459+
TrafficPrioritizedLevel IntersectionModule::getTrafficPrioritizedLevel(lanelet::ConstLanelet lane)
14631460
{
14641461
using TrafficSignalElement = autoware_perception_msgs::msg::TrafficSignalElement;
14651462

1466-
std::optional<int> tl_id = std::nullopt;
1463+
std::optional<lanelet::Id> tl_id = std::nullopt;
14671464
for (auto && tl_reg_elem : lane.regulatoryElementsAs<lanelet::TrafficLight>()) {
14681465
tl_id = tl_reg_elem->id();
14691466
break;
@@ -1472,12 +1469,12 @@ TrafficPrioritizedLevel IntersectionModule::getTrafficPrioritizedLevel(
14721469
// this lane has no traffic light
14731470
return TrafficPrioritizedLevel::NOT_PRIORITIZED;
14741471
}
1475-
const auto tl_info_it = tl_infos.find(tl_id.value());
1476-
if (tl_info_it == tl_infos.end()) {
1477-
// the info of this traffic light is not available
1472+
const auto tl_info_opt = planner_data_->getTrafficSignal(
1473+
tl_id.value(), true /* traffic light module keeps last observation*/);
1474+
if (!tl_info_opt) {
14781475
return TrafficPrioritizedLevel::NOT_PRIORITIZED;
14791476
}
1480-
const auto & tl_info = tl_info_it->second;
1477+
const auto & tl_info = tl_info_opt.value();
14811478
bool has_amber_signal{false};
14821479
for (auto && tl_light : tl_info.signal.elements) {
14831480
if (tl_light.color == TrafficSignalElement::AMBER) {

planning/behavior_velocity_intersection_module/src/scene_intersection.hpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,7 @@ class IntersectionModule : public SceneModuleInterface
668668
* @fn
669669
* @brief find TrafficPrioritizedLevel
670670
*/
671-
TrafficPrioritizedLevel getTrafficPrioritizedLevel(
672-
lanelet::ConstLanelet lane, const std::map<int, TrafficSignalStamped> & tl_infos);
671+
TrafficPrioritizedLevel getTrafficPrioritizedLevel(lanelet::ConstLanelet lane);
673672

674673
/**
675674
* @fn
@@ -776,6 +775,12 @@ class IntersectionModule : public SceneModuleInterface
776775
const std::vector<lanelet::ConstLineString3d> & lane_divisions,
777776
const TargetObjects & target_objects);
778777

778+
/*
779+
* @fn
780+
* @brief check if associated traffic light is green
781+
*/
782+
bool isGreenSolidOn(lanelet::ConstLanelet lane);
783+
779784
/*
780785
bool IntersectionModule::checkFrontVehicleDeceleration(
781786
lanelet::ConstLanelets & ego_lane_with_next_lane, lanelet::ConstLanelet & closest_lanelet,

planning/behavior_velocity_planner/src/node.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,21 @@ void BehaviorVelocityPlannerNode::onTrafficSignals(
334334
TrafficSignalStamped traffic_signal;
335335
traffic_signal.stamp = msg->stamp;
336336
traffic_signal.signal = signal;
337-
planner_data_.traffic_light_id_map[signal.traffic_signal_id] = traffic_signal;
337+
planner_data_.traffic_light_id_map_raw_[signal.traffic_signal_id] = traffic_signal;
338+
const bool is_unknown_observation =
339+
std::any_of(signal.elements.begin(), signal.elements.end(), [](const auto & element) {
340+
return element.color == autoware_perception_msgs::msg::TrafficSignalElement::UNKNOWN;
341+
});
342+
// if the observation is UNKNOWN and past observation is available, only update the timestamp
343+
// and keep the body of the info
344+
if (
345+
is_unknown_observation &&
346+
planner_data_.traffic_light_id_map_last_observed_.count(signal.traffic_signal_id) == 1) {
347+
planner_data_.traffic_light_id_map_last_observed_[signal.traffic_signal_id].stamp =
348+
msg->stamp;
349+
} else {
350+
planner_data_.traffic_light_id_map_last_observed_[signal.traffic_signal_id] = traffic_signal;
351+
}
338352
}
339353
}
340354

planning/behavior_velocity_planner_common/include/behavior_velocity_planner_common/planner_data.hpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ struct PlannerData
7777
double ego_nearest_yaw_threshold;
7878

7979
// other internal data
80-
std::map<int, TrafficSignalStamped> traffic_light_id_map;
80+
// traffic_light_id_map_raw is the raw observation, while traffic_light_id_map_keep_last keeps the
81+
// last observed infomation for UNKNOWN
82+
std::map<lanelet::Id, TrafficSignalStamped> traffic_light_id_map_raw_;
83+
std::map<lanelet::Id, TrafficSignalStamped> traffic_light_id_map_last_observed_;
8184
std::optional<tier4_planning_msgs::msg::VelocityLimit> external_velocity_limit;
8285
std::map<int, TrafficSignalTimeToRedStamped> traffic_light_time_to_red_id_map;
8386
tier4_v2x_msgs::msg::VirtualTrafficLightStateArray::ConstSharedPtr virtual_traffic_light_states;
@@ -131,12 +134,20 @@ struct PlannerData
131134
return true;
132135
}
133136

134-
std::shared_ptr<TrafficSignalStamped> getTrafficSignal(const int id) const
137+
/**
138+
*@fn
139+
*@brief queries the traffic signal information of given Id. if keep_last_observation = true,
140+
*recent UNKNOWN observation is overwritten as the last non-UNKNOWN observation
141+
*/
142+
std::optional<TrafficSignalStamped> getTrafficSignal(
143+
const lanelet::Id id, const bool keep_last_observation = false) const
135144
{
145+
const auto & traffic_light_id_map =
146+
keep_last_observation ? traffic_light_id_map_last_observed_ : traffic_light_id_map_raw_;
136147
if (traffic_light_id_map.count(id) == 0) {
137-
return {};
148+
return std::nullopt;
138149
}
139-
return std::make_shared<TrafficSignalStamped>(traffic_light_id_map.at(id));
150+
return std::make_optional<TrafficSignalStamped>(traffic_light_id_map.at(id));
140151
}
141152

142153
std::optional<TrafficSignalTimeToRedStamped> getRestTimeToRedSignal(const int id) const

planning/behavior_velocity_traffic_light_module/src/scene.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -413,15 +413,15 @@ bool TrafficLightModule::isTrafficSignalStop(
413413
bool TrafficLightModule::findValidTrafficSignal(TrafficSignalStamped & valid_traffic_signal) const
414414
{
415415
// get traffic signal associated with the regulatory element id
416-
const auto traffic_signal_stamped = planner_data_->getTrafficSignal(traffic_light_reg_elem_.id());
417-
if (!traffic_signal_stamped) {
416+
const auto traffic_signal_stamped_opt = planner_data_->getTrafficSignal(
417+
traffic_light_reg_elem_.id(), true /* traffic light module keeps last observation */);
418+
if (!traffic_signal_stamped_opt) {
418419
RCLCPP_WARN_THROTTLE(
419420
logger_, *clock_, 5000 /* ms */,
420421
"the traffic signal data associated with regulatory element id is not received");
421422
return false;
422423
}
423-
424-
valid_traffic_signal = *traffic_signal_stamped;
424+
valid_traffic_signal = traffic_signal_stamped_opt.value();
425425
return true;
426426
}
427427

0 commit comments

Comments
 (0)