blob: 381e577a88110bee02acb8d98ab62d420fd24b0e [file] [log] [blame]
James Kuszmauladab8f92013-11-06 08:42:34 -08001#!/usr/bin/python
2
3import numpy
4import sys
James Kuszmaula0850442013-11-06 18:27:20 -08005sys.path.append('../../frc971/control_loops/python')
James Kuszmauladab8f92013-11-06 08:42:34 -08006from matplotlib import pylab
7import control_loop
8import slycot
9
10class Shooter(control_loop.ControlLoop):
11 def __init__(self):
12 super(Shooter, self).__init__("Shooter")
13 # Stall Torque in N m
14 self.stall_torque = 2.42211227883219
15 # Stall Current in Amps
16 self.stall_current = 133
17 # Free Speed in RPM
18 self.free_speed = 4650.0
19 # Free Current in Amps
20 self.free_current = 2.7
21 # Moment of inertia of the shooter wheel in kg m^2
22 self.J = 0.0032
23 # Resistance of the motor, divided by 2 to account for the 2 motors
24 self.R = 12.0 / self.stall_current
25 # Motor velocity constant
26 self.Kv = ((self.free_speed / 60.0 * 2.0 * numpy.pi) /
27 (12.0 - self.R * self.free_current))
28 # Torque constant
29 self.Kt = self.stall_torque / self.stall_current
30 # Gear ratio
31 self.G = 40.0 / 34.0
32 # Control loop time step
33 self.dt = 0.01
34
35 # State feedback matrices
36 self.A_continuous = numpy.matrix(
37 [[-self.Kt / self.Kv / (self.J * self.G * self.G * self.R)]])
38 self.B_continuous = numpy.matrix(
39 [[self.Kt / (self.J * self.G * self.R)]])
40 self.C = numpy.matrix([[1]])
41 self.D = numpy.matrix([[0]])
42
43 self.A, self.B = self.ContinuousToDiscrete(self.A_continuous, self.B_continuous,
44 self.dt)
45
46 self.InitializeState()
47
48 self.PlaceControllerPoles([.8])
49 # LQR stuff for optimization, if needed.
50 #print self.K
51 #self.R_LQR = numpy.matrix([[1.5]])
52 #self.P = slycot.sb02od(1, 1, self.A, self.B, self.C * self.C.T, self.R, 'D')[0]
53 #self.K = (numpy.linalg.inv(self.R_LQR + self.B.T * self.P * self.B)
54 # * self.B.T * self.P * self.A)
55 #print numpy.linalg.eig(self.A - self.B * self.K)
56
57
58 self.PlaceObserverPoles([0.45])
59
60 self.U_max = numpy.matrix([[12.0]])
61 self.U_min = numpy.matrix([[-12.0]])
62
63
64def main(argv):
65 # Simulate the response of the system to a step input.
66 shooter_data = numpy.genfromtxt('shooter/shooter_data.csv', delimiter=',')
67 shooter = Shooter()
68 simulated_x = []
69 real_x = []
70 x_vel = []
71 initial_x = shooter_data[0, 2]
72 last_x = initial_x
73 for i in xrange(shooter_data.shape[0]):
74 shooter.Update(numpy.matrix([[shooter_data[i, 1]]]))
75 simulated_x.append(shooter.X[0, 0])
76 x_offset = shooter_data[i, 2] - initial_x
77 real_x.append(x_offset)
78 x_vel.append((shooter_data[i, 2] - last_x) * 100.0)
79 last_x = shooter_data[i, 2]
80
81 sim_delay = 1
82# pylab.plot(range(sim_delay, shooter_data.shape[0] + sim_delay),
83# simulated_x, label='Simulation')
84# pylab.plot(range(shooter_data.shape[0]), real_x, label='Reality')
85# pylab.plot(range(shooter_data.shape[0]), x_vel, label='Velocity')
86# pylab.legend()
87# pylab.show()
88
89 # Simulate the closed loop response of the system to a step input.
90 shooter = Shooter()
91 close_loop_x = []
92 close_loop_U = []
93 velocity_goal = 400
94 R = numpy.matrix([[velocity_goal]])
95 goal = False
96 for i in pylab.linspace(0,1.99,200):
97 # Iterate the position up.
98 R = numpy.matrix([[velocity_goal]])
99 U = numpy.clip(shooter.K * (R - shooter.X_hat) +
100 (numpy.identity(shooter.A.shape[0]) - shooter.A) * R / shooter.B,
101 shooter.U_min, shooter.U_max)
102 shooter.UpdateObserver(U)
103 shooter.Update(U)
104 close_loop_x.append(shooter.X[0, 0])
105 close_loop_U.append(U[0, 0])
106 if (abs(R[0, 0] - shooter.X[0, 0]) < R[0, 0]* 0.01 and (not goal)):
107 goal = True
108 print i
109
110 #pylab.plotfile("shooter.csv", (0,1))
111 pylab.plot(pylab.linspace(0,1.99,200), close_loop_U)
112 #pylab.plotfile("shooter.csv", (0,2))
113 pylab.plot(pylab.linspace(0,1.99,200), close_loop_x)
114 pylab.show()
115
116 # Simulate spin down.
117 spin_down_x = [];
118 for _ in xrange(150):
119 U = 0
120 shooter.UpdateObserver(U)
121 shooter.Update(U)
122 spin_down_x.append(shooter.X[0, 0])
123
124 #pylab.plot(range(150), spin_down_x)
125 #pylab.show()
126
127 if len(argv) != 3:
128 print "Expected .h file name and .cc file name"
129 else:
James Kuszmaula0850442013-11-06 18:27:20 -0800130 loop_writer = control_loop.ControlLoopWriter("Shooter", [shooter], namespaces=['bot3','control_loops'])
James Kuszmauladab8f92013-11-06 08:42:34 -0800131 if argv[1][-3:] == '.cc':
132 loop_writer.Write(argv[2], argv[1])
133 else:
134 loop_writer.Write(argv[1], argv[2])
135
136
137if __name__ == '__main__':
138 sys.exit(main(sys.argv))