-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathLesson-3-starter-code.py
More file actions
72 lines (52 loc) · 2.26 KB
/
Copy pathLesson-3-starter-code.py
File metadata and controls
72 lines (52 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import numpy as np
from pydrake.all import (
Linearize,
TemplateSystem,
LeafSystem_,
LinearQuadraticRegulator,
)
@TemplateSystem.define("Pendulum_")
def Pendulum_(T):
class Impl(LeafSystem_[T]):
def _construct(self, converter=None):
LeafSystem_[T].__init__(self, converter)
# declare input port
self.DeclareVectorInputPort("u", 1) # torque (N-m)
# declare continuous state
state_index = self.DeclareContinuousState(1, 1, 0) # theta, theta_dot
self.DeclareStateOutputPort("x", state_index)
# write down some system parameters
self.m = 1.0
self.b = 0.1
self.g = 9.81
self.l = 1.0
def _construct_copy(self, other, converter=None):
Impl._construct(self, converter=converter)
def DoCalcTimeDerivatives(self, context, derivatives):
# unpack the state
state = context.get_continuous_state_vector().CopyToVector()
theta, theta_dot = state
# read the input
u = self.get_input_port().Eval(context)[0]
# state space equations
theta_ddot = 1/(self.m*self.l**2) * (u - self.b*theta_dot - self.m*self.g*self.l*np.sin(theta))
derivatives.get_mutable_vector().SetFromVector(
np.array([theta_dot, theta_ddot])
)
return Impl
Pendulum = Pendulum_[None] # default instantiation
if __name__ == "__main__":
# linearize the pendulum about the bottom equilibrium point
pendulum = Pendulum()
# choose the equilibrium point we wish to linearize about
context = pendulum.CreateDefaultContext()
context.SetContinuousState([np.pi, 0])
pendulum.get_input_port().FixValue(context, [0])
sys = Linearize(pendulum, context)
# Compute the LQR controller for the pendulum (you can tune Q, R as you wish)
Q = np.diag([10, 1])
R = np.diag([1])
K = LinearQuadraticRegulator(sys.A(), sys.B(), Q, R)[0]
# print the results of linearization and LQR
print(f"{sys.A()=}, \n{sys.B()=}, \n{sys.C()=}, \n{sys.D()=}")
print(f"Computed LQR controller: {K=}")