Skip to content

Refactor ActionNode to isolate side effects via pure virtual methods #1612

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ class ActionNode : public BT::ActionNodeBase
lanelet::Ids route_lanelets_;
traffic_simulator_msgs::msg::BehaviorParameter behavior_parameter_;

virtual bool checkPreconditions() { return true; }
virtual BT::NodeStatus doAction() = 0;
auto getDistanceToTargetEntity(
const math::geometry::CatmullRomSplineInterface & spline,
const traffic_simulator::CanonicalizedEntityStatus & status) const -> std::optional<double>;
Expand All @@ -137,6 +139,7 @@ class ActionNode : public BT::ActionNodeBase
-> std::vector<traffic_simulator::CanonicalizedEntityStatus>;
auto isOtherEntityAtConsideredAltitude(
const traffic_simulator::CanonicalizedEntityStatus & entity_status) const -> bool;
auto tick() -> BT::NodeStatus override;

std::shared_ptr<EuclideanDistancesMap> euclidean_distances_map_;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class FollowLaneAction : public entity_behavior::PedestrianActionNode
{
public:
FollowLaneAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
void getBlackBoardValues() override;
static BT::PortsList providedPorts()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ struct FollowPolylineTrajectoryAction : public PedestrianActionNode

static auto providedPorts() -> BT::PortsList;

auto tick() -> BT::NodeStatus override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
};
} // namespace pedestrian
} // namespace entity_behavior
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class WalkStraightAction : public entity_behavior::PedestrianActionNode
{
public:
WalkStraightAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
void getBlackBoardValues() override;
static BT::PortsList providedPorts()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class FollowFrontEntityAction : public entity_behavior::VehicleActionNode
{
public:
FollowFrontEntityAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
static BT::PortsList providedPorts()
{
return entity_behavior::VehicleActionNode::providedPorts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class FollowLaneAction : public entity_behavior::VehicleActionNode
{
public:
FollowLaneAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
void getBlackBoardValues() override;
static BT::PortsList providedPorts()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class MoveBackwardAction : public entity_behavior::VehicleActionNode
{
public:
MoveBackwardAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
void getBlackBoardValues() override;
static BT::PortsList providedPorts()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class StopAtCrossingEntityAction : public entity_behavior::VehicleActionNode
{
public:
StopAtCrossingEntityAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
static BT::PortsList providedPorts()
{
return entity_behavior::VehicleActionNode::providedPorts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class StopAtStopLineAction : public entity_behavior::VehicleActionNode
{
public:
StopAtStopLineAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
static BT::PortsList providedPorts()
{
return entity_behavior::VehicleActionNode::providedPorts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class StopAtTrafficLightAction : public entity_behavior::VehicleActionNode
{
public:
StopAtTrafficLightAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
static BT::PortsList providedPorts()
{
return entity_behavior::VehicleActionNode::providedPorts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class YieldAction : public entity_behavior::VehicleActionNode
{
public:
YieldAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
static BT::PortsList providedPorts()
{
return entity_behavior::VehicleActionNode::providedPorts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ struct FollowPolylineTrajectoryAction : public VehicleActionNode

static auto providedPorts() -> BT::PortsList;

auto tick() -> BT::NodeStatus override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
};
} // namespace vehicle
} // namespace entity_behavior
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class LaneChangeAction : public entity_behavior::VehicleActionNode
{
public:
LaneChangeAction(const std::string & name, const BT::NodeConfiguration & config);
BT::NodeStatus tick() override;
bool checkPreconditions() override;
BT::NodeStatus doAction() override;
static BT::PortsList providedPorts()
{
return BT::PortsList(
Expand Down
9 changes: 9 additions & 0 deletions simulation/behavior_tree_plugin/src/action_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ ActionNode::ActionNode(const std::string & name, const BT::NodeConfiguration & c

auto ActionNode::executeTick() -> BT::NodeStatus { return BT::ActionNodeBase::executeTick(); }

auto ActionNode::tick() -> BT::NodeStatus
{
getBlackBoardValues();
if (!checkPreconditions()) {
return BT::NodeStatus::FAILURE;
}
return doAction();
}

auto ActionNode::getBlackBoardValues() -> void
{
if (!getInput<traffic_simulator::behavior::Request>("request", request_)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,19 @@ bool FollowLaneAction::detectObstacleInLane(
return false;
}
}

BT::NodeStatus FollowLaneAction::tick()
bool FollowLaneAction::checkPreconditions()
{
getBlackBoardValues();
if (
request_ != traffic_simulator::behavior::Request::NONE &&
request_ != traffic_simulator::behavior::Request::FOLLOW_LANE) {
return BT::NodeStatus::FAILURE;
return false;
} else {
return true;
}
}

BT::NodeStatus FollowLaneAction::doAction()
{
if (!canonicalized_entity_status_->isInLanelet()) {
stopEntity();
return BT::NodeStatus::RUNNING;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,34 @@ auto FollowPolylineTrajectoryAction::providedPorts() -> BT::PortsList
return ports;
}

auto FollowPolylineTrajectoryAction::tick() -> BT::NodeStatus
bool FollowPolylineTrajectoryAction::checkPreconditions()
{
auto getTargetSpeed = [&]() -> double {
if (target_speed_.has_value()) {
return target_speed_.value();
} else {
return canonicalized_entity_status_->getTwist().linear.x;
}
};

if (getBlackBoardValues();
request_ != traffic_simulator::behavior::Request::FOLLOW_POLYLINE_TRAJECTORY or
not getInput<decltype(polyline_trajectory)>("polyline_trajectory", polyline_trajectory) or
not getInput<decltype(target_speed_)>("target_speed", target_speed_) or
not polyline_trajectory) {
return BT::NodeStatus::FAILURE;
return false;
} else if (std::isnan(canonicalized_entity_status_->getTime())) {
THROW_SIMULATION_ERROR(
"Time in canonicalized_entity_status is NaN - FollowTrajectoryAction does not support such "
"case.");
} else if (
} else {
return true;
}
}

auto FollowPolylineTrajectoryAction::doAction() -> BT::NodeStatus
{
auto getTargetSpeed = [&]() -> double {
if (target_speed_.has_value()) {
return target_speed_.value();
} else {
return canonicalized_entity_status_->getTwist().linear.x;
}
};

if (
const auto entity_status_updated = traffic_simulator::follow_trajectory::makeUpdatedStatus(
static_cast<traffic_simulator::EntityStatus>(*canonicalized_entity_status_),
*polyline_trajectory, behavior_parameter_, hdmap_utils_, step_time_,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ WalkStraightAction::WalkStraightAction(

void WalkStraightAction::getBlackBoardValues() { PedestrianActionNode::getBlackBoardValues(); }

BT::NodeStatus WalkStraightAction::tick()
bool WalkStraightAction::checkPreconditions()
{
return request_ == traffic_simulator::behavior::Request::WALK_STRAIGHT;
}

BT::NodeStatus WalkStraightAction::doAction()
{
getBlackBoardValues();
if (request_ != traffic_simulator::behavior::Request::WALK_STRAIGHT) {
return BT::NodeStatus::FAILURE;
}
if (!target_speed_) {
target_speed_ = 1.111;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,23 @@ const traffic_simulator_msgs::msg::WaypointsArray FollowFrontEntityAction::calcu
}
}

BT::NodeStatus FollowFrontEntityAction::tick()
bool FollowFrontEntityAction::checkPreconditions()
{
getBlackBoardValues();
if (
request_ != traffic_simulator::behavior::Request::NONE &&
request_ != traffic_simulator::behavior::Request::FOLLOW_LANE) {
return BT::NodeStatus::FAILURE;
}
if (getRightOfWayEntities(route_lanelets_).size() != 0) {
return BT::NodeStatus::FAILURE;
}
if (!behavior_parameter_.see_around) {
return BT::NodeStatus::FAILURE;
return false;
} else if (!getRightOfWayEntities(route_lanelets_).empty()) {
return false;
} else if (!behavior_parameter_.see_around) {
return false;
} else {
return true;
}
}

BT::NodeStatus FollowFrontEntityAction::doAction()
{
const auto waypoints = calculateWaypoints();
if (waypoints.waypoints.empty()) {
return BT::NodeStatus::FAILURE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,19 @@ void FollowLaneAction::getBlackBoardValues()
}
}

BT::NodeStatus FollowLaneAction::tick()
bool FollowLaneAction::checkPreconditions()
{
getBlackBoardValues();
if (
request_ != traffic_simulator::behavior::Request::NONE &&
request_ != traffic_simulator::behavior::Request::FOLLOW_LANE) {
return BT::NodeStatus::FAILURE;
return false;
} else {
return true;
}
}

BT::NodeStatus FollowLaneAction::doAction()
{
if (!canonicalized_entity_status_->isInLanelet()) {
stopEntity();
const auto waypoints = traffic_simulator_msgs::msg::WaypointsArray{};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,21 @@ const traffic_simulator_msgs::msg::WaypointsArray MoveBackwardAction::calculateW

void MoveBackwardAction::getBlackBoardValues() { VehicleActionNode::getBlackBoardValues(); }

BT::NodeStatus MoveBackwardAction::tick()
bool MoveBackwardAction::checkPreconditions()
{
getBlackBoardValues();
if (
request_ != traffic_simulator::behavior::Request::NONE &&
request_ != traffic_simulator::behavior::Request::FOLLOW_LANE) {
return BT::NodeStatus::FAILURE;
}
if (!canonicalized_entity_status_->isInLanelet()) {
return BT::NodeStatus::FAILURE;
return false;
} else if (!canonicalized_entity_status_->isInLanelet()) {
return false;
} else {
return true;
}
}

BT::NodeStatus MoveBackwardAction::doAction()
{
const auto waypoints = calculateWaypoints();
if (waypoints.waypoints.empty()) {
return BT::NodeStatus::FAILURE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,25 @@ std::optional<double> StopAtCrossingEntityAction::calculateTargetSpeed(double cu
return current_velocity;
}

BT::NodeStatus StopAtCrossingEntityAction::tick()
bool StopAtCrossingEntityAction::checkPreconditions()
{
getBlackBoardValues();
if (
request_ != traffic_simulator::behavior::Request::NONE &&
request_ != traffic_simulator::behavior::Request::FOLLOW_LANE) {
return BT::NodeStatus::FAILURE;
}
if (!canonicalized_entity_status_->isInLanelet()) {
return BT::NodeStatus::FAILURE;
}
if (!behavior_parameter_.see_around) {
return BT::NodeStatus::FAILURE;
}
if (getRightOfWayEntities(route_lanelets_).size() != 0) {
return BT::NodeStatus::FAILURE;
return false;
} else if (!canonicalized_entity_status_->isInLanelet()) {
return false;
} else if (!behavior_parameter_.see_around) {
return false;
} else if (!getRightOfWayEntities(route_lanelets_).empty()) {
return false;
} else {
return true;
}
}

BT::NodeStatus StopAtCrossingEntityAction::doAction()
{
const auto waypoints = calculateWaypoints();
if (waypoints.waypoints.empty()) {
return BT::NodeStatus::FAILURE;
Expand Down
Loading
Loading