Skip to content

Commit 47dbea9

Browse files
test benchmark
1 parent 1ab319c commit 47dbea9

2 files changed

Lines changed: 79 additions & 3 deletions

File tree

src/smsfusion/_smoothing.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ class FixedIntervalSmoother:
4242
_x = np.array([]) # smoothed state estimates
4343
_P = np.array([]) # smoothed erro covariance estimate
4444

45-
4645
def __init__(self, ains: AidedINS | AHRS | VRU, cov_smoothing: bool = True) -> None:
4746
warn(
4847
"FixedIntervalSmoother is experimental and may change or be removed in the future.",
@@ -199,7 +198,7 @@ def bias_gyro(self, degrees: bool = False) -> NDArray:
199198
if degrees:
200199
bg = (180.0 / np.pi) * bg
201200
return bg
202-
201+
203202
def euler(self, degrees: bool = False) -> NDArray:
204203
"""
205204
Smoothed Euler angles estimates.

tests/test_smoothing.py

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import numpy as np
44
import smsfusion as sf
55
from smsfusion import FixedIntervalSmoother
6+
from smsfusion.benchmark import (
7+
benchmark_full_pva_beat_202311A,
8+
benchmark_full_pva_chirp_202311A,
9+
)
610

711

812
class Test_FixedIntervalSmoother:
@@ -12,7 +16,7 @@ def ains(self):
1216
x0[6:10] = np.array([1.0, 0.0, 0.0, 0.0])
1317
ains = sf.AidedINS(10.24, x0)
1418
return ains
15-
19+
1620
def test__init__(self, ains):
1721
smoother = FixedIntervalSmoother(ains)
1822
assert smoother._ains is ains
@@ -24,3 +28,76 @@ def test__init__(self, ains):
2428
assert smoother.quaternion().size == 0
2529
assert smoother.bias_acc().size == 0
2630
assert smoother.bias_gyro().size == 0
31+
32+
@pytest.mark.parametrize(
33+
"benchmark_gen",
34+
[benchmark_full_pva_beat_202311A, benchmark_full_pva_chirp_202311A],
35+
)
36+
def test_benchmark(self, benchmark_gen):
37+
fs_imu = 10.0
38+
fs_aiding = 1.0
39+
fs_ratio = np.ceil(fs_imu / fs_aiding)
40+
warmup = int(fs_imu * 600.0) # truncate 600 seconds from the beginning
41+
compass_noise_std = 0.5
42+
gps_noise_std = 0.1
43+
vel_noise_std = 0.1
44+
45+
# Reference signals (without noise)
46+
t, pos_ref, vel_ref, euler_ref, acc_ref, gyro_ref = benchmark_gen(fs_imu)
47+
euler_ref = np.degrees(euler_ref)
48+
gyro_ref = np.degrees(gyro_ref)
49+
50+
rng = np.random.default_rng(seed=1)
51+
52+
# IMU measurements (with noise)
53+
err_acc = sf.constants.ERR_ACC_MOTION2
54+
err_gyro = sf.constants.ERR_GYRO_MOTION2
55+
noise_model = sf.noise.IMUNoise(err_acc, err_gyro, seed=0)
56+
imu_noise = noise_model(fs_imu, len(t))
57+
acc_meas = acc_ref + imu_noise[:, :3]
58+
gyro_meas = gyro_ref + imu_noise[:, 3:]
59+
60+
# Compass / heading (aiding) measurements
61+
head_noise = compass_noise_std * rng.standard_normal(len(t))
62+
head_meas = euler_ref[:, 2] + head_noise
63+
64+
# GPS / position (aiding) measurements
65+
pos_noise = gps_noise_std * rng.standard_normal((len(t), 3))
66+
pos_meas = pos_ref + pos_noise
67+
68+
# Velocity (aiding) measurements
69+
vel_noise = vel_noise_std * rng.standard_normal((len(t), 3))
70+
vel_meas = vel_ref + vel_noise
71+
72+
# MEKF
73+
p0 = pos_ref[0] # position [m]
74+
v0 = vel_ref[0] # velocity [m/s]
75+
q0 = sf.quaternion_from_euler(euler_ref[0]) # attitude as unit quaternion
76+
ba0 = np.zeros(3) # accelerometer bias [m/s^2]
77+
bg0 = np.zeros(3) # gyroscope bias [rad/s]
78+
x0 = np.concatenate((p0, v0, q0, ba0, bg0))
79+
P0 = sf.constants.P0
80+
ains = sf.AidedINS(fs_imu, x0, P0, err_acc, err_gyro)
81+
82+
smoother = FixedIntervalSmoother(ains, cov_smoothing=True)
83+
84+
for i, (acc_i, gyro_i, pos_i, vel_i, head_i) in enumerate(
85+
zip(acc_meas, gyro_meas, pos_meas, vel_meas, head_meas)
86+
):
87+
if not (i % fs_ratio): # with aiding
88+
smoother.update(
89+
acc_i,
90+
gyro_i,
91+
degrees=True,
92+
pos=pos_i,
93+
pos_var=gps_noise_std**2 * np.ones(3),
94+
vel=vel_i,
95+
vel_var=vel_noise_std**2 * np.ones(3),
96+
head=head_i,
97+
head_var=compass_noise_std**2,
98+
head_degrees=True,
99+
g_ref=True,
100+
g_var=0.1**2 * np.ones(3),
101+
)
102+
else: # without aiding
103+
smoother.update(acc_i, gyro_i, degrees=True)

0 commit comments

Comments
 (0)