Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Python API example files #2683

Merged
merged 6 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions PythonClient/airsim/types.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import print_function
import msgpackrpc #install as admin: pip install msgpack-rpc-python
import numpy as np #pip install numpy
import math

class MsgpackMixin:
def __repr__(self):
Expand Down Expand Up @@ -62,6 +63,9 @@ def __init__(self, x_val = 0.0, y_val = 0.0, z_val = 0.0):
def nanVector3r():
return Vector3r(np.nan, np.nan, np.nan)

def containsNan(self):
return (math.isnan(self.x_val) or math.isnan(self.y_val) or math.isnan(self.z_val))

def __add__(self, other):
return Vector3r(self.x_val + other.x_val, self.y_val + other.y_val, self.z_val + other.z_val)

Expand Down Expand Up @@ -122,6 +126,9 @@ def __init__(self, x_val = 0.0, y_val = 0.0, z_val = 0.0, w_val = 1.0):
def nanQuaternionr():
return Quaternionr(np.nan, np.nan, np.nan, np.nan)

def containsNan(self):
return (math.isnan(self.w_val) or math.isnan(self.x_val) or math.isnan(self.y_val) or math.isnan(self.z_val))

def __add__(self, other):
if type(self) == type(other):
return Quaternionr( self.x_val+other.x_val, self.y_val+other.y_val, self.z_val+other.z_val, self.w_val+other.w_val )
Expand Down Expand Up @@ -207,6 +214,9 @@ def __init__(self, position_val = None, orientation_val = None):
def nanPose():
return Pose(Vector3r.nanVector3r(), Quaternionr.nanQuaternionr())

def containsNan(self):
return (self.position.containsNan() or self.orientation.containsNan())


class CollisionInfo(MsgpackMixin):
has_collided = False
Expand Down
33 changes: 9 additions & 24 deletions PythonClient/airsim/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import inspect
import types
import re
import cv2 # pip install opencv-python
import logging

from .types import *

Expand Down Expand Up @@ -41,6 +43,10 @@ def to_str(obj):


def write_file(filename, bstr):
"""
Write binary data to file.
Used for writing compressed PNG images
"""
with open(filename, 'wb') as afile:
afile.write(bstr)

Expand Down Expand Up @@ -196,27 +202,6 @@ def write_pfm(file, image, scale=1):
def write_png(filename, image):
""" image must be numpy array H X W X channels
"""
import zlib, struct

buf = image.flatten().tobytes()
width = image.shape[1]
height = image.shape[0]

# reverse the vertical line order and add null bytes at the start
width_byte_3 = width * 3
raw_data = b''.join(b'\x00' + buf[span:span + width_byte_3]
for span in range((height - 1) * width_byte_3, -1, - width_byte_3))

def png_pack(png_tag, data):
chunk_head = png_tag + data
return (struct.pack("!I", len(data)) +
chunk_head +
struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head)))

