Compare commits
19 Commits
use_errors
...
1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb4bdb7b19 | ||
|
|
803d7f27be | ||
|
|
cac761373f | ||
|
|
66114c3a4a | ||
|
|
ccf2f1c760 | ||
|
|
846e4ce9d3 | ||
|
|
e24f402238 | ||
|
|
4d1de47df3 | ||
|
|
5b1877adc4 | ||
|
|
e0d0e03078 | ||
|
|
d10f7b7c62 | ||
|
|
f160a8bc1d | ||
|
|
e2dbc5d5d5 | ||
|
|
13c09acfad | ||
|
|
f69b18203f | ||
|
|
ef6434026f | ||
|
|
1c943d16fc | ||
|
|
e6325839f1 | ||
|
|
9150201d28 |
@@ -8,7 +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.
|
||||
|
||||
Visit the [rclcpp API documentation](http://docs.ros2.org/eloquent/api/rclcpp/) for a complete list of its main components.
|
||||
Visit the [rclcpp API documentation](http://docs.ros2.org/latest/api/rclcpp/) for a complete list of its main components.
|
||||
|
||||
### Examples
|
||||
|
||||
|
||||
@@ -2,6 +2,106 @@
|
||||
Changelog for package rclcpp
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
1.0.0 (2020-05-12)
|
||||
------------------
|
||||
* Remove MANUAL_BY_NODE liveliness API (`#1107 <https://github.com/ros2/rclcpp/issues/1107>`_)
|
||||
* Use rosidl_default_generators dependency in test (`#1114 <https://github.com/ros2/rclcpp/issues/1114>`_)
|
||||
* Make sure to include what you use (`#1112 <https://github.com/ros2/rclcpp/issues/1112>`_)
|
||||
* Mark flaky test with xfail: TestMultiThreadedExecutor (`#1109 <https://github.com/ros2/rclcpp/issues/1109>`_)
|
||||
* Contributors: Chris Lalancette, Ivan Santiago Paunovic, Karsten Knese, Louise Poubel
|
||||
|
||||
0.9.1 (2020-05-08)
|
||||
------------------
|
||||
* Fix tests that were not properly torn down (`#1073 <https://github.com/ros2/rclcpp/issues/1073>`_)
|
||||
* Added docblock in rclcpp (`#1103 <https://github.com/ros2/rclcpp/issues/1103>`_)
|
||||
* Added Quality declaration: rclcpp, rclpp_action, rclcpp_components andrclcpp_lifecycle (`#1100 <https://github.com/ros2/rclcpp/issues/1100>`_)
|
||||
* Use RCL_RET_SERVICE_TAKE_FAILED and not RCL_RET_CLIENT_TAKE_FAILED when checking a request take (`#1101 <https://github.com/ros2/rclcpp/issues/1101>`_)
|
||||
* Update comment about return value in Executor::get_next_ready_executable (`#1085 <https://github.com/ros2/rclcpp/issues/1085>`_)
|
||||
* Contributors: Alejandro Hernández Cordero, Christophe Bedard, Devin Bonnie, Ivan Santiago Paunovic
|
||||
|
||||
0.9.0 (2020-04-29)
|
||||
------------------
|
||||
* Serialized message move constructor (`#1097 <https://github.com/ros2/rclcpp/issues/1097>`_)
|
||||
* Enforce a precedence for wildcard matching in parameter overrides. (`#1094 <https://github.com/ros2/rclcpp/issues/1094>`_)
|
||||
* Add serialized_message.hpp header (`#1095 <https://github.com/ros2/rclcpp/issues/1095>`_)
|
||||
* Add received message age metric to topic statistics (`#1080 <https://github.com/ros2/rclcpp/issues/1080>`_)
|
||||
* Deprecate redundant namespaces (`#1083 <https://github.com/ros2/rclcpp/issues/1083>`_)
|
||||
* Export targets in addition to include directories / libraries (`#1088 <https://github.com/ros2/rclcpp/issues/1088>`_)
|
||||
* Ensure logging is initialized just once (`#998 <https://github.com/ros2/rclcpp/issues/998>`_)
|
||||
* Adapt subscription traits to rclcpp::SerializedMessage (`#1092 <https://github.com/ros2/rclcpp/issues/1092>`_)
|
||||
* Protect subscriber_statistics_collectors\_ with a mutex (`#1084 <https://github.com/ros2/rclcpp/issues/1084>`_)
|
||||
* Remove unused test variable (`#1087 <https://github.com/ros2/rclcpp/issues/1087>`_)
|
||||
* Use serialized message (`#1081 <https://github.com/ros2/rclcpp/issues/1081>`_)
|
||||
* Integrate topic statistics (`#1072 <https://github.com/ros2/rclcpp/issues/1072>`_)
|
||||
* Fix rclcpp interface traits test (`#1086 <https://github.com/ros2/rclcpp/issues/1086>`_)
|
||||
* Generate node interfaces' getters and traits (`#1069 <https://github.com/ros2/rclcpp/issues/1069>`_)
|
||||
* Use composition for serialized message (`#1082 <https://github.com/ros2/rclcpp/issues/1082>`_)
|
||||
* Dnae adas/serialized message (`#1075 <https://github.com/ros2/rclcpp/issues/1075>`_)
|
||||
* Reflect changes in rclcpp API (`#1079 <https://github.com/ros2/rclcpp/issues/1079>`_)
|
||||
* Fix build regression (`#1078 <https://github.com/ros2/rclcpp/issues/1078>`_)
|
||||
* Add NodeDefault option for enabling topic statistics (`#1074 <https://github.com/ros2/rclcpp/issues/1074>`_)
|
||||
* Topic Statistics: Add SubscriptionTopicStatistics class (`#1050 <https://github.com/ros2/rclcpp/issues/1050>`_)
|
||||
* Add SubscriptionOptions for topic statistics (`#1057 <https://github.com/ros2/rclcpp/issues/1057>`_)
|
||||
* Remove warning message from failing to register default callback (`#1067 <https://github.com/ros2/rclcpp/issues/1067>`_)
|
||||
* Create a default warning for qos incompatibility (`#1051 <https://github.com/ros2/rclcpp/issues/1051>`_)
|
||||
* Add WaitSet class and modify entities to work without executor (`#1047 <https://github.com/ros2/rclcpp/issues/1047>`_)
|
||||
* Include what you use (`#1059 <https://github.com/ros2/rclcpp/issues/1059>`_)
|
||||
* Rename rosidl_generator_cpp namespace to rosidl_runtime_cpp (`#1060 <https://github.com/ros2/rclcpp/issues/1060>`_)
|
||||
* Changed rosidl_generator_c/cpp to rosidl_runtime_c/cpp (`#1014 <https://github.com/ros2/rclcpp/issues/1014>`_)
|
||||
* Use constexpr for endpoint type name (`#1055 <https://github.com/ros2/rclcpp/issues/1055>`_)
|
||||
* Add InvalidParameterTypeException (`#1027 <https://github.com/ros2/rclcpp/issues/1027>`_)
|
||||
* Support for ON_REQUESTED_INCOMPATIBLE_QOS and ON_OFFERED_INCOMPATIBLE_QOS events (`#924 <https://github.com/ros2/rclcpp/issues/924>`_)
|
||||
* Fixup clang warning (`#1040 <https://github.com/ros2/rclcpp/issues/1040>`_)
|
||||
* Adding a "static" single threaded executor (`#1034 <https://github.com/ros2/rclcpp/issues/1034>`_)
|
||||
* Add equality operators for QoS profile (`#1032 <https://github.com/ros2/rclcpp/issues/1032>`_)
|
||||
* Remove extra vertical whitespace (`#1030 <https://github.com/ros2/rclcpp/issues/1030>`_)
|
||||
* Switch IntraProcessMessage to test_msgs/Empty (`#1017 <https://github.com/ros2/rclcpp/issues/1017>`_)
|
||||
* Add new type of exception that may be thrown during creation of publisher/subscription (`#1026 <https://github.com/ros2/rclcpp/issues/1026>`_)
|
||||
* Don't check lifespan on publisher QoS (`#1002 <https://github.com/ros2/rclcpp/issues/1002>`_)
|
||||
* Fix get_parameter_tyeps of AsyncPrameterClient results are always empty (`#1019 <https://github.com/ros2/rclcpp/issues/1019>`_)
|
||||
* Cleanup node interfaces includes (`#1016 <https://github.com/ros2/rclcpp/issues/1016>`_)
|
||||
* Add ifdefs to remove tracing-related calls if tracing is disabled (`#1001 <https://github.com/ros2/rclcpp/issues/1001>`_)
|
||||
* Include missing header in node_graph.cpp (`#994 <https://github.com/ros2/rclcpp/issues/994>`_)
|
||||
* Add missing includes of logging.hpp (`#995 <https://github.com/ros2/rclcpp/issues/995>`_)
|
||||
* Zero initialize publisher GID in subscription intra process callback (`#1011 <https://github.com/ros2/rclcpp/issues/1011>`_)
|
||||
* Removed ament_cmake dependency (`#989 <https://github.com/ros2/rclcpp/issues/989>`_)
|
||||
* Switch to using new rcutils_strerror (`#993 <https://github.com/ros2/rclcpp/issues/993>`_)
|
||||
* Ensure all rclcpp::Clock accesses are thread-safe
|
||||
* Use a PIMPL for rclcpp::Clock implementation
|
||||
* Replace rmw_implementation for rmw dependency in package.xml (`#990 <https://github.com/ros2/rclcpp/issues/990>`_)
|
||||
* Add missing service callback registration tracepoint (`#986 <https://github.com/ros2/rclcpp/issues/986>`_)
|
||||
* Rename rmw_topic_endpoint_info_array count to size (`#996 <https://github.com/ros2/rclcpp/issues/996>`_)
|
||||
* Implement functions to get publisher and subcription informations like QoS policies from topic name (`#960 <https://github.com/ros2/rclcpp/issues/960>`_)
|
||||
* Code style only: wrap after open parenthesis if not in one line (`#977 <https://github.com/ros2/rclcpp/issues/977>`_)
|
||||
* Accept taking an rvalue ref future in spin_until_future_complete (`#971 <https://github.com/ros2/rclcpp/issues/971>`_)
|
||||
* Allow node clock use in logging macros (`#969 <https://github.com/ros2/rclcpp/issues/969>`_) (`#970 <https://github.com/ros2/rclcpp/issues/970>`_)
|
||||
* Change order of deprecated and visibility attributes (`#968 <https://github.com/ros2/rclcpp/issues/968>`_)
|
||||
* Deprecated is_initialized() (`#967 <https://github.com/ros2/rclcpp/issues/967>`_)
|
||||
* Don't specify calling convention in std::_Binder template (`#952 <https://github.com/ros2/rclcpp/issues/952>`_)
|
||||
* Added missing include to logging.hpp (`#964 <https://github.com/ros2/rclcpp/issues/964>`_)
|
||||
* Assigning make_shared result to variables in test (`#963 <https://github.com/ros2/rclcpp/issues/963>`_)
|
||||
* Fix unused parameter warning (`#962 <https://github.com/ros2/rclcpp/issues/962>`_)
|
||||
* Stop retaining ownership of the rcl context in GraphListener (`#946 <https://github.com/ros2/rclcpp/issues/946>`_)
|
||||
* Clear sub contexts when starting another init-shutdown cycle (`#947 <https://github.com/ros2/rclcpp/issues/947>`_)
|
||||
* Avoid possible UB in Clock jump callbacks (`#954 <https://github.com/ros2/rclcpp/issues/954>`_)
|
||||
* Handle unknown global ROS arguments (`#951 <https://github.com/ros2/rclcpp/issues/951>`_)
|
||||
* Mark get_clock() as override to fix clang warnings (`#939 <https://github.com/ros2/rclcpp/issues/939>`_)
|
||||
* Create node clock calls const (try 2) (`#922 <https://github.com/ros2/rclcpp/issues/922>`_)
|
||||
* Fix asserts on shared_ptr::use_count; expects long, got uint32 (`#936 <https://github.com/ros2/rclcpp/issues/936>`_)
|
||||
* Use absolute topic name for parameter events (`#929 <https://github.com/ros2/rclcpp/issues/929>`_)
|
||||
* Add enable_rosout into NodeOptions. (`#900 <https://github.com/ros2/rclcpp/issues/900>`_)
|
||||
* Removing "virtual", adding "override" keywords (`#897 <https://github.com/ros2/rclcpp/issues/897>`_)
|
||||
* Use weak_ptr to store context in GraphListener (`#906 <https://github.com/ros2/rclcpp/issues/906>`_)
|
||||
* Complete published event message when declaring a parameter (`#928 <https://github.com/ros2/rclcpp/issues/928>`_)
|
||||
* Fix duration.cpp lint error (`#930 <https://github.com/ros2/rclcpp/issues/930>`_)
|
||||
* Intra-process subscriber should use RMW actual qos. (ros2`#913 <https://github.com/ros2/rclcpp/issues/913>`_) (`#914 <https://github.com/ros2/rclcpp/issues/914>`_)
|
||||
* Type conversions fixes (`#901 <https://github.com/ros2/rclcpp/issues/901>`_)
|
||||
* Add override keyword to functions
|
||||
* Remove unnecessary virtual keywords
|
||||
* Only check for new work once in spin_some (`#471 <https://github.com/ros2/rclcpp/issues/471>`_) (`#844 <https://github.com/ros2/rclcpp/issues/844>`_)
|
||||
* Add addition/subtraction assignment operators to Time (`#748 <https://github.com/ros2/rclcpp/issues/748>`_)
|
||||
* Contributors: Alberto Soragna, Alejandro Hernández Cordero, Barry Xu, Chris Lalancette, Christophe Bedard, Claire Wang, Dan Rose, DensoADAS, Devin Bonnie, Dino Hüllmann, Dirk Thomas, DongheeYe, Emerson Knapp, Ivan Santiago Paunovic, Jacob Perron, Jaison Titus, Karsten Knese, Matt Schickler, Miaofei Mei, Michel Hidalgo, Mikael Arguedas, Monika Idzik, Prajakta Gokhale, Roger Strain, Scott K Logan, Sean Kelly, Stephen Brawner, Steven Macenski, Steven! Ragnarök, Todd Malsbary, Tomoya Fujita, William Woodall, Zachary Michaels
|
||||
|
||||
0.8.3 (2019-11-19)
|
||||
------------------
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ find_package(rcpputils REQUIRED)
|
||||
find_package(rcutils REQUIRED)
|
||||
find_package(rmw REQUIRED)
|
||||
find_package(rosgraph_msgs REQUIRED)
|
||||
find_package(rosidl_default_generators REQUIRED)
|
||||
find_package(rosidl_runtime_cpp REQUIRED)
|
||||
find_package(rosidl_typesupport_c REQUIRED)
|
||||
find_package(rosidl_typesupport_cpp REQUIRED)
|
||||
@@ -217,6 +216,7 @@ if(BUILD_TESTING)
|
||||
ament_lint_auto_find_test_dependencies()
|
||||
|
||||
find_package(rmw_implementation_cmake REQUIRED)
|
||||
find_package(rosidl_default_generators REQUIRED)
|
||||
|
||||
find_package(test_msgs REQUIRED)
|
||||
|
||||
@@ -604,6 +604,7 @@ if(BUILD_TESTING)
|
||||
ament_target_dependencies(test_multi_threaded_executor
|
||||
"rcl")
|
||||
target_link_libraries(test_multi_threaded_executor ${PROJECT_NAME})
|
||||
ament_add_test_label(test_multi_threaded_executor xfail)
|
||||
endif()
|
||||
|
||||
ament_add_gtest(test_guard_condition test/test_guard_condition.cpp
|
||||
|
||||
173
rclcpp/QUALITY_DECLARATION.md
Normal file
173
rclcpp/QUALITY_DECLARATION.md
Normal file
@@ -0,0 +1,173 @@
|
||||
This document is a declaration of software quality for the `rclcpp` package, based on the guidelines in [REP-2004](https://github.com/ros-infrastructure/rep/blob/rep-2004/rep-2004.rst).
|
||||
|
||||
# `rclcpp` Quality Declaration
|
||||
|
||||
The package `rclcpp` claims to be in the **Quality Level 4** category.
|
||||
|
||||
Below are the rationales, notes, and caveats for this claim, organized by each requirement listed in the [Package Quality Categories in REP-2004](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#package-quality-categories) of the ROS2 developer guide.
|
||||
|
||||
## Version Policy [1]
|
||||
|
||||
### Version Scheme [1.i]
|
||||
|
||||
`rclcpp` uses `semver` according to the recommendation for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#versioning)
|
||||
|
||||
### Version Stability [1.ii]
|
||||
|
||||
`rclcpp` is not yet at a stable version, i.e. `>= 1.0.0`.
|
||||
The current version can be found in its [package.xml](package.xml), and its change history can be found in its [CHANGELOG](CHANGELOG.rst).
|
||||
|
||||
### Public API Declaration [1.iii]
|
||||
|
||||
All symbols in the installed headers are considered part of the public API.
|
||||
|
||||
Except for the exclusions listed below, all installed headers are in the `include` directory of the package, headers in any other folders are not installed and considered private.
|
||||
Headers under the folder `experimental` are not considered part of the public API as they have not yet been stabilized. These symbols are namespaced `rclcpp::experimental`.
|
||||
Headers under the folder `detail` are not considered part of the public API and are subject to change without notice. These symbols are namespaced `rclcpp::detail`.
|
||||
|
||||
### API Stability Policy [1.iv]
|
||||
|
||||
`rclcpp` will not break public API within a released ROS distribution, i.e. no major releases once the ROS distribution is released.
|
||||
|
||||
### ABI Stability Policy [1.v]
|
||||
|
||||
`rclcpp` contains C++ code and therefore must be concerned with ABI stability, and will maintain ABI stability within a ROS distribution.
|
||||
|
||||
### ABI and ABI Stability Within a Released ROS Distribution [1.vi]
|
||||
|
||||
`rclcpp` will not break API nor ABI within a released ROS distribution, i.e. no major releases once the ROS distribution is released.
|
||||
|
||||
## Change Control Process [2]
|
||||
|
||||
`rclcpp` follows the recommended guidelines for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process).
|
||||
|
||||
### Change Requests [2.i]
|
||||
|
||||
All changes will occur through a pull request, check [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process) for additional information.
|
||||
|
||||
### Contributor Origin [2.ii]
|
||||
|
||||
This package uses DCO as its confirmation of contributor origin policy. More information can be found in [CONTRIBUTING](../CONTRIBUTING.md).
|
||||
|
||||
### Peer Review Policy [2.iii]
|
||||
|
||||
All pull requests will be peer-reviewed, check [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process) for additional information.
|
||||
|
||||
### 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)
|
||||
|
||||
Currently nightly results can be seen here:
|
||||
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp/)
|
||||
|
||||
### Documentation Policy [2.v]
|
||||
|
||||
All pull requests must resolve related documentation changes before merging.
|
||||
|
||||
## Documentation [3]
|
||||
|
||||
### Feature Documentation [3.i]
|
||||
|
||||
`rclcpp` has a [feature list](http://docs.ros2.org/latest/api/rclcpp/) and each item in the list links to the corresponding feature documentation. There is documentation for all of the features, and new features require documentation before being added.
|
||||
|
||||
### Public API Documentation [3.ii]
|
||||
|
||||
The API is publicly available in the [ROS 2 API documentation](http://docs.ros2.org/latest/api/rclcpp/).
|
||||
|
||||
### License [3.iii]
|
||||
|
||||
The license for `rclcpp` is Apache 2.0, and a summary is in each source file, the type is declared in the [`package.xml`](./package.xml) manifest file, and a full copy of the license is in the [`LICENSE`](../LICENSE) file.
|
||||
|
||||
There is an automated test which runs a linter that ensures each file has a license statement. [Here](http://build.ros2.org/view/Epr/job/Epr__rclcpp__ubuntu_bionic_amd64/lastBuild/testReport/rclcpp/) can be found a list with the latest results of the various linters being run on the package.
|
||||
|
||||
### Copyright Statements [3.iv]
|
||||
|
||||
The copyright holders each provide a statement of copyright in each source code file in `rclcpp`.
|
||||
|
||||
There is an automated test which runs a linter that ensures each file has at least one copyright statement. Latest linter result report can be seen [here](http://build.ros2.org/view/Epr/job/Epr__rclcpp__ubuntu_bionic_amd64/lastBuild/testReport/rclcpp/copyright/).
|
||||
|
||||
## Testing [4]
|
||||
|
||||
### Feature Testing [4.i]
|
||||
|
||||
Each feature in `rclcpp` has corresponding tests which simulate typical usage, and they are located in the [`test`](https://github.com/ros2/rclcpp/tree/master/test) directory.
|
||||
New features are required to have tests before being added.
|
||||
|
||||
Currently nightly test results can be seen here:
|
||||
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp/)
|
||||
|
||||
### Public API Testing [4.ii]
|
||||
|
||||
Each part of the public API has tests, and new additions or changes to the public API require tests before being added.
|
||||
The tests aim to cover both typical usage and corner cases, but are quantified by contributing to code coverage.
|
||||
|
||||
### Coverage [4.iii]
|
||||
|
||||
`rclcpp` follows the recommendations for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#code-coverage), and opts to use line coverage instead of branch coverage.
|
||||
|
||||
This includes:
|
||||
|
||||
- tracking and reporting line coverage statistics
|
||||
- achieving and maintaining a reasonable branch line coverage (90-100%)
|
||||
- no lines are manually skipped in coverage calculations
|
||||
|
||||
Changes are required to make a best effort to keep or increase coverage before being accepted, but decreases are allowed if properly justified and accepted by reviewers.
|
||||
|
||||
### Performance [4.iv]
|
||||
|
||||
It is not yet defined if this package requires performance testing and how addresses this topic.
|
||||
|
||||
### Linters and Static Analysis [4.v]
|
||||
|
||||
`rclcpp` uses and passes all the ROS2 standard linters and static analysis tools for a C++ package as described in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#linters-and-static-analysis). Passing implies there are no linter/static errors when testing against CI of supported platforms.
|
||||
|
||||
Currently nightly test results can be seen here:
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp/)
|
||||
|
||||
## Dependencies [5]
|
||||
|
||||
### Direct and Optional Runtime ROS Dependencies [5.i]/[5.ii]
|
||||
|
||||
`rclcpp` has the following runtime ROS dependencies:
|
||||
- libstatistics_collector
|
||||
- rcl
|
||||
- rcl_yaml_param_parser
|
||||
- rcpputils
|
||||
- rcutils
|
||||
- rmw
|
||||
- statistics_msgs
|
||||
- tracetools
|
||||
|
||||
It has several "buildtool" dependencies, which do not affect the resulting quality of the package, because they do not contribute to the public library API.
|
||||
It also has several test dependencies, which do not affect the resulting quality of the package, because they are only used to build and run the test code.
|
||||
|
||||
### Direct Runtime non-ROS Dependency [5.iii]
|
||||
|
||||
`rclcpp` has no run-time or build-time dependencies that need to be considered for this declaration.
|
||||
|
||||
## 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.
|
||||
|
||||
Currently nightly build status can be seen here:
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/rclcpp/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/rclcpp/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/rclcpp/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/rclcpp/)
|
||||
|
||||
## Security
|
||||
|
||||
### Vulnerability Disclosure Policy [7.i]
|
||||
|
||||
This package does not yet have a Vulnerability Disclosure Policy
|
||||
7
rclcpp/README.md
Normal file
7
rclcpp/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# `rclcpp`
|
||||
|
||||
The ROS client library in C++. Visit the [rclcpp API documentation](http://docs.ros2.org/latest/api/rclcpp/) for a complete list of its main components.
|
||||
|
||||
## Quality Declaration
|
||||
|
||||
This package claims to be in the **Quality Level 4** category, see the [Quality Declaration](QUALITY_DECLARATION.md) for more details.
|
||||
@@ -84,22 +84,42 @@ public:
|
||||
bool
|
||||
take_type_erased_response(void * response_out, rmw_request_id_t & request_header_out);
|
||||
|
||||
/// Return the name of the service.
|
||||
/** \return The name of the service. */
|
||||
RCLCPP_PUBLIC
|
||||
const char *
|
||||
get_service_name() const;
|
||||
|
||||
/// Return the rcl_client_t client handle in a std::shared_ptr.
|
||||
/**
|
||||
* This handle remains valid after the Client is destroyed.
|
||||
* The actual rcl client is not finalized until it is out of scope everywhere.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
std::shared_ptr<rcl_client_t>
|
||||
get_client_handle();
|
||||
|
||||
/// Return the rcl_client_t client handle in a std::shared_ptr.
|
||||
/**
|
||||
* This handle remains valid after the Client is destroyed.
|
||||
* The actual rcl client is not finalized until it is out of scope everywhere.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
std::shared_ptr<const rcl_client_t>
|
||||
get_client_handle() const;
|
||||
|
||||
/// Return if the service is ready.
|
||||
/**
|
||||
* \return `true` if the service is ready, `false` otherwise
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
bool
|
||||
service_is_ready() const;
|
||||
|
||||
/// Wait for a service to be ready.
|
||||
/**
|
||||
* \param timeout maximum time to wait
|
||||
*/
|
||||
template<typename RepT = int64_t, typename RatioT = std::milli>
|
||||
bool
|
||||
wait_for_service(
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
bool
|
||||
ros_time_is_active();
|
||||
|
||||
/// Return the rcl_clock_t clock handle
|
||||
RCLCPP_PUBLIC
|
||||
rcl_clock_t *
|
||||
get_clock_handle() noexcept;
|
||||
@@ -97,6 +98,7 @@ public:
|
||||
rcl_clock_type_t
|
||||
get_clock_type() const noexcept;
|
||||
|
||||
/// Get the clock's mutex
|
||||
RCLCPP_PUBLIC
|
||||
std::mutex &
|
||||
get_clock_mutex() noexcept;
|
||||
|
||||
@@ -26,11 +26,22 @@ namespace rclcpp
|
||||
class RCLCPP_PUBLIC Duration
|
||||
{
|
||||
public:
|
||||
/// Duration constructor.
|
||||
/**
|
||||
* Initializes the time values for seconds and nanoseconds individually.
|
||||
* Large values for nsecs are wrapped automatically with the remainder added to secs.
|
||||
* Both inputs must be integers.
|
||||
* Seconds can be negative.
|
||||
*
|
||||
* \param seconds time in seconds
|
||||
* \param nanoseconds time in nanoseconds
|
||||
*/
|
||||
Duration(int32_t seconds, uint32_t nanoseconds);
|
||||
|
||||
// This constructor matches any numeric value - ints or floats
|
||||
// This constructor matches any numeric value - ints or floats.
|
||||
explicit Duration(rcl_duration_value_t nanoseconds);
|
||||
|
||||
// This constructor matches std::chrono::nanoseconds.
|
||||
explicit Duration(std::chrono::nanoseconds nanoseconds);
|
||||
|
||||
// This constructor matches any std::chrono value other than nanoseconds
|
||||
@@ -44,6 +55,10 @@ public:
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
Duration(const builtin_interfaces::msg::Duration & duration_msg); // NOLINT(runtime/explicit)
|
||||
|
||||
/// Time constructor
|
||||
/**
|
||||
* \param duration rcl_duration_t structure to copy.
|
||||
*/
|
||||
explicit Duration(const rcl_duration_t & duration);
|
||||
|
||||
Duration(const Duration & rhs);
|
||||
@@ -80,6 +95,10 @@ public:
|
||||
Duration
|
||||
operator-(const rclcpp::Duration & rhs) const;
|
||||
|
||||
/// Get the maximum representable value.
|
||||
/**
|
||||
* \return the maximum representable value
|
||||
*/
|
||||
static
|
||||
Duration
|
||||
max();
|
||||
@@ -87,19 +106,27 @@ public:
|
||||
Duration
|
||||
operator*(double scale) const;
|
||||
|
||||
/// Get duration in nanosecods
|
||||
/**
|
||||
* \return the duration in nanoseconds as a rcl_duration_value_t.
|
||||
*/
|
||||
rcl_duration_value_t
|
||||
nanoseconds() const;
|
||||
|
||||
/// \return the duration in seconds as a floating point number.
|
||||
/// \warning Depending on sizeof(double) there could be significant precision loss.
|
||||
/// When an exact time is required use nanoseconds() instead.
|
||||
/// Get duration in seconds
|
||||
/**
|
||||
* \warning Depending on sizeof(double) there could be significant precision loss.
|
||||
* When an exact time is required use nanoseconds() instead.
|
||||
* \return the duration in seconds as a floating point number.
|
||||
*/
|
||||
double
|
||||
seconds() const;
|
||||
|
||||
// Create a duration object from a floating point number representing seconds
|
||||
/// Create a duration object from a floating point number representing seconds
|
||||
static Duration
|
||||
from_seconds(double seconds);
|
||||
|
||||
/// Convert Duration into a std::chrono::Duration.
|
||||
template<class DurationT>
|
||||
DurationT
|
||||
to_chrono() const
|
||||
@@ -107,6 +134,7 @@ public:
|
||||
return std::chrono::duration_cast<DurationT>(std::chrono::nanoseconds(this->nanoseconds()));
|
||||
}
|
||||
|
||||
/// Convert Duration into rmw_time_t.
|
||||
rmw_time_t
|
||||
to_rmw_time() const;
|
||||
|
||||
|
||||
@@ -186,8 +186,8 @@ public:
|
||||
/// Create and return a Subscription.
|
||||
/**
|
||||
* \param[in] topic_name The topic to subscribe on.
|
||||
* \param[in] qos QoS profile for Subcription.
|
||||
* \param[in] callback The user-defined callback function to receive a message
|
||||
* \param[in] qos_history_depth The depth of the subscription's incoming message queue.
|
||||
* \param[in] options Additional options for the creation of the Subscription.
|
||||
* \param[in] msg_mem_strat The message memory strategy to use for allocating messages.
|
||||
* \return Shared pointer to the created subscription.
|
||||
@@ -229,7 +229,13 @@ public:
|
||||
CallbackT callback,
|
||||
rclcpp::CallbackGroup::SharedPtr group = nullptr);
|
||||
|
||||
/* Create and return a Client. */
|
||||
/// Create and return a Client.
|
||||
/**
|
||||
* \param[in] service_name The topic to service on.
|
||||
* \param[in] 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.
|
||||
*/
|
||||
template<typename ServiceT>
|
||||
typename rclcpp::Client<ServiceT>::SharedPtr
|
||||
create_client(
|
||||
@@ -237,7 +243,14 @@ public:
|
||||
const rmw_qos_profile_t & qos_profile = rmw_qos_profile_services_default,
|
||||
rclcpp::CallbackGroup::SharedPtr group = nullptr);
|
||||
|
||||
/* Create and return a Service. */
|
||||
/// Create and return a Service.
|
||||
/**
|
||||
* \param[in] service_name The topic to service on.
|
||||
* \param[in] callback User-defined callback function.
|
||||
* \param[in] 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.
|
||||
*/
|
||||
template<typename ServiceT, typename CallbackT>
|
||||
typename rclcpp::Service<ServiceT>::SharedPtr
|
||||
create_service(
|
||||
@@ -1111,19 +1124,6 @@ public:
|
||||
const rclcpp::NodeOptions &
|
||||
get_node_options() const;
|
||||
|
||||
/// Manually assert that this Node is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE).
|
||||
/**
|
||||
* If the rmw Liveliness policy is set to RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE, the creator
|
||||
* of this node may manually call `assert_liveliness` at some point in time to signal to the rest
|
||||
* of the system that this Node is still alive.
|
||||
*
|
||||
* \return `true` if the liveliness was asserted successfully, otherwise `false`
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
RCUTILS_WARN_UNUSED
|
||||
bool
|
||||
assert_liveliness() const;
|
||||
|
||||
protected:
|
||||
/// Construct a sub-node, which will extend the namespace of all entities created with it.
|
||||
/**
|
||||
|
||||
@@ -91,11 +91,6 @@ public:
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
|
||||
bool
|
||||
assert_liveliness() const override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
|
||||
rclcpp::CallbackGroup::SharedPtr
|
||||
create_callback_group(rclcpp::CallbackGroupType group_type) override;
|
||||
|
||||
|
||||
@@ -102,12 +102,6 @@ public:
|
||||
std::shared_ptr<const rcl_node_t>
|
||||
get_shared_rcl_node_handle() const = 0;
|
||||
|
||||
/// Manually assert that this Node is alive (for RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE).
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
bool
|
||||
assert_liveliness() const = 0;
|
||||
|
||||
/// Create and return a callback group.
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
|
||||
@@ -83,18 +83,22 @@ public:
|
||||
bool
|
||||
operator!=(const Parameter & rhs) const;
|
||||
|
||||
/// Get the type of the parameter
|
||||
RCLCPP_PUBLIC
|
||||
ParameterType
|
||||
get_type() const;
|
||||
|
||||
/// Get the type name of the parameter
|
||||
RCLCPP_PUBLIC
|
||||
std::string
|
||||
get_type_name() const;
|
||||
|
||||
/// Get the name of the parameter
|
||||
RCLCPP_PUBLIC
|
||||
const std::string &
|
||||
get_name() const;
|
||||
|
||||
/// Get value of parameter as a parameter message.
|
||||
RCLCPP_PUBLIC
|
||||
rcl_interfaces::msg::ParameterValue
|
||||
get_value_message() const;
|
||||
@@ -105,6 +109,9 @@ public:
|
||||
get_parameter_value() const;
|
||||
|
||||
/// Get value of parameter using rclcpp::ParameterType as template argument.
|
||||
/**
|
||||
* \throws rclcpp::exceptions::InvalidParameterTypeException if the type doesn't match
|
||||
*/
|
||||
template<ParameterType ParamT>
|
||||
decltype(auto)
|
||||
get_value() const
|
||||
@@ -117,50 +124,89 @@ public:
|
||||
decltype(auto)
|
||||
get_value() const;
|
||||
|
||||
/// Get value of parameter as boolean.
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
bool
|
||||
as_bool() const;
|
||||
|
||||
/// Get value of parameter as integer.
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
int64_t
|
||||
as_int() const;
|
||||
|
||||
/// Get value of parameter as double.
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
double
|
||||
as_double() const;
|
||||
|
||||
/// Get value of parameter as string.
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
const std::string &
|
||||
as_string() const;
|
||||
|
||||
/// Get value of parameter as byte array (vector<uint8_t>).
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
const std::vector<uint8_t> &
|
||||
as_byte_array() const;
|
||||
|
||||
/// Get value of parameter as bool array (vector<bool>).
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
const std::vector<bool> &
|
||||
as_bool_array() const;
|
||||
|
||||
/// Get value of parameter as integer array (vector<int64_t>).
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
const std::vector<int64_t> &
|
||||
as_integer_array() const;
|
||||
|
||||
/// Get value of parameter as double array (vector<double>).
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
const std::vector<double> &
|
||||
as_double_array() const;
|
||||
|
||||
/// Get value of parameter as string array (vector<std::string>).
|
||||
/**
|
||||
* \throws rclcpp::ParameterTypeException if the type doesn't match
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
const std::vector<std::string> &
|
||||
as_string_array() const;
|
||||
|
||||
/// Convert a parameter message in a Parameter class object.
|
||||
RCLCPP_PUBLIC
|
||||
static Parameter
|
||||
from_parameter_msg(const rcl_interfaces::msg::Parameter & parameter);
|
||||
|
||||
/// Convert the class in a parameter message.
|
||||
RCLCPP_PUBLIC
|
||||
rcl_interfaces::msg::Parameter
|
||||
to_parameter_msg() const;
|
||||
|
||||
/// Get value of parameter as a string.
|
||||
RCLCPP_PUBLIC
|
||||
std::string
|
||||
value_to_string() const;
|
||||
|
||||
@@ -59,6 +59,17 @@ public:
|
||||
|
||||
RCLCPP_SMART_PTR_DEFINITIONS(Publisher<MessageT, AllocatorT>)
|
||||
|
||||
/// Default constructor.
|
||||
/**
|
||||
* The constructor for a Publisher is almost never called directly.
|
||||
* Instead, subscriptions should be instantiated through the function
|
||||
* rclcpp::create_publisher().
|
||||
*
|
||||
* \param[in] node_base NodeBaseInterface pointer that is used in part of the setup.
|
||||
* \param[in] topic Name of the topic to publish to.
|
||||
* \param[in] qos QoS profile for Subcription.
|
||||
* \param[in] options options for the subscription.
|
||||
*/
|
||||
Publisher(
|
||||
rclcpp::node_interfaces::NodeBaseInterface * node_base,
|
||||
const std::string & topic,
|
||||
|
||||
@@ -161,6 +161,18 @@ bool operator==(const QoS & left, const QoS & right);
|
||||
RCLCPP_PUBLIC
|
||||
bool operator!=(const QoS & left, const QoS & right);
|
||||
|
||||
/**
|
||||
* Sensor Data QoS class
|
||||
* - History: Keep last,
|
||||
* - Depth: 5,
|
||||
* - Reliability: Best effort,
|
||||
* - Durability: Volatile,
|
||||
* - Deadline: Default,
|
||||
* - Lifespan: Default,
|
||||
* - Liveliness: System default,
|
||||
* - Liveliness lease duration: default,
|
||||
* - avoid ros namespace conventions: false
|
||||
*/
|
||||
class RCLCPP_PUBLIC SensorDataQoS : public QoS
|
||||
{
|
||||
public:
|
||||
@@ -171,6 +183,18 @@ public:
|
||||
));
|
||||
};
|
||||
|
||||
/**
|
||||
* Parameters QoS class
|
||||
* - History: Keep last,
|
||||
* - Depth: 1000,
|
||||
* - Reliability: Reliable,
|
||||
* - Durability: Volatile,
|
||||
* - Deadline: Default,
|
||||
* - Lifespan: Default,
|
||||
* - Liveliness: System default,
|
||||
* - Liveliness lease duration: default,
|
||||
* - Avoid ros namespace conventions: false
|
||||
*/
|
||||
class RCLCPP_PUBLIC ParametersQoS : public QoS
|
||||
{
|
||||
public:
|
||||
@@ -181,6 +205,18 @@ public:
|
||||
));
|
||||
};
|
||||
|
||||
/**
|
||||
* Services QoS class
|
||||
* - History: Keep last,
|
||||
* - Depth: 10,
|
||||
* - Reliability: Reliable,
|
||||
* - Durability: Volatile,
|
||||
* - Deadline: Default,
|
||||
* - Lifespan: Default,
|
||||
* - Liveliness: System default,
|
||||
* - Liveliness lease duration: default,
|
||||
* - Avoid ros namespace conventions: false
|
||||
*/
|
||||
class RCLCPP_PUBLIC ServicesQoS : public QoS
|
||||
{
|
||||
public:
|
||||
@@ -191,6 +227,18 @@ public:
|
||||
));
|
||||
};
|
||||
|
||||
/**
|
||||
* Parameter events QoS class
|
||||
* - History: Keep last,
|
||||
* - Depth: 1000,
|
||||
* - Reliability: Reliable,
|
||||
* - Durability: Volatile,
|
||||
* - Deadline: Default,
|
||||
* - Lifespan: Default,
|
||||
* - Liveliness: System default,
|
||||
* - Liveliness lease duration: default,
|
||||
* - Avoid ros namespace conventions: false
|
||||
*/
|
||||
class RCLCPP_PUBLIC ParameterEventsQoS : public QoS
|
||||
{
|
||||
public:
|
||||
@@ -201,6 +249,18 @@ public:
|
||||
));
|
||||
};
|
||||
|
||||
/**
|
||||
* System defaults QoS class
|
||||
* - History: System default,
|
||||
* - Depth: System default,
|
||||
* - Reliability: System default,
|
||||
* - Durability: System default,
|
||||
* - Deadline: Default,
|
||||
* - Lifespan: Default,
|
||||
* - Liveliness: System default,
|
||||
* - Liveliness lease duration: System default,
|
||||
* - Avoid ros namespace conventions: false
|
||||
*/
|
||||
class RCLCPP_PUBLIC SystemDefaultsQoS : public QoS
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
* - rclcpp/context.hpp
|
||||
* - rclcpp/contexts/default_context.hpp
|
||||
* - Various utilities:
|
||||
* - rclcpp/duration.hpp
|
||||
* - rclcpp/function_traits.hpp
|
||||
* - rclcpp/macros.hpp
|
||||
* - rclcpp/scope_exit.hpp
|
||||
|
||||
@@ -50,14 +50,26 @@ public:
|
||||
RCLCPP_PUBLIC
|
||||
virtual ~ServiceBase();
|
||||
|
||||
/// Return the name of the service.
|
||||
/** \return The name of the service. */
|
||||
RCLCPP_PUBLIC
|
||||
const char *
|
||||
get_service_name();
|
||||
|
||||
/// Return the rcl_service_t service handle in a std::shared_ptr.
|
||||
/**
|
||||
* This handle remains valid after the Service is destroyed.
|
||||
* The actual rcl service is not finalized until it is out of scope everywhere.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
std::shared_ptr<rcl_service_t>
|
||||
get_service_handle();
|
||||
|
||||
/// Return the rcl_service_t service handle in a std::shared_ptr.
|
||||
/**
|
||||
* This handle remains valid after the Service is destroyed.
|
||||
* The actual rcl service is not finalized until it is out of scope everywhere.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
std::shared_ptr<const rcl_service_t>
|
||||
get_service_handle() const;
|
||||
|
||||
@@ -90,9 +90,14 @@ public:
|
||||
* \param[in] node_base NodeBaseInterface pointer that is used in part of the setup.
|
||||
* \param[in] type_support_handle rosidl type support struct, for the Message type of the topic.
|
||||
* \param[in] topic_name Name of the topic to subscribe to.
|
||||
* \param[in] qos QoS profile for Subcription.
|
||||
* \param[in] callback User defined callback to call when a message is received.
|
||||
* \param[in] options options for the subscription.
|
||||
* \param[in] message_memory_strategy The memory strategy to be used for managing message memory.
|
||||
* \param[in] subscription_topic_statistics pointer to a topic statistics subcription.
|
||||
* \throws std::invalid_argument if the QoS is uncompatible with intra-process (if one
|
||||
* of the following conditions are true: qos_profile.history == RMW_QOS_POLICY_HISTORY_KEEP_ALL,
|
||||
* qos_profile.depth == 0 or qos_profile.durability != RMW_QOS_POLICY_DURABILITY_VOLATILE).
|
||||
*/
|
||||
Subscription(
|
||||
rclcpp::node_interfaces::NodeBaseInterface * node_base,
|
||||
|
||||
@@ -89,6 +89,10 @@ struct SubscriptionOptionsWithAllocator : public SubscriptionOptionsBase
|
||||
{}
|
||||
|
||||
/// Convert this class, with a rclcpp::QoS, into an rcl_subscription_options_t.
|
||||
/**
|
||||
* \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
|
||||
|
||||
@@ -31,26 +31,54 @@ class Clock;
|
||||
class Time
|
||||
{
|
||||
public:
|
||||
/// Time constructor
|
||||
/**
|
||||
* Initializes the time values for seconds and nanoseconds individually.
|
||||
* Large values for nanoseconds are wrapped automatically with the remainder added to seconds.
|
||||
* Both inputs must be integers.
|
||||
*
|
||||
* \param seconds part of the time in seconds since time epoch
|
||||
* \param nanoseconds part of the time in nanoseconds since time epoch
|
||||
* \param clock_type clock type
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
Time(int32_t seconds, uint32_t nanoseconds, rcl_clock_type_t clock_type = RCL_SYSTEM_TIME);
|
||||
|
||||
/// Time constructor
|
||||
/**
|
||||
* \param nanoseconds since time epoch
|
||||
* \param clock_type clock type
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
explicit Time(int64_t nanoseconds = 0, rcl_clock_type_t clock = RCL_SYSTEM_TIME);
|
||||
|
||||
/// Copy constructor
|
||||
RCLCPP_PUBLIC
|
||||
Time(const Time & rhs);
|
||||
|
||||
/// Time constructor
|
||||
/**
|
||||
* \param time_msg builtin_interfaces time message to copy
|
||||
* \param clock_type clock type
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
Time(
|
||||
const builtin_interfaces::msg::Time & time_msg,
|
||||
rcl_clock_type_t ros_time = RCL_ROS_TIME);
|
||||
|
||||
/// Time constructor
|
||||
/**
|
||||
* \param time_point rcl_time_point_t structure to copy
|
||||
* \param clock_type clock type
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
explicit Time(const rcl_time_point_t & time_point);
|
||||
|
||||
/// Time destructor
|
||||
RCLCPP_PUBLIC
|
||||
virtual ~Time();
|
||||
|
||||
/// Return a builtin_interfaces::msg::Time object based
|
||||
RCLCPP_PUBLIC
|
||||
operator builtin_interfaces::msg::Time() const;
|
||||
|
||||
@@ -106,21 +134,37 @@ public:
|
||||
Time &
|
||||
operator-=(const rclcpp::Duration & rhs);
|
||||
|
||||
/// Get the nanoseconds since epoch
|
||||
/**
|
||||
* \return the nanoseconds since epoch as a rcl_time_point_value_t structure.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
rcl_time_point_value_t
|
||||
nanoseconds() const;
|
||||
|
||||
/// Get the maximum representable value.
|
||||
/**
|
||||
* \return the maximum representable value
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
static Time
|
||||
max();
|
||||
|
||||
/// \return the seconds since epoch as a floating point number.
|
||||
/// \warning Depending on sizeof(double) there could be significant precision loss.
|
||||
/// When an exact time is required use nanoseconds() instead.
|
||||
/// Get the seconds since epoch
|
||||
/**
|
||||
* \warning Depending on sizeof(double) there could be significant precision loss.
|
||||
* When an exact time is required use nanoseconds() instead.
|
||||
*
|
||||
* \return the seconds since epoch as a floating point number.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
double
|
||||
seconds() const;
|
||||
|
||||
/// Get the clock type
|
||||
/**
|
||||
* \return the clock type
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
rcl_clock_type_t
|
||||
get_clock_type() const;
|
||||
|
||||
@@ -35,15 +35,42 @@ class Clock;
|
||||
class TimeSource
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
/**
|
||||
* The node will be attached to the time source.
|
||||
*
|
||||
* \param node std::shared pointer to a initialized node
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
explicit TimeSource(rclcpp::Node::SharedPtr node);
|
||||
|
||||
/// Empty constructor
|
||||
/**
|
||||
* An Empty TimeSource class
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
TimeSource();
|
||||
|
||||
/// Attack node to the time source.
|
||||
/**
|
||||
* \param node std::shared pointer to a initialized node
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
void attachNode(rclcpp::Node::SharedPtr node);
|
||||
|
||||
/// Attack node to the time source.
|
||||
/**
|
||||
* If the parameter `use_sim_time` is `true` then the source time is the simulation time,
|
||||
* otherwise the source time is defined by the system.
|
||||
*
|
||||
* \param node_base_interface Node base interface.
|
||||
* \param node_topics_interface Node topic base interface.
|
||||
* \param node_graph_interface Node graph interface.
|
||||
* \param node_services_interface Node service interface.
|
||||
* \param node_logging_interface Node logging interface.
|
||||
* \param node_clock_interface Node clock interface.
|
||||
* \param node_parameters_interface Node parameters interface.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
void attachNode(
|
||||
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_interface,
|
||||
@@ -54,19 +81,22 @@ public:
|
||||
rclcpp::node_interfaces::NodeClockInterface::SharedPtr node_clock_interface,
|
||||
rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters_interface);
|
||||
|
||||
/// Detach the node from the time source
|
||||
RCLCPP_PUBLIC
|
||||
void detachNode();
|
||||
|
||||
/// Attach a clock to the time source to be updated
|
||||
/**
|
||||
* \throws std::invalid_argument if node is nullptr
|
||||
* \throws std::invalid_argument the time source must be a RCL_ROS_TIME otherwise throws an exception
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
void attachClock(rclcpp::Clock::SharedPtr clock);
|
||||
|
||||
/// Detach a clock to the time source
|
||||
RCLCPP_PUBLIC
|
||||
void detachClock(rclcpp::Clock::SharedPtr clock);
|
||||
|
||||
/// TimeSource Destructor
|
||||
RCLCPP_PUBLIC
|
||||
~TimeSource();
|
||||
|
||||
|
||||
@@ -48,15 +48,26 @@ class TimerBase
|
||||
public:
|
||||
RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(TimerBase)
|
||||
|
||||
/// TimerBase constructor
|
||||
/**
|
||||
* \param clock A clock to use for time and sleeping
|
||||
* \param period The interval at which the timer fires
|
||||
* \param context node context
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
explicit TimerBase(
|
||||
Clock::SharedPtr clock,
|
||||
std::chrono::nanoseconds period,
|
||||
rclcpp::Context::SharedPtr context);
|
||||
|
||||
/// TimerBase destructor
|
||||
RCLCPP_PUBLIC
|
||||
~TimerBase();
|
||||
|
||||
/// Cancel the timer.
|
||||
/**
|
||||
* \throws std::runtime_error if the rcl_timer_cancel returns a failure
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
void
|
||||
cancel();
|
||||
@@ -71,10 +82,15 @@ public:
|
||||
bool
|
||||
is_canceled();
|
||||
|
||||
/// Reset the timer.
|
||||
/**
|
||||
* \throws std::runtime_error if the rcl_timer_reset returns a failure
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
void
|
||||
reset();
|
||||
|
||||
/// Call the callback function when the timer signal is emitted.
|
||||
RCLCPP_PUBLIC
|
||||
virtual void
|
||||
execute_callback() = 0;
|
||||
@@ -209,6 +225,8 @@ public:
|
||||
callback_(*this);
|
||||
}
|
||||
|
||||
/// Is the clock steady (i.e. is the time between ticks constant?)
|
||||
/** \return True if the clock used by this timer is steady. */
|
||||
bool
|
||||
is_steady() override
|
||||
{
|
||||
@@ -233,6 +251,12 @@ class WallTimer : public GenericTimer<FunctorT>
|
||||
public:
|
||||
RCLCPP_SMART_PTR_DEFINITIONS(WallTimer)
|
||||
|
||||
/// Wall timer constructor
|
||||
/**
|
||||
* \param period The interval at which the timer fires
|
||||
* \param callback The callback function to execute every interval
|
||||
* \param context node context
|
||||
*/
|
||||
WallTimer(
|
||||
std::chrono::nanoseconds period,
|
||||
FunctorT && callback,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp</name>
|
||||
<version>0.8.3</version>
|
||||
<version>1.0.0</version>
|
||||
<description>The ROS client library in C++.</description>
|
||||
<maintainer email="dthomas@osrfoundation.org">Dirk Thomas</maintainer>
|
||||
<license>Apache License 2.0</license>
|
||||
|
||||
@@ -602,7 +602,7 @@ Executor::get_next_ready_executable(AnyExecutable & any_executable)
|
||||
any_executable.callback_group->can_be_taken_from().store(false);
|
||||
}
|
||||
}
|
||||
// If there is no ready executable, return a null ptr
|
||||
// If there is no ready executable, return false
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -499,9 +499,3 @@ Node::get_node_options() const
|
||||
{
|
||||
return this->node_options_;
|
||||
}
|
||||
|
||||
bool
|
||||
Node::assert_liveliness() const
|
||||
{
|
||||
return node_base_->assert_liveliness();
|
||||
}
|
||||
|
||||
@@ -202,12 +202,6 @@ NodeBase::get_shared_rcl_node_handle() const
|
||||
return node_handle_;
|
||||
}
|
||||
|
||||
bool
|
||||
NodeBase::assert_liveliness() const
|
||||
{
|
||||
return RCL_RET_OK == rcl_node_assert_liveliness(get_rcl_node_handle());
|
||||
}
|
||||
|
||||
rclcpp::CallbackGroup::SharedPtr
|
||||
NodeBase::create_callback_group(rclcpp::CallbackGroupType group_type)
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "rclcpp/logging.hpp"
|
||||
#include "rclcpp/macros.hpp"
|
||||
#include "rclcpp/node.hpp"
|
||||
#include "rclcpp/qos_event.hpp"
|
||||
|
||||
using rclcpp::PublisherBase;
|
||||
|
||||
@@ -246,7 +247,8 @@ PublisherBase::setup_intra_process(
|
||||
}
|
||||
|
||||
void
|
||||
PublisherBase::default_incompatible_qos_callback(QOSOfferedIncompatibleQoSInfo & event) const
|
||||
PublisherBase::default_incompatible_qos_callback(
|
||||
rclcpp::QOSOfferedIncompatibleQoSInfo & event) const
|
||||
{
|
||||
std::string policy_name = qos_policy_name_from_kind(event.last_policy_kind);
|
||||
RCLCPP_WARN(
|
||||
|
||||
@@ -41,7 +41,7 @@ ServiceBase::take_type_erased_request(void * request_out, rmw_request_id_t & req
|
||||
this->get_service_handle().get(),
|
||||
&request_id_out,
|
||||
request_out);
|
||||
if (RCL_RET_CLIENT_TAKE_FAILED == ret) {
|
||||
if (RCL_RET_SERVICE_TAKE_FAILED == ret) {
|
||||
return false;
|
||||
} else if (RCL_RET_OK != ret) {
|
||||
rclcpp::exceptions::throw_from_rcl_error(ret);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "rclcpp/experimental/intra_process_manager.hpp"
|
||||
#include "rclcpp/logging.hpp"
|
||||
#include "rclcpp/node_interfaces/node_base_interface.hpp"
|
||||
#include "rclcpp/qos_event.hpp"
|
||||
|
||||
#include "rmw/error_handling.h"
|
||||
#include "rmw/rmw.h"
|
||||
@@ -238,7 +239,8 @@ SubscriptionBase::get_intra_process_waitable() const
|
||||
}
|
||||
|
||||
void
|
||||
SubscriptionBase::default_incompatible_qos_callback(QOSRequestedIncompatibleQoSInfo & event) const
|
||||
SubscriptionBase::default_incompatible_qos_callback(
|
||||
rclcpp::QOSRequestedIncompatibleQoSInfo & event) const
|
||||
{
|
||||
std::string policy_name = qos_policy_name_from_kind(event.last_policy_kind);
|
||||
RCLCPP_WARN(
|
||||
|
||||
@@ -2591,7 +2591,7 @@ TEST_F(TestNode, get_publishers_subscriptions_info_by_topic) {
|
||||
RMW_QOS_POLICY_DURABILITY_VOLATILE,
|
||||
{15, 1678},
|
||||
{29, 2345},
|
||||
RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE,
|
||||
RMW_QOS_POLICY_LIVELINESS_AUTOMATIC,
|
||||
{5, 23456},
|
||||
false
|
||||
};
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "rclcpp/exceptions.hpp"
|
||||
#include "rclcpp/publisher.hpp"
|
||||
@@ -51,6 +51,10 @@ public:
|
||||
{
|
||||
rclcpp::init(0, nullptr);
|
||||
}
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
rclcpp::shutdown();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() {}
|
||||
|
||||
@@ -65,7 +65,7 @@ TEST(TestQoS, equality_liveliness) {
|
||||
EXPECT_NE(a, b);
|
||||
b.liveliness_lease_duration(duration);
|
||||
EXPECT_EQ(a, b);
|
||||
a.liveliness(RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_NODE);
|
||||
a.liveliness(RMW_QOS_POLICY_LIVELINESS_MANUAL_BY_TOPIC);
|
||||
EXPECT_NE(a, b);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ public:
|
||||
{
|
||||
rclcpp::init(0, nullptr);
|
||||
}
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
rclcpp::shutdown();
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetUp() {}
|
||||
|
||||
@@ -3,6 +3,26 @@ Changelog for package rclcpp_action
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
1.0.0 (2020-05-12)
|
||||
------------------
|
||||
|
||||
0.9.1 (2020-05-08)
|
||||
------------------
|
||||
* Added Quality declaration: rclcpp, rclpp_action, rclcpp_components andrclcpp_lifecycle (`#1100 <https://github.com/ros2/rclcpp/issues/1100>`_)
|
||||
* Contributors: Alejandro Hernández Cordero
|
||||
|
||||
0.9.0 (2020-04-29)
|
||||
------------------
|
||||
* Increasing test coverage of rclcpp_action (`#1043 <https://github.com/ros2/rclcpp/issues/1043>`_)
|
||||
* Export targets in addition to include directories / libraries (`#1096 <https://github.com/ros2/rclcpp/issues/1096>`_)
|
||||
* Deprecate redundant namespaces (`#1083 <https://github.com/ros2/rclcpp/issues/1083>`_)
|
||||
* Rename rosidl_generator_c namespace to rosidl_runtime_c (`#1062 <https://github.com/ros2/rclcpp/issues/1062>`_)
|
||||
* Changed rosidl_generator_c/cpp to rosidl_runtime_c/cpp (`#1014 <https://github.com/ros2/rclcpp/issues/1014>`_)
|
||||
* Fix unknown macro errors reported by cppcheck 1.90 (`#1000 <https://github.com/ros2/rclcpp/issues/1000>`_)
|
||||
* Removed rosidl_generator_c dependency (`#992 <https://github.com/ros2/rclcpp/issues/992>`_)
|
||||
* Fix typo in action client logger name (`#937 <https://github.com/ros2/rclcpp/issues/937>`_)
|
||||
* Contributors: Alejandro Hernández Cordero, Dirk Thomas, Jacob Perron, Stephen Brawner, William Woodall
|
||||
|
||||
0.8.3 (2019-11-19)
|
||||
------------------
|
||||
* issue-919 Fixed "memory leak" in action clients (`#920 <https://github.com/ros2/rclcpp/issues/920>`_)
|
||||
|
||||
@@ -103,6 +103,16 @@ if(BUILD_TESTING)
|
||||
${PROJECT_NAME}
|
||||
)
|
||||
endif()
|
||||
|
||||
ament_add_gtest(test_types test/test_types.cpp)
|
||||
if(TARGET test_types)
|
||||
ament_target_dependencies(test_types
|
||||
"test_msgs"
|
||||
)
|
||||
target_link_libraries(test_types
|
||||
${PROJECT_NAME}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
ament_package()
|
||||
|
||||
166
rclcpp_action/QUALITY_DECLARATION.md
Normal file
166
rclcpp_action/QUALITY_DECLARATION.md
Normal file
@@ -0,0 +1,166 @@
|
||||
This document is a declaration of software quality for the `rclcpp_action` package, based on the guidelines in [REP-2004](https://github.com/ros-infrastructure/rep/blob/rep-2004/rep-2004.rst).
|
||||
|
||||
# `rclcpp_action` Quality Declaration
|
||||
|
||||
The package `rclcpp_action` claims to be in the **Quality Level 4** category.
|
||||
|
||||
Below are the rationales, notes, and caveats for this claim, organized by each requirement listed in the [Package Quality Categories in REP-2004](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#package-quality-categories) of the ROS2 developer guide.
|
||||
|
||||
## Version Policy [1]
|
||||
|
||||
### Version Scheme [1.i]
|
||||
|
||||
`rclcpp_action` uses `semver` according to the recommendation for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#versioning)
|
||||
|
||||
### Version Stability [1.ii]
|
||||
|
||||
`rclcpp_action` is not yet at a stable version, i.e. `>= 1.0.0`.
|
||||
The current version can be found in its [package.xml](package.xml), and its change history can be found in its [CHANGELOG](CHANGELOG.rst).
|
||||
|
||||
### Public API Declaration [1.iii]
|
||||
|
||||
All symbols in the installed headers are considered part of the public API.
|
||||
|
||||
All installed headers are in the `include` directory of the package, headers in any other folders are not installed and considered private.
|
||||
|
||||
### API Stability Policy [1.iv]
|
||||
|
||||
`rclcpp_action` will not break public API within a released ROS distribution, i.e. no major releases once the ROS distribution is released.
|
||||
|
||||
### ABI Stability Policy [1.v]
|
||||
|
||||
`rclcpp_action` contains C++ code and therefore must be concerned with ABI stability, and will maintain ABI stability within a ROS distribution.
|
||||
|
||||
### ABI and ABI Stability Within a Released ROS Distribution [1.vi]
|
||||
|
||||
`rclcpp_action` will not break API nor ABI within a released ROS distribution, i.e. no major releases once the ROS distribution is released.
|
||||
|
||||
## Change Control Process [2]
|
||||
|
||||
`rclcpp_action` follows the recommended guidelines for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process).
|
||||
|
||||
### Change Requests [2.i]
|
||||
|
||||
All changes will occur through a pull request, check [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process) for additional information.
|
||||
|
||||
### Contributor Origin [2.ii]
|
||||
|
||||
This package uses DCO as its confirmation of contributor origin policy. More information can be found in [CONTRIBUTING](../CONTRIBUTING.md).
|
||||
|
||||
### Peer Review Policy [2.iii]
|
||||
|
||||
All pull requests will be peer-reviewed, check [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process) for additional information.
|
||||
|
||||
### 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)
|
||||
|
||||
Currently nightly results can be seen here:
|
||||
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_action/)
|
||||
|
||||
### Documentation Policy [2.v]
|
||||
|
||||
All pull requests must resolve related documentation changes before merging.
|
||||
|
||||
## Documentation [3]
|
||||
|
||||
### Feature Documentation [3.i]
|
||||
|
||||
`rclcpp_action` has a [feature list](http://docs.ros2.org/latest/api/rclcpp_action/) and each item in the list links to the corresponding feature documentation. There is documentation for all of the features, and new features require documentation before being added.
|
||||
|
||||
### Public API Documentation [3.ii]
|
||||
|
||||
The API is publicly available in the [ROS 2 API documentation](http://docs.ros2.org/latest/api/rclcpp_action/).
|
||||
|
||||
### License [3.iii]
|
||||
|
||||
The license for `rclcpp_action` is Apache 2.0, and a summary is in each source file, the type is declared in the [`package.xml`](./package.xml) manifest file, and a full copy of the license is in the [`LICENSE`](../LICENSE) file.
|
||||
|
||||
There is an automated test which runs a linter that ensures each file has a license statement. [Here](http://build.ros2.org/view/Epr/job/Epr__rclcpp_action__ubuntu_bionic_amd64/lastBuild/testReport/rclcpp_action/) can be found a list with the latest results of the various linters being run on the package.
|
||||
|
||||
### Copyright Statements [3.iv]
|
||||
|
||||
The copyright holders each provide a statement of copyright in each source code file in `rclcpp_action`.
|
||||
|
||||
There is an automated test which runs a linter that ensures each file has at least one copyright statement. Latest linter result report can be seen [here](http://build.ros2.org/view/Epr/job/Epr__rclcpp_action__ubuntu_bionic_amd64/lastBuild/testReport/rclcpp_action/copyright/).
|
||||
|
||||
## Testing [4]
|
||||
|
||||
### Feature Testing [4.i]
|
||||
|
||||
Each feature in `rclcpp_action` has corresponding tests which simulate typical usage, and they are located in the [`test`](https://github.com/ros2/rclcpp_action/tree/master/test) directory.
|
||||
New features are required to have tests before being added.
|
||||
|
||||
Currently nightly test results can be seen here:
|
||||
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_action/)
|
||||
|
||||
### Public API Testing [4.ii]
|
||||
|
||||
Each part of the public API has tests, and new additions or changes to the public API require tests before being added.
|
||||
The tests aim to cover both typical usage and corner cases, but are quantified by contributing to code coverage.
|
||||
|
||||
### Coverage [4.iii]
|
||||
|
||||
`rclcpp_action` follows the recommendations for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#code-coverage), and opts to use line coverage instead of branch coverage.
|
||||
|
||||
This includes:
|
||||
|
||||
- tracking and reporting line coverage statistics
|
||||
- achieving and maintaining a reasonable branch line coverage (90-100%)
|
||||
- no lines are manually skipped in coverage calculations
|
||||
|
||||
Changes are required to make a best effort to keep or increase coverage before being accepted, but decreases are allowed if properly justified and accepted by reviewers.
|
||||
|
||||
### Performance [4.iv]
|
||||
|
||||
It is not yet defined if this package requires performance testing and how addresses this topic.
|
||||
|
||||
### Linters and Static Analysis [4.v]
|
||||
|
||||
`rclcpp_action` uses and passes all the ROS2 standard linters and static analysis tools for a C++ package as described in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#linters-and-static-analysis). Passing implies there are no linter/static errors when testing against CI of supported platforms.
|
||||
|
||||
Currently nightly test results can be seen here:
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_action/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_action/)
|
||||
|
||||
## Dependencies [5]
|
||||
|
||||
### Direct and Optional Runtime ROS Dependencies [5.i]/[5.ii]
|
||||
|
||||
`rclcpp_action` has the following runtime ROS dependencies:
|
||||
- action_msgs
|
||||
- rclcpp
|
||||
- rcl_action
|
||||
|
||||
It has several "buildtool" dependencies, which do not affect the resulting quality of the package, because they do not contribute to the public library API.
|
||||
It also has several test dependencies, which do not affect the resulting quality of the package, because they are only used to build and run the test code.
|
||||
|
||||
### Direct Runtime non-ROS Dependency [5.iii]
|
||||
|
||||
`rclcpp_action` has no run-time or build-time dependencies that need to be considered for this declaration.
|
||||
|
||||
## Platform Support [6]
|
||||
|
||||
`rclcpp_action` 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.
|
||||
|
||||
Currently nightly build status can be seen here:
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/rclcpp_action/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/rclcpp_action/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/rclcpp_action/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/rclcpp_action/)
|
||||
|
||||
## Security
|
||||
|
||||
### Vulnerability Disclosure Policy [7.i]
|
||||
|
||||
This package does not yet have a Vulnerability Disclosure Policy
|
||||
7
rclcpp_action/README.md
Normal file
7
rclcpp_action/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# `rclcpp_action`
|
||||
|
||||
Adds action APIs for C++. Visit the [rclcpp API documentation](http://docs.ros2.org/latest/api/rclcpp_action/) for a complete list of its main components or the [design document](http://design.ros2.org/articles/actions.html).
|
||||
|
||||
## Quality Declaration
|
||||
|
||||
This package claims to be in the **Quality Level 4** category, see the [Quality Declaration](QUALITY_DECLARATION.md) for more details.
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_action</name>
|
||||
<version>0.8.3</version>
|
||||
<version>1.0.0</version>
|
||||
<description>Adds action APIs for C++.</description>
|
||||
<maintainer email="dthomas@osrfoundation.org">Dirk Thomas</maintainer>
|
||||
<license>Apache License 2.0</license>
|
||||
|
||||
@@ -270,6 +270,21 @@ TEST_F(TestClient, construction_and_destruction)
|
||||
ASSERT_NO_THROW(rclcpp_action::create_client<ActionType>(client_node, action_name).reset());
|
||||
}
|
||||
|
||||
TEST_F(TestClient, construction_and_destruction_callback_group)
|
||||
{
|
||||
auto group = client_node->create_callback_group(
|
||||
rclcpp::CallbackGroupType::MutuallyExclusive);
|
||||
ASSERT_NO_THROW(
|
||||
rclcpp_action::create_client<ActionType>(
|
||||
client_node->get_node_base_interface(),
|
||||
client_node->get_node_graph_interface(),
|
||||
client_node->get_node_logging_interface(),
|
||||
client_node->get_node_waitables_interface(),
|
||||
action_name,
|
||||
group
|
||||
).reset());
|
||||
}
|
||||
|
||||
TEST_F(TestClient, async_send_goal_no_callbacks)
|
||||
{
|
||||
auto action_client = rclcpp_action::create_client<ActionType>(client_node, action_name);
|
||||
|
||||
@@ -95,6 +95,32 @@ TEST_F(TestServer, construction_and_destruction)
|
||||
(void)as;
|
||||
}
|
||||
|
||||
TEST_F(TestServer, construction_and_destruction_callback_group)
|
||||
{
|
||||
auto node = std::make_shared<rclcpp::Node>("construct_node", "/rclcpp_action/construct");
|
||||
auto group = node->create_callback_group(
|
||||
rclcpp::CallbackGroupType::MutuallyExclusive);
|
||||
const rcl_action_server_options_t & options = rcl_action_server_get_default_options();
|
||||
|
||||
using GoalHandle = rclcpp_action::ServerGoalHandle<Fibonacci>;
|
||||
ASSERT_NO_THROW(
|
||||
rclcpp_action::create_server<Fibonacci>(
|
||||
node->get_node_base_interface(),
|
||||
node->get_node_clock_interface(),
|
||||
node->get_node_logging_interface(),
|
||||
node->get_node_waitables_interface(),
|
||||
"fibonacci",
|
||||
[](const GoalUUID &, std::shared_ptr<const Fibonacci::Goal>) {
|
||||
return rclcpp_action::GoalResponse::REJECT;
|
||||
},
|
||||
[](std::shared_ptr<GoalHandle>) {
|
||||
return rclcpp_action::CancelResponse::REJECT;
|
||||
},
|
||||
[](std::shared_ptr<GoalHandle>) {},
|
||||
options,
|
||||
group));
|
||||
}
|
||||
|
||||
TEST_F(TestServer, handle_goal_called)
|
||||
{
|
||||
auto node = std::make_shared<rclcpp::Node>("handle_goal_node", "/rclcpp_action/handle_goal");
|
||||
|
||||
61
rclcpp_action/test/test_types.cpp
Normal file
61
rclcpp_action/test/test_types.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2020 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <limits>
|
||||
#include "rclcpp_action/types.hpp"
|
||||
|
||||
TEST(TestActionTypes, goal_uuid_to_string) {
|
||||
rclcpp_action::GoalUUID goal_id;
|
||||
for (uint8_t i = 0; i < UUID_SIZE; ++i) {
|
||||
goal_id[i] = i;
|
||||
}
|
||||
EXPECT_STREQ("0123456789abcdef", rclcpp_action::to_string(goal_id).c_str());
|
||||
|
||||
for (uint8_t i = 0; i < UUID_SIZE; ++i) {
|
||||
goal_id[i] = 16u + i;
|
||||
}
|
||||
EXPECT_STREQ("101112131415161718191a1b1c1d1e1f", rclcpp_action::to_string(goal_id).c_str());
|
||||
|
||||
for (uint8_t i = 0; i < UUID_SIZE; ++i) {
|
||||
goal_id[i] = std::numeric_limits<uint8_t>::max() - i;
|
||||
}
|
||||
EXPECT_STREQ("fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0", rclcpp_action::to_string(goal_id).c_str());
|
||||
}
|
||||
|
||||
TEST(TestActionTypes, goal_uuid_to_rcl_action_goal_info) {
|
||||
rclcpp_action::GoalUUID goal_id;
|
||||
for (uint8_t i = 0; i < UUID_SIZE; ++i) {
|
||||
goal_id[i] = i;
|
||||
}
|
||||
rcl_action_goal_info_t goal_info = rcl_action_get_zero_initialized_goal_info();
|
||||
rclcpp_action::convert(goal_id, &goal_info);
|
||||
for (uint8_t i = 0; i < UUID_SIZE; ++i) {
|
||||
EXPECT_EQ(goal_info.goal_id.uuid[i], goal_id[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TestActionTypes, rcl_action_goal_info_to_goal_uuid) {
|
||||
rcl_action_goal_info_t goal_info = rcl_action_get_zero_initialized_goal_info();
|
||||
for (uint8_t i = 0; i < UUID_SIZE; ++i) {
|
||||
goal_info.goal_id.uuid[i] = i;
|
||||
}
|
||||
|
||||
rclcpp_action::GoalUUID goal_id;
|
||||
rclcpp_action::convert(goal_id, &goal_info);
|
||||
for (uint8_t i = 0; i < UUID_SIZE; ++i) {
|
||||
EXPECT_EQ(goal_info.goal_id.uuid[i], goal_id[i]);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,36 @@
|
||||
Changelog for package rclcpp_components
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
1.0.0 (2020-05-12)
|
||||
------------------
|
||||
* Increasing test coverage of rclcpp_components (`#1044 <https://github.com/ros2/rclcpp/issues/1044>`_)
|
||||
* Increasing test coverage of rclcpp_components
|
||||
Signed-off-by: Stephen Brawner <brawner@gmail.com>
|
||||
* PR fixup
|
||||
Signed-off-by: Stephen Brawner <brawner@gmail.com>
|
||||
* Fixup
|
||||
Signed-off-by: Stephen Brawner <brawner@gmail.com>
|
||||
* Removing throws test for now
|
||||
Signed-off-by: Stephen Brawner <brawner@gmail.com>
|
||||
* Contributors: brawner
|
||||
|
||||
0.9.1 (2020-05-08)
|
||||
------------------
|
||||
* Added Quality declaration: rclcpp, rclpp_action, rclcpp_components andrclcpp_lifecycle (`#1100 <https://github.com/ros2/rclcpp/issues/1100>`_)
|
||||
* Contributors: Alejandro Hernández Cordero
|
||||
|
||||
0.9.0 (2020-04-29)
|
||||
------------------
|
||||
* Added rclcpp_components Doxyfile (`#1091 <https://github.com/ros2/rclcpp/issues/1091>`_)
|
||||
* Deprecate redundant namespaces (`#1083 <https://github.com/ros2/rclcpp/issues/1083>`_)
|
||||
* Export targets in addition to include directories / libraries (`#1088 <https://github.com/ros2/rclcpp/issues/1088>`_)
|
||||
* Export component manager (`#1070 <https://github.com/ros2/rclcpp/issues/1070>`_)
|
||||
* Install the component_manager library (`#1068 <https://github.com/ros2/rclcpp/issues/1068>`_)
|
||||
* Make Component Manager public (`#1065 <https://github.com/ros2/rclcpp/issues/1065>`_)
|
||||
* Remove absolute path from installed CMake code (`#948 <https://github.com/ros2/rclcpp/issues/948>`_)
|
||||
* Fix function docblock, check for unparsed arguments (`#945 <https://github.com/ros2/rclcpp/issues/945>`_)
|
||||
* Contributors: Alejandro Hernández Cordero, DensoADAS, Dirk Thomas, Jacob Perron, Karsten Knese, Michael Carroll, William Woodall
|
||||
|
||||
0.8.3 (2019-11-19)
|
||||
------------------
|
||||
|
||||
|
||||
@@ -78,11 +78,19 @@ if(BUILD_TESTING)
|
||||
set(components "${components}test_rclcpp_components::TestComponentBar;$<TARGET_FILE:test_component>\n")
|
||||
set(components "${components}test_rclcpp_components::TestComponentNoNode;$<TARGET_FILE:test_component>\n")
|
||||
|
||||
# A properly formed resource only has one ';', this is used to catch an invalid resource entry
|
||||
set(invalid_components "test_rclcpp_components::TestComponentFoo;;$<TARGET_FILE:test_component>\n")
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/test_ament_index/$<CONFIG>/share/ament_index/resource_index/rclcpp_components/${PROJECT_NAME}"
|
||||
CONTENT "${components}")
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/test_ament_index/$<CONFIG>/share/ament_index/resource_index/rclcpp_components/invalid_${PROJECT_NAME}"
|
||||
CONTENT "${invalid_components}")
|
||||
|
||||
set(append_library_dirs "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
if(WIN32)
|
||||
set(append_library_dirs "${append_library_dirs}/$<CONFIG>")
|
||||
|
||||
33
rclcpp_components/Doxyfile
Normal file
33
rclcpp_components/Doxyfile
Normal file
@@ -0,0 +1,33 @@
|
||||
# All settings not listed here will use the Doxygen default values.
|
||||
|
||||
PROJECT_NAME = "rclcpp_components"
|
||||
PROJECT_NUMBER = master
|
||||
PROJECT_BRIEF = "Package containing tools for dynamically loadable components"
|
||||
|
||||
# Use these lines to include the generated logging.hpp (update install path if needed)
|
||||
# Otherwise just generate for the local (non-generated header files)
|
||||
INPUT = ./include
|
||||
|
||||
RECURSIVE = YES
|
||||
OUTPUT_DIRECTORY = doc_output
|
||||
|
||||
EXTRACT_ALL = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
|
||||
GENERATE_LATEX = NO
|
||||
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = RCLCPP_COMPONENTS_PUBLIC=
|
||||
|
||||
# Tag files that do not exist will produce a warning and cross-project linking will not work.
|
||||
TAGFILES += "../../../../doxygen_tag_files/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/"
|
||||
# Consider changing "latest" to the version you want to reference (e.g. beta1 or 1.0.0)
|
||||
TAGFILES += "../../../../doxygen_tag_files/class_loader.tag=http://docs.ros2.org/latest/api/class_loader/"
|
||||
TAGFILES += "../../../../doxygen_tag_files/rclcpp.tag=http://docs.ros2.org/latest/api/rclcpp/"
|
||||
TAGFILES += "../../../../doxygen_tag_files/rcl.tag=http://docs.ros2.org/latest/api/rcl/"
|
||||
TAGFILES += "../../../../doxygen_tag_files/rcutils.tag=http://docs.ros2.org/latest/api/rcutils/"
|
||||
TAGFILES += "../../../../doxygen_tag_files/rmw.tag=http://docs.ros2.org/latest/api/rmw/"
|
||||
# Uncomment to generate tag files for cross-project linking.
|
||||
GENERATE_TAGFILE = "../../../../doxygen_tag_files/rclcpp_components.tag"
|
||||
169
rclcpp_components/QUALITY_DECLARATION.md
Normal file
169
rclcpp_components/QUALITY_DECLARATION.md
Normal file
@@ -0,0 +1,169 @@
|
||||
This document is a declaration of software quality for the `rclcpp_components` package, based on the guidelines in [REP-2004](https://github.com/ros-infrastructure/rep/blob/rep-2004/rep-2004.rst).
|
||||
|
||||
# `rclcpp_components` Quality Declaration
|
||||
|
||||
The package `rclcpp_components` claims to be in the **Quality Level 4** category.
|
||||
|
||||
Below are the rationales, notes, and caveats for this claim, organized by each requirement listed in the [Package Quality Categories in REP-2004](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#package-quality-categories) of the ROS2 developer guide.
|
||||
|
||||
## Version Policy [1]
|
||||
|
||||
### Version Scheme [1.i]
|
||||
|
||||
`rclcpp_components` uses `semver` according to the recommendation for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#versioning)
|
||||
|
||||
### Version Stability [1.ii]
|
||||
|
||||
`rclcpp_components` is not yet at a stable version, i.e. `>= 1.0.0`.
|
||||
The current version can be found in its [package.xml](package.xml), and its change history can be found in its [CHANGELOG](CHANGELOG.rst).
|
||||
|
||||
### Public API Declaration [1.iii]
|
||||
|
||||
All symbols in the installed headers are considered part of the public API.
|
||||
|
||||
All installed headers are in the `include` directory of the package, headers in any other folders are not installed and considered private.
|
||||
|
||||
### API Stability Policy [1.iv]
|
||||
|
||||
`rclcpp_components` will not break public API within a released ROS distribution, i.e. no major releases once the ROS distribution is released.
|
||||
|
||||
### ABI Stability Policy [1.v]
|
||||
|
||||
`rclcpp_components` contains C++ code and therefore must be concerned with ABI stability, and will maintain ABI stability within a ROS distribution.
|
||||
|
||||
### ABI and ABI Stability Within a Released ROS Distribution [1.vi]
|
||||
|
||||
`rclcpp_components` will not break API nor ABI within a released ROS distribution, i.e. no major releases once the ROS distribution is released.
|
||||
|
||||
## Change Control Process [2]
|
||||
|
||||
`rclcpp_components` follows the recommended guidelines for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process).
|
||||
|
||||
### Change Requests [2.i]
|
||||
|
||||
All changes will occur through a pull request, check [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process) for additional information.
|
||||
|
||||
### Contributor Origin [2.ii]
|
||||
|
||||
This package uses DCO as its confirmation of contributor origin policy. More information can be found in [CONTRIBUTING](../CONTRIBUTING.md).
|
||||
|
||||
### Peer Review Policy [2.iii]
|
||||
|
||||
All pull requests will be peer-reviewed, check [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process) for additional information.
|
||||
|
||||
### 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)
|
||||
|
||||
Currently nightly results can be seen here:
|
||||
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_components/)
|
||||
|
||||
### Documentation Policy [2.v]
|
||||
|
||||
All pull requests must resolve related documentation changes before merging.
|
||||
|
||||
## Documentation [3]
|
||||
|
||||
### Feature Documentation [3.i]
|
||||
|
||||
`rclcpp_components` does not have a documented feature list.
|
||||
|
||||
### Public API Documentation [3.ii]
|
||||
|
||||
`rclcpp_components` does not cover a public API documentation.
|
||||
|
||||
The API is publicly available in the [ROS 2 API documentation](http://docs.ros2.org/latest/api/rclcpp_components/).
|
||||
|
||||
### License [3.iii]
|
||||
|
||||
The license for `rclcpp_components` is Apache 2.0, and a summary is in each source file, the type is declared in the [`package.xml`](./package.xml) manifest file, and a full copy of the license is in the [`LICENSE`](../LICENSE) file.
|
||||
|
||||
There is an automated test which runs a linter that ensures each file has a license statement. [Here](http://build.ros2.org/view/Epr/job/Epr__rclcpp_components__ubuntu_bionic_amd64/lastBuild/testReport/rclcpp_components/) can be found a list with the latest results of the various linters being run on the package.
|
||||
|
||||
### Copyright Statements [3.iv]
|
||||
|
||||
The copyright holders each provide a statement of copyright in each source code file in `rclcpp_components`.
|
||||
|
||||
There is an automated test which runs a linter that ensures each file has at least one copyright statement. Latest linter result report can be seen [here](http://build.ros2.org/view/Epr/job/Epr__rclcpp_components__ubuntu_bionic_amd64/lastBuild/testReport/rclcpp_components/copyright/).
|
||||
|
||||
## Testing [4]
|
||||
|
||||
### Feature Testing [4.i]
|
||||
|
||||
Each feature in `rclcpp_components` has corresponding tests which simulate typical usage, and they are located in the [`test`](https://github.com/ros2/rclcpp_components/tree/master/test) directory.
|
||||
New features are required to have tests before being added.
|
||||
|
||||
Currently nightly test results can be seen here:
|
||||
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_components/)
|
||||
|
||||
### Public API Testing [4.ii]
|
||||
|
||||
Each part of the public API has tests, and new additions or changes to the public API require tests before being added.
|
||||
The tests aim to cover both typical usage and corner cases, but are quantified by contributing to code coverage.
|
||||
|
||||
### Coverage [4.iii]
|
||||
|
||||
`rclcpp_components` follows the recommendations for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#code-coverage), and opts to use line coverage instead of branch coverage.
|
||||
|
||||
This includes:
|
||||
|
||||
- tracking and reporting line coverage statistics
|
||||
- achieving and maintaining a reasonable branch line coverage (90-100%)
|
||||
- no lines are manually skipped in coverage calculations
|
||||
|
||||
Changes are required to make a best effort to keep or increase coverage before being accepted, but decreases are allowed if properly justified and accepted by reviewers.
|
||||
|
||||
### Performance [4.iv]
|
||||
|
||||
It is not yet defined if this package requires performance testing and how addresses this topic.
|
||||
|
||||
### Linters and Static Analysis [4.v]
|
||||
|
||||
`rclcpp_components` uses and passes all the ROS2 standard linters and static analysis tools for a C++ package as described in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#linters-and-static-analysis). Passing implies there are no linter/static errors when testing against CI of supported platforms.
|
||||
|
||||
Currently nightly test results can be seen here:
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_components/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_components/)
|
||||
|
||||
## Dependencies [5]
|
||||
|
||||
### Direct and Optional Runtime ROS Dependencies [5.i]/[5.ii]
|
||||
|
||||
`rclcpp_components` has the following runtime ROS dependencies:
|
||||
- ament_index_cpp
|
||||
- class_loader
|
||||
- composition_interfaces
|
||||
- rclcpp
|
||||
|
||||
It has several "buildtool" dependencies, which do not affect the resulting quality of the package, because they do not contribute to the public library API.
|
||||
It also has several test dependencies, which do not affect the resulting quality of the package, because they are only used to build and run the test code.
|
||||
|
||||
### Direct Runtime non-ROS Dependency [5.iii]
|
||||
|
||||
`rclcpp_components` has no run-time or build-time dependencies that need to be considered for this declaration.
|
||||
|
||||
## Platform Support [6]
|
||||
|
||||
`rclcpp_components` 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.
|
||||
|
||||
Currently nightly build status can be seen here:
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/rclcpp_components/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/rclcpp_components/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/rclcpp_components/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/rclcpp_components/)
|
||||
|
||||
## Security
|
||||
|
||||
### Vulnerability Disclosure Policy [7.i]
|
||||
|
||||
This package does not yet have a Vulnerability Disclosure Policy
|
||||
7
rclcpp_components/README.md
Normal file
7
rclcpp_components/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# `rclcpp_components`
|
||||
|
||||
Package containing tools for dynamically loadable components.
|
||||
|
||||
## Quality Declaration
|
||||
|
||||
This package claims to be in the **Quality Level 4** category, see the [Quality Declaration](QUALITY_DECLARATION.md) for more details.
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_components</name>
|
||||
<version>0.8.3</version>
|
||||
<version>1.0.0</version>
|
||||
<description>Package containing tools for dynamically loadable components</description>
|
||||
<maintainer email="michael@openrobotics.org">Michael Carroll</maintainer>
|
||||
<license>Apache License 2.0</license>
|
||||
|
||||
@@ -55,7 +55,6 @@ private:
|
||||
rclcpp::Node node_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace test_rclcpp_components
|
||||
|
||||
#include "rclcpp_components/register_node_macro.hpp"
|
||||
|
||||
@@ -88,4 +88,9 @@ TEST_F(TestComponentManager, create_component_factory_invalid)
|
||||
auto resources = manager->get_component_resources("rclcpp_components");
|
||||
auto factory = manager->create_component_factory({"foo_class", resources[0].second});
|
||||
EXPECT_EQ(nullptr, factory);
|
||||
|
||||
// Test improperly formed resources file
|
||||
EXPECT_THROW(
|
||||
auto resources = manager->get_component_resources("invalid_rclcpp_components"),
|
||||
rclcpp_components::ComponentManagerException);
|
||||
}
|
||||
|
||||
@@ -143,6 +143,65 @@ TEST_F(TestComponentManager, components_api)
|
||||
EXPECT_EQ(result.get()->unique_id, 0u);
|
||||
}
|
||||
|
||||
{
|
||||
// Remap rules
|
||||
auto request = std::make_shared<composition_interfaces::srv::LoadNode::Request>();
|
||||
request->package_name = "rclcpp_components";
|
||||
request->plugin_name = "test_rclcpp_components::TestComponentFoo";
|
||||
request->node_name = "test_component_remap";
|
||||
request->remap_rules.push_back("alice:=bob");
|
||||
|
||||
auto result = client->async_send_request(request);
|
||||
auto ret = exec->spin_until_future_complete(result, 5s); // Wait for the result.
|
||||
EXPECT_EQ(ret, rclcpp::FutureReturnCode::SUCCESS);
|
||||
EXPECT_EQ(result.get()->success, true);
|
||||
EXPECT_EQ(result.get()->error_message, "");
|
||||
EXPECT_EQ(result.get()->full_node_name, "/test_component_remap");
|
||||
EXPECT_EQ(result.get()->unique_id, 5u);
|
||||
}
|
||||
|
||||
{
|
||||
// use_intra_process_comms
|
||||
auto request = std::make_shared<composition_interfaces::srv::LoadNode::Request>();
|
||||
request->package_name = "rclcpp_components";
|
||||
request->plugin_name = "test_rclcpp_components::TestComponentFoo";
|
||||
request->node_name = "test_component_intra_process";
|
||||
rclcpp::Parameter use_intraprocess_comms("use_intra_process_comms",
|
||||
rclcpp::ParameterValue(true));
|
||||
request->extra_arguments.push_back(use_intraprocess_comms.to_parameter_msg());
|
||||
|
||||
auto result = client->async_send_request(request);
|
||||
auto ret = exec->spin_until_future_complete(result, 5s); // Wait for the result.
|
||||
EXPECT_EQ(ret, rclcpp::FutureReturnCode::SUCCESS);
|
||||
EXPECT_EQ(result.get()->success, true);
|
||||
EXPECT_EQ(result.get()->error_message, "");
|
||||
std::cout << result.get()->full_node_name << std::endl;
|
||||
EXPECT_EQ(result.get()->full_node_name, "/test_component_intra_process");
|
||||
EXPECT_EQ(result.get()->unique_id, 6u);
|
||||
}
|
||||
|
||||
{
|
||||
// use_intra_process_comms is not a bool type parameter
|
||||
auto request = std::make_shared<composition_interfaces::srv::LoadNode::Request>();
|
||||
request->package_name = "rclcpp_components";
|
||||
request->plugin_name = "test_rclcpp_components::TestComponentFoo";
|
||||
request->node_name = "test_component_intra_process_str";
|
||||
|
||||
rclcpp::Parameter use_intraprocess_comms("use_intra_process_comms",
|
||||
rclcpp::ParameterValue("hello"));
|
||||
request->extra_arguments.push_back(use_intraprocess_comms.to_parameter_msg());
|
||||
|
||||
auto result = client->async_send_request(request);
|
||||
auto ret = exec->spin_until_future_complete(result, 5s); // Wait for the result.
|
||||
EXPECT_EQ(ret, rclcpp::FutureReturnCode::SUCCESS);
|
||||
EXPECT_EQ(result.get()->success, false);
|
||||
EXPECT_EQ(
|
||||
result.get()->error_message,
|
||||
"Extra component argument 'use_intra_process_comms' must be a boolean");
|
||||
EXPECT_EQ(result.get()->full_node_name, "");
|
||||
EXPECT_EQ(result.get()->unique_id, 0u);
|
||||
}
|
||||
|
||||
auto node_names = node->get_node_names();
|
||||
|
||||
auto find_in_nodes = [node_names](std::string name) {
|
||||
@@ -170,16 +229,20 @@ TEST_F(TestComponentManager, components_api)
|
||||
auto node_names = result.get()->full_node_names;
|
||||
auto unique_ids = result.get()->unique_ids;
|
||||
|
||||
EXPECT_EQ(node_names.size(), 4u);
|
||||
EXPECT_EQ(node_names.size(), 6u);
|
||||
EXPECT_EQ(node_names[0], "/test_component_foo");
|
||||
EXPECT_EQ(node_names[1], "/test_component_bar");
|
||||
EXPECT_EQ(node_names[2], "/test_component_baz");
|
||||
EXPECT_EQ(node_names[3], "/ns/test_component_bing");
|
||||
EXPECT_EQ(unique_ids.size(), 4u);
|
||||
EXPECT_EQ(node_names[4], "/test_component_remap");
|
||||
EXPECT_EQ(node_names[5], "/test_component_intra_process");
|
||||
EXPECT_EQ(unique_ids.size(), 6u);
|
||||
EXPECT_EQ(unique_ids[0], 1u);
|
||||
EXPECT_EQ(unique_ids[1], 2u);
|
||||
EXPECT_EQ(unique_ids[2], 3u);
|
||||
EXPECT_EQ(unique_ids[3], 4u);
|
||||
EXPECT_EQ(unique_ids[4], 5u);
|
||||
EXPECT_EQ(unique_ids[5], 6u);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,14 +293,18 @@ TEST_F(TestComponentManager, components_api)
|
||||
auto node_names = result.get()->full_node_names;
|
||||
auto unique_ids = result.get()->unique_ids;
|
||||
|
||||
EXPECT_EQ(node_names.size(), 3u);
|
||||
EXPECT_EQ(node_names.size(), 5u);
|
||||
EXPECT_EQ(node_names[0], "/test_component_bar");
|
||||
EXPECT_EQ(node_names[1], "/test_component_baz");
|
||||
EXPECT_EQ(node_names[2], "/ns/test_component_bing");
|
||||
EXPECT_EQ(unique_ids.size(), 3u);
|
||||
EXPECT_EQ(node_names[3], "/test_component_remap");
|
||||
EXPECT_EQ(node_names[4], "/test_component_intra_process");
|
||||
EXPECT_EQ(unique_ids.size(), 5u);
|
||||
EXPECT_EQ(unique_ids[0], 2u);
|
||||
EXPECT_EQ(unique_ids[1], 3u);
|
||||
EXPECT_EQ(unique_ids[2], 4u);
|
||||
EXPECT_EQ(unique_ids[3], 5u);
|
||||
EXPECT_EQ(unique_ids[4], 6u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,31 @@ Changelog for package rclcpp_lifecycle
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
1.0.0 (2020-05-12)
|
||||
------------------
|
||||
* Avoid callback_group deprecation (`#1108 <https://github.com/ros2/rclcpp/issues/1108>`_)
|
||||
* Contributors: Karsten Knese
|
||||
|
||||
0.9.1 (2020-05-08)
|
||||
------------------
|
||||
* Added rclcpp lifecycle Doxyfile (`#1089 <https://github.com/ros2/rclcpp/issues/1089>`_)
|
||||
* Added Quality declaration: rclcpp, rclpp_action, rclcpp_components andrclcpp_lifecycle (`#1100 <https://github.com/ros2/rclcpp/issues/1100>`_)
|
||||
* Increasing test coverage of rclcpp_lifecycle (`#1045 <https://github.com/ros2/rclcpp/issues/1045>`_)
|
||||
* Contributors: Alejandro Hernández Cordero, brawner
|
||||
|
||||
0.9.0 (2020-04-29)
|
||||
------------------
|
||||
* Export targets in addition to include directories / libraries (`#1096 <https://github.com/ros2/rclcpp/issues/1096>`_)
|
||||
* Deprecate redundant namespaces (`#1083 <https://github.com/ros2/rclcpp/issues/1083>`_)
|
||||
* Integrate topic statistics (`#1072 <https://github.com/ros2/rclcpp/issues/1072>`_)
|
||||
* Reflect changes in rclcpp API (`#1079 <https://github.com/ros2/rclcpp/issues/1079>`_)
|
||||
* Fix unknown macro errors reported by cppcheck 1.90 (`#1000 <https://github.com/ros2/rclcpp/issues/1000>`_)
|
||||
* Rremoved rmw_implementation from package.xml (`#991 <https://github.com/ros2/rclcpp/issues/991>`_)
|
||||
* Implement functions to get publisher and subcription informations like QoS policies from topic name (`#960 <https://github.com/ros2/rclcpp/issues/960>`_)
|
||||
* Create node clock calls const (`#922 <https://github.com/ros2/rclcpp/issues/922>`_)
|
||||
* Type conversions fixes (`#901 <https://github.com/ros2/rclcpp/issues/901>`_)
|
||||
* Contributors: Alejandro Hernández Cordero, Barry Xu, Devin Bonnie, Dirk Thomas, Jacob Perron, Monika Idzik, Prajakta Gokhale, Steven Macenski, William Woodall
|
||||
|
||||
0.8.3 (2019-11-19)
|
||||
------------------
|
||||
|
||||
|
||||
@@ -59,6 +59,14 @@ if(BUILD_TESTING)
|
||||
)
|
||||
target_link_libraries(test_lifecycle_node ${PROJECT_NAME})
|
||||
endif()
|
||||
ament_add_gtest(test_lifecycle_service_client test/test_lifecycle_service_client.cpp)
|
||||
if(TARGET test_lifecycle_service_client)
|
||||
ament_target_dependencies(test_lifecycle_service_client
|
||||
"rcl_lifecycle"
|
||||
"rclcpp"
|
||||
)
|
||||
target_link_libraries(test_lifecycle_service_client ${PROJECT_NAME})
|
||||
endif()
|
||||
ament_add_gtest(test_state_machine_info test/test_state_machine_info.cpp)
|
||||
if(TARGET test_state_machine_info)
|
||||
ament_target_dependencies(test_state_machine_info
|
||||
|
||||
33
rclcpp_lifecycle/Doxyfile
Normal file
33
rclcpp_lifecycle/Doxyfile
Normal file
@@ -0,0 +1,33 @@
|
||||
# All settings not listed here will use the Doxygen default values.
|
||||
|
||||
PROJECT_NAME = "rclcpp_lifecycle"
|
||||
PROJECT_NUMBER = master
|
||||
PROJECT_BRIEF = "C++ ROS Lifecycle Library API"
|
||||
|
||||
# Use these lines to include the generated logging.hpp (update install path if needed)
|
||||
# Otherwise just generate for the local (non-generated header files)
|
||||
|
||||
|
||||
INPUT = ./include
|
||||
|
||||
RECURSIVE = YES
|
||||
OUTPUT_DIRECTORY = doc_output
|
||||
|
||||
EXTRACT_ALL = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
|
||||
GENERATE_LATEX = NO
|
||||
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = RCLCPP_LIFECYCLE_PUBLIC=
|
||||
|
||||
# Tag files that do not exist will produce a warning and cross-project linking will not work.
|
||||
TAGFILES += "../../../../doxygen_tag_files/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/"
|
||||
# Consider changing "latest" to the version you want to reference (e.g. beta1 or 1.0.0)
|
||||
TAGFILES += "../../../../doxygen_tag_files/rclcpp.tag=http://docs.ros2.org/latest/api/rclcpp/"
|
||||
TAGFILES += "../../../../doxygen_tag_files/rcl_lifecycle.tag=http://docs.ros2.org/latest/api/rcl_lifecycle/"
|
||||
TAGFILES += "../../../../doxygen_tag_files/rmw.tag=http://docs.ros2.org/latest/api/rmw/"
|
||||
# Uncomment to generate tag files for cross-project linking.
|
||||
GENERATE_TAGFILE = "../../../../doxygen_tag_files/rclcpp_lifecycle.tag"
|
||||
167
rclcpp_lifecycle/QUALITY_DECLARATION.md
Normal file
167
rclcpp_lifecycle/QUALITY_DECLARATION.md
Normal file
@@ -0,0 +1,167 @@
|
||||
This document is a declaration of software quality for the `rclcpp_lifecycle` package, based on the guidelines in [REP-2004](https://github.com/ros-infrastructure/rep/blob/rep-2004/rep-2004.rst).
|
||||
|
||||
# `rclcpp_lifecycle` Quality Declaration
|
||||
|
||||
The package `rclcpp_lifecycle` claims to be in the **Quality Level 4** category.
|
||||
|
||||
Below are the rationales, notes, and caveats for this claim, organized by each requirement listed in the [Package Quality Categories in REP-2004](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#package-quality-categories) of the ROS2 developer guide.
|
||||
|
||||
## Version Policy [1]
|
||||
|
||||
### Version Scheme [1.i]
|
||||
|
||||
`rclcpp_lifecycle` uses `semver` according to the recommendation for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#versioning)
|
||||
|
||||
### Version Stability [1.ii]
|
||||
|
||||
`rclcpp_lifecycle` is not yet at a stable version, i.e. `>= 1.0.0`.
|
||||
The current version can be found in its [package.xml](package.xml), and its change history can be found in its [CHANGELOG](CHANGELOG.rst).
|
||||
|
||||
### Public API Declaration [1.iii]
|
||||
|
||||
All symbols in the installed headers are considered part of the public API.
|
||||
|
||||
All installed headers are in the `include` directory of the package, headers in any other folders are not installed and considered private.
|
||||
|
||||
### API Stability Policy [1.iv]
|
||||
|
||||
`rclcpp_lifecycle` will not break public API within a released ROS distribution, i.e. no major releases once the ROS distribution is released.
|
||||
|
||||
### ABI Stability Policy [1.v]
|
||||
|
||||
`rclcpp_lifecycle` contains C++ code and therefore must be concerned with ABI stability, and will maintain ABI stability within a ROS distribution.
|
||||
|
||||
### ABI and ABI Stability Within a Released ROS Distribution [1.vi]
|
||||
|
||||
`rclcpp_lifecycle` will not break API nor ABI within a released ROS distribution, i.e. no major releases once the ROS distribution is released.
|
||||
|
||||
## Change Control Process [2]
|
||||
|
||||
`rclcpp_lifecycle` follows the recommended guidelines for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process).
|
||||
|
||||
### Change Requests [2.i]
|
||||
|
||||
All changes will occur through a pull request, check [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process) for additional information.
|
||||
|
||||
### Contributor Origin [2.ii]
|
||||
|
||||
This package uses DCO as its confirmation of contributor origin policy. More information can be found in [CONTRIBUTING](../CONTRIBUTING.md).
|
||||
|
||||
### Peer Review Policy [2.iii]
|
||||
|
||||
All pull requests will be peer-reviewed, check [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#change-control-process) for additional information.
|
||||
|
||||
### 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)
|
||||
|
||||
Currently nightly results can be seen here:
|
||||
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
|
||||
### Documentation Policy [2.v]
|
||||
|
||||
All pull requests must resolve related documentation changes before merging.
|
||||
|
||||
## Documentation [3]
|
||||
|
||||
### Feature Documentation [3.i]
|
||||
|
||||
`rclcpp_lifecycle` does not have a documented feature list.
|
||||
|
||||
### Public API Documentation [3.ii]
|
||||
|
||||
`rclcpp_lifecycle` does not cover a public API documentation.
|
||||
|
||||
### License [3.iii]
|
||||
|
||||
The license for `rclcpp_lifecycle` is Apache 2.0, and a summary is in each source file, the type is declared in the [`package.xml`](./package.xml) manifest file, and a full copy of the license is in the [`LICENSE`](../LICENSE) file.
|
||||
|
||||
There is an automated test which runs a linter that ensures each file has a license statement. [Here](http://build.ros2.org/view/Epr/job/Epr__rclcpp_lifecycle__ubuntu_bionic_amd64/lastBuild/testReport/rclcpp_lifecycle/) can be found a list with the latest results of the various linters being run on the package.
|
||||
|
||||
### Copyright Statements [3.iv]
|
||||
|
||||
The copyright holders each provide a statement of copyright in each source code file in `rclcpp_lifecycle`.
|
||||
|
||||
There is an automated test which runs a linter that ensures each file has at least one copyright statement. Latest linter result report can be seen [here](http://build.ros2.org/view/Epr/job/Epr__rclcpp_lifecycle__ubuntu_bionic_amd64/lastBuild/testReport/rclcpp_lifecycle/copyright/).
|
||||
|
||||
## Testing [4]
|
||||
|
||||
### Feature Testing [4.i]
|
||||
|
||||
Each feature in `rclcpp_lifecycle` has corresponding tests which simulate typical usage, and they are located in the [`test`](https://github.com/ros2/rclcpp_lifecycle/tree/master/test) directory.
|
||||
New features are required to have tests before being added.
|
||||
|
||||
Currently nightly test results can be seen here:
|
||||
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
|
||||
### Public API Testing [4.ii]
|
||||
|
||||
Each part of the public API has tests, and new additions or changes to the public API require tests before being added.
|
||||
The tests aim to cover both typical usage and corner cases, but are quantified by contributing to code coverage.
|
||||
|
||||
### Coverage [4.iii]
|
||||
|
||||
`rclcpp_lifecycle` follows the recommendations for ROS Core packages in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#code-coverage), and opts to use line coverage instead of branch coverage.
|
||||
|
||||
This includes:
|
||||
|
||||
- tracking and reporting line coverage statistics
|
||||
- achieving and maintaining a reasonable branch line coverage (90-100%)
|
||||
- no lines are manually skipped in coverage calculations
|
||||
|
||||
Changes are required to make a best effort to keep or increase coverage before being accepted, but decreases are allowed if properly justified and accepted by reviewers.
|
||||
|
||||
### Performance [4.iv]
|
||||
|
||||
It is not yet defined if this package requires performance testing and how addresses this topic.
|
||||
|
||||
### Linters and Static Analysis [4.v]
|
||||
|
||||
`rclcpp_lifecycle` uses and passes all the ROS2 standard linters and static analysis tools for a C++ package as described in the [ROS 2 Developer Guide](https://index.ros.org/doc/ros2/Contributing/Developer-Guide/#linters-and-static-analysis). Passing implies there are no linter/static errors when testing against CI of supported platforms.
|
||||
|
||||
Currently nightly test results can be seen here:
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rclcpp_lifecycle/)
|
||||
|
||||
## Dependencies [5]
|
||||
|
||||
### Direct and Optional Runtime ROS Dependencies [5.i]/[5.ii]
|
||||
|
||||
`rclcpp_lifecycle` has the following runtime ROS dependencies:
|
||||
- lifecycle_msgs
|
||||
- rclcpp
|
||||
- rcl_lifecycle
|
||||
- rosidl_typesupport_cpp
|
||||
|
||||
It has several "buildtool" dependencies, which do not affect the resulting quality of the package, because they do not contribute to the public library API.
|
||||
It also has several test dependencies, which do not affect the resulting quality of the package, because they are only used to build and run the test code.
|
||||
|
||||
### Direct Runtime non-ROS Dependency [5.iii]
|
||||
|
||||
`rclcpp_lifecycle` has no run-time or build-time dependencies that need to be considered for this declaration.
|
||||
|
||||
## Platform Support [6]
|
||||
|
||||
`rclcpp_lifecycle` 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.
|
||||
|
||||
Currently nightly build status can be seen here:
|
||||
* [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/rclcpp_lifecycle/)
|
||||
* [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/rclcpp_lifecycle/)
|
||||
* [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/rclcpp_lifecycle/)
|
||||
* [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/rclcpp_lifecycle/)
|
||||
|
||||
## Security
|
||||
|
||||
### Vulnerability Disclosure Policy [7.i]
|
||||
|
||||
This package does not yet have a Vulnerability Disclosure Policy
|
||||
7
rclcpp_lifecycle/README.md
Normal file
7
rclcpp_lifecycle/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# `rclcpp_lifecycle`
|
||||
|
||||
Package containing a prototype for lifecycle implementation. Visit the [design document](https://design.ros2.org/articles/node_lifecycle.html) for more information about this package.
|
||||
|
||||
## Quality Declaration
|
||||
|
||||
This package claims to be in the **Quality Level 4** category, see the [Quality Declaration](QUALITY_DECLARATION.md) for more details.
|
||||
@@ -2,7 +2,7 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="2">
|
||||
<name>rclcpp_lifecycle</name>
|
||||
<version>0.8.3</version>
|
||||
<version>1.0.0</version>
|
||||
<description>Package containing a prototype for lifecycle implementation</description>
|
||||
<maintainer email="karsten@osrfoundation.org">Karsten Knese</maintainer>
|
||||
<license>Apache License 2.0</license>
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include "lifecycle_msgs/msg/state.hpp"
|
||||
@@ -162,6 +165,38 @@ TEST_F(TestDefaultStateMachine, trigger_transition) {
|
||||
|
||||
TEST_F(TestDefaultStateMachine, trigger_transition_with_error_code) {
|
||||
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
|
||||
auto success = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
|
||||
auto reset_key = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR;
|
||||
auto ret = reset_key;
|
||||
|
||||
EXPECT_EQ(State::PRIMARY_STATE_UNCONFIGURED, test_node->get_current_state().id());
|
||||
test_node->trigger_transition(
|
||||
rclcpp_lifecycle::Transition(Transition::TRANSITION_CONFIGURE), ret);
|
||||
ASSERT_EQ(success, ret);
|
||||
ret = reset_key;
|
||||
|
||||
test_node->trigger_transition(
|
||||
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVATE), ret);
|
||||
ASSERT_EQ(success, ret);
|
||||
ret = reset_key;
|
||||
|
||||
test_node->trigger_transition(
|
||||
rclcpp_lifecycle::Transition(Transition::TRANSITION_DEACTIVATE), ret);
|
||||
ASSERT_EQ(success, ret);
|
||||
ret = reset_key;
|
||||
|
||||
test_node->trigger_transition(
|
||||
rclcpp_lifecycle::Transition(Transition::TRANSITION_CLEANUP), ret);
|
||||
ASSERT_EQ(success, ret);
|
||||
ret = reset_key;
|
||||
|
||||
test_node->trigger_transition(
|
||||
rclcpp_lifecycle::Transition(Transition::TRANSITION_UNCONFIGURED_SHUTDOWN), ret);
|
||||
ASSERT_EQ(success, ret);
|
||||
}
|
||||
|
||||
TEST_F(TestDefaultStateMachine, call_transitions_with_error_code) {
|
||||
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
|
||||
|
||||
auto success = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
|
||||
auto reset_key = rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR;
|
||||
@@ -188,6 +223,25 @@ TEST_F(TestDefaultStateMachine, trigger_transition_with_error_code) {
|
||||
EXPECT_EQ(success, ret);
|
||||
}
|
||||
|
||||
TEST_F(TestDefaultStateMachine, call_transitions_without_code) {
|
||||
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
|
||||
|
||||
auto configured = test_node->configure();
|
||||
EXPECT_EQ(configured.id(), State::PRIMARY_STATE_INACTIVE);
|
||||
|
||||
auto activated = test_node->activate();
|
||||
EXPECT_EQ(activated.id(), State::PRIMARY_STATE_ACTIVE);
|
||||
|
||||
auto deactivated = test_node->deactivate();
|
||||
EXPECT_EQ(deactivated.id(), State::PRIMARY_STATE_INACTIVE);
|
||||
|
||||
auto unconfigured = test_node->cleanup();
|
||||
EXPECT_EQ(unconfigured.id(), State::PRIMARY_STATE_UNCONFIGURED);
|
||||
|
||||
auto finalized = test_node->shutdown();
|
||||
EXPECT_EQ(finalized.id(), State::PRIMARY_STATE_FINALIZED);
|
||||
}
|
||||
|
||||
TEST_F(TestDefaultStateMachine, good_mood) {
|
||||
auto test_node = std::make_shared<MoodyLifecycleNode<GoodMood>>("testnode");
|
||||
|
||||
@@ -233,3 +287,259 @@ TEST_F(TestDefaultStateMachine, lifecycle_subscriber) {
|
||||
|
||||
SUCCEED();
|
||||
}
|
||||
|
||||
// Parameters are tested more thoroughly in rclcpp's test_node.cpp
|
||||
// These are provided for coverage of lifecycle node's API
|
||||
TEST_F(TestDefaultStateMachine, declare_parameters) {
|
||||
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
|
||||
|
||||
auto list_result = test_node->list_parameters({}, 0u);
|
||||
EXPECT_EQ(list_result.names.size(), 1u);
|
||||
EXPECT_STREQ(list_result.names[0].c_str(), "use_sim_time");
|
||||
|
||||
const std::string bool_name = "test_boolean";
|
||||
const std::string int_name = "test_int";
|
||||
|
||||
// Default descriptor overload
|
||||
test_node->declare_parameter(bool_name, rclcpp::ParameterValue(false));
|
||||
|
||||
// Explicit descriptor overload
|
||||
rcl_interfaces::msg::ParameterDescriptor int_descriptor;
|
||||
int_descriptor.name = int_name;
|
||||
int_descriptor.type = rcl_interfaces::msg::ParameterType::PARAMETER_INTEGER;
|
||||
int_descriptor.description = "Example integer parameter";
|
||||
test_node->declare_parameter(int_name, rclcpp::ParameterValue(42), int_descriptor);
|
||||
|
||||
std::map<std::string, std::string> str_parameters;
|
||||
str_parameters["str_one"] = "stringy_string";
|
||||
str_parameters["str_two"] = "stringy_string_string";
|
||||
|
||||
// Default descriptor overload
|
||||
test_node->declare_parameters("test_string", str_parameters);
|
||||
|
||||
std::map<std::string,
|
||||
std::pair<double, rcl_interfaces::msg::ParameterDescriptor>> double_parameters;
|
||||
rcl_interfaces::msg::ParameterDescriptor double_descriptor_one;
|
||||
double_descriptor_one.name = "double_one";
|
||||
double_descriptor_one.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE;
|
||||
double_parameters["double_one"] = std::make_pair(1.0, double_descriptor_one);
|
||||
|
||||
rcl_interfaces::msg::ParameterDescriptor double_descriptor_two;
|
||||
double_descriptor_two.name = "double_two";
|
||||
double_descriptor_two.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE;
|
||||
double_parameters["double_two"] = std::make_pair(2.0, double_descriptor_two);
|
||||
|
||||
// Explicit descriptor overload
|
||||
test_node->declare_parameters("test_double", double_parameters);
|
||||
|
||||
list_result = test_node->list_parameters({}, 0u);
|
||||
EXPECT_EQ(list_result.names.size(), 7u);
|
||||
|
||||
// The order of these names is not controlled by lifecycle_node, doing set equality
|
||||
std::set<std::string> expected_names = {
|
||||
"test_boolean",
|
||||
"test_double.double_one",
|
||||
"test_double.double_two",
|
||||
"test_int",
|
||||
"test_string.str_one",
|
||||
"test_string.str_two",
|
||||
"use_sim_time",
|
||||
};
|
||||
std::set<std::string> actual_names(list_result.names.begin(), list_result.names.end());
|
||||
|
||||
EXPECT_EQ(expected_names, actual_names);
|
||||
}
|
||||
|
||||
TEST_F(TestDefaultStateMachine, check_parameters) {
|
||||
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
|
||||
|
||||
auto list_result = test_node->list_parameters({}, 0u);
|
||||
EXPECT_EQ(list_result.names.size(), 1u);
|
||||
EXPECT_STREQ(list_result.names[0].c_str(), "use_sim_time");
|
||||
|
||||
const std::string bool_name = "test_boolean";
|
||||
const std::string int_name = "test_int";
|
||||
std::vector<std::string> parameter_names = {bool_name, int_name};
|
||||
|
||||
EXPECT_FALSE(test_node->has_parameter(bool_name));
|
||||
EXPECT_FALSE(test_node->has_parameter(int_name));
|
||||
EXPECT_THROW(
|
||||
test_node->get_parameters(parameter_names),
|
||||
rclcpp::exceptions::ParameterNotDeclaredException);
|
||||
|
||||
// Default descriptor overload
|
||||
test_node->declare_parameter(bool_name, rclcpp::ParameterValue(true));
|
||||
|
||||
// Explicit descriptor overload
|
||||
rcl_interfaces::msg::ParameterDescriptor int_descriptor;
|
||||
int_descriptor.name = int_name;
|
||||
int_descriptor.type = rcl_interfaces::msg::ParameterType::PARAMETER_INTEGER;
|
||||
int_descriptor.description = "Example integer parameter";
|
||||
test_node->declare_parameter(int_name, rclcpp::ParameterValue(42), int_descriptor);
|
||||
|
||||
// describe parameters
|
||||
auto descriptors = test_node->describe_parameters(parameter_names);
|
||||
EXPECT_EQ(descriptors.size(), parameter_names.size());
|
||||
|
||||
EXPECT_THROW(
|
||||
test_node->describe_parameter("not_a_real_parameter"),
|
||||
rclcpp::exceptions::ParameterNotDeclaredException);
|
||||
|
||||
// describe parameter matches explicit descriptor
|
||||
auto descriptor = test_node->describe_parameter(int_name);
|
||||
EXPECT_STREQ(descriptor.name.c_str(), int_descriptor.name.c_str());
|
||||
EXPECT_EQ(descriptor.type, int_descriptor.type);
|
||||
EXPECT_STREQ(descriptor.description.c_str(), int_descriptor.description.c_str());
|
||||
|
||||
// bool parameter exists and value matches
|
||||
EXPECT_TRUE(test_node->has_parameter(bool_name));
|
||||
EXPECT_EQ(test_node->get_parameter(bool_name).as_bool(), true);
|
||||
|
||||
// int parameter exists and value matches
|
||||
EXPECT_TRUE(test_node->has_parameter(int_name));
|
||||
EXPECT_EQ(test_node->get_parameter(int_name).as_int(), 42);
|
||||
|
||||
// Get multiple parameters at a time
|
||||
auto parameters = test_node->get_parameters(parameter_names);
|
||||
EXPECT_EQ(parameters.size(), parameter_names.size());
|
||||
EXPECT_EQ(parameters[0].as_bool(), true);
|
||||
EXPECT_EQ(parameters[1].as_int(), 42);
|
||||
|
||||
// Get multiple parameters at a time with map
|
||||
std::map<std::string, rclcpp::ParameterValue> parameter_map;
|
||||
EXPECT_TRUE(test_node->get_parameters({}, parameter_map));
|
||||
|
||||
// int param, bool param, and use_sim_time
|
||||
EXPECT_EQ(parameter_map.size(), 3u);
|
||||
|
||||
// Check parameter types
|
||||
auto parameter_types = test_node->get_parameter_types(parameter_names);
|
||||
EXPECT_EQ(parameter_types.size(), parameter_names.size());
|
||||
EXPECT_EQ(parameter_types[0], rcl_interfaces::msg::ParameterType::PARAMETER_BOOL);
|
||||
EXPECT_EQ(parameter_types[1], rcl_interfaces::msg::ParameterType::PARAMETER_INTEGER);
|
||||
|
||||
// Setting parameters
|
||||
size_t parameters_set = 0;
|
||||
auto callback = [¶meters_set](const std::vector<rclcpp::Parameter> & parameters) {
|
||||
parameters_set += parameters.size();
|
||||
rcl_interfaces::msg::SetParametersResult result;
|
||||
result.successful = true;
|
||||
return result;
|
||||
};
|
||||
|
||||
test_node->set_on_parameters_set_callback(callback);
|
||||
rclcpp::Parameter bool_parameter(bool_name, rclcpp::ParameterValue(false));
|
||||
EXPECT_TRUE(test_node->set_parameter(bool_parameter).successful);
|
||||
EXPECT_EQ(parameters_set, 1u);
|
||||
|
||||
rclcpp::Parameter int_parameter(int_name, rclcpp::ParameterValue(7));
|
||||
test_node->set_parameters({int_parameter});
|
||||
EXPECT_EQ(parameters_set, 2u);
|
||||
|
||||
// List parameters
|
||||
list_result = test_node->list_parameters({}, 0u);
|
||||
EXPECT_EQ(list_result.names.size(), 3u);
|
||||
EXPECT_STREQ(list_result.names[0].c_str(), parameter_names[0].c_str());
|
||||
EXPECT_STREQ(list_result.names[1].c_str(), parameter_names[1].c_str());
|
||||
EXPECT_STREQ(list_result.names[2].c_str(), "use_sim_time");
|
||||
|
||||
// Undeclare parameter
|
||||
test_node->undeclare_parameter(bool_name);
|
||||
EXPECT_FALSE(test_node->has_parameter(bool_name));
|
||||
rclcpp::Parameter parameter;
|
||||
EXPECT_FALSE(test_node->get_parameter(bool_name, parameter));
|
||||
|
||||
// Bool parameter has been undeclared, atomic setting should fail
|
||||
parameters = {
|
||||
rclcpp::Parameter(bool_name, rclcpp::ParameterValue(true)),
|
||||
rclcpp::Parameter(int_name, rclcpp::ParameterValue(0))};
|
||||
EXPECT_THROW(
|
||||
test_node->set_parameters_atomically(parameters),
|
||||
rclcpp::exceptions::ParameterNotDeclaredException);
|
||||
|
||||
// Since setting parameters failed, this should remain the same
|
||||
EXPECT_EQ(test_node->get_parameter(int_name).as_int(), 7);
|
||||
|
||||
// Bool parameter no longer exists, using "or" value
|
||||
EXPECT_FALSE(
|
||||
test_node->get_parameter_or(
|
||||
bool_name, parameter, rclcpp::Parameter(bool_name, rclcpp::ParameterValue(true))));
|
||||
EXPECT_TRUE(parameter.as_bool());
|
||||
}
|
||||
|
||||
TEST_F(TestDefaultStateMachine, test_getters) {
|
||||
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
|
||||
auto options = test_node->get_node_options();
|
||||
EXPECT_EQ(0u, options.arguments().size());
|
||||
EXPECT_NE(nullptr, test_node->get_node_base_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_clock_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_graph_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_logging_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_time_source_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_timers_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_topics_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_services_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_parameters_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_node_waitables_interface());
|
||||
EXPECT_NE(nullptr, test_node->get_graph_event());
|
||||
EXPECT_NE(nullptr, test_node->get_clock());
|
||||
EXPECT_LT(0u, test_node->now().nanoseconds());
|
||||
EXPECT_STREQ("testnode", test_node->get_logger().get_name());
|
||||
EXPECT_NE(nullptr, const_cast<const EmptyLifecycleNode *>(test_node.get())->get_clock());
|
||||
}
|
||||
|
||||
TEST_F(TestDefaultStateMachine, test_graph) {
|
||||
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
|
||||
auto names = test_node->get_node_names();
|
||||
EXPECT_EQ(names.size(), 1u);
|
||||
EXPECT_STREQ(names[0].c_str(), "/testnode");
|
||||
|
||||
// parameter_events, rosout, /testnode/transition_event
|
||||
auto topic_names_and_types = test_node->get_topic_names_and_types();
|
||||
EXPECT_EQ(topic_names_and_types.size(), 3u);
|
||||
EXPECT_STREQ(
|
||||
topic_names_and_types["/testnode/transition_event"][0].c_str(),
|
||||
"lifecycle_msgs/msg/TransitionEvent");
|
||||
|
||||
auto service_names_and_types = test_node->get_service_names_and_types();
|
||||
EXPECT_EQ(service_names_and_types.size(), 11u);
|
||||
// These are specific to lifecycle nodes, other services are provided by rclcpp::Node
|
||||
EXPECT_STREQ(
|
||||
service_names_and_types["/testnode/change_state"][0].c_str(),
|
||||
"lifecycle_msgs/srv/ChangeState");
|
||||
EXPECT_STREQ(
|
||||
service_names_and_types["/testnode/get_available_states"][0].c_str(),
|
||||
"lifecycle_msgs/srv/GetAvailableStates");
|
||||
EXPECT_STREQ(
|
||||
service_names_and_types["/testnode/get_available_transitions"][0].c_str(),
|
||||
"lifecycle_msgs/srv/GetAvailableTransitions");
|
||||
EXPECT_STREQ(
|
||||
service_names_and_types["/testnode/get_state"][0].c_str(),
|
||||
"lifecycle_msgs/srv/GetState");
|
||||
EXPECT_STREQ(
|
||||
service_names_and_types["/testnode/get_transition_graph"][0].c_str(),
|
||||
"lifecycle_msgs/srv/GetAvailableTransitions");
|
||||
|
||||
EXPECT_EQ(1u, test_node->count_publishers("/testnode/transition_event"));
|
||||
EXPECT_EQ(0u, test_node->count_subscribers("/testnode/transition_event"));
|
||||
|
||||
auto publishers_info = test_node->get_publishers_info_by_topic("/testnode/transition_event");
|
||||
EXPECT_EQ(publishers_info.size(), 1u);
|
||||
auto subscriptions_info =
|
||||
test_node->get_subscriptions_info_by_topic("/testnode/transition_event");
|
||||
EXPECT_EQ(subscriptions_info.size(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(TestDefaultStateMachine, test_callback_groups) {
|
||||
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
|
||||
auto groups = test_node->get_callback_groups();
|
||||
EXPECT_EQ(groups.size(), 1u);
|
||||
|
||||
auto group = test_node->create_callback_group(
|
||||
rclcpp::CallbackGroupType::MutuallyExclusive);
|
||||
EXPECT_NE(nullptr, group);
|
||||
|
||||
groups = test_node->get_callback_groups();
|
||||
EXPECT_EQ(groups.size(), 2u);
|
||||
EXPECT_EQ(groups[1].lock().get(), group.get());
|
||||
}
|
||||
|
||||
346
rclcpp_lifecycle/test/test_lifecycle_service_client.cpp
Normal file
346
rclcpp_lifecycle/test/test_lifecycle_service_client.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
// Copyright 2020 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* Service client test was adopted from:
|
||||
* https://github.com/ros2/demos/blob/master/lifecycle/src/lifecycle_service_client.cpp
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "lifecycle_msgs/msg/state.hpp"
|
||||
#include "lifecycle_msgs/msg/transition.hpp"
|
||||
#include "lifecycle_msgs/msg/transition_description.hpp"
|
||||
#include "lifecycle_msgs/srv/change_state.hpp"
|
||||
#include "lifecycle_msgs/srv/get_available_states.hpp"
|
||||
#include "lifecycle_msgs/srv/get_available_transitions.hpp"
|
||||
#include "lifecycle_msgs/srv/get_state.hpp"
|
||||
|
||||
#include "rclcpp/rclcpp.hpp"
|
||||
#include "rclcpp_lifecycle/lifecycle_node.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
constexpr char const * lifecycle_node_name = "lc_talker";
|
||||
|
||||
constexpr char const * node_get_state_topic = "/lc_talker/get_state";
|
||||
constexpr char const * node_change_state_topic = "/lc_talker/change_state";
|
||||
constexpr char const * node_get_available_states_topic = "/lc_talker/get_available_states";
|
||||
constexpr char const * node_get_available_transitions_topic =
|
||||
"/lc_talker/get_available_transitions";
|
||||
constexpr char const * node_get_transition_graph_topic =
|
||||
"/lc_talker/get_transition_graph";
|
||||
const lifecycle_msgs::msg::State unknown_state = lifecycle_msgs::msg::State();
|
||||
|
||||
class EmptyLifecycleNode : public rclcpp_lifecycle::LifecycleNode
|
||||
{
|
||||
public:
|
||||
EmptyLifecycleNode()
|
||||
: rclcpp_lifecycle::LifecycleNode(lifecycle_node_name)
|
||||
{}
|
||||
};
|
||||
|
||||
class LifecycleServiceClient : public rclcpp::Node
|
||||
{
|
||||
public:
|
||||
explicit LifecycleServiceClient(std::string node_name)
|
||||
: Node(node_name)
|
||||
{
|
||||
client_get_available_states_ = this->create_client<lifecycle_msgs::srv::GetAvailableStates>(
|
||||
node_get_available_states_topic);
|
||||
client_get_available_transitions_ =
|
||||
this->create_client<lifecycle_msgs::srv::GetAvailableTransitions>(
|
||||
node_get_available_transitions_topic);
|
||||
client_get_transition_graph_ =
|
||||
this->create_client<lifecycle_msgs::srv::GetAvailableTransitions>(
|
||||
node_get_transition_graph_topic);
|
||||
client_get_state_ = this->create_client<lifecycle_msgs::srv::GetState>(
|
||||
node_get_state_topic);
|
||||
client_change_state_ = this->create_client<lifecycle_msgs::srv::ChangeState>(
|
||||
node_change_state_topic);
|
||||
}
|
||||
|
||||
lifecycle_msgs::msg::State
|
||||
get_state(std::chrono::seconds time_out = 1s)
|
||||
{
|
||||
auto request = std::make_shared<lifecycle_msgs::srv::GetState::Request>();
|
||||
|
||||
if (!client_get_state_->wait_for_service(time_out)) {
|
||||
return unknown_state;
|
||||
}
|
||||
|
||||
auto future_result = client_get_state_->async_send_request(request);
|
||||
auto future_status = future_result.wait_for(time_out);
|
||||
|
||||
if (future_status != std::future_status::ready) {
|
||||
return unknown_state;
|
||||
}
|
||||
|
||||
if (future_result.get()) {
|
||||
return future_result.get()->current_state;
|
||||
} else {
|
||||
return unknown_state;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
change_state(std::uint8_t transition, std::chrono::seconds time_out = 1s)
|
||||
{
|
||||
auto request = std::make_shared<lifecycle_msgs::srv::ChangeState::Request>();
|
||||
request->transition.id = transition;
|
||||
|
||||
if (!client_change_state_->wait_for_service(time_out)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto future_result = client_change_state_->async_send_request(request);
|
||||
auto future_status = future_result.wait_for(time_out);
|
||||
|
||||
if (future_status != std::future_status::ready) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return future_result.get()->success;
|
||||
}
|
||||
|
||||
std::vector<lifecycle_msgs::msg::State>
|
||||
get_available_states(std::chrono::seconds time_out = 1s)
|
||||
{
|
||||
auto request = std::make_shared<lifecycle_msgs::srv::GetAvailableStates::Request>();
|
||||
|
||||
if (!client_get_available_states_->wait_for_service(time_out)) {
|
||||
return std::vector<lifecycle_msgs::msg::State>();
|
||||
}
|
||||
|
||||
auto future_result = client_get_available_states_->async_send_request(request);
|
||||
auto future_status = future_result.wait_for(time_out);
|
||||
|
||||
if (future_status != std::future_status::ready) {
|
||||
return std::vector<lifecycle_msgs::msg::State>();
|
||||
}
|
||||
|
||||
if (future_result.get()) {
|
||||
return future_result.get()->available_states;
|
||||
}
|
||||
|
||||
return std::vector<lifecycle_msgs::msg::State>();
|
||||
}
|
||||
|
||||
std::vector<lifecycle_msgs::msg::TransitionDescription>
|
||||
get_available_transitions(std::chrono::seconds time_out = 1s)
|
||||
{
|
||||
auto request = std::make_shared<lifecycle_msgs::srv::GetAvailableTransitions::Request>();
|
||||
|
||||
if (!client_get_available_transitions_->wait_for_service(time_out)) {
|
||||
return std::vector<lifecycle_msgs::msg::TransitionDescription>();
|
||||
}
|
||||
|
||||
auto future_result = client_get_available_transitions_->async_send_request(request);
|
||||
auto future_status = future_result.wait_for(time_out);
|
||||
|
||||
if (future_status != std::future_status::ready) {
|
||||
return std::vector<lifecycle_msgs::msg::TransitionDescription>();
|
||||
}
|
||||
|
||||
if (future_result.get()) {
|
||||
return future_result.get()->available_transitions;
|
||||
}
|
||||
|
||||
return std::vector<lifecycle_msgs::msg::TransitionDescription>();
|
||||
}
|
||||
|
||||
std::vector<lifecycle_msgs::msg::TransitionDescription>
|
||||
get_transition_graph(std::chrono::seconds time_out = 1s)
|
||||
{
|
||||
auto request = std::make_shared<lifecycle_msgs::srv::GetAvailableTransitions::Request>();
|
||||
|
||||
if (!client_get_transition_graph_->wait_for_service(time_out)) {
|
||||
return std::vector<lifecycle_msgs::msg::TransitionDescription>();
|
||||
}
|
||||
|
||||
auto future_result = client_get_transition_graph_->async_send_request(request);
|
||||
auto future_status = future_result.wait_for(time_out);
|
||||
|
||||
if (future_status != std::future_status::ready) {
|
||||
return std::vector<lifecycle_msgs::msg::TransitionDescription>();
|
||||
}
|
||||
|
||||
if (future_result.get()) {
|
||||
return future_result.get()->available_transitions;
|
||||
}
|
||||
|
||||
return std::vector<lifecycle_msgs::msg::TransitionDescription>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<rclcpp::Client<lifecycle_msgs::srv::GetAvailableStates>>
|
||||
client_get_available_states_;
|
||||
std::shared_ptr<rclcpp::Client<lifecycle_msgs::srv::GetAvailableTransitions>>
|
||||
client_get_available_transitions_;
|
||||
std::shared_ptr<rclcpp::Client<lifecycle_msgs::srv::GetAvailableTransitions>>
|
||||
client_get_transition_graph_;
|
||||
std::shared_ptr<rclcpp::Client<lifecycle_msgs::srv::GetState>> client_get_state_;
|
||||
std::shared_ptr<rclcpp::Client<lifecycle_msgs::srv::ChangeState>> client_change_state_;
|
||||
};
|
||||
|
||||
|
||||
class TestLifecycleServiceClient : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
EmptyLifecycleNode * lifecycle_node() {return lifecycle_node_.get();}
|
||||
LifecycleServiceClient * lifecycle_client() {return lifecycle_client_.get();}
|
||||
|
||||
private:
|
||||
void SetUp() override
|
||||
{
|
||||
rclcpp::init(0, nullptr);
|
||||
lifecycle_node_ = std::make_shared<EmptyLifecycleNode>();
|
||||
lifecycle_client_ = std::make_shared<LifecycleServiceClient>("client");
|
||||
spinner_ = std::thread(&TestLifecycleServiceClient::spin, this);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
rclcpp::shutdown();
|
||||
spinner_.join();
|
||||
}
|
||||
|
||||
void spin()
|
||||
{
|
||||
while (rclcpp::ok()) {
|
||||
rclcpp::spin_some(lifecycle_node_->get_node_base_interface());
|
||||
rclcpp::spin_some(lifecycle_client_);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<EmptyLifecycleNode> lifecycle_node_;
|
||||
std::shared_ptr<LifecycleServiceClient> lifecycle_client_;
|
||||
std::thread spinner_;
|
||||
};
|
||||
|
||||
|
||||
TEST_F(TestLifecycleServiceClient, construct_destruct) {
|
||||
EXPECT_NE(nullptr, lifecycle_client());
|
||||
EXPECT_NE(nullptr, lifecycle_node());
|
||||
}
|
||||
|
||||
TEST_F(TestLifecycleServiceClient, available_states) {
|
||||
auto states = lifecycle_client()->get_available_states();
|
||||
EXPECT_EQ(states.size(), 11u);
|
||||
EXPECT_EQ(states[0].id, lifecycle_msgs::msg::State::PRIMARY_STATE_UNKNOWN);
|
||||
EXPECT_EQ(states[1].id, lifecycle_msgs::msg::State::PRIMARY_STATE_UNCONFIGURED);
|
||||
EXPECT_EQ(states[2].id, lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE);
|
||||
EXPECT_EQ(states[3].id, lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE);
|
||||
EXPECT_EQ(states[4].id, lifecycle_msgs::msg::State::PRIMARY_STATE_FINALIZED);
|
||||
EXPECT_EQ(states[5].id, lifecycle_msgs::msg::State::TRANSITION_STATE_CONFIGURING);
|
||||
EXPECT_EQ(states[6].id, lifecycle_msgs::msg::State::TRANSITION_STATE_CLEANINGUP);
|
||||
EXPECT_EQ(states[7].id, lifecycle_msgs::msg::State::TRANSITION_STATE_SHUTTINGDOWN);
|
||||
EXPECT_EQ(states[8].id, lifecycle_msgs::msg::State::TRANSITION_STATE_ACTIVATING);
|
||||
EXPECT_EQ(states[9].id, lifecycle_msgs::msg::State::TRANSITION_STATE_DEACTIVATING);
|
||||
EXPECT_EQ(states[10].id, lifecycle_msgs::msg::State::TRANSITION_STATE_ERRORPROCESSING);
|
||||
}
|
||||
|
||||
TEST_F(TestLifecycleServiceClient, transition_graph) {
|
||||
auto transitions = lifecycle_client()->get_transition_graph();
|
||||
EXPECT_EQ(transitions.size(), 25u);
|
||||
}
|
||||
|
||||
TEST_F(TestLifecycleServiceClient, available_transitions) {
|
||||
auto transitions = lifecycle_client()->get_available_transitions();
|
||||
EXPECT_EQ(transitions.size(), 2u);
|
||||
EXPECT_EQ(transitions[0].transition.id, lifecycle_msgs::msg::Transition::TRANSITION_CONFIGURE);
|
||||
EXPECT_EQ(
|
||||
transitions[1].transition.id,
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_UNCONFIGURED_SHUTDOWN);
|
||||
}
|
||||
|
||||
TEST_F(TestLifecycleServiceClient, lifecycle_transitions) {
|
||||
EXPECT_EQ(
|
||||
lifecycle_client()->get_state().id, lifecycle_msgs::msg::State::PRIMARY_STATE_UNCONFIGURED);
|
||||
|
||||
auto transitions = lifecycle_client()->get_available_transitions();
|
||||
EXPECT_EQ(transitions.size(), 2u);
|
||||
EXPECT_EQ(transitions[0].transition.id, lifecycle_msgs::msg::Transition::TRANSITION_CONFIGURE);
|
||||
EXPECT_EQ(
|
||||
transitions[1].transition.id,
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_UNCONFIGURED_SHUTDOWN);
|
||||
|
||||
EXPECT_TRUE(
|
||||
lifecycle_client()->change_state(
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_CONFIGURE));
|
||||
EXPECT_EQ(
|
||||
lifecycle_client()->get_state().id,
|
||||
lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE);
|
||||
transitions = lifecycle_client()->get_available_transitions();
|
||||
EXPECT_EQ(transitions.size(), 3u);
|
||||
EXPECT_EQ(transitions[0].transition.id, lifecycle_msgs::msg::Transition::TRANSITION_CLEANUP);
|
||||
EXPECT_EQ(transitions[1].transition.id, lifecycle_msgs::msg::Transition::TRANSITION_ACTIVATE);
|
||||
EXPECT_EQ(
|
||||
transitions[2].transition.id,
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_INACTIVE_SHUTDOWN);
|
||||
|
||||
EXPECT_TRUE(
|
||||
lifecycle_client()->change_state(
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_ACTIVATE));
|
||||
EXPECT_EQ(lifecycle_client()->get_state().id, lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE);
|
||||
transitions = lifecycle_client()->get_available_transitions();
|
||||
EXPECT_EQ(transitions.size(), 2u);
|
||||
EXPECT_EQ(transitions[0].transition.id, lifecycle_msgs::msg::Transition::TRANSITION_DEACTIVATE);
|
||||
EXPECT_EQ(
|
||||
transitions[1].transition.id,
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_ACTIVE_SHUTDOWN);
|
||||
|
||||
EXPECT_TRUE(
|
||||
lifecycle_client()->change_state(
|
||||
lifecycle_msgs::msg::Transition::
|
||||
TRANSITION_DEACTIVATE));
|
||||
EXPECT_EQ(
|
||||
lifecycle_client()->get_state().id,
|
||||
lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE);
|
||||
transitions = lifecycle_client()->get_available_transitions();
|
||||
EXPECT_EQ(transitions.size(), 3u);
|
||||
EXPECT_EQ(transitions[0].transition.id, lifecycle_msgs::msg::Transition::TRANSITION_CLEANUP);
|
||||
EXPECT_EQ(transitions[1].transition.id, lifecycle_msgs::msg::Transition::TRANSITION_ACTIVATE);
|
||||
EXPECT_EQ(
|
||||
transitions[2].transition.id,
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_INACTIVE_SHUTDOWN);
|
||||
|
||||
EXPECT_TRUE(
|
||||
lifecycle_client()->change_state(
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_CLEANUP));
|
||||
EXPECT_EQ(
|
||||
lifecycle_client()->get_state().id, lifecycle_msgs::msg::State::PRIMARY_STATE_UNCONFIGURED);
|
||||
transitions = lifecycle_client()->get_available_transitions();
|
||||
EXPECT_EQ(transitions.size(), 2u);
|
||||
EXPECT_EQ(transitions[0].transition.id, lifecycle_msgs::msg::Transition::TRANSITION_CONFIGURE);
|
||||
EXPECT_EQ(
|
||||
transitions[1].transition.id,
|
||||
lifecycle_msgs::msg::Transition::TRANSITION_UNCONFIGURED_SHUTDOWN);
|
||||
|
||||
EXPECT_TRUE(
|
||||
lifecycle_client()->change_state(
|
||||
lifecycle_msgs::msg::Transition::
|
||||
TRANSITION_UNCONFIGURED_SHUTDOWN));
|
||||
EXPECT_EQ(
|
||||
lifecycle_client()->get_state().id,
|
||||
lifecycle_msgs::msg::State::PRIMARY_STATE_FINALIZED);
|
||||
transitions = lifecycle_client()->get_available_transitions();
|
||||
EXPECT_EQ(transitions.size(), 0u);
|
||||
}
|
||||
@@ -28,6 +28,17 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class StateDerived : public rclcpp_lifecycle::State
|
||||
{
|
||||
public:
|
||||
StateDerived(uint8_t id, const std::string & label)
|
||||
: State(id, label) {}
|
||||
void expose_reset()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestStateWrapper, wrapper) {
|
||||
{
|
||||
rclcpp_lifecycle::State state(1, "my_state");
|
||||
@@ -95,6 +106,10 @@ TEST_F(TestStateWrapper, copy_constructor) {
|
||||
|
||||
TEST_F(TestStateWrapper, assignment_operator) {
|
||||
auto a = std::make_shared<rclcpp_lifecycle::State>(1, "one");
|
||||
*a = *a;
|
||||
EXPECT_EQ(1, a->id());
|
||||
EXPECT_STREQ("one", a->label().c_str());
|
||||
|
||||
auto b = std::make_shared<rclcpp_lifecycle::State>(2, "two");
|
||||
*b = *a;
|
||||
|
||||
@@ -166,3 +181,16 @@ TEST_F(TestStateWrapper, assignment_operator4) {
|
||||
|
||||
delete lc_state1;
|
||||
}
|
||||
|
||||
TEST_F(TestStateWrapper, exceptions) {
|
||||
EXPECT_THROW((void)rclcpp_lifecycle::State(0, ""), std::runtime_error);
|
||||
|
||||
const rcl_lifecycle_state_t * null_handle = nullptr;
|
||||
EXPECT_THROW((void)rclcpp_lifecycle::State(null_handle), std::runtime_error);
|
||||
|
||||
auto reset_state = std::make_shared<StateDerived>(1, "one");
|
||||
reset_state->expose_reset();
|
||||
|
||||
EXPECT_THROW(reset_state->id(), std::runtime_error);
|
||||
EXPECT_THROW(reset_state->label(), std::runtime_error);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,19 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class TransitionDerived : public rclcpp_lifecycle::Transition
|
||||
{
|
||||
public:
|
||||
TransitionDerived(
|
||||
uint8_t id, const std::string & label,
|
||||
rclcpp_lifecycle::State && start, rclcpp_lifecycle::State && goal)
|
||||
: Transition(id, label, std::move(start), std::move(goal)) {}
|
||||
void expose_reset()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestTransitionWrapper, empty_transition) {
|
||||
auto a = std::make_shared<rclcpp_lifecycle::Transition>(1, "my_transition");
|
||||
EXPECT_NO_THROW(a.reset());
|
||||
@@ -75,7 +88,15 @@ TEST_F(TestTransitionWrapper, copy_constructor) {
|
||||
}
|
||||
|
||||
TEST_F(TestTransitionWrapper, assignment_operator) {
|
||||
auto a = std::make_shared<rclcpp_lifecycle::Transition>(1, "one");
|
||||
rclcpp_lifecycle::State start_state(1, "start_state");
|
||||
rclcpp_lifecycle::State goal_state(2, "goal_state");
|
||||
auto a = std::make_shared<rclcpp_lifecycle::Transition>(
|
||||
1, "one", std::move(start_state),
|
||||
std::move(goal_state));
|
||||
*a = *a;
|
||||
EXPECT_EQ(1, a->id());
|
||||
EXPECT_STREQ("one", a->label().c_str());
|
||||
|
||||
auto b = std::make_shared<rclcpp_lifecycle::Transition>(2, "two");
|
||||
*b = *a;
|
||||
|
||||
@@ -83,4 +104,25 @@ TEST_F(TestTransitionWrapper, assignment_operator) {
|
||||
|
||||
EXPECT_EQ(1, b->id());
|
||||
EXPECT_STREQ("one", b->label().c_str());
|
||||
EXPECT_STREQ("start_state", b->start_state().label().c_str());
|
||||
EXPECT_STREQ("goal_state", b->goal_state().label().c_str());
|
||||
EXPECT_EQ(1, b->start_state().id());
|
||||
EXPECT_EQ(2, b->goal_state().id());
|
||||
}
|
||||
|
||||
TEST_F(TestTransitionWrapper, exceptions) {
|
||||
rcl_lifecycle_transition_t * null_handle = nullptr;
|
||||
EXPECT_THROW((void)rclcpp_lifecycle::Transition(null_handle), std::runtime_error);
|
||||
|
||||
rclcpp_lifecycle::State start_state(1, "start_state");
|
||||
rclcpp_lifecycle::State goal_state(2, "goal_state");
|
||||
auto a = std::make_shared<TransitionDerived>(
|
||||
1, "one", std::move(start_state),
|
||||
std::move(goal_state));
|
||||
|
||||
a->expose_reset();
|
||||
EXPECT_THROW(a->start_state(), std::runtime_error);
|
||||
EXPECT_THROW(a->goal_state(), std::runtime_error);
|
||||
EXPECT_THROW(a->id(), std::runtime_error);
|
||||
EXPECT_THROW(a->label(), std::runtime_error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user