blob: a801649df086c6d868e11b1b09b64dd31c9ba7e9 [file] [log] [blame]
Austin Schuhc8ca2442013-02-23 12:29:33 -08001#!/usr/bin/python
2
Austin Schuh3c542312013-02-24 01:53:50 -08003import control_loop
Austin Schuh0d9467a2014-02-15 22:36:45 -08004import controls
Austin Schuhc8ca2442013-02-23 12:29:33 -08005import numpy
Austin Schuhc8ca2442013-02-23 12:29:33 -08006import sys
Austin Schuhc8ca2442013-02-23 12:29:33 -08007from matplotlib import pylab
Austin Schuhc8ca2442013-02-23 12:29:33 -08008
Austin Schuh3bb9a442014-02-02 16:01:45 -08009class Claw(control_loop.ControlLoop):
10 def __init__(self, name="RawClaw"):
11 super(Claw, self).__init__(name)
Austin Schuhc8ca2442013-02-23 12:29:33 -080012 # Stall Torque in N m
James Kuszmaule1755b32014-02-13 06:27:48 -080013 self.stall_torque = 2.42
Austin Schuhc8ca2442013-02-23 12:29:33 -080014 # Stall Current in Amps
James Kuszmaule1755b32014-02-13 06:27:48 -080015 self.stall_current = 133
James Kuszmaul92797402014-02-17 14:08:49 -080016 # Free Speed in RPM
17 self.free_speed = 5500.0
Austin Schuh3c542312013-02-24 01:53:50 -080018 # Free Current in Amps
James Kuszmaule1755b32014-02-13 06:27:48 -080019 self.free_current = 2.7
Austin Schuh3bb9a442014-02-02 16:01:45 -080020 # Moment of inertia of the claw in kg m^2
James Kuszmaul92797402014-02-17 14:08:49 -080021 # measured from CAD
22 self.J_top = 0.3
23 self.J_bottom = 0.9
Austin Schuhc8ca2442013-02-23 12:29:33 -080024 # Resistance of the motor
James Kuszmaul92797402014-02-17 14:08:49 -080025 self.R = 12.0 / self.stall_current
Austin Schuhc8ca2442013-02-23 12:29:33 -080026 # Motor velocity constant
Austin Schuh3c542312013-02-24 01:53:50 -080027 self.Kv = ((self.free_speed / 60.0 * 2.0 * numpy.pi) /
28 (13.5 - self.R * self.free_current))
Austin Schuhc8ca2442013-02-23 12:29:33 -080029 # Torque constant
30 self.Kt = self.stall_torque / self.stall_current
31 # Gear ratio
James Kuszmaule1755b32014-02-13 06:27:48 -080032 self.G = 14.0 / 48.0 * 18.0 / 32.0 * 18.0 / 66.0 * 12.0 / 60.0
Austin Schuhc8ca2442013-02-23 12:29:33 -080033 # Control loop time step
34 self.dt = 0.01
35
James Kuszmaule2afbe42014-02-17 22:29:59 -080036 # State is [bottom position, bottom velocity, top - bottom position,
37 # top - bottom velocity]
38 # Input is [bottom power, top power - bottom power * J_top / J_bottom]
James Kuszmaul92797402014-02-17 14:08:49 -080039 # Motor time constants. difference_bottom refers to the constant for how the
40 # bottom velocity affects the difference of the top and bottom velocities.
41 self.common_motor_constant = -self.Kt / self.Kv / (self.G * self.G * self.R)
42 self.bottom_bottom = self.common_motor_constant / self.J_bottom
43 self.difference_bottom = self.common_motor_constant * (1 / self.J_bottom
44 - 1 / self.J_top)
45 self.difference_difference = self.common_motor_constant / self.J_top
Austin Schuhc8ca2442013-02-23 12:29:33 -080046 # State feedback matrices
James Kuszmaule2afbe42014-02-17 22:29:59 -080047
Austin Schuhc8ca2442013-02-23 12:29:33 -080048 self.A_continuous = numpy.matrix(
James Kuszmaule2afbe42014-02-17 22:29:59 -080049 [[0, 0, 0, 0],
50 [0, 0, 0, 0],
James Kuszmaul92797402014-02-17 14:08:49 -080051 [0, 0, self.bottom_bottom, 0],
52 [0, 0, self.difference_bottom, self.difference_difference]])
Austin Schuh0d9467a2014-02-15 22:36:45 -080053
James Kuszmaule2afbe42014-02-17 22:29:59 -080054 self.A_bottom_cont = numpy.matrix(
55 [[0, 1],
56 [0, self.bottom_bottom]])
57
58 self.A_diff_cont = numpy.matrix(
59 [[0, 1],
60 [0, self.difference_difference]])
61
62 self.A_continuous[0:2, 0:2] = self.A_bottom_cont
63 self.A_continuous[2:4, 2:4] = self.A_diff_cont
64 self.A_continuous[3, 1] = self.difference_bottom
65
James Kuszmaul92797402014-02-17 14:08:49 -080066 self.motor_feedforward = self.Kt / (self.G * self.R)
James Kuszmaulf2ed6e62014-02-17 17:52:07 -080067 self.motor_feedforward_bottom = self.motor_feedforward / self.J_bottom
68 self.motor_feedforward_difference = self.motor_feedforward / self.J_top
James Kuszmaul92797402014-02-17 14:08:49 -080069 self.motor_feedforward_difference_bottom = (
70 self.motor_feedforward * (1 / self.J_bottom - 1 / self.J_top))
Austin Schuhc8ca2442013-02-23 12:29:33 -080071 self.B_continuous = numpy.matrix(
Austin Schuh0d9467a2014-02-15 22:36:45 -080072 [[0, 0],
James Kuszmaul92797402014-02-17 14:08:49 -080073 [self.motor_feedforward_bottom, 0],
James Kuszmaule2afbe42014-02-17 22:29:59 -080074 [0, 0],
75 [0,#self.motor_feedforward_difference_bottom,
James Kuszmaul92797402014-02-17 14:08:49 -080076 self.motor_feedforward_difference]])
James Kuszmaule2afbe42014-02-17 22:29:59 -080077
78 self.B_bottom_cont = numpy.matrix(
79 [[0],
80 [self.motor_feedforward_bottom]])
81
82 self.B_diff_cont = numpy.matrix(
83 [[0],
84 [self.motor_feedforward_difference]])
85
Austin Schuh0d9467a2014-02-15 22:36:45 -080086 self.C = numpy.matrix([[1, 0, 0, 0],
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -080087 [1, 0, 1, 0]])
Austin Schuh0d9467a2014-02-15 22:36:45 -080088 self.D = numpy.matrix([[0, 0],
89 [0, 0]])
Austin Schuhc8ca2442013-02-23 12:29:33 -080090
Austin Schuhc1f68892013-03-16 17:06:27 -070091 self.A, self.B = self.ContinuousToDiscrete(
92 self.A_continuous, self.B_continuous, self.dt)
Austin Schuhc8ca2442013-02-23 12:29:33 -080093
James Kuszmaule2afbe42014-02-17 22:29:59 -080094 self.A_bottom, self.B_bottom = controls.c2d(
95 self.A_bottom_cont, self.B_bottom_cont, self.dt)
96 self.A_diff, self.B_diff = controls.c2d(
97 self.A_diff_cont, self.B_diff_cont, self.dt)
98
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -080099 print "A, A_bot, A_diff:"
100 print self.A, self.A_bottom, self.A_diff
101 print "B, B_bot, B_diff:"
102 print self.B, self.B_bottom, self.B_diff
103
104 # If B should equal [[B_bot, 0],[0, B_diff]], then the B
105 # generated by ContinuousToDiscrete adds in a couple extra
106 # numbers which make it impossible to control 4 values in K.
107 # Here, I make B equal what I had thought it should, thereby
108 # allowing us to control 4 values in K.
109 self.B_actual = numpy.matrix(self.B)
110 self.B[2, 0] = 0.0
111 self.B[3, 0] = 0.0
112 # If we do the above, with setting values of B to zero,
113 # then we can no longer make all the necessary values of A - B * K
114 # zero, because the discrete transform added a term affecting position
115 # over the timestep and that term can no longer be cancelled out if we
116 # are to also cancel out the term where the velocity of the bottom
117 # affects the velocity of the separation.
118 self.A_actual = numpy.matrix(self.A)
119 self.A[2, 1] = self.A[3, 1] * self.B[2, 1] / self.B[3, 1]
James Kuszmaule2afbe42014-02-17 22:29:59 -0800120
Austin Schuh0d9467a2014-02-15 22:36:45 -0800121 #controlability = controls.ctrb(self.A, self.B);
122 #print "Rank of controlability matrix.", numpy.linalg.matrix_rank(controlability)
123
James Kuszmaulf2ed6e62014-02-17 17:52:07 -0800124 self.Q = numpy.matrix([[(1.0 / (0.40 ** 2.0)), 0.0, 0.0, 0.0],
125 [0.0, (1.0 / (0.007 ** 2.0)), 0.0, 0.0],
Austin Schuhcda86af2014-02-16 16:16:39 -0800126 [0.0, 0.0, 0.2, 0.0],
127 [0.0, 0.0, 0.0, 2.00]])
128
James Kuszmaulf2ed6e62014-02-17 17:52:07 -0800129 self.R = numpy.matrix([[(1.0 / (40.0 ** 2.0)), 0.0],
130 [0.0, (1.0 / (5.0 ** 2.0))]])
James Kuszmaule2afbe42014-02-17 22:29:59 -0800131 #self.K = controls.dlqr(self.A, self.B, self.Q, self.R)
132
133 # TODO(james): Fix this for discrete time domain.
134 self.K = numpy.matrix([[0, 0, 0.0, 0.0],
135 [0.0, self.A[3, 1] / self.B[3, 1], 0, 0]])
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800136 self.K_bottom = controls.dplace(self.A_bottom, self.B_bottom, [0.6, 0.7])
137 self.K_diff = controls.dplace(self.A_diff, self.B_diff, [0.3, 0.5])
James Kuszmaule2afbe42014-02-17 22:29:59 -0800138 self.K[0, 0:2] = self.K_bottom
139 self.K[1, 2:4] = self.K_diff
140 #lstsq_A = numpy.identity(2)
141 #lstsq_A[0] = self.B[1]
142 #lstsq_A[1] = self.B[3]
143 #self.K[0:2, 0] = numpy.linalg.lstsq(lstsq_A, numpy.matrix([[0.0], [0.0]]))[0]
144 #self.K[0:2, 2] = numpy.linalg.lstsq(
145 # lstsq_A,
146 # numpy.matrix([[self.A[1, 2]], [self.A[3, 2]]]))[0]
Austin Schuhcda86af2014-02-16 16:16:39 -0800147
148 print "K unaugmented"
149 print self.K
James Kuszmaule2afbe42014-02-17 22:29:59 -0800150 print "B * K unaugmented"
151 print self.B * self.K
152 F = self.A - self.B * self.K
James Kuszmaule2afbe42014-02-17 22:29:59 -0800153 print "A - B * K unaugmented"
154 print F
155 print "eigenvalues"
156 print numpy.linalg.eig(F)[0]
Austin Schuhc8ca2442013-02-23 12:29:33 -0800157
158 self.rpl = .05
159 self.ipl = 0.008
Austin Schuh3c542312013-02-24 01:53:50 -0800160 self.PlaceObserverPoles([self.rpl + 1j * self.ipl,
Austin Schuh0d9467a2014-02-15 22:36:45 -0800161 self.rpl + 1j * self.ipl,
James Kuszmaule2afbe42014-02-17 22:29:59 -0800162 self.rpl - 1j * self.ipl,
Austin Schuh3c542312013-02-24 01:53:50 -0800163 self.rpl - 1j * self.ipl])
Austin Schuhc8ca2442013-02-23 12:29:33 -0800164
James Kuszmaul92797402014-02-17 14:08:49 -0800165 # The box formed by U_min and U_max must encompass all possible values,
166 # or else Austin's code gets angry.
Austin Schuhcda86af2014-02-16 16:16:39 -0800167 self.U_max = numpy.matrix([[12.0], [24.0]])
168 self.U_min = numpy.matrix([[-12.0], [-24.0]])
Austin Schuhc8ca2442013-02-23 12:29:33 -0800169
Austin Schuhc1f68892013-03-16 17:06:27 -0700170 self.InitializeState()
171
172
Austin Schuh3bb9a442014-02-02 16:01:45 -0800173class ClawDeltaU(Claw):
174 def __init__(self, name="Claw"):
175 super(ClawDeltaU, self).__init__(name)
Austin Schuhc1f68892013-03-16 17:06:27 -0700176 A_unaugmented = self.A
177 B_unaugmented = self.B
Austin Schuh0d9467a2014-02-15 22:36:45 -0800178 C_unaugmented = self.C
Austin Schuhc1f68892013-03-16 17:06:27 -0700179
Austin Schuh0d9467a2014-02-15 22:36:45 -0800180 self.A = numpy.matrix([[0.0, 0.0, 0.0, 0.0, 0.0],
181 [0.0, 0.0, 0.0, 0.0, 0.0],
182 [0.0, 0.0, 0.0, 0.0, 0.0],
183 [0.0, 0.0, 0.0, 0.0, 0.0],
184 [0.0, 0.0, 0.0, 0.0, 1.0]])
185 self.A[0:4, 0:4] = A_unaugmented
186 self.A[0:4, 4] = B_unaugmented[0:4, 0]
Austin Schuhc1f68892013-03-16 17:06:27 -0700187
Austin Schuh0d9467a2014-02-15 22:36:45 -0800188 self.B = numpy.matrix([[0.0, 0.0],
189 [0.0, 0.0],
190 [0.0, 0.0],
191 [0.0, 0.0],
192 [1.0, 0.0]])
193 self.B[0:4, 1] = B_unaugmented[0:4, 1]
Austin Schuhc1f68892013-03-16 17:06:27 -0700194
Austin Schuh0d9467a2014-02-15 22:36:45 -0800195 self.C = numpy.concatenate((C_unaugmented, numpy.matrix([[0.0], [0.0]])),
196 axis=1)
197 self.D = numpy.matrix([[0.0, 0.0],
198 [0.0, 0.0]])
Austin Schuhc1f68892013-03-16 17:06:27 -0700199
Austin Schuh0d9467a2014-02-15 22:36:45 -0800200 #self.PlaceControllerPoles([0.55, 0.35, 0.55, 0.35, 0.80])
201 self.Q = numpy.matrix([[(1.0 / (0.04 ** 2.0)), 0.0, 0.0, 0.0, 0.0],
202 [0.0, (1.0 / (0.01 ** 2)), 0.0, 0.0, 0.0],
203 [0.0, 0.0, 0.01, 0.0, 0.0],
204 [0.0, 0.0, 0.0, 0.08, 0.0],
205 [0.0, 0.0, 0.0, 0.0, (1.0 / (10.0 ** 2))]])
206
207 self.R = numpy.matrix([[0.000001, 0.0],
208 [0.0, 1.0 / (10.0 ** 2.0)]])
209 self.K = controls.dlqr(self.A, self.B, self.Q, self.R)
210
211 self.K = numpy.matrix([[50.0, 0.0, 10.0, 0.0, 1.0],
212 [50.0, 0.0, 10.0, 0.0, 1.0]])
213 #self.K = numpy.matrix([[50.0, -100.0, 0, -10, 0],
214 # [50.0, 100.0, 0, 10, 0]])
215
216 controlability = controls.ctrb(self.A, self.B);
217 print "Rank of augmented controlability matrix.", numpy.linalg.matrix_rank(controlability)
Austin Schuhc1f68892013-03-16 17:06:27 -0700218
219 print "K"
220 print self.K
221 print "Placed controller poles are"
222 print numpy.linalg.eig(self.A - self.B * self.K)[0]
Austin Schuh0d9467a2014-02-15 22:36:45 -0800223 print [numpy.abs(x) for x in numpy.linalg.eig(self.A - self.B * self.K)[0]]
Austin Schuhc1f68892013-03-16 17:06:27 -0700224
225 self.rpl = .05
226 self.ipl = 0.008
Austin Schuh0d9467a2014-02-15 22:36:45 -0800227 self.PlaceObserverPoles([self.rpl + 1j * self.ipl, 0.10, 0.09,
Brian Silverman23a67ca2013-03-16 23:48:50 -0700228 self.rpl - 1j * self.ipl, 0.90])
Austin Schuh0d9467a2014-02-15 22:36:45 -0800229 #print "A is"
230 #print self.A
231 #print "L is"
232 #print self.L
233 #print "C is"
234 #print self.C
235 #print "A - LC is"
236 #print self.A - self.L * self.C
Austin Schuhc1f68892013-03-16 17:06:27 -0700237
Austin Schuh0d9467a2014-02-15 22:36:45 -0800238 #print "Placed observer poles are"
239 #print numpy.linalg.eig(self.A - self.L * self.C)[0]
240
241 self.U_max = numpy.matrix([[12.0], [12.0]])
242 self.U_min = numpy.matrix([[-12.0], [-12.0]])
Austin Schuhc1f68892013-03-16 17:06:27 -0700243
244 self.InitializeState()
245
246
Austin Schuhcda86af2014-02-16 16:16:39 -0800247def FullSeparationPriority(claw, U):
248 bottom_u = U[0, 0]
249 top_u = U[1, 0] + bottom_u
250
251 #print "Bottom is", new_unclipped_bottom_u, "Top is", top_u
252 if bottom_u > claw.U_max[0, 0]:
253 #print "Bottom is too big. Was", new_unclipped_bottom_u, "changing top by", new_unclipped_bottom_u - claw.U_max[0, 0]
254 top_u -= bottom_u - claw.U_max[0, 0]
255 if top_u < claw.U_min[1, 0]:
256 top_u = claw.U_min[1, 0]
257
258 bottom_u = claw.U_max[0, 0]
259 if top_u > claw.U_max[1, 0]:
260 bottom_u -= top_u - claw.U_max[1, 0]
261 if bottom_u < claw.U_min[0, 0]:
262 bottom_u = claw.U_min[0, 0]
263
264 top_u = claw.U_max[1, 0]
265 if top_u < claw.U_min[1, 0]:
266 bottom_u -= top_u - claw.U_min[1, 0]
267 if bottom_u > claw.U_max[0, 0]:
268 bottom_u = claw.U_max[0, 0]
269
270 top_u = claw.U_min[1, 0]
271 if bottom_u < claw.U_min[0, 0]:
272 top_u -= bottom_u - claw.U_min[0, 0]
273 if top_u > claw.U_max[1, 0]:
274 top_u = claw.U_max[1, 0]
275
276 bottom_u = claw.U_min[0, 0]
277
278 return numpy.matrix([[bottom_u], [top_u - bottom_u]])
279
280def AverageUFix(claw, U):
281 bottom_u = U[0, 0]
James Kuszmaulf2ed6e62014-02-17 17:52:07 -0800282 top_u = bottom_u + U[1, 0]
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800283 top_u = bottom_u * claw.J_top / claw.J_bottom + U[1, 0]
Austin Schuhcda86af2014-02-16 16:16:39 -0800284
285 #print "Bottom is", new_unclipped_bottom_u, "Top is", top_u
James Kuszmaul92797402014-02-17 14:08:49 -0800286 if (bottom_u > claw.U_max[0, 0] or top_u > claw.U_max[0, 0] or
287 top_u < claw.U_min[0, 0] or bottom_u < claw.U_min[0, 0]):
Austin Schuhcda86af2014-02-16 16:16:39 -0800288 scalar = 12.0 / max(numpy.abs(top_u), numpy.abs(bottom_u))
289 top_u *= scalar
290 bottom_u *= scalar
291
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800292 #return numpy.matrix([[bottom_u], [top_u - bottom_u]])
293 return numpy.matrix([[bottom_u], [top_u - bottom_u * claw.J_top / claw.J_bottom]])
Austin Schuhcda86af2014-02-16 16:16:39 -0800294
Austin Schuh0d9467a2014-02-15 22:36:45 -0800295def ClipDeltaU(claw, U):
296 delta_u = U[0, 0]
297 top_u = U[1, 0]
298 old_bottom_u = claw.X[4, 0]
299
300 # TODO(austin): Preserve the difference between the top and bottom power.
301 new_unclipped_bottom_u = old_bottom_u + delta_u
302
303 #print "Bottom is", new_unclipped_bottom_u, "Top is", top_u
304 if new_unclipped_bottom_u > claw.U_max[0, 0]:
305 #print "Bottom is too big. Was", new_unclipped_bottom_u, "changing top by", new_unclipped_bottom_u - claw.U_max[0, 0]
306 top_u -= new_unclipped_bottom_u - claw.U_max[0, 0]
307 new_unclipped_bottom_u = claw.U_max[0, 0]
308 if top_u > claw.U_max[1, 0]:
309 new_unclipped_bottom_u -= top_u - claw.U_max[1, 0]
310 top_u = claw.U_max[1, 0]
311 if top_u < claw.U_min[1, 0]:
312 new_unclipped_bottom_u -= top_u - claw.U_min[1, 0]
313 top_u = claw.U_min[1, 0]
314 if new_unclipped_bottom_u < claw.U_min[0, 0]:
315 top_u -= new_unclipped_bottom_u - claw.U_min[0, 0]
316 new_unclipped_bottom_u = claw.U_min[0, 0]
317
318 new_bottom_u = numpy.clip(new_unclipped_bottom_u, claw.U_min[0, 0], claw.U_max[0, 0])
319 new_top_u = numpy.clip(top_u, claw.U_min[1, 0], claw.U_max[1, 0])
320
321 return numpy.matrix([[new_bottom_u - old_bottom_u], [new_top_u]])
Austin Schuhc1f68892013-03-16 17:06:27 -0700322
Austin Schuhc8ca2442013-02-23 12:29:33 -0800323def main(argv):
Austin Schuh3c542312013-02-24 01:53:50 -0800324 # Simulate the response of the system to a step input.
Austin Schuh0d9467a2014-02-15 22:36:45 -0800325 #claw = ClawDeltaU()
326 #simulated_x = []
327 #for _ in xrange(100):
328 # claw.Update(numpy.matrix([[12.0]]))
329 # simulated_x.append(claw.X[0, 0])
Austin Schuhc8ca2442013-02-23 12:29:33 -0800330
Austin Schuh0d9467a2014-02-15 22:36:45 -0800331 #pylab.plot(range(100), simulated_x)
332 #pylab.show()
Austin Schuhc8ca2442013-02-23 12:29:33 -0800333
James Kuszmaulf2ed6e62014-02-17 17:52:07 -0800334 # Simulate the closed loop response of the system.
Austin Schuhcda86af2014-02-16 16:16:39 -0800335 claw = Claw("TopClaw")
336 t = []
Austin Schuh0d9467a2014-02-15 22:36:45 -0800337 close_loop_x_bottom = []
338 close_loop_x_sep = []
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800339 actual_sep = []
340 actual_x_bottom = []
James Kuszmaulf2ed6e62014-02-17 17:52:07 -0800341 close_loop_x_top = []
Austin Schuh0d9467a2014-02-15 22:36:45 -0800342 close_loop_u_bottom = []
343 close_loop_u_top = []
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800344 R = numpy.matrix([[0.0], [0.00], [0.0], [0.0]])
345 claw.X[0, 0] = 1
346 claw.X_hat[0, 0] = 1
347 X_actual = claw.X
348 print "B actual"
349 print claw.B_actual
Austin Schuhcda86af2014-02-16 16:16:39 -0800350 for i in xrange(100):
351 #print "Error is", (R - claw.X_hat)
352 U = claw.K * (R - claw.X_hat)
353 #U = numpy.clip(claw.K * (R - claw.X_hat), claw.U_min, claw.U_max)
354 #U = FullSeparationPriority(claw, U)
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800355 #U = AverageUFix(claw, U)
Austin Schuhcda86af2014-02-16 16:16:39 -0800356 #U = claw.K * (R - claw.X_hat)
357 #U = ClipDeltaU(claw, U)
358 claw.UpdateObserver(U)
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800359 #claw.Update(U)
360 X_actual = claw.A_actual * X_actual + claw.B_actual * U
361 claw.Y = claw.C * X_actual
362 close_loop_x_bottom.append(claw.X_hat[0, 0] * 10)
Austin Schuhcda86af2014-02-16 16:16:39 -0800363 close_loop_u_bottom.append(U[0, 0])
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800364 actual_sep.append(X_actual[2, 0] * 100)
365 actual_x_bottom.append(X_actual[0, 0] * 10)
366 close_loop_x_sep.append(claw.X_hat[2, 0] * 100)
367 close_loop_x_top.append((claw.X_hat[2, 0] + claw.X_hat[0, 0]) * 10)
368 close_loop_u_top.append(U[1, 0] + U[0, 0] * claw.J_top / claw.J_bottom)
Austin Schuhcda86af2014-02-16 16:16:39 -0800369 t.append(0.01 * i)
Austin Schuhc8ca2442013-02-23 12:29:33 -0800370
Austin Schuhcda86af2014-02-16 16:16:39 -0800371 pylab.plot(t, close_loop_x_bottom, label='x bottom')
James Kuszmaulf2ed6e62014-02-17 17:52:07 -0800372 pylab.plot(t, close_loop_x_sep, label='separation')
James Kuszmaul4e4ec8e2014-02-18 10:46:49 -0800373 pylab.plot(t, actual_x_bottom, label='true x bottom')
374 pylab.plot(t, actual_sep, label='true separation')
James Kuszmaulf2ed6e62014-02-17 17:52:07 -0800375 pylab.plot(t, close_loop_x_top, label='x top')
Austin Schuhcda86af2014-02-16 16:16:39 -0800376 pylab.plot(t, close_loop_u_bottom, label='u bottom')
377 pylab.plot(t, close_loop_u_top, label='u top')
Austin Schuh0d9467a2014-02-15 22:36:45 -0800378 pylab.legend()
Austin Schuhfa033692013-02-24 01:00:55 -0800379 pylab.show()
Austin Schuhc8ca2442013-02-23 12:29:33 -0800380
Austin Schuh3c542312013-02-24 01:53:50 -0800381 # Write the generated constants out to a file.
Austin Schuhcda86af2014-02-16 16:16:39 -0800382 if len(argv) != 3:
383 print "Expected .h file name and .cc file name for the claw."
Austin Schuhc8ca2442013-02-23 12:29:33 -0800384 else:
Austin Schuhcda86af2014-02-16 16:16:39 -0800385 claw = Claw("Claw")
386 loop_writer = control_loop.ControlLoopWriter("Claw", [claw])
Austin Schuh683a0d02013-03-02 01:51:31 -0800387 if argv[1][-3:] == '.cc':
Austin Schuhcda86af2014-02-16 16:16:39 -0800388 loop_writer.Write(argv[2], argv[1])
Austin Schuh683a0d02013-03-02 01:51:31 -0800389 else:
Austin Schuhcda86af2014-02-16 16:16:39 -0800390 loop_writer.Write(argv[1], argv[2])
Austin Schuhc8ca2442013-02-23 12:29:33 -0800391
392if __name__ == '__main__':
393 sys.exit(main(sys.argv))