> ## Documentation Index
> Fetch the complete documentation index at: https://docs.altnautica.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GPS driver

> Implement a GpsDriver to add a new GNSS receiver.

A `GpsDriver` decodes a position-fix stream from a u-blox, NMEA,
RTK, or vendor-custom receiver and exposes it as a series of
`GpsFix` samples. Drivers that support RTK can also accept RTCM
correction payloads.

## The interface

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from ados.sdk.drivers.gps import (
    GpsDriver,
    GpsCandidate,
    GpsCapabilities,
    GpsSession,
    GpsFix,
)

class MyGpsDriver(GpsDriver):
    async def discover(self) -> list[GpsCandidate]:
        ...

    async def open(self, candidate, config) -> GpsSession:
        ...

    async def close(self, session) -> None:
        ...

    def capabilities(self, session) -> GpsCapabilities:
        ...

    async def fix_iterator(self, session):
        # async generator yielding GpsFix
        ...

    async def inject_rtcm(self, session, payload: bytes) -> None:
        ...
```

`inject_rtcm` is a no-op for non-RTK drivers.

## Rust

The same driver exists in the Rust SDK as the `ados-sdk::drivers::GpsDriver`
trait. It mirrors the Python base class method for method, with an associated
`Session` type in place of the opaque `GpsSession` and a `SampleStream<GpsFix>`
(a boxed async stream) in place of the Python async generator.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
use std::collections::BTreeMap;
use async_trait::async_trait;
use rmpv::Value;
use ados_sdk::drivers::{
    Bus, DriverResult, GpsCandidate, GpsCapabilities, GpsDriver, GpsFix, SampleStream,
};

struct MyGpsDriver;

#[async_trait]
impl GpsDriver for MyGpsDriver {
    type Session = MySession;

    async fn discover(&self) -> DriverResult<Vec<GpsCandidate>> { todo!() }

    async fn open(
        &self,
        candidate: &GpsCandidate,
        config: &BTreeMap<String, Value>,
    ) -> DriverResult<Self::Session> { todo!() }

    async fn close(&self, session: Self::Session) -> DriverResult<()> { todo!() }

    fn capabilities(&self, session: &Self::Session) -> GpsCapabilities { todo!() }

    async fn fix_iterator(
        &self,
        session: &Self::Session,
    ) -> DriverResult<SampleStream<GpsFix>> { todo!() }

    async fn inject_rtcm(
        &self,
        session: &Self::Session,
        payload: &[u8],
    ) -> DriverResult<()> { todo!() }
}
```

A Rust GPS driver returns `Err(DriverError::NotSupported(...))` from
`inject_rtcm` when the receiver has no RTK support, where the Python driver
raises `NotImplementedError`. The `GpsFix` and `GpsCapabilities` fields are
identical to the Python ones below.

## Capabilities

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
GpsCapabilities(
    protocol="ubx",
    constellations=["GPS", "GLONASS", "Galileo", "BeiDou"],
    max_update_hz=10.0,
    supports_rtk=True,
    supports_dual_band=False,
    supports_heading=False,
)
```

## Fix samples

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
GpsFix(
    timestamp_ns=ns,
    latitude_deg=12.97,
    longitude_deg=77.59,
    altitude_msl_m=920.0,
    fix_type=3,
    satellites_used=14,
    hdop=0.9,
    vdop=1.4,
    speed_mps=0.0,
    heading_deg=None,
)
```

`fix_type` follows the common convention: 0 no fix, 2 2D, 3 3D, 4
DGPS, 5 RTK float, 6 RTK fixed.

## Manifest permissions

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
agent:
  permissions:
    - id: sensor.payload.register   # GPS drivers register under the payload cap (no dedicated GPS cap in the current catalog)
    - id: hardware.uart             # serial or USB-CDC receiver
    - id: hardware.usb              # for a raw USB device behind a vendor SDK
```

`inject_rtcm` writes corrections back over the same device link the
driver already opened, so it needs no extra capability.

## See also

* [Driver layer](/developers/driver-layer) for the contract.
