forked from StanfordASL/AA274_HW1
-
Notifications
You must be signed in to change notification settings - Fork 0
/
P1_optimal_control.py
164 lines (126 loc) · 4.62 KB
/
P1_optimal_control.py
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import numpy as np
import math
import scikits.bvp_solver
import matplotlib.pyplot as plt
from utils import *
dt = 0.005
def ode_fun(tau, z):
'''
This function computes the dz given tau and z. It is used in the bvp solver.
Inputs:
tau: the independent variable. This must be the first argument.
z: the state vector. The first three states are [x, y, th, ...]
Output:
dz: the state derivative vector. Returns a numpy array.
'''
########## Code starts here ##########
########## Code ends here ##########
return dz
def bc_fun(za, zb):
'''
This function computes boundary conditions. It is used in the bvp solver.
Inputs:
za: the state vector at the initial time
zb: the state vector at the final time
Output:
bca: tuple of boundary conditions at initial time
bcb: tuple of boundary conditions at final time
'''
# final goal pose
xf = 5
yf = 5
thf = -np.pi/2.0
xf = [xf, yf, thf]
# initial pose
x0 = [0, 0, -np.pi/2.0]
########## Code starts here ##########
########## Code ends here ##########
return (bca, bcb)
def solve_bvp(problem_inputs, initial_guess):
'''
This function solves the bvp_problem.
Inputs:
problem_inputs: a dictionary of the arguments needs to define the problem
num_ODE, num_parameters, num_left_boundary_conditions, boundary_points, function, boundary_conditions
initial_guess: initial guess of the solution
Outputs:
z: a numpy array of the solution. It is of size [time, state_dim]
Read this documentation -- https://pythonhosted.org/scikits.bvp_solver/tutorial.html
'''
problem = scikits.bvp_solver.ProblemDefinition(**problem_inputs)
soln = scikits.bvp_solver.solve(problem, solution_guess=initial_guess)
# Test if time is reversed in bvp_solver solution
flip, tf = check_flip(soln(0))
t = np.arange(0,tf,dt)
z = soln(t/tf)
if flip:
z[3:7,:] = -z[3:7,:]
z = z.T # solution arranged so that it is [time, state_dim]
return z
def compute_controls(z):
'''
This function computes the controls V, om, given the state z. It is used in main().
Input:
z: z is the state vector for multiple time instances. It has size [time, state_dim]
Outputs:
V: velocity control input
om: angular rate control input
'''
########## Code starts here ##########
########## Code ends here ##########
return V, om
def main():
'''
This function solves the specified bvp problem and returns the corresponding optimal contol sequence
Outputs:
V: optimal V control sequence
om: optimal om ccontrol sequence
You are required to define the problem inputs, initial guess, and compute the controls
HINT: The total time is between 15-25
'''
########## Code starts here ##########
########## Code ends here ##########
problem_inputs = {
'num_ODE' : num_ODE,
'num_parameters' : num_parameters,
'num_left_boundary_conditions' : num_left_boundary_conditions,
'boundary_points' : boundary_points,
'function' : function,
'boundary_conditions' : boundary_conditions
}
z = solve_bvp(problem_inputs, initial_guess)
V, om = compute_controls(z)
return z, V, om
if __name__ == '__main__':
z, V, om = main()
tf = z[0,-1]
t = np.arange(0,tf,dt)
x = z[:,0]
y = z[:,1]
th = z[:,2]
data = {'z': z, 'V': V, 'om': om}
save_dict(data, 'data/optimal_control.pkl')
maybe_makedirs('plots')
# plotting
# plt.rc('font', weight='bold', size=16)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(x, y,'k-',linewidth=2)
plt.quiver(x[1:-1:200], y[1:-1:200],np.cos(th[1:-1:200]),np.sin(th[1:-1:200]))
plt.grid('on')
plt.plot(0,0,'go',markerfacecolor='green',markersize=15)
plt.plot(5,5,'ro',markerfacecolor='red', markersize=15)
plt.xlabel('X')
plt.ylabel('Y')
plt.axis([-1, 6, -1, 6])
plt.title('Optimal Control Trajectory')
plt.subplot(1, 2, 2)
plt.plot(t, V,linewidth=2)
plt.plot(t, om,linewidth=2)
plt.grid('on')
plt.xlabel('Time [s]')
plt.legend(['V [m/s]', '$\omega$ [rad/s]'], loc='best')
plt.title('Optimal control sequence')
plt.tight_layout()
plt.savefig('plots/optimal_control.png')
plt.show()