Skip to content

Latest commit

 

History

History
491 lines (382 loc) · 22 KB

File metadata and controls

491 lines (382 loc) · 22 KB

Transitioning from AirSim

Converting an AirSim Unreal environment to Project AirSim

To convert an existing AirSim Unreal environment to Project AirSim, you can perform the following steps:

  1. Delete the AirSim plugin folder in <environment>/Plugins/AirSim

  2. Edit the environment project's <environment>.uproject file:

    In "Modules", delete:

     "AdditionalDependencies": [
         "AirSim"
     ]
    

    In "Plugins", delete:

     {
     "Name": "AirSim",
     "Enabled": true
     },
    
  3. Add Project AirSim to the environment following How to add the Project AirSim Plugin to a custom Unreal environment, including the part about setting the GameMode to AirSimVNextGameMode since AirSimGameMode is no longer valid.

  4. On first opening of the <environment>.uproject file with Unreal Engine 4.25, there may be some warnings about failing to load some AirSim content such as:

     Failed to load /AirSim/StarterContent/Materials/M_Tech_Hex_Tile_Pulse.M_Tech_Hex_Tile_Pulse Referenced by StaticMeshComponent0
     Failed to load /AirSim/VehicleAdv/SUV/AutomotiveMaterials/Materials/Glass/M_Glass.M_Glass Referenced by StaticMeshComponent0
     ...
    

    These warnings can be cleared by simply re-saving the environment's levels after AirSim has been deleted from it.

  5. Check the environment's config ini files in <environment>/Config to remove any AirSim-specific paths or settings.

Major changes

  1. The Sky system has been upgraded to take advantage of latest UE Sky Atmosphere and Volumetric clouds.

    • The lighting itself is the same. However, there are new API to fine tune the lighting in the scene. Checkout SetSunLightIntesity(), SetCloudShadowStrength() in the API Overview.
    • If you currently use your own scene/environment and work with AirsimVnext by dropping it into the scene as a plugin. This might break existing TimeOfDay APIs. See the "Trasition your scene from SkySphere to SunSky" section below for dealing with this properly.
  2. SetSunAngle(pitch, yaw) is discontinued and has been replaced by SetSunAngleFromDateTime(datetime, is_dst) which is more intuitive and supports more realistic sun positions depending on the location of the scene.

Transition from SkySphere to SunSky

SunSky is the new Unreal environment that provides a more natural and integrated lighting conditions. See https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/LightingAndShadows/SunSky/ for more details.

General guidelines to update your environment to SunSky:

  1. First enable the "Sun Position Calculator" plugin using the Unreal Editor.
  2. Delete any existing "DirectionalLight", "SkyLight", "SkyAtmosphere", "ExpoenntialHeightFog" actors from your scene.
  3. Add the SunSky Actor using the "Place Actors" widget.
  4. The initial scene might be very bright since the default lighting are configured to be very bright. To correct this, select the SunSky actor from the World Outliner and goto the inherited DirectionalLight actor inside the components of the SunSky.
  5. There is a 'Intensity' field inside this directionalLight actor that can adjusted to your needs.
  6. Make sure the ID Name of the SunSky actor is "SunSky_2" (you can see this by hovering the mouse over the actor label in the World Outliner actor liss). The "SunSky_2" is the default unless there are other SunSky actors in your scene.
  7. You can also add "Volumetric Clouds" actor to the scene to make the sky dome more realistic.

Converting an AirSim OSS configuration to Project AirSim

Refer to the documentation on configuration for information about Project AirSim's configuration files and what settings are available.

The following is a rough guide on how to handle each element from the AirSim OSS configuration in Project AirSim. Some items are introduced without highlighting their position in the Project AirSim configuration hierarchy. Refer to the documentation to know the exact positions of each configuration item.

"SimMode":

Project Airsim assumes that any autonomous vehicle is in use (Ground or Aerial for now). For ComputerVision, take a look at computer_vision.py.

"ViewMode", "CameraDirector":

