Compare commits

..

36 Commits

Author SHA1 Message Date
Alejandro Hernandez Cordero
4551b69f6e 29.5.6 2025-12-23 11:22:23 +01:00
Alejandro Hernandez Cordero
785b45a2fc Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-12-23 11:22:17 +01:00
mergify[bot]
c5b427c2ec Unified Node Interfaces: Add const version of get_node_x_interface() (#3006) (#3008)
(cherry picked from commit 825b4e4650)

Signed-off-by: Fabian Hirmann <f.hirmann@arti-robots.com>
Co-authored-by: fabianhirmann <117293434+fabianhirmann@users.noreply.github.com>
2025-12-18 22:21:01 +01:00
Tomoya Fujita
3ce946f6e9 remove I/O from signal handler. (#3000)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-12-04 10:00:50 +01:00
mergify[bot]
ebb6175dfa correct test function descriptions (#2970) (#2992)
(cherry picked from commit 354413c060)

Signed-off-by: Yuchen Liu <lyuchen9696@gmail.com>
Co-authored-by: Yuchen966 <70603129+Yuchen966@users.noreply.github.com>
2025-11-18 16:17:05 +01:00
Alejandro Hernandez Cordero
fc13cfe5fe 29.5.5 2025-11-18 14:49:13 +01:00
Alejandro Hernandez Cordero
331bcb2ec9 Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-11-18 14:49:07 +01:00
mergify[bot]
4db3e3303b Fix REP url locations (#2987) (#2989)
This popped up in my global replace


(cherry picked from commit ad019b9827)

Signed-off-by: Tim Clephas <tim.clephas@nobleo.nl>
Co-authored-by: Tim Clephas <tim.clephas@nobleo.nl>
2025-11-17 10:09:04 +01:00
mergify[bot]
bda164fb4d Add get_parameter_or overload returning value or alternative (#2973) (#2976)
(cherry picked from commit eb49444c32)

Signed-off-by: Zheng Qu <quzhengrobot@gmail.com>
Co-authored-by: Zheng Qu <quzhengrobot@gmail.com>
2025-11-10 08:54:59 +01:00
Alejandro Hernandez Cordero
a35bc62b8c 29.5.4 2025-10-21 11:48:59 +02:00
Alejandro Hernandez Cordero
8a9f0468e3 Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-10-21 11:48:54 +02:00
mergify[bot]
6a2d90ebf8 it misses the iterator second to lock the weakptr. (#2958) (#2959)
(cherry picked from commit aa60fcf22a)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-09-30 15:42:35 +02:00
Alejandro Hernandez Cordero
c21065e979 29.5.3 2025-09-11 15:32:55 +02:00
Alejandro Hernandez Cordero
c4ee11a5c7 Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-09-11 15:32:51 +02:00
mergify[bot]
14ecbc3f0b Fix: improve exception context for parameter_value_from (#2917) (#2919)
(cherry picked from commit 1f2adc9829)

Signed-off-by: Michiel Leegwater <mleegwt@users.noreply.github.com>
Signed-off-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
Co-authored-by: Michiel Leegwater <mleegwt@users.noreply.github.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2025-08-18 19:59:13 +02:00
Tim Clephas
8a4cb48b2c Allow for implicitly convertable loggers as well (#2922) (#2936)
Signed-off-by: Tim Clephas <tim.clephas@nobleo.nl>
2025-08-18 13:59:13 +02:00
mergify[bot]
aa634b28df Clearer warning message, the old one lacked information and was perhaps misleading (#2927) (#2931)
* change misleading warning message, making it more correct and informative



* Fix compile error. Needed to also build rcl from source.



* explicitely initialize pointer as null, to adhere to best practice



---------


(cherry picked from commit 37677791ca)

Signed-off-by: Peter Mitrano (AR) <peter.mitrano@agile-robots.com>
Co-authored-by: Peter Mitrano (AR) <peter.mitrano@agile-robots.com>
2025-08-13 10:37:17 +02:00
mergify[bot]
8ec31edd4a fix cmake deprecation (#2914) (#2915)
cmake version < then 3.10 is deprecated


(cherry picked from commit 6392ee5187)

Signed-off-by: Mos <realeandrea@yahoo.it>
Co-authored-by: mosfet80 <10235105+mosfet80@users.noreply.github.com>
2025-07-24 17:01:57 +02:00
mergify[bot]
a709d81a93 Fix start_type_description_service param handling (#2897) (#2908)
* Fix `start_type_description_service` param handling



* Add test



* Demonstrate different exceptions depending on node options



* Same exact exception and `what()` message in both cases



* Uncrustify



---------


(cherry picked from commit 4fb558ae7b)

Signed-off-by: Patrick Roncagliolo <ronca.pat@gmail.com>
Co-authored-by: Patrick Roncagliolo <ronca.pat@gmail.com>
2025-07-16 21:53:03 -07:00
mergify[bot]
a35793ad28 Add qos parameter for wait_for_message function (#2903) (#2905)
(cherry picked from commit 2fcef70ea7)

Signed-off-by: Sriharsha Ghanta <ghanta1996@gmail.com>
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Sriharsha Ghanta <ghanta_sriharsha@mymail.sutd.edu.sg>
Co-authored-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-07-16 15:51:14 -07:00
mergify[bot]
7cba3c4882 Expose typesupport_helpers API needed for the Rosbag2 (#2858) (#2901)
* Expose extract_type_identifier and get_typesupport_library_path API

- Rationale: We need to use this API in the Rosbag2
- Reference PR https://github.com/ros2/rosbag2/pull/2017 in the Rosbag2



* Use C++ style in doxygen documentation



---------


(cherry picked from commit 448287b109)

Signed-off-by: Michael Orlov <michael.orlov@apex.ai>
Co-authored-by: Michael Orlov <morlovmr@gmail.com>
2025-07-13 23:17:31 -07:00
mergify[bot]
27e800b910 Fujitatomoya/test append parameter override (#2896) (#2899)
(cherry picked from commit 84c6fb1cfc)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-07-10 09:21:48 +02:00
mergify[bot]
e6f6b2a7ad Add overload of append_parameter_override (#2891) (#2894)
(cherry picked from commit fa0cf2da31)

Signed-off-by: Patrick Roncagliolo <ronca.pat@gmail.com>
Co-authored-by: Patrick Roncagliolo <ronca.pat@gmail.com>
2025-07-09 14:03:59 -07:00
Scott K Logan
6c95d10cca 29.5.2 2025-07-07 16:06:10 -05:00
mergify[bot]
a5a7febb60 Shutdown deadlock fix jazzy (#2887) (#2888)
* fix: Don't deadlock if removing shutdown callbacks in a shutdown callback



* refactor: Made fix API compatible



---------



(cherry picked from commit 7aab9b6f99)

Signed-off-by: Janosch Machowinski <J.Machowinski@cellumation.com>
Co-authored-by: Janosch Machowinski <jmachowinski@users.noreply.github.com>
Co-authored-by: Janosch Machowinski <J.Machowinski@cellumation.com>
2025-07-03 08:30:37 +02:00
mergify[bot]
7373669455 fix test_publisher_with_system_default_qos. (#2881) (#2884)
(cherry picked from commit e6577c6792)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-06-26 22:58:08 +02:00
Alejandro Hernandez Cordero
ae930aa2e5 29.5.1 2025-06-23 16:45:44 +02:00
Alejandro Hernandez Cordero
24846c3109 Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-06-23 16:45:40 +02:00
mergify[bot]
160da7b432 Removed warning test_qos (#2859) (#2873)
(cherry picked from commit df3a303a17)

Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2025-06-13 08:59:48 +02:00
mergify[bot]
22939ddf9b Fix for memory leaks in rclcpp::SerializedMessage (#2861) (#2863)
(cherry picked from commit 8d44b95d8b)

Signed-off-by: Michael Orlov <morlovmr@gmail.com>
Signed-off-by: Michael Orlov <michael.orlov@apex.ai>
Co-authored-by: Michael Orlov <morlovmr@gmail.com>
Co-authored-by: kylemarcey <marcey.kyle@gmail.com>
2025-05-30 22:17:14 +02:00
mergify[bot]
ea1d764f42 Replace std::default_random_engine with std::mt19937 (rolling) (#2843) (#2866)
(cherry picked from commit db8d917a12)

Signed-off-by: keeponoiro <keeeeeeep@gmail.com>
Co-authored-by: keeponoiro <keeeeeeep@gmail.com>
2025-05-30 10:49:59 +02:00
mergify[bot]
82666affcd get_all_data_impl() does not handle null pointers properly, causing segmentation fault (backport #2840) (#2850)
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-05-26 18:29:37 +02:00
mergify[bot]
0be3acf32f Added missing chrono includes (#2854) (#2855)
(cherry picked from commit 373a63c5e6)

Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2025-05-26 13:25:57 +02:00
mergify[bot]
34005e903f QoSInitialization::from_rmw does not validate invalid history policy values, leading to silent failures (#2841) (#2846)
(cherry picked from commit 73e9bfb62b)

Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2025-05-19 08:57:33 +02:00
mergify[bot]
288be9c981 Add missing 's' to 'NodeParametersInterface' in doc/comment (#2831) (#2833)
(cherry picked from commit b1ec85df16)

Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
Co-authored-by: Christophe Bedard <bedard.christophe@gmail.com>
2025-04-30 10:10:19 -07:00
mergify[bot]
93028ff38d subordinate node consistent behavior and update docstring. (#2822) (#2830)
* subordinate node consistent behavior and update docstring.



* add subnode_parameter_operation test.



* typo fixes.



---------


(cherry picked from commit c89a2b1013)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-04-29 20:26:22 -07:00
187 changed files with 2902 additions and 5382 deletions

View File

@@ -2,100 +2,50 @@
Changelog for package rclcpp
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30.1.5 (2026-02-09)
29.5.6 (2025-12-23)
-------------------
* remove default: so that compiler can detect the missing case. (`#3048 <https://github.com/ros2/rclcpp/issues/3048>`_)
* use weak_ptr for rcl entities in the memory strategy. (`#2988 <https://github.com/ros2/rclcpp/issues/2988>`_)
* remove test_static_executor_entities_collector.cpp (`#3041 <https://github.com/ros2/rclcpp/issues/3041>`_)
* include the 1st spin that might throw the exception. (`#3042 <https://github.com/ros2/rclcpp/issues/3042>`_)
* print warning message on owner node if the parameter operation fails. (`#3037 <https://github.com/ros2/rclcpp/issues/3037>`_)
* fix context in wait for message wait set (`#3030 <https://github.com/ros2/rclcpp/issues/3030>`_)
* Revert "construct wait set with passed in context (`#3021 <https://github.com/ros2/rclcpp/issues/3021>`_)" (`#3028 <https://github.com/ros2/rclcpp/issues/3028>`_)
* construct wait set with passed in context (`#3021 <https://github.com/ros2/rclcpp/issues/3021>`_)
* Improve the robustness of the TopicEndpointInfo constructor (`#3013 <https://github.com/ros2/rclcpp/issues/3013>`_)
* Deprecate the shared_ptr<MessageT> subscription callback signatures (`#2975 <https://github.com/ros2/rclcpp/issues/2975>`_)
* Contributors: Barry Xu, Maurice Alexander Purnawan, Michael Carroll, Rahat Dhande, Tomoya Fujita
* Unified Node Interfaces: Add const version of get_node_x_interface() (`#3006 <https://github.com/ros2/rclcpp/issues/3006>`_) (`#3008 <https://github.com/ros2/rclcpp/issues/3008>`_)
* remove I/O from signal handler. (`#3000 <https://github.com/ros2/rclcpp/issues/3000>`_)
* correct test function descriptions (`#2970 <https://github.com/ros2/rclcpp/issues/2970>`_) (`#2992 <https://github.com/ros2/rclcpp/issues/2992>`_)
* Contributors: Tomoya Fujita, mergify[bot]
30.1.4 (2025-12-23)
29.5.5 (2025-11-18)
-------------------
* Updated deprecated ament_index_cpp API (`#3011 <https://github.com/ros2/rclcpp/issues/3011>`_)
* Unified Node Interfaces: Add const version of get_node_x_interface() (`#3006 <https://github.com/ros2/rclcpp/issues/3006>`_)
* Parameter Descriptor Simplification (`#2179 <https://github.com/ros2/rclcpp/issues/2179>`_)
* ParameterEventHandler support ContentFiltering (`#2971 <https://github.com/ros2/rclcpp/issues/2971>`_)
* update policy_name_from_kind && test_qos (`#2156 <https://github.com/ros2/rclcpp/issues/2156>`_)
* Add ability to disable and enable subscription's callbacks (`#2985 <https://github.com/ros2/rclcpp/issues/2985>`_)
* Switch to isolated testing via rmw_test_fixture (`#2929 <https://github.com/ros2/rclcpp/issues/2929>`_)
* remove I/O from signal handler. (`#2986 <https://github.com/ros2/rclcpp/issues/2986>`_)
* Contributors: Alejandro Hernández Cordero, Andrianov Roman, Barry Xu, Lucas Wendland, Michael Orlov, Tomoya Fujita, fabianhirmann, yadunund
* Fix REP url locations (`#2987 <https://github.com/ros2/rclcpp/issues/2987>`_) (`#2989 <https://github.com/ros2/rclcpp/issues/2989>`_)
* Contributors: mergify[bot]
30.1.3 (2025-11-18)
29.5.4 (2025-10-21)
-------------------
* correct test function descriptions (`#2970 <https://github.com/ros2/rclcpp/issues/2970>`_)
* add : get clients, servers info (`#2569 <https://github.com/ros2/rclcpp/issues/2569>`_)
* Fix REP url locations (`#2987 <https://github.com/ros2/rclcpp/issues/2987>`_)
* Contributors: Minju, Lee, Tim Clephas, Yuchen966
30.1.2 (2025-10-21)
29.5.3 (2025-09-11)
-------------------
* clear handles before node destruction in test_memory_strategy. (`#2969 <https://github.com/ros2/rclcpp/issues/2969>`_)
* Added static assert asserting custom types have no overloaded operator new (`#2954 <https://github.com/ros2/rclcpp/issues/2954>`_)
* Store graph listener inside the context instead of the node graph (`#2952 <https://github.com/ros2/rclcpp/issues/2952>`_)
* Reapply "Catch the exception from rate.sleep() if the context is invalid. (`#2956 <https://github.com/ros2/rclcpp/issues/2956>`_)" (`#2963 <https://github.com/ros2/rclcpp/issues/2963>`_) (`#2964 <https://github.com/ros2/rclcpp/issues/2964>`_)
* Revert "Catch the exception from rate.sleep() if the context is invalid. (`#2956 <https://github.com/ros2/rclcpp/issues/2956>`_)" (`#2963 <https://github.com/ros2/rclcpp/issues/2963>`_)
* Catch the exception from rate.sleep() if the context is invalid. (`#2956 <https://github.com/ros2/rclcpp/issues/2956>`_)
* update Time documentation (`#2955 <https://github.com/ros2/rclcpp/issues/2955>`_)
* Contributors: Ilario A. Azzollini, Ivo Ivanov, Skyler Medeiros, Tomoya Fujita
* Fix: improve exception context for parameter_value_from (`#2917 <https://github.com/ros2/rclcpp/issues/2917>`_) (`#2919 <https://github.com/ros2/rclcpp/issues/2919>`_)
* Allow for implicitly convertable loggers as well (`#2922 <https://github.com/ros2/rclcpp/issues/2922>`_) (`#2936 <https://github.com/ros2/rclcpp/issues/2936>`_)
* Fix `start_type_description_service` param handling (`#2897 <https://github.com/ros2/rclcpp/issues/2897>`_) (`#2908 <https://github.com/ros2/rclcpp/issues/2908>`_)
* Add qos parameter for wait_for_message function (`#2903 <https://github.com/ros2/rclcpp/issues/2903>`_) (`#2905 <https://github.com/ros2/rclcpp/issues/2905>`_)
* Expose `typesupport_helpers` API needed for the Rosbag2 (`#2858 <https://github.com/ros2/rclcpp/issues/2858>`_) (`#2901 <https://github.com/ros2/rclcpp/issues/2901>`_)
* Fujitatomoya/test append parameter override (`#2896 <https://github.com/ros2/rclcpp/issues/2896>`_) (`#2899 <https://github.com/ros2/rclcpp/issues/2899>`_)
* Add overload of `append_parameter_override` (`#2891 <https://github.com/ros2/rclcpp/issues/2891>`_) (`#2894 <https://github.com/ros2/rclcpp/issues/2894>`_)
* Contributors: Tim Clephas, mergify[bot]
30.1.1 (2025-09-11)
29.5.2 (2025-07-07)
-------------------
* Removed warning (`#2949 <https://github.com/ros2/rclcpp/issues/2949>`_)
* add note about problems with spin_until_future_complete (`#2849 <https://github.com/ros2/rclcpp/issues/2849>`_)
* deprecate rclcpp::spin_some and rclcpp::spin_all (`#2848 <https://github.com/ros2/rclcpp/issues/2848>`_)
* Improve the function extract_type_identifier (`#2923 <https://github.com/ros2/rclcpp/issues/2923>`_)
* Allow for implicitly convertable loggers as well (`#2922 <https://github.com/ros2/rclcpp/issues/2922>`_)
* Contributors: Alberto Soragna, Alejandro Hernández Cordero, Barry Xu, Tim Clephas
* Shutdown deadlock fix jazzy (`#2887 <https://github.com/ros2/rclcpp/issues/2887>`_) (`#2888 <https://github.com/ros2/rclcpp/issues/2888>`_)
* Fix test_publisher_with_system_default_qos (`#2881 <https://github.com/ros2/rclcpp/issues/2881>`_) (`#2884 <https://github.com/ros2/rclcpp/issues/2884>`_)
* Contributors: Tomoya Fujita, Janosch Machowinski
30.1.0 (2025-07-29)
-------------------
* Fix: improve exception context for parameter_value_from (`#2917 <https://github.com/ros2/rclcpp/issues/2917>`_)
* Fix `start_type_description_service` param handling (`#2897 <https://github.com/ros2/rclcpp/issues/2897>`_)
* Add qos parameter for wait_for_message function (`#2903 <https://github.com/ros2/rclcpp/issues/2903>`_)
* Fujitatomoya/test append parameter override (`#2896 <https://github.com/ros2/rclcpp/issues/2896>`_)
* Expose `typesupport_helpers` API needed for the Rosbag2 (`#2858 <https://github.com/ros2/rclcpp/issues/2858>`_)
* Remove comment about now-removed StaticSingleThreadedExecutor (`#2893 <https://github.com/ros2/rclcpp/issues/2893>`_)
* Add overload of `append_parameter_override` (`#2891 <https://github.com/ros2/rclcpp/issues/2891>`_)
* fix: Don't deadlock if removing shutdown callbacks in a shutdown callback (`#2886 <https://github.com/ros2/rclcpp/issues/2886>`_)
* Contributors: Christophe Bedard, Janosch Machowinski, Michael Orlov, Michiel Leegwater, Patrick Roncagliolo, Sriharsha Ghanta, Tomoya Fujita
30.0.0 (2025-07-01)
-------------------
* Hand-code logging.hpp (`#2870 <https://github.com/ros2/rclcpp/issues/2870>`_)
* Adressed TODO in node_graph (`#2877 <https://github.com/ros2/rclcpp/issues/2877>`_)
* fix test_publisher_with_system_default_qos. (`#2881 <https://github.com/ros2/rclcpp/issues/2881>`_)
* Contributors: Alejandro Hernández Cordero, Chris Lalancette, Tomoya Fujita
29.6.1 (2025-06-23)
-------------------
* Fix for memory leaks in rclcpp::SerializedMessage (`#2861 <https://github.com/ros2/rclcpp/issues/2861>`_)
* Removed warning test_qos (`#2859 <https://github.com/ros2/rclcpp/issues/2859>`_)
* Added missing chrono includes (`#2854 <https://github.com/ros2/rclcpp/issues/2854>`_)
* get_all_data_impl() does not handle null pointers properly, causing segmentation fault (`#2840 <https://github.com/ros2/rclcpp/issues/2840>`_)
* QoSInitialization::from_rmw does not validate invalid history policy values, leading to silent failures (`#2841 <https://github.com/ros2/rclcpp/issues/2841>`_)
* remove get_notify_guard_condition from NodeBaseInterface. (`#2839 <https://github.com/ros2/rclcpp/issues/2839>`_)
* Removed deprecated StaticSingleThreadedExecutor (`#2835 <https://github.com/ros2/rclcpp/issues/2835>`_)
* Removed deprecated rcpputils Path (`#2834 <https://github.com/ros2/rclcpp/issues/2834>`_)
* Add range constraints for applicable array parameters (`#2828 <https://github.com/ros2/rclcpp/issues/2828>`_)
* Update RingBufferImplementation to clear internal data. (`#2837 <https://github.com/ros2/rclcpp/issues/2837>`_)
* Removed deprecated cancel_sleep_or_wait (`#2836 <https://github.com/ros2/rclcpp/issues/2836>`_)
* Add missing 's' to 'NodeParametersInterface' in doc/comment (`#2831 <https://github.com/ros2/rclcpp/issues/2831>`_)
* subordinate node consistent behavior and update docstring. (`#2822 <https://github.com/ros2/rclcpp/issues/2822>`_)
* Contributors: Alejandro Hernández Cordero, Alex Youngs, Christophe Bedard, Michael Carlstrom, Michael Orlov, Tomoya Fujita
29.6.0 (2025-04-25)
29.5.1 (2025-06-23)
-------------------
* Removed warning test_qos (`#2859 <https://github.com/ros2/rclcpp/issues/2859>`_) (`#2873 <https://github.com/ros2/rclcpp/issues/2873>`_)
* Fix for memory leaks in rclcpp::SerializedMessage (`#2861 <https://github.com/ros2/rclcpp/issues/2861>`_) (`#2863 <https://github.com/ros2/rclcpp/issues/2863>`_)
* get_all_data_impl() does not handle null pointers properly, causing segmentation fault (backport `#2840 <https://github.com/ros2/rclcpp/issues/2840>`_) (`#2850 <https://github.com/ros2/rclcpp/issues/2850>`_)
* Added missing chrono includes (`#2854 <https://github.com/ros2/rclcpp/issues/2854>`_) (`#2855 <https://github.com/ros2/rclcpp/issues/2855>`_)
* QoSInitialization::from_rmw does not validate invalid history policy values, leading to silent failures (`#2841 <https://github.com/ros2/rclcpp/issues/2841>`_) (`#2846 <https://github.com/ros2/rclcpp/issues/2846>`_)
* Add missing 's' to 'NodeParametersInterface' in doc/comment (`#2831 <https://github.com/ros2/rclcpp/issues/2831>`_) (`#2833 <https://github.com/ros2/rclcpp/issues/2833>`_)
* subordinate node consistent behavior and update docstring. (`#2822 <https://github.com/ros2/rclcpp/issues/2822>`_) (`#2830 <https://github.com/ros2/rclcpp/issues/2830>`_)
* throws std::invalid_argument if ParameterEvent is NULL. (`#2814 <https://github.com/ros2/rclcpp/issues/2814>`_)
* Removed clang warnings (`#2823 <https://github.com/ros2/rclcpp/issues/2823>`_)
* Contributors: Alejandro Hernández Cordero, Tomoya Fujita
* Contributors: Alejandro Hernández Cordero, Tomoya Fujita, mergify[bot]
29.5.0 (2025-04-18)
-------------------

View File

@@ -70,6 +70,7 @@ set(${PROJECT_NAME}_SRCS
src/rclcpp/executors/executor_notify_waitable.cpp
src/rclcpp/executors/multi_threaded_executor.cpp
src/rclcpp/executors/single_threaded_executor.cpp
src/rclcpp/executors/static_single_threaded_executor.cpp
src/rclcpp/expand_topic_or_service_name.cpp
src/rclcpp/experimental/executors/events_executor/events_executor.cpp
src/rclcpp/experimental/timers_manager.cpp
@@ -103,7 +104,6 @@ set(${PROJECT_NAME}_SRCS
src/rclcpp/node_options.cpp
src/rclcpp/parameter.cpp
src/rclcpp/parameter_client.cpp
src/rclcpp/parameter_descriptor_wrapper.cpp
src/rclcpp/parameter_event_handler.cpp
src/rclcpp/parameter_events_filter.cpp
src/rclcpp/parameter_map.cpp
@@ -147,6 +147,27 @@ set(Python3_FIND_UNVERSIONED_NAMES FIRST)
find_package(Python3 REQUIRED COMPONENTS Interpreter)
# "watch" template for changes
configure_file(
"resource/logging.hpp.em"
"logging.hpp.em.watch"
COPYONLY
)
# generate header with logging macros
set(python_code_logging
"import em"
"em.invoke(['-o', 'include/rclcpp/logging.hpp', '${CMAKE_CURRENT_SOURCE_DIR}/resource/logging.hpp.em'])")
string(REPLACE ";" "$<SEMICOLON>" python_code_logging "${python_code_logging}")
add_custom_command(OUTPUT include/rclcpp/logging.hpp
COMMAND ${CMAKE_COMMAND} -E make_directory "include/rclcpp"
COMMAND Python3::Interpreter ARGS -c "${python_code_logging}"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/logging.hpp.em.watch"
COMMENT "Expanding logging.hpp.em"
VERBATIM
)
list(APPEND ${PROJECT_NAME}_SRCS
include/rclcpp/logging.hpp)
file(GLOB interface_files "include/rclcpp/node_interfaces/node_*_interface.hpp")
foreach(interface_file ${interface_files})
get_filename_component(interface_name ${interface_file} NAME_WE)

View File

@@ -21,22 +21,6 @@ GENERATE_LATEX = NO
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
EXCLUDE_SYMBOLS += RCLCPP_STATIC_ASSERT_LOGGER
EXCLUDE_SYMBOLS += RCLCPP_LOG
EXCLUDE_SYMBOLS += RCLCPP_LOG_ONCE
EXCLUDE_SYMBOLS += RCLCPP_LOG_EXPRESSION
EXCLUDE_SYMBOLS += RCLCPP_LOG_FUNCTION
EXCLUDE_SYMBOLS += RCLCPP_LOG_SKIPFIRST
EXCLUDE_SYMBOLS += RCLCPP_LOG_TIME_POINT_FUNC
EXCLUDE_SYMBOLS += RCLCPP_LOG_THROTTLE
EXCLUDE_SYMBOLS += RCLCPP_LOG_SKIPFIRST_THROTTLE
EXCLUDE_SYMBOLS += RCLCPP_LOG_STREAM
EXCLUDE_SYMBOLS += RCLCPP_LOG_STREAM_ONCE
EXCLUDE_SYMBOLS += RCLCPP_LOG_STREAM_EXPRESSION
EXCLUDE_SYMBOLS += RCLCPP_LOG_STREAM_FUNCTION
EXCLUDE_SYMBOLS += RCLCPP_LOG_STREAM_SKIPFIRST
EXCLUDE_SYMBOLS += RCLCPP_LOG_STREAM_THROTTLE
EXCLUDE_SYMBOLS += RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE
PREDEFINED += DOXYGEN_ONLY
PREDEFINED += RCLCPP_LOCAL=
PREDEFINED += RCLCPP_PUBLIC=

View File

@@ -27,39 +27,10 @@ namespace rclcpp
namespace allocator
{
template<typename T>
using clean_t = std::remove_cv_t<std::remove_reference_t<T>>;
// Primary template: false
template<typename, typename = std::void_t<>>
struct has_get_rcl_allocator : std::false_type {};
// Specialization: true if expression is valid
template<typename T>
struct has_get_rcl_allocator<T,
std::void_t<
decltype(std::declval<clean_t<T> &>().get_rcl_allocator())
>
>
: std::bool_constant<
std::is_same_v<
decltype(std::declval<clean_t<T> &>().get_rcl_allocator()),
rcl_allocator_t
>
>
{};
// Helper variable template
template<typename T>
inline constexpr bool has_get_rcl_allocator_v =
has_get_rcl_allocator<T>::value;
template<typename T, typename Alloc>
using AllocRebind = typename std::allocator_traits<Alloc>::template rebind_traits<T>;
template<typename Alloc>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros.")]]
void * retyped_allocate(size_t size, void * untyped_allocator)
{
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
@@ -70,8 +41,6 @@ void * retyped_allocate(size_t size, void * untyped_allocator)
}
template<typename Alloc>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros.")]]
void * retyped_zero_allocate(size_t number_of_elem, size_t size_of_elem, void * untyped_allocator)
{
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
@@ -88,8 +57,6 @@ void * retyped_zero_allocate(size_t number_of_elem, size_t size_of_elem, void *
}
template<typename T, typename Alloc>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros.")]]
void retyped_deallocate(void * untyped_pointer, void * untyped_allocator)
{
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
@@ -101,8 +68,6 @@ void retyped_deallocate(void * untyped_pointer, void * untyped_allocator)
}
template<typename T, typename Alloc>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros.")]]
void * retyped_reallocate(void * untyped_pointer, size_t size, void * untyped_allocator)
{
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
@@ -120,9 +85,6 @@ template<
typename T,
typename Alloc,
typename std::enable_if<!std::is_same<Alloc, std::allocator<void>>::value>::type * = nullptr>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros. To suppress this warning"
"define the method 'rcl_allocator_t get_rcl_allocator()' on your allocator")]]
rcl_allocator_t get_rcl_allocator(Alloc & allocator)
{
rcl_allocator_t rcl_allocator = rcl_get_default_allocator();

View File

@@ -15,10 +15,8 @@
#ifndef RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
#define RCLCPP__ANY_SUBSCRIPTION_CALLBACK_HPP_
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>
#include <stdexcept>
#include <type_traits>
#include <utility>
@@ -377,19 +375,7 @@ public:
allocator::set_allocator_for_deleter(&ros_message_type_deleter_, &ros_message_type_allocator_);
}
AnySubscriptionCallback(const AnySubscriptionCallback & other)
: callback_variant_(other.callback_variant_),
callback_disabled_(other.callback_disabled_.load()),
subscribed_type_allocator_(other.subscribed_type_allocator_),
subscribed_type_deleter_(other.subscribed_type_deleter_),
ros_message_type_allocator_(other.ros_message_type_allocator_),
ros_message_type_deleter_(other.ros_message_type_deleter_),
serialized_message_allocator_(other.serialized_message_allocator_),
serialized_message_deleter_(other.serialized_message_deleter_)
{
allocator::set_allocator_for_deleter(&subscribed_type_deleter_, &subscribed_type_allocator_);
allocator::set_allocator_for_deleter(&ros_message_type_deleter_, &ros_message_type_allocator_);
}
AnySubscriptionCallback(const AnySubscriptionCallback &) = default;
/// Generic function for setting the callback.
/**
@@ -407,91 +393,12 @@ public:
// converted to one another, e.g. shared_ptr and unique_ptr.
using scbth = detail::SubscriptionCallbackTypeHelper<MessageT, CallbackT>;
// Determine if the given CallbackT is a deprecated signature or not.
constexpr auto is_deprecated =
rclcpp::function_traits::same_arguments<
typename scbth::callback_type,
std::function<void(std::shared_ptr<SubscribedType>)>
>::value ||
rclcpp::function_traits::same_arguments<
typename scbth::callback_type,
std::function<void(std::shared_ptr<SubscribedType>, const rclcpp::MessageInfo &)>
>::value ||
rclcpp::function_traits::same_arguments<
typename scbth::callback_type,
std::function<void(std::shared_ptr<ROSMessageType>)>
>::value ||
rclcpp::function_traits::same_arguments<
typename scbth::callback_type,
std::function<void(std::shared_ptr<ROSMessageType>, const rclcpp::MessageInfo &)>
>::value ||
rclcpp::function_traits::same_arguments<
typename scbth::callback_type,
std::function<void(std::shared_ptr<rclcpp::SerializedMessage>)>
>::value ||
rclcpp::function_traits::same_arguments<
typename scbth::callback_type,
std::function<void(std::shared_ptr<rclcpp::SerializedMessage>, const rclcpp::MessageInfo &)>
>::value;
// Use the discovered type to force the type of callback when assigning
// into the variant.
if constexpr (is_deprecated) {
// If deprecated, call sub-routine that is deprecated.
set_deprecated(static_cast<typename scbth::callback_type>(callback));
} else {
// Otherwise just assign it.
callback_variant_ = static_cast<typename scbth::callback_type>(callback);
}
callback_variant_ = static_cast<typename scbth::callback_type>(callback);
// Return copy of self for easier testing, normally will be compiled out.
return *this;
}
/// Function for shared_ptr to non-const MessageT, which is deprecated.
template<typename SetT>
// *INDENT-OFF*
#if !defined(RCLCPP_AVOID_DEPRECATIONS_FOR_UNIT_TESTS)
// suppress deprecation warnings in `test_any_subscription_callback.cpp`
[[deprecated("use 'void(std::shared_ptr<const MessageT>)' instead")]]
#endif
// *INDENT-ON*
void
set_deprecated(std::function<void(std::shared_ptr<SetT>)> callback)
{
callback_variant_ = callback;
}
/// Function for shared_ptr to non-const MessageT with MessageInfo, which is deprecated.
template<typename SetT>
// *INDENT-OFF*
#if !defined(RCLCPP_AVOID_DEPRECATIONS_FOR_UNIT_TESTS)
// suppress deprecation warnings in `test_any_subscription_callback.cpp`
[[deprecated(
"use 'void(std::shared_ptr<const MessageT>, const rclcpp::MessageInfo &)' instead"
)]]
#endif
// *INDENT-ON*
void
set_deprecated(std::function<void(std::shared_ptr<SetT>, const rclcpp::MessageInfo &)> callback)
{
callback_variant_ = callback;
}
/// Disable the callback from being called during dispatch.
void disable()
{
std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
callback_disabled_.store(true);
}
/// Enable the callback to be called during dispatch.
void enable()
{
std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
callback_disabled_.store(false);
}
std::unique_ptr<ROSMessageType, ROSMessageTypeDeleter>
create_ros_unique_ptr_from_ros_shared_ptr_message(
const std::shared_ptr<const ROSMessageType> & message)
@@ -562,10 +469,6 @@ public:
std::shared_ptr<ROSMessageType> message,
const rclcpp::MessageInfo & message_info)
{
std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
if (callback_disabled_.load()) {
return;
}
TRACETOOLS_TRACEPOINT(callback_start, static_cast<const void *>(this), false);
// Check if the variant is "unset", throw if it is.
if (callback_variant_.index() == 0) {
@@ -666,10 +569,6 @@ public:
std::shared_ptr<const rclcpp::SerializedMessage> serialized_message,
const rclcpp::MessageInfo & message_info)
{
std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
if (callback_disabled_.load()) {
return;
}
TRACETOOLS_TRACEPOINT(callback_start, static_cast<const void *>(this), false);
// Check if the variant is "unset", throw if it is.
if (callback_variant_.index() == 0) {
@@ -749,10 +648,6 @@ public:
std::shared_ptr<const SubscribedType> message,
const rclcpp::MessageInfo & message_info)
{
std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
if (callback_disabled_.load()) {
return;
}
TRACETOOLS_TRACEPOINT(callback_start, static_cast<const void *>(this), true);
// Check if the variant is "unset", throw if it is.
if (callback_variant_.index() == 0) {
@@ -883,10 +778,6 @@ public:
std::unique_ptr<SubscribedType, SubscribedTypeDeleter> message,
const rclcpp::MessageInfo & message_info)
{
std::unique_lock<std::recursive_mutex> callback_lock(callback_mutex_);
if (callback_disabled_.load()) {
return;
}
TRACETOOLS_TRACEPOINT(callback_start, static_cast<const void *>(this), true);
// Check if the variant is "unset", throw if it is.
if (callback_variant_.index() == 0) {
@@ -1081,8 +972,6 @@ private:
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2162r0.html
// For now, compose the variant into this class as a private attribute.
typename HelperT::variant_type callback_variant_;
std::recursive_mutex callback_mutex_;
std::atomic_bool callback_disabled_{false};
SubscribedTypeAllocator subscribed_type_allocator_;
SubscribedTypeDeleter subscribed_type_deleter_;

View File

@@ -97,7 +97,7 @@ public:
RCLCPP_PUBLIC
explicit CallbackGroup(
CallbackGroupType group_type,
const rclcpp::Context::WeakPtr & context,
rclcpp::Context::WeakPtr context,
bool automatically_add_to_executor_with_node = true);
/// Default destructor.
@@ -106,35 +106,35 @@ public:
template<typename Function>
rclcpp::SubscriptionBase::SharedPtr
find_subscription_ptrs_if(const Function & func) const
find_subscription_ptrs_if(Function func) const
{
return _find_ptrs_if_impl<rclcpp::SubscriptionBase, Function>(func, subscription_ptrs_);
}
template<typename Function>
rclcpp::TimerBase::SharedPtr
find_timer_ptrs_if(const Function & func) const
find_timer_ptrs_if(Function func) const
{
return _find_ptrs_if_impl<rclcpp::TimerBase, Function>(func, timer_ptrs_);
}
template<typename Function>
rclcpp::ServiceBase::SharedPtr
find_service_ptrs_if(const Function & func) const
find_service_ptrs_if(Function func) const
{
return _find_ptrs_if_impl<rclcpp::ServiceBase, Function>(func, service_ptrs_);
}
template<typename Function>
rclcpp::ClientBase::SharedPtr
find_client_ptrs_if(const Function & func) const
find_client_ptrs_if(Function func) const
{
return _find_ptrs_if_impl<rclcpp::ClientBase, Function>(func, client_ptrs_);
}
template<typename Function>
rclcpp::Waitable::SharedPtr
find_waitable_ptrs_if(const Function & func) const
find_waitable_ptrs_if(Function func) const
{
return _find_ptrs_if_impl<rclcpp::Waitable, Function>(func, waitable_ptrs_);
}
@@ -179,11 +179,11 @@ public:
RCLCPP_PUBLIC
void
collect_all_ptrs(
const std::function<void(const rclcpp::SubscriptionBase::SharedPtr &)> & sub_func,
const std::function<void(const rclcpp::ServiceBase::SharedPtr &)> & service_func,
const std::function<void(const rclcpp::ClientBase::SharedPtr &)> & client_func,
const std::function<void(const rclcpp::TimerBase::SharedPtr &)> & timer_func,
const std::function<void(const rclcpp::Waitable::SharedPtr &)> & waitable_func) const;
std::function<void(const rclcpp::SubscriptionBase::SharedPtr &)> sub_func,
std::function<void(const rclcpp::ServiceBase::SharedPtr &)> service_func,
std::function<void(const rclcpp::ClientBase::SharedPtr &)> client_func,
std::function<void(const rclcpp::TimerBase::SharedPtr &)> timer_func,
std::function<void(const rclcpp::Waitable::SharedPtr &)> waitable_func) const;
/// Return a reference to the 'associated with executor' atomic boolean.
/**
@@ -228,31 +228,31 @@ protected:
RCLCPP_PUBLIC
void
add_publisher(const rclcpp::PublisherBase::SharedPtr & publisher_ptr);
add_publisher(const rclcpp::PublisherBase::SharedPtr publisher_ptr);
RCLCPP_PUBLIC
void
add_subscription(const rclcpp::SubscriptionBase::SharedPtr & subscription_ptr);
add_subscription(const rclcpp::SubscriptionBase::SharedPtr subscription_ptr);
RCLCPP_PUBLIC
void
add_timer(const rclcpp::TimerBase::SharedPtr & timer_ptr);
add_timer(const rclcpp::TimerBase::SharedPtr timer_ptr);
RCLCPP_PUBLIC
void
add_service(const rclcpp::ServiceBase::SharedPtr & service_ptr);
add_service(const rclcpp::ServiceBase::SharedPtr service_ptr);
RCLCPP_PUBLIC
void
add_client(const rclcpp::ClientBase::SharedPtr & client_ptr);
add_client(const rclcpp::ClientBase::SharedPtr client_ptr);
RCLCPP_PUBLIC
void
add_waitable(const rclcpp::Waitable::SharedPtr & waitable_ptr);
add_waitable(const rclcpp::Waitable::SharedPtr waitable_ptr);
RCLCPP_PUBLIC
void
remove_waitable(const rclcpp::Waitable::SharedPtr & waitable_ptr) noexcept;
remove_waitable(const rclcpp::Waitable::SharedPtr waitable_ptr) noexcept;
CallbackGroupType type_;
// Mutex to protect the subsequent vectors of pointers.
@@ -274,7 +274,7 @@ protected:
private:
template<typename TypeT, typename Function>
typename TypeT::SharedPtr _find_ptrs_if_impl(
const Function & func, const std::vector<typename TypeT::WeakPtr> & vect_ptrs) const
Function func, const std::vector<typename TypeT::WeakPtr> & vect_ptrs) const
{
std::lock_guard<std::mutex> lock(mutex_);
for (auto & weak_ptr : vect_ptrs) {

View File

@@ -145,7 +145,7 @@ public:
RCLCPP_PUBLIC
ClientBase(
rclcpp::node_interfaces::NodeBaseInterface * node_base,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr & node_graph);
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph);
RCLCPP_PUBLIC
virtual ~ClientBase() = default;
@@ -221,8 +221,7 @@ public:
virtual std::shared_ptr<void> create_response() = 0;
virtual std::shared_ptr<rmw_request_id_t> create_request_header() = 0;
virtual void handle_response(
const std::shared_ptr<rmw_request_id_t> & request_header,
const std::shared_ptr<void> & response) = 0;
std::shared_ptr<rmw_request_id_t> request_header, std::shared_ptr<void> response) = 0;
/// Exchange the "in use by wait set" state for this client.
/**
@@ -297,7 +296,7 @@ public:
* \param[in] callback functor to be called when a new response is received
*/
void
set_on_new_response_callback(const std::function<void(size_t)> & callback)
set_on_new_response_callback(std::function<void(size_t)> callback)
{
if (!callback) {
throw std::invalid_argument(
@@ -478,7 +477,7 @@ public:
*/
Client(
rclcpp::node_interfaces::NodeBaseInterface * node_base,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr & node_graph,
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
const std::string & service_name,
rcl_client_options_t & client_options)
: ClientBase(node_base, node_graph),
@@ -557,8 +556,8 @@ public:
*/
void
handle_response(
const std::shared_ptr<rmw_request_id_t> & request_header,
const std::shared_ptr<void> & response) override
std::shared_ptr<rmw_request_id_t> request_header,
std::shared_ptr<void> response) override
{
std::optional<CallbackInfoVariant>
optional_pending_request = this->get_and_erase_pending_request(request_header->sequence_number);
@@ -567,7 +566,7 @@ public:
}
auto & value = *optional_pending_request;
auto typed_response = std::static_pointer_cast<typename ServiceT::Response>(
response);
std::move(response));
if (std::holds_alternative<Promise>(value)) {
auto & promise = std::get<Promise>(value);
promise.set_value(std::move(typed_response));
@@ -618,7 +617,7 @@ public:
* \return a FutureAndRequestId instance.
*/
FutureAndRequestId
async_send_request(const SharedRequest & request)
async_send_request(SharedRequest request)
{
Promise promise;
auto future = promise.get_future();
@@ -653,7 +652,7 @@ public:
>::type * = nullptr
>
SharedFutureAndRequestId
async_send_request(const SharedRequest & request, CallbackT && cb)
async_send_request(SharedRequest request, CallbackT && cb)
{
Promise promise;
auto shared_future = promise.get_future().share();
@@ -684,7 +683,7 @@ public:
>::type * = nullptr
>
SharedFutureWithRequestAndRequestId
async_send_request(const SharedRequest & request, CallbackT && cb)
async_send_request(SharedRequest request, CallbackT && cb)
{
PromiseWithRequest promise;
auto shared_future = promise.get_future().share();
@@ -796,7 +795,7 @@ public:
*/
void
configure_introspection(
const Clock::SharedPtr & clock, const QoS & qos_service_event_pub,
Clock::SharedPtr clock, const QoS & qos_service_event_pub,
rcl_service_introspection_state_t introspection_state)
{
rcl_publisher_options_t pub_opts = rcl_publisher_get_default_options();

View File

@@ -117,8 +117,8 @@ public:
RCLCPP_PUBLIC
bool
sleep_until(
const Time & until,
const Context::SharedPtr & context = contexts::get_global_default_context());
Time until,
Context::SharedPtr context = contexts::get_global_default_context());
/**
* Sleep for a specified Duration.
@@ -141,8 +141,8 @@ public:
RCLCPP_PUBLIC
bool
sleep_for(
const Duration & rel_time,
const Context::SharedPtr & context = contexts::get_global_default_context());
Duration rel_time,
Context::SharedPtr context = contexts::get_global_default_context());
/**
* Check if the clock is started.
@@ -168,7 +168,7 @@ public:
*/
RCLCPP_PUBLIC
bool
wait_until_started(const Context::SharedPtr & context = contexts::get_global_default_context());
wait_until_started(Context::SharedPtr context = contexts::get_global_default_context());
/**
* Wait for clock to start, with timeout.
@@ -186,7 +186,7 @@ public:
bool
wait_until_started(
const rclcpp::Duration & timeout,
const Context::SharedPtr & context = contexts::get_global_default_context(),
Context::SharedPtr context = contexts::get_global_default_context(),
const rclcpp::Duration & wait_tick_ns = rclcpp::Duration(0, static_cast<uint32_t>(1e7)));
/**
@@ -200,6 +200,21 @@ public:
bool
ros_time_is_active();
/**
* Deprecated. This API is broken, as there is no way to get a deep
* copy of a clock. Therefore one can experience spurious wakeups triggered
* by some other instance of a clock.
*
* Cancels an ongoing or future sleep operation of one thread.
*
* This function can be used by one thread, to wakeup another thread that is
* blocked using any of the sleep_ or wait_ methods of this class.
*/
[[deprecated("Use ClockConditionalVariable")]]
RCLCPP_PUBLIC
void
cancel_sleep_or_wait();
/// Return the rcl_clock_t clock handle
RCLCPP_PUBLIC
rcl_clock_t *
@@ -238,8 +253,8 @@ public:
RCLCPP_PUBLIC
JumpHandler::SharedPtr
create_jump_callback(
const JumpHandler::pre_callback_t & pre_callback,
const JumpHandler::post_callback_t & post_callback,
JumpHandler::pre_callback_t pre_callback,
JumpHandler::post_callback_t post_callback,
const rcl_jump_threshold_t & threshold);
private:
@@ -327,7 +342,7 @@ public:
RCLCPP_PUBLIC
ClockConditionalVariable(
const rclcpp::Clock::SharedPtr & clock,
const rclcpp::Context::SharedPtr & context = rclcpp::contexts::get_global_default_context());
rclcpp::Context::SharedPtr context = rclcpp::contexts::get_global_default_context());
RCLCPP_PUBLIC
~ClockConditionalVariable();
@@ -347,7 +362,7 @@ public:
RCLCPP_PUBLIC
bool
wait_until(
std::unique_lock<std::mutex> & lock, const rclcpp::Time & until,
std::unique_lock<std::mutex> & lock, rclcpp::Time until,
const std::function<bool ()> & pred);
/**

View File

@@ -37,10 +37,6 @@
namespace rclcpp
{
namespace graph_listener
{
class GraphListener;
} // namespace graph_listener
/// Thrown when init is called on an already initialized context.
class ContextAlreadyInitialized : public std::runtime_error
@@ -229,7 +225,7 @@ public:
RCLCPP_PUBLIC
virtual
OnShutdownCallback
on_shutdown(const OnShutdownCallback & callback);
on_shutdown(OnShutdownCallback callback);
/// Add a on_shutdown callback to be called when shutdown is called for this context.
/**
@@ -253,7 +249,7 @@ public:
RCLCPP_PUBLIC
virtual
OnShutdownCallbackHandle
add_on_shutdown_callback(const OnShutdownCallback & callback);
add_on_shutdown_callback(OnShutdownCallback callback);
/// Remove an registered on_shutdown callbacks.
/**
@@ -280,7 +276,7 @@ public:
RCLCPP_PUBLIC
virtual
PreShutdownCallbackHandle
add_pre_shutdown_callback(const PreShutdownCallback & callback);
add_pre_shutdown_callback(PreShutdownCallback callback);
/// Remove an registered pre_shutdown callback.
/**
@@ -313,10 +309,6 @@ public:
std::shared_ptr<rcl_context_t>
get_rcl_context();
RCLCPP_PUBLIC
std::shared_ptr<rclcpp::graph_listener::GraphListener>
get_graph_listener();
/// Sleep for a given period of time or until shutdown() is called.
/**
* This function can be interrupted early if:
@@ -389,19 +381,16 @@ private:
std::recursive_mutex sub_contexts_mutex_;
std::vector<std::shared_ptr<OnShutdownCallback>> on_shutdown_callbacks_;
mutable std::recursive_mutex on_shutdown_callbacks_mutex_;
mutable std::mutex on_shutdown_callbacks_mutex_;
std::vector<std::shared_ptr<PreShutdownCallback>> pre_shutdown_callbacks_;
mutable std::recursive_mutex pre_shutdown_callbacks_mutex_;
mutable std::mutex pre_shutdown_callbacks_mutex_;
/// Condition variable for timed sleep (see sleep_for).
std::condition_variable interrupt_condition_variable_;
/// Mutex for protecting the global condition variable.
std::mutex interrupt_mutex_;
/// Graph Listener which waits on graph changes for the node and is shared across nodes.
std::shared_ptr<rclcpp::graph_listener::GraphListener> graph_listener_;
/// Keep shared ownership of global vector of weak contexts
std::shared_ptr<WeakContextsWrapper> weak_contexts_;
@@ -417,7 +406,7 @@ private:
RCLCPP_LOCAL
ShutdownCallbackHandle
add_shutdown_callback(
const ShutdownCallback & callback);
ShutdownCallback callback);
template<ShutdownType shutdown_type>
RCLCPP_LOCAL

View File

@@ -46,13 +46,13 @@ namespace rclcpp
RCLCPP_PUBLIC
rclcpp::GenericClient::SharedPtr
create_generic_client(
const std::shared_ptr<node_interfaces::NodeBaseInterface> & node_base,
const std::shared_ptr<node_interfaces::NodeGraphInterface> & node_graph,
const std::shared_ptr<node_interfaces::NodeServicesInterface> & node_services,
std::shared_ptr<node_interfaces::NodeBaseInterface> node_base,
std::shared_ptr<node_interfaces::NodeGraphInterface> node_graph,
std::shared_ptr<node_interfaces::NodeServicesInterface> node_services,
const std::string & service_name,
const std::string & service_type,
const rclcpp::QoS & qos = rclcpp::ServicesQoS(),
const rclcpp::CallbackGroup::SharedPtr & group = rclcpp::CallbackGroup::SharedPtr());
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create a generic service client with a name of given type.
/**

View File

@@ -270,8 +270,8 @@ apply_qos_override(
RCLCPP_DETAIL_APPLY_QOS_OVERRIDE_FROM_PARAMETER_STRING(
reliability, RELIABILITY, value, qos);
break;
case QosPolicyKind::Invalid:
throw std::invalid_argument{"invalid QosPolicyKind"};
default:
throw std::invalid_argument{"unknown QosPolicyKind"};
}
}
@@ -332,11 +332,9 @@ get_default_qos_param_value(rclcpp::QosPolicyKind kind, const rclcpp::QoS & qos)
return ParameterValue(
check_if_stringified_policy_is_null(
rmw_qos_reliability_policy_to_str(rmw_qos.reliability), kind));
case QosPolicyKind::Invalid:
throw std::invalid_argument{"invalid QoS policy kind"};
default:
throw std::invalid_argument{"unknown QoS policy kind"};
}
return ParameterValue();
}
} // namespace detail

View File

@@ -29,7 +29,7 @@ template<typename OptionsT, typename NodeBaseT>
bool
resolve_enable_topic_statistics(const OptionsT & options, const NodeBaseT & node_base)
{
bool topic_stats_enabled = false;
bool topic_stats_enabled;
switch (options.topic_stats_options.state) {
case TopicStatisticsState::Enable:
topic_stats_enabled = true;

View File

@@ -30,7 +30,7 @@ template<typename OptionsT, typename NodeBaseT>
bool
resolve_use_intra_process(const OptionsT & options, const NodeBaseT & node_base)
{
bool use_intra_process = false;
bool use_intra_process;
switch (options.use_intra_process_comm) {
case IntraProcessSetting::Enable:
use_intra_process = true;
@@ -43,6 +43,7 @@ resolve_use_intra_process(const OptionsT & options, const NodeBaseT & node_base)
break;
default:
throw std::runtime_error("Unrecognized IntraProcessSetting value");
break;
}
return use_intra_process;

View File

@@ -15,7 +15,6 @@
#ifndef RCLCPP__EVENT_HANDLER_HPP_
#define RCLCPP__EVENT_HANDLER_HPP_
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>
@@ -111,14 +110,6 @@ public:
RCLCPP_PUBLIC
virtual ~EventHandlerBase();
RCLCPP_PUBLIC
virtual
void enable() = 0;
RCLCPP_PUBLIC
virtual
void disable() = 0;
/// Get the number of ready events
RCLCPP_PUBLIC
size_t
@@ -201,7 +192,7 @@ public:
}
};
std::lock_guard<std::recursive_mutex> lock(on_new_event_callback_mutex_);
std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
// Set it temporarily to the new callback, while we replace the old one.
// This two-step setting, prevents a gap where the old std::function has
@@ -224,7 +215,7 @@ public:
void
clear_on_ready_callback() override
{
std::lock_guard<std::recursive_mutex> lock(on_new_event_callback_mutex_);
std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
if (on_new_event_callback_) {
set_on_new_event_callback(nullptr, nullptr);
on_new_event_callback_ = nullptr;
@@ -243,7 +234,7 @@ protected:
void
set_on_new_event_callback(rcl_event_callback_t callback, const void * user_data);
std::recursive_mutex on_new_event_callback_mutex_;
std::recursive_mutex callback_mutex_;
std::function<void(size_t)> on_new_event_callback_{nullptr};
rcl_event_t event_handle_;
@@ -311,10 +302,6 @@ public:
void
execute(const std::shared_ptr<void> & data) override
{
std::unique_lock<std::mutex> event_callback_lock(event_callback_mutex_);
if (disabled_.load()) {
return;
}
if (!data) {
throw std::runtime_error("'data' is empty");
}
@@ -323,53 +310,12 @@ public:
callback_ptr.reset();
}
/// Disable the event callback from being called when execute(..) invoked
/**
* This will also temporarily remove the on_new_event_callback from the underlying rmw layer,
* so that it is not called from the middleware while disabled.
*/
void disable() override
{
{
// Temporary remove the on_new_event_callback_ to prevent it from being called
std::lock_guard<std::recursive_mutex> on_new_event_lock(on_new_event_callback_mutex_);
if (on_new_event_callback_) {
set_on_new_event_callback(nullptr, nullptr);
}
}
std::lock_guard<std::mutex> event_callback_lock(event_callback_mutex_);
disabled_.store(true);
}
/// Enable the event callback to be called when execute(..) invoked
/**
* This will also set back the on_new_event_callback to the underlying rmw layer, if it was
* previously removed with disable().
*/
void enable() override
{
{
// Set callback again if it was previously removed in disable()
std::lock_guard<std::recursive_mutex> on_new_event_lock(on_new_event_callback_mutex_);
if (on_new_event_callback_) {
set_on_new_event_callback(
rclcpp::detail::cpp_callback_trampoline<
decltype(on_new_event_callback_), const void *, size_t>,
static_cast<const void *>(&on_new_event_callback_));
}
}
std::lock_guard<std::mutex> event_callback_lock(event_callback_mutex_);
disabled_.store(false);
}
private:
using EventCallbackInfoT = typename std::remove_reference<typename
rclcpp::function_traits::function_traits<EventCallbackT>::template argument_type<0>>::type;
ParentHandleT parent_handle_;
EventCallbackT event_callback_;
std::mutex event_callback_mutex_;
std::atomic_bool disabled_{false};
};
} // namespace rclcpp

View File

@@ -102,8 +102,8 @@ public:
RCLCPP_PUBLIC
virtual void
add_callback_group(
const rclcpp::CallbackGroup::SharedPtr & group_ptr,
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
rclcpp::CallbackGroup::SharedPtr group_ptr,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
bool notify = true);
/// Get callback groups that belong to executor.
@@ -173,7 +173,7 @@ public:
RCLCPP_PUBLIC
virtual void
remove_callback_group(
const rclcpp::CallbackGroup::SharedPtr & group_ptr,
rclcpp::CallbackGroup::SharedPtr group_ptr,
bool notify = true);
/// Add a node to the executor.
@@ -197,9 +197,7 @@ public:
*/
RCLCPP_PUBLIC
virtual void
add_node(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
bool notify = true);
add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify = true);
/// Convenience function which takes Node and forwards NodeBaseInterface.
/**
@@ -207,7 +205,7 @@ public:
*/
RCLCPP_PUBLIC
virtual void
add_node(const std::shared_ptr<rclcpp::Node> & node_ptr, bool notify = true);
add_node(std::shared_ptr<rclcpp::Node> node_ptr, bool notify = true);
/// Remove a node from the executor.
/**
@@ -227,9 +225,7 @@ public:
*/
RCLCPP_PUBLIC
virtual void
remove_node(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
bool notify = true);
remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify = true);
/// Convenience function which takes Node and forwards NodeBaseInterface.
/**
@@ -237,7 +233,7 @@ public:
*/
RCLCPP_PUBLIC
virtual void
remove_node(const std::shared_ptr<rclcpp::Node> & node_ptr, bool notify = true);
remove_node(std::shared_ptr<rclcpp::Node> node_ptr, bool notify = true);
/// Add a node to executor, execute the next available unit of work, and remove the node.
/**
@@ -249,7 +245,7 @@ public:
template<typename RepT = int64_t, typename T = std::milli>
void
spin_node_once(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
std::chrono::duration<RepT, T> timeout = std::chrono::duration<RepT, T>(-1))
{
return spin_node_once_nanoseconds(
@@ -262,7 +258,7 @@ public:
template<typename NodeT = rclcpp::Node, typename RepT = int64_t, typename T = std::milli>
void
spin_node_once(
const std::shared_ptr<NodeT> & node,
std::shared_ptr<NodeT> node,
std::chrono::duration<RepT, T> timeout = std::chrono::duration<RepT, T>(-1))
{
return spin_node_once_nanoseconds(
@@ -277,12 +273,12 @@ public:
*/
RCLCPP_PUBLIC
virtual void
spin_node_some(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node);
spin_node_some(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node);
/// Convenience function which takes Node and forwards NodeBaseInterface.
RCLCPP_PUBLIC
virtual void
spin_node_some(const std::shared_ptr<rclcpp::Node> & node);
spin_node_some(std::shared_ptr<rclcpp::Node> node);
/// Collect work once and execute all available work, optionally within a max duration.
/**
@@ -325,13 +321,13 @@ public:
RCLCPP_PUBLIC
virtual void
spin_node_all(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
std::chrono::nanoseconds max_duration);
/// Convenience function which takes Node and forwards NodeBaseInterface.
RCLCPP_PUBLIC
virtual void
spin_node_all(const std::shared_ptr<rclcpp::Node> & node, std::chrono::nanoseconds max_duration);
spin_node_all(std::shared_ptr<rclcpp::Node> node, std::chrono::nanoseconds max_duration);
/// Collect and execute work repeatedly within a duration or until no more work is available.
/**
@@ -375,9 +371,6 @@ public:
* If the time spent inside the blocking loop exceeds this timeout, return a TIMEOUT return
* code.
* \return The return code, one of `SUCCESS`, `INTERRUPTED`, or `TIMEOUT`.
* \note This method will check the future and the timeout only when the executor is woken up.
* If this future is unrelated to an executor's entity, this method will not correctly detect
* when it's completed and therefore may wait forever and never time out.
*/
template<typename FutureT, typename TimeRepT = int64_t, typename TimeT = std::milli>
FutureReturnCode
@@ -431,7 +424,7 @@ protected:
RCLCPP_PUBLIC
void
spin_node_once_nanoseconds(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
std::chrono::nanoseconds timeout);
/// Spin (blocking) until the future is complete, it times out waiting, or rclcpp is interrupted.
@@ -482,7 +475,7 @@ protected:
RCLCPP_PUBLIC
static void
execute_subscription(
const rclcpp::SubscriptionBase::SharedPtr & subscription);
rclcpp::SubscriptionBase::SharedPtr subscription);
/// Run timer executable.
/**
@@ -491,7 +484,7 @@ protected:
*/
RCLCPP_PUBLIC
static void
execute_timer(const rclcpp::TimerBase::SharedPtr & timer, const std::shared_ptr<void> & data_ptr);
execute_timer(rclcpp::TimerBase::SharedPtr timer, const std::shared_ptr<void> & data_ptr);
/// Run service server executable.
/**
@@ -500,7 +493,7 @@ protected:
*/
RCLCPP_PUBLIC
static void
execute_service(const rclcpp::ServiceBase::SharedPtr & service);
execute_service(rclcpp::ServiceBase::SharedPtr service);
/// Run service client executable.
/**
@@ -509,7 +502,7 @@ protected:
*/
RCLCPP_PUBLIC
static void
execute_client(const rclcpp::ClientBase::SharedPtr & client);
execute_client(rclcpp::ClientBase::SharedPtr client);
/// Gather all of the waitable entities from associated nodes and callback groups.
RCLCPP_PUBLIC

View File

@@ -20,6 +20,7 @@
#include "rclcpp/executors/multi_threaded_executor.hpp"
#include "rclcpp/executors/single_threaded_executor.hpp"
#include "rclcpp/executors/static_single_threaded_executor.hpp"
#include "rclcpp/experimental/executors/events_executor/events_executor.hpp"
#include "rclcpp/node.hpp"
#include "rclcpp/utilities.hpp"
@@ -28,95 +29,37 @@
namespace rclcpp
{
/**
* @brief Create a default single-threaded executor and execute all available work exhaustively.
* @param node_ptr Shared pointer to the base interface of the node to spin.
* @param max_duration max duration to spin
*
* This method is deprecated because it can lead to very bad performance if used in a loop:
* each call will create a new executor and register the node, which is an expensive operation.
* It's recommended to always manually instantiate an executor and call the methods with
* the same name on it.
* For example:
* SingleThreadedExecutor executor;
* executor.add_node(node_ptr);
* executor.spin_all(max_duration);
* If you are using a non-default context, this should be passed to the executor's constructor.
*/
[[deprecated("use SingleThreadedExecutor::spin_all instead")]]
/// Create a default single-threaded executor and execute all available work exhaustively.
/** \param[in] node_ptr Shared pointer to the node to spin. */
RCLCPP_PUBLIC
void
spin_all(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
std::chrono::nanoseconds max_duration);
/**
* @brief Create a default single-threaded executor and execute all available work exhaustively.
* @param node_ptr Shared pointer to the node to spin.
* @param max_duration max duration to spin
*
* This method is deprecated because it can lead to very bad performance if used in a loop:
* each call will create a new executor and register the node, which is an expensive operation.
* It's recommended to always manually instantiate an executor and call the methods with
* the same name on it.
* For example:
* SingleThreadedExecutor executor;
* executor.add_node(node_ptr);
* executor.spin_all(max_duration);
* If you are using a non-default context, this should be passed to the executor's constructor.
*/
[[deprecated("use SingleThreadedExecutor::spin_all instead")]]
RCLCPP_PUBLIC
void
spin_all(const rclcpp::Node::SharedPtr & node_ptr, std::chrono::nanoseconds max_duration);
spin_all(rclcpp::Node::SharedPtr node_ptr, std::chrono::nanoseconds max_duration);
/**
* @brief Create a default single-threaded executor and execute any immediately available work.
* @param node_ptr Shared pointer to the base interface of the node to spin.
*
* This method is deprecated because it can lead to very bad performance if used in a loop:
* each call will create a new executor and register the node, which is an expensive operation.
* It's recommended to always manually instantiate an executor and call the methods with
* the same name on it.
* For example:
* SingleThreadedExecutor executor;
* executor.add_node(node_ptr);
* executor.spin_some();
* If you are using a non-default context, this should be passed to the executor's constructor.
*/
[[deprecated("use SingleThreadedExecutor::spin_some instead")]]
/// Create a default single-threaded executor and execute any immediately available work.
/** \param[in] node_ptr Shared pointer to the node to spin. */
RCLCPP_PUBLIC
void
spin_some(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr);
spin_some(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr);
/**
* @brief Create a default single-threaded executor and execute any immediately available work.
* @param node_ptr Shared pointer to the node to spin.
*
* This method is deprecated because it can lead to very bad performance if used in a loop:
* each call will create a new executor and register the node, which is an expensive operation.
* It's recommended to always manually instantiate an executor and call the methods with
* the same name on it.
* For example:
* SingleThreadedExecutor executor;
* executor.add_node(node_ptr);
* executor.spin_some();
* If you are using a non-default context, this should be passed to the executor's constructor.
*/
[[deprecated("use SingleThreadedExecutor::spin_some instead")]]
RCLCPP_PUBLIC
void
spin_some(const rclcpp::Node::SharedPtr & node_ptr);
spin_some(rclcpp::Node::SharedPtr node_ptr);
/// Create a default single-threaded executor and spin the specified node.
/** \param[in] node_ptr Shared pointer to the node to spin. */
RCLCPP_PUBLIC
void
spin(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr);
spin(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr);
RCLCPP_PUBLIC
void
spin(const rclcpp::Node::SharedPtr & node_ptr);
spin(rclcpp::Node::SharedPtr node_ptr);
namespace executors
{
@@ -140,7 +83,7 @@ template<typename FutureT, typename TimeRepT = int64_t, typename TimeT = std::mi
rclcpp::FutureReturnCode
spin_node_until_future_complete(
rclcpp::Executor & executor,
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
const FutureT & future,
std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
{
@@ -157,7 +100,7 @@ template<typename NodeT = rclcpp::Node, typename FutureT, typename TimeRepT = in
rclcpp::FutureReturnCode
spin_node_until_future_complete(
rclcpp::Executor & executor,
const std::shared_ptr<NodeT> & node_ptr,
std::shared_ptr<NodeT> node_ptr,
const FutureT & future,
std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
{
@@ -173,7 +116,7 @@ spin_node_until_future_complete(
template<typename FutureT, typename TimeRepT = int64_t, typename TimeT = std::milli>
rclcpp::FutureReturnCode
spin_until_future_complete(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
const FutureT & future,
std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
{
@@ -187,7 +130,7 @@ template<typename NodeT = rclcpp::Node, typename FutureT, typename TimeRepT = in
typename TimeT = std::milli>
rclcpp::FutureReturnCode
spin_until_future_complete(
const std::shared_ptr<NodeT> & node_ptr,
std::shared_ptr<NodeT> node_ptr,
const FutureT & future,
std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
{

View File

@@ -63,7 +63,7 @@ public:
*/
RCLCPP_PUBLIC
explicit ExecutorEntitiesCollector(
const std::shared_ptr<ExecutorNotifyWaitable> & notify_waitable);
std::shared_ptr<ExecutorNotifyWaitable> notify_waitable);
/// Destructor
RCLCPP_PUBLIC
@@ -82,7 +82,7 @@ public:
*/
RCLCPP_PUBLIC
void
add_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr);
add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr);
/// Remove a node from the entity collector
/**
@@ -92,7 +92,7 @@ public:
*/
RCLCPP_PUBLIC
void
remove_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr);
remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr);
/// Add a callback group to the entity collector
/**
@@ -101,7 +101,7 @@ public:
*/
RCLCPP_PUBLIC
void
add_callback_group(const rclcpp::CallbackGroup::SharedPtr & group_ptr);
add_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr);
/// Remove a callback group from the entity collector
/**
@@ -111,7 +111,7 @@ public:
*/
RCLCPP_PUBLIC
void
remove_callback_group(const rclcpp::CallbackGroup::SharedPtr & group_ptr);
remove_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr);
/// Get all callback groups known to this entity collector
/**
@@ -211,7 +211,7 @@ protected:
RCLCPP_PUBLIC
void
add_callback_group_to_collection(
const rclcpp::CallbackGroup::SharedPtr & group_ptr,
rclcpp::CallbackGroup::SharedPtr group_ptr,
CallbackGroupCollection & collection) RCPPUTILS_TSA_REQUIRES(mutex_);
/// Iterate over queued added/remove nodes and callback_groups

View File

@@ -43,8 +43,7 @@ public:
*/
RCLCPP_PUBLIC
explicit ExecutorNotifyWaitable(
const std::function<void(void)> & on_execute_callback = {},
const rclcpp::Context::SharedPtr & context =
std::function<void(void)> on_execute_callback = {}, const rclcpp::Context::SharedPtr & context =
rclcpp::contexts::get_global_default_context());
// Destructor
@@ -116,7 +115,7 @@ public:
*/
RCLCPP_PUBLIC
void
add_guard_condition(const rclcpp::GuardCondition::WeakPtr & guard_condition);
add_guard_condition(rclcpp::GuardCondition::WeakPtr guard_condition);
/// Unset any callback registered via set_on_ready_callback.
/**
@@ -140,7 +139,7 @@ public:
*/
RCLCPP_PUBLIC
void
remove_guard_condition(const rclcpp::GuardCondition::WeakPtr & weak_guard_condition);
remove_guard_condition(rclcpp::GuardCondition::WeakPtr weak_guard_condition);
/// Get the number of ready guard_conditions
/**

View File

@@ -0,0 +1,145 @@
// Copyright 2019 Nobleo Technology
//
// 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 RCLCPP__EXECUTORS__STATIC_SINGLE_THREADED_EXECUTOR_HPP_
#define RCLCPP__EXECUTORS__STATIC_SINGLE_THREADED_EXECUTOR_HPP_
#include <atomic>
#include <chrono>
#include <memory>
#include "rclcpp/executor.hpp"
#include "rclcpp/executors/executor_entities_collection.hpp"
#include "rclcpp/executors/single_threaded_executor.hpp"
namespace rclcpp
{
namespace executors
{
/// Static executor implementation
/**
* This executor is a static version of the original single threaded executor.
* It contains some performance optimization to avoid unnecessary reconstructions of
* the executable list for every iteration.
* All nodes, callbackgroups, timers, subscriptions etc. are created before
* spin() is called, and modified only when an entity is added/removed to/from a node.
* This executor is deprecated because these performance improvements have now been
* applied to all other executors.
* This executor is also considered unstable due to known bugs.
* See the unit-tests that are only applied to `StandardExecutors` for information
* on the known limitations.
*
* To run this executor instead of SingleThreadedExecutor replace:
* rclcpp::executors::SingleThreadedExecutor exec;
* by
* rclcpp::executors::StaticSingleThreadedExecutor exec;
* in your source code and spin node(s) in the following way:
* exec.add_node(node);
* exec.spin();
* exec.remove_node(node);
*/
class [[deprecated("Use rclcpp::executors::SingleThreadedExecutor")]] StaticSingleThreadedExecutor
: public rclcpp::Executor
{
public:
RCLCPP_SMART_PTR_DEFINITIONS(StaticSingleThreadedExecutor)
/// Default constructor. See the default constructor for Executor.
RCLCPP_PUBLIC
explicit StaticSingleThreadedExecutor(
const rclcpp::ExecutorOptions & options = rclcpp::ExecutorOptions());
/// Default destructor.
RCLCPP_PUBLIC
virtual ~StaticSingleThreadedExecutor();
/// Static executor implementation of spin.
/**
* This function will block until work comes in, execute it, and keep blocking.
* It will only be interrupted by a CTRL-C (managed by the global signal handler).
* \throws std::runtime_error when spin() called while already spinning
*/
RCLCPP_PUBLIC
void
spin() override;
/// Static executor implementation of spin some
/**
* This non-blocking function will execute entities that
* were ready when this API was called, until timeout or no
* more work available. Entities that got ready while
* executing work, won't be taken into account here.
*
* Example:
* while(condition) {
* spin_some();
* sleep(); // User should have some sync work or
* // sleep to avoid a 100% CPU usage
* }
*/
RCLCPP_PUBLIC
void
spin_some(std::chrono::nanoseconds max_duration = std::chrono::nanoseconds(0)) override;
/// Static executor implementation of spin all
/**
* This non-blocking function will execute entities until timeout (must be >= 0)
* or no more work available.
* If timeout is `0`, potentially it blocks forever until no more work is available.
* If new entities get ready while executing work available, they will be executed
* as long as the timeout hasn't expired.
*
* Example:
* while(condition) {
* spin_all();
* sleep(); // User should have some sync work or
* // sleep to avoid a 100% CPU usage
* }
*/
RCLCPP_PUBLIC
void
spin_all(std::chrono::nanoseconds max_duration) override;
protected:
/**
* @brief Executes ready executables from wait set.
* @param collection entities to evaluate for ready executables.
* @param wait_result result to check for ready executables.
* @param spin_once if true executes only the first ready executable.
* @return true if any executable was ready.
*/
bool
execute_ready_executables(
const rclcpp::executors::ExecutorEntitiesCollection & collection,
rclcpp::WaitResult<rclcpp::WaitSet> & wait_result,
bool spin_once);
void
spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive);
void
spin_once_impl(std::chrono::nanoseconds timeout) override;
std::optional<rclcpp::WaitResult<rclcpp::WaitSet>>
collect_and_wait(std::chrono::nanoseconds timeout);
private:
RCLCPP_DISABLE_COPY(StaticSingleThreadedExecutor)
};
} // namespace executors
} // namespace rclcpp
#endif // RCLCPP__EXECUTORS__STATIC_SINGLE_THREADED_EXECUTOR_HPP_

View File

@@ -178,8 +178,6 @@ public:
void clear() override
{
TRACETOOLS_TRACEPOINT(rclcpp_ring_buffer_clear, static_cast<const void *>(this));
std::lock_guard<std::mutex> lock(mutex_);
clear_();
}
private:
@@ -229,14 +227,6 @@ private:
return capacity_ - size_;
}
inline void clear_()
{
ring_buffer_.clear();
size_ = 0;
read_index_ = 0;
write_index_ = capacity_ - 1;
}
/// Traits for checking if a type is std::unique_ptr
template<typename ...>
struct is_std_unique_ptr final : std::false_type {};
@@ -306,7 +296,7 @@ private:
return {};
}
const size_t capacity_;
size_t capacity_;
std::vector<BufferT> ring_buffer_;

View File

@@ -82,9 +82,10 @@ create_intra_process_buffer(
break;
}
case IntraProcessBufferType::CallbackDefault:
default:
{
throw std::runtime_error("IntraProcessBufferType::CallbackDefault is not allowed");
throw std::runtime_error("Unrecognized IntraProcessBufferType value");
break;
}
}

View File

@@ -64,17 +64,17 @@ public:
/// Default constructor. See the default constructor for Executor.
/**
* \param[in] options Options used to configure the executor.
* \param[in] events_queue The queue used to store events.
* \param[in] execute_timers_separate_thread If true, timers are executed in a separate
* thread. If false, timers are executed in the same thread as all other entities.
* \param[in] options Options used to configure the executor.
*/
RCLCPP_PUBLIC
EventsExecutor(
const rclcpp::ExecutorOptions & options = rclcpp::ExecutorOptions(),
rclcpp::experimental::executors::EventsQueue::UniquePtr events_queue = std::make_unique<
rclcpp::experimental::executors::SimpleEventsQueue>(),
bool execute_timers_separate_thread = false);
bool execute_timers_separate_thread = false,
const rclcpp::ExecutorOptions & options = rclcpp::ExecutorOptions());
/// Default destructor.
RCLCPP_PUBLIC

View File

@@ -19,7 +19,6 @@
#include <shared_mutex>
#include <algorithm>
#include <iterator>
#include <memory>
#include <stdexcept>
@@ -119,8 +118,7 @@ public:
typename Alloc = std::allocator<ROSMessageType>
>
uint64_t
add_subscription(
const rclcpp::experimental::SubscriptionIntraProcessBase::SharedPtr & subscription)
add_subscription(rclcpp::experimental::SubscriptionIntraProcessBase::SharedPtr subscription)
{
std::unique_lock<std::shared_timed_mutex> lock(mutex_);
@@ -177,8 +175,8 @@ public:
RCLCPP_PUBLIC
uint64_t
add_publisher(
const rclcpp::PublisherBase::SharedPtr & publisher,
const rclcpp::experimental::buffers::IntraProcessBufferBase::SharedPtr & buffer =
rclcpp::PublisherBase::SharedPtr publisher,
rclcpp::experimental::buffers::IntraProcessBufferBase::SharedPtr buffer =
rclcpp::experimental::buffers::IntraProcessBufferBase::SharedPtr());
/// Unregister a publisher using the publisher's unique id.
@@ -388,39 +386,6 @@ private:
std::vector<uint64_t> take_ownership_subscriptions;
};
/// Hash function for rmw_gid_t to enable use in unordered_map
struct rmw_gid_hash
{
std::size_t operator()(const rmw_gid_t & gid) const noexcept
{
// Using the FNV-1a hash algorithm on the gid data
constexpr std::size_t FNV_prime = 1099511628211u;
std::size_t result = 14695981039346656037u;
for (std::size_t i = 0; i < RMW_GID_STORAGE_SIZE; ++i) {
result ^= gid.data[i];
result *= FNV_prime;
}
return result;
}
};
/// Equality comparison for rmw_gid_t to enable use in unordered_map
struct rmw_gid_equal
{
bool operator()(const rmw_gid_t & lhs, const rmw_gid_t & rhs) const noexcept
{
// Compare the data bytes only.
// implementation_identifier pointer comparison is not used here because
// intra-process communication is always within the same process and RMW,
// and pointer comparison is fragile across dynamically loaded components.
return std::equal(
std::begin(lhs.data),
std::end(lhs.data),
std::begin(rhs.data));
}
};
using SubscriptionMap =
std::unordered_map<uint64_t, rclcpp::experimental::SubscriptionIntraProcessBase::WeakPtr>;
@@ -433,16 +398,6 @@ private:
using PublisherToSubscriptionIdsMap =
std::unordered_map<uint64_t, SplittedSubscriptions>;
/// Structure to store publisher information in GID lookup map
struct PublisherInfo
{
uint64_t pub_id;
rclcpp::PublisherBase::WeakPtr publisher;
};
using GidToPublisherInfoMap =
std::unordered_map<rmw_gid_t, PublisherInfo, rmw_gid_hash, rmw_gid_equal>;
RCLCPP_PUBLIC
static
uint64_t
@@ -455,8 +410,8 @@ private:
RCLCPP_PUBLIC
bool
can_communicate(
const rclcpp::PublisherBase::SharedPtr & pub,
const rclcpp::experimental::SubscriptionIntraProcessBase::SharedPtr & sub) const;
rclcpp::PublisherBase::SharedPtr pub,
rclcpp::experimental::SubscriptionIntraProcessBase::SharedPtr sub) const;
template<
typename ROSMessageType,
@@ -687,8 +642,6 @@ private:
PublisherBufferMap publisher_buffers_;
mutable std::shared_timed_mutex mutex_;
GidToPublisherInfoMap gid_to_publisher_info_;
};
} // namespace experimental

View File

@@ -154,29 +154,6 @@ public:
execute_impl<SubscribedType>(data);
}
/// Disable callbacks from being called
/**
* This method will block, until any subscription's callbacks currently being executed are
* finished.
* This method is thread safe, and provides a safe way to atomically disable the callbacks.
*/
void disable_callbacks() override
{
SubscriptionIntraProcessBase::disable_callbacks();
any_callback_.disable();
}
/// Enable the callbacks to be called
/**
* This method is thread safe, and provides a safe way to atomically enable the callbacks
* in a multithreaded environment.
*/
void enable_callbacks() override
{
SubscriptionIntraProcessBase::enable_callbacks();
any_callback_.enable();
}
protected:
template<typename T>
typename std::enable_if<std::is_same<T, rcl_serialized_message_t>::value, void>::type

View File

@@ -87,22 +87,6 @@ public:
void
execute(const std::shared_ptr<void> & data) override = 0;
/// Disable callbacks from being called
/**
* This function temporary disable on_new_message_callback to prevent it from being called.
*/
RCLCPP_PUBLIC
virtual
void disable_callbacks();
/// Enable the callbacks to be called
/**
* This function enable the on_new_message_callback if it was previously set.
*/
RCLCPP_PUBLIC
virtual
void enable_callbacks();
virtual
bool
use_take_shared_method() const = 0;
@@ -174,7 +158,7 @@ public:
}
};
std::lock_guard<std::recursive_mutex> lock(on_new_message_callback_mutex_);
std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
on_new_message_callback_ = new_callback;
if (unread_count_ > 0) {
@@ -192,7 +176,7 @@ public:
void
clear_on_ready_callback() override
{
std::lock_guard<std::recursive_mutex> lock(on_new_message_callback_mutex_);
std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
on_new_message_callback_ = nullptr;
}
@@ -204,9 +188,8 @@ public:
}
protected:
std::recursive_mutex on_new_message_callback_mutex_;
std::recursive_mutex callback_mutex_;
std::function<void(size_t)> on_new_message_callback_ {nullptr};
bool on_new_message_callback_disabled_{false};
size_t unread_count_{0};
rclcpp::GuardCondition gc_;
@@ -216,13 +199,11 @@ protected:
void
invoke_on_new_message()
{
std::lock_guard<std::recursive_mutex> lock(this->on_new_message_callback_mutex_);
if (!on_new_message_callback_disabled_) {
if (this->on_new_message_callback_) {
this->on_new_message_callback_(1);
} else {
this->unread_count_++;
}
std::lock_guard<std::recursive_mutex> lock(this->callback_mutex_);
if (this->on_new_message_callback_) {
this->on_new_message_callback_(1);
} else {
this->unread_count_++;
}
}

View File

@@ -103,7 +103,7 @@ public:
* @throws std::invalid_argument if timer is a nullptr.
*/
RCLCPP_PUBLIC
void add_timer(const rclcpp::TimerBase::SharedPtr & timer);
void add_timer(rclcpp::TimerBase::SharedPtr timer);
/**
* @brief Remove a single timer from the object storage.
@@ -113,7 +113,7 @@ public:
* @param timer the timer to remove.
*/
RCLCPP_PUBLIC
void remove_timer(const rclcpp::TimerBase::SharedPtr & timer);
void remove_timer(rclcpp::TimerBase::SharedPtr timer);
/**
* @brief Remove all the timers stored in the object.

View File

@@ -95,7 +95,7 @@ public:
GenericClient(
rclcpp::node_interfaces::NodeBaseInterface * node_base,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr & node_graph,
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
const std::string & service_name,
const std::string & service_type,
rcl_client_options_t & client_options);
@@ -111,8 +111,8 @@ public:
RCLCPP_PUBLIC
void
handle_response(
const std::shared_ptr<rmw_request_id_t> & request_header,
const std::shared_ptr<void> & response) override;
std::shared_ptr<rmw_request_id_t> request_header,
std::shared_ptr<void> response) override;
/// Send a request to the service server.
/**
@@ -144,7 +144,7 @@ public:
*/
RCLCPP_PUBLIC
FutureAndRequestId
async_send_request(const Request & request);
async_send_request(const Request request);
/// Send a request to the service server and schedule a callback in the executor.
/**
@@ -172,7 +172,7 @@ public:
>::type * = nullptr
>
SharedFutureAndRequestId
async_send_request(const Request & request, CallbackT && cb)
async_send_request(const Request request, CallbackT && cb)
{
Promise promise;
auto shared_future = promise.get_future().share();
@@ -280,7 +280,7 @@ protected:
RCLCPP_PUBLIC
int64_t
async_send_request_impl(
const Request & request,
const Request request,
CallbackInfoVariant value);
std::optional<CallbackInfoVariant>

View File

@@ -159,10 +159,10 @@ public:
if (std::holds_alternative<SharedPtrCallback>(callback_)) {
(void)request_header;
const auto & cb = std::get<SharedPtrCallback>(callback_);
cb(std::move(request), response);
cb(std::move(request), std::move(response));
} else if (std::holds_alternative<SharedPtrWithRequestHeaderCallback>(callback_)) {
const auto & cb = std::get<SharedPtrWithRequestHeaderCallback>(callback_);
cb(request_header, std::move(request), response);
cb(request_header, std::move(request), std::move(response));
}
TRACETOOLS_TRACEPOINT(callback_end, static_cast<const void *>(this));
return response;
@@ -245,7 +245,7 @@ public:
*/
RCLCPP_PUBLIC
GenericService(
const std::shared_ptr<rcl_node_t> & node_handle,
std::shared_ptr<rcl_node_t> node_handle,
const std::string & service_name,
const std::string & service_type,
GenericServiceCallback any_callback,
@@ -270,7 +270,7 @@ public:
*/
RCLCPP_PUBLIC
bool
take_request(SharedRequest & request_out, rmw_request_id_t & request_id_out);
take_request(SharedRequest request_out, rmw_request_id_t & request_id_out);
RCLCPP_PUBLIC
std::shared_ptr<void>
@@ -287,8 +287,8 @@ public:
RCLCPP_PUBLIC
void
handle_request(
const std::shared_ptr<rmw_request_id_t> & request_header,
const std::shared_ptr<void> & request) override;
std::shared_ptr<rmw_request_id_t> request_header,
std::shared_ptr<void> request) override;
RCLCPP_PUBLIC
void

View File

@@ -80,7 +80,7 @@ public:
node_base,
*rclcpp::get_message_typesupport_handle(topic_type, "rosidl_typesupport_cpp", *ts_lib),
topic_name,
force_cpu_buffer_backend_(options).to_rcl_subscription_options(qos),
options.to_rcl_subscription_options(qos),
options.event_callbacks,
options.use_default_callbacks,
DeliveredMessageKind::SERIALIZED_MESSAGE),
@@ -111,26 +111,6 @@ public:
RCLCPP_PUBLIC
std::shared_ptr<rclcpp::SerializedMessage> create_serialized_message() override;
/// Disable callbacks from being called
/**
* This method will block, until any subscription's callbacks provided during construction
* currently being executed are finished.
* \note This method also temporary removes the on new message callback and all
* on new event callbacks from the rmw layer to prevent them from being called. However, this
* method will not block and wait until the currently executing on_new_[message]event callbacks
* are finished.
*/
RCLCPP_PUBLIC
void disable_callbacks() override;
/// Enable the callbacks to be called
/**
* This method is thread safe, and provides a safe way to atomically enable the callbacks
* in a multithreaded environment.
*/
RCLCPP_PUBLIC
void enable_callbacks() override;
/// Cast the message to a rclcpp::SerializedMessage and call the callback.
RCLCPP_PUBLIC
void handle_message(
@@ -182,17 +162,6 @@ public:
private:
RCLCPP_DISABLE_COPY(GenericSubscription)
template<typename AllocatorT>
static rclcpp::SubscriptionOptionsWithAllocator<AllocatorT>
force_cpu_buffer_backend_(
const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & options)
{
auto opts = options;
opts.acceptable_buffer_backends = "cpu";
return opts;
}
AnySubscriptionCallback<rclcpp::SerializedMessage, std::allocator<void>> any_callback_;
// The type support library should stay loaded, so it is stored in the GenericSubscription
std::shared_ptr<rcpputils::SharedLibrary> ts_lib_;

View File

@@ -154,12 +154,6 @@ public:
bool
is_shutdown();
/// Return true if the graph listener was started.
RCLCPP_PUBLIC
virtual
bool
is_started();
protected:
/// Main function for the listening thread.
RCLCPP_PUBLIC
@@ -187,6 +181,7 @@ private:
void
__shutdown();
std::weak_ptr<rclcpp::Context> weak_parent_context_;
std::shared_ptr<rcl_context_t> rcl_parent_context_;
std::thread listener_thread_;

View File

@@ -120,7 +120,7 @@ public:
*/
RCLCPP_PUBLIC
void
set_on_trigger_callback(const std::function<void(size_t)> & callback);
set_on_trigger_callback(std::function<void(size_t)> callback);
protected:
rcl_guard_condition_t rcl_guard_condition_;

View File

@@ -78,6 +78,34 @@ RCLCPP_PUBLIC
Logger
get_node_logger(const rcl_node_t * node);
// TODO(ahcorde): Remove deprecated class on the next release (in Rolling after Kilted).
#if !defined(_WIN32)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#else // !defined(_WIN32)
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
/// Get the current logging directory.
/**
* For more details of how the logging directory is determined,
* see rcl_logging_get_logging_directory().
*
* \returns the logging directory being used.
* \throws rclcpp::exceptions::RCLError if an unexpected error occurs.
*/
[[deprecated("use rclcpp::get_log_directory instead of rclcpp::get_logging_directory")]]
RCLCPP_PUBLIC
rcpputils::fs::path
get_logging_directory();
// remove warning suppression
#if !defined(_WIN32)
# pragma GCC diagnostic pop
#else // !defined(_WIN32)
# pragma warning(pop)
#endif
/// Get the current logging directory.
/**
* For more details of how the logging directory is determined,

View File

@@ -1,983 +0,0 @@
// Copyright 2017 Open Source Robotics Foundation, Inc.
//
// 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 RCLCPP__LOGGING_HPP_
#define RCLCPP__LOGGING_HPP_
#include <sstream>
#include <type_traits>
#include "rclcpp/logger.hpp"
#include "rcutils/logging_macros.h"
// These are used for compiling out logging macros lower than a minimum severity.
#define RCLCPP_LOG_MIN_SEVERITY_DEBUG 0
#define RCLCPP_LOG_MIN_SEVERITY_INFO 1
#define RCLCPP_LOG_MIN_SEVERITY_WARN 2
#define RCLCPP_LOG_MIN_SEVERITY_ERROR 3
#define RCLCPP_LOG_MIN_SEVERITY_FATAL 4
#define RCLCPP_LOG_MIN_SEVERITY_NONE 5
#define RCLCPP_STATIC_ASSERT_LOGGER(logger) \
do { \
static_assert( \
::std::is_convertible_v<decltype(logger), ::rclcpp::Logger>, \
"First argument to logging macros must be an rclcpp::Logger"); \
} while (0)
/**
* \def RCLCPP_LOG
* Log a message with given severity.
* \param logger The `rclcpp::Logger` to use
* \param ... The format string, followed by the variable arguments for the format string.
*/
#define RCLCPP_LOG(severity, logger, ...) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
RCUTILS_LOG_NAMED(severity, (logger).get_name(), __VA_ARGS__); \
} while (0)
/**
* \def RCLCPP_LOG_ONCE
* Log a message with given severity with the following condition:
* - All log calls except the first one are ignored.
*
* \param logger The `rclcpp::Logger` to use
* \param ... The format string, followed by the variable arguments for the format string.
*/
#define RCLCPP_LOG_ONCE(severity, logger, ...) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
RCUTILS_LOG_ONCE_NAMED(severity, (logger).get_name(), __VA_ARGS__); \
} while (0)
/**
* \def RCLCPP_LOG_EXPRESSION
* Log a message with given severity with the following condition:
* - Log calls are ignored when the expression evaluates to false.
*
* \param logger The `rclcpp::Logger` to use
* \param expression The expression determining if the message should be logged
* \param ... The format string, followed by the variable arguments for the format string.
*/
#define RCLCPP_LOG_EXPRESSION(severity, logger, expression, ...) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
RCUTILS_LOG_EXPRESSION_NAMED(severity, expression, (logger).get_name(), __VA_ARGS__); \
} while (0)
/**
* \def RCLCPP_LOG_FUNCTION
* Log a message with given severity with the following condition:
* - Log calls are ignored when the function returns false.
*
* \param logger The `rclcpp::Logger` to use
* \param function The functions return value determines if the message should be logged
* \param ... The format string, followed by the variable arguments for the format string.
*/
#define RCLCPP_LOG_FUNCTION(severity, logger, function, ...) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
RCUTILS_LOG_FUNCTION_NAMED(severity, function, (logger).get_name(), __VA_ARGS__); \
} while (0)
/**
* \def RCLCPP_LOG_SKIPFIRST
* Log a message with given severity with the following condition:
* - The first log call is ignored but all subsequent calls are processed.
*
* \param logger The `rclcpp::Logger` to use
* \param ... The format string, followed by the variable arguments for the format string.
*/
#define RCLCPP_LOG_SKIPFIRST(severity, logger, ...) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
RCUTILS_LOG_SKIPFIRST_NAMED(severity, (logger).get_name(), __VA_ARGS__); \
} while (0)
#define RCLCPP_LOG_TIME_POINT_FUNC(clock) \
[&c = clock](rcutils_time_point_value_t * time_point)->rcutils_ret_t { \
try { \
*time_point = c.now().nanoseconds(); \
} catch (...) { \
RCUTILS_SAFE_FWRITE_TO_STDERR( \
"[rclcpp|logging.hpp] RCLCPP_DEBUG_THROTTLE could not get current time stamp\n"); \
return RCUTILS_RET_ERROR; \
} \
return RCUTILS_RET_OK; \
}
/**
* \def RCLCPP_LOG_THROTTLE
* Log a message with given severity with the following condition:
* - Log calls are ignored if the last logged message is not longer ago than the specified duration.
*
* \param logger The `rclcpp::Logger` to use
* \param clock rclcpp::Clock that will be used to get the time point.
* \param duration The duration of the throttle interval as an integral value in milliseconds.
* \param ... The format string, followed by the variable arguments for the format string.
*/
#define RCLCPP_LOG_THROTTLE(severity, logger, clock, duration, ...) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
RCUTILS_LOG_THROTTLE_NAMED( \
severity, \
RCLCPP_LOG_TIME_POINT_FUNC(clock), \
duration, \
(logger).get_name(), \
__VA_ARGS__); \
} while (0)
/**
* \def RCLCPP_LOG_SKIPFIRST_THROTTLE
* Log a message with given severity with the following conditions:
* - The first log call is ignored but all subsequent calls are processed.
* - Log calls are ignored if the last logged message is not longer ago than the specified duration.
*
* \param logger The `rclcpp::Logger` to use
* \param clock rclcpp::Clock that will be used to get the time point.
* \param duration The duration of the throttle interval as an integral value in milliseconds.
* \param ... The format string, followed by the variable arguments for the format string.
*/
#define RCLCPP_LOG_SKIPFIRST_THROTTLE(severity, logger, clock, duration, ...) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
RCUTILS_LOG_SKIPFIRST_THROTTLE_NAMED( \
severity, \
RCLCPP_LOG_TIME_POINT_FUNC(clock), \
duration, \
(logger).get_name(), \
__VA_ARGS__); \
} while (0)
/**
* \def RCLCPP_LOG_STREAM
* Log a message with given severity.
*
* \param logger The `rclcpp::Logger` to use
* \param stream_arg The argument << into a stringstream
*/
#define RCLCPP_LOG_STREAM(severity, logger, stream_arg) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
std::stringstream rclcpp_stream_ss_; \
rclcpp_stream_ss_ << stream_arg; \
RCUTILS_LOG_NAMED(severity, (logger).get_name(), "%s", rclcpp_stream_ss_.str().c_str()); \
} while (0)
/**
* \def RCLCPP_LOG_STREAM_ONCE
* Log a message with given severity with the following condition:
* - All log calls except the first one are ignored.
*
* \param logger The `rclcpp::Logger` to use
* \param stream_arg The argument << into a stringstream
*/
#define RCLCPP_LOG_STREAM_ONCE(severity, logger, stream_arg) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
std::stringstream rclcpp_stream_ss_; \
rclcpp_stream_ss_ << stream_arg; \
RCUTILS_LOG_ONCE_NAMED(severity, (logger).get_name(), "%s", rclcpp_stream_ss_.str().c_str()); \
} while (0)
/**
* \def RCLCPP_LOG_STREAM_EXPRESSION
* Log a message with given severity with the following condition:
* - Log calls are being ignored when the expression evaluates to false.
*
* \param logger The `rclcpp::Logger` to use
* \param expression The expression determining if the message should be logged
* \param stream_arg The argument << into a stringstream
*/
#define RCLCPP_LOG_STREAM_EXPRESSION(severity, logger, expression, stream_arg) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
std::stringstream rclcpp_stream_ss_; \
rclcpp_stream_ss_ << stream_arg; \
RCUTILS_LOG_EXPRESSION_NAMED( \
severity, \
expression, \
(logger).get_name(), \
"%s", rclcpp_stream_ss_.str().c_str()); \
} while (0)
/**
* \def RCLCPP_LOG_STREAM_FUNCTION
* Log a message with given severity with the following condition:
* - Log calls are being ignored when the function returns false.
*
* \param logger The `rclcpp::Logger` to use
* \param function The functions return value determines if the message should be logged
* \param stream_arg The argument << into a stringstream
*/
#define RCLCPP_LOG_STREAM_FUNCTION(severity, logger, function, stream_arg) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
std::stringstream rclcpp_stream_ss_; \
rclcpp_stream_ss_ << stream_arg; \
RCUTILS_LOG_FUNCTION_NAMED( \
severity, \
function, \
(logger).get_name(), \
"%s", rclcpp_stream_ss_.str().c_str()); \
} while (0)
/**
* \def RCLCPP_LOG_STREAM_SKIPFIRST
* Log a message with given severity with the following condition:
* - The first log call is ignored but all subsequent calls are processed.
*
* \param logger The `rclcpp::Logger` to use
* \param stream_arg The argument << into a stringstream
*/
#define RCLCPP_LOG_STREAM_SKIPFIRST(severity, logger, stream_arg) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
std::stringstream rclcpp_stream_ss_; \
rclcpp_stream_ss_ << stream_arg; \
RCUTILS_LOG_SKIPFIRST_NAMED( \
severity, \
(logger).get_name(), \
"%s", rclcpp_stream_ss_.str().c_str()); \
} while (0)
/**
* \def RCLCPP_LOG_STREAM_THROTTLE
* Log a message with given severity with the following condition:
* - Log calls are ignored if the last logged message is not longer ago than the specified duration.
*
* \param logger The `rclcpp::Logger` to use
* \param clock rclcpp::Clock that will be used to get the time point.
* \param duration The duration of the throttle interval as an integral value in milliseconds.
* \param stream_arg The argument << into a stringstream
*/
#define RCLCPP_LOG_STREAM_THROTTLE(severity, logger, clock, duration, stream_arg) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
std::stringstream rclcpp_stream_ss_; \
rclcpp_stream_ss_ << stream_arg; \
RCUTILS_LOG_THROTTLE_NAMED( \
severity, \
RCLCPP_LOG_TIME_POINT_FUNC(clock), \
duration, \
(logger).get_name(), \
"%s", rclcpp_stream_ss_.str().c_str()); \
} while (0)
/**
* \def RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE
* Log a message with given severity with the following conditions:
* - The first log call is ignored but all subsequent calls are processed.
* - Log calls are ignored if the last logged message is not longer ago than the specified duration.
*
* \param logger The `rclcpp::Logger` to use
* \param clock rclcpp::Clock that will be used to get the time point.
* \param duration The duration of the throttle interval as an integral value in milliseconds.
* \param stream_arg The argument << into a stringstream
*/
#define RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE(severity, logger, clock, duration, stream_arg) \
do { \
RCLCPP_STATIC_ASSERT_LOGGER(logger); \
std::stringstream rclcpp_stream_ss_; \
rclcpp_stream_ss_ << stream_arg; \
RCUTILS_LOG_SKIPFIRST_THROTTLE_NAMED( \
severity, \
RCLCPP_LOG_TIME_POINT_FUNC(clock), \
duration, \
(logger).get_name(), \
"%s", rclcpp_stream_ss_.str().c_str()); \
} while (0)
/**
* \def RCLCPP_LOG_MIN_SEVERITY
* Define RCLCPP_LOG_MIN_SEVERITY=RCLCPP_LOG_MIN_SEVERITY_[DEBUG|INFO|WARN|ERROR|FATAL]
* in your build options to compile out anything below that severity.
* Use RCLCPP_LOG_MIN_SEVERITY_NONE to compile out all macros.
*/
#ifndef RCLCPP_LOG_MIN_SEVERITY
#define RCLCPP_LOG_MIN_SEVERITY RCLCPP_LOG_MIN_SEVERITY_DEBUG
#endif
/** @name Logging macros for severity DEBUG.
*/
#if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_DEBUG)
// empty logging macros for severity DEBUG when being disabled at compile time
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_SKIPFIRST_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_STREAM(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_STREAM_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_STREAM_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_STREAM_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_STREAM_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_STREAM_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_DEBUG_STREAM_SKIPFIRST_THROTTLE(...)
#else
/**
* \def RCLCPP_DEBUG
* \copydoc RCLCPP_LOG
*/
#define RCLCPP_DEBUG(logger, ...) RCLCPP_LOG(RCUTILS_LOG_SEVERITY_DEBUG, logger, __VA_ARGS__)
/**
* \def RCLCPP_DEBUG_ONCE
* \copydoc RCLCPP_LOG_ONCE
*/
#define RCLCPP_DEBUG_ONCE(logger, ...) \
RCLCPP_LOG_ONCE(RCUTILS_LOG_SEVERITY_DEBUG, logger, __VA_ARGS__)
/**
* \def RCLCPP_DEBUG_EXPRESSION
* \copydoc RCLCPP_LOG_EXPRESSION
*/
#define RCLCPP_DEBUG_EXPRESSION(logger, expression, ...) \
RCLCPP_LOG_EXPRESSION(RCUTILS_LOG_SEVERITY_DEBUG, logger, expression, __VA_ARGS__)
/**
* \def RCLCPP_DEBUG_FUNCTION
* \copydoc RCLCPP_LOG_FUNCTION
*/
#define RCLCPP_DEBUG_FUNCTION(logger, function, ...) \
RCLCPP_LOG_FUNCTION(RCUTILS_LOG_SEVERITY_DEBUG, logger, function, __VA_ARGS__)
/**
* \def RCLCPP_DEBUG_SKIPFIRST
* \copydoc RCLCPP_LOG_SKIPFIRST
*/
#define RCLCPP_DEBUG_SKIPFIRST(logger, ...) \
RCLCPP_LOG_SKIPFIRST(RCUTILS_LOG_SEVERITY_DEBUG, logger, __VA_ARGS__)
/**
* \def RCLCPP_DEBUG_THROTTLE
* \copydoc RCLCPP_LOG_THROTTLE
*/
#define RCLCPP_DEBUG_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_THROTTLE(RCUTILS_LOG_SEVERITY_DEBUG, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_DEBUG_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_SKIPFIRST_THROTTLE
*/
#define RCLCPP_DEBUG_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_DEBUG, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_DEBUG_STREAM
* \copydoc RCLCPP_LOG_STREAM
*/
#define RCLCPP_DEBUG_STREAM(logger, stream_arg) \
RCLCPP_LOG_STREAM(RCUTILS_LOG_SEVERITY_DEBUG, logger, stream_arg)
/**
* \def RCLCPP_DEBUG_STREAM_ONCE
* \copydoc RCLCPP_LOG_STREAM_ONCE
*/
#define RCLCPP_DEBUG_STREAM_ONCE(logger, stream_arg) \
RCLCPP_LOG_STREAM_ONCE(RCUTILS_LOG_SEVERITY_DEBUG, logger, stream_arg)
/**
* \def RCLCPP_DEBUG_STREAM_EXPRESSION
* \copydoc RCLCPP_LOG_STREAM_EXPRESSION
*/
#define RCLCPP_DEBUG_STREAM_EXPRESSION(logger, expression, stream_arg) \
RCLCPP_LOG_STREAM_EXPRESSION(RCUTILS_LOG_SEVERITY_DEBUG, logger, expression, stream_arg)
/**
* \def RCLCPP_DEBUG_STREAM_FUNCTION
* \copydoc RCLCPP_LOG_STREAM_FUNCTION
*/
#define RCLCPP_DEBUG_STREAM_FUNCTION(logger, function, stream_arg) \
RCLCPP_LOG_STREAM_FUNCTION(RCUTILS_LOG_SEVERITY_DEBUG, logger, function, stream_args)
/**
* \def RCLCPP_DEBUG_STREAM_SKIPFIRST
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST
*/
#define RCLCPP_DEBUG_STREAM_SKIPFIRST(logger, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST(RCUTILS_LOG_SEVERITY_DEBUG, logger, stream_arg)
/**
* \def RCLCPP_DEBUG_STREAM_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_THROTTLE
*/
#define RCLCPP_DEBUG_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_THROTTLE(RCUTILS_LOG_SEVERITY_DEBUG, logger, clock, duration, stream_arg)
/**
* \def RCLCPP_DEBUG_STREAM_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE
*/
#define RCLCPP_DEBUG_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_DEBUG, logger, clock, duration, \
stream_arg)
#endif
/** @name Logging macros for severity INFO.
*/
#if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_INFO)
// empty logging macros for severity INFO when being disabled at compile time
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_SKIPFIRST_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_STREAM(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_STREAM_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_STREAM_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_STREAM_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_STREAM_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_STREAM_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_INFO_STREAM_SKIPFIRST_THROTTLE(...)
#else
/**
* \def RCLCPP_INFO
* \copydoc RCLCPP_LOG
*/
#define RCLCPP_INFO(logger, ...) RCLCPP_LOG(RCUTILS_LOG_SEVERITY_INFO, logger, __VA_ARGS__)
/**
* \def RCLCPP_INFO_ONCE
* \copydoc RCLCPP_LOG_ONCE
*/
#define RCLCPP_INFO_ONCE(logger, ...) \
RCLCPP_LOG_ONCE(RCUTILS_LOG_SEVERITY_INFO, logger, __VA_ARGS__)
/**
* \def RCLCPP_INFO_EXPRESSION
* \copydoc RCLCPP_LOG_EXPRESSION
*/
#define RCLCPP_INFO_EXPRESSION(logger, expression, ...) \
RCLCPP_LOG_EXPRESSION(RCUTILS_LOG_SEVERITY_INFO, logger, expression, __VA_ARGS__)
/**
* \def RCLCPP_INFO_FUNCTION
* \copydoc RCLCPP_LOG_FUNCTION
*/
#define RCLCPP_INFO_FUNCTION(logger, function, ...) \
RCLCPP_LOG_FUNCTION(RCUTILS_LOG_SEVERITY_INFO, logger, function, __VA_ARGS__)
/**
* \def RCLCPP_INFO_SKIPFIRST
* \copydoc RCLCPP_LOG_SKIPFIRST
*/
#define RCLCPP_INFO_SKIPFIRST(logger, ...) \
RCLCPP_LOG_SKIPFIRST(RCUTILS_LOG_SEVERITY_INFO, logger, __VA_ARGS__)
/**
* \def RCLCPP_INFO_THROTTLE
* \copydoc RCLCPP_LOG_THROTTLE
*/
#define RCLCPP_INFO_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_THROTTLE(RCUTILS_LOG_SEVERITY_INFO, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_INFO_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_SKIPFIRST_THROTTLE
*/
#define RCLCPP_INFO_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_INFO, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_INFO_STREAM
* \copydoc RCLCPP_LOG_STREAM
*/
#define RCLCPP_INFO_STREAM(logger, stream_arg) \
RCLCPP_LOG_STREAM(RCUTILS_LOG_SEVERITY_INFO, logger, stream_arg)
/**
* \def RCLCPP_INFO_STREAM_ONCE
* \copydoc RCLCPP_LOG_STREAM_ONCE
*/
#define RCLCPP_INFO_STREAM_ONCE(logger, stream_arg) \
RCLCPP_LOG_STREAM_ONCE(RCUTILS_LOG_SEVERITY_INFO, logger, stream_arg)
/**
* \def RCLCPP_INFO_STREAM_EXPRESSION
* \copydoc RCLCPP_LOG_STREAM_EXPRESSION
*/
#define RCLCPP_INFO_STREAM_EXPRESSION(logger, expression, stream_arg) \
RCLCPP_LOG_STREAM_EXPRESSION(RCUTILS_LOG_SEVERITY_INFO, logger, expression, stream_arg)
/**
* \def RCLCPP_INFO_STREAM_FUNCTION
* \copydoc RCLCPP_LOG_STREAM_FUNCTION
*/
#define RCLCPP_INFO_STREAM_FUNCTION(logger, function, stream_arg) \
RCLCPP_LOG_STREAM_FUNCTION(RCUTILS_LOG_SEVERITY_INFO, logger, function, stream_args)
/**
* \def RCLCPP_INFO_STREAM_SKIPFIRST
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST
*/
#define RCLCPP_INFO_STREAM_SKIPFIRST(logger, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST(RCUTILS_LOG_SEVERITY_INFO, logger, stream_arg)
/**
* \def RCLCPP_INFO_STREAM_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_THROTTLE
*/
#define RCLCPP_INFO_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_THROTTLE(RCUTILS_LOG_SEVERITY_INFO, logger, clock, duration, stream_arg)
/**
* \def RCLCPP_INFO_STREAM_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE
*/
#define RCLCPP_INFO_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_INFO, logger, clock, duration, \
stream_arg)
#endif
/** @name Logging macros for severity WARN.
*/
#if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_WARN)
// empty logging macros for severity WARN when being disabled at compile time
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_SKIPFIRST_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_STREAM(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_STREAM_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_STREAM_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_STREAM_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_STREAM_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_STREAM_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_WARN_STREAM_SKIPFIRST_THROTTLE(...)
#else
/**
* \def RCLCPP_WARN
* \copydoc RCLCPP_LOG
*/
#define RCLCPP_WARN(logger, ...) RCLCPP_LOG(RCUTILS_LOG_SEVERITY_WARN, logger, __VA_ARGS__)
/**
* \def RCLCPP_WARN_ONCE
* \copydoc RCLCPP_LOG_ONCE
*/
#define RCLCPP_WARN_ONCE(logger, ...) \
RCLCPP_LOG_ONCE(RCUTILS_LOG_SEVERITY_WARN, logger, __VA_ARGS__)
/**
* \def RCLCPP_WARN_EXPRESSION
* \copydoc RCLCPP_LOG_EXPRESSION
*/
#define RCLCPP_WARN_EXPRESSION(logger, expression, ...) \
RCLCPP_LOG_EXPRESSION(RCUTILS_LOG_SEVERITY_WARN, logger, expression, __VA_ARGS__)
/**
* \def RCLCPP_WARN_FUNCTION
* \copydoc RCLCPP_LOG_FUNCTION
*/
#define RCLCPP_WARN_FUNCTION(logger, function, ...) \
RCLCPP_LOG_FUNCTION(RCUTILS_LOG_SEVERITY_WARN, logger, function, __VA_ARGS__)
/**
* \def RCLCPP_WARN_SKIPFIRST
* \copydoc RCLCPP_LOG_SKIPFIRST
*/
#define RCLCPP_WARN_SKIPFIRST(logger, ...) \
RCLCPP_LOG_SKIPFIRST(RCUTILS_LOG_SEVERITY_WARN, logger, __VA_ARGS__)
/**
* \def RCLCPP_WARN_THROTTLE
* \copydoc RCLCPP_LOG_THROTTLE
*/
#define RCLCPP_WARN_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_THROTTLE(RCUTILS_LOG_SEVERITY_WARN, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_WARN_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_SKIPFIRST_THROTTLE
*/
#define RCLCPP_WARN_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_WARN, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_WARN_STREAM
* \copydoc RCLCPP_LOG_STREAM
*/
#define RCLCPP_WARN_STREAM(logger, stream_arg) \
RCLCPP_LOG_STREAM(RCUTILS_LOG_SEVERITY_WARN, logger, stream_arg)
/**
* \def RCLCPP_WARN_STREAM_ONCE
* \copydoc RCLCPP_LOG_STREAM_ONCE
*/
#define RCLCPP_WARN_STREAM_ONCE(logger, stream_arg) \
RCLCPP_LOG_STREAM_ONCE(RCUTILS_LOG_SEVERITY_WARN, logger, stream_arg)
/**
* \def RCLCPP_WARN_STREAM_EXPRESSION
* \copydoc RCLCPP_LOG_STREAM_EXPRESSION
*/
#define RCLCPP_WARN_STREAM_EXPRESSION(logger, expression, stream_arg) \
RCLCPP_LOG_STREAM_EXPRESSION(RCUTILS_LOG_SEVERITY_WARN, logger, expression, stream_arg)
/**
* \def RCLCPP_WARN_STREAM_FUNCTION
* \copydoc RCLCPP_LOG_STREAM_FUNCTION
*/
#define RCLCPP_WARN_STREAM_FUNCTION(logger, function, stream_arg) \
RCLCPP_LOG_STREAM_FUNCTION(RCUTILS_LOG_SEVERITY_WARN, logger, function, stream_args)
/**
* \def RCLCPP_WARN_STREAM_SKIPFIRST
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST
*/
#define RCLCPP_WARN_STREAM_SKIPFIRST(logger, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST(RCUTILS_LOG_SEVERITY_WARN, logger, stream_arg)
/**
* \def RCLCPP_WARN_STREAM_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_THROTTLE
*/
#define RCLCPP_WARN_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_THROTTLE(RCUTILS_LOG_SEVERITY_WARN, logger, clock, duration, stream_arg)
/**
* \def RCLCPP_WARN_STREAM_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE
*/
#define RCLCPP_WARN_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_WARN, logger, clock, duration, \
stream_arg)
#endif
/** @name Logging macros for severity ERROR.
*/
#if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_ERROR)
// empty logging macros for severity ERROR when being disabled at compile time
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_SKIPFIRST_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_STREAM(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_STREAM_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_STREAM_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_STREAM_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_STREAM_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_STREAM_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_ERROR_STREAM_SKIPFIRST_THROTTLE(...)
#else
/**
* \def RCLCPP_ERROR
* \copydoc RCLCPP_LOG
*/
#define RCLCPP_ERROR(logger, ...) RCLCPP_LOG(RCUTILS_LOG_SEVERITY_ERROR, logger, __VA_ARGS__)
/**
* \def RCLCPP_ERROR_ONCE
* \copydoc RCLCPP_LOG_ONCE
*/
#define RCLCPP_ERROR_ONCE(logger, ...) \
RCLCPP_LOG_ONCE(RCUTILS_LOG_SEVERITY_ERROR, logger, __VA_ARGS__)
/**
* \def RCLCPP_ERROR_EXPRESSION
* \copydoc RCLCPP_LOG_EXPRESSION
*/
#define RCLCPP_ERROR_EXPRESSION(logger, expression, ...) \
RCLCPP_LOG_EXPRESSION(RCUTILS_LOG_SEVERITY_ERROR, logger, expression, __VA_ARGS__)
/**
* \def RCLCPP_ERROR_FUNCTION
* \copydoc RCLCPP_LOG_FUNCTION
*/
#define RCLCPP_ERROR_FUNCTION(logger, function, ...) \
RCLCPP_LOG_FUNCTION(RCUTILS_LOG_SEVERITY_ERROR, logger, function, __VA_ARGS__)
/**
* \def RCLCPP_ERROR_SKIPFIRST
* \copydoc RCLCPP_LOG_SKIPFIRST
*/
#define RCLCPP_ERROR_SKIPFIRST(logger, ...) \
RCLCPP_LOG_SKIPFIRST(RCUTILS_LOG_SEVERITY_ERROR, logger, __VA_ARGS__)
/**
* \def RCLCPP_ERROR_THROTTLE
* \copydoc RCLCPP_LOG_THROTTLE
*/
#define RCLCPP_ERROR_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_THROTTLE(RCUTILS_LOG_SEVERITY_ERROR, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_ERROR_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_SKIPFIRST_THROTTLE
*/
#define RCLCPP_ERROR_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_ERROR, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_ERROR_STREAM
* \copydoc RCLCPP_LOG_STREAM
*/
#define RCLCPP_ERROR_STREAM(logger, stream_arg) \
RCLCPP_LOG_STREAM(RCUTILS_LOG_SEVERITY_ERROR, logger, stream_arg)
/**
* \def RCLCPP_ERROR_STREAM_ONCE
* \copydoc RCLCPP_LOG_STREAM_ONCE
*/
#define RCLCPP_ERROR_STREAM_ONCE(logger, stream_arg) \
RCLCPP_LOG_STREAM_ONCE(RCUTILS_LOG_SEVERITY_ERROR, logger, stream_arg)
/**
* \def RCLCPP_ERROR_STREAM_EXPRESSION
* \copydoc RCLCPP_LOG_STREAM_EXPRESSION
*/
#define RCLCPP_ERROR_STREAM_EXPRESSION(logger, expression, stream_arg) \
RCLCPP_LOG_STREAM_EXPRESSION(RCUTILS_LOG_SEVERITY_ERROR, logger, expression, stream_arg)
/**
* \def RCLCPP_ERROR_STREAM_FUNCTION
* \copydoc RCLCPP_LOG_STREAM_FUNCTION
*/
#define RCLCPP_ERROR_STREAM_FUNCTION(logger, function, stream_arg) \
RCLCPP_LOG_STREAM_FUNCTION(RCUTILS_LOG_SEVERITY_ERROR, logger, function, stream_args)
/**
* \def RCLCPP_ERROR_STREAM_SKIPFIRST
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST
*/
#define RCLCPP_ERROR_STREAM_SKIPFIRST(logger, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST(RCUTILS_LOG_SEVERITY_ERROR, logger, stream_arg)
/**
* \def RCLCPP_ERROR_STREAM_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_THROTTLE
*/
#define RCLCPP_ERROR_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_THROTTLE(RCUTILS_LOG_SEVERITY_ERROR, logger, clock, duration, stream_arg)
/**
* \def RCLCPP_ERROR_STREAM_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE
*/
#define RCLCPP_ERROR_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_ERROR, logger, clock, duration, \
stream_arg)
#endif
/** @name Logging macros for severity FATAL.
*/
#if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_FATAL)
// empty logging macros for severity FATAL when being disabled at compile time
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_SKIPFIRST_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_STREAM(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_STREAM_ONCE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_STREAM_EXPRESSION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_STREAM_FUNCTION(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_STREAM_SKIPFIRST(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_STREAM_THROTTLE(...)
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_FATAL_STREAM_SKIPFIRST_THROTTLE(...)
#else
/**
* \def RCLCPP_FATAL
* \copydoc RCLCPP_LOG
*/
#define RCLCPP_FATAL(logger, ...) RCLCPP_LOG(RCUTILS_LOG_SEVERITY_FATAL, logger, __VA_ARGS__)
/**
* \def RCLCPP_FATAL_ONCE
* \copydoc RCLCPP_LOG_ONCE
*/
#define RCLCPP_FATAL_ONCE(logger, ...) \
RCLCPP_LOG_ONCE(RCUTILS_LOG_SEVERITY_FATAL, logger, __VA_ARGS__)
/**
* \def RCLCPP_FATAL_EXPRESSION
* \copydoc RCLCPP_LOG_EXPRESSION
*/
#define RCLCPP_FATAL_EXPRESSION(logger, expression, ...) \
RCLCPP_LOG_EXPRESSION(RCUTILS_LOG_SEVERITY_FATAL, logger, expression, __VA_ARGS__)
/**
* \def RCLCPP_FATAL_FUNCTION
* \copydoc RCLCPP_LOG_FUNCTION
*/
#define RCLCPP_FATAL_FUNCTION(logger, function, ...) \
RCLCPP_LOG_FUNCTION(RCUTILS_LOG_SEVERITY_FATAL, logger, function, __VA_ARGS__)
/**
* \def RCLCPP_FATAL_SKIPFIRST
* \copydoc RCLCPP_LOG_SKIPFIRST
*/
#define RCLCPP_FATAL_SKIPFIRST(logger, ...) \
RCLCPP_LOG_SKIPFIRST(RCUTILS_LOG_SEVERITY_FATAL, logger, __VA_ARGS__)
/**
* \def RCLCPP_FATAL_THROTTLE
* \copydoc RCLCPP_LOG_THROTTLE
*/
#define RCLCPP_FATAL_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_THROTTLE(RCUTILS_LOG_SEVERITY_FATAL, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_FATAL_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_SKIPFIRST_THROTTLE
*/
#define RCLCPP_FATAL_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
RCLCPP_LOG_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_FATAL, logger, clock, duration, __VA_ARGS__)
/**
* \def RCLCPP_FATAL_STREAM
* \copydoc RCLCPP_LOG_STREAM
*/
#define RCLCPP_FATAL_STREAM(logger, stream_arg) \
RCLCPP_LOG_STREAM(RCUTILS_LOG_SEVERITY_FATAL, logger, stream_arg)
/**
* \def RCLCPP_FATAL_STREAM_ONCE
* \copydoc RCLCPP_LOG_STREAM_ONCE
*/
#define RCLCPP_FATAL_STREAM_ONCE(logger, stream_arg) \
RCLCPP_LOG_STREAM_ONCE(RCUTILS_LOG_SEVERITY_FATAL, logger, stream_arg)
/**
* \def RCLCPP_FATAL_STREAM_EXPRESSION
* \copydoc RCLCPP_LOG_STREAM_EXPRESSION
*/
#define RCLCPP_FATAL_STREAM_EXPRESSION(logger, expression, stream_arg) \
RCLCPP_LOG_STREAM_EXPRESSION(RCUTILS_LOG_SEVERITY_FATAL, logger, expression, stream_arg)
/**
* \def RCLCPP_FATAL_STREAM_FUNCTION
* \copydoc RCLCPP_LOG_STREAM_FUNCTION
*/
#define RCLCPP_FATAL_STREAM_FUNCTION(logger, function, stream_arg) \
RCLCPP_LOG_STREAM_FUNCTION(RCUTILS_LOG_SEVERITY_FATAL, logger, function, stream_args)
/**
* \def RCLCPP_FATAL_STREAM_SKIPFIRST
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST
*/
#define RCLCPP_FATAL_STREAM_SKIPFIRST(logger, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST(RCUTILS_LOG_SEVERITY_FATAL, logger, stream_arg)
/**
* \def RCLCPP_FATAL_STREAM_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_THROTTLE
*/
#define RCLCPP_FATAL_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_THROTTLE(RCUTILS_LOG_SEVERITY_FATAL, logger, clock, duration, stream_arg)
/**
* \def RCLCPP_FATAL_STREAM_SKIPFIRST_THROTTLE
* \copydoc RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE
*/
#define RCLCPP_FATAL_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
RCLCPP_LOG_STREAM_SKIPFIRST_THROTTLE(RCUTILS_LOG_SEVERITY_FATAL, logger, clock, duration, \
stream_arg)
#endif
#endif // RCLCPP__LOGGING_HPP_

View File

@@ -18,7 +18,6 @@
#include <memory>
#include <stdexcept>
#include "rcl/allocator.h"
#include "rcl/types.h"
#include "rclcpp/allocator/allocator_common.hpp"
@@ -62,16 +61,7 @@ public:
message_allocator_ = std::make_shared<MessageAlloc>();
serialized_message_allocator_ = std::make_shared<SerializedMessageAlloc>();
buffer_allocator_ = std::make_shared<BufferAlloc>();
if constexpr (std::is_same_v<Alloc, std::allocator<void>>) {
rcutils_allocator_ = rcl_get_default_allocator();
} else {
if constexpr (rclcpp::allocator::has_get_rcl_allocator_v<Alloc>) {
rcutils_allocator_ = message_allocator_->get_rcl_allocator();
} else {
rcutils_allocator_ = allocator::get_rcl_allocator<char,
BufferAlloc>(*buffer_allocator_.get());
}
}
rcutils_allocator_ = allocator::get_rcl_allocator<char, BufferAlloc>(*buffer_allocator_.get());
}
explicit MessageMemoryStrategy(std::shared_ptr<Alloc> allocator)
@@ -79,16 +69,7 @@ public:
message_allocator_ = std::make_shared<MessageAlloc>(*allocator.get());
serialized_message_allocator_ = std::make_shared<SerializedMessageAlloc>(*allocator.get());
buffer_allocator_ = std::make_shared<BufferAlloc>(*allocator.get());
if constexpr (std::is_same_v<Alloc, std::allocator<void>>) {
rcutils_allocator_ = rcl_get_default_allocator();
} else {
if constexpr (rclcpp::allocator::has_get_rcl_allocator_v<Alloc>) {
rcutils_allocator_ = allocator->get_rcl_allocator();
} else {
rcutils_allocator_ = allocator::get_rcl_allocator<char,
BufferAlloc>(*buffer_allocator_.get());
}
}
rcutils_allocator_ = allocator::get_rcl_allocator<char, BufferAlloc>(*buffer_allocator_.get());
}
virtual ~MessageMemoryStrategy() = default;

View File

@@ -242,7 +242,7 @@ public:
create_wall_timer(
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
const rclcpp::CallbackGroup::SharedPtr & group = nullptr,
rclcpp::CallbackGroup::SharedPtr group = nullptr,
bool autostart = true);
/// Create a timer that uses the node clock to drive the callback.
@@ -256,7 +256,7 @@ public:
create_timer(
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
const rclcpp::CallbackGroup::SharedPtr & group = nullptr);
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a Client.
/**
@@ -270,7 +270,7 @@ public:
create_client(
const std::string & service_name,
const rclcpp::QoS & qos = rclcpp::ServicesQoS(),
const rclcpp::CallbackGroup::SharedPtr & group = nullptr);
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a Service.
/**
@@ -286,7 +286,7 @@ public:
const std::string & service_name,
CallbackT && callback,
const rclcpp::QoS & qos = rclcpp::ServicesQoS(),
const rclcpp::CallbackGroup::SharedPtr & group = nullptr);
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a GenericClient.
/**
@@ -302,7 +302,7 @@ public:
const std::string & service_name,
const std::string & service_type,
const rclcpp::QoS & qos = rclcpp::ServicesQoS(),
const rclcpp::CallbackGroup::SharedPtr & group = nullptr);
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a GenericService.
/**
@@ -320,7 +320,7 @@ public:
const std::string & service_type,
CallbackT && callback,
const rclcpp::QoS & qos = rclcpp::ServicesQoS(),
const rclcpp::CallbackGroup::SharedPtr & group = nullptr);
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a GenericPublisher.
/**
@@ -1388,66 +1388,6 @@ public:
std::vector<rclcpp::TopicEndpointInfo>
get_subscriptions_info_by_topic(const std::string & topic_name, bool no_mangle = false) const;
/// Return the service endpoint information about clients on a given service.
/**
* The returned parameter is a list of service endpoint information, where each item will contain
* the node name, node namespace, service type, endpoint type, endpoint count,
* service endpoint's GIDs, and its QoS profiles.
*
* When the `no_mangle` parameter is `true`, the provided `service_name` should be a valid service
* name for the middleware (useful when combining ROS with native middleware apps).
* When the `no_mangle` parameter is `false`, the provided `service_name` should follow
* ROS service name conventions. In DDS-based RMWs, services are implemented as topics with mangled
* names (e.g., `rq/my_serviceRequest` and `rp/my_serviceReply`), so `no_mangle = true` is not
* supported and will result in an error. Use `get_publishers_info_by_topic` or
* `get_subscriptions_info_by_topic` for unmangled topic queries in such cases. Other RMWs
* (e.g., Zenoh) may support `no_mangle = true` if they natively handle services without topic-based
*
* 'service_name` may be a relative, private, or fully qualified service name.
* A relative or private service will be expanded using this node's namespace and name.
* The queried `service_name` is not remapped.
*
* \param[in] service_name the actual service name used; it will not be automatically remapped.
* \param[in] no_mangle if `true`, `service_name` needs to be a valid middleware service name,
* otherwise it should be a valid ROS service name. Defaults to `false`.
* \return a list of SeviceEndpointInfo representing all the clients on this service.
* \throws InvalidServiceNameError if the given service_name is invalid.
* \throws std::runtime_error if internal error happens.
*/
RCLCPP_PUBLIC
std::vector<rclcpp::ServiceEndpointInfo>
get_clients_info_by_service(const std::string & service_name, bool no_mangle = false) const;
/// Return the service endpoint information about servers on a given service.
/**
* The returned parameter is a list of service endpoint information, where each item will contain
* the node name, node namespace, service type, endpoint type, endpoint count,
* service endpoint's GIDs, and its QoS profiles.
*
* When the `no_mangle` parameter is `true`, the provided `service_name` should be a valid service
* name for the middleware (useful when combining ROS with native middleware apps).
* When the `no_mangle` parameter is `false`, the provided `service_name` should follow
* ROS service name conventions. In DDS-based RMWs, services are implemented as topics with mangled
* names (e.g., `rq/my_serviceRequest` and `rp/my_serviceReply`), so `no_mangle = true` is not
* supported and will result in an error. Use `rcl_get_publishers_info_by_topic` or
* `rcl_get_subscriptions_info_by_topic` for unmangled topic queries in such cases. Other RMWs
* (e.g., Zenoh) may support `no_mangle = true` if they natively handle services without topic-based
*
* 'service_name` may be a relative, private, or fully qualified service name.
* A relative or private service will be expanded using this node's namespace and name.
* The queried `service_name` is not remapped.
*
* \param[in] service_name the actual service name used; it will not be automatically remapped.
* \param[in] no_mangle if `true`, `service_name` needs to be a valid middleware service name,
* otherwise it should be a valid ROS service name. Defaults to `false`.
* \return a list of SeviceEndpointInfo representing all the servers on this service.
* \throws InvalidServiceNameError if the given service_name is invalid.
* \throws std::runtime_error if internal error happens.
*/
RCLCPP_PUBLIC
std::vector<rclcpp::ServiceEndpointInfo>
get_servers_info_by_service(const std::string & service_name, bool no_mangle = false) const;
/// Return a graph event, which will be set anytime a graph change occurs.
/* The graph Event object is a loan which must be returned.
* The Event object is scoped and therefore to return the loan just let it go
@@ -1471,7 +1411,7 @@ public:
RCLCPP_PUBLIC
void
wait_for_graph_change(
const rclcpp::Event::SharedPtr & event,
rclcpp::Event::SharedPtr event,
std::chrono::nanoseconds timeout);
/// Get a clock as a non-const shared pointer which is managed by the node.

View File

@@ -111,7 +111,7 @@ typename rclcpp::WallTimer<CallbackT>::SharedPtr
Node::create_wall_timer(
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
const rclcpp::CallbackGroup::SharedPtr & group,
rclcpp::CallbackGroup::SharedPtr group,
bool autostart)
{
return rclcpp::create_wall_timer(
@@ -128,7 +128,7 @@ typename rclcpp::GenericTimer<CallbackT>::SharedPtr
Node::create_timer(
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
const rclcpp::CallbackGroup::SharedPtr & group)
rclcpp::CallbackGroup::SharedPtr group)
{
return rclcpp::create_timer(
this->get_clock(),
@@ -144,7 +144,7 @@ typename Client<ServiceT>::SharedPtr
Node::create_client(
const std::string & service_name,
const rclcpp::QoS & qos,
const rclcpp::CallbackGroup::SharedPtr & group)
rclcpp::CallbackGroup::SharedPtr group)
{
return rclcpp::create_client<ServiceT>(
node_base_,
@@ -161,7 +161,7 @@ Node::create_service(
const std::string & service_name,
CallbackT && callback,
const rclcpp::QoS & qos,
const rclcpp::CallbackGroup::SharedPtr & group)
rclcpp::CallbackGroup::SharedPtr group)
{
return rclcpp::create_service<ServiceT, CallbackT>(
node_base_,
@@ -179,7 +179,7 @@ Node::create_generic_service(
const std::string & service_type,
CallbackT && callback,
const rclcpp::QoS & qos,
const rclcpp::CallbackGroup::SharedPtr & group)
rclcpp::CallbackGroup::SharedPtr group)
{
return rclcpp::create_generic_service<CallbackT>(
node_base_,

View File

@@ -121,6 +121,11 @@ public:
std::atomic_bool &
get_associated_with_executor_atomic() override;
[[deprecated("Use get_shared_notify_guard_condition or trigger_notify_guard_condition instead")]]
RCLCPP_PUBLIC
rclcpp::GuardCondition &
get_notify_guard_condition() override;
RCLCPP_PUBLIC
rclcpp::GuardCondition::SharedPtr
get_shared_notify_guard_condition() override;

View File

@@ -144,6 +144,17 @@ public:
std::atomic_bool &
get_associated_with_executor_atomic() = 0;
/// Return a guard condition that should be notified when the internal node state changes.
/**
* For example, this should be notified when a publisher is added or removed.
*
* \return the GuardCondition if it is valid, else throw runtime error
*/
RCLCPP_PUBLIC
virtual
rclcpp::GuardCondition &
get_notify_guard_condition() = 0;
/// Return a guard condition that should be notified when the internal node state changes.
/**
* For example, this should be notified when a publisher is added or removed.

View File

@@ -33,7 +33,6 @@
#include "rclcpp/node_interfaces/node_base_interface.hpp"
#include "rclcpp/node_interfaces/node_graph_interface.hpp"
#include "rclcpp/visibility_control.hpp"
#include "rmw/service_endpoint_info_array.h"
#include "rmw/topic_endpoint_info_array.h"
namespace rclcpp
@@ -160,24 +159,14 @@ public:
const std::string & topic_name,
bool no_mangle = false) const override;
RCLCPP_PUBLIC
std::vector<rclcpp::ServiceEndpointInfo>
get_clients_info_by_service(
const std::string & service_name,
bool no_mangle = false) const override;
RCLCPP_PUBLIC
std::vector<rclcpp::ServiceEndpointInfo>
get_servers_info_by_service(
const std::string & service_name,
bool no_mangle = false) const override;
private:
RCLCPP_DISABLE_COPY(NodeGraph)
/// Handle to the NodeBaseInterface given in the constructor.
rclcpp::node_interfaces::NodeBaseInterface * node_base_;
/// Graph Listener which waits on graph changes for the node and is shared across nodes.
std::shared_ptr<rclcpp::graph_listener::GraphListener> graph_listener_;
/// Whether or not this node needs to be added to the graph listener.
std::atomic_bool should_add_to_graph_listener_;

View File

@@ -18,8 +18,6 @@
#include <algorithm>
#include <array>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <map>
#include <string>
#include <tuple>
@@ -42,9 +40,7 @@ enum class EndpointType
{
Invalid = RMW_ENDPOINT_INVALID,
Publisher = RMW_ENDPOINT_PUBLISHER,
Subscription = RMW_ENDPOINT_SUBSCRIPTION,
Client = RMW_ENDPOINT_CLIENT,
Server = RMW_ENDPOINT_SERVER
Subscription = RMW_ENDPOINT_SUBSCRIPTION
};
/**
@@ -57,17 +53,13 @@ public:
/// Construct a TopicEndpointInfo from a rcl_topic_endpoint_info_t.
RCLCPP_PUBLIC
explicit TopicEndpointInfo(const rcl_topic_endpoint_info_t & info)
: endpoint_type_(static_cast<rclcpp::EndpointType>(info.endpoint_type)),
: node_name_(info.node_name),
node_namespace_(info.node_namespace),
topic_type_(info.topic_type),
endpoint_type_(static_cast<rclcpp::EndpointType>(info.endpoint_type)),
qos_profile_({info.qos_profile.history, info.qos_profile.depth}, info.qos_profile),
topic_type_hash_(info.topic_type_hash)
{
if (!info.node_name || !info.node_namespace || !info.topic_type) {
throw std::invalid_argument("Constructor TopicEndpointInfo with invalid topic endpoint info");
}
node_name_ = info.node_name;
node_namespace_ = info.node_namespace;
topic_type_ = info.topic_type;
std::copy(info.endpoint_gid, info.endpoint_gid + RMW_GID_STORAGE_SIZE, endpoint_gid_.begin());
}
@@ -151,125 +143,6 @@ private:
rosidl_type_hash_t topic_type_hash_;
};
/**
* Struct that contains service endpoint information like the associated node name, node namespace,
* service type, endpoint type, endpoint count, endpoint GIDs, and its QoS profiles.
*/
class ServiceEndpointInfo
{
public:
/// Construct a ServiceEndpointInfo from a rcl_service_endpoint_info_t.
RCLCPP_PUBLIC
explicit ServiceEndpointInfo(const rcl_service_endpoint_info_t & info)
: node_name_(info.node_name),
node_namespace_(info.node_namespace),
service_type_(info.service_type),
endpoint_type_(static_cast<rclcpp::EndpointType>(info.endpoint_type)),
service_type_hash_(info.service_type_hash),
endpoint_count_(info.endpoint_count)
{
for(size_t i = 0; i < endpoint_count_; i++) {
std::array<uint8_t, RMW_GID_STORAGE_SIZE> gid;
std::copy(info.endpoint_gids[i], info.endpoint_gids[i] + RMW_GID_STORAGE_SIZE, gid.begin());
endpoint_gids_.push_back(gid);
rclcpp::QoS qos(
{info.qos_profiles[i].history, info.qos_profiles[i].depth}, info.qos_profiles[i]);
qos_profiles_.push_back(qos);
}
}
/// Get a mutable reference to the node name.
RCLCPP_PUBLIC
std::string &
node_name();
/// Get a const reference to the node name.
RCLCPP_PUBLIC
const std::string &
node_name() const;
/// Get a mutable reference to the node namespace.
RCLCPP_PUBLIC
std::string &
node_namespace();
/// Get a const reference to the node namespace.
RCLCPP_PUBLIC
const std::string &
node_namespace() const;
/// Get a mutable reference to the service type string.
RCLCPP_PUBLIC
std::string &
service_type();
/// Get a const reference to the service type string.
RCLCPP_PUBLIC
const std::string &
service_type() const;
/// Get a mutable reference to the service endpoint type.
RCLCPP_PUBLIC
rclcpp::EndpointType &
endpoint_type();
/// Get a const reference to the service endpoint type.
RCLCPP_PUBLIC
const rclcpp::EndpointType &
endpoint_type() const;
/// Get a mutable reference to the endpoint count.
RCLCPP_PUBLIC
size_t &
endpoint_count();
/// Get a const reference to the endpoint count.
RCLCPP_PUBLIC
const size_t &
endpoint_count() const;
/// Get a mutable reference to the GID of the service endpoint.
RCLCPP_PUBLIC
std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> &
endpoint_gids();
/// Get a const reference to the GID of the service endpoint.
RCLCPP_PUBLIC
const std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> &
endpoint_gids() const;
/// Get a mutable reference to the QoS profile of the service endpoint.
RCLCPP_PUBLIC
std::vector<rclcpp::QoS> &
qos_profiles();
/// Get a const reference to the QoS profile of the service endpoint.
RCLCPP_PUBLIC
const std::vector<rclcpp::QoS> &
qos_profiles() const;
/// Get a mutable reference to the type hash of the service endpoint.
RCLCPP_PUBLIC
rosidl_type_hash_t &
service_type_hash();
/// Get a const reference to the type hash of the service endpoint.
RCLCPP_PUBLIC
const rosidl_type_hash_t &
service_type_hash() const;
private:
std::string node_name_;
std::string node_namespace_;
std::string service_type_;
rclcpp::EndpointType endpoint_type_;
std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> endpoint_gids_;
std::vector<rclcpp::QoS> qos_profiles_;
rosidl_type_hash_t service_type_hash_;
size_t endpoint_count_;
};
namespace node_interfaces
{
@@ -535,30 +408,6 @@ public:
virtual
std::vector<rclcpp::TopicEndpointInfo>
get_subscriptions_info_by_topic(const std::string & topic_name, bool no_mangle = false) const = 0;
/// Return the service endpoint information about clients on a given service.
/**
* \param[in] service_name the actual service name used; it will not be automatically remapped.
* \param[in] no_mangle if `true`, `service_name` needs to be a valid middleware service name,
* otherwise it should be a valid ROS service name.
* \sa rclcpp::Node::get_clients_info_by_service
*/
RCLCPP_PUBLIC
virtual
std::vector<rclcpp::ServiceEndpointInfo>
get_clients_info_by_service(const std::string & service_name, bool no_mangle = false) const = 0;
/// Return the service endpoint information about servers on a given service.
/**
* \param[in] service_name the actual service name used; it will not be automatically remapped.
* \param[in] no_mangle if `true`, `service_name` needs to be a valid middleware service name,
* otherwise it should be a valid ROS service name.
* \sa rclcpp::Node::get_servers_info_by_service
*/
RCLCPP_PUBLIC
virtual
std::vector<rclcpp::ServiceEndpointInfo>
get_servers_info_by_service(const std::string & service_name, bool no_mangle = false) const = 0;
};
} // namespace node_interfaces

View File

@@ -38,7 +38,7 @@ public:
RCLCPP_SMART_PTR_ALIASES_ONLY(NodeLoggingInterface)
RCLCPP_PUBLIC
explicit NodeLogging(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_base);
explicit NodeLogging(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base);
RCLCPP_PUBLIC
virtual
@@ -55,7 +55,7 @@ public:
RCLCPP_PUBLIC
void
create_logger_services(
const node_interfaces::NodeServicesInterface::SharedPtr & node_services) override;
node_interfaces::NodeServicesInterface::SharedPtr node_services) override;
private:
RCLCPP_DISABLE_COPY(NodeLogging)

View File

@@ -61,7 +61,7 @@ public:
virtual
void
create_logger_services(
const node_interfaces::NodeServicesInterface::SharedPtr & node_services) = 0;
node_interfaces::NodeServicesInterface::SharedPtr node_services) = 0;
};
} // namespace node_interfaces

