Skip to content

Commit 2385604

Browse files
committed
output diag safety msg
Signed-off-by: Mamoru Sobue <mamoru.sobue@tier4.jp>
1 parent 32cc0cb commit 2385604

10 files changed

+426
-81
lines changed

planning/behavior_velocity_intersection_module/config/intersection.param.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
object_expected_deceleration: 2.0
6060
ignore_on_red_traffic_light:
6161
object_margin_to_path: 2.0
62+
avoid_collision_by_acceleration:
63+
object_time_margin_to_collision_point: 4.0
6264

6365
occlusion:
6466
enable: false

planning/behavior_velocity_intersection_module/package.xml

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,19 @@
2222
<depend>autoware_auto_planning_msgs</depend>
2323
<depend>autoware_perception_msgs</depend>
2424
<depend>behavior_velocity_planner_common</depend>
25+
<depend>fmt</depend>
2526
<depend>geometry_msgs</depend>
2627
<depend>interpolation</depend>
2728
<depend>lanelet2_extension</depend>
2829
<depend>libopencv-dev</depend>
30+
<depend>magic_enum</depend>
2931
<depend>motion_utils</depend>
3032
<depend>nav_msgs</depend>
3133
<depend>pluginlib</depend>
3234
<depend>rclcpp</depend>
3335
<depend>route_handler</depend>
3436
<depend>rtc_interface</depend>
3537
<depend>tf2_geometry_msgs</depend>
36-
<depend>tier4_api_msgs</depend>
3738
<depend>tier4_autoware_utils</depend>
3839
<depend>tier4_planning_msgs</depend>
3940
<depend>vehicle_info_util</depend>

planning/behavior_velocity_intersection_module/src/debug.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ constexpr std::tuple<float, float, float> red()
192192
return {r, g, b};
193193
}
194194

195+
constexpr std::tuple<float, float, float> light_blue()
196+
{
197+
constexpr uint64_t code = 0x96cde6;
198+
constexpr float r = static_cast<int>(code >> 16) / 255.0;
199+
constexpr float g = static_cast<int>((code << 48) >> 56) / 255.0;
200+
constexpr float b = static_cast<int>((code << 56) >> 56) / 255.0;
201+
return {r, g, b};
202+
}
195203
} // namespace
196204

