Skip to content

Commit d1ae5d0

Browse files
fix(trajectory_validator): replace is_feasible boolean to risk level … (#3358)
* fix(trajectory_validator): replace is_feasible boolean to risk level check Signed-off-by: Zulfaqar Azmi <zulfaqar.azmi@tier4.jp> * use value comparison Co-authored-by: mkquda <168697710+mkquda@users.noreply.github.com> * fix: rename function name Signed-off-by: Zulfaqar Azmi <zulfaqar.azmi@tier4.jp> * fix: docstring Signed-off-by: Zulfaqar Azmi <zulfaqar.azmi@tier4.jp> --------- Signed-off-by: Zulfaqar Azmi <zulfaqar.azmi@tier4.jp> Co-authored-by: mkquda <168697710+mkquda@users.noreply.github.com>
1 parent 2ee7ee6 commit d1ae5d0

17 files changed

Lines changed: 132 additions & 74 deletions

File tree

‎control/autoware_control_validator/src/control_validator.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ void VelocityValidator::validate(
174174
if (is_stopped || std::abs(v_vel) < params_.rolling_back_velocity) {
175175
return false;
176176
}
177-
177+
178178
if (std::abs(t_vel) < stopped_vel_th) {
179179
return std::signbit(v_vel);
180180
}

‎planning/autoware_trajectory_validator/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This package provides a pluginlib-based C++ library for evaluating candidate tra
99
For each input `CandidateTrajectories` message the library runs every loaded plugin against every trajectory:
1010

1111
1. **Plugin evaluation**: each plugin's `is_feasible()` is called with the trajectory points and the current `ValidatorContext` (odometry, predicted objects, acceleration, HD map, traffic light states).
12-
2. **Feasibility decision**: a trajectory survives if every plugin listed in `filter_names` returns `is_feasible = true`. Plugins listed in `shadow_mode_filter_names` are evaluated and reported but never remove a trajectory.
12+
2. **Feasibility decision**: each plugin reports metrics with a risk level. A plugin accepts the trajectory when the worst risk level of its metrics is `SAFE`, `LOW_CAUTION`, or `HIGH_CAUTION`, and rejects it on `DANGER` or `FATAL`. A trajectory survives if every plugin listed in `filter_names` accepts it. Plugins listed in `shadow_mode_filter_names` are evaluated and reported but never remove a trajectory.
1313
3. **Diagnostics**: `TrajectoryValidatorDiagnostic` selects the best candidate (the one with the least severe action across all active filters), resolves the `(filter_name, action)` pair to a named `DiagnosticStatus` via the `configured_actions` parameter, and publishes every tracked status every cycle (active ones at their level, inactive ones at `OK` to prevent staleness). Shadow-mode filters never contribute to the action aggregation. See [docs/TrajectoryValidatorDiagnostic.md](docs/TrajectoryValidatorDiagnostic.md) for details.
1414

1515
## Built-in Plugins

‎planning/autoware_trajectory_validator/include/autoware/trajectory_validator/detail/risk_utils.hpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,15 @@ inline RiskLevelType worst_risk_level(const std::vector<MetricReport> & metrics)
5454
}
5555
return worst;
5656
}
57+
58+
/**
59+
* @brief Returns a boolean indicating the trajectory is feasible based on risk level.
60+
* @param metrics Worst risk level.
61+
* @return True if risk level is less or equal to HIGH_CAUTION.
62+
*/
63+
inline bool is_feasible(const RiskLevelType risk_level)
64+
{
65+
return risk_level <= RiskLevel::HIGH_CAUTION;
66+
}
5767
} // namespace autoware::trajectory_validator
5868
#endif // AUTOWARE__TRAJECTORY_VALIDATOR__DETAIL__RISK_UTILS_HPP_

‎planning/autoware_trajectory_validator/include/autoware/trajectory_validator/validator_interface.hpp‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ using autoware_trajectory_validator::msg::RiskLevel;
4545
/** @brief Result of a single plugin's feasibility check. */
4646
struct ValidationResult
4747
{
48-
bool is_feasible{true};
4948
std::vector<MetricReport> metrics;
5049
PlanningFactorArray planning_factors{};
5150
};

‎planning/autoware_trajectory_validator/src/detail/trajectory_validator.cpp‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,13 @@ std::pair<PluginEvaluation, RiskLevel> TrajectoryValidator::summarize_feasibilit
169169
}
170170

171171
const auto & val = res.value();
172-
evaluation.is_feasible = val.is_feasible;
172+
risk_level.level = worst_risk_level(val.metrics);
173+
evaluation.is_feasible = is_feasible(risk_level.level);
174+
173175
if (!evaluation.is_feasible) {
174176
evaluation.reason = "Found failed metrics";
175177
}
176178

177-
risk_level.level = worst_risk_level(val.metrics);
178179
return {evaluation, risk_level};
179180
}
180181

‎planning/autoware_trajectory_validator/src/filters/safety/collision_check_filter/collision_check_filter.cpp‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ CollisionCheckFilter::result_t CollisionCheckFilter::is_feasible(
157157
debug_markers_, global_params_.time_resolution);
158158

159159
return ValidationResult{
160-
calc_worst_risk({drac_artifact.risk, rss_artifact.risk}) < RiskLevel::DANGER,
161160
generate_metric_reports(drac_artifact, rss_artifact), std::move(planning_factors)};
162161
}
163162

‎planning/autoware_trajectory_validator/src/filters/safety/point_cloud_collision_check/point_cloud_collision_check_filter.cpp‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "point_cloud_collision_check_filter.hpp"
1616