View File

@@ -39,10 +39,10 @@ public:
RCLCPP_PUBLIC
explicit NodeTypeDescriptions(
const NodeBaseInterface::SharedPtr & node_base,
const NodeLoggingInterface::SharedPtr & node_logging,
const NodeParametersInterface::SharedPtr & node_parameters,
const NodeServicesInterface::SharedPtr & node_services);
NodeBaseInterface::SharedPtr node_base,
NodeLoggingInterface::SharedPtr node_logging,
NodeParametersInterface::SharedPtr node_parameters,
NodeServicesInterface::SharedPtr node_services);
RCLCPP_PUBLIC
virtual

View File

@@ -100,7 +100,7 @@ public:
/// Set the context, return this for parameter idiom.
RCLCPP_PUBLIC
NodeOptions &
context(const rclcpp::Context::SharedPtr & context);
context(rclcpp::Context::SharedPtr context);
/// Return a reference to the list of arguments for the node.
RCLCPP_PUBLIC

View File

@@ -64,13 +64,13 @@ public:
*/
RCLCPP_PUBLIC
AsyncParametersClient(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_base_interface,
const rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr & node_topics_interface,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr & node_graph_interface,
const rclcpp::node_interfaces::NodeServicesInterface::SharedPtr & node_services_interface,
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_interface,
const rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_interface,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph_interface,
const rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services_interface,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS(),
const rclcpp::CallbackGroup::SharedPtr & group = nullptr);
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/**
* \param[in] node The async parameters client will be added to this node.
@@ -80,10 +80,10 @@ public:
*/
template<typename NodeT>
explicit AsyncParametersClient(
const std::shared_ptr<NodeT> & node,
const std::shared_ptr<NodeT> node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS(),
const rclcpp::CallbackGroup::SharedPtr & group = nullptr)
rclcpp::CallbackGroup::SharedPtr group = nullptr)
: AsyncParametersClient(
node->get_node_base_interface(),
node->get_node_topics_interface(),
@@ -105,7 +105,7 @@ public:
NodeT * node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS(),
const rclcpp::CallbackGroup::SharedPtr & group = nullptr)
rclcpp::CallbackGroup::SharedPtr group = nullptr)
: AsyncParametersClient(
node->get_node_base_interface(),
node->get_node_topics_interface(),
@@ -120,41 +120,41 @@ public:
std::shared_future<std::vector<rclcpp::Parameter>>
get_parameters(
const std::vector<std::string> & names,
const std::function<
std::function<
void(std::shared_future<std::vector<rclcpp::Parameter>>)
> & callback = nullptr);
> callback = nullptr);
RCLCPP_PUBLIC
std::shared_future<std::vector<rcl_interfaces::msg::ParameterDescriptor>>
describe_parameters(
const std::vector<std::string> & names,
const std::function<
std::function<
void(std::shared_future<std::vector<rcl_interfaces::msg::ParameterDescriptor>>)
> & callback = nullptr);
> callback = nullptr);
RCLCPP_PUBLIC
std::shared_future<std::vector<rclcpp::ParameterType>>
get_parameter_types(
const std::vector<std::string> & names,
const std::function<
std::function<
void(std::shared_future<std::vector<rclcpp::ParameterType>>)
> & callback = nullptr);
> callback = nullptr);
RCLCPP_PUBLIC
std::shared_future<std::vector<rcl_interfaces::msg::SetParametersResult>>
set_parameters(
const std::vector<rclcpp::Parameter> & parameters,
const std::function<
std::function<
void(std::shared_future<std::vector<rcl_interfaces::msg::SetParametersResult>>)
> & callback = nullptr);
> callback = nullptr);
RCLCPP_PUBLIC
std::shared_future<rcl_interfaces::msg::SetParametersResult>
set_parameters_atomically(
const std::vector<rclcpp::Parameter> & parameters,
const std::function<
std::function<
void(std::shared_future<rcl_interfaces::msg::SetParametersResult>)
> & callback = nullptr);
> callback = nullptr);
/// Delete several parameters at once.
/**
@@ -200,9 +200,9 @@ public:
list_parameters(
const std::vector<std::string> & prefixes,
uint64_t depth,
const std::function<
std::function<
void(std::shared_future<rcl_interfaces::msg::ListParametersResult>)
> & callback = nullptr);
> callback = nullptr);
template<
typename CallbackT,
@@ -304,7 +304,7 @@ public:
template<typename NodeT>
explicit SyncParametersClient(
const std::shared_ptr<NodeT> & node,
std::shared_ptr<NodeT> node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS())
: SyncParametersClient(
@@ -316,8 +316,8 @@ public:
template<typename NodeT>
SyncParametersClient(
const rclcpp::Executor::SharedPtr & executor,
const std::shared_ptr<NodeT> & node,
rclcpp::Executor::SharedPtr executor,
std::shared_ptr<NodeT> node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS())
: SyncParametersClient(
@@ -344,7 +344,7 @@ public:
template<typename NodeT>
SyncParametersClient(
const rclcpp::Executor::SharedPtr & executor,
rclcpp::Executor::SharedPtr executor,
NodeT * node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS())
@@ -360,11 +360,11 @@ public:
RCLCPP_PUBLIC
SyncParametersClient(
const rclcpp::Executor::SharedPtr & executor,
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_base_interface,
const rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr & node_topics_interface,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr & node_graph_interface,
const rclcpp::node_interfaces::NodeServicesInterface::SharedPtr & node_services_interface,
rclcpp::Executor::SharedPtr executor,
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_interface,
const rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_interface,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph_interface,
const rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services_interface,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS())
: executor_(executor), node_base_interface_(node_base_interface)

View File

@@ -1,82 +0,0 @@
// Copyright 2023 Open Source Robotics Foundation, Inc.
//
// 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 RCLCPP__PARAMETER_DESCRIPTOR_WRAPPER_HPP_
#define RCLCPP__PARAMETER_DESCRIPTOR_WRAPPER_HPP_
// C++ Standard library includes
#include <functional>
#include <utility>
#include <memory>
#include <string>
// Additional ROS libraries needed
#include "rcl_interfaces/msg/parameter_descriptor.hpp"
#include "rclcpp/node.hpp"
#include "rclcpp/parameter_value.hpp"
#include "rclcpp/node_interfaces/get_node_parameters_interface.hpp"
#include "rclcpp/visibility_control.hpp"
#include "node_interfaces/node_parameters_interface.hpp"
namespace rclcpp
{
// Implements ParameterDesription class with builder design pattern
class ParameterDescription
{
public:
RCLCPP_SMART_PTR_DEFINITIONS(ParameterDescription)
// List of classes the builder manages
RCLCPP_PUBLIC
ParameterDescription();
// Our Main build methods which will construct the base class
RCLCPP_PUBLIC rcl_interfaces::msg::ParameterDescriptor build() const;
// Builder Methods:
// Describes the instances in a parameter_description object
RCLCPP_PUBLIC ParameterDescription & set_name(const std::string & name);
RCLCPP_PUBLIC ParameterDescription & set_type(std::uint8_t type);
RCLCPP_PUBLIC ParameterDescription & set_description_text(const std::string & description);
RCLCPP_PUBLIC ParameterDescription & set_additional_constraints(const std::string & constraints);
RCLCPP_PUBLIC ParameterDescription & set_read_only(bool read_only);
RCLCPP_PUBLIC ParameterDescription & set_dynamic_typing(bool dynamic_typing);
RCLCPP_PUBLIC ParameterDescription & set_floating_point_description_range(
float min, float max, float step);
RCLCPP_PUBLIC ParameterDescription & set_integer_description_range(int min, int max, int step);
// Need the current node in order to begin the configuration state
// for it via the declare_parameter function
template<typename NodeT>
ParameterDescription & declare_parameter(
const rclcpp::ParameterValue & default_value,
NodeT && node)
{
auto node_param = rclcpp::node_interfaces::get_node_parameters_interface(node);
node_param->declare_parameter(
parameter_descriptor.name, default_value,
parameter_descriptor);
return *this;
}
private:
// The main descriptor object we're meant to initialize and adjust
rcl_interfaces::msg::ParameterDescriptor parameter_descriptor;
};
} // namespace rclcpp
#endif // RCLCPP__PARAMETER_DESCRIPTOR_WRAPPER_HPP_

View File

@@ -184,7 +184,7 @@ public:
*/
template<typename NodeT>
explicit ParameterEventHandler(
const NodeT & node,
NodeT node,
const rclcpp::QoS & qos =
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(rmw_qos_profile_parameter_events)))
: node_base_(rclcpp::node_interfaces::get_node_base_interface(node))
@@ -217,7 +217,7 @@ public:
RCUTILS_WARN_UNUSED
ParameterEventCallbackHandle::SharedPtr
add_parameter_event_callback(
const ParameterEventCallbackType & callback);
ParameterEventCallbackType callback);
/// Remove parameter event callback registered with add_parameter_event_callback.
/**
@@ -226,7 +226,7 @@ public:
RCLCPP_PUBLIC
void
remove_parameter_event_callback(
const ParameterEventCallbackHandle::SharedPtr & callback_handle);
ParameterEventCallbackHandle::SharedPtr callback_handle);
using ParameterCallbackType = ParameterCallbackHandle::ParameterCallbackType;
@@ -234,10 +234,6 @@ public:
/**
* If a node_name is not provided, defaults to the current node.
*
* The configure_nodes_filter() function will affect the behavior of this function.
* If the node specified in this function isn't included in the nodes specified in
* configure_nodes_filter(), the callback will never be called.
*
* Note: if the returned callback handle smart pointer is not captured, the callback
* is immediately unregistered. A compiler warning should be generated to warn
* of this.
@@ -252,34 +248,9 @@ public:
ParameterCallbackHandle::SharedPtr
add_parameter_callback(
const std::string & parameter_name,
const ParameterCallbackType & callback,
ParameterCallbackType callback,
const std::string & node_name = "");
/// Configure which node parameter events will be received.
/**
* This function depends on rmw implementation support for content filtering.
* If middleware doesn't support contentfilter, return false.
*
* If node_names is empty, the configured node filter will be cleared.
*
* If this function return true, only parameter events from the specified node will be received.
* It affects the behavior of the following two functions.
* - add_parameter_event_callback()
* The callback will only be called for parameter events from the specified nodes which are
* configured in this function.
* - add_parameter_callback()
* The callback will only be called for parameter events from the specified nodes which are
* configured in this function and add_parameter_callback().
* If the nodes specified in this function is different from the nodes specified in
* add_parameter_callback(), the callback will never be called.
*
* \param[in] node_names Node names to filter parameter events from.
* \returns true if configuring was successfully applied, false otherwise.
* \throws rclcpp::exceptions::RCLError if internal error occurred when calling the rcl function.
*/
RCLCPP_PUBLIC
bool configure_nodes_filter(const std::vector<std::string> & node_names);
/// Remove a parameter callback registered with add_parameter_callback.
/**
* The parameter name and node name are inspected from the callback handle. The callback handle
@@ -291,7 +262,7 @@ public:
RCLCPP_PUBLIC
void
remove_parameter_callback(
const ParameterCallbackHandle::SharedPtr & callback_handle);
ParameterCallbackHandle::SharedPtr callback_handle);
/// Get an rclcpp::Parameter from a parameter event.
/**

View File

@@ -42,8 +42,8 @@ public:
RCLCPP_PUBLIC
ParameterService(
const std::shared_ptr<node_interfaces::NodeBaseInterface> & node_base,
const std::shared_ptr<node_interfaces::NodeServicesInterface> & node_services,
const std::shared_ptr<node_interfaces::NodeBaseInterface> node_base,
const std::shared_ptr<node_interfaces::NodeServicesInterface> node_services,
rclcpp::node_interfaces::NodeParametersInterface * node_params,
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS());

View File

@@ -574,13 +574,6 @@ protected:
std::unique_ptr<PublishedType, PublishedTypeDeleter>
duplicate_type_adapt_message_as_unique_ptr(const PublishedType & msg)
{
/// Assert that the published type has no overloaded operator new since this leads to
/// new/delete mismatch (see https://github.com/ros2/rclcpp/issues/2951)
static_assert(!detail::has_overloaded_operator_new_v<PublishedType>,
"When publishing by value (i.e. when calling publish(const T& msg)), the published "
"message type must not have an overloaded operator new. In this case, please use the "
"publish(std::unique_ptr<T> msg) method instead.");
auto ptr = PublishedTypeAllocatorTraits::allocate(published_type_allocator_, 1);
PublishedTypeAllocatorTraits::construct(published_type_allocator_, ptr, msg);
return std::unique_ptr<PublishedType, PublishedTypeDeleter>(ptr, published_type_deleter_);

View File

@@ -210,7 +210,7 @@ public:
void
setup_intra_process(
uint64_t intra_process_publisher_id,
const IntraProcessManagerSharedPtr & ipm);
IntraProcessManagerSharedPtr ipm);
/// Get network flow endpoints
/**
@@ -300,7 +300,7 @@ public:
*/
void
set_on_new_qos_event_callback(
const std::function<void(size_t)> & callback,
std::function<void(size_t)> callback,
rcl_publisher_event_type_t event_type)
{
if (event_handlers_.count(event_type) == 0) {
@@ -319,7 +319,7 @@ public:
// The on_ready_callback signature has an extra `int` argument used to disambiguate between
// possible different entities within a generic waitable.
// We hide that detail to users of this method.
std::function<void(size_t, int)> new_callback = [callback] (size_t nr, int) {callback(nr);};
std::function<void(size_t, int)> new_callback = std::bind(callback, std::placeholders::_1);
event_handlers_[event_type]->set_on_ready_callback(new_callback);
}

View File

@@ -123,20 +123,11 @@ private:
rcl_allocator_t
get_rcl_allocator() const
{
if constexpr (std::is_same_v<Allocator, std::allocator<void>>) {
return rcl_get_default_allocator();
} else {
if constexpr (rclcpp::allocator::has_get_rcl_allocator_v<Allocator>) {
return get_allocator()->get_rcl_allocator();
} else {
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
}
return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
}
return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}
// This is a temporal workaround, to make sure that get_allocator()

View File

@@ -58,12 +58,12 @@ public:
RCLCPP_PUBLIC
explicit Rate(
const double rate,
const Clock::SharedPtr & clock = std::make_shared<Clock>(RCL_SYSTEM_TIME));
Clock::SharedPtr clock = std::make_shared<Clock>(RCL_SYSTEM_TIME));
RCLCPP_PUBLIC
explicit Rate(
const Duration & period,
const Clock::SharedPtr & clock = std::make_shared<Clock>(RCL_SYSTEM_TIME));
Clock::SharedPtr clock = std::make_shared<Clock>(RCL_SYSTEM_TIME));
RCLCPP_PUBLIC
virtual bool

