Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |
Dependant Packages
Launch files
Messages
Services
Plugins
Recent questions tagged autoware_component_interface_utils at Robotics Stack Exchange
Package Summary
| Version | 1.10.0 |
| License | Apache License 2.0 |
| Build type | AMENT_CMAKE |
| Use | RECOMMENDED |
Repository Summary
| Checkout URI | https://github.com/autowarefoundation/autoware_core.git |
| VCS Type | git |
| VCS Version | main |
| Last Updated | 2026-09-28 |
| Dev Status | DEVELOPED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Package Description
Maintainers
- Yutaka Kondo
- Takagi, Isamu
- Yukihiro Saito
Authors
autoware_component_interface_utils
Features
This is a utility package that provides the following features:
- Instantiation of the wrapper class
- Registration of every interface a node creates into a queryable manifest
- Serialization of that manifest to the admission manifest document schema
- Opt-in service introspection for service and client
- Service exception for response
- Relays for topic and service
- A test helper for pinning a package’s committed manifest fragment against what a node actually registers
Design
This package provides the wrappers for the interface classes of rclcpp. The wrappers limit the usage of the original class to enforce the processing recommended by the component interface. Do not inherit the class of rclcpp, and forward or wrap the member function that is allowed to be used.
Instantiation of the wrapper class
The wrapper class requires interface information in this format.
struct SampleService
{
using Service = sample_msgs::srv::ServiceType;
static constexpr char name[] = "/sample/service";
};
struct SampleMessage
{
using Message = sample_msgs::msg::MessageType;
static constexpr char name[] = "/sample/message";
static constexpr size_t depth = 1;
static constexpr auto reliability = RMW_QOS_POLICY_RELIABILITY_RELIABLE;
static constexpr auto durability = RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL;
};
Create the wrapper by asking the adaptor for it directly, giving the specification as an explicit template argument.
This is the current style: these are non-const member functions, so the adaptor must not be declared const when they are used.
// source file
auto node = autoware::component_interface_utils::NodeAdaptor(this);
srv_ = node.create_service<SampleService>(callback);
cli_ = node.create_client<SampleService>();
pub_ = node.create_publisher<SampleMessage>();
sub_ = node.create_subscription<SampleMessage>(callback);
The adaptor also provides deducing forms that take the output variable instead of an explicit template argument (init_srv, init_cli, init_pub, init_sub).
They create the same wrappers as the create_* methods above, but they are the legacy form; see Migrating from init_* for the create_* replacement of each overload.
// header file
autoware::component_interface_utils::Service<SampleService>::SharedPtr srv_;
autoware::component_interface_utils::Client<SampleService>::SharedPtr cli_;
autoware::component_interface_utils::Publisher<SampleMessage>::SharedPtr pub_;
autoware::component_interface_utils::Subscription<SampleMessage>::SharedPtr sub_;
// source file
const auto node = autoware::component_interface_utils::NodeAdaptor(this);
node.init_srv(srv_, callback); // legacy form, prefer create_service<SampleService>(callback)
node.init_cli(cli_); // legacy form, prefer create_client<SampleService>()
node.init_pub(pub_); // legacy form, prefer create_publisher<SampleMessage>()
node.init_sub(sub_, callback); // legacy form, prefer create_subscription<SampleMessage>(callback)
Migrating from init_*
Every init_* overload is the legacy form and has a create_* replacement that returns the wrapper instead of writing it into an output parameter.
Both styles register the interface identically, so migrating a call site is a mechanical rewrite with no behavior change.
| Legacy overload | Replacement |
|---|---|
init_pub(pub) |
pub = create_publisher<Spec>() |
init_sub(sub, callback) |
sub = create_subscription<Spec>(callback) |
init_sub(sub, instance, &Instance::pointer_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::pointer_callback, instance, _1)) |
init_sub(sub, instance, &Instance::reference_callback) |
sub = create_subscription<Spec>(std::bind(&Instance::reference_callback, instance, _1)) |
init_cli(cli, group) |
cli = create_client<Spec>(group) |
init_srv(srv, callback, group) |
srv = create_service<Spec>(callback, group) |
init_srv(srv, instance, &Instance::service_callback, group) |
srv = create_service<Spec>(std::bind(&Instance::service_callback, instance, _1, _2), group) |
The init_* overloads are not removed, so existing call sites keep compiling as-is; create_* is preferred for new code, and existing call sites are expected to migrate over time.
Opt-in service introspection for service and client
This package does not trace service calls by itself.
What it provides is a single node-scoped switch that turns on the standard ROS 2 service introspection for every wrapper of that node, so the wrappers do not have to be configured one by one.
Each node that creates wrappers through NodeAdaptor declares the following parameter, and its value is applied to all the Service and Client wrappers that the adaptor creates.
| Name | Type | Default | Description |
|---|---|---|---|
component_interface.service_introspection |
string |
off |
Introspection mode of the service wrappers. One of off, metadata, contents. |
Introspection is disabled by default, so nothing is recorded unless the parameter is set.
When the mode is not off, each wrapper exposes the service event topic <service name>/_service_event, which is /sample/service/_service_event for the specification above.
File truncated at 100 lines see the full file
Changelog for package autoware_component_interface_utils
1.10.0 (2026-09-28)
-
chore: align package versions to 1.9.0 and reset changelogs
-
Merge remote-tracking branch 'origin/main' into tmp/bot/bump_version_base
-
feat(component_interface_utils): let non-rclcpp node types supply the polling and response types (#1362)
-
feat(autoware_component_interface_utils): impl-layer interface registration and node manifest serialization (#1332)
- feat(autoware_component_interface_utils): add the interface record registry
* test(autoware_component_interface_utils): strengthen registration test assertions Close four test-strength gaps found in review of the interface record registry commit, without touching any production code:
- Assert minor/patch alongside major so the version-copy check in make_record is no longer vacuous against two specs both at 0.x.y.
- Assert make_record's forwarded/derived fields (interface_name, resolved_name, type_name, kind, role, reliability, durability, depth), previously verified only through has_version.
- Register two records with distinct names in registry_accumulates_and_returns_records and assert both the count and the registration order, since the prior version registered only one record despite the test's name.
- Add a static_assert that HasDomainVersion is false for map::PointCloudMap, whose domain declares both the DEFINE_DOMAIN template overload and a deleted non-template overload, exercising the non-template-beats-template tiebreak that the existing single-deleted-candidate case does not cover.
* test(autoware_component_interface_utils): remove vacuous make_record assertions The prior round's added assertions on the version/kind/role/interface_name fields happened to equal InterfaceRecord's own default initializers, so an omission bug in make_record could still pass:
- major/patch on the KinematicState-derived record were both 0, matching the domain's 0.1.0 version and the struct's {0, 0, 0} defaults.
- kind/role were asserted against Kind::Topic/Role::Provide, which are exactly the defaults.
- interface_name and resolved_name were asserted from the same caller-supplied name, so a bug that copied one field into the other would go unnoticed. Add a local spec (test_specs::Versioned) with a non-deleted domain version of {2, 3, 4}, and exercise make_record with Kind::Service, Role::Require, and a resolved_name that differs from the spec name (simulating a remap). None of the resulting assertions can coincide with a default initializer or with each other. Verified by temporarily deleting/aliasing each corresponding line in make_record and confirming the matching assertion fails.
* feat(autoware_component_interface_utils): register every interface at the create/init layer Wire InterfaceRecord registration into every publisher, subscription, service server, and service client creation path so a node's manifest is complete by the end of construction, with no bypass:
- create_publisher_impl and create_subscription_impl now take NodeInterface::SharedPtr (instead of a raw node pointer) and register a record built from the actually-applied topic name and QoS after the rclcpp object is created. The subscription impl holds the created subscription in a local variable across the callback vs. polling branches so registration happens exactly once regardless of which form was used.
- Client and Service constructors register a record after the client/service handle is created, in both the Iron+ and pre-Iron #if branches, using the actual resolved service name and the shared services QoS profile.
- rclcpp.hpp passes the NodeInterface down to the topic impls instead of the bare node pointer, and its four create_* doc comments are reworded to describe current behavior instead of stale phasing language. Adds two tests to test_registration.cpp: one confirming a remapped publisher registers with the resolved (not spec-declared) name, and one exercising every entry path (polling subscription, service server, service client, and the legacy init_pub) to confirm each leaves exactly one record.
* test(autoware_component_interface_utils): pin the callback subscription branch and de-vacuous the manifest assertions Fix round 1 on the Task 6 registration tests, per review:
- every_entry_path_registers previously only exercised the polling (nullptr callback) branch of create_subscription_impl's [if
File truncated at 100 lines see the full file
Package Dependencies
System Dependencies
| Name |
|---|
| nlohmann-json-dev |