vt100: include pgmspace.h as we use PROGMEM macro
[aversive.git] / projects / microb2010 / ballboard / cs.c
1 /*
2  *  Copyright Droids Corporation
3  *  Olivier Matz <zer0@droids-corp.org>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *  Revision : $Id: cs.c,v 1.4 2009-05-27 20:04:07 zer0 Exp $
20  *
21  */
22
23 #include <stdio.h>
24 #include <string.h>
25
26 #include <aversive.h>
27 #include <aversive/error.h>
28
29 #include <ax12.h>
30 #include <spi.h>
31 #include <encoders_spi.h>
32 #include <pwm_ng.h>
33 #include <timer.h>
34 #include <scheduler.h>
35 #include <clock_time.h>
36 #include <adc.h>
37
38 #include <pid.h>
39 #include <quadramp.h>
40 #include <control_system_manager.h>
41 #include <blocking_detection_manager.h>
42
43 #include <parse.h>
44 #include <rdline.h>
45
46 #include "main.h"
47 #include "actuator.h"
48 #include "beacon.h"
49
50 int32_t encoders_spi_update_roller_speed(void *number)
51 {
52         static volatile int32_t roller_pos;
53         int32_t tmp, speed;
54         tmp = encoders_spi_get_value(number);
55         speed = tmp - roller_pos;
56         roller_pos = tmp;
57         return speed;
58 }
59
60 /* called every 5 ms */
61 static void do_cs(void *dummy)
62 {
63         /* read encoders */
64         if (ballboard.flags & DO_ENCODERS) {
65                 encoders_spi_manage(NULL);
66         }
67         /* control system */
68         if (ballboard.flags & DO_CS) {
69                 if (ballboard.roller.on)
70                         cs_manage(&ballboard.roller.cs);
71                 if (ballboard.forktrans.on)
72                         cs_manage(&ballboard.forktrans.cs);
73                 if (ballboard.forkrot.on)
74                         cs_manage(&ballboard.forkrot.cs);
75                 if (ballboard.beacon.on)
76                         cs_manage(&ballboard.beacon.cs);
77         }
78         if ((ballboard.flags & DO_BD) && (ballboard.flags & DO_POWER)) {
79                 bd_manage_from_cs(&ballboard.forktrans.bd, &ballboard.forktrans.cs);
80                 bd_manage_from_cs(&ballboard.forkrot.bd, &ballboard.forkrot.cs);
81                 bd_manage_from_speed_cmd(&ballboard.roller.bd,
82                                          cs_get_filtered_feedback(&ballboard.roller.cs),
83                                          cs_get_out(&ballboard.roller.cs));
84
85 #if 0
86                 /* urgent case: stop power on blocking */
87                 if (ballboard.flags & DO_ERRBLOCKING) {
88                         if (bd_get(&ballboard.forktrans.bd) ||
89                             bd_get(&ballboard.forkrot.bd)) {
90                                 printf_P(PSTR("MOTOR BLOCKED STOP ALL\r\n"));
91                                 ballboard.flags &= ~(DO_POWER | DO_ERRBLOCKING);
92                         }
93                 }
94 #endif
95         }
96         if (ballboard.flags & DO_POWER)
97                 BRAKE_OFF();
98         else
99                 BRAKE_ON();
100 }
101
102 void dump_cs(const char *name, struct cs *cs)
103 {
104         printf_P(PSTR("%s cons=% .5ld fcons=% .5ld err=% .5ld "
105                       "in=% .5ld out=% .5ld\r\n"),
106                  name, cs_get_consign(cs), cs_get_filtered_consign(cs),
107                  cs_get_error(cs), cs_get_filtered_feedback(cs),
108                  cs_get_out(cs));
109 }
110
111 void dump_pid(const char *name, struct pid_filter *pid)
112 {
113         printf_P(PSTR("%s P=% .8ld I=% .8ld D=% .8ld out=% .8ld\r\n"),
114                  name,
115                  pid_get_value_in(pid) * pid_get_gain_P(pid),
116                  pid_get_value_I(pid) * pid_get_gain_I(pid),
117                  pid_get_value_D(pid) * pid_get_gain_D(pid),
118                  pid_get_value_out(pid));
119 }
120
121 void microb_cs_init(void)
122 {
123         /* ---- CS roller */
124         /* PID */
125         pid_init(&ballboard.roller.pid);
126         pid_set_gains(&ballboard.roller.pid, 80, 80, 250);
127         pid_set_maximums(&ballboard.roller.pid, 0, 10000, 4095);
128         pid_set_out_shift(&ballboard.roller.pid, 6);
129         pid_set_derivate_filter(&ballboard.roller.pid, 6);
130
131         /* QUADRAMP (used as a ramp filter) */
132         quadramp_init(&ballboard.roller.qr);
133         quadramp_set_1st_order_vars(&ballboard.roller.qr, 20, 20);
134         quadramp_set_2nd_order_vars(&ballboard.roller.qr, 0, 0);
135
136         /* CS */
137         cs_init(&ballboard.roller.cs);
138         cs_set_consign_filter(&ballboard.roller.cs, quadramp_do_filter, &ballboard.roller.qr);
139         cs_set_correct_filter(&ballboard.roller.cs, pid_do_filter, &ballboard.roller.pid);
140         cs_set_process_in(&ballboard.roller.cs, pwm_ng_set, ROLLER_PWM);
141         cs_set_process_out(&ballboard.roller.cs, encoders_spi_update_roller_speed, ROLLER_ENCODER);
142         cs_set_consign(&ballboard.roller.cs, 0);
143
144         /* Blocking detection */
145         bd_init(&ballboard.roller.bd);
146 #define ROLLER_SPEED_THRES (ROLLER_SPEED * 0.75)
147         bd_set_speed_threshold(&ballboard.roller.bd, ROLLER_SPEED_THRES);
148         bd_set_current_thresholds(&ballboard.roller.bd, 500, 1500, 1200000, 70);
149
150         /* ---- CS forktrans */
151         /* PID */
152         pid_init(&ballboard.forktrans.pid);
153         pid_set_gains(&ballboard.forktrans.pid, 30, 5, 0);
154         pid_set_maximums(&ballboard.forktrans.pid, 0, 10000, 2047);
155         pid_set_out_shift(&ballboard.forktrans.pid, 6);
156         pid_set_derivate_filter(&ballboard.forktrans.pid, 6);
157
158         /* QUADRAMP */
159         quadramp_init(&ballboard.forktrans.qr);
160         quadramp_set_1st_order_vars(&ballboard.forktrans.qr, 200, 200); /* set speed */
161         quadramp_set_2nd_order_vars(&ballboard.forktrans.qr, 20, 20); /* set accel */
162
163         /* CS */
164         cs_init(&ballboard.forktrans.cs);
165         cs_set_consign_filter(&ballboard.forktrans.cs, quadramp_do_filter, &ballboard.forktrans.qr);
166         cs_set_correct_filter(&ballboard.forktrans.cs, pid_do_filter, &ballboard.forktrans.pid);
167         cs_set_process_in(&ballboard.forktrans.cs, pwm_ng_set, FORKTRANS_PWM);
168         cs_set_process_out(&ballboard.forktrans.cs, encoders_spi_get_value, FORKTRANS_ENCODER);
169         cs_set_consign(&ballboard.forktrans.cs, 0);
170
171         /* Blocking detection */
172         bd_init(&ballboard.forktrans.bd);
173         bd_set_speed_threshold(&ballboard.forktrans.bd, 150);
174         bd_set_current_thresholds(&ballboard.forktrans.bd, 500, 8000, 1000000, 200);
175
176         /* ---- CS forkrot */
177         /* PID */
178         pid_init(&ballboard.forkrot.pid);
179         pid_set_gains(&ballboard.forkrot.pid, 30, 5, 0);
180         pid_set_maximums(&ballboard.forkrot.pid, 0, 10000, 2047);
181         pid_set_out_shift(&ballboard.forkrot.pid, 6);
182         pid_set_derivate_filter(&ballboard.forkrot.pid, 6);
183
184         /* QUADRAMP */
185         quadramp_init(&ballboard.forkrot.qr);
186         quadramp_set_1st_order_vars(&ballboard.forkrot.qr, 1000, 500); /* set speed */
187         quadramp_set_2nd_order_vars(&ballboard.forkrot.qr, 100, 20); /* set accel */
188
189         /* CS */
190         cs_init(&ballboard.forkrot.cs);
191         cs_set_consign_filter(&ballboard.forkrot.cs, quadramp_do_filter, &ballboard.forkrot.qr);
192         cs_set_correct_filter(&ballboard.forkrot.cs, pid_do_filter, &ballboard.forkrot.pid);
193         cs_set_process_in(&ballboard.forkrot.cs, pwm_ng_set, FORKROT_PWM);
194         cs_set_process_out(&ballboard.forkrot.cs, encoders_spi_get_value, FORKROT_ENCODER);
195         cs_set_consign(&ballboard.forkrot.cs, 0);
196
197         /* Blocking detection */
198         bd_init(&ballboard.forkrot.bd);
199         bd_set_speed_threshold(&ballboard.forkrot.bd, 150);
200         bd_set_current_thresholds(&ballboard.forkrot.bd, 500, 8000, 1000000, 200);
201
202         /* BEACON */
203
204         /* PID */
205         pid_init(&ballboard.beacon.pid);
206         pid_set_gains(&ballboard.beacon.pid, 80, 80, 250);
207         pid_set_maximums(&ballboard.beacon.pid, 0, 10000, 1500);
208         pid_set_out_shift(&ballboard.beacon.pid, 6);
209         pid_set_derivate_filter(&ballboard.beacon.pid, 6);
210
211         /* CS */
212         cs_init(&ballboard.beacon.cs);
213         cs_set_correct_filter(&ballboard.beacon.cs, pid_do_filter, &ballboard.beacon.pid);
214         cs_set_process_in(&ballboard.beacon.cs, pwm_ng_set, BEACON_PWM);
215         cs_set_process_out(&ballboard.beacon.cs, encoders_spi_update_beacon_speed, BEACON_ENCODER);
216         cs_set_consign(&ballboard.beacon.cs, 0);
217
218         /* set them on !! */
219         ballboard.roller.on = 1;
220         ballboard.forktrans.on = 1;
221         ballboard.forkrot.on = 0;
222         ballboard.beacon.on = 0;
223
224
225         scheduler_add_periodical_event_priority(do_cs, NULL,
226                                                 5000L / SCHEDULER_UNIT,
227                                                 CS_PRIO);
228 }