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
66// Can be used to directly control each actuator from the control algorithm
68
71
72#if USE_SHELL
73#include "modules/core/shell.h"
74#include "printf.h"
75#include "string.h"
76
77static void show_actuator(shell_stream_t *sh, uint8_t i) {
78 chprintf(sh, "Actuator %d: driver no %d, servo idx %d\r\n", i,
79 actuators[i].config.driver_no, actuators[i].config.servo_idx);
80 chprintf(sh, " min: %d, max: %d, neutral %d\r\n",
81 actuators[i].config.min, actuators[i].config.max, actuators[i].config.neutral);
82 if (actuators[i].set == NULL) {
83 chprintf(sh, " no set function registered");
84 }
85 chprintf(sh, " pprz value : %d\r\n", actuators[i].pprz_val);
86 chprintf(sh, " driver value: %d\r\n", actuators[i].driver_val);
87}
88
89static void cmd_actuator(shell_stream_t *sh, int argc, const char *const argv[])
90{
91 (void) argv;
92 if (argc == 0) {
93 chprintf(sh, "Usage: actuator [command] [options]\r\n");
94 chprintf(sh, " show [pprz_idx] Print list of actuators with their config or a single one\r\n");
95 chprintf(sh, " get_pprz pprz_idx Get current actuator value in pprz unit\r\n");
96 chprintf(sh, " get_driver driver_no servo_idx Get current actuator value in driver unit\r\n");
97 chprintf(sh, " set_pprz pprz_idx value Set actuator value in pprz unit (values are bounded to [-9600; 9600])\r\n");
98 chprintf(sh, " set_driver driver_no servo_idx value Set actuator value in driver unit (warning: values are not bounded)\r\n");
99 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");
100 return;
101 }
102
103 if (argc >= 1) {
104 if (strcmp(argv[0], "show") == 0) {
105 if (argc == 1) {
106 for (int i = 0; i < ACTUATORS_NB; i++) {
107 show_actuator(sh, i);
108 }
109 } else {
110 uint8_t idx = atoi(argv[1]);
111 show_actuator(sh, idx);
112 }
113 } else if (strcmp(argv[0], "get_pprz") == 0) {
114 if (argc >= 2) {
115 uint8_t idx = atoi(argv[1]);
116 chprintf(sh, "%d\r\n", actuators[idx].pprz_val);
117 }
118 } else if (strcmp(argv[0], "get_driver") == 0) {
119 if (argc >= 3) {
120 uint8_t d_idx = atoi(argv[1]);
121 uint8_t s_idx = atoi(argv[2]);
123 }
124 } else if (strcmp(argv[0], "set_pprz") == 0) {
125 if (argc >= 3) {
126 uint8_t idx = atoi(argv[1]);
127 int16_t val = atoi(argv[2]);
129 }
130 } else if (strcmp(argv[0], "set_driver") == 0) {
131 if (argc >= 4) {
132 uint8_t d_idx = atoi(argv[1]);
133 uint8_t s_idx = atoi(argv[2]);
135 int16_t val = atoi(argv[3]);
136 actuators[p_idx].driver_val = val;
137 if (actuators[p_idx].set != NULL) {
138 actuators[p_idx].set(actuators[p_idx].config.servo_idx, actuators[p_idx].driver_val);
139 }
140 }
141 } else if (strcmp(argv[0], "set_conf") == 0) {
142 if (argc >= 5) {
143 uint8_t idx = atoi(argv[1]);
144 int32_t min = atoi(argv[2]);
145 int32_t max = atoi(argv[3]);
146 int32_t neutral = atoi(argv[4]);
147 uint8_t d_idx = actuators[idx].config.driver_no;
148 uint8_t s_idx = actuators[idx].config.servo_idx;
152 }
153 } else {
154 chprintf(sh, "unknown actuator command\r\n");
155 }
156 }
157}
158
159#endif // USE_SHELL
160
161void actuators_init(void)
162{
163
164#if defined ACTUATORS_START_DELAY && ! defined SITL
165 actuators_delay_done = false;
167#else
170#endif
171
172 // Init macro from generated airframe.h
173#if (defined INTERMCU_AP)
174 // TODO ApOnlyActuatorsInit();
175#elif (defined INTERMCU_FBW)
177#else
178 // default, init all actuators
180 // TODO ApOnlyActuatorsInit();
181#endif
182
183#if PERIODIC_TELEMETRY
186#endif
187
188#if USE_SHELL
189 shell_add_entry("actuator", cmd_actuator);
190#endif
191
192}
193
198void actuators_periodic(void)
199{
200#if USE_COMMANDS
202 int i;
203 for (i = 0; i < COMMANDS_NB; i++) {trimmed_commands[i] = commands[i];}
204
205#ifdef COMMAND_ROLL
207#endif /* COMMAND_ROLL */
208
209#ifdef COMMAND_PITCH
211#endif /* COMMAND_PITCH */
212
213#ifdef COMMAND_YAW
215#endif /* COMMAND_YAW */
216
217#if (defined INTERMCU_AP)
219 // TODO SetApOnlyActuatorsFromCommands(ap_commands, autopilot_get_mode());
220#elif (defined INTERMCU_FBW)
222#else
223 // default, apply all commands
225 // TODO SetApOnlyActuatorsFromCommands(ap_commands, autopilot_get_mode());
226#endif
227#endif // USE_COMMANDS
228}
229
231{
234
236 command_value = actuators[pprz_idx].pprz_val * (pprz_value>0 ? actuators[pprz_idx].config.travel_up : actuators[pprz_idx].config.travel_down);
237 servo_value = actuators[pprz_idx].config.neutral + command_value;
238 actuators[pprz_idx].driver_val = Clip(servo_value, actuators[pprz_idx].config.min, actuators[pprz_idx].config.max);
239 if (actuators[pprz_idx].set != NULL) {
240 actuators[pprz_idx].set(actuators[pprz_idx].config.servo_idx, actuators[pprz_idx].driver_val);
241 }
242}
243
245{
246 return actuators[pprz_idx].driver_val;
247}
248
252uint8_t actuator_get_idx(uint8_t driver_no, uint8_t servo_idx)
253{
254 uint8_t i = 0;
255 for (i = 0; i < ACTUATORS_NB; i++) {
256 if (actuators[i].config.driver_no == driver_no &&
257 actuators[i].config.servo_idx == servo_idx) {
258 break;
259 }
260 }
261 return i; // returns ACTUATORS_NB if not found
262}
263
264int32_t actuator_get_min(uint8_t driver_no, uint8_t servo_idx)
265{
266 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
267 if (idx != ACTUATORS_NB) {
268 return actuators[idx].config.min;
269 }
270 return 0;
271}
272
273int32_t actuator_get_max(uint8_t driver_no, uint8_t servo_idx)
274{
275 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
276 if (idx != ACTUATORS_NB) {
277 return actuators[idx].config.max;
278 }
279 return 0;
280}
281
282int32_t actuator_get_neutral(uint8_t driver_no, uint8_t servo_idx)
283{
284 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
285 if (idx != ACTUATORS_NB) {
286 return actuators[idx].config.neutral;
287 }
288 return 0;
289}
290
291void actuator_set_min(uint8_t driver_no, uint8_t servo_idx, int32_t min)
292{
293 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
294 if (idx == ACTUATORS_NB) return; // wrong index
295 actuators[idx].config.min = min;
296 int32_t delta = actuators[idx].config.neutral - min;
297 actuators[idx].config.travel_down = (float) delta / MAX_PPRZ;
298}
299
300void actuator_set_max(uint8_t driver_no, uint8_t servo_idx, int32_t max)
301{
302 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
303 if (idx == ACTUATORS_NB) return; // wrong index
304 actuators[idx].config.max = max;
305 int32_t delta = max - actuators[idx].config.neutral;
306 actuators[idx].config.travel_up = (float) delta / MAX_PPRZ;
307}
308
309void actuator_set_neutral(uint8_t driver_no, uint8_t servo_idx, int32_t neutral)
310{
311 uint8_t idx = actuator_get_idx(driver_no, servo_idx);
312 if (idx == ACTUATORS_NB) return; // wrong index
313 actuators[idx].config.neutral = neutral;
314 int32_t delta_max = actuators[idx].config.max - neutral;
315 actuators[idx].config.travel_up = (float) delta_max / MAX_PPRZ;
316 int32_t delta_min = neutral - actuators[idx].config.min;
317 actuators[idx].config.travel_down = (float) delta_min / MAX_PPRZ;
318}
319
320
321
322#else // No command_laws section or no actuators
323
324void actuators_init(void) {}
326
327#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:325
void actuators_init(void)
Definition actuators.c:324
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:227
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.