Skip to main content

A Python library for attitude and linear motion estimation using inertial sensor data

Project description

AttiPy

AttiPy is a lightweight Python library for representing and estimating the attitude (orientation) and linear motion of a body using IMU measurements and optional external aiding. It provides a multiplicative extended Kalman filter (MEKF) for position, velocity and attitude (PVA) estimation, and an attitude abstraction with clearly defined reference frames and rotation conventions.

Installation

pip install attipy

Quick start

Convert to/from a variety of attitude representations using the Attitude class:

import attipy as ap
import numpy as np


# From Euler angles to unit quaternion
att = ap.Attitude.from_euler([0.0, 0.0, 0.0])
q = att.as_quaternion()

Estimate roll and pitch from IMU measurements (accelerometer and gyroscope) using the MEKF class:

import attipy as ap
import numpy as np


# Position, velocity, attitude and IMU reference signals
fs = 10.0  # Hz
t, pos, vel, euler, f, w = ap.pva_sim(fs)

# Add IMU measurement noise
acc_noise_density = 0.001  # (m/s^2) / sqrt(Hz)
gyro_noise_density = 0.0001  # (rad/s) / sqrt(Hz)
bg = (0.001, 0.002, 0.003)  # rad/s
rng = np.random.default_rng(42)
f_meas = f + acc_noise_density * np.sqrt(fs) * rng.standard_normal(f.shape)
w_meas = w + bg + gyro_noise_density * np.sqrt(fs) * rng.standard_normal(w.shape)

# Estimate attitude using MEKF
att = ap.Attitude.from_euler(euler[0])
mekf = ap.MEKF(fs, att)
euler_est = []
for f_i, w_i in zip(f_meas, w_meas):
    mekf.update(f_i, w_i)
    euler_est.append(mekf.attitude.as_euler())
euler_est = np.asarray(euler_est)

To limit integration drift, the MEKF corrects its state estimates using long-term stable aiding measurements. When no aiding measurements are available (as in the example above), stationarity is assumed to ensure convergence. By default, zero-velocity aiding with a 10 m/s standard deviation is applied; this constrains roll and pitch only, as these are the only degrees of freedom observable from specific force measurements and the known direction of gravity. Under sustained linear acceleration, velocity and/or position aiding is recommended to maintain accurate attitude estimates.

The following example demonstrates how to estimate position, velocity and attitude (including yaw) from IMU and aiding measurements.

import attipy as ap
import numpy as np


# Position, velocity, attitude and IMU reference signals
fs = 10.0  # Hz
t, pos, vel, euler, f, w = ap.pva_sim(fs)
yaw = euler[:, 2]

# Add IMU measurement noise
acc_noise_density = 0.001  # (m/s^2) / sqrt(Hz)
gyro_noise_density = 0.0001  # (rad/s) / sqrt(Hz)
bg = (0.001, 0.002, 0.003)  # rad/s
rng = np.random.default_rng(42)
f_meas = f + acc_noise_density * np.sqrt(fs) * rng.standard_normal(f.shape)
w_meas = w + bg + gyro_noise_density * np.sqrt(fs) * rng.standard_normal(w.shape)

# Add velocity and heading measurement noise
pos_var = 0.1  # m
vel_var = 0.01  # (m/s)^2
yaw_var = 0.0001  # rad^2
rng = np.random.default_rng(42)
pos_meas = pos + np.sqrt(pos_var) * rng.standard_normal(pos.shape)
vel_meas = vel + np.sqrt(vel_var) * rng.standard_normal(vel.shape)
yaw_meas = yaw + np.sqrt(yaw_var) * rng.standard_normal(yaw.shape)

# Estimate position, velocity and attitude using MEKF
att = ap.Attitude.from_euler(euler[0])
mekf = ap.MEKF(fs, att)
pos_est, vel_est, euler_est = [], [], []
for f_i, w_i, p_i, v_i, y_i in zip(f_meas, w_meas, pos_meas, vel_meas, yaw_meas):
    mekf.update(
        f_i,
        w_i,
        pos=p_i,
        pos_var=pos_var*np.ones(3),
        vel=v_i,
        vel_var=vel_var*np.ones(3),
        yaw=y_i,
        yaw_var=yaw_var
    )
    pos_est.append(mekf.position)
    vel_est.append(mekf.velocity)
    euler_est.append(mekf.attitude.as_euler())
pos_est = np.asarray(pos_est)
vel_est = np.asarray(vel_est)
euler_est = np.asarray(euler_est)

Limitations and assumptions

  • Intended for small-area, low-velocity applications; Earth rotation is neglected, and gravitational acceleration is assumed constant.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

attipy-0.0.9.tar.gz (26.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

attipy-0.0.9-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

File details

Details for the file attipy-0.0.9.tar.gz.

File metadata

  • Download URL: attipy-0.0.9.tar.gz
  • Upload date:
  • Size: 26.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for attipy-0.0.9.tar.gz
Algorithm Hash digest
SHA256 0ad3897dc8d6f9f59029a2fa061a6cfec26cfe811998750fe5f8070edaa599ba
MD5 fe3fa61a3b1647d1208c234b3af3dce2
BLAKE2b-256 97c78edf981a6cf9a2207c16b9b91f70e700f212c907273b6bbbddc799f0b262

See more details on using hashes here.

File details

Details for the file attipy-0.0.9-py3-none-any.whl.

File metadata

  • Download URL: attipy-0.0.9-py3-none-any.whl
  • Upload date:
  • Size: 20.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for attipy-0.0.9-py3-none-any.whl
Algorithm Hash digest
SHA256 a57eab8ee9e58ec29cacaa50637ab17281b3f8210ee80bfe89a1fbf753cc842f
MD5 1a7cd661dbd2a353d7fc405a2bcbb05d
BLAKE2b-256 fcd5b4b47185dd68d4453cde77fa709e1adc456dfc45cccc6d5cf681829e8e02

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page