View File

@@ -68,6 +68,8 @@
*
* - Executors (responsible for execution of callbacks through a blocking spin):
* - rclcpp::spin()
* - rclcpp::spin_some()
* - rclcpp::spin_until_future_complete()
* - rclcpp::executors::SingleThreadedExecutor
* - rclcpp::executors::SingleThreadedExecutor::add_node()
* - rclcpp::executors::SingleThreadedExecutor::spin()
@@ -175,7 +177,6 @@
#include "rclcpp/parameter_event_handler.hpp"
#include "rclcpp/parameter.hpp"
#include "rclcpp/parameter_service.hpp"
#include "rclcpp/parameter_descriptor_wrapper.hpp"
#include "rclcpp/rate.hpp"
#include "rclcpp/time.hpp"
#include "rclcpp/utilities.hpp"

View File

@@ -58,10 +58,10 @@ public:
explicit SerializedMessage(const rcl_serialized_message_t & other);
/// Move Constructor for a SerializedMessage
SerializedMessage(SerializedMessage && other) noexcept;
SerializedMessage(SerializedMessage && other);
/// Constructor for a SerializedMessage from a moved rcl_serialized_message_t
explicit SerializedMessage(rcl_serialized_message_t && other) noexcept;
explicit SerializedMessage(rcl_serialized_message_t && other);
/// Copy assignment operator
SerializedMessage & operator=(const SerializedMessage & other);
@@ -70,10 +70,10 @@ public:
SerializedMessage & operator=(const rcl_serialized_message_t & other);
/// Move assignment operator
SerializedMessage & operator=(SerializedMessage && other) noexcept;
SerializedMessage & operator=(SerializedMessage && other);
/// Move assignment operator from a rcl_serialized_message_t
SerializedMessage & operator=(rcl_serialized_message_t && other) noexcept;
SerializedMessage & operator=(rcl_serialized_message_t && other);
/// Destructor for a SerializedMessage
virtual ~SerializedMessage();