In the Robot Config, the first listed camera with "streaming-enabled: true" is the viewpoint camera for that robot. Configure the "origin" and "gimbal" to obtain the desired view.

"TimeOfDay":

Not configurable. Use the world.SetTimeOfDay() client API call.

"OriginGeopoint":

Set "home-geo-point" in the scene configuration.

"SubWindows":

No longer part of configuration. Use the ImageDisplay clientside API to work with subwindows.

"Recording":

Server-side recording is not supported yet. All data should be recorded clientside.

"ClockSpeed":

To control the clock speed, select a "steppable" clock in the scene config. The ratio of "step-ns" to "real-time-update-rate" replaces "ClockSpeed". For example, the following configuration is equivalent to '"ClockSpeed": 0.5`:

"clock": {
    "type": "steppable",
    "step-ns": 1500000,
    "real-time-update-rate": 3000000,
    "pause-on-start": false
  }

"Segmentation":

Set "segmentation" in the Scene Config.

Old Setting Name New Setting Name
"InitMethod": "" or "InitMethod": "CommonObjectsRandomIDs" "initialized-ids": true
"InitMethod": "None" "initialized-ids": false
"OverrideExisting" ignore-existing
"MeshNamingMethod" use-owner-name

"Wind":

Not configurable. Use the world.SetWindVelocity() client API call.

"VehicleType":

For multirotor vehicles, set up the "controller" in the vehicle config e.g.:

"controller": {
  "id": "Simple_Flight_Controller",
  "airframe-setup": "quadrotor-x",
  "type": "simple-flight-api",
  "simple-flight-api-settings": {...}
}

Set an appropriate name for the id, then specify "simple-flight-api", "px4-api", or "manual-controller-api" as the "type" and fill in the "simple-flight-api-settings", "px4-settings", or "manual-controller-api-setttings" as appropriate.

"PawnPath":

Set the "visual" in the vehicle config. E.g:

"visual": {
  "geometry": {
    "type": "unreal_mesh",
    "name": "/Drone/Quadrotor1",
    "scale": "1.0 1.0 1.0"
  }
}

"DefaultVehicleState":

Not configurable. The drone always starts disarmed.

"AutoCreate":

Not needed.

"RC":

Not selected through config. See the remote control guide for information on how to set up a remote controller with Project Airsim.

"X", "Y", "Z", "Yaw", "Roll", "Pitch":

In the scene settings, set "origin" to

{
    "xyz": "x, y, z",
    "rpy": "r, p, y"
}

Project AirSim uses radians for roll, pitch, and yaw. You will need to convert your values from degrees to radians.

"IsFpvVehicle":

Any vehicle with "IsFpvVehicle": true should be listed first in the config instead. In general, the vehicle camera will follow the first vehicle listed.

"Px4 Settings":

Old Setting Name New Setting Name
Lockstep lock-step
ControlIp control-ip-address
ControlPortLocal control-port
ControlPortRemote control-port
QgcHostIp qgc-host-ip
QgcPort qgc-port
TcpPort tcp-port
SerialPort serial-port
UseSerial use-serial
UseTcp use-tcp
Parameters parameters
Other settings Not present.

"Sensors":

SensorTypes are now denoted with string values instead of enum values:

