Skip to content
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

Behavior Tree uses Error Codes #3324

Merged
merged 35 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
073a0f6
rough outline for condition node
Dec 12, 2022
34b0742
completed error code condition
Dec 13, 2022
9c4430a
behavior tree with error codes
Dec 13, 2022
59cdada
created generic code ex
Dec 13, 2022
0e09faa
test for error_code_condition
Dec 14, 2022
b6edc0f
generic error code bt node
Dec 14, 2022
8f9baff
remove error code condition
Dec 15, 2022
3da4740
updates
Dec 15, 2022
dbec469
updated error code condition
Dec 17, 2022
6354a0c
would a controller recovery help
Dec 17, 2022
b9f9565
rename
Dec 20, 2022
7c4a850
added planner recovery condition
Dec 20, 2022
4df6348
initial draft
Dec 20, 2022
ec0744a
complete with one error code as input
Dec 20, 2022
8d3469c
revert cmake
Dec 20, 2022
4351d39
bt conversion test
Dec 21, 2022
f0d77fc
code review
Dec 21, 2022
f8f9efb
code review
Dec 29, 2022
4f08804
code review
Jan 2, 2023
a1c47ea
refactor behavior tree tests
Jan 4, 2023
478b2ad
cleanup
Jan 4, 2023
2d66b29
final cleanup
Jan 4, 2023
0cfa26f
uncomment
Jan 5, 2023
5bcfcd5
removed logger
Jan 5, 2023
d20f8b8
function header update
Jan 5, 2023
63be7ef
Merge branch 'main' into bt_uses_error_codes
Jan 6, 2023
fc54e30
update bt to include would a planner recovery help
Jan 6, 2023
4184d92
copyright cleanup
Jan 7, 2023
ed22975
added bt node for smoother recovery
Jan 7, 2023
062f3ed
smoother test
Jan 7, 2023
761e8d6
costmap filter test fix
Jan 7, 2023
c5ffdc1
remove include
Jan 9, 2023
8d4a26f
test if commit counted
jwallace42 Jan 9, 2023
d71cd5b
update copyright
jwallace42 Jan 10, 2023
723d38a
code review
jwallace42 Jan 10, 2023
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
6 changes: 6 additions & 0 deletions nav2_behavior_tree/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ list(APPEND plugin_libs nav2_initial_pose_received_condition_bt_node)
add_library(nav2_is_battery_low_condition_bt_node SHARED plugins/condition/is_battery_low_condition.cpp)
list(APPEND plugin_libs nav2_is_battery_low_condition_bt_node)

add_library(nav2_is_error_code_active_condition_bt_node SHARED plugins/condition/is_error_code_active_condition.cpp)
list(APPEND plugin_libs nav2_is_error_code_active_condition_bt_node)

add_library(nav2_would_a_controller_recovery_help_condition_bt_node SHARED plugins/condition/would_a_controller_recovery_help_condition.cpp)
list(APPEND plugin_libs nav2_would_a_controller_recovery_help_condition_bt_node)

add_library(nav2_reinitialize_global_localization_service_bt_node SHARED plugins/action/reinitialize_global_localization_service.cpp)
list(APPEND plugin_libs nav2_reinitialize_global_localization_service_bt_node)

Expand Down
14 changes: 14 additions & 0 deletions nav2_behavior_tree/include/nav2_behavior_tree/bt_conversions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define NAV2_BEHAVIOR_TREE__BT_CONVERSIONS_HPP_

#include <string>
#include <set>

#include "rclcpp/time.hpp"
#include "behaviortree_cpp_v3/behavior_tree.h"
Expand Down Expand Up @@ -111,6 +112,19 @@ inline std::chrono::milliseconds convertFromString<std::chrono::milliseconds>(co
return std::chrono::milliseconds(std::stoul(key.data()));
}

template<>
inline std::set<int> convertFromString(StringView str)
{
// We expect real numbers separated by commas
auto parts = splitString(str, ',');

std::set<int> vec_int;
for (const auto part : parts) {
vec_int.insert(convertFromString<int>(part));
}
return vec_int;
}

} // namespace BT