View File

@@ -22,7 +22,6 @@
#include <mutex>
#include <sstream>
#include <string>
#include <utility>
#include "rcl/error_handling.h"
#include "rcl/event_callback.h"
@@ -55,7 +54,7 @@ public:
RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(ServiceBase)
RCLCPP_PUBLIC
explicit ServiceBase(const std::shared_ptr<rcl_node_t> & node_handle);
explicit ServiceBase(std::shared_ptr<rcl_node_t> node_handle);
RCLCPP_PUBLIC
virtual ~ServiceBase() = default;
@@ -114,8 +113,8 @@ public:
virtual
void
handle_request(
const std::shared_ptr<rmw_request_id_t> & request_header,
const std::shared_ptr<void> & request) = 0;
std::shared_ptr<rmw_request_id_t> request_header,
std::shared_ptr<void> request) = 0;
/// Exchange the "in use by wait set" state for this service.
/**
@@ -191,7 +190,7 @@ public:
* \param[in] callback functor to be called when a new request is received
*/
void
set_on_new_request_callback(const std::function<void(size_t)> & callback)
set_on_new_request_callback(std::function<void(size_t)> callback)
{
if (!callback) {
throw std::invalid_argument(
@@ -287,7 +286,6 @@ class Service
public std::enable_shared_from_this<Service<ServiceT>>
{
public:
using ServiceType = ServiceT;
using CallbackType = std::function<
void (
const std::shared_ptr<typename ServiceT::Request>,
@@ -374,10 +372,10 @@ public:
* \param[in] any_callback User defined callback to call when a client request is received.
*/
Service(
const std::shared_ptr<rcl_node_t> & node_handle,
const std::shared_ptr<rcl_service_t> & service_handle,
std::shared_ptr<rcl_node_t> node_handle,
std::shared_ptr<rcl_service_t> service_handle,
AnyServiceCallback<ServiceT> any_callback)
: ServiceBase(node_handle), any_callback_(std::move(any_callback)),
: ServiceBase(node_handle), any_callback_(any_callback),
srv_type_support_handle_(rosidl_typesupport_cpp::get_service_type_support_handle<ServiceT>())
{
// check if service handle was initialized
@@ -409,10 +407,10 @@ public:
* \param[in] any_callback User defined callback to call when a client request is received.
*/
Service(
const std::shared_ptr<rcl_node_t> & node_handle,
std::shared_ptr<rcl_node_t> node_handle,
rcl_service_t * service_handle,
AnyServiceCallback<ServiceT> any_callback)
: ServiceBase(node_handle), any_callback_(std::move(any_callback)),
: ServiceBase(node_handle), any_callback_(any_callback),
srv_type_support_handle_(rosidl_typesupport_cpp::get_service_type_support_handle<ServiceT>())
{
// check if service handle was initialized
@@ -473,8 +471,8 @@ public:
void
handle_request(
const std::shared_ptr<rmw_request_id_t> & request_header,
const std::shared_ptr<void> & request) override
std::shared_ptr<rmw_request_id_t> request_header,
std::shared_ptr<void> request) override
{
auto typed_request = std::static_pointer_cast<typename ServiceT::Request>(request);
auto response = any_callback_.dispatch(this->shared_from_this(), request_header, typed_request);
@@ -512,7 +510,7 @@ public:
*/
void
configure_introspection(
const Clock::SharedPtr & clock, const QoS & qos_service_event_pub,
Clock::SharedPtr clock, const QoS & qos_service_event_pub,
rcl_service_introspection_state_t introspection_state)
{
rcl_publisher_options_t pub_opts = rcl_publisher_get_default_options();

View File

@@ -99,92 +99,49 @@ public:
// Important to use subscription_handles_.size() instead of wait set's size since
// there may be more subscriptions in the wait set due to Waitables added to the end.
// The same logic applies for other entities.
// Mark corresponding weak_ptr as expired for entities that are null in the wait set
size_t valid_subscription_count = 0;
for (size_t i = 0; i < subscription_handles_.size(); ++i) {
if (valid_subscription_count < wait_set->size_of_subscriptions &&
!wait_set->subscriptions[valid_subscription_count])
{
subscription_handles_[i] = std::weak_ptr<const rcl_subscription_t>{};
}
if (subscription_handles_[i].lock()) {
++valid_subscription_count;
if (!wait_set->subscriptions[i]) {
subscription_handles_[i].reset();
}
}
size_t valid_service_count = 0;
for (size_t i = 0; i < service_handles_.size(); ++i) {
if (valid_service_count < wait_set->size_of_services &&
!wait_set->services[valid_service_count])
{
service_handles_[i] = std::weak_ptr<const rcl_service_t>{};
}
if (service_handles_[i].lock()) {
++valid_service_count;
if (!wait_set->services[i]) {
service_handles_[i].reset();
}
}
size_t valid_client_count = 0;
for (size_t i = 0; i < client_handles_.size(); ++i) {
if (valid_client_count < wait_set->size_of_clients &&
!wait_set->clients[valid_client_count])
{
client_handles_[i] = std::weak_ptr<const rcl_client_t>{};
}
if (client_handles_[i].lock()) {
++valid_client_count;
if (!wait_set->clients[i]) {
client_handles_[i].reset();
}
}
size_t valid_timer_count = 0;
for (size_t i = 0; i < timer_handles_.size(); ++i) {
if (valid_timer_count < wait_set->size_of_timers &&
!wait_set->timers[valid_timer_count])
{
timer_handles_[i] = std::weak_ptr<const rcl_timer_t>{};
}
if (timer_handles_[i].lock()) {
++valid_timer_count;
if (!wait_set->timers[i]) {
timer_handles_[i].reset();
}
}
for (size_t i = 0; i < waitable_handles_.size(); ++i) {
if (!waitable_handles_[i]->is_ready(*wait_set)) {
waitable_handles_[i].reset();
}
}
// Remove expired weak_ptr instances
subscription_handles_.erase(
std::remove_if(subscription_handles_.begin(), subscription_handles_.end(),
[](const std::weak_ptr<const rcl_subscription_t> & weak_ptr) {
return weak_ptr.expired();
}),
std::remove(subscription_handles_.begin(), subscription_handles_.end(), nullptr),
subscription_handles_.end()
);
service_handles_.erase(
std::remove_if(service_handles_.begin(), service_handles_.end(),
[](const std::weak_ptr<const rcl_service_t> & weak_ptr) {
return weak_ptr.expired();
}),
std::remove(service_handles_.begin(), service_handles_.end(), nullptr),
service_handles_.end()
);
client_handles_.erase(
std::remove_if(client_handles_.begin(), client_handles_.end(),
[](const std::weak_ptr<const rcl_client_t> & weak_ptr) {
return weak_ptr.expired();
}),
std::remove(client_handles_.begin(), client_handles_.end(), nullptr),
client_handles_.end()
);
timer_handles_.erase(
std::remove_if(timer_handles_.begin(), timer_handles_.end(),
[](const std::weak_ptr<const rcl_timer_t> & weak_ptr) {
return weak_ptr.expired();
}),
std::remove(timer_handles_.begin(), timer_handles_.end(), nullptr),
timer_handles_.end()
);
@@ -239,13 +196,7 @@ public:
bool add_handles_to_wait_set(rcl_wait_set_t * wait_set) override
{
for (const std::weak_ptr<const rcl_subscription_t> & weak_subscription :
subscription_handles_)
{
auto subscription = weak_subscription.lock();
if (!subscription) {
continue; // Skip expired handles
}
for (const std::shared_ptr<const rcl_subscription_t> & subscription : subscription_handles_) {
if (rcl_wait_set_add_subscription(wait_set, subscription.get(), NULL) != RCL_RET_OK) {
RCUTILS_LOG_ERROR_NAMED(
"rclcpp",
@@ -255,11 +206,7 @@ public:
}
}
for (const std::weak_ptr<const rcl_client_t> & weak_client : client_handles_) {
auto client = weak_client.lock();
if (!client) {
continue; // Skip expired handles
}
for (const std::shared_ptr<const rcl_client_t> & client : client_handles_) {
if (rcl_wait_set_add_client(wait_set, client.get(), NULL) != RCL_RET_OK) {
RCUTILS_LOG_ERROR_NAMED(
"rclcpp",
@@ -269,11 +216,7 @@ public:
}
}
for (const std::weak_ptr<const rcl_service_t> & weak_service : service_handles_) {
auto service = weak_service.lock();
if (!service) {
continue; // Skip expired handles
}
for (const std::shared_ptr<const rcl_service_t> & service : service_handles_) {
if (rcl_wait_set_add_service(wait_set, service.get(), NULL) != RCL_RET_OK) {
RCUTILS_LOG_ERROR_NAMED(
"rclcpp",
@@ -283,11 +226,7 @@ public:
}
}
for (const std::weak_ptr<const rcl_timer_t> & weak_timer : timer_handles_) {
auto timer = weak_timer.lock();
if (!timer) {
continue; // Skip expired handles
}
for (const std::shared_ptr<const rcl_timer_t> & timer : timer_handles_) {
if (rcl_wait_set_add_timer(wait_set, timer.get(), NULL) != RCL_RET_OK) {
RCUTILS_LOG_ERROR_NAMED(
"rclcpp",
@@ -314,13 +253,7 @@ public:
{
auto it = subscription_handles_.begin();
while (it != subscription_handles_.end()) {
auto subscription_handle = it->lock();
if (!subscription_handle) {
// Handle expired, remove it and continue
it = subscription_handles_.erase(it);
continue;
}
auto subscription = get_subscription_by_handle(subscription_handle, weak_groups_to_nodes);
auto subscription = get_subscription_by_handle(*it, weak_groups_to_nodes);
if (subscription) {
// Find the group for this handle and see if it can be serviced
auto group = get_group_by_subscription(subscription, weak_groups_to_nodes);
@@ -355,13 +288,7 @@ public:
{
auto it = service_handles_.begin();
while (it != service_handles_.end()) {
auto service_handle = it->lock();
if (!service_handle) {
// Handle expired, remove it and continue
it = service_handles_.erase(it);
continue;
}
auto service = get_service_by_handle(service_handle, weak_groups_to_nodes);
auto service = get_service_by_handle(*it, weak_groups_to_nodes);
if (service) {
// Find the group for this handle and see if it can be serviced
auto group = get_group_by_service(service, weak_groups_to_nodes);
@@ -396,13 +323,7 @@ public:
{
auto it = client_handles_.begin();
while (it != client_handles_.end()) {
auto client_handle = it->lock();
if (!client_handle) {
// Handle expired, remove it and continue
it = client_handles_.erase(it);
continue;
}
auto client = get_client_by_handle(client_handle, weak_groups_to_nodes);
auto client = get_client_by_handle(*it, weak_groups_to_nodes);
if (client) {
// Find the group for this handle and see if it can be serviced
auto group = get_group_by_client(client, weak_groups_to_nodes);
@@ -437,13 +358,7 @@ public:
{
auto it = timer_handles_.begin();
while (it != timer_handles_.end()) {
auto timer_handle = it->lock();
if (!timer_handle) {
// Handle expired, remove it and continue
it = timer_handles_.erase(it);
continue;
}
auto timer = get_timer_by_handle(timer_handle, weak_groups_to_nodes);
auto timer = get_timer_by_handle(*it, weak_groups_to_nodes);
if (timer) {
// Find the group for this handle and see if it can be serviced
auto group = get_group_by_timer(timer, weak_groups_to_nodes);
@@ -515,22 +430,12 @@ public:
rcl_allocator_t get_allocator() override
{
if constexpr (std::is_same_v<Alloc, std::allocator<void>>) {
return rcl_get_default_allocator();
} else {
return rclcpp::allocator::get_rcl_allocator<void *, VoidAlloc>(*allocator_.get());
}
return rclcpp::allocator::get_rcl_allocator<void *, VoidAlloc>(*allocator_.get());
}
size_t number_of_ready_subscriptions() const override
{
size_t number_of_subscriptions = 0;
// Count only non-expired weak_ptr references
for (const auto & weak_subscription : subscription_handles_) {
if (!weak_subscription.expired()) {
++number_of_subscriptions;
}
}
size_t number_of_subscriptions = subscription_handles_.size();
for (const std::shared_ptr<Waitable> & waitable : waitable_handles_) {
number_of_subscriptions += waitable->get_number_of_ready_subscriptions();
}
@@ -539,13 +444,7 @@ public:
size_t number_of_ready_services() const override
{
size_t number_of_services = 0;
// Count only non-expired weak_ptr references
for (const auto & weak_service : service_handles_) {
if (!weak_service.expired()) {
++number_of_services;
}
}
size_t number_of_services = service_handles_.size();
for (const std::shared_ptr<Waitable> & waitable : waitable_handles_) {
number_of_services += waitable->get_number_of_ready_services();
}
@@ -563,13 +462,7 @@ public:
size_t number_of_ready_clients() const override
{
size_t number_of_clients = 0;
// Count only non-expired weak_ptr references
for (const auto & weak_client : client_handles_) {
if (!weak_client.expired()) {
++number_of_clients;
}
}
size_t number_of_clients = client_handles_.size();
for (const std::shared_ptr<Waitable> & waitable : waitable_handles_) {
number_of_clients += waitable->get_number_of_ready_clients();
}
@@ -587,13 +480,7 @@ public:
size_t number_of_ready_timers() const override
{
size_t number_of_timers = 0;
// Count only non-expired weak_ptr references
for (const auto & weak_timer : timer_handles_) {
if (!weak_timer.expired()) {
++number_of_timers;
}
}
size_t number_of_timers = timer_handles_.size();
for (const std::shared_ptr<Waitable> & waitable : waitable_handles_) {
number_of_timers += waitable->get_number_of_ready_timers();
}
@@ -612,10 +499,10 @@ private:
VectorRebind<const rclcpp::GuardCondition *> guard_conditions_;
VectorRebind<std::weak_ptr<const rcl_subscription_t>> subscription_handles_;
VectorRebind<std::weak_ptr<const rcl_service_t>> service_handles_;
VectorRebind<std::weak_ptr<const rcl_client_t>> client_handles_;
VectorRebind<std::weak_ptr<const rcl_timer_t>> timer_handles_;
VectorRebind<std::shared_ptr<const rcl_subscription_t>> subscription_handles_;
VectorRebind<std::shared_ptr<const rcl_service_t>> service_handles_;
VectorRebind<std::shared_ptr<const rcl_client_t>> client_handles_;
VectorRebind<std::shared_ptr<const rcl_timer_t>> timer_handles_;
VectorRebind<std::shared_ptr<Waitable>> waitable_handles_;
std::shared_ptr<VoidAlloc> allocator_;

View File

@@ -279,50 +279,6 @@ public:
return message_memory_strategy_->borrow_serialized_message();
}
/// Disable callbacks from being called
/**
* This method will block, until any subscription's callbacks provided during construction
* currently being executed are finished.
* \note This method also temporary removes the on new message callback and all
* on new event callbacks from the rmw layer to prevent them from being called. However, this
* method will not block and wait until the currently executing on_new_[message]event callbacks
* are finished.
*/
void
disable_callbacks() override
{
SubscriptionBase::disable_callbacks();
any_callback_.disable();
if (subscription_intra_process_) {
subscription_intra_process_->disable_callbacks();
}
for (const auto & [_, event_ptr] : event_handlers_) {
if (event_ptr) {
event_ptr->disable();
}
}
}
/// Enable the callbacks to be called
/**
* This method is thread safe, and provides a safe way to atomically enable the callbacks
* in a multithreaded environment.
*/
void
enable_callbacks() override
{
SubscriptionBase::enable_callbacks();
any_callback_.enable();
if (subscription_intra_process_) {
subscription_intra_process_->enable_callbacks();
}
for (const auto & [_, event_ptr] : event_handlers_) {
if (event_ptr) {
event_ptr->enable();
}
}
}
void
handle_message(
std::shared_ptr<void> & message,

View File

@@ -212,23 +212,6 @@ public:
std::shared_ptr<rclcpp::SerializedMessage>
create_serialized_message() = 0;
/// Disable callbacks from being called
/**
* This function temporary removes the on_new_message_callback to prevent it from being called.
*/
RCLCPP_PUBLIC
virtual
void disable_callbacks();
/// Enable the callbacks to be called
/**
* This function sets back the on_new_message_callback if it was previously removed in
* disable_callbacks().
*/
RCLCPP_PUBLIC
virtual
void enable_callbacks();
/// Check if we need to handle the message, and execute the callback if we do.
/**
* \param[in] message Shared pointer to the message to handle.
@@ -372,7 +355,7 @@ public:
* \param[in] callback functor to be called when a new message is received
*/
void
set_on_new_message_callback(const std::function<void(size_t)> & callback)
set_on_new_message_callback(std::function<void(size_t)> callback)
{
if (!callback) {
throw std::invalid_argument(
@@ -400,7 +383,7 @@ public:
}
};
std::lock_guard<std::recursive_mutex> lock(on_new_message_callback_mutex_);
std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
// Set it temporarily to the new callback, while we replace the old one.
// This two-step setting, prevents a gap where the old std::function has
@@ -423,7 +406,7 @@ public:
void
clear_on_new_message_callback()
{
std::lock_guard<std::recursive_mutex> lock(on_new_message_callback_mutex_);
std::lock_guard<std::recursive_mutex> lock(callback_mutex_);
if (on_new_message_callback_) {
set_on_new_message_callback(nullptr, nullptr);
@@ -450,7 +433,7 @@ public:
* \param[in] callback functor to be called when a new message is received
*/
void
set_on_new_intra_process_message_callback(const std::function<void(size_t)> & callback)
set_on_new_intra_process_message_callback(std::function<void(size_t)> callback)
{
if (!use_intra_process_) {
RCLCPP_WARN(
@@ -468,7 +451,7 @@ public:
// The on_ready_callback signature has an extra `int` argument used to disambiguate between
// possible different entities within a generic waitable.
// We hide that detail to users of this method.
std::function<void(size_t, int)> new_callback = [callback] (size_t nr, int) {callback(nr);};
std::function<void(size_t, int)> new_callback = std::bind(callback, std::placeholders::_1);
subscription_intra_process_->set_on_ready_callback(new_callback);
}
@@ -514,7 +497,7 @@ public:
*/
void
set_on_new_qos_event_callback(
const std::function<void(size_t)> & callback,
std::function<void(size_t)> callback,
rcl_subscription_event_type_t event_type)
{
if (event_handlers_.count(event_type) == 0) {
@@ -533,7 +516,7 @@ public:
// The on_ready_callback signature has an extra `int` argument used to disambiguate between
// possible different entities within a generic waitable.
// We hide that detail to users of this method.
std::function<void(size_t, int)> new_callback = [callback] (size_t nr, int) {callback(nr);};
std::function<void(size_t, int)> new_callback = std::bind(callback, std::placeholders::_1);
event_handlers_[event_type]->set_on_ready_callback(new_callback);
}
@@ -663,7 +646,7 @@ protected:
std::shared_ptr<rcl_node_t> node_handle_;
std::recursive_mutex on_new_message_callback_mutex_;
std::recursive_mutex callback_mutex_;
// It is important to declare on_new_message_callback_ before
// subscription_handle_, so on destruction the subscription is
// destroyed first. Otherwise, the rmw subscription callback

View File

@@ -89,15 +89,6 @@ struct SubscriptionOptionsBase
QosOverridingOptions qos_overriding_options;
ContentFilterOptions content_filter_options;
/// Acceptable buffer backend names for this subscription.
/**
* Empty string or "cpu" means CPU-only (default for backward compatibility).
* "any" means all installed backends are acceptable.
* Comma-separated for specific backends, e.g. "cuda,demo".
* CPU is always implicitly acceptable regardless of this value.
*/
std::string acceptable_buffer_backends{"cpu"};
};
/// Structure containing optional configuration for Subscriptions.
@@ -154,11 +145,6 @@ struct SubscriptionOptionsWithAllocator : public SubscriptionOptionsBase
}
}
if (!acceptable_buffer_backends.empty()) {
result.rmw_subscription_options.acceptable_buffer_backends =
acceptable_buffer_backends.c_str();
}
return result;
}
@@ -181,20 +167,11 @@ private:
rcl_allocator_t
get_rcl_allocator() const
{
if constexpr (std::is_same_v<Allocator, std::allocator<void>>) {
return rcl_get_default_allocator();
} else {
if constexpr (rclcpp::allocator::has_get_rcl_allocator_v<Allocator>) {
return get_allocator()->get_rcl_allocator();
} else {
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
}
return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
}
return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}
// This is a temporal workaround, to make sure that get_allocator()

View File

@@ -33,11 +33,12 @@ class Time
public:
/// Time constructor
/**
* Indicates a specific point in time, relative to a clock's 0 point (its epoch).
* The total time since the epoch is given by seconds + nanoseconds.
* Initializes the time values for seconds and nanoseconds individually.
* Large values for nanoseconds are wrapped automatically with the remainder added to seconds.
* Both inputs must be integers.
*
* \param seconds the seconds component, valid only if positive
* \param nanoseconds the nanoseconds component, to be added to the seconds component
* \param seconds part of the time in seconds since time epoch
* \param nanoseconds part of the time in nanoseconds since time epoch
* \param clock_type clock type
* \throws std::runtime_error if seconds are negative
*/
@@ -46,7 +47,7 @@ public:
/// Time constructor
/**
* \param nanoseconds the total time since the epoch in nanoseconds
* \param nanoseconds since time epoch
* \param clock_type clock type
* \throws std::runtime_error if nanoseconds are negative
*/
@@ -189,7 +190,7 @@ public:
/// Get the nanoseconds since epoch
/**
* \return the total time since the epoch in nanoseconds, as a rcl_time_point_value_t structure.
* \return the nanoseconds since epoch as a rcl_time_point_value_t structure.
*/
RCLCPP_PUBLIC
rcl_time_point_value_t
@@ -208,7 +209,7 @@ public:
* \warning Depending on sizeof(double) there could be significant precision loss.
* When an exact time is required use nanoseconds() instead.
*
* \return the total time since the epoch in seconds, as a floating point number.
* \return the seconds since epoch as a floating point number.
*/
RCLCPP_PUBLIC
double

View File

@@ -60,7 +60,7 @@ public:
*/
RCLCPP_PUBLIC
explicit TimeSource(
const rclcpp::Node::SharedPtr & node,
rclcpp::Node::SharedPtr node,
const rclcpp::QoS & qos = rclcpp::ClockQoS(),
bool use_clock_thread = true);
@@ -89,7 +89,7 @@ public:
* \param node std::shared pointer to a initialized node
*/
RCLCPP_PUBLIC
void attachNode(const rclcpp::Node::SharedPtr & node);
void attachNode(rclcpp::Node::SharedPtr node);
/// Attach node to the time source.
/**
@@ -124,11 +124,11 @@ public:
* \throws std::invalid_argument the time source must be a RCL_ROS_TIME otherwise throws an exception
*/
RCLCPP_PUBLIC
void attachClock(const rclcpp::Clock::SharedPtr & clock);
void attachClock(rclcpp::Clock::SharedPtr clock);
/// Detach a clock from the time source
RCLCPP_PUBLIC
void detachClock(const rclcpp::Clock::SharedPtr & clock);
void detachClock(rclcpp::Clock::SharedPtr clock);
/// Get whether a separate clock thread is used or not
RCLCPP_PUBLIC

View File

@@ -183,7 +183,7 @@ public:
*/
RCLCPP_PUBLIC
void
set_on_reset_callback(const std::function<void(size_t)> & callback);
set_on_reset_callback(std::function<void(size_t)> callback);
/// Unset the callback registered for reset timer
RCLCPP_PUBLIC

View File

@@ -16,7 +16,6 @@
#define RCLCPP__TYPE_ADAPTER_HPP_
#include <type_traits>
#include <new>
namespace rclcpp
{
@@ -129,24 +128,6 @@ struct assert_type_pair_is_specialized_type_adapter
"No type adapter for this custom type/ros message type pair");
};
template<typename, typename = void>
struct has_overloaded_operator_new : std::false_type {};
template<typename T>
struct has_overloaded_operator_new<T, std::void_t<
decltype(T::operator new(std::size_t()))
>>: std::true_type {};
template<typename, typename = void>
struct has_overloaded_aligned_operator_new : std::false_type {};
template<typename T>
struct has_overloaded_aligned_operator_new<T,
std::void_t<decltype( T::operator new(std::size_t(), std::align_val_t()) )>>
: std::true_type {};
template<typename T>
inline constexpr bool has_overloaded_operator_new_v = has_overloaded_operator_new<T>::value ||
has_overloaded_aligned_operator_new<T>::value;
} // namespace detail
/// Template metafunction that can make the type being adapted explicit.

View File

@@ -22,7 +22,6 @@
#include <vector>
#include "rclcpp/context.hpp"
#include "rclcpp/contexts/default_context.hpp"
#include "rclcpp/init_options.hpp"
#include "rclcpp/visibility_control.hpp"
@@ -174,7 +173,7 @@ remove_ros_arguments(int argc, char const * const * argv);
*/
RCLCPP_PUBLIC
bool
ok(const rclcpp::Context::SharedPtr & context = rclcpp::contexts::get_global_default_context());
ok(rclcpp::Context::SharedPtr context = nullptr);
/// Shutdown rclcpp context, invalidating it for derived entities.
/**
@@ -193,7 +192,7 @@ ok(const rclcpp::Context::SharedPtr & context = rclcpp::contexts::get_global_def
RCLCPP_PUBLIC
bool
shutdown(
const rclcpp::Context::SharedPtr & context = rclcpp::contexts::get_global_default_context(),
rclcpp::Context::SharedPtr context = nullptr,
const std::string & reason = "user called rclcpp::shutdown()");
/// Register a function to be called when shutdown is called on the context.
@@ -213,9 +212,7 @@ shutdown(
*/
RCLCPP_PUBLIC
void
on_shutdown(
const std::function<void()> & callback,
const rclcpp::Context::SharedPtr & context = rclcpp::contexts::get_global_default_context());
on_shutdown(std::function<void()> callback, rclcpp::Context::SharedPtr context = nullptr);
/// Use the global condition variable to block for the specified amount of time.
/**
@@ -234,7 +231,7 @@ RCLCPP_PUBLIC
bool
sleep_for(
const std::chrono::nanoseconds & nanoseconds,
const rclcpp::Context::SharedPtr & context = rclcpp::contexts::get_global_default_context());
rclcpp::Context::SharedPtr context = nullptr);
/// Safely check if addition will overflow.
/**

View File

@@ -56,7 +56,7 @@ bool wait_for_message(
}
});
rclcpp::WaitSet wait_set({}, {}, {}, {}, {}, {}, context);
rclcpp::WaitSet wait_set;
wait_set.add_subscription(subscription);
RCPPUTILS_SCOPE_EXIT(wait_set.remove_subscription(subscription); );
wait_set.add_guard_condition(gc);

View File

@@ -704,12 +704,10 @@ public:
return WaitResult<WaitSetTemplate>::from_timeout_wait_result_kind();
case WaitResultKind::Empty:
return WaitResult<WaitSetTemplate>::from_empty_wait_result_kind();
case WaitResultKind::Invalid:
auto msg = "invalid WaitResultKind with value: " + std::to_string(wait_result_kind);
default:
auto msg = "unknown WaitResultKind with value: " + std::to_string(wait_result_kind);
throw std::runtime_error(msg);
}
// This should never be reached, but is needed to satisfy the compiler
throw std::runtime_error("unreachable code in wait result kind switch");
}
);
}

View File

@@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="2">
<name>rclcpp</name>
<version>30.1.5</version>
<version>29.5.6</version>
<description>The ROS client library in C++.</description>
<maintainer email="ivanpauno@ekumenlabs.com">Ivan Paunovic</maintainer>
@@ -17,7 +17,6 @@
<buildtool_depend>ament_cmake_ros</buildtool_depend>
<buildtool_depend>ament_cmake_gen_version_h</buildtool_depend>
<buildtool_depend>python3</buildtool_depend>
<buildtool_depend>python3-empy</buildtool_depend>
<build_depend>ament_index_cpp</build_depend>
<build_depend>builtin_interfaces</build_depend>
@@ -47,9 +46,9 @@
<depend>statistics_msgs</depend>
<depend>tracetools</depend>
<test_depend>ament_cmake_gmock</test_depend>
<test_depend>ament_cmake_google_benchmark</test_depend>
<test_depend>ament_cmake_gtest</test_depend>
<test_depend>ament_cmake_ros</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<test_depend>mimick_vendor</test_depend>

View File

@@ -0,0 +1,164 @@
// generated from rclcpp/resource/logging.hpp.em
// Copyright 2017 Open Source Robotics Foundation, Inc.
//
// 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 RCLCPP__LOGGING_HPP_
#define RCLCPP__LOGGING_HPP_
#include <sstream>
#include <type_traits>
#include "rclcpp/logger.hpp"
#include "rcutils/logging_macros.h"
#include "rclcpp/utilities.hpp"
// These are used for compiling out logging macros lower than a minimum severity.
#define RCLCPP_LOG_MIN_SEVERITY_DEBUG 0
#define RCLCPP_LOG_MIN_SEVERITY_INFO 1
#define RCLCPP_LOG_MIN_SEVERITY_WARN 2
#define RCLCPP_LOG_MIN_SEVERITY_ERROR 3
#define RCLCPP_LOG_MIN_SEVERITY_FATAL 4
#define RCLCPP_LOG_MIN_SEVERITY_NONE 5
#define RCLCPP_FIRST_ARG(N, ...) N
#define RCLCPP_ALL_BUT_FIRST_ARGS(N, ...) __VA_ARGS__
/**
* \def RCLCPP_LOG_MIN_SEVERITY
* Define RCLCPP_LOG_MIN_SEVERITY=RCLCPP_LOG_MIN_SEVERITY_[DEBUG|INFO|WARN|ERROR|FATAL]
* in your build options to compile out anything below that severity.
* Use RCLCPP_LOG_MIN_SEVERITY_NONE to compile out all macros.
*/
#ifndef RCLCPP_LOG_MIN_SEVERITY
#define RCLCPP_LOG_MIN_SEVERITY RCLCPP_LOG_MIN_SEVERITY_DEBUG
#endif
@{
from collections import OrderedDict
from copy import deepcopy
from rcutils.logging import feature_combinations
from rcutils.logging import get_suffix_from_features
from rcutils.logging import severities
from rcutils.logging import throttle_args
from rcutils.logging import throttle_params
throttle_args['condition_before'] = 'RCUTILS_LOG_CONDITION_THROTTLE_BEFORE(clock, duration)'
del throttle_params['get_time_point_value']
throttle_params['clock'] = 'rclcpp::Clock that will be used to get the time point.'
throttle_params.move_to_end('clock', last=False)
rclcpp_feature_combinations = OrderedDict()
for combinations, feature in feature_combinations.items():
# skip feature combinations using 'named'
if 'named' in combinations:
continue
rclcpp_feature_combinations[combinations] = feature
# add a stream variant for each available feature combination
stream_arg = 'stream_arg'
for combinations, feature in list(rclcpp_feature_combinations.items()):
combinations = ('stream', ) + combinations
feature = deepcopy(feature)
feature.params[stream_arg] = 'The argument << into a stringstream'
rclcpp_feature_combinations[combinations] = feature
def get_rclcpp_suffix_from_features(features):
suffix = get_suffix_from_features(features)
if 'stream' in features:
suffix = '_STREAM' + suffix
return suffix
}@
@[for severity in severities]@
/** @@name Logging macros for severity @(severity).
*/
///@@{
#if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_@(severity))
// empty logging macros for severity @(severity) when being disabled at compile time
@[ for feature_combination in rclcpp_feature_combinations.keys()]@
@{suffix = get_rclcpp_suffix_from_features(feature_combination)}@
/// Empty logging macro due to the preprocessor definition of RCLCPP_LOG_MIN_SEVERITY.
#define RCLCPP_@(severity)@(suffix)(...)
@[ end for]@
#else
@[ for feature_combination in rclcpp_feature_combinations.keys()]@
@{suffix = get_rclcpp_suffix_from_features(feature_combination)}@
// The RCLCPP_@(severity)@(suffix) macro is surrounded by do { .. } while (0)
// to implement the standard C macro idiom to make the macro safe in all
// contexts; see http://c-faq.com/cpp/multistmt.html for more information.
/**
* \def RCLCPP_@(severity)@(suffix)
* Log a message with severity @(severity)@
@[ if rclcpp_feature_combinations[feature_combination].doc_lines]@
with the following conditions:
@[ else]@
.
@[ end if]@
@[ for doc_line in rclcpp_feature_combinations[feature_combination].doc_lines]@
* @(doc_line)
@[ end for]@
* \param logger The `rclcpp::Logger` to use
@[ for param_name, doc_line in rclcpp_feature_combinations[feature_combination].params.items()]@
* \param @(param_name) @(doc_line)
@[ end for]@
@[ if 'stream' not in feature_combination]@
* \param ... The format string, followed by the variable arguments for the format string.
@[ end if]@
*/
@{params = rclcpp_feature_combinations[feature_combination].params.keys()}@
#define RCLCPP_@(severity)@(suffix)(logger@(''.join([', ' + p for p in params]))@
@[ if 'stream' not in feature_combination]@
, ...@
@[ end if]@
) \
do { \
static_assert( \
::std::is_convertible_v<decltype(logger), ::rclcpp::Logger>, \
"First argument to logging macros must be an rclcpp::Logger"); \
@[ if 'throttle' in feature_combination]@ \
auto get_time_point = [&c=clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
try { \
*time_point = c.now().nanoseconds(); \
} catch (...) { \
RCUTILS_SAFE_FWRITE_TO_STDERR( \
"[rclcpp|logging.hpp] RCLCPP_@(severity)@(suffix) could not get current time stamp\n"); \
return RCUTILS_RET_ERROR; \
} \
return RCUTILS_RET_OK; \
}; \
@[ end if] \
@[ if 'stream' in feature_combination]@
std::stringstream rclcpp_stream_ss_; \
rclcpp_stream_ss_ << @(stream_arg); \
@[ end if]@
RCUTILS_LOG_@(severity)@(get_suffix_from_features(feature_combination))_NAMED( \
@{params = ['get_time_point' if p == 'clock' and 'throttle' in feature_combination else p for p in params]}@
@[ if params]@
@(''.join([' ' + p + ', \\\n' for p in params if p != stream_arg]))@
@[ end if]@
(logger).get_name(), \
@[ if 'stream' not in feature_combination]@
__VA_ARGS__); \
@[ else]@
"%s", rclcpp_stream_ss_.str().c_str()); \
@[ end if]@
} while (0)
@[ end for]@
#endif
///@@}
@[end for]@
#endif // RCLCPP__LOGGING_HPP_

View File

@@ -31,7 +31,7 @@ using rclcpp::CallbackGroupType;
CallbackGroup::CallbackGroup(
CallbackGroupType group_type,
const rclcpp::Context::WeakPtr & context,
rclcpp::Context::WeakPtr context,
bool automatically_add_to_executor_with_node)
: type_(group_type), associated_with_executor_(false),
can_be_taken_from_(true),
@@ -59,7 +59,6 @@ CallbackGroup::type() const
size_t
CallbackGroup::size() const
{
std::lock_guard<std::mutex> lock(mutex_);
return
subscription_ptrs_.size() +
service_ptrs_.size() +
@@ -69,11 +68,11 @@ CallbackGroup::size() const
}
void CallbackGroup::collect_all_ptrs(
const std::function<void(const rclcpp::SubscriptionBase::SharedPtr &)> & sub_func,
const std::function<void(const rclcpp::ServiceBase::SharedPtr &)> & service_func,
const std::function<void(const rclcpp::ClientBase::SharedPtr &)> & client_func,
const std::function<void(const rclcpp::TimerBase::SharedPtr &)> & timer_func,
const std::function<void(const rclcpp::Waitable::SharedPtr &)> & waitable_func) const
std::function<void(const rclcpp::SubscriptionBase::SharedPtr &)> sub_func,
std::function<void(const rclcpp::ServiceBase::SharedPtr &)> service_func,
std::function<void(const rclcpp::ClientBase::SharedPtr &)> client_func,
std::function<void(const rclcpp::TimerBase::SharedPtr &)> timer_func,
std::function<void(const rclcpp::Waitable::SharedPtr &)> waitable_func) const
{
std::lock_guard<std::mutex> lock(mutex_);
@@ -150,7 +149,7 @@ CallbackGroup::trigger_notify_guard_condition()
void
CallbackGroup::add_subscription(
const rclcpp::SubscriptionBase::SharedPtr & subscription_ptr)
const rclcpp::SubscriptionBase::SharedPtr subscription_ptr)
{
std::lock_guard<std::mutex> lock(mutex_);
subscription_ptrs_.push_back(subscription_ptr);
@@ -158,12 +157,12 @@ CallbackGroup::add_subscription(
std::remove_if(
subscription_ptrs_.begin(),
subscription_ptrs_.end(),
[](const rclcpp::SubscriptionBase::WeakPtr & x) {return x.expired();}),
[](rclcpp::SubscriptionBase::WeakPtr x) {return x.expired();}),
subscription_ptrs_.end());
}
void
CallbackGroup::add_timer(const rclcpp::TimerBase::SharedPtr & timer_ptr)
CallbackGroup::add_timer(const rclcpp::TimerBase::SharedPtr timer_ptr)
{
std::lock_guard<std::mutex> lock(mutex_);
timer_ptrs_.push_back(timer_ptr);
@@ -171,12 +170,12 @@ CallbackGroup::add_timer(const rclcpp::TimerBase::SharedPtr & timer_ptr)
std::remove_if(
timer_ptrs_.begin(),
timer_ptrs_.end(),
[](const rclcpp::TimerBase::WeakPtr & x) {return x.expired();}),
[](rclcpp::TimerBase::WeakPtr x) {return x.expired();}),
timer_ptrs_.end());
}
void
CallbackGroup::add_service(const rclcpp::ServiceBase::SharedPtr & service_ptr)
CallbackGroup::add_service(const rclcpp::ServiceBase::SharedPtr service_ptr)
{
std::lock_guard<std::mutex> lock(mutex_);
service_ptrs_.push_back(service_ptr);
@@ -184,12 +183,12 @@ CallbackGroup::add_service(const rclcpp::ServiceBase::SharedPtr & service_ptr)
std::remove_if(
service_ptrs_.begin(),
service_ptrs_.end(),
[](const rclcpp::ServiceBase::WeakPtr & x) {return x.expired();}),
[](rclcpp::ServiceBase::WeakPtr x) {return x.expired();}),
service_ptrs_.end());
}
void
CallbackGroup::add_client(const rclcpp::ClientBase::SharedPtr & client_ptr)
CallbackGroup::add_client(const rclcpp::ClientBase::SharedPtr client_ptr)
{
std::lock_guard<std::mutex> lock(mutex_);
client_ptrs_.push_back(client_ptr);
@@ -197,12 +196,12 @@ CallbackGroup::add_client(const rclcpp::ClientBase::SharedPtr & client_ptr)
std::remove_if(
client_ptrs_.begin(),
client_ptrs_.end(),
[](const rclcpp::ClientBase::WeakPtr & x) {return x.expired();}),
[](rclcpp::ClientBase::WeakPtr x) {return x.expired();}),
client_ptrs_.end());
}
void
CallbackGroup::add_waitable(const rclcpp::Waitable::SharedPtr & waitable_ptr)
CallbackGroup::add_waitable(const rclcpp::Waitable::SharedPtr waitable_ptr)
{
std::lock_guard<std::mutex> lock(mutex_);
waitable_ptrs_.push_back(waitable_ptr);
@@ -210,12 +209,12 @@ CallbackGroup::add_waitable(const rclcpp::Waitable::SharedPtr & waitable_ptr)
std::remove_if(
waitable_ptrs_.begin(),
waitable_ptrs_.end(),
[](const rclcpp::Waitable::WeakPtr & x) {return x.expired();}),
[](rclcpp::Waitable::WeakPtr x) {return x.expired();}),
waitable_ptrs_.end());
}
void
CallbackGroup::remove_waitable(const rclcpp::Waitable::SharedPtr & waitable_ptr) noexcept
CallbackGroup::remove_waitable(const rclcpp::Waitable::SharedPtr waitable_ptr) noexcept
{
std::lock_guard<std::mutex> lock(mutex_);
for (auto iter = waitable_ptrs_.begin(); iter != waitable_ptrs_.end(); ++iter) {

View File

@@ -37,7 +37,7 @@ using rclcpp::exceptions::throw_from_rcl_error;
ClientBase::ClientBase(
rclcpp::node_interfaces::NodeBaseInterface * node_base,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr & node_graph)
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph)
: node_graph_(node_graph),
node_handle_(node_base->get_shared_rcl_node_handle()),
context_(node_base->get_context()),

View File

@@ -60,8 +60,8 @@ JumpHandler::JumpHandler(
pre_callback_t pre_callback,
post_callback_t post_callback,
const rcl_jump_threshold_t & threshold)
: pre_callback(std::move(pre_callback)),
post_callback(std::move(post_callback)),
: pre_callback(pre_callback),
post_callback(post_callback),
notice_threshold(threshold)
{}
@@ -83,10 +83,20 @@ Clock::now() const
return now;
}
void
Clock::cancel_sleep_or_wait()
{
{
std::unique_lock lock(impl_->wait_mutex_);
impl_->stop_sleeping_ = true;
}
impl_->cv_.notify_one();
}
bool
Clock::sleep_until(
const Time & until,
const Context::SharedPtr & context)
Time until,
Context::SharedPtr context)
{
if (!context || !context->is_valid()) {
throw std::runtime_error("context cannot be slept with because it's invalid");
@@ -194,7 +204,7 @@ Clock::sleep_until(
}
bool
Clock::sleep_for(const Duration & rel_time, const Context::SharedPtr & context)
Clock::sleep_for(Duration rel_time, Context::SharedPtr context)
{
return sleep_until(now() + rel_time, context);
}
@@ -209,7 +219,7 @@ Clock::started()
}
bool
Clock::wait_until_started(const Context::SharedPtr & context)
Clock::wait_until_started(Context::SharedPtr context)
{
if (!context || !context->is_valid()) {
throw std::runtime_error("context cannot be slept with because it's invalid");
@@ -229,7 +239,7 @@ Clock::wait_until_started(const Context::SharedPtr & context)
bool
Clock::wait_until_started(
const Duration & timeout,
const Context::SharedPtr & context,
Context::SharedPtr context,
const Duration & wait_tick_ns)
{
if (!context || !context->is_valid()) {
@@ -318,8 +328,8 @@ Clock::on_time_jump(
JumpHandler::SharedPtr
Clock::create_jump_callback(
const JumpHandler::pre_callback_t & pre_callback,
const JumpHandler::post_callback_t & post_callback,
JumpHandler::pre_callback_t pre_callback,
JumpHandler::post_callback_t post_callback,
const rcl_jump_threshold_t & threshold)
{
// Allocate a new jump handler
@@ -516,7 +526,7 @@ class ClockConditionalVariable::Impl
ClockWaiter::UniquePtr clock_;
public:
Impl(const rclcpp::Clock::SharedPtr & clock, const rclcpp::Context::SharedPtr & context)
Impl(const rclcpp::Clock::SharedPtr & clock, rclcpp::Context::SharedPtr context)
:context_(context),
clock_(std::make_unique<ClockWaiter>(clock))
{
@@ -541,7 +551,7 @@ public:
bool
wait_until(
std::unique_lock<std::mutex> & lock, const rclcpp::Time & until,
std::unique_lock<std::mutex> & lock, rclcpp::Time until,
const std::function<bool ()> & pred)
{
if(lock.mutex() != &pred_mutex_) {
@@ -571,7 +581,7 @@ public:
ClockConditionalVariable::ClockConditionalVariable(
const rclcpp::Clock::SharedPtr & clock,
const rclcpp::Context::SharedPtr & context)
rclcpp::Context::SharedPtr context)
:impl_(std::make_unique<Impl>(clock, context))
{
}
@@ -586,7 +596,7 @@ ClockConditionalVariable::notify_one()
bool
ClockConditionalVariable::wait_until(
std::unique_lock<std::mutex> & lock, const rclcpp::Time & until,
std::unique_lock<std::mutex> & lock, rclcpp::Time until,
const std::function<bool ()> & pred)
{
return impl_->wait_until(lock, until, pred);

View File

@@ -14,6 +14,7 @@
#include "rclcpp/context.hpp"
#include <map>
#include <memory>
#include <mutex>
#include <sstream>
@@ -28,7 +29,7 @@
#include "rclcpp/detail/utilities.hpp"
#include "rclcpp/exceptions.hpp"
#include "rclcpp/logging.hpp"
#include "rclcpp/graph_listener.hpp"
#include "rcutils/error_handling.h"
#include "rcutils/macros.h"
@@ -59,7 +60,7 @@ public:
std::remove_if(
weak_contexts_.begin(),
weak_contexts_.end(),
[context](const Context::WeakPtr & weak_context) {
[context](const Context::WeakPtr weak_context) {
auto locked_context = weak_context.lock();
if (!locked_context) {
// take advantage and removed expired contexts
@@ -142,12 +143,52 @@ rclcpp_logging_output_handler(
}
} // extern "C"
/**
* Global storage for pre and post shutdown recursive mutexes.
* Note, this is a ABI compatibility hack.
*/
class MutexLookup
{
std::mutex m;
struct MutexHolder
{
std::recursive_mutex on_shutdown_callbacks_mutex_;
std::recursive_mutex pre_shutdown_callbacks_mutex_;
};
std::map<const Context *, std::unique_ptr<MutexHolder>> mutexMap;
public:
MutexHolder & getMutexes(const Context *forContext)
{
auto it = mutexMap.find(forContext);
if(it == mutexMap.end()) {
it = mutexMap.emplace(forContext, std::make_unique<MutexHolder>()).first;
}
return *(it->second);
}
/**
* Only supposed to be called on deletion of context
*/
void removeMutexes(const Context *forContext)
{
mutexMap.erase(forContext);
}
};
MutexLookup mutexStorage;
Context::Context()
: rcl_context_(nullptr),
shutdown_reason_(""),
logging_mutex_(nullptr),
graph_listener_(nullptr)
{}
logging_mutex_(nullptr)
{
// allocate mutexes
mutexStorage.getMutexes(this);
}
Context::~Context()
{
@@ -166,6 +207,9 @@ Context::~Context()
} catch (...) {
RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "unhandled exception in ~Context()");
}
// delete mutexes
mutexStorage.removeMutexes(this);
}
RCLCPP_LOCAL
@@ -244,24 +288,6 @@ Context::init(
weak_contexts_ = get_weak_contexts();
weak_contexts_->add_context(this->shared_from_this());
std::lock_guard<std::recursive_mutex> lock (on_shutdown_callbacks_mutex_);
graph_listener_ = std::make_shared<graph_listener::GraphListener>(shared_from_this());
if (!graph_listener_->is_started()) {
// Register an on_shutdown hook to shutdown the graph listener.
// This is important to ensure that the wait set is finalized before
// destruction of static objects occurs.
std::weak_ptr<rclcpp::graph_listener::GraphListener> weak_graph_listener = graph_listener_;
on_shutdown ([weak_graph_listener]() {
auto shared_graph_listener = weak_graph_listener.lock();
if(shared_graph_listener) {
shared_graph_listener->shutdown(std::nothrow);
}
});
}
} catch (const std::exception & e) {
ret = rcl_shutdown(rcl_context_.get());
rcl_context_.reset();
@@ -329,7 +355,8 @@ Context::shutdown(const std::string & reason)
// call each pre-shutdown callback
{
std::lock_guard<std::recursive_mutex> lock{pre_shutdown_callbacks_mutex_};
std::lock_guard<std::recursive_mutex> lock{mutexStorage.getMutexes(
this).pre_shutdown_callbacks_mutex_};
// callbacks may delete other callbacks during the execution,
// therefore we need to save a copy and check before execution
// if the next callback is still present
@@ -351,7 +378,8 @@ Context::shutdown(const std::string & reason)
shutdown_reason_ = reason;
// call each shutdown callback
{
std::lock_guard<std::recursive_mutex> lock(on_shutdown_callbacks_mutex_);
std::lock_guard<std::recursive_mutex> lock(mutexStorage.getMutexes(
this).on_shutdown_callbacks_mutex_);
// callbacks may delete other callbacks during the execution,
// therefore we need to save a copy and check before execution
// if the next callback is still present
@@ -388,14 +416,14 @@ Context::shutdown(const std::string & reason)
}
rclcpp::Context::OnShutdownCallback
Context::on_shutdown(const OnShutdownCallback & callback)
Context::on_shutdown(OnShutdownCallback callback)
{
add_on_shutdown_callback(callback);
return callback;
}
rclcpp::OnShutdownCallbackHandle
Context::add_on_shutdown_callback(const OnShutdownCallback & callback)
Context::add_on_shutdown_callback(OnShutdownCallback callback)
{
return add_shutdown_callback<ShutdownType::on_shutdown>(callback);
}
@@ -407,7 +435,7 @@ Context::remove_on_shutdown_callback(const OnShutdownCallbackHandle & callback_h
}
rclcpp::PreShutdownCallbackHandle
Context::add_pre_shutdown_callback(const PreShutdownCallback & callback)
Context::add_pre_shutdown_callback(PreShutdownCallback callback)
{
return add_shutdown_callback<ShutdownType::pre_shutdown>(callback);
}
@@ -422,7 +450,7 @@ Context::remove_pre_shutdown_callback(
template<Context::ShutdownType shutdown_type>
rclcpp::ShutdownCallbackHandle
Context::add_shutdown_callback(
const ShutdownCallback & callback)
ShutdownCallback callback)
{
auto callback_shared_ptr =
std::make_shared<ShutdownCallbackHandle::ShutdownCallbackType>(callback);
@@ -431,10 +459,12 @@ Context::add_shutdown_callback(
shutdown_type == ShutdownType::pre_shutdown || shutdown_type == ShutdownType::on_shutdown);
if constexpr (shutdown_type == ShutdownType::pre_shutdown) {
std::lock_guard<std::recursive_mutex> lock(pre_shutdown_callbacks_mutex_);
std::lock_guard<std::recursive_mutex> lock(mutexStorage.getMutexes(
this).pre_shutdown_callbacks_mutex_);
pre_shutdown_callbacks_.emplace_back(callback_shared_ptr);
} else {
std::lock_guard<std::recursive_mutex> lock(on_shutdown_callbacks_mutex_);
std::lock_guard<std::recursive_mutex> lock(mutexStorage.getMutexes(
this).on_shutdown_callbacks_mutex_);
on_shutdown_callbacks_.emplace_back(callback_shared_ptr);
}
@@ -465,6 +495,7 @@ Context::remove_shutdown_callback(
return false;
}
callback_vector.erase(iter);
return true;
};
@@ -472,9 +503,11 @@ Context::remove_shutdown_callback(
shutdown_type == ShutdownType::pre_shutdown || shutdown_type == ShutdownType::on_shutdown);
if constexpr (shutdown_type == ShutdownType::pre_shutdown) {
return remove_callback(pre_shutdown_callbacks_mutex_, pre_shutdown_callbacks_);
return remove_callback(mutexStorage.getMutexes(this).pre_shutdown_callbacks_mutex_,
pre_shutdown_callbacks_);
} else {
return remove_callback(on_shutdown_callbacks_mutex_, on_shutdown_callbacks_);
return remove_callback(mutexStorage.getMutexes(this).on_shutdown_callbacks_mutex_,
on_shutdown_callbacks_);
}
}
@@ -497,9 +530,8 @@ Context::get_shutdown_callback() const
const auto get_callback_vector = [](auto & mutex, auto & callback_set) {
const std::lock_guard<std::recursive_mutex> lock(mutex);
std::vector<rclcpp::Context::ShutdownCallback> callbacks;
callbacks.reserve(callback_set.size());
for (auto & callback : callback_set) {
callbacks.emplace_back(*callback);
callbacks.push_back(*callback);
}
return callbacks;
};
@@ -508,9 +540,11 @@ Context::get_shutdown_callback() const
shutdown_type == ShutdownType::pre_shutdown || shutdown_type == ShutdownType::on_shutdown);
if constexpr (shutdown_type == ShutdownType::pre_shutdown) {
return get_callback_vector(pre_shutdown_callbacks_mutex_, pre_shutdown_callbacks_);
return get_callback_vector(mutexStorage.getMutexes(this).pre_shutdown_callbacks_mutex_,
pre_shutdown_callbacks_);
} else {
return get_callback_vector(on_shutdown_callbacks_mutex_, on_shutdown_callbacks_);
return get_callback_vector(mutexStorage.getMutexes(this).on_shutdown_callbacks_mutex_,
on_shutdown_callbacks_);
}
}
@@ -520,12 +554,6 @@ Context::get_rcl_context()
return rcl_context_;
}
std::shared_ptr<rclcpp::graph_listener::GraphListener>
Context::get_graph_listener()
{
return graph_listener_;
}
bool
Context::sleep_for(const std::chrono::nanoseconds & nanoseconds)
{

View File

@@ -19,13 +19,13 @@ namespace rclcpp
{
rclcpp::GenericClient::SharedPtr
create_generic_client(
const std::shared_ptr<node_interfaces::NodeBaseInterface> & node_base,
const std::shared_ptr<node_interfaces::NodeGraphInterface> & node_graph,
const std::shared_ptr<node_interfaces::NodeServicesInterface> & node_services,
std::shared_ptr<node_interfaces::NodeBaseInterface> node_base,
std::shared_ptr<node_interfaces::NodeGraphInterface> node_graph,
std::shared_ptr<node_interfaces::NodeServicesInterface> node_services,
const std::string & service_name,
const std::string & service_type,
const rclcpp::QoS & qos,
const rclcpp::CallbackGroup::SharedPtr & group)
rclcpp::CallbackGroup::SharedPtr group)
{
rcl_client_options_t options = rcl_client_get_default_options();
options.qos = qos.get_rmw_qos_profile();

View File

@@ -18,7 +18,6 @@
#include <iterator>
#include <memory>
#include <map>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
@@ -53,7 +52,6 @@ class rclcpp::ExecutorImplementation {};
Executor::Executor(const std::shared_ptr<rclcpp::Context> & context)
: spinning(false),
context_(context),
entities_need_rebuild_(true),
collector_(nullptr),
wait_set_({}, {}, {}, {}, {}, {}, context)
@@ -99,29 +97,29 @@ Executor::~Executor()
notify_waitable_->remove_guard_condition(shutdown_guard_condition_);
current_collection_.timers.update(
{}, {},
[this](auto timer) {wait_set_.remove_timer(std::move(timer));});
[this](auto timer) {wait_set_.remove_timer(timer);});
current_collection_.subscriptions.update(
{}, {},
[this](auto subscription) {
wait_set_.remove_subscription(std::move(subscription), kDefaultSubscriptionMask);
wait_set_.remove_subscription(subscription, kDefaultSubscriptionMask);
});
current_collection_.clients.update(
{}, {},
[this](auto client) {wait_set_.remove_client(std::move(client));});
[this](auto client) {wait_set_.remove_client(client);});
current_collection_.services.update(
{}, {},
[this](auto service) {wait_set_.remove_service(std::move(service));});
[this](auto service) {wait_set_.remove_service(service);});
current_collection_.guard_conditions.update(
{}, {},
[this](auto guard_condition) {wait_set_.remove_guard_condition(std::move(guard_condition));});
[this](auto guard_condition) {wait_set_.remove_guard_condition(guard_condition);});
current_collection_.waitables.update(
{}, {},
[this](auto waitable) {wait_set_.remove_waitable(std::move(waitable));});
[this](auto waitable) {wait_set_.remove_waitable(waitable);});
// Remove shutdown callback handle registered to Context
if (!context_->remove_on_shutdown_callback(shutdown_callback_handle_)) {
@@ -170,8 +168,8 @@ Executor::get_automatically_added_callback_groups_from_nodes()
void
Executor::add_callback_group(
const rclcpp::CallbackGroup::SharedPtr & group_ptr,
[[maybe_unused]] const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
rclcpp::CallbackGroup::SharedPtr group_ptr,
[[maybe_unused]] rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
bool notify)
{
this->collector_.add_callback_group(group_ptr);
@@ -186,15 +184,8 @@ Executor::add_callback_group(
}
void
Executor::add_node(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
bool notify)
Executor::add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify)
{
if (node_ptr->get_context() != context_) {
throw std::runtime_error(
"add_node() called with a node with a different context from this executor");
}
this->collector_.add_node(node_ptr);
try {
@@ -208,7 +199,7 @@ Executor::add_node(
void
Executor::remove_callback_group(
const rclcpp::CallbackGroup::SharedPtr & group_ptr,
rclcpp::CallbackGroup::SharedPtr group_ptr,
bool notify)
{
this->collector_.remove_callback_group(group_ptr);
@@ -223,15 +214,13 @@ Executor::remove_callback_group(
}
void
Executor::add_node(const std::shared_ptr<rclcpp::Node> & node_ptr, bool notify)
Executor::add_node(std::shared_ptr<rclcpp::Node> node_ptr, bool notify)
{
this->add_node(node_ptr->get_node_base_interface(), notify);
}
void
Executor::remove_node(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
bool notify)
Executor::remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify)
{
this->collector_.remove_node(node_ptr);
@@ -245,14 +234,14 @@ Executor::remove_node(
}
void
Executor::remove_node(const std::shared_ptr<rclcpp::Node> & node_ptr, bool notify)
Executor::remove_node(std::shared_ptr<rclcpp::Node> node_ptr, bool notify)
{
this->remove_node(node_ptr->get_node_base_interface(), notify);
}
void
Executor::spin_node_once_nanoseconds(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
std::chrono::nanoseconds timeout)
{
this->add_node(node, false);
@@ -315,7 +304,7 @@ Executor::spin_until_future_complete_impl(
}
void
Executor::spin_node_some(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node)
Executor::spin_node_some(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node)
{
this->add_node(node, false);
spin_some();
@@ -323,7 +312,7 @@ Executor::spin_node_some(const rclcpp::node_interfaces::NodeBaseInterface::Share
}
void
Executor::spin_node_some(const std::shared_ptr<rclcpp::Node> & node)
Executor::spin_node_some(std::shared_ptr<rclcpp::Node> node)
{
this->spin_node_some(node->get_node_base_interface());
}
@@ -335,7 +324,7 @@ void Executor::spin_some(std::chrono::nanoseconds max_duration)
void
Executor::spin_node_all(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
std::chrono::nanoseconds max_duration)
{
this->add_node(node, false);
@@ -344,9 +333,7 @@ Executor::spin_node_all(
}
void
Executor::spin_node_all(
const std::shared_ptr<rclcpp::Node> & node,
std::chrono::nanoseconds max_duration)
Executor::spin_node_all(std::shared_ptr<rclcpp::Node> node, std::chrono::nanoseconds max_duration)
{
this->spin_node_all(node->get_node_base_interface(), max_duration);
}
@@ -552,7 +539,7 @@ take_and_do_error_handling(
}
void
Executor::execute_subscription(const rclcpp::SubscriptionBase::SharedPtr & subscription)
Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription)
{
using rclcpp::dynamic_typesupport::DynamicMessage;
@@ -646,7 +633,7 @@ Executor::execute_subscription(const rclcpp::SubscriptionBase::SharedPtr & subsc
throw std::runtime_error("Unimplemented");
}
case rclcpp::DeliveredMessageKind::INVALID:
default:
{
throw std::runtime_error("Delivered message kind is not supported");
}
@@ -654,15 +641,13 @@ Executor::execute_subscription(const rclcpp::SubscriptionBase::SharedPtr & subsc
}
void
Executor::execute_timer(
const rclcpp::TimerBase::SharedPtr & timer,
const std::shared_ptr<void> & data_ptr)
Executor::execute_timer(rclcpp::TimerBase::SharedPtr timer, const std::shared_ptr<void> & data_ptr)
{
timer->execute_callback(data_ptr);
}
void
Executor::execute_service(const rclcpp::ServiceBase::SharedPtr & service)
Executor::execute_service(rclcpp::ServiceBase::SharedPtr service)
{
auto request_header = service->create_request_header();
std::shared_ptr<void> request = service->create_request();
@@ -674,7 +659,7 @@ Executor::execute_service(const rclcpp::ServiceBase::SharedPtr & service)
}
void
Executor::execute_client(const rclcpp::ClientBase::SharedPtr & client)
Executor::execute_client(rclcpp::ClientBase::SharedPtr client)
{
auto request_header = client->create_request_header();
std::shared_ptr<void> response = client->create_response();
@@ -716,37 +701,37 @@ Executor::collect_entities()
// from the wait set as necessary.
current_collection_.timers.update(
collection.timers,
[this](auto timer) {wait_set_.add_timer(std::move(timer));},
[this](auto timer) {wait_set_.remove_timer(std::move(timer));});
[this](auto timer) {wait_set_.add_timer(timer);},
[this](auto timer) {wait_set_.remove_timer(timer);});
current_collection_.subscriptions.update(
collection.subscriptions,
[this](auto subscription) {
wait_set_.add_subscription(std::move(subscription), kDefaultSubscriptionMask);
wait_set_.add_subscription(subscription, kDefaultSubscriptionMask);
},
[this](auto subscription) {
wait_set_.remove_subscription(std::move(subscription), kDefaultSubscriptionMask);
wait_set_.remove_subscription(subscription, kDefaultSubscriptionMask);
});
current_collection_.clients.update(
collection.clients,
[this](auto client) {wait_set_.add_client(std::move(client));},
[this](auto client) {wait_set_.remove_client(std::move(client));});
[this](auto client) {wait_set_.add_client(client);},
[this](auto client) {wait_set_.remove_client(client);});
current_collection_.services.update(
collection.services,
[this](auto service) {wait_set_.add_service(std::move(service));},
[this](auto service) {wait_set_.remove_service(std::move(service));});
[this](auto service) {wait_set_.add_service(service);},
[this](auto service) {wait_set_.remove_service(service);});
current_collection_.guard_conditions.update(
collection.guard_conditions,
[this](auto guard_condition) {wait_set_.add_guard_condition(std::move(guard_condition));},
[this](auto guard_condition) {wait_set_.remove_guard_condition(std::move(guard_condition));});
[this](auto guard_condition) {wait_set_.add_guard_condition(guard_condition);},
[this](auto guard_condition) {wait_set_.remove_guard_condition(guard_condition);});
current_collection_.waitables.update(
collection.waitables,
[this](auto waitable) {wait_set_.add_waitable(std::move(waitable));},
[this](auto waitable) {wait_set_.remove_waitable(std::move(waitable));});
[this](auto waitable) {wait_set_.add_waitable(waitable);},
[this](auto waitable) {wait_set_.remove_waitable(waitable);});
// In the case that an entity already has an expired weak pointer
// before being removed from the waitset, additionally prune the waitset.

View File

@@ -13,11 +13,10 @@
// limitations under the License.
#include "rclcpp/executors.hpp"
#include "rcpputils/compile_warnings.hpp"
void
rclcpp::spin_all(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
std::chrono::nanoseconds max_duration)
{
rclcpp::ExecutorOptions options;
@@ -27,7 +26,13 @@ rclcpp::spin_all(
}
void
rclcpp::spin_some(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr)
rclcpp::spin_all(rclcpp::Node::SharedPtr node_ptr, std::chrono::nanoseconds max_duration)
{
rclcpp::spin_all(node_ptr->get_node_base_interface(), max_duration);
}
void
rclcpp::spin_some(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr)
{
rclcpp::ExecutorOptions options;
options.context = node_ptr->get_context();
@@ -36,7 +41,13 @@ rclcpp::spin_some(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &
}
void
rclcpp::spin(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr)
rclcpp::spin_some(rclcpp::Node::SharedPtr node_ptr)
{
rclcpp::spin_some(node_ptr->get_node_base_interface());
}
void
rclcpp::spin(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr)
{
rclcpp::ExecutorOptions options;
options.context = node_ptr->get_context();
@@ -47,23 +58,7 @@ rclcpp::spin(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_
}
void
rclcpp::spin(const rclcpp::Node::SharedPtr & node_ptr)
rclcpp::spin(rclcpp::Node::SharedPtr node_ptr)
{
rclcpp::spin(node_ptr->get_node_base_interface());
}
void
rclcpp::spin_all(const rclcpp::Node::SharedPtr & node_ptr, std::chrono::nanoseconds max_duration)
{
RCPPUTILS_DEPRECATION_WARNING_OFF_START
rclcpp::spin_all(node_ptr->get_node_base_interface(), max_duration);
RCPPUTILS_DEPRECATION_WARNING_OFF_STOP
}
void
rclcpp::spin_some(const rclcpp::Node::SharedPtr & node_ptr)
{
RCPPUTILS_DEPRECATION_WARNING_OFF_START
rclcpp::spin_some(node_ptr->get_node_base_interface());
RCPPUTILS_DEPRECATION_WARNING_OFF_STOP
}

View File

@@ -70,7 +70,7 @@ build_entities_collection(
{
collection.clear();
for (const auto & weak_group_ptr : callback_groups) {
for (auto weak_group_ptr : callback_groups) {
auto group_ptr = weak_group_ptr.lock();
if (!group_ptr) {
continue;

View File

@@ -24,7 +24,7 @@ namespace executors
{
ExecutorEntitiesCollector::ExecutorEntitiesCollector(
const std::shared_ptr<ExecutorNotifyWaitable> & notify_waitable)
std::shared_ptr<ExecutorNotifyWaitable> notify_waitable)
: notify_waitable_(notify_waitable)
{
}
@@ -47,7 +47,7 @@ ExecutorEntitiesCollector::~ExecutorEntitiesCollector()
weak_group_it = remove_weak_callback_group(weak_group_it, manually_added_groups_);
}
for (const auto & weak_node_ptr : pending_added_nodes_) {
for (auto weak_node_ptr : pending_added_nodes_) {
auto node_ptr = weak_node_ptr.lock();
if (node_ptr) {
node_ptr->get_associated_with_executor_atomic().store(false);
@@ -56,7 +56,7 @@ ExecutorEntitiesCollector::~ExecutorEntitiesCollector()
pending_added_nodes_.clear();
pending_removed_nodes_.clear();
for (const auto & weak_group_ptr : pending_manually_added_groups_) {
for (auto weak_group_ptr : pending_manually_added_groups_) {
auto group_ptr = weak_group_ptr.lock();
if (group_ptr) {
group_ptr->get_associated_with_executor_atomic().store(false);
@@ -83,8 +83,7 @@ ExecutorEntitiesCollector::has_pending() const
}
void
ExecutorEntitiesCollector::add_node(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr)
ExecutorEntitiesCollector::add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr)
{
// If the node already has an executor
std::atomic_bool & has_executor = node_ptr->get_associated_with_executor_atomic();
@@ -110,7 +109,7 @@ ExecutorEntitiesCollector::add_node(
void
ExecutorEntitiesCollector::remove_node(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr)
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr)
{
std::atomic_bool & has_executor = node_ptr->get_associated_with_executor_atomic();
if (!has_executor.exchange(false)) {
@@ -134,7 +133,7 @@ ExecutorEntitiesCollector::remove_node(
}
void
ExecutorEntitiesCollector::add_callback_group(const rclcpp::CallbackGroup::SharedPtr & group_ptr)
ExecutorEntitiesCollector::add_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr)
{
std::atomic_bool & has_executor = group_ptr->get_associated_with_executor_atomic();
if (has_executor.exchange(true)) {
@@ -159,7 +158,7 @@ ExecutorEntitiesCollector::add_callback_group(const rclcpp::CallbackGroup::Share
}
void
ExecutorEntitiesCollector::remove_callback_group(const rclcpp::CallbackGroup::SharedPtr & group_ptr)
ExecutorEntitiesCollector::remove_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr)
{
if (!group_ptr->get_associated_with_executor_atomic().load()) {
throw std::runtime_error("Callback group needs to be associated with an executor.");
@@ -289,7 +288,7 @@ ExecutorEntitiesCollector::remove_weak_callback_group(
void
ExecutorEntitiesCollector::add_callback_group_to_collection(
const rclcpp::CallbackGroup::SharedPtr & group_ptr,
rclcpp::CallbackGroup::SharedPtr group_ptr,
CallbackGroupCollection & collection)
{
auto iter = collection.insert(group_ptr);
@@ -306,7 +305,7 @@ ExecutorEntitiesCollector::add_callback_group_to_collection(
void
ExecutorEntitiesCollector::process_queues()
{
for (const auto & weak_node_ptr : pending_added_nodes_) {
for (auto weak_node_ptr : pending_added_nodes_) {
auto node_ptr = weak_node_ptr.lock();
if (!node_ptr) {
continue;
@@ -321,7 +320,7 @@ ExecutorEntitiesCollector::process_queues()
}
pending_added_nodes_.clear();
for (const auto & weak_node_ptr : pending_removed_nodes_) {
for (auto weak_node_ptr : pending_removed_nodes_) {
auto node_it = weak_nodes_.find(weak_node_ptr);
if (node_it != weak_nodes_.end()) {
remove_weak_node(node_it);
@@ -349,7 +348,7 @@ ExecutorEntitiesCollector::process_queues()
}
pending_removed_nodes_.clear();
for (const auto & weak_group_ptr : pending_manually_added_groups_) {
for (auto weak_group_ptr : pending_manually_added_groups_) {
auto group_ptr = weak_group_ptr.lock();
if (group_ptr) {
this->add_callback_group_to_collection(group_ptr, manually_added_groups_);
@@ -364,7 +363,7 @@ ExecutorEntitiesCollector::process_queues()
}
pending_manually_added_groups_.clear();
for (const auto & weak_group_ptr : pending_manually_removed_groups_) {
for (auto weak_group_ptr : pending_manually_removed_groups_) {
auto group_ptr = weak_group_ptr.lock();
if (group_ptr) {
auto group_it = manually_added_groups_.find(group_ptr);
@@ -387,7 +386,7 @@ ExecutorEntitiesCollector::add_automatically_associated_callback_groups(
auto node = weak_node.lock();
if (node) {
node->for_each_callback_group(
[this, node](const rclcpp::CallbackGroup::SharedPtr & group_ptr)
[this, node](rclcpp::CallbackGroup::SharedPtr group_ptr)
{
if (!group_ptr->get_associated_with_executor_atomic().load() &&
group_ptr->automatically_add_to_executor_with_node())

View File

@@ -21,7 +21,7 @@ namespace executors
{
ExecutorNotifyWaitable::ExecutorNotifyWaitable(
const std::function<void(void)> & on_execute_callback,
std::function<void(void)> on_execute_callback,
const rclcpp::Context::SharedPtr & context)
: execute_callback_(on_execute_callback),
guard_condition_(std::make_shared<rclcpp::GuardCondition>(context))
@@ -144,13 +144,13 @@ ExecutorNotifyWaitable::take_data_by_entity_id([[maybe_unused]] size_t id)
}
void
ExecutorNotifyWaitable::set_on_ready_callback(std::function<void(size_t, int)> callback_in)
ExecutorNotifyWaitable::set_on_ready_callback(std::function<void(size_t, int)> callback)
{
// The second argument of the callback could be used to identify which guard condition
// triggered the event.
// We could indicate which of the guard conditions was triggered, but the executor
// is already going to check that.
auto gc_callback = [callback = std::move(callback_in)](size_t count) {
auto gc_callback = [callback](size_t count) {
callback(count, 0);
};
@@ -179,12 +179,11 @@ void
ExecutorNotifyWaitable::set_execute_callback(std::function<void(void)> on_execute_callback)
{
std::lock_guard<std::mutex> lock(execute_mutex_);
execute_callback_ = std::move(on_execute_callback);
execute_callback_ = on_execute_callback;
}
void
ExecutorNotifyWaitable::add_guard_condition(
const rclcpp::GuardCondition::WeakPtr & weak_guard_condition)
ExecutorNotifyWaitable::add_guard_condition(rclcpp::GuardCondition::WeakPtr weak_guard_condition)
{
std::lock_guard<std::mutex> lock(guard_condition_mutex_);
const auto & guard_condition = weak_guard_condition.lock();
@@ -197,8 +196,7 @@ ExecutorNotifyWaitable::add_guard_condition(
}
void
ExecutorNotifyWaitable::remove_guard_condition(
const rclcpp::GuardCondition::WeakPtr & weak_guard_condition)
ExecutorNotifyWaitable::remove_guard_condition(rclcpp::GuardCondition::WeakPtr weak_guard_condition)
{
std::lock_guard<std::mutex> lock(guard_condition_mutex_);
const auto & guard_condition = weak_guard_condition.lock();

View File

@@ -0,0 +1,223 @@
// Copyright 2019 Nobleo Technology
//
// 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 "rclcpp/executors/executor_entities_collection.hpp"
#include "rcpputils/scope_exit.hpp"
#include "rclcpp/executors/static_single_threaded_executor.hpp"
#include "rclcpp/any_executable.hpp"
using rclcpp::executors::StaticSingleThreadedExecutor;
StaticSingleThreadedExecutor::StaticSingleThreadedExecutor(const rclcpp::ExecutorOptions & options)
: rclcpp::Executor(options)
{
}
StaticSingleThreadedExecutor::~StaticSingleThreadedExecutor() {}
void
StaticSingleThreadedExecutor::spin()
{
if (spinning.exchange(true)) {
throw std::runtime_error("spin() called while already spinning");
}
RCPPUTILS_SCOPE_EXIT(this->spinning.store(false); );
// This is essentially the contents of the rclcpp::Executor::wait_for_work method,
// except we need to keep the wait result to reproduce the StaticSingleThreadedExecutor
// behavior.
while (rclcpp::ok(this->context_) && spinning.load()) {
this->spin_once_impl(std::chrono::nanoseconds(-1));
}
}
void
StaticSingleThreadedExecutor::spin_some(std::chrono::nanoseconds max_duration)
{
// In this context a 0 input max_duration means no duration limit
if (std::chrono::nanoseconds(0) == max_duration) {
max_duration = std::chrono::nanoseconds::max();
}
return this->spin_some_impl(max_duration, false);
}
void
StaticSingleThreadedExecutor::spin_all(std::chrono::nanoseconds max_duration)
{
if (max_duration < std::chrono::nanoseconds(0)) {
throw std::invalid_argument("max_duration must be greater than or equal to 0");
}
return this->spin_some_impl(max_duration, true);
}
void
StaticSingleThreadedExecutor::spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive)
{
auto start = std::chrono::steady_clock::now();
auto max_duration_not_elapsed = [max_duration, start]() {
const auto spin_forever = std::chrono::nanoseconds(0) == max_duration;
const auto cur_duration = std::chrono::steady_clock::now() - start;
return spin_forever || (cur_duration < max_duration);
};
if (spinning.exchange(true)) {
throw std::runtime_error("spin_some() called while already spinning");
}
RCPPUTILS_SCOPE_EXIT(this->spinning.store(false););
while (rclcpp::ok(context_) && spinning.load() && max_duration_not_elapsed()) {
// Get executables that are ready now
std::lock_guard<std::mutex> guard(mutex_);
auto wait_result = this->collect_and_wait(std::chrono::nanoseconds(0));
if (wait_result.has_value()) {
// Execute ready executables
bool work_available = this->execute_ready_executables(
current_collection_,
wait_result.value(),
false);
if (!work_available || !exhaustive) {
break;
}
}
}
}
void
StaticSingleThreadedExecutor::spin_once_impl(std::chrono::nanoseconds timeout)
{
if (rclcpp::ok(context_) && spinning.load()) {
std::lock_guard<std::mutex> guard(mutex_);
auto wait_result = this->collect_and_wait(timeout);
if (wait_result.has_value()) {
this->execute_ready_executables(current_collection_, wait_result.value(), true);
}
}
}
std::optional<rclcpp::WaitResult<rclcpp::WaitSet>>
StaticSingleThreadedExecutor::collect_and_wait(std::chrono::nanoseconds timeout)
{
// we need to make sure that callback groups don't get out of scope
// during the wait. As in jazzy, they are not covered by the DynamicStorage,
// we explicitly hold them here as a bugfix
std::vector<rclcpp::CallbackGroup::SharedPtr> cbgs;
if (this->entities_need_rebuild_.exchange(false) || current_collection_.empty()) {
this->collect_entities();
}
auto callback_groups = this->collector_.get_all_callback_groups();
cbgs.resize(callback_groups.size());
for(const auto & w_ptr : callback_groups) {
auto shr_ptr = w_ptr.lock();
if(shr_ptr) {
cbgs.push_back(std::move(shr_ptr));
}
}
auto wait_result = wait_set_.wait(std::chrono::nanoseconds(timeout));
// drop references to the callback groups, before trying to execute anything
cbgs.clear();
if (wait_result.kind() == WaitResultKind::Empty) {
RCUTILS_LOG_WARN_NAMED(
"rclcpp",
"empty wait set received in wait(). This should never happen.");
return {};
} else {
if (wait_result.kind() == WaitResultKind::Ready && current_notify_waitable_) {
auto & rcl_wait_set = wait_result.get_wait_set().get_rcl_wait_set();
if (current_notify_waitable_->is_ready(rcl_wait_set)) {
current_notify_waitable_->execute(current_notify_waitable_->take_data());
}
}
}
return wait_result;
}
// This preserves the "scheduling semantics" of the StaticSingleThreadedExecutor
// from the original implementation.
bool StaticSingleThreadedExecutor::execute_ready_executables(
const rclcpp::executors::ExecutorEntitiesCollection & collection,
rclcpp::WaitResult<rclcpp::WaitSet> & wait_result,
bool spin_once)
{
bool any_ready_executable = false;
if (wait_result.kind() != rclcpp::WaitResultKind::Ready) {
return any_ready_executable;
}
while (auto subscription = wait_result.next_ready_subscription()) {
auto entity_iter = collection.subscriptions.find(subscription->get_subscription_handle().get());
if (entity_iter != collection.subscriptions.end()) {
execute_subscription(subscription);
any_ready_executable = true;
if (spin_once) {return any_ready_executable;}
}
}
size_t current_timer_index = 0;
while (true) {
auto [timer, timer_index] = wait_result.peek_next_ready_timer(current_timer_index);
if (nullptr == timer) {
break;
}
current_timer_index = timer_index;
auto entity_iter = collection.timers.find(timer->get_timer_handle().get());
if (entity_iter != collection.timers.end()) {
wait_result.clear_timer_with_index(current_timer_index);
auto data = timer->call();
if (!data) {
// someone canceled the timer between is_ready and call
continue;
}
execute_timer(std::move(timer), data);
any_ready_executable = true;
if (spin_once) {return any_ready_executable;}
}
}
while (auto client = wait_result.next_ready_client()) {
auto entity_iter = collection.clients.find(client->get_client_handle().get());
if (entity_iter != collection.clients.end()) {
execute_client(client);
any_ready_executable = true;
if (spin_once) {return any_ready_executable;}
}
}
while (auto service = wait_result.next_ready_service()) {
auto entity_iter = collection.services.find(service->get_service_handle().get());
if (entity_iter != collection.services.end()) {
execute_service(service);
any_ready_executable = true;
if (spin_once) {return any_ready_executable;}
}
}
while (auto waitable = wait_result.next_ready_waitable()) {
auto entity_iter = collection.waitables.find(waitable.get());
if (entity_iter != collection.waitables.end()) {
const auto data = waitable->take_data();
waitable->execute(data);
any_ready_executable = true;
if (spin_once) {return any_ready_executable;}
}
}
return any_ready_executable;
}

View File

@@ -25,9 +25,9 @@ using namespace std::chrono_literals;
using rclcpp::experimental::executors::EventsExecutor;
EventsExecutor::EventsExecutor(
const rclcpp::ExecutorOptions & options,
rclcpp::experimental::executors::EventsQueue::UniquePtr events_queue,
bool execute_timers_separate_thread)
bool execute_timers_separate_thread,
const rclcpp::ExecutorOptions & options)
: rclcpp::Executor(options)
{
// Get ownership of the queue used to store events.

View File

@@ -29,7 +29,7 @@ TimersManager::TimersManager(
std::shared_ptr<rclcpp::Context> context,
std::function<void(const rclcpp::TimerBase *, const std::shared_ptr<void> &)> on_ready_callback)
: on_ready_callback_(on_ready_callback),
context_(std::move(context))
context_(context)
{
}
@@ -42,7 +42,7 @@ TimersManager::~TimersManager()
this->stop();
}
void TimersManager::add_timer(const rclcpp::TimerBase::SharedPtr & timer)
void TimersManager::add_timer(rclcpp::TimerBase::SharedPtr timer)
{
if (!timer) {
throw std::invalid_argument("TimersManager::add_timer() trying to add nullptr timer");
@@ -311,7 +311,7 @@ void TimersManager::clear()
timers_cv_.notify_one();
}
void TimersManager::remove_timer(const TimerPtr & timer)
void TimersManager::remove_timer(TimerPtr timer)
{
bool removed = false;
{

View File

@@ -25,7 +25,7 @@ namespace rclcpp
{
GenericClient::GenericClient(
rclcpp::node_interfaces::NodeBaseInterface * node_base,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr & node_graph,
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
const std::string & service_name,
const std::string & service_type,
rcl_client_options_t & client_options)
@@ -97,8 +97,8 @@ GenericClient::create_request_header()
void
GenericClient::handle_response(
const std::shared_ptr<rmw_request_id_t> & request_header,
const std::shared_ptr<void> & response)
std::shared_ptr<rmw_request_id_t> request_header,
std::shared_ptr<void> response)
{
auto optional_pending_request =
this->get_and_erase_pending_request(request_header->sequence_number);
@@ -108,13 +108,13 @@ GenericClient::handle_response(
auto & value = *optional_pending_request;
if (std::holds_alternative<Promise>(value)) {
auto & promise = std::get<Promise>(value);
promise.set_value(response);
promise.set_value(std::move(response));
} else if (std::holds_alternative<CallbackTypeValueVariant>(value)) {
auto & inner = std::get<CallbackTypeValueVariant>(value);
const auto & callback = std::get<CallbackType>(inner);
auto & promise = std::get<Promise>(inner);
auto & future = std::get<SharedFuture>(inner);
promise.set_value(response);
promise.set_value(std::move(response));
callback(std::move(future));
}
}
@@ -164,7 +164,7 @@ GenericClient::get_and_erase_pending_request(int64_t request_number)
}
GenericClient::FutureAndRequestId
GenericClient::async_send_request(const Request & request)
GenericClient::async_send_request(const Request request)
{
Promise promise;
auto future = promise.get_future();
@@ -175,7 +175,7 @@ GenericClient::async_send_request(const Request & request)
}
int64_t
GenericClient::async_send_request_impl(const Request & request, CallbackInfoVariant value)
GenericClient::async_send_request_impl(const Request request, CallbackInfoVariant value)
{
int64_t sequence_number;
std::lock_guard<std::mutex> lock(pending_requests_mutex_);

View File

@@ -17,13 +17,13 @@
namespace rclcpp
{
GenericService::GenericService(
const std::shared_ptr<rcl_node_t> & node_handle,
std::shared_ptr<rcl_node_t> node_handle,
const std::string & service_name,
const std::string & service_type,
GenericServiceCallback any_callback,
rcl_service_options_t & service_options)
: ServiceBase(node_handle),
any_callback_(std::move(any_callback))
any_callback_(any_callback)
{
const rosidl_service_type_support_t * service_ts;
try {
@@ -98,7 +98,7 @@ GenericService::GenericService(
bool
GenericService::take_request(
SharedRequest & request_out,
SharedRequest request_out,
rmw_request_id_t & request_id_out)
{
request_out = create_request();
@@ -141,8 +141,8 @@ GenericService::create_request_header()
void
GenericService::handle_request(
const std::shared_ptr<rmw_request_id_t> & request_header,
const std::shared_ptr<void> & request)
std::shared_ptr<rmw_request_id_t> request_header,
std::shared_ptr<void> request)
{
auto response = any_callback_.dispatch(
this->shared_from_this(), request_header, request, create_response());

View File

@@ -37,30 +37,6 @@ GenericSubscription::create_serialized_message()
return std::make_shared<rclcpp::SerializedMessage>(0);
}
void
GenericSubscription::disable_callbacks()
{
SubscriptionBase::disable_callbacks();
any_callback_.disable();
for (const auto & [_, event_ptr] : event_handlers_) {
if (event_ptr) {
event_ptr->disable();
}
}
}
void
GenericSubscription::enable_callbacks()
{
SubscriptionBase::enable_callbacks();
any_callback_.enable();
for (const auto & [_, event_ptr] : event_handlers_) {
if (event_ptr) {
event_ptr->enable();
}
}
}
void
GenericSubscription::handle_message(
std::shared_ptr<void> &,

View File

@@ -19,6 +19,7 @@
#include <memory>
#include <string>
#include <vector>
#include "rcl/error_handling.h"
#include "rcl/types.h"
#include "rclcpp/detail/add_guard_condition_to_rcl_wait_set.hpp"
@@ -37,7 +38,8 @@ namespace graph_listener
{
GraphListener::GraphListener(const std::shared_ptr<Context> & parent_context)
: rcl_parent_context_(parent_context->get_rcl_context()),
: weak_parent_context_(parent_context),
rcl_parent_context_(parent_context->get_rcl_context()),
is_started_(false),
is_shutdown_(false),
interrupt_guard_condition_(parent_context)
@@ -70,11 +72,23 @@ void
GraphListener::start_if_not_started()
{
std::lock_guard<std::mutex> shutdown_lock(shutdown_mutex_);
if (is_shutdown()) {
if (is_shutdown_.load()) {
throw GraphListenerShutdownError();
}
if (!is_started()) {
auto parent_context = weak_parent_context_.lock();
if (!is_started_ && parent_context) {
// Register an on_shutdown hook to shtudown the graph listener.
// This is important to ensure that the wait set is finalized before
// destruction of static objects occurs.
std::weak_ptr<GraphListener> weak_this = shared_from_this();
parent_context->on_shutdown(
[weak_this]() {
auto shared_this = weak_this.lock();
if (shared_this) {
// should not throw from on_shutdown if it can be avoided
shared_this->shutdown(std::nothrow);
}
});
// Initialize the wait set before starting.
init_wait_set();
// Start the listener thread.
@@ -108,7 +122,7 @@ GraphListener::run_loop()
{
while (true) {
// If shutdown() was called, exit.
if (is_shutdown()) {
if (is_shutdown_.load()) {
return;
}
rcl_ret_t ret;
@@ -176,7 +190,7 @@ GraphListener::run_loop()
if (graph_gc == wait_set_.guard_conditions[graph_gc_indexes[i]]) {
node_ptr->notify_graph_change();
}
if (is_shutdown()) {
if (is_shutdown_) {
// If shutdown, then notify the node of this as well.
node_ptr->notify_shutdown();
}
@@ -243,7 +257,7 @@ GraphListener::add_node(rclcpp::node_interfaces::NodeGraphInterface * node_graph
throw std::invalid_argument("node is nullptr");
}
std::lock_guard<std::mutex> shutdown_lock(shutdown_mutex_);
if (is_shutdown()) {
if (is_shutdown_.load()) {
throw GraphListenerShutdownError();
}
@@ -318,11 +332,11 @@ GraphListener::__shutdown()
{
std::lock_guard<std::mutex> shutdown_lock(shutdown_mutex_);
if (!is_shutdown_.exchange(true)) {
if (is_started()) {
if (is_started_) {
interrupt_(&interrupt_guard_condition_);
listener_thread_.join();
}
if (is_started()) {
if (is_started_) {
cleanup_wait_set();
}
}
@@ -351,12 +365,6 @@ GraphListener::shutdown(const std::nothrow_t &) noexcept
}
}
bool
GraphListener::is_started()
{
return is_started_;
}
bool
GraphListener::is_shutdown()
{

View File

@@ -112,7 +112,7 @@ GuardCondition::add_to_wait_set(rcl_wait_set_t & wait_set)
}
void
GuardCondition::set_on_trigger_callback(const std::function<void(size_t)> & callback)
GuardCondition::set_on_trigger_callback(std::function<void(size_t)> callback)
{
std::lock_guard<std::recursive_mutex> lock(reentrant_mutex_);

View File

@@ -33,8 +33,8 @@ IntraProcessManager::~IntraProcessManager()
uint64_t
IntraProcessManager::add_publisher(
const rclcpp::PublisherBase::SharedPtr & publisher,
const rclcpp::experimental::buffers::IntraProcessBufferBase::SharedPtr & buffer)
rclcpp::PublisherBase::SharedPtr publisher,
rclcpp::experimental::buffers::IntraProcessBufferBase::SharedPtr buffer)
{
std::unique_lock<std::shared_timed_mutex> lock(mutex_);
@@ -51,9 +51,6 @@ IntraProcessManager::add_publisher(
}
}
// Add GID to publisher info mapping for fast lookups (stores both ID and weak_ptr)
gid_to_publisher_info_[publisher->get_gid()] = {pub_id, publisher};
// Initialize the subscriptions storage for this publisher.
pub_to_subs_[pub_id] = SplittedSubscriptions();
@@ -101,24 +98,6 @@ IntraProcessManager::remove_publisher(uint64_t intra_process_publisher_id)
{
std::unique_lock<std::shared_timed_mutex> lock(mutex_);
// Remove GID to publisher info mapping.
// First try via the publisher's own GID (fast path).
auto pub_it = publishers_.find(intra_process_publisher_id);
if (pub_it != publishers_.end()) {
auto publisher = pub_it->second.lock();
if (publisher) {
gid_to_publisher_info_.erase(publisher->get_gid());
} else {
// Publisher weak_ptr already expired, fall back to linear scan by pub_id.
for (auto git = gid_to_publisher_info_.begin(); git != gid_to_publisher_info_.end(); ++git) {
if (git->second.pub_id == intra_process_publisher_id) {
gid_to_publisher_info_.erase(git);
break;
}
}
}
}
publishers_.erase(intra_process_publisher_id);
publisher_buffers_.erase(intra_process_publisher_id);
pub_to_subs_.erase(intra_process_publisher_id);
@@ -129,15 +108,16 @@ IntraProcessManager::matches_any_publishers(const rmw_gid_t * id) const
{
std::shared_lock<std::shared_timed_mutex> lock(mutex_);
// Single O(1) hash map lookup - struct contains both ID and weak_ptr
auto it = gid_to_publisher_info_.find(*id);
if (it == gid_to_publisher_info_.end()) {
return false;
for (auto & publisher_pair : publishers_) {
auto publisher = publisher_pair.second.lock();
if (!publisher) {
continue;
}
if (*publisher.get() == id) {
return true;
}
}
// Verify the publisher still exists by checking the weak_ptr
auto publisher = it->second.publisher.lock();
return publisher != nullptr;
return false;
}
size_t
@@ -217,8 +197,8 @@ IntraProcessManager::insert_sub_id_for_pub(
bool
IntraProcessManager::can_communicate(
const rclcpp::PublisherBase::SharedPtr & pub,
const rclcpp::experimental::SubscriptionIntraProcessBase::SharedPtr & sub) const
rclcpp::PublisherBase::SharedPtr pub,
rclcpp::experimental::SubscriptionIntraProcessBase::SharedPtr sub) const
{
// publisher and subscription must be on the same topic
if (strcmp(pub->get_topic_name(), sub->get_topic_name()) != 0) {

View File

@@ -55,6 +55,34 @@ get_node_logger(const rcl_node_t * node)
return rclcpp::get_logger(logger_name);
}
// TODO(ahcorde): Remove deprecated class on the next release (in Rolling after Kilted).
#if !defined(_WIN32)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#else // !defined(_WIN32)
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
rcpputils::fs::path
get_logging_directory()
{
char * log_dir = NULL;
auto allocator = rcutils_get_default_allocator();
rcl_logging_ret_t ret = rcl_logging_get_logging_directory(allocator, &log_dir);
if (RCL_LOGGING_RET_OK != ret) {
rclcpp::exceptions::throw_from_rcl_error(ret);
}
std::string path{log_dir};
allocator.deallocate(log_dir, allocator.state);
return path;
}
// remove warning suppression
#if !defined(_WIN32)
# pragma GCC diagnostic pop
#else // !defined(_WIN32)
# pragma warning(pop)
#endif
std::filesystem::path
get_log_directory()
{

View File

@@ -547,18 +547,6 @@ Node::get_subscriptions_info_by_topic(const std::string & topic_name, bool no_ma
return node_graph_->get_subscriptions_info_by_topic(topic_name, no_mangle);
}
std::vector<rclcpp::ServiceEndpointInfo>
Node::get_clients_info_by_service(const std::string & service_name, bool no_mangle) const
{
return node_graph_->get_clients_info_by_service(service_name, no_mangle);
}
std::vector<rclcpp::ServiceEndpointInfo>
Node::get_servers_info_by_service(const std::string & service_name, bool no_mangle) const
{
return node_graph_->get_servers_info_by_service(service_name, no_mangle);
}
void
Node::for_each_callback_group(
const node_interfaces::NodeBaseInterface::CallbackGroupFunction & func)
@@ -574,7 +562,7 @@ Node::get_graph_event()
void
Node::wait_for_graph_change(
const rclcpp::Event::SharedPtr & event,
rclcpp::Event::SharedPtr event,
std::chrono::nanoseconds timeout)
{
node_graph_->wait_for_graph_change(event, timeout);
@@ -695,7 +683,7 @@ Node::create_generic_client(
const std::string & service_name,
const std::string & service_type,
const rclcpp::QoS & qos,
const rclcpp::CallbackGroup::SharedPtr & group)
rclcpp::CallbackGroup::SharedPtr group)
{
return rclcpp::create_generic_client(
node_base_,

View File

@@ -42,13 +42,13 @@ NodeBase::NodeBase(
bool use_intra_process_default,
bool enable_topic_statistics_default,
rclcpp::CallbackGroup::SharedPtr default_callback_group)
: context_(std::move(context)),
: context_(context),
use_intra_process_default_(use_intra_process_default),
enable_topic_statistics_default_(enable_topic_statistics_default),
node_handle_(nullptr),
default_callback_group_(std::move(default_callback_group)),
default_callback_group_(default_callback_group),
associated_with_executor_(false),
notify_guard_condition_(std::make_shared<rclcpp::GuardCondition>(context_)),
notify_guard_condition_(std::make_shared<rclcpp::GuardCondition>(context)),
notify_guard_condition_is_valid_(false)
{
// Create the rcl node and store it in a shared_ptr with a custom destructor.
@@ -275,6 +275,16 @@ NodeBase::get_associated_with_executor_atomic()
return associated_with_executor_;
}
rclcpp::GuardCondition &
NodeBase::get_notify_guard_condition()
{
std::lock_guard<std::recursive_mutex> notify_condition_lock(notify_guard_condition_mutex_);
if (!notify_guard_condition_is_valid_) {
throw std::runtime_error("failed to get notify guard condition because it is invalid");
}
return *notify_guard_condition_;
}
rclcpp::GuardCondition::SharedPtr
NodeBase::get_shared_notify_guard_condition()
{

View File

@@ -26,11 +26,11 @@ NodeClock::NodeClock(
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services,
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
rcl_clock_type_t clock_type)
: node_base_(std::move(node_base)),
node_topics_(std::move(node_topics)),
node_graph_(std::move(node_graph)),
node_services_(std::move(node_services)),
node_logging_(std::move(node_logging)),
: node_base_(node_base),
node_topics_(node_topics),
node_graph_(node_graph),
node_services_(node_services),
node_logging_(node_logging),
clock_(std::make_shared<rclcpp::Clock>(clock_type))
{}

View File

@@ -15,7 +15,6 @@
#include "rclcpp/node_interfaces/node_graph.hpp"
#include <algorithm>
#include <cstddef>
#include <map>
#include <string>
#include <tuple>
@@ -37,6 +36,9 @@ using rclcpp::graph_listener::GraphListener;
NodeGraph::NodeGraph(rclcpp::node_interfaces::NodeBaseInterface * node_base)
: node_base_(node_base),
graph_listener_(
node_base->get_context()->get_sub_context<GraphListener>(node_base->get_context())
),
should_add_to_graph_listener_(true),
graph_users_count_(0)
{}
@@ -48,7 +50,7 @@ NodeGraph::~NodeGraph()
// graph listener after checking that it was not here.
if (!should_add_to_graph_listener_.exchange(false)) {
// If it was already false, then it needs to now be removed.
node_base_->get_context()->get_graph_listener()->remove_node(this);
graph_listener_->remove_node(this);
}
}
@@ -417,7 +419,7 @@ NodeGraph::get_node_names_and_namespaces() const
rcl_get_error_string().str;
rcl_reset_error();
}
RCUTILS_LOG_ERROR_NAMED("rclcpp", "%s", error_msg.c_str());
// TODO(karsten1987): Append rcutils_error_message once it's in master
throw std::runtime_error(error_msg);
}
@@ -432,15 +434,20 @@ NodeGraph::get_node_names_and_namespaces() const
std::string error;
rcl_ret_t ret_names = rcutils_string_array_fini(&node_names_c);
if (ret_names != RCUTILS_RET_OK) {
error = std::string("could not destroy node names: ") + rcl_get_error_string().str;
// *INDENT-OFF*
// TODO(karsten1987): Append rcutils_error_message once it's in master
error = "could not destroy node names";
// *INDENT-ON*
}
rcl_ret_t ret_ns = rcutils_string_array_fini(&node_namespaces_c);
if (ret_ns != RCUTILS_RET_OK) {
error += std::string(", could not destroy node namespaces: ") + rcl_get_error_string().str;
// *INDENT-OFF*
// TODO(karsten1987): Append rcutils_error_message once it's in master
error += ", could not destroy node namespaces";
// *INDENT-ON*
}
if (ret_names != RCUTILS_RET_OK || ret_ns != RCUTILS_RET_OK) {
RCUTILS_LOG_ERROR_NAMED("rclcpp", "%s", error.c_str());
throw std::runtime_error(error);
}
@@ -596,8 +603,8 @@ NodeGraph::get_graph_event()
}
// on first call, add node to graph_listener_
if (should_add_to_graph_listener_.exchange(false)) {
node_base_->get_context()->get_graph_listener()->add_node(this);
node_base_->get_context()->get_graph_listener()->start_if_not_started();
graph_listener_->add_node(this);
graph_listener_->start_if_not_started();
}
return event;
}
@@ -645,9 +652,8 @@ std::vector<rclcpp::TopicEndpointInfo>
convert_to_topic_info_list(const rcl_topic_endpoint_info_array_t & info_array)
{
std::vector<rclcpp::TopicEndpointInfo> topic_info_list;
topic_info_list.reserve(info_array.size);
for (size_t i = 0; i < info_array.size; ++i) {
topic_info_list.emplace_back(info_array.info_array[i]);
topic_info_list.push_back(rclcpp::TopicEndpointInfo(info_array.info_array[i]));
}
return topic_info_list;
}
@@ -755,123 +761,6 @@ NodeGraph::get_subscriptions_info_by_topic(
rcl_get_subscriptions_info_by_topic);
}
static
std::vector<rclcpp::ServiceEndpointInfo>
convert_to_service_info_list(const rcl_service_endpoint_info_array_t & info_array)
{
std::vector<rclcpp::ServiceEndpointInfo> service_info_list;
service_info_list.reserve(info_array.size);
for (size_t i = 0; i < info_array.size; ++i) {
service_info_list.emplace_back(info_array.info_array[i]);
}
return service_info_list;
}
template<const char * EndpointType, typename FunctionT>
static std::vector<rclcpp::ServiceEndpointInfo>
get_info_by_service(
rclcpp::node_interfaces::NodeBaseInterface * node_base,
const std::string & service_name,
bool no_mangle,
FunctionT rcl_get_info_by_service)
{
std::string fqdn;
auto rcl_node_handle = node_base->get_rcl_node_handle();
if (no_mangle) {
fqdn = service_name;
} else {
fqdn = rclcpp::expand_topic_or_service_name(
service_name,
rcl_node_get_name(rcl_node_handle),
rcl_node_get_namespace(rcl_node_handle),
true);
// Get the node options
const rcl_node_options_t * node_options = rcl_node_get_options(rcl_node_handle);
if (nullptr == node_options) {
throw std::runtime_error("Need valid node options in get_info_by_service()");
}
const rcl_arguments_t * global_args = nullptr;
if (node_options->use_global_arguments) {
global_args = &(rcl_node_handle->context->global_arguments);
}
char * remapped_service_name = nullptr;
rcl_ret_t ret = rcl_remap_service_name(
&(node_options->arguments),
global_args,
fqdn.c_str(),
rcl_node_get_name(rcl_node_handle),
rcl_node_get_namespace(rcl_node_handle),
node_options->allocator,
&remapped_service_name);
if (RCL_RET_OK != ret) {
throw_from_rcl_error(ret, std::string("Failed to remap service name ") + fqdn);
} else if (nullptr != remapped_service_name) {
fqdn = remapped_service_name;
node_options->allocator.deallocate(remapped_service_name, node_options->allocator.state);
}
}
rcutils_allocator_t allocator = rcutils_get_default_allocator();
rcl_service_endpoint_info_array_t info_array =
rcl_get_zero_initialized_service_endpoint_info_array();
rcl_ret_t ret =
rcl_get_info_by_service(rcl_node_handle, &allocator, fqdn.c_str(), no_mangle, &info_array);
if (RCL_RET_OK != ret) {
auto error_msg =
std::string("Failed to get information by service for ") + EndpointType + std::string(":");
if (RCL_RET_UNSUPPORTED == ret) {
error_msg += std::string("function not supported by RMW_IMPLEMENTATION");
} else {
error_msg += rcl_get_error_string().str;
}
rcl_reset_error();
if (RCL_RET_OK != rcl_service_endpoint_info_array_fini(&info_array, &allocator)) {
error_msg += std::string(", failed also to cleanup service info array, leaking memory: ") +
rcl_get_error_string().str;
rcl_reset_error();
}
throw_from_rcl_error(ret, error_msg);
}
std::vector<rclcpp::ServiceEndpointInfo> service_info_list =
convert_to_service_info_list(info_array);
ret = rcl_service_endpoint_info_array_fini(&info_array, &allocator);
if (RCL_RET_OK != ret) {
throw_from_rcl_error(ret, "rcl_service_info_array_fini failed.");
}
return service_info_list;
}
static constexpr char kClientEndpointTypeName[] = "clients";
std::vector<rclcpp::ServiceEndpointInfo>
NodeGraph::get_clients_info_by_service(
const std::string & service_name,
bool no_mangle) const
{
return get_info_by_service<kClientEndpointTypeName>(
node_base_,
service_name,
no_mangle,
rcl_get_clients_info_by_service);
}
static constexpr char kServerEndpointTypeName[] = "servers";
std::vector<rclcpp::ServiceEndpointInfo>
NodeGraph::get_servers_info_by_service(
const std::string & service_name,
bool no_mangle) const
{
return get_info_by_service<kServerEndpointTypeName>(
node_base_,
service_name,
no_mangle,
rcl_get_servers_info_by_service);
}
std::string &
rclcpp::TopicEndpointInfo::node_name()
{
@@ -955,99 +844,3 @@ rclcpp::TopicEndpointInfo::topic_type_hash() const
{
return topic_type_hash_;
}
std::string &
rclcpp::ServiceEndpointInfo::node_name()
{
return node_name_;
}
const std::string &
rclcpp::ServiceEndpointInfo::node_name() const
{
return node_name_;
}
std::string &
rclcpp::ServiceEndpointInfo::node_namespace()
{
return node_namespace_;
}
const std::string &
rclcpp::ServiceEndpointInfo::node_namespace() const
{
return node_namespace_;
}
std::string &
rclcpp::ServiceEndpointInfo::service_type()
{
return service_type_;
}
const std::string &
rclcpp::ServiceEndpointInfo::service_type() const
{
return service_type_;
}
rclcpp::EndpointType &
rclcpp::ServiceEndpointInfo::endpoint_type()
{
return endpoint_type_;
}
const rclcpp::EndpointType &
rclcpp::ServiceEndpointInfo::endpoint_type() const
{
return endpoint_type_;
}
size_t &
rclcpp::ServiceEndpointInfo::endpoint_count()
{
return endpoint_count_;
}
const size_t &
rclcpp::ServiceEndpointInfo::endpoint_count() const
{
return endpoint_count_;
}
std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> &
rclcpp::ServiceEndpointInfo::endpoint_gids()
{
return endpoint_gids_;
}
const std::vector<std::array<uint8_t, RMW_GID_STORAGE_SIZE>> &
rclcpp::ServiceEndpointInfo::endpoint_gids() const
{
return endpoint_gids_;
}
std::vector<rclcpp::QoS> &
rclcpp::ServiceEndpointInfo::qos_profiles()
{
return qos_profiles_;
}
const std::vector<rclcpp::QoS> &
rclcpp::ServiceEndpointInfo::qos_profiles() const
{
return qos_profiles_;
}
rosidl_type_hash_t &
rclcpp::ServiceEndpointInfo::service_type_hash()
{
return service_type_hash_;
}
const rosidl_type_hash_t &
rclcpp::ServiceEndpointInfo::service_type_hash() const
{
return service_type_hash_;
}

View File

@@ -18,7 +18,7 @@
using rclcpp::node_interfaces::NodeLogging;
NodeLogging::NodeLogging(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_base)
NodeLogging::NodeLogging(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base)
: node_base_(node_base)
{
logger_ = rclcpp::get_logger(NodeLogging::get_logger_name());
@@ -41,7 +41,7 @@ NodeLogging::get_logger_name() const
}
void NodeLogging::create_logger_services(
const node_interfaces::NodeServicesInterface::SharedPtr & node_services)
node_interfaces::NodeServicesInterface::SharedPtr node_services)
{
rclcpp::ServicesQoS qos_profile;
const std::string node_name = node_base_->get_name();
@@ -51,8 +51,8 @@ void NodeLogging::create_logger_services(
node_base_, node_services,
node_name + "/get_logger_levels",
[](
const std::shared_ptr<rmw_request_id_t> &,
const std::shared_ptr<rcl_interfaces::srv::GetLoggerLevels::Request> & request,
const std::shared_ptr<rmw_request_id_t>,
const std::shared_ptr<rcl_interfaces::srv::GetLoggerLevels::Request> request,
std::shared_ptr<rcl_interfaces::srv::GetLoggerLevels::Response> response)
{
for (auto & name : request->names) {
@@ -73,8 +73,8 @@ void NodeLogging::create_logger_services(
node_base_, node_services,
node_name + "/set_logger_levels",
[](
const std::shared_ptr<rmw_request_id_t> &,
const std::shared_ptr<rcl_interfaces::srv::SetLoggerLevels::Request> & request,
const std::shared_ptr<rmw_request_id_t>,
const std::shared_ptr<rcl_interfaces::srv::SetLoggerLevels::Request> request,
std::shared_ptr<rcl_interfaces::srv::SetLoggerLevels::Response> response)
{
rcl_interfaces::msg::SetLoggerLevelsResult result;

View File

@@ -192,65 +192,6 @@ format_range_reason(const std::string & name, const char * range_type)
return ss.str();
}
RCLCPP_LOCAL
rcl_interfaces::msg::SetParametersResult
__check_integer_range(
const rcl_interfaces::msg::ParameterDescriptor & descriptor,
const int64_t value)
{
rcl_interfaces::msg::SetParametersResult result;
result.successful = true;
auto integer_range = descriptor.integer_range.at(0);
if (value == integer_range.from_value || value == integer_range.to_value) {
return result;
}
if ((value < integer_range.from_value) || (value > integer_range.to_value)) {
result.successful = false;
result.reason = format_range_reason(descriptor.name, "integer");
return result;
}
if (integer_range.step == 0) {
return result;
}
if (((value - integer_range.from_value) % integer_range.step) == 0) {
return result;
}
result.successful = false;
result.reason = format_range_reason(descriptor.name, "integer");
return result;
}
RCLCPP_LOCAL
rcl_interfaces::msg::SetParametersResult
__check_double_range(
const rcl_interfaces::msg::ParameterDescriptor & descriptor,
const double value)
{
rcl_interfaces::msg::SetParametersResult result;
result.successful = true;
auto fp_range = descriptor.floating_point_range.at(0);
if (__are_doubles_equal(value, fp_range.from_value) || __are_doubles_equal(value,
fp_range.to_value))
{
return result;
}
if ((value < fp_range.from_value) || (value > fp_range.to_value)) {
result.successful = false;
result.reason = format_range_reason(descriptor.name, "floating point");
return result;
}
if (fp_range.step == 0.0) {
return result;
}
double rounded_div = std::round((value - fp_range.from_value) / fp_range.step);
if (__are_doubles_equal(value, fp_range.from_value + rounded_div * fp_range.step)) {
return result;
}
result.successful = false;
result.reason = format_range_reason(descriptor.name, "floating point");
return result;
}
RCLCPP_LOCAL
rcl_interfaces::msg::SetParametersResult
__check_parameter_value_in_range(
@@ -260,39 +201,49 @@ __check_parameter_value_in_range(
rcl_interfaces::msg::SetParametersResult result;
result.successful = true;
if (!descriptor.integer_range.empty() && value.get_type() == rclcpp::PARAMETER_INTEGER) {
result = __check_integer_range(descriptor, value.get<int64_t>());
return result;
}
if (!descriptor.integer_range.empty() && value.get_type() == rclcpp::PARAMETER_INTEGER_ARRAY) {
std::vector<int64_t> val_array = value.get<std::vector<int64_t>>();
for (const int64_t & val : val_array) {
result = __check_integer_range(descriptor, val);
if (!result.successful) {
return result;
}
int64_t v = value.get<int64_t>();
auto integer_range = descriptor.integer_range.at(0);
if (v == integer_range.from_value || v == integer_range.to_value) {
return result;
}
if ((v < integer_range.from_value) || (v > integer_range.to_value)) {
result.successful = false;
result.reason = format_range_reason(descriptor.name, "integer");
return result;
}
if (integer_range.step == 0) {
return result;
}
if (((v - integer_range.from_value) % integer_range.step) == 0) {
return result;
}
result.successful = false;
result.reason = format_range_reason(descriptor.name, "integer");
return result;
}
if (!descriptor.floating_point_range.empty() && value.get_type() == rclcpp::PARAMETER_DOUBLE) {
result = __check_double_range(descriptor, value.get<double>());
return result;
}
if (!descriptor.floating_point_range.empty() &&
value.get_type() == rclcpp::PARAMETER_DOUBLE_ARRAY)
{
std::vector<double> val_array = value.get<std::vector<double>>();
for (const double & val : val_array) {
result = __check_double_range(descriptor, val);
if (!result.successful) {
return result;
}
double v = value.get<double>();
auto fp_range = descriptor.floating_point_range.at(0);
if (__are_doubles_equal(v, fp_range.from_value) || __are_doubles_equal(v, fp_range.to_value)) {
return result;
}
if ((v < fp_range.from_value) || (v > fp_range.to_value)) {
result.successful = false;
result.reason = format_range_reason(descriptor.name, "floating point");
return result;
}
if (fp_range.step == 0.0) {
return result;
}
double rounded_div = std::round((v - fp_range.from_value) / fp_range.step);
if (__are_doubles_equal(v, fp_range.from_value + rounded_div * fp_range.step)) {
return result;
}
result.successful = false;
result.reason = format_range_reason(descriptor.name, "floating point");
return result;
}
return result;
}

View File

@@ -29,13 +29,13 @@ NodeTimeSource::NodeTimeSource(
rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters,
const rclcpp::QoS & qos,
bool use_clock_thread)
: node_base_(std::move(node_base)),
node_topics_(std::move(node_topics)),
node_graph_(std::move(node_graph)),
node_services_(std::move(node_services)),
node_logging_(std::move(node_logging)),
node_clock_(std::move(node_clock)),
node_parameters_(std::move(node_parameters)),
: node_base_(node_base),
node_topics_(node_topics),
node_graph_(node_graph),
node_services_(node_services),
node_logging_(node_logging),
node_clock_(node_clock),
node_parameters_(node_parameters),
time_source_(qos, use_clock_thread)
{
time_source_.attachNode(

View File

@@ -59,11 +59,11 @@ public:
NodeTypeDescriptionsImpl(
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr & node_logging,
const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & node_parameters,
const rclcpp::node_interfaces::NodeServicesInterface::SharedPtr & node_services)
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters,
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services)
: logger_(node_logging->get_logger()),
node_base_(std::move(node_base))
node_base_(node_base)
{
rclcpp::ParameterValue enable_param;
const std::string enable_param_name = "start_type_description_service";
@@ -92,7 +92,7 @@ public:
}
if (enable_param.get<bool>()) {
auto * rcl_node = node_base_->get_rcl_node_handle();
auto * rcl_node = node_base->get_rcl_node_handle();
std::shared_ptr<rcl_service_t> rcl_srv(
new rcl_service_t,
[rcl_node, logger = this->logger_](rcl_service_t * service)
@@ -121,9 +121,9 @@ public:
rclcpp::AnyServiceCallback<ServiceT> cb;
cb.set(
[this](
const std::shared_ptr<rmw_request_id_t> & header,
const std::shared_ptr<ServiceT::Request> & request,
const std::shared_ptr<ServiceT::Response> & response
std::shared_ptr<rmw_request_id_t> header,
std::shared_ptr<ServiceT::Request> request,
std::shared_ptr<ServiceT::Response> response
) {
rcl_node_type_description_service_handle_request(
node_base_->get_rcl_node_handle(),
@@ -144,10 +144,10 @@ public:
};
NodeTypeDescriptions::NodeTypeDescriptions(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_base,
const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr & node_logging,
const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & node_parameters,
const rclcpp::node_interfaces::NodeServicesInterface::SharedPtr & node_services)
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters,
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services)
: impl_(new NodeTypeDescriptionsImpl(
node_base,
node_logging,

View File

@@ -143,7 +143,7 @@ NodeOptions::context() const
}
NodeOptions &
NodeOptions::context(const rclcpp::Context::SharedPtr & context)
NodeOptions::context(rclcpp::Context::SharedPtr context)
{
this->context_ = context;
return *this;

View File

@@ -30,13 +30,13 @@ using rclcpp::AsyncParametersClient;
using rclcpp::SyncParametersClient;
AsyncParametersClient::AsyncParametersClient(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_base_interface,
const rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr & node_topics_interface,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr & node_graph_interface,
const rclcpp::node_interfaces::NodeServicesInterface::SharedPtr & node_services_interface,
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_interface,
const rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_interface,
const rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph_interface,
const rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services_interface,
const std::string & remote_node_name,
const rclcpp::QoS & qos_profile,
const rclcpp::CallbackGroup::SharedPtr & group)
rclcpp::CallbackGroup::SharedPtr group)
: node_topics_interface_(node_topics_interface)
{
if (remote_node_name != "") {
@@ -107,9 +107,9 @@ AsyncParametersClient::AsyncParametersClient(
std::shared_future<std::vector<rclcpp::Parameter>>
AsyncParametersClient::get_parameters(
const std::vector<std::string> & names,
const std::function<
std::function<
void(std::shared_future<std::vector<rclcpp::Parameter>>)
> & callback)
> callback)
{
auto promise_result =
std::make_shared<std::promise<std::vector<rclcpp::Parameter>>>();
@@ -147,9 +147,9 @@ AsyncParametersClient::get_parameters(
std::shared_future<std::vector<rcl_interfaces::msg::ParameterDescriptor>>
AsyncParametersClient::describe_parameters(
const std::vector<std::string> & names,
const std::function<
std::function<
void(std::shared_future<std::vector<rcl_interfaces::msg::ParameterDescriptor>>)
> & callback)
> callback)
{
auto promise_result =
std::make_shared<std::promise<std::vector<rcl_interfaces::msg::ParameterDescriptor>>>();
@@ -176,9 +176,9 @@ AsyncParametersClient::describe_parameters(
std::shared_future<std::vector<rclcpp::ParameterType>>
AsyncParametersClient::get_parameter_types(
const std::vector<std::string> & names,
const std::function<
std::function<
void(std::shared_future<std::vector<rclcpp::ParameterType>>)
> & callback)
> callback)
{
auto promise_result =
std::make_shared<std::promise<std::vector<rclcpp::ParameterType>>>();
@@ -210,9 +210,9 @@ AsyncParametersClient::get_parameter_types(
std::shared_future<std::vector<rcl_interfaces::msg::SetParametersResult>>
AsyncParametersClient::set_parameters(
const std::vector<rclcpp::Parameter> & parameters,
const std::function<
std::function<
void(std::shared_future<std::vector<rcl_interfaces::msg::SetParametersResult>>)
> & callback)
> callback)
{
auto promise_result =
std::make_shared<std::promise<std::vector<rcl_interfaces::msg::SetParametersResult>>>();
@@ -243,9 +243,9 @@ AsyncParametersClient::set_parameters(
std::shared_future<rcl_interfaces::msg::SetParametersResult>
AsyncParametersClient::set_parameters_atomically(
const std::vector<rclcpp::Parameter> & parameters,
const std::function<
std::function<
void(std::shared_future<rcl_interfaces::msg::SetParametersResult>)
> & callback)
> callback)
{
auto promise_result =
std::make_shared<std::promise<rcl_interfaces::msg::SetParametersResult>>();
@@ -322,9 +322,9 @@ std::shared_future<rcl_interfaces::msg::ListParametersResult>
AsyncParametersClient::list_parameters(
const std::vector<std::string> & prefixes,
uint64_t depth,
const std::function<
std::function<
void(std::shared_future<rcl_interfaces::msg::ListParametersResult>)
> & callback)
> callback)
{
auto promise_result =
std::make_shared<std::promise<rcl_interfaces::msg::ListParametersResult>>();

View File

@@ -1,97 +0,0 @@
// Copyright 2023 Open Source Robotics Foundation, Inc.
//
// 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 "rclcpp/parameter_descriptor_wrapper.hpp"
namespace rclcpp
{
ParameterDescription::ParameterDescription()
{
// Need to set this in the constructor, but it doesn't necessarily need to be used
parameter_descriptor.type = rcl_interfaces::msg::ParameterType::PARAMETER_NOT_SET;
}
rcl_interfaces::msg::ParameterDescriptor ParameterDescription::build() const
{
// Return some some sort message
return parameter_descriptor;
}
// Builder methods which set up the original class
// They all follow the same format of initing the value given within the base class
// then returning the current class
ParameterDescription & ParameterDescription::set_name(const std::string & name)
{
parameter_descriptor.name = name;
return *this;
}
ParameterDescription & ParameterDescription::set_type(std::uint8_t type)
{
parameter_descriptor.type = type;
return *this;
}
ParameterDescription & ParameterDescription::set_description_text(const std::string & description)
{
parameter_descriptor.description = description;
return *this;
}
ParameterDescription & ParameterDescription::set_additional_constraints(
const std::string & constraints)
{
parameter_descriptor.additional_constraints = constraints;
return *this;
}
ParameterDescription & ParameterDescription::set_read_only(bool read_only)
{
parameter_descriptor.read_only = read_only;
return *this;
}
ParameterDescription & ParameterDescription::set_dynamic_typing(bool dynamic_typing)
{
parameter_descriptor.dynamic_typing = dynamic_typing;
return *this;
}
// Here is the Specific range function for this parameter description
ParameterDescription & ParameterDescription::set_floating_point_description_range(
float min, float max, float step)
{
if (parameter_descriptor.type == rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE) {
parameter_descriptor.floating_point_range.resize(1);
parameter_descriptor.floating_point_range.at(0).from_value = min;
parameter_descriptor.floating_point_range.at(0).to_value = max;
parameter_descriptor.floating_point_range.at(0).step = step;
}
return *this;
}
ParameterDescription & ParameterDescription::set_integer_description_range(
int min, int max, int step)
{
if (parameter_descriptor.type == rcl_interfaces::msg::ParameterType::PARAMETER_INTEGER) {
parameter_descriptor.integer_range.resize(1);
parameter_descriptor.integer_range.at(0).from_value = min;
parameter_descriptor.integer_range.at(0).to_value = max;
parameter_descriptor.integer_range.at(0).step = step;
}
return *this;
}
} // namespace rclcpp

View File

@@ -27,7 +27,7 @@ namespace rclcpp
ParameterEventCallbackHandle::SharedPtr
ParameterEventHandler::add_parameter_event_callback(
const ParameterEventCallbackType & callback)
ParameterEventCallbackType callback)
{
std::lock_guard<std::recursive_mutex> lock(callbacks_->mutex_);
auto handle = std::make_shared<ParameterEventCallbackHandle>();
@@ -39,7 +39,7 @@ ParameterEventHandler::add_parameter_event_callback(
void
ParameterEventHandler::remove_parameter_event_callback(
const ParameterEventCallbackHandle::SharedPtr & callback_handle)
ParameterEventCallbackHandle::SharedPtr callback_handle)
{
std::lock_guard<std::recursive_mutex> lock(callbacks_->mutex_);
auto it = std::find_if(
@@ -58,7 +58,7 @@ ParameterEventHandler::remove_parameter_event_callback(
ParameterCallbackHandle::SharedPtr
ParameterEventHandler::add_parameter_callback(
const std::string & parameter_name,
const ParameterCallbackType & callback,
ParameterCallbackType callback,
const std::string & node_name)
{
std::lock_guard<std::recursive_mutex> lock(callbacks_->mutex_);
@@ -74,41 +74,9 @@ ParameterEventHandler::add_parameter_callback(
return handle;
}
bool
ParameterEventHandler::configure_nodes_filter(const std::vector<std::string> & node_names)
{
if (node_names.empty()) {
// Clear content filter
event_subscription_->set_content_filter("");
if (event_subscription_->is_cft_enabled()) {
return false;
}
return true;
}
std::string filter_expression;
size_t total = node_names.size();
for (size_t i = 0; i < total; ++i) {
filter_expression += "node = %" + std::to_string(i);
if (i < total - 1) {
filter_expression += " OR ";
}
}
// Enclose each node name in "'".
std::vector<std::string> quoted_node_names;
for (const auto & name : node_names) {
quoted_node_names.push_back("'" + resolve_path(name) + "'");
}
event_subscription_->set_content_filter(filter_expression, quoted_node_names);
return event_subscription_->is_cft_enabled();
}
void
ParameterEventHandler::remove_parameter_callback(
const ParameterCallbackHandle::SharedPtr & callback_handle)
ParameterCallbackHandle::SharedPtr callback_handle)
{
std::lock_guard<std::recursive_mutex> lock(callbacks_->mutex_);
auto handle = callback_handle.get();

Some files were not shown because too many files have changed in this diff Show More