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

Add nav2_gps_waypoint_follower #2111

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5f33ac5
Add nav2_gps_waypoint_follower
jediofgever Dec 1, 2020
277c1e1
use correct client node while calling it to spin
jediofgever Dec 2, 2020
c6ee437
changed after 1'st review
jediofgever Dec 4, 2020
7b6f8cf
apply requested changes
jediofgever Dec 7, 2020
ac94d2d
nav2_util::ServiceClient instead of CallbackGroup
jediofgever Dec 7, 2020
cd9a287
another iteration to adress issues
jediofgever Dec 8, 2020
9c0e408
update poses with function in the follower logic
jediofgever Dec 8, 2020
f94e3b3
add deps of robot_localization: diagnostics
jediofgever Dec 8, 2020
e4fe184
fix typo in underlay.repo
jediofgever Dec 8, 2020
c2f4d95
add deps of robot_localization: geographic_info
jediofgever Dec 8, 2020
98804f1
minor clean-ups
jediofgever Dec 8, 2020
e95f55a
merge ros-planning::navigation2::main into jediofgever::navigation2::…
jediofgever Dec 9, 2020
960bb13
bond_core version has been updated
jediofgever Dec 9, 2020
623c6a6
rotation should also be considered in GPS WPFing
jediofgever Dec 14, 2020
ef57df0
use better namings related to gps wpf orientation
jediofgever Dec 14, 2020
063b8e7
handle cpplint errors
jediofgever Dec 14, 2020
e544fde
tf_listener needs to be initialized
jediofgever Dec 15, 2020
84c7ef0
apply requested changes
jediofgever Dec 17, 2020
d2c4127
apply requested changes 2.5/3.0
jediofgever Dec 17, 2020
aee13ca
apply requested changes 3.0/3.0
jediofgever Dec 17, 2020
4f83167
fix misplaced ";"
jediofgever Dec 17, 2020
6e322ea
use run time param for gps transform timeout
jediofgever Dec 18, 2020
81c7c64
change timeout var name
jediofgever Dec 18, 2020
7c69520
make use of stop_on_failure for GPS too
jediofgever Dec 21, 2020
7889ae3
passing emptywaypont vectors are seen as failure
jediofgever Dec 23, 2020
c28b93e
pull changes from ros-planing::navigation2::main
jediofgever Jan 5, 2021
c6613a8
update warning for empty requests
jediofgever Jan 8, 2021
0d0d59c
get upstream changes
jediofgever Jan 23, 2021
d7e2ad4
consider utm -> map yaw offset
jediofgever Jan 23, 2021
d6527d2
fix missed RCLCPP info
jediofgever Jan 23, 2021
f99ebff
reorrect action;s name
jediofgever Jan 23, 2021
e0a3aa6
get mainstream changes
jediofgever Mar 18, 2021
5fcfb83
waypoint stamps need to be updated
jediofgever Mar 19, 2021
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
1 change: 1 addition & 0 deletions doc/parameters/param_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ When `planner_plugins` parameter is not overridden, the following default plugin
| ----------| --------| ------------|
| stop_on_failure | true | Whether to fail action task if a single waypoint fails. If false, will continue to next waypoint. |
| loop_rate | 20 | Rate to check for results from current navigation task |
| transform_tolerance | 0.1 | Amount of time in seconds to wait before a timeout exception is thrown while transforming a GPS waypoint form `utm` frame to `map ` frame. |
| waypoint_task_executor_plugin | `waypoint_task_executor` | Name of plugin to be loaded for executing waypoint tasks.|

## WaitAtWaypoint plugin
Expand Down
1 change: 1 addition & 0 deletions nav2_bringup/bringup/params/nav2_params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ waypoint_follower:
ros__parameters:
loop_rate: 20
stop_on_failure: false
transform_tolerance: 0.1
waypoint_task_executor_plugin: "wait_at_waypoint"
wait_at_waypoint:
plugin: "nav2_waypoint_follower::WaitAtWaypoint"
Expand Down
5 changes: 4 additions & 1 deletion nav2_msgs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ find_package(nav_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(std_msgs REQUIRED)
find_package(sensor_msgs)
find_package(action_msgs REQUIRED)

nav2_package()
Expand All @@ -21,6 +22,7 @@ rosidl_generate_interfaces(${PROJECT_NAME}
"msg/BehaviorTreeLog.msg"
"msg/Particle.msg"
"msg/ParticleCloud.msg"
"msg/OrientedNavSatFix.msg"
"srv/GetCostmap.srv"
"srv/ClearCostmapExceptRegion.srv"
"srv/ClearCostmapAroundRobot.srv"
Expand All @@ -36,7 +38,8 @@ rosidl_generate_interfaces(${PROJECT_NAME}
"action/Spin.action"
"action/DummyRecovery.action"
"action/FollowWaypoints.action"
DEPENDENCIES builtin_interfaces geometry_msgs std_msgs action_msgs nav_msgs
"action/FollowGPSWaypoints.action"
DEPENDENCIES builtin_interfaces geometry_msgs std_msgs action_msgs nav_msgs sensor_msgs
)

ament_export_dependencies(rosidl_default_runtime)
Expand Down
8 changes: 8 additions & 0 deletions nav2_msgs/action/FollowGPSWaypoints.action
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#goal definition
nav2_msgs/OrientedNavSatFix[] gps_poses
---
#result definition
int32[] missed_waypoints
---
#feedback
uint32 current_waypoint
2 changes: 2 additions & 0 deletions nav2_msgs/msg/OrientedNavSatFix.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sensor_msgs/NavSatFix position
geometry_msgs/Quaternion orientation
1 change: 1 addition & 0 deletions nav2_msgs/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<depend>geometry_msgs</depend>
<depend>action_msgs</depend>
<depend>nav_msgs</depend>
<depend>sensor_msgs</depend>

<member_of_group>rosidl_interface_packages</member_of_group>

Expand Down
5 changes: 5 additions & 0 deletions nav2_waypoint_follower/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 3.5)
project(nav2_waypoint_follower)

# Default to C++17
set(CMAKE_CXX_STANDARD 17)

# Try for OpenCV 4.X, but settle for whatever is installed
find_package(OpenCV 4 QUIET)
if(NOT OpenCV_FOUND)
Expand All @@ -21,6 +24,7 @@ find_package(nav2_util REQUIRED)
find_package(tf2_ros REQUIRED)
find_package(nav2_core REQUIRED)
find_package(pluginlib REQUIRED)
find_package(robot_localization REQUIRED)
SteveMacenski marked this conversation as resolved.
Show resolved Hide resolved
SteveMacenski marked this conversation as resolved.
Show resolved Hide resolved

nav2_package()

Expand Down Expand Up @@ -53,6 +57,7 @@ set(dependencies
image_transport
cv_bridge
OpenCV
robot_localization
)

ament_target_dependencies(${executable_name}
Expand Down
19 changes: 19 additions & 0 deletions nav2_waypoint_follower/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,22 @@ In the first, the ``nav2_waypoint_follower`` is fully sufficient to create a pro
In the second, the ``nav2_waypoint_follower`` is a nice sample application / proof of concept, but you really need your waypoint following / autonomy system on the robot to carry more weight in making a robust solution. In this case, you should use the ``nav2_behavior_tree`` package to create a custom application-level behavior tree using navigation to complete the task. This can include subtrees like checking for the charge status mid-task for returning to dock or handling more than 1 unit of work in a more complex task. Soon, there will be a ``nav2_bt_waypoint_follower`` (name subject to adjustment) that will allow you to create this application more easily. In this school of thought, the waypoint following application is more closely tied to the system autonomy, or in many cases, is the system autonomy.
Copy link
Member

@SteveMacenski SteveMacenski Dec 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need any new parameters or actions exposed by the waypoint follower added to the navigation.ros.org website configuration docs. Also adding a node in the migration guide that WP follower now does GPS in the Foxy migration guide. The WP follower configuration page should also add a paragraph on top with the basic package description mentioning GPS waypoint following now. That's part of another documentation PR, just FYI. You don't need to do this right now, we can wait until this is ready.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, lets make this PR good enough to merge then navigation.ros.org will be next


Neither is better than the other, it highly depends on the tasks your robot(s) are completing, in what type of environment, and with what cloud resources available. Often this distinction is very clear for a given business case.

## Nav2 GPS Waypoint Follower
jediofgever marked this conversation as resolved.
Show resolved Hide resolved

`nav2_waypoint_follower` provides an action server named `FollowGPSWaypoints` which accepts GPS waypoint following requests by using tools provided by `robot_localization` and `nav2_waypoint_follower` itself.

`robot_localization`'s `navsat_transform_node` provides a service `fromLL`, which is used to convert pure GPS coordinates(longitude, latitude, alitude)
to cartesian coordinates in map frame(x,y), then the existent action named `FollowWaypoints` from `nav2_waypoint_follower` is used to get robot go through each converted waypoints.
The action msg definition for GPS waypoint following can be found [here](https://github.com/ros-planning/navigation2/blob/main/nav2_msgs/action/FollowGPSWaypoints.action).

In a common use case, an client node can read a set of GPS waypoints from a YAML file an create a client to action server named as `FollowGPSWaypoints`.
For instance,

```cpp
using ClientT = nav2_msgs::action::FollowGPSWaypoints;
rclcpp_action::Client<ClientT>::SharedPtr gps_waypoint_follower_action_client_;
gps_waypoint_follower_action_client_ = rclcpp_action::create_client<ClientT>(this, "FollowGPSWaypoints");
```

All other functionalities provided by `nav2_waypoint_follower` such as WaypointTaskExecutors are usable and can be configured in WaypointTaskExecutor.
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,24 @@
#include <string>
#include <vector>

#include "rclcpp_action/rclcpp_action.hpp"
#include "pluginlib/class_loader.hpp"
#include "pluginlib/class_list_macros.hpp"
#include "nav2_msgs/msg/oriented_nav_sat_fix.hpp"
#include "nav2_util/lifecycle_node.hpp"
#include "nav2_msgs/action/navigate_to_pose.hpp"
#include "nav2_msgs/action/follow_waypoints.hpp"
#include "nav_msgs/msg/path.hpp"
#include "nav2_util/simple_action_server.hpp"
#include "rclcpp_action/rclcpp_action.hpp"

#include "nav2_util/node_utils.hpp"
#include "nav2_msgs/action/follow_gps_waypoints.hpp"
#include "nav2_util/service_client.hpp"
#include "nav2_core/waypoint_task_executor.hpp"
#include "pluginlib/class_loader.hpp"
#include "pluginlib/class_list_macros.hpp"

#include "robot_localization/srv/from_ll.hpp"
#include "tf2_ros/buffer.h"
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
#include "tf2_ros/transform_listener.h"

namespace nav2_waypoint_follower
{
Expand All @@ -55,6 +62,10 @@ class WaypointFollower : public nav2_util::LifecycleNode
using ActionServer = nav2_util::SimpleActionServer<ActionT>;
using ActionClient = rclcpp_action::Client<ClientT>;

// Shorten the types for GPS waypoint following
using ActionTGPS = nav2_msgs::action::FollowGPSWaypoints;
using ActionServerGPS = nav2_util::SimpleActionServer<ActionTGPS>;

/**
* @brief A constructor for nav2_waypoint_follower::WaypointFollower class
*/
Expand Down Expand Up @@ -98,32 +109,87 @@ class WaypointFollower : public nav2_util::LifecycleNode
*/
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State & state) override;

/**
* @brief Templated function to perform internal logic behind waypoint following,
* Both GPS and non GPS waypoint following callbacks makes use of this function when a client asked to do so.
* Callbacks fills in appropriate types for the tempelated types, see followWaypointCallback funtions for details.
*
* @tparam T action_server
* @tparam V feedback
* @tparam Z result
* @param action_server
* @param poses
* @param feedback
* @param result
*/
template<typename T, typename V, typename Z>
void followWaypointsLogic(
const T & action_server,
const V & feedback,
const Z & result);

/**
* @brief Action server callbacks
*/
void followWaypoints();
void followWaypointsCallback();

/**
* @brief Action client result callback
* @param result Result of action server updated asynchronously
* @brief send robot through each of GPS
* point , which are converted to map frame first then using a client to
* `FollowWaypoints` action.
*
* @param waypoints, acquired from action client
*/
void resultCallback(const rclcpp_action::ClientGoalHandle<ClientT>::WrappedResult & result);
void followGPSWaypointsCallback();

/**
* @brief Action client result callback
* @param result Result of action server updated asynchronously
*/
template<typename T>
void resultCallback(const T & result);

/**
* @brief Action client goal response callback
* @param goal Response of action server updated asynchronously
*/
void goalResponseCallback(const rclcpp_action::ClientGoalHandle<ClientT>::SharedPtr & goal);
template<typename T>
void goalResponseCallback(const T & goal);

/**
* @brief given some gps_poses, converts them to map frame using robot_localization's service `fromLL`.
* Constructs a vector of stamped poses in map frame and returns them.
*
* @param gps_poses
* @param parent_node
* @param fromll_client
* @return std::vector<geometry_msgs::msg::PoseStamped>
*/
std::vector<geometry_msgs::msg::PoseStamped> convertGPSPoses2MapPoses(
const std::vector<nav2_msgs::msg::OrientedNavSatFix> & gps_poses,
const rclcpp_lifecycle::LifecycleNode::SharedPtr & parent_node,
const
std::unique_ptr<nav2_util::ServiceClient<robot_localization::srv::FromLL>> & fromll_client);

template<typename T>
std::vector<geometry_msgs::msg::PoseStamped> getLatestGoalPoses(const T & action_server);

// Common vars used for both GPS and cartesian point following
rclcpp::Node::SharedPtr client_node_;
std::vector<int> failed_ids_;
int loop_rate_;
bool stop_on_failure_;

// Our action server
// Our action server for waypoint following
std::unique_ptr<ActionServer> action_server_;
ActionClient::SharedPtr nav_to_pose_client_;
rclcpp::Node::SharedPtr client_node_;
std::shared_future<rclcpp_action::ClientGoalHandle<ClientT>::SharedPtr> future_goal_handle_;
bool stop_on_failure_;
ActionStatus current_goal_status_;
int loop_rate_;
std::vector<int> failed_ids_;

// Our action server for GPS waypoint following
std::unique_ptr<ActionServerGPS> gps_action_server_;
std::unique_ptr<nav2_util::ServiceClient<robot_localization::srv::FromLL>> from_ll_to_map_client_;
double transform_tolerance_;

// Task Execution At Waypoint Plugin
pluginlib::ClassLoader<nav2_core::WaypointTaskExecutor>
Expand All @@ -132,6 +198,10 @@ class WaypointFollower : public nav2_util::LifecycleNode
waypoint_task_executor_;
std::string waypoint_task_executor_id_;
std::string waypoint_task_executor_type_;

// tf buffer to get transfroms
std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
std::shared_ptr<tf2_ros::TransformListener> tf_listener_;
};

} // namespace nav2_waypoint_follower
Expand Down
3 changes: 2 additions & 1 deletion nav2_waypoint_follower/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
<depend>nav2_util</depend>
<depend>nav2_core</depend>
<depend>tf2_ros</depend>

<depend>robot_localization</depend>

<test_depend>ament_lint_common</test_depend>
<test_depend>ament_lint_auto</test_depend>

Expand Down
Loading