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) - 273.15;
220  canardDecodeScalar(transfer, 80, 18, true, (void *)&telem[esc_idx].rpm);
221 
222 #if UAVCAN_ACTUATORS_USE_CURRENT
223  // Update total current
224  electrical.current = 0;
225 #ifdef UAVCAN1_TELEM_NB
226  for (uint8_t i = 0; i < UAVCAN1_TELEM_NB; ++i) {
227  electrical.current += uavcan1_telem[i].current;
228  }
229 #endif
230 #ifdef UAVCAN2_TELEM_NB
231  for (uint8_t i = 0; i < UAVCAN2_TELEM_NB; ++i) {
232  electrical.current += uavcan2_telem[i].current;
233  }
234 #endif
235 #endif
236 
237  // Feedback ABI RPM messages
238 #ifdef UAVCAN1_TELEM_NB
239  if (iface == &uavcan1) {
240  struct act_feedback_t feedback = {0};
241  feedback.rpm = telem[esc_idx].rpm;
242  feedback.set.rpm = true;
243 
244 #ifdef SERVOS_UAVCAN1_NB
245  feedback.idx = get_servo_idx_UAVCAN1(esc_idx);
246 #endif
247 #ifdef SERVOS_UAVCAN1CMD_NB
248  if(esc_idx < SERVOS_UAVCAN1CMD_NB && actuators_uavcan1cmd_values[esc_idx] != UAVCAN_CMD_UNUSED) {
249  feedback.idx = get_servo_idx_UAVCAN1CMD(esc_idx);
250  }
251 #endif
252 
253  // Send ABI message
254  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_UAVCAN_ID, &feedback, 1);
255  }
256 #endif
257 #ifdef UAVCAN2_TELEM_NB
258  if (iface == &uavcan2) {
259  struct act_feedback_t feedback = {0};
260  feedback.rpm = telem[esc_idx].rpm;
261  feedback.set.rpm = true;
262 
263 #ifdef SERVOS_UAVCAN2_NB
264  feedback.idx = get_servo_idx_UAVCAN2(esc_idx);
265 #endif
266 #ifdef SERVOS_UAVCAN2CMD_NB
267  if(esc_idx < SERVOS_UAVCAN2CMD_NB && actuators_uavcan2cmd_values[esc_idx] != UAVCAN_CMD_UNUSED) {
268  feedback.idx = get_servo_idx_UAVCAN2CMD(esc_idx);
269  }
270 #endif
271 
272  // Send ABI message
273  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_UAVCAN_ID, &feedback, 1);
274  }
275 #endif
276 }
277 
281 static void actuators_uavcan_actuator_status_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
282 {
283  uint8_t actuator_idx;
284  uint16_t tmp_float;
285 
286  struct actuators_uavcan_telem_t *telem = NULL;
287  uint8_t max_id = 0;
288 #ifdef UAVCAN1_TELEM_NB
289  if (iface == &uavcan1) {
290  telem = uavcan1_telem;
291  max_id = UAVCAN1_TELEM_NB;
292  }
293 #endif
294 #ifdef UAVCAN2_TELEM_NB
295  if (iface == &uavcan2) {
296  telem = uavcan2_telem;
297  max_id = UAVCAN2_TELEM_NB;
298  }
299 #endif
300 
301  canardDecodeScalar(transfer, 0, 8, false, (void *)&actuator_idx);
302  //Could not find the right interface
303  if (actuator_idx >= max_id || telem == NULL || max_id == 0) {
304  return;
305  }
306 
307  //telem[actuator_idx].set = true;
308  canardDecodeScalar(transfer, 8, 16, true, (void *)&tmp_float);
309  telem[actuator_idx].position = canardConvertFloat16ToNativeFloat(tmp_float);
310 
311 #ifdef UAVCAN1_TELEM_NB
312  if (iface == &uavcan1) {
313  struct act_feedback_t feedback = {0};
314  feedback.position = telem[actuator_idx].position;
315  feedback.set.position = true;
316 
317 #ifdef SERVOS_UAVCAN1_NB
318  feedback.idx = get_servo_idx_UAVCAN1(actuator_idx);
319 #endif
320 #ifdef SERVOS_UAVCAN1CMD_NB
321  if(actuator_idx < SERVOS_UAVCAN1CMD_NB && actuators_uavcan1cmd_values[actuator_idx] != UAVCAN_CMD_UNUSED) {
322  feedback.idx = get_servo_idx_UAVCAN1CMD(actuator_idx);
323  }
324 #endif
325 
326  // Send ABI message
327  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_UAVCAN_ID, &feedback, 1);
328  }
329 #endif
330 
331 #ifdef UAVCAN2_TELEM_NB
332  if (iface == &uavcan2) {
333  struct act_feedback_t feedback = {0};
334  feedback.position = telem[actuator_idx].position;
335  feedback.set.position = true;
336 
337 #ifdef SERVOS_UAVCAN2_NB
338  feedback.idx = get_servo_idx_UAVCAN2(actuator_idx);
339 #endif
340 #ifdef SERVOS_UAVCAN2CMD_NB
341  if(actuator_idx < SERVOS_UAVCAN2CMD_NB && actuators_uavcan2cmd_values[actuator_idx] != UAVCAN_CMD_UNUSED) {
342  feedback.idx = get_servo_idx_UAVCAN2CMD(actuator_idx);
343  }
344 #endif
345 
346  // Send ABI message
347  AbiSendMsgACT_FEEDBACK(ACT_FEEDBACK_UAVCAN_ID, &feedback, 1);
348  }
349 #endif
350 }
351 
355 static void actuators_uavcan_device_temperature_cb(struct uavcan_iface_t *iface, CanardRxTransfer *transfer)
356 {
357  uint16_t device_id;
358  uint16_t tmp_float;
359 
360  struct actuators_uavcan_telem_t *telem = NULL;
361  uint8_t max_id = 0;
362 #ifdef UAVCAN1_TELEM_NB
363  if (iface == &uavcan1) {
364  telem = uavcan1_telem;
365  max_id = UAVCAN1_TELEM_NB;
366  }
367 #endif
368 #ifdef UAVCAN2_TELEM_NB
369  if (iface == &uavcan2) {
370  telem = uavcan2_telem;
371  max_id = UAVCAN2_TELEM_NB;
372  }
373 #endif
374 
375 
376  canardDecodeScalar(transfer, 0, 16, false, (void*)&device_id);
377  //Could not find the right interface
378  if (device_id >= max_id || telem == NULL || max_id == 0) {
379  return;
380  }
381 
382  telem[device_id].set = true;
383  canardDecodeScalar(transfer, 16, 16, false, (void*)&tmp_float);
384  telem[device_id].temperature_dev = canardConvertFloat16ToNativeFloat(tmp_float) - 273.15;
385 }
386 
387 
391 void actuators_uavcan_init(struct uavcan_iface_t *iface __attribute__((unused)))
392 {
393  // Check if not already initialized (for multiple interfaces, needs only 1)
394  if (actuators_uavcan_initialized) { return; }
395 
396  // Bind uavcan ESC_STATUS message from EQUIPMENT
399  // Bind uavcan ACTUATOR_STATUS message from EQUIPMENT
402  // Bind uavcan DEVICE_TEMPERATURE message from EQUIPMENT
405 
406  // Configure telemetry
407 #if PERIODIC_TELEMETRY
409 #endif
410 
411  // Set default to not set
412 #ifdef SERVOS_UAVCAN1CMD_NB
413  for(uint8_t i = 0; i < SERVOS_UAVCAN1CMD_NB; i++)
415 #endif
416 #ifdef SERVOS_UAVCAN2CMD_NB
417  for(uint8_t i = 0; i < SERVOS_UAVCAN2CMD_NB; i++)
419 #endif
420 
421  // Set initialization
423 
424  // Initialize Random (for telemetry)
425  init_random();
426 }
427 
431 void actuators_uavcan_commit(struct uavcan_iface_t *iface, int16_t *values, uint8_t nb)
432 {
434  uint32_t offset = 0;
435 
436  // Encode the values as 14-bit signed integers
437  for (uint8_t i = 0; i < nb; i++) {
438  canardEncodeScalar(buffer, offset, 14, (void *)&values[i]);
439  offset += 14;
440  }
441 
442  // Broadcast the raw command message on the interface
444  CANARD_TRANSFER_PRIORITY_HIGH, buffer, (offset + 7) / 8);
445 }
446 
451 {
453  uint32_t offset = 0;
454  uint8_t command_type = 0; // 0:UNITLESS, 1:meter or radian, 2:N or Nm, 3:m/s or rad/s
455 
456  // Encode the values for each command
457  for (uint8_t i = 0; i < nb; i++) {
458  // Skip unused commands
459  if(values[i] == UAVCAN_CMD_UNUSED || values[i] < MIN_PPRZ || values[i] > MAX_PPRZ)
460  continue;
461 
462  // Set the command id
463  canardEncodeScalar(buffer, offset, 8, (void*)&i); // 255
464  offset += 8;
465 
466  // Set the command type
467  canardEncodeScalar(buffer, offset, 8, (void*)&command_type); // 255
468  offset += 8;
469 
470  // Set the command value
471  uint16_t tmp_float = canardConvertNativeFloatToFloat16((float)values[i] / (float)MAX_PPRZ);
472  canardEncodeScalar(buffer, offset, 16, (void*)&tmp_float); // 32767
473  offset += 16;
474  }
475 
476  // Broadcast the raw command message on the interface
478  CANARD_TRANSFER_PRIORITY_HIGH, buffer, (offset + 7) / 8);
479 }
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)