Old Type New Type
0 camera
1 barometer
2 imu
3 gps
4 magnetometer
5 (distance sensor isn't implemented yet)
6 lidar

Make sure to add: "parent-link": "Frame" to all sensor configurations.

"Cameras":

Note that the new "compress" and "pixels-as-float" settings in "capture-settings" are required, as is "capture-enabled".

Old Setting Name New Setting Name
Enabled enabled
CaptureSettings capture-settings
ImageType image-type (some image types are not yet implemented)
Width width
Height height
FOV_Degrees fov-degrees
TargetGamma target-gamma
AutoExposureSpeed Not implemented.
AutoExposureBias Not implemented.
AutoExposureMaxBrightness Not implemented.
MotionBlurAmount Not implemented.
ProjectionMode Not implemented.
OrthoWidth Not implemented.
RandContrib rand-contrib
RandSpeed rand-speed
RandSize rand-size
RandDensity rand-density
HorzWaveContrib horz-wave-contrib
HorzWaveStrength horz-wave-strength
HorzWaveVertSize horz-wave-vert-size
HorzWaveScreenSize horz-wave-screen-size
HorzNoiseLinesContrib horz-noise-lines-contrib
HorzNoiseLinesDensityY horz-noise-lines-density-y
HorzNoiseLinesDensityXY horz-noise-lines-density-xy
HorzDistortionContrib horz-distortion-contrib
HorzDistortionStrength horz-distortion-strength

"Barometer":

Old Setting Name New Setting Name
Enabled enabled
PressureFactorSigma pressure-factor-sigma
PressureFactorTau pressure-factor-tau
UncorrelatedNoiseSigma uncorrelated-noise-sigma
UpdateLatency update-latency
UpdateFrequency update-frequency
StartupDelay startup-delay

"Imu":

Old Setting Name New Setting Name
Enabled enabled
AngularRandomWalk gyroscope : { angle-random-walk }
GyroBiasStabilityTau gyroscope: { tau }
GyroBiasStability gyroscope: { bias-stability }
VelocityRandomWalk accelerometer: { velocity-random-walk }
AccelBiasStabilityTau accelerometer: { tau }
AccelBiasStability accelerometer: { bias-stability }

"Gps":

Old Setting Name New Setting Name
Enabled enabled
EphTimeConstant eph-time-constant
EpvTimeConstant epv-time-constant
EphInitial eph-initial
EpvInitial epv-initial
EphFinal eph-final
EpvFinal epv-final
EphMin3d eph-min_3d
EphMin2d eph-min_2d
UpdateLatency Not implemented.
UpdateFrequency Not implemented.
StartupDelay Not implemented.

"Magnetometer":

Old Setting Name New Setting Name
Enabled enabled
NoiseSigma noise-sigma
ScaleFactor scale-factor
NoiseBias noise-bias
UpdateLatency Not implemented.
UpdateFrequency Not implemented.
StartupDelay Not implemented.

"Lidar":

Old Setting Name New Setting Name
Enabled enabled
NumberOfChannels number-of-channels
Range range
PointsPerSecond points-per-second
RotationsPerSecond horizontal-rotation-frequency or vertical-rotation-frequency
HorizontalFOVStart horizontal-fov-start-deg
HorizontalFOVEnd horizontal-fov-end-deg
VerticalFOVUpper vertical-fov-upper-deg
VerticalFOVLower vertical-fov-lower-deg
X, Y, Z origin: { "xyz": "x, y, z" }
Roll, Pitch, Yaw origin: { "rpy": "r p y" }
DrawDebugPoints draw-debug-points
DataFrame Not implemented?
ExternalController Not implemented?

"PhysicsEngineName":

Set "physics-type" in the robot configuration.

Old Engine Name New Engine Name
FastPhysicsEngine fast-physics
ExternalPhysicsEngine non-physics

"LocalHostIp", "ApiServerPort":

Not part of configuration. Use the address, port_topics, and port_services parameters when initializing the AirSimVNextClient.

Converting an AirSim OSS client code to Project AirSim

General considerations

You cannot connect to Project AirSim with more than one client script at a time. If a second script connects, the first script will suffer a fatal error.

Unlike AirSim OSS, Project AirSim's client does not connect when it is instantiated. To connect to the server, use the client.connect() function of the client object.

While in AirSim OSS all method calls were made through the client, in Project AirSim there is a hierarchy of classes such as World for accesing methods that apply to the environment and Drone for methods that apply to drones.

Project Airsim has a logging framework which should be used in preference to print(). E.g. airsim_vnext_log().info("").

Project Airsim's client does not automatically set up the environment from a settings.json file. One must initialize it manually using a valid scene configuration file.

world = World(client, "scene_config.jsonc")

Note that the file path is relative to .\sim_config where . is the location of the script. For information on writing scene configuration files see the Scene Configuration Settings documentation.

To take control of a drone, initialize it using the name it has in the config.

drone = Drone(client, world, "Drone1")

You can then call the drone's method's to control it. If multiple drones exist in the scene, each one can be initialized and controlled in this fashion. This replaces the vehicle_name parameter from AirSim OSS's functions.

Project AirSim uses Radians as a standard for all interactions. Make sure that your code does not give commands in Degrees.

Note on asynchronous methods

All asynchronous methods in Project AirSim use the asyncio library for Python, meaning they must be handled with asyncio's syntax. For example, instead of using

client.takeoffAsync().join()

as you would in AirSim OSS, use

takeoff_task = await drone.takeoff_async()
await takeoff_task

We await takeoff_async, which retrieves an asychronous task. We then execute the task by awaiting it.

Reference table for api migration

Methods

Connection and API Control

AirSim OSS Project AirSim Observations
client.enableApiControl(bool) drone.enable_api_control(), drone.disable_api_control()
client.isApiControlEnabled() Not implemented.
client.reset() World() To reset the scene, instantiate the same World again.
client.confirmConnection() Not implemented.
client.ping() Not implemented.
client.simRunConsoleCommand() Not implemented.

Drone Control

AirSim OSS Project AirSim Observations
client.armDisarm(bool) drone.arm(), drone.disarm()
client.takeoffAsync() drone.takeoff_async()
client.landAsync() drone.land_async() Default timeout has changed from 60 to 3e38 seconds.
client.hoverAsync() drone.hover_async()
client.moveByVelocityAsync(vx, vy, vz, duration, drivetrain, yaw_mode) drone.move_by_velocity_async(self,v_north,v_east,v_down,duration,yaw_control_mode,yaw_is_rate,yaw) YawMode struct does not exist. Pass yaw and yaw_is_rate separately.
client.moveByVelocityZAsync(vx, vy, vz, duration, drivetrain, yaw_mode) drone.move_by_velocity_z_async(self,v_north,v_east,v_down,duration,yaw_control_mode,yaw_is_rate,yaw) YawMode struct does not exist. Pass yaw and yaw_is_rate separately.
client.moveToPositionAsync(self, x, y, z, velocity, timeout_sec, drivetrain, yaw_mode, lookahead, adaptive_lookahead) drone.move_to_position_async(self, north, east, down, velocity, timeout_sec, yaw_control_mode, yaw_is_rate, yaw, lookahead, adaptive_lookahead) YawMode struct does not exist. Pass yaw and yaw_is_rate separately.
client.moveOnPathAsync() drone.move_on_path_async() Path is now given as a 2D array.
client.moveToZAsync() Not implemented.
client.simSetVehiclePose() drone.set_pose()
client.simSetKinematics() drone.get_ground_truth_kinematics()
client.moveByManualAsync() See info on how to set up remote controller.
client.moveByRc() flight_rc.set() Only needs to be called once.

Images

AirSim OSS Project AirSim Observations
client.simGetImage() Not implemented. Use drone.get_images with only one image_type_id to request a single image.
client.simGetImages(requests) drone.get_images(camera_id, image_type_ids) Instead of sending a set of ImageRequests, call requests a set of ImageTypes from a given camera.
client.simSetCameraPose() drone.set_camera_pose()
client.simGetCameraInfo() Not implemented.
client.simSetCameraFov() Not implemented.
client.simGetDistortionParams() Not implemented.
client.simSetDistortionParams() Not implemented.
client.simSetDetectionFilterRadius() Not implemented.
client.simAddDetectionFilterMeshName() Configurable. Set "object_id" in the "annotations" section of the camera config.
client.simGetDetections() Use drone.get_images on a camera with "annotations" configured. The returned data will include an "annotations" section.
client.simClearDetectionMeshNames() Not implemented.

Sensors and Ground Truth

AirSim OSS Project AirSim Observations
client.getMultirotorState() No equivalent. The API for estimated kinematics is not implemented yet. Use GetGroundTruthKinematics for now; it's the same unless a flight controller with estimation such as PX4 is in use. Collision info can be obtained by using self.client.subscribe() to subscribe to the collision sensor.
client.getImuData() drone.get_imu_data(sensor_name)
client.getBarometerData() drone.get_barometer_data(sensor_name)
client.getMagnetometerData() drone.get_magnetometer_data(sensor_name)
client.getGpsData() drone.get_gps_data(sensor_name)
client.getLidarData() Not implemented. Use self.client.subscribe() to subscribe to the LiDAR sensor and handle LiDAR data in the callback.
client.simGetVehiclePose() drone.get_ground_truth_pose()
client.getHomeGeoPoint() Not implemented.

Simulation

AirSim OSS Project AirSim Observations
client.simSetTraceLine() world.set_trace_line()
client.simSetWind(wind) world.set_wind_velocity(n, e, d) Wind isn't implemented in the physics yet, but the API exists.
client.simEnableWeather() Run world.enable_weather_visual_effects(), world.disable_weather_visual_effects()
client.simSetWeatherParameter() world.set_weather_visual_effects_param()
client.simTestLineOfSightToPoint() Not implemented.
client.simTestLineOfSightBetweenPoints() Not implemented.
client.simGetWorldExtents() Not implemented.
client.simPause() world.pause(), world.resume()
client.simContinueForTime() world.continue_for_sim_time() Units have changed from seconds to nanoseconds.
client.simAddVehicle() Not supported. ProjectAirsim does not currently support adding new drones while the sim is running. All required drones should be added to the scene configuration.
client.simGetSegmentationObjectId() world.get_segmentation_id_by_name()
client.simSetSegmentationObjectId() world.set_segmentation_id_by_name()
client.simSetObjectMaterial() Not implemented.
client.simSetObjectMaterialFromTexture() world.set_object_material() Use the file:/// protocol to access local textures.
client.simListAssets() Not implemented.
client.simSpawnObject() world.spawn_object()
client.simDestroyObject() world.destroy_object()
client.simListSceneObjects() world.list_objects()
client.simGetObjectPose() world.get_object_pose()
client.simSetObjectPose() world.set_object_pose()
client.simGetObjectScale() world.get_object_scale()
client.simSetObjectScale() world.set_object_scale()
client.simSwapTextures() Not implemented.
client.simSetLightIntensity() Not implemented.
client.simPlotArrows() world.plot_debug_arrows()
client.simPlotPoints() world.plot_debug_points()
client.simPlotLineStrip() world.plot_debug_solid_line()
client.simPlotLineList() world.plot_debug_dashed_line()
client.simPlotStrings() world.plot_debug_strings()
client.simPlotTransforms() world.plot_debug_transforms()
client.simPlotTransformsWithNames() world.plot_debug_transforms_with_names()
client.simFlushPersistentMarkers() world.flush_persistent_markers()

Utilities

AirSim OSS Project AirSim Observations
airsim.to_eularian_angles() projectairsim.utils.quaternion_to_rpy()
airsim.to_quaternion() projectairsim.utils.rpy_to_quaternion()

Types

Images

Image Types

AirSim OSS Project AirSim Observations
Scene = 0 SCENE = 0
DepthPlanar = 1 DEPTH_PLANAR = 1
DepthPerspective = 2 DEPTH_PERSPECTIVE = 2
DepthVis = 3
DisparityNormalized = 4
Segmentation = 5 SEGMENTATION = 3
SurfaceNormals = 6
Infrared = 7
OpticalFlow = 8
OpticalFlowVis = 9

Classes

AirSim OSS Project AirSim Observations
ImuDataOSS ImuDataPA The orientation parameter for OSS is in Euler and for PA in Quaternions

Migrated AirSim v1 Scripts examples

In the "../client/python/airsimv1_scripts_migrated" folder, you will find examples of AirSim scripts that have been translated to work with Project AirSim. These scripts demonstrate how to adapt existing functionalities from AirSim OSS to Project AirSim, serving as a practical reference for migrating your own scripts.


Copyright (C) Microsoft Corporation.
Copyright (C) 2025 IAMAI CONSULTING CORP

MIT License. All rights reserved.