2 * Copyright Droids Corporation (2008)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Revision : $Id: commands_cs.c,v 1.4 2009-05-02 10:08:09 zer0 Exp $
20 * Olivier MATZ <zer0@droids-corp.org>
26 #include <aversive/pgmspace.h>
27 #include <aversive/wait.h>
28 #include <aversive/error.h>
34 #include <clock_time.h>
38 #include <control_system_manager.h>
39 #include <trajectory_manager.h>
40 #include <vect_base.h>
43 #include <obstacle_avoidance.h>
44 #include <blocking_detection_manager.h>
45 #include <robot_system.h>
46 #include <position_manager.h>
50 #include <parse_string.h>
51 #include <parse_num.h>
58 const prog_char *name;
62 prog_char csb_angle_str[] = "angle";
63 prog_char csb_distance_str[] = "distance";
64 prog_char csb_left_cobroller_str[] = "left_cobroller";
65 prog_char csb_right_cobroller_str[] = "right_cobroller";
66 struct csb_list csb_list[] = {
67 { .name = csb_angle_str, .csb = &mainboard.angle },
68 { .name = csb_distance_str, .csb = &mainboard.distance },
69 { .name = csb_left_cobroller_str, .csb = &mainboard.left_cobroller },
70 { .name = csb_right_cobroller_str, .csb = &mainboard.right_cobroller },
73 struct cmd_cs_result {
74 fixed_string_t cmdname;
75 fixed_string_t csname;
78 /* token to be used for all cs-related commands */
79 prog_char str_csb_name[] = "angle#distance#left_cobroller#right_cobroller";
80 parse_pgm_token_string_t cmd_csb_name_tok = TOKEN_STRING_INITIALIZER(struct cmd_cs_result, csname, str_csb_name);
82 struct cs_block *cs_from_name(const char *name)
86 for (i=0; i<(sizeof(csb_list)/sizeof(*csb_list)); i++) {
87 if (!strcmp_P(name, csb_list[i].name))
88 return csb_list[i].csb;
93 /**********************************************************/
94 /* Gains for control system */
96 /* this structure is filled when cmd_gain is parsed successfully */
97 struct cmd_gain_result {
98 struct cmd_cs_result cs;
104 /* function called when cmd_gain is parsed successfully */
105 static void cmd_gain_parsed(void * parsed_result, void *show)
107 struct cmd_gain_result *res = parsed_result;
108 struct cs_block *csb;
110 csb = cs_from_name(res->cs.csname);
112 printf_P(PSTR("null csb\r\n"));
117 pid_set_gains(&csb->pid, res->p, res->i, res->d);
119 printf_P(PSTR("%s %s %d %d %d\r\n"),
122 pid_get_gain_P(&csb->pid),
123 pid_get_gain_I(&csb->pid),
124 pid_get_gain_D(&csb->pid));
127 prog_char str_gain_arg0[] = "gain";
128 parse_pgm_token_string_t cmd_gain_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_gain_result, cs.cmdname, str_gain_arg0);
129 parse_pgm_token_num_t cmd_gain_p = TOKEN_NUM_INITIALIZER(struct cmd_gain_result, p, INT16);
130 parse_pgm_token_num_t cmd_gain_i = TOKEN_NUM_INITIALIZER(struct cmd_gain_result, i, INT16);
131 parse_pgm_token_num_t cmd_gain_d = TOKEN_NUM_INITIALIZER(struct cmd_gain_result, d, INT16);
133 prog_char help_gain[] = "Set gain values for PID";
134 parse_pgm_inst_t cmd_gain = {
135 .f = cmd_gain_parsed, /* function to call */
136 .data = NULL, /* 2nd arg of func */
137 .help_str = help_gain,
138 .tokens = { /* token list, NULL terminated */
139 (prog_void *)&cmd_gain_arg0,
140 (prog_void *)&cmd_csb_name_tok,
141 (prog_void *)&cmd_gain_p,
142 (prog_void *)&cmd_gain_i,
143 (prog_void *)&cmd_gain_d,
149 /* this structure is filled when cmd_gain is parsed successfully */
150 struct cmd_gain_show_result {
151 struct cmd_cs_result cs;
155 prog_char str_gain_show_arg[] = "show";
156 parse_pgm_token_string_t cmd_gain_show_arg = TOKEN_STRING_INITIALIZER(struct cmd_gain_show_result, show, str_gain_show_arg);
158 prog_char help_gain_show[] = "Show gain values for PID";
159 parse_pgm_inst_t cmd_gain_show = {
160 .f = cmd_gain_parsed, /* function to call */
161 .data = (void *)1, /* 2nd arg of func */
162 .help_str = help_gain_show,
163 .tokens = { /* token list, NULL terminated */
164 (prog_void *)&cmd_gain_arg0,
165 (prog_void *)&cmd_csb_name_tok,
166 (prog_void *)&cmd_gain_show_arg,
171 /**********************************************************/
172 /* Speeds for control system */
174 /* this structure is filled when cmd_speed is parsed successfully */
175 struct cmd_speed_result {
176 struct cmd_cs_result cs;
180 /* function called when cmd_speed is parsed successfully */
181 static void cmd_speed_parsed(void *parsed_result, void *show)
183 struct cmd_speed_result * res = parsed_result;
185 struct cs_block *csb;
187 csb = cs_from_name(res->cs.csname);
189 printf_P(PSTR("null csb\r\n"));
195 ramp_set_vars(&csb->ramp, res->s, res->s); /* set speed */
197 printf_P(PSTR("%s %"PRIu32"\r\n"),
201 printf_P(PSTR("TODO\r\n"));
205 prog_char str_speed_arg0[] = "speed";
206 parse_pgm_token_string_t cmd_speed_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_speed_result, cs.cmdname, str_speed_arg0);
207 parse_pgm_token_num_t cmd_speed_s = TOKEN_NUM_INITIALIZER(struct cmd_speed_result, s, UINT16);
209 prog_char help_speed[] = "Set speed values for ramp filter";
210 parse_pgm_inst_t cmd_speed = {
211 .f = cmd_speed_parsed, /* function to call */
212 .data = NULL, /* 2nd arg of func */
213 .help_str = help_speed,
214 .tokens = { /* token list, NULL terminated */
215 (prog_void *)&cmd_speed_arg0,
216 (prog_void *)&cmd_csb_name_tok,
217 (prog_void *)&cmd_speed_s,
223 struct cmd_speed_show_result {
224 struct cmd_cs_result cs;
228 prog_char str_speed_show_arg[] = "show";
229 parse_pgm_token_string_t cmd_speed_show_arg = TOKEN_STRING_INITIALIZER(struct cmd_speed_show_result, show, str_speed_show_arg);
231 prog_char help_speed_show[] = "Show speed values for ramp filter";
232 parse_pgm_inst_t cmd_speed_show = {
233 .f = cmd_speed_parsed, /* function to call */
234 .data = (void *)1, /* 2nd arg of func */
235 .help_str = help_speed_show,
236 .tokens = { /* token list, NULL terminated */
237 (prog_void *)&cmd_speed_arg0,
238 (prog_void *)&cmd_csb_name_tok,
239 (prog_void *)&cmd_speed_show_arg,
244 /**********************************************************/
245 /* Derivate_Filters for control system */
247 /* this structure is filled when cmd_derivate_filter is parsed successfully */
248 struct cmd_derivate_filter_result {
249 struct cmd_cs_result cs;
254 /* function called when cmd_derivate_filter is parsed successfully */
255 static void cmd_derivate_filter_parsed(void *parsed_result, void *show)
257 struct cmd_derivate_filter_result * res = parsed_result;
258 struct cs_block *csb;
260 csb = cs_from_name(res->cs.csname);
262 printf_P(PSTR("null csb\r\n"));
267 pid_set_derivate_filter(&csb->pid, res->size);
269 printf_P(PSTR("%s %s %u\r\n"),
272 pid_get_derivate_filter(&csb->pid));
275 prog_char str_derivate_filter_arg0[] = "derivate_filter";
276 parse_pgm_token_string_t cmd_derivate_filter_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_derivate_filter_result, cs.cmdname, str_derivate_filter_arg0);
277 parse_pgm_token_num_t cmd_derivate_filter_size = TOKEN_NUM_INITIALIZER(struct cmd_derivate_filter_result, size, UINT8);
279 prog_char help_derivate_filter[] = "Set derivate_filter values for PID (in, I, out)";
280 parse_pgm_inst_t cmd_derivate_filter = {
281 .f = cmd_derivate_filter_parsed, /* function to call */
282 .data = NULL, /* 2nd arg of func */
283 .help_str = help_derivate_filter,
284 .tokens = { /* token list, NULL terminated */
285 (prog_void *)&cmd_derivate_filter_arg0,
286 (prog_void *)&cmd_csb_name_tok,
287 (prog_void *)&cmd_derivate_filter_size,
294 prog_char str_derivate_filter_show_arg[] = "show";
295 parse_pgm_token_string_t cmd_derivate_filter_show_arg = TOKEN_STRING_INITIALIZER(struct cmd_derivate_filter_result, show, str_derivate_filter_show_arg);
297 prog_char help_derivate_filter_show[] = "Show derivate_filter values for PID";
298 parse_pgm_inst_t cmd_derivate_filter_show = {
299 .f = cmd_derivate_filter_parsed, /* function to call */
300 .data = (void *)1, /* 2nd arg of func */
301 .help_str = help_derivate_filter_show,
302 .tokens = { /* token list, NULL terminated */
303 (prog_void *)&cmd_derivate_filter_arg0,
304 (prog_void *)&cmd_csb_name_tok,
305 (prog_void *)&cmd_derivate_filter_show_arg,
311 /**********************************************************/
312 /* Consign for control system */
314 /* this structure is filled when cmd_consign is parsed successfully */
315 struct cmd_consign_result {
316 struct cmd_cs_result cs;
320 /* function called when cmd_consign is parsed successfully */
321 static void cmd_consign_parsed(void * parsed_result, void *data)
323 struct cmd_consign_result * res = parsed_result;
324 struct cs_block *csb;
326 csb = cs_from_name(res->cs.csname);
328 printf_P(PSTR("null csb\r\n"));
332 cs_set_consign(&csb->cs, res->p);
335 prog_char str_consign_arg0[] = "consign";
336 parse_pgm_token_string_t cmd_consign_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_consign_result, cs.cmdname, str_consign_arg0);
337 parse_pgm_token_num_t cmd_consign_p = TOKEN_NUM_INITIALIZER(struct cmd_consign_result, p, INT32);
339 prog_char help_consign[] = "Set consign value";
340 parse_pgm_inst_t cmd_consign = {
341 .f = cmd_consign_parsed, /* function to call */
342 .data = NULL, /* 2nd arg of func */
343 .help_str = help_consign,
344 .tokens = { /* token list, NULL terminated */
345 (prog_void *)&cmd_consign_arg0,
346 (prog_void *)&cmd_csb_name_tok,
347 (prog_void *)&cmd_consign_p,
353 /**********************************************************/
354 /* Maximums for control system */
356 /* this structure is filled when cmd_maximum is parsed successfully */
357 struct cmd_maximum_result {
358 struct cmd_cs_result cs;
364 /* function called when cmd_maximum is parsed successfully */
365 static void cmd_maximum_parsed(void *parsed_result, void *show)
367 struct cmd_maximum_result * res = parsed_result;
369 struct cs_block *csb;
371 csb = cs_from_name(res->cs.csname);
373 printf_P(PSTR("null csb\r\n"));
378 pid_set_maximums(&csb->pid, res->in, res->i, res->out);
380 printf_P(PSTR("maximum %s %"PRIu32" %"PRIu32" %"PRIu32"\r\n"),
382 pid_get_max_in(&csb->pid),
383 pid_get_max_I(&csb->pid),
384 pid_get_max_out(&csb->pid));
387 prog_char str_maximum_arg0[] = "maximum";
388 parse_pgm_token_string_t cmd_maximum_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_maximum_result, cs.cmdname, str_maximum_arg0);
389 parse_pgm_token_num_t cmd_maximum_in = TOKEN_NUM_INITIALIZER(struct cmd_maximum_result, in, UINT32);
390 parse_pgm_token_num_t cmd_maximum_i = TOKEN_NUM_INITIALIZER(struct cmd_maximum_result, i, UINT32);
391 parse_pgm_token_num_t cmd_maximum_out = TOKEN_NUM_INITIALIZER(struct cmd_maximum_result, out, UINT32);
393 prog_char help_maximum[] = "Set maximum values for PID (in, I, out)";
394 parse_pgm_inst_t cmd_maximum = {
395 .f = cmd_maximum_parsed, /* function to call */
396 .data = NULL, /* 2nd arg of func */
397 .help_str = help_maximum,
398 .tokens = { /* token list, NULL terminated */
399 (prog_void *)&cmd_maximum_arg0,
400 (prog_void *)&cmd_csb_name_tok,
401 (prog_void *)&cmd_maximum_in,
402 (prog_void *)&cmd_maximum_i,
403 (prog_void *)&cmd_maximum_out,
410 /* this structure is filled when cmd_maximum is parsed successfully */
411 struct cmd_maximum_show_result {
412 struct cmd_cs_result cs;
415 prog_char str_maximum_show_arg[] = "show";
416 parse_pgm_token_string_t cmd_maximum_show_arg = TOKEN_STRING_INITIALIZER(struct cmd_maximum_show_result, show, str_maximum_show_arg);
418 prog_char help_maximum_show[] = "Show maximum values for PID";
419 parse_pgm_inst_t cmd_maximum_show = {
420 .f = cmd_maximum_parsed, /* function to call */
421 .data = (void *)1, /* 2nd arg of func */
422 .help_str = help_maximum_show,
423 .tokens = { /* token list, NULL terminated */
424 (prog_void *)&cmd_maximum_arg0,
425 (prog_void *)&cmd_csb_name_tok,
426 (prog_void *)&cmd_maximum_show_arg,
431 /**********************************************************/
432 /* Quadramp for control system */
434 /* this structure is filled when cmd_quadramp is parsed successfully */
435 struct cmd_quadramp_result {
436 struct cmd_cs_result cs;
443 /* function called when cmd_quadramp is parsed successfully */
444 static void cmd_quadramp_parsed(void *parsed_result, void *show)
446 struct cmd_quadramp_result * res = parsed_result;
448 struct cs_block *csb;
450 csb = cs_from_name(res->cs.csname);
452 printf_P(PSTR("null csb\r\n"));
457 quadramp_set_1st_order_vars(&csb->qr, res->sp, res->sn);
458 quadramp_set_2nd_order_vars(&csb->qr, res->ap, res->an);
461 printf_P(PSTR("quadramp %s %2.2f %2.2f %2.2f %2.2f\r\n"),
463 csb->qr.var_2nd_ord_pos,
464 csb->qr.var_2nd_ord_neg,
465 csb->qr.var_1st_ord_pos,
466 csb->qr.var_1st_ord_neg);
469 prog_char str_quadramp_arg0[] = "quadramp";
470 parse_pgm_token_string_t cmd_quadramp_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_quadramp_result, cs.cmdname, str_quadramp_arg0);
471 parse_pgm_token_num_t cmd_quadramp_ap = TOKEN_NUM_INITIALIZER(struct cmd_quadramp_result, ap, FLOAT);
472 parse_pgm_token_num_t cmd_quadramp_an = TOKEN_NUM_INITIALIZER(struct cmd_quadramp_result, an, FLOAT);
473 parse_pgm_token_num_t cmd_quadramp_sp = TOKEN_NUM_INITIALIZER(struct cmd_quadramp_result, sp, FLOAT);
474 parse_pgm_token_num_t cmd_quadramp_sn = TOKEN_NUM_INITIALIZER(struct cmd_quadramp_result, sn, FLOAT);
476 prog_char help_quadramp[] = "Set quadramp values (acc+, acc-, speed+, speed-)";
477 parse_pgm_inst_t cmd_quadramp = {
478 .f = cmd_quadramp_parsed, /* function to call */
479 .data = NULL, /* 2nd arg of func */
480 .help_str = help_quadramp,
481 .tokens = { /* token list, NULL terminated */
482 (prog_void *)&cmd_quadramp_arg0,
483 (prog_void *)&cmd_csb_name_tok,
484 (prog_void *)&cmd_quadramp_ap,
485 (prog_void *)&cmd_quadramp_an,
486 (prog_void *)&cmd_quadramp_sp,
487 (prog_void *)&cmd_quadramp_sn,
495 struct cmd_quadramp_show_result {
496 struct cmd_cs_result cs;
500 prog_char str_quadramp_show_arg[] = "show";
501 parse_pgm_token_string_t cmd_quadramp_show_arg = TOKEN_STRING_INITIALIZER(struct cmd_quadramp_show_result, show, str_quadramp_show_arg);
503 prog_char help_quadramp_show[] = "Get quadramp values for control system";
504 parse_pgm_inst_t cmd_quadramp_show = {
505 .f = cmd_quadramp_parsed, /* function to call */
506 .data = (void *)1, /* 2nd arg of func */
507 .help_str = help_quadramp_show,
508 .tokens = { /* token list, NULL terminated */
509 (prog_void *)&cmd_quadramp_arg0,
510 (prog_void *)&cmd_csb_name_tok,
511 (prog_void *)&cmd_quadramp_show_arg,
518 /**********************************************************/
519 /* cs_status show for control system */
521 /* this structure is filled when cmd_cs_status is parsed successfully */
522 struct cmd_cs_status_result {
523 struct cmd_cs_result cs;
527 /* function called when cmd_cs_status is parsed successfully */
528 static void cmd_cs_status_parsed(void *parsed_result, void *data)
530 struct cmd_cs_status_result *res = parsed_result;
531 struct cs_block *csb;
533 uint8_t print_pid = 0, print_cs = 0;
535 csb = cs_from_name(res->cs.csname);
537 printf_P(PSTR("null csb\r\n"));
540 if (strcmp_P(res->arg, PSTR("on")) == 0) {
542 printf_P(PSTR("%s is on\r\n"), res->cs.csname);
545 else if (strcmp_P(res->arg, PSTR("off")) == 0) {
547 printf_P(PSTR("%s is off\r\n"), res->cs.csname);
550 else if (strcmp_P(res->arg, PSTR("show")) == 0) {
553 else if (strcmp_P(res->arg, PSTR("loop_show")) == 0) {
557 else if (strcmp_P(res->arg, PSTR("pid_show")) == 0) {
560 else if (strcmp_P(res->arg, PSTR("pid_loop_show")) == 0) {
565 printf_P(PSTR("%s cs is %s\r\n"), res->cs.csname, csb->on ? "on":"off");
568 dump_cs(res->cs.csname, &csb->cs);
570 dump_pid(res->cs.csname, &csb->pid);
572 } while(loop && !cmdline_keypressed());
575 prog_char str_cs_status_arg0[] = "cs_status";
576 parse_pgm_token_string_t cmd_cs_status_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_cs_status_result, cs.cmdname, str_cs_status_arg0);
577 prog_char str_cs_status_arg[] = "pid_show#pid_loop_show#show#loop_show#on#off";
578 parse_pgm_token_string_t cmd_cs_status_arg = TOKEN_STRING_INITIALIZER(struct cmd_cs_status_result, arg, str_cs_status_arg);
580 prog_char help_cs_status[] = "Show cs status";
581 parse_pgm_inst_t cmd_cs_status = {
582 .f = cmd_cs_status_parsed, /* function to call */
583 .data = NULL, /* 2nd arg of func */
584 .help_str = help_cs_status,
585 .tokens = { /* token list, NULL terminated */
586 (prog_void *)&cmd_cs_status_arg0,
587 (prog_void *)&cmd_csb_name_tok,
588 (prog_void *)&cmd_cs_status_arg,
594 /**********************************************************/
595 /* Blocking_I for control system */
597 /* this structure is filled when cmd_blocking_i is parsed successfully */
598 struct cmd_blocking_i_result {
599 struct cmd_cs_result cs;
606 /* function called when cmd_blocking_i is parsed successfully */
607 static void cmd_blocking_i_parsed(void *parsed_result, void *show)
609 struct cmd_blocking_i_result * res = parsed_result;
611 struct cs_block *csb;
613 csb = cs_from_name(res->cs.csname);
615 printf_P(PSTR("null csb\r\n"));
620 bd_set_current_thresholds(&csb->bd, res->k1, res->k2,
623 printf_P(PSTR("%s %s %"PRIi32" %"PRIi32" %"PRIi32" %d\r\n"),
632 prog_char str_blocking_i_arg0[] = "blocking";
633 parse_pgm_token_string_t cmd_blocking_i_arg0 = TOKEN_STRING_INITIALIZER(struct cmd_blocking_i_result, cs.cmdname, str_blocking_i_arg0);
634 parse_pgm_token_num_t cmd_blocking_i_k1 = TOKEN_NUM_INITIALIZER(struct cmd_blocking_i_result, k1, INT32);
635 parse_pgm_token_num_t cmd_blocking_i_k2 = TOKEN_NUM_INITIALIZER(struct cmd_blocking_i_result, k2, INT32);
636 parse_pgm_token_num_t cmd_blocking_i_i = TOKEN_NUM_INITIALIZER(struct cmd_blocking_i_result, i, UINT32);
637 parse_pgm_token_num_t cmd_blocking_i_cpt = TOKEN_NUM_INITIALIZER(struct cmd_blocking_i_result, cpt, UINT16);
639 prog_char help_blocking_i[] = "Set blocking detection values (k1, k2, i, cpt)";
640 parse_pgm_inst_t cmd_blocking_i = {
641 .f = cmd_blocking_i_parsed, /* function to call */
642 .data = NULL, /* 2nd arg of func */
643 .help_str = help_blocking_i,
644 .tokens = { /* token list, NULL terminated */
645 (prog_void *)&cmd_blocking_i_arg0,
646 (prog_void *)&cmd_csb_name_tok,
647 (prog_void *)&cmd_blocking_i_k1,
648 (prog_void *)&cmd_blocking_i_k2,
649 (prog_void *)&cmd_blocking_i_i,
650 (prog_void *)&cmd_blocking_i_cpt,
657 struct cmd_blocking_i_show_result {
658 struct cmd_cs_result cs;
662 prog_char str_blocking_i_show_arg[] = "show";
663 parse_pgm_token_string_t cmd_blocking_i_show_arg = TOKEN_STRING_INITIALIZER(struct cmd_blocking_i_show_result, show, str_blocking_i_show_arg);
665 prog_char help_blocking_i_show[] = "Show blocking detection values";
666 parse_pgm_inst_t cmd_blocking_i_show = {
667 .f = cmd_blocking_i_parsed, /* function to call */
668 .data = (void *)1, /* 2nd arg of func */
669 .help_str = help_blocking_i_show,
670 .tokens = { /* token list, NULL terminated */
671 (prog_void *)&cmd_blocking_i_arg0,
672 (prog_void *)&cmd_csb_name_tok,
673 (prog_void *)&cmd_blocking_i_show_arg,