summaryrefslogtreecommitdiffstats
path: root/uav.m
blob: 453bd0016eac87458e18f641baca6f7b096c3cc5 (plain)
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
% Copyright (c) 2024, Naoki Sean Pross, ETH Zürich
%
% Controller design for a ducted fan VTOL micro-UAV.

%  ------------------------------------------------------------------------
% Clear environment and generate parameters

clear; clc; close all; s = tf('s');
params = uav_params();

do_plots = false;

% ------------------------------------------------------------------------
%% Define performance requirements

% Mechanically, flaps are constrained to a max of 20~25 degrees,
% and they have a maximal angular speed
alpha_max = params.actuators.ServoAbsMaxAngle;
alpha_dot_max = params.actuators.ServoNominalAngularVelocity;

W_Palpha = (s + 100 * alpha_dot_max) / (s + alpha_dot_max);
W_Palpha = alpha_max * W_Palpha / dcgain(W_Palpha); % adjust gain

% Mechanically we have a maximal angular velocity for the propeller in the
% thruster, also there are a lot of unmodelled dynamics in the thruster
omega_max = params.actuators.TurbineMaxSpeed;
W_Pomega = (s + 50 * omega_max) / (s + omega_max);

% We want a nice and smooth movements
v_xy_max = params.performance.MaxHorizontalSpeed;
v_z_max = params.performance.MaxVerticalSpeed;

W_Pxy = 1 / (s + 1 / v_xy_max);
W_Pz = 1 / (s + 1 / v_z_max);

if do_plots
  % Bode plots of performance requirements
  figure; hold on;

  bodemag(1/W_Palpha);
  bodemag(1/W_Pomega);
  bodemag(1/W_Pxy);
  bodemag(1/W_Pz);

  grid on;
  legend('$W_{P,\alpha}$', '$W_{P,\omega}$', ...
    '$W_{P,xy}$', '$W_{P,z}$', ...
    'interpreter', 'latex', 'fontSize', 8);
  title('Performance requirements');


  % Step response of position requirements
  figure; hold on;
  step(W_Pxy); step(W_Pz);
  grid on;
  legend('$W_{P,xy}$', '$W_{P,z}$', 'interpreter', 'latex', 'fontSize', 8);
  title('Step responses of position performance requirements');
end

% Construct performance for position vector by combining xy and z
W_PP = blkdiag(W_Pxy * eye(2), W_Pz);
W_PPdot = tf(1,1) * eye(3);
W_PTheta = tf(1,1) * eye(3);
W_POmega = tf(1,1) * eye(3);

perf = struct(...
  'FlapAngle', W_Palpha * eye(4), ...
  'Thrust', W_Pomega, ...
  'Position', W_PP, ...
  'Velocity', W_PPdot, ...
  'Angle', W_PTheta, ...
  'AngularVelocity', W_POmega); 

%  ------------------------------------------------------------------------
%% Define stability requirements

W_malpha = tf(1,1);
W_momega = tf(1,1);
W_mState = tf(1,1);

if do_plots
  figure; hold on;

  bodemag(W_malpha);
  bodemag(W_momega);
  bodemag(W_mState);

  grid on;
  legend('$W_{m,\alpha}$', '$W_{m,\omega}$', ...
    '$W_{m,\Theta}$', '$W_{m,\Omega}$', ...
    'interpreter', 'latex', 'fontSize', 8);
  title('Uncertainties')
end

uncert = struct(...
  'FlapAngle', W_malpha * eye(4), ...
  'Thrust', W_momega, ...
  'StateLinApprox', W_mState * eye(12));
  
% ------------------------------------------------------------------------
% Create UAV model

model = uav_model(params, perf, uncert);

% ------------------------------------------------------------------------
%% Perform H-infinity design

idx = model.uncertain.index;
idx_ey = [idx.OutputError; idx.OutputNominal];
idx_wu = [idx.InputDisturbance; idx.InputReference; idx.InputNominal];

nmeas = max(size(idx.OutputNominal)); % size of y
nctrl = max(size(idx.InputNominal)); % size of u

% Get nominal system without uncertainty (lower LFT)
G = minreal(model.uncertain.StateSpace(idx_ey, idx_wu));

hinfopt = hinfsynOptions('Display', 'on', 'Method', 'RIC', 'RelTol', 0.01);
[K_inf, N_inf, gamma, info] = hinfsyn(G, nmeas, nctrl, hinfopt);

%  ------------------------------------------------------------------------
% Verify performance satisfaction

%  ------------------------------------------------------------------------
% Perform mu-Analysis & DK iteration

% vim: ts=2 sw=2 et: