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

Madgwick AHRS filter, 6-DOF IMU variant, implemented as a
`BB.Estimator`.

Fuses gyroscope and accelerometer measurements into a drift-free
orientation using a gradient-descent optimisation step. Consumes
`BB.Message.Sensor.Imu` inputs and republishes them with `:orientation`
replaced by the fused estimate; `:angular_velocity` and
`:linear_acceleration` are passed through unchanged.

## Usage

    sensor :imu, BB.Sensor.SomeImu, ... do
      estimator :orientation, {BB.Estimator.Ahrs.Madgwick, beta: 0.1}
    end

## Options

- `:beta` — gradient-descent step size. Higher = tracks faster but
  noisier. Default `0.1`.
- `:accel_threshold` — accepted deviation of `|accel| / g` from `1.0`
  before the accelerometer correction is suppressed (gyro integration
  only). Default `0.1` (i.e. ±10% of 1 g).

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

# `t`

```elixir
@type t() :: %BB.Estimator.Ahrs.Madgwick{
  accel_threshold: float(),
  beta: float(),
  last_monotonic_time: integer() | nil,
  q: BB.Estimator.Ahrs.Quaternion.t()
}
```

# `orientation`

```elixir
@spec orientation(t()) :: BB.Math.Quaternion.t()
```

Convenience: returns the current orientation as a `BB.Math.Quaternion`.
Useful for direct callers.

# `step`

```elixir
@spec step(t(), {float(), float(), float()}, {float(), float(), float()}, float()) ::
  t()
```

Runs one Madgwick step against `state`. `dt` is the time since the
previous step in seconds; `gyro` is rad/s, `accel` is m/s².

Use this directly for testing or for callers who don't want the
`BB.Estimator` envelope.

---

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