> ## 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.

# Data Types

AirGen exposes a compact set of Python classes for representing positions, orientations, and geospatial locations. Mastering these data types makes it easier to compose movement commands, interpret sensor returns, and debug trajectories across the full robot fleet.

All spatial coordinates follow the **North-East-Down (NED)** convention unless otherwise noted:

* **X** → North / forward
* **Y** → East / right
* **Z** → Down (negative values move upward)

Throughout the examples below, assume `client` is an instantiated AirGen client (for example, `client = airgen.RobotClient()` or `airgen.MultirotorClient()`).

## Vector3r

[`Vector3r`](/simulation/airgen/reference/datatypes#vector3r) tracks a three-element float vector and is returned by many APIs, including `simGetRobotPose`, `simGetGroundTruthKinematics`, and most sensor interfaces.

* Access components via `.x_val`, `.y_val`, `.z_val`.
* Helpful constants: `Vector3r.ZERO`, `Vector3r.ONE`, `Vector3r.FORWARD`, `Vector3r.UP`, *etc.*
* Supports arithmetic (`+`, `-`, `*`, `/`), vector math (`dot`, `cross`, `distance_to`), and normalization.

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

offset = Vector3r(2.0, 0.0, -1.5)  # 2 m forward, 1.5 m above current altitude

if not offset.containsNan():
    direction = offset.normalized()
    print("Heading", direction)
```

<Tip>
  `Vector3r.to_numpy_array()` returns a NumPy-friendly representation for downstream pipelines.
</Tip>

## Quaternionr

[`Quaternionr`](/simulation/airgen/reference/datatypes#quaternionr) stores orientation in **wxyz** order (scalar part first). Compared to Euler angles, quaternions avoid gimbal lock and interpolate smoothly.

* Construct from Euler angles via `Quaternionr.from_euler_angles_degrees(roll, pitch, yaw)` or from axis/angle using `Quaternionr.from_axis_angle(axis, angle)`.
* Convert back to Euler angles with `.to_euler_angles()` (radians) or `.to_euler_angles_degrees()`.
* Implements quaternion algebra (`*`, scalar multiplication, `inverse()`, `slerp()`, `rotate()`).

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

yaw_45 = Quaternionr.from_euler_angles_degrees(roll=0.0, pitch=0.0, yaw=45.0)
rotated = Vector3r.FORWARD.rotate(yaw_45)

print(rotated.x_val, rotated.y_val, rotated.z_val)
```

## Pose

[`Pose`](/simulation/airgen/reference/datatypes#pose) bundles a `Vector3r` position with a `Quaternionr` orientation. Poses are used throughout the API (`simSetRobotPose`, `simSetObjectPose`, trajectory planners, sensor extrinsics, *etc.*).

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

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

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

Use `Pose.toLocal(client, robot_name="")` and `Pose.toWorld(client, robot_name="")` to transform between a robot's local NED frame (defined at spawn) and the global simulation frame.

## GeoPoint

[`GeoPoint`](/simulation/airgen/reference/datatypes#geopoint) captures latitude, longitude, and altitude in the WGS84 reference ellipsoid. It is the input to GPS-style APIs such as `moveToGPSAsync`, `moveOnGPSPath`, and `simSetGeoReference`.

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

home = client.getHomeGeoPoint(robot_name="drone0")
loiter_point = GeoPoint(
    latitude=home.latitude + 0.0001,
    longitude=home.longitude,
    altitude=home.altitude + 20.0,
)
```

## GeoPose

[`GeoPose`](/simulation/airgen/reference/datatypes#geopose) pairs a `GeoPoint` with a `Quaternionr` orientation, enabling geodetic placement of robots and movable actors.

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

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

client.simSetRobotGeoPose(
    geopose=approach_pose,
    ignore_collision=False,
    on_ground=True,
    robot_name="drone0",
).join()
```

## Geo ↔︎ World Conversions

When mixing GPS waypoints with local motion planning, convert between `GeoPoint` and `Vector3r` using helpers in `airgen.utils.geodetic`.

```python theme={null}
from airgen.types import GeoPoint
from airgen.utils import geodetic

origin = client.getHomeGeoPoint(robot_name="drone0")
target = GeoPoint(
    latitude=origin.latitude + 0.0001,
    longitude=origin.longitude,
    altitude=origin.altitude,
)

ned_offset = geodetic.lla2ned(target, origin)  # Geo → world (meters)
round_trip = geodetic.ned2lla(ned_offset, origin)
```

The conversion utilities assume the same WGS84 ellipsoid as the simulator. Combine them with [`Pose`](#pose) when you need to synthesize world-space placements that align with real-world latitude/longitude targets.

***

Continue with the [Movement](/simulation/airgen/features/movement) page to see how these types are used when commanding drones, cars, and legged robots.
