blob: f9ee4beaca25998d89d1c7173a761cbe891ca6fd [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001close all;
2load 'drivetrain_spin_low'
3load 'drivetrain_strait_low'
James Kuszmaulf254c1a2013-03-10 16:31:26 -07004% Max power amps of CIM or maybe half the mass of the robot in lbs or the whole robot in kg.
brians343bc112013-02-10 01:53:46 +00005m = 68;
James Kuszmaulf254c1a2013-03-10 16:31:26 -07006% Must be in meters. Maybe width of robot (distance of center wheels from center).
brians343bc112013-02-10 01:53:46 +00007rb = 0.617998644 / 2.0;
James Kuszmaulf254c1a2013-03-10 16:31:26 -07008% Moment of Inertia
brians343bc112013-02-10 01:53:46 +00009J = 7;
10stall_current = 133.0;
James Kuszmaulf254c1a2013-03-10 16:31:26 -070011% Resistance of the motor, divided by the number of motors.
brians343bc112013-02-10 01:53:46 +000012R = 12.0 / stall_current / 4 / 0.43;
James Kuszmaulf254c1a2013-03-10 16:31:26 -070013% Motor Constant
brians343bc112013-02-10 01:53:46 +000014Km = (12.0 - R * 2.7) / (4650.0 / 60.0 * 2.0 * pi);
James Kuszmaulf254c1a2013-03-10 16:31:26 -070015% Torque Constant
brians343bc112013-02-10 01:53:46 +000016Kt = 0.008;
17r = 0.04445; % 3.5 inches diameter
18G_low = 60.0 / 15.0 * 50.0 / 15.0;
19G_high = 45.0 / 30.0 * 50.0 / 15.0;
20dt = 0.01;
21
22G = G_low;
23
James Kuszmaulf254c1a2013-03-10 16:31:26 -070024% must refer to how each side of the robot affects the other? Units of 1 / kg
25% I think that if the center of mass is in the center of the robot, then
26% msp will evaluate to 2/(mass of robot) and msn will evaluate to 0.
brians343bc112013-02-10 01:53:46 +000027msp = (1.0 / m + rb ^ 2.0 / J);
28msn = (1.0 / m - rb ^ 2.0 / J);
29tc = -Km * Kt * G ^ 2.0 / (R * r ^ 2.0);
30mp = G * Kt / (R * r);
31
32A = [0 1 0 0; 0 msp*tc 0 msn*tc; 0 0 0 1; 0 msn*tc 0 msp*tc];
33B = [0 0; msp * mp msn * mp; 0 0; msn * mp msp * mp];
34C = [1 0 0 0; 0 0 1 0];
35D = [0 0; 0 0];
36
37dm = c2d(ss(A, B, C, D), dt);
38
39hp = .8;
40lp = .85;
41K = place(dm.a, dm.b, [hp, hp, lp, lp]);
42
43hlp = 0.07;
44llp = 0.09;
45L = place(dm.a', dm.c', [hlp, hlp, llp, llp])';
46
47% Plot what we computed
48
Brian Silverman14fd0fb2014-01-14 21:42:01 -080049fd = fopen('/home/aschuh/frc971/2012/trunk/src/prime/control_loops/Drivetrain.mat', 'w');
brians343bc112013-02-10 01:53:46 +000050n = 1;
51sm = [];
52writeMatHeader(fd, size(dm.a, 1), size(dm.b, 2));
53writeMat(fd, dm.a, 'A');
54writeMat(fd, dm.b, 'B');
55writeMat(fd, dm.c, 'C');
56writeMat(fd, dm.d, 'D');
57writeMat(fd, L, 'L');
58writeMat(fd, K, 'K');
59writeMat(fd, [12; 12], 'U_max');
60writeMat(fd, [-12; -12], 'U_min');
61writeMatFooter(fd);
62fclose(fd);
63
64full_model = dss([dm.a (-dm.b * K); eye(4) (dm.a - dm.b * K - L * dm.c)], [0, 0; 0, 0; 0, 0; 0, 0; L], [C, [0, 0, 0, 0; 0, 0, 0, 0]], 0, eye(8), 0.01);
65
66n = 1;
67sm_strait = [];
68t = drivetrain_strait_low(1, 1) + dt * (n - 1);
69x = [drivetrain_strait_low(1, 2); 0; drivetrain_strait_low(1, 3); 0];
70while t < drivetrain_strait_low(end, 1)
71 sm_strait(n, 1) = t;
72 sm_strait(n, 2) = (x(1,1) + x(3,1)) / 2.0;
73 t = t + dt;
74 x = dm.a * x + dm.b * [drivetrain_strait_low(n, 4); drivetrain_strait_low(n, 5)];
75 n = n + 1;
76end
77
78figure;
79plot(drivetrain_strait_low(:, 1), (drivetrain_strait_low(:, 2) + drivetrain_strait_low(:, 3)) / 2.0, sm_strait(:, 1), sm_strait(:, 2));
80legend('actual', 'sim');
81
82n = 1;
83sm_spin = [];
84t = drivetrain_spin_low(1, 1) + dt * (n - 1);
85x = [drivetrain_spin_low(1, 2); 0; drivetrain_spin_low(1, 3); 0];
86while t < drivetrain_spin_low(end, 1)
87 sm_spin(n, 1) = t;
88 sm_spin(n, 2) = (x(1,1) - x(3,1)) / 2.0;
89 t = t + dt;
90 x = dm.a * x + dm.b * [drivetrain_spin_low(n, 4); drivetrain_spin_low(n, 5)];
91 n = n + 1;
92end
93
94figure;
95plot(drivetrain_spin_low(:, 1), (drivetrain_spin_low(:, 2) - drivetrain_spin_low(:, 3)) / 2.0, sm_spin(:, 1), sm_spin(:, 2));
96legend('actual', 'sim');
97
98%figure;
99%nyquist(full_model);
100
101
102%%
103t = 0;
104x = [0; 0; 0; 0;];
105while t < logging(end, 1)
106 sm(n, 1) = t;
107 sm(n, 2) = x(1,1);
108 sm(n, 3) = x(3,1);
109 t = t + dt;
110 x = dm.a * x + dm.b * [12.0; 12.0];
111 n = n + 1;
112end
113
114figure;
115plot(logging(:, 1), logging(:, 2), sm(:, 1), sm(:, 2));
116legend('actual', 'sim');
117
118%% Simulation of a small turn angle with a large distance to travel
119tf = 2;
120x = [0; 0; 0.1; 0;];
121r = [10; 0; 10; 0];
122
123smt = zeros(tf / dt, 8);
124t = 0;
125xhat = x;
126n = 1;
127% 1 means scale
128% 2 means just limit to 12 volts
129% 3 means preserve the difference in power
130captype = 1;
131while n <= size(smt, 1)
132 smt(n, 1) = t;
133 smt(n, 2) = x(1,1);
134 smt(n, 3) = x(3,1);
135 t = t + dt;
136
137 u = K * (r - xhat);
138 smt(n, 4) = u(1,1);
139 smt(n, 5) = u(2,1);
140
141 if captype == 1
142 if sum(abs(u) > 12.0)
143 % We have a problem!
144 % Check to see if it's a big steering power problem,
145 % or a big drive error.
146 turnPower = (u(1, 1) - u(2, 1));
147 drivePower = (u(1, 1) + u(2, 1));
148 scaleFactor = 12.0 / max(abs(u));
149 smt(n, 8) = 1.0 / scaleFactor;
150 % Only start scaling the turn power up if we are far out of
151 % range.
152 if abs(turnPower) < 0.5 * abs(drivePower)
153 % Turn power is swamped.
154 deltaTurn = turnPower / 2.0 / scaleFactor * 0.5;
155 u(1, 1) = u(1, 1) + deltaTurn;
156 u(2, 1) = u(2, 1) - deltaTurn;
157 scaleFactor = 12.0 / max(abs(u));
158 else
159 if 0.5 * abs(turnPower) > abs(drivePower)
160 % Drive power is swamped.
161 deltaDrive = drivePower / 2.0 / scaleFactor * 0.5;
162 u(1, 1) = u(1, 1) + deltaDrive;
163 u(2, 1) = u(2, 1) + deltaDrive;
164 scaleFactor = 12.0 / max(abs(u));
165 end
166 end
167 u = u * scaleFactor;
168 end
169 else
170 if captype == 2
171 if u(1, 1) > 12.0
172 u(1, 1) = 12.0;
173 end
174 if u(1, 1) < -12.0
175 u(1, 1) = -12.0;
176 end
177 if u(2, 1) > 12.0
178 u(2, 1) = 12.0;
179 end
180 if u(2, 1) < -12.0
181 u(2, 1) = -12.0;
182 end
183 else
184 if captype == 3
185 if u(1, 1) > 12.0
186 u(2, 1) = u(2, 1) - (u(1, 1) - 12.0);
187 else
188 if u(1, 1) < -12.0
189 u(2, 1) = u(2, 1) - (u(1, 1) + 12.0);
190 end
191 end
192 if u(2, 1) > 12.0
193 u(1, 1) = u(1, 1) - (u(2, 1) - 12.0);
194 else
195 if u(2, 1) < -12.0
196 u(1, 1) = u(1, 1) - (u(2, 1) + 12.0);
197 end
198 end
199 if u(1, 1) > 12.0
200 u(1, 1) = 12.0;
201 end
202 if u(1, 1) < -12.0
203 u(1, 1) = -12.0;
204 end
205 if u(2, 1) > 12.0
206 u(2, 1) = 12.0;
207 end
208 if u(2, 1) < -12.0
209 u(2, 1) = -12.0;
210 end
211 end
212 end
213
214 end
215 smt(n, 6) = u(1,1);
216 smt(n, 7) = u(2,1);
217 xhat = dm.a * xhat + dm.b * u + L * (dm.c * x - dm.c * xhat);
218 x = dm.a * x + dm.b * u;
219
220 n = n + 1;
221end
222
223figure;
224subplot(6, 1, 1);
225plot(smt(:, 1), smt(:, 2) + smt(:, 3));
226legend('dist');
227subplot(6, 1, 2);
228plot(smt(:, 1), smt(:, 2) - smt(:, 3));
229legend('angle');
230subplot(3, 1, 2);
231plot(smt(:, 1), smt(:, 4), smt(:, 1), smt(:, 5));
232legend('lu', 'ru');
233subplot(3, 1, 3);
234plot(smt(:, 1), smt(:, 6), smt(:, 1), smt(:, 7));
235legend('lu_{real}', 'ru_{real}');
236
237%figure;
238%plot(smt(:, 1), smt(:, 8))
239%legend('Scale Factor');
240