Simulation: Testing Drone Crashes in AirSim Before Real Flight

Prevent costly hardware failures by simulating drone crash scenarios in AirSim. Learn to test edge cases safely before your first real flight.

Problem: Real Drone Crashes Are Expensive

You've written flight control code, but you're not sure how it handles wind gusts, sensor failures, or bad waypoints. A single crash can destroy a $500+ drone.

You'll learn:

  • How to set up AirSim crash scenarios with Python
  • How to simulate sensor failures and adverse conditions before real flight
  • How to read crash telemetry to fix your control logic

Time: 25 min | Level: Intermediate


Why This Happens

Most flight code looks fine in normal conditions. Problems surface in edge cases — low battery during a turn, GPS dropout mid-route, sudden wind at low altitude. AirSim lets you inject these failures programmatically and observe exactly how your drone behaves.

Common symptoms in real flights:

  • Drone drifts on hover (untuned PID or compass interference)
  • Crash on return-to-home (GPS accuracy drops near obstacles)
  • Flip on takeoff (motor assignment mismatch or center-of-gravity issue)

Setup

Step 1: Install AirSim and the Python Client

# Install the AirSim Python package
pip install airsim

# Confirm it's working
python -c "import airsim; print(airsim.__version__)"

Expected: A version number like 1.8.1 with no errors.

Download the prebuilt AirSim environment from the AirSim releases page. The "Blocks" environment is the lightest and best for crash testing.

Step 2: Configure Your Drone in settings.json

AirSim reads from ~/Documents/AirSim/settings.json. Use a quadrotor with realistic physics:

{
  "SettingsVersion": 1.2,
  "SimMode": "Multirotor",
  "Vehicles": {
    "Drone1": {
      "VehicleType": "SimpleFlight",
      "X": 0, "Y": 0, "Z": 0,
      "EnableCollisionPassthrough": false
    }
  },
  "Wind": {
    "X": 0, "Y": 0, "Z": 0
  }
}

Why EnableCollisionPassthrough: false: This ensures AirSim actually simulates collisions instead of ignoring them — critical for crash testing.


Solution: Simulate Crash Scenarios

Step 3: Connect and Arm the Drone

import airsim
import time

# Connect to AirSim (must be running first)
client = airsim.MultirotorClient()
client.confirmConnection()
client.enableApiControl(True)
client.armDisarm(True)

print("Connected and armed.")

If it fails:

  • ConnectionRefusedError: AirSim isn't running — launch the environment first.
  • API control not enabled: Check settings.json for conflicting vehicle configs.

Step 4: Simulate a GPS Failure Mid-Flight

import airsim
import time

client = airsim.MultirotorClient()
client.confirmConnection()
client.enableApiControl(True)
client.armDisarm(True)

# Take off and fly to a waypoint
client.takeoffAsync().join()
client.moveToPositionAsync(10, 0, -5, 3).join()  # x, y, z (NED), speed m/s

# Inject GPS failure by spoofing zero-confidence GPS data
# AirSim doesn't have a direct GPS-off API, so we simulate via noise
client.simSetDetectionFilterRadius("Drone1", 0)  # Shrinks sensor range

time.sleep(3)  # Observe behavior during "lost GPS"

# Log state at failure
state = client.getMultirotorState()
pos = state.kinematics_estimated.position
print(f"Position at GPS loss: x={pos.x_val:.2f}, y={pos.y_val:.2f}, z={pos.z_val:.2f}")

# Reset
client.landAsync().join()
client.armDisarm(False)

Expected: The drone hovers or drifts slightly. If it immediately falls or flips, your control loop has no GPS fallback — fix that before real flight.


Step 5: Simulate Wind Gusts

AirSim supports runtime wind injection via the API:

# Set a sudden crosswind (5 m/s from the east)
wind_vector = airsim.Vector3r(0, 5, 0)  # NED frame: Y = east
client.simSetWind(wind_vector)

# Fly and observe drift
client.moveToPositionAsync(20, 0, -5, 3).join()

state = client.getMultirotorState()
pos = state.kinematics_estimated.position
print(f"Final position with wind: y_drift={pos.y_val:.2f}m")  # Should be near 0 if PID is tuned

# Reset wind
client.simSetWind(airsim.Vector3r(0, 0, 0))

What good looks like: Position error under 1m for a 20m flight in 5 m/s wind. Over 3m means your PID gains need tuning.

If it fails:

  • AttributeError: 'MultirotorClient' has no 'simSetWind': Update AirSim — this API was added in v1.4.

Step 6: Force a Crash and Inspect Telemetry

# Fly fast into the ground — simulate control failure
client.takeoffAsync().join()
client.moveByVelocityAsync(0, 0, 5, 2).join()  # Descend at 5 m/s for 2 seconds

# Check collision info
collision = client.simGetCollisionInfo()
print(f"Collision detected: {collision.has_collided}")
print(f"Impact point: {collision.position}")
print(f"Impact normal: {collision.normal}")
print(f"Penetration depth: {collision.penetration_depth:.4f}m")

Expected output:

Collision detected: True
Impact point: Vector3r(x=0.02, y=-0.01, z=0.00)
Impact normal: Vector3r(x=0.00, y=0.00, z=1.00)
Penetration depth: 0.0412m

Use collision.normal to determine impact angle. A Z-normal of 1.0 means flat ground impact — expected. An X or Y-dominant normal means your drone hit something at an angle, which is useful for diagnosing waypoint routing bugs.


Verification

Run your full test suite against the simulation:

python crash_test_suite.py --environment blocks --runs 10

You should see: All 10 runs complete with telemetry logged. Review crash_log.json for any run where has_collided: true in unexpected scenarios.

If any scenario crashes unexpectedly, that's the scenario to fix before real flight.


What You Learned

  • AirSim's Python API lets you inject wind, sensor degradation, and velocity commands to reproduce edge cases
  • simGetCollisionInfo() returns enough data to reconstruct impact geometry and fix routing logic
  • GPS fallback behavior must be tested explicitly — AirSim won't test it by accident

Limitation: AirSim's aerodynamic model is simplified. Real-world turbulence, prop wash, and ground effect behave differently. Use simulation to catch logic errors, not to validate aerodynamics.

When NOT to use this: Don't skip field testing with a tethered drone. Simulation catches software bugs; it won't catch hardware issues like a loose motor mount or bad ESC calibration.


Tested on AirSim 1.8.1, Python 3.11, Ubuntu 22.04 and Windows 11