In [155]:
%pylab inline
import control
import scipy.linalg
In [156]:
eps = 0.000001
A = array([[0, 1], [-1, -1]])
B = array([[0],[1]])
C = eye(2)
D = array([[0],[0]])
sys = control.ss(A, B, C, D)
sys.damp()
Out[156]:
In [157]:
K = control.care(sys.A, sys.B, eye(2), eye(1))[2]
sys_closed = control.feedback(sys, control.ss(0,[0,0],0,K))
sys_closed.damp()
Out[157]:
In [176]:
Q = diag([1, -1])
R = 0.01*eye(1)
P = scipy.linalg.solve_continuous_are(sys.A, sys.B, Q, R)
K_destab = -linalg.inv(R).dot(B.T).dot(P)
sys_destab = control.feedback(
sys_closed, control.ss(0,[0,0],0,K_destab))
t, y, x = control.forced_response(
sys_destab,
T=linspace(0,10, 1000), X0=[0.001,0])
plot(t, x.T)
u = K_destab.dot(x)
plot(t, u.T, '--')
sys_destab.damp()
Out[176]:
In [5]:
Ac = sys_closed.A
Bc = sys_closed.B
Ac.T.dot(P) + P.dot(Ac) - P.dot(Bc).dot(linalg.inv(R)).dot(Bc.T).dot(P) + Q
Out[5]:
In [10]:
P = scipy.linalg.solve_continuous_are(Ar, Br, Q, R)
P
Out[10]:
In [11]:
Ar.T.dot(P) + P.dot(Ar) - P.dot(Br).dot(linalg.inv(R)).dot(Br.T).dot(P) + Q
Out[11]:
In [153]:
A = array([[-1]])
B = array([[1]])
C = array([[1]])
D = array([[1]])
Q=array([[-1]])
R=array([[1]])
sys = control.ss(A, B, C, D)
P = scipy.linalg.solve_continuous_are(A, B, Q, R)
A.T.dot(P) + P.dot(A) - P.dot(B).dot(linalg.inv(R)).dot(B.T).dot(P) + Q
Out[153]:
In [154]:
linalg.inv(array([[1]]))
Out[154]:
In [151]:
%pylab inline
import picos as pic
import cvxopt as cvx
import numpy as np
import scipy.linalg
import scipy.optimize
import scipy.integrate
def solve_bounded_disturbance(A, B, C, D):
def solve_lmi(A_data, B_data, C_data, D_data, alpha, verbose=False):
sdp = pic.Problem()
# shape
n_x = A_data.shape[0]
n_u = B_data.shape[1]
# variables
P = sdp.add_variable('P', (n_x, n_x), vtype='symmetric')
alpha = pic.new_param('alpha', alpha)
mu_1 = sdp.add_variable('mu_1')
mu_2 = sdp.add_variable('mu_2')
# parameters
A = pic.new_param('A', cvx.matrix(A_data))
B = pic.new_param('B', cvx.matrix(B_data))
C = pic.new_param('C', cvx.matrix(C_data))
D = pic.new_param('D', cvx.matrix(D_data))
I_n_u = pic.new_param('I', cvx.sparse(cvx.matrix(np.eye(n_u))))
I_n_x = pic.new_param('I', cvx.sparse(cvx.matrix(np.eye(n_x))))
eps = 1e-10
sdp.add_constraint(
(P*A + A.T*P + 2*alpha*P & P*B) //
(B.T*P & -2*alpha*mu_1*I_n_u) << -eps)
sdp.add_constraint(
(C.T*C - P & C.T*D) //
(D.T*C & D.T*D - mu_2*I_n_u) << -eps)
sdp.add_constraint(P >> eps*I_n_x)
sdp.add_constraint(mu_1 << 0.01)
sdp.add_constraint(mu_2 << 0.01)
sdp.set_objective('max', mu_1 + mu_2)
try:
sdp.solve(verbose=verbose)
mu_1 = sdp.variables['mu_1'].value[0,0]
mu_2 = sdp.variables['mu_2'].value[0,0]
gamma = np.sqrt(mu_1 + mu_2)
except Exception as e:
print e
gamma = -1
return gamma, sdp
# we use fmin to solve a line search problem in alpha for minimum gamma
print('line search')
alpha_opt = scipy.optimize.fmin(lambda alpha: -solve_lmi(A, B, C, D, alpha)[0], x0=-1)
gamma, sdp = solve_lmi(A, B, C, D, alpha_opt)
print sdp
if sdp.status == 'optimal':
P = sdp.variables['P'].value
mu_1 = sdp.variables['mu_1'].value[0,0]
mu_2 = sdp.variables['mu_2'].value[0,0]
print 'optimal alpha: ', alpha_opt
print 'gamma: ', gamma
print 'mu_1: ', mu_1
print 'mu_2: ', mu_2
print 'P: ', P
else:
sdp = solve_lmi(A, B, C, D, alpha_opt, verbose=True)
raise RuntimeError('Optimization failed')
return sdp, P, alpha_opt, gamma
In [152]:
A = array([[0,1],[-1,-1]])
B = array([[0],[1]])
C = eye(2)
D = array([[0], [0]])
sdp, P, alpha, gamma = solve_bounded_disturbance(A, B, C, D)
In [ ]: