Master Thesis Code
by Simon Moser
Loading...
Searching...
No Matches
MyVqf.m
Go to the documentation of this file.
1% =========================================================================== %
2%> @brief MyVqf is an interface to the VQF python package.
3%>
4%> This class is an interface to the VQF python package. It is used to create
5%> a VQF object that can be used to perform VQF operations. The VQF package
6%> is a python package that provides a VQF algorithm implementation. This
7%> algorithm is used to estimate the orientation of a sensor in 3D space. The
8%> VQF algorithm is based on the work of the following paper:
9%> https://doi.org/10.1016/j.inffus.2022.10.014
10%>
11%> @code
12%> % Example usage:
13%> % create example data with the JumpSensor class
14%> js = JumpSensor();
15%> data = js.generate(zeros(1000,3), zeros(1000,3), quaternion.ones(1000,1));
16%>
17%> % create VQF object
18%> vqf = MyVqf();
19%>
20%> % filter the data
21%> result = vqf.filter(data.tt.acc, data.tt.gyr, data.tt.mag);
22%> @endcode
23%>
24%> @note The implementation currently always uses the root python environment.
25%>
26%> @copyright see the file @ref LICENSE in the root directory of the repository
27% =========================================================================== %
28
29classdef MyVqf
30
31 properties (Access=public)
32 %> python environment
33 pe
34
35 %> VQF python package
36 vqf
37
38 %> VQF object with forward filter configuration
39 vqfForward
40
41 %> numpy package
42 np
44 %> @name Sampling times
45 %> @{
46 %> sampling times for the sensors in [s]
47 gyrTs = 1/200;
48 accTs = 1/200;
49 magTs = 1/200;
50 %> @}
51
52 %> @name VQF parameters
53 %> @{
54 %> default values according to the VQF documentation
55 tauAcc = 3; % [s]
56 tauMag = 9; % [s]
57 motionBiasEstEnabled = true;
58 restBiasEstEnabled = true;
59 magDistRejectionEnabled = true; % (default: true)
60 biasSigmaInit = 0.5; % [°/s]
61 biasForgettingTime = 100; % [s]
62 biasClip = 15; % [°/s] (default is 2.0 °/s, but the used MPU has higher ratings)
63 biasSigmaMotion = 0.1; % [°/s] (dafault is 0.1 °/s)
64 biasVerticalForgettingFactor = 0.0001;
65 biasSigmaRest = 0.03; % [°/s] (default is 0.03 °/s)
66 restMinT = 1.5; % [s] (default is 1.5 s)
67 restFilterTau = 0.5; % [s]
68 restThGyr = 2; % [°/s] (default is 2 °/s)
69 restThAcc = 0.5; % [m/s^2] (default is 0.5 m/s^2)
70 magCurrentTau = 0.05; % [s]
71 magRefTau = 20; % [s]
72 magNormTh = 0.2; % (default is 0.1 = 10%)
73 magDipTh = 20; % [°] (dfeault is 10 °)
74 magNewTime = 20; % [s]
75 magNewFirstTime = 5; % [s]
76 magNewMinGyr = 10; % [°/s] (default is 20 °/s)
77 magMinUndisturbedTime = 0.5; % [s]
78 magMaxRejectionTime = 60; % [s]
79 magRejectionFactor = 2;
80 %> @}
81
82 end
83
84 methods (Access=public)
85
86 % ====================================================================== %
87 %> @brief Constructor of the MyVqf class.
88 %>
89 %> @param None
90 %>
91 %> @retval obj -Instance of the MyVqf class.
92 %>
93 %> @note The root python environment is used and the packages 'vqf' and
94 %> 'numpy' must be installed in the python environment.
95 % ====================================================================== %
96 function obj = MyVqf()
97 % create python environment
98 obj.pe = pyenv("ExecutionMode","OutOfProcess");
99 end
101 % ====================================================================== %
102 %> @brief Destructor of the MyVqf class.
103 %>
104 %> @param obj -Instance of the MyVqf class.
105 %>
106 %> @retval None
107 % ====================================================================== %
108 function delete(obj)
109 % delete python environment
110 delete(obj.pe);
111 end
113 % ====================================================================== %
114 %> @brief Filter the data using the VQF algorithm (only forward).
115 %>
116 %> @param obj - Instance of the MyVqf class.
117 %> @param acc - Accelerometer data [Nx3] (m/s^2).
118 %> @param gyr - Gyroscope data [Nx3] (rad/s).
119 %> @param mag - Magnetometer data [Nx3] (uT).
120 %>
121 %> @retval data - Struct with the filtered data.
122 % ====================================================================== %
123 function data = filter(obj, acc, gyr, mag)
124
125 % convert gyr from deg/s to rad/s
126 gyr = gyr * pi/180;
127
128 % create numpy arrays
129 acc = py.numpy.ascontiguousarray(acc);
130 gyr = py.numpy.ascontiguousarray(gyr);
131 mag = py.numpy.ascontiguousarray(mag);
132
133 % create new VQF
134 obj = obj.createVQF();
135
136 % filter data
137 data = obj.vqfForward.updateBatch(gyr, acc, mag);
138
139 % output as struct with matlab arrays
140 data = struct(data);
141 data.quat6D = double(data.quat6D);
142 data.quat9D = double(data.quat9D);
143 data.delta = double(data.delta);
144 data.bias = double(data.bias);
145 data.biasSigma = double(data.biasSigma);
146 data.restDetected = boolean(data.restDetected);
147 data.magDistDetected = boolean(data.magDistDetected);
148 end
149
150 % ====================================================================== %
151 %> @brief Filter the data using the VQF algorithm (offline, forward and
152 %> backward).
153 %>
154 %> @param obj - Instance of the MyVqf class.
155 %> @param acc - Accelerometer data [Nx3] (m/s^2).
156 %> @param gyr - Gyroscope data [Nx3] (rad/s).
157 %> @param mag - Magnetometer data [Nx3] (uT).
158 %>
159 %> @retval data - Struct with the filtered data.
160 % ====================================================================== %
161 function data = filterOffline(obj, acc, gyr, mag)
162
163 % convert gyr from deg/s to rad/s
164 gyr = gyr * pi/180;
165
166 % create numpy arrays
167 acc = py.numpy.ascontiguousarray(acc);
168 gyr = py.numpy.ascontiguousarray(gyr);
169 mag = py.numpy.ascontiguousarray(mag);
170
171 % filter data
172 data = obj.offlineVQF(acc, gyr, mag);
173
174 % output as struct with matlab arrays
175 data = struct(data);
176 data.quat6D = double(data.quat6D);
177 data.quat9D = double(data.quat9D);
178 data.delta = double(data.delta);
179 data.bias = double(data.bias);
180 data.biasSigma = double(data.biasSigma);
181 data.restDetected = boolean(data.restDetected);
182 data.magDistDetected = boolean(data.magDistDetected);
183 end
184
185 % ====================================================================== %
186 %> @brief method to set properties of the VQF filter
187 %>
188 %> @param obj - Instance of the MyVqf class.
189 %> @param params - Struct with the properties to set.
190 %> - params.tauAcc (optional)
191 %> - params.tauMag (optional)
192 %> - params.motionBiasEstEnabled (optional)
193 %> - params.restBiasEstEnabled (optional)
194 %> - params.magDistRejectionEnabled (optional)
195 %> - params.biasSigmaInit (optional)
196 %> - params.biasForgettingTime (optional)
197 %> - params.biasClip (optional)
198 %> - params.biasSigmaMotion (optional)
199 %> - params.biasVerticalForgettingFactor (optional)
200 %> - params.biasSigmaRest (optional)
201 %> - params.restMinT (optional)
202 %> - params.restFilterTau (optional)
203 %> - params.restThGyr (optional)
204 %> - params.restThAcc (optional)
205 %> - params.magCurrentTau (optional)
206 %> - params.magRefTau (optional)
207 %> - params.magNormTh (optional)
208 %> - params.magDipTh (optional)
209 %> - params.magNewTime (optional)
210 %> - params.magNewFirstTime (optional)
211 %> - params.magNewMinGyr (optional)
212 %> - params.magMinUndisturbedTime (optional)
213 %> - params.magMaxRejectionTime (optional)
214 %> - params.magRejectionFactor (optional)
215 %>
216 %> @retval obj - Instance of the MyVqf class.
217 %>
218 %> @note The properties are set to the default values if not provided.
219 %> @note see the VQF documentation for the meaning of the properties.
220 % ====================================================================== %
221 function obj = setProperties(obj, params)
222
223 % check and init with default
224 arguments
225 obj {mustBeA(obj, 'my_VQF')}
226 params.tauAcc (1,1) double {mustBePositive} = obj.tauAcc;
227 params.tauMag (1,1) double {mustBePositive} = obj.tauMag;
228 params.motionBiasEstEnabled (1,1) logical = obj.motionBiasEstEnabled;
229 params.restBiasEstEnabled (1,1) logical = obj.restBiasEstEnabled;
230 params.magDistRejectionEnabled (1,1) logical = obj.magDistRejectionEnabled;
231 params.biasSigmaInit (1,1) double {mustBePositive} = obj.biasSigmaInit;
232 params.biasForgettingTime (1,1) double {mustBePositive} = obj.biasForgettingTime;
233 params.biasClip (1,1) double {mustBePositive} = obj.biasClip;
234 params.biasSigmaMotion (1,1) double {mustBePositive} = obj.biasSigmaMotion;
235 params.biasVerticalForgettingFactor (1,1) double {mustBePositive} = obj.biasVerticalForgettingFactor;
236 params.biasSigmaRest (1,1) double {mustBePositive} = obj.biasSigmaRest;
237 params.restMinT (1,1) double {mustBePositive} = obj.restMinT;
238 params.restFilterTau (1,1) double {mustBePositive} = obj.restFilterTau;
239 params.restThGyr (1,1) double {mustBePositive} = obj.restThGyr;
240 params.restThAcc (1,1) double {mustBePositive} = obj.restThAcc;
241 params.magCurrentTau (1,1) double {mustBePositive} = obj.magCurrentTau;
242 params.magRefTau (1,1) double {mustBePositive} = obj.magRefTau;
243 params.magNormTh (1,1) double {mustBePositive} = obj.magNormTh;
244 params.magDipTh (1,1) double {mustBePositive} = obj.magDipTh;
245 params.magNewTime (1,1) double {mustBePositive} = obj.magNewTime;
246 params.magNewFirstTime (1,1) double {mustBePositive} = obj.magNewFirstTime;
247 params.magNewMinGyr (1,1) double {mustBePositive} = obj.magNewMinGyr;
248 params.magMinUndisturbedTime (1,1) double {mustBePositive} = obj.magMinUndisturbedTime;
249 params.magMaxRejectionTime (1,1) double {mustBePositive} = obj.magMaxRejectionTime;
250 params.magRejectionFactor (1,1) double {mustBePositive} = obj.magRejectionFactor;
251 end
252
253 % set properties
254 obj.tauAcc = params.tauAcc;
255 obj.tauMag = params.tauMag;
256 obj.motionBiasEstEnabled = params.motionBiasEstEnabled;
257 obj.restBiasEstEnabled = params.restBiasEstEnabled;
258 obj.magDistRejectionEnabled = params.magDistRejectionEnabled;
259 obj.biasSigmaInit = params.biasSigmaInit;
260 obj.biasForgettingTime = params.biasForgettingTime;
261 obj.biasClip = params.biasClip;
262 obj.biasSigmaMotion = params.biasSigmaMotion;
263 obj.biasVerticalForgettingFactor = params.biasVerticalForgettingFactor;
264 obj.biasSigmaRest = params.biasSigmaRest;
265 obj.restMinT = params.restMinT;
266 obj.restFilterTau = params.restFilterTau;
267 obj.restThGyr = params.restThGyr;
268 obj.restThAcc = params.restThAcc;
269 obj.magCurrentTau = params.magCurrentTau;
270 obj.magRefTau = params.magRefTau;
271 obj.magNormTh = params.magNormTh;
272 obj.magDipTh = params.magDipTh;
273 obj.magNewTime = params.magNewTime;
274 obj.magNewFirstTime = params.magNewFirstTime;
275 obj.magNewMinGyr = params.magNewMinGyr;
276 obj.magMinUndisturbedTime = params.magMinUndisturbedTime;
277 obj.magMaxRejectionTime = params.magMaxRejectionTime;
278 obj.magRejectionFactor = params.magRejectionFactor;
279 end
280
281 % properties getter
282 function params = getProperties(obj)
283 params.tauAcc = obj.tauAcc;
284 params.tauMag = obj.tauMag;
285 params.motionBiasEstEnabled = obj.motionBiasEstEnabled;
286 params.restBiasEstEnabled = obj.restBiasEstEnabled;
287 params.magDistRejectionEnabled = obj.magDistRejectionEnabled;
288 params.biasSigmaInit = obj.biasSigmaInit;
289 params.biasForgettingTime = obj.biasForgettingTime;
290 params.biasClip = obj.biasClip;
291 params.biasSigmaMotion = obj.biasSigmaMotion;
292 params.biasVerticalForgettingFactor = obj.biasVerticalForgettingFactor;
293 params.biasSigmaRest = obj.biasSigmaRest;
294 params.restMinT = obj.restMinT;
295 params.restFilterTau = obj.restFilterTau;
296 params.restThGyr = obj.restThGyr;
297 params.restThAcc = obj.restThAcc;
298 params.magCurrentTau = obj.magCurrentTau;
299 params.magRefTau = obj.magRefTau;
300 params.magNormTh = obj.magNormTh;
301 params.magDipTh = obj.magDipTh;
302 params.magNewTime = obj.magNewTime;
303 params.magNewFirstTime = obj.magNewFirstTime;
304 params.magNewMinGyr = obj.magNewMinGyr;
305 params.magMinUndisturbedTime = obj.magMinUndisturbedTime;
306 params.magMaxRejectionTime = obj.magMaxRejectionTime;
307 params.magRejectionFactor = obj.magRejectionFactor;
308 end
309
310 end
311
312 methods (Access=protected)
313
314 % ====================================================================== %
315 %> @brief Create and configure VQF forward filter.
316 %>
317 %> @param obj - Instance of the MyVqf class.
318 %>
319 %> @retval obj - Instance of the MyVqf class.
320 % ====================================================================== %
321 function obj = createVQF(obj)
322 % create VQF object
323 vqf = py.vqf.VQF(...
324 obj.gyrTs, ...
325 accTs=obj.accTs, ...
326 magTs=obj.magTs, ...
327 tauAcc=obj.tauAcc, ...
328 tauMag = obj.tauMag, ...
329 motionBiasEstEnabled = obj.motionBiasEstEnabled, ...
330 restBiasEstEnabled = obj.restBiasEstEnabled, ...
331 magDistRejectionEnabled = obj.magDistRejectionEnabled, ...
332 biasSigmaInit = obj.biasSigmaInit, ...
333 biasForgettingTime = obj.biasForgettingTime, ...
334 biasClip = obj.biasClip, ...
335 biasSigmaMotion = obj.biasSigmaMotion, ...
336 biasVerticalForgettingFactor = obj.biasVerticalForgettingFactor, ...
337 biasSigmaRest = obj.biasSigmaRest, ...
338 restMinT = obj.restMinT, ...
339 restFilterTau = obj.restFilterTau, ...
340 restThGyr = obj.restThGyr, ...
341 restThAcc = obj.restThAcc, ...
342 magCurrentTau = obj.magCurrentTau, ...
343 magRefTau = obj.magRefTau, ...
344 magNormTh = obj.magNormTh, ...
345 magDipTh = obj.magDipTh, ...
346 magNewTime = obj.magNewTime, ...
347 magNewFirstTime = obj.magNewFirstTime, ...
348 magNewMinGyr = obj.magNewMinGyr, ...
349 magMinUndisturbedTime = obj.magMinUndisturbedTime, ...
350 magMaxRejectionTime = obj.magMaxRejectionTime, ...
351 magRejectionFactor = obj.magRejectionFactor);
352
353 obj.vqfForward = vqf;
354
355 end
356
357 % ====================================================================== %
358 %> @brief Call the offline VQF algorithm.
359 %>
360 %> @param obj - Instance of the MyVqf class.
361 %> @param acc - Accelerometer data [Nx3] (m/s^2).
362 %> @param gyr - Gyroscope data [Nx3] (rad/s).
363 %> @param mag - Magnetometer data [Nx3] (uT).
364 %>
365 %> @retval data - Struct with the filtered data.
366 %>
367 %> @note See the VQF documentation for the structure of the data.
368 % ====================================================================== %
369 function data = offlineVQF(obj, acc, gyr, mag)
370
371 % create python dict with params
372 params = py.dict(...
373 tauAcc = obj.tauAcc, ...
374 tauMag = obj.tauMag, ...
375 motionBiasEstEnabled = obj.motionBiasEstEnabled, ...
376 restBiasEstEnabled = obj.restBiasEstEnabled, ...
377 magDistRejectionEnabled = obj.magDistRejectionEnabled, ...
378 biasSigmaInit = obj.biasSigmaInit, ...
379 biasForgettingTime = obj.biasForgettingTime, ...
380 biasClip = obj.biasClip, ...
381 biasSigmaMotion = obj.biasSigmaMotion, ...
382 biasVerticalForgettingFactor = obj.biasVerticalForgettingFactor, ...
383 biasSigmaRest = obj.biasSigmaRest, ...
384 restMinT = obj.restMinT, ...
385 restFilterTau = obj.restFilterTau, ...
386 restThGyr = obj.restThGyr, ...
387 restThAcc = obj.restThAcc, ...
388 magCurrentTau = obj.magCurrentTau, ...
389 magRefTau = obj.magRefTau, ...
390 magNormTh = obj.magNormTh, ...
391 magDipTh = obj.magDipTh, ...
392 magNewTime = obj.magNewTime, ...
393 magNewFirstTime = obj.magNewFirstTime, ...
394 magNewMinGyr = obj.magNewMinGyr, ...
395 magMinUndisturbedTime = obj.magMinUndisturbedTime, ...
396 magMaxRejectionTime = obj.magMaxRejectionTime, ...
397 magRejectionFactor = obj.magRejectionFactor);
398
399 % call the offline VQF
400 data = py.vqf.offlineVQF(gyr, acc, mag, obj.gyrTs, params);
401 end
402
403 end
404end
405
MyVqf is an interface to the VQF python package.
Definition MyVqf.m:29
Property magRefTau
Definition MyVqf.m:96
Property magMinUndisturbedTime
Definition MyVqf.m:108
Property magRejectionFactor
Definition MyVqf.m:112
Property magMaxRejectionTime
Definition MyVqf.m:110
Property np
numpy package
Definition MyVqf.m:47
Property magNewMinGyr
Definition MyVqf.m:106
function MyVqf()
Constructor of the MyVqf class.
Property magTs
Definition MyVqf.m:57
Property biasVerticalForgettingFactor
Definition MyVqf.m:82
Property accTs
Definition MyVqf.m:55
Property restThGyr
Definition MyVqf.m:90
Property gyrTs
Definition MyVqf.m:53
Property tauMag
Definition MyVqf.m:66
Property magNewTime
Definition MyVqf.m:102
Property magNewFirstTime
Definition MyVqf.m:104
Property biasSigmaRest
Definition MyVqf.m:84
function createVQF(in obj)
Create and configure VQF forward filter.
Property motionBiasEstEnabled
Definition MyVqf.m:68
function offlineVQF(in obj, in acc, in gyr, in mag)
Call the offline VQF algorithm.
function filter(in obj, in acc, in gyr, in mag)
Filter the data using the VQF algorithm (only forward).
Property biasClip
Definition MyVqf.m:78
Property restBiasEstEnabled
Definition MyVqf.m:70
Property vqfForward
VQF object with forward filter configuration.
Definition MyVqf.m:43
Property biasForgettingTime
Definition MyVqf.m:76
Property restFilterTau
Definition MyVqf.m:88
function filterOffline(in obj, in acc, in gyr, in mag)
Filter the data using the VQF algorithm (offline, forward and backward).
Property pe
python environment
Definition MyVqf.m:35
Property magDipTh
Definition MyVqf.m:100
Property magCurrentTau
Definition MyVqf.m:94
Property magDistRejectionEnabled
Definition MyVqf.m:72
Property magNormTh
Definition MyVqf.m:98
Property tauAcc
Definition MyVqf.m:64
function getProperties(in obj)
Property biasSigmaInit
Definition MyVqf.m:74
Property restMinT
Definition MyVqf.m:86
function setProperties(in obj, in params)
method to set properties of the VQF filter
Property vqf
VQF python package.
Definition MyVqf.m:39
Property biasSigmaMotion
Definition MyVqf.m:80
Property restThAcc
Definition MyVqf.m:92