Skip to content

Commit 2cf7618

Browse files
Adding migration instructions for Nav2 ROS Common package upgrades (#712)
* adding migration instructions Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> * precommit Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> * formatting Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> * formatting Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> * final update Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> --------- Signed-off-by: Steve Macenski <stevenmacenski@gmail.com>
1 parent c2ae824 commit 2cf7618

1 file changed

Lines changed: 189 additions & 0 deletions

File tree

migration/Kilted.rst

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,195 @@ Kilted to L-turtle
55

66
Moving from ROS 2 Kilted to L-Turtle, a number of stability improvements were added that we will not specifically address here.
77

8+
New Nav2 ROS Common & Nav2 Lifecycle Node
9+
-----------------------------------------
10+
11+
Starting in Lyrical, a new package ``nav2_ros_common`` was added that contains a set of Nav2, ROS 2 utilities, wrappers, and overrides for working with ROS 2 in Nav2 in a standardized and controllable way.
12+
This ingests previous capabilities from ``nav2_util`` like the ``LifecycleNode`` and ``SimpleActionServer``, but extends it to wrap all ROS 2 interfaces with Nav2 variants in the ``nav2::`` namespace.
13+
The new ``nav2::LifecycleNode``'s factory members (``create_client``, ``create_service``, ``create_publisher``, ``create_subscriber``, ``create_action_server``, and ``create_action_client``) now return these Nav2 objects.
14+
This requires some migration of custom plugins, Task Servers, or other components in the Nav2 styling and/or application that wish to use Nav2's utilities.
15+
Additionally, it contains a set of QoS profiles to be globally used within the stack to give developers complete control over the QoS settings of the system and a one-stop location to update or test different profiles and be applied globally in the stack.
16+
17+
This work is motived by a need to set certain global configurations for interfaces, such as enabling QoS overrides for publishers and subscribers via a run-time parameter and enabling Action and Service introspection.
18+
It also lets us add additional configuration, tracing, advanced features, and wrappers than was previously possible throughout the codebase at large.
19+
20+
The expectation is that all Nav2 nodes and packages use the utilities in this package globally to be consistent and to avoid code duplication.
21+
The lifecycle node includes factories for subscriptions, publishers, clients, and servers that return Nav2 objects in this package rather than the ROS 2 base classes as a level of abstraction of common boilerplate configurations and capabilities.
22+
The factories are listed below:
23+
24+
- `create_client` --> `nav2::ServiceClient`
25+
- `create_service` --> `nav2::ServiceServer`
26+
- `create_publisher` --> `nav2::Publisher`
27+
- `create_subscriber` --> `nav2::Subscriber`
28+
- `create_action_server` --> `nav2::SimpleActionServer`
29+
- `create_action_client` --> `nav2::ActionClient`
30+
31+
`A large-scale migration example can be found here <https://github.com/ros-navigation/navigation2/pull/5288>`_.
32+
33+
In most cases, these are very similar to the previous ``rclcpp`` version.
34+
If a previous ``nav2_util`` version existed, the APIs should be largely the same, except now they should be constructed using the ``create_*`` factory rather than manually to make use of the abstracted configuration settings and advanced features to come.
35+
Where changed, it is typically to move the QoS profile specification to the end of the arguments, which is now optional and defaults to the `nav2::qos::StandardTopicQoS` profile (reliable, volitile, queue depth of 10).
36+
37+
* `nav2_util::LifecycleNode` is now `nav2::LifecycleNode`, which is largely the same except for the factories and a couple of internal implementation details.
38+
* The Service Client, Service Server, and Simple Action Server were also moved to the `nav2::` namespace, but they should not be accessed directly. Use the `create_*` factories from the `nav2::LifecycleNode`, such as `create_action_server` or `create_action_client`.
39+
* There are now `nav2::qos` profiles for QoS to be used in the codebase for homologation and later easier changing: `nav2::qos::StandardTopicQoS` `nav2::qos::LatchedPublisherQoS`, `nav2::qos::LatchedSubscriberQoS` and `nav2::qos::SensorDataQoS`. These should be used rather than `rclcpp` profiles.
40+
* The APIs for `create_*` are very similar to the default ones, but slightly different to move the now optional QoS profile specification below required information. When this is not specified the `StandardTopicQoS` is used (reliable, queue size 10). Only override this if you want another QoS type. Avoid use of `SystemDefaultsQoS`.
41+
42+
Plugin Migration
43+
^^^^^^^^^^^^^^^^
44+
45+
All plugins now use `nav2::LifecycleNode` instead of `rclcpp_lifecycle::LifecycleNode` or `nav2_util::LifecycleNode`.
46+
All must be updated to use this new API from planners and controllers to behavior tree nodes.
47+
Similarly, calls to the `create_*` factories will now point to the Nav2 objects, where applicable.
48+
See above for what those look like and below for a migration from the existing code usage to the new version in order to make use of the new features and API.
49+
50+
Service Client Migration
51+
^^^^^^^^^^^^^^^^^^^^^^^^
52+
53+
We no longer need to create the object manually, nor should we as it bypasses the lifecycle node factories that set introspection and other future features.
54+
We can use the node now to do this instead of passing in a node and we don't need to specify the node type anymore as a template.
55+
All Nav2 servers should use ``nav2::ServiceClient<T>``.
56+
57+
.. code-block:: cpp
58+
59+
// If using rclcpp::Client<T> from previous create_client factor
60+
main_client_ = node->create_client<SrvT>(main_srv_name_, rclcpp::SystemDefaultsQoS(), callback_group_); // Type rclcpp:Client<T>
61+
62+
// If using nav2_util::ServiceClient<T> manually
63+
main_client_ =
64+
std::make_shared<nav2_util::ServiceClient<SrvT>>(
65+
main_srv_name_,
66+
node,
67+
false /* Does not create and spin an internal executor*/); // Type nav2_util::ServiceClient<T>
68+
69+
To:
70+
71+
.. code-block:: cpp
72+
73+
main_client_ = node->create_client<SrvT>(main_srv_name_, false /* Does not create and spin an internal executor*/); // Type nav2::ServiceClient<T>
74+
75+
If migrating from the ``rclcpp::Client<T>`` factory, check out the ``nav2::ServiceClient<T>`` API for its features like ``invoke()`` which wraps the async call and spinning for results using the given node or another internal executor.
76+
You may optionally directly migrate by changing calls from ``async_send_request`` to ``async_call`` and otherwise handle the future in your application code.
77+
78+
Service Server Migration
79+
^^^^^^^^^^^^^^^^^^^^^^^^
80+
81+
Services should now use ``nav2::ServiceServer<T>`` instead of ``rclcpp::Service<T>`` or ``nav2_util::ServiceServer<T>``.
82+
The factory is now available from the node ``create_service(...)``, so we can use that to create the service server.
83+
The callback should now include the ``rmw_request_id_t`` header now, so we have 3 placeholders rather than 2:
84+
85+
.. code-block:: cpp
86+
87+
// If using previous create_service factory
88+
service_ = node->create_service<std_srvs::srv::Trigger>(
89+
std::string(node->get_name()) + "/" + getName() + "/reroute",
90+
std::bind(
91+
&ReroutingService::serviceCb, this,
92+
std::placeholders::_1, std::placeholders::_2)); // type rclcpp::Service<T>
93+
94+
// If using nav2_util::ServiceServer<T> manually
95+
service_ = std::make_shared<nav2_util::ServiceServer<std_srvs::srv::Trigger,
96+
std::shared_ptr<rclcpp_lifecycle::LifecycleNode>>>(
97+
std::string(node->get_name()) + "/" + getName() + "/reroute",
98+
node,
99+
std::bind(
100+
&ReroutingService::serviceCb, this,
101+
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); // type nav2_util::ServiceServer<T>
102+
103+
To
104+
105+
.. code-block:: cpp
106+
107+
service_ = node->create_service<std_srvs::srv::Trigger>(
108+
std::string(node->get_name()) + "/" + getName() + "/reroute",
109+
std::bind(&ReroutingService::serviceCb, this,
110+
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); // type nav2::ServiceServer<T>
111+
112+
No additional changes should be required since the operations are handled in the same way as before.
113+
It now supports service introspection using the parameter ``service_introspection_mode``.
114+
115+
Action Server Migration
116+
^^^^^^^^^^^^^^^^^^^^^^^
117+
118+
We can use the factory now from the node and the node is not required as an argument.
119+
This otherwise does not change.
120+
This is analog to the action server but configures with action introspection and other features that are not available in the base ``rclcpp_action::Server<T>``.
121+
122+
.. code-block:: cpp
123+
124+
compute_and_track_route_server_ = std::make_shared<ComputeAndTrackRouteServer>(
125+
node, "compute_and_track_route",
126+
std::bind(&RouteServer::computeAndTrackRoute, this),
127+
nullptr, std::chrono::milliseconds(500), true); // Type nav2_util::SimpleActionServer<T>
128+
129+
To
130+
131+
.. code-block:: cpp
132+
133+
compute_and_track_route_server_ = create_action_server<ComputeAndTrackRoute>(
134+
"compute_and_track_route",
135+
std::bind(&RouteServer::computeAndTrackRoute, this),
136+
nullptr, std::chrono::milliseconds(500), true); // Type nav2::SimpleActionServer<T>
137+
138+
No additional changes should be required since the operations are handled in the same way as before.
139+
It now supports action request, feedback, and result introspection using the parameter ``service_introspection_mode``.
140+
141+
Action Client Migration
142+
^^^^^^^^^^^^^^^^^^^^^^^
143+
144+
We can use the node now to create an action client using ``create_action_client`` without providing all the node interfaces.
145+
This is analog to the action client but configures with action introspection and other features that are not available in the base ``rclcpp_action::Client<T>``.
146+
147+
.. code-block:: cpp
148+
149+
nav_to_pose_client_ = rclcpp_action::create_client<ClientT>(
150+
get_node_base_interface(),
151+
get_node_graph_interface(),
152+
get_node_logging_interface(),
153+
get_node_waitables_interface(),
154+
"navigate_to_pose", callback_group_); // Type rclcpp_action::Client<T>
155+
156+
To
157+
158+
.. code-block:: cpp
159+
160+
nav_to_pose_client_ = create_action_client<ClientT>(
161+
"navigate_to_pose", callback_group_); // Type nav2::ActionClient<T>
162+
163+
No additional changes should be required since the operations are handled in the same way as before.
164+
It now supports action request, feedback, and result introspection using the parameter ``service_introspection_mode``.
165+
166+
Publisher Subscriber Migration
167+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
168+
169+
To migrate, the order of the arguments in the Subscription must change since the QoS profile is now optional. It is now ``(topic, callback, QoS)`` whereas QoS defaults to the StandardTopicQoS, which is the same as ``rclcpp::QoS`` for the moment.
170+
171+
Publishers that explicitly specify a QoS profile do not require changes, though if the constructor using `depth` is used, it must now specify a policy explicitly.
172+
Both are now ``nav2::Publisher`` and ``nav2::Subscription`` objects that today just typedef the rclcpp and rclcpp_lifecycle versions.
173+
In the future, more features will be added here like lifecycle support for the subscriptions, so its highly recommended as part of this migration to migrate the ``rclcpp::`` to ``nav2::`` as well so those updates are already easily available.
174+
175+
.. code-block:: cpp
176+
177+
plan_publisher_ = create_publisher<nav_msgs::msg::Path>("plan", 1);
178+
plan_publisher_ = create_publisher<nav_msgs::msg::Path>("plan", rclcpp::QoS(), callback_group);
179+
180+
data_sub_ = node->create_subscription<sensor_msgs::msg::Range>(
181+
source_topic, range_qos,
182+
std::bind(&Range::dataCallback, this, std::placeholders::_1));
183+
184+
To
185+
186+
.. code-block:: cpp
187+
188+
plan_publisher_ = create_publisher<nav_msgs::msg::Path>("plan"); // No QoS is required if using the StandardTopicQoS, else it can be provided
189+
190+
data_sub_ = node->create_subscription<sensor_msgs::msg::Range>(
191+
source_topic,
192+
std::bind(&Range::dataCallback, this, std::placeholders::_1)); // QoS can be omitted if using StandardTopicQoS, else it can be provided last
193+
194+
No additional changes should be required since the operations are handled in the same way as before.
195+
Now, it supports future extensions for lifecycle subscriptions or additional wrapper APIs for ease of use.
196+
Additionally, it supports QoS override using the parameter ``allow_parameter_qos_overrides``.
8197

9198
Removed Parameter action_server_result_timeout
10199
**********************************************

0 commit comments

Comments
 (0)