-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Bug report
Please use this template to report bugs.
Steps to reproduce
- Run any demo/system with a node in root namespace (e.g., namespace="") that publishes topics under its node name (e.g., /fault_manager/events)
- Use gateway in runtime_only mode with create_synthetic_components: true and topic_only_policy: create_component
- Check /api/v1/components endpoint
The node should appear only once - as part of the synthetic "root" component (or as a single component if grouping is disabled).
Actual behavior
The node appears twice:
- As an app inside synthetic component "root" (correct)
- As a separate topic-based component with ID matching the node name (e.g., "fault_manager")
Root cause: In runtime_discovery.cpp, get_node_namespaces() (line 478) excludes "root" area from the namespace set:
if (area != "root") {
namespaces.insert(area);
}
This means node names in root namespace (like "fault_manager") are not added to node_namespaces. When discover_topic_components() processes topic /fault_manager/events, it extracts namespace "fault_manager" and checks if it's in node_namespaces. Since it's not there (only areas like "sensors", "processing" are), a duplicate topic-based component is created.
Trace:
get_node_namespaces() returns: {"sensors", "processing", "bridge", "diagnostics"}
(missing: "fault_manager" because area="root" is skipped)
discover_topic_components() for topic /fault_manager/events:
→ ns = "fault_manager"
→ node_namespaces.count("fault_manager") = 0 ← NOT FOUND
→ Creates topic-based component "fault_manager" ← DUPLICATE!
Environment
- ros2_medkit version: main branch
- ROS 2 distro:
- OS:
Additional information
Affected file: src/ros2_medkit_gateway/src/discovery/runtime_discovery.cpp
Proposed fix: In get_node_namespaces(), also add node names for nodes in root namespace:
std::set<std::string> RuntimeDiscoveryStrategy::get_node_namespaces() {
std::set<std::string> namespaces;
auto node_graph = node_->get_node_graph_interface();
auto names_and_namespaces = node_graph->get_node_names_and_namespaces();
for (const auto & name_and_ns : names_and_namespaces) {
std::string ns = name_and_ns.second;
std::string name = name_and_ns.first;
std::string area = extract_area_from_namespace(ns);
if (area != "root") {
namespaces.insert(area);
} else {
// For root namespace nodes, add node name to prevent
// topic-based component collision with /node_name/* topics
namespaces.insert(name);
}
}
return namespaces;
}
Discovered in: sensor_diagnostics demo where fault_manager runs in root namespace.