From d3dde9c0cb35f8a2d1bafcefe9c42dcca5548cf5 Mon Sep 17 00:00:00 2001 From: Captain Yoshi Date: Tue, 22 Oct 2024 13:04:21 -0400 Subject: [PATCH 01/15] [refac] replace jump_threshold with precision --- src/create_mtc_cartesian_path.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/create_mtc_cartesian_path.cpp b/src/create_mtc_cartesian_path.cpp index 5a621c3..0267279 100644 --- a/src/create_mtc_cartesian_path.cpp +++ b/src/create_mtc_cartesian_path.cpp @@ -18,23 +18,24 @@ BT::NodeStatus CreateMTCCartesianPath::tick() double max_velocity_scaling_factor; double max_acceleration_scaling_factor; double step_size; - double jump_treshold; double min_fraction; + moveit::core::CartesianPrecision precision; if(!getInput("max_velocity_scaling_factor", max_velocity_scaling_factor) || !getInput("max_acceleration_scaling_factor", max_acceleration_scaling_factor) || !getInput("step_size", step_size) || !getInput("min_fraction", min_fraction) || - !getInput("jump_threshold", jump_treshold)) + !getInput("precision", precision)) return NodeStatus::FAILURE; - //build solver + // Build solver auto solver = std::make_shared(); solver->setMaxVelocityScalingFactor(max_velocity_scaling_factor); solver->setMaxAccelerationScalingFactor(max_acceleration_scaling_factor); solver->setStepSize(step_size); - solver->setJumpThreshold(jump_treshold); solver->setMinFraction(min_fraction); + solver->setPrecision(precision); + // Upcast to base class moveit::task_constructor::solvers::PlannerInterfacePtr base_solver = solver; @@ -47,9 +48,9 @@ BT::PortsList CreateMTCCartesianPath::providedPorts() return { BT::InputPort("max_velocity_scaling_factor", 0.1, "scale down max velocity by this factor"), BT::InputPort("max_acceleration_scaling_factor", 0.1, "scale down max acceleration by this factor"), - BT::InputPort("step_size", 0.01, "step size between consecutive waypoints"), BT::InputPort("min_fraction", 1.0, "fraction of motion required for success"), - BT::InputPort("jump_threshold", 1.5, "acceptable fraction of mean joint motion per step"), + BT::InputPort("precision", moveit::core::CartesianPrecision({ .translational = 0.001, .rotational = 0.01, .max_resolution = 1e-5 }), "linear and rotational precision"), + BT::InputPort("step_size", 0.01, "step size between consecutive waypoints"), BT::OutputPort("solver", "{solver}", "Planner interface using pipeline motion solver"), }; } From 2f957dcd57e3f0f88eba217c0129561004ad8e54 Mon Sep 17 00:00:00 2001 From: Captain Yoshi Date: Tue, 5 Nov 2024 17:14:23 -0500 Subject: [PATCH 02/15] Make MTC planning preemptable (#26) We must stop the planning thread fast when the halt() method is invoked. https://www.behaviortree.dev/docs/guides/asynchronous_nodes#the-problem-with-multi-threading --- include/behaviortree_mtc/plan_mtc_task.h | 7 + src/plan_mtc_task.cpp | 49 +++++- tests/CMakeLists.txt | 8 + tests/gtest_plan_mtc_task.cpp | 57 +++++++ tests/models.cpp | 25 +++ tests/models.h | 15 ++ tests/stage_mockups.cpp | 163 ++++++++++++++++++ tests/stage_mockups.h | 201 +++++++++++++++++++++++ 8 files changed, 521 insertions(+), 4 deletions(-) create mode 100644 tests/gtest_plan_mtc_task.cpp create mode 100644 tests/models.cpp create mode 100644 tests/models.h create mode 100644 tests/stage_mockups.cpp create mode 100644 tests/stage_mockups.h diff --git a/include/behaviortree_mtc/plan_mtc_task.h b/include/behaviortree_mtc/plan_mtc_task.h index da37688..1879eec 100644 --- a/include/behaviortree_mtc/plan_mtc_task.h +++ b/include/behaviortree_mtc/plan_mtc_task.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace BT { namespace MTC { @@ -11,7 +12,13 @@ class PlanMTCTask : public BT::ThreadedAction PlanMTCTask(const std::string& name, const BT::NodeConfig& config); BT::NodeStatus tick() override; + void halt() override; static BT::PortsList providedPorts(); + +private: + moveit::task_constructor::TaskPtr task_; + + std::mutex task_mutex_; }; } // namespace MTC diff --git a/src/plan_mtc_task.cpp b/src/plan_mtc_task.cpp index 3d38db1..2b7f4e8 100644 --- a/src/plan_mtc_task.cpp +++ b/src/plan_mtc_task.cpp @@ -1,7 +1,5 @@ #include -#include - namespace BT { namespace MTC { @@ -11,21 +9,64 @@ PlanMTCTask::PlanMTCTask(const std::string& name, const BT::NodeConfig& config) BT::NodeStatus PlanMTCTask::tick() { + // Inputs const size_t max_solutions = getInput("max_solutions").value(); if(auto any_ptr = getLockedPortContent("task")) { if(auto* task_ptr = any_ptr->castPtr()) { auto& task = *task_ptr; - if(task->plan(max_solutions)) + + // copy task internally { - return NodeStatus::SUCCESS; + std::unique_lock lock{ task_mutex_ }; + task_ = task; } } } + + if(task_) + { + moveit::core::MoveItErrorCode ec; + try + { + task_->resetPreemptRequest(); // should not be needed + ec = task_->plan(max_solutions); + std::cout << ec.toString(ec) << std::endl; + } + catch(moveit::task_constructor::InitStageException e) + { + std::cout << e << std::endl; + return NodeStatus::FAILURE; + } + + { + std::unique_lock lock{ task_mutex_ }; + task_ = nullptr; + } + + if(ec.val == ec.SUCCESS) + return NodeStatus::SUCCESS; + } + return NodeStatus::FAILURE; } +void PlanMTCTask::halt() +{ + { + std::unique_lock lock{ task_mutex_ }; + + if(task_) + { + task_->preempt(); + } + } + + // halt base class + ThreadedAction::halt(); +} + BT::PortsList PlanMTCTask::providedPorts() { return { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 325ec91..c654fb1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,15 +4,23 @@ set(BT_MTC_TESTS gtest_mtc_properties.cpp gtest_mtc_modify_planning_scene.cpp + gtest_plan_mtc_task.cpp ) set(TEST_DEPENDECIES + gtest_utils ${PROJECT_NAME} ) if(CATKIN_ENABLE_TESTING) find_package(rostest REQUIRED) + + + + add_library(gtest_utils models.cpp stage_mockups.cpp) + target_link_libraries(gtest_utils ${PROJECT_NAME}) + catkin_add_gtest(${PROJECT_NAME}_test ${BT_MTC_TESTS}) target_link_libraries(${PROJECT_NAME}_test ${TEST_DEPENDECIES} diff --git a/tests/gtest_plan_mtc_task.cpp b/tests/gtest_plan_mtc_task.cpp new file mode 100644 index 0000000..c9f9734 --- /dev/null +++ b/tests/gtest_plan_mtc_task.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include "stage_mockups.h" +#include "models.h" + +using namespace BT; +using namespace BT::MTC; + +TEST(PlanMTCTask, Preempt) +{ + BT::BehaviorTreeFactory factory; + + // clang-format off + + static const char* xml_text = R"( + + + + +