31 properties (Access=
public)
38 %> VQF object with forward filter configuration
44 %> @name Sampling times
46 %> sampling times for the sensors in [s]
52 %> @name VQF parameters
54 %>
default values according to the VQF documentation
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]
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;
84 methods (Access=
public)
86 % ====================================================================== %
87 %> @brief Constructor of the
MyVqf class.
91 %> @retval obj -Instance of the
MyVqf class.
93 %> @note The root python environment is used and the packages 'vqf' and
94 %> 'numpy' must be installed in the python environment.
95 % ====================================================================== %
97 % create python environment
98 obj.pe = pyenv("ExecutionMode","OutOfProcess");
101 % ====================================================================== %
102 %> @brief Destructor of the
MyVqf class.
104 %> @param obj -Instance of the
MyVqf class.
107 % ====================================================================== %
109 % delete python environment
113 % ====================================================================== %
114 %> @brief Filter the data
using the VQF algorithm (only forward).
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).
121 %> @retval data - Struct with the filtered data.
122 % ====================================================================== %
123 function data = filter(obj, acc, gyr, mag)
125 % convert gyr from deg/s to rad/s
128 % create numpy arrays
129 acc = py.numpy.ascontiguousarray(acc);
130 gyr = py.numpy.ascontiguousarray(gyr);
131 mag = py.numpy.ascontiguousarray(mag);
137 data = obj.vqfForward.updateBatch(gyr, acc, mag);
139 % output as
struct with matlab arrays
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);
150 % ====================================================================== %
151 %> @brief Filter the data
using the VQF algorithm (offline, forward and
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).
159 %> @retval data - Struct with the filtered data.
160 % ====================================================================== %
161 function data = filterOffline(obj, acc, gyr, mag)
163 % convert gyr from deg/s to rad/s
166 % create numpy arrays
167 acc = py.numpy.ascontiguousarray(acc);
168 gyr = py.numpy.ascontiguousarray(gyr);
169 mag = py.numpy.ascontiguousarray(mag);
174 % output as
struct with matlab arrays
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);
185 % ====================================================================== %
186 %> @brief method to set properties of the VQF filter
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)
216 %> @retval obj - Instance of the
MyVqf class.
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)
223 % check and init with default
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;
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;
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;
312 methods (Access=
protected)
314 % ====================================================================== %
315 %> @brief Create and configure VQF forward filter.
317 %> @param obj - Instance of the
MyVqf class.
319 %> @retval obj - Instance of the
MyVqf class.
320 % ====================================================================== %
321 function obj = createVQF(obj)
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);
357 % ====================================================================== %
358 %> @brief Call the offline VQF algorithm.
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).
365 %> @retval data - Struct with the filtered data.
367 %> @note See the VQF documentation for the structure of the data.
368 % ====================================================================== %
369 function data = offlineVQF(obj, acc, gyr, mag)
371 % create python dict with params
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);
399 % call the offline VQF
400 data = py.
vqf.offlineVQF(gyr, acc, mag, obj.gyrTs, params);