Source code for qmt.blocks.utils

# SPDX-FileCopyrightText: 2021 Daniel Laidig <laidig@control.tu-berlin.de>
#
# SPDX-License-Identifier: MIT
import numpy as np

from qmt import Block


[docs] class LowpassFilterBlock(Block): """ Second-order Butterworth low-pass filter block. This block uses the filter implementation of the VQF orientation estimation algorithm. The cutoff frequency can either directly be specified in Hz, or a time constant can be given. This time constant corresponds to the cutoff frequency as follows: :math:`f_\\mathrm{c} = \\frac{\\sqrt{2}}{2\\pi\\tau}`. For the first :math:`\\tau` seconds, the filter output is the mean of all previous samples, to ensure fast initial convergence. """ def __init__(self, Ts, fc=None, tau=None): """ :param Ts: sampling time in seconds :param fc: cutoff frequency in Hz :param tau: time constant in seconds (either ``fc`` or ``tau`` has to be None) """ super().__init__() if tau is None: assert fc is not None tau = np.sqrt(2)/(2*np.pi*fc) else: assert fc is None # either tau or fc has to be set self.Ts = Ts self.tau = tau from vqf import VQF self.b, self.a = VQF.filterCoeffs(tau, Ts) self.N = None self.state = None
[docs] def step(self, signal): from vqf import VQF signal = np.atleast_1d(np.asarray(signal, float)) if self.N is None: assert signal.ndim == 1 self.N = signal.shape[0] self.state = np.full((max(2, self.N) * 2), np.nan) if self.N == 1: extended = np.concatenate([signal, np.zeros(1)]) # filterVec needs at least 2 elements return VQF.filterVec(extended, self.tau, self.Ts, self.b, self.a, self.state)[0] return VQF.filterVec(signal, self.tau, self.Ts, self.b, self.a, self.state)