-
Notifications
You must be signed in to change notification settings - Fork 1
/
models.py
210 lines (164 loc) · 6.05 KB
/
models.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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
import numpy as np
import scipy.integrate as scp
class model_simple():
def __init__(self):
print('Initialize model')
self.u_min, self.u_max, self.nu, self.nx, self.x0 = self.specifications()
def specifications(self):
nu = 1
nx = 1
u_min = np.double(np.array([-1.])) # lower bound of inputs
u_max = np.double(np.array([1.])) # upper bound of inputs
x0 = 1
return u_min, u_max, nu, nx, x0
def simulate(self, x0, u, t, ref):
done = False
next_state = x0 * 1.1 + u
reward = -abs(next_state - ref) - 0.01 * abs(u)
if t >= 20 or -reward <= 1e-5:
done = True
return next_state, reward, done
def reset(self):
return self.x0
class model_double_intergator():
def __init__(self):
print('Initialize model')
self.u_min, self.u_max, self.nu, self.nx, self.x0 = self.specifications()
def specifications(self):
nu = 1
nx = 2
u_min = np.double(np.array([-5.])) # lower bound of inputs
u_max = np.double(np.array([5.])) # upper bound of inputs
x0 = [5, -5]
return u_min, u_max, nu, nx, x0
def simulate(self, x0, u, t, ref):
done = False
x0 = np.array(x0).reshape((self.nx, 1))
A = np.array([[1, 0.1], [-0.2, 0.95]])
B = np.array([[0], [1]])
next_state = A @ x0 + B * u
reward = -abs(next_state[0] - ref) - abs(next_state[1] - ref) - 0.01 * (u) ** 2
if t >= 50: # or -reward<=1e-5:
done = True
return next_state.reshape(self.nx, ), reward, done
def reset(self):
return self.x0
class ModelIntegration:
'''
This files integrates the model.
model: this is were the model should be changed
'''
# --- initializing model --- #
def __init__(self, parameters):
# Object variable definitions
self.parameters = parameters
self.u_min = np.double(np.array([0.])) # lower bound of inputs
self.u_max = np.double(np.array([1.])) # upper bound of inputs
self.nx, self.nu, self.x_init = 2, 1, np.array([-1., 0.])
# --- dynamic model definition --- #
def model(self, t, state):
# internal definitions
params = self.parameters
u = self.u
# define controls here
a = u[0]
# state vector
V = state[0]
tank_t = state[1]
# parameters
self.F_out = a * V
# differential equations
dV = self.F_in - self.F_out
dtank_t = 1
return np.array([dV, dtank_t], dtype='float64')
# --- simulation --- #
def reset(self):
return self.x_init
def simulation(self, controls, tf, x0, d):
'''
u shape -> (u_{dim},steps)
'''
# external definitions
self.x0, self.tf, self.F_in = 2*x0+2, tf, d*0.5 + 1.5
# internal definitions
steps, model, params = 20, self.model, self.parameters
dt = tf / (steps)
# compile state trajectories
xt = np.zeros((x0.shape[0], steps + 1))
tt = np.zeros((steps + 1))
Fit = np.zeros((steps + 1))
Fot = np.zeros((steps + 1))
# initialize simulation
current_state = self.x0
xt[:, 0] = current_state
tt[0] = 0.
Fit[0] = params["F_nom"]
Fot[0] = 0.
# simulation
for s in range(steps):
self.u = controls # [:, s] # control for this step
ode = scp.ode(model) # define ode
ode.set_integrator('lsoda', nsteps=3000) # define integrator
ode.set_initial_value(current_state, dt) # set initial value
current_state = list(ode.integrate(ode.t + dt)) # integrate system
xt[:, s + 1] = current_state # add current state
tt[s + 1] = (s + 1) * dt
Fit[s + 1] = self.F_in
Fot[s + 1] = self.F_out
reward = -abs(xt[0, -1] - 2)# - 0.01* controls**2
done = False
return [(xt[0, -1]-2)/2, d], (reward-1)/1, done
class simple_CSTR:
'''
This files integrates the model.
model: this is were the model should be changed
'''
# --- initializing model --- #
def __init__(self):
# Object variable definitions
self.u_min = np.double(np.array([0.])) # lower bound of inputs
self.u_max = np.double(np.array([1.])) # upper bound of inputs
self.nx, self.nu, self.x_init = 1, 1, np.array([(0.2-0.5)/0.5])
self.dt = 0.1
# --- dynamic model definition --- #
def model(self, t, state):
# internal definitions
u = self.u
x0 = 1.#self.x_init*0.5+0.5
# define controls here
uu = 3000*u[0]
# state vector
c = state[0]
# differential equations
dc = uu/5000 * (x0- c) - 2*c**3
return np.array([dc], dtype='float64')
# --- simulation --- #
def reset(self):
return self.x_init
def simulation(self, controls, tf, x0):
'''
u shape -> (u_{dim},steps)
'''
# external definitions
self.x0, self.tf = 0.5*x0+0.5, tf
# internal definitions
steps, model = 20, self.model
dt = tf / (steps)
# compile state trajectories
xt = np.zeros((x0.shape[0], steps + 1))
tt = np.zeros((steps + 1))
# initialize simulation
current_state = self.x0
xt[:, 0] = current_state
# simulation
for s in range(steps):
self.u = controls # [:, s] # control for this step
ode = scp.ode(model) # define ode
ode.set_integrator('lsoda', nsteps=3000) # define integrator
ode.set_initial_value(current_state, dt) # set initial value
current_state = list(ode.integrate(ode.t + dt)) # integrate system
xt[:, s + 1] = current_state # add current state
tt[s + 1] = (s + 1) * dt
reward = -(abs(xt[0, -1] - 0.3))# - 0.01* controls**2
done = False
return [(xt[0, -1]-0.5)/0.5], (reward), done