17+
#include <utility>
1718
#include <vector>
1819

1920
namespace autoware::trajectory_validator::plugin::safety
@@ -47,13 +48,14 @@ std::vector<pcc::StopObstacle> PointCloudCollisionCheckFilter::calc_obstacle_sto
4748
return {};
4849
}
4950

50-
bool PointCloudCollisionCheckFilter::judge_stop_feasibility(
51+
RiskLevel PointCloudCollisionCheckFilter::judge_stop_risk(
5152
[[maybe_unused]] const std::vector<pcc::StopObstacle> & stop_obstacles,
5253
[[maybe_unused]] const geometry_msgs::msg::Twist & twist) const
5354
{
54-
// It is not currently implemented. always return true.
55-
bool is_feasible = true;
56-
return is_feasible;
55+
// It is not currently implemented. always return SAFE.
56+
RiskLevel risk_level;
57+
risk_level.level = RiskLevel::SAFE;
58+
return risk_level;
5759
}
5860

5961
PointCloudCollisionCheckFilter::result_t PointCloudCollisionCheckFilter::is_feasible(
@@ -70,10 +72,15 @@ PointCloudCollisionCheckFilter::result_t PointCloudCollisionCheckFilter::is_feas
7072

7173
const auto stop_obstacles = calc_obstacle_stop(candidate_trajectory.points);
7274

73-
ValidationResult result{};
74-
result.is_feasible = judge_stop_feasibility(stop_obstacles, context.odometry->twist.twist);
75+
std::vector<MetricReport> metrics{
76+
autoware_trajectory_validator::build<MetricReport>()
77+
.validator_name(get_name())
78+
.validator_category(category())
79+
.metric_name("point_cloud_stop_feasibility")
80+
.metric_value(static_cast<double>(stop_obstacles.size()))
81+
.risk(judge_stop_risk(stop_obstacles, context.odometry->twist.twist))};
7582

76-
return result;
83+
return ValidationResult{std::move(metrics)};
7784
}
7885

7986
void PointCloudCollisionCheckFilter::update_parameters(const validator::Params & params)

‎planning/autoware_trajectory_validator/src/filters/safety/point_cloud_collision_check/point_cloud_collision_check_filter.hpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class PointCloudCollisionCheckFilter final : public plugin::ValidatorInterface
4343

4444
private:
4545
/// @brief 評価に必要な入力が揃っているかを判定する。
46-
/// false のとき is_feasible は評価せず feasible(ValidationResult{})を返す。
46+
/// false のとき is_feasible は評価せず、メトリクスなし(ValidationResult{})を返す。
4747
bool is_available_data(
4848
const CandidateTrajectory & candidate_trajectory, const FilterContext & context) const;
4949

@@ -60,8 +60,8 @@ class PointCloudCollisionCheckFilter final : public plugin::ValidatorInterface
6060
std::vector<point_cloud_collision_check::StopObstacle> calc_obstacle_stop(
6161
const std::vector<TrajectoryPoint> & raw_trajectory_points);
6262

63-
/// @brief 停止対象から停止可否を判定する。未実装のため現状は常に true を返す。
64-
bool judge_stop_feasibility(
63+
/// @brief 停止対象から停止可否のリスクレベルを判定する。未実装のため現状は常に SAFE を返す。
64+
RiskLevel judge_stop_risk(
6565
const std::vector<point_cloud_collision_check::StopObstacle> & stop_obstacles,
6666
const geometry_msgs::msg::Twist & twist) const;
6767

‎planning/autoware_trajectory_validator/src/filters/safety/trajectory_feasibility_filter.cpp‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,16 @@ TrajectoryFeasibilityFilter::result_t TrajectoryFeasibilityFilter::is_feasible(
177177
return tl::make_unexpected("Vehicle info not set");
178178
}
179179

180-
// NOTE: Feasibility decision logic might be more complex in the future, but for now we just
181-
// check all constraints and return false if any are violated
182-
bool is_feasible = true;
180+
// Each checker reports its own risk level. The core derives feasibility from the worst risk
181+
// level of these metrics, so a violated constraint reports HIGH_CAUTION and does not reject the
182+
// trajectory on its own.
183183
std::vector<MetricReport> metrics;
184184
for (const auto & checker : checkers_) {
185185
auto report = (this->*checker)(traj_points, context);
186-
is_feasible &= report.risk.level == RiskLevel::SAFE;
187186
metrics.push_back(report);
188187
}
189188

190-
return ValidationResult{is_feasible, std::move(metrics)};
189+
return ValidationResult{std::move(metrics)};
191190
}
192191

193192
MetricReport TrajectoryFeasibilityFilter::check_speed(

‎planning/autoware_trajectory_validator/src/filters/safety/uncrossable_boundary_departure.cpp‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ UncrossableBoundaryDepartureFilter::result_t UncrossableBoundaryDepartureFilter:
7575
.metric_value(status.lat_dist_to_uncrossable_bound)
7676
.risk(risk_level)};
7777

78-
// Only a CRITICAL departure rejects the trajectory. NEAR_BOUNDARY is advisory.
79-
return ValidationResult{!is_critical_departure, std::move(metrics)};
78+
// Only a CRITICAL departure rejects the trajectory, because it reports DANGER. NEAR_BOUNDARY
79+
// reports LOW_CAUTION and is advisory.
80+
return ValidationResult{std::move(metrics)};
8081
}
8182

8283
void UncrossableBoundaryDepartureFilter::update_parameters(const validator::Params & params)

0 commit comments

Comments
 (0)