Compare commits

..

95 Commits

Author SHA1 Message Date
mergify[bot]
3a053fb46c Avoid unecessary creation of MultiThreadedExecutor (#3090) (#3096)
(cherry picked from commit 8cd4d47ec5)

Signed-off-by: solonovamax <solonovamax@12oclockpoint.com>
Co-authored-by: solo <solonovamax@12oclockpoint.com>
2026-03-13 12:58:13 +01:00
mergify[bot]
217e7a705c Fix component registering in subdirectories (#3064) (#3076)
(cherry picked from commit fc1afcb3bc)

Signed-off-by: pum1k <55055380+pum1k@users.noreply.github.com>
Co-authored-by: pum1k <55055380+pum1k@users.noreply.github.com>
2026-02-23 10:19:31 +01:00
mergify[bot]
b21707f2c9 fix: Use default rcl allocator if allocator is std::allocator (#3069) (#3072)
This fixes a bunch of warnings if using ASAN / valgrind on newer
OS versions. It also fixed a real bug, as giving the wrong size
on deallocate is undefined behavior according to the C++ standard.

This version of the patch keeps the behavior for users that
specified an own allocator the same and in therefore back portable.



(cherry picked from commit dc4a1dbbca)

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>
2026-02-19 10:01:41 +01:00
mergify[bot]
1f66148892 fix: Various data races in test cases (#3057) (#3063)
(cherry picked from commit 6ff4d83498)

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>
2026-02-13 09:48:27 +01:00
Alejandro Hernandez Cordero
035777622b 16.0.18 2026-02-09 15:02:40 +01:00
Alejandro Hernandez Cordero
a490ca1418 Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2026-02-09 15:02:35 +01:00
mergify[bot]
fea542a131 print warning message on owner node if the parameter operation fails. (backport #3037) (#3040)
* print warning message on owner node if the parameter operation fails. (#3037)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit f8a7ace7a8)

# Conflicts:
#	rclcpp/src/rclcpp/parameter_service.cpp

* resolve conflict.

Signed-off-by: Tomoya.Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya.Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2026-01-30 15:14:14 +01:00
mergify[bot]
78bc4734df fix context in wait for message wait set (#3030) (#3033)
(cherry picked from commit fcc505f453)

Signed-off-by: Rahat Dhande <rahatchd@gmail.com>
Co-authored-by: Rahat Dhande <rahatchd@gmail.com>
2026-01-23 09:44:31 +01:00
mergify[bot]
6040d745e7 Update exception documentation for goal cancellation in ServerGoalHandle (#3019) (#3024)
* Update exception documentation for goal cancellation

The documentation for the canceled function is misleading.
Previously, the description said:
1. "Only call this if the goal is canceling." and
2. "\throws rclcpp::exceptions::RCLError If the goal is in any state besides executing."
This is a contradiction.
Experimentally verified that if the goal is executing and this method is called, an error is thrown. This makes the second statement wrong => correct the statement in the documentation.


(cherry picked from commit 6397047d47)

Signed-off-by: Andrei Costinescu <AndreiCostinescu@users.noreply.github.com>
Co-authored-by: Andrei Costinescu <AndreiCostinescu@users.noreply.github.com>
2026-01-21 10:22:30 +01:00
mergify[bot]
66dbc789bc Improve the robustness of the TopicEndpointInfo constructor (backport #3013) (#3016)
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Barry Xu <barry.xu@sony.com>
Co-authored-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2026-01-13 12:34:19 +01:00
Alejandro Hernandez Cordero
41182a9720 16.0.17 2025-12-23 11:55:13 +01:00
Alejandro Hernandez Cordero
bc14074e3b Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-12-23 11:55:06 +01:00
mergify[bot]
c42bb23a52 Unified Node Interfaces: Add const version of get_node_x_interface() (#3006) (#3010)
(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:23:15 +01:00
fabianhirmann
4e834faf91 [Humble] Implement Unified Node Interface (NodeInterfaces class) (backport #2041) (#3002)
Signed-off-by: Fabian Hirmann <f.hirmann@arti-robots.com>
Co-authored-by: methylDragon <methylDragon@gmail.com>
Co-authored-by: William Woodall <william+github@osrfoundation.org>
2025-12-18 10:11:02 +01:00
mergify[bot]
2ba0b01d09 remove I/O from signal handler. (#3000) (#3005)
(cherry picked from commit 3ce946f6e9)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-12-08 10:57:51 +09:00
mergify[bot]
b6238def58 correct test function descriptions (backport #2970) (#2994)
* correct test function descriptions (#2970)

Signed-off-by: Yuchen Liu <lyuchen9696@gmail.com>
(cherry picked from commit 354413c060)

Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Yuchen966 <70603129+Yuchen966@users.noreply.github.com>
Co-authored-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-11-18 17:28:33 +01:00
Alejandro Hernandez Cordero
36d0aee198 16.0.16 2025-11-18 15:10:08 +01:00
Alejandro Hernandez Cordero
3c5631b4fe Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-11-18 15:10:02 +01:00
mergify[bot]
a9d1abe402 Fix REP url locations (backport #2987) (#2991)
* Fix REP url locations (#2987)

This popped up in my global replace

Signed-off-by: Tim Clephas <tim.clephas@nobleo.nl>
(cherry picked from commit ad019b9827)
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Tim Clephas <tim.clephas@nobleo.nl>
Co-authored-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-11-17 10:11:16 +01:00
mergify[bot]
e69382c357 Add get_parameter_or overload returning value or alternative (#2973) (#2978)
(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:55:37 +01:00
Alejandro Hernandez Cordero
632a41e6fa 16.0.15 2025-09-11 15:21:37 +02:00
Alejandro Hernandez Cordero
e41abc37f3 Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-09-11 15:21:33 +02:00
Peter Mitrano (AR)
81b628d4e6 Add a clearer warning message, the old one lacked information and was misleading (#2924)
Signed-off-by: Peter Mitrano (AR) <peter.mitrano@agile-robots.com>
2025-08-19 10:58:16 +02:00
mergify[bot]
443b69b6e1 Allow for implicitly convertable loggers as well (#2922) (#2936) (#2938)
(cherry picked from commit 8a4cb48b2c)

Signed-off-by: Tim Clephas <tim.clephas@nobleo.nl>
Co-authored-by: Tim Clephas <tim.clephas@nobleo.nl>
2025-08-19 09:33:14 +02:00
mergify[bot]
0036533e94 Fix: improve exception context for parameter_value_from (backport #2917) (#2921)
Signed-off-by: Michiel Leegwater <mleegwt@users.noreply.github.com>
Signed-off-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
Signed-off-by: Alejandro Hernandez 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 20:04:17 +02:00
mergify[bot]
76cdd45da3 Removed warning test_qos (#2859) (#2925)
(cherry picked from commit df3a303a17)

Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Signed-off-by: Crola1702 <cristobal.arroyo@ekumenlabs.com>
Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2025-08-07 11:35:53 -05:00
mergify[bot]
8e19cbaa14 Add qos parameter for wait_for_message function (#2903) (#2907)
(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 21:53:27 -07:00
Christophe Bedard
75b8684b86 16.0.14
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
2025-07-16 11:33:28 -07:00
Christophe Bedard
5a0c24c0dd Update changelogs
Signed-off-by: Christophe Bedard <bedard.christophe@gmail.com>
2025-07-16 11:33:05 -07:00
mergify[bot]
4a5bbfa42f fix test_publisher_with_system_default_qos. (backport #2881) (#2882)
* fix test_publisher_with_system_default_qos. (#2881)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit e6577c6792)

* intraprocess communication allowed only with volatile durability.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-07-10 13:27:40 -07:00
Alejandro Hernandez Cordero
5237763f7d 16.0.13 2025-06-23 16:57:35 +02:00
Alejandro Hernandez Cordero
6212355775 Changelog
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
2025-06-23 16:57:29 +02:00
keeponoiro
a0e2240ca3 Replace std::default_random_engine with std::mt19937 (humble) (#2847)
Signed-off-by: keeponoiro <keeeeeeep@gmail.com>
2025-05-30 13:01:54 -07:00
mergify[bot]
c4e82ddabb Fix for memory leaks in rclcpp::SerializedMessage (#2861) (#2865)
(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 10:43:20 +02:00
mergify[bot]
f43d4edc6b Added missing chrono includes (backport #2854) (#2857)
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2025-05-26 13:29:17 +02:00
mergify[bot]
53eed44771 QoSInitialization::from_rmw does not validate invalid history policy … (backport #2841) (#2844)
Signed-off-by: Alejandro Hernandez Cordero <ahcorde@gmail.com>
Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2025-05-19 16:02:59 +02:00
mergify[bot]
b6cd8393db throws std::invalid_argument if ParameterEvent is NULL. (#2814) (#2824)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit 8b9691f42d)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-05-01 11:15:09 -07:00
mergify[bot]
1b040e7df8 remove redundant typesupport check in serialization module (#2808) (#2816)
Signed-off-by: Tanishq Chaudhary <tanishqchaudhary101010@gmail.com>
(cherry picked from commit f78ed952b2)

Co-authored-by: Tanishq Chaudhary <tanishqchaudhary101010@gmail.com>
2025-04-15 09:40:57 +02:00
mergify[bot]
c751dfb76b should pull valid transition before trying to change the state. (backport #2774) (#2785)
* should pull valid transition before trying to change the state. (#2774)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit 7b6ee8a2e7)
2025-03-31 10:10:56 +02:00
mergify[bot]
493fe2b5d5 Harden rclcpp_action::convert(). (backport #2786) (#2788)
* Harden rclcpp_action::convert(). (#2786)

* Harden rclcpp_action::convert().

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* update docstring.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit ce86ef7e62)

# Conflicts:
#	rclcpp_action/src/types.cpp

* resolve conflicts.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2025-03-30 11:33:00 -07:00
Audrow Nash
6084057f89 16.0.12
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2025-03-25 08:19:47 -05:00
mergify[bot]
d3e6254ff1 doc: Added warning to not instantiate Clock directly with RCL_ROS_TIME (#2768) (#2770)
Signed-off-by: Janosch Machowinski <J.Machowinski@cellumation.com>
Signed-off-by: Janosch Machowinski <jmachowinski@users.noreply.github.com>
Co-authored-by: Janosch Machowinski <J.Machowinski@cellumation.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit 30e61c955d)

Co-authored-by: Janosch Machowinski <jmachowinski@users.noreply.github.com>
2025-03-14 17:25:09 -07:00
LihanChen2004
19773973a8 Redundant .c_str() usage in rclcpp_components triggers ament_clang_tidy warning (#2718)
* fix: Simplify string assignment for class name in node_main.cpp.in

Signed-off-by: LihanChen2004 <757003373@qq.com>

* Remove redundant local variable `name`

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Signed-off-by: LihanChen2004 <74599182+LihanChen2004@users.noreply.github.com>

---------

Signed-off-by: LihanChen2004 <757003373@qq.com>
Signed-off-by: LihanChen2004 <74599182+LihanChen2004@users.noreply.github.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-12-29 15:51:58 -08:00
mergify[bot]
99f1d8d124 apply actual QoS from rmw to the IPC publisher. (backport #2707) (#2711)
* apply actual QoS from rmw to the IPC publisher. (#2707)

* apply actual QoS from rmw to the IPC publisher.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* address uncrustify warning.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit 016cfeac99)

# Conflicts:
#	rclcpp/include/rclcpp/publisher.hpp

* resolve conflicts for backport humble.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* address uncrustify failure.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-12-16 21:51:50 -08:00
mergify[bot]
1a353f09c0 Adding in topic name to logging on IPC issues (#2706) (#2709)
* Adding in topic name to logging on IPC issues

Signed-off-by: Steve Macenski <stevenmacenski@gmail.com>

* Update test matching output logging

Signed-off-by: Steve Macenski <stevenmacenski@gmail.com>

* adding in single quotes

Signed-off-by: Steve Macenski <stevenmacenski@gmail.com>

---------

Signed-off-by: Steve Macenski <stevenmacenski@gmail.com>
(cherry picked from commit a13e16e2cb)

Co-authored-by: Steve Macenski <stevenmacenski@gmail.com>
2024-12-14 15:17:16 -08:00
Audrow Nash
e9edc3fda0 16.0.11
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2024-11-25 11:41:24 -06:00
Camilo Camacho
82ec3f000e fix: Fixed race condition in action server between is_ready and take. Backport from iron #2531 (#2635)
Signed-off-by: Camilo Camacho <camilo.im93@gmail.com>
Co-authored-by: Janosch Machowinski <J.Machowinski@cellumation.com>
2024-10-31 10:03:26 +01:00
roscan-tech
28de27e4ff Fix subscription.is_serialized() for callbacks with message info (#1950) (#2622)
* Fix subscription.is_serialized() for callbacks with message info argument

* Add tests + please linters

Signed-off-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
Signed-off-by: roscan-tech <liwei4402@mail2.sysu.edu.cn>
Co-authored-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
2024-10-07 10:49:43 -07:00
mergify[bot]
9be01cf400 Use the same context for the specified node in rclcpp::spin functions… (#2618) (#2620)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Signed-off-by: Kotaro Yoshimoto <pythagora.yoshimoto@gmail.com>
(cherry picked from commit 531b2b1a08)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-09-09 10:32:23 -07:00
Audrow Nash
e97d4e8616 16.0.10
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2024-07-26 10:14:48 -05:00
Tomoya Fujita
6737773a5d revert call shutdown in LifecycleNode destructor (Humble) (#2560)
* Revert "lifecycle node dtor shutdown should be called only in primary state. (#2544)"

This reverts commit 595badb55c.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* Revert "call shutdown in LifecycleNode dtor to avoid leaving the device in un… (#2450) (#2491)"

This reverts commit 0f9604d1b7.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-06-12 09:51:49 -07:00
mergify[bot]
32f19615bb Add test creating two content filter topics with the same topic name (#2546) (#2549) (#2551)
Signed-off-by: Mario-DL <mariodominguez@eprosima.com>
Co-authored-by: Mario Domínguez López <116071334+Mario-DL@users.noreply.github.com>
(cherry picked from commit 7c096888ca)

Co-authored-by: Alejandro Hernández Cordero <ahcorde@gmail.com>
2024-06-11 18:19:37 -07:00
Tomoya Fujita
595badb55c lifecycle node dtor shutdown should be called only in primary state. (#2544)
* lifecycle node dtor shutdown should be called only in primary state.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* LifecycleNode shutdown on dtor only with valid context. (#2545)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-06-06 11:04:38 -07:00
mergify[bot]
f95ac7cdda rclcpp::shutdown should not be called before LifecycleNode dtor. (backport #2527) (#2538)
* rclcpp::shutdown should not be called before LifecycleNode dtor. (#2527)

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit 22df1d593a)

# Conflicts:
#	rclcpp_lifecycle/test/test_lifecycle_publisher.cpp

* resolve conflicts.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-05-23 22:13:23 -07:00
Audrow Nash
844ab6b6c5 16.0.9
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2024-05-15 18:03:19 -05:00
mergify[bot]
ecf4ac4b2b Fix logging macros to build with msvc and cpp20 (#2063) (#2529)
Signed-off-by: Mateusz Szczygielski <mateusz.szczygielski@robotec.ai>

Signed-off-by: Mateusz Szczygielski <mateusz.szczygielski@robotec.ai>
(cherry picked from commit 86335dd4ac)

Co-authored-by: Mateusz Szczygielski <112629916+msz-rai@users.noreply.github.com>
2024-05-14 07:46:21 -07:00
mergify[bot]
058b54f7c7 Do not generate the exception when action service response timeout. (#2464) (#2518)
* Do not generate the exception when action service response timeout.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* address review comment.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit 6c7764e968)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-05-03 09:32:53 -07:00
mergify[bot]
0f9604d1b7 call shutdown in LifecycleNode dtor to avoid leaving the device in un… (#2450) (#2491)
* call shutdown in LifecycleNode dtor to avoid leaving the device in unknown state.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

* add test to verify LifecycleNode::shutdown is called on destructor.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit 04ea0bb002)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-04-07 14:59:24 -07:00
mergify[bot]
4fb589eea5 address ambiguous auto variable. (#2481) (#2485)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Signed-off-by: Steve Nogar <stephen.m.nogar.civ@army.mil>
(cherry picked from commit 3cdb25934e)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2024-04-04 16:59:30 -07:00
Tamaki Nishino
c1cfcb6880 Fix clang warning: bugprone-use-after-move (#2116) (#2459)
Signed-off-by: Mauro Passerino <mpasserino@irobot.com>
Signed-off-by: Tamaki Nishino <otamachan@gmail.com>
Co-authored-by: mauropasse <mauropasse@hotmail.com>
Co-authored-by: Mauro Passerino <mpasserino@irobot.com>
2024-03-29 08:25:53 -05:00
Audrow Nash
47c977d1bc 16.0.8
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2024-01-24 00:42:12 +00:00
mergify[bot]
3594381e04 Add missing header required by the rclcpp::NodeOptions type (#2324) (#2407)
Signed-off-by: Ignacio Vizzo <ignacio@dexory.com>
(cherry picked from commit d6bd8baac5)

Co-authored-by: Ignacio Vizzo <ignaciovizzo@gmail.com>
2024-01-18 08:39:18 -05:00
gentoo90
f279b707fe Add missing stdexcept include (#2186) (#2394)
Signed-off-by: Øystein Sture <os@skarvtech.com>
Signed-off-by: gentoo90 <gentoo90@gmail.com>
Co-authored-by: Øystein Sture <oysstu@users.noreply.github.com>
2023-12-20 19:49:31 -05:00
mergify[bot]
2c8d2aa453 fix(rclcpp_components): increase the service queue sizes in component_container (backport #2363) (#2380)
* fix(rclcpp_components): increase the service queue sizes in component_container (#2363)

* Use rmw_qos_profile_t.

Humble doesn't support create_service with the rclcpp::QoS object.

Signed-off-by: M. Fatih Cırıt <mfc@leodrive.ai>
(cherry picked from commit 9c098e544e)
Signed-off-by: Chris Lalancette <clalancette@gmail.com>
2023-12-01 17:05:03 -05:00
Audrow Nash
47712ecf58 16.0.7
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2023-11-13 21:57:33 +00:00
mergify[bot]
24f059c5aa Disable the loaned messages inside the executor. (backport #2335) (#2364)
* Disable the loaned messages inside the executor. (#2335)

* Disable the loaned messages inside the executor.

They are currently unsafe to use; see the comment in the
commit for more information.

Signed-off-by: Chris Lalancette <clalancette@gmail.com>
(cherry picked from commit f294488e17)
2023-11-10 09:00:03 -05:00
mergify[bot]
c1bf0d382e Add missing 'enable_rosout' comments (#2345) (#2347)
Signed-off-by: Jiaqi Li <ljq0831@qq.com>
(cherry picked from commit fff009a751)

Co-authored-by: Jiaqi Li <ljq0831@qq.com>
2023-10-31 08:17:51 -07:00
mergify[bot]
8709146df8 address rate related flaky tests. (#2329) (#2342)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit fcbe64cff4)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2023-10-26 07:45:47 -07:00
mergify[bot]
adfc546408 Update SignalHandler get_global_signal_handler to avoid complex types in static memory (#2316) (#2321)
* Update SignalHandler get_global_signal_handler to avoid complex types in static memory

This was flagged by msan as a problem.

There's a description of why this is a potential problem here: https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables

Signed-off-by: Tully Foote <tullyfoote@intrinsic.ai>
Co-authored-by: William Woodall <william+github@osrfoundation.org>
(cherry picked from commit 7c1143dc15)
2023-10-04 01:03:21 -07:00
mergify[bot]
37f38e30a9 Fix C++20 allocator construct deprecation (#2292) (#2319)
Signed-off-by: Guilherme Rodrigues <guilherme.rodrigues@ait.ac.at>
(cherry picked from commit fa732b9ee8)

Co-authored-by: AiVerisimilitude <133206333+AiVerisimilitude@users.noreply.github.com>
2023-09-27 15:50:23 -04:00
Audrow Nash
0f6b5449f6 16.0.6
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2023-09-19 13:39:23 +00:00
mergify[bot]
724b4588ec Topic correct typeadapter deduction (#2294) (#2297)
* fix TypeAdapter deduction

Signed-off-by: Chen Lihui <lihui.chen@sony.com>
(cherry picked from commit 5e152d77d8)

Co-authored-by: Chen Lihui <lihui.chen@sony.com>
2023-09-16 11:43:32 -07:00
mergify[bot]
2ae824e8e8 check thread whether joinable before join (#2019) (#2275)
Signed-off-by: uupks <uupks0325@gmail.com>
(cherry picked from commit b9b1468d15)

Co-authored-by: uupks <uupks0325@gmail.com>
2023-09-06 09:18:32 -04:00
mergify[bot]
689e510cf0 Do not crash Executor when send_response fails due to client failure. (#2276) (#2280)
* Do not crash Executor when send_response fails due to client failure.

Related to https://github.com/ros2/ros2/issues/1253

It is not sane that a faulty client can crash our service Executor, as
discussed in the referred issue, if the client is not setup properly,
send_response may return RCL_RET_TIMEOUT, we should not throw an error
in this case.

Signed-off-by: Zang MingJie <zealot0630@gmail.com>

* Update rclcpp/include/rclcpp/service.hpp

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Signed-off-by: Zang MingJie <zealot0630@gmail.com>

* address review comments.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>

---------

Signed-off-by: Zang MingJie <zealot0630@gmail.com>
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Zang MingJie <zealot0630@gmail.com>
(cherry picked from commit fbe8f28cd1)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2023-09-01 08:25:35 -07:00
Tony Najjar
ec4d00e405 Switch lifecycle to use the RCLCPP macros Signed-off-by: Tony Najjar <tony.najjar.1997@gmail.com> (#2234)
Signed-off-by: Tony Najjar <tony.najjar@logivations.com>
2023-07-24 12:59:20 +09:00
Audrow Nash
52327dd3a3 16.0.5
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2023-07-17 22:40:27 +00:00
Joseph Schornak
25263e838d Fix thread safety in LifecycleNode::get_current_state() for Humble (#2183)
* add initially-failing test case

* apply changes to LifecycleNodeInterfaceImpl from #1756

* add static member to State for managing state_handle_ access

* allow parallel read access in MutexMap

Signed-off-by: Joe Schornak <joe.schornak@gmail.com>
2023-06-26 20:46:58 -04:00
mergify[bot]
a75baa6b26 warning: comparison of integer expressions of different signedness (#2219) (#2223)
https://github.com/ros2/rclcpp/pull/2167#issuecomment-1597197552

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit fe2e0e4c64)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2023-06-23 13:00:14 -04:00
Tomoya Fujita
5f7485f4fd Trigger the intraprocess guard condition with data (#2164) (#2167)
If the intraprocess buffer still has data after taking, re-trigger the
guard condition to ensure that the executor will continue to service it,
even if incoming publications stop.

Signed-off-by: Michael Carroll <michael@openrobotics.org>
(cherry picked from commit 5f9695afb0)

Co-authored-by: Michael Carroll <michael@openrobotics.org>
2023-06-15 15:19:56 -07:00
mergify[bot]
613d192cd6 Implement validity checks for rclcpp::Clock (#2040) (#2210)
(cherry picked from commit c091fe1a45)

Co-authored-by: methylDragon <methylDragon@gmail.com>
2023-06-14 14:04:50 -07:00
Audrow Nash
00ef09cbf3 16.0.4
Signed-off-by: Audrow Nash <audrow@intrinsic.ai>
2023-04-25 20:55:32 +00:00
Tomoya Fujita
b2b7bdeac1 Revert "Revert "extract the result response before the callback is issued. (#2133)" (#2148)" (#2152)
This reverts commit 19a666f1c9.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2023-04-02 18:03:05 -07:00
Tomoya Fujita
19a666f1c9 Revert "extract the result response before the callback is issued. (#2133)" (#2148)
This reverts commit c8ac675035.

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2023-03-31 08:45:10 -07:00
Tomoya Fujita
c8ac675035 extract the result response before the callback is issued. (#2133)
backport of https://github.com/ros2/rclcpp/pull/2132

Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
Co-authored-by: Chen Lihui <lihui.chen@sony.com>
2023-03-30 08:43:03 -07:00
mergify[bot]
4196a2a8b4 use allocator via init_options argument. (#2129) (#2131)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
(cherry picked from commit 1a796b5515)

Co-authored-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
2023-03-20 13:36:32 -07:00
Audrow Nash
9171122eae 16.0.3
Signed-off-by: Audrow Nash <audrow@openrobotics.org>
2023-01-10 07:58:19 -06:00
mergify[bot]
ce13f1afba Fix SharedFuture from async_send_request never becomes valid (#2044) (#2076)
Signed-off-by: Lei Liu <Lei.Liu.AP@sony.com>
(cherry picked from commit 66b19448b0)

Co-authored-by: Lei Liu <64953129+llapx@users.noreply.github.com>
2023-01-06 10:19:33 -08:00
mergify[bot]
df08474d38 do not throw exception if trying to dequeue an empty intra-process buffer (#2061) (#2070)
Signed-off-by: Alberto Soragna <alberto.soragna@gmail.com>

Signed-off-by: Alberto Soragna <alberto.soragna@gmail.com>
(cherry picked from commit 3fb012e2e9)

Co-authored-by: Alberto Soragna <alberto.soragna@gmail.com>
2022-12-22 14:14:36 -08:00
mergify[bot]
f9050cd666 fix nullptr dereference in prune_requests_older_than (#2008) (#2065)
* fix nullptr dereference in prune_requests_older_than

Signed-off-by: akela1101 <akela1101@gmail.com>

* add tests for prune_requests_older_than

Signed-off-by: akela1101 <akela1101@gmail.com>

* Update rclcpp/test/rclcpp/test_client.cpp

Co-authored-by: Chen Lihui <lihui.chen@sony.com>
Signed-off-by: akela1101 <akela1101@gmail.com>

Signed-off-by: akela1101 <akela1101@gmail.com>
Co-authored-by: Chen Lihui <lihui.chen@sony.com>
(cherry picked from commit 1ac37b692c)

Co-authored-by: andrei <akela1101@gmail.com>
2022-12-13 15:40:16 -03:00
mergify[bot]
33cbd76c07 Fix bug that a callback not reached (#1640) (#2033)
* Add a test case

a subscriber on a new executor with a callback group triggered to receive a message

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* fix flaky and not to use spin_some

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* update comment

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* update for not using anti-pattern source code

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* add a notify guard condition for callback group

Co-authored-by: William Woodall <william@osrfoundation.org>
Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* Notify guard condition of Node not to be used in Executor

it is only for the waitset of GraphListener

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* put code in the try catch

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* defer to create guard condition

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* use context directly for the create function

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* cpplint

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* fix that some case might call add_node after shutdown

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* nitpick and fix some potential bug

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* add sanity check as some case might not create notify guard condition after shutdown

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* Cleanup includes.

Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>

* remove destroy method

make a callback group can only create one guard condition

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* remove limitation that guard condition can not be re-created in callback group

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

Signed-off-by: Chen Lihui <lihui.chen@sony.com>
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
Co-authored-by: William Woodall <william@osrfoundation.org>
Co-authored-by: Chris Lalancette <clalancette@openrobotics.org>
(cherry picked from commit d119157948)

Co-authored-by: Chen Lihui <lihui.chen@sony.com>
2022-11-09 22:16:14 -08:00
Audrow Nash
ae8b033ae0 16.0.2
Signed-off-by: Audrow Nash <audrow@openrobotics.org>
2022-11-07 09:12:14 -06:00
mergify[bot]
4fa3489cfd fix mismatched issue if using zero_allocate (#1995) (#2026)
* fix mismatched issue if uzing zero_allocated

Signed-off-by: Chen Lihui <lihui.chen@sony.com>
(cherry picked from commit 978439191f)

Co-authored-by: Chen Lihui <lihui.chen@sony.com>
2022-10-17 10:50:44 -07:00
mergify[bot]
7f575103d8 use regex for wildcard matching (backport #1839) (#1986)
* use regex for wildcard matching (#1839)

* use regex for wildcard matching

Co-authored-by: Aaron Lipinski <aaron.lipinski@roboticsplus.co.nz>
Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* use map to process the content of parameter file by order

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* add more test cases

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* try to not decrease the performance and make the param win last

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* update node name

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* update document comment

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

* add more test for parameter_map_from

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

Co-authored-by: Aaron Lipinski <aaron.lipinski@roboticsplus.co.nz>
(cherry picked from commit 6dd3a0377b)

* not to break ABI

Signed-off-by: Chen Lihui <lihui.chen@sony.com>

Signed-off-by: Chen Lihui <lihui.chen@sony.com>
Co-authored-by: Chen Lihui <lihui.chen@sony.com>
2022-09-09 11:55:00 -07:00
mergify[bot]
166007dde3 Drop wrong template specialization (#1926) (#1937)
This fails with g++ -std=gnu++20.

Signed-off-by: Jochen Sprickerhof <git@jochen.sprickerhof.de>
(cherry picked from commit 02802bcc38)

Co-authored-by: Jochen Sprickerhof <github@jochen.sprickerhof.de>
2022-06-15 15:02:18 -03:00
mergify[bot]
cf2a27805e Add statistics for handle_loaned_message (#1927) (#1932)
* Add statistics for handle_loaned_message

Signed-off-by: Barry Xu <barry.xu@sony.com>
(cherry picked from commit 5c688303b3)

Co-authored-by: Barry Xu <barry.xu@sony.com>
2022-06-09 08:54:15 -07:00
173 changed files with 3120 additions and 4571 deletions

View File

@@ -1,13 +0,0 @@
name: Mirror rolling to master
on:
push:
branches: [ rolling ]
jobs:
mirror-to-master:
runs-on: ubuntu-latest
steps:
- uses: zofrex/mirror-branch@v1
with:
target-branch: master

View File

@@ -1,2 +0,0 @@
# This file was generated by https://github.com/audrow/update-ros2-repos
* @ivanpauno @hidmic @wjwwood

View File

@@ -8,8 +8,7 @@ rclcpp provides the standard C++ API for interacting with ROS 2.
`#include "rclcpp/rclcpp.hpp"` allows use of the most common elements of the ROS 2 system.
The link to the latest API documentation can be found on the rclcpp package info page, at the [ROS Index](https://index.ros.org/p/rclcpp/).
Visit the [rclcpp API documentation](http://docs.ros2.org/latest/api/rclcpp/) for a complete list of its main components.
### Examples

View File

@@ -2,75 +2,121 @@
Changelog for package rclcpp
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18.0.0 (2022-12-29)
-------------------
* Implement Unified Node Interface (NodeInterfaces class) (`#2041 <https://github.com/ros2/rclcpp/issues/2041>`_)
* Do not throw exception if trying to dequeue an empty intra-process buffer (`#2061 <https://github.com/ros2/rclcpp/issues/2061>`_)
* Move event callback binding to PublisherBase and SubscriptionBase (`#2066 <https://github.com/ros2/rclcpp/issues/2066>`_)
* Implement validity checks for rclcpp::Clock (`#2040 <https://github.com/ros2/rclcpp/issues/2040>`_)
* Explicitly set callback type (`#2059 <https://github.com/ros2/rclcpp/issues/2059>`_)
* Fix logging macros to build with msvc and cpp20 (`#2063 <https://github.com/ros2/rclcpp/issues/2063>`_)
* Add clock type to node_options (`#1982 <https://github.com/ros2/rclcpp/issues/1982>`_)
* Fix nullptr dereference in prune_requests_older_than (`#2008 <https://github.com/ros2/rclcpp/issues/2008>`_)
* Remove templating on to_rcl_subscription_options (`#2056 <https://github.com/ros2/rclcpp/issues/2056>`_)
* Fix SharedFuture from async_send_request never becoming valid (`#2044 <https://github.com/ros2/rclcpp/issues/2044>`_)
* Add in a warning for a KeepLast depth of 0. (`#2048 <https://github.com/ros2/rclcpp/issues/2048>`_)
* Mark rclcpp::Clock::now() as const (`#2050 <https://github.com/ros2/rclcpp/issues/2050>`_)
* Fix a case that did not throw ParameterUninitializedException (`#2036 <https://github.com/ros2/rclcpp/issues/2036>`_)
* Update maintainers (`#2043 <https://github.com/ros2/rclcpp/issues/2043>`_)
* Contributors: Alberto Soragna, Audrow Nash, Chen Lihui, Chris Lalancette, Jeffery Hsu, Lei Liu, Mateusz Szczygielski, Shane Loretz, andrei, mauropasse, methylDragon
16.0.18 (2026-02-09)
--------------------
* print warning message on owner node if the parameter operation fails. (backport `#3037 <https://github.com/ros2/rclcpp/issues/3037>`_) (`#3040 <https://github.com/ros2/rclcpp/issues/3040>`_)
* fix context in wait for message wait set (`#3030 <https://github.com/ros2/rclcpp/issues/3030>`_) (`#3033 <https://github.com/ros2/rclcpp/issues/3033>`_)
* Improve the robustness of the TopicEndpointInfo constructor (backport `#3013 <https://github.com/ros2/rclcpp/issues/3013>`_) (`#3016 <https://github.com/ros2/rclcpp/issues/3016>`_)
* Contributors: mergify[bot]
17.1.0 (2022-11-02)
-------------------
* MultiThreadExecutor number of threads is at least 2+ in default. (`#2032 <https://github.com/ros2/rclcpp/issues/2032>`_)
* Fix bug that a callback not reached (`#1640 <https://github.com/ros2/rclcpp/issues/1640>`_)
* Set the minimum number of threads of the Multithreaded executor to 2 (`#2030 <https://github.com/ros2/rclcpp/issues/2030>`_)
* check thread whether joinable before join (`#2019 <https://github.com/ros2/rclcpp/issues/2019>`_)
* Set cpplint test timeout to 3 minutes (`#2022 <https://github.com/ros2/rclcpp/issues/2022>`_)
* Make sure to include-what-you-use in the node_interfaces. (`#2018 <https://github.com/ros2/rclcpp/issues/2018>`_)
* Do not clear entities callbacks on destruction (`#2002 <https://github.com/ros2/rclcpp/issues/2002>`_)
* fix mismatched issue if using zero_allocate (`#1995 <https://github.com/ros2/rclcpp/issues/1995>`_)
* Contributors: Alexis Paques, Chen Lihui, Chris Lalancette, Cristóbal Arroyo, Tomoya Fujita, mauropasse, uupks
16.0.17 (2025-12-23)
--------------------
* Unified Node Interfaces: Add const version of get_node_x_interface() (`#3006 <https://github.com/ros2/rclcpp/issues/3006>`_) (`#3010 <https://github.com/ros2/rclcpp/issues/3010>`_)
* [Humble] Implement Unified Node Interface (NodeInterfaces class) (backport `#2041 <https://github.com/ros2/rclcpp/issues/2041>`_) (`#3002 <https://github.com/ros2/rclcpp/issues/3002>`_)
* remove I/O from signal handler. (`#3000 <https://github.com/ros2/rclcpp/issues/3000>`_) (`#3005 <https://github.com/ros2/rclcpp/issues/3005>`_)
* correct test function descriptions (backport `#2970 <https://github.com/ros2/rclcpp/issues/2970>`_) (`#2994 <https://github.com/ros2/rclcpp/issues/2994>`_)
* Contributors: fabianhirmann, mergify[bot]
17.0.0 (2022-09-13)
-------------------
* Make ParameterService and Sync/AsyncParameterClient accept rclcpp::QoS (`#1978 <https://github.com/ros2/rclcpp/issues/1978>`_)
* support regex match for parameter client (`#1992 <https://github.com/ros2/rclcpp/issues/1992>`_)
* operator+= and operator-= for Duration (`#1988 <https://github.com/ros2/rclcpp/issues/1988>`_)
* Revert "Revert "Add a create_timer method to Node and `LifecycleNode` classes (`#1975 <https://github.com/ros2/rclcpp/issues/1975>`_)" (`#2009 <https://github.com/ros2/rclcpp/issues/2009>`_) (`#2010 <https://github.com/ros2/rclcpp/issues/2010>`_)
* force compiler warning if callback handles not captured (`#2000 <https://github.com/ros2/rclcpp/issues/2000>`_)
* Revert "Add a `create_timer` method to `Node` and `LifecycleNode` classes (`#1975 <https://github.com/ros2/rclcpp/issues/1975>`_)" (`#2009 <https://github.com/ros2/rclcpp/issues/2009>`_)
* Add a `create_timer` method to `Node` and `LifecycleNode` classes (`#1975 <https://github.com/ros2/rclcpp/issues/1975>`_)
* [docs] add note about callback lifetime for {on, post}_set_parameter_callback (`#1981 <https://github.com/ros2/rclcpp/issues/1981>`_)
* fix memory leak (`#1994 <https://github.com/ros2/rclcpp/issues/1994>`_)
* Support pre-set and post-set parameter callbacks in addition to on-set-parameter-callback. (`#1947 <https://github.com/ros2/rclcpp/issues/1947>`_)
* Make create_service accept rclcpp::QoS (`#1969 <https://github.com/ros2/rclcpp/issues/1969>`_)
* Make create_client accept rclcpp::QoS (`#1964 <https://github.com/ros2/rclcpp/issues/1964>`_)
* Fix the documentation for rclcpp::ok to be accurate. (`#1965 <https://github.com/ros2/rclcpp/issues/1965>`_)
* use regex for wildcard matching (`#1839 <https://github.com/ros2/rclcpp/issues/1839>`_)
* Revert "Introduce executors new spin_for method, replace spin_until_future_complete with spin_until_complete. (`#1821 <https://github.com/ros2/rclcpp/issues/1821>`_) (`#1874 <https://github.com/ros2/rclcpp/issues/1874>`_)" (`#1956 <https://github.com/ros2/rclcpp/issues/1956>`_)
* Introduce executors new spin_for method, replace spin_until_future_complete with spin_until_complete. (`#1821 <https://github.com/ros2/rclcpp/issues/1821>`_) (`#1874 <https://github.com/ros2/rclcpp/issues/1874>`_)
* test adjustment for LoanedMessage. (`#1951 <https://github.com/ros2/rclcpp/issues/1951>`_)
* fix virtual dispatch issues identified by clang-tidy (`#1816 <https://github.com/ros2/rclcpp/issues/1816>`_)
* Remove unused on_parameters_set_callback\_ (`#1945 <https://github.com/ros2/rclcpp/issues/1945>`_)
* Fix subscription.is_serialized() for callbacks with message info (`#1950 <https://github.com/ros2/rclcpp/issues/1950>`_)
* wait for subscriptions on another thread. (`#1940 <https://github.com/ros2/rclcpp/issues/1940>`_)
* Fix documentation of `RCLCPP\_[INFO,WARN,...]` (`#1943 <https://github.com/ros2/rclcpp/issues/1943>`_)
* Always trigger guard condition waitset (`#1923 <https://github.com/ros2/rclcpp/issues/1923>`_)
* Add statistics for handle_loaned_message (`#1927 <https://github.com/ros2/rclcpp/issues/1927>`_)
* Drop wrong template specialization (`#1926 <https://github.com/ros2/rclcpp/issues/1926>`_)
* Contributors: Alberto Soragna, Andrew Symington, Barry Xu, Brian, Chen Lihui, Chris Lalancette, Daniel Reuter, Deepanshu Bansal, Hubert Liberacki, Ivan Santiago Paunovic, Jochen Sprickerhof, Nikolai Morin, Shane Loretz, Tomoya Fujita, Tyler Weaver, William Woodall, schrodinbug
16.0.16 (2025-11-18)
--------------------
* Fix REP url locations (backport `#2987 <https://github.com/ros2/rclcpp/issues/2987>`_) (`#2991 <https://github.com/ros2/rclcpp/issues/2991>`_)
* Contributors: mergify[bot]
16.2.0 (2022-05-03)
-------------------
* Update get_parameter_from_event to follow the function description (`#1922 <https://github.com/ros2/rclcpp/issues/1922>`_)
* Add 'best available' QoS enum values and methods (`#1920 <https://github.com/ros2/rclcpp/issues/1920>`_)
* Contributors: Barry Xu, Jacob Perron
16.0.15 (2025-09-11)
--------------------
* Allow for implicitly convertable loggers as well (`#2922 <https://github.com/ros2/rclcpp/issues/2922>`_) (`#2936 <https://github.com/ros2/rclcpp/issues/2936>`_) (`#2938 <https://github.com/ros2/rclcpp/issues/2938>`_)
* Fix: improve exception context for parameter_value_from (backport `#2917 <https://github.com/ros2/rclcpp/issues/2917>`_) (`#2921 <https://github.com/ros2/rclcpp/issues/2921>`_)
* Removed warning test_qos (`#2859 <https://github.com/ros2/rclcpp/issues/2859>`_) (`#2925 <https://github.com/ros2/rclcpp/issues/2925>`_)
* Add qos parameter for wait_for_message function (`#2903 <https://github.com/ros2/rclcpp/issues/2903>`_) (`#2907 <https://github.com/ros2/rclcpp/issues/2907>`_)
* Contributors: mergify[bot]
16.1.0 (2022-04-29)
16.0.14 (2025-07-16)
--------------------
* fix test_publisher_with_system_default_qos. (backport `#2881 <https://github.com/ros2/rclcpp/issues/2881>`_) (`#2882 <https://github.com/ros2/rclcpp/issues/2882>`_)
* Contributors: mergify[bot]
16.0.13 (2025-06-23)
--------------------
* Fix for memory leaks in rclcpp::SerializedMessage (`#2861 <https://github.com/ros2/rclcpp/issues/2861>`_) (`#2865 <https://github.com/ros2/rclcpp/issues/2865>`_)
* Added missing chrono includes (backport `#2854 <https://github.com/ros2/rclcpp/issues/2854>`_) (`#2857 <https://github.com/ros2/rclcpp/issues/2857>`_)
* QoSInitialization::from_rmw does not validate invalid history policy … (backport `#2841 <https://github.com/ros2/rclcpp/issues/2841>`_) (`#2844 <https://github.com/ros2/rclcpp/issues/2844>`_)
* throws std::invalid_argument if ParameterEvent is NULL. (`#2814 <https://github.com/ros2/rclcpp/issues/2814>`_) (`#2824 <https://github.com/ros2/rclcpp/issues/2824>`_)
* remove redundant typesupport check in serialization module (`#2808 <https://github.com/ros2/rclcpp/issues/2808>`_) (`#2816 <https://github.com/ros2/rclcpp/issues/2816>`_)
* Contributors: mergify[bot]
16.0.12 (2025-03-25)
--------------------
* doc: Added warning to not instantiate Clock directly with RCL_ROS_TIME (`#2768 <https://github.com/ros2/rclcpp/issues/2768>`_) (`#2770 <https://github.com/ros2/rclcpp/issues/2770>`_)
* apply actual QoS from rmw to the IPC publisher. (backport `#2707 <https://github.com/ros2/rclcpp/issues/2707>`_) (`#2711 <https://github.com/ros2/rclcpp/issues/2711>`_)
* Adding in topic name to logging on IPC issues (`#2706 <https://github.com/ros2/rclcpp/issues/2706>`_) (`#2709 <https://github.com/ros2/rclcpp/issues/2709>`_)
* Contributors: mergify[bot]
16.0.11 (2024-11-25)
--------------------
* Fix subscription.is_serialized() for callbacks with message info (`#1950 <https://github.com/ros2/rclcpp/issues/1950>`_) (`#2622 <https://github.com/ros2/rclcpp/issues/2622>`_)
* Use the same context for the specified node in rclcpp::spin functions… (`#2618 <https://github.com/ros2/rclcpp/issues/2618>`_) (`#2620 <https://github.com/ros2/rclcpp/issues/2620>`_)
* Contributors: mergify[bot], roscan-tech
16.0.10 (2024-07-26)
--------------------
* Add test creating two content filter topics with the same topic name (`#2546 <https://github.com/ros2/rclcpp/issues/2546>`_) (`#2549 <https://github.com/ros2/rclcpp/issues/2549>`_) (`#2551 <https://github.com/ros2/rclcpp/issues/2551>`_)
* Contributors: mergify[bot]
16.0.9 (2024-05-15)
-------------------
* use reinterpret_cast for function pointer conversion. (`#1919 <https://github.com/ros2/rclcpp/issues/1919>`_)
* Contributors: Tomoya Fujita
* Fix logging macros to build with msvc and cpp20 (`#2063 <https://github.com/ros2/rclcpp/issues/2063>`_) (`#2529 <https://github.com/ros2/rclcpp/issues/2529>`_)
* address ambiguous auto variable. (`#2481 <https://github.com/ros2/rclcpp/issues/2481>`_) (`#2485 <https://github.com/ros2/rclcpp/issues/2485>`_)
* Fix clang warning: bugprone-use-after-move (`#2116 <https://github.com/ros2/rclcpp/issues/2116>`_) (`#2459 <https://github.com/ros2/rclcpp/issues/2459>`_)
* Contributors: Tamaki Nishino, mergify[bot]
16.0.8 (2024-01-24)
-------------------
* Add missing stdexcept include (`#2186 <https://github.com/ros2/rclcpp/issues/2186>`_) (`#2394 <https://github.com/ros2/rclcpp/issues/2394>`_)
* Contributors: gentoo90
16.0.7 (2023-11-13)
-------------------
* Disable the loaned messages inside the executor. (backport `#2335 <https://github.com/ros2/rclcpp/issues/2335>`_) (`#2364 <https://github.com/ros2/rclcpp/issues/2364>`_)
* Add missing 'enable_rosout' comments (`#2345 <https://github.com/ros2/rclcpp/issues/2345>`_) (`#2347 <https://github.com/ros2/rclcpp/issues/2347>`_)
* address rate related flaky tests. (`#2329 <https://github.com/ros2/rclcpp/issues/2329>`_) (`#2342 <https://github.com/ros2/rclcpp/issues/2342>`_)
* Update SignalHandler get_global_signal_handler to avoid complex types in static memory (`#2316 <https://github.com/ros2/rclcpp/issues/2316>`_) (`#2321 <https://github.com/ros2/rclcpp/issues/2321>`_)
* Fix C++20 allocator construct deprecation (`#2292 <https://github.com/ros2/rclcpp/issues/2292>`_) (`#2319 <https://github.com/ros2/rclcpp/issues/2319>`_)
* Contributors: mergify[bot]
16.0.6 (2023-09-19)
-------------------
* Topic correct typeadapter deduction (`#2294 <https://github.com/ros2/rclcpp/issues/2294>`_) (`#2297 <https://github.com/ros2/rclcpp/issues/2297>`_)
* check thread whether joinable before join (`#2019 <https://github.com/ros2/rclcpp/issues/2019>`_) (`#2275 <https://github.com/ros2/rclcpp/issues/2275>`_)
* Do not crash Executor when send_response fails due to client failure. (`#2276 <https://github.com/ros2/rclcpp/issues/2276>`_) (`#2280 <https://github.com/ros2/rclcpp/issues/2280>`_)
* Contributors: mergify[bot]
16.0.5 (2023-07-17)
-------------------
* warning: comparison of integer expressions of different signedness (`#2219 <https://github.com/ros2/rclcpp/issues/2219>`_) (`#2223 <https://github.com/ros2/rclcpp/issues/2223>`_)
* Trigger the intraprocess guard condition with data (`#2164 <https://github.com/ros2/rclcpp/issues/2164>`_) (`#2167 <https://github.com/ros2/rclcpp/issues/2167>`_)
* Implement validity checks for rclcpp::Clock (`#2040 <https://github.com/ros2/rclcpp/issues/2040>`_) (`#2210 <https://github.com/ros2/rclcpp/issues/2210>`_)
* Contributors: Tomoya Fujita, mergify[bot]
16.0.4 (2023-04-25)
-------------------
* use allocator via init_options argument. (`#2129 <https://github.com/ros2/rclcpp/issues/2129>`_) (`#2131 <https://github.com/ros2/rclcpp/issues/2131>`_)
* Contributors: mergify[bot]
16.0.3 (2023-01-10)
-------------------
* Fix SharedFuture from async_send_request never becomes valid (`#2044 <https://github.com/ros2/rclcpp/issues/2044>`_) (`#2076 <https://github.com/ros2/rclcpp/issues/2076>`_)
* do not throw exception if trying to dequeue an empty intra-process buffer (`#2061 <https://github.com/ros2/rclcpp/issues/2061>`_) (`#2070 <https://github.com/ros2/rclcpp/issues/2070>`_)
* fix nullptr dereference in prune_requests_older_than (`#2008 <https://github.com/ros2/rclcpp/issues/2008>`_) (`#2065 <https://github.com/ros2/rclcpp/issues/2065>`_)
* Fix bug that a callback not reached (`#1640 <https://github.com/ros2/rclcpp/issues/1640>`_) (`#2033 <https://github.com/ros2/rclcpp/issues/2033>`_)
* Contributors: mergify[bot]
16.0.2 (2022-11-07)
-------------------
* fix mismatched issue if using zero_allocate (`#1995 <https://github.com/ros2/rclcpp/issues/1995>`_) (`#2026 <https://github.com/ros2/rclcpp/issues/2026>`_)
* use regex for wildcard matching (backport `#1839 <https://github.com/ros2/rclcpp/issues/1839>`_) (`#1986 <https://github.com/ros2/rclcpp/issues/1986>`_)
* Drop wrong template specialization (`#1926 <https://github.com/ros2/rclcpp/issues/1926>`_) (`#1937 <https://github.com/ros2/rclcpp/issues/1937>`_)
* Add statistics for handle_loaned_message (`#1927 <https://github.com/ros2/rclcpp/issues/1927>`_) (`#1932 <https://github.com/ros2/rclcpp/issues/1932>`_)
* Contributors: mergify[bot]
16.0.1 (2022-04-13)
-------------------

View File

@@ -259,8 +259,4 @@ if(TEST cppcheck)
set_tests_properties(cppcheck PROPERTIES TIMEOUT 500)
endif()
if(TEST cpplint)
set_tests_properties(cpplint PROPERTIES TIMEOUT 180)
endif()
ament_generate_version_header(${PROJECT_NAME})

View File

@@ -1,10 +1,10 @@
This document is a declaration of software quality for the `rclcpp` package, based on the guidelines in [REP-2004](https://www.ros.org/reps/rep-2004.html).
This document is a declaration of software quality for the `rclcpp` package, based on the guidelines in [REP-2004](https://reps.openrobotics.org/rep-2004/).
# rclcpp Quality Declaration
The package `rclcpp` claims to be in the **Quality Level 1** category when it is used with a **Quality Level 1** middleware.
Below are the rationales, notes, and caveats for this claim, organized by each requirement listed in the [Package Quality Categories in REP-2004](https://www.ros.org/reps/rep-2004.html) of the ROS2 developer guide.
Below are the rationales, notes, and caveats for this claim, organized by each requirement listed in the [Package Quality Categories in REP-2004](https://reps.openrobotics.org/rep-2004/) of the ROS2 developer guide.
## Version Policy [1]
@@ -55,7 +55,7 @@ All pull requests will be peer-reviewed, check [ROS 2 Developer Guide](https://d
### Continuous Integration [2.iv]
All pull requests must pass CI on all [tier 1 platforms](https://www.ros.org/reps/rep-2000.html#support-tiers)
All pull requests must pass CI on all [tier 1 platforms](https://reps.openrobotics.org/rep-2000/#support-tiers)
Currently nightly results can be seen here:
@@ -213,7 +213,7 @@ It is **Quality Level 1**, see its [Quality Declaration document](https://gitlab
## Platform Support [6]
`rclcpp` supports all of the tier 1 platforms as described in [REP-2000](https://www.ros.org/reps/rep-2000.html#support-tiers), and tests each change against all of them.
`rclcpp` supports all of the tier 1 platforms as described in [REP-2000](https://reps.openrobotics.org/rep-2000/#support-tiers), and tests each change against all of them.
Currently nightly build status can be seen here:
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/rclcpp/)
@@ -225,4 +225,4 @@ Currently nightly build status can be seen here:
### Vulnerability Disclosure Policy [7.i]
This package conforms to the Vulnerability Disclosure Policy in [REP-2006](https://www.ros.org/reps/rep-2006.html).
This package conforms to the Vulnerability Disclosure Policy in [REP-2006](https://reps.openrobotics.org/rep-2006/).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

View File

@@ -1,29 +0,0 @@
# Proposed node parameters callback Design
## Introduction:
The original requirement came in **gazebo_ros_pkgs** for setting individual wheel slip parameters based on global wheel slip value [link to original issue](https://github.com/ros-simulation/gazebo_ros_pkgs/pull/1365).
The main requirement is to set one or more parameters after another parameter is set successfully.
Additionally, it would be nice if users could be notified locally (via a callback) when parameters have been set successfully (i.e. post validation).
Related discussion can be found in [#609](https://github.com/ros2/rclcpp/issues/609) [#1789](https://github.com/ros2/rclcpp/pull/1789)
With the current parameters API, the `add_on_set_parameters_callback` is intended for validation of parameter values before they are set, it should **not** cause any side-effects.
There is also the `ParameterEventHandler` that publishes changes to node parameters on `/parameter_events` topic for external nodes to see. Though the node could subscribe to the `/parameter_events` topic to be notified of changes to its own parameters, it is less than ideal since there is a delay caused by waiting for an executor to process the callback.
We propose adding a `PostSetParametersCallbackHandle` for successful parameter set similar to `OnSetParametersCallbackHandle` for parameter validation. Also, we propose adding a `PreSetParametersCallbackHandle` useful for modifying list of parameters being set.
The validation callback is often abused to trigger side effects in the code, for instance updating class attributes even before a parameter has been set successfully. Instead of relying on the `/parameter_events` topic to be notified of parameter changes, users can register a callback with a new API, `add_post_set_parameters_callback`.
It is possible to use the proposed `add_post_set_parameters_callback` for setting additional parameters, but this might result in infinite recursion and does not allow those additional parameters to be set atomically with the original parameter(s) changed.
To workaround these issues, we propose adding a "pre set" callback type that can be registered with `add_pre_set_parameters_callback`, which will be triggered before the validation callbacks and can be used to modify the parameter list.
![Desgin API](https://github.com/ros2/rclcpp/blob/deepanshu/local-param-changed-callback-support/rclcpp/doc/param_callback_design.png?raw=true)
## Alternatives
* Users could call `set_parameter` while processing a message from the `/parameter_events` topic, however, there is extra overhead in having to create subscription (as noted earlier).
* Users could call `set_parameter` inside the "on set" parameters callback, however it is not well-defined how side-effects should handle cases where parameter validation fails.

View File

@@ -130,7 +130,7 @@ public:
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph);
RCLCPP_PUBLIC
virtual ~ClientBase() = default;
virtual ~ClientBase();
/// Take the next response for this client as a type erased pointer.
/**
@@ -312,7 +312,7 @@ public:
// This two-step setting, prevents a gap where the old std::function has
// been replaced but the middleware hasn't been told about the new one yet.
set_on_new_response_callback(
rclcpp::detail::cpp_callback_trampoline<decltype(new_callback), const void *, size_t>,
rclcpp::detail::cpp_callback_trampoline<const void *, size_t>,
static_cast<const void *>(&new_callback));
// Store the std::function to keep it in scope, also overwrites the existing one.
@@ -320,8 +320,7 @@ public:
// Set it again, now using the permanent storage.
set_on_new_response_callback(
rclcpp::detail::cpp_callback_trampoline<
decltype(on_new_response_callback_), const void *, size_t>,
rclcpp::detail::cpp_callback_trampoline<const void *, size_t>,
static_cast<const void *>(&on_new_response_callback_));
}
@@ -817,7 +816,7 @@ protected:
"Received invalid sequence number. Ignoring...");
return std::nullopt;
}
auto value = std::move(it->second.second);
std::optional<CallbackInfoVariant> value = std::move(it->second.second);
this->pending_requests_.erase(request_number);
return value;
}

View File

@@ -60,6 +60,13 @@ public:
/**
* Initializes the clock instance with the given clock_type.
*
* WARNING Don't instantiate a clock using RCL_ROS_TIME directly,
* unless you really know what you are doing. By default no TimeSource
* is attached to a new clock. This will lead to the unexpected behavior,
* that your RCL_ROS_TIME will run always on system time. If you want
* a RCL_ROS_TIME use Node::get_clock(), or make sure to attach a
* TimeSource yourself.
*
* \param clock_type type of the clock.
* \throws anything rclcpp::exceptions::throw_from_rcl_error can throw.
*/
@@ -77,7 +84,7 @@ public:
*/
RCLCPP_PUBLIC
Time
now() const;
now();
/**
* Sleep until a specified Time, according to clock type.

View File

@@ -26,6 +26,7 @@
#include <unordered_set>
#include <utility>
#include <vector>
#include <stdexcept>
#include "rcl/context.h"
#include "rcl/guard_condition.h"
@@ -183,11 +184,6 @@ public:
*
* This function is thread-safe.
*
* Note that if you override this method, but leave shutdown to be called in
* the destruction of this base class, it will not call the overridden
* version from your base class.
* So you need to ensure you call your class's shutdown() in its destructor.
*
* \param[in] reason the description of why shutdown happened
* \return true if shutdown was successful, false if context was already shutdown
* \throw various exceptions derived from rclcpp::exceptions::RCLError, if rcl_shutdown fails
@@ -323,6 +319,7 @@ public:
/// Interrupt any blocking sleep_for calls, causing them to return immediately and return true.
RCLCPP_PUBLIC
virtual
void
interrupt_all_sleep_for();
@@ -355,6 +352,7 @@ protected:
// Called by constructor and destructor to clean up by finalizing the
// shutdown rcl context and preparing for a new init cycle.
RCLCPP_PUBLIC
virtual
void
clean_up();

View File

@@ -20,40 +20,10 @@
#include "rclcpp/node_interfaces/node_base_interface.hpp"
#include "rclcpp/node_interfaces/node_services_interface.hpp"
#include "rclcpp/qos.hpp"
#include "rmw/rmw.h"
namespace rclcpp
{
/// Create a service client with a given type.
/**
* \param[in] node_base NodeBaseInterface implementation of the node on which
* to create the client.
* \param[in] node_graph NodeGraphInterface implementation of the node on which
* to create the client.
* \param[in] node_services NodeServicesInterface implementation of the node on
* which to create the client.
* \param[in] service_name The name on which the service is accessible.
* \param[in] qos Quality of service profile for client.
* \param[in] group Callback group to handle the reply to service calls.
* \return Shared pointer to the created client.
*/
template<typename ServiceT>
typename rclcpp::Client<ServiceT>::SharedPtr
create_client(
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 rclcpp::QoS & qos = rclcpp::ServicesQoS(),
rclcpp::CallbackGroup::SharedPtr group = nullptr)
{
return create_client<ServiceT>(
node_base, node_graph, node_services,
service_name,
qos.get_rmw_qos_profile(),
group);
}
/// Create a service client with a given type.
/// \internal

View File

@@ -26,32 +26,6 @@
namespace rclcpp
{
/// Create a service with a given type.
/**
* \param[in] node_base NodeBaseInterface implementation of the node on which
* to create the service.
* \param[in] node_services NodeServicesInterface implementation of the node on
* which to create the service.
* \param[in] service_name The name on which the service is accessible.
* \param[in] callback The callback to call when the service gets a request.
* \param[in] qos Quality of service profile for the service.
* \param[in] group Callback group to handle the reply to service calls.
* \return Shared pointer to the created service.
*/
template<typename ServiceT, typename CallbackT>
typename rclcpp::Service<ServiceT>::SharedPtr
create_service(
std::shared_ptr<node_interfaces::NodeBaseInterface> node_base,
std::shared_ptr<node_interfaces::NodeServicesInterface> node_services,
const std::string & service_name,
CallbackT && callback,
const rclcpp::QoS & qos,
rclcpp::CallbackGroup::SharedPtr group)
{
return create_service<ServiceT, CallbackT>(
node_base, node_services, service_name,
std::forward<CallbackT>(callback), qos.get_rmw_qos_profile(), group);
}
/// Create a service with a given type.
/// \internal

View File

@@ -23,29 +23,85 @@
#include "rclcpp/duration.hpp"
#include "rclcpp/node_interfaces/get_node_base_interface.hpp"
#include "rclcpp/node_interfaces/get_node_clock_interface.hpp"
#include "rclcpp/node_interfaces/get_node_timers_interface.hpp"
#include "rclcpp/node_interfaces/node_base_interface.hpp"
#include "rclcpp/node_interfaces/node_clock_interface.hpp"
#include "rclcpp/node_interfaces/node_timers_interface.hpp"
namespace rclcpp
{
namespace detail
/// Create a timer with a given clock
/// \internal
template<typename CallbackT>
typename rclcpp::TimerBase::SharedPtr
create_timer(
std::shared_ptr<node_interfaces::NodeBaseInterface> node_base,
std::shared_ptr<node_interfaces::NodeTimersInterface> node_timers,
rclcpp::Clock::SharedPtr clock,
rclcpp::Duration period,
CallbackT && callback,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
{
/// Perform a safe cast to a timer period in nanoseconds
auto timer = rclcpp::GenericTimer<CallbackT>::make_shared(
clock,
period.to_chrono<std::chrono::nanoseconds>(),
std::forward<CallbackT>(callback),
node_base->get_context());
node_timers->add_timer(timer, group);
return timer;
}
/// Create a timer with a given clock
template<typename NodeT, typename CallbackT>
typename rclcpp::TimerBase::SharedPtr
create_timer(
NodeT node,
rclcpp::Clock::SharedPtr clock,
rclcpp::Duration period,
CallbackT && callback,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
{
return create_timer(
rclcpp::node_interfaces::get_node_base_interface(node),
rclcpp::node_interfaces::get_node_timers_interface(node),
clock,
period,
std::forward<CallbackT>(callback),
group);
}
/// Convenience method to create a timer with node resources.
/**
*
* \tparam DurationRepT
* \tparam DurationT
* \tparam CallbackT
* \param period period to execute callback. This duration must be 0 <= period < nanoseconds::max()
* \return period, expressed as chrono::duration::nanoseconds
* \throws std::invalid_argument if period is negative or too large
* \param callback callback to execute via the timer period
* \param group
* \param node_base
* \param node_timers
* \return
* \throws std::invalid argument if either node_base or node_timers
* are null, or period is negative or too large
*/
template<typename DurationRepT, typename DurationT>
std::chrono::nanoseconds
safe_cast_to_period_in_ns(std::chrono::duration<DurationRepT, DurationT> period)
template<typename DurationRepT, typename DurationT, typename CallbackT>
typename rclcpp::WallTimer<CallbackT>::SharedPtr
create_wall_timer(
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
rclcpp::CallbackGroup::SharedPtr group,
node_interfaces::NodeBaseInterface * node_base,
node_interfaces::NodeTimersInterface * node_timers)
{
if (node_base == nullptr) {
throw std::invalid_argument{"input node_base cannot be null"};
}
if (node_timers == nullptr) {
throw std::invalid_argument{"input node_timers cannot be null"};
}
if (period < std::chrono::duration<DurationRepT, DurationT>::zero()) {
throw std::invalid_argument{"timer period cannot be negative"};
}
@@ -76,135 +132,12 @@ safe_cast_to_period_in_ns(std::chrono::duration<DurationRepT, DurationT> period)
"Casting timer period to nanoseconds resulted in integer overflow."};
}
return period_ns;
}
} // namespace detail
/// Create a timer with a given clock
/// \internal
template<typename CallbackT>
typename rclcpp::TimerBase::SharedPtr
create_timer(
std::shared_ptr<node_interfaces::NodeBaseInterface> node_base,
std::shared_ptr<node_interfaces::NodeTimersInterface> node_timers,
rclcpp::Clock::SharedPtr clock,
rclcpp::Duration period,
CallbackT && callback,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
{
return create_timer(
clock,
period.to_chrono<std::chrono::nanoseconds>(),
std::forward<CallbackT>(callback),
group,
node_base.get(),
node_timers.get());
}
/// Create a timer with a given clock
template<typename NodeT, typename CallbackT>
typename rclcpp::TimerBase::SharedPtr
create_timer(
NodeT node,
rclcpp::Clock::SharedPtr clock,
rclcpp::Duration period,
CallbackT && callback,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
{
return create_timer(
clock,
period.to_chrono<std::chrono::nanoseconds>(),
std::forward<CallbackT>(callback),
group,
rclcpp::node_interfaces::get_node_base_interface(node).get(),
rclcpp::node_interfaces::get_node_timers_interface(node).get());
}
/// Convenience method to create a general timer with node resources.
/**
*
* \tparam DurationRepT
* \tparam DurationT
* \tparam CallbackT
* \param clock clock to be used
* \param period period to execute callback. This duration must be 0 <= period < nanoseconds::max()
* \param callback callback to execute via the timer period
* \param group callback group
* \param node_base node base interface
* \param node_timers node timer interface
* \return shared pointer to a generic timer
* \throws std::invalid_argument if either clock, node_base or node_timers
* are nullptr, or period is negative or too large
*/
template<typename DurationRepT, typename DurationT, typename CallbackT>
typename rclcpp::GenericTimer<CallbackT>::SharedPtr
create_timer(
rclcpp::Clock::SharedPtr clock,
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
rclcpp::CallbackGroup::SharedPtr group,
node_interfaces::NodeBaseInterface * node_base,
node_interfaces::NodeTimersInterface * node_timers)
{
if (clock == nullptr) {
throw std::invalid_argument{"clock cannot be null"};
}
if (node_base == nullptr) {
throw std::invalid_argument{"input node_base cannot be null"};
}
if (node_timers == nullptr) {
throw std::invalid_argument{"input node_timers cannot be null"};
}
const std::chrono::nanoseconds period_ns = detail::safe_cast_to_period_in_ns(period);
// Add a new generic timer.
auto timer = rclcpp::GenericTimer<CallbackT>::make_shared(
std::move(clock), period_ns, std::move(callback), node_base->get_context());
node_timers->add_timer(timer, group);
return timer;
}
/// Convenience method to create a wall timer with node resources.
/**
*
* \tparam DurationRepT
* \tparam DurationT
* \tparam CallbackT
* \param period period to execute callback. This duration must be 0 <= period < nanoseconds::max()
* \param callback callback to execute via the timer period
* \param group callback group
* \param node_base node base interface
* \param node_timers node timer interface
* \return shared pointer to a wall timer
* \throws std::invalid_argument if either node_base or node_timers
* are null, or period is negative or too large
*/
template<typename DurationRepT, typename DurationT, typename CallbackT>
typename rclcpp::WallTimer<CallbackT>::SharedPtr
create_wall_timer(
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
rclcpp::CallbackGroup::SharedPtr group,
node_interfaces::NodeBaseInterface * node_base,
node_interfaces::NodeTimersInterface * node_timers)
{
if (node_base == nullptr) {
throw std::invalid_argument{"input node_base cannot be null"};
}
if (node_timers == nullptr) {
throw std::invalid_argument{"input node_timers cannot be null"};
}
const std::chrono::nanoseconds period_ns = detail::safe_cast_to_period_in_ns(period);
// Add a new wall timer.
auto timer = rclcpp::WallTimer<CallbackT>::make_shared(
period_ns, std::move(callback), node_base->get_context());
node_timers->add_timer(timer, group);
return timer;
}
} // namespace rclcpp
#endif // RCLCPP__CREATE_TIMER_HPP_

View File

@@ -41,7 +41,6 @@ namespace detail
* so no exceptions should be thrown at this point, and doing so results in
* undefined behavior.
*
* \tparam UserDataRealT Declared type of the passed function
* \tparam UserDataT Deduced type based on what is passed for user data,
* usually this type is either `void *` or `const void *`.
* \tparam Args the arguments being passed to the callback
@@ -51,7 +50,6 @@ namespace detail
* \returns whatever the callback returns, if anything
*/
template<
typename UserDataRealT,
typename UserDataT,
typename ... Args,
typename ReturnT = void
@@ -59,7 +57,7 @@ template<
ReturnT
cpp_callback_trampoline(UserDataT user_data, Args ... args) noexcept
{
auto & actual_callback = *static_cast<const UserDataRealT *>(user_data);
auto & actual_callback = *reinterpret_cast<const std::function<ReturnT(Args...)> *>(user_data);
return actual_callback(args ...);
}

View File

@@ -92,13 +92,9 @@ public:
Duration
operator+(const rclcpp::Duration & rhs) const;
Duration & operator+=(const rclcpp::Duration & rhs);
Duration
operator-(const rclcpp::Duration & rhs) const;
Duration & operator-=(const rclcpp::Duration & rhs);
/// Get the maximum representable value.
/**
* \return the maximum representable value
@@ -110,9 +106,6 @@ public:
Duration
operator*(double scale) const;
Duration &
operator*=(double scale);
/// Get duration in nanosecods
/**
* \return the duration in nanoseconds as a rcl_duration_value_t.

View File

@@ -107,7 +107,9 @@ spin_until_future_complete(
const FutureT & future,
std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
{
rclcpp::executors::SingleThreadedExecutor executor;
rclcpp::ExecutorOptions options;
options.context = node_ptr->get_context();
rclcpp::executors::SingleThreadedExecutor executor(options);
return executors::spin_node_until_future_complete<FutureT>(executor, node_ptr, future, timeout);
}

View File

@@ -47,7 +47,7 @@ public:
*
* \param options common options for all executors
* \param number_of_threads number of threads to have in the thread pool,
* the default 0 will use the number of cpu cores found (minimum of 2)
* the default 0 will use the number of cpu cores found instead
* \param yield_before_execute if true std::this_thread::yield() is called
* \param timeout maximum time to wait
*/

View File

@@ -454,6 +454,8 @@ private:
if (std::next(it) == subscription_ids.end()) {
// If this is the last subscription, give up ownership
subscription->provide_intra_process_data(std::move(message));
// Last message delivered, break from for loop
break;
} else {
// Copy the message since we have additional subscriptions to serve
Deleter deleter = message.get_deleter();
@@ -479,13 +481,13 @@ private:
"subscription use different allocator types, which is not supported");
}
if constexpr (rclcpp::TypeAdapter<MessageT>::is_specialized::value) {
if constexpr (rclcpp::TypeAdapter<MessageT, ROSMessageType>::is_specialized::value) {
ROSMessageTypeAllocator ros_message_alloc(allocator);
auto ptr = ros_message_alloc.allocate(1);
ros_message_alloc.construct(ptr);
auto ptr = ROSMessageTypeAllocatorTraits::allocate(ros_message_alloc, 1);
ROSMessageTypeAllocatorTraits::construct(ros_message_alloc, ptr);
ROSMessageTypeDeleter deleter;
allocator::set_allocator_for_deleter(&deleter, &allocator);
rclcpp::TypeAdapter<MessageT>::convert_to_ros_message(*message, *ptr);
rclcpp::TypeAdapter<MessageT, ROSMessageType>::convert_to_ros_message(*message, *ptr);
auto ros_msg = std::unique_ptr<ROSMessageType, ROSMessageTypeDeleter>(ptr, deleter);
ros_message_subscription->provide_intra_process_message(std::move(ros_msg));
} else {
@@ -493,6 +495,8 @@ private:
if (std::next(it) == subscription_ids.end()) {
// If this is the last subscription, give up ownership
ros_message_subscription->provide_intra_process_message(std::move(message));
// Last message delivered, break from for loop
break;
} else {
// Copy the message since we have additional subscriptions to serve
Deleter deleter = message.get_deleter();

View File

@@ -118,6 +118,13 @@ public:
return nullptr;
}
}
if (this->buffer_->has_data()) {
// If there is data still to be processed, indicate to the
// executor or waitset by triggering the guard condition.
this->trigger_guard_condition();
}
return std::static_pointer_cast<void>(
std::make_shared<std::pair<ConstMessageSharedPtr, MessageUniquePtr>>(
std::pair<ConstMessageSharedPtr, MessageUniquePtr>(

View File

@@ -52,7 +52,7 @@ public:
{}
RCLCPP_PUBLIC
virtual ~SubscriptionIntraProcessBase() = default;
virtual ~SubscriptionIntraProcessBase();
RCLCPP_PUBLIC
size_t

View File

@@ -78,12 +78,38 @@ public:
node_base,
topic_name,
*rclcpp::get_typesupport_handle(topic_type, "rosidl_typesupport_cpp", *ts_lib),
options.template to_rcl_publisher_options<rclcpp::SerializedMessage>(qos),
// NOTE(methylDragon): Passing these args separately is necessary for event binding
options.event_callbacks,
options.use_default_callbacks),
options.template to_rcl_publisher_options<rclcpp::SerializedMessage>(qos)),
ts_lib_(ts_lib)
{}
{
// This is unfortunately duplicated with the code in publisher.hpp.
// TODO(nnmm): Deduplicate by moving this into PublisherBase.
if (options.event_callbacks.deadline_callback) {
this->add_event_handler(
options.event_callbacks.deadline_callback,
RCL_PUBLISHER_OFFERED_DEADLINE_MISSED);
}
if (options.event_callbacks.liveliness_callback) {
this->add_event_handler(
options.event_callbacks.liveliness_callback,
RCL_PUBLISHER_LIVELINESS_LOST);
}
if (options.event_callbacks.incompatible_qos_callback) {
this->add_event_handler(
options.event_callbacks.incompatible_qos_callback,
RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS);
} else if (options.use_default_callbacks) {
// Register default callback when not specified
try {
this->add_event_handler(
[this](QOSOfferedIncompatibleQoSInfo & info) {
this->default_incompatible_qos_callback(info);
},
RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS);
} catch (UnsupportedEventTypeException & /*exc*/) {
// pass
}
}
}
RCLCPP_PUBLIC
virtual ~GenericPublisher() = default;

View File

@@ -81,13 +81,45 @@ public:
node_base,
*rclcpp::get_typesupport_handle(topic_type, "rosidl_typesupport_cpp", *ts_lib),
topic_name,
options.to_rcl_subscription_options(qos),
options.event_callbacks,
options.use_default_callbacks,
options.template to_rcl_subscription_options<rclcpp::SerializedMessage>(qos),
true),
callback_(callback),
ts_lib_(ts_lib)
{}
{
// This is unfortunately duplicated with the code in subscription.hpp.
// TODO(nnmm): Deduplicate by moving this into SubscriptionBase.
if (options.event_callbacks.deadline_callback) {
this->add_event_handler(
options.event_callbacks.deadline_callback,
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED);
}
if (options.event_callbacks.liveliness_callback) {
this->add_event_handler(
options.event_callbacks.liveliness_callback,
RCL_SUBSCRIPTION_LIVELINESS_CHANGED);
}
if (options.event_callbacks.incompatible_qos_callback) {
this->add_event_handler(
options.event_callbacks.incompatible_qos_callback,
RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS);
} else if (options.use_default_callbacks) {
// Register default callback when not specified
try {
this->add_event_handler(
[this](QOSRequestedIncompatibleQoSInfo & info) {
this->default_incompatible_qos_callback(info);
},
RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS);
} catch (UnsupportedEventTypeException & /*exc*/) {
// pass
}
}
if (options.event_callbacks.message_lost_callback) {
this->add_event_handler(
options.event_callbacks.message_lost_callback,
RCL_SUBSCRIPTION_MESSAGE_LOST);
}
}
RCLCPP_PUBLIC
virtual ~GenericSubscription() = default;

View File

@@ -128,11 +128,6 @@ public:
* If start_if_not_started() was never called, this function still succeeds,
* but start_if_not_started() still cannot be called after this function.
*
* Note that if you override this method, but leave shutdown to be called in
* the destruction of this base class, it will not call the overridden
* version from your base class.
* So you need to ensure you call your class's shutdown() in its destructor.
*
* \throws rclcpp::execptions::RCLError from rcl_guard_condition_fini()
* \throws rclcpp::execptions::RCLError from rcl_wait_set_fini()
* \throws std::system_error anything std::mutex::lock() throws

View File

@@ -72,7 +72,7 @@ public:
const rcl_guard_condition_t &
get_rcl_guard_condition() const;
/// Signal that the condition has been met, notifying both the wait set and listeners, if any.
/// Notify the wait set waiting on this condition, if any, that the condition had been met.
/**
* This function is thread-safe, and may be called concurrently with waiting
* on this guard condition in a wait set.
@@ -107,22 +107,6 @@ public:
void
add_to_wait_set(rcl_wait_set_t * wait_set);
/// Set a callback to be called whenever the guard condition is triggered.
/**
* The callback receives a size_t which is the number of times the guard condition was triggered
* since the last time this callback was called.
* Normally this is 1, but can be > 1 if the guard condition was triggered before any
* callback was set.
*
* Calling it again will clear any previously set callback.
*
* This function is thread-safe.
*
* If you want more information available in the callback, like the guard condition
* or other information, you may use a lambda with captures or std::bind.
*
* \param[in] callback functor to be called when the guard condition is triggered
*/
RCLCPP_PUBLIC
void
set_on_trigger_callback(std::function<void(size_t)> callback);

View File

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

View File

@@ -227,7 +227,7 @@ public:
)
);
/// Create a wall timer that uses the wall clock to drive the callback.
/// Create a timer.
/**
* \param[in] period Time interval between triggers of the callback.
* \param[in] callback User-defined callback function.
@@ -240,47 +240,18 @@ public:
CallbackT callback,
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create a timer that uses the node clock to drive the callback.
/**
* \param[in] period Time interval between triggers of the callback.
* \param[in] callback User-defined callback function.
* \param[in] group Callback group to execute this timer's callback in.
*/
template<typename DurationRepT = int64_t, typename DurationT = std::milli, typename CallbackT>
typename rclcpp::GenericTimer<CallbackT>::SharedPtr
create_timer(
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a Client.
/**
* \param[in] service_name The topic to service on.
* \param[in] qos_profile rmw_qos_profile_t Quality of service profile for client.
* \param[in] group Callback group to call the service.
* \return Shared pointer to the created client.
* \deprecated use rclcpp::QoS instead of rmw_qos_profile_t
*/
template<typename ServiceT>
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
typename rclcpp::Client<ServiceT>::SharedPtr
create_client(
const std::string & service_name,
const rmw_qos_profile_t & qos_profile,
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a Client.
/**
* \param[in] service_name The name on which the service is accessible.
* \param[in] qos Quality of service profile for client.
* \param[in] group Callback group to handle the reply to service calls.
* \return Shared pointer to the created client.
*/
template<typename ServiceT>
typename rclcpp::Client<ServiceT>::SharedPtr
create_client(
const std::string & service_name,
const rclcpp::QoS & qos = rclcpp::ServicesQoS(),
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_services_default,
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a Service.
@@ -290,31 +261,13 @@ public:
* \param[in] qos_profile rmw_qos_profile_t Quality of service profile for client.
* \param[in] group Callback group to call the service.
* \return Shared pointer to the created service.
* \deprecated use rclcpp::QoS instead of rmw_qos_profile_t
*/
template<typename ServiceT, typename CallbackT>
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
typename rclcpp::Service<ServiceT>::SharedPtr
create_service(
const std::string & service_name,
CallbackT && callback,
const rmw_qos_profile_t & qos_profile,
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a Service.
/**
* \param[in] service_name The topic to service on.
* \param[in] callback User-defined callback function.
* \param[in] qos Quality of service profile for the service.
* \param[in] group Callback group to call the service.
* \return Shared pointer to the created service.
*/
template<typename ServiceT, typename CallbackT>
typename rclcpp::Service<ServiceT>::SharedPtr
create_service(
const std::string & service_name,
CallbackT && callback,
const rclcpp::QoS & qos = rclcpp::ServicesQoS(),
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_services_default,
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Create and return a GenericPublisher.
@@ -383,21 +336,11 @@ public:
*
* If `ignore_override` is `true`, the parameter override will be ignored.
*
* This method will result in any callback registered with
* `add_on_set_parameters_callback` and `add_post_set_parameters_callback`
* to be called for the parameter being set.
*
* If a callback was registered previously with `add_on_set_parameters_callback`,
* it will be called prior to setting the parameter for the node.
* This method, if successful, will result in any callback registered with
* add_on_set_parameters_callback to be called.
* If that callback prevents the initial value for the parameter from being
* set then rclcpp::exceptions::InvalidParameterValueException is thrown.
*
* If a callback was registered previously with `add_post_set_parameters_callback`,
* it will be called after setting the parameter successfully for the node.
*
* This method will _not_ result in any callbacks registered with
* `add_pre_set_parameters_callback` to be called.
*
* The returned reference will remain valid until the parameter is
* undeclared.
*
@@ -514,22 +457,11 @@ public:
* If `ignore_overrides` is `true`, all the overrides of the parameters declared
* by the function call will be ignored.
*
* This method will result in any callback registered with
* `add_on_set_parameters_callback` and `add_post_set_parameters_callback`
* to be called once for each parameter.
*
* This method, if successful, will result in any callback registered with
* `add_on_set_parameters_callback` to be called, once for each parameter.
* add_on_set_parameters_callback to be called, once for each parameter.
* If that callback prevents the initial value for any parameter from being
* set then rclcpp::exceptions::InvalidParameterValueException is thrown.
*
* If a callback was registered previously with `add_post_set_parameters_callback`,
* it will be called after setting the parameters successfully for the node,
* once for each parameter.
*
* This method will _not_ result in any callbacks registered with
* `add_pre_set_parameters_callback` to be called.
*
* \param[in] namespace_ The namespace in which to declare the parameters.
* \param[in] parameters The parameters to set in the given namespace.
* \param[in] ignore_overrides When `true`, the parameters overrides are ignored.
@@ -567,9 +499,8 @@ public:
/// Undeclare a previously declared parameter.
/**
* This method will _not_ cause a callback registered with any of the
* `add_pre_set_parameters_callback`, `add_on_set_parameters_callback` and
* `add_post_set_parameters_callback` to be called.
* This method will not cause a callback registered with
* add_on_set_parameters_callback to be called.
*
* \param[in] name The name of the parameter to be undeclared.
* \throws rclcpp::exceptions::ParameterNotDeclaredException if the parameter
@@ -603,24 +534,11 @@ public:
* Parameter overrides are ignored by set_parameter.
*
* This method will result in any callback registered with
* `add_pre_set_parameters_callback`, add_on_set_parameters_callback` and
* `add_post_set_parameters_callback` to be called once for the parameter
* being set.
*
* This method will result in any callback registered with
* `add_on_set_parameters_callback` to be called.
* add_on_set_parameters_callback to be called.
* If the callback prevents the parameter from being set, then it will be
* reflected in the SetParametersResult that is returned, but no exception
* will be thrown.
*
* If a callback was registered previously with `add_pre_set_parameters_callback`,
* it will be called once prior to the validation of the parameter for the node.
* If this callback makes modified parameter list empty, then it will be reflected
* in the returned result; no exceptions will be raised in this case.
*
* If a callback was registered previously with `add_post_set_parameters_callback`,
* it will be called once after setting the parameter successfully for the node.
*
* If the value type of the parameter is rclcpp::PARAMETER_NOT_SET, and the
* existing parameter type is something else, then the parameter will be
* implicitly undeclared.
@@ -657,25 +575,11 @@ public:
* corresponding SetParametersResult in the vector returned by this function.
*
* This method will result in any callback registered with
* `add_pre_set_parameters_callback`, `add_on_set_parameters_callback` and
* `add_post_set_parameters_callback` to be called once for each parameter.
* If a callback was registered previously with `add_pre_set_parameters_callback`,
* it will be called prior to the validation of parameters for the node,
* once for each parameter.
* If this callback makes modified parameter list empty, then it will be reflected
* in the returned result; no exceptions will be raised in this case.
*
* This method will result in any callback registered with
* `add_on_set_parameters_callback` to be called, once for each parameter.
* add_on_set_parameters_callback to be called, once for each parameter.
* If the callback prevents the parameter from being set, then, as mentioned
* before, it will be reflected in the corresponding SetParametersResult
* that is returned, but no exception will be thrown.
*
* If a callback was registered previously with `add_post_set_parameters_callback`,
* it will be called after setting the parameters successfully for the node,
* once for each parameter.
*
* Like set_parameter() this method will implicitly undeclare parameters
* with the type rclcpp::PARAMETER_NOT_SET.
*
@@ -702,25 +606,11 @@ public:
* If the exception is thrown then none of the parameters will have been set.
*
* This method will result in any callback registered with
* `add_pre_set_parameters_callback`, `add_on_set_parameters_callback` and
* `add_post_set_parameters_callback` to be called only 'once' for all parameters.
*
* If a callback was registered previously with `add_pre_set_parameters_callback`,
* it will be called prior to the validation of node parameters, just one time
* for all parameters.
* If this callback makes modified parameter list empty, then it will be reflected
* in the returned result; no exceptions will be raised in this case.
*
* This method will result in any callback registered with
* 'add_on_set_parameters_callback' to be called, just one time.
* add_on_set_parameters_callback to be called, just one time.
* If the callback prevents the parameters from being set, then it will be
* reflected in the SetParametersResult which is returned, but no exception
* will be thrown.
*
* If a callback was registered previously with `add_post_set_parameters_callback`,
* it will be called after setting the node parameters successfully, just one time
* for all parameters.
*
* If you pass multiple rclcpp::Parameter instances with the same name, then
* only the last one in the vector (forward iteration) will be set.
*
@@ -740,21 +630,17 @@ public:
/**
* If the parameter has not been declared, then this method may throw the
* rclcpp::exceptions::ParameterNotDeclaredException exception.
* If the parameter has not been initialized, then this method may throw the
* rclcpp::exceptions::ParameterUninitializedException exception.
*
* If undeclared parameters are allowed, see the node option
* rclcpp::NodeOptions::allow_undeclared_parameters, then this method will
* not throw the rclcpp::exceptions::ParameterNotDeclaredException exception,
* and instead return a default initialized rclcpp::Parameter, which has a type of
* not throw an exception, and instead return a default initialized
* rclcpp::Parameter, which has a type of
* rclcpp::ParameterType::PARAMETER_NOT_SET.
*
* \param[in] name The name of the parameter to get.
* \return The requested parameter inside of a rclcpp parameter object.
* \throws rclcpp::exceptions::ParameterNotDeclaredException if the parameter
* has not been declared and undeclared parameters are not allowed.
* \throws rclcpp::exceptions::ParameterUninitializedException if the parameter
* has not been initialized.
*/
RCLCPP_PUBLIC
rclcpp::Parameter
@@ -838,12 +724,12 @@ public:
/// Return the parameters by the given parameter names.
/**
* Like get_parameter(const std::string &), this method may throw the
* Like get_parameters(), this method may throw the
* rclcpp::exceptions::ParameterNotDeclaredException exception if the
* requested parameter has not been declared and undeclared parameters are
* not allowed, and may throw the rclcpp::exceptions::ParameterUninitializedException exception.
* not allowed.
*
* Also like get_parameter(const std::string &), if undeclared parameters are allowed and the
* Also like get_parameters(), if undeclared parameters are allowed and the
* parameter has not been declared, then the corresponding rclcpp::Parameter
* will be default initialized and therefore have the type
* rclcpp::ParameterType::PARAMETER_NOT_SET.
@@ -853,8 +739,6 @@ public:
* \throws rclcpp::exceptions::ParameterNotDeclaredException if any of the
* parameters have not been declared and undeclared parameters are not
* allowed.
* \throws rclcpp::exceptions::ParameterUninitializedException if any of the
* parameters have not been initialized.
*/
RCLCPP_PUBLIC
std::vector<rclcpp::Parameter>
@@ -975,85 +859,12 @@ public:
rcl_interfaces::msg::ListParametersResult
list_parameters(const std::vector<std::string> & prefixes, uint64_t depth) const;
using PreSetParametersCallbackHandle =
rclcpp::node_interfaces::PreSetParametersCallbackHandle;
using PreSetParametersCallbackType =
rclcpp::node_interfaces::NodeParametersInterface::PreSetParametersCallbackType;
using OnSetParametersCallbackHandle =
rclcpp::node_interfaces::OnSetParametersCallbackHandle;
using OnSetParametersCallbackType =
rclcpp::node_interfaces::NodeParametersInterface::OnSetParametersCallbackType;
using OnParametersSetCallbackType [[deprecated("use OnSetParametersCallbackType instead")]] =
OnSetParametersCallbackType;
using OnParametersSetCallbackType =
rclcpp::node_interfaces::NodeParametersInterface::OnParametersSetCallbackType;
using PostSetParametersCallbackHandle =
rclcpp::node_interfaces::PostSetParametersCallbackHandle;
using PostSetParametersCallbackType =
rclcpp::node_interfaces::NodeParametersInterface::PostSetParametersCallbackType;
/// Add a callback that gets triggered before parameters are validated.
/**
* This callback can be used to modify the original list of parameters being
* set by the user.
*
* The modified list of parameters is then forwarded to the "on set parameter"
* callback for validation.
*
* The callback is called whenever any of the `set_parameter*` methods are called
* or when a set parameter service request is received.
*
* The callback takes a reference to the vector of parameters to be set.
*
* The vector of parameters may be modified by the callback.
*
* One of the use case of "pre set callback" can be updating additional parameters
* conditioned on changes to a parameter.
*
* Users should retain a copy of the returned shared pointer, as the callback
* is valid only as long as the smart pointer is alive.
*
* For an example callback:
*
*```cpp
* void
* preSetParameterCallback(std::vector<rclcpp::Parameter> & parameters)
* {
* for (auto & param : parameters) {
* if (param.get_name() == "param1") {
* parameters.push_back(rclcpp::Parameter("param2", 4.0));
* }
* }
* }
* ```
* The above callback appends 'param2' to the list of parameters to be set if
* 'param1' is being set by the user.
*
* All parameters in the vector will be set atomically.
*
* Note that the callback is only called while setting parameters with `set_parameter`,
* `set_parameters`, `set_parameters_atomically`, or externally with a parameters service.
*
* The callback is not called when parameters are declared with `declare_parameter`
* or `declare_parameters`.
*
* The callback is not called when parameters are undeclared with `undeclare_parameter`.
*
* An empty modified parameter list from the callback will result in "set_parameter*"
* returning an unsuccessful result.
*
* The `remove_pre_set_parameters_callback` can be used to deregister the callback.
*
* \param callback The callback to register.
* \returns A shared pointer. The callback is valid as long as the smart pointer is alive.
* \throws std::bad_alloc if the allocation of the PreSetParametersCallbackHandle fails.
*/
RCLCPP_PUBLIC
RCUTILS_WARN_UNUSED
PreSetParametersCallbackHandle::SharedPtr
add_pre_set_parameters_callback(PreSetParametersCallbackType callback);
/// Add a callback to validate parameters before they are set.
/// Add a callback for when parameters are being set.
/**
* The callback signature is designed to allow handling of any of the above
* `set_parameter*` or `declare_parameter*` methods, and so it takes a const
@@ -1061,9 +872,6 @@ public:
* rcl_interfaces::msg::SetParametersResult to indicate whether or not the
* parameter should be set or not, and if not why.
*
* Users should retain a copy of the returned shared pointer, as the callback
* is valid only as long as the smart pointer is alive.
*
* For an example callback:
*
* ```cpp
@@ -1095,8 +903,6 @@ public:
* this callback, so when checking a new value against the existing one, you
* must account for the case where the parameter is not yet set.
*
* The callback is not called when parameters are undeclared with `undeclare_parameter`.
*
* Some constraints like read_only are enforced before the callback is called.
*
* The callback may introspect other already set parameters (by calling any
@@ -1125,80 +931,7 @@ public:
RCLCPP_PUBLIC
RCUTILS_WARN_UNUSED
OnSetParametersCallbackHandle::SharedPtr
add_on_set_parameters_callback(OnSetParametersCallbackType callback);
/// Add a callback that gets triggered after parameters are set successfully.
/**
* The callback is called when any of the `set_parameter*` or `declare_parameter*`
* methods are successful.
*
* Users should retain a copy of the returned shared pointer, as the callback
* is valid only as long as the smart pointer is alive.
*
* The callback takes a reference to a const vector of parameters that have been
* set successfully.
*
* The post callback can be valuable as a place to cause side-effects based on
* parameter changes.
* For instance updating internally tracked class attributes once parameters
* have been changed successfully.
*
* For an example callback:
*
* ```cpp
* void
* postSetParameterCallback(const std::vector<rclcpp::Parameter> & parameters)
* {
* for(const auto & param:parameters) {
* // the internal class member can be changed after
* // successful change to param1 or param2
* if(param.get_name() == "param1") {
* internal_tracked_class_parameter_1_ = param.get_value<double>();
* }
* else if(param.get_name() == "param2") {
* internal_tracked_class_parameter_2_ = param.get_value<double>();
* }
* }
* }
* ```
*
* The above callback takes a const reference to list of parameters that have been
* set successfully and as a result of this updates the internally tracked class attributes
* `internal_tracked_class_parameter_1_` and `internal_tracked_class_parameter_2_`
* respectively.
*
* This callback should not modify parameters.
*
* The callback is called when parameters are declared with `declare_parameter`
* or `declare_parameters`. See `declare_parameter` or `declare_parameters` above.
*
* The callback is not called when parameters are undeclared with `undeclare_parameter`.
*
* If you want to make changes to parameters based on changes to another, use
* `add_pre_set_parameters_callback`.
*
* The `remove_post_set_parameters_callback` can be used to deregister the callback.
*
* \param callback The callback to register.
* \returns A shared pointer. The callback is valid as long as the smart pointer is alive.
* \throws std::bad_alloc if the allocation of the OnSetParametersCallbackHandle fails.
*/
RCLCPP_PUBLIC
RCUTILS_WARN_UNUSED
PostSetParametersCallbackHandle::SharedPtr
add_post_set_parameters_callback(PostSetParametersCallbackType callback);
/// Remove a callback registered with `add_pre_set_parameters_callback`.
/**
* Delete a handler returned by `add_pre_set_parameters_callback`.
*
* \param handler The callback handler to remove.
* \throws std::runtime_error if the handler was not created with `add_pre_set_parameters_callback`,
* or if it has been removed before.
*/
RCLCPP_PUBLIC
void
remove_pre_set_parameters_callback(const PreSetParametersCallbackHandle * const handler);
add_on_set_parameters_callback(OnParametersSetCallbackType callback);
/// Remove a callback registered with `add_on_set_parameters_callback`.
/**
@@ -1227,18 +960,6 @@ public:
void
remove_on_set_parameters_callback(const OnSetParametersCallbackHandle * const handler);
/// Remove a callback registered with `add_post_set_parameters_callback`.
/**
* Delete a handler returned by `add_post_set_parameters_callback`.
*
* \param handler The callback handler to remove.
* \throws std::runtime_error if the handler was not created with `add_post_set_parameters_callback`,
* or if it has been removed before.
*/
RCLCPP_PUBLIC
void
remove_post_set_parameters_callback(const PostSetParametersCallbackHandle * const handler);
/// Get the fully-qualified names of all available nodes.
/**
* The fully-qualified name includes the local namespace and name of the node.

View File

@@ -120,38 +120,6 @@ Node::create_wall_timer(
this->node_timers_.get());
}
template<typename DurationRepT, typename DurationT, typename CallbackT>
typename rclcpp::GenericTimer<CallbackT>::SharedPtr
Node::create_timer(
std::chrono::duration<DurationRepT, DurationT> period,
CallbackT callback,
rclcpp::CallbackGroup::SharedPtr group)
{
return rclcpp::create_timer(
this->get_clock(),
period,
std::move(callback),
group,
this->node_base_.get(),
this->node_timers_.get());
}
template<typename ServiceT>
typename Client<ServiceT>::SharedPtr
Node::create_client(
const std::string & service_name,
const rclcpp::QoS & qos,
rclcpp::CallbackGroup::SharedPtr group)
{
return rclcpp::create_client<ServiceT>(
node_base_,
node_graph_,
node_services_,
extend_name_with_sub_namespace(service_name, this->get_sub_namespace()),
qos,
group);
}
template<typename ServiceT>
typename Client<ServiceT>::SharedPtr
Node::create_client(
@@ -168,23 +136,6 @@ Node::create_client(
group);
}
template<typename ServiceT, typename CallbackT>
typename rclcpp::Service<ServiceT>::SharedPtr
Node::create_service(
const std::string & service_name,
CallbackT && callback,
const rclcpp::QoS & qos,
rclcpp::CallbackGroup::SharedPtr group)
{
return rclcpp::create_service<ServiceT, CallbackT>(
node_base_,
node_services_,
extend_name_with_sub_namespace(service_name, this->get_sub_namespace()),
std::forward<CallbackT>(callback),
qos,
group);
}
template<typename ServiceT, typename CallbackT>
typename rclcpp::Service<ServiceT>::SharedPtr
Node::create_service(

View File

@@ -194,6 +194,12 @@ init_tuple(NodeT & n)
{ \
return StorageClassT::template get<NodeInterfaceType>(); \
} \
\
std::shared_ptr<const NodeInterfaceType> \
get_node_ ## NodeInterfaceName ## _interface() const \
{ \
return StorageClassT::template get<NodeInterfaceType>(); \
} \
}; \
} // namespace rclcpp::node_interfaces::detail

View File

@@ -15,7 +15,7 @@
#ifndef RCLCPP__NODE_INTERFACES__NODE_BASE_HPP_
#define RCLCPP__NODE_INTERFACES__NODE_BASE_HPP_
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
@@ -39,13 +39,6 @@ class NodeBase : public NodeBaseInterface, public std::enable_shared_from_this<N
public:
RCLCPP_SMART_PTR_ALIASES_ONLY(NodeBase)
/// Constructor.
/**
* If nullptr (default) is given for the default_callback_group, one will
* be created by the constructor using the create_callback_group() method,
* but virtual dispatch will not occur so overrides of that method will not
* be used.
*/
RCLCPP_PUBLIC
NodeBase(
const std::string & node_name,
@@ -53,8 +46,7 @@ public:
rclcpp::Context::SharedPtr context,
const rcl_node_options_t & rcl_node_options,
bool use_intra_process_default,
bool enable_topic_statistics_default,
rclcpp::CallbackGroup::SharedPtr default_callback_group = nullptr);
bool enable_topic_statistics_default);
RCLCPP_PUBLIC
virtual

View File

@@ -15,10 +15,10 @@
#ifndef RCLCPP__NODE_INTERFACES__NODE_BASE_INTERFACE_HPP_
#define RCLCPP__NODE_INTERFACES__NODE_BASE_INTERFACE_HPP_
#include <atomic>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "rcl/node.h"

View File

@@ -15,7 +15,6 @@
#ifndef RCLCPP__NODE_INTERFACES__NODE_CLOCK_HPP_
#define RCLCPP__NODE_INTERFACES__NODE_CLOCK_HPP_
#include "rcl/time.h"
#include "rclcpp/clock.hpp"
#include "rclcpp/macros.hpp"
#include "rclcpp/node_interfaces/node_base_interface.hpp"
@@ -43,8 +42,7 @@ public:
rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics,
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services,
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
rcl_clock_type_t clock_type);
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging);
RCLCPP_PUBLIC
virtual
@@ -69,7 +67,7 @@ private:
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services_;
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_;
rclcpp::Clock::SharedPtr clock_;
rclcpp::Clock::SharedPtr ros_clock_;
};
} // namespace node_interfaces

View File

@@ -15,9 +15,7 @@
#ifndef RCLCPP__NODE_INTERFACES__NODE_GRAPH_HPP_
#define RCLCPP__NODE_INTERFACES__NODE_GRAPH_HPP_
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <map>
#include <memory>
#include <mutex>

View File

@@ -53,12 +53,16 @@ public:
/// Construct a TopicEndpointInfo from a rcl_topic_endpoint_info_t.
RCLCPP_PUBLIC
explicit TopicEndpointInfo(const rcl_topic_endpoint_info_t & info)
: node_name_(info.node_name),
node_namespace_(info.node_namespace),
topic_type_(info.topic_type),
endpoint_type_(static_cast<rclcpp::EndpointType>(info.endpoint_type)),
: endpoint_type_(static_cast<rclcpp::EndpointType>(info.endpoint_type)),
qos_profile_({info.qos_profile.history, info.qos_profile.depth}, info.qos_profile)
{
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());
}

View File

@@ -150,7 +150,13 @@ public:
/// NodeT::SharedPtr Constructor
template<typename NodeT>
NodeInterfaces(std::shared_ptr<NodeT> node) // NOLINT(runtime/explicit)
: NodeInterfaces(node ? *node : throw std::invalid_argument("given node pointer is nullptr"))
: NodeInterfaces(
[&]() -> NodeT & {
if (!node) {
throw std::invalid_argument("given node pointer is nullptr");
}
return *node;
}())
{}
explicit NodeInterfaces(std::shared_ptr<InterfaceTs>... args)

View File

@@ -38,18 +38,14 @@ public:
~NodeLoggingInterface() = default;
/// Return the logger of the node.
/**
* \return The logger of the node.
*/
/** \return The logger of the node. */
RCLCPP_PUBLIC
virtual
rclcpp::Logger
get_logger() const = 0;
/// Return the logger name associated with the node.
/**
* \return The logger name associated with the node.
*/
/** \return The logger name associated with the node. */
RCLCPP_PUBLIC
virtual
const char *

View File

@@ -15,10 +15,9 @@
#ifndef RCLCPP__NODE_INTERFACES__NODE_PARAMETERS_HPP_
#define RCLCPP__NODE_INTERFACES__NODE_PARAMETERS_HPP_
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <list>
#include <string>
#include <vector>
@@ -85,16 +84,6 @@ class NodeParameters : public NodeParametersInterface
public:
RCLCPP_SMART_PTR_ALIASES_ONLY(NodeParameters)
/// Constructor.
/**
* If using automatically_declare_parameters_from_overrides, overrides of
* get_parameter_overrides(), has_parameter(), declare_parameter() will not
* be respected.
* If this is an issue, pass false for
* automatically_declare_parameters_from_overrides and invoke
* perform_automatically_declare_parameters_from_overrides() manually after
* construction.
*/
RCLCPP_PUBLIC
NodeParameters(
const node_interfaces::NodeBaseInterface::SharedPtr node_base,
@@ -182,48 +171,20 @@ public:
rcl_interfaces::msg::ListParametersResult
list_parameters(const std::vector<std::string> & prefixes, uint64_t depth) const override;
RCLCPP_PUBLIC
RCUTILS_WARN_UNUSED
PreSetParametersCallbackHandle::SharedPtr
add_pre_set_parameters_callback(PreSetParametersCallbackType callback) override;
RCLCPP_PUBLIC
RCUTILS_WARN_UNUSED
OnSetParametersCallbackHandle::SharedPtr
add_on_set_parameters_callback(OnSetParametersCallbackType callback) override;
RCLCPP_PUBLIC
RCUTILS_WARN_UNUSED
PostSetParametersCallbackHandle::SharedPtr
add_post_set_parameters_callback(PostSetParametersCallbackType callback) override;
add_on_set_parameters_callback(OnParametersSetCallbackType callback) override;
RCLCPP_PUBLIC
void
remove_on_set_parameters_callback(const OnSetParametersCallbackHandle * const handler) override;
RCLCPP_PUBLIC
void
remove_post_set_parameters_callback(const PostSetParametersCallbackHandle * const handler)
override;
RCLCPP_PUBLIC
void
remove_pre_set_parameters_callback(const PreSetParametersCallbackHandle * const handler) override;
RCLCPP_PUBLIC
const std::map<std::string, rclcpp::ParameterValue> &
get_parameter_overrides() const override;
using PreSetCallbacksHandleContainer = std::list<PreSetParametersCallbackHandle::WeakPtr>;
using OnSetCallbacksHandleContainer = std::list<OnSetParametersCallbackHandle::WeakPtr>;
using PostSetCallbacksHandleContainer = std::list<PostSetParametersCallbackHandle::WeakPtr>;
using CallbacksContainerType [[deprecated("use OnSetCallbacksHandleContainer instead")]] =
OnSetCallbacksHandleContainer;
protected:
RCLCPP_PUBLIC
void
perform_automatically_declare_parameters_from_overrides();
using CallbacksContainerType = std::list<OnSetParametersCallbackHandle::WeakPtr>;
private:
RCLCPP_DISABLE_COPY(NodeParameters)
@@ -235,11 +196,9 @@ private:
// declare_parameter, etc). In those cases, this will be set to false.
bool parameter_modification_enabled_{true};
PreSetCallbacksHandleContainer pre_set_parameters_callback_container_;
OnParametersSetCallbackType on_parameters_set_callback_ = nullptr;
OnSetCallbacksHandleContainer on_set_parameters_callback_container_;
PostSetCallbacksHandleContainer post_set_parameters_callback_container_;
CallbacksContainerType on_parameters_set_callback_container_;
std::map<std::string, ParameterInfo> parameters_;

View File

@@ -15,8 +15,8 @@
#ifndef RCLCPP__NODE_INTERFACES__NODE_PARAMETERS_INTERFACE_HPP_
#define RCLCPP__NODE_INTERFACES__NODE_PARAMETERS_INTERFACE_HPP_
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>
@@ -34,38 +34,16 @@ namespace rclcpp
namespace node_interfaces
{
struct PreSetParametersCallbackHandle
{
RCLCPP_SMART_PTR_DEFINITIONS(PreSetParametersCallbackHandle)
using PreSetParametersCallbackType =
std::function<void (std::vector<rclcpp::Parameter> &)>;
PreSetParametersCallbackType callback;
};
struct OnSetParametersCallbackHandle
{
RCLCPP_SMART_PTR_DEFINITIONS(OnSetParametersCallbackHandle)
using OnSetParametersCallbackType =
using OnParametersSetCallbackType =
std::function<
rcl_interfaces::msg::SetParametersResult(
const std::vector<rclcpp::Parameter> &)>;
using OnParametersSetCallbackType [[deprecated("use OnSetParametersCallbackType instead")]] =
OnSetParametersCallbackType;
OnSetParametersCallbackType callback;
};
struct PostSetParametersCallbackHandle
{
RCLCPP_SMART_PTR_DEFINITIONS(PostSetParametersCallbackHandle)
using PostSetParametersCallbackType =
std::function<void (const std::vector<rclcpp::Parameter> &)>;
PostSetParametersCallbackType callback;
OnParametersSetCallbackType callback;
};
/// Pure virtual interface class for the NodeParameters part of the Node API.
@@ -208,46 +186,16 @@ public:
rcl_interfaces::msg::ListParametersResult
list_parameters(const std::vector<std::string> & prefixes, uint64_t depth) const = 0;
using OnSetParametersCallbackType = OnSetParametersCallbackHandle::OnSetParametersCallbackType;
using PostSetParametersCallbackType =
PostSetParametersCallbackHandle::PostSetParametersCallbackType;
using PreSetParametersCallbackType = PreSetParametersCallbackHandle::PreSetParametersCallbackType;
using OnParametersSetCallbackType = OnSetParametersCallbackHandle::OnParametersSetCallbackType;
/// Add a callback that gets triggered before parameters are validated.
/**
* \sa rclcpp::Node::add_pre_set_parameters_callback
*/
RCLCPP_PUBLIC
virtual
PreSetParametersCallbackHandle::SharedPtr
add_pre_set_parameters_callback(PreSetParametersCallbackType callback) = 0;
/// Add a callback to validate parameters before they are set.
/// Add a callback for when parameters are being set.
/**
* \sa rclcpp::Node::add_on_set_parameters_callback
*/
RCLCPP_PUBLIC
virtual
OnSetParametersCallbackHandle::SharedPtr
add_on_set_parameters_callback(OnSetParametersCallbackType callback) = 0;
/// Add a callback that gets triggered after parameters are set successfully.
/**
* \sa rclcpp::Node::add_post_set_parameters_callback
*/
RCLCPP_PUBLIC
virtual
PostSetParametersCallbackHandle::SharedPtr
add_post_set_parameters_callback(PostSetParametersCallbackType callback) = 0;
/// Remove a callback registered with `add_pre_set_parameters_callback`.
/**
* \sa rclcpp::Node::remove_pre_set_parameters_callback
*/
RCLCPP_PUBLIC
virtual
void
remove_pre_set_parameters_callback(const PreSetParametersCallbackHandle * const handler) = 0;
add_on_set_parameters_callback(OnParametersSetCallbackType callback) = 0;
/// Remove a callback registered with `add_on_set_parameters_callback`.
/**
@@ -258,15 +206,6 @@ public:
void
remove_on_set_parameters_callback(const OnSetParametersCallbackHandle * const handler) = 0;
/// Remove a callback registered with `add_post_set_parameters_callback`.
/**
* \sa rclcpp::Node::remove_post_set_parameters_callback
*/
RCLCPP_PUBLIC
virtual
void
remove_post_set_parameters_callback(const PostSetParametersCallbackHandle * const handler) = 0;
/// Return the initial parameter values used by the NodeParameters to override default values.
RCLCPP_PUBLIC
virtual

View File

@@ -15,6 +15,8 @@
#ifndef RCLCPP__NODE_INTERFACES__NODE_TOPICS_INTERFACE_HPP_
#define RCLCPP__NODE_INTERFACES__NODE_TOPICS_INTERFACE_HPP_
#include <functional>
#include <memory>
#include <string>
#include "rcl/publisher.h"

View File

@@ -19,7 +19,6 @@
#include <string>
#include <vector>
#include "rcl/time.h"
#include "rcl/node_options.h"
#include "rclcpp/context.hpp"
#include "rclcpp/contexts/default_context.hpp"
@@ -43,11 +42,11 @@ public:
* - arguments = {}
* - parameter_overrides = {}
* - use_global_arguments = true
* - enable_rosout = true
* - use_intra_process_comms = false
* - enable_topic_statistics = false
* - start_parameter_services = true
* - start_parameter_event_publisher = true
* - clock_type = RCL_ROS_TIME
* - clock_qos = rclcpp::ClockQoS()
* - use_clock_thread = true
* - rosout_qos = rclcpp::RosoutQoS()
@@ -248,19 +247,6 @@ public:
NodeOptions &
start_parameter_event_publisher(bool start_parameter_event_publisher);
/// Return a reference to the clock type.
RCLCPP_PUBLIC
const rcl_clock_type_t &
clock_type() const;
/// Set the clock type.
/**
* The clock type to be used by the node.
*/
RCLCPP_PUBLIC
NodeOptions &
clock_type(const rcl_clock_type_t & clock_type);
/// Return a reference to the clock QoS.
RCLCPP_PUBLIC
const rclcpp::QoS &
@@ -415,8 +401,6 @@ private:
bool start_parameter_event_publisher_ {true};
rcl_clock_type_t clock_type_ {RCL_ROS_TIME};
rclcpp::QoS clock_qos_ = rclcpp::ClockQoS();
bool use_clock_thread_ {true};

View File

@@ -39,7 +39,6 @@
#include "rclcpp/node.hpp"
#include "rclcpp/parameter.hpp"
#include "rclcpp/parameter_map.hpp"
#include "rclcpp/qos.hpp"
#include "rclcpp/type_support_decl.hpp"
#include "rclcpp/visibility_control.hpp"
#include "rmw/rmw.h"
@@ -52,37 +51,6 @@ class AsyncParametersClient
public:
RCLCPP_SMART_PTR_DEFINITIONS(AsyncParametersClient)
/// Create an async parameters client.
/**
* \param[in] node_base_interface The node base interface of the corresponding node.
* \param[in] node_topics_interface Node topic base interface.
* \param[in] node_graph_interface The node graph interface of the corresponding node.
* \param[in] node_services_interface Node service interface.
* \param[in] remote_node_name Name of the remote node
* \param[in] qos_profile The rmw qos profile to use to subscribe
* \param[in] group (optional) The async parameter client will be added to this callback group.
* \deprecated use rclcpp::QoS instead of rmw_qos_profile_t
*/
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
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 std::string & remote_node_name,
const rmw_qos_profile_t & qos_profile,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
: AsyncParametersClient(
node_base_interface,
node_topics_interface,
node_graph_interface,
node_services_interface,
remote_node_name,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)),
group)
{}
/// Create an async parameters client.
/**
* \param[in] node_base_interface The node base interface of the corresponding node.
@@ -90,7 +58,7 @@ public:
* \param[in] node_graph_interface The node graph interface of the corresponding node.
* \param[in] node_services_interface Node service interface.
* \param[in] remote_node_name (optional) name of the remote node
* \param[in] qos_profile (optional) The qos profile to use to subscribe
* \param[in] qos_profile (optional) The rmw qos profile to use to subscribe
* \param[in] group (optional) The async parameter client will be added to this callback group.
*/
RCLCPP_PUBLIC
@@ -100,45 +68,21 @@ public:
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 rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters,
rclcpp::CallbackGroup::SharedPtr group = nullptr);
/// Constructor
/**
* \param[in] node The async parameters client will be added to this node.
* \param[in] remote_node_name name of the remote node
* \param[in] qos_profile The rmw qos profile to use to subscribe
* \param[in] group (optional) The async parameter client will be added to this callback group.
* \deprecated use rclcpp::QoS instead of rmw_qos_profile_t
*/
template<typename NodeT>
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
AsyncParametersClient(
const std::shared_ptr<NodeT> node,
const std::string & remote_node_name,
const rmw_qos_profile_t & qos_profile,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
: AsyncParametersClient(
node->get_node_base_interface(),
node->get_node_topics_interface(),
node->get_node_graph_interface(),
node->get_node_services_interface(),
remote_node_name,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)),
group)
{}
/**
* \param[in] node The async parameters client will be added to this node.
* \param[in] node The async paramters client will be added to this node.
* \param[in] remote_node_name (optional) name of the remote node
* \param[in] qos_profile (optional) The qos profile to use to subscribe
* \param[in] qos_profile (optional) The rmw qos profile to use to subscribe
* \param[in] group (optional) The async parameter client will be added to this callback group.
*/
template<typename NodeT>
explicit AsyncParametersClient(
const std::shared_ptr<NodeT> node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS(),
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
: AsyncParametersClient(
node->get_node_base_interface(),
@@ -152,40 +96,16 @@ public:
/// Constructor
/**
* \param[in] node The async parameters client will be added to this node.
* \param[in] remote_node_name Name of the remote node
* \param[in] qos_profile The rmw qos profile to use to subscribe
* \param[in] group (optional) The async parameter client will be added to this callback group.
* \deprecated use rclcpp::QoS instead of rmw_qos_profile_t
*/
template<typename NodeT>
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
AsyncParametersClient(
NodeT * node,
const std::string & remote_node_name,
const rmw_qos_profile_t & qos_profile,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
: AsyncParametersClient(
node->get_node_base_interface(),
node->get_node_topics_interface(),
node->get_node_graph_interface(),
node->get_node_services_interface(),
remote_node_name,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)),
group)
{}
/**
* \param[in] node The async parameters client will be added to this node.
* \param[in] node The async paramters client will be added to this node.
* \param[in] remote_node_name (optional) name of the remote node
* \param[in] qos_profile (optional) The qos profile to use to subscribe
* \param[in] qos_profile (optional) The rmw qos profile to use to subscribe
* \param[in] group (optional) The async parameter client will be added to this callback group.
*/
template<typename NodeT>
explicit AsyncParametersClient(
NodeT * node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS(),
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters,
rclcpp::CallbackGroup::SharedPtr group = nullptr)
: AsyncParametersClient(
node->get_node_base_interface(),
@@ -265,9 +185,6 @@ public:
/**
* This function filters the parameters to be set based on the node name.
*
* If two duplicate keys exist in node names belongs to one FQN, there is no guarantee
* which one could be set.
*
* \param parameter_map named parameters to be loaded
* \return the future of the set_parameter service used to load the parameters
* \throw InvalidParametersException if there is no parameter to set
@@ -291,7 +208,9 @@ public:
typename rclcpp::Subscription<rcl_interfaces::msg::ParameterEvent>::SharedPtr
on_parameter_event(
CallbackT && callback,
const rclcpp::QoS & qos = rclcpp::ParameterEventsQoS(),
const rclcpp::QoS & qos = (
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(rmw_qos_profile_parameter_events))
),
const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & options = (
rclcpp::SubscriptionOptionsWithAllocator<AllocatorT>()
))
@@ -316,7 +235,9 @@ public:
on_parameter_event(
NodeT && node,
CallbackT && callback,
const rclcpp::QoS & qos = rclcpp::ParameterEventsQoS(),
const rclcpp::QoS & qos = (
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(rmw_qos_profile_parameter_events))
),
const rclcpp::SubscriptionOptionsWithAllocator<AllocatorT> & options = (
rclcpp::SubscriptionOptionsWithAllocator<AllocatorT>()
))
@@ -383,24 +304,11 @@ class SyncParametersClient
public:
RCLCPP_SMART_PTR_DEFINITIONS(SyncParametersClient)
template<typename NodeT>
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
SyncParametersClient(
std::shared_ptr<NodeT> node,
const std::string & remote_node_name,
const rmw_qos_profile_t & qos_profile)
: SyncParametersClient(
std::make_shared<rclcpp::executors::SingleThreadedExecutor>(),
node,
remote_node_name,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)))
{}
template<typename NodeT>
explicit SyncParametersClient(
std::shared_ptr<NodeT> node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS())
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters)
: SyncParametersClient(
std::make_shared<rclcpp::executors::SingleThreadedExecutor>(),
node,
@@ -408,29 +316,12 @@ public:
qos_profile)
{}
template<typename NodeT>
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
SyncParametersClient(
rclcpp::Executor::SharedPtr executor,
std::shared_ptr<NodeT> node,
const std::string & remote_node_name,
const rmw_qos_profile_t & qos_profile)
: SyncParametersClient(
executor,
node->get_node_base_interface(),
node->get_node_topics_interface(),
node->get_node_graph_interface(),
node->get_node_services_interface(),
remote_node_name,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)))
{}
template<typename NodeT>
SyncParametersClient(
rclcpp::Executor::SharedPtr executor,
std::shared_ptr<NodeT> node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS())
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters)
: SyncParametersClient(
executor,
node->get_node_base_interface(),
@@ -441,24 +332,11 @@ public:
qos_profile)
{}
template<typename NodeT>
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
SyncParametersClient(
NodeT * node,
const std::string & remote_node_name,
const rmw_qos_profile_t & qos_profile)
: SyncParametersClient(
std::make_shared<rclcpp::executors::SingleThreadedExecutor>(),
node,
remote_node_name,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)))
{}
template<typename NodeT>
explicit SyncParametersClient(
NodeT * node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS())
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters)
: SyncParametersClient(
std::make_shared<rclcpp::executors::SingleThreadedExecutor>(),
node,
@@ -466,29 +344,12 @@ public:
qos_profile)
{}
template<typename NodeT>
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
SyncParametersClient(
rclcpp::Executor::SharedPtr executor,
NodeT * node,
const std::string & remote_node_name,
const rmw_qos_profile_t & qos_profile)
: SyncParametersClient(
executor,
node->get_node_base_interface(),
node->get_node_topics_interface(),
node->get_node_graph_interface(),
node->get_node_services_interface(),
remote_node_name,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)))
{}
template<typename NodeT>
SyncParametersClient(
rclcpp::Executor::SharedPtr executor,
NodeT * node,
const std::string & remote_node_name = "",
const rclcpp::QoS & qos_profile = rclcpp::ParametersQoS())
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters)
: SyncParametersClient(
executor,
node->get_node_base_interface(),
@@ -499,28 +360,6 @@ public:
qos_profile)
{}
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
RCLCPP_PUBLIC
SyncParametersClient(
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 rmw_qos_profile_t & qos_profile)
: executor_(executor), node_base_interface_(node_base_interface)
{
async_parameters_client_ =
std::make_shared<AsyncParametersClient>(
node_base_interface,
node_topics_interface,
node_graph_interface,
node_services_interface,
remote_node_name,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)));
}
RCLCPP_PUBLIC
SyncParametersClient(
rclcpp::Executor::SharedPtr executor,
@@ -529,7 +368,7 @@ public:
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 rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters)
: executor_(executor), node_base_interface_(node_base_interface)
{
async_parameters_client_ =

View File

@@ -86,9 +86,6 @@ struct ParameterEventCallbackHandle
* the ROS node supplied in the ParameterEventHandler constructor.
* The callback, a lambda function in this case, simply prints out the value of the parameter.
*
* Note: the object returned from add_parameter_callback must be captured or the callback will
* be immediately unregistered.
*
* You may also monitor for changes to parameters in other nodes by supplying the node
* name to add_parameter_callback:
*
@@ -106,8 +103,8 @@ struct ParameterEventCallbackHandle
* In this case, the callback will be invoked whenever "some_remote_param_name" changes
* on remote node "some_remote_node_name".
*
* To remove a parameter callback, reset the callback handle smart pointer or call
* remove_parameter_callback, passing the handle returned from add_parameter_callback:
* To remove a parameter callback, call remove_parameter_callback, passing the handle returned
* from add_parameter_callback:
*
* param_handler->remove_parameter_callback(handle2);
*
@@ -155,12 +152,9 @@ struct ParameterEventCallbackHandle
* For both parameter callbacks and parameter event callbacks, when multiple callbacks are added,
* the callbacks are invoked last-in, first-called order (LIFO).
*
* Note: the callback handle returned from add_parameter_event_callback must be captured or
* the callback will immediately be unregistered.
* To remove a parameter event callback, use:
*
* To remove a parameter event callback, reset the callback smart pointer or use:
*
* param_handler->remove_event_parameter_callback(handle3);
* param_handler->remove_event_parameter_callback(handle);
*/
class ParameterEventHandler
{
@@ -195,14 +189,10 @@ public:
/**
* This function may be called multiple times to set multiple parameter event callbacks.
*
* Note: if the returned callback handle smart pointer is not captured, the callback is
* immediatedly unregistered. A compiler warning should be generated to warn of this.
*
* \param[in] callback Function callback to be invoked on parameter updates.
* \returns A handle used to refer to the callback.
*/
RCLCPP_PUBLIC
RCUTILS_WARN_UNUSED
ParameterEventCallbackHandle::SharedPtr
add_parameter_event_callback(
ParameterEventCallbackType callback);
@@ -222,17 +212,12 @@ public:
/**
* If a node_name is not provided, defaults to the current node.
*
* 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.
*
* \param[in] parameter_name Name of parameter to monitor.
* \param[in] callback Function callback to be invoked upon parameter update.
* \param[in] node_name Name of node which hosts the parameter.
* \returns A handle used to refer to the callback.
*/
RCLCPP_PUBLIC
RCUTILS_WARN_UNUSED
ParameterCallbackHandle::SharedPtr
add_parameter_callback(
const std::string & parameter_name,
@@ -283,7 +268,6 @@ public:
* \param[in] parameter_name Name of parameter.
* \param[in] node_name Name of node which hosts the parameter.
* \returns The resultant rclcpp::Parameter from the event.
* \throws std::runtime_error if input node name doesn't match the node name in parameter event.
*/
RCLCPP_PUBLIC
static rclcpp::Parameter

View File

@@ -45,6 +45,7 @@ public:
* \param[in] names A list of parameter names of interest.
* \param[in] types A list of the types of parameter events of iterest.
* EventType NEW, DELETED, or CHANGED
* \throws std::invalid_argument if event is NULL.
*
* Example Usage:
*

View File

@@ -33,6 +33,14 @@ namespace rclcpp
/// A map of fully qualified node names to a list of parameters
using ParameterMap = std::unordered_map<std::string, std::vector<Parameter>>;
/// Convert parameters from rcl_yaml_param_parser into C++ class instances.
/// \param[in] c_params C structures containing parameters for multiple nodes.
/// \returns a map where the keys are fully qualified node names and values a list of parameters.
/// \throws InvalidParametersException if the `rcl_params_t` is inconsistent or invalid.
RCLCPP_PUBLIC
ParameterMap
parameter_map_from(const rcl_params_t * const c_params);
/// Convert parameters from rcl_yaml_param_parser into C++ class instances.
/// \param[in] c_params C structures containing parameters for multiple nodes.
/// \param[in] node_fqn a Fully Qualified Name of node, default value is nullptr.
@@ -41,7 +49,7 @@ using ParameterMap = std::unordered_map<std::string, std::vector<Parameter>>;
/// \throws InvalidParametersException if the `rcl_params_t` is inconsistent or invalid.
RCLCPP_PUBLIC
ParameterMap
parameter_map_from(const rcl_params_t * const c_params, const char * node_fqn = nullptr);
parameter_map_from(const rcl_params_t * const c_params, const char * node_fqn);
/// Convert parameter value from rcl_yaml_param_parser into a C++ class instance.
/// \param[in] c_value C structure containing a value of a parameter.
@@ -53,20 +61,11 @@ parameter_value_from(const rcl_variant_t * const c_value);
/// Get the ParameterMap from a yaml file.
/// \param[in] yaml_filename full name of the yaml file.
/// \param[in] node_fqn a Fully Qualified Name of node, default value is nullptr.
/// \returns an instance of a parameter map
/// \throws from rcl error of rcl_parse_yaml_file()
RCLCPP_PUBLIC
ParameterMap
parameter_map_from_yaml_file(const std::string & yaml_filename, const char * node_fqn = nullptr);
/// Get the Parameters from ParameterMap.
/// \param[in] parameter_map a parameter map.
/// \param[in] node_fqn a Fully Qualified Name of node, default value is nullptr.
/// \returns a list of a parameter
RCLCPP_PUBLIC
std::vector<Parameter>
parameters_from_map(const ParameterMap & parameter_map, const char * node_fqn = nullptr);
parameter_map_from_yaml_file(const std::string & yaml_filename);
} // namespace rclcpp

View File

@@ -28,7 +28,6 @@
#include "rclcpp/macros.hpp"
#include "rclcpp/node.hpp"
#include "rclcpp/parameter.hpp"
#include "rclcpp/qos.hpp"
#include "rclcpp/visibility_control.hpp"
#include "rmw/rmw.h"
@@ -40,26 +39,12 @@ class ParameterService
public:
RCLCPP_SMART_PTR_DEFINITIONS(ParameterService)
[[deprecated("use rclcpp::QoS instead of rmw_qos_profile_t")]]
RCLCPP_PUBLIC
ParameterService(
explicit ParameterService(
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 rmw_qos_profile_t & qos_profile)
: ParameterService(
node_base,
node_services,
node_params,
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile)))
{}
RCLCPP_PUBLIC
ParameterService(
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());
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_parameters);
private:
rclcpp::Service<rcl_interfaces::srv::GetParameters>::SharedPtr get_parameters_service_;

View File

@@ -131,16 +131,40 @@ public:
node_base,
topic,
rclcpp::get_message_type_support_handle<MessageT>(),
options.template to_rcl_publisher_options<MessageT>(qos),
// NOTE(methylDragon): Passing these args separately is necessary for event binding
options.event_callbacks,
options.use_default_callbacks),
options.template to_rcl_publisher_options<MessageT>(qos)),
options_(options),
published_type_allocator_(*options.get_allocator()),
ros_message_type_allocator_(*options.get_allocator())
{
allocator::set_allocator_for_deleter(&published_type_deleter_, &published_type_allocator_);
allocator::set_allocator_for_deleter(&ros_message_type_deleter_, &ros_message_type_allocator_);
if (options_.event_callbacks.deadline_callback) {
this->add_event_handler(
options_.event_callbacks.deadline_callback,
RCL_PUBLISHER_OFFERED_DEADLINE_MISSED);
}
if (options_.event_callbacks.liveliness_callback) {
this->add_event_handler(
options_.event_callbacks.liveliness_callback,
RCL_PUBLISHER_LIVELINESS_LOST);
}
if (options_.event_callbacks.incompatible_qos_callback) {
this->add_event_handler(
options_.event_callbacks.incompatible_qos_callback,
RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS);
} else if (options_.use_default_callbacks) {
// Register default callback when not specified
try {
this->add_event_handler(
[this](QOSOfferedIncompatibleQoSInfo & info) {
this->default_incompatible_qos_callback(info);
},
RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS);
} catch (UnsupportedEventTypeException & /*exc*/) {
// pass
}
}
// Setup continues in the post construction method, post_init_setup().
}
@@ -153,8 +177,7 @@ public:
const rclcpp::QoS & qos,
const rclcpp::PublisherOptionsWithAllocator<AllocatorT> & options)
{
// Topic is unused for now.
(void)topic;
(void)qos;
(void)options;
// If needed, setup intra process communication.
@@ -162,19 +185,23 @@ public:
auto context = node_base->get_context();
// Get the intra process manager instance for this context.
auto ipm = context->get_sub_context<rclcpp::experimental::IntraProcessManager>();
// Register the publisher with the intra process manager.
if (qos.history() != rclcpp::HistoryPolicy::KeepLast) {
// Check if the QoS is compatible with intra-process.
auto qos_profile = get_actual_qos();
if (qos_profile.history() != rclcpp::HistoryPolicy::KeepLast) {
throw std::invalid_argument(
"intraprocess communication allowed only with keep last history qos policy");
"intraprocess communication on topic '" + topic +
"' allowed only with keep last history qos policy");
}
if (qos.depth() == 0) {
if (qos_profile.depth() == 0) {
throw std::invalid_argument(
"intraprocess communication is not allowed with a zero qos history depth value");
"intraprocess communication on topic '" + topic +
"' is not allowed with a zero qos history depth value");
}
if (qos.durability() != rclcpp::DurabilityPolicy::Volatile) {
if (qos_profile.durability() != rclcpp::DurabilityPolicy::Volatile) {
throw std::invalid_argument(
"intraprocess communication allowed only with volatile durability");
}
// Register the publisher with the intra process manager.
uint64_t intra_process_publisher_id = ipm->add_publisher(this->shared_from_this());
this->setup_intra_process(
intra_process_publisher_id,

View File

@@ -78,18 +78,11 @@ public:
rclcpp::node_interfaces::NodeBaseInterface * node_base,
const std::string & topic,
const rosidl_message_type_support_t & type_support,
const rcl_publisher_options_t & publisher_options,
const PublisherEventCallbacks & event_callbacks,
bool use_default_callbacks);
const rcl_publisher_options_t & publisher_options);
RCLCPP_PUBLIC
virtual ~PublisherBase();
/// Add event handlers for passed in event_callbacks.
RCLCPP_PUBLIC
void
bind_event_callbacks(const PublisherEventCallbacks & event_callbacks, bool use_default_callbacks);
/// Get the topic that this publisher publishes on.
/** \return The topic name. */
RCLCPP_PUBLIC
@@ -355,8 +348,6 @@ protected:
rmw_gid_t rmw_gid_;
const rosidl_message_type_support_t type_support_;
const PublisherEventCallbacks event_callbacks_;
};
} // namespace rclcpp

View File

@@ -119,6 +119,10 @@ private:
rcl_allocator_t
get_rcl_allocator() const
{
if constexpr (std::is_same_v<Allocator, std::allocator<void>>) {
return rcl_get_default_allocator();
}
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());

View File

@@ -44,7 +44,6 @@ enum class ReliabilityPolicy
BestEffort = RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT,
Reliable = RMW_QOS_POLICY_RELIABILITY_RELIABLE,
SystemDefault = RMW_QOS_POLICY_RELIABILITY_SYSTEM_DEFAULT,
BestAvailable = RMW_QOS_POLICY_RELIABILITY_BEST_AVAILABLE,
Unknown = RMW_QOS_POLICY_RELIABILITY_UNKNOWN,
};
@@ -53,7 +52,6 @@ enum class DurabilityPolicy
Volatile = RMW_QOS_POLICY_DURABILITY_VOLATILE,
TransientLocal = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL,
SystemDefault = RMW_QOS_POLICY_DURABILITY_SYSTEM_DEFAULT,
BestAvailable = RMW_QOS_POLICY_DURABILITY_BEST_AVAILABLE,
Unknown = RMW_QOS_POLICY_DURABILITY_UNKNOWN,
};
@@ -62,7 +60,6 @@ enum class LivelinessPolicy
Automatic = RMW_QOS_POLICY_LIVELINESS_AUTOMATIC,
ManualByTopic = RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC,
SystemDefault = RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT,
BestAvailable = RMW_QOS_POLICY_LIVELINESS_BEST_AVAILABLE,
Unknown = RMW_QOS_POLICY_LIVELINESS_UNKNOWN,
};
@@ -183,10 +180,6 @@ public:
QoS &
best_effort();
/// Set the reliability setting to best available.
QoS &
reliability_best_available();
/// Set the durability setting.
QoS &
durability(rmw_qos_durability_policy_t durability);
@@ -206,10 +199,6 @@ public:
QoS &
transient_local();
/// Set the durability setting to best available.
QoS &
durability_best_available();
/// Set the deadline setting.
QoS &
deadline(rmw_time_t deadline);
@@ -499,36 +488,6 @@ public:
));
};
/**
* Best available QoS class
*
* Match majority of endpoints currently available while maintaining the highest level of service.
* Policies are chosen at the time of creating a subscription or publisher.
* The middleware is not expected to update policies after creating a subscription or publisher,
* even if one or more policies are incompatible with newly discovered endpoints.
* Therefore, this profile should be used with care since non-deterministic behavior can occur due
* to races with discovery.
*
* - History: Keep last,
* - Depth: 10,
* - Reliability: Best available,
* - Durability: Best available,
* - Deadline: Best available,
* - Lifespan: Default,
* - Liveliness: Best available,
* - Liveliness lease duration: Best available,
* - avoid ros namespace conventions: false
*/
class RCLCPP_PUBLIC BestAvailableQoS : public QoS
{
public:
explicit
BestAvailableQoS(
const QoSInitialization & qos_initialization = (
QoSInitialization::from_rmw(rmw_qos_profile_best_available)
));
};
} // namespace rclcpp
#endif // RCLCPP__QOS_HPP_

View File

@@ -185,7 +185,7 @@ public:
// This two-step setting, prevents a gap where the old std::function has
// been replaced but the middleware hasn't been told about the new one yet.
set_on_new_event_callback(
rclcpp::detail::cpp_callback_trampoline<decltype(new_callback), const void *, size_t>,
rclcpp::detail::cpp_callback_trampoline<const void *, size_t>,
static_cast<const void *>(&new_callback));
// Store the std::function to keep it in scope, also overwrites the existing one.
@@ -193,8 +193,7 @@ public:
// Set it again, now using the permanent storage.
set_on_new_event_callback(
rclcpp::detail::cpp_callback_trampoline<
decltype(on_new_event_callback_), const void *, size_t>,
rclcpp::detail::cpp_callback_trampoline<const void *, size_t>,
static_cast<const void *>(&on_new_event_callback_));
}

View File

@@ -55,7 +55,7 @@ public:
explicit ServiceBase(std::shared_ptr<rcl_node_t> node_handle);
RCLCPP_PUBLIC
virtual ~ServiceBase() = default;
virtual ~ServiceBase();
/// Return the name of the service.
/** \return The name of the service. */
@@ -222,7 +222,7 @@ public:
// This two-step setting, prevents a gap where the old std::function has
// been replaced but the middleware hasn't been told about the new one yet.
set_on_new_request_callback(
rclcpp::detail::cpp_callback_trampoline<decltype(new_callback), const void *, size_t>,
rclcpp::detail::cpp_callback_trampoline<const void *, size_t>,
static_cast<const void *>(&new_callback));
// Store the std::function to keep it in scope, also overwrites the existing one.
@@ -230,8 +230,7 @@ public:
// Set it again, now using the permanent storage.
set_on_new_request_callback(
rclcpp::detail::cpp_callback_trampoline<
decltype(on_new_request_callback_), const void *, size_t>,
rclcpp::detail::cpp_callback_trampoline<const void *, size_t>,
static_cast<const void *>(&on_new_request_callback_));
}
@@ -482,6 +481,14 @@ public:
{
rcl_ret_t ret = rcl_send_response(get_service_handle().get(), &req_id, &response);
if (ret == RCL_RET_TIMEOUT) {
RCLCPP_WARN(
node_logger_.get_child("rclcpp"),
"failed to send response to %s (timeout): %s",
this->get_service_name(), rcl_get_error_string().str);
rcl_reset_error();
return;
}
if (ret != RCL_RET_OK) {
rclcpp::exceptions::throw_from_rcl_error(ret, "failed to send response");
}

View File

@@ -424,7 +424,11 @@ public:
rcl_allocator_t get_allocator() override
{
return rclcpp::allocator::get_rcl_allocator<void *, VoidAlloc>(*allocator_.get());
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());
}
}
size_t number_of_ready_subscriptions() const override

View File

@@ -140,15 +140,44 @@ public:
node_base,
type_support_handle,
topic_name,
options.to_rcl_subscription_options(qos),
// NOTE(methylDragon): Passing these args separately is necessary for event binding
options.event_callbacks,
options.use_default_callbacks,
options.template to_rcl_subscription_options<ROSMessageType>(qos),
callback.is_serialized_message_callback()),
any_callback_(callback),
options_(options),
message_memory_strategy_(message_memory_strategy)
{
if (options_.event_callbacks.deadline_callback) {
this->add_event_handler(
options_.event_callbacks.deadline_callback,
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED);
}
if (options_.event_callbacks.liveliness_callback) {
this->add_event_handler(
options_.event_callbacks.liveliness_callback,
RCL_SUBSCRIPTION_LIVELINESS_CHANGED);
}
if (options_.event_callbacks.incompatible_qos_callback) {
this->add_event_handler(
options_.event_callbacks.incompatible_qos_callback,
RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS);
} else if (options_.use_default_callbacks) {
// Register default callback when not specified
try {
this->add_event_handler(
[this](QOSRequestedIncompatibleQoSInfo & info) {
this->default_incompatible_qos_callback(info);
},
RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS);
} catch (UnsupportedEventTypeException & /*exc*/) {
// pass
}
}
if (options_.event_callbacks.message_lost_callback) {
this->add_event_handler(
options_.event_callbacks.message_lost_callback,
RCL_SUBSCRIPTION_MESSAGE_LOST);
}
// Setup intra process publishing if requested.
if (rclcpp::detail::resolve_use_intra_process(options_, *node_base)) {
using rclcpp::detail::resolve_intra_process_buffer_type;
@@ -157,11 +186,13 @@ public:
auto qos_profile = get_actual_qos();
if (qos_profile.history() != rclcpp::HistoryPolicy::KeepLast) {
throw std::invalid_argument(
"intraprocess communication allowed only with keep last history qos policy");
"intraprocess communication on topic '" + topic_name +
"' allowed only with keep last history qos policy");
}
if (qos_profile.depth() == 0) {
throw std::invalid_argument(
"intraprocess communication is not allowed with 0 depth qos policy");
"intraprocess communication on topic '" + topic_name +
"' is not allowed with 0 depth qos policy");
}
if (qos_profile.durability() != rclcpp::DurabilityPolicy::Volatile) {
throw std::invalid_argument(

View File

@@ -84,20 +84,12 @@ public:
const rosidl_message_type_support_t & type_support_handle,
const std::string & topic_name,
const rcl_subscription_options_t & subscription_options,
const SubscriptionEventCallbacks & event_callbacks,
bool use_default_callbacks,
bool is_serialized = false);
/// Destructor.
RCLCPP_PUBLIC
virtual ~SubscriptionBase();
/// Add event handlers for passed in event_callbacks.
RCLCPP_PUBLIC
void
bind_event_callbacks(
const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks);
/// Get the topic that this subscription is subscribed on.
RCLCPP_PUBLIC
const char *
@@ -356,7 +348,7 @@ public:
// This two-step setting, prevents a gap where the old std::function has
// been replaced but the middleware hasn't been told about the new one yet.
set_on_new_message_callback(
rclcpp::detail::cpp_callback_trampoline<decltype(new_callback), const void *, size_t>,
rclcpp::detail::cpp_callback_trampoline<const void *, size_t>,
static_cast<const void *>(&new_callback));
// Store the std::function to keep it in scope, also overwrites the existing one.
@@ -364,8 +356,7 @@ public:
// Set it again, now using the permanent storage.
set_on_new_message_callback(
rclcpp::detail::cpp_callback_trampoline<
decltype(on_new_message_callback_), const void *, size_t>,
rclcpp::detail::cpp_callback_trampoline<const void *, size_t>,
static_cast<const void *>(&on_new_message_callback_));
}
@@ -578,8 +569,6 @@ protected:
uint64_t intra_process_subscription_id_;
std::shared_ptr<rclcpp::experimental::SubscriptionIntraProcessBase> subscription_intra_process_;
const SubscriptionEventCallbacks event_callbacks_;
private:
RCLCPP_DISABLE_COPY(SubscriptionBase)

View File

@@ -110,6 +110,7 @@ struct SubscriptionOptionsWithAllocator : public SubscriptionOptionsBase
* \param qos QoS profile for subcription.
* \return rcl_subscription_options_t structure based on the rclcpp::QoS
*/
template<typename MessageT>
rcl_subscription_options_t
to_rcl_subscription_options(const rclcpp::QoS & qos) const
{
@@ -162,11 +163,15 @@ private:
rcl_allocator_t
get_rcl_allocator() const
{
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
if constexpr (std::is_same_v<Allocator, std::allocator<void>>) {
return rcl_get_default_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_);
}
return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}
// This is a temporal workaround, to make sure that get_allocator()

View File

@@ -189,10 +189,10 @@ public:
TRACEPOINT(
rclcpp_timer_callback_added,
static_cast<const void *>(get_timer_handle().get()),
reinterpret_cast<const void *>(&callback_));
static_cast<const void *>(&callback_));
TRACEPOINT(
rclcpp_callback_register,
reinterpret_cast<const void *>(&callback_),
static_cast<const void *>(&callback_),
tracetools::get_symbol(callback_));
}
@@ -226,9 +226,9 @@ public:
void
execute_callback() override
{
TRACEPOINT(callback_start, reinterpret_cast<const void *>(&callback_), false);
TRACEPOINT(callback_start, static_cast<const void *>(&callback_), false);
execute_callback_delegate<>();
TRACEPOINT(callback_end, reinterpret_cast<const void *>(&callback_));
TRACEPOINT(callback_end, static_cast<const void *>(&callback_));
}
// void specialization

View File

@@ -169,7 +169,7 @@ remove_ros_arguments(int argc, char const * const * argv);
* the context initialized by rclcpp::init().
*
* \param[in] context Optional check for shutdown of this Context.
* \return false if shutdown has been called, true otherwise
* \return true if shutdown has been called, false otherwise
*/
RCLCPP_PUBLIC
bool

View File

@@ -15,6 +15,7 @@
#ifndef RCLCPP__WAIT_FOR_MESSAGE_HPP_
#define RCLCPP__WAIT_FOR_MESSAGE_HPP_
#include <future>
#include <memory>
#include <string>
@@ -23,6 +24,7 @@
#include "rclcpp/node.hpp"
#include "rclcpp/visibility_control.hpp"
#include "rclcpp/wait_set.hpp"
#include "rclcpp/qos.hpp"
namespace rclcpp
{
@@ -54,7 +56,7 @@ bool wait_for_message(
}
});
rclcpp::WaitSet wait_set;
rclcpp::WaitSet wait_set({}, {}, {}, {}, {}, {}, context);
wait_set.add_subscription(subscription);
RCPPUTILS_SCOPE_EXIT(wait_set.remove_subscription(subscription); );
wait_set.add_guard_condition(gc);
@@ -79,10 +81,11 @@ bool wait_for_message(
/**
* Wait for the next incoming message to arrive on a specified topic before the specified timeout.
*
* \param[out] out is the message to be filled when a new message is arriving.
* \param[out] out is the message to be filled when a new message is arriving
* \param[in] node the node pointer to initialize the subscription on.
* \param[in] topic the topic to wait for messages.
* \param[in] time_to_wait parameter specifying the timeout before returning.
* \param[in] qos parameter specifying QoS settings for the subscription.
* \return true if a message was successfully received, false if message could not
* be obtained or shutdown was triggered asynchronously on the context.
*/
@@ -91,9 +94,10 @@ bool wait_for_message(
MsgT & out,
rclcpp::Node::SharedPtr node,
const std::string & topic,
std::chrono::duration<Rep, Period> time_to_wait = std::chrono::duration<Rep, Period>(-1))
std::chrono::duration<Rep, Period> time_to_wait = std::chrono::duration<Rep, Period>(-1),
const rclcpp::QoS & qos = rclcpp::SystemDefaultsQoS())
{
auto sub = node->create_subscription<MsgT>(topic, 1, [](const std::shared_ptr<const MsgT>) {});
auto sub = node->create_subscription<MsgT>(topic, qos, [](const std::shared_ptr<const MsgT>) {});
return wait_for_message<MsgT, Rep, Period>(
out, sub, node->get_node_options().context(), time_to_wait);
}

View File

@@ -2,17 +2,13 @@
<?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>18.0.0</version>
<version>16.0.18</version>
<description>The ROS client library in C++.</description>
<maintainer email="ivanpauno@ekumenlabs.com">Ivan Paunovic</maintainer>
<maintainer email="michel@ekumenlabs.com">Michel Hidalgo</maintainer>
<maintainer email="jacob@openrobotics.org">Jacob Perron</maintainer>
<maintainer email="william@openrobotics.org">William Woodall</maintainer>
<license>Apache License 2.0</license>
<author email="dthomas@openrobotics.org">Dirk Thomas</author>
<author email="jacob@openrobotics.org">Jacob Perron</author>
<buildtool_depend>ament_cmake_ros</buildtool_depend>
<buildtool_depend>ament_cmake_gen_version_h</buildtool_depend>

View File

@@ -114,6 +114,7 @@ def get_rclcpp_suffix_from_features(features):
@[ end for]@
@[ if 'stream' not in feature_combination]@
* \param ... The format string, followed by the variable arguments for the format string.
* It also accepts a single argument of type std::string.
@[ end if]@
*/
@{params = rclcpp_feature_combinations[feature_combination].params.keys()}@
@@ -124,8 +125,7 @@ def get_rclcpp_suffix_from_features(features):
) \
do { \
static_assert( \
::std::is_same<typename std::remove_cv_t<typename std::remove_reference_t<decltype(logger)>>, \
typename ::rclcpp::Logger>::value, \
::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 { \

View File

@@ -65,6 +65,13 @@ ClientBase::ClientBase(
});
}
ClientBase::~ClientBase()
{
clear_on_new_response_callback();
// Make sure the client handle is destructed as early as possible and before the node handle
client_handle_.reset();
}
bool
ClientBase::take_type_erased_response(void * response_out, rmw_request_id_t & request_header_out)
{

View File

@@ -67,7 +67,7 @@ Clock::Clock(rcl_clock_type_t clock_type)
Clock::~Clock() {}
Time
Clock::now() const
Clock::now()
{
Time now(0, 0, impl_->rcl_clock_.type);

View File

@@ -154,9 +154,7 @@ Context::~Context()
// this will not prevent errors, but will maybe make them easier to reproduce
std::lock_guard<std::recursive_mutex> lock(init_mutex_);
try {
// Cannot rely on virtual dispatch in a destructor, so explicitly use the
// shutdown() provided by this base class.
Context::shutdown("context destructor was called while still not shutdown");
this->shutdown("context destructor was called while still not shutdown");
// at this point it is shutdown and cannot reinit
// clean_up will finalize the rcl context
this->clean_up();
@@ -219,7 +217,7 @@ Context::init(
if (0u == count) {
ret = rcl_logging_configure_with_output_handler(
&rcl_context_->global_arguments,
rcl_init_options_get_allocator(init_options_.get_rcl_init_options()),
rcl_init_options_get_allocator(init_options.get_rcl_init_options()),
rclcpp_logging_output_handler);
if (RCL_RET_OK != ret) {
rcl_context_.reset();
@@ -499,7 +497,7 @@ Context::sleep_for(const std::chrono::nanoseconds & nanoseconds)
std::unique_lock<std::mutex> lock(interrupt_mutex_);
auto start = std::chrono::steady_clock::now();
// this will release the lock while waiting
interrupt_condition_variable_.wait_for(lock, nanoseconds);
interrupt_condition_variable_.wait_for(lock, time_left);
time_left -= std::chrono::steady_clock::now() - start;
}
} while (time_left > std::chrono::nanoseconds::zero() && this->is_valid());

View File

@@ -161,13 +161,6 @@ Duration::operator+(const rclcpp::Duration & rhs) const
rcl_duration_.nanoseconds + rhs.rcl_duration_.nanoseconds);
}
Duration &
Duration::operator+=(const rclcpp::Duration & rhs)
{
*this = *this + rhs;
return *this;
}
void
bounds_check_duration_difference(int64_t lhsns, int64_t rhsns, uint64_t max)
{
@@ -197,13 +190,6 @@ Duration::operator-(const rclcpp::Duration & rhs) const
rcl_duration_.nanoseconds - rhs.rcl_duration_.nanoseconds);
}
Duration &
Duration::operator-=(const rclcpp::Duration & rhs)
{
*this = *this - rhs;
return *this;
}
void
bounds_check_duration_scale(int64_t dns, double scale, uint64_t max)
{
@@ -236,13 +222,6 @@ Duration::operator*(double scale) const
static_cast<long double>(rcl_duration_.nanoseconds) * scale_ld));
}
Duration &
Duration::operator*=(double scale)
{
*this = *this * scale;
return *this;
}
rcl_duration_value_t
Duration::nanoseconds() const
{

View File

@@ -646,6 +646,11 @@ Executor::execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription)
subscription->get_topic_name(),
[&]() {return subscription->take_type_erased(message.get(), message_info);},
[&]() {subscription->handle_message(message, message_info);});
// TODO(clalancette): In the case that the user is using the MessageMemoryPool,
// and they take a shared_ptr reference to the message in the callback, this can
// inadvertently return the message to the pool when the user is still using it.
// This is a bug that needs to be fixed in the pool, and we should probably have
// a custom deleter for the message that actually does the return_message().
subscription->return_message(message);
}
}

View File

@@ -17,7 +17,9 @@
void
rclcpp::spin_some(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr)
{
rclcpp::executors::SingleThreadedExecutor exec;
rclcpp::ExecutorOptions options;
options.context = node_ptr->get_context();
rclcpp::executors::SingleThreadedExecutor exec(options);
exec.spin_node_some(node_ptr);
}
@@ -30,7 +32,9 @@ rclcpp::spin_some(rclcpp::Node::SharedPtr node_ptr)
void
rclcpp::spin(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr)
{
rclcpp::executors::SingleThreadedExecutor exec;
rclcpp::ExecutorOptions options;
options.context = node_ptr->get_context();
rclcpp::executors::SingleThreadedExecutor exec(options);
exec.add_node(node_ptr);
exec.spin();
exec.remove_node(node_ptr);

View File

@@ -21,7 +21,6 @@
#include "rcpputils/scope_exit.hpp"
#include "rclcpp/logging.hpp"
#include "rclcpp/utilities.hpp"
using rclcpp::executors::MultiThreadedExecutor;
@@ -35,15 +34,9 @@ MultiThreadedExecutor::MultiThreadedExecutor(
yield_before_execute_(yield_before_execute),
next_exec_timeout_(next_exec_timeout)
{
number_of_threads_ = number_of_threads > 0 ?
number_of_threads :
std::max(std::thread::hardware_concurrency(), 2U);
if (number_of_threads_ == 1) {
RCLCPP_WARN(
rclcpp::get_logger("rclcpp"),
"MultiThreadedExecutor is used with a single thread.\n"
"Use the SingleThreadedExecutor instead.");
number_of_threads_ = number_of_threads ? number_of_threads : std::thread::hardware_concurrency();
if (number_of_threads_ == 0) {
number_of_threads_ = 1;
}
}

View File

@@ -48,7 +48,7 @@ GraphListener::GraphListener(const std::shared_ptr<Context> & parent_context)
GraphListener::~GraphListener()
{
GraphListener::shutdown(std::nothrow);
this->shutdown(std::nothrow);
}
void GraphListener::init_wait_set()

View File

@@ -74,19 +74,16 @@ GuardCondition::get_rcl_guard_condition() const
void
GuardCondition::trigger()
{
rcl_ret_t ret = rcl_trigger_guard_condition(&rcl_guard_condition_);
if (RCL_RET_OK != ret) {
rclcpp::exceptions::throw_from_rcl_error(ret);
}
std::lock_guard<std::recursive_mutex> lock(reentrant_mutex_);
{
std::lock_guard<std::recursive_mutex> lock(reentrant_mutex_);
if (on_trigger_callback_) {
on_trigger_callback_(1);
} else {
unread_count_++;
if (on_trigger_callback_) {
on_trigger_callback_(1);
} else {
rcl_ret_t ret = rcl_trigger_guard_condition(&rcl_guard_condition_);
if (RCL_RET_OK != ret) {
rclcpp::exceptions::throw_from_rcl_error(ret);
}
unread_count_++;
}
}
@@ -128,9 +125,10 @@ GuardCondition::set_on_trigger_callback(std::function<void(size_t)> callback)
callback(unread_count_);
unread_count_ = 0;
}
} else {
on_trigger_callback_ = nullptr;
return;
}
on_trigger_callback_ = nullptr;
}
} // namespace rclcpp

View File

@@ -14,6 +14,7 @@
#include <memory>
#include <mutex>
#include <stdexcept>
#include "rcutils/macros.h"

View File

@@ -176,8 +176,7 @@ Node::Node(
node_topics_,
node_graph_,
node_services_,
node_logging_,
options.clock_type()
node_logging_
)),
node_parameters_(new rclcpp::node_interfaces::NodeParameters(
node_base_,
@@ -354,7 +353,7 @@ Node::has_parameter(const std::string & name) const
rcl_interfaces::msg::SetParametersResult
Node::set_parameter(const rclcpp::Parameter & parameter)
{
return node_parameters_->set_parameters_atomically({parameter});
return this->set_parameters_atomically({parameter});
}
std::vector<rcl_interfaces::msg::SetParametersResult>
@@ -419,40 +418,16 @@ Node::list_parameters(const std::vector<std::string> & prefixes, uint64_t depth)
return node_parameters_->list_parameters(prefixes, depth);
}
rclcpp::Node::PreSetParametersCallbackHandle::SharedPtr
Node::add_pre_set_parameters_callback(PreSetParametersCallbackType callback)
{
return node_parameters_->add_pre_set_parameters_callback(callback);
}
rclcpp::Node::OnSetParametersCallbackHandle::SharedPtr
Node::add_on_set_parameters_callback(OnSetParametersCallbackType callback)
Node::add_on_set_parameters_callback(OnParametersSetCallbackType callback)
{
return node_parameters_->add_on_set_parameters_callback(callback);
}
rclcpp::Node::PostSetParametersCallbackHandle::SharedPtr
Node::add_post_set_parameters_callback(PostSetParametersCallbackType callback)
{
return node_parameters_->add_post_set_parameters_callback(callback);
}
void
Node::remove_pre_set_parameters_callback(const PreSetParametersCallbackHandle * const handler)
Node::remove_on_set_parameters_callback(const OnSetParametersCallbackHandle * const callback)
{
node_parameters_->remove_pre_set_parameters_callback(handler);
}
void
Node::remove_on_set_parameters_callback(const OnSetParametersCallbackHandle * const handler)
{
node_parameters_->remove_on_set_parameters_callback(handler);
}
void
Node::remove_post_set_parameters_callback(const PostSetParametersCallbackHandle * const handler)
{
node_parameters_->remove_post_set_parameters_callback(handler);
return node_parameters_->remove_on_set_parameters_callback(callback);
}
std::vector<std::string>

View File

@@ -37,13 +37,12 @@ NodeBase::NodeBase(
rclcpp::Context::SharedPtr context,
const rcl_node_options_t & rcl_node_options,
bool use_intra_process_default,
bool enable_topic_statistics_default,
rclcpp::CallbackGroup::SharedPtr default_callback_group)
bool enable_topic_statistics_default)
: context_(context),
use_intra_process_default_(use_intra_process_default),
enable_topic_statistics_default_(enable_topic_statistics_default),
node_handle_(nullptr),
default_callback_group_(default_callback_group),
default_callback_group_(nullptr),
associated_with_executor_(false),
notify_guard_condition_(context),
notify_guard_condition_is_valid_(false)
@@ -129,12 +128,9 @@ NodeBase::NodeBase(
delete node;
});
// Create the default callback group, if needed.
if (nullptr == default_callback_group_) {
using rclcpp::CallbackGroupType;
default_callback_group_ =
NodeBase::create_callback_group(CallbackGroupType::MutuallyExclusive);
}
// Create the default callback group.
using rclcpp::CallbackGroupType;
default_callback_group_ = create_callback_group(CallbackGroupType::MutuallyExclusive);
// Indicate the notify_guard_condition is now valid.
notify_guard_condition_is_valid_ = true;

View File

@@ -24,14 +24,13 @@ NodeClock::NodeClock(
rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics,
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph,
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services,
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
rcl_clock_type_t clock_type)
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr 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))
ros_clock_(std::make_shared<rclcpp::Clock>(RCL_ROS_TIME))
{}
NodeClock::~NodeClock()
@@ -40,11 +39,11 @@ NodeClock::~NodeClock()
rclcpp::Clock::SharedPtr
NodeClock::get_clock()
{
return clock_;
return ros_clock_;
}
rclcpp::Clock::ConstSharedPtr
NodeClock::get_clock() const
{
return clock_;
return ros_clock_;
}

View File

@@ -19,7 +19,7 @@ using rclcpp::node_interfaces::NodeLogging;
NodeLogging::NodeLogging(rclcpp::node_interfaces::NodeBaseInterface * node_base)
: node_base_(node_base)
{
logger_ = rclcpp::get_logger(NodeLogging::get_logger_name());
logger_ = rclcpp::get_logger(this->get_logger_name());
}
NodeLogging::~NodeLogging()

View File

@@ -39,31 +39,6 @@
using rclcpp::node_interfaces::NodeParameters;
RCLCPP_LOCAL
void
local_perform_automatically_declare_parameters_from_overrides(
const std::map<std::string, rclcpp::ParameterValue> & parameter_overrides,
std::function<bool(const std::string &)> has_parameter,
std::function<void(
const std::string &,
const rclcpp::ParameterValue &,
const rcl_interfaces::msg::ParameterDescriptor &,
bool)>
declare_parameter)
{
rcl_interfaces::msg::ParameterDescriptor descriptor;
descriptor.dynamic_typing = true;
for (const auto & pair : parameter_overrides) {
if (!has_parameter(pair.first)) {
declare_parameter(
pair.first,
pair.second,
descriptor,
true);
}
}
}
NodeParameters::NodeParameters(
const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base,
const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging,
@@ -126,41 +101,18 @@ NodeParameters::NodeParameters(
// If asked, initialize any parameters that ended up in the initial parameter values,
// but did not get declared explcitily by this point.
if (automatically_declare_parameters_from_overrides) {
using namespace std::placeholders;
local_perform_automatically_declare_parameters_from_overrides(
this->get_parameter_overrides(),
std::bind(&NodeParameters::has_parameter, this, _1),
[this](
const std::string & name,
const rclcpp::ParameterValue & default_value,
const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor,
bool ignore_override)
{
NodeParameters::declare_parameter(
name, default_value, parameter_descriptor, ignore_override);
rcl_interfaces::msg::ParameterDescriptor descriptor;
descriptor.dynamic_typing = true;
for (const auto & pair : this->get_parameter_overrides()) {
if (!this->has_parameter(pair.first)) {
this->declare_parameter(
pair.first,
pair.second,
descriptor,
true);
}
);
}
}
void
NodeParameters::perform_automatically_declare_parameters_from_overrides()
{
local_perform_automatically_declare_parameters_from_overrides(
this->get_parameter_overrides(),
[this](const std::string & name) {
return this->has_parameter(name);
},
[this](
const std::string & name,
const rclcpp::ParameterValue & default_value,
const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor,
bool ignore_override)
{
this->declare_parameter(
name, default_value, parameter_descriptor, ignore_override);
}
);
}
}
NodeParameters::~NodeParameters()
@@ -305,54 +257,19 @@ __check_parameters(
return result;
}
using PreSetParametersCallbackType =
rclcpp::node_interfaces::NodeParametersInterface::PreSetParametersCallbackType;
using PreSetParametersCallbackHandle =
rclcpp::node_interfaces::PreSetParametersCallbackHandle;
using PreSetCallbacksHandleContainer =
rclcpp::node_interfaces::NodeParameters::PreSetCallbacksHandleContainer;
using OnSetParametersCallbackType =
rclcpp::node_interfaces::NodeParametersInterface::OnSetParametersCallbackType;
using OnParametersSetCallbackType =
rclcpp::node_interfaces::NodeParametersInterface::OnParametersSetCallbackType;
using CallbacksContainerType =
rclcpp::node_interfaces::NodeParameters::CallbacksContainerType;
using OnSetParametersCallbackHandle =
rclcpp::node_interfaces::OnSetParametersCallbackHandle;
using OnSetCallbacksHandleContainer =
rclcpp::node_interfaces::NodeParameters::OnSetCallbacksHandleContainer;
using PostSetParametersCallbackType =
rclcpp::node_interfaces::NodeParametersInterface::PostSetParametersCallbackType;
using PostSetParametersCallbackHandle =
rclcpp::node_interfaces::PostSetParametersCallbackHandle;
using PostSetCallbacksHandleContainer =
rclcpp::node_interfaces::NodeParameters::PostSetCallbacksHandleContainer;
RCLCPP_LOCAL
void
__call_pre_set_parameters_callbacks(
std::vector<rclcpp::Parameter> & parameters,
PreSetCallbacksHandleContainer & callback_container)
{
if (callback_container.empty()) {
return;
}
auto it = callback_container.begin();
while (it != callback_container.end()) {
auto shared_handle = it->lock();
if (nullptr != shared_handle) {
shared_handle->callback(parameters);
it++;
} else {
it = callback_container.erase(it);
}
}
}
RCLCPP_LOCAL
rcl_interfaces::msg::SetParametersResult
__call_on_set_parameters_callbacks(
__call_on_parameters_set_callbacks(
const std::vector<rclcpp::Parameter> & parameters,
OnSetCallbacksHandleContainer & callback_container)
CallbacksContainerType & callback_container,
const OnParametersSetCallbackType & callback)
{
rcl_interfaces::msg::SetParametersResult result;
result.successful = true;
@@ -369,37 +286,19 @@ __call_on_set_parameters_callbacks(
it = callback_container.erase(it);
}
}
if (callback) {
result = callback(parameters);
}
return result;
}
RCLCPP_LOCAL
void __call_post_set_parameters_callbacks(
const std::vector<rclcpp::Parameter> & parameters,
PostSetCallbacksHandleContainer & callback_container)
{
if (callback_container.empty()) {
return;
}
auto it = callback_container.begin();
while (it != callback_container.end()) {
auto shared_handle = it->lock();
if (nullptr != shared_handle) {
shared_handle->callback(parameters);
it++;
} else {
it = callback_container.erase(it);
}
}
}
RCLCPP_LOCAL
rcl_interfaces::msg::SetParametersResult
__set_parameters_atomically_common(
const std::vector<rclcpp::Parameter> & parameters,
std::map<std::string, rclcpp::node_interfaces::ParameterInfo> & parameter_infos,
OnSetCallbacksHandleContainer & on_set_callback_container,
PostSetCallbacksHandleContainer & post_set_callback_container,
CallbacksContainerType & callback_container,
const OnParametersSetCallbackType & callback,
bool allow_undeclared = false)
{
// Check if the value being set complies with the descriptor.
@@ -408,9 +307,9 @@ __set_parameters_atomically_common(
if (!result.successful) {
return result;
}
// Call the user callbacks to see if the new value(s) are allowed.
// Call the user callback to see if the new value(s) are allowed.
result =
__call_on_set_parameters_callbacks(parameters, on_set_callback_container);
__call_on_parameters_set_callbacks(parameters, callback_container, callback);
if (!result.successful) {
return result;
}
@@ -422,8 +321,6 @@ __set_parameters_atomically_common(
parameter_infos[name].descriptor.type = parameters[i].get_type();
parameter_infos[name].value = parameters[i].get_parameter_value();
}
// Call the user post set parameter callback
__call_post_set_parameters_callbacks(parameters, post_set_callback_container);
}
// Either way, return the result.
@@ -438,8 +335,8 @@ __declare_parameter_common(
const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor,
std::map<std::string, rclcpp::node_interfaces::ParameterInfo> & parameters_out,
const std::map<std::string, rclcpp::ParameterValue> & overrides,
OnSetCallbacksHandleContainer & on_set_callback_container,
PostSetCallbacksHandleContainer & post_set_callback_container,
CallbacksContainerType & callback_container,
const OnParametersSetCallbackType & callback,
rcl_interfaces::msg::ParameterEvent * parameter_event_out,
bool ignore_override = false)
{
@@ -469,15 +366,14 @@ __declare_parameter_common(
return result;
}
// Check with the user's callbacks to see if the initial value can be set.
// Check with the user's callback to see if the initial value can be set.
std::vector<rclcpp::Parameter> parameter_wrappers {rclcpp::Parameter(name, *initial_value)};
// This function also takes care of default vs initial value.
auto result = __set_parameters_atomically_common(
parameter_wrappers,
parameter_infos,
on_set_callback_container,
post_set_callback_container
);
callback_container,
callback);
if (!result.successful) {
return result;
@@ -504,8 +400,8 @@ declare_parameter_helper(
bool ignore_override,
std::map<std::string, rclcpp::node_interfaces::ParameterInfo> & parameters,
const std::map<std::string, rclcpp::ParameterValue> & overrides,
OnSetCallbacksHandleContainer & on_set_callback_container,
PostSetCallbacksHandleContainer & post_set_callback_container,
CallbacksContainerType & callback_container,
const OnParametersSetCallbackType & callback,
rclcpp::Publisher<rcl_interfaces::msg::ParameterEvent> * events_publisher,
const std::string & combined_name,
rclcpp::node_interfaces::NodeClockInterface & node_clock)
@@ -541,8 +437,8 @@ declare_parameter_helper(
parameter_descriptor,
parameters,
overrides,
on_set_callback_container,
post_set_callback_container,
callback_container,
callback,
&parameter_event,
ignore_override);
@@ -589,8 +485,8 @@ NodeParameters::declare_parameter(
ignore_override,
parameters_,
parameter_overrides_,
on_set_parameters_callback_container_,
post_set_parameters_callback_container_,
on_parameters_set_callback_container_,
on_parameters_set_callback_,
events_publisher_.get(),
combined_name_,
*node_clock_);
@@ -625,8 +521,8 @@ NodeParameters::declare_parameter(
ignore_override,
parameters_,
parameter_overrides_,
on_set_parameters_callback_container_,
post_set_parameters_callback_container_,
on_parameters_set_callback_container_,
on_parameters_set_callback_,
events_publisher_.get(),
combined_name_,
*node_clock_);
@@ -700,27 +596,12 @@ NodeParameters::set_parameters_atomically(const std::vector<rclcpp::Parameter> &
rcl_interfaces::msg::SetParametersResult result;
// call any user registered pre set parameter callbacks
// this callback can make changes to the original parameters list
// also check if the changed parameter list is empty or not, if empty return
std::vector<rclcpp::Parameter> parameters_after_pre_set_callback(parameters);
__call_pre_set_parameters_callbacks(
parameters_after_pre_set_callback,
pre_set_parameters_callback_container_);
if (parameters_after_pre_set_callback.empty()) {
result.successful = false;
result.reason = "parameter list cannot be empty, this might be due to "
"pre_set_parameters_callback modifying the original parameters list.";
return result;
}
// Check if any of the parameters are read-only, or if any parameters are not
// declared.
// If not declared, keep track of them in order to declare them later, when
// undeclared parameters are allowed, and if they're not allowed, fail.
std::vector<const rclcpp::Parameter *> parameters_to_be_declared;
for (const auto & parameter : parameters_after_pre_set_callback) {
for (const auto & parameter : parameters) {
const std::string & name = parameter.get_name();
// Check to make sure the parameter name is valid.
@@ -755,13 +636,12 @@ NodeParameters::set_parameters_atomically(const std::vector<rclcpp::Parameter> &
// Declare parameters into a temporary "staging area", incase one of the declares fail.
// We will use the staged changes as input to the "set atomically" action.
// We explicitly avoid calling the user callbacks here, so that it may be called once, with
// We explicitly avoid calling the user callback here, so that it may be called once, with
// all the other parameters to be set (already declared parameters).
std::map<std::string, rclcpp::node_interfaces::ParameterInfo> staged_parameter_changes;
rcl_interfaces::msg::ParameterEvent parameter_event_msg;
parameter_event_msg.node = combined_name_;
OnSetCallbacksHandleContainer empty_on_set_callback_container;
PostSetCallbacksHandleContainer empty_post_set_callback_container;
CallbacksContainerType empty_callback_container;
// Implicit declare uses dynamic type descriptor.
rcl_interfaces::msg::ParameterDescriptor descriptor;
@@ -776,8 +656,8 @@ NodeParameters::set_parameters_atomically(const std::vector<rclcpp::Parameter> &
staged_parameter_changes,
parameter_overrides_,
// Only call callbacks once below
empty_on_set_callback_container, // callback_container is explicitly empty
empty_post_set_callback_container, // callback_container is explicitly empty
empty_callback_container, // callback_container is explicitly empty
nullptr, // callback is explicitly null.
&parameter_event_msg,
true);
if (!result.successful) {
@@ -790,14 +670,12 @@ NodeParameters::set_parameters_atomically(const std::vector<rclcpp::Parameter> &
// If there were implicitly declared parameters, then we may need to copy the input parameters
// and then assign the value that was selected after the declare (could be affected by the
// initial parameter values).
const std::vector<rclcpp::Parameter> * parameters_to_be_set = &parameters_after_pre_set_callback;
const std::vector<rclcpp::Parameter> * parameters_to_be_set = &parameters;
std::vector<rclcpp::Parameter> parameters_copy;
if (0 != staged_parameter_changes.size()) { // If there were any implicitly declared parameters.
bool any_initial_values_used = false;
for (const auto & staged_parameter_change : staged_parameter_changes) {
auto it = __find_parameter_by_name(
parameters_after_pre_set_callback,
staged_parameter_change.first);
auto it = __find_parameter_by_name(parameters, staged_parameter_change.first);
if (it->get_parameter_value() != staged_parameter_change.second.value) {
// In this case, the value of the staged parameter differs from the
// input from the user, and therefore we need to update things before setting.
@@ -807,7 +685,7 @@ NodeParameters::set_parameters_atomically(const std::vector<rclcpp::Parameter> &
}
}
if (any_initial_values_used) {
parameters_copy = parameters_after_pre_set_callback;
parameters_copy = parameters;
for (const auto & staged_parameter_change : staged_parameter_changes) {
auto it = __find_parameter_by_name(parameters_copy, staged_parameter_change.first);
*it = Parameter(staged_parameter_change.first, staged_parameter_change.second.value);
@@ -839,10 +717,11 @@ NodeParameters::set_parameters_atomically(const std::vector<rclcpp::Parameter> &
*parameters_to_be_set,
// they are actually set on the official parameter storage
parameters_,
// this will get called once, with all the parameters to be set
on_parameters_set_callback_container_,
// These callbacks are called once. When a callback returns an unsuccessful result,
// the remaining aren't called
on_set_parameters_callback_container_,
post_set_parameters_callback_container_,
// the remaining aren't called.
on_parameters_set_callback_,
allow_undeclared_); // allow undeclared
// If not successful, then stop here.
@@ -898,18 +777,29 @@ NodeParameters::set_parameters_atomically(const std::vector<rclcpp::Parameter> &
parameter_event_msg.stamp = node_clock_->get_clock()->now();
events_publisher_->publish(parameter_event_msg);
}
return result;
}
std::vector<rclcpp::Parameter>
NodeParameters::get_parameters(const std::vector<std::string> & names) const
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
std::vector<rclcpp::Parameter> results;
results.reserve(names.size());
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (auto & name : names) {
results.emplace_back(this->get_parameter(name));
auto found_parameter = parameters_.find(name);
if (found_parameter != parameters_.cend()) {
// found
results.emplace_back(name, found_parameter->second.value);
} else if (this->allow_undeclared_) {
// not found, but undeclared allowed
results.emplace_back(name, rclcpp::ParameterValue());
} else {
// not found, and undeclared are not allowed
throw rclcpp::exceptions::ParameterNotDeclaredException(name);
}
}
return results;
}
@@ -920,18 +810,18 @@ NodeParameters::get_parameter(const std::string & name) const
std::lock_guard<std::recursive_mutex> lock(mutex_);
auto param_iter = parameters_.find(name);
if (parameters_.end() != param_iter) {
if (
param_iter->second.value.get_type() != rclcpp::ParameterType::PARAMETER_NOT_SET ||
param_iter->second.descriptor.dynamic_typing)
{
return rclcpp::Parameter{name, param_iter->second.value};
}
throw rclcpp::exceptions::ParameterUninitializedException(name);
if (
parameters_.end() != param_iter &&
(param_iter->second.value.get_type() != rclcpp::ParameterType::PARAMETER_NOT_SET ||
param_iter->second.descriptor.dynamic_typing))
{
return rclcpp::Parameter{name, param_iter->second.value};
} else if (this->allow_undeclared_) {
return rclcpp::Parameter{name};
} else {
return rclcpp::Parameter{};
} else if (parameters_.end() == param_iter) {
throw rclcpp::exceptions::ParameterNotDeclaredException(name);
} else {
throw rclcpp::exceptions::ParameterUninitializedException(name);
}
}
@@ -1073,26 +963,6 @@ NodeParameters::list_parameters(const std::vector<std::string> & prefixes, uint6
return result;
}
void
NodeParameters::remove_pre_set_parameters_callback(
const PreSetParametersCallbackHandle * const handle)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
ParameterMutationRecursionGuard guard(parameter_modification_enabled_);
auto it = std::find_if(
pre_set_parameters_callback_container_.begin(),
pre_set_parameters_callback_container_.end(),
[handle](const auto & weak_handle) {
return handle == weak_handle.lock().get();
});
if (it != pre_set_parameters_callback_container_.end()) {
pre_set_parameters_callback_container_.erase(it);
} else {
throw std::runtime_error("Pre set parameter callback doesn't exist");
}
}
void
NodeParameters::remove_on_set_parameters_callback(
const OnSetParametersCallbackHandle * const handle)
@@ -1101,53 +971,20 @@ NodeParameters::remove_on_set_parameters_callback(
ParameterMutationRecursionGuard guard(parameter_modification_enabled_);
auto it = std::find_if(
on_set_parameters_callback_container_.begin(),
on_set_parameters_callback_container_.end(),
on_parameters_set_callback_container_.begin(),
on_parameters_set_callback_container_.end(),
[handle](const auto & weak_handle) {
return handle == weak_handle.lock().get();
});
if (it != on_set_parameters_callback_container_.end()) {
on_set_parameters_callback_container_.erase(it);
if (it != on_parameters_set_callback_container_.end()) {
on_parameters_set_callback_container_.erase(it);
} else {
throw std::runtime_error("On set parameter callback doesn't exist");
throw std::runtime_error("Callback doesn't exist");
}
}
void
NodeParameters::remove_post_set_parameters_callback(
const PostSetParametersCallbackHandle * const handle)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
ParameterMutationRecursionGuard guard(parameter_modification_enabled_);
auto it = std::find_if(
post_set_parameters_callback_container_.begin(),
post_set_parameters_callback_container_.end(),
[handle](const auto & weak_handle) {
return handle == weak_handle.lock().get();
});
if (it != post_set_parameters_callback_container_.end()) {
post_set_parameters_callback_container_.erase(it);
} else {
throw std::runtime_error("Post set parameter callback doesn't exist");
}
}
PreSetParametersCallbackHandle::SharedPtr
NodeParameters::add_pre_set_parameters_callback(PreSetParametersCallbackType callback)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
ParameterMutationRecursionGuard guard(parameter_modification_enabled_);
auto handle = std::make_shared<PreSetParametersCallbackHandle>();
handle->callback = callback;
// the last callback registered is executed first.
pre_set_parameters_callback_container_.emplace_front(handle);
return handle;
}
OnSetParametersCallbackHandle::SharedPtr
NodeParameters::add_on_set_parameters_callback(OnSetParametersCallbackType callback)
NodeParameters::add_on_set_parameters_callback(OnParametersSetCallbackType callback)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
ParameterMutationRecursionGuard guard(parameter_modification_enabled_);
@@ -1155,21 +992,7 @@ NodeParameters::add_on_set_parameters_callback(OnSetParametersCallbackType callb
auto handle = std::make_shared<OnSetParametersCallbackHandle>();
handle->callback = callback;
// the last callback registered is executed first.
on_set_parameters_callback_container_.emplace_front(handle);
return handle;
}
PostSetParametersCallbackHandle::SharedPtr
NodeParameters::add_post_set_parameters_callback(
PostSetParametersCallbackType callback)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
ParameterMutationRecursionGuard guard(parameter_modification_enabled_);
auto handle = std::make_shared<PostSetParametersCallbackHandle>();
handle->callback = callback;
// the last callback registered is executed first.
post_set_parameters_callback_container_.emplace_front(handle);
on_parameters_set_callback_container_.emplace_front(handle);
return handle;
}

View File

@@ -77,7 +77,6 @@ NodeOptions::operator=(const NodeOptions & other)
this->enable_topic_statistics_ = other.enable_topic_statistics_;
this->start_parameter_services_ = other.start_parameter_services_;
this->start_parameter_event_publisher_ = other.start_parameter_event_publisher_;
this->clock_type_ = other.clock_type_;
this->clock_qos_ = other.clock_qos_;
this->use_clock_thread_ = other.use_clock_thread_;
this->parameter_event_qos_ = other.parameter_event_qos_;
@@ -261,19 +260,6 @@ NodeOptions::start_parameter_event_publisher(bool start_parameter_event_publishe
return *this;
}
const rcl_clock_type_t &
NodeOptions::clock_type() const
{
return this->clock_type_;
}
NodeOptions &
NodeOptions::clock_type(const rcl_clock_type_t & clock_type)
{
this->clock_type_ = clock_type;
return *this;
}
const rclcpp::QoS &
NodeOptions::clock_qos() const
{

View File

@@ -35,7 +35,7 @@ AsyncParametersClient::AsyncParametersClient(
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 rmw_qos_profile_t & qos_profile,
rclcpp::CallbackGroup::SharedPtr group)
: node_topics_interface_(node_topics_interface)
{
@@ -46,7 +46,7 @@ AsyncParametersClient::AsyncParametersClient(
}
rcl_client_options_t options = rcl_client_get_default_options();
options.qos = qos_profile.get_rmw_qos_profile();
options.qos = qos_profile;
using rclcpp::Client;
using rclcpp::ClientBase;
@@ -290,24 +290,28 @@ std::shared_future<std::vector<rcl_interfaces::msg::SetParametersResult>>
AsyncParametersClient::load_parameters(
const std::string & yaml_filename)
{
rclcpp::ParameterMap parameter_map =
rclcpp::parameter_map_from_yaml_file(yaml_filename, remote_node_name_.c_str());
auto iter = parameter_map.find(remote_node_name_);
if (iter == parameter_map.end() || iter->second.size() == 0) {
throw rclcpp::exceptions::InvalidParametersException("No valid parameter");
}
auto future_result = set_parameters(iter->second);
return future_result;
rclcpp::ParameterMap parameter_map = rclcpp::parameter_map_from_yaml_file(yaml_filename);
return this->load_parameters(parameter_map);
}
std::shared_future<std::vector<rcl_interfaces::msg::SetParametersResult>>
AsyncParametersClient::load_parameters(
const rclcpp::ParameterMap & parameter_map)
{
std::vector<rclcpp::Parameter> parameters =
rclcpp::parameters_from_map(parameter_map, remote_node_name_.c_str());
std::vector<rclcpp::Parameter> parameters;
std::string remote_name = remote_node_name_.substr(remote_node_name_.substr(1).find("/") + 2);
for (const auto & params : parameter_map) {
std::string node_full_name = params.first;
std::string node_name = node_full_name.substr(node_full_name.find("/*/") + 3);
if (node_full_name == remote_node_name_ ||
node_full_name == "/**" ||
(node_name == remote_name))
{
for (const auto & param : params.second) {
parameters.push_back(param);
}
}
}
if (parameters.size() == 0) {
throw rclcpp::exceptions::InvalidParametersException("No valid parameter");

View File

@@ -133,13 +133,9 @@ ParameterEventHandler::get_parameter_from_event(
{
rclcpp::Parameter p;
if (!get_parameter_from_event(event, p, parameter_name, node_name)) {
if (event.node == node_name) {
return rclcpp::Parameter(parameter_name, rclcpp::PARAMETER_NOT_SET);
} else {
throw std::runtime_error(
"The node name '" + node_name + "' of parameter '" + parameter_name +
+"' doesn't match the node name '" + event.node + "' in parameter event");
}
throw std::runtime_error(
"Parameter '" + parameter_name + "' of node '" + node_name +
"' is not part of parameter event");
}
return p;
}

View File

@@ -28,6 +28,9 @@ ParameterEventsFilter::ParameterEventsFilter(
const std::vector<EventType> & types)
: event_(event)
{
if (!event) {
throw std::invalid_argument("event cannot be null");
}
if (std::find(types.begin(), types.end(), EventType::NEW) != types.end()) {
for (auto & new_parameter : event->new_parameters) {
if (std::find(names.begin(), names.end(), new_parameter.name) != names.end()) {

View File

@@ -17,7 +17,6 @@
#include <vector>
#include "rcpputils/find_and_replace.hpp"
#include "rcpputils/scope_exit.hpp"
#include "rclcpp/parameter_map.hpp"
using rclcpp::exceptions::InvalidParametersException;
@@ -25,11 +24,10 @@ using rclcpp::exceptions::InvalidParameterValueException;
using rclcpp::ParameterMap;
using rclcpp::ParameterValue;
static bool is_node_name_matched(const std::string & node_name, const char * node_fqn)
ParameterMap
rclcpp::parameter_map_from(const rcl_params_t * const c_params)
{
// Update the regular expression ["/*" -> "(/\\w+)" and "/**" -> "(/\\w+)*"]
std::string regex = rcpputils::find_and_replace(node_name, "/*", "(/\\w+)");
return std::regex_match(node_fqn, std::regex(regex));
return parameter_map_from(c_params, nullptr);
}
ParameterMap
@@ -60,7 +58,9 @@ rclcpp::parameter_map_from(const rcl_params_t * const c_params, const char * nod
}
if (node_fqn) {
if (!is_node_name_matched(node_name, node_fqn)) {
// Update the regular expression ["/*" -> "(/\\w+)" and "/**" -> "(/\\w+)*"]
std::string regex = rcpputils::find_and_replace(node_name, "/*", "(/\\w+)");
if (!std::regex_match(node_fqn, std::regex(regex))) {
// No need to parse the items because the user just care about node_fqn
continue;
}
@@ -81,7 +81,15 @@ rclcpp::parameter_map_from(const rcl_params_t * const c_params, const char * nod
throw InvalidParametersException(message);
}
const rcl_variant_t * const c_param_value = &(c_params_node->parameter_values[p]);
params_node.emplace_back(c_param_name, parameter_value_from(c_param_value));
ParameterValue value;
try {
value = parameter_value_from(c_param_value);
} catch (const InvalidParameterValueException & e) {
throw InvalidParameterValueException(
std::string("parameter_value_from failed for parameter '") +
c_param_name + "': " + e.what());
}
params_node.emplace_back(c_param_name, value);
}
}
@@ -148,31 +156,13 @@ rclcpp::parameter_value_from(const rcl_variant_t * const c_param_value)
}
ParameterMap
rclcpp::parameter_map_from_yaml_file(const std::string & yaml_filename, const char * node_fqn)
rclcpp::parameter_map_from_yaml_file(const std::string & yaml_filename)
{
rcutils_allocator_t allocator = rcutils_get_default_allocator();
rcl_params_t * rcl_parameters = rcl_yaml_node_struct_init(allocator);
RCPPUTILS_SCOPE_EXIT(rcl_yaml_node_struct_fini(rcl_parameters); );
const char * path = yaml_filename.c_str();
if (!rcl_parse_yaml_file(path, rcl_parameters)) {
rclcpp::exceptions::throw_from_rcl_error(RCL_RET_ERROR);
}
return rclcpp::parameter_map_from(rcl_parameters, node_fqn);
}
std::vector<rclcpp::Parameter>
rclcpp::parameters_from_map(const ParameterMap & parameter_map, const char * node_fqn)
{
std::vector<rclcpp::Parameter> parameters;
std::string node_name_old;
for (auto & [node_name, node_parameters] : parameter_map) {
if (node_fqn && !is_node_name_matched(node_name, node_fqn)) {
// No need to parse the items because the user just care about node_fqn
continue;
}
parameters.insert(parameters.end(), node_parameters.begin(), node_parameters.end());
}
return parameters;
return rclcpp::parameter_map_from(rcl_parameters);
}

View File

@@ -29,7 +29,7 @@ ParameterService::ParameterService(
const std::shared_ptr<rclcpp::node_interfaces::NodeBaseInterface> node_base,
const std::shared_ptr<rclcpp::node_interfaces::NodeServicesInterface> node_services,
rclcpp::node_interfaces::NodeParametersInterface * node_params,
const rclcpp::QoS & qos_profile)
const rmw_qos_profile_t & qos_profile)
{
const std::string node_name = node_base->get_name();
@@ -47,9 +47,7 @@ ParameterService::ParameterService(
response->values.push_back(param.get_value_message());
}
} catch (const rclcpp::exceptions::ParameterNotDeclaredException & ex) {
RCLCPP_DEBUG(rclcpp::get_logger("rclcpp"), "Failed to get parameters: %s", ex.what());
} catch (const rclcpp::exceptions::ParameterUninitializedException & ex) {
RCLCPP_DEBUG(rclcpp::get_logger("rclcpp"), "Failed to get parameters: %s", ex.what());
RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to get parameters: %s", ex.what());
}
},
qos_profile, nullptr);
@@ -70,7 +68,7 @@ ParameterService::ParameterService(
return static_cast<rclcpp::ParameterType>(type);
});
} catch (const rclcpp::exceptions::ParameterNotDeclaredException & ex) {
RCLCPP_DEBUG(rclcpp::get_logger("rclcpp"), "Failed to get parameter types: %s", ex.what());
RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to get parameter types: %s", ex.what());
}
},
qos_profile, nullptr);
@@ -91,7 +89,7 @@ ParameterService::ParameterService(
result = node_params->set_parameters_atomically(
{rclcpp::Parameter::from_parameter_msg(p)});
} catch (const rclcpp::exceptions::ParameterNotDeclaredException & ex) {
RCLCPP_DEBUG(rclcpp::get_logger("rclcpp"), "Failed to set parameter: %s", ex.what());
RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to set parameter: %s", ex.what());
result.successful = false;
result.reason = ex.what();
}
@@ -119,7 +117,7 @@ ParameterService::ParameterService(
auto result = node_params->set_parameters_atomically(pvariants);
response->result = result;
} catch (const rclcpp::exceptions::ParameterNotDeclaredException & ex) {
RCLCPP_DEBUG(
RCLCPP_WARN(
rclcpp::get_logger("rclcpp"), "Failed to set parameters atomically: %s", ex.what());
response->result.successful = false;
response->result.reason = "One or more parameters were not declared before setting";
@@ -139,7 +137,7 @@ ParameterService::ParameterService(
auto descriptors = node_params->describe_parameters(request->names);
response->descriptors = descriptors;
} catch (const rclcpp::exceptions::ParameterNotDeclaredException & ex) {
RCLCPP_DEBUG(rclcpp::get_logger("rclcpp"), "Failed to describe parameters: %s", ex.what());
RCLCPP_WARN(rclcpp::get_logger("rclcpp"), "Failed to describe parameters: %s", ex.what());
}
},
qos_profile, nullptr);

View File

@@ -45,14 +45,11 @@ PublisherBase::PublisherBase(
rclcpp::node_interfaces::NodeBaseInterface * node_base,
const std::string & topic,
const rosidl_message_type_support_t & type_support,
const rcl_publisher_options_t & publisher_options,
const PublisherEventCallbacks & event_callbacks,
bool use_default_callbacks)
const rcl_publisher_options_t & publisher_options)
: rcl_node_handle_(node_base->get_shared_rcl_node_handle()),
intra_process_is_enabled_(false),
intra_process_publisher_id_(0),
type_support_(type_support),
event_callbacks_(event_callbacks)
type_support_(type_support)
{
auto custom_deleter = [node_handle = this->rcl_node_handle_](rcl_publisher_t * rcl_pub)
{
@@ -101,12 +98,15 @@ PublisherBase::PublisherBase(
rmw_reset_error();
throw std::runtime_error(msg);
}
bind_event_callbacks(event_callbacks_, use_default_callbacks);
}
PublisherBase::~PublisherBase()
{
for (const auto & pair : event_handlers_) {
rcl_publisher_event_type_t event_type = pair.first;
clear_on_new_qos_event_callback(event_type);
}
// must fini the events before fini-ing the publisher
event_handlers_.clear();
@@ -131,38 +131,6 @@ PublisherBase::get_topic_name() const
return rcl_publisher_get_topic_name(publisher_handle_.get());
}
void
PublisherBase::bind_event_callbacks(
const PublisherEventCallbacks & event_callbacks, bool use_default_callbacks)
{
if (event_callbacks.deadline_callback) {
this->add_event_handler(
event_callbacks.deadline_callback,
RCL_PUBLISHER_OFFERED_DEADLINE_MISSED);
}
if (event_callbacks.liveliness_callback) {
this->add_event_handler(
event_callbacks.liveliness_callback,
RCL_PUBLISHER_LIVELINESS_LOST);
}
if (event_callbacks.incompatible_qos_callback) {
this->add_event_handler(
event_callbacks.incompatible_qos_callback,
RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS);
} else if (use_default_callbacks) {
// Register default callback when not specified
try {
this->add_event_handler(
[this](QOSOfferedIncompatibleQoSInfo & info) {
this->default_incompatible_qos_callback(info);
},
RCL_PUBLISHER_OFFERED_INCOMPATIBLE_QOS);
} catch (UnsupportedEventTypeException & /*exc*/) {
// pass
}
}
}
size_t
PublisherBase::get_queue_size() const
{

View File

@@ -16,8 +16,6 @@
#include <string>
#include "rclcpp/logging.hpp"
#include "rmw/error_handling.h"
#include "rmw/types.h"
#include "rmw/qos_profiles.h"
@@ -58,8 +56,10 @@ QoSInitialization::from_rmw(const rmw_qos_profile_t & rmw_qos)
case RMW_QOS_POLICY_HISTORY_KEEP_LAST:
case RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT:
case RMW_QOS_POLICY_HISTORY_UNKNOWN:
default:
return KeepLast(rmw_qos.depth);
default:
throw std::invalid_argument(
"Invalid history policy enum value passed to QoSInitialization::from_rmw");
}
}
@@ -69,30 +69,13 @@ KeepAll::KeepAll()
KeepLast::KeepLast(size_t depth)
: QoSInitialization(RMW_QOS_POLICY_HISTORY_KEEP_LAST, depth)
{
if (depth == 0) {
RCLCPP_WARN_ONCE(
rclcpp::get_logger(
"rclcpp"),
"A zero depth with KEEP_LAST doesn't make sense; no data could be stored."
"This will be interpreted as SYSTEM_DEFAULT");
}
}
{}
QoS::QoS(
const QoSInitialization & qos_initialization,
const rmw_qos_profile_t & initial_profile)
: rmw_qos_profile_(initial_profile)
{
if (qos_initialization.history_policy == RMW_QOS_POLICY_HISTORY_KEEP_LAST &&
qos_initialization.depth == 0)
{
RCLCPP_WARN_ONCE(
rclcpp::get_logger(
"rclcpp"),
"A zero depth with KEEP_LAST doesn't make sense; no data could be stored."
"This will be interpreted as SYSTEM_DEFAULT");
}
rmw_qos_profile_.history = qos_initialization.history_policy;
rmw_qos_profile_.depth = qos_initialization.depth;
}
@@ -130,14 +113,6 @@ QoS::history(HistoryPolicy history)
QoS &
QoS::keep_last(size_t depth)
{
if (depth == 0) {
RCLCPP_WARN_ONCE(
rclcpp::get_logger(
"rclcpp"),
"A zero depth with KEEP_LAST doesn't make sense; no data could be stored."
"This will be interpreted as SYSTEM_DEFAULT");
}
rmw_qos_profile_.history = RMW_QOS_POLICY_HISTORY_KEEP_LAST;
rmw_qos_profile_.depth = depth;
return *this;
@@ -177,12 +152,6 @@ QoS::best_effort()
return this->reliability(RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT);
}
QoS &
QoS::reliability_best_available()
{
return this->reliability(RMW_QOS_POLICY_RELIABILITY_BEST_AVAILABLE);
}
QoS &
QoS::durability(rmw_qos_durability_policy_t durability)
{
@@ -209,12 +178,6 @@ QoS::transient_local()
return this->durability(RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL);
}
QoS &
QoS::durability_best_available()
{
return this->durability(RMW_QOS_POLICY_DURABILITY_BEST_AVAILABLE);
}
QoS &
QoS::deadline(rmw_time_t deadline)
{
@@ -419,8 +382,4 @@ SystemDefaultsQoS::SystemDefaultsQoS(const QoSInitialization & qos_initializatio
: QoS(qos_initialization, rmw_qos_profile_system_default)
{}
BestAvailableQoS::BestAvailableQoS(const QoSInitialization & qos_initialization)
: QoS(qos_initialization, rmw_qos_profile_best_available)
{}
} // namespace rclcpp

View File

@@ -35,11 +35,6 @@ UnsupportedEventTypeException::UnsupportedEventTypeException(
QOSEventHandlerBase::~QOSEventHandlerBase()
{
// Since the rmw event listener holds a reference to
// this callback, we need to clear it on destruction of this class.
// This clearing is not needed for other rclcpp entities like pub/subs, since
// they do own the underlying rmw entities, which are destroyed
// on their rclcpp destructors, thus no risk of dangling pointers.
if (on_new_event_callback_) {
clear_on_ready_callback();
}

View File

@@ -36,7 +36,6 @@ SerializationBase::SerializationBase(const rosidl_message_type_support_t * type_
void SerializationBase::serialize_message(
const void * ros_message, SerializedMessage * serialized_message) const
{
rcpputils::check_true(nullptr != type_support_, "Typesupport is nullpointer.");
rcpputils::check_true(nullptr != ros_message, "ROS message is nullpointer.");
rcpputils::check_true(nullptr != serialized_message, "Serialized message is nullpointer.");
@@ -52,7 +51,6 @@ void SerializationBase::serialize_message(
void SerializationBase::deserialize_message(
const SerializedMessage * serialized_message, void * ros_message) const
{
rcpputils::check_true(nullptr != type_support_, "Typesupport is nullpointer.");
rcpputils::check_true(nullptr != serialized_message, "Serialized message is nullpointer.");
rcpputils::check_true(
0u != serialized_message->capacity(),

View File

@@ -26,8 +26,13 @@ namespace rclcpp
inline void copy_rcl_message(const rcl_serialized_message_t & from, rcl_serialized_message_t & to)
{
const auto ret = rmw_serialized_message_init(
&to, from.buffer_capacity, &from.allocator);
auto ret = RCL_RET_ERROR;
if (nullptr == to.buffer) {
ret = rmw_serialized_message_init(&to, from.buffer_capacity, &from.allocator);
} else {
ret = rmw_serialized_message_resize(&to, from.buffer_capacity);
}
if (RCL_RET_OK != ret) {
rclcpp::exceptions::throw_from_rcl_error(ret);
}
@@ -78,7 +83,6 @@ SerializedMessage::SerializedMessage(rcl_serialized_message_t && other)
SerializedMessage & SerializedMessage::operator=(const SerializedMessage & other)
{
if (this != &other) {
serialized_message_ = rmw_get_zero_initialized_serialized_message();
copy_rcl_message(other.serialized_message_, serialized_message_);
}
@@ -88,7 +92,6 @@ SerializedMessage & SerializedMessage::operator=(const SerializedMessage & other
SerializedMessage & SerializedMessage::operator=(const rcl_serialized_message_t & other)
{
if (&serialized_message_ != &other) {
serialized_message_ = rmw_get_zero_initialized_serialized_message();
copy_rcl_message(other, serialized_message_);
}
@@ -98,6 +101,14 @@ SerializedMessage & SerializedMessage::operator=(const rcl_serialized_message_t
SerializedMessage & SerializedMessage::operator=(SerializedMessage && other)
{
if (this != &other) {
if (nullptr != serialized_message_.buffer) {
const auto fini_ret = rmw_serialized_message_fini(&serialized_message_);
if (RCL_RET_OK != fini_ret) {
RCLCPP_ERROR(
get_logger("rclcpp"),
"Failed to destroy serialized message: %s", rcl_get_error_string().str);
}
}
serialized_message_ =
std::exchange(other.serialized_message_, rmw_get_zero_initialized_serialized_message());
}
@@ -108,6 +119,14 @@ SerializedMessage & SerializedMessage::operator=(SerializedMessage && other)
SerializedMessage & SerializedMessage::operator=(rcl_serialized_message_t && other)
{
if (&serialized_message_ != &other) {
if (nullptr != serialized_message_.buffer) {
const auto fini_ret = rmw_serialized_message_fini(&serialized_message_);
if (RCL_RET_OK != fini_ret) {
RCLCPP_ERROR(
get_logger("rclcpp"),
"Failed to destroy serialized message: %s", rcl_get_error_string().str);
}
}
serialized_message_ =
std::exchange(other, rmw_get_zero_initialized_serialized_message());
}

View File

@@ -32,6 +32,10 @@ ServiceBase::ServiceBase(std::shared_ptr<rcl_node_t> node_handle)
node_logger_(rclcpp::get_node_logger(node_handle_.get()))
{}
ServiceBase::~ServiceBase()
{
clear_on_new_request_callback();
}
bool
ServiceBase::take_type_erased_request(void * request_out, rmw_request_id_t & request_id_out)

View File

@@ -68,7 +68,6 @@ void
SignalHandler::signal_handler(
int signum, siginfo_t * siginfo, void * context)
{
RCLCPP_INFO(SignalHandler::get_logger(), "signal_handler(signum=%d)", signum);
auto & instance = SignalHandler::get_global_signal_handler();
auto old_signal_handler = instance.get_old_signal_handler(signum);
@@ -91,7 +90,6 @@ SignalHandler::signal_handler(
void
SignalHandler::signal_handler(int signum)
{
RCLCPP_INFO(SignalHandler::get_logger(), "signal_handler(signum=%d)", signum);
auto & instance = SignalHandler::get_global_signal_handler();
auto old_signal_handler = instance.get_old_signal_handler(signum);
if (
@@ -113,7 +111,7 @@ SignalHandler::get_logger()
SignalHandler &
SignalHandler::get_global_signal_handler()
{
static SignalHandler signal_handler;
static SignalHandler & signal_handler = *new SignalHandler();
return signal_handler;
}
@@ -249,9 +247,6 @@ SignalHandler::signal_handler_common()
{
auto & instance = SignalHandler::get_global_signal_handler();
instance.signal_received_.store(true);
RCLCPP_DEBUG(
get_logger(),
"signal_handler(): notifying deferred signal handler");
instance.notify_signal_handler();
}
@@ -260,6 +255,7 @@ SignalHandler::deferred_signal_handler()
{
while (true) {
if (signal_received_.exchange(false)) {
RCLCPP_INFO(SignalHandler::get_logger(), "signal_handler(SIGINT/SIGTERM)");
RCLCPP_DEBUG(get_logger(), "deferred_signal_handler(): shutting down");
for (auto context_ptr : rclcpp::get_contexts()) {
if (context_ptr->get_init_options().shutdown_on_signal) {

View File

@@ -39,15 +39,12 @@ SubscriptionBase::SubscriptionBase(
const rosidl_message_type_support_t & type_support_handle,
const std::string & topic_name,
const rcl_subscription_options_t & subscription_options,
const SubscriptionEventCallbacks & event_callbacks,
bool use_default_callbacks,
bool is_serialized)
: node_base_(node_base),
node_handle_(node_base_->get_shared_rcl_node_handle()),
node_logger_(rclcpp::get_node_logger(node_handle_.get())),
use_intra_process_(false),
intra_process_subscription_id_(0),
event_callbacks_(event_callbacks),
type_support_(type_support_handle),
is_serialized_(is_serialized)
{
@@ -83,14 +80,20 @@ SubscriptionBase::SubscriptionBase(
rcl_node_get_name(rcl_node_handle),
rcl_node_get_namespace(rcl_node_handle));
}
rclcpp::exceptions::throw_from_rcl_error(ret, "could not create subscription");
}
bind_event_callbacks(event_callbacks_, use_default_callbacks);
}
SubscriptionBase::~SubscriptionBase()
{
clear_on_new_message_callback();
for (const auto & pair : event_handlers_) {
rcl_subscription_event_type_t event_type = pair.first;
clear_on_new_qos_event_callback(event_type);
}
if (!use_intra_process_) {
return;
}
@@ -105,43 +108,6 @@ SubscriptionBase::~SubscriptionBase()
ipm->remove_subscription(intra_process_subscription_id_);
}
void
SubscriptionBase::bind_event_callbacks(
const SubscriptionEventCallbacks & event_callbacks, bool use_default_callbacks)
{
if (event_callbacks.deadline_callback) {
this->add_event_handler(
event_callbacks.deadline_callback,
RCL_SUBSCRIPTION_REQUESTED_DEADLINE_MISSED);
}
if (event_callbacks.liveliness_callback) {
this->add_event_handler(
event_callbacks.liveliness_callback,
RCL_SUBSCRIPTION_LIVELINESS_CHANGED);
}
if (event_callbacks.incompatible_qos_callback) {
this->add_event_handler(
event_callbacks.incompatible_qos_callback,
RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS);
} else if (use_default_callbacks) {
// Register default callback when not specified
try {
this->add_event_handler(
[this](QOSRequestedIncompatibleQoSInfo & info) {
this->default_incompatible_qos_callback(info);
},
RCL_SUBSCRIPTION_REQUESTED_INCOMPATIBLE_QOS);
} catch (UnsupportedEventTypeException & /*exc*/) {
// pass
}
}
if (event_callbacks.message_lost_callback) {
this->add_event_handler(
event_callbacks.message_lost_callback,
RCL_SUBSCRIPTION_MESSAGE_LOST);
}
}
const char *
SubscriptionBase::get_topic_name() const
{
@@ -263,7 +229,20 @@ SubscriptionBase::setup_intra_process(
bool
SubscriptionBase::can_loan_messages() const
{
return rcl_subscription_can_loan_messages(subscription_handle_.get());
bool retval = rcl_subscription_can_loan_messages(subscription_handle_.get());
if (retval) {
// TODO(clalancette): The loaned message interface is currently not safe to use with
// shared_ptr callbacks. If a user takes a copy of the shared_ptr, it can get freed from
// underneath them via rcl_return_loaned_message_from_subscription(). The correct solution is
// to return the loaned message in a custom deleter, but that needs to be carefully handled
// with locking. Warn the user about this until we fix it.
RCLCPP_WARN_ONCE(
this->node_logger_,
"Loaned messages are only safe with const ref subscription callbacks. "
"If you are using any other kind of subscriptions, "
"set the ROS_DISABLE_LOANED_MESSAGES environment variable to 1 (the default).");
}
return retval;
}
rclcpp::Waitable::SharedPtr

View File

@@ -17,6 +17,11 @@
using rclcpp::experimental::SubscriptionIntraProcessBase;
SubscriptionIntraProcessBase::~SubscriptionIntraProcessBase()
{
clear_on_ready_callback();
}
void
SubscriptionIntraProcessBase::add_to_wait_set(rcl_wait_set_t * wait_set)
{

View File

@@ -91,13 +91,10 @@ public:
// Attach a clock
void attachClock(rclcpp::Clock::SharedPtr clock)
{
{
std::lock_guard<std::mutex> clock_guard(clock->get_clock_mutex());
if (clock->get_clock_type() != RCL_ROS_TIME && ros_time_active_) {
throw std::invalid_argument(
"ros_time_active_ can't be true while clock is not of RCL_ROS_TIME type");
}
if (clock->get_clock_type() != RCL_ROS_TIME) {
throw std::invalid_argument("Cannot attach clock to a time source that's not a ROS clock");
}
std::lock_guard<std::mutex> guard(clock_list_lock_);
associated_clocks_.push_back(clock);
// Set the clock to zero unless there's a recently received message
@@ -128,32 +125,27 @@ public:
{
std::lock_guard<std::mutex> clock_guard(clock->get_clock_mutex());
if (clock->get_clock_type() == RCL_ROS_TIME) {
// Do change
if (!set_ros_time_enabled && clock->ros_time_is_active()) {
auto ret = rcl_disable_ros_time_override(clock->get_clock_handle());
if (ret != RCL_RET_OK) {
rclcpp::exceptions::throw_from_rcl_error(
ret, "Failed to disable ros_time_override_status");
}
} else if (set_ros_time_enabled && !clock->ros_time_is_active()) {
auto ret = rcl_enable_ros_time_override(clock->get_clock_handle());
if (ret != RCL_RET_OK) {
rclcpp::exceptions::throw_from_rcl_error(
ret, "Failed to enable ros_time_override_status");
}
}
auto ret = rcl_set_ros_time_override(
clock->get_clock_handle(),
rclcpp::Time(*msg).nanoseconds());
// Do change
if (!set_ros_time_enabled && clock->ros_time_is_active()) {
auto ret = rcl_disable_ros_time_override(clock->get_clock_handle());
if (ret != RCL_RET_OK) {
rclcpp::exceptions::throw_from_rcl_error(
ret, "Failed to set ros_time_override_status");
ret, "Failed to disable ros_time_override_status");
}
} else if (set_ros_time_enabled) {
throw std::invalid_argument(
"set_ros_time_enabled can't be true while clock is not of RCL_ROS_TIME type");
} else if (set_ros_time_enabled && !clock->ros_time_is_active()) {
auto ret = rcl_enable_ros_time_override(clock->get_clock_handle());
if (ret != RCL_RET_OK) {
rclcpp::exceptions::throw_from_rcl_error(
ret, "Failed to enable ros_time_override_status");
}
}
auto ret = rcl_set_ros_time_override(
clock->get_clock_handle(),
rclcpp::Time(*msg).nanoseconds());
if (ret != RCL_RET_OK) {
rclcpp::exceptions::throw_from_rcl_error(
ret, "Failed to set ros_time_override_status");
}
}
@@ -174,18 +166,6 @@ public:
last_msg_set_ = msg;
}
bool are_all_clocks_rcl_ros_time()
{
std::lock_guard<std::mutex> guard(clock_list_lock_);
for (auto & clock : associated_clocks_) {
std::lock_guard<std::mutex> clock_guard(clock->get_clock_mutex());
if (clock->get_clock_type() != RCL_ROS_TIME) {
return false;
}
}
return true;
}
private:
// Store (and update on node attach) logger for logging.
Logger logger_;
@@ -286,10 +266,6 @@ public:
throw std::invalid_argument("Invalid type for parameter 'use_sim_time', should be 'bool'");
}
on_set_parameters_callback_ = node_parameters_->add_on_set_parameters_callback(
std::bind(&TimeSource::NodeState::on_set_parameters, this, std::placeholders::_1));
// TODO(tfoote) use parameters interface not subscribe to events via topic ticketed #609
parameter_subscription_ = rclcpp::AsyncParametersClient::on_parameter_event(
node_topics_,
@@ -309,10 +285,6 @@ public:
// can't possibly call any of the callbacks as we are cleaning up.
destroy_clock_sub();
clocks_state_.disable_ros_time();
if (on_set_parameters_callback_) {
node_parameters_->remove_on_set_parameters_callback(on_set_parameters_callback_.get());
}
on_set_parameters_callback_.reset();
parameter_subscription_.reset();
node_base_.reset();
node_topics_.reset();
@@ -447,34 +419,10 @@ private:
clock_subscription_.reset();
}
// On set Parameters callback handle
node_interfaces::OnSetParametersCallbackHandle::SharedPtr on_set_parameters_callback_{nullptr};
// Parameter Event subscription
using ParamSubscriptionT = rclcpp::Subscription<rcl_interfaces::msg::ParameterEvent>;
std::shared_ptr<ParamSubscriptionT> parameter_subscription_;
// Callback for parameter settings
rcl_interfaces::msg::SetParametersResult on_set_parameters(
const std::vector<rclcpp::Parameter> & parameters)
{
rcl_interfaces::msg::SetParametersResult result;
result.successful = true;
for (const auto & param : parameters) {
if (param.get_name() == "use_sim_time" && param.get_type() == rclcpp::PARAMETER_BOOL) {
if (param.as_bool() && !(clocks_state_.are_all_clocks_rcl_ros_time())) {
result.successful = false;
result.reason =
"use_sim_time parameter can't be true while clocks are not all of RCL_ROS_TIME type";
RCLCPP_ERROR(
logger_,
"use_sim_time parameter can't be true while clocks are not all of RCL_ROS_TIME type");
}
}
}
return result;
}
// Callback for parameter updates
void on_parameter_event(std::shared_ptr<const rcl_interfaces::msg::ParameterEvent> event)
{

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <chrono>
#include <memory>
#include <string>
#include <utility>

View File

@@ -314,7 +314,7 @@ if(TARGET test_init_options)
ament_target_dependencies(test_init_options "rcl")
target_link_libraries(test_init_options ${PROJECT_NAME} mimick)
endif()
ament_add_gmock(test_parameter_client test_parameter_client.cpp)
ament_add_gtest(test_parameter_client test_parameter_client.cpp)
if(TARGET test_parameter_client)
ament_target_dependencies(test_parameter_client
"rcl_interfaces"

View File

@@ -21,6 +21,7 @@
#include <algorithm>
#include <chrono>
#include <future>
#include <limits>
#include <memory>
#include <string>
@@ -80,7 +81,7 @@ public:
rclcpp::Node::SharedPtr node;
rclcpp::Publisher<test_msgs::msg::Empty>::SharedPtr publisher;
rclcpp::Subscription<test_msgs::msg::Empty>::SharedPtr subscription;
int callback_count;
std::atomic<int> callback_count;
};
// spin_all and spin_some are not implemented correctly in StaticSingleThreadedExecutor, see:
@@ -178,7 +179,7 @@ TYPED_TEST(TestExecutors, spinWithTimer) {
using ExecutorType = TypeParam;
ExecutorType executor;
bool timer_completed = false;
std::atomic<bool> timer_completed = false;
auto timer = this->node->create_wall_timer(1ms, [&]() {timer_completed = true;});
executor.add_node(this->node);
@@ -282,7 +283,7 @@ TYPED_TEST(TestExecutors, testSpinUntilFutureCompleteNoTimeout) {
}
});
bool spin_exited = false;
std::atomic<bool> spin_exited = false;
// Timeout set to negative for no timeout.
std::thread spinner([&]() {
@@ -318,7 +319,7 @@ TYPED_TEST(TestExecutors, testSpinUntilFutureCompleteWithTimeout) {
ExecutorType executor;
executor.add_node(this->node);
bool spin_exited = false;
std::atomic<bool> spin_exited = false;
// Needs to run longer than spin_until_future_complete's timeout.
std::future<void> future = std::async(
@@ -412,7 +413,7 @@ TYPED_TEST(TestExecutors, spinAll) {
// Long timeout, but should not block test if spin_all works as expected as we cancel the
// executor.
bool spin_exited = false;
std::atomic<bool> spin_exited = false;
std::thread spinner([&spin_exited, &executor, this]() {
executor.spin_all(1s);
executor.remove_node(this->node, true);
@@ -518,7 +519,7 @@ TYPED_TEST(TestExecutors, testSpinUntilFutureCompleteInterrupted) {
ExecutorType executor;
executor.add_node(this->node);
bool spin_exited = false;
std::atomic<bool> spin_exited = false;
// This needs to block longer than it takes to get to the shutdown call below and for
// spin_until_future_complete to return
@@ -593,3 +594,134 @@ TEST(TestExecutors, testSpinUntilFutureCompleteNodePtr) {
rclcpp::shutdown();
}
template<typename T>
class TestIntraprocessExecutors : public ::testing::Test
{
public:
static void SetUpTestCase()
{
rclcpp::init(0, nullptr);
}
static void TearDownTestCase()
{
rclcpp::shutdown();
}
void SetUp()
{
const auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
std::stringstream test_name;
test_name << test_info->test_case_name() << "_" << test_info->name();
node = std::make_shared<rclcpp::Node>("node", test_name.str());
callback_count = 0u;
const std::string topic_name = std::string("topic_") + test_name.str();
rclcpp::PublisherOptions po;
po.use_intra_process_comm = rclcpp::IntraProcessSetting::Enable;
publisher = node->create_publisher<test_msgs::msg::Empty>(topic_name, rclcpp::QoS(1), po);
auto callback = [this](test_msgs::msg::Empty::ConstSharedPtr) {
this->callback_count.fetch_add(1u);
};
rclcpp::SubscriptionOptions so;
so.use_intra_process_comm = rclcpp::IntraProcessSetting::Enable;
subscription =
node->create_subscription<test_msgs::msg::Empty>(
topic_name, rclcpp::QoS(kNumMessages), std::move(callback), so);
}
void TearDown()
{
publisher.reset();
subscription.reset();
node.reset();
}
const size_t kNumMessages = 100;
rclcpp::Node::SharedPtr node;
rclcpp::Publisher<test_msgs::msg::Empty>::SharedPtr publisher;
rclcpp::Subscription<test_msgs::msg::Empty>::SharedPtr subscription;
std::atomic_size_t callback_count;
};
TYPED_TEST_SUITE(TestIntraprocessExecutors, ExecutorTypes, ExecutorTypeNames);
TYPED_TEST(TestIntraprocessExecutors, testIntraprocessRetrigger) {
// This tests that executors will continue to service intraprocess subscriptions in the case
// that publishers aren't continuing to publish.
// This was previously broken in that intraprocess guard conditions were only triggered on
// publish and the test was added to prevent future regressions.
const size_t kNumMessages = 100;
using ExecutorType = TypeParam;
ExecutorType executor;
executor.add_node(this->node);
EXPECT_EQ(0u, this->callback_count.load());
this->publisher->publish(test_msgs::msg::Empty());
// Wait for up to 5 seconds for the first message to come available.
const std::chrono::milliseconds sleep_per_loop(10);
int loops = 0;
while (1u != this->callback_count.load() && loops < 500) {
rclcpp::sleep_for(sleep_per_loop);
executor.spin_some();
loops++;
}
EXPECT_EQ(1u, this->callback_count.load());
// reset counter
this->callback_count.store(0u);
for (size_t ii = 0; ii < kNumMessages; ++ii) {
this->publisher->publish(test_msgs::msg::Empty());
}
// Fire a timer every 10ms up to 5 seconds waiting for subscriptions to be read.
loops = 0;
auto timer = this->node->create_wall_timer(
std::chrono::milliseconds(10), [this, &executor, &loops, &kNumMessages]() {
loops++;
if (kNumMessages == this->callback_count.load() ||
loops == 500)
{
executor.cancel();
}
});
executor.spin();
EXPECT_EQ(kNumMessages, this->callback_count.load());
}
// Check spin functions with non default context
TEST(TestExecutors, testSpinWithNonDefaultContext)
{
auto non_default_context = std::make_shared<rclcpp::Context>();
non_default_context->init(0, nullptr);
{
auto node =
std::make_unique<rclcpp::Node>("node", rclcpp::NodeOptions().context(non_default_context));
EXPECT_NO_THROW(rclcpp::spin_some(node->get_node_base_interface()));
auto check_spin_until_future_complete = [&]() {
std::promise<bool> promise;
std::future<bool> future = promise.get_future();
promise.set_value(true);
auto shared_future = future.share();
auto ret = rclcpp::spin_until_future_complete(
node->get_node_base_interface(), shared_future, 1s);
EXPECT_EQ(rclcpp::FutureReturnCode::SUCCESS, ret);
};
EXPECT_NO_THROW(check_spin_until_future_complete());
}
rclcpp::shutdown(non_default_context);
}

View File

@@ -183,7 +183,7 @@ TEST_F(TestNodeInterfaces, ni_init) {
/*
Testing macro'ed getters.
*/
TEST_F(TestNodeInterfaces, ni_all_init) {
TEST_F(TestNodeInterfaces, ni_all_init_non_const) {
auto node = std::make_shared<rclcpp::Node>("my_node", "/ns");
using rclcpp::node_interfaces::NodeInterfaces;
@@ -243,3 +243,64 @@ TEST_F(TestNodeInterfaces, ni_all_init) {
time_source = ni.get_node_time_source_interface();
}
}
TEST_F(TestNodeInterfaces, ni_all_init_const) {
auto node = std::make_shared<rclcpp::Node>("my_node", "/ns");
using rclcpp::node_interfaces::NodeInterfaces;
using rclcpp::node_interfaces::NodeBaseInterface;
using rclcpp::node_interfaces::NodeClockInterface;
using rclcpp::node_interfaces::NodeGraphInterface;
using rclcpp::node_interfaces::NodeLoggingInterface;
using rclcpp::node_interfaces::NodeTimersInterface;
using rclcpp::node_interfaces::NodeTopicsInterface;
using rclcpp::node_interfaces::NodeServicesInterface;
using rclcpp::node_interfaces::NodeWaitablesInterface;
using rclcpp::node_interfaces::NodeParametersInterface;
using rclcpp::node_interfaces::NodeTimeSourceInterface;
const auto ni = rclcpp::node_interfaces::NodeInterfaces<ALL_RCLCPP_NODE_INTERFACES>(*node);
{
auto base = ni.get<NodeBaseInterface>();
base = ni.get_node_base_interface();
EXPECT_STREQ(base->get_name(), "my_node"); // Test for functionality
}
{
auto clock = ni.get<NodeClockInterface>();
clock = ni.get_node_clock_interface();
clock->get_clock();
}
{
auto graph = ni.get<NodeGraphInterface>();
graph = ni.get_node_graph_interface();
}
{
auto logging = ni.get<NodeLoggingInterface>();
logging = ni.get_node_logging_interface();
}
{
auto timers = ni.get<NodeTimersInterface>();
timers = ni.get_node_timers_interface();
}
{
auto topics = ni.get<NodeTopicsInterface>();
topics = ni.get_node_topics_interface();
}
{
auto services = ni.get<NodeServicesInterface>();
services = ni.get_node_services_interface();
}
{
auto waitables = ni.get<NodeWaitablesInterface>();
waitables = ni.get_node_waitables_interface();
}
{
auto parameters = ni.get<NodeParametersInterface>();
parameters = ni.get_node_parameters_interface();
}
{
auto time_source = ni.get<NodeTimeSourceInterface>();
time_source = ni.get_node_time_source_interface();
}
}

View File

@@ -175,7 +175,7 @@ TEST_F(TestNodeParameters, set_parameters) {
EXPECT_TRUE(result[0].successful);
}
TEST_F(TestNodeParameters, add_remove_on_set_parameters_callback) {
TEST_F(TestNodeParameters, add_remove_parameters_callback) {
rcl_interfaces::msg::ParameterDescriptor bool_descriptor;
bool_descriptor.name = "bool_parameter";
bool_descriptor.type = rcl_interfaces::msg::ParameterType::PARAMETER_BOOL;
@@ -202,123 +202,7 @@ TEST_F(TestNodeParameters, add_remove_on_set_parameters_callback) {
RCLCPP_EXPECT_THROW_EQ(
node_parameters->remove_on_set_parameters_callback(handle.get()),
std::runtime_error("On set parameter callback doesn't exist"));
}
TEST_F(TestNodeParameters, add_remove_pre_set_parameters_callback) {
// `add_pre_set_parameters_callback` used to modify parameters list.
auto modify_parameter_list_callback = [](std::vector<rclcpp::Parameter> & parameters) {
for (const auto & param : parameters) {
if (param.get_name() == "param1") {
parameters.emplace_back("param2", 2.0);
}
}
};
// `add_pre_set_parameters_callback` used to make the parameters list empty.
auto empty_parameter_list_callback = [](std::vector<rclcpp::Parameter> & parameters) {
parameters = {};
};
auto handle1 =
node_parameters->add_pre_set_parameters_callback(modify_parameter_list_callback);
double default_value = 0.0;
node_parameters->declare_parameter(
"param1", rclcpp::ParameterValue(default_value));
node_parameters->declare_parameter(
"param2", rclcpp::ParameterValue(default_value));
// verify that `declare_parameter` does not call any of the callbacks registered with
// `add_pre_set_parameters_callback`
EXPECT_TRUE(node_parameters->has_parameter("param1"));
EXPECT_EQ(node_parameters->get_parameter("param1").get_value<double>(), default_value);
EXPECT_TRUE(node_parameters->has_parameter("param2"));
EXPECT_EQ(node_parameters->get_parameter("param2").get_value<double>(), default_value);
// verify that the `param2` was set successfully conditioned on setting of
// `param1`
const std::vector<rclcpp::Parameter> parameters_to_be_set = {
rclcpp::Parameter("param1", 1.0)};
auto result = node_parameters->set_parameters(parameters_to_be_set);
// we expect the result size to be same as the original "parameters_to_be_set"
// since the pre set parameter callback will set the modified param list atomically.
ASSERT_EQ(1u, result.size());
EXPECT_TRUE(result[0].successful);
EXPECT_TRUE(node_parameters->has_parameter("param1"));
EXPECT_EQ(node_parameters->get_parameter("param1").get_value<double>(), 1.0);
EXPECT_TRUE(node_parameters->has_parameter("param2"));
EXPECT_EQ(node_parameters->get_parameter("param2").get_value<double>(), 2.0);
EXPECT_NO_THROW(node_parameters->remove_pre_set_parameters_callback(handle1.get()));
RCLCPP_EXPECT_THROW_EQ(
node_parameters->remove_pre_set_parameters_callback(handle1.get()),
std::runtime_error("Pre set parameter callback doesn't exist"));
// verify that the result should be unsuccessful if the pre set callback makes
// parameter list empty
auto handle2 =
node_parameters->add_pre_set_parameters_callback(empty_parameter_list_callback);
auto results = node_parameters->set_parameters(parameters_to_be_set);
std::string reason = "parameter list cannot be empty, this might be due to "
"pre_set_parameters_callback modifying the original parameters list.";
EXPECT_FALSE(results[0].successful);
EXPECT_EQ(results[0].reason, reason);
EXPECT_NO_THROW(node_parameters->remove_pre_set_parameters_callback(handle2.get()));
RCLCPP_EXPECT_THROW_EQ(
node_parameters->remove_pre_set_parameters_callback(handle2.get()),
std::runtime_error("Pre set parameter callback doesn't exist"));
}
TEST_F(TestNodeParameters, add_remove_post_set_parameters_callback) {
rcl_interfaces::msg::ParameterDescriptor param1_descriptor;
param1_descriptor.name = "double_parameter1";
param1_descriptor.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE;
param1_descriptor.read_only = false;
rcl_interfaces::msg::ParameterDescriptor param2_descriptor;
param2_descriptor.name = "double_parameter2";
param2_descriptor.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE;
param2_descriptor.read_only = false;
double variable_tracking_param1_internally = node_parameters->declare_parameter(
"param1", rclcpp::ParameterValue(0.0), param1_descriptor, false).get<double>();
double variable_tracking_param2_internally = node_parameters->declare_parameter(
"param2", rclcpp::ParameterValue(0.0), param2_descriptor, false).get<double>();
EXPECT_EQ(variable_tracking_param1_internally, 0.0);
EXPECT_EQ(variable_tracking_param2_internally, 0.0);
const std::vector<rclcpp::Parameter> parameters_to_be_set = {
rclcpp::Parameter("param1", 1.0),
rclcpp::Parameter("param2", 2.0)};
// register a callback for successful set parameter and change the internally tracked variables.
auto callback = [&](const std::vector<rclcpp::Parameter> & parameters) {
for (const auto & param : parameters) {
if (param.get_name() == "param1") {
variable_tracking_param1_internally = param.get_value<double>();
} else if (param.get_name() == "param2") {
variable_tracking_param2_internally = param.get_value<double>();
}
}
};
auto handle = node_parameters->add_post_set_parameters_callback(callback);
auto result = node_parameters->set_parameters(parameters_to_be_set);
ASSERT_EQ(2u, result.size());
EXPECT_TRUE(result[0].successful);
EXPECT_TRUE(result[1].successful);
EXPECT_TRUE(node_parameters->has_parameter("param1"));
EXPECT_TRUE(node_parameters->has_parameter("param2"));
EXPECT_EQ(variable_tracking_param1_internally, 1.0);
EXPECT_EQ(variable_tracking_param2_internally, 2.0);
EXPECT_NO_THROW(node_parameters->remove_post_set_parameters_callback(handle.get()));
RCLCPP_EXPECT_THROW_EQ(
node_parameters->remove_post_set_parameters_callback(handle.get()),
std::runtime_error("Post set parameter callback doesn't exist"));
std::runtime_error("Callback doesn't exist"));
}
TEST_F(TestNodeParameters, wildcard_with_namespace)

View File

@@ -36,14 +36,16 @@ const rosidl_message_type_support_t EmptyTypeSupport()
return *rosidl_typesupport_cpp::get_message_type_support_handle<test_msgs::msg::Empty>();
}
const rclcpp::PublisherOptionsWithAllocator<std::allocator<void>> PublisherOptions()
const rcl_publisher_options_t PublisherOptions()
{
return rclcpp::PublisherOptionsWithAllocator<std::allocator<void>>();
return rclcpp::PublisherOptionsWithAllocator<std::allocator<void>>().template
to_rcl_publisher_options<test_msgs::msg::Empty>(rclcpp::QoS(10));
}
const rclcpp::SubscriptionOptionsWithAllocator<std::allocator<void>> SubscriptionOptions()
const rcl_subscription_options_t SubscriptionOptions()
{
return rclcpp::SubscriptionOptionsWithAllocator<std::allocator<void>>();
return rclcpp::SubscriptionOptionsWithAllocator<std::allocator<void>>().template
to_rcl_subscription_options<test_msgs::msg::Empty>(rclcpp::QoS(10));
}
} // namespace
@@ -53,9 +55,7 @@ class TestPublisher : public rclcpp::PublisherBase
public:
explicit TestPublisher(rclcpp::Node * node)
: rclcpp::PublisherBase(
node->get_node_base_interface().get(), "topic", EmptyTypeSupport(),
PublisherOptions().to_rcl_publisher_options<test_msgs::msg::Empty>(rclcpp::QoS(10)),
PublisherOptions().event_callbacks, PublisherOptions().use_default_callbacks) {}
node->get_node_base_interface().get(), "topic", EmptyTypeSupport(), PublisherOptions()) {}
};
class TestSubscription : public rclcpp::SubscriptionBase
@@ -63,9 +63,7 @@ class TestSubscription : public rclcpp::SubscriptionBase
public:
explicit TestSubscription(rclcpp::Node * node)
: rclcpp::SubscriptionBase(
node->get_node_base_interface().get(), EmptyTypeSupport(), "topic",
SubscriptionOptions().to_rcl_subscription_options(rclcpp::QoS(10)),
SubscriptionOptions().event_callbacks, SubscriptionOptions().use_default_callbacks) {}
node->get_node_base_interface().get(), EmptyTypeSupport(), "topic", SubscriptionOptions()) {}
std::shared_ptr<void> create_message() override {return nullptr;}
std::shared_ptr<rclcpp::SerializedMessage>

View File

@@ -162,7 +162,7 @@ protected:
services_.push_back(
node_with_service->create_service<test_msgs::srv::Empty>(
"service", std::move(service_callback), rclcpp::ServicesQoS(), callback_group));
"service", std::move(service_callback), rmw_qos_profile_services_default, callback_group));
return node_with_service;
}
@@ -177,7 +177,7 @@ protected:
clients_.push_back(
node_with_client->create_client<test_msgs::srv::Empty>(
"service", rclcpp::ServicesQoS(), callback_group));
"service", rmw_qos_profile_services_default, callback_group));
return node_with_client;
}
@@ -793,7 +793,7 @@ TEST_F(TestAllocatorMemoryStrategy, get_next_service_out_of_scope) {
[](const test_msgs::srv::Empty::Request::SharedPtr,
test_msgs::srv::Empty::Response::SharedPtr) {};
auto service = node->create_service<test_msgs::srv::Empty>(
"service", std::move(service_callback), rclcpp::ServicesQoS(), callback_group);
"service", std::move(service_callback), rmw_qos_profile_services_default, callback_group);
node->for_each_callback_group(
[node, &weak_groups_to_nodes](rclcpp::CallbackGroup::SharedPtr group_ptr)
@@ -831,7 +831,7 @@ TEST_F(TestAllocatorMemoryStrategy, get_next_client_out_of_scope) {
node->create_callback_group(
rclcpp::CallbackGroupType::MutuallyExclusive);
auto client = node->create_client<test_msgs::srv::Empty>(
"service", rclcpp::ServicesQoS(), callback_group);
"service", rmw_qos_profile_services_default, callback_group);
weak_groups_to_nodes.insert(
std::pair<rclcpp::CallbackGroup::WeakPtr,

View File

@@ -92,30 +92,6 @@ TEST_F(TestClient, construction_and_destruction) {
{
auto client = node->create_client<ListParameters>("service");
}
{
// suppress deprecated function warning
#if !defined(_WIN32)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#else // !defined(_WIN32)
# pragma warning(push)
# pragma warning(disable: 4996)
#endif
auto client = node->create_client<ListParameters>(
"service", rmw_qos_profile_services_default);
// remove warning suppression
#if !defined(_WIN32)
# pragma GCC diagnostic pop
#else // !defined(_WIN32)
# pragma warning(pop)
#endif
}
{
auto client = node->create_client<ListParameters>(
"service", rclcpp::ServicesQoS());
}
{
ASSERT_THROW(
@@ -147,27 +123,6 @@ TEST_F(TestClient, construction_with_free_function) {
nullptr);
}, rclcpp::exceptions::InvalidServiceNameError);
}
{
auto client = rclcpp::create_client<rcl_interfaces::srv::ListParameters>(
node->get_node_base_interface(),
node->get_node_graph_interface(),
node->get_node_services_interface(),
"service",
rclcpp::ServicesQoS(),
nullptr);
}
{
ASSERT_THROW(
{
auto client = rclcpp::create_client<rcl_interfaces::srv::ListParameters>(
node->get_node_base_interface(),
node->get_node_graph_interface(),
node->get_node_services_interface(),
"invalid_?service",
rclcpp::ServicesQoS(),
nullptr);
}, rclcpp::exceptions::InvalidServiceNameError);
}
}
TEST_F(TestClient, construct_with_rcl_error) {
@@ -417,8 +372,8 @@ TEST_F(TestClient, on_new_response_callback) {
auto client_node = std::make_shared<rclcpp::Node>("client_node", "ns");
auto server_node = std::make_shared<rclcpp::Node>("server_node", "ns");
rclcpp::ServicesQoS client_qos;
client_qos.keep_last(3);
rmw_qos_profile_t client_qos = rmw_qos_profile_services_default;
client_qos.depth = 3;
auto client = client_node->create_client<test_msgs::srv::Empty>("test_service", client_qos);
std::atomic<size_t> server_requests_count {0};
auto server_callback = [&server_requests_count](
@@ -521,30 +476,32 @@ TEST_F(TestClient, rcl_client_response_subscription_get_actual_qos_error) {
}
TEST_F(TestClient, client_qos) {
rclcpp::ServicesQoS qos_profile;
qos_profile.liveliness(rclcpp::LivelinessPolicy::Automatic);
rclcpp::Duration duration(std::chrono::nanoseconds(1));
qos_profile.deadline(duration);
qos_profile.lifespan(duration);
qos_profile.liveliness_lease_duration(duration);
rmw_qos_profile_t qos_profile = rmw_qos_profile_services_default;
qos_profile.liveliness = RMW_QOS_POLICY_LIVELINESS_AUTOMATIC;
uint64_t duration = 1;
qos_profile.deadline = {duration, duration};
qos_profile.lifespan = {duration, duration};
qos_profile.liveliness_lease_duration = {duration, duration};
auto client =
node->create_client<test_msgs::srv::Empty>("client", qos_profile);
auto init_qos =
rclcpp::QoS(rclcpp::QoSInitialization::from_rmw(qos_profile), qos_profile);
auto rp_qos = client->get_request_publisher_actual_qos();
auto rs_qos = client->get_response_subscription_actual_qos();
EXPECT_EQ(qos_profile, rp_qos);
EXPECT_EQ(init_qos, rp_qos);
// Lifespan has no meaning for subscription/readers
rs_qos.lifespan(qos_profile.lifespan());
EXPECT_EQ(qos_profile, rs_qos);
rs_qos.lifespan(qos_profile.lifespan);
EXPECT_EQ(init_qos, rs_qos);
}
TEST_F(TestClient, client_qos_depth) {
using namespace std::literals::chrono_literals;
rclcpp::ServicesQoS client_qos_profile;
client_qos_profile.keep_last(2);
rmw_qos_profile_t client_qos_profile = rmw_qos_profile_default;
client_qos_profile.depth = 2;
auto client = node->create_client<test_msgs::srv::Empty>("test_qos_depth", client_qos_profile);
@@ -555,10 +512,10 @@ TEST_F(TestClient, client_qos_depth) {
auto server_node = std::make_shared<rclcpp::Node>("server_node", "/ns");
rclcpp::QoS server_qos(rclcpp::QoSInitialization::from_rmw(rmw_qos_profile_default));
rmw_qos_profile_t server_qos_profile = rmw_qos_profile_default;
auto server = server_node->create_service<test_msgs::srv::Empty>(
"test_qos_depth", std::move(server_callback), server_qos);
"test_qos_depth", std::move(server_callback), server_qos_profile);
auto request = std::make_shared<test_msgs::srv::Empty::Request>();
::testing::AssertionResult request_result = ::testing::AssertionSuccess();
@@ -586,10 +543,10 @@ TEST_F(TestClient, client_qos_depth) {
std::this_thread::sleep_for(2ms);
}
EXPECT_GT(server_cb_count_, client_qos_profile.depth());
EXPECT_GT(server_cb_count_, client_qos_profile.depth);
start = std::chrono::steady_clock::now();
while ((client_cb_count_ < client_qos_profile.depth()) &&
while ((client_cb_count_ < client_qos_profile.depth) &&
(std::chrono::steady_clock::now() - start) < 1s)
{
rclcpp::spin_some(node);
@@ -599,5 +556,5 @@ TEST_F(TestClient, client_qos_depth) {
// so more client callbacks might be called than expected.
rclcpp::spin_some(node);
EXPECT_EQ(client_cb_count_, client_qos_profile.depth());
EXPECT_EQ(client_cb_count_, client_qos_profile.depth);
}

View File

@@ -93,3 +93,19 @@ TEST_F(TestCreateSubscription, create_with_statistics) {
ASSERT_NE(nullptr, subscription);
EXPECT_STREQ("/ns/topic_name", subscription->get_topic_name());
}
TEST_F(TestCreateSubscription, create_with_intra_process_com) {
auto node = std::make_shared<rclcpp::Node>("my_node", "/ns");
auto options = rclcpp::SubscriptionOptions();
options.use_intra_process_comm = rclcpp::IntraProcessSetting::Enable;
auto callback = [](test_msgs::msg::Empty::ConstSharedPtr) {};
rclcpp::Subscription<test_msgs::msg::Empty>::SharedPtr subscription;
ASSERT_NO_THROW(
{
subscription = rclcpp::create_subscription<test_msgs::msg::Empty>(
node, "topic_name", rclcpp::SystemDefaultsQoS(), callback, options);
});
ASSERT_NE(nullptr, subscription);
EXPECT_STREQ("/ns/topic_name", subscription->get_topic_name());
}

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