197205
namespace behavior_velocity_planner
@@ -280,6 +288,13 @@ visualization_msgs::msg::MarkerArray IntersectionModule::createDebugMarkerArray(
280288
static constexpr auto green = ::green();
281289
static constexpr auto yellow = ::yellow();
282290
static constexpr auto red = ::red();
291+
static constexpr auto light_blue = ::light_blue();
292+
appendMarkerArray(
293+
debug::createObjectsMarkerArray(
294+
debug_data_.safe_under_traffic_control_targets, "safe_under_traffic_control_targets",
295+
module_id_, now, std::get<0>(light_blue), std::get<1>(light_blue), std::get<2>(light_blue)),
296+
&debug_marker_array, now);
297+
283298
appendMarkerArray(
284299
debug::createObjectsMarkerArray(
285300
debug_data_.unsafe_targets, "unsafe_targets", module_id_, now, std::get<0>(green),

planning/behavior_velocity_intersection_module/src/decision_result.cpp

+11-6
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@ std::string formatDecisionResult(const DecisionResult & decision_result)
2525
if (std::holds_alternative<OverPassJudge>(decision_result)) {
2626
const auto state = std::get<OverPassJudge>(decision_result);
2727
return "OverPassJudge:\nsafety_report:" + state.safety_report + "\nevasive_report:\n" +
28-
state.evasive_report + "\n";
28+
state.evasive_report;
2929
}
3030
if (std::holds_alternative<StuckStop>(decision_result)) {
3131
return "StuckStop";
3232
}
3333
if (std::holds_alternative<YieldStuckStop>(decision_result)) {
34-
return "YieldStuckStop";
34+
const auto state = std::get<YieldStuckStop>(decision_result);
35+
return "YieldStuckStop:\nsafety_report:" + state.safety_report;
3536
}
3637
if (std::holds_alternative<NonOccludedCollisionStop>(decision_result)) {
37-
return "NonOccludedCollisionStop";
38+
const auto state = std::get<NonOccludedCollisionStop>(decision_result);
39+
return "NonOccludedCollisionStop\nsafety_report:" + state.safety_report;
3840
}
3941
if (std::holds_alternative<FirstWaitBeforeOcclusion>(decision_result)) {
4042
return "FirstWaitBeforeOcclusion";
@@ -43,16 +45,19 @@ std::string formatDecisionResult(const DecisionResult & decision_result)
4345
return "PeekingTowardOcclusion";
4446
}
4547
if (std::holds_alternative<OccludedCollisionStop>(decision_result)) {
46-
return "OccludedCollisionStop";
48+
const auto state = std::get<OccludedCollisionStop>(decision_result);
49+
return "OccludedCollisionStop\nsafety_report:" + state.safety_report;
4750
}
4851
if (std::holds_alternative<OccludedAbsenceTrafficLight>(decision_result)) {
49-
return "OccludedAbsenceTrafficLight";
52+
const auto state = std::get<OccludedAbsenceTrafficLight>(decision_result);
53+
return "OccludedAbsenceTrafficLight\nsafety_report:" + state.safety_report;
5054
}
5155
if (std::holds_alternative<Safe>(decision_result)) {
5256
return "Safe";
5357
}
5458
if (std::holds_alternative<FullyPrioritized>(decision_result)) {
55-
return "FullyPrioritized";
59+
const auto state = std::get<FullyPrioritized>(decision_result);
60+
return "FullyPrioritized\nsafety_report:" + state.safety_report;
5661
}
5762
return "";
5863
}

planning/behavior_velocity_intersection_module/src/manager.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ IntersectionModuleManager::IntersectionModuleManager(rclcpp::Node & node)
133133
ip.collision_detection.ignore_on_red_traffic_light.object_margin_to_path =
134134
getOrDeclareParameter<double>(
135135
node, ns + ".collision_detection.ignore_on_red_traffic_light.object_margin_to_path");
136+
ip.collision_detection.avoid_collision_by_acceleration
137+
.object_time_margin_to_collision_point = getOrDeclareParameter<double>(
138+
node,
139+
ns +
140+
".collision_detection.avoid_collision_by_acceleration.object_time_margin_to_collision_point");
136141

137142
ip.occlusion.enable = getOrDeclareParameter<bool>(node, ns + ".occlusion.enable");
138143
ip.occlusion.occlusion_attention_area_length =

planning/behavior_velocity_intersection_module/src/object_manager.cpp

+33-8
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,27 @@ void ObjectInfo::update_safety(
9393
safe_under_traffic_control_ = safe_under_traffic_control;
9494
}
9595

96+
std::optional<geometry_msgs::msg::Point> ObjectInfo::estimated_past_position(
97+
const double past_duration) const
98+
{
99+
if (!attention_lanelet_opt) {
100+
return std::nullopt;
101+
}
102+
const auto attention_lanelet = attention_lanelet_opt.value();
103+
const auto current_arc_coords = lanelet::utils::getArcCoordinates(
104+
{attention_lanelet}, predicted_object_.kinematics.initial_pose_with_covariance.pose);
105+
const auto distance = current_arc_coords.distance;
106+
const auto past_length =
107+
current_arc_coords.length -
108+
predicted_object_.kinematics.initial_twist_with_covariance.twist.linear.x * past_duration;
109+
const auto past_point = lanelet::geometry::fromArcCoordinates(
110+
attention_lanelet.centerline2d(), lanelet::ArcCoordinates{past_length, distance});
111+
geometry_msgs::msg::Point past_position;
112+
past_position.x = past_point.x();
113+
past_position.y = past_point.y();
114+
return std::make_optional(past_position);
115+
}
116+
96117
void ObjectInfo::calc_dist_to_stopline()
97118
{
98119
if (!stopline_opt || !attention_lanelet_opt) {
@@ -233,7 +254,7 @@ std::optional<intersection::CollisionInterval> findPassageInterval(
233254
const autoware_auto_perception_msgs::msg::Shape & shape,
234255
const lanelet::BasicPolygon2d & ego_lane_poly,
235256
const std::optional<lanelet::ConstLanelet> & first_attention_lane_opt,
236-
[[maybe_unused]] const std::optional<lanelet::ConstLanelet> & second_attention_lane_opt)
257+
const std::optional<lanelet::ConstLanelet> & second_attention_lane_opt)
237258
{
238259
const auto first_itr = std::adjacent_find(
239260
predicted_path.path.cbegin(), predicted_path.path.cend(), [&](const auto & a, const auto & b) {
@@ -259,26 +280,30 @@ std::optional<intersection::CollisionInterval> findPassageInterval(
259280
const size_t exit_idx = std::distance(predicted_path.path.begin(), last_itr.base()) - 1;
260281
const double object_exit_time =
261282
static_cast<double>(exit_idx) * rclcpp::Duration(predicted_path.time_step).seconds();
262-
const auto [lane_position, lane_id] =
263-
[&]() -> std::pair<intersection::CollisionInterval::LanePosition, lanelet::Id> {
283+
const auto lane_position = [&]() {
264284
if (first_attention_lane_opt) {
265285
if (lanelet::geometry::inside(
266286
first_attention_lane_opt.value(),
267287
lanelet::BasicPoint2d(first_itr->position.x, first_itr->position.y))) {
268-
return std::make_pair(
269-
intersection::CollisionInterval::LanePosition::FIRST,
270-
first_attention_lane_opt.value().id());
288+
return intersection::CollisionInterval::LanePosition::FIRST;
289+
}
290+
}
291+
if (second_attention_lane_opt) {
292+
if (lanelet::geometry::inside(
293+
second_attention_lane_opt.value(),
294+
lanelet::BasicPoint2d(first_itr->position.x, first_itr->position.y))) {
295+
return intersection::CollisionInterval::LanePosition::SECOND;
271296
}
272297
}
273-
return std::make_pair(intersection::CollisionInterval::LanePosition::ELSE, lanelet::InvalId);
298+
return intersection::CollisionInterval::LanePosition::ELSE;
274299
}();
275300

276301
std::vector<geometry_msgs::msg::Pose> path;
277302
for (const auto & pose : predicted_path.path) {
278303
path.push_back(pose);
279304
}
280305
return intersection::CollisionInterval{
281-
lane_position, lane_id, path, {enter_idx, exit_idx}, {object_enter_time, object_exit_time}};
306+
lane_position, path, {enter_idx, exit_idx}, {object_enter_time, object_exit_time}};
282307
}
283308

284309
} // namespace behavior_velocity_planner::intersection

planning/behavior_velocity_intersection_module/src/object_manager.hpp

+21-26
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <geometry_msgs/msg/pose.hpp>
2222
#include <unique_identifier_msgs/msg/uuid.hpp>
2323

24-
#include <boost/unordered_map.hpp>
24+
#include <boost/functional/hash.hpp>
2525
#include <boost/uuid/uuid.hpp>
2626

2727
#include <lanelet2_core/primitives/Lanelet.h>
@@ -62,10 +62,10 @@ struct CollisionInterval
6262
{
6363
enum LanePosition {
6464
FIRST,
65+
SECOND,
6566
ELSE,
6667
};
6768
LanePosition lane_position{LanePosition::ELSE};
68-
lanelet::Id lane_id{lanelet::InvalId};
6969

7070
//! original predicted path
7171
std::vector<geometry_msgs::msg::Pose> path;
@@ -82,34 +82,18 @@ struct CollisionKnowledge
8282
//! the time when the expected collision is judged
8383
rclcpp::Time stamp;
8484

85-
//! if judged as SAFE/UNSAFE
86-
bool safe{false};
87-
88-
//! if judged as SAFE given traffic control
89-
bool safe_under_traffic_control{false};
85+
enum SafeType {
86+
UNSAFE,
87+
SAFE,
88+
SAFE_UNDER_TRAFFIC_CONTROL,
89+
};
90+
SafeType safe_type{SafeType::UNSAFE};
9091

9192
//! if !safe, this has value, and it safe, this maybe null if the predicted path does not
9293
//! intersect with ego path
9394
std::optional<CollisionInterval> interval{std::nullopt};
9495

9596
double observed_velocity;
96-
/**
97-
* diag format:
98-
* for objects with decision_at_1st_pass_judge_line_passage or
99-
* decision_at_2nd_pass_judge_line_passage:
100-
* [uuid] was detected as [safe] at [stamp] with the
101-
* velocity of [observed_velocity] and the possible collision position was at
102-
* [(path[interval_position.first])] on the Lanelet[interval.lane_id] which was expected to
103-
* happen after [interval_time.first] seconds. Now it is judged as unsafe with the velocity of
104-
* [new observed_velocity] at [(new path[new interval_position.first])] on the Lanelet[new
105-
* interval.lane_id]
106-
* for objects without the above members:
107-
* [uuid] was not detected when ego passed the 1st/2nd pass judge line at
108-
* [manager.passed_1st/2nd_judge_line_first_time], so collision detection was impossible at that
109-
* time. but now collision is expected on the 1st/2nd attention lanelet. This dangerous situation
110-
* is because at time [manager.passed_1st/2nd_judge_line_first_time] ego could not detect [uuid]
111-
* which was estimated to be xxx meter behind from yyy position
112-
*/
11397
};
11498

11599
/**
@@ -136,6 +120,8 @@ class ObjectInfo
136120
return unsafe_interval_;
137121
}
138122

123+
bool is_safe_under_traffic_control() const { return safe_under_traffic_control_; }
124+
139125
/**
140126
* @brief update predicted_object_, attention_lanelet, stopline, dist_to_stopline
141127
*/
@@ -155,7 +141,8 @@ class ObjectInfo
155141
/**
156142
* @brief find the estimated position of the object in the past
157143
*/
158-
geometry_msgs::msg::Pose estimated_past_pose(const double past_duration) const;
144+
std::optional<geometry_msgs::msg::Point> estimated_past_position(
145+
const double past_duration) const;
159146

160147
/**
161148
* @brief check if object can stop before stopline under the deceleration. return false if
@@ -186,6 +173,13 @@ class ObjectInfo
186173
decision_at_2nd_pass_judge_line_passage_ = knowledge;
187174
}
188175

176+
const std::optional<CollisionInterval> & unsafe_interval() const { return unsafe_interval_; }
177+
178+
double observed_velocity() const
179+
{
180+
return predicted_object_.kinematics.initial_twist_with_covariance.twist.linear.x;
181+
}
182+
189183
const std::optional<CollisionKnowledge> & decision_at_1st_pass_judge_line_passage() const
190184
{
191185
return decision_at_1st_pass_judge_line_passage_;
@@ -196,8 +190,9 @@ class ObjectInfo
196190
return decision_at_2nd_pass_judge_line_passage_;
197191
}
198192

199-
private:
200193
const std::string uuid_str;
194+
195+
private:
201196
autoware_auto_perception_msgs::msg::PredictedObject predicted_object_;
202197

203198
//! null if the object in intersection_area but not in attention_area

planning/behavior_velocity_intersection_module/src/scene_intersection.cpp

+21-8
Original file line numberDiff line numberDiff line change
@@ -218,29 +218,42 @@ intersection::DecisionResult IntersectionModule::modifyPathVelocityDetail(
218218

219219
// ==========================================================================================
220220
// run collision checking for each objects considering traffic light level. Also if ego just
221-
// passed each pass judge line for the first time, save current collision status.
221+
// passed each pass judge line for the first time, save current collision status for late
222+
// diagnosis
222223
// ==========================================================================================
223224
updateObjectInfoManagerCollision(
224225
path_lanelets, time_distance_array, traffic_prioritized_level, safely_passed_1st_judge_line,
225226
safely_passed_2nd_judge_line);
226227

227-
const auto [has_collision, collision_position] =
228+
const auto [has_collision, collision_position, too_late_detect_objects, misjudge_objects] =
228229
detectCollision(is_over_1st_pass_judge_line, is_over_2nd_pass_judge_line);
230+
const std::string safety_diag =
231+
generateDetectionBlameDiagnosis(too_late_detect_objects, misjudge_objects);
229232
if (is_permanent_go_) {
230233
if (has_collision) {
231-
return intersection::OverPassJudge{"TODO", "ego needs acceleration to keep safe"};
234+
const auto closest_idx = intersection_stoplines.closest_idx;
235+
const std::string evasive_diag = generateEgoRiskEvasiveDiagnosis(
236+
*path, closest_idx, time_distance_array, too_late_detect_objects, misjudge_objects);
237+
return intersection::OverPassJudge{safety_diag, evasive_diag};
232238
}
233239
return intersection::OverPassJudge{
234240
"no collision is detected", "ego can safely pass the intersection at this rate"};
235241
}
236242

237-
std::string safety_report{""};
238243
const bool collision_on_1st_attention_lane =
239-
has_collision && collision_position == intersection::CollisionInterval::LanePosition::FIRST;
244+
has_collision && (collision_position == intersection::CollisionInterval::LanePosition::FIRST);
245+
// ==========================================================================================
246+
// this state is very dangerous because ego is very close/over the boundary of 1st attention lane
247+
// and collision is detected on the 1st lane. Since the 2nd attention lane also exists in this
248+
// case, possible another collision may be expected on the 2nd attention lane too.
249+
// ==========================================================================================
250+
std::string safety_report = safety_diag;
240251
if (
241252
is_over_1st_pass_judge_line && is_over_2nd_pass_judge_line &&
242253
is_over_2nd_pass_judge_line.value() && collision_on_1st_attention_lane) {
243-
safety_report = "TODO";
254+
safety_report +=
255+
"\nego is between the 1st and 2nd pass judge line but collision is expected on the 1st "
256+
"attention lane, which is dangerous.";
244257
}
245258

246259
const auto closest_idx = intersection_stoplines.closest_idx;
@@ -1244,7 +1257,7 @@ IntersectionModule::PassJudgeStatus IntersectionModule::isOverPassJudgeLinesStat
12441257
util::isOverTargetIndex(path, closest_idx, current_pose, pass_judge_line_idx);
12451258
bool safely_passed_1st_judge_line_first_time = false;
12461259
if (is_over_1st_pass_judge_line && was_safe && !safely_passed_1st_judge_line_time_) {
1247-
safely_passed_1st_judge_line_time_ = clock_->now();
1260+
safely_passed_1st_judge_line_time_ = std::make_pair(clock_->now(), current_pose);
12481261
safely_passed_1st_judge_line_first_time = true;
12491262
}
12501263
const double baselink2front = planner_data_->vehicle_info_.max_longitudinal_offset_m;
@@ -1261,7 +1274,7 @@ IntersectionModule::PassJudgeStatus IntersectionModule::isOverPassJudgeLinesStat
12611274
if (
12621275
is_over_2nd_pass_judge_line && is_over_2nd_pass_judge_line.value() && was_safe &&
12631276
!safely_passed_2nd_judge_line_time_) {
1264-
safely_passed_2nd_judge_line_time_ = clock_->now();
1277+
safely_passed_2nd_judge_line_time_ = std::make_pair(clock_->now(), current_pose);
12651278
safely_passed_2nd_judge_line_first_time = true;
12661279
}
12671280
if (second_pass_judge_line_idx_opt) {

0 commit comments

Comments
 (0)