CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/simulink/arducopter/functions/resampleLog.m
Views: 1799
1
function [logResampled] = resampleLog(log,resampling,method)
2
% Resamples log if resample is set to true, so that all included messages
3
% have the same first time stamp and the same amount of elements
4
% (if they have the same sample time)
5
% If resample is set to false, the Time vector of all messages is just
6
% adapted to the first time stamp of the log
7
%
8
% Fabian Bredemeier - IAV GmbH
9
% License: GPL v3
10
11
headerProps2Copy = {'fileName', 'filePathName', 'platform', 'version', ...
12
'commit', 'bootTimeUTC', 'msgsContained', 'totalLogMsgs', 'msgFilter', ...
13
'numMsgs'};
14
15
% Define messages that are to be excluded from resampling, but still copied
16
msgs2Exclude = {'FMT', 'FMTU', 'MODE', 'MULT', 'UNIT', 'PARM', 'SIDS'};
17
18
% Messages with multiple instances
19
msgWithMultInstances = {'ARSP', 'BARO', 'BAT', 'BCL', 'BCL2', 'ESC', ...
20
'GPA', 'GPS', 'IMU', 'MAG', 'PRX', 'RFND'};
21
22
% Define message header props that need to be copied to new log
23
msgProps2Copy = {'typeNumID', 'fieldUnits', 'fieldMultipliers', 'name', ...
24
'MsgInstance'};
25
26
% Define message props that need to be excluded in new log
27
msgProps2Exclude = {'TimeS', 'LineNo', 'DatenumUTC', 'TimeUS'};
28
29
% Define sample times that are used for logging
30
TsVec = [0.00025 0.001 0.0025 0.01 0.02 0.04 0.1 0.2 1];
31
32
% Allowed jitter percentage of sample time
33
TsJitPerc = 0.5;
34
35
% Get first timestamp of log
36
timeZero = getTimeZero(log, log.msgsContained, msgs2Exclude);
37
38
% Convert LogMsgGroup object into structs
39
log = log.getStruct();
40
41
for prop = string(fieldnames(log))'
42
propObj = log.(prop);
43
44
% Just copy property if contained in cell array
45
if any(strcmp(prop, headerProps2Copy))
46
logResampled.(prop) = propObj;
47
continue;
48
end
49
50
% Skip message if it shall be excluded
51
if any(strcmp(prop, msgs2Exclude))
52
logResampled.(prop) = propObj;
53
continue;
54
end
55
56
% Skip message if it is a deleted handle
57
if isempty(propObj)
58
continue;
59
end
60
61
% Handle messages with multiple instances (like BAT)
62
if any(strcmp(msgWithMultInstances, prop))
63
% Create idx vector for certain instance
64
if isfield(propObj, 'Instance') % Check message name of instance
65
idxVec = propObj.Instance == 0;
66
elseif isfield(propObj, 'I')
67
idxVec = propObj.I == 0;
68
elseif isfield(propObj, 'C') % XKF messages
69
idxVec = propObj.C == 0;
70
end
71
else % Message without multiple instances
72
idxVec = logical(ones(length(propObj.TimeS),1));
73
end
74
75
% Get plausibilized time vector
76
timePlaus = plausibilizeTime(log.(prop).TimeS(idxVec));
77
78
% Determine sample time of message
79
TsRaw = mean(diff(timePlaus));
80
Ts = 0;
81
for TsElem = TsVec
82
if TsRaw > TsElem*(1-TsJitPerc) && TsRaw < TsElem*(1+TsJitPerc)
83
Ts = TsElem;
84
break;
85
end
86
end
87
% Throw error if Ts could not be determined
88
if Ts == 0
89
error(['Sample time of message ' char(prop) ' could not be determined. Mean: ' num2str(TsRaw) 's']);
90
end
91
92
% Copy properties to new object. Resample signals
93
msgProps = string(fieldnames(log.(prop)))';
94
for msgProp = msgProps(1:end)
95
96
% Copy property if included in msgProps2Copy
97
if any(strcmp(msgProp, msgProps2Copy))
98
logResampled.(prop).(msgProp) = propObj.(msgProp);
99
continue;
100
end
101
102
% Skip property if included in msgProps2Exclude
103
if any(strcmp(msgProp, msgProps2Exclude))
104
continue;
105
end
106
107
% Get signal values for the correct indices
108
signal = propObj.(msgProp)(idxVec);
109
110
% Define time starting from first time stamp
111
time = propObj.TimeS(idxVec) - timeZero;
112
113
% Plausibilize time and signal vector
114
[time, signal] = plausibilizeTime(time, signal);
115
116
% If any time sample is still larger than the final time,
117
% plausibilize the time vector again
118
while(any(time > time(end)))
119
[time, signal] = plausibilizeTime(time, signal);
120
end
121
122
% Define old time vector. Insert zero at beginning for the signals
123
% to start at 0s. Insert first signal value in value vector.
124
if time(1) > 1e-3
125
timeOld = zeros(length(time)+1,1);
126
signalOld = zeros(length(signal)+1,1);
127
timeOld(2:length(time)+1, 1) = time;
128
timeOld(1) = 0;
129
signalOld(2:length(signal)+1, 1) = signal;
130
signalOld(1) = signal(1);
131
else
132
timeOld = time;
133
signalOld = signal;
134
end
135
136
% Catch nan in signal
137
if any(isnan(signalOld))
138
signalOld = zeros(length(signalOld),1);
139
warning(['Detected nan in ' char(prop) '.' char(msgProp)])
140
end
141
142
if resampling
143
% Resample signal
144
if any(strcmp(method, 'makima')) || any(strcmp(method, 'nearest'))
145
len = round(timeOld(end) / Ts, 0); % Get amount of time vec elements
146
timeNew = Ts * (0:len)';
147
signalNew = interp1(timeOld, signalOld, timeNew, method, 'extrap');
148
else
149
[signalNew, timeNew] = resample(signalOld, timeOld, 1/Ts, method);
150
end
151
else
152
signalNew = signal;
153
timeNew = Ts*(0:length(signal)-1)';
154
end
155
156
% Insert property
157
logResampled.(prop).(msgProp) = signalNew;
158
% Add new property sampling time Ts
159
logResampled.(prop).Ts = Ts;
160
end
161
162
% Add Time Property
163
logResampled.(prop).TimeS = timeNew;
164
end
165
end
166
167
168