blob: d7e2feca1d3507e2cf708b41ae5bd6688c45e58d [file] [log] [blame]
Austin Schuh999a19e2024-05-04 14:52:39 -07001#!/usr/bin/python3
2
3import numpy
4import sympy
5import scipy.integrate
6from frc971.control_loops.python import control_loop
7from frc971.control_loops.python import controls
8
James Kuszmaulaa52ff82024-08-10 15:16:49 -07009import matplotlib
Austin Schuh999a19e2024-05-04 14:52:39 -070010from matplotlib import pylab
11import sys
12import gflags
13import glog
14
15FLAGS = gflags.FLAGS
16
James Kuszmaulaa52ff82024-08-10 15:16:49 -070017matplotlib.use("GTK3Agg")
18
Austin Schuh999a19e2024-05-04 14:52:39 -070019
20class SwerveSimulation(object):
21
22 def __init__(self):
23 self.motor = control_loop.KrakenFOC()
24
25 vx, vy, omega = sympy.symbols('vx vy omega')
26 fx, fy = sympy.symbols('fx fy')
27 t = sympy.symbols('t')
28
29 # 5kg of force got us a slip angle of 0.05 radians with 4 tires.
30 self.C = 5 * 9.8 / 0.05 / 4.0
31
32 self.r = 2 * 0.0254
33
34 # Base is 20kg without battery.
35 self.m = 25.0
36 self.G = 1.0 / 6.75
37
38 I = sympy.symbols('I')
39
40 # Absolute linear velocity in x and y of the robot.
41 self.dvx = (self.C * (self.r * omega - vx) / vx + fx) / self.m
42 self.dvy = (-self.C * sympy.atan2(vy, vx) + fy) / self.m
43 # Angular velocity of the wheel.
44 self.domega = (-self.G * self.C * (self.r * omega - vx) / vx * self.r +
45 self.motor.Kt * I) * self.G / self.motor.motor_inertia
46
47 self.x0 = sympy.lambdify((vx, vy, omega, fx, fy, I), self.dvx)
48 self.x1 = sympy.lambdify((vx, vy, omega, fx, fy, I), self.dvy)
49 self.x2 = sympy.lambdify((vx, vy, omega, fx, fy, I), self.domega)
50
51 self.f = lambda X, fx, fy, I: numpy.array([
52 self.x0(X[0], X[1], X[2], fx, fy, I),
53 self.x1(X[0], X[1], X[2], fx, fy, I),
54 self.x2(X[0], X[1], X[2], fx, fy, I)
55 ])
56
57 print(self.f)
58 print(
59 'f',
60 self.f(numpy.matrix([[1.0], [0.0], [1.0 / self.r]]), 0.0, 0.0,
61 0.0))
62
63 print(self.dvx)
64 print(self.dvy)
65 print(self.domega)
66
67 def run(self, X_initial):
68 print(X_initial)
69
70 fx = -9.8
71 fy = 0.0
72 I = -(fx * self.r * self.G / self.motor.Kt)
73 print(f"Fx: {fx}, Fy: {fy}, I: {I}")
74
75 def f_const(t, X):
76 return self.f(
77 X=X,
78 fx=fx,
79 fy=fy,
80 I=I,
81 )
82
83 result = scipy.integrate.solve_ivp(
84 f_const, (0, 2.0),
85 numpy.squeeze(numpy.array(X_initial.transpose())),
86 max_step=0.01)
87
88 pylab.plot(result.t, result.y[0, :], label="y0")
89 pylab.plot(result.t, result.y[1, :], label="y1")
90 pylab.plot(result.t, result.y[2, :], label="y2")
91
92 pylab.legend()
93 pylab.show()
94
95
96def main(argv):
97 s = SwerveSimulation()
98 s.run(numpy.matrix([[1.0], [0.0], [1.0 / s.r]]))
99
100 return 0
101
102
103if __name__ == '__main__':
104 argv = FLAGS(sys.argv)
105 glog.init()
106 sys.exit(main(argv))