diff --git a/.circleci/config.yml b/.circleci/config.yml
index 7e6fed842ab..ef14bf0d667 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -75,6 +75,9 @@ references:
rosdep install -q -y \
--from-paths src \
--ignore-src \
+ --skip-keys " \
+ slam_toolbox \
+ " \
--verbose | \
awk '$1 ~ /^resolution\:/' | \
awk -F'[][]' '{print $2}' | \
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index d2d3108e77b..884227ea104 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -11,6 +11,8 @@ For Bug report or feature requests, please fill out the relevant category below
- Operating System:
-
+- ROS2 Version:
+ -
- Version or commit hash:
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nav2_bt_navigator/doc/follow_point.png b/nav2_bt_navigator/doc/follow_point.png
new file mode 100644
index 00000000000..825bc4e16c8
Binary files /dev/null and b/nav2_bt_navigator/doc/follow_point.png differ
diff --git a/nav2_bt_navigator/include/nav2_bt_navigator/bt_navigator.hpp b/nav2_bt_navigator/include/nav2_bt_navigator/bt_navigator.hpp
index 76e63c7d5da..5c87558a2ed 100644
--- a/nav2_bt_navigator/include/nav2_bt_navigator/bt_navigator.hpp
+++ b/nav2_bt_navigator/include/nav2_bt_navigator/bt_navigator.hpp
@@ -82,11 +82,6 @@ class BtNavigator : public nav2_util::LifecycleNode
* @return SUCCESS or FAILURE
*/
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State & state) override;
- /**
- * @brief Called when in error state
- * @param state Reference to LifeCycle node state
- */
- nav2_util::CallbackReturn on_error(const rclcpp_lifecycle::State & state) override;
using Action = nav2_msgs::action::NavigateToPose;
diff --git a/nav2_bt_navigator/package.xml b/nav2_bt_navigator/package.xml
index bf8ead1cf38..433ac40fdc6 100644
--- a/nav2_bt_navigator/package.xml
+++ b/nav2_bt_navigator/package.xml
@@ -2,7 +2,7 @@
nav2_bt_navigator
- 0.4.1
+ 0.4.2
TODO
Michael Jeronimo
Apache-2.0
diff --git a/nav2_bt_navigator/src/bt_navigator.cpp b/nav2_bt_navigator/src/bt_navigator.cpp
index f0c063c79a6..fcb761322c6 100644
--- a/nav2_bt_navigator/src/bt_navigator.cpp
+++ b/nav2_bt_navigator/src/bt_navigator.cpp
@@ -51,6 +51,8 @@ BtNavigator::BtNavigator()
"nav2_rate_controller_bt_node",
"nav2_distance_controller_bt_node",
"nav2_speed_controller_bt_node",
+ "nav2_truncate_path_action_bt_node",
+ "nav2_change_goal_node_bt_node",
"nav2_recovery_node_bt_node",
"nav2_pipeline_sequence_bt_node",
"nav2_round_robin_node_bt_node",
@@ -206,6 +208,7 @@ BtNavigator::on_cleanup(const rclcpp_lifecycle::State & /*state*/)
action_server_.reset();
plugin_lib_names_.clear();
+ current_bt_xml_filename_.clear();
blackboard_.reset();
bt_->haltAllActions(tree_.rootNode());
bt_.reset();
@@ -214,13 +217,6 @@ BtNavigator::on_cleanup(const rclcpp_lifecycle::State & /*state*/)
return nav2_util::CallbackReturn::SUCCESS;
}
-nav2_util::CallbackReturn
-BtNavigator::on_error(const rclcpp_lifecycle::State & /*state*/)
-{
- RCLCPP_FATAL(get_logger(), "Lifecycle node entered error state");
- return nav2_util::CallbackReturn::SUCCESS;
-}
-
nav2_util::CallbackReturn
BtNavigator::on_shutdown(const rclcpp_lifecycle::State & /*state*/)
{
@@ -247,6 +243,19 @@ BtNavigator::navigateToPose()
return action_server_->is_cancel_requested();
};
+ auto bt_xml_filename = action_server_->get_current_goal()->behavior_tree;
+
+ // Empty id in request is default for backward compatibility
+ bt_xml_filename = bt_xml_filename == "" ? default_bt_xml_filename_ : bt_xml_filename;
+
+ if (!loadBehaviorTree(bt_xml_filename)) {
+ RCLCPP_ERROR(
+ get_logger(), "BT file not found: %s. Navigation canceled",
+ bt_xml_filename.c_str(), current_bt_xml_filename_.c_str());
+ action_server_->terminate_current();
+ return;
+ }
+
RosTopicLogger topic_logger(client_node_, tree_);
std::shared_ptr feedback_msg = std::make_shared();
@@ -276,19 +285,6 @@ BtNavigator::navigateToPose()
action_server_->publish_feedback(feedback_msg);
};
- auto bt_xml_filename = action_server_->get_current_goal()->behavior_tree;
-
- // Empty id in request is default for backward compatibility
- bt_xml_filename = bt_xml_filename == "" ? default_bt_xml_filename_ : bt_xml_filename;
-
- if (!loadBehaviorTree(bt_xml_filename)) {
- RCLCPP_ERROR(
- get_logger(), "BT file not found: %s. Navigation canceled",
- bt_xml_filename.c_str(), current_bt_xml_filename_.c_str());
- action_server_->terminate_current();
- return;
- }
-
// Execute the BT that was previously created in the configure step
nav2_behavior_tree::BtStatus rc = bt_->run(&tree_, on_loop, is_canceling);
// Make sure that the Bt is not in a running state from a previous execution
@@ -310,9 +306,6 @@ BtNavigator::navigateToPose()
RCLCPP_INFO(get_logger(), "Navigation canceled");
action_server_->terminate_all();
break;
-
- default:
- throw std::logic_error("Invalid status return from BT");
}
}
diff --git a/nav2_common/package.xml b/nav2_common/package.xml
index f51ddff6659..6820a84f4fa 100644
--- a/nav2_common/package.xml
+++ b/nav2_common/package.xml
@@ -2,7 +2,7 @@
nav2_common
- 0.4.1
+ 0.4.2
Common support functionality used throughout the navigation 2 stack
Carl Delsey
Apache-2.0
diff --git a/nav2_controller/CMakeLists.txt b/nav2_controller/CMakeLists.txt
index b4cb1b50d03..5ca5a22605c 100644
--- a/nav2_controller/CMakeLists.txt
+++ b/nav2_controller/CMakeLists.txt
@@ -4,6 +4,7 @@ project(nav2_controller)
find_package(ament_cmake REQUIRED)
find_package(nav2_core REQUIRED)
find_package(nav2_common REQUIRED)
+find_package(angles REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_action REQUIRED)
find_package(std_msgs REQUIRED)
@@ -29,12 +30,12 @@ set(library_name ${executable_name}_core)
add_library(${library_name}
src/nav2_controller.cpp
- src/progress_checker.cpp
)
target_compile_definitions(${library_name} PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
set(dependencies
+ angles
rclcpp
rclcpp_action
std_msgs
@@ -46,6 +47,22 @@ set(dependencies
pluginlib
)
+add_library(simple_progress_checker SHARED plugins/simple_progress_checker.cpp)
+ament_target_dependencies(simple_progress_checker ${dependencies})
+# prevent pluginlib from using boost
+target_compile_definitions(simple_progress_checker PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
+
+add_library(simple_goal_checker SHARED plugins/simple_goal_checker.cpp)
+ament_target_dependencies(simple_goal_checker ${dependencies})
+# prevent pluginlib from using boost
+target_compile_definitions(simple_goal_checker PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
+
+add_library(stopped_goal_checker SHARED plugins/stopped_goal_checker.cpp)
+target_link_libraries(stopped_goal_checker simple_goal_checker)
+ament_target_dependencies(stopped_goal_checker ${dependencies})
+# prevent pluginlib from using boost
+target_compile_definitions(stopped_goal_checker PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
+
ament_target_dependencies(${library_name}
${dependencies}
)
@@ -53,13 +70,23 @@ ament_target_dependencies(${library_name}
# prevent pluginlib from using boost
target_compile_definitions(${library_name} PUBLIC "PLUGINLIB__DISABLE_BOOST_FUNCTIONS")
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ # the following line skips the linter which checks for copyrights
+ set(ament_cmake_copyright_FOUND TRUE)
+ ament_lint_auto_find_test_dependencies()
+
+ find_package(ament_cmake_gtest REQUIRED)
+ add_subdirectory(plugins/test)
+endif()
+
ament_target_dependencies(${executable_name}
${dependencies}
)
target_link_libraries(${executable_name} ${library_name})
-install(TARGETS ${library_name}
+install(TARGETS simple_progress_checker simple_goal_checker stopped_goal_checker ${library_name}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
@@ -79,6 +106,10 @@ if(BUILD_TESTING)
endif()
ament_export_include_directories(include)
-ament_export_libraries(${library_name})
+ament_export_libraries(simple_progress_checker
+ simple_goal_checker
+ stopped_goal_checker
+ ${library_name})
+pluginlib_export_plugin_description_file(nav2_core plugins.xml)
ament_package()
diff --git a/nav2_controller/include/nav2_controller/nav2_controller.hpp b/nav2_controller/include/nav2_controller/nav2_controller.hpp
index b0b28b462a1..f59b65b9999 100644
--- a/nav2_controller/include/nav2_controller/nav2_controller.hpp
+++ b/nav2_controller/include/nav2_controller/nav2_controller.hpp
@@ -22,6 +22,8 @@
#include
#include "nav2_core/controller.hpp"
+#include "nav2_core/progress_checker.hpp"
+#include "nav2_core/goal_checker.hpp"
#include "nav2_costmap_2d/costmap_2d_ros.hpp"
#include "tf2_ros/transform_listener.h"
#include "nav2_msgs/action/follow_path.hpp"
@@ -100,12 +102,6 @@ class ControllerServer : public nav2_util::LifecycleNode
* @return Success or Failure
*/
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State & state) override;
- /**
- * @brief Called when in Error state
- * @param state LifeCycle Node's state
- * @return Success or Failure
- */
- nav2_util::CallbackReturn on_error(const rclcpp_lifecycle::State & state) override;
using Action = nav2_msgs::action::FollowPath;
using ActionServer = nav2_util::SimpleActionServer;
@@ -201,6 +197,22 @@ class ControllerServer : public nav2_util::LifecycleNode
std::unique_ptr odom_sub_;
rclcpp_lifecycle::LifecyclePublisher::SharedPtr vel_publisher_;
+ // Progress Checker Plugin
+ pluginlib::ClassLoader progress_checker_loader_;
+ nav2_core::ProgressChecker::Ptr progress_checker_;
+ std::string default_progress_checker_id_;
+ std::string default_progress_checker_type_;
+ std::string progress_checker_id_;
+ std::string progress_checker_type_;
+
+ // Goal Checker Plugin
+ pluginlib::ClassLoader goal_checker_loader_;
+ nav2_core::GoalChecker::Ptr goal_checker_;
+ std::string default_goal_checker_id_;
+ std::string default_goal_checker_type_;
+ std::string goal_checker_id_;
+ std::string goal_checker_type_;
+
// Controller Plugins
pluginlib::ClassLoader lp_loader_;
ControllerMap controllers_;
@@ -210,15 +222,12 @@ class ControllerServer : public nav2_util::LifecycleNode
std::vector controller_types_;
std::string controller_ids_concat_, current_controller_;
- std::unique_ptr progress_checker_;
-
double controller_frequency_;
double min_x_velocity_threshold_;
double min_y_velocity_threshold_;
double min_theta_velocity_threshold_;
// Whether we've published the single controller warning yet
- bool single_controller_warning_given_{false};
geometry_msgs::msg::Pose end_pose_;
};
diff --git a/nav2_dwb_controller/dwb_plugins/include/dwb_plugins/simple_goal_checker.hpp b/nav2_controller/include/nav2_controller/plugins/simple_goal_checker.hpp
similarity index 92%
rename from nav2_dwb_controller/dwb_plugins/include/dwb_plugins/simple_goal_checker.hpp
rename to nav2_controller/include/nav2_controller/plugins/simple_goal_checker.hpp
index 697a0dc10e4..b7e483c1611 100644
--- a/nav2_dwb_controller/dwb_plugins/include/dwb_plugins/simple_goal_checker.hpp
+++ b/nav2_controller/include/nav2_controller/plugins/simple_goal_checker.hpp
@@ -32,8 +32,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DWB_PLUGINS__SIMPLE_GOAL_CHECKER_HPP_
-#define DWB_PLUGINS__SIMPLE_GOAL_CHECKER_HPP_
+#ifndef NAV2_CONTROLLER__PLUGINS__SIMPLE_GOAL_CHECKER_HPP_
+#define NAV2_CONTROLLER__PLUGINS__SIMPLE_GOAL_CHECKER_HPP_
#include
#include
@@ -42,7 +42,7 @@
#include "rclcpp_lifecycle/lifecycle_node.hpp"
#include "nav2_core/goal_checker.hpp"
-namespace dwb_plugins
+namespace nav2_controller
{
/**
@@ -72,6 +72,6 @@ class SimpleGoalChecker : public nav2_core::GoalChecker
double xy_goal_tolerance_sq_;
};
-} // namespace dwb_plugins
+} // namespace nav2_controller
-#endif // DWB_PLUGINS__SIMPLE_GOAL_CHECKER_HPP_
+#endif // NAV2_CONTROLLER__PLUGINS__SIMPLE_GOAL_CHECKER_HPP_
diff --git a/nav2_controller/include/nav2_controller/progress_checker.hpp b/nav2_controller/include/nav2_controller/plugins/simple_progress_checker.hpp
similarity index 63%
rename from nav2_controller/include/nav2_controller/progress_checker.hpp
rename to nav2_controller/include/nav2_controller/plugins/simple_progress_checker.hpp
index 3d754ad7aa2..92a5374a5e0 100644
--- a/nav2_controller/include/nav2_controller/progress_checker.hpp
+++ b/nav2_controller/include/nav2_controller/plugins/simple_progress_checker.hpp
@@ -12,40 +12,32 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef NAV2_CONTROLLER__PROGRESS_CHECKER_HPP_
-#define NAV2_CONTROLLER__PROGRESS_CHECKER_HPP_
+#ifndef NAV2_CONTROLLER__PLUGINS__SIMPLE_PROGRESS_CHECKER_HPP_
+#define NAV2_CONTROLLER__PLUGINS__SIMPLE_PROGRESS_CHECKER_HPP_
+#include
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_lifecycle/lifecycle_node.hpp"
+#include "nav2_core/progress_checker.hpp"
#include "geometry_msgs/msg/pose_stamped.hpp"
#include "geometry_msgs/msg/pose2_d.hpp"
namespace nav2_controller
{
/**
- * @class nav2_controller::ProgressChecker
- * @brief This class is used to check the position of the robot to make sure
- * that it is actually progressing towards a goal.
- */
-class ProgressChecker
+* @class SimpleProgressChecker
+* @brief This plugin is used to check the position of the robot to make sure
+* that it is actually progressing towards a goal.
+*/
+
+class SimpleProgressChecker : public nav2_core::ProgressChecker
{
public:
- /**
- * @brief Constructor of ProgressChecker
- * @param node Node pointer
- */
- explicit ProgressChecker(const rclcpp_lifecycle::LifecycleNode::SharedPtr & node);
- /**
- * @brief Checks if the robot has moved compare to previous
- * pose
- * @param current_pose Current pose of the robot
- * @throw nav2_core::PlannerException when failed to make progress
- */
- void check(geometry_msgs::msg::PoseStamped & current_pose);
- /**
- * @brief Reset class state upon calling
- */
- void reset() {baseline_pose_set_ = false;}
+ void initialize(
+ const rclcpp_lifecycle::LifecycleNode::SharedPtr & node,
+ const std::string & plugin_name) override;
+ bool check(geometry_msgs::msg::PoseStamped & current_pose) override;
+ void reset() override;
protected:
/**
@@ -72,4 +64,4 @@ class ProgressChecker
};
} // namespace nav2_controller
-#endif // NAV2_CONTROLLER__PROGRESS_CHECKER_HPP_
+#endif // NAV2_CONTROLLER__PLUGINS__SIMPLE_PROGRESS_CHECKER_HPP_
diff --git a/nav2_dwb_controller/dwb_plugins/include/dwb_plugins/stopped_goal_checker.hpp b/nav2_controller/include/nav2_controller/plugins/stopped_goal_checker.hpp
similarity index 88%
rename from nav2_dwb_controller/dwb_plugins/include/dwb_plugins/stopped_goal_checker.hpp
rename to nav2_controller/include/nav2_controller/plugins/stopped_goal_checker.hpp
index 23f727d9456..869edb6330b 100644
--- a/nav2_dwb_controller/dwb_plugins/include/dwb_plugins/stopped_goal_checker.hpp
+++ b/nav2_controller/include/nav2_controller/plugins/stopped_goal_checker.hpp
@@ -32,17 +32,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DWB_PLUGINS__STOPPED_GOAL_CHECKER_HPP_
-#define DWB_PLUGINS__STOPPED_GOAL_CHECKER_HPP_
+#ifndef NAV2_CONTROLLER__PLUGINS__STOPPED_GOAL_CHECKER_HPP_
+#define NAV2_CONTROLLER__PLUGINS__STOPPED_GOAL_CHECKER_HPP_
#include
#include
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_lifecycle/lifecycle_node.hpp"
-#include "dwb_plugins/simple_goal_checker.hpp"
+#include "nav2_controller/plugins/simple_goal_checker.hpp"
-namespace dwb_plugins
+namespace nav2_controller
{
/**
@@ -65,6 +65,6 @@ class StoppedGoalChecker : public SimpleGoalChecker
double rot_stopped_velocity_, trans_stopped_velocity_;
};
-} // namespace dwb_plugins
+} // namespace nav2_controller
-#endif // DWB_PLUGINS__STOPPED_GOAL_CHECKER_HPP_
+#endif // NAV2_CONTROLLER__PLUGINS__STOPPED_GOAL_CHECKER_HPP_
diff --git a/nav2_controller/package.xml b/nav2_controller/package.xml
index c678de23c75..d0c6bbf7763 100644
--- a/nav2_controller/package.xml
+++ b/nav2_controller/package.xml
@@ -2,13 +2,14 @@
nav2_controller
- 0.4.1
+ 0.4.2
Controller action interface
Carl Delsey
Apache-2.0
ament_cmake
nav2_common
+ angles
rclcpp
rclcpp_action
std_msgs
@@ -24,5 +25,6 @@
ament_cmake
+
diff --git a/nav2_controller/plugins.xml b/nav2_controller/plugins.xml
new file mode 100644
index 00000000000..ad27127c03d
--- /dev/null
+++ b/nav2_controller/plugins.xml
@@ -0,0 +1,17 @@
+
+
+
+ Checks if distance between current and previous pose is above a threshold
+
+
+
+
+ Checks if current pose is within goal window for x,y and yaw
+
+
+
+
+ Checks linear and angular velocity after stopping
+
+
+
diff --git a/nav2_dwb_controller/dwb_plugins/src/simple_goal_checker.cpp b/nav2_controller/plugins/simple_goal_checker.cpp
similarity index 94%
rename from nav2_dwb_controller/dwb_plugins/src/simple_goal_checker.cpp
rename to nav2_controller/plugins/simple_goal_checker.cpp
index b108b551989..f1ec7dba6ca 100644
--- a/nav2_dwb_controller/dwb_plugins/src/simple_goal_checker.cpp
+++ b/nav2_controller/plugins/simple_goal_checker.cpp
@@ -34,7 +34,7 @@
#include
#include
-#include "dwb_plugins/simple_goal_checker.hpp"
+#include "nav2_controller/plugins/simple_goal_checker.hpp"
#include "pluginlib/class_list_macros.hpp"
#include "angles/angles.h"
#include "nav2_util/node_utils.hpp"
@@ -43,7 +43,7 @@
#include "tf2/utils.h"
#pragma GCC diagnostic pop
-namespace dwb_plugins
+namespace nav2_controller
{
SimpleGoalChecker::SimpleGoalChecker()
@@ -103,6 +103,6 @@ bool SimpleGoalChecker::isGoalReached(
return fabs(dyaw) < yaw_goal_tolerance_;
}
-} // namespace dwb_plugins
+} // namespace nav2_controller
-PLUGINLIB_EXPORT_CLASS(dwb_plugins::SimpleGoalChecker, nav2_core::GoalChecker)
+PLUGINLIB_EXPORT_CLASS(nav2_controller::SimpleGoalChecker, nav2_core::GoalChecker)
diff --git a/nav2_controller/src/progress_checker.cpp b/nav2_controller/plugins/simple_progress_checker.cpp
similarity index 65%
rename from nav2_controller/src/progress_checker.cpp
rename to nav2_controller/plugins/simple_progress_checker.cpp
index 68fe96de50c..498d13256cb 100644
--- a/nav2_controller/src/progress_checker.cpp
+++ b/nav2_controller/plugins/simple_progress_checker.cpp
@@ -12,33 +12,37 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "nav2_controller/progress_checker.hpp"
+#include "nav2_controller/plugins/simple_progress_checker.hpp"
#include
+#include
#include "nav2_core/exceptions.hpp"
#include "nav_2d_utils/conversions.hpp"
#include "geometry_msgs/msg/pose_stamped.hpp"
#include "geometry_msgs/msg/pose2_d.hpp"
#include "nav2_util/node_utils.hpp"
+#include "pluginlib/class_list_macros.hpp"
namespace nav2_controller
{
static double pose_distance(const geometry_msgs::msg::Pose2D &, const geometry_msgs::msg::Pose2D &);
-ProgressChecker::ProgressChecker(const rclcpp_lifecycle::LifecycleNode::SharedPtr & node)
-: nh_(node)
+void SimpleProgressChecker::initialize(
+ const rclcpp_lifecycle::LifecycleNode::SharedPtr & node,
+ const std::string & plugin_name)
{
+ nh_ = node;
nav2_util::declare_parameter_if_not_declared(
- nh_, "required_movement_radius", rclcpp::ParameterValue(0.5));
+ nh_, plugin_name + ".required_movement_radius", rclcpp::ParameterValue(0.5));
nav2_util::declare_parameter_if_not_declared(
- nh_, "movement_time_allowance", rclcpp::ParameterValue(10.0));
+ nh_, plugin_name + ".movement_time_allowance", rclcpp::ParameterValue(10.0));
// Scale is set to 0 by default, so if it was not set otherwise, set to 0
- nh_->get_parameter_or("required_movement_radius", radius_, 0.5);
+ nh_->get_parameter_or(plugin_name + ".required_movement_radius", radius_, 0.5);
double time_allowance_param = 0.0;
- nh_->get_parameter_or("movement_time_allowance", time_allowance_param, 10.0);
+ nh_->get_parameter_or(plugin_name + ".movement_time_allowance", time_allowance_param, 10.0);
time_allowance_ = rclcpp::Duration::from_seconds(time_allowance_param);
}
-void ProgressChecker::check(geometry_msgs::msg::PoseStamped & current_pose)
+bool SimpleProgressChecker::check(geometry_msgs::msg::PoseStamped & current_pose)
{
// relies on short circuit evaluation to not call is_robot_moved_enough if
// baseline_pose is not set.
@@ -47,21 +51,27 @@ void ProgressChecker::check(geometry_msgs::msg::PoseStamped & current_pose)
if ((!baseline_pose_set_) || (is_robot_moved_enough(current_pose2d))) {
reset_baseline_pose(current_pose2d);
- return;
+ return true;
}
if ((nh_->now() - baseline_time_) > time_allowance_) {
- throw nav2_core::PlannerException("Failed to make progress");
+ return false;
}
+ return true;
+}
+
+void SimpleProgressChecker::reset()
+{
+ baseline_pose_set_ = false;
}
-void ProgressChecker::reset_baseline_pose(const geometry_msgs::msg::Pose2D & pose)
+void SimpleProgressChecker::reset_baseline_pose(const geometry_msgs::msg::Pose2D & pose)
{
baseline_pose_ = pose;
baseline_time_ = nh_->now();
baseline_pose_set_ = true;
}
-bool ProgressChecker::is_robot_moved_enough(const geometry_msgs::msg::Pose2D & pose)
+bool SimpleProgressChecker::is_robot_moved_enough(const geometry_msgs::msg::Pose2D & pose)
{
if (pose_distance(pose, baseline_pose_) > radius_) {
return true;
@@ -81,3 +91,5 @@ static double pose_distance(
}
} // namespace nav2_controller
+
+PLUGINLIB_EXPORT_CLASS(nav2_controller::SimpleProgressChecker, nav2_core::ProgressChecker)
diff --git a/nav2_dwb_controller/dwb_plugins/src/stopped_goal_checker.cpp b/nav2_controller/plugins/stopped_goal_checker.cpp
similarity index 93%
rename from nav2_dwb_controller/dwb_plugins/src/stopped_goal_checker.cpp
rename to nav2_controller/plugins/stopped_goal_checker.cpp
index c94948e8967..2e24ad181aa 100644
--- a/nav2_dwb_controller/dwb_plugins/src/stopped_goal_checker.cpp
+++ b/nav2_controller/plugins/stopped_goal_checker.cpp
@@ -35,14 +35,14 @@
#include
#include
#include
-#include "dwb_plugins/stopped_goal_checker.hpp"
+#include "nav2_controller/plugins/stopped_goal_checker.hpp"
#include "pluginlib/class_list_macros.hpp"
#include "nav2_util/node_utils.hpp"
using std::hypot;
using std::fabs;
-namespace dwb_plugins
+namespace nav2_controller
{
StoppedGoalChecker::StoppedGoalChecker()
@@ -80,6 +80,6 @@ bool StoppedGoalChecker::isGoalReached(
hypot(velocity.linear.x, velocity.linear.y) <= trans_stopped_velocity_;
}
-} // namespace dwb_plugins
+} // namespace nav2_controller
-PLUGINLIB_EXPORT_CLASS(dwb_plugins::StoppedGoalChecker, nav2_core::GoalChecker)
+PLUGINLIB_EXPORT_CLASS(nav2_controller::StoppedGoalChecker, nav2_core::GoalChecker)
diff --git a/nav2_controller/plugins/test/CMakeLists.txt b/nav2_controller/plugins/test/CMakeLists.txt
new file mode 100644
index 00000000000..d4f34d3918f
--- /dev/null
+++ b/nav2_controller/plugins/test/CMakeLists.txt
@@ -0,0 +1,4 @@
+ament_add_gtest(pctest progress_checker.cpp)
+target_link_libraries(pctest simple_progress_checker)
+ament_add_gtest(gctest goal_checker.cpp)
+target_link_libraries(gctest simple_goal_checker stopped_goal_checker)
diff --git a/nav2_dwb_controller/dwb_plugins/test/goal_checker.cpp b/nav2_controller/plugins/test/goal_checker.cpp
similarity index 94%
rename from nav2_dwb_controller/dwb_plugins/test/goal_checker.cpp
rename to nav2_controller/plugins/test/goal_checker.cpp
index 3e5b5e0357b..fe175db4450 100644
--- a/nav2_dwb_controller/dwb_plugins/test/goal_checker.cpp
+++ b/nav2_controller/plugins/test/goal_checker.cpp
@@ -36,13 +36,13 @@
#include
#include "gtest/gtest.h"
-#include "dwb_plugins/simple_goal_checker.hpp"
-#include "dwb_plugins/stopped_goal_checker.hpp"
+#include "nav2_controller/plugins/simple_goal_checker.hpp"
+#include "nav2_controller/plugins/stopped_goal_checker.hpp"
#include "nav_2d_utils/conversions.hpp"
#include "nav2_util/lifecycle_node.hpp"
-using dwb_plugins::SimpleGoalChecker;
-using dwb_plugins::StoppedGoalChecker;
+using nav2_controller::SimpleGoalChecker;
+using nav2_controller::StoppedGoalChecker;
void checkMacro(
nav2_core::GoalChecker & gc,
@@ -151,8 +151,8 @@ TEST(VelocityIterator, two_checks)
SimpleGoalChecker gc;
StoppedGoalChecker sgc;
- gc.initialize(x, "dwb");
- sgc.initialize(x, "dwb");
+ gc.initialize(x, "nav2_controller");
+ sgc.initialize(x, "nav2_controller");
sameResult(gc, sgc, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
sameResult(gc, sgc, 0, 0, 0, 1, 0, 0, 0, 0, 0, false);
sameResult(gc, sgc, 0, 0, 0, 0, 1, 0, 0, 0, 0, false);
diff --git a/nav2_controller/plugins/test/progress_checker.cpp b/nav2_controller/plugins/test/progress_checker.cpp
new file mode 100644
index 00000000000..418ff1032ae
--- /dev/null
+++ b/nav2_controller/plugins/test/progress_checker.cpp
@@ -0,0 +1,135 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ * Copyright (c) 2017, Locus Robotics
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include
+#include
+
+#include "gtest/gtest.h"
+#include "nav2_controller/plugins/simple_progress_checker.hpp"
+#include "nav_2d_utils/conversions.hpp"
+#include "nav2_util/lifecycle_node.hpp"
+
+using nav2_controller::SimpleProgressChecker;
+
+class TestLifecycleNode : public nav2_util::LifecycleNode
+{
+public:
+ explicit TestLifecycleNode(const std::string & name)
+ : nav2_util::LifecycleNode(name)
+ {
+ }
+
+ nav2_util::CallbackReturn on_configure(const rclcpp_lifecycle::State &)
+ {
+ return nav2_util::CallbackReturn::SUCCESS;
+ }
+
+ nav2_util::CallbackReturn on_activate(const rclcpp_lifecycle::State &)
+ {
+ return nav2_util::CallbackReturn::SUCCESS;
+ }
+
+ nav2_util::CallbackReturn on_deactivate(const rclcpp_lifecycle::State &)
+ {
+ return nav2_util::CallbackReturn::SUCCESS;
+ }
+
+ nav2_util::CallbackReturn on_cleanup(const rclcpp_lifecycle::State &)
+ {
+ return nav2_util::CallbackReturn::SUCCESS;
+ }
+
+ nav2_util::CallbackReturn onShutdown(const rclcpp_lifecycle::State &)
+ {
+ return nav2_util::CallbackReturn::SUCCESS;
+ }
+
+ nav2_util::CallbackReturn onError(const rclcpp_lifecycle::State &)
+ {
+ return nav2_util::CallbackReturn::SUCCESS;
+ }
+};
+
+void checkMacro(
+ nav2_core::ProgressChecker & pc,
+ double x0, double y0,
+ double x1, double y1,
+ int delay,
+ bool expected_result)
+{
+ pc.reset();
+ geometry_msgs::msg::PoseStamped pose0, pose1;
+ pose0.pose.position.x = x0;
+ pose0.pose.position.y = y0;
+ pose1.pose.position.x = x1;
+ pose1.pose.position.y = y1;
+ EXPECT_TRUE(pc.check(pose0));
+ rclcpp::sleep_for(std::chrono::seconds(delay));
+ if (expected_result) {
+ EXPECT_TRUE(pc.check(pose1));
+ } else {
+ EXPECT_FALSE(pc.check(pose1));
+ }
+}
+
+TEST(SimpleProgressChecker, progress_checker_reset)
+{
+ auto x = std::make_shared("progress_checker");
+
+ nav2_core::ProgressChecker * pc = new SimpleProgressChecker;
+ pc->reset();
+ delete pc;
+ EXPECT_TRUE(true);
+}
+
+TEST(SimpleProgressChecker, unit_tests)
+{
+ auto x = std::make_shared("progress_checker");
+
+ SimpleProgressChecker pc;
+ pc.initialize(x, "nav2_controller");
+ checkMacro(pc, 0, 0, 0, 0, 1, true);
+ checkMacro(pc, 0, 0, 1, 0, 1, true);
+ checkMacro(pc, 0, 0, 0, 1, 1, true);
+ checkMacro(pc, 0, 0, 1, 0, 11, true);
+ checkMacro(pc, 0, 0, 0, 1, 11, true);
+ checkMacro(pc, 0, 0, 0, 0, 11, false);
+}
+
+int main(int argc, char ** argv)
+{
+ rclcpp::init(argc, argv);
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/nav2_controller/src/nav2_controller.cpp b/nav2_controller/src/nav2_controller.cpp
index fc7c36e2737..97846ba8eee 100644
--- a/nav2_controller/src/nav2_controller.cpp
+++ b/nav2_controller/src/nav2_controller.cpp
@@ -22,7 +22,6 @@
#include "nav_2d_utils/conversions.hpp"
#include "nav2_util/node_utils.hpp"
#include "nav2_util/geometry_utils.hpp"
-#include "nav2_controller/progress_checker.hpp"
#include "nav2_controller/nav2_controller.hpp"
using namespace std::chrono_literals;
@@ -32,6 +31,12 @@ namespace nav2_controller
ControllerServer::ControllerServer()
: LifecycleNode("controller_server", "", true),
+ progress_checker_loader_("nav2_core", "nav2_core::ProgressChecker"),
+ default_progress_checker_id_{"progress_checker"},
+ default_progress_checker_type_{"nav2_controller::SimpleProgressChecker"},
+ goal_checker_loader_("nav2_core", "nav2_core::GoalChecker"),
+ default_goal_checker_id_{"goal_checker"},
+ default_goal_checker_type_{"nav2_controller::SimpleGoalChecker"},
lp_loader_("nav2_core", "nav2_core::Controller"),
default_ids_{"FollowPath"},
default_types_{"dwb_core::DWBLocalPlanner"}
@@ -40,6 +45,8 @@ ControllerServer::ControllerServer()
declare_parameter("controller_frequency", 20.0);
+ declare_parameter("progress_checker_plugin", default_progress_checker_id_);
+ declare_parameter("goal_checker_plugin", default_goal_checker_id_);
declare_parameter("controller_plugins", default_ids_);
declare_parameter("min_x_velocity_threshold", rclcpp::ParameterValue(0.0001));
declare_parameter("min_y_velocity_threshold", rclcpp::ParameterValue(0.0001));
@@ -61,12 +68,29 @@ ControllerServer::~ControllerServer()
nav2_util::CallbackReturn
ControllerServer::on_configure(const rclcpp_lifecycle::State & state)
{
+ auto node = shared_from_this();
+
RCLCPP_INFO(get_logger(), "Configuring controller interface");
+ get_parameter("progress_checker_plugin", progress_checker_id_);
+ if (progress_checker_id_ == default_progress_checker_id_) {
+ nav2_util::declare_parameter_if_not_declared(
+ node, default_progress_checker_id_ + ".plugin",
+ rclcpp::ParameterValue(default_progress_checker_type_));
+ }
+ get_parameter("goal_checker_plugin", goal_checker_id_);
+ if (goal_checker_id_ == default_goal_checker_id_) {
+ nav2_util::declare_parameter_if_not_declared(
+ node, default_goal_checker_id_ + ".plugin",
+ rclcpp::ParameterValue(default_goal_checker_type_));
+ }
+
get_parameter("controller_plugins", controller_ids_);
if (controller_ids_ == default_ids_) {
for (size_t i = 0; i < default_ids_.size(); ++i) {
- declare_parameter(default_ids_[i] + ".plugin", default_types_[i]);
+ nav2_util::declare_parameter_if_not_declared(
+ node, default_ids_[i] + ".plugin",
+ rclcpp::ParameterValue(default_types_[i]));
}
}
controller_types_.resize(controller_ids_.size());
@@ -79,9 +103,30 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & state)
costmap_ros_->on_configure(state);
- auto node = shared_from_this();
-
- progress_checker_ = std::make_unique(node);
+ try {
+ progress_checker_type_ = nav2_util::get_plugin_type_param(node, progress_checker_id_);
+ progress_checker_ = progress_checker_loader_.createUniqueInstance(progress_checker_type_);
+ RCLCPP_INFO(
+ get_logger(), "Created progress_checker : %s of type %s",
+ progress_checker_id_.c_str(), progress_checker_type_.c_str());
+ progress_checker_->initialize(node, progress_checker_id_);
+ } catch (const pluginlib::PluginlibException & ex) {
+ RCLCPP_FATAL(
+ get_logger(),
+ "Failed to create progress_checker. Exception: %s", ex.what());
+ }
+ try {
+ goal_checker_type_ = nav2_util::get_plugin_type_param(node, goal_checker_id_);
+ goal_checker_ = goal_checker_loader_.createUniqueInstance(goal_checker_type_);
+ RCLCPP_INFO(
+ get_logger(), "Created goal_checker : %s of type %s",
+ goal_checker_id_.c_str(), goal_checker_type_.c_str());
+ goal_checker_->initialize(node, goal_checker_id_);
+ } catch (const pluginlib::PluginlibException & ex) {
+ RCLCPP_FATAL(
+ get_logger(),
+ "Failed to create goal_checker. Exception: %s", ex.what());
+ }
for (size_t i = 0; i != controller_ids_.size(); i++) {
try {
@@ -96,8 +141,9 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & state)
costmap_ros_->getTfBuffer(), costmap_ros_);
controllers_.insert({controller_ids_[i], controller});
} catch (const pluginlib::PluginlibException & ex) {
- RCLCPP_FATAL(get_logger(), "Failed to create controller. Exception: %s", ex.what());
- exit(-1);
+ RCLCPP_FATAL(
+ get_logger(),
+ "Failed to create controller. Exception: %s", ex.what());
}
}
@@ -105,6 +151,10 @@ ControllerServer::on_configure(const rclcpp_lifecycle::State & state)
controller_ids_concat_ += controller_ids_[i] + std::string(" ");
}
+ RCLCPP_INFO(
+ get_logger(),
+ "Controller Server has %s controllers available.", controller_ids_concat_.c_str());
+
odom_sub_ = std::make_unique(node);
vel_publisher_ = create_publisher("cmd_vel", 1);
@@ -165,24 +215,14 @@ ControllerServer::on_cleanup(const rclcpp_lifecycle::State & state)
// Release any allocated resources
action_server_.reset();
- for (it = controllers_.begin(); it != controllers_.end(); ++it) {
- it->second.reset();
- }
odom_sub_.reset();
-
vel_publisher_.reset();
action_server_.reset();
+ goal_checker_->reset();
return nav2_util::CallbackReturn::SUCCESS;
}
-nav2_util::CallbackReturn
-ControllerServer::on_error(const rclcpp_lifecycle::State &)
-{
- RCLCPP_FATAL(get_logger(), "Lifecycle node entered error state");
- return nav2_util::CallbackReturn::SUCCESS;
-}
-
nav2_util::CallbackReturn
ControllerServer::on_shutdown(const rclcpp_lifecycle::State &)
{
@@ -196,13 +236,10 @@ bool ControllerServer::findControllerId(
{
if (controllers_.find(c_name) == controllers_.end()) {
if (controllers_.size() == 1 && c_name.empty()) {
- if (!single_controller_warning_given_) {
- RCLCPP_WARN(
- get_logger(), "No controller was specified in action call."
- " Server will use only plugin loaded %s. "
- "This warning will appear once.", controller_ids_concat_.c_str());
- single_controller_warning_given_ = true;
- }
+ RCLCPP_WARN_ONCE(
+ get_logger(), "No controller was specified in action call."
+ " Server will use only plugin loaded %s. "
+ "This warning will appear once.", controller_ids_concat_.c_str());
current_controller = controllers_.begin()->first;
} else {
RCLCPP_ERROR(
@@ -212,6 +249,7 @@ bool ControllerServer::findControllerId(
return false;
}
} else {
+ RCLCPP_DEBUG(get_logger(), "Selected controller: %s.", c_name.c_str());
current_controller = c_name;
}
@@ -237,13 +275,8 @@ void ControllerServer::computeControl()
rclcpp::Rate loop_rate(controller_frequency_);
while (rclcpp::ok()) {
- if (action_server_ == nullptr) {
- RCLCPP_DEBUG(get_logger(), "Action server unavailable. Stopping.");
- return;
- }
-
- if (!action_server_->is_server_active()) {
- RCLCPP_DEBUG(get_logger(), "Action server is inactive. Stopping.");
+ if (action_server_ == nullptr || !action_server_->is_server_active()) {
+ RCLCPP_DEBUG(get_logger(), "Action server unavailable or inactive. Stopping.");
return;
}
@@ -276,7 +309,7 @@ void ControllerServer::computeControl()
return;
}
- RCLCPP_DEBUG(get_logger(), "DWB succeeded, setting result");
+ RCLCPP_DEBUG(get_logger(), "Controller succeeded, setting result");
publishZeroVelocity();
@@ -294,7 +327,8 @@ void ControllerServer::setPlannerPath(const nav_msgs::msg::Path & path)
}
controllers_[current_controller_]->setPlan(path);
- auto end_pose = *(path.poses.end() - 1);
+ auto end_pose = path.poses.back();
+ goal_checker_->reset();
RCLCPP_DEBUG(
get_logger(), "Path end point is (%.2f, %.2f)",
@@ -310,7 +344,9 @@ void ControllerServer::computeAndPublishVelocity()
throw nav2_core::PlannerException("Failed to obtain robot pose");
}
- progress_checker_->check(pose);
+ if (!progress_checker_->check(pose)) {
+ throw nav2_core::PlannerException("Failed to make progress");
+ }
nav_2d_msgs::msg::Twist2D twist = getThresholdedTwist(odom_sub_->getTwist());
@@ -350,7 +386,12 @@ void ControllerServer::updateGlobalPath()
void ControllerServer::publishVelocity(const geometry_msgs::msg::TwistStamped & velocity)
{
auto cmd_vel = std::make_unique(velocity.twist);
- vel_publisher_->publish(std::move(cmd_vel));
+ if (
+ vel_publisher_->is_activated() &&
+ this->count_subscribers(vel_publisher_->get_topic_name()) > 0)
+ {
+ vel_publisher_->publish(std::move(cmd_vel));
+ }
}
void ControllerServer::publishZeroVelocity()
@@ -362,6 +403,8 @@ void ControllerServer::publishZeroVelocity()
velocity.twist.linear.x = 0;
velocity.twist.linear.y = 0;
velocity.twist.linear.z = 0;
+ velocity.header.frame_id = costmap_ros_->getBaseFrameID();
+ velocity.header.stamp = now();
publishVelocity(velocity);
}
@@ -375,14 +418,13 @@ bool ControllerServer::isGoalReached()
nav_2d_msgs::msg::Twist2D twist = getThresholdedTwist(odom_sub_->getTwist());
geometry_msgs::msg::Twist velocity = nav_2d_utils::twist2Dto3D(twist);
- return controllers_[current_controller_]->isGoalReached(pose, velocity);
+ return goal_checker_->isGoalReached(pose.pose, end_pose_, velocity);
}
bool ControllerServer::getRobotPose(geometry_msgs::msg::PoseStamped & pose)
{
geometry_msgs::msg::PoseStamped current_pose;
if (!costmap_ros_->getRobotPose(current_pose)) {
- RCLCPP_ERROR(this->get_logger(), "Could not get robot pose");
return false;
}
pose = current_pose;
diff --git a/nav2_core/include/nav2_core/controller.hpp b/nav2_core/include/nav2_core/controller.hpp
index 1e6e98052c3..69aa10f25b0 100644
--- a/nav2_core/include/nav2_core/controller.hpp
+++ b/nav2_core/include/nav2_core/controller.hpp
@@ -112,20 +112,6 @@ class Controller
virtual geometry_msgs::msg::TwistStamped computeVelocityCommands(
const geometry_msgs::msg::PoseStamped & pose,
const geometry_msgs::msg::Twist & velocity) = 0;
-
- /**
- * @brief Controller isGoalReached - Check whether the robot has reached its goal, given the current pose & velocity.
- *
- * The pose that it checks against is the last pose in the current global plan.
- * The calculation is delegated to the goal_checker plugin.
- *
- * @param pose Current pose
- * @param velocity Current velocity
- * @return True if the robot should be considered as having reached the goal.
- */
- virtual bool isGoalReached(
- const geometry_msgs::msg::PoseStamped & pose,
- const geometry_msgs::msg::Twist & velocity) = 0;
};
} // namespace nav2_core
diff --git a/nav2_core/include/nav2_core/progress_checker.hpp b/nav2_core/include/nav2_core/progress_checker.hpp
new file mode 100644
index 00000000000..2dd9c5bef89
--- /dev/null
+++ b/nav2_core/include/nav2_core/progress_checker.hpp
@@ -0,0 +1,62 @@
+// Copyright (c) 2019 Intel Corporation
+//
+// 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_CORE__PROGRESS_CHECKER_HPP_
+#define NAV2_CORE__PROGRESS_CHECKER_HPP_
+
+#include
+#include
+
+#include "rclcpp/rclcpp.hpp"
+#include "rclcpp_lifecycle/lifecycle_node.hpp"
+#include "geometry_msgs/msg/pose_stamped.hpp"
+#include "geometry_msgs/msg/pose2_d.hpp"
+
+namespace nav2_core
+{
+/**
+ * @class nav2_core::ProgressChecker
+ * @brief This class defines the plugin interface used to check the
+ * position of the robot to make sure that it is actually progressing
+ * towards a goal.
+ */
+class ProgressChecker
+{
+public:
+ typedef std::shared_ptr Ptr;
+
+ virtual ~ProgressChecker() {}
+
+ /**
+ * @brief Initialize parameters for ProgressChecker
+ * @param node Node pointer
+ */
+ virtual void initialize(
+ const rclcpp_lifecycle::LifecycleNode::SharedPtr & node,
+ const std::string & plugin_name) = 0;
+ /**
+ * @brief Checks if the robot has moved compare to previous
+ * pose
+ * @param current_pose Current pose of the robot
+ * @return True if progress is made
+ */
+ virtual bool check(geometry_msgs::msg::PoseStamped & current_pose) = 0;
+ /**
+ * @brief Reset class state upon calling
+ */
+ virtual void reset() = 0;
+};
+} // namespace nav2_core
+
+#endif // NAV2_CORE__PROGRESS_CHECKER_HPP_
diff --git a/nav2_core/package.xml b/nav2_core/package.xml
index d9e50dcd9cb..2ae59bc25ad 100644
--- a/nav2_core/package.xml
+++ b/nav2_core/package.xml
@@ -2,7 +2,7 @@
nav2_core
- 0.4.1
+ 0.4.2
A set of headers for plugins core to the navigation2 stack
Steve Macenski
Carl Delsey
diff --git a/nav2_costmap_2d/CMakeLists.txt b/nav2_costmap_2d/CMakeLists.txt
index d7508415edf..4c9a2a93666 100644
--- a/nav2_costmap_2d/CMakeLists.txt
+++ b/nav2_costmap_2d/CMakeLists.txt
@@ -22,6 +22,7 @@ find_package(tf2 REQUIRED)
find_package(tf2_ros REQUIRED)
find_package(tf2_sensor_msgs REQUIRED)
find_package(visualization_msgs REQUIRED)
+find_package(angles REQUIRED)
remove_definitions(-DDISABLE_LIBUSB-1.0)
find_package(Eigen3 REQUIRED)
@@ -72,6 +73,7 @@ set(dependencies
tf2_ros
tf2_sensor_msgs
visualization_msgs
+ angles
)
ament_target_dependencies(nav2_costmap_2d_core
@@ -84,6 +86,7 @@ add_library(layers SHARED
plugins/obstacle_layer.cpp
src/observation_buffer.cpp
plugins/voxel_layer.cpp
+ plugins/range_sensor_layer.cpp
)
ament_target_dependencies(layers
${dependencies}
diff --git a/nav2_costmap_2d/costmap_plugins.xml b/nav2_costmap_2d/costmap_plugins.xml
index 62bfac732b9..a0725392332 100644
--- a/nav2_costmap_2d/costmap_plugins.xml
+++ b/nav2_costmap_2d/costmap_plugins.xml
@@ -12,6 +12,9 @@
Similar to obstacle costmap, but uses 3D voxel grid to store data.
+
+ A range-sensor (sonar, IR) based obstacle layer for costmap_2d
+
diff --git a/nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp b/nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp
index 5524f5737d3..541a246a513 100644
--- a/nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp
+++ b/nav2_costmap_2d/include/nav2_costmap_2d/costmap_2d_ros.hpp
@@ -97,7 +97,6 @@ class Costmap2DROS : public nav2_util::LifecycleNode
nav2_util::CallbackReturn on_deactivate(const rclcpp_lifecycle::State & state) override;
nav2_util::CallbackReturn on_cleanup(const rclcpp_lifecycle::State & state) override;
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State & state) override;
- nav2_util::CallbackReturn on_error(const rclcpp_lifecycle::State & state) override;
/**
* @brief Subscribes to sensor topics if necessary and starts costmap
diff --git a/nav2_costmap_2d/include/nav2_costmap_2d/range_sensor_layer.hpp b/nav2_costmap_2d/include/nav2_costmap_2d/range_sensor_layer.hpp
new file mode 100644
index 00000000000..ce2861599d7
--- /dev/null
+++ b/nav2_costmap_2d/include/nav2_costmap_2d/range_sensor_layer.hpp
@@ -0,0 +1,138 @@
+/*
+ * Software License Agreement (BSD License)
+ *
+ * Copyright (c) 2018 David V. Lu!!
+ * Copyright (c) 2020, Bytes Robotics
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NAV2_COSTMAP_2D__RANGE_SENSOR_LAYER_HPP_
+#define NAV2_COSTMAP_2D__RANGE_SENSOR_LAYER_HPP_
+
+#include
+#include
+#include
+#include
+
+#include "map_msgs/msg/occupancy_grid_update.hpp"
+#include "message_filters/subscriber.h"
+#include "nav2_costmap_2d/costmap_layer.hpp"
+#include "nav2_costmap_2d/layered_costmap.hpp"
+#include "nav_msgs/msg/occupancy_grid.hpp"
+#include "rclcpp/rclcpp.hpp"
+#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
+#include "sensor_msgs/msg/range.hpp"
+
+namespace nav2_costmap_2d
+{
+
+class RangeSensorLayer : public CostmapLayer
+{
+public:
+ enum class InputSensorType
+ {
+ VARIABLE,
+ FIXED,
+ ALL
+ };
+
+ RangeSensorLayer();
+
+ virtual void onInitialize();
+ virtual void updateBounds(
+ double robot_x, double robot_y, double robot_yaw,
+ double * min_x, double * min_y, double * max_x, double * max_y);
+ virtual void updateCosts(
+ nav2_costmap_2d::Costmap2D & master_grid, int min_i,
+ int min_j, int max_i, int max_j);
+ virtual void reset();
+ virtual void deactivate();
+ virtual void activate();
+
+ void bufferIncomingRangeMsg(const sensor_msgs::msg::Range::SharedPtr range_message);
+
+private:
+ void updateCostmap();
+ void updateCostmap(sensor_msgs::msg::Range & range_message, bool clear_sensor_cone);
+
+ void processRangeMsg(sensor_msgs::msg::Range & range_message);
+ void processFixedRangeMsg(sensor_msgs::msg::Range & range_message);
+ void processVariableRangeMsg(sensor_msgs::msg::Range & range_message);
+
+ void resetRange();
+
+ inline double gamma(double theta);
+ inline double delta(double phi);
+ inline double sensor_model(double r, double phi, double theta);
+
+ inline void get_deltas(double angle, double * dx, double * dy);
+ inline void update_cell(
+ double ox, double oy, double ot,
+ double r, double nx, double ny, bool clear);
+
+ inline double to_prob(unsigned char c)
+ {
+ return static_cast(c) / nav2_costmap_2d::LETHAL_OBSTACLE;
+ }
+ inline unsigned char to_cost(double p)
+ {
+ return static_cast(p * nav2_costmap_2d::LETHAL_OBSTACLE);
+ }
+
+ std::function processRangeMessageFunc_;
+ std::mutex range_message_mutex_;
+ std::list range_msgs_buffer_;
+
+ double max_angle_, phi_v_;
+ double inflate_cone_;
+ std::string global_frame_;
+
+ double clear_threshold_, mark_threshold_;
+ bool clear_on_max_reading_;
+
+ tf2::Duration transform_tolerance_;
+ double no_readings_timeout_;
+ rclcpp::Time last_reading_time_;
+ unsigned int buffered_readings_;
+ std::vector::SharedPtr> range_subs_;
+ double min_x_, min_y_, max_x_, max_y_;
+
+ float area(int x1, int y1, int x2, int y2, int x3, int y3)
+ {
+ return fabs((x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2.0);
+ }
+
+ int orient2d(int Ax, int Ay, int Bx, int By, int Cx, int Cy)
+ {
+ return (Bx - Ax) * (Cy - Ay) - (By - Ay) * (Cx - Ax);
+ }
+};
+} // namespace nav2_costmap_2d
+#endif // NAV2_COSTMAP_2D__RANGE_SENSOR_LAYER_HPP_
diff --git a/nav2_costmap_2d/include/nav2_costmap_2d/static_layer.hpp b/nav2_costmap_2d/include/nav2_costmap_2d/static_layer.hpp
index f6f01e8c563..bbd5daa757e 100644
--- a/nav2_costmap_2d/include/nav2_costmap_2d/static_layer.hpp
+++ b/nav2_costmap_2d/include/nav2_costmap_2d/static_layer.hpp
@@ -111,6 +111,8 @@ class StaticLayer : public CostmapLayer
bool trinary_costmap_;
bool map_received_{false};
tf2::Duration transform_tolerance_;
+ std::atomic update_in_progress_;
+ nav_msgs::msg::OccupancyGrid::SharedPtr map_buffer_;
};
} // namespace nav2_costmap_2d
diff --git a/nav2_costmap_2d/package.xml b/nav2_costmap_2d/package.xml
index 7ca65cc7c2f..02f6c7fd9db 100644
--- a/nav2_costmap_2d/package.xml
+++ b/nav2_costmap_2d/package.xml
@@ -2,7 +2,7 @@
nav2_costmap_2d
- 0.4.1
+ 0.4.2
This package provides an implementation of a 2D costmap that takes in sensor
data from the world, builds a 2D or 3D occupancy grid of the data (depending
diff --git a/nav2_costmap_2d/plugins/inflation_layer.cpp b/nav2_costmap_2d/plugins/inflation_layer.cpp
index 86561d334b3..df8405a3c91 100644
--- a/nav2_costmap_2d/plugins/inflation_layer.cpp
+++ b/nav2_costmap_2d/plugins/inflation_layer.cpp
@@ -40,6 +40,8 @@
#include
#include