Skip to content

Commit 39d406e

Browse files
authored
fix(avoidance): fix RTC state transition (#7142)
* fix(avoidance): fix RTC state transition Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com> * fix(rtc_interface): check if the cooperate status is registered Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com> * refactor(avoidance): rebuild avoidance module state Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com> --------- Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com>
1 parent 9dfca09 commit 39d406e

File tree

4 files changed

+68
-79
lines changed

4 files changed

+68
-79
lines changed

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/data_structs.hpp

+4-8
Original file line numberDiff line numberDiff line change
@@ -501,11 +501,9 @@ using AvoidOutlines = std::vector<AvoidOutline>;
501501
* avoidance state
502502
*/
503503
enum class AvoidanceState {
504-
NOT_AVOID = 0,
505-
AVOID_EXECUTE,
506-
YIELD,
507-
AVOID_PATH_READY,
508-
AVOID_PATH_NOT_READY,
504+
RUNNING = 0,
505+
CANCEL,
506+
SUCCEEDED,
509507
};
510508

511509
/*
@@ -514,7 +512,7 @@ enum class AvoidanceState {
514512
struct AvoidancePlanningData
515513
{
516514
// ego final state
517-
AvoidanceState state{AvoidanceState::NOT_AVOID};
515+
AvoidanceState state{AvoidanceState::RUNNING};
518516

519517
// un-shifted pose (for current lane detection)
520518
Pose reference_pose;
@@ -566,8 +564,6 @@ struct AvoidancePlanningData
566564

567565
bool ready{false};
568566

569-
bool success{false};
570-
571567
bool comfortable{false};
572568

573569
bool avoid_required{false};

planning/behavior_path_avoidance_module/include/behavior_path_avoidance_module/scene.hpp

+20-16
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <memory>
3131
#include <string>
3232
#include <unordered_map>
33+
#include <utility>
3334
#include <vector>
3435

3536
namespace behavior_path_planner
@@ -64,7 +65,14 @@ class AvoidanceModule : public SceneModuleInterface
6465
std::shared_ptr<AvoidanceDebugMsgArray> get_debug_msg_array() const;
6566

6667
private:
67-
bool isSatisfiedSuccessCondition(const AvoidancePlanningData & data) const;
68+
/**
69+
* @brief return the result whether the module can stop path generation process.
70+
* @param avoidance data.
71+
* @return it will return AvoidanceState::RUNNING when there are obstacles ego should avoid.
72+
* it will return AvoidanceState::CANCEL when all obstacles have gone.
73+
* it will return AvoidanceState::SUCCEEDED when the ego avoid all obstacles.
74+
*/
75+
AvoidanceState getCurrentModuleState(const AvoidancePlanningData & data) const;
6876

6977
bool canTransitSuccessState() override;
7078

@@ -188,14 +196,6 @@ class AvoidanceModule : public SceneModuleInterface
188196
*/
189197
void updateRTCData();
190198

191-
// ego state check
192-
193-
/**
194-
* @brief update ego status based on avoidance path and surround condition.
195-
* @param ego status. (NOT_AVOID, AVOID, YIELD, AVOID_EXECUTE, AVOID_PATH_NOT_READY)
196-
*/
197-
AvoidanceState updateEgoState(const AvoidancePlanningData & data) const;
198-
199199
// ego behavior update
200200

201201
/**
@@ -359,7 +359,7 @@ class AvoidanceModule : public SceneModuleInterface
359359
* @brief reset registered shift lines.
360360
* @details reset only when the base offset is zero. Otherwise, sudden steering will be caused;
361361
*/
362-
void removeRegisteredShiftLines()
362+
void removeRegisteredShiftLines(const uint8_t state)
363363
{
364364
constexpr double threshold = 0.1;
365365
if (std::abs(path_shifter_.getBaseOffset()) > threshold) {
@@ -370,15 +370,19 @@ class AvoidanceModule : public SceneModuleInterface
370370
unlockNewModuleLaunch();
371371

372372
for (const auto & left_shift : left_shift_array_) {
373-
rtc_interface_ptr_map_.at("left")->updateCooperateStatus(
374-
left_shift.uuid, true, State::FAILED, std::numeric_limits<double>::lowest(),
375-
std::numeric_limits<double>::lowest(), clock_->now());
373+
if (rtc_interface_ptr_map_.at("left")->isRegistered(left_shift.uuid)) {
374+
rtc_interface_ptr_map_.at("left")->updateCooperateStatus(
375+
left_shift.uuid, true, state, std::numeric_limits<double>::lowest(),
376+
std::numeric_limits<double>::lowest(), clock_->now());
377+
}
376378
}
377379

378380
for (const auto & right_shift : right_shift_array_) {
379-
rtc_interface_ptr_map_.at("right")->updateCooperateStatus(
380-
right_shift.uuid, true, State::FAILED, std::numeric_limits<double>::lowest(),
381-
std::numeric_limits<double>::lowest(), clock_->now());
381+
if (rtc_interface_ptr_map_.at("right")->isRegistered(right_shift.uuid)) {
382+
rtc_interface_ptr_map_.at("right")->updateCooperateStatus(
383+
right_shift.uuid, true, state, std::numeric_limits<double>::lowest(),
384+
std::numeric_limits<double>::lowest(), clock_->now());
385+
}
382386
}
383387

384388
if (!path_shifter_.getShiftLines().empty()) {

planning/behavior_path_avoidance_module/src/scene.cpp

+38-52
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,14 @@ bool AvoidanceModule::isExecutionReady() const
115115
return avoid_data_.safe && avoid_data_.comfortable && avoid_data_.valid && avoid_data_.ready;
116116
}
117117

118-
bool AvoidanceModule::isSatisfiedSuccessCondition(const AvoidancePlanningData & data) const
118+
AvoidanceState AvoidanceModule::getCurrentModuleState(const AvoidancePlanningData & data) const
119119
{
120120
const bool has_avoidance_target = std::any_of(
121121
data.target_objects.begin(), data.target_objects.end(),
122122
[this](const auto & o) { return !helper_->isAbsolutelyNotAvoidable(o); });
123123

124124
if (has_avoidance_target) {
125-
return false;
125+
return AvoidanceState::RUNNING;
126126
}
127127

128128
// If the ego is on the shift line, keep RUNNING.
@@ -133,7 +133,7 @@ bool AvoidanceModule::isSatisfiedSuccessCondition(const AvoidancePlanningData &
133133
};
134134
for (const auto & shift_line : path_shifter_.getShiftLines()) {
135135
if (within(shift_line, idx)) {
136-
return false;
136+
return AvoidanceState::RUNNING;
137137
}
138138
}
139139
}
@@ -142,17 +142,21 @@ bool AvoidanceModule::isSatisfiedSuccessCondition(const AvoidancePlanningData &
142142
const bool has_base_offset =
143143
std::abs(path_shifter_.getBaseOffset()) > parameters_->lateral_execution_threshold;
144144

145+
if (has_base_offset) {
146+
return AvoidanceState::RUNNING;
147+
}
148+
145149
// Nothing to do. -> EXIT.
146-
if (!has_shift_point && !has_base_offset) {
147-
return true;
150+
if (!has_shift_point) {
151+
return AvoidanceState::SUCCEEDED;
148152
}
149153

150154
// Be able to canceling avoidance path. -> EXIT.
151155
if (!helper_->isShifted() && parameters_->enable_cancel_maneuver) {
152-
return true;
156+
return AvoidanceState::CANCEL;
153157
}
154158

155-
return false;
159+
return AvoidanceState::RUNNING;
156160
}
157161

158162
bool AvoidanceModule::canTransitSuccessState()
@@ -183,7 +187,7 @@ bool AvoidanceModule::canTransitSuccessState()
183187
}
184188
}
185189

186-
return data.success;
190+
return data.state == AvoidanceState::CANCEL || data.state == AvoidanceState::SUCCEEDED;
187191
}
188192

189193
void AvoidanceModule::fillFundamentalData(AvoidancePlanningData & data, DebugData & debug)
@@ -502,7 +506,7 @@ void AvoidanceModule::fillShiftLine(AvoidancePlanningData & data, DebugData & de
502506
void AvoidanceModule::fillEgoStatus(
503507
AvoidancePlanningData & data, [[maybe_unused]] DebugData & debug) const
504508
{
505-
data.success = isSatisfiedSuccessCondition(data);
509+
data.state = getCurrentModuleState(data);
506510

507511
/**
508512
* Find the nearest object that should be avoid. When the ego follows reference path,
@@ -633,27 +637,6 @@ void AvoidanceModule::fillDebugData(
633637
}
634638
}
635639

636-
AvoidanceState AvoidanceModule::updateEgoState(const AvoidancePlanningData & data) const
637-
{
638-
if (data.yield_required) {
639-
return AvoidanceState::YIELD;
640-
}
641-
642-
if (!data.avoid_required) {
643-
return AvoidanceState::NOT_AVOID;
644-
}
645-
646-
if (!data.found_avoidance_path) {
647-
return AvoidanceState::AVOID_PATH_NOT_READY;
648-
}
649-
650-
if (isWaitingApproval() && path_shifter_.getShiftLines().empty()) {
651-
return AvoidanceState::AVOID_PATH_READY;
652-
}
653-
654-
return AvoidanceState::AVOID_EXECUTE;
655-
}
656-
657640
void AvoidanceModule::updateEgoBehavior(const AvoidancePlanningData & data, ShiftedPath & path)
658641
{
659642
if (parameters_->disable_path_update) {
@@ -663,29 +646,30 @@ void AvoidanceModule::updateEgoBehavior(const AvoidancePlanningData & data, Shif
663646
insertPrepareVelocity(path);
664647
insertAvoidanceVelocity(path);
665648

666-
switch (data.state) {
667-
case AvoidanceState::NOT_AVOID: {
668-
break;
669-
}
670-
case AvoidanceState::YIELD: {
649+
const auto insert_velocity = [this, &data, &path]() {
650+
if (data.yield_required) {
671651
insertWaitPoint(isBestEffort(parameters_->policy_deceleration), path);
672-
break;
652+
return;
673653
}
674-
case AvoidanceState::AVOID_PATH_NOT_READY: {
675-
insertWaitPoint(isBestEffort(parameters_->policy_deceleration), path);
676-
break;
654+
655+
if (!data.avoid_required) {
656+
return;
677657
}
678-
case AvoidanceState::AVOID_PATH_READY: {
658+
659+
if (!data.found_avoidance_path) {
679660
insertWaitPoint(isBestEffort(parameters_->policy_deceleration), path);
680-
break;
661+
return;
681662
}
682-
case AvoidanceState::AVOID_EXECUTE: {
683-
insertStopPoint(isBestEffort(parameters_->policy_deceleration), path);
684-
break;
663+
664+
if (isWaitingApproval() && path_shifter_.getShiftLines().empty()) {
665+
insertWaitPoint(isBestEffort(parameters_->policy_deceleration), path);
666+
return;
685667
}
686-
default:
687-
throw std::domain_error("invalid behavior");
688-
}
668+
669+
insertStopPoint(isBestEffort(parameters_->policy_deceleration), path);
670+
};
671+
672+
insert_velocity();
689673

690674
insertReturnDeadLine(isBestEffort(parameters_->policy_deceleration), path);
691675

@@ -869,12 +853,16 @@ BehaviorModuleOutput AvoidanceModule::plan()
869853

870854
updatePathShifter(data.safe_shift_line);
871855

872-
if (data.success) {
873-
removeRegisteredShiftLines();
856+
if (data.state == AvoidanceState::SUCCEEDED) {
857+
removeRegisteredShiftLines(State::SUCCEEDED);
858+
}
859+
860+
if (data.state == AvoidanceState::CANCEL) {
861+
removeRegisteredShiftLines(State::FAILED);
874862
}
875863

876864
if (data.yield_required) {
877-
removeRegisteredShiftLines();
865+
removeRegisteredShiftLines(State::FAILED);
878866
}
879867

880868
// generate path with shift points that have been inserted.
@@ -941,8 +929,6 @@ BehaviorModuleOutput AvoidanceModule::plan()
941929
spline_shift_path.path, parameters_->resample_interval_for_output);
942930
}
943931

944-
avoid_data_.state = updateEgoState(data);
945-
946932
// update output data
947933
{
948934
updateEgoBehavior(data, spline_shift_path);

planning/behavior_path_planner_common/include/behavior_path_planner_common/interface/scene_module_interface.hpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -508,9 +508,12 @@ class SceneModuleInterface
508508
{
509509
for (const auto & [module_name, ptr] : rtc_interface_ptr_map_) {
510510
if (ptr) {
511-
ptr->updateCooperateStatus(
512-
uuid_map_.at(module_name), true, State::SUCCEEDED, std::numeric_limits<double>::lowest(),
513-
std::numeric_limits<double>::lowest(), clock_->now());
511+
if (ptr->isRegistered(uuid_map_.at(module_name))) {
512+
ptr->updateCooperateStatus(
513+
uuid_map_.at(module_name), true, State::SUCCEEDED,
514+
std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(),
515+
clock_->now());
516+
}
514517
}
515518
}
516519
}

0 commit comments

Comments
 (0)