Skip to content

Commit 1261eb7

Browse files
committed
AP_DDS: add parameters for topic publish rates
Adds DDS_RATE_* parameters so users can configure ROS 2 topic publication rates without recompiling. Defaults are taken from the existing AP_DDS_DELAY_*_TOPIC_MS defines so existing behaviour is preserved. Setting a rate to 0 disables that topic. Fixes ArduPilot#32960
1 parent 70fe712 commit 1261eb7

2 files changed

Lines changed: 180 additions & 77 deletions

File tree

libraries/AP_DDS/AP_DDS_Client.cpp

Lines changed: 142 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -55,70 +55,15 @@
5555

5656
// Enable DDS at runtime by default
5757
static constexpr uint8_t ENABLED_BY_DEFAULT = 1;
58-
#if AP_DDS_TIME_PUB_ENABLED
59-
static constexpr uint16_t DELAY_TIME_TOPIC_MS = AP_DDS_DELAY_TIME_TOPIC_MS;
60-
#endif // AP_DDS_TIME_PUB_ENABLED
61-
#if AP_DDS_BATTERY_STATE_PUB_ENABLED
62-
static constexpr uint16_t DELAY_BATTERY_STATE_TOPIC_MS = AP_DDS_DELAY_BATTERY_STATE_TOPIC_MS;
63-
#endif // AP_DDS_BATTERY_STATE_PUB_ENABLED
64-
#if AP_DDS_IMU_PUB_ENABLED
65-
static constexpr uint16_t DELAY_IMU_TOPIC_MS = AP_DDS_DELAY_IMU_TOPIC_MS;
66-
#endif // AP_DDS_IMU_PUB_ENABLED
67-
#if AP_DDS_LOCAL_POSE_PUB_ENABLED
68-
static constexpr uint16_t DELAY_LOCAL_POSE_TOPIC_MS = AP_DDS_DELAY_LOCAL_POSE_TOPIC_MS;
69-
#endif // AP_DDS_LOCAL_POSE_PUB_ENABLED
70-
#if AP_DDS_LOCAL_VEL_PUB_ENABLED
71-
static constexpr uint16_t DELAY_LOCAL_VELOCITY_TOPIC_MS = AP_DDS_DELAY_LOCAL_VELOCITY_TOPIC_MS;
72-
#endif // AP_DDS_LOCAL_VEL_PUB_ENABLED
73-
#if AP_DDS_AIRSPEED_PUB_ENABLED
74-
static constexpr uint16_t DELAY_AIRSPEED_TOPIC_MS = AP_DDS_DELAY_AIRSPEED_TOPIC_MS;
75-
#endif // AP_DDS_AIRSPEED_PUB_ENABLED
76-
#if AP_DDS_RC_PUB_ENABLED
77-
static constexpr uint16_t DELAY_RC_TOPIC_MS = AP_DDS_DELAY_RC_TOPIC_MS;
78-
#endif // AP_DDS_RC_PUB_ENABLED
79-
#if AP_DDS_GEOPOSE_PUB_ENABLED
80-
static constexpr uint16_t DELAY_GEO_POSE_TOPIC_MS = AP_DDS_DELAY_GEO_POSE_TOPIC_MS;
81-
#endif // AP_DDS_GEOPOSE_PUB_ENABLED
82-
#if AP_DDS_GOAL_PUB_ENABLED
83-
static constexpr uint16_t DELAY_GOAL_TOPIC_MS = AP_DDS_DELAY_GOAL_TOPIC_MS ;
84-
#endif // AP_DDS_GOAL_PUB_ENABLED
85-
#if AP_DDS_CLOCK_PUB_ENABLED
86-
static constexpr uint16_t DELAY_CLOCK_TOPIC_MS =AP_DDS_DELAY_CLOCK_TOPIC_MS;
87-
#endif // AP_DDS_CLOCK_PUB_ENABLED
88-
#if AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
89-
static constexpr uint16_t DELAY_GPS_GLOBAL_ORIGIN_TOPIC_MS = AP_DDS_DELAY_GPS_GLOBAL_ORIGIN_TOPIC_MS;
90-
#endif // AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
91-
static constexpr uint16_t DELAY_PING_MS = 500;
92-
#if AP_DDS_STATUS_PUB_ENABLED
93-
static constexpr uint16_t DELAY_STATUS_TOPIC_MS = AP_DDS_DELAY_STATUS_TOPIC_MS;
94-
#endif // AP_DDS_STATUS_PUB_ENABLED
95-
96-
// Define the subscriber data members, which are static class scope.
97-
// If these are created on the stack in the subscriber,
98-
// the AP_DDS_Client::on_topic frame size is exceeded.
99-
#if AP_DDS_JOY_SUB_ENABLED
100-
sensor_msgs_msg_Joy AP_DDS_Client::rx_joy_topic {};
101-
#endif // AP_DDS_JOY_SUB_ENABLED
102-
#if AP_DDS_DYNAMIC_TF_SUB_ENABLED
103-
tf2_msgs_msg_TFMessage AP_DDS_Client::rx_dynamic_transforms_topic {};
104-
#endif // AP_DDS_DYNAMIC_TF_SUB_ENABLED
105-
#if AP_DDS_VEL_CTRL_ENABLED
106-
geometry_msgs_msg_TwistStamped AP_DDS_Client::rx_velocity_control_topic {};
107-
#endif // AP_DDS_VEL_CTRL_ENABLED
108-
#if AP_DDS_GLOBAL_POS_CTRL_ENABLED
109-
ardupilot_msgs_msg_GlobalPosition AP_DDS_Client::rx_global_position_control_topic {};
110-
#endif // AP_DDS_GLOBAL_POS_CTRL_ENABLED
111-
112-
// Define the parameter server data members, which are static class scope.
113-
// If these are created on the stack, then the AP_DDS_Client::on_request
114-
// frame size is exceeded.
115-
#if AP_DDS_PARAMETER_SERVER_ENABLED
116-
rcl_interfaces_srv_SetParameters_Request AP_DDS_Client::set_parameter_request {};
117-
rcl_interfaces_srv_SetParameters_Response AP_DDS_Client::set_parameter_response {};
118-
rcl_interfaces_srv_GetParameters_Request AP_DDS_Client::get_parameters_request {};
119-
rcl_interfaces_srv_GetParameters_Response AP_DDS_Client::get_parameters_response {};
120-
rcl_interfaces_msg_Parameter AP_DDS_Client::param {};
121-
#endif
58+
// returns publish period in ms for the given rate (Hz).
59+
// rate <= 0 returns UINT32_MAX so the publish-due check never triggers.
60+
static uint32_t rate_hz_to_period_ms(int16_t rate_hz)
61+
{
62+
if (rate_hz <= 0) {
63+
return UINT32_MAX;
64+
}
65+
return 1000U / uint16_t(rate_hz);
66+
}
12267

