Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
actuators.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006 Pascal Brisset, Antoine Drouin
3 * Copyright (C) 2012 Gautier Hattenberger
4 *
5 * This file is part of paparazzi.
6 *
7 * paparazzi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * paparazzi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with paparazzi; see the file COPYING. If not, write to
19 * the Free Software Foundation, 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
30#include "mcu_periph/sys_time.h"
31#ifdef INTERMCU_AP
33#endif
34#ifdef INTERMCU_FBW
35#include "main_fbw.h"
36#endif
37
38#if ACTUATORS_NB
39
40#if PERIODIC_TELEMETRY
42
43static void send_actuators_raw(struct transport_tx *trans, struct link_device *dev)
44{
45 // Downlink the actuators raw driver values
46 int16_t v[ACTUATORS_NB] = {0};
47 for (int i = 0; i < ACTUATORS_NB; i++) {
48 v[i] = actuators[i].driver_val;
49 }
51}
52
53static void send_actuators(struct transport_tx *trans, struct link_device *dev)
54{
55 // Downlink the actuators pprz actuator values
56 int16_t v[ACTUATORS_NB] = {0};
57 for (int i = 0; i < ACTUATORS_NB; i++) {
58 v[i] = actuators[i].pprz_val;
59 }
61}
62#endif
63
65
68
69#if USE_SHELL
70#include "modules/core/shell.h"
71#include "printf.h"
72#include "string.h"
73
74static void show_actuator(shell_stream_t *sh, uint8_t i) {
75 chprintf(sh, "Actuator %d: driver no %d, servo idx %d\r\n", i,
76 actuators[i].config.driver_no, actuators[i].config.servo_idx);
77 chprintf(sh, " min: %d, max: %d, neutral %d\r\n",
78 actuators[i].config.min, actuators[i].config.max, actuators[i].config.neutral);
79 if (actuators[i].set == NULL) {
80 chprintf(sh, " no set function registered");
81 }
82 chprintf(sh, " pprz value : %d\r\n", actuators[i].pprz_val);
83 chprintf(sh, " driver value: %d\r\n", actuators[i].driver_val);
84}
85
86static void cmd_actuator(shell_stream_t *sh, int argc, const char *const argv[])
87{
88 (void) argv;
89 if (argc == 0) {
90 chprintf(sh, "Usage: actuator [command] [options]\r\n");
91 chprintf(sh, " show [pprz_idx] Print list of actuators with their config or a single one\r\n");
92 chprintf(sh, " get_pprz pprz_idx Get current actuator value in pprz unit\r\n");
93 chprintf(sh, " get_driver driver_no servo_idx Get current actuator value in driver unit\r\n");
94 chprintf(sh, " set_pprz pprz_idx value Set actuator value in pprz unit (values are bounded to [-9600; 9600])\r\n");
95 chprintf(sh, " set_driver driver_no servo_idx value Set actuator value in driver unit (warning: values are not bounded)\r\n");
96 chprintf(sh, " set_conf pprz_idx min max neutral Set actuator min, max and neutral values in driver unit (warning: values are not bounded)\r\n");
97 return;
98 }
99
100 if (argc >= 1) {
101 if (strcmp(argv[0], "show") == 0) {
102 if (argc == 1) {
103 for (int i = 0; i < ACTUATORS_NB; i++) {
104 show_actuator(sh, i);
105 }
106 } else {
107 uint8_t idx = atoi(argv[1]);
108 show_actuator(sh, idx);
109 }
110 } else if (strcmp(argv[0], "get_pprz") == 0) {
111 if (argc >= 2) {
112 uint8_t idx = atoi(argv[1]);
113 chprintf(sh, "%d\r\n", actuators[idx].pprz_val);
114 }
115 } else if (strcmp(argv[0], "get_driver") == 0) {
116 if (argc >= 3) {
117 uint8_t d_idx = atoi(argv[1]);
118 uint8_t s_idx = atoi(argv[2]);
120 }
121 } else if (strcmp(argv[0], "set_pprz") == 0) {
122 if (argc >= 3) {
123 uint8_t idx = atoi(argv[1]);
124 int16_t val = atoi(argv[2]);
126 }
127 } else if (strcmp(argv[0], "set_driver") == 0) {
128 if (argc >= 4) {
129 uint8_t d_idx = atoi(argv[1]);
130 uint8_t s_idx = atoi(argv[2]);
132 int16_t val = atoi(argv[3]);
133 actuators[p_idx].driver_val = val;
134 if (actuators[p_idx].set != NULL) {
135 actuators[p_idx].set(actuators[p_idx].config.servo_idx, actuators[p_idx].driver_val);
136 }
137 }
138 } else if (strcmp(argv[0], "set_conf") == 0) {
139 if (argc >= 5) {
140 uint8_t idx = atoi(argv[1]);
141 int32_t min = atoi(argv[2]);
142 int32_t max = atoi(argv[3]);
143 int32_t neutral = atoi(argv[4]);
144 uint8_t d_idx = actuators[idx].config.driver_no;
145 uint8_t s_idx = actuators[idx].config.servo_idx;
149 }
150 } else {
151 chprintf(sh, "unknown actuator command\r\n");
152 }
153 }
154}
155
156#endif // USE_SHELL
157
158void actuators_init(void)
159{
160
161#if defined ACTUATORS_START_DELAY && ! defined SITL
162 actuators_delay_done = false;
164#else
167#endif
168
169 // Init macro from generated airframe.h
170#if (defined INTERMCU_AP)
171 // TODO ApOnlyActuatorsInit();
172#elif (defined INTERMCU_FBW)
174#else
175 // default, init all actuators
177 // TODO ApOnlyActuatorsInit();
178#endif
179
180#if PERIODIC_TELEMETRY
183#endif
184
185#if USE_SHELL
186 shell_add_entry("actuator", cmd_actuator);
187#endif
188
189}
190
195void actuators_periodic(void)
196{
197#if USE_COMMANDS
199 int i;
200 for (i = 0; i < COMMANDS_NB; i++) {trimmed_commands[i] = commands[i];}
201
202#ifdef COMMAND_ROLL
204#endif /* COMMAND_ROLL */
205
206#ifdef COMMAND_PITCH
208#endif /* COMMAND_PITCH */
209
210#ifdef COMMAND_YAW
212#endif /* COMMAND_YAW */
213
214#if (defined INTERMCU_AP)
216 // TODO SetApOnlyActuatorsFromCommands(ap_commands, autopilot_get_mode());
217#elif (defined INTERMCU_FBW)
219#else
220 // default, apply all commands
222 // TODO SetApOnlyActuatorsFromCommands(ap_commands, autopilot_get_mode());
223#endif
224#endif // USE_COMMANDS
225}
226
228{
231
233 command_value = actuators[pprz_idx].pprz_val * (pprz_value>0 ? actuators[pprz_idx].config.travel_up : actuators[pprz_idx].config.travel_down);
234 servo_value = actuators[pprz_idx].config.neutral + command_value;
235 actuators[pprz_idx].driver_val = Clip(servo_value, actuators[pprz_idx].config.min, actuators[pprz_idx].config.max);
236 if (actuators[pprz_idx].set != NULL) {
237 actuators[pprz_idx].set(actuators[pprz_idx].config.servo_idx, actuators[pprz_idx].driver_val);
238 }
239}
240
242{
243 return actuators[pprz_idx].driver_val;
244}
245
249uint8_t actuator_get_idx(uint8_t driver_no, uint8_t servo_idx)
250{
251 uint8_t i = 0;
252 for (i = 0; i < ACTUATORS_NB; i++) {
253 if (actuators[i].config.driver_no == driver_no &&
254 actuators[i].config.servo_idx == servo_idx) {
255 break;
256 }
257 }
258 return i; // returns ACTUATORS_NB if not found
259}
260
261int32_t actuator_get_min(uint8_t driver_no, uint8_t servo_idx)
262{
263 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
264 if (idx != ACTUATORS_NB) {
265 return actuators[idx].config.min;
266 }
267 return 0;
268}
269
270int32_t actuator_get_max(uint8_t driver_no, uint8_t servo_idx)
271{
272 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
273 if (idx != ACTUATORS_NB) {
274 return actuators[idx].config.max;
275 }
276 return 0;
277}
278
279int32_t actuator_get_neutral(uint8_t driver_no, uint8_t servo_idx)
280{
281 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
282 if (idx != ACTUATORS_NB) {
283 return actuators[idx].config.neutral;
284 }
285 return 0;
286}
287
288void actuator_set_min(uint8_t driver_no, uint8_t servo_idx, int32_t min)
289{
290 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
291 if (idx == ACTUATORS_NB) return; // wrong index
292 actuators[idx].config.min = min;
293 int32_t delta = actuators[idx].config.neutral - min;
294 actuators[idx].config.travel_down = (float) delta / MAX_PPRZ;
295}
296
297void actuator_set_max(uint8_t driver_no, uint8_t servo_idx, int32_t max)
298{
299 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
300 if (idx == ACTUATORS_NB) return; // wrong index
301 actuators[idx].config.max = max;
302 int32_t delta = max - actuators[idx].config.neutral;
303 actuators[idx].config.travel_up = (float) delta / MAX_PPRZ;
304}
305
306void actuator_set_neutral(uint8_t driver_no, uint8_t servo_idx, int32_t neutral)
307{
308 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
309 if (idx == ACTUATORS_NB) return; // wrong index
310 actuators[idx].config.neutral = neutral;
311 int32_t delta_max = actuators[idx].config.max - neutral;
312 actuators[idx].config.travel_up = (float) delta_max / MAX_PPRZ;
313 int32_t delta_min = neutral - actuators[idx].config.min;
314 actuators[idx].config.travel_down = (float) delta_min / MAX_PPRZ;
315}
316
317
318
319#else // No command_laws section or no actuators
320
321void actuators_init(void) {}
323
324#endif
uint8_t autopilot_get_mode(void)
get autopilot mode
Definition autopilot.c:222
pprz_t command_pitch_trim
Definition commands.c:34
pprz_t command_roll_trim
Definition commands.c:33
pprz_t command_yaw_trim
Definition commands.c:35
Hardware independent code for commands handling.
static void send_actuators(struct transport_tx *trans, struct link_device *dev)
void chprintf(BaseSequentialStream *lchp, const char *fmt,...)
Definition printf.c:395
void intermcu_send_commands(pprz_t *command_values, uint8_t ap_mode)
send command vector over intermcu link instead of actuators
Inter-MCU on the AP side.
uint16_t foo
Definition main_demo5.c:58
Fly By Wire:
void actuators_periodic(void)
Definition actuators.c:322
void actuators_init(void)
Definition actuators.c:321
Hardware independent API for actuators (servos, motor controllers).
static uint32_t idx
int16_t pprz_t
Definition paparazzi.h:6
#define MAX_PPRZ
Definition paparazzi.h:8
Mini printf-like functionality.
static const ShellCommand commands[]
Definition shell_arch.c:78
void shell_add_entry(char *cmd_name, shell_cmd_t *cmd)
Add dynamic entry.
Definition shell_arch.c:92
BaseSequentialStream shell_stream_t
Definition shell_arch.h:31
static const struct usb_config_descriptor config
Definition usb_ser_hw.c:200
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
Architecture independent timing functions.
#define SysTimeTimerStart(_t)
Definition sys_time.h:256
int16_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint16_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
uint16_t val[TCOUPLE_NB]
int int32_t
Typedef defining 32 bit int type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
short int16_t
Typedef defining 16 bit short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.