Skip to content

Commit d7cfc72

Browse files
committed
feat(planning_data_analyzer): add human filter and synthetic epdms
1 parent 98259e3 commit d7cfc72

7 files changed

Lines changed: 768 additions & 0 deletions

File tree

planning/autoware_planning_data_analyzer/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ ament_auto_add_library(${PROJECT_NAME} SHARED
1111
src/or_event_extractor.cpp
1212
src/or_scene_evaluator.cpp
1313
src/metrics/deviation_metrics.cpp
14+
src/metrics/epdms_aggregation.cpp
1415
src/metrics/ego_progress.cpp
1516
src/metrics/driving_direction_compliance.cpp
1617
src/metrics/history_comfort.cpp
@@ -39,6 +40,7 @@ if(BUILD_TESTING)
3940
test_metrics
4041
test/metrics/test_deviation_metrics.cpp
4142
test/metrics/test_driving_direction_compliance.cpp
43+
test/metrics/test_epdms_aggregation.cpp
4244
test/metrics/test_lane_keeping.cpp
4345
test/metrics/test_ego_progress.cpp
4446
test/metrics/test_drivable_area_compliance.cpp
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// Copyright 2026 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "epdms_aggregation.hpp"
16+
17+
#include <cmath>
18+
19+
namespace autoware::planning_data_analyzer::metrics
20+
{
21+
22+
namespace
23+
{
24+
25+
constexpr double kHumanFilterZeroEpsilon = 1.0e-9;
26+
27+
double apply_human_filter(
28+
const double agent_value, const bool agent_available, const double human_value,
29+
const bool human_available, bool & applied)
30+
{
31+
applied = agent_available && human_available && std::abs(human_value) <= kHumanFilterZeroEpsilon;
32+
return applied ? 1.0 : agent_value;
33+
}
34+
35+
} // namespace
36+
37+
HumanFilterMetrics calculate_human_filter_metrics(
38+
const EpdmsMetricSnapshot & agent_metrics, const EpdmsMetricSnapshot & human_metrics)
39+
{
40+
HumanFilterMetrics result;
41+
42+
result.human_history_comfort = human_metrics.history_comfort;
43+
result.human_history_comfort_available = human_metrics.history_comfort_available;
44+
result.filtered_history_comfort = apply_human_filter(
45+
agent_metrics.history_comfort, agent_metrics.history_comfort_available,
46+
human_metrics.history_comfort, human_metrics.history_comfort_available,
47+
result.history_comfort_filter_applied);
48+
49+
result.human_extended_comfort = human_metrics.extended_comfort;
50+
result.human_extended_comfort_available = human_metrics.extended_comfort_available;
51+
result.filtered_extended_comfort = apply_human_filter(
52+
agent_metrics.extended_comfort, agent_metrics.extended_comfort_available,
53+
human_metrics.extended_comfort, human_metrics.extended_comfort_available,
54+
result.extended_comfort_filter_applied);
55+
56+
result.human_ego_progress = human_metrics.ego_progress;
57+
result.human_ego_progress_available = human_metrics.ego_progress_available;
58+
result.filtered_ego_progress = apply_human_filter(
59+
agent_metrics.ego_progress, agent_metrics.ego_progress_available, human_metrics.ego_progress,
60+
human_metrics.ego_progress_available, result.ego_progress_filter_applied);
61+
62+
result.human_time_to_collision_within_bound = human_metrics.time_to_collision_within_bound;
63+
result.human_time_to_collision_within_bound_available =
64+
human_metrics.time_to_collision_within_bound_available;
65+
result.filtered_time_to_collision_within_bound = apply_human_filter(
66+
agent_metrics.time_to_collision_within_bound,
67+
agent_metrics.time_to_collision_within_bound_available,
68+
human_metrics.time_to_collision_within_bound,
69+
human_metrics.time_to_collision_within_bound_available,
70+
result.time_to_collision_within_bound_filter_applied);
71+
72+
result.human_lane_keeping = human_metrics.lane_keeping;
73+
result.human_lane_keeping_available = human_metrics.lane_keeping_available;
74+
result.filtered_lane_keeping = apply_human_filter(
75+
agent_metrics.lane_keeping, agent_metrics.lane_keeping_available, human_metrics.lane_keeping,
76+
human_metrics.lane_keeping_available, result.lane_keeping_filter_applied);
77+
78+
result.human_drivable_area_compliance = human_metrics.drivable_area_compliance;
79+
result.human_drivable_area_compliance_available =
80+
human_metrics.drivable_area_compliance_available;
81+
result.filtered_drivable_area_compliance = apply_human_filter(
82+
agent_metrics.drivable_area_compliance, agent_metrics.drivable_area_compliance_available,
83+
human_metrics.drivable_area_compliance, human_metrics.drivable_area_compliance_available,
84+
result.drivable_area_compliance_filter_applied);
85+
86+
result.human_no_at_fault_collision = human_metrics.no_at_fault_collision;
87+
result.human_no_at_fault_collision_available = human_metrics.no_at_fault_collision_available;
88+
result.filtered_no_at_fault_collision = apply_human_filter(
89+
agent_metrics.no_at_fault_collision, agent_metrics.no_at_fault_collision_available,
90+
human_metrics.no_at_fault_collision, human_metrics.no_at_fault_collision_available,
91+
result.no_at_fault_collision_filter_applied);
92+
93+
result.human_driving_direction_compliance = human_metrics.driving_direction_compliance;
94+
result.human_driving_direction_compliance_available =
95+
human_metrics.driving_direction_compliance_available;
96+
result.filtered_driving_direction_compliance = apply_human_filter(
97+
agent_metrics.driving_direction_compliance,
98+
agent_metrics.driving_direction_compliance_available,
99+
human_metrics.driving_direction_compliance,
100+
human_metrics.driving_direction_compliance_available,
101+
result.driving_direction_compliance_filter_applied);
102+
103+
result.human_traffic_light_compliance = human_metrics.traffic_light_compliance;
104+
result.human_traffic_light_compliance_available =
105+
human_metrics.traffic_light_compliance_available;
106+
result.filtered_traffic_light_compliance = apply_human_filter(
107+
agent_metrics.traffic_light_compliance, agent_metrics.traffic_light_compliance_available,
108+
human_metrics.traffic_light_compliance, human_metrics.traffic_light_compliance_available,
109+
result.traffic_light_compliance_filter_applied);
110+
111+
return result;
112+
}
113+
114+
SyntheticEpdmsMetrics calculate_synthetic_epdms(
115+
const EpdmsMetricSnapshot & agent_metrics, const HumanFilterMetrics & human_filter_metrics)
116+
{
117+
SyntheticEpdmsMetrics result;
118+
constexpr double kSyntheticWeightedDenominator = 16.0;
119+
120+
const bool raw_multiplicative_available = agent_metrics.no_at_fault_collision_available &&
121+
agent_metrics.drivable_area_compliance_available &&
122+
agent_metrics.driving_direction_compliance_available &&
123+
agent_metrics.traffic_light_compliance_available;
124+
const bool raw_weighted_available = agent_metrics.ego_progress_available &&
125+
agent_metrics.time_to_collision_within_bound_available &&
126+
agent_metrics.lane_keeping_available &&
127+
agent_metrics.history_comfort_available &&
128+
agent_metrics.extended_comfort_available;
129+
result.raw_available = raw_multiplicative_available && raw_weighted_available;
130+
if (result.raw_available) {
131+
result.raw_multiplicative_metrics_prod =
132+
agent_metrics.no_at_fault_collision * agent_metrics.drivable_area_compliance *
133+
agent_metrics.driving_direction_compliance * agent_metrics.traffic_light_compliance;
134+
result.raw_weighted_metrics =
135+
(5.0 * agent_metrics.ego_progress + 5.0 * agent_metrics.time_to_collision_within_bound +
136+
2.0 * agent_metrics.lane_keeping + 2.0 * agent_metrics.history_comfort +
137+
2.0 * agent_metrics.extended_comfort) /
138+
kSyntheticWeightedDenominator;
139+
result.raw_epdms = result.raw_multiplicative_metrics_prod * result.raw_weighted_metrics;
140+
}
141+
142+
const bool human_filtered_multiplicative_available =
143+
agent_metrics.no_at_fault_collision_available &&
144+
agent_metrics.drivable_area_compliance_available &&
145+
agent_metrics.driving_direction_compliance_available &&
146+
agent_metrics.traffic_light_compliance_available;
147+
const bool human_filtered_weighted_available =
148+
agent_metrics.ego_progress_available &&
149+
agent_metrics.time_to_collision_within_bound_available &&
150+
agent_metrics.lane_keeping_available && agent_metrics.history_comfort_available &&
151+
agent_metrics.extended_comfort_available;
152+
result.human_filtered_available =
153+
human_filtered_multiplicative_available && human_filtered_weighted_available;
154+
if (result.human_filtered_available) {
155+
result.human_filtered_multiplicative_metrics_prod =
156+
human_filter_metrics.filtered_no_at_fault_collision *
157+
human_filter_metrics.filtered_drivable_area_compliance *
158+
human_filter_metrics.filtered_driving_direction_compliance *
159+
human_filter_metrics.filtered_traffic_light_compliance;
160+
const double filtered_ego_progress =
161+
human_filter_metrics.ego_progress_filter_applied ? 1.0 : agent_metrics.ego_progress;
162+
result.human_filtered_weighted_metrics =
163+
(5.0 * filtered_ego_progress +
164+
5.0 * human_filter_metrics.filtered_time_to_collision_within_bound +
165+
2.0 * human_filter_metrics.filtered_lane_keeping +
166+
2.0 * human_filter_metrics.filtered_history_comfort +
167+
2.0 * human_filter_metrics.filtered_extended_comfort) /
168+
kSyntheticWeightedDenominator;
169+
result.human_filtered_epdms =
170+
result.human_filtered_multiplicative_metrics_prod * result.human_filtered_weighted_metrics;
171+
}
172+
173+
return result;
174+
}
175+
176+
} // namespace autoware::planning_data_analyzer::metrics
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright 2026 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef METRICS__EPDMS_AGGREGATION_HPP_
16+
#define METRICS__EPDMS_AGGREGATION_HPP_
17+
18+
#include <cstddef>
19+
20+
namespace autoware::planning_data_analyzer::metrics
21+
{
22+
23+
struct EpdmsMetricSnapshot
24+
{
25+
double history_comfort{0.0};
26+
bool history_comfort_available{false};
27+
28+
double extended_comfort{0.0};
29+
bool extended_comfort_available{false};
30+
31+
double ego_progress{0.0};
32+
bool ego_progress_available{false};
33+
34+
double time_to_collision_within_bound{0.0};
35+
bool time_to_collision_within_bound_available{false};
36+
37+
double lane_keeping{0.0};
38+
bool lane_keeping_available{false};
39+
40+
double drivable_area_compliance{0.0};
41+
bool drivable_area_compliance_available{false};
42+
43+
double no_at_fault_collision{0.0};
44+
bool no_at_fault_collision_available{false};
45+
46+
double driving_direction_compliance{0.0};
47+
bool driving_direction_compliance_available{false};
48+
49+
double traffic_light_compliance{0.0};
50+
bool traffic_light_compliance_available{false};
51+
};
52+
53+
struct HumanFilterMetrics
54+
{
55+
double human_history_comfort{0.0};
56+
bool human_history_comfort_available{false};
57+
double filtered_history_comfort{0.0};
58+
bool history_comfort_filter_applied{false};
59+
60+
double human_extended_comfort{0.0};
61+
bool human_extended_comfort_available{false};
62+
double filtered_extended_comfort{0.0};
63+
bool extended_comfort_filter_applied{false};
64+
65+
double human_ego_progress{0.0};
66+
bool human_ego_progress_available{false};
67+
double filtered_ego_progress{0.0};
68+
bool ego_progress_filter_applied{false};
69+
70+
double human_time_to_collision_within_bound{0.0};
71+
bool human_time_to_collision_within_bound_available{false};
72+
double filtered_time_to_collision_within_bound{0.0};
73+
bool time_to_collision_within_bound_filter_applied{false};
74+
75+
double human_lane_keeping{0.0};
76+
bool human_lane_keeping_available{false};
77+
double filtered_lane_keeping{0.0};
78+
bool lane_keeping_filter_applied{false};
79+
80+
double human_drivable_area_compliance{0.0};
81+
bool human_drivable_area_compliance_available{false};
82+
double filtered_drivable_area_compliance{0.0};
83+
bool drivable_area_compliance_filter_applied{false};
84+
85+
double human_no_at_fault_collision{0.0};
86+
bool human_no_at_fault_collision_available{false};
87+
double filtered_no_at_fault_collision{0.0};
88+
bool no_at_fault_collision_filter_applied{false};
89+
90+
double human_driving_direction_compliance{0.0};
91+
bool human_driving_direction_compliance_available{false};
92+
double filtered_driving_direction_compliance{0.0};
93+
bool driving_direction_compliance_filter_applied{false};
94+
95+
double human_traffic_light_compliance{0.0};
96+
bool human_traffic_light_compliance_available{false};
97+
double filtered_traffic_light_compliance{0.0};
98+
bool traffic_light_compliance_filter_applied{false};
99+
};
100+
101+
struct SyntheticEpdmsMetrics
102+
{
103+
bool raw_available{false};
104+
double raw_multiplicative_metrics_prod{0.0};
105+
double raw_weighted_metrics{0.0};
106+
double raw_epdms{0.0};
107+
108+
bool human_filtered_available{false};
109+
double human_filtered_multiplicative_metrics_prod{0.0};
110+
double human_filtered_weighted_metrics{0.0};
111+
double human_filtered_epdms{0.0};
112+
};
113+
114+
HumanFilterMetrics calculate_human_filter_metrics(
115+
const EpdmsMetricSnapshot & agent_metrics, const EpdmsMetricSnapshot & human_metrics);
116+
117+
SyntheticEpdmsMetrics calculate_synthetic_epdms(
118+
const EpdmsMetricSnapshot & agent_metrics, const HumanFilterMetrics & human_filter_metrics);
119+
120+
} // namespace autoware::planning_data_analyzer::metrics
121+
122+
#endif // METRICS__EPDMS_AGGREGATION_HPP_

0 commit comments

Comments
 (0)