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

# GPS Navigation

GPS tooling in AirGen is targeted at **multirotor platforms** operating in georeferenced scenes (for example, Cesium streaming). The APIs below let you reposition drones using latitude/longitude/altitude targets instead of world-space meters.

```python theme={null}
import airgen

client = airgen.MultirotorClient()
client.confirmConnection()
```

Before issuing GPS commands, review the [Data Types](/simulation/airgen/features/data-types#geopoint) page—particularly `GeoPoint` and `GeoPose`—and verify that `client.getHomeGeoPoint()` reflects the correct geo-reference.

## simSetRobotGeoPose

Instantly relocate a drone to a geodetic pose while optionally enforcing collisions and ground alignment.

```python theme={null}
from airgen.types import GeoPose, GeoPoint, Quaternionr, Vector3r

landing_pose = GeoPose(
    geopoint_val=GeoPoint(37.7749, -122.4194, 30.0),
    orientation_val=Quaternionr.from_euler_angles_degrees(0.0, 0.0, 90.0),
)

future = client.simSetRobotGeoPose(
    geopose=landing_pose,
    ignore_collision=False,
    sweep=True,
    on_ground=True,
    bounds_trim=Vector3r(0.05, 0.05, 0.05),
    robot_name="drone0",
)

if future.get():
    print("Drone repositioned successfully")
```

Parameter highlights:

* **`ignore_collision`** — Allow placement even if the target pose intersects geometry.
* **`sweep`** — When `True`, performs a swept collision check from the current pose to the target pose.
* **`on_ground`** — Snap the target altitude to the first ground hit along the vertical ray. Tune the search window with `ground_trace_range_up` / `ground_trace_range_down`.
* **`bounds_trim`** — Shrink collision bounds when `ignore_collision=False` (default `Vector3r(0.05, 0.05, 0.05)`).
* **`timeout_sec`** — Maximum time allowed to find a ground trace when `on_ground=True`.

## moveToGPSAsync

Plan a straight-line flight toward a geodetic goal at a specified speed.

```python theme={null}
from airgen.types import GeoPoint, YawMode

goal = GeoPoint(latitude=37.7750, longitude=-122.4185, altitude=40.0)

client.moveToGPSAsync(
    lla=goal,
    velocity=5.0,
    drivetrain=airgen.DrivetrainType.MaxDegreeOfFreedom,
    yaw_mode=YawMode(is_rate=False, yaw_or_rate=45.0),
    robot_name="drone0",
)
```

* **`velocity`** is expressed in meters per second.
* When `yaw_mode.is_rate` is `False`, `yaw_or_rate` specifies the absolute yaw angle to maintain.
* Drivetrain, lookahead, and timeout parameters mirror `moveToPositionAsync`.

## moveOnGPSPath

Follow multiple GPS waypoints with optional orientations between segments.

```python theme={null}
from airgen.types import GeoPoint, Quaternionr

geopath = [
    GeoPoint(37.7749, -122.4194, 25.0),
    GeoPoint(37.7752, -122.4185, 25.0),
    GeoPoint(37.7754, -122.4176, 25.0),
]

orientations = [
    Quaternionr.IDENTITY,
    Quaternionr.from_euler_angles_degrees(0.0, 0.0, 90.0),
    Quaternionr.IDENTITY,
]

client.moveOnGPSPath(
    geopoints=geopath,
    orientations=orientations,
    velocity=6.0,
    lookahead=-1,
    adaptive_lookahead=1,
    robot_name="drone0",
)
```

Provide an empty `orientations` list to preserve the current heading along the path.

## Choosing Between simSetRobotPose and simSetRobotGeoPose

* **`simSetRobotPose`** accepts a [`Pose`](/simulation/airgen/features/data-types#pose) in world meters. Use it for relative moves, scenario resets, or when working entirely in the simulation frame.
* **`simSetRobotGeoPose`** accepts a [`GeoPose`](/simulation/airgen/features/data-types#geopose) in latitude/longitude/altitude. Use it when aligning drones with GIS datasets or real-world coordinates.

In GPS-enabled scenes, combine both approaches: use `simSetRobotGeoPose` for long-distance placement and `simSetRobotPose` for fine local adjustments.

## Ground Snapping Strategies

When flying close to the surface, leverage the ground-snapping utilities in both pose setters:

* Pass `on_ground=True` to `simSetRobotPose` or `simSetRobotGeoPose` to project the target onto the first ground intersection within the specified trace ranges.
* Adjust `ground_trace_range_up` / `ground_trace_range_down` (defaults ±13 km) for tall structures or underground placements.

```python theme={null}
from airgen.types import Pose, Quaternionr, Vector3r

hover_pose = Pose(
    position_val=Vector3r(10.0, 0.0, -1.0),
    orientation_val=Quaternionr.IDENTITY,
)

client.simSetRobotPose(
    pose=hover_pose,
    ignore_collision=False,
    on_ground=True,
    ground_trace_range_down=50.0,
    robot_name="drone0",
).join()
```

***

For local-frame movement commands, return to the [Movement](/simulation/airgen/features/movement) page. To script scene layout, explore [Pose Control](/simulation/airgen/features/pose-control) and [Runtime Object Spawning](/simulation/airgen/features/runtime-object-spawning).