png_bytes = b''.join([
b'\x89PNG\r\n\x1a\n',
png_pack(b'IHDR', struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
png_pack(b'IDAT', zlib.compress(raw_data, 9)),
png_pack(b'IEND', b'')])

write_file(filename, png_bytes)
ret = cv2.imwrite(filename, image)
if not ret:
logging.error(f"Writing PNG file {filename} failed")
36 changes: 21 additions & 15 deletions PythonClient/car/hello_car.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import setup_path
import airsim
import cv2
import numpy as np
import os
import setup_path
import time
import tempfile

# connect to the AirSim simulator
# connect to the AirSim simulator
client = airsim.CarClient()
client.confirmConnection()
client.enableApiControl(True)
print("API Control enabled: %s" % client.isApiControlEnabled())
car_controls = airsim.CarControls()

tmp_dir = os.path.join(tempfile.gettempdir(), "airsim_car")
print ("Saving images to %s" % tmp_dir)
try:
os.makedirs(tmp_dir)
except OSError:
if not os.path.isdir(tmp_dir):
raise

for idx in range(3):
# get state of the car
car_state = client.getCarState()
Expand All @@ -32,34 +42,33 @@

# go reverse
car_controls.throttle = -0.5
car_controls.is_manual_gear = True;
car_controls.is_manual_gear = True
car_controls.manual_gear = -1
car_controls.steering = 0
client.setCarControls(car_controls)
print("Go reverse, steer right")
time.sleep(3) # let car drive a bit
car_controls.is_manual_gear = False; # change back gear to auto
car_controls.manual_gear = 0
car_controls.is_manual_gear = False # change back gear to auto
car_controls.manual_gear = 0

# apply brakes
car_controls.brake = 1
client.setCarControls(car_controls)
print("Apply brakes")
time.sleep(3) # let car drive a bit
car_controls.brake = 0 #remove brake

# get camera images from the car
responses = client.simGetImages([
airsim.ImageRequest("0", airsim.ImageType.DepthVis), #depth visualization image
airsim.ImageRequest("1", airsim.ImageType.DepthPerspective, True), #depth in perspective projection
airsim.ImageRequest("1", airsim.ImageType.Scene), #scene vision image in png format
airsim.ImageRequest("1", airsim.ImageType.Scene, False, False)]) #scene vision image in uncompressed RGB array
print('Retrieved images: %d', len(responses))
print('Retrieved images: %d' % len(responses))

for response_idx, response in enumerate(responses):
filename = os.path.join(tmp_dir, f"{idx}_{response.image_type}_{response_idx}")

for response in responses:
filename = 'c:/temp/py' + str(idx)
if not os.path.exists('c:/temp/'):
os.makedirs('c:/temp/')
if response.pixels_as_float:
print("Type %d, size %d" % (response.image_type, len(response.image_data_float)))
airsim.write_pfm(os.path.normpath(filename + '.pfm'), airsim.get_pfm_array(response))
Expand All @@ -70,12 +79,9 @@
print("Type %d, size %d" % (response.image_type, len(response.image_data_uint8)))
img1d = np.fromstring(response.image_data_uint8, dtype=np.uint8) # get numpy array
img_rgb = img1d.reshape(response.height, response.width, 3) # reshape array to 3 channel image array H X W X 3
cv2.imwrite(os.path.normpath(filename + '.png'), img_rgb) # write to png
cv2.imwrite(os.path.normpath(filename + '.png'), img_rgb) # write to png

#restore to original state
client.reset()

client.enableApiControl(False)



76 changes: 0 additions & 76 deletions PythonClient/car/legacy_hello_car.py

This file was deleted.

26 changes: 19 additions & 7 deletions PythonClient/computer_vision/cv_mode.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
# In settings.json first activate computer vision mode:
# In settings.json first activate computer vision mode:
# https://github.com/Microsoft/AirSim/blob/master/docs/image_apis.md#computer-vision-mode

import setup_path
import setup_path
import airsim

import pprint
import os
import time
import math
import tempfile

pp = pprint.PrettyPrinter(indent=4)

client = airsim.VehicleClient()
client.confirmConnection()

airsim.wait_key('Press any key to set camera-0 gimbal to 15-degree pitch')
camera_pose = airsim.Pose(airsim.Vector3r(0, 0, 0), airsim.to_quaternion(0.261799, 0, 0)) #radians
camera_pose = airsim.Pose(airsim.Vector3r(0, 0, 0), airsim.to_quaternion(math.radians(15), 0, 0)) #radians
client.simSetCameraPose("0", camera_pose)

airsim.wait_key('Press any key to get camera parameters')
for camera_name in range(5):
camera_info = client.simGetCameraInfo(str(camera_name))
print("CameraInfo %d: %s" % (camera_name, pp.pprint(camera_info)))
print("CameraInfo %d:" % camera_name)
pp.pprint(camera_info)

tmp_dir = os.path.join(tempfile.gettempdir(), "airsim_cv_mode")
print ("Saving images to %s" % tmp_dir)
try:
os.makedirs(tmp_dir)
except OSError:
if not os.path.isdir(tmp_dir):
raise

airsim.wait_key('Press any key to get images')
for x in range(3): # do few times
Expand All @@ -36,17 +47,18 @@
airsim.ImageRequest("4", airsim.ImageType.SurfaceNormals)])

for i, response in enumerate(responses):
filename = os.path.join(tmp_dir, str(x) + "_" + str(i))
if response.pixels_as_float:
print("Type %d, size %d, pos %s" % (response.image_type, len(response.image_data_float), pprint.pformat(response.camera_position)))
airsim.write_pfm(os.path.normpath('/temp/cv_mode_' + str(x) + "_" + str(i) + '.pfm'), airsim.get_pfm_array(response))
airsim.write_pfm(os.path.normpath(filename + '.pfm'), airsim.get_pfm_array(response))
else:
print("Type %d, size %d, pos %s" % (response.image_type, len(response.image_data_uint8), pprint.pformat(response.camera_position)))
airsim.write_file(os.path.normpath('/temp/cv_mode_' + str(x) + "_" + str(i) + '.png'), response.image_data_uint8)
airsim.write_file(os.path.normpath(filename + '.png'), response.image_data_uint8)

pose = client.simGetVehiclePose()
pp.pprint(pose)

time.sleep(3)

# currently reset() doesn't work in CV mode. Below is the workaround
client.simSetPose(airsim.Pose(airsim.Vector3r(0, 0, 0), airsim.to_quaternion(0, 0, 0)), True)
client.simSetVehiclePose(airsim.Pose(airsim.Vector3r(0, 0, 0), airsim.to_quaternion(0, 0, 0)), True)
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private List<byte> GetFrameData(ImageType type, bool isCompress) {
frameData.Add(c.r);
frameData.Add(c.g);
frameData.Add(c.b);
frameData.Add(c.a);
// frameData.Add(c.a); // Unreal is just sending RGB images, so don't include Alpha channel here
}
}
RenderTexture.active = null;
Expand Down