-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolve_riccati_ode.m
117 lines (102 loc) · 3.59 KB
/
solve_riccati_ode.m
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
%==========================================================================
%
% solve_riccati_ode Solves the Riccati differential equation for the
% finite-horizon linear quadratic regulator.
%
% [t,P] = solve_riccati_ode(A,B,Q,R,[],PT,tspan)
% [t,P] = solve_riccati_ode(A,B,Q,R,S,PT,tspan)
%
% Copyright © 2021 Tamas Kis
% Last Update: 2022-12-08
% Website: https://tamaskis.github.io
% Contact: [email protected]
%
% TECHNICAL DOCUMENTATION:
% https://tamaskis.github.io/files/Riccati_Differential_Equation.pdf
%
% DEPENDENCIES:
% • IVP Solver Toolbox (https://www.mathworks.com/matlabcentral/fileexchange/103975-ivp-solver-toolbox)
%
%--------------------------------------------------------------------------
%
% ------
% INPUT:
% ------
% A - (n×n double) state/system/dynamics matrix
% B - (n×m double) input/control matrix
% Q - (n×n double) state weighting matrix
% R - (m×m double) input/control weighting matrix
% S - (OPTIONAL) (n×m double) cross-coupling weighting matrix
% --> defaults to 0
% PT - (n×n double) terminal condition at time t = T
% tspan - (1×2 or 1×(N+1) double) time interval to solve over
% --> To specify the interval only and allow MATLAB to choose
% the intermediate times, use the 1×2 vector [t0 T]
% --> To specify specific times you want the solution at, use
% the 1×(N+1) vector: [t0 t1 ... tN]
%
% -------
% OUTPUT:
% -------
% t - ((N+1)×1 double) time vector
% P - (n×n×(N+1) double) solution of Riccati differential equation
%
% -----------
% CONDITIONS:
% -----------
% 1. M ⪰ 0 (positive semidefinite). If S = 0, this conditions reduces to
% the following two conditions:
% (a) Q ⪰ 0 (positive semidefinite)
% (b) R ≻ 0 (positive definite)
% 2. PT ⪰ 0 (positive semidefinite)
% 3. (A,B) stabilizable
% 4. (A-BR^(-1)S^T,Q-SR^(-1)S^T) detectable
% • if S = 0, this condition reduces to (A,Q^(1/2)) detectable
%
% -----
% NOTE:
% -----
% --> The nth page of "M" stores the solution corresponding to the nth
% time in "t".
%
%==========================================================================
function [t,P] = solve_riccati_ode(A,B,Q,R,S,PT,tspan)
% ----------------------
% Determines dimensions.
% ----------------------
% state dimension
n = size(A,1);
% input dimension
m = size(B,2);
% ----------------------------------------------------
% Sets unspecified parameters to their default values.
% ----------------------------------------------------
% defaults cross-coupling matrix to 0
if isempty(S)
S = zeros(n,m);
end
% ---------
% Solution.
% ---------
% flips tspan so the Riccati ODE is solved backwards in time
tspan = fliplr(tspan);
% defines Riccati ODE has a matrix-valued ODE
dPdt = @(t,P) -(A.'*P+P*A-(P*B+S)/R*(B.'*P+S.')+Q);
% converts matrix-valued ODE to vector-valued ODE
dydt = mat2vec_ODE(dPdt,n);
% converts matrix initial condition to vector initial condition
yT = mat2vec_IC(PT);
% solves Riccati ODE
[t,y] = ode45(dydt,tspan,yT);
% transforms solution matrix for vector-valued ODE into solution array
% for matrix-valued ODE
P = vec2mat_sol(y,n);
% reorders t so that time is increasing
t = flipud(t);
% reorders solution for P
P_reordered = zeros(size(P));
for k = 1:length(t)
P_reordered(:,:,k) = P(:,:,length(t)-k+1);
end
P = P_reordered;
end