AirSim Adapter¶
Overview¶
The AirSimAdapter is a concrete implementation of DroneAdapter that wraps the AirSim Python client library.
It provides a full bridge between the DroneAdapter interface and the AirSim multirotor API.
Prerequisites¶
1. AirSim runtime¶
An AirSim instance must already be running before connect() is called.
Default configuration: - host: localhost - port: 41451
2. Python package¶
The AirSim Python package must be available in the active environment.
It should be installed when running via:
uv runin the services environment- or equivalent virtual environment setup
Coordinate System (AirSim NED)¶
AirSim uses a North-East-Down coordinate system:
- +x = North (forward)
- +y = East (right)
- +z = Down (negative altitude when airborne)
Implications¶
- Move up -> negative z velocity
- Move down -> positive z velocity
- Altitude must negate z position
All conversions are handled inside this adapter so that external consumers always receive consistent telemetry data.
Async Behaviour Notes¶
AirSim movement calls return async-style objects that require .join() to block until completion.
Because this can block the event loop, operations are executed using:
asyncio.get_event_loop().run_in_executor()
This is currently abstracted via _run().
Important note¶
For simplicity, .join() is still used directly inside the executor.
This should be refactored in production for fully non-blocking behaviour.
Configuration Constants¶
Movement¶
- DEFAULT_DISTANCE_M = 1.0
- DEFAULT_SPEED_MS = 2.0
- DEFAULT_DURATION_S = 0.5
Rotation¶
- DEFAULT_ROTATE_DEG = 15.0
- DEFAULT_YAW_RATE_DPS = 45.0
AirSimAdapter Class¶
Purpose¶
Wraps airsim.MultirotorClient and implements the DroneAdapter interface.
Constructor¶
AirSimAdapter(host, port, vehicle_name)¶
Parameters:
- host: IP address of AirSim instance (default: localhost)
- port: RPC port (default: 41451)
- vehicle_name: multirotor name in settings.json
Internal State¶
- _host: connection host
- _port: RPC port
- _vehicle: vehicle identifier
- _client: AirSim MultirotorClient instance
- _connected: connection state flag
Connection Lifecycle¶
connect() -> bool¶
Connects to AirSim, enables API control, and arms the vehicle.
Returns: - True if successful - False if connection fails
Behavior: - Chooses default or custom client initialization - Calls confirmConnection() - Enables API control - Arms vehicle
disconnect() -> None¶
- Disarms vehicle
- Disables API control
- Marks adapter as disconnected
Flight Commands¶
takeoff()¶
Commands drone to ascend to hover altitude.
Note:
- Currently blocks until completion using .join()
land()¶
Commands drone to land and disarm.
hover()¶
Stops movement and holds position.
emergency_stop()¶
Immediately cancels active tasks and triggers hover.
Behavior: - Calls cancelLastTask() - Calls hoverAsync()
If client is None, logs warning and returns safely.
Movement¶
move(direction: CommandType, **kwargs)¶
Executes directional movement or rotation.
Parameters¶
- direction: CommandType
- speed_ms: movement speed (default: 2.0)
- duration_s: movement duration (default: 0.5)
- degrees: rotation amount (for rotation commands)
Supported Commands¶
Movement¶
- MOVE_FORWARD
- MOVE_BACKWARD
- MOVE_LEFT
- MOVE_RIGHT
- MOVE_UP
- MOVE_DOWN
Mapped to velocity vectors in NED frame.
Rotation¶
- ROTATE_CW
- ROTATE_CCW
Handled via _rotate() using yaw rate control.
Post-move behaviour¶
After every movement: - drone is forced into hover state to prevent drift
Telemetry¶
get_telemetry() -> TelemetryData¶
Returns a normalized snapshot of drone state.
Fields¶
- altitude_m: computed from NED z inversion
- speed_ms: magnitude of velocity vector
- battery_pct: fixed at 100 (AirSim limitation)
- heading_deg: derived from quaternion yaw
- is_flying: derived from landed state
- source: "airsim"
- extra: omitted (not used here)
Failure cases¶
Returns:
- TelemetryData(source="airsim-disconnected") if not connected
- TelemetryData(source="airsim-error") on exception
Rotation Helper¶
_rotate(direction, degrees)¶
Rotates drone using yaw rate control.
- clockwise = positive yaw rate
- counter-clockwise = negative yaw rate
Duration is computed from: degrees / DEFAULT_YAW_RATE_DPS
Heading Calculation¶
_get_heading_deg()¶
Converts quaternion orientation into degrees:
- 0–360 range
- clockwise from North
Falls back to 0.0 on failure.
Connection Guard¶
_assert_connected()¶
Raises RuntimeError if:
- client is None
- adapter is not connected
Prevents invalid command execution.
Summary¶
This adapter is responsible for:
- AirSim connection lifecycle management
- NED coordinate conversion
- Movement and rotation abstraction
- Telemetry normalization
- Async-to-blocking bridging via executor