# `BB.Estimator.Ahrs.Math`
[🔗](https://github.com/beam-bots/bb_estimator_ahrs/blob/main/lib/bb/estimator/ahrs/math.ex#L6)

Stateless mathematical utilities shared across the AHRS filters.

All inputs and outputs are in SI units (rad/s for angular velocity,
m/s² for linear acceleration, radians for angles). Unit conversion is
the responsibility of the sensor driver populating the inbound
`BB.Message.Sensor.Imu` payload.

Ported from [gworkman/ahrs](https://github.com/gworkman/ahrs)'
`Ahrs.Math`.

# `accel_to_tilt`

```elixir
@spec accel_to_tilt(float(), float(), float()) :: {roll :: float(), pitch :: float()}
```

Calculates roll and pitch in radians from a 3-axis acceleration
vector. Yaw is unobservable from acceleration alone.

Returns `{roll, pitch}`. The accel components are in any unit; only
their relative magnitudes matter.

# `euler_to_quaternion`

```elixir
@spec euler_to_quaternion(roll :: float(), pitch :: float(), yaw :: float()) ::
  BB.Estimator.Ahrs.Quaternion.t()
```

Converts Euler angles in radians to a quaternion (Z-Y-X Tait-Bryan).

# `gravity`

```elixir
@spec gravity() :: float()
```

Standard gravity in m/s².

# `gravity_only?`

```elixir
@spec gravity_only?(float(), float(), float(), float()) :: boolean()
```

Returns `true` if the magnitude of an accel vector in m/s² is within
`threshold` of standard gravity, where `threshold` is a fractional
value (e.g. `0.1` means ±10% around 1 g).

Used by Madgwick and Mahony to reject readings dominated by linear
acceleration rather than gravity.

# `normalize_angle`

```elixir
@spec normalize_angle(float()) :: float()
```

Normalises an angle to the range `(-π, π]`.

# `quaternion_to_euler`

```elixir
@spec quaternion_to_euler(
  BB.Estimator.Ahrs.Quaternion.t(),
  keyword()
) :: {roll :: float(), pitch :: float(), yaw :: float()}
```

Converts a quaternion to Euler angles using the Z-Y-X Tait-Bryan
convention. Returns `{roll, pitch, yaw}` in radians, unless `:degrees`
is passed.

# `rotate_vector`

```elixir
@spec rotate_vector({float(), float(), float()}, BB.Estimator.Ahrs.Quaternion.t()) ::
  {float(), float(), float()}
```

Rotates a 3D `{x, y, z}` vector by a quaternion. Equivalent to
`q * v * conjugate(q)`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