12368
const AP_Param::GroupInfo AP_DDS_Client::var_info[] {
12469

@@ -180,6 +125,126 @@ const AP_Param::GroupInfo AP_DDS_Client::var_info[] {
180125
// @User: Standard
181126
AP_GROUPINFO("_USE_NS", 7, AP_DDS_Client, use_ns, 0),
182127

128+
#if AP_DDS_TIME_PUB_ENABLED
129+
// @Param: _RATE_TIME
130+
// @DisplayName: DDS time topic publish rate
131+
// @Description: Publish rate for the time topic. 0 disables it.
132+
// @Units: Hz
133+
// @Range: 0 1000
134+
// @User: Advanced
135+
AP_GROUPINFO("_RATE_TIME", 8, AP_DDS_Client, rate_time_hz, 1000 / AP_DDS_DELAY_TIME_TOPIC_MS),
136+
#endif
137+
138+
#if AP_DDS_BATTERY_STATE_PUB_ENABLED
139+
// @Param: _RATE_BATT
140+
// @DisplayName: DDS battery_state topic publish rate
141+
// @Description: Publish rate for the battery_state topic. 0 disables it.
142+
// @Units: Hz
143+
// @Range: 0 1000
144+
// @User: Advanced
145+
AP_GROUPINFO("_RATE_BATT", 9, AP_DDS_Client, rate_battery_hz, 1000 / AP_DDS_DELAY_BATTERY_STATE_TOPIC_MS),
146+
#endif
147+
148+
#if AP_DDS_LOCAL_POSE_PUB_ENABLED
149+
// @Param: _RATE_LPOSE
150+
// @DisplayName: DDS local pose topic publish rate
151+
// @Description: Publish rate for the local pose topic. 0 disables it.
152+
// @Units: Hz
153+
// @Range: 0 1000
154+
// @User: Advanced
155+
AP_GROUPINFO("_RATE_LPOSE", 10, AP_DDS_Client, rate_local_pose_hz, 1000 / AP_DDS_DELAY_LOCAL_POSE_TOPIC_MS),
156+
#endif
157+
158+
#if AP_DDS_LOCAL_VEL_PUB_ENABLED
159+
// @Param: _RATE_LVEL
160+
// @DisplayName: DDS local velocity topic publish rate
161+
// @Description: Publish rate for the local velocity topic. 0 disables it.
162+
// @Units: Hz
163+
// @Range: 0 1000
164+
// @User: Advanced
165+
AP_GROUPINFO("_RATE_LVEL", 11, AP_DDS_Client, rate_local_vel_hz, 1000 / AP_DDS_DELAY_LOCAL_VELOCITY_TOPIC_MS),
166+
#endif
167+
168+
#if AP_DDS_AIRSPEED_PUB_ENABLED
169+
// @Param: _RATE_AIRSP
170+
// @DisplayName: DDS airspeed topic publish rate
171+
// @Description: Publish rate for the airspeed topic. 0 disables it.
172+
// @Units: Hz
173+
// @Range: 0 1000
174+
// @User: Advanced
175+
AP_GROUPINFO("_RATE_AIRSP", 12, AP_DDS_Client, rate_airspeed_hz, 1000 / AP_DDS_DELAY_AIRSPEED_TOPIC_MS),
176+
#endif
177+
178+
#if AP_DDS_RC_PUB_ENABLED
179+
// @Param: _RATE_RC
180+
// @DisplayName: DDS rc topic publish rate
181+
// @Description: Publish rate for the rc topic. 0 disables it.
182+
// @Units: Hz
183+
// @Range: 0 1000
184+
// @User: Advanced
185+
AP_GROUPINFO("_RATE_RC", 13, AP_DDS_Client, rate_rc_hz, 1000 / AP_DDS_DELAY_RC_TOPIC_MS),
186+
#endif
187+
188+
#if AP_DDS_IMU_PUB_ENABLED
189+
// @Param: _RATE_IMU
190+
// @DisplayName: DDS imu topic publish rate
191+
// @Description: Publish rate for the imu topic. 0 disables it.
192+
// @Units: Hz
193+
// @Range: 0 1000
194+
// @User: Advanced
195+
AP_GROUPINFO("_RATE_IMU", 14, AP_DDS_Client, rate_imu_hz, 1000 / AP_DDS_DELAY_IMU_TOPIC_MS),
196+
#endif
197+
198+
#if AP_DDS_GEOPOSE_PUB_ENABLED
199+
// @Param: _RATE_GPOSE
200+
// @DisplayName: DDS geo_pose topic publish rate
201+
// @Description: Publish rate for the geo_pose topic. 0 disables it.
202+
// @Units: Hz
203+
// @Range: 0 1000
204+
// @User: Advanced
205+
AP_GROUPINFO("_RATE_GPOSE", 15, AP_DDS_Client, rate_geo_pose_hz, 1000 / AP_DDS_DELAY_GEO_POSE_TOPIC_MS),
206+
#endif
207+
208+
#if AP_DDS_CLOCK_PUB_ENABLED
209+
// @Param: _RATE_CLOCK
210+
// @DisplayName: DDS clock topic publish rate
211+
// @Description: Publish rate for the clock topic. 0 disables it.
212+
// @Units: Hz
213+
// @Range: 0 1000
214+
// @User: Advanced
215+
AP_GROUPINFO("_RATE_CLOCK", 16, AP_DDS_Client, rate_clock_hz, 1000 / AP_DDS_DELAY_CLOCK_TOPIC_MS),
216+
#endif
217+
218+
#if AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
219+
// @Param: _RATE_GPSOR
220+
// @DisplayName: DDS gps_global_origin topic publish rate
221+
// @Description: Publish rate for the gps_global_origin topic. 0 disables it.
222+
// @Units: Hz
223+
// @Range: 0 1000
224+
// @User: Advanced
225+
AP_GROUPINFO("_RATE_GPSOR", 17, AP_DDS_Client, rate_gps_origin_hz, 1000 / AP_DDS_DELAY_GPS_GLOBAL_ORIGIN_TOPIC_MS),
226+
#endif
227+
228+
#if AP_DDS_GOAL_PUB_ENABLED
229+
// @Param: _RATE_GOAL
230+
// @DisplayName: DDS goal topic publish rate
231+
// @Description: Publish rate for the goal topic. 0 disables it.
232+
// @Units: Hz
233+
// @Range: 0 1000
234+
// @User: Advanced
235+
AP_GROUPINFO("_RATE_GOAL", 18, AP_DDS_Client, rate_goal_hz, 1000 / AP_DDS_DELAY_GOAL_TOPIC_MS),
236+
#endif
237+
238+
#if AP_DDS_STATUS_PUB_ENABLED
239+
// @Param: _RATE_STAT
240+
// @DisplayName: DDS status topic publish rate
241+
// @Description: Publish rate for the status topic. 0 disables it.
242+
// @Units: Hz
243+
// @Range: 0 1000
244+
// @User: Advanced
245+
AP_GROUPINFO("_RATE_STAT", 19, AP_DDS_Client, rate_status_hz, 1000 / AP_DDS_DELAY_STATUS_TOPIC_MS),
246+
#endif
247+
183248
AP_GROUPEND
184249
};
185250

@@ -763,7 +828,7 @@ bool AP_DDS_Client::update_topic(ardupilot_msgs_msg_Status& msg)
763828
last_status_publish_time_ms = timestamp;
764829
update_topic(msg.header.stamp);
765830
return true;
766-
} else if (timestamp - last_status_publish_time_ms > DELAY_STATUS_TOPIC_MS * 5) {
831+
} else if (timestamp - last_status_publish_time_ms > rate_hz_to_period_ms(rate_status_hz) * 5) {
767832
// Publish the status message at 2Hz even if no change is detected.
768833
last_status_publish_time_ms = timestamp;
769834
update_topic(msg.header.stamp);
@@ -1812,7 +1877,7 @@ void AP_DDS_Client::update()
18121877
const auto cur_time_ms = AP_HAL::millis64();
18131878

18141879
#if AP_DDS_TIME_PUB_ENABLED
1815-
if (cur_time_ms - last_time_time_ms > DELAY_TIME_TOPIC_MS) {
1880+
if (cur_time_ms - last_time_time_ms > rate_hz_to_period_ms(rate_time_hz)) {
18161881
update_topic(time_topic);
18171882
last_time_time_ms = cur_time_ms;
18181883
write_time_topic();
@@ -1826,7 +1891,7 @@ void AP_DDS_Client::update()
18261891
}
18271892
#endif // AP_DDS_NAVSATFIX_PUB_ENABLED
18281893
#if AP_DDS_BATTERY_STATE_PUB_ENABLED
1829-
if (cur_time_ms - last_battery_state_time_ms > DELAY_BATTERY_STATE_TOPIC_MS) {
1894+
if (cur_time_ms - last_battery_state_time_ms > rate_hz_to_period_ms(rate_battery_hz)) {
18301895
for (uint8_t battery_instance = 0; battery_instance < AP_BATT_MONITOR_MAX_INSTANCES; battery_instance++) {
18311896
update_topic(battery_state_topic, battery_instance);
18321897
if (battery_state_topic.present) {
@@ -1837,73 +1902,73 @@ void AP_DDS_Client::update()
18371902
}
18381903
#endif // AP_DDS_BATTERY_STATE_PUB_ENABLED
18391904
#if AP_DDS_LOCAL_POSE_PUB_ENABLED
1840-
if (cur_time_ms - last_local_pose_time_ms > DELAY_LOCAL_POSE_TOPIC_MS) {
1905+
if (cur_time_ms - last_local_pose_time_ms > rate_hz_to_period_ms(rate_local_pose_hz)) {
18411906
update_topic(local_pose_topic);
18421907
last_local_pose_time_ms = cur_time_ms;
18431908
write_local_pose_topic();
18441909
}
18451910
#endif // AP_DDS_LOCAL_POSE_PUB_ENABLED
18461911
#if AP_DDS_LOCAL_VEL_PUB_ENABLED
1847-
if (cur_time_ms - last_local_velocity_time_ms > DELAY_LOCAL_VELOCITY_TOPIC_MS) {
1912+
if (cur_time_ms - last_local_velocity_time_ms > rate_hz_to_period_ms(rate_local_vel_hz)) {
18481913
update_topic(tx_local_velocity_topic);
18491914
last_local_velocity_time_ms = cur_time_ms;
18501915
write_tx_local_velocity_topic();
18511916
}
18521917
#endif // AP_DDS_LOCAL_VEL_PUB_ENABLED
18531918
#if AP_DDS_AIRSPEED_PUB_ENABLED
1854-
if (cur_time_ms - last_airspeed_time_ms > DELAY_AIRSPEED_TOPIC_MS) {
1919+
if (cur_time_ms - last_airspeed_time_ms > rate_hz_to_period_ms(rate_airspeed_hz)) {
18551920
last_airspeed_time_ms = cur_time_ms;
18561921
if (update_topic(tx_local_airspeed_topic)) {
18571922
write_tx_local_airspeed_topic();
18581923
}
18591924
}
18601925
#endif // AP_DDS_AIRSPEED_PUB_ENABLED
18611926
#if AP_DDS_RC_PUB_ENABLED
1862-
if (cur_time_ms - last_rc_time_ms > DELAY_RC_TOPIC_MS) {
1927+
if (cur_time_ms - last_rc_time_ms > rate_hz_to_period_ms(rate_rc_hz)) {
18631928
last_rc_time_ms = cur_time_ms;
18641929
if (update_topic(tx_local_rc_topic)) {
18651930
write_tx_local_rc_topic();
18661931
}
18671932
}
18681933
#endif // AP_DDS_RC_PUB_ENABLED
18691934
#if AP_DDS_IMU_PUB_ENABLED
1870-
if (cur_time_ms - last_imu_time_ms > DELAY_IMU_TOPIC_MS) {
1935+
if (cur_time_ms - last_imu_time_ms > rate_hz_to_period_ms(rate_imu_hz)) {
18711936
update_topic(imu_topic);
18721937
last_imu_time_ms = cur_time_ms;
18731938
write_imu_topic();
18741939
}
18751940
#endif // AP_DDS_IMU_PUB_ENABLED
18761941
#if AP_DDS_GEOPOSE_PUB_ENABLED
1877-
if (cur_time_ms - last_geo_pose_time_ms > DELAY_GEO_POSE_TOPIC_MS) {
1942+
if (cur_time_ms - last_geo_pose_time_ms > rate_hz_to_period_ms(rate_geo_pose_hz)) {
18781943
update_topic(geo_pose_topic);
18791944
last_geo_pose_time_ms = cur_time_ms;
18801945
write_geo_pose_topic();
18811946
}
18821947
#endif // AP_DDS_GEOPOSE_PUB_ENABLED
18831948
#if AP_DDS_CLOCK_PUB_ENABLED
1884-
if (cur_time_ms - last_clock_time_ms > DELAY_CLOCK_TOPIC_MS) {
1949+
if (cur_time_ms - last_clock_time_ms > rate_hz_to_period_ms(rate_clock_hz)) {
18851950
update_topic(clock_topic);
18861951
last_clock_time_ms = cur_time_ms;
18871952
write_clock_topic();
18881953
}
18891954
#endif // AP_DDS_CLOCK_PUB_ENABLED
18901955
#if AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
1891-
if (cur_time_ms - last_gps_global_origin_time_ms > DELAY_GPS_GLOBAL_ORIGIN_TOPIC_MS) {
1956+
if (cur_time_ms - last_gps_global_origin_time_ms > rate_hz_to_period_ms(rate_gps_origin_hz)) {
18921957
update_topic(gps_global_origin_topic);
18931958
last_gps_global_origin_time_ms = cur_time_ms;
18941959
write_gps_global_origin_topic();
18951960
}
18961961
#endif // AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
18971962
#if AP_DDS_GOAL_PUB_ENABLED
1898-
if (cur_time_ms - last_goal_time_ms > DELAY_GOAL_TOPIC_MS) {
1963+
if (cur_time_ms - last_goal_time_ms > rate_hz_to_period_ms(rate_goal_hz)) {
18991964
if (update_topic_goal(goal_topic)) {
19001965
write_goal_topic();
19011966
}
19021967
last_goal_time_ms = cur_time_ms;
19031968
}
19041969
#endif // AP_DDS_GOAL_PUB_ENABLED
19051970
#if AP_DDS_STATUS_PUB_ENABLED
1906-
if (cur_time_ms - last_status_check_time_ms > DELAY_STATUS_TOPIC_MS) {
1971+
if (cur_time_ms - last_status_check_time_ms > rate_hz_to_period_ms(rate_status_hz)) {
19071972
if (update_topic(status_topic)) {
19081973
write_status_topic();
19091974
}

libraries/AP_DDS/AP_DDS_Client.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,44 @@ class AP_DDS_Client
359359
//! @brief Use namespace when enabled
360360
AP_Int8 use_ns;
361361

362+
//! @brief Publish rate (Hz) per topic. 0 disables a topic.
363+
#if AP_DDS_TIME_PUB_ENABLED
364+
AP_Int16 rate_time_hz;
365+
#endif
366+
#if AP_DDS_BATTERY_STATE_PUB_ENABLED
367+
AP_Int16 rate_battery_hz;
368+
#endif
369+
#if AP_DDS_LOCAL_POSE_PUB_ENABLED
370+
AP_Int16 rate_local_pose_hz;
371+
#endif
372+
#if AP_DDS_LOCAL_VEL_PUB_ENABLED
373+
AP_Int16 rate_local_vel_hz;
374+
#endif
375+
#if AP_DDS_AIRSPEED_PUB_ENABLED
376+
AP_Int16 rate_airspeed_hz;
377+
#endif
378+
#if AP_DDS_RC_PUB_ENABLED
379+
AP_Int16 rate_rc_hz;
380+
#endif
381+
#if AP_DDS_IMU_PUB_ENABLED
382+
AP_Int16 rate_imu_hz;
383+
#endif
384+
#if AP_DDS_GEOPOSE_PUB_ENABLED
385+
AP_Int16 rate_geo_pose_hz;
386+
#endif
387+
#if AP_DDS_CLOCK_PUB_ENABLED
388+
AP_Int16 rate_clock_hz;
389+
#endif
390+
#if AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
391+
AP_Int16 rate_gps_origin_hz;
392+
#endif
393+
#if AP_DDS_GOAL_PUB_ENABLED
394+
AP_Int16 rate_goal_hz;
395+
#endif
396+
#if AP_DDS_STATUS_PUB_ENABLED
397+
AP_Int16 rate_status_hz;
398+
#endif
399+
362400
//! @brief Enum used to mark a topic as a data reader or writer
363401
enum class Topic_rw : uint8_t {
364402
DataReader = 0,

0 commit comments

Comments
 (0)