[formatting] format with python black

This commit is contained in:
madratman 2020-07-02 08:55:50 -07:00
Родитель 56630e756e
Коммит ecb0993c7d
9 изменённых файлов: 507 добавлений и 184 удалений

4
.vscode/settings.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,4 @@
{
"editor.formatOnSave": true,
"python.formatting.provider": "black"
}

Просмотреть файл

@ -9,7 +9,13 @@ import math
# drone_name should match the name in ~/Document/AirSim/settings.json
class BaselineRacer(object):
def __init__(self, drone_name = "drone_1", viz_traj=True, viz_traj_color_rgba=[1.0, 0.0, 0.0, 1.0], viz_image_cv2=True):
def __init__(
self,
drone_name="drone_1",
viz_traj=True,
viz_traj_color_rgba=[1.0, 0.0, 0.0, 1.0],
viz_image_cv2=True,
):
self.drone_name = drone_name
self.gate_poses_ground_truth = None
self.viz_image_cv2 = viz_image_cv2
@ -20,26 +26,33 @@ class BaselineRacer(object):
self.airsim_client.confirmConnection()
# we need two airsim MultirotorClient objects because the comm lib we use (rpclib) is not thread safe
# so we poll images in a thread using one airsim MultirotorClient object
# and use another airsim MultirotorClient for querying state commands
# and use another airsim MultirotorClient for querying state commands
self.airsim_client_images = airsim.MultirotorClient()
self.airsim_client_images.confirmConnection()
self.airsim_client_odom = airsim.MultirotorClient()
self.airsim_client_odom.confirmConnection()
self.level_name = None
self.image_callback_thread = threading.Thread(target=self.repeat_timer_image_callback, args=(self.image_callback, 0.03))
self.odometry_callback_thread = threading.Thread(target=self.repeat_timer_odometry_callback, args=(self.odometry_callback, 0.02))
self.image_callback_thread = threading.Thread(
target=self.repeat_timer_image_callback, args=(self.image_callback, 0.03)
)
self.odometry_callback_thread = threading.Thread(
target=self.repeat_timer_odometry_callback,
args=(self.odometry_callback, 0.02),
)
self.is_image_thread_active = False
self.is_odometry_thread_active = False
self.MAX_NUMBER_OF_GETOBJECTPOSE_TRIALS = 10 # see https://github.com/microsoft/AirSim-Drone-Racing-Lab/issues/38
self.MAX_NUMBER_OF_GETOBJECTPOSE_TRIALS = (
10 # see https://github.com/microsoft/AirSim-Drone-Racing-Lab/issues/38
)
# loads desired level
def load_level(self, level_name, sleep_sec = 2.0):
def load_level(self, level_name, sleep_sec=2.0):
self.level_name = level_name
self.airsim_client.simLoadLevel(self.level_name)
self.airsim_client.confirmConnection() # failsafe
time.sleep(sleep_sec) # let the environment load completely
self.airsim_client.confirmConnection() # failsafe
time.sleep(sleep_sec) # let the environment load completely
# Starts an instance of a race in your given level, if valid
def start_race(self, tier=3):
@ -54,28 +67,54 @@ class BaselineRacer(object):
self.airsim_client.enableApiControl(vehicle_name=self.drone_name)
self.airsim_client.arm(vehicle_name=self.drone_name)
# set default values for trajectory tracker gains
traj_tracker_gains = airsim.TrajectoryTrackerGains(kp_cross_track = 5.0, kd_cross_track = 0.0,
kp_vel_cross_track = 3.0, kd_vel_cross_track = 0.0,
kp_along_track = 0.4, kd_along_track = 0.0,
kp_vel_along_track = 0.04, kd_vel_along_track = 0.0,
kp_z_track = 2.0, kd_z_track = 0.0,
kp_vel_z = 0.4, kd_vel_z = 0.0,
kp_yaw = 3.0, kd_yaw = 0.1)
# set default values for trajectory tracker gains
traj_tracker_gains = airsim.TrajectoryTrackerGains(
kp_cross_track=5.0,
kd_cross_track=0.0,
kp_vel_cross_track=3.0,
kd_vel_cross_track=0.0,
kp_along_track=0.4,
kd_along_track=0.0,
kp_vel_along_track=0.04,
kd_vel_along_track=0.0,
kp_z_track=2.0,
kd_z_track=0.0,
kp_vel_z=0.4,
kd_vel_z=0.0,
kp_yaw=3.0,
kd_yaw=0.1,
)
self.airsim_client.setTrajectoryTrackerGains(traj_tracker_gains, vehicle_name=self.drone_name)
self.airsim_client.setTrajectoryTrackerGains(
traj_tracker_gains, vehicle_name=self.drone_name
)
time.sleep(0.2)
def takeoffAsync(self):
self.airsim_client.takeoffAsync().join()
# like takeoffAsync(), but with moveOnSpline()
def takeoff_with_moveOnSpline(self, takeoff_height = 1.0):
start_position = self.airsim_client.simGetVehiclePose(vehicle_name=self.drone_name).position
takeoff_waypoint = airsim.Vector3r(start_position.x_val, start_position.y_val, start_position.z_val-takeoff_height)
def takeoff_with_moveOnSpline(self, takeoff_height=1.0):
start_position = self.airsim_client.simGetVehiclePose(
vehicle_name=self.drone_name
).position
takeoff_waypoint = airsim.Vector3r(
start_position.x_val,
start_position.y_val,
start_position.z_val - takeoff_height,
)
self.airsim_client.moveOnSplineAsync([takeoff_waypoint], vel_max=15.0, acc_max=5.0, add_position_constraint=True, add_velocity_constraint=False,
add_acceleration_constraint=False, viz_traj=self.viz_traj, viz_traj_color_rgba=self.viz_traj_color_rgba, vehicle_name=self.drone_name).join()
self.airsim_client.moveOnSplineAsync(
[takeoff_waypoint],
vel_max=15.0,
acc_max=5.0,
add_position_constraint=True,
add_velocity_constraint=False,
add_acceleration_constraint=False,
viz_traj=self.viz_traj,
viz_traj_color_rgba=self.viz_traj_color_rgba,
vehicle_name=self.drone_name,
).join()
# stores gate ground truth poses as a list of airsim.Pose() objects in self.gate_poses_ground_truth
def get_ground_truth_gate_poses(self):
@ -83,54 +122,110 @@ class BaselineRacer(object):
# gate_names_sorted_bad is of the form `GateN_GARBAGE`. for example:
# ['Gate0', 'Gate10_21', 'Gate11_23', 'Gate1_3', 'Gate2_5', 'Gate3_7', 'Gate4_9', 'Gate5_11', 'Gate6_13', 'Gate7_15', 'Gate8_17', 'Gate9_19']
# we sort them by their ibdex of occurence along the race track(N), and ignore the unreal garbage number after the underscore(GARBAGE)
gate_indices_bad = [int(gate_name.split('_')[0][4:]) for gate_name in gate_names_sorted_bad]
gate_indices_correct = sorted(range(len(gate_indices_bad)), key=lambda k: gate_indices_bad[k])
gate_names_sorted = [gate_names_sorted_bad[gate_idx] for gate_idx in gate_indices_correct]
gate_indices_bad = [
int(gate_name.split("_")[0][4:]) for gate_name in gate_names_sorted_bad
]
gate_indices_correct = sorted(
range(len(gate_indices_bad)), key=lambda k: gate_indices_bad[k]
)
gate_names_sorted = [
gate_names_sorted_bad[gate_idx] for gate_idx in gate_indices_correct
]
self.gate_poses_ground_truth = []
for gate_name in gate_names_sorted:
curr_pose = self.airsim_client.simGetObjectPose(gate_name)
counter = 0
while (math.isnan(curr_pose.position.x_val) or math.isnan(curr_pose.position.y_val) or math.isnan(curr_pose.position.z_val)) and (counter < self.MAX_NUMBER_OF_GETOBJECTPOSE_TRIALS):
while (
math.isnan(curr_pose.position.x_val)
or math.isnan(curr_pose.position.y_val)
or math.isnan(curr_pose.position.z_val)
) and (counter < self.MAX_NUMBER_OF_GETOBJECTPOSE_TRIALS):
print(f"DEBUG: {gate_name} position is nan, retrying...")
counter += 1
curr_pose = self.airsim_client.simGetObjectPose(gate_name)
assert not math.isnan(curr_pose.position.x_val), f"ERROR: {gate_name} curr_pose.position.x_val is still {curr_pose.position.x_val} after {counter} trials"
assert not math.isnan(curr_pose.position.y_val), f"ERROR: {gate_name} curr_pose.position.y_val is still {curr_pose.position.y_val} after {counter} trials"
assert not math.isnan(curr_pose.position.z_val), f"ERROR: {gate_name} curr_pose.position.z_val is still {curr_pose.position.z_val} after {counter} trials"
assert not math.isnan(
curr_pose.position.x_val
), f"ERROR: {gate_name} curr_pose.position.x_val is still {curr_pose.position.x_val} after {counter} trials"
assert not math.isnan(
curr_pose.position.y_val
), f"ERROR: {gate_name} curr_pose.position.y_val is still {curr_pose.position.y_val} after {counter} trials"
assert not math.isnan(
curr_pose.position.z_val
), f"ERROR: {gate_name} curr_pose.position.z_val is still {curr_pose.position.z_val} after {counter} trials"
self.gate_poses_ground_truth.append(curr_pose)
# this is utility function to get a velocity constraint which can be passed to moveOnSplineVelConstraints()
# this is utility function to get a velocity constraint which can be passed to moveOnSplineVelConstraints()
# the "scale" parameter scales the gate facing vector accordingly, thereby dictating the speed of the velocity constraint
def get_gate_facing_vector_from_quaternion(self, airsim_quat, scale = 1.0):
def get_gate_facing_vector_from_quaternion(self, airsim_quat, scale=1.0):
import numpy as np
# convert gate quaternion to rotation matrix.
# convert gate quaternion to rotation matrix.
# ref: https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion; https://www.lfd.uci.edu/~gohlke/code/transformations.py.html
q = np.array([airsim_quat.w_val, airsim_quat.x_val, airsim_quat.y_val, airsim_quat.z_val], dtype=np.float64)
q = np.array(
[
airsim_quat.w_val,
airsim_quat.x_val,
airsim_quat.y_val,
airsim_quat.z_val,
],
dtype=np.float64,
)
n = np.dot(q, q)
if n < np.finfo(float).eps:
return airsim.Vector3r(0.0, 1.0, 0.0)
q *= np.sqrt(2.0 / n)
q = np.outer(q, q)
rotation_matrix = np.array([[1.0-q[2, 2]-q[3, 3], q[1, 2]-q[3, 0], q[1, 3]+q[2, 0]],
[ q[1, 2]+q[3, 0], 1.0-q[1, 1]-q[3, 3], q[2, 3]-q[1, 0]],
[ q[1, 3]-q[2, 0], q[2, 3]+q[1, 0], 1.0-q[1, 1]-q[2, 2]]])
gate_facing_vector = rotation_matrix[:,1]
return airsim.Vector3r(scale * gate_facing_vector[0], scale * gate_facing_vector[1], scale * gate_facing_vector[2])
rotation_matrix = np.array(
[
[1.0 - q[2, 2] - q[3, 3], q[1, 2] - q[3, 0], q[1, 3] + q[2, 0]],
[q[1, 2] + q[3, 0], 1.0 - q[1, 1] - q[3, 3], q[2, 3] - q[1, 0]],
[q[1, 3] - q[2, 0], q[2, 3] + q[1, 0], 1.0 - q[1, 1] - q[2, 2]],
]
)
gate_facing_vector = rotation_matrix[:, 1]
return airsim.Vector3r(
scale * gate_facing_vector[0],
scale * gate_facing_vector[1],
scale * gate_facing_vector[2],
)
def fly_through_all_gates_one_by_one_with_moveOnSpline(self):
if self.level_name == "Building99_Hard":
vel_max = 5.0
acc_max = 2.0
if self.level_name in ["Soccer_Field_Medium", "Soccer_Field_Easy", "ZhangJiaJie_Medium"] :
if self.level_name in [
"Soccer_Field_Medium",
"Soccer_Field_Easy",
"ZhangJiaJie_Medium",
]:
vel_max = 10.0
acc_max = 5.0
return self.airsim_client.moveOnSplineAsync([gate_pose.position], vel_max=vel_max, acc_max=acc_max,
add_position_constraint=True, add_velocity_constraint=False, add_acceleration_constraint=False, viz_traj=self.viz_traj, viz_traj_color_rgba=self.viz_traj_color_rgba, vehicle_name=self.drone_name)
return self.airsim_client.moveOnSplineAsync(
[gate_pose.position],
vel_max=vel_max,
acc_max=acc_max,
add_position_constraint=True,
add_velocity_constraint=False,
add_acceleration_constraint=False,
viz_traj=self.viz_traj,
viz_traj_color_rgba=self.viz_traj_color_rgba,
vehicle_name=self.drone_name,
)
def fly_through_all_gates_at_once_with_moveOnSpline(self):
if self.level_name in ["Soccer_Field_Medium", "Soccer_Field_Easy", "ZhangJiaJie_Medium", "Qualifier_Tier_1", "Qualifier_Tier_2", "Qualifier_Tier_3", "Final_Tier_1", "Final_Tier_2", "Final_Tier_3"] :
if self.level_name in [
"Soccer_Field_Medium",
"Soccer_Field_Easy",
"ZhangJiaJie_Medium",
"Qualifier_Tier_1",
"Qualifier_Tier_2",
"Qualifier_Tier_3",
"Final_Tier_1",
"Final_Tier_2",
"Final_Tier_3",
]:
vel_max = 30.0
acc_max = 15.0
@ -138,14 +233,23 @@ class BaselineRacer(object):
vel_max = 4.0
acc_max = 1.0
return self.airsim_client.moveOnSplineAsync([gate_pose.position for gate_pose in self.gate_poses_ground_truth], vel_max=vel_max, acc_max=acc_max,
add_position_constraint=True, add_velocity_constraint=False, add_acceleration_constraint=False, viz_traj=self.viz_traj, viz_traj_color_rgba=self.viz_traj_color_rgba, vehicle_name=self.drone_name)
return self.airsim_client.moveOnSplineAsync(
[gate_pose.position for gate_pose in self.gate_poses_ground_truth],
vel_max=vel_max,
acc_max=acc_max,
add_position_constraint=True,
add_velocity_constraint=False,
add_acceleration_constraint=False,
viz_traj=self.viz_traj,
viz_traj_color_rgba=self.viz_traj_color_rgba,
vehicle_name=self.drone_name,
)
def fly_through_all_gates_one_by_one_with_moveOnSplineVelConstraints(self):
add_velocity_constraint = True
add_acceleration_constraint = False
if self.level_name in ["Soccer_Field_Medium", "Soccer_Field_Easy"] :
if self.level_name in ["Soccer_Field_Medium", "Soccer_Field_Easy"]:
vel_max = 15.0
acc_max = 3.0
speed_through_gate = 2.5
@ -161,15 +265,30 @@ class BaselineRacer(object):
speed_through_gate = 0.5
add_velocity_constraint = False
# scale param scales the gate facing vector by desired speed.
return self.airsim_client.moveOnSplineVelConstraintsAsync([gate_pose.position],
[self.get_gate_facing_vector_from_quaternion(gate_pose.orientation, scale = speed_through_gate)],
vel_max=vel_max, acc_max=acc_max,
add_position_constraint=True, add_velocity_constraint=add_velocity_constraint, add_acceleration_constraint=add_acceleration_constraint,
viz_traj=self.viz_traj, viz_traj_color_rgba=self.viz_traj_color_rgba, vehicle_name=self.drone_name)
# scale param scales the gate facing vector by desired speed.
return self.airsim_client.moveOnSplineVelConstraintsAsync(
[gate_pose.position],
[
self.get_gate_facing_vector_from_quaternion(
gate_pose.orientation, scale=speed_through_gate
)
],
vel_max=vel_max,
acc_max=acc_max,
add_position_constraint=True,
add_velocity_constraint=add_velocity_constraint,
add_acceleration_constraint=add_acceleration_constraint,
viz_traj=self.viz_traj,
viz_traj_color_rgba=self.viz_traj_color_rgba,
vehicle_name=self.drone_name,
)
def fly_through_all_gates_at_once_with_moveOnSplineVelConstraints(self):
if self.level_name in ["Soccer_Field_Easy", "Soccer_Field_Medium", "ZhangJiaJie_Medium"]:
if self.level_name in [
"Soccer_Field_Easy",
"Soccer_Field_Medium",
"ZhangJiaJie_Medium",
]:
vel_max = 15.0
acc_max = 7.5
speed_through_gate = 2.5
@ -179,17 +298,29 @@ class BaselineRacer(object):
acc_max = 2.0
speed_through_gate = 1.0
return self.airsim_client.moveOnSplineVelConstraintsAsync([gate_pose.position for gate_pose in self.gate_poses_ground_truth],
[self.get_gate_facing_vector_from_quaternion(gate_pose.orientation, scale = speed_through_gate) for gate_pose in self.gate_poses_ground_truth],
vel_max=vel_max, acc_max=acc_max,
add_position_constraint=True, add_velocity_constraint=True, add_acceleration_constraint=False,
viz_traj=self.viz_traj, viz_traj_color_rgba=self.viz_traj_color_rgba, vehicle_name=self.drone_name)
return self.airsim_client.moveOnSplineVelConstraintsAsync(
[gate_pose.position for gate_pose in self.gate_poses_ground_truth],
[
self.get_gate_facing_vector_from_quaternion(
gate_pose.orientation, scale=speed_through_gate
)
for gate_pose in self.gate_poses_ground_truth
],
vel_max=vel_max,
acc_max=acc_max,
add_position_constraint=True,
add_velocity_constraint=True,
add_acceleration_constraint=False,
viz_traj=self.viz_traj,
viz_traj_color_rgba=self.viz_traj_color_rgba,
vehicle_name=self.drone_name,
)
def image_callback(self):
# get uncompressed fpv cam image
request = [airsim.ImageRequest("fpv_cam", airsim.ImageType.Scene, False, False)]
response = self.airsim_client_images.simGetImages(request)
img_rgb_1d = np.fromstring(response[0].image_data_uint8, dtype=np.uint8)
img_rgb_1d = np.fromstring(response[0].image_data_uint8, dtype=np.uint8)
img_rgb = img_rgb_1d.reshape(response[0].height, response[0].width, 3)
if self.viz_image_cv2:
cv2.imshow("img_rgb", img_rgb)
@ -199,12 +330,12 @@ class BaselineRacer(object):
# get uncompressed fpv cam image
drone_state = self.airsim_client_odom.getMultirotorState()
# in world frame:
position = drone_state.kinematics_estimated.position
position = drone_state.kinematics_estimated.position
orientation = drone_state.kinematics_estimated.orientation
linear_velocity = drone_state.kinematics_estimated.linear_velocity
angular_velocity = drone_state.kinematics_estimated.angular_velocity
# call task() method every "period" seconds.
# call task() method every "period" seconds.
def repeat_timer_image_callback(self, task, period):
while self.is_image_thread_active:
task()
@ -239,9 +370,15 @@ class BaselineRacer(object):
self.odometry_callback_thread.join()
print("Stopped odometry callback thread.")
def main(args):
# ensure you have generated the neurips planning settings file by running python generate_settings_file.py
baseline_racer = BaselineRacer(drone_name="drone_1", viz_traj=args.viz_traj, viz_traj_color_rgba=[1.0, 1.0, 0.0, 1.0], viz_image_cv2=args.viz_image_cv2)
baseline_racer = BaselineRacer(
drone_name="drone_1",
viz_traj=args.viz_traj,
viz_traj_color_rgba=[1.0, 1.0, 0.0, 1.0],
viz_image_cv2=args.viz_image_cv2,
)
baseline_racer.load_level(args.level_name)
if args.level_name == "Qualifier_Tier_1":
args.race_tier = 1
@ -256,7 +393,7 @@ def main(args):
baseline_racer.start_image_callback_thread()
baseline_racer.start_odometry_callback_thread()
if args.planning_baseline_type == "all_gates_at_once" :
if args.planning_baseline_type == "all_gates_at_once":
if args.planning_and_control_api == "moveOnSpline":
baseline_racer.fly_through_all_gates_at_once_with_moveOnSpline().join()
if args.planning_and_control_api == "moveOnSplineVelConstraints":
@ -268,19 +405,52 @@ def main(args):
if args.planning_and_control_api == "moveOnSplineVelConstraints":
baseline_racer.fly_through_all_gates_one_by_one_with_moveOnSplineVelConstraints().join()
# Comment out the following if you observe the python script exiting prematurely, and resetting the race
# Comment out the following if you observe the python script exiting prematurely, and resetting the race
baseline_racer.stop_image_callback_thread()
baseline_racer.stop_odometry_callback_thread()
baseline_racer.reset_race()
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument('--level_name', type=str, choices=["Soccer_Field_Easy", "Soccer_Field_Medium", "ZhangJiaJie_Medium", "Building99_Hard",
"Qualifier_Tier_1", "Qualifier_Tier_2", "Qualifier_Tier_3", "Final_Tier_1", "Final_Tier_2", "Final_Tier_3"], default="ZhangJiaJie_Medium")
parser.add_argument('--planning_baseline_type', type=str, choices=["all_gates_at_once","all_gates_one_by_one"], default="all_gates_at_once")
parser.add_argument('--planning_and_control_api', type=str, choices=["moveOnSpline", "moveOnSplineVelConstraints"], default="moveOnSpline")
parser.add_argument('--enable_viz_traj', dest='viz_traj', action='store_true', default=False)
parser.add_argument('--enable_viz_image_cv2', dest='viz_image_cv2', action='store_true', default=False)
parser.add_argument('--race_tier', type=int, choices=[1,2,3], default=1)
parser.add_argument(
"--level_name",
type=str,
choices=[
"Soccer_Field_Easy",
"Soccer_Field_Medium",
"ZhangJiaJie_Medium",
"Building99_Hard",
"Qualifier_Tier_1",
"Qualifier_Tier_2",
"Qualifier_Tier_3",
"Final_Tier_1",
"Final_Tier_2",
"Final_Tier_3",
],
default="ZhangJiaJie_Medium",
)
parser.add_argument(
"--planning_baseline_type",
type=str,
choices=["all_gates_at_once", "all_gates_one_by_one"],
default="all_gates_at_once",
)
parser.add_argument(
"--planning_and_control_api",
type=str,
choices=["moveOnSpline", "moveOnSplineVelConstraints"],
default="moveOnSpline",
)
parser.add_argument(
"--enable_viz_traj", dest="viz_traj", action="store_true", default=False
)
parser.add_argument(
"--enable_viz_image_cv2",
dest="viz_image_cv2",
action="store_true",
default=False,
)
parser.add_argument("--race_tier", type=int, choices=[1, 2, 3], default=1)
args = parser.parse_args()
main(args)

Просмотреть файл

@ -7,22 +7,33 @@ import numpy as np
import cv2
from baseline_racer import BaselineRacer
class BaselineRacerImageBenchmarker(BaselineRacer):
def __init__(self,
img_benchmark_type = 'simGetImage',
drone_name = "drone_1",
viz_traj = False,
viz_traj_color_rgba=[1.0, 1.0, 0.0, 1.0],
viz_image_cv2 = False):
super().__init__(drone_name=drone_name, viz_traj=viz_traj, viz_image_cv2=viz_image_cv2)
def __init__(
self,
img_benchmark_type="simGetImage",
drone_name="drone_1",
viz_traj=False,
viz_traj_color_rgba=[1.0, 1.0, 0.0, 1.0],
viz_image_cv2=False,
):
super().__init__(
drone_name=drone_name, viz_traj=viz_traj, viz_image_cv2=viz_image_cv2
)
self.image_benchmark_num_images = 0
self.image_benchmark_total_time = 0.0
self.image_callback_thread = None
if img_benchmark_type == "simGetImage":
self.image_callback_thread = threading.Thread(target=self.repeat_timer_img, args=(self.image_callback_benchmark_simGetImage, 0.05))
self.image_callback_thread = threading.Thread(
target=self.repeat_timer_img,
args=(self.image_callback_benchmark_simGetImage, 0.05),
)
if img_benchmark_type == "simGetImages":
self.image_callback_thread = threading.Thread(target=self.repeat_timer_img, args=(self.image_callback_benchmark_simGetImages, 0.05))
self.image_callback_thread = threading.Thread(
target=self.repeat_timer_img,
args=(self.image_callback_benchmark_simGetImages, 0.05),
)
self.is_image_thread_active = False
def start_img_benchmark_thread(self):
@ -43,45 +54,73 @@ class BaselineRacerImageBenchmarker(BaselineRacer):
time.sleep(period)
def print_benchmark_results(self):
avg_fps = 1.0 / ((self.image_benchmark_total_time) / float(self.image_benchmark_num_images))
print(self.level_name + ": {} avg_fps for {} num of images".format(avg_fps, self.image_benchmark_num_images))
avg_fps = 1.0 / (
(self.image_benchmark_total_time) / float(self.image_benchmark_num_images)
)
print(
self.level_name
+ ": {} avg_fps for {} num of images".format(
avg_fps, self.image_benchmark_num_images
)
)
def image_callback_benchmark_simGetImage(self):
self.image_benchmark_num_images += 1
iter_start_time = time.time()
response = self.airsim_client_images.simGetImage("fpv_cam", airsim.ImageType.Scene)
img_rgb = cv2.imdecode(airsim.string_to_uint8_array(response), cv2.IMREAD_UNCHANGED)
response = self.airsim_client_images.simGetImage(
"fpv_cam", airsim.ImageType.Scene
)
img_rgb = cv2.imdecode(
airsim.string_to_uint8_array(response), cv2.IMREAD_UNCHANGED
)
self.image_benchmark_total_time += time.time() - iter_start_time
avg_fps = 1.0 / ((self.image_benchmark_total_time) / float(self.image_benchmark_num_images))
print(self.level_name + ": {} avg_fps for {} num of images".format(avg_fps, self.image_benchmark_num_images))
avg_fps = 1.0 / (
(self.image_benchmark_total_time) / float(self.image_benchmark_num_images)
)
print(
self.level_name
+ ": {} avg_fps for {} num of images".format(
avg_fps, self.image_benchmark_num_images
)
)
# uncomment following lines to viz image
# if self.viz_image_cv2:
# cv2.imshow("img_rgb", img_rgb_1d_new)
# cv2.waitKey(1)
# cv2.imshow("img_rgb", img_rgb_1d_new)
# cv2.waitKey(1)
def image_callback_benchmark_simGetImages(self):
self.image_benchmark_num_images += 1
iter_start_time = time.time()
request = [airsim.ImageRequest("fpv_cam", airsim.ImageType.Scene, False, False)]
response = self.airsim_client_images.simGetImages(request)
img_rgb_1d = np.fromstring(response[0].image_data_uint8, dtype=np.uint8)
img_rgb_1d = np.fromstring(response[0].image_data_uint8, dtype=np.uint8)
img_rgb = img_rgb_1d.reshape(response[0].height, response[0].width, 3)
self.image_benchmark_total_time += time.time() - iter_start_time
avg_fps = 1.0 / ((self.image_benchmark_total_time) / float(self.image_benchmark_num_images))
print(self.level_name + ": {} avg_fps for {} num of images".format(avg_fps, self.image_benchmark_num_images))
avg_fps = 1.0 / (
(self.image_benchmark_total_time) / float(self.image_benchmark_num_images)
)
print(
self.level_name
+ ": {} avg_fps for {} num of images".format(
avg_fps, self.image_benchmark_num_images
)
)
# uncomment following lines to viz image
# if self.viz_image_cv2:
# cv2.imshow("img_rgb", img_rgb_1d_new)
# cv2.waitKey(1)
# cv2.imshow("img_rgb", img_rgb_1d_new)
# cv2.waitKey(1)
def main(args):
# ensure you have generated the neurips planning settings file by running python generate_settings_file.py
baseline_racer = BaselineRacerImageBenchmarker(img_benchmark_type=args.img_benchmark_type, \
drone_name="drone_1", \
viz_traj=args.viz_traj, \
viz_traj_color_rgba=[1.0, 1.0, 0.0, 1.0], \
viz_image_cv2=args.viz_image_cv2)
baseline_racer = BaselineRacerImageBenchmarker(
img_benchmark_type=args.img_benchmark_type,
drone_name="drone_1",
viz_traj=args.viz_traj,
viz_traj_color_rgba=[1.0, 1.0, 0.0, 1.0],
viz_image_cv2=args.viz_image_cv2,
)
baseline_racer.load_level(args.level_name)
if args.level_name == "Qualifier_Tier_1":
args.race_tier = 1
@ -99,14 +138,39 @@ def main(args):
baseline_racer.stop_img_benchmark_thread()
baseline_racer.print_benchmark_results()
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument('--level_name', type=str, choices=["Soccer_Field_Easy", "Soccer_Field_Medium", "ZhangJiaJie_Medium", "Building99_Hard",
"Qualifier_Tier_1", "Qualifier_Tier_2", "Qualifier_Tier_3"], default="ZhangJiaJie_Medium")
parser.add_argument('--enable_viz_traj', dest='viz_traj', action='store_true', default=False)
parser.add_argument('--img_benchmark_type', type=str, choices=["simGetImage", "simGetImages"], default="simGetImages")
parser.add_argument('--enable_viz_image_cv2', dest='viz_image_cv2', action='store_true', default=False)
parser.add_argument('--race_tier', type=int, choices=[1,2,3], default=1)
parser.add_argument(
"--level_name",
type=str,
choices=[
"Soccer_Field_Easy",
"Soccer_Field_Medium",
"ZhangJiaJie_Medium",
"Building99_Hard",
"Qualifier_Tier_1",
"Qualifier_Tier_2",
"Qualifier_Tier_3",
],
default="ZhangJiaJie_Medium",
)
parser.add_argument(
"--enable_viz_traj", dest="viz_traj", action="store_true", default=False
)
parser.add_argument(
"--img_benchmark_type",
type=str,
choices=["simGetImage", "simGetImages"],
default="simGetImages",
)
parser.add_argument(
"--enable_viz_image_cv2",
dest="viz_image_cv2",
action="store_true",
default=False,
)
parser.add_argument("--race_tier", type=int, choices=[1, 2, 3], default=1)
args = parser.parse_args()
main(args)
main(args)

Просмотреть файл

@ -1,3 +1,3 @@
from utils import AirSimSettingsCreator
AirSimSettingsCreator().write_airsim_neurips_baseline_settings_file()
AirSimSettingsCreator().write_airsim_neurips_baseline_settings_file()

Просмотреть файл

@ -3,39 +3,49 @@ import json
import numpy as np
import os
def to_airsim_vector(np_arr):
assert np.size(np_arr) == 3
return airsim.Vector3r(np.float(np_arr[0]), np.float(np_arr[1]), np.float(np_arr[2]))
return airsim.Vector3r(
np.float(np_arr[0]), np.float(np_arr[1]), np.float(np_arr[2])
)
def to_airsim_vectors(np_arr):
return [to_airsim_vector(np_arr[i, :]) for i in range(np.size(np_arr, 0))]
# these clases are only meant to be settings generator.
# for everything else, there's airsimdroneracinglab.Pose()
class Position():
def __init__(self, x = 0.0, y = 0.0, z = 0.0):
class Position:
def __init__(self, x=0.0, y=0.0, z=0.0):
self.x = x
self.y = y
self.z = z
class Rotation():
def __init__(self, yaw = 0.0, pitch = 0.0, roll = 0.0):
class Rotation:
def __init__(self, yaw=0.0, pitch=0.0, roll=0.0):
self.yaw = yaw
self.pitch = pitch
self.roll = roll
class Pose():
class Pose:
def __init__(self, position, rotation):
self.position = position
self.rotation = rotation
class AirSimSettingsCreator(object):
def __init__(self, sim_mode = "Multirotor"):
def __init__(self, sim_mode="Multirotor"):
self.sim_mode = sim_mode
self.settings_dict = {}
def add_minimal(self):
self.settings_dict["SeeDocsAt"] = "https://github.com/Microsoft/AirSim/blob/master/docs/settings.md"
self.settings_dict[
"SeeDocsAt"
] = "https://github.com/Microsoft/AirSim/blob/master/docs/settings.md"
self.settings_dict["SettingsVersion"] = 1.2
self.settings_dict["SimMode"] = self.sim_mode
self.settings_dict["ClockSpeed"] = 1
@ -50,28 +60,37 @@ class AirSimSettingsCreator(object):
setting_key["Yaw"] = pose.rotation.yaw
def add_multirotor(self, vehicle_name, pose):
assert(self.settings_dict["SimMode"] == "Multirotor")
assert self.settings_dict["SimMode"] == "Multirotor"
if "Vehicles" not in self.settings_dict.keys():
self.settings_dict['Vehicles'] = {}
self.settings_dict["Vehicles"] = {}
self.settings_dict['Vehicles'][vehicle_name] = {}
self.settings_dict['Vehicles'][vehicle_name]["VehicleType"] = "SimpleFlight"
self.set_pose(self.settings_dict['Vehicles'][vehicle_name], pose)
self.settings_dict["Vehicles"][vehicle_name] = {}
self.settings_dict["Vehicles"][vehicle_name]["VehicleType"] = "SimpleFlight"
self.set_pose(self.settings_dict["Vehicles"][vehicle_name], pose)
def add_camera(self, vehicle_name, camera_name, relative_pose, image_type, image_width, image_height, fov_horizontal_degrees):
def add_camera(
self,
vehicle_name,
camera_name,
relative_pose,
image_type,
image_width,
image_height,
fov_horizontal_degrees,
):
# fetch vehicle setting dict
vehicle_setting = self.settings_dict['Vehicles'][vehicle_name]
# initialize vehicle's camera setting dict to empty
vehicle_setting['Cameras'] = {}
vehicle_setting['Cameras'][camera_name] = {}
camera_setting = vehicle_setting['Cameras'][camera_name]
vehicle_setting = self.settings_dict["Vehicles"][vehicle_name]
# initialize vehicle's camera setting dict to empty
vehicle_setting["Cameras"] = {}
vehicle_setting["Cameras"][camera_name] = {}
camera_setting = vehicle_setting["Cameras"][camera_name]
self.set_pose(camera_setting, relative_pose)
capture_setting = {}
capture_setting['Width'] = image_width
capture_setting['Height'] = image_height
capture_setting['ImageType'] = image_type
capture_setting['FOV_Degrees'] = fov_horizontal_degrees
camera_setting['CaptureSettings'] = [capture_setting]
capture_setting["Width"] = image_width
capture_setting["Height"] = image_height
capture_setting["ImageType"] = image_type
capture_setting["FOV_Degrees"] = fov_horizontal_degrees
camera_setting["CaptureSettings"] = [capture_setting]
# default linux: /home/$USER/Documents/AirSim/settings.json
# default windows: C:\\Users\\%USERNAME%\\Documents\\AirSim\\settings.json
@ -88,8 +107,19 @@ class AirSimSettingsCreator(object):
def write_airsim_neurips_baseline_settings_file(self):
instance = self.__class__()
instance.add_minimal()
instance.add_multirotor(vehicle_name = "drone_1", pose = Pose(Position(), Rotation()))
instance.add_camera(vehicle_name = "drone_1", camera_name = 'fpv_cam', relative_pose=Pose(Position(0.25, 0.0, 0.0), Rotation()),
image_type = 0, image_width = 320, image_height = 240, fov_horizontal_degrees = 90)
instance.add_multirotor(vehicle_name = "drone_2", pose = Pose(Position(), Rotation()))
instance.write_airsim_settings_file()
instance.add_multirotor(
vehicle_name="drone_1", pose=Pose(Position(), Rotation())
)
instance.add_camera(
vehicle_name="drone_1",
camera_name="fpv_cam",
relative_pose=Pose(Position(0.25, 0.0, 0.0), Rotation()),
image_type=0,
image_width=320,
image_height=240,
fov_horizontal_degrees=90,
)
instance.add_multirotor(
vehicle_name="drone_2", pose=Pose(Position(), Rotation())
)
instance.write_airsim_settings_file()

Просмотреть файл

@ -1,36 +1,55 @@
from argparse import ArgumentParser
import subprocess
class DockerImageBuilder():
class DockerImageBuilder:
def __init__(self, args):
self.args = args
self.args = args
def build_docker_image(self):
# if a base image is not specified, we use the Ubuntu 18, CUDA 10 image from NVIDIA
docker_build_command = ['docker', 'build', '--network=host', \
'-t', self.args.target_image, \
'-f', self.args.dockerfile, \
'--build-arg', 'BASE_IMAGE=' + self.args.base_image, \
'.']
docker_build_command = [
"docker",
"build",
"--network=host",
"-t",
self.args.target_image,
"-f",
self.args.dockerfile,
"--build-arg",
"BASE_IMAGE=" + self.args.base_image,
".",
]
print(" ".join(docker_build_command))
subprocess.call(docker_build_command)
def main(args):
docker_image_builder = DockerImageBuilder(args)
docker_image_builder.build_docker_image()
if __name__=="__main__":
parser = ArgumentParser(description='AirSim Drone Racing Lab docker image builder')
parser.add_argument('--dockerfile', type=str, default='Dockerfile', help='path to docker file')
parser.add_argument('--base_image', type=str, default="nvidia/cudagl:10.0-devel-ubuntu18.04", help='base image name AND tag, on top of which the target image is built')
parser.add_argument('--target_image', type=str, help='desired name of target image name AND tag')
if __name__ == "__main__":
parser = ArgumentParser(description="AirSim Drone Racing Lab docker image builder")
parser.add_argument(
"--dockerfile", type=str, default="Dockerfile", help="path to docker file"
)
parser.add_argument(
"--base_image",
type=str,
default="nvidia/cudagl:10.0-devel-ubuntu18.04",
help="base image name AND tag, on top of which the target image is built",
)
parser.add_argument(
"--target_image", type=str, help="desired name of target image name AND tag"
)
args = parser.parse_args()
# if a target image name is not specified, let's call it adrl:SOURCE_IMAGE_TAG
if not args.target_image:
target_image_tag = args.base_image.split(":")[1]
args.target_image = 'adrl' + ':' + target_image_tag
target_image_tag = args.base_image.split(":")[1]
args.target_image = "adrl" + ":" + target_image_tag
main(args)
main(args)

Просмотреть файл

@ -5,20 +5,23 @@ import time
disqualified_racers = set()
finished_racers = set()
def open_file():
list_of_files = glob.glob('*.log')
list_of_files = glob.glob("*.log")
latest_file = max(list_of_files, key=os.path.getctime)
print("Opened file: " + latest_file)
return open(latest_file, "r+")
def follow(filename):
filename.seek(0,2)
filename.seek(0, 2)
while True:
line = filename.readline()
if not line:
time.sleep(0.1)
continue
yield line
yield line
def process(line):
tokens = line.split()
@ -27,35 +30,49 @@ def process(line):
print("Tokens: " + str(tokens))
return
if tokens[3] == "disqualified" and tokens[4] == '1' and tokens[0] not in disqualified_racers:
if (
tokens[3] == "disqualified"
and tokens[4] == "1"
and tokens[0] not in disqualified_racers
):
disqualified_racers.add(tokens[0])
handle_disqualified_racer(tokens[0])
return
if tokens[3] == "finished" and tokens[4] == '1' and tokens[0] not in finished_racers:
if (
tokens[3] == "finished"
and tokens[4] == "1"
and tokens[0] not in finished_racers
):
finished_racers.add(tokens[0])
handle_finished_racer(tokens[0])
return
if tokens[3] == "gates_passed":
handle_gate_passed(tokens[0], tokens[4])
handle_gate_passed(tokens[0], tokens[4])
def handle_disqualified_racer(racer_name):
print(racer_name + " has been disqualified!")
#Start a new race.
# Start a new race.
def handle_finished_racer(racer_name):
print(racer_name + " has finished!")
#Start a new race.
# Start a new race.
def handle_gate_passed(racer_name, gate_idx_passed):
# log file gate indices are 1-indexed, not 0-indexed
print("{} passed gate idx {}".format(racer_name, gate_idx_passed - 1))
def main():
f = open_file()
for line in follow(f):
process(line)
if __name__ == "__main__":
main()
main()

Просмотреть файл

@ -3,7 +3,7 @@
"SeeDocsAt": "https://github.com/Microsoft/AirSim/blob/master/docs/settings.md",
"SettingsVersion": 1.2,
"SimMode": "Multirotor",
"ViewMode": "NoDisplay",
"ViewMode": "NoDisplay",
"Vehicles": {
"drone_1": {
"Cameras": {
@ -42,4 +42,4 @@
"Z": 0.0
}
}
}
}

Просмотреть файл

@ -2,16 +2,23 @@ import airsimdroneracinglab
import threading
import time
class ReproduceResetRaceCondition():
def __init__(self, drone_name = "drone_1"):
class ReproduceResetRaceCondition:
def __init__(self, drone_name="drone_1"):
self.airsim_client = airsimdroneracinglab.MultirotorClient()
self.airsim_client_2 = airsimdroneracinglab.MultirotorClient()
self.airsim_client_3 = airsimdroneracinglab.MultirotorClient()
self.drone_name = drone_name
self.is_thread_active = False
self.thread_reset = threading.Thread(target=self.repeat_timer, args=(self.reset, 0.05))
self.thread_reset_race = threading.Thread(target=self.repeat_timer, args=(self.reset_race, 0.03))
self.thread_reset_and_reset_race = threading.Thread(target=self.repeat_timer, args=(self.reset_and_reset_race, 0.09))
self.thread_reset = threading.Thread(
target=self.repeat_timer, args=(self.reset, 0.05)
)
self.thread_reset_race = threading.Thread(
target=self.repeat_timer, args=(self.reset_race, 0.03)
)
self.thread_reset_and_reset_race = threading.Thread(
target=self.repeat_timer, args=(self.reset_and_reset_race, 0.09)
)
self.is_thread_active = False
def repeat_timer(self, callback, period):
@ -19,43 +26,54 @@ class ReproduceResetRaceCondition():
callback()
time.sleep(period)
def load_level(self, level_name, sleep_sec = 2.0):
def load_level(self, level_name, sleep_sec=2.0):
self.level_name = level_name
self.airsim_client.simLoadLevel(self.level_name)
self.airsim_client.confirmConnection() # failsafe
time.sleep(sleep_sec) # let the environment load completely
self.airsim_client.confirmConnection() # failsafe
time.sleep(sleep_sec) # let the environment load completely
def reset(self):
print(time.time(), 'called reset')
print(time.time(), "called reset")
self.airsim_client.reset()
def reset_race(self):
print(time.time(), 'called simResetRace')
print(time.time(), "called simResetRace")
self.airsim_client_2.simResetRace()
def reset_and_reset_race(self):
print(time.time(), 'called reset, followed by simResetRace')
print(time.time(), "called reset, followed by simResetRace")
self.airsim_client_3.reset()
self.airsim_client_3.simResetRace()
def start_race(self, tier):
print(time.time(), 'called start race')
print(time.time(), "called start race")
self.airsim_client.simStartRace(tier)
def initialize_drone(self):
self.airsim_client.enableApiControl(vehicle_name=self.drone_name)
self.airsim_client.arm(vehicle_name=self.drone_name)
# set default values for trajectory tracker gains
traj_tracker_gains = airsimdroneracinglab.TrajectoryTrackerGains(kp_cross_track = 5.0, kd_cross_track = 0.0,
kp_vel_cross_track = 3.0, kd_vel_cross_track = 0.0,
kp_along_track = 0.4, kd_along_track = 0.0,
kp_vel_along_track = 0.04, kd_vel_along_track = 0.0,
kp_z_track = 2.0, kd_z_track = 0.0,
kp_vel_z = 0.4, kd_vel_z = 0.0,
kp_yaw = 3.0, kd_yaw = 0.1)
# set default values for trajectory tracker gains
traj_tracker_gains = airsimdroneracinglab.TrajectoryTrackerGains(
kp_cross_track=5.0,
kd_cross_track=0.0,
kp_vel_cross_track=3.0,
kd_vel_cross_track=0.0,
kp_along_track=0.4,
kd_along_track=0.0,
kp_vel_along_track=0.04,
kd_vel_along_track=0.0,
kp_z_track=2.0,
kd_z_track=0.0,
kp_vel_z=0.4,
kd_vel_z=0.0,
kp_yaw=3.0,
kd_yaw=0.1,
)
self.airsim_client.setTrajectoryTrackerGains(traj_tracker_gains, vehicle_name=self.drone_name)
self.airsim_client.setTrajectoryTrackerGains(
traj_tracker_gains, vehicle_name=self.drone_name
)
time.sleep(0.2)
def start_threads(self):
@ -74,9 +92,10 @@ class ReproduceResetRaceCondition():
self.thread_reset_and_reset_race.join()
print("Stopped threads.")
if __name__ == "__main__":
reproducer = ReproduceResetRaceCondition('drone_1')
reproducer.load_level('Qualifier_Tier_1')
reproducer = ReproduceResetRaceCondition("drone_1")
reproducer.load_level("Qualifier_Tier_1")
reproducer.initialize_drone()
reproducer.start_race(3)
time.sleep(5)