CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_DDS/AP_DDS_Client.h
Views: 1798
1
#pragma once
2
3
#include "AP_DDS_config.h"
4
5
#if AP_DDS_ENABLED
6
7
#include "uxr/client/client.h"
8
#include "ucdr/microcdr.h"
9
10
#if AP_DDS_GLOBAL_POS_CTRL_ENABLED
11
#include "ardupilot_msgs/msg/GlobalPosition.h"
12
#endif // AP_DDS_GLOBAL_POS_CTRL_ENABLED
13
#if AP_DDS_TIME_PUB_ENABLED
14
#include "builtin_interfaces/msg/Time.h"
15
#endif // AP_DDS_TIME_PUB_ENABLED
16
#if AP_DDS_NAVSATFIX_PUB_ENABLED
17
#include "sensor_msgs/msg/NavSatFix.h"
18
#endif // AP_DDS_NAVSATFIX_PUB_ENABLED
19
#if AP_DDS_NEEDS_TRANSFORMS
20
#include "tf2_msgs/msg/TFMessage.h"
21
#endif // AP_DDS_NEEDS_TRANSFORMS
22
#if AP_DDS_BATTERY_STATE_PUB_ENABLED
23
#include "sensor_msgs/msg/BatteryState.h"
24
#endif // AP_DDS_BATTERY_STATE_PUB_ENABLED
25
#if AP_DDS_IMU_PUB_ENABLED
26
#include "sensor_msgs/msg/Imu.h"
27
#endif // AP_DDS_IMU_PUB_ENABLED
28
#if AP_DDS_STATUS_PUB_ENABLED
29
#include "ardupilot_msgs/msg/Status.h"
30
#endif // AP_DDS_STATUS_PUB_ENABLED
31
#if AP_DDS_JOY_SUB_ENABLED
32
#include "sensor_msgs/msg/Joy.h"
33
#endif // AP_DDS_JOY_SUB_ENABLED
34
#if AP_DDS_LOCAL_POSE_PUB_ENABLED
35
#include "geometry_msgs/msg/PoseStamped.h"
36
#endif // AP_DDS_LOCAL_POSE_PUB_ENABLED
37
#if AP_DDS_NEEDS_TWIST
38
#include "geometry_msgs/msg/TwistStamped.h"
39
#endif // AP_DDS_NEEDS_TWIST
40
#if AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
41
#include "geographic_msgs/msg/GeoPointStamped.h"
42
#endif // AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
43
#if AP_DDS_AIRSPEED_PUB_ENABLED
44
#include "geometry_msgs/msg/Vector3Stamped.h"
45
#endif // AP_DDS_AIRSPEED_PUB_ENABLED
46
#if AP_DDS_GEOPOSE_PUB_ENABLED
47
#include "geographic_msgs/msg/GeoPoseStamped.h"
48
#endif // AP_DDS_GEOPOSE_PUB_ENABLED
49
#if AP_DDS_CLOCK_PUB_ENABLED
50
#include "rosgraph_msgs/msg/Clock.h"
51
#endif // AP_DDS_CLOCK_PUB_ENABLED
52
#if AP_DDS_PARAMETER_SERVER_ENABLED
53
#include "rcl_interfaces/srv/SetParameters.h"
54
#include "rcl_interfaces/msg/Parameter.h"
55
#include "rcl_interfaces/msg/SetParametersResult.h"
56
#include "rcl_interfaces/msg/ParameterValue.h"
57
#include "rcl_interfaces/msg/ParameterType.h"
58
#include "rcl_interfaces/srv/GetParameters.h"
59
#endif //AP_DDS_PARAMETER_SERVER_ENABLED
60
61
#include <AP_HAL/AP_HAL.h>
62
#include <AP_HAL/Scheduler.h>
63
#include <AP_HAL/Semaphores.h>
64
65
#include "fcntl.h"
66
67
#include <AP_Param/AP_Param.h>
68
69
#define DDS_MTU 512
70
#define DDS_STREAM_HISTORY 8
71
#define DDS_BUFFER_SIZE DDS_MTU * DDS_STREAM_HISTORY
72
73
#if AP_DDS_UDP_ENABLED
74
#include <AP_HAL/utility/Socket.h>
75
#include <AP_Networking/AP_Networking_address.h>
76
#endif
77
78
extern const AP_HAL::HAL& hal;
79
80
class AP_DDS_Client
81
{
82
83
private:
84
85
AP_Int8 enabled;
86
87
// Serial Allocation
88
uxrSession session; //Session
89
bool is_using_serial; // true when using serial transport
90
91
// input and output stream
92
uint8_t *input_reliable_stream;
93
uint8_t *output_reliable_stream;
94
uxrStreamId reliable_in;
95
uxrStreamId reliable_out;
96
97
// Outgoing Sensor and AHRS data
98
99
#if AP_DDS_TIME_PUB_ENABLED
100
builtin_interfaces_msg_Time time_topic;
101
// The last ms timestamp AP_DDS wrote a Time message
102
uint64_t last_time_time_ms;
103
//! @brief Serialize the current time state and publish to the IO stream(s)
104
void write_time_topic();
105
static void update_topic(builtin_interfaces_msg_Time& msg);
106
#endif // AP_DDS_TIME_PUB_ENABLED
107
108
#if AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
109
geographic_msgs_msg_GeoPointStamped gps_global_origin_topic;
110
// The last ms timestamp AP_DDS wrote a gps global origin message
111
uint64_t last_gps_global_origin_time_ms;
112
//! @brief Serialize the current gps global origin and publish to the IO stream(s)
113
void write_gps_global_origin_topic();
114
static void update_topic(geographic_msgs_msg_GeoPointStamped& msg);
115
# endif // AP_DDS_GPS_GLOBAL_ORIGIN_PUB_ENABLED
116
117
#if AP_DDS_GOAL_PUB_ENABLED
118
geographic_msgs_msg_GeoPointStamped goal_topic;
119
// The last ms timestamp AP_DDS wrote a goal message
120
uint64_t last_goal_time_ms;
121
//! @brief Serialize the current goal and publish to the IO stream(s)
122
void write_goal_topic();
123
bool update_topic_goal(geographic_msgs_msg_GeoPointStamped& msg);
124
geographic_msgs_msg_GeoPointStamped prev_goal_msg;
125
#endif // AP_DDS_GOAL_PUB_ENABLED
126
127
#if AP_DDS_GEOPOSE_PUB_ENABLED
128
geographic_msgs_msg_GeoPoseStamped geo_pose_topic;
129
// The last ms timestamp AP_DDS wrote a GeoPose message
130
uint64_t last_geo_pose_time_ms;
131
//! @brief Serialize the current geo_pose and publish to the IO stream(s)
132
void write_geo_pose_topic();
133
static void update_topic(geographic_msgs_msg_GeoPoseStamped& msg);
134
#endif // AP_DDS_GEOPOSE_PUB_ENABLED
135
136
#if AP_DDS_LOCAL_POSE_PUB_ENABLED
137
geometry_msgs_msg_PoseStamped local_pose_topic;
138
// The last ms timestamp AP_DDS wrote a Local Pose message
139
uint64_t last_local_pose_time_ms;
140
//! @brief Serialize the current local_pose and publish to the IO stream(s)
141
void write_local_pose_topic();
142
static void update_topic(geometry_msgs_msg_PoseStamped& msg);
143
#endif // AP_DDS_LOCAL_POSE_PUB_ENABLED
144
145
#if AP_DDS_LOCAL_VEL_PUB_ENABLED
146
geometry_msgs_msg_TwistStamped tx_local_velocity_topic;
147
// The last ms timestamp AP_DDS wrote a Local Velocity message
148
uint64_t last_local_velocity_time_ms;
149
//! @brief Serialize the current local velocity and publish to the IO stream(s)
150
void write_tx_local_velocity_topic();
151
static void update_topic(geometry_msgs_msg_TwistStamped& msg);
152
#endif // AP_DDS_LOCAL_VEL_PUB_ENABLED
153
154
#if AP_DDS_AIRSPEED_PUB_ENABLED
155
geometry_msgs_msg_Vector3Stamped tx_local_airspeed_topic;
156
// The last ms timestamp AP_DDS wrote a airspeed message
157
uint64_t last_airspeed_time_ms;
158
//! @brief Serialize the current local airspeed and publish to the IO stream(s)
159
void write_tx_local_airspeed_topic();
160
static bool update_topic(geometry_msgs_msg_Vector3Stamped& msg);
161
#endif //AP_DDS_AIRSPEED_PUB_ENABLED
162
163
#if AP_DDS_BATTERY_STATE_PUB_ENABLED
164
sensor_msgs_msg_BatteryState battery_state_topic;
165
// The last ms timestamp AP_DDS wrote a BatteryState message
166
uint64_t last_battery_state_time_ms;
167
//! @brief Serialize the current nav_sat_fix state and publish it to the IO stream(s)
168
void write_battery_state_topic();
169
static void update_topic(sensor_msgs_msg_BatteryState& msg, const uint8_t instance);
170
#endif // AP_DDS_BATTERY_STATE_PUB_ENABLED
171
172
#if AP_DDS_NAVSATFIX_PUB_ENABLED
173
sensor_msgs_msg_NavSatFix nav_sat_fix_topic;
174
// The last ms timestamp AP_DDS wrote a NavSatFix message
175
uint64_t last_nav_sat_fix_time_ms;
176
//! @brief Serialize the current nav_sat_fix state and publish to the IO stream(s)
177
void write_nav_sat_fix_topic();
178
bool update_topic(sensor_msgs_msg_NavSatFix& msg, const uint8_t instance) WARN_IF_UNUSED;
179
#endif // AP_DDS_NAVSATFIX_PUB_ENABLED
180
181
#if AP_DDS_IMU_PUB_ENABLED
182
sensor_msgs_msg_Imu imu_topic;
183
// The last ms timestamp AP_DDS wrote an IMU message
184
uint64_t last_imu_time_ms;
185
static void update_topic(sensor_msgs_msg_Imu& msg);
186
//! @brief Serialize the current IMU data and publish to the IO stream(s)
187
void write_imu_topic();
188
#endif // AP_DDS_IMU_PUB_ENABLED
189
190
#if AP_DDS_CLOCK_PUB_ENABLED
191
rosgraph_msgs_msg_Clock clock_topic;
192
// The last ms timestamp AP_DDS wrote a Clock message
193
uint64_t last_clock_time_ms;
194
//! @brief Serialize the current clock and publish to the IO stream(s)
195
void write_clock_topic();
196
static void update_topic(rosgraph_msgs_msg_Clock& msg);
197
#endif // AP_DDS_CLOCK_PUB_ENABLED
198
199
#if AP_DDS_STATUS_PUB_ENABLED
200
ardupilot_msgs_msg_Status status_topic;
201
bool update_topic(ardupilot_msgs_msg_Status& msg);
202
// The last ms timestamp AP_DDS wrote/checked a status message
203
uint64_t last_status_check_time_ms;
204
// last status values;
205
ardupilot_msgs_msg_Status last_status_msg_;
206
//! @brief Serialize the current status and publish to the IO stream(s)
207
void write_status_topic();
208
#endif // AP_DDS_STATUS_PUB_ENABLED
209
210
#if AP_DDS_STATIC_TF_PUB_ENABLED
211
// outgoing transforms
212
tf2_msgs_msg_TFMessage tx_static_transforms_topic;
213
//! @brief Serialize the static transforms and publish to the IO stream(s)
214
void write_static_transforms();
215
static void populate_static_transforms(tf2_msgs_msg_TFMessage& msg);
216
#endif // AP_DDS_STATIC_TF_PUB_ENABLED
217
218
#if AP_DDS_JOY_SUB_ENABLED
219
// incoming joystick data
220
static sensor_msgs_msg_Joy rx_joy_topic;
221
#endif // AP_DDS_JOY_SUB_ENABLED
222
#if AP_DDS_VEL_CTRL_ENABLED
223
// incoming REP147 velocity control
224
static geometry_msgs_msg_TwistStamped rx_velocity_control_topic;
225
#endif // AP_DDS_VEL_CTRL_ENABLED
226
#if AP_DDS_GLOBAL_POS_CTRL_ENABLED
227
// incoming REP147 goal interface global position
228
static ardupilot_msgs_msg_GlobalPosition rx_global_position_control_topic;
229
#endif // AP_DDS_GLOBAL_POS_CTRL_ENABLED
230
#if AP_DDS_DYNAMIC_TF_SUB_ENABLED
231
// incoming transforms
232
static tf2_msgs_msg_TFMessage rx_dynamic_transforms_topic;
233
#endif // AP_DDS_DYNAMIC_TF_SUB_ENABLED
234
HAL_Semaphore csem;
235
236
#if AP_DDS_PARAMETER_SERVER_ENABLED
237
static rcl_interfaces_srv_SetParameters_Request set_parameter_request;
238
static rcl_interfaces_srv_SetParameters_Response set_parameter_response;
239
static rcl_interfaces_srv_GetParameters_Request get_parameters_request;
240
static rcl_interfaces_srv_GetParameters_Response get_parameters_response;
241
static rcl_interfaces_msg_Parameter param;
242
#endif
243
244
// connection parametrics
245
bool status_ok{false};
246
bool connected{false};
247
248
// subscription callback function
249
static void on_topic_trampoline(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id, struct ucdrBuffer* ub, uint16_t length, void* args);
250
void on_topic(uxrSession* session, uxrObjectId object_id, uint16_t request_id, uxrStreamId stream_id, struct ucdrBuffer* ub, uint16_t length);
251
252
// service replier callback function
253
static void on_request_trampoline(uxrSession* session, uxrObjectId object_id, uint16_t request_id, SampleIdentity* sample_id, ucdrBuffer* ub, uint16_t length, void* args);
254
void on_request(uxrSession* session, uxrObjectId object_id, uint16_t request_id, SampleIdentity* sample_id, ucdrBuffer* ub, uint16_t length);
255
256
// delivery control parameters
257
uxrDeliveryControl delivery_control {
258
.max_samples = UXR_MAX_SAMPLES_UNLIMITED,
259
.max_elapsed_time = 0,
260
.max_bytes_per_second = 0,
261
.min_pace_period = 0
262
};
263
264
// functions for serial transport
265
bool ddsSerialInit();
266
static bool serial_transport_open(uxrCustomTransport* args);
267
static bool serial_transport_close(uxrCustomTransport* transport);
268
static size_t serial_transport_write(uxrCustomTransport* transport, const uint8_t* buf, size_t len, uint8_t* error);
269
static size_t serial_transport_read(uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* error);
270
struct {
271
AP_HAL::UARTDriver *port;
272
uxrCustomTransport transport;
273
} serial;
274
275
#if AP_DDS_UDP_ENABLED
276
// functions for udp transport
277
bool ddsUdpInit();
278
static bool udp_transport_open(uxrCustomTransport* args);
279
static bool udp_transport_close(uxrCustomTransport* transport);
280
static size_t udp_transport_write(uxrCustomTransport* transport, const uint8_t* buf, size_t len, uint8_t* error);
281
static size_t udp_transport_read(uxrCustomTransport* transport, uint8_t* buf, size_t len, int timeout, uint8_t* error);
282
283
struct {
284
AP_Int32 port;
285
// UDP endpoint
286
AP_Networking_IPV4 ip{AP_DDS_DEFAULT_UDP_IP_ADDR};
287
// UDP Allocation
288
uxrCustomTransport transport;
289
SocketAPM *socket;
290
} udp;
291
#endif
292
// pointer to transport's communication structure
293
uxrCommunication *comm{nullptr};
294
295
// client key we present
296
static constexpr uint32_t key = 0xAAAABBBB;
297
298
299
public:
300
~AP_DDS_Client();
301
302
bool start(void);
303
void main_loop(void);
304
305
//! @brief Initialize the client's transport
306
//! @return True on successful initialization, false on failure
307
bool init_transport() WARN_IF_UNUSED;
308
309
//! @brief Initialize the client's uxr session and IO stream(s)
310
//! @return True on successful initialization, false on failure
311
bool init_session() WARN_IF_UNUSED;
312
313
//! @brief Set up the client's participants, data read/writes,
314
// publishers, subscribers
315
//! @return True on successful creation, false on failure
316
bool create() WARN_IF_UNUSED;
317
318
//! @brief Update the internally stored DDS messages with latest data
319
void update();
320
321
//! @brief GCS message prefix
322
static constexpr const char* msg_prefix = "DDS:";
323
324
//! @brief Parameter storage
325
static const struct AP_Param::GroupInfo var_info[];
326
327
//! @brief ROS_DOMAIN_ID
328
AP_Int32 domain_id;
329
330
//! @brief Timeout in milliseconds when pinging the XRCE agent
331
AP_Int32 ping_timeout_ms;
332
333
//! @brief Maximum number of attempts to ping the XRCE agent before exiting
334
AP_Int8 ping_max_retry;
335
336
//! @brief Enum used to mark a topic as a data reader or writer
337
enum class Topic_rw : uint8_t {
338
DataReader = 0,
339
DataWriter = 1,
340
};
341
342
//! @brief Convenience grouping for a single "channel" of data
343
struct Topic_table {
344
const uint8_t topic_id;
345
const uint8_t pub_id;
346
const uint8_t sub_id; // added sub_id fields to avoid confusion
347
const uxrObjectId dw_id;
348
const uxrObjectId dr_id; // added dr_id fields to avoid confusion
349
const Topic_rw topic_rw;
350
const char* topic_name;
351
const char* type_name;
352
const uxrQoS_t qos;
353
};
354
static const struct Topic_table topics[];
355
356
//! @brief Enum used to mark a service as a requester or replier
357
enum class Service_rr : uint8_t {
358
Requester = 0,
359
Replier = 1,
360
};
361
362
//! @brief Convenience grouping for a single "channel" of services
363
struct Service_table {
364
//! @brief Request ID for the service
365
const uint8_t req_id;
366
367
//! @brief Reply ID for the service
368
const uint8_t rep_id;
369
370
//! @brief Service is requester or replier
371
const Service_rr service_rr;
372
373
//! @brief Service name as it appears in ROS
374
const char* service_name;
375
376
//! @brief Service requester message type
377
const char* request_type;
378
379
//! @brief Service replier message type
380
const char* reply_type;
381
382
//! @brief Service requester topic name
383
const char* request_topic_name;
384
385
//! @brief Service replier topic name
386
const char* reply_topic_name;
387
388
//! @brief QoS for the service
389
const uxrQoS_t qos;
390
};
391
static const struct Service_table services[];
392
};
393
394
#endif // AP_DDS_ENABLED
395
396
397
398