0
$\begingroup$

I am building a variometer as a hobbie, this could be a duplicate from an existing question: How to use Kalman filter for altitude prediction based on barometer data? .

Details follow:

I have a https://es.wikipedia.org/wiki/NodeMCU running http://www.micropython.org/ , it works nice and I have attached a BMP180 barometric pressure sensor, so I can retrieve: temperature, pressure and altitude, however, while the sensor is fixed in my desk and if I read from three seconds I can get values that range from (982.409 to 983.956 ) in terms of altitude, see the log: https://pastebin.com/C3RbuyDn . So there is an error margin of more than 1 meter .

I would like to use it as a variometer for paragliding, and I only have the pressure sensor, I read it is better to combile with a magnetic sensor, however I want to keep it simple, so it is possible to have an accurate variometer with just the pressure sensor and some algorithms behind and off course with no lag ( no more than 1 second ) ?

Is there any existent algorithm for getting the variation (m/s) with just one variable (altitute) and also considering this chip report the altitude ?

Please look at the data referenced in pastebin .

Thanks for your time.

$\endgroup$
2
$\begingroup$

If you add an accelerometer to the project, a Kalman filter can give a good estimation of vertical speed.

With only a barometric sensor, I don't think it's possible to reduce the lag below 1 second.

enter image description here

import numpy as np
import matplotlib.pyplot as plt
import random

from filterpy.kalman import KalmanFilter
from filterpy.common import Q_discrete_white_noise

random.seed(65537)

# Standard deviation of simulated sensor data
std_a = 0.075
std_h = 0.42

# Earth gravity
g_n = 9.80665

# Sensor sample period, s
dt = 0.05

kf1 = KalmanFilter(dim_x=2, dim_z=1)
kf1.H = np.array([[1, 0]])
kf1.F = np.array([[1, dt], [0, 1]])

kf2 = KalmanFilter(dim_x=3, dim_z=2)
kf2.H = np.array([[1, 0, 0], [0, 0, 1]])
kf2.F = np.array([[1, dt, dt * dt * 0.5], [0, 1, dt], [0, 0, 1]])

# initial process covariance
kf1.P = np.array([[1, 0], [0, 0.01]])
kf2.P = np.array([[std_h * std_h, 0, 0], [0, 0.0001, 0], [0, 0, std_a * std_a]])

# Process noise matrix
std = 0.0039
var = std * std
kf1.Q = Q_discrete_white_noise(dim=2, dt=dt, var=0.0625)
kf2.Q = Q_discrete_white_noise(dim=3, dt=dt, var=var)

# Measurement covariance
kf1.R *= np.array([[std_h * std_h]])
kf2.R *= np.array([[std_h * std_h, 0], [0, std_a * std_a]])

n = 300
r_n = 1.0 / n

t = np.zeros(n)
h_sim = np.zeros(n)
v_sim = np.zeros(n)
a_sim = np.zeros(n)
measured_h = np.zeros(n)
measured_a = np.zeros(n)
v_est_kf1 = np.zeros(n)
v_est_kf2 = np.zeros(n)

v0 = 0
v = v0
h = 0

for i in range(n):
    t[i] = (i * dt)
    a = 1.0 / 32 * g_n * np.sin(4 * np.pi * i * r_n)
    a_sim[i] = (a)
    v += a * dt
    v_sim[i] = v
    h += v * dt + (a * dt * dt) / 2
    h_sim[i] = h
    measured_a[i] = a + random.gauss(0, std_a)
    measured_h[i] = h + random.gauss(0, std_h)

# Compute the speed estimations

for i in range(n):
    kf1.predict()
    kf1.update(np.array([measured_h[i]]))
    v_est_kf1[i] = kf1.x[1]

    kf2.predict()
    kf2.update(np.array([[measured_h[i]], [measured_a[i]]]))
    v_est_kf2[i] = kf2.x[1]

# Plot the results

plt.figure(1, figsize=(8, 12), dpi=80)

plt.subplot(311)
plt.axis([0, n * dt, -0.75, 0.75])
plt.plot(t, measured_a, 'y+')
plt.plot(t, a_sim, 'r')
plt.title('Vertical acceleration - gravity, m/s^2')
plt.legend(('Measured', 'True (simulation)'), loc='best')

plt.subplot(312)
plt.axis([0, n * dt, -1, 7])
plt.plot(t, measured_h, 'c+')
plt.plot(t, h_sim, 'b')
plt.title('Altitude, m')
plt.legend(('Measured', 'True (simulation)'), loc='best')

plt.subplot(313)
plt.axis([0, n * dt, -0.5, 1.0])
plt.plot(t, v_sim, 'b')
plt.plot(t, v_est_kf1, 'r')
plt.plot(t, v_est_kf2, 'c')
plt.title('Vertical speed, m/s')
plt.legend(('True (simulation)', 'Kalman filter (1 sensor)', 'Kalman filter (2 sensors)'), loc='best')

plt.savefig('kalman_vsi.svg')
plt.show()

After some experiments with simulated sensor data, I wrote an Android app that uses smartphone sensors. Source code on GitHub

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.