#endif // NAV2_BEHAVIOR_TREE__BT_CONVERSIONS_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) 2022 Joshua Wallace
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef NAV2_BEHAVIOR_TREE__PLUGINS__CONDITION__IS_ERROR_CODE_ACTIVE_CONDITION_HPP_
#define NAV2_BEHAVIOR_TREE__PLUGINS__CONDITION__IS_ERROR_CODE_ACTIVE_CONDITION_HPP_

#include <string>
#include <memory>
#include <vector>
#include <set>

#include "rclcpp/rclcpp.hpp"
#include "behaviortree_cpp_v3/condition_node.h"

namespace nav2_behavior_tree
{

class IsErrorCodeActive : public BT::ConditionNode
SteveMacenski marked this conversation as resolved.
Show resolved Hide resolved
{
public:
IsErrorCodeActive(
const std::string & condition_name,
const BT::NodeConfiguration & conf)
: BT::ConditionNode(condition_name, conf)
{
getInput<std::set<int>>("error_codes_to_check", error_codes_to_check_);
}

IsErrorCodeActive() = delete;

BT::NodeStatus tick()
SteveMacenski marked this conversation as resolved.
Show resolved Hide resolved
{
getInput<std::set<int>>("current_error_codes", current_error_codes_);

for (const auto & error_code_to_check : error_codes_to_check_) {
if (current_error_codes_.find(error_code_to_check) != current_error_codes_.end()) {
return BT::NodeStatus::SUCCESS;
}
}

return BT::NodeStatus::FAILURE;
}

static BT::PortsList providedPorts()
{
return
{
BT::InputPort<std::set<int>>("current_error_codes"),
BT::InputPort<std::set<int>>("error_codes_to_check")
};
}

protected:
std::set<int> current_error_codes_;
std::set<int> error_codes_to_check_;
};

} // namespace nav2_behavior_tree

#endif // NAV2_BEHAVIOR_TREE__PLUGINS__CONDITION__IS_ERROR_CODE_ACTIVE_CONDITION_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2022 Joshua Wallace
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef NAV2_BEHAVIOR_TREE__PLUGINS__CONDITION__WOULD_A_CONTROLLER_RECOVERY_HELP_CONDITION_HPP_
#define NAV2_BEHAVIOR_TREE__PLUGINS__CONDITION__WOULD_A_CONTROLLER_RECOVERY_HELP_CONDITION_HPP_

#include <string>

#include "nav2_msgs/action/follow_path.hpp"
#include "nav2_behavior_tree/plugins/condition/is_error_code_active_condition.hpp"

namespace nav2_behavior_tree
{

class WouldAControllerRecoveryHelp : public IsErrorCodeActive
{
using Action = nav2_msgs::action::FollowPath;
using ActionGoal = Action::Goal;

public:
WouldAControllerRecoveryHelp(
SteveMacenski marked this conversation as resolved.
Show resolved Hide resolved
const std::string & condition_name,
const BT::NodeConfiguration & conf);

WouldAControllerRecoveryHelp() = delete;
};

} // namespace nav2_behavior_tree
#endif // NAV2_BEHAVIOR_TREE__PLUGINS__CONDITION__WOULD_A_CONTROLLER_RECOVERY_HELP_CONDITION_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2022 Joshua Wallace
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "nav2_behavior_tree/plugins/condition/is_error_code_active_condition.hpp"

#include "behaviortree_cpp_v3/bt_factory.h"
BT_REGISTER_NODES(factory)
{
factory.registerNodeType<nav2_behavior_tree::IsErrorCodeActive>(
"IsErrorCodeActive");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2022 Joshua Wallace
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "nav2_behavior_tree/plugins/condition/would_a_controller_recovery_help_condition.hpp"
#include <memory>

namespace nav2_behavior_tree
{

WouldAControllerRecoveryHelp::WouldAControllerRecoveryHelp(
SteveMacenski marked this conversation as resolved.
Show resolved Hide resolved
const std::string & condition_name,
const BT::NodeConfiguration & conf)
: IsErrorCodeActive(condition_name, conf)
{
error_codes_to_check_ = {
ActionGoal::UNKNOWN,
ActionGoal::PATIENCE_EXCEEDED,
ActionGoal::FAILED_TO_MAKE_PROGRESS,
ActionGoal::NO_VALID_CONTROL
};
}

} // namespace nav2_behavior_tree

#include "behaviortree_cpp_v3/bt_factory.h"
BT_REGISTER_NODES(factory)
{
factory.registerNodeType<nav2_behavior_tree::WouldAControllerRecoveryHelp>(
"WouldAControllerRecoveryHelp");
}
8 changes: 8 additions & 0 deletions nav2_behavior_tree/test/plugins/condition/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,11 @@ ament_target_dependencies(test_condition_is_battery_low ${dependencies})
ament_add_gtest(test_condition_is_path_valid test_is_path_valid.cpp)
target_link_libraries(test_condition_is_path_valid nav2_is_path_valid_condition_bt_node)
ament_target_dependencies(test_condition_is_path_valid ${dependencies})

ament_add_gtest(test_is_error_code_active test_is_error_code_active.cpp)
target_link_libraries(test_is_error_code_active nav2_is_error_code_active_condition_bt_node)
ament_target_dependencies(test_is_error_code_active ${dependencies})

ament_add_gtest(test_would_a_controller_recovery_help test_would_a_controller_recovery_help.cpp)
target_link_libraries(test_would_a_controller_recovery_help nav2_would_a_controller_recovery_help_condition_bt_node)
ament_target_dependencies(test_would_a_controller_recovery_help ${dependencies})
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) 2022 Joshua Wallace
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>
#include <memory>
#include <map>

#include "../../test_behavior_tree_fixture.hpp"
#include "nav2_behavior_tree/plugins/condition/is_error_code_active_condition.hpp"
#include "nav2_msgs/action/follow_path.hpp"

class IsErrorCodeActiveFixture : public nav2_behavior_tree::BehaviorTreeTestFixture
{
public:
using Action = nav2_msgs::action::FollowPath;
using ActionGoal = Action::Goal;
void SetUp()
{
std::set<int> current_error_codes = {ActionGoal::NONE};
std::set<int> error_codes_to_check = {ActionGoal::UNKNOWN};
config_->blackboard->set("current_error_codes", current_error_codes);
config_->blackboard->set("error_codes_to_check", error_codes_to_check);

std::string xml_txt =
R"(
<root main_tree_to_execute = "MainTree" >
<BehaviorTree ID="MainTree">
<IsErrorCodeActive current_error_codes="{current_error_codes}" error_codes_to_check="{error_codes_to_check}"/>
</BehaviorTree>
</root>)";

factory_->registerNodeType<nav2_behavior_tree::IsErrorCodeActive>(
"IsErrorCodeActive");
tree_ = std::make_shared<BT::Tree>(factory_->createTreeFromText(xml_txt, config_->blackboard));
}

void TearDown()
{
tree_.reset();
}

protected:
static std::shared_ptr<BT::Tree> tree_;
};

std::shared_ptr<BT::Tree> IsErrorCodeActiveFixture::tree_ = nullptr;

TEST_F(IsErrorCodeActiveFixture, test_condition)
{
std::map<int, BT::NodeStatus> error_to_status_map = {
{ActionGoal::NONE, BT::NodeStatus::FAILURE},
{ActionGoal::UNKNOWN, BT::NodeStatus::SUCCESS},
};

for (const auto & error_to_status : error_to_status_map) {
std::set<int> error = {error_to_status.first};
config_->blackboard->set("current_error_codes", error);
EXPECT_EQ(tree_->tickRoot(), error_to_status.second);
}
}

int main(int argc, char ** argv)
{
::testing::InitGoogleTest(&argc, argv);

// initialize ROS
rclcpp::init(argc, argv);

bool all_successful = RUN_ALL_TESTS();

// shutdown ROS
rclcpp::shutdown();

return all_successful;
}
Loading