<jupyter_start><jupyter_text>Low Pass Filterpossible Options: First order low pass filter, n-th order Butterworth, First order "alpha" IIR Filter (leaky integrator)<jupyter_code>f_s = 1000 # 1kHz sampling frequency
T = 1/f_s
f_c = 50
def bode_plot(w, mag, phase):
    """Generate a bode plot for transfer function"""
    
    # Magnitude plot
    plt.semilogx(w, mag)
    plt.ylabel("Magnitude ($dB$)")
    plt.xlim([min(w),max(w)])
    plt.ylim([min(mag),max(mag)])

    # Phase plot
    plt.figure()
    plt.semilogx(w, phase)  # Bode phase plot
    plt.ylabel("Phase ($^\circ$)")
    plt.xlabel("$\omega$ (rad/s)")
    plt.xlim([min(w),max(w)])<jupyter_output><empty_output><jupyter_text>First Order Low Pass$ H(s) = \frac{\omega_c}{s+\omega_c}$<jupyter_code># Low-pass filter
ω_0 = 2*np.pi*f_c;  # pole frequency (rad/s)
num = ω_0         # transfer function numerator coefficients
den = [1, ω_0]    # transfer function denominator coefficients
lowpass = signal.TransferFunction(num,den) # Transfer function

w, mag, phase = lowpass.bode()

bode_plot(w, mag, phase)<jupyter_output><empty_output><jupyter_text>not digitalized yet, needs still to be done..  First order IIR Filter (leaky integrator)$ H(z) = \frac{1 - \alpha}{1-\alpha z^{-1}}, \quad \text{with}\; \alpha = \frac{t_\mathrm{c}}{T + t_\mathrm{c}}$<jupyter_code>t_c = 1/f_c
α = t_c / (T + t_c)
Θ = 2* np.pi * np.geomspace( 1e-4, f_s/2000, 500 )
mag = 10 * np.log10((1 - α) / np.sqrt( (1 + α**2) - 2 * α * np.cos(Θ)))
phase = np.rad2deg(np.arctan2( α * np.sin(Θ), 1 - α * np.cos(Θ)))

bode_plot(f_s*Θ, mag, phase)<jupyter_output><empty_output><jupyter_text>ugly artifacts in high frequency domain, though ready to be implemented and used in px4<jupyter_code>def get_first_order_iir_low_pass(T, t_c):
    y_n = 0.0

    α = T / (T + t_c)
    
    print(f"alpha is {α}")
    
    def filter(x_n):
        nonlocal y_n, α
        
        y_n = (1-α) * y_n + α * x_n
        
        return y_n
    return filter<jupyter_output><empty_output><jupyter_text>Generate test data<jupyter_code>x = np.linspace(0, 500*T, 1000)
f1 = 5
f2 = 300

# base sine
y1 = np.sin(2*np.pi*f1*x)
# disturbance sine
y2 = 0.2 * np.sin(2*np.pi*f2*x)
#combination
y3 = y1 + y2

plt.figure(figsize=(15,10))
plt.plot(x, y3)
lp = get_first_order_iir_low_pass(T, 1/50)

y4 = np.array([lp(ay) for ay in y3])

plt.figure(figsize=(15,10))
plt.plot(x, y1)
plt.plot(x, y3, '--')
plt.plot(x, y4, '+-')
data = np.vstack((y3, y4)).T

with open("../../tests/lib/control/src/test_low_pass_data.inc", "w") as afile:
    afile.write(f"const float test_data_lp[{data.shape[0]}][{data.shape[1]}] = {{\n")
    for row in data:
        afile.write(("\t{{" + len(row)*"{:2.16f}f, " +"}},\n").format(*row))

    afile.write("};\n")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.18018018018018017, 'fraction_numerical': 0.03279279279279279, 'mean_word_length': 3.7615780445969125, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '287998', 'license': 'Apache-2.0', 'n_tokens_mistral': 1241, 'n_tokens_neox': 1174, 'n_words': 249, 'path': 'prototyping/05_Controller/nb01_low_pass_filter.ipynb', 'repo_name': 'abishekvupputur/zephly', 'size': '2775'}