-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgen_high_level_params_mat.m
108 lines (91 loc) · 3.63 KB
/
gen_high_level_params_mat.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
% GEN_HIGH_LEVEL_PARAMS_MAT Generates the high-level parameters matrix file.
%
% A function for generating the high-level parameters matrix file following
% the High-Level FOFB IOC conventions. This file can be directly inputed into
% the High-Level FOFB GUI.
%
% The arguments are:
% cl_ps_idtf_fpath: filepath to the power supplies' closed-loop fitted models
% obtained by sysid/ps_cl_tfest
% ps_pi_fpga_gains_fpath: filepath to the power supplies' PI gains file
% obtained by sysid/ps_pi_tune
% params_out_fn: output parameters filename
% Copyright (C) 2024 CNPEM (cnpem.br)
% Author: Guilherme Ricioli <guilherme.ricioli@lnls.br>
function gen_high_level_params_mat(cl_ps_idtf_fpath, ps_pi_fpga_gains_fpath, ...
params_out_fn)
% Constants
fs = 48193;
ncorr = 160;
nbiquads = 4;
excluded_corr = [1, 80, 81, 160];
actuator_bw = 10000;
addpath('sysid');
cl_ps_idtf = load(cl_ps_idtf_fpath).cl_ps_idtf;
ps_pi_fpga_gains = readmatrix(ps_pi_fpga_gains_fpath);
pass_through_biquad.sos = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0];
pass_through_biquad.g = 1.0;
filter.sos = repmat(pass_through_biquad.sos, nbiquads, 1);
filter.g = pass_through_biquad.g;
% Common filters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Biquad 1: Notch filter @ FOFB/4
biquad = calc_notch_biquad(0.5, 8);
filter.sos(1, :) = biquad.sos;
filter.g = filter.g*biquad.g;
% Biquad 2: Notch filter @ FOFB/2
biquad = calc_notch_biquad(0.9999999999, 8);
filter.sos(2, :) = biquad.sos;
filter.g = filter.g*biquad.g;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Specific filters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
filters = cell(ncorr, 1);
for i = 1:ncorr
filters{i} = filter;
% We don't have fitted models for the excluded correctors
if ~ismember(i, excluded_corr)
cl_ps_bw = bandwidth(cl_ps_idtf{i})/(2*pi);
% Biquad 3: Pre-emphasis shelf filter
biquad = calc_shelf_biquad(-cl_ps_bw, -actuator_bw, 1/fs);
filters{i}.sos(3, :) = biquad.sos;
filters{i}.g = filters{i}.g*biquad.g;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot composed filters' bode
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure();
opts = bodeoptions;
opts.FreqUnits = 'Hz';
opts.PhaseWrapping = 'on';
for i = 1:ncorr
if ~ismember(i, excluded_corr)
[b, a] = sos2tf(filters{i}.sos, filters{i}.g);
sys = tf(b, a, 1/fs);
% DC gain should be 0 dB
assert((dcgain(sys) - 1.0) < 0.001);
bode(sys, opts);
hold on;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Build high-level parameters matrix
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nparams = 2 + 1 + 5*nbiquads; % 2 for kp and ki,
% 1 for filters' accumulated gain and
% 5*nbiquads for filters' coefficients.
params = zeros(ncorr, nparams);
% Columns 1, 2: kp, ki
params(:, 1:2) = ps_pi_fpga_gains;
for i = 1:ncorr
filter = filters{i};
filter.sos(:, 4) = []; % a0 is assumed to be 1
% Column 3: filters' accumulated gain
params(i, 3) = filter.g;
% Columns 4 to (4 + 5*nbiquads) - 1: filters' coefficients
params(i, 4:end) = reshape(filter.sos', 1, 5*nbiquads);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
writematrix(params, params_out_fn);
end