Skip to content

Commit 34e1240

Browse files
committed
fix: address review feedback on beacon mode PR
- Split beacon_helper.hpp into .hpp/.cpp with static library - Use std::map for stable metadata key ordering - Use int64_t for process_id parameter to avoid truncation - Make entity_id a node parameter with default (reduces manifest coupling) - Move import sys to top-level in launch file - Increase beacon TTL from 10s to 15s (3x publish interval) - Hardcode BEACON_MODE=none in CI service for deterministic tests
1 parent 1932eef commit 34e1240

9 files changed

Lines changed: 133 additions & 104 deletions

File tree

demos/sensor_diagnostics/CMakeLists.txt

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,53 @@ find_package(diagnostic_msgs REQUIRED)
1515
find_package(rcl_interfaces REQUIRED)
1616
find_package(ros2_medkit_msgs REQUIRED)
1717

18+
# Beacon helper library (shared across sensor nodes)
19+
add_library(beacon_helper STATIC src/beacon_helper.cpp)
20+
ament_target_dependencies(beacon_helper PUBLIC
21+
rclcpp
22+
diagnostic_msgs
23+
ros2_medkit_msgs
24+
)
25+
target_include_directories(beacon_helper PUBLIC
26+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
27+
)
28+
1829
# LiDAR simulator node
1930
add_executable(lidar_sim_node src/lidar_sim_node.cpp)
31+
target_link_libraries(lidar_sim_node beacon_helper)
2032
ament_target_dependencies(lidar_sim_node
2133
rclcpp
2234
sensor_msgs
2335
diagnostic_msgs
2436
rcl_interfaces
25-
ros2_medkit_msgs
2637
)
2738

2839
# IMU simulator node
2940
add_executable(imu_sim_node src/imu_sim_node.cpp)
41+
target_link_libraries(imu_sim_node beacon_helper)
3042
ament_target_dependencies(imu_sim_node
3143
rclcpp
3244
sensor_msgs
3345
diagnostic_msgs
34-
ros2_medkit_msgs
3546
)
3647

3748
# GPS simulator node
3849
add_executable(gps_sim_node src/gps_sim_node.cpp)
50+
target_link_libraries(gps_sim_node beacon_helper)
3951
ament_target_dependencies(gps_sim_node
4052
rclcpp
4153
sensor_msgs
4254
diagnostic_msgs
43-
ros2_medkit_msgs
4455
)
4556

4657
# Camera simulator node
4758
add_executable(camera_sim_node src/camera_sim_node.cpp)
59+
target_link_libraries(camera_sim_node beacon_helper)
4860
ament_target_dependencies(camera_sim_node
4961
rclcpp
5062
sensor_msgs
5163
diagnostic_msgs
5264
rcl_interfaces
53-
ros2_medkit_msgs
5465
)
5566

5667
# Anomaly detector node

demos/sensor_diagnostics/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ services:
3838
container_name: sensor_diagnostics_demo_ci
3939
environment:
4040
- ROS_DOMAIN_ID=40
41-
- BEACON_MODE=${BEACON_MODE:-none}
41+
- BEACON_MODE=none
4242
ports:
4343
- "8080:8080"
4444
command: >

demos/sensor_diagnostics/launch/demo.launch.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"""
2525

2626
import os
27+
import sys
2728

2829
from ament_index_python.packages import get_package_prefix
2930
from ament_index_python.packages import get_package_share_directory
@@ -59,7 +60,6 @@ def generate_launch_description():
5960
beacon_mode = os.environ.get('BEACON_MODE', 'none').strip().lower()
6061
valid_beacon_modes = ('none', 'topic', 'param')
6162
if beacon_mode not in valid_beacon_modes:
62-
import sys
6363
print(
6464
f"WARNING: Invalid BEACON_MODE='{beacon_mode}'. "
6565
f"Valid values: {', '.join(valid_beacon_modes)}. "
@@ -93,9 +93,8 @@ def generate_launch_description():
9393
plugin_overrides['plugins.topic_beacon.path'] = topic_beacon_path
9494
plugin_overrides['plugins.topic_beacon.topic'] = \
9595
'/ros2_medkit/discovery'
96-
plugin_overrides['plugins.topic_beacon.beacon_ttl_sec'] = 10.0
96+
plugin_overrides['plugins.topic_beacon.beacon_ttl_sec'] = 15.0
9797
else:
98-
import sys
9998
print(
10099
"WARNING: BEACON_MODE=topic but topic_beacon plugin not "
101100
"found. Falling back to none.",
@@ -112,7 +111,6 @@ def generate_launch_description():
112111
plugin_overrides['plugins.parameter_beacon.poll_interval_sec'] = \
113112
5.0
114113
else:
115-
import sys
116114
print(
117115
"WARNING: BEACON_MODE=param but param_beacon plugin not "
118116
"found. Falling back to none.",
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2026 selfpatch
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#include "beacon_helper.hpp"
5+
6+
#include <unistd.h>
7+
8+
#include "diagnostic_msgs/msg/key_value.hpp"
9+
10+
namespace sensor_diagnostics
11+
{
12+
13+
BeaconHelper::BeaconHelper(rclcpp::Node * node, const Config & config)
14+
: node_(node), config_(config)
15+
{
16+
node_->declare_parameter("beacon_mode", "none");
17+
mode_ = node_->get_parameter("beacon_mode").as_string();
18+
19+
// Cache process info (constant during lifetime)
20+
pid_ = static_cast<uint32_t>(getpid());
21+
char hostname_buf[256];
22+
hostname_buf[sizeof(hostname_buf) - 1] = '\0';
23+
if (gethostname(hostname_buf, sizeof(hostname_buf) - 1) == 0) {
24+
hostname_ = hostname_buf;
25+
}
26+
27+
if (mode_ == "topic") {
28+
init_topic_beacon();
29+
} else if (mode_ == "param") {
30+
init_param_beacon();
31+
} else if (mode_ != "none") {
32+
RCLCPP_WARN(
33+
node_->get_logger(),
34+
"Unknown beacon_mode '%s', expected none/topic/param. Beacon disabled.",
35+
mode_.c_str());
36+
}
37+
}
38+
39+
void BeaconHelper::init_topic_beacon()
40+
{
41+
beacon_pub_ = node_->create_publisher<ros2_medkit_msgs::msg::MedkitDiscoveryHint>(
42+
"/ros2_medkit/discovery", 10);
43+
44+
beacon_timer_ = node_->create_wall_timer(
45+
std::chrono::seconds(5),
46+
[this]() { publish_beacon(); });
47+
48+
// First publish likely dropped due to DDS discovery delay, next arrives in 5s
49+
publish_beacon();
50+
51+
RCLCPP_INFO(
52+
node_->get_logger(), "Topic beacon enabled (entity: %s)",
53+
config_.entity_id.c_str());
54+
}
55+
56+
void BeaconHelper::init_param_beacon()
57+
{
58+
node_->declare_parameter("ros2_medkit.discovery.entity_id", config_.entity_id);
59+
node_->declare_parameter("ros2_medkit.discovery.display_name", config_.display_name);
60+
node_->declare_parameter("ros2_medkit.discovery.component_id", config_.component_id);
61+
node_->declare_parameter("ros2_medkit.discovery.function_ids", config_.function_ids);
62+
node_->declare_parameter(
63+
"ros2_medkit.discovery.process_id", static_cast<int64_t>(pid_));
64+
node_->declare_parameter("ros2_medkit.discovery.process_name", node_->get_name());
65+
66+
if (!hostname_.empty()) {
67+
node_->declare_parameter("ros2_medkit.discovery.hostname", hostname_);
68+
}
69+
70+
for (const auto & [key, value] : config_.metadata) {
71+
node_->declare_parameter("ros2_medkit.discovery.metadata." + key, value);
72+
}
73+
74+
RCLCPP_INFO(
75+
node_->get_logger(), "Parameter beacon enabled (entity: %s)",
76+
config_.entity_id.c_str());
77+
}
78+
79+
void BeaconHelper::publish_beacon()
80+
{
81+
auto msg = ros2_medkit_msgs::msg::MedkitDiscoveryHint();
82+
msg.entity_id = config_.entity_id;
83+
msg.display_name = config_.display_name;
84+
msg.component_id = config_.component_id;
85+
msg.function_ids = config_.function_ids;
86+
msg.process_id = pid_;
87+
msg.process_name = node_->get_name();
88+
msg.hostname = hostname_;
89+
msg.stamp = node_->now();
90+
91+
for (const auto & [key, value] : config_.metadata) {
92+
diagnostic_msgs::msg::KeyValue kv;
93+
kv.key = key;
94+
kv.value = value;
95+
msg.metadata.push_back(kv);
96+
}
97+
98+
beacon_pub_->publish(msg);
99+
}
100+
101+
} // namespace sensor_diagnostics

demos/sensor_diagnostics/src/beacon_helper.hpp

Lines changed: 6 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@
1111
#pragma once
1212

1313
#include <chrono>
14+
#include <map>
1415
#include <memory>
1516
#include <string>
16-
#include <unordered_map>
1717
#include <vector>
1818

19-
#include <unistd.h>
20-
21-
#include "diagnostic_msgs/msg/key_value.hpp"
2219
#include "rclcpp/rclcpp.hpp"
2320
#include "ros2_medkit_msgs/msg/medkit_discovery_hint.hpp"
2421

@@ -34,97 +31,15 @@ class BeaconHelper
3431
std::string display_name;
3532
std::string component_id;
3633
std::vector<std::string> function_ids;
37-
std::unordered_map<std::string, std::string> metadata;
34+
std::map<std::string, std::string> metadata;
3835
};
3936

40-
BeaconHelper(rclcpp::Node * node, const Config & config)
41-
: node_(node), config_(config)
42-
{
43-
node_->declare_parameter("beacon_mode", "none");
44-
mode_ = node_->get_parameter("beacon_mode").as_string();
45-
46-
// Cache process info (constant during lifetime)
47-
pid_ = static_cast<uint32_t>(getpid());
48-
char hostname_buf[256];
49-
hostname_buf[sizeof(hostname_buf) - 1] = '\0';
50-
if (gethostname(hostname_buf, sizeof(hostname_buf) - 1) == 0) {
51-
hostname_ = hostname_buf;
52-
}
53-
54-
if (mode_ == "topic") {
55-
init_topic_beacon();
56-
} else if (mode_ == "param") {
57-
init_param_beacon();
58-
} else if (mode_ != "none") {
59-
RCLCPP_WARN(
60-
node_->get_logger(),
61-
"Unknown beacon_mode '%s', expected none/topic/param. Beacon disabled.",
62-
mode_.c_str());
63-
}
64-
}
37+
BeaconHelper(rclcpp::Node * node, const Config & config);
6538

6639
private:
67-
void init_topic_beacon()
68-
{
69-
beacon_pub_ = node_->create_publisher<ros2_medkit_msgs::msg::MedkitDiscoveryHint>(
70-
"/ros2_medkit/discovery", 10);
71-
72-
beacon_timer_ = node_->create_wall_timer(
73-
std::chrono::seconds(5),
74-
[this]() { publish_beacon(); });
75-
76-
// Publish immediately on startup
77-
publish_beacon();
78-
79-
RCLCPP_INFO(
80-
node_->get_logger(), "Topic beacon enabled (entity: %s)",
81-
config_.entity_id.c_str());
82-
}
83-
84-
void init_param_beacon()
85-
{
86-
node_->declare_parameter("ros2_medkit.discovery.entity_id", config_.entity_id);
87-
node_->declare_parameter("ros2_medkit.discovery.display_name", config_.display_name);
88-
node_->declare_parameter("ros2_medkit.discovery.component_id", config_.component_id);
89-
node_->declare_parameter("ros2_medkit.discovery.function_ids", config_.function_ids);
90-
node_->declare_parameter(
91-
"ros2_medkit.discovery.process_id", static_cast<int>(pid_));
92-
node_->declare_parameter("ros2_medkit.discovery.process_name", node_->get_name());
93-
94-
if (!hostname_.empty()) {
95-
node_->declare_parameter("ros2_medkit.discovery.hostname", hostname_);
96-
}
97-
98-
for (const auto & [key, value] : config_.metadata) {
99-
node_->declare_parameter("ros2_medkit.discovery.metadata." + key, value);
100-
}
101-
102-
RCLCPP_INFO(
103-
node_->get_logger(), "Parameter beacon enabled (entity: %s)",
104-
config_.entity_id.c_str());
105-
}
106-
107-
void publish_beacon()
108-
{
109-
auto msg = ros2_medkit_msgs::msg::MedkitDiscoveryHint();
110-
msg.entity_id = config_.entity_id;
111-
msg.display_name = config_.display_name;
112-
msg.component_id = config_.component_id;
113-
msg.function_ids = config_.function_ids;
114-
msg.process_id = pid_;
115-
msg.process_name = node_->get_name();
116-
msg.hostname = hostname_;
117-
msg.stamp = node_->now();
118-
119-
for (const auto & [key, value] : config_.metadata) {
120-
diagnostic_msgs::msg::KeyValue kv;
121-
kv.key = key;
122-
kv.value = value;
123-
msg.metadata.push_back(kv);
124-
}
125-
126-
beacon_pub_->publish(msg);
127-
}
40+
void init_topic_beacon();
41+
void init_param_beacon();
42+
void publish_beacon();
12843

12944
rclcpp::Node * node_;
13045
Config config_;

demos/sensor_diagnostics/src/camera_sim_node.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ class CameraSimNode : public rclcpp::Node
7474
std::bind(&CameraSimNode::on_parameter_change, this, std::placeholders::_1));
7575

7676
// Initialize beacon (reads beacon_mode parameter: none/topic/param)
77+
auto entity_id = this->declare_parameter("entity_id", "camera-sim");
7778
beacon_ = std::make_unique<BeaconHelper>(this, BeaconHelper::Config{
78-
"camera-sim", "Camera Simulator", "camera-unit",
79+
entity_id, "Camera Simulator", "camera-unit",
7980
{"sensor-monitoring"},
8081
{{"sensor_type", "camera"}, {"data_topic", "image_raw"}, {"frame_id", "camera_link"}},
8182
});

demos/sensor_diagnostics/src/gps_sim_node.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ class GpsSimNode : public rclcpp::Node
7474
std::bind(&GpsSimNode::on_parameter_change, this, std::placeholders::_1));
7575

7676
// Initialize beacon (reads beacon_mode parameter: none/topic/param)
77+
auto entity_id = this->declare_parameter("entity_id", "gps-sim");
7778
beacon_ = std::make_unique<BeaconHelper>(this, BeaconHelper::Config{
78-
"gps-sim", "GPS Simulator", "gps-unit",
79+
entity_id, "GPS Simulator", "gps-unit",
7980
{"sensor-monitoring"},
8081
{{"sensor_type", "gps"}, {"data_topic", "fix"}, {"frame_id", "gps_link"}},
8182
});

demos/sensor_diagnostics/src/imu_sim_node.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ class ImuSimNode : public rclcpp::Node
7070
std::bind(&ImuSimNode::on_parameter_change, this, std::placeholders::_1));
7171

7272
// Initialize beacon (reads beacon_mode parameter: none/topic/param)
73+
auto entity_id = this->declare_parameter("entity_id", "imu-sim");
7374
beacon_ = std::make_unique<BeaconHelper>(this, BeaconHelper::Config{
74-
"imu-sim", "IMU Simulator", "imu-unit",
75+
entity_id, "IMU Simulator", "imu-unit",
7576
{"sensor-monitoring"},
7677
{{"sensor_type", "imu"}, {"data_topic", "imu"}, {"frame_id", "imu_link"}},
7778
});

demos/sensor_diagnostics/src/lidar_sim_node.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ class LidarSimNode : public rclcpp::Node
8383
std::bind(&LidarSimNode::on_parameter_change, this, std::placeholders::_1));
8484

8585
// Initialize beacon (reads beacon_mode parameter: none/topic/param)
86+
auto entity_id = this->declare_parameter("entity_id", "lidar-sim");
8687
beacon_ = std::make_unique<BeaconHelper>(this, BeaconHelper::Config{
87-
"lidar-sim", "LiDAR Simulator", "lidar-unit",
88+
entity_id, "LiDAR Simulator", "lidar-unit",
8889
{"sensor-monitoring"},
8990
{{"sensor_type", "lidar"}, {"data_topic", "scan"}, {"frame_id", "lidar_link"}},
9091
});

0 commit comments

Comments
 (0)