Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
actuators_uavcan.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2021 Freek van Tienen <freek.v.tienen@gmail.com>
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
27 #include "actuators_uavcan.h"
29 #include "math/pprz_random.h"
30 #include "modules/core/abi.h"
32 
33 /* By default enable the usage of the current sensing in the ESC telemetry */
34 #ifndef UAVCAN_ACTUATORS_USE_CURRENT
35 #define UAVCAN_ACTUATORS_USE_CURRENT TRUE
36 #endif
37 
38 /* uavcan ESC status telemetry structure */
40  bool set;
42  float timestamp;
43  float voltage;
44  float current;
45  float temperature;
49  float position;
50 };
51 
52 /* The transmitted actuator values */
53 #ifdef SERVOS_UAVCAN1_NB
54 int16_t actuators_uavcan1_values[SERVOS_UAVCAN1_NB];
55 #endif
56 #ifdef SERVOS_UAVCAN2_NB
57 int16_t actuators_uavcan2_values[SERVOS_UAVCAN2_NB];
58 #endif
59 #ifdef SERVOS_UAVCAN1CMD_NB
60 int16_t actuators_uavcan1cmd_values[SERVOS_UAVCAN1CMD_NB];
61 #endif
62 #ifdef SERVOS_UAVCAN2CMD_NB
63 int16_t actuators_uavcan2cmd_values[SERVOS_UAVCAN2CMD_NB];
64 #endif
65 
66 /* Set the actual telemetry length (ID's from actuators can't collide with the command version) */
67 #if SERVOS_UAVCAN1CMD_NB > SERVOS_UAVCAN1_NB
68 #define UAVCAN1_TELEM_NB SERVOS_UAVCAN1CMD_NB
69 static struct actuators_uavcan_telem_t uavcan1_telem[SERVOS_UAVCAN1CMD_NB] = {0};
70 #elif defined(SERVOS_UAVCAN1_NB)
71 #define UAVCAN1_TELEM_NB SERVOS_UAVCAN1_NB
72 static struct actuators_uavcan_telem_t uavcan1_telem[SERVOS_UAVCAN1_NB] = {0};
73 #endif
74 
75 #if SERVOS_UAVCAN2CMD_NB > SERVOS_UAVCAN2_NB
76 #define UAVCAN2_TELEM_NB SERVOS_UAVCAN2CMD_NB
77 static struct actuators_uavcan_telem_t uavcan2_telem[SERVOS_UAVCAN2CMD_NB] = {0};
78 #elif defined(SERVOS_UAVCAN2_NB)
79 #define UAVCAN2_TELEM_NB SERVOS_UAVCAN2_NB
80 static struct actuators_uavcan_telem_t uavcan2_telem[SERVOS_UAVCAN2_NB] = {0};
81 #endif
82 
83 /* UNUSED value for CMD */
84 #define UAVCAN_CMD_UNUSED (MIN_PPRZ-1)
85 
86 /* uavcan EQUIPMENT_ESC_STATUS message definition */
87 #define UAVCAN_EQUIPMENT_ESC_STATUS_ID 1034
88 #define UAVCAN_EQUIPMENT_ESC_STATUS_SIGNATURE (0xA9AF28AEA2FBB254ULL)
89 #define UAVCAN_EQUIPMENT_ESC_STATUS_MAX_SIZE ((110 + 7)/8)
90 
91 /* uavcan EQUIPMENT_ESC_RAWCOMMAND message definition */
92 #define UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_ID 1030
93 #define UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_SIGNATURE (0x217F5C87D7EC951DULL)
94 #define UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_MAX_SIZE ((285 + 7)/8)
95 
96 /* uavcan EQUIPMENT_ACTUATOR_STATUS message definition */
97 #define UAVCAN_EQUIPMENT_ACTUATOR_STATUS_ID 1011
98 #define UAVCAN_EQUIPMENT_ACTUATOR_STATUS_SIGNATURE (0x5E9BBA44FAF1EA04ULL)
99 #define UAVCAN_EQUIPMENT_ACTUATOR_STATUS_MAX_SIZE ((64 + 7)/8)
100 
101 /* uavcan EQUIPMENT_ACTUATOR_ARRAYCOMMAND message definition */
102 #define UAVCAN_EQUIPMENT_ACTUATOR_ARRAYCOMMAND_ID 1010
103 #define UAVCAN_EQUIPMENT_ACTUATOR_ARRAYCOMMAND_SIGNATURE (0xD8A7486238EC3AF3ULL)
104 #define UAVCAN_EQUIPMENT_ACTUATOR_ARRAYCOMMAND_MAX_SIZE ((484 + 7)/8)
105 
106 /* uavcan EQUIMPENT_DEVICE_TEMPERATURE message definition */
107 #define UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_ID 1110
108 #define UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_SIGNATURE (0x70261C28A94144C6ULL)
109 #define UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_MAX_SIZE ((40 + 7)/8)
110 
111 /* private variables */
112 static bool actuators_uavcan_initialized = false;
116 
117 #if PERIODIC_TELEMETRY
119 
120 static uint8_t old_idx = 0;
121 static uint8_t esc_idx = 0;
123  // Randomness added for multiple transport devices
124  uint8_t add_idx = 0;
125  if (rand_uniform() > 0.02) {
126  add_idx = 1;
127  }
128 
129  // Find the next set telemetry
130  uint8_t offset = 0;
131 #ifdef UAVCAN1_TELEM_NB
132  for(uint8_t i = esc_idx - offset; i < UAVCAN1_TELEM_NB; i++) {
133  if(uavcan1_telem[i].set) {
134  old_idx = i + offset;
135  esc_idx = i + offset + add_idx;
136  return &uavcan1_telem[i];
137  } else {
138  esc_idx = i + offset + 1;
139  }
140  }
141  offset += UAVCAN1_TELEM_NB;
142 #endif
143 #ifdef UAVCAN2_TELEM_NB
144  for(uint8_t i = esc_idx - offset; i < UAVCAN2_TELEM_NB; i++) {
145  if(uavcan2_telem[i].set) {
146  old_idx = i + offset;
147  esc_idx = i + offset + add_idx;
148  return &uavcan2_telem[i];
149  } else {
150  esc_idx = i + offset + 1;
151  }
152  }
153  offset += UAVCAN2_TELEM_NB;
154 #endif
155 
156  // Going round or no telemetry found
157  esc_idx = 0;
158  return NULL;
159 }
160 
161 static void actuators_uavcan_send_esc(struct transport_tx *trans, struct link_device *dev)
162 {
163  // Find the correct telemetry (Try twice if going round)
165  if(telem == NULL) {
166  telem = actuators_uavcan_next_telem();
167  }
168 
169  // Safety check (no telemetry received 2 times)
170  if (telem == NULL) {
171  return;
172  }
173 
174  float power = telem->current * telem->voltage;
175  float rpm = telem->rpm;
176  float energy = telem->energy;
177  pprz_msg_send_ESC(trans, dev, AC_ID, &telem->current, &electrical.vsupply, &power,
178  &rpm, &telem->voltage, &energy, &telem->temperature, &telem->temperature_dev, &telem->node_id, &old_idx);
179 }
180 #endif
181 
185 static void actuators_uavcan_esc_status_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
186 {
188  uint16_t tmp_float;
189 
190  struct actuators_uavcan_telem_t *telem = NULL;
191  uint8_t max_id = 0;
192 #ifdef UAVCAN1_TELEM_NB
193  if (iface == &uavcan1) {
194  telem = uavcan1_telem;
195  max_id = UAVCAN1_TELEM_NB;
196  }
197 #endif
198 #ifdef UAVCAN2_TELEM_NB
199  if (iface == &uavcan2) {
200  telem = uavcan2_telem;
201  max_id = UAVCAN2_TELEM_NB;
202  }
203 #endif
204 
205  canardDecodeScalar(transfer, 105, 5, false, (void *)&esc_idx);
206  //Could not find the right interface
207  if (esc_idx >= max_id || telem == NULL || max_id == 0) {
208  return;
209  }
210  telem[esc_idx].set = true;
211  telem[esc_idx].node_id = transfer->source_node_id;
213  canardDecodeScalar(transfer, 0, 32, false, (void *)&telem[esc_idx].energy);
214  canardDecodeScalar(transfer, 32, 16, true, (void *)&tmp_float);
215  telem[esc_idx].voltage = canardConvertFloat16ToNativeFloat(tmp_float);
216  canardDecodeScalar(transfer, 48, 16, true, (void *)&tmp_float);
217  telem[esc_idx].current = canardConvertFloat16ToNativeFloat(tmp_float);
218  canardDecodeScalar(transfer, 64, 16, true, (void *)&tmp_float);
219  telem[esc_idx].temperature = canardConvertFloat16ToNativeFloat(tmp_float);
220  canardDecodeScalar(transfer, 80, 18, true, (void *)&telem[esc_idx].rpm);
221 
222  /* Specification says Kelvin, but some are transmitting in Celsius */
223  if (telem[esc_idx].temperature > 230.f) {
224  telem[esc_idx].temperature -= 273.15;
225  }
226 
227 #if UAVCAN_ACTUATORS_USE_CURRENT
228  // Update total current
229  electrical.current = 0;
230 #ifdef UAVCAN1_TELEM_NB
231  for (uint8_t i = 0; i < UAVCAN1_TELEM_NB; ++i) {
232  electrical.current += uavcan1_telem[i].current;
233  }
234 #endif
235 #ifdef UAVCAN2_TELEM_NB
236  for (uint8_t i = 0; i < UAVCAN2_TELEM_NB; ++i) {
237  electrical.current += uavcan2_telem[i].current;
238  }
239 #endif
240 #endif
241 
242  // Feedback ABI RPM messages
243 #ifdef UAVCAN1_TELEM_NB
244  if (iface == &uavcan1) {
245  struct act_feedback_t feedback = {0};
246  feedback.rpm = telem[esc_idx].rpm;
247  feedback.set.rpm = true;
248 
249 #ifdef SERVOS_UAVCAN1_NB
250  feedback.idx = get_servo_idx_UAVCAN1(esc_idx);
251 #endif
252 #ifdef SERVOS_UAVCAN1CMD_NB
253  if(esc_idx < SERVOS_UAVCAN1CMD_NB && actuators_uavcan1cmd_values[esc_idx] != UAVCAN_CMD_UNUSED) {
254  feedback.idx = get_servo_idx_UAVCAN1CMD(esc_idx);
255  }
256 #endif
257 
258  // Send ABI message
259  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_UAVCAN_ID, &feedback, 1);
260  }
261 #endif
262 #ifdef UAVCAN2_TELEM_NB
263  if (iface == &uavcan2) {
264  struct act_feedback_t feedback = {0};
265  feedback.rpm = telem[esc_idx].rpm;
266  feedback.set.rpm = true;
267 
268 #ifdef SERVOS_UAVCAN2_NB
269  feedback.idx = get_servo_idx_UAVCAN2(esc_idx);
270 #endif
271 #ifdef SERVOS_UAVCAN2CMD_NB
272  if(esc_idx < SERVOS_UAVCAN2CMD_NB && actuators_uavcan2cmd_values[esc_idx] != UAVCAN_CMD_UNUSED) {
273  feedback.idx = get_servo_idx_UAVCAN2CMD(esc_idx);
274  }
275 #endif
276 
277  // Send ABI message
278  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_UAVCAN_ID, &feedback, 1);
279  }
280 #endif
281 }
282 
286 static void actuators_uavcan_actuator_status_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
287 {
288  uint8_t actuator_idx;
289  uint16_t tmp_float;
290 
291  struct actuators_uavcan_telem_t *telem = NULL;
292  uint8_t max_id = 0;
293 #ifdef UAVCAN1_TELEM_NB
294  if (iface == &uavcan1) {
295  telem = uavcan1_telem;
296  max_id = UAVCAN1_TELEM_NB;
297  }
298 #endif
299 #ifdef UAVCAN2_TELEM_NB
300  if (iface == &uavcan2) {
301  telem = uavcan2_telem;
302  max_id = UAVCAN2_TELEM_NB;
303  }
304 #endif
305 
306  canardDecodeScalar(transfer, 0, 8, false, (void *)&actuator_idx);
307  //Could not find the right interface
308  if (actuator_idx >= max_id || telem == NULL || max_id == 0) {
309  return;
310  }
311 
312  //telem[actuator_idx].set = true;
313  canardDecodeScalar(transfer, 8, 16, true, (void *)&tmp_float);
314  telem[actuator_idx].position = canardConvertFloat16ToNativeFloat(tmp_float);
315 
316 #ifdef UAVCAN1_TELEM_NB
317  if (iface == &uavcan1) {
318  struct act_feedback_t feedback = {0};
319  feedback.position = telem[actuator_idx].position;
320  feedback.set.position = true;
321 
322 #ifdef SERVOS_UAVCAN1_NB
323  feedback.idx = get_servo_idx_UAVCAN1(actuator_idx);
324 #endif
325 #ifdef SERVOS_UAVCAN1CMD_NB
326  if(actuator_idx < SERVOS_UAVCAN1CMD_NB && actuators_uavcan1cmd_values[actuator_idx] != UAVCAN_CMD_UNUSED) {
327  feedback.idx = get_servo_idx_UAVCAN1CMD(actuator_idx);
328  }
329 #endif
330 
331  // Send ABI message
332  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_UAVCAN_ID, &feedback, 1);
333  }
334 #endif
335 
336 #ifdef UAVCAN2_TELEM_NB
337  if (iface == &uavcan2) {
338  struct act_feedback_t feedback = {0};
339  feedback.position = telem[actuator_idx].position;
340  feedback.set.position = true;
341 
342 #ifdef SERVOS_UAVCAN2_NB
343  feedback.idx = get_servo_idx_UAVCAN2(actuator_idx);
344 #endif
345 #ifdef SERVOS_UAVCAN2CMD_NB
346  if(actuator_idx < SERVOS_UAVCAN2CMD_NB && actuators_uavcan2cmd_values[actuator_idx] != UAVCAN_CMD_UNUSED) {
347  feedback.idx = get_servo_idx_UAVCAN2CMD(actuator_idx);
348  }
349 #endif
350 
351  // Send ABI message
352  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_UAVCAN_ID, &feedback, 1);
353  }
354 #endif
355 }
356 
360 static void actuators_uavcan_device_temperature_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
361 {
362  uint16_t device_id;
363  uint16_t tmp_float;
364 
365  struct actuators_uavcan_telem_t *telem = NULL;
366  uint8_t max_id = 0;
367 #ifdef UAVCAN1_TELEM_NB
368  if (iface == &uavcan1) {
369  telem = uavcan1_telem;
370  max_id = UAVCAN1_TELEM_NB;
371  }
372 #endif
373 #ifdef UAVCAN2_TELEM_NB
374  if (iface == &uavcan2) {
375  telem = uavcan2_telem;
376  max_id = UAVCAN2_TELEM_NB;
377  }
378 #endif
379 
380 
381  canardDecodeScalar(transfer, 0, 16, false, (void*)&device_id);
382  //Could not find the right interface
383  if (device_id >= max_id || telem == NULL || max_id == 0) {
384  return;
385  }
386 
387  telem[device_id].set = true;
388  canardDecodeScalar(transfer, 16, 16, false, (void*)&tmp_float);
389  telem[device_id].temperature_dev = canardConvertFloat16ToNativeFloat(tmp_float) - 273.15;
390 }
391 
392 
396 void actuators_uavcan_init(struct uavcan_iface_t *iface __attribute__((unused)))
397 {
398  // Check if not already initialized (for multiple interfaces, needs only 1)
399  if (actuators_uavcan_initialized) { return; }
400 
401  // Bind uavcan ESC_STATUS message from EQUIPMENT
404  // Bind uavcan ACTUATOR_STATUS message from EQUIPMENT
407  // Bind uavcan DEVICE_TEMPERATURE message from EQUIPMENT
410 
411  // Configure telemetry
412 #if PERIODIC_TELEMETRY
414 #endif
415 
416  // Set default to not set
417 #ifdef SERVOS_UAVCAN1CMD_NB
418  for(uint8_t i = 0; i < SERVOS_UAVCAN1CMD_NB; i++)
420 #endif
421 #ifdef SERVOS_UAVCAN2CMD_NB
422  for(uint8_t i = 0; i < SERVOS_UAVCAN2CMD_NB; i++)
424 #endif
425 
426  // Set initialization
428 
429  // Initialize Random (for telemetry)
430  init_random();
431 }
432 
436 void actuators_uavcan_commit(struct uavcan_iface_t *iface, int16_t *values, uint8_t nb)
437 {
439  uint32_t offset = 0;
440 
441  // Encode the values as 14-bit signed integers
442  for (uint8_t i = 0; i < nb; i++) {
443  canardEncodeScalar(buffer, offset, 14, (void *)&values[i]);
444  offset += 14;
445  }
446 
447  // Broadcast the raw command message on the interface
449  CANARD_TRANSFER_PRIORITY_HIGH, buffer, (offset + 7) / 8);
450 }
451 
456 {
458  uint32_t offset = 0;
459  uint8_t command_type = 0; // 0:UNITLESS, 1:meter or radian, 2:N or Nm, 3:m/s or rad/s
460 
461  // Encode the values for each command
462  for (uint8_t i = 0; i < nb; i++) {
463  // Skip unused commands
464  if(values[i] == UAVCAN_CMD_UNUSED || values[i] < MIN_PPRZ || values[i] > MAX_PPRZ)
465  continue;
466 
467  // Set the command id
468  canardEncodeScalar(buffer, offset, 8, (void*)&i); // 255
469  offset += 8;
470 
471  // Set the command type
472  canardEncodeScalar(buffer, offset, 8, (void*)&command_type); // 255
473  offset += 8;
474 
475  // Set the command value
476  uint16_t tmp_float = canardConvertNativeFloatToFloat16((float)values[i] / (float)MAX_PPRZ);
477  canardEncodeScalar(buffer, offset, 16, (void*)&tmp_float); // 32767
478  offset += 16;
479  }
480 
481  // Broadcast the raw command message on the interface
483  CANARD_TRANSFER_PRIORITY_HIGH, buffer, (offset + 7) / 8);
484 }
Main include for ABI (AirBorneInterface).
#define ACT_FEEDBACK_UAVCAN_ID
int16_t actuators_uavcan1_values[SERVOS_UAVCAN1_NB]
Stub file needed per uavcan interface because of generator.
int16_t actuators_uavcan1cmd_values[SERVOS_UAVCAN1CMD_NB]
Stub file needed per uavcan interface because of generator.
int16_t actuators_uavcan2_values[SERVOS_UAVCAN2_NB]
Stub file needed per interface because of generator.
int16_t actuators_uavcan2cmd_values[SERVOS_UAVCAN2CMD_NB]
Stub file needed per uavcan interface because of generator.
#define UAVCAN_EQUIPMENT_ESC_STATUS_ID
static void actuators_uavcan_send_esc(struct transport_tx *trans, struct link_device *dev)
void actuators_uavcan_init(struct uavcan_iface_t *iface)
Initialize an uavcan interface.
static void actuators_uavcan_device_temperature_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
Whevener an DEVICE_TEMPERATURE message from the EQUIPMENT group is received.
static uavcan_event actuator_status_ev
#define UAVCAN_EQUIPMENT_ACTUATOR_ARRAYCOMMAND_MAX_SIZE
#define UAVCAN_EQUIPMENT_ESC_STATUS_SIGNATURE
void actuators_uavcan_commit(struct uavcan_iface_t *iface, int16_t *values, uint8_t nb)
Commit actuator values to the uavcan interface (EQUIPMENT_ESC_RAWCOMMAND)
#define UAVCAN_EQUIPMENT_ACTUATOR_ARRAYCOMMAND_ID
#define UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_SIGNATURE
static struct actuators_uavcan_telem_t * actuators_uavcan_next_telem(void)
#define UAVCAN_EQUIPMENT_ACTUATOR_ARRAYCOMMAND_SIGNATURE
static void actuators_uavcan_esc_status_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
Whevener an ESC_STATUS message from the EQUIPMENT group is received.
static uavcan_event device_temperature_ev
static void actuators_uavcan_actuator_status_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
Whevener an ACTUATOR_STATUS message from the EQUIPMENT group is received.
static bool actuators_uavcan_initialized
#define UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_SIGNATURE
static uint8_t old_idx
static uint8_t esc_idx
#define UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_ID
void actuators_uavcan_cmd_commit(struct uavcan_iface_t *iface, int16_t *values, uint8_t nb)
Commit actuator values to the uavcan interface (EQUIPMENT_ACTUATOR_ARRAYCOMMAND)
#define UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_ID
#define UAVCAN_EQUIPMENT_ACTUATOR_STATUS_SIGNATURE
#define UAVCAN_CMD_UNUSED
static uavcan_event esc_status_ev
#define UAVCAN_EQUIPMENT_ESC_RAWCOMMAND_MAX_SIZE
#define UAVCAN_EQUIPMENT_ACTUATOR_STATUS_ID
Main uavcan event structure for registering/calling callbacks.
Definition: uavcan.h:60
static const float offset[]
struct Electrical electrical
Definition: electrical.c:92
Interface for electrical status: supply voltage, current, battery status, etc.
float current
current in A
Definition: electrical.h:47
float vsupply
supply voltage in V
Definition: electrical.h:45
Hardware independent API for actuators (servos, motor controllers).
int32_t rpm
RPM.
Definition: actuators.h:51
bool position
Position is set.
Definition: actuators.h:48
struct act_feedback_t::act_feedback_set_t set
Bitset registering what is set as feedback.
uint8_t idx
General index of the actuators (generated in airframe.h)
Definition: actuators.h:45
float position
In radians.
Definition: actuators.h:52
#define MAX_PPRZ
Definition: paparazzi.h:8
#define MIN_PPRZ
Definition: paparazzi.h:9
void init_random(void)
Definition: pprz_random.c:35
double rand_uniform(void)
Definition: pprz_random.c:45
uint16_t rpm
Definition: rpm_sensor.c:33
uavcan interface structure
Definition: uavcan.h:34
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
static float get_sys_time_float(void)
Get the time in seconds since startup.
Definition: sys_time.h:138
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition: telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition: telemetry.h:66
void uavcan_broadcast(struct uavcan_iface_t *iface, uint64_t data_type_signature, uint16_t data_type_id, uint8_t priority, const void *payload, uint16_t payload_len)
Broadcast an uavcan message to a specific interface.
Definition: uavcan.c:427
void uavcan_bind(uint16_t data_type_id, uint64_t data_type_signature, uavcan_event *ev, uavcan_callback cb)
Bind to a receiving message from uavcan.
Definition: uavcan.c:412
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
int int32_t
Typedef defining 32 bit int type.
Definition: vl53l1_types.h:83
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
short int16_t
Typedef defining 16 bit short type.
Definition: vl53l1_types.h:93
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
int transfer(const Mat *from, const image_t *to)