Skip to main content

A Python library for attitude estimation using inertial measurement units (IMUs)

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 is 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 and correct accumulated position and velocity drift. Heading (yaw) aiding should also be applied to correct yaw drift. The following example demonstrates how to incorporate all aiding sources.

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.
  • Accelerometer bias is not estimated; a calibrated accelerometer is assumed.

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.8.tar.gz (26.2 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.8-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: attipy-0.0.8.tar.gz
  • Upload date:
  • Size: 26.2 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.8.tar.gz
Algorithm Hash digest
SHA256 3be9a4981ba9b87a7a73c7d4e73a2f16392c7561794270f7eb2dda5f536c9c1b
MD5 075f5e8cc6d1e05f9036e6c91209155e
BLAKE2b-256 e31750f7fb898681b8f4656eb287151e40ce9f94ecc5b669683750407d3e0094

See more details on using hashes here.

File details

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

File metadata

  • Download URL: attipy-0.0.8-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.8-py3-none-any.whl
Algorithm Hash digest
SHA256 577b0032c8c51d61205a21f2264fcae9ee998b4fd4f8fda24d43599c11f07760
MD5 c14776aa39d8c2a9281d1abd8cfc316e
BLAKE2b-256 5217b3f7ab894d6d9330cfad76e286cdc3e2bcb427a7214693c59f73477a7747

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