Exemple #1
0
    def __init__(self, instance_id=0, cv_mode=False, is_real=False):
        self.instance_id = instance_id
        self.env_id = None
        self.params = get_current_parameters()["PomdpInterface"]
        step_interval = self.params["step_interval"]
        flight_height = self.params["flight_height"]
        self.max_horizon = self.params["max_horizon"]
        self.scale = self.params["scale"]
        self.is_real = is_real

        self.drone = drone_controller_factory(simulator=not is_real)(instance=instance_id, flight_height=flight_height)
        rate = step_interval / self.drone.get_real_time_rate()

        self.rate = Rate(rate)
        print("Adjusted rate: " + str(rate), "Step interval: ", step_interval)

        self.segment_path = None

        self.rewards = []
        self.reward_weights = []

        self.instruction_set = None
        self.current_segment_ordinal = None
        self.current_segment_idx = None
        self.cv_mode = cv_mode

        self.seg_start = 0
        self.seg_end = 0
        self.stepcount = 0

        self.instruction_override = None
Exemple #2
0
    def __init__(self, instance=0, flight_height=100.0):
        self.instance = instance
        self.port = PORTS[instance]
        self.clock_speed = self._read_clock_speed()
        self.control_interval = 0.5
        self.flight_height = flight_height  # Flight height is in config units, as with everything
        self.units = UnrealUnits()
        print("DroneController Initialize")
        self.rate = Rate(0.1 / self.clock_speed)

        self.samples = []

        killAirSim()
        self._write_airsim_settings()
        startAirSim(self, instance, self.port)
Exemple #3
0
    def __init__(self, instance=0, flight_height=100.0):
        super(DroneController, self).__init__()
        self.instance = instance
        self.port = PORTS[instance]
        self.clock_speed = self._read_clock_speed()
        self.control_interval = 5.0
        self.flight_height = -flight_height

        print("DroneController Initialize")
        self.rate = Rate(0.1 / self.clock_speed)
        self.height_offset = P.get_current_parameters()["DroneController"].get("start_height_offset")

        self.samples = []

        killAirSim()
        self._write_airsim_settings()
        startAirSim(self, instance, self.port)
Exemple #4
0
    def __init__(self, instance_id=0, cv_mode=False):
        self.instance_id = instance_id
        self.env_id = None
        self.params = get_current_parameters()["PomdpInterface"]
        step_interval = self.params["step_interval"]
        flight_height = self.params["flight_height"]
        self.scale = self.params["scale"]
        self.drone = DroneController(instance=instance_id,
                                     flight_height=flight_height)

        rate = step_interval / self.drone.clock_speed
        self.rate = Rate(rate)
        print("Adjusted rate: " + str(rate), "Step interval: ", step_interval)
        self.path = None
        self.reward = None
        self.reward_shaping = None
        self.instruction_set = None
        self.current_segment = None
        self.done = None
        self.cv_mode = cv_mode

        self.seg_start = 0
        self.seg_end = 0
Exemple #5
0
        self.mon = MonitorSuper()
        self.thread = threading.Thread(target=self.run, args=())
        self.thread.daemon = True
        self.thread.start()

    def run(self):
        self.mon.run()

    def get_command(self):
        return self.mon.current_vel


initialize_experiment("nl_datacollect_cage")

teleoper = KeyTeleop()
rate = Rate(0.1)

env = PomdpInterface()

train_instructions, dev_instructions, test_instructions, _ = get_all_instructions(
)

count = 0
stuck_count = 0


def show_depth(image):
    grayscale = np.mean(image[:, :, 0:3], axis=2)
    depth = image[:, :, 3]
    comb = np.stack([grayscale, grayscale, depth], axis=2)
    comb -= comb.min()
Exemple #6
0
def interactive_demo():

    P.initialize_experiment()
    InteractAPI.launch_ui()

    rate = Rate(0.1)

    env = PomdpInterface(
        is_real=get_current_parameters()["Setup"]["real_drone"])
    train_instructions, dev_instructions, test_instructions, corpus = get_all_instructions(
    )
    all_instr = {
        **train_instructions,
        **dev_instructions,
        **train_instructions
    }
    token2term, word2token = get_word_to_token_map(corpus)

    # Run on dev set
    interact_instructions = dev_instructions

    env_range_start = get_current_parameters()["Setup"].get(
        "env_range_start", 0)
    env_range_end = get_current_parameters()["Setup"].get(
        "env_range_end", 10e10)
    interact_instructions = {
        k: v
        for k, v in interact_instructions.items()
        if env_range_start < k < env_range_end
    }

    count = 0
    stuck_count = 0

    model, _ = load_model(get_current_parameters()["Setup"]["model"])

    InteractAPI.write_empty_instruction()
    InteractAPI.write_real_instruction("None")
    instruction_str = InteractAPI.read_instruction_file()
    print("Initial instruction: ", instruction_str)

    for instruction_sets in interact_instructions.values():
        for set_idx, instruction_set in enumerate(instruction_sets):
            env_id = instruction_set['env']
            env.set_environment(env_id, instruction_set["instructions"])

            presenter = Presenter()
            cumulative_reward = 0
            for seg_idx in range(len(instruction_set["instructions"])):

                print(f"RUNNING ENV {env_id} SEG {seg_idx}")

                real_instruction_str = instruction_set["instructions"][
                    seg_idx]["instruction"]
                InteractAPI.write_real_instruction(real_instruction_str)
                valid_segment = env.set_current_segment(seg_idx)
                if not valid_segment:
                    continue
                state = env.reset(seg_idx)

                keep_going = True
                while keep_going:
                    InteractAPI.write_real_instruction(real_instruction_str)

                    while True:
                        cv2.waitKey(200)
                        instruction = InteractAPI.read_instruction_file()
                        if instruction == "CMD: Next":
                            print("Advancing")
                            keep_going = False
                            InteractAPI.write_empty_instruction()
                            break
                        elif instruction == "CMD: Reset":
                            print("Resetting")
                            env.reset(seg_idx)
                            InteractAPI.write_empty_instruction()
                        elif len(instruction.split(" ")) > 1:
                            instruction_str = instruction
                            break

                    if not keep_going:
                        continue

                    env.override_instruction(instruction_str)
                    tok_instruction = tokenize_instruction(
                        instruction_str, word2token)

                    state = env.reset(seg_idx)
                    print("Executing: f{instruction_str}")
                    while True:
                        rate.sleep()
                        action, internals = model.get_action(
                            state, tok_instruction)

                        state, reward, done, expired, oob = env.step(action)
                        cumulative_reward += reward
                        presenter.show_sample(state, action, reward,
                                              cumulative_reward,
                                              instruction_str)
                        #show_depth(state.image)
                        if done:
                            break
                    InteractAPI.write_empty_instruction()
                    print("Segment finished!")
        print("Env finished!")
import os

import scipy.misc

from drones.airsim_interface.rate import Rate
from env_config.definitions.landmarks import LANDMARK_RADII
from data_io.paths import get_landmark_images_dir
from pomdp.pomdp_interface import PomdpInterface
from visualization import Presenter
"""
This script is used to take pictures of various landmarks
"""
from parameters import parameter_server as P
P.initialize_experiment("nl_datacollect")

rate = Rate(0.1)

IMAGES_PER_LANDMARK_TRAIN = 1000
IMAGES_PER_LANDMARK_TEST = 200

env = PomdpInterface()

count = 0

presenter = Presenter()


def save_landmark_img(state, landmark_name, i, eval):
    data_dir = get_landmark_images_dir(landmark_name, eval)
    os.makedirs(data_dir, exist_ok=True)
    full_path = os.path.join(data_dir, landmark_name + "_" + str(i) + ".jpg")
Exemple #8
0
class PomdpInterface:
    """Unreal must be running before this is called for now..."""
    def __init__(self, instance_id=0, cv_mode=False):
        self.instance_id = instance_id
        self.env_id = None
        self.params = get_current_parameters()["PomdpInterface"]
        step_interval = self.params["step_interval"]
        flight_height = self.params["flight_height"]
        self.scale = self.params["scale"]
        self.drone = DroneController(instance=instance_id,
                                     flight_height=flight_height)

        rate = step_interval / self.drone.clock_speed
        self.rate = Rate(rate)
        print("Adjusted rate: " + str(rate), "Step interval: ", step_interval)
        self.path = None
        self.reward = None
        self.reward_shaping = None
        self.instruction_set = None
        self.current_segment = None
        self.done = None
        self.cv_mode = cv_mode

        self.seg_start = 0
        self.seg_end = 0

    def _get_reward(self, state, drone_action):
        # If we don't have an instruction set, we can't provide a reward
        if self.instruction_set is None:
            return 0, False

        # If the agent already executed all the actions, return 0 error and done thereafter
        if self.done:
            return 0, self.done

        # Obtain the reward from the reward function
        reward, seg_complete = self.reward.get_reward(state, drone_action)
        reward += self.reward_shaping.get_reward(state, drone_action)

        # If the segment was completed, tell the reward function that we will be following the next segment
        if seg_complete:
            self.current_segment += 1
            if self.current_segment < len(self.instruction_set):
                self.seg_start = self.seg_end
                self.seg_end = self.instruction_set[
                    self.current_segment]["end_idx"]
                self.reward.set_current_segment(self.seg_start, self.seg_end)
            # Unless this was the last segment, in which case we set this pomdp as done and return accordingly
            else:
                self.done = True
        return reward, self.done

    def set_environment(self, env_id, instruction_set=None, fast=False):
        """
        Switch the simulation to env_id. Causes the environment configuration from
        configs/configs/random_config_<env_id>.json to be loaded and landmarks arranged in the simulator
        :param env_id: integer ID
        :param instruction_set: Instruction set to follow for displaying instructions
        :param fast: Set to True to skip a delay at a risk of environment not loading before subsequent function calls
        :return:
        """
        self.env_id = env_id

        self.drone.set_current_env_id(env_id, self.instance_id)
        self.drone.reset_environment()

        # This is necessary to allow the new frame to be rendered with the new pomdp, so that the drone doesn't
        # accidentally see the old pomdp at the start
        if not fast:
            time.sleep(0.1)

        self.current_segment = 0
        self.seg_start = 0
        self.seg_end = 0

        self.path = load_path(env_id)
        if self.path is not None:
            self.reward = FollowPathReward(self.path)
            self.reward_shaping = ImitationReward(self.path)
            self.seg_end = len(self.path) - 1

        self.instruction_set = instruction_set

        if instruction_set is not None:
            self.reward.set_current_segment(self.seg_start, self.seg_end)
            if len(instruction_set) == 0:
                print("OOOPS! Instruction set of length 0!" + str(env_id))
                return

            self.seg_end = instruction_set[self.current_segment]["end_idx"]

            if self.seg_end >= len(self.path):
                print("OOOPS! For env " + str(env_id) + " segment " +
                      str(self.current_segment) + " end oob: " +
                      str(self.seg_end))
                self.seg_end = len(self.path) - 1

    def reset(self, seg_idx=0, landmark_pos=None, random_yaw=0):
        self.rate.reset()
        self.drone.reset_environment()
        start_pos, start_angle = self.get_start_pos(seg_idx, landmark_pos)

        if self.cv_mode:
            start_rpy = start_angle
            self.drone.teleport_3d(start_pos, start_rpy, pos_in_airsim=False)

        else:
            start_yaw = start_angle
            if self.params["randomize_init_pos"]:
                yaw_offset = float(
                    np.random.normal(0, self.params["init_yaw_variance"], 1))
                pos_offset = np.random.normal(0,
                                              self.params["init_pos_variance"],
                                              2)
                print("offset:", pos_offset, yaw_offset)

                start_pos = np.asarray(start_pos) + pos_offset
                start_yaw = start_yaw + yaw_offset
            self.drone.teleport_to(start_pos, start_yaw)

        self.rate.sleep(quiet=True)
        time.sleep(0.2)
        drone_state, image = self.drone.get_state()
        self.done = False

        return DroneState(image, drone_state)

    def get_start_pos(self, seg_idx=0, landmark_pos=None):

        # If we are not in CV mode, then we have a path to follow and track reward for following it closely
        if not self.cv_mode:
            if self.instruction_set:
                start_pos = self.instruction_set[seg_idx]["start_pos"]
                start_angle = self.instruction_set[seg_idx]["start_yaw"]
            else:
                start_pos = [0, 0, 0]
                start_angle = 0

        # If we are in CV mode, there is no path to be followed. Instead we are collecting images of landmarks.
        # Initialize the drone to face the position provided. TODO: Generalize this to other CV uses
        else:
            drone_angle = random.uniform(0, 2 * math.pi)
            drone_dist_mult = random.uniform(0, 1)
            drone_dist = 60 + drone_dist_mult * 300
            drone_pos_dir = np.asarray(
                [math.cos(drone_angle),
                 math.sin(drone_angle)])

            start_pos = landmark_pos + drone_pos_dir * drone_dist
            start_height = random.uniform(-1.5, -2.5)
            start_pos = [start_pos[0], start_pos[1], start_height]

            drone_dir = -drone_pos_dir
            start_yaw = vec_to_yaw(drone_dir)
            start_roll = 0
            start_pitch = 0
            start_angle = [start_roll, start_pitch, start_yaw]

        return start_pos, start_angle

    def reset_to_random_cv_env(self, landmark_name=None):
        config, pos_x, pos_z = make_config_with_landmark(landmark_name)
        self.drone.set_current_env_from_config(config,
                                               instance_id=self.instance_id)
        time.sleep(0.2)
        landmark_pos_2d = np.asarray([pos_x, pos_z])
        self.cv_mode = True
        return self.reset(landmark_pos=landmark_pos_2d)

    def snap_birdseye(self, fast=False, small_env=False):
        self.drone.reset_environment()
        # TODO: Check environment dimensions
        if small_env:
            pos_birdseye_as = [2.25, 2.35, -3.92]
            rpy_birdseye_as = [-1.3089, 0, 0]  # For 15 deg camera
        else:
            pos_birdseye_as = [15, 15, -25]
            rpy_birdseye_as = [-1.3089, 0, 0]  # For 15 deg camera
        self.drone.teleport_3d(pos_birdseye_as, rpy_birdseye_as, fast=fast)
        _, image = self.drone.get_state(depth=False)
        return image

    def snap_cv(self, pos, quat):
        self.drone.reset_environment()
        pos_birdseye_as = pos
        rpy_birdseye_as = euler.quat2euler(quat)
        self.drone.teleport_3d(pos_birdseye_as,
                               rpy_birdseye_as,
                               pos_in_airsim=True,
                               fast=True)
        time.sleep(0.3)
        self.drone.teleport_3d(pos_birdseye_as,
                               rpy_birdseye_as,
                               pos_in_airsim=True,
                               fast=True)
        time.sleep(0.3)
        _, image = self.drone.get_state(depth=False)
        return image

    def get_current_nl_command(self):
        if self.current_segment < len(self.instruction_set):
            return self.instruction_set[self.current_segment]["instruction"]
        return "FINISHED!"

    def step(self, action):
        """
        Takes an action, executes it in the simulation and returns the state, reward and done indicator
        :param action: array of length 4: [forward velocity, left velocity, yaw rate, stop probability]
        :return: DroneState object, reward (float), done (bool)
        """
        #Action
        drone_action = action[0:3]
        drone_stop = action[3]
        #print("Action: ", action)
        if drone_stop > 0.99:
            drone_action = np.array([0, 0, 0])

        self.drone.send_local_velocity_command(
            unnormalize_action(drone_action))
        self.rate.sleep(quiet=True)
        drone_state, image = self.drone.get_state()
        state = DroneState(image, drone_state)

        reward, done = self._get_reward(state, action)

        return state, reward, done
Exemple #9
0
def automatic_demo():

    P.initialize_experiment()
    instruction_display = InstructionDisplay()

    rate = Rate(0.1)

    env = PomdpInterface(
        is_real=get_current_parameters()["Setup"]["real_drone"])
    train_instructions, dev_instructions, test_instructions, corpus = get_all_instructions(
    )
    all_instr = {
        **train_instructions,
        **dev_instructions,
        **train_instructions
    }
    token2term, word2token = get_word_to_token_map(corpus)

    # Run on dev set
    interact_instructions = dev_instructions

    env_range_start = get_current_parameters()["Setup"].get(
        "env_range_start", 0)
    env_range_end = get_current_parameters()["Setup"].get(
        "env_range_end", 10e10)
    interact_instructions = {
        k: v
        for k, v in interact_instructions.items()
        if env_range_start < k < env_range_end
    }

    model, _ = load_model(get_current_parameters()["Setup"]["model"])

    # Loop over the select few examples
    while True:

        for instruction_sets in interact_instructions.values():
            for set_idx, instruction_set in enumerate(instruction_sets):
                env_id = instruction_set['env']
                found_example = None
                for example in examples:
                    if example[0] == env_id:
                        found_example = example
                if found_example is None:
                    continue
                env.set_environment(env_id, instruction_set["instructions"])

                presenter = Presenter()
                cumulative_reward = 0
                for seg_idx in range(len(instruction_set["instructions"])):
                    if seg_idx != found_example[2]:
                        continue

                    print(f"RUNNING ENV {env_id} SEG {seg_idx}")

                    real_instruction_str = instruction_set["instructions"][
                        seg_idx]["instruction"]
                    instruction_display.show_instruction(real_instruction_str)
                    valid_segment = env.set_current_segment(seg_idx)
                    if not valid_segment:
                        continue
                    state = env.reset(seg_idx)

                    for i in range(START_PAUSE):
                        instruction_display.tick()
                        time.sleep(1)

                        tok_instruction = tokenize_instruction(
                            real_instruction_str, word2token)

                    state = env.reset(seg_idx)
                    print("Executing: f{instruction_str}")
                    while True:
                        instruction_display.tick()
                        rate.sleep()
                        action, internals = model.get_action(
                            state, tok_instruction)
                        state, reward, done, expired, oob = env.step(action)
                        cumulative_reward += reward
                        #presenter.show_sample(state, action, reward, cumulative_reward, real_instruction_str)
                        #show_depth(state.image)
                        if done:
                            break

                    for i in range(END_PAUSE):
                        instruction_display.tick()
                        time.sleep(1)
                        print("Segment finished!")
                    instruction_display.show_instruction("...")

            print("Env finished!")
Exemple #10
0
class PomdpInterface:

    class EnvException(Exception):
        def __init__(self, message):
            super(PomdpInterface.EnvException, self).__init__(message)

    """Unreal must be running before this is called for now..."""
    def __init__(self, instance_id=0, cv_mode=False, is_real=False):
        self.instance_id = instance_id
        self.env_id = None
        self.params = get_current_parameters()["PomdpInterface"]
        step_interval = self.params["step_interval"]
        flight_height = self.params["flight_height"]
        self.max_horizon = self.params["max_horizon"]
        self.scale = self.params["scale"]
        self.is_real = is_real

        self.drone = drone_controller_factory(simulator=not is_real)(instance=instance_id, flight_height=flight_height)
        rate = step_interval / self.drone.get_real_time_rate()

        self.rate = Rate(rate)
        print("Adjusted rate: " + str(rate), "Step interval: ", step_interval)

        self.segment_path = None

        self.rewards = []
        self.reward_weights = []

        self.instruction_set = None
        self.current_segment_ordinal = None
        self.current_segment_idx = None
        self.cv_mode = cv_mode

        self.seg_start = 0
        self.seg_end = 0
        self.stepcount = 0

        self.instruction_override = None

    def _get_reward(self, state, drone_action, done_now):
        # If we don't have an instruction set, we can't provide a reward
        if self.instruction_set is None:
            raise ValueError("No instruction set: Can't provide a reward.")

        # Obtain the reward from the reward function
        rewards = [w * r(state, drone_action, done_now) for r, w in zip(self.rewards, self.reward_weights)]
        total_reward = sum(rewards)

        return total_reward

    def _is_out_of_bounds(self, state):
        curr_pos = state.get_pos_2d()

        if len(self.segment_path) == 0:
            print("OH NO OH NO OH NO!")
            return True

        distances = np.asarray([np.linalg.norm(p - curr_pos) for p in self.segment_path])
        minidx = np.argmin(distances)
        mindist = distances[minidx]
        #print(f"Idx: {minidx} / {len(self.segment_path)}. Dst to path: {mindist}")
        #done = (mindist > END_DISTANCE and minidx >= len(self.segment_path) - 1) or mindist > PATH_MAX_DISTANCE
        done = mindist > PATH_MAX_DISTANCE
        return done

    def land(self):
        """
        If using the real drone, this causes it to land and disarm
        :return:
        """
        try:
            self.drone.land()
        except RolloutException as e:
            raise PomdpInterface.EnvException("Retry rollout")

    def set_environment(self, env_id, instruction_set=None, fast=False):
        """
        Switch the simulation to env_id. Causes the environment configuration from
        configs/configs/random_config_<env_id>.json to be loaded and landmarks arranged in the simulator
        :param env_id: integer ID
        :param instruction_set: Instruction set to follow for displaying instructions
        :param fast: Set to True to skip a delay at a risk of environment not loading before subsequent function calls
        :return:
        """
        self.env_id = env_id

        try:
            self.drone.set_current_env_id(env_id, self.instance_id)
            self.drone.reset_environment()
        except RolloutException as e:
            raise PomdpInterface.EnvException("Retry rollout")

        # This is necessary to allow the new frame to be rendered with the new pomdp, so that the drone doesn't
        # accidentally see the old pomdp at the start
        if not fast:
            time.sleep(0.1)

        self.instruction_set = instruction_set
        self.stepcount = 0
        self.instruction_override = None

    def set_current_segment(self, seg_idx):
        self.current_segment_ordinal = None
        for i, seg in enumerate(self.instruction_set):
            if seg["seg_idx"] == seg_idx:
                self.current_segment_ordinal = i
        assert self.current_segment_ordinal is not None, f"Requested segment {seg_idx} not found in provided instruction data"
        self.current_segment_idx = seg_idx

        try:
            self.drone.set_current_seg_idx(seg_idx, self.instance_id)
        except RolloutException as e:
            raise PomdpInterface.EnvException("Retry rollout")

        end_idx = self.instruction_set[self.current_segment_ordinal]["end_idx"]
        start_idx = self.instruction_set[self.current_segment_ordinal]["start_idx"]
        full_path = load_and_convert_path(self.env_id)
        self.segment_path = full_path[start_idx:end_idx]
        self.instruction_override = None

        self.stepcount = 0
        if start_idx == end_idx:
            return False

        if self.segment_path is not None:
            self.rewards = [FollowPathFieldReward(self.segment_path), StopCorrectlyReward(self.segment_path)]
            self.reward_weights = [1.0, 1.0]
        return True

    def reset(self, seg_idx=0, landmark_pos=None, random_yaw=0):
        try:
            self.rate.reset()
            self.drone.reset_environment()
            self.stepcount = 0
            start_pos, start_angle = self.get_start_pos(seg_idx, landmark_pos)

            if self.cv_mode:
                start_rpy = start_angle
                self.drone.teleport_3d(start_pos, start_rpy, pos_in_airsim=False)

            else:
                start_yaw = start_angle
                if self.params["randomize_init_pos"]:
                    np.random.seed()
                    yaw_offset = float(np.random.normal(0, self.params["init_yaw_variance"], 1))
                    pos_offset = np.random.normal(0, self.params["init_pos_variance"], 2)
                    #print("offset:", pos_offset, yaw_offset)

                    start_pos = np.asarray(start_pos) + pos_offset
                    start_yaw = start_yaw + yaw_offset
                self.drone.teleport_to(start_pos, start_yaw)

            if self.params.get("voice"):
                cmd = self.get_current_nl_command()
                say(cmd)

            self.drone.rollout_begin(self.get_current_nl_command())
            self.rate.sleep(quiet=True)
            #time.sleep(0.2)
            drone_state, image = self.drone.get_state()

            return DroneState(image, drone_state)
        except RolloutException as e:
            raise PomdpInterface.EnvException("Retry rollout")

    def get_end_pos(self, seg_idx=0, landmark_pos=None):

        seg_ordinal = self.seg_idx_to_ordinal(seg_idx)
        if not self.cv_mode:
            if self.instruction_set:
                end_pos = convert_pos_from_config(self.instruction_set[seg_ordinal]["end_pos"])
                end_angle = convert_yaw_from_config(self.instruction_set[seg_ordinal]["end_yaw"])
            else:
                end_pos = [0, 0, 0]
                end_angle = 0
        return end_pos, end_angle

    def seg_idx_to_ordinal(self, seg_idx):
        for i, instr in enumerate(self.instruction_set):
            if instr["seg_idx"] == seg_idx:
                return i

    def get_start_pos(self, seg_idx=0, landmark_pos=None):

        seg_ordinal = self.seg_idx_to_ordinal(seg_idx)
        # If we are not in CV mode, then we have a path to follow and track reward for following it closely
        if not self.cv_mode:
            if self.instruction_set:
                start_pos = convert_pos_from_config(self.instruction_set[seg_ordinal]["start_pos"])
                start_angle = convert_yaw_from_config(self.instruction_set[seg_ordinal]["start_yaw"])
            else:
                start_pos = [0, 0, 0]
                start_angle = 0

        # If we are in CV mode, there is no path to be followed. Instead we are collecting images of landmarks.
        # Initialize the drone to face the position provided. TODO: Generalize this to other CV uses
        else:
            drone_angle = random.uniform(0, 2 * math.pi)
            drone_dist_mult = random.uniform(0, 1)
            drone_dist = 60 + drone_dist_mult * 300
            drone_pos_dir = np.asarray([math.cos(drone_angle), math.sin(drone_angle)])

            start_pos = landmark_pos + drone_pos_dir * drone_dist
            start_height = random.uniform(-1.5, -2.5)
            start_pos = [start_pos[0], start_pos[1], start_height]

            drone_dir = -drone_pos_dir
            start_yaw = vec_to_yaw(drone_dir)
            start_roll = 0
            start_pitch = 0
            start_angle = [start_roll, start_pitch, start_yaw]
        return start_pos, start_angle

    def get_current_nl_command(self):
        if self.instruction_override:
            return self.instruction_override
        if self.current_segment_ordinal < len(self.instruction_set):
            return self.instruction_set[self.current_segment_ordinal]["instruction"]
        return "FINISHED!"

    def override_instruction(self, instr_str):
        self.instruction_override = instr_str

    def act(self, action):
        # Action
        action = deepcopy(action)
        drone_action = action[0:3]
        # print("Action: ", action)

        raw_action = unnormalize_action(drone_action)
        # print(drone_action, raw_action)
        try:
            self.drone.send_local_velocity_command(raw_action)
        except RolloutException as e:
            raise PomdpInterface.EnvException("Retry rollout")

    def await_env(self):
        self.rate.sleep(quiet=True)

    def observe(self, prev_action):
        try:
            drone_state, image = self.drone.get_state()
            state = DroneState(image, drone_state)
            out_of_bounds = self._is_out_of_bounds(state)
            reward = self._get_reward(state, prev_action, out_of_bounds)

            self.stepcount += 1
            expired = self.stepcount > self.max_horizon

            drone_stop = prev_action[3]
            done = out_of_bounds or drone_stop > 0.5 or expired

            # Actually stop the drone (execute stop-action)
            if done:
                self.drone.send_local_velocity_command([0, 0, 0, 1])
                self.drone.rollout_end()

            # TODO: Respect the done
            return state, reward, done, expired, out_of_bounds
        except RolloutException as e:
            raise PomdpInterface.EnvException("Retry rollout")

    def step(self, action):
        """
        Takes an action, executes it in the simulation and returns the state, reward and done indicator
        :param action: array of length 4: [forward velocity, left velocity, yaw rate, stop probability]
        :return: DroneState object, reward (float), done (bool)
        """
        self.act(action)
        self.await_env()
        return self.observe(action)



    # -----------------------------------------------------------------------------------------------------------------
    # CRAP:

    def reset_to_random_cv_env(self, landmark_name=None):
        config, pos_x, pos_z = make_config_with_landmark(landmark_name)
        self.drone.set_current_env_from_config(config, instance_id=self.instance_id)
        time.sleep(0.2)
        landmark_pos_2d = np.asarray([pos_x, pos_z])
        self.cv_mode = True
        return self.reset(landmark_pos=landmark_pos_2d)

    def snap_birdseye(self, fast=False, small_env=False):
        self.drone.reset_environment()
        # TODO: Check environment dimensions
        if small_env:
            pos_birdseye_as = [2.25, 2.35, -4.92*2 - 0.06 - 0.12]
            rpy_birdseye_as = [-1.3089, 0, 0]   # For 15 deg camera
        else:
            pos_birdseye_as = [15, 15, -25]
            rpy_birdseye_as = [-1.3089, 0, 0]   # For 15 deg camera
        self.drone.teleport_3d(pos_birdseye_as, rpy_birdseye_as, fast=fast)
        _, image = self.drone.get_state(depth=False)
        return image

    def snap_cv(self, pos, quat):
        self.drone.reset_environment()
        pos_birdseye_as = pos
        rpy_birdseye_as = euler.quat2euler(quat)
        self.drone.teleport_3d(pos_birdseye_as, rpy_birdseye_as, pos_in_airsim=True, fast=True)
        time.sleep(0.3)
        self.drone.teleport_3d(pos_birdseye_as, rpy_birdseye_as, pos_in_airsim=True, fast=True)
        time.sleep(0.3)
        _, image = self.drone.get_state(depth=False)
        return image
Exemple #11
0
class DroneController(DroneControllerBase):
    def __init__(self, instance=0, flight_height=100.0):
        super(DroneController, self).__init__()
        self.instance = instance
        self.port = PORTS[instance]
        self.clock_speed = self._read_clock_speed()
        self.control_interval = 5.0
        self.flight_height = -flight_height

        print("DroneController Initialize")
        self.rate = Rate(0.1 / self.clock_speed)
        self.height_offset = P.get_current_parameters()["DroneController"].get("start_height_offset")

        self.samples = []

        killAirSim()
        self._write_airsim_settings()
        startAirSim(self, instance, self.port)

    def _get_config(self, name, i=None, instance_id=None):
        config = load_env_config(id)
        return config

    def _set_config(self, json_data, subfolder, name, i=None, instance_id=None):
        folder = paths.get_current_config_folder(i, instance_id)
        id = "" if i is None else "_" + str(i)
        path = os.path.join(paths.get_sim_config_dir(), folder, subfolder, name + id + ".json")

        if not os.path.isdir(os.path.dirname(path)):
            try:
                os.makedirs(os.path.dirname(path))
            except Exception:
                pass

        if os.path.isfile(path):
            os.remove(path)

        # print("Dumping config in: " + path)
        with open(path, 'w') as fp:
            json.dump(json_data, fp)

        subprocess.check_call(["touch", path])

    def _load_drone_config(self, i, instance_id=None):
        conf_json = load_env_config(i)
        self._set_config(conf_json, "", "random_config", i=None, instance_id=instance_id)

    def _start_call(self):
        try:
            self.client.enableApiControl(True)
            self.client.armDisarm(True)
        except Exception as e:
            import traceback
            from utils.colors import print_error
            print_error("Error encountered during policy rollout!")
            print_error(e)
            print_error(traceback.format_exc())

            startAirSim(self, self.instance, self.port)

            raise RolloutException("Exception encountered during start_call. Rollout should be re-tried")

    def _start(self):
        self.client = MultirotorClient('127.0.0.1', self.port)
        self.client.confirmConnection()
        self._start_call()

        # got to initial height
        pos_as = self.client.getPosition()
        pos_as = [pos_as.x_val, pos_as.y_val, pos_as.z_val]
        pos_as[2] = self.flight_height - self.height_offset
        #pos = self.units.pos3d_from_as(pos_as)
        #pos[2] = self.units.height_to_as(self.flight_height)
        print ("Telporting to initial position in cfg: ", pos_as)
        self.teleport_3d(pos_as, [0, 0, 0])

    def _read_clock_speed(self):
        speed = 1.0
        if "ClockSpeed" in P.get_current_parameters()["AirSim"]:
            speed = P.get_current_parameters()["AirSim"]["ClockSpeed"]
        print("Read clock speed: " + str(speed))
        return speed

    def _write_airsim_settings(self):
        airsim_settings = P.get_current_parameters()["AirSim"]
        airsim_settings_path = P.get_current_parameters()["Environment"]["airsim_settings_path"]
        airsim_settings_path = os.path.expanduser(airsim_settings_path)
        save_json(airsim_settings, airsim_settings_path)
        print("Wrote new AirSim settings to " + str(airsim_settings_path))

    """def _action_to_global(self, action):
        drone_yaw = self.get_yaw()
        action_global = np.zeros(3)
        # TODO: Add action[1]
        action_global[0] = action[0] * math.cos(drone_yaw)
        action_global[1] = action[0] * math.sin(drone_yaw)
        action_global[2] = action[2]
        return action_global
    """

    def _try_teleport_to(self, position, yaw, pitch=None, roll=None):
        #pos_as = self.units.pos2d_to_as(position[:2])
        #yaw_as = self.units.yaw_to_as(yaw)
        #tgt_h = self.units.height_to_as(self.flight_height)

        pos_as = position[:2]
        yaw_as = yaw
        tgt_h = self.flight_height - self.height_offset

        tele_orientation = self.client.toQuaternion(0, 0, yaw_as)
        self.send_local_velocity_command([0, 0, 0])

        tele_pos = Vector3r()
        tele_pos.x_val = pos_as[0]
        tele_pos.y_val = pos_as[1]

        uphigh = True
        if uphigh:
            self.rate.sleep_n_intervals(3)
            pos1 = self.client.getPosition()
            current_z = pos1.z_val
            pos1.z_val = tgt_h - 50
            self.client.simSetPose(pos1, tele_orientation)
            self.rate.sleep_n_intervals(2)
            tele_pos.z_val = tgt_h - 50
            self.client.simSetPose(tele_pos, tele_orientation)
            self.rate.sleep_n_intervals(2)

        tele_pos.z_val = tgt_h
        self.client.simSetPose(tele_pos, tele_orientation)
        self.send_local_velocity_command([0, 0, 0])
        self.rate.sleep_n_intervals(10)
        #time.sleep(0.2)

    def _get_yaw(self):
        o = self.client.getOrientation()
        roll, pitch, yaw = euler.quat2euler([o.w_val, o.x_val, o.y_val, o.z_val])
        return yaw

    def get_real_time_rate(self):
        return self.clock_speed

    def send_local_velocity_command(self, cmd_vel):
        """
        :param cmd_vel: x in m/s and yaw rate in rad/s
        :return:
        """
        try:
            # Convert the drone reference frame command to a global command as understood by AirSim
            cmd_vel = self._action_to_global(cmd_vel)
            if len(cmd_vel) == 3:
                vel_x = cmd_vel[0]
                vel_y = cmd_vel[1]
                yaw_rate = cmd_vel[2] * 180 / 3.14
                yaw_mode = YawMode(is_rate=True, yaw_or_rate=yaw_rate)
                tgt_h = self.flight_height - self.height_offset
                self.client.moveByVelocityZ(vel_x, vel_y, tgt_h, self.control_interval, yaw_mode=yaw_mode)
        except msgpackrpc.error.TimeoutError as e:
            startAirSim(self, self.instance, self.port)
            raise RolloutException("Simulator Died")

    def teleport_to(self, position, yaw):
        #pos_as = self.units.pos2d_to_as(position[0:2])
        #tgt_h = self.units.height_to_as(self.flight_height)
        try:
            pos_as = position[0:2]
            tgt_h = self.flight_height - self.height_offset

            teleported = False
            for i in range(10):
                self._try_teleport_to(position, yaw)
                curr_pos = self.client.getPosition()
                curr_pos_np = np.asarray([curr_pos.x_val, curr_pos.y_val])

                if np.linalg.norm(pos_as - curr_pos_np) < 1.0 and math.fabs(tgt_h - curr_pos.z_val) < 1.0:
                    teleported = True
                    break
            if not teleported:
                print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
                print("Failed to teleport after 10 attempts!")
                print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
                self.client.moveToPosition(velocity=1.0, x=0.0, y=0.0, z=-10.0)
        except msgpackrpc.error.TimeoutError as e:
            startAirSim(self, self.instance, self.port)
            raise RolloutException("Simulator Died")


    def teleport_3d(self, position, rpy, fast=False):
        try:
            pos_as = position
            tele_rot = self.client.toQuaternion(rpy[0], rpy[1], rpy[2])
            self.send_local_velocity_command([0, 0, 0])
            self.rate.sleep_n_intervals(1)
            tele_pos = Vector3r()
            tele_pos.x_val = pos_as[0]
            tele_pos.y_val = pos_as[1]
            tele_pos.z_val = pos_as[2]

            self.client.simSetPose(tele_pos, tele_rot)
            self.send_local_velocity_command([0, 0, 0])
            if not fast:
                time.sleep(0.2)
        except msgpackrpc.error.TimeoutError as e:
            startAirSim(self, self.instance, self.port)
            raise RolloutException("Simulator Died")


    def get_state(self, depth=False, segmentation=False):
        try:
            # Get images
            request = [ImageRequest(0, AirSimImageType.Scene, False, False)]
            if depth:
                request.append(ImageRequest(0, AirSimImageType.DepthPlanner, True))
            if segmentation:
                request.append(ImageRequest(0, AirSimImageType.Segmentation, False, False))

            response = self.client.simGetImages(request)

            pos_dict = response[0].camera_position
            rot_dict = response[0].camera_orientation

            cam_pos = [pos_dict[b"x_val"], pos_dict[b"y_val"], pos_dict[b"z_val"] + self.height_offset]
            cam_rot = [rot_dict[b"w_val"], rot_dict[b"x_val"], rot_dict[b"y_val"], rot_dict[b"z_val"]]

            img_data = np.frombuffer(response[0].image_data_uint8, np.uint8)
            image_raw = img_data.reshape(response[0].height, response[0].width, 4)
            image_raw = image_raw[:, :, 0:3]

            concat = [image_raw]

            if depth:
                # Depth is cast to uint8, because otherwise it takes up a lot of space and we don't need such fine-grained
                # resolution
                depth_data = np.asarray(response[1].image_data_float)
                depth_raw = depth_data.reshape(response[1].height, response[1].width, 1)
                depth_raw = np.clip(depth_raw, 0, 254 / DEPTH_SCALE)
                depth_raw *= DEPTH_SCALE
                depth_raw = depth_raw.astype(np.uint8)
                concat.append(depth_raw)

            if segmentation:
                seg_data = np.frombuffer(response[2].image_data_uint8, np.uint8)
                seg_raw = seg_data.reshape(response[2].height, response[2].width, 4)
                concat.append(seg_raw)

            img_state = np.concatenate(concat, axis=2)

            # cam_pos, cam_rot are in ned coordinate frame in the simulator. They're left as-is
            # drones position gets converted to config coordinates instead

            # Get drone's physical location, orientation and velocity
            pos = self.client.getPosition()
            vel = self.client.getVelocity()
            o = self.client.getOrientation()

            # Convert to numpys
            drn_pos = np.asarray([pos.x_val, pos.y_val, pos.z_val + self.height_offset]) # xyz
            drn_vel = np.asarray([vel.x_val, vel.y_val, vel.z_val]) # xyz
            #drn_rot = np.asarray([o.w_val, o.x_val, o.y_val, o.z_val]) #wxyz
            drn_rot = np.asarray(euler.quat2euler([o.w_val, o.x_val, o.y_val, o.z_val]))

            # Turn it into a nice 9-D vector with euler angles
            """
            roll, pitch, yaw = self.units.euler_from_as(r_as, p_as, y_as)
            pos_3d_as = np.asarray([pos.x_val, pos.y_val, pos.z_val])
            pos_state = self.units.pos3d_from_as(pos_3d_as)
            vel_state = self.units.vel3d_from_as(np.asarray([vel.x_val, vel.y_val, vel.z_val]))
            ori_state = [roll, pitch, yaw]
            """

            drone_state = np.concatenate((drn_pos, drn_rot, drn_vel, cam_pos, cam_rot), axis=0)

            return drone_state, img_state
        except msgpackrpc.error.TimeoutError as e:
            startAirSim(self, self.instance, self.port)
            raise RolloutException("Simulator Died")

    def set_current_env_from_config(self, config, instance_id=None):
        """
        Store the provided dict representation of a random_config.json into the
        correct folder for instance_id simulator instance to read it when resetting it's pomdp.
        :param config: Random pomdp configuration to store
        :param instance_id: Simulator instance for which to store it.
        """
        try:
            self._set_config(config, "", "random_config", instance_id=instance_id)
        except msgpackrpc.error.TimeoutError as e:
            startAirSim(self, self.instance, self.port)
            raise RolloutException("Simulator Died")

    def set_current_env_id(self, env_id, instance_id=None):
        try:
            self._load_drone_config(env_id, instance_id)
            gc.collect()
        except msgpackrpc.error.TimeoutError as e:
            startAirSim(self, self.instance, self.port)
            raise RolloutException("Simulator Died")

    def set_current_seg_idx(self, seg_idx, instance_id=None):
        pass

    def rollout_begin(self, instruction):
        pass

    def rollout_end(self):
        pass

    def reset_environment(self):
        self._start_call()
        self.client.simResetEnv()
        self._start_call()

    def land(self):
        pass
Exemple #12
0
    def __init__(self):
        self.mon = MonitorSuper()
        self.thread = threading.Thread(target=self.run, args=())
        self.thread.daemon = True
        self.thread.start()

    def run(self):
        self.mon.run()

    def get_command(self):
        return self.mon.current_vel

initialize_experiment("nl_datacollect_cage")

teleoper = KeyTeleop()
rate = Rate(0.1)

env = PomdpInterface()

env_ids = get_available_env_ids()

count = 0
stuck_count = 0


def show_depth(image):
    grayscale = np.mean(image[:, :, 0:3], axis=2)
    depth = image[:, :, 3]
    comb = np.stack([grayscale, grayscale, depth], axis=2)
    comb -= comb.min()
    comb /= (comb.max() + 1e-9)
Exemple #13
0
class DroneController():
    def __init__(self, instance=0, flight_height=100.0):
        self.instance = instance
        self.port = PORTS[instance]
        self.clock_speed = self._read_clock_speed()
        self.control_interval = 0.5
        self.flight_height = flight_height  # Flight height is in config units, as with everything
        self.units = UnrealUnits()
        print("DroneController Initialize")
        self.rate = Rate(0.1 / self.clock_speed)

        self.samples = []

        killAirSim()
        self._write_airsim_settings()
        startAirSim(self, instance, self.port)

    def _get_config(self, name, i=None, instance_id=None):
        print("_get_config load_env_config")
        config = load_env_config(i)
        return config

    def _set_config(self,
                    json_data,
                    subfolder,
                    name,
                    i=None,
                    instance_id=None):
        folder = paths.get_current_config_folder(i, instance_id)
        id = "" if i is None else "_" + str(i)
        path = os.path.join(paths.get_sim_config_dir(), folder, subfolder,
                            name + id + ".json")
        print("_set_config folder:", folder)
        print("_set_config subfolder:", subfolder)
        print("_set_config path:", path)
        if not os.path.isdir(os.path.dirname(path)):
            try:
                os.makedirs(os.path.dirname(path))
            except Exception:
                pass

        if os.path.isfile(path):
            os.remove(path)

        # print("Dumping config in: " + path)
        with open(path, 'w') as fp:
            json.dump(json_data, fp)

        subprocess.check_call(["touch", path])

    def _load_drone_config(self, i, instance_id=None):
        print("_load_drone_config load_env_config")
        conf_json = load_env_config(i)
        self._set_config(conf_json,
                         "",
                         "random_config",
                         i=None,
                         instance_id=instance_id)

    def _start_call(self):
        try:
            self.client.enableApiControl(True)
            self.client.armDisarm(True)
        except Exception as e:
            import traceback
            from utils.colors import print_error
            print_error("Error encountered during policy rollout!")
            print_error(e)
            print_error(traceback.format_exc())

            startAirSim(self, self.instance, self.port)

            raise RolloutException(
                "Exception encountered during start_call. Rollout should be re-tried"
            )

    def _start(self):
        self.client = MultirotorClient('127.0.0.1', self.port)
        self.client.confirmConnection()
        self._start_call()

        # got to initial height
        pos_as = self.client.getPosition()
        pos_as = [pos_as.x_val, pos_as.y_val, pos_as.z_val]
        pos = self.units.pos3d_from_as(pos_as)
        pos[2] = self.units.height_to_as(self.flight_height)
        print("Telporting to initial position in cfg: ", pos)
        self.teleport_3d(pos, [0, 0, 0])

    def _read_clock_speed(self):
        speed = 1.0
        if "ClockSpeed" in P.get_current_parameters()["AirSim"]:
            speed = P.get_current_parameters()["AirSim"]["ClockSpeed"]
        print("Read clock speed: " + str(speed))
        return speed

    def _write_airsim_settings(self):
        airsim_settings = P.get_current_parameters()["AirSim"]
        airsim_settings_path = P.get_current_parameters(
        )["Environment"]["airsim_settings_path"]
        airsim_settings_path = os.path.expanduser(airsim_settings_path)
        save_json(airsim_settings, airsim_settings_path)
        print("Wrote new AirSim settings to " + str(airsim_settings_path))

    def _action_to_global(self, action):
        drone_yaw = self.get_yaw()
        action_global = np.zeros(3)
        # TODO: Add action[1]
        action_global[0] = action[0] * math.cos(drone_yaw)
        action_global[1] = action[0] * math.sin(drone_yaw)
        action_global[2] = action[2]
        return action_global

    def _try_teleport_to(self, position, yaw, pitch=None, roll=None):
        pos_as = self.units.pos2d_to_as(position[:2])
        yaw_as = self.units.yaw_to_as(yaw)
        tgt_h = self.units.height_to_as(self.flight_height)

        tele_orientation = self.client.toQuaternion(0, 0, yaw_as)
        self.send_local_velocity_command([0, 0, 0])
        self.rate.sleep_n_intervals(3)
        pos1 = self.client.getPosition()
        current_z = pos1.z_val
        pos1.z_val = tgt_h - 50

        self.client.simSetPose(pos1, tele_orientation)
        self.rate.sleep_n_intervals(2)

        tele_pos = Vector3r()
        tele_pos.x_val = pos_as[0]
        tele_pos.y_val = pos_as[1]
        tele_pos.z_val = tgt_h - 50

        self.client.simSetPose(tele_pos, tele_orientation)
        self.rate.sleep_n_intervals(2)

        tele_pos.z_val = tgt_h

        self.client.simSetPose(tele_pos, tele_orientation)
        self.send_local_velocity_command([0, 0, 0])
        self.rate.sleep_n_intervals(3)
        time.sleep(0.1)

    def get_yaw(self):
        o = self.client.getOrientation()
        vec, theta = quaternions.quat2axangle(
            [o.w_val, o.x_val, o.y_val, o.z_val])
        new_vec = self.units.vel3d_from_as(vec)
        roll, pitch, yaw = euler.axangle2euler(new_vec, theta)
        return yaw

    def send_local_velocity_command(self, cmd_vel):
        # Convert the drone reference frame command to a global command as understood by AirSim
        cmd_vel = self._action_to_global(cmd_vel)
        #print("                  global action: ", cmd_vel)
        if len(cmd_vel) == 3:
            cmd_vel_as = self.units.vel2d_to_as(cmd_vel[:2])
            cmd_yaw_as = self.units.yaw_rate_to_as(cmd_vel[2])
            #print("                         AirSim command: ", cmd_vel_as, "yaw rate: ", cmd_yaw_as)
            vel_x = cmd_vel_as[0]
            vel_y = cmd_vel_as[1]
            yaw_rate = cmd_yaw_as
            z = self.units.height_to_as(self.flight_height)
            yaw_mode = YawMode(is_rate=True, yaw_or_rate=yaw_rate)
            self.client.moveByVelocityZ(vel_x,
                                        vel_y,
                                        z,
                                        self.control_interval,
                                        yaw_mode=yaw_mode)

    def teleport_to(self, position, yaw):
        pos_as = self.units.pos2d_to_as(position[0:2])
        tgt_h = self.units.height_to_as(self.flight_height)
        teleported = False
        for i in range(10):
            self._try_teleport_to(position, yaw)
            curr_pos = self.client.getPosition()
            curr_pos_np = np.asarray([curr_pos.x_val, curr_pos.y_val])

            if np.linalg.norm(pos_as - curr_pos_np) < 1.0 and math.fabs(
                    tgt_h - curr_pos.z_val) < 1.0:
                teleported = True
                break
        if not teleported:
            print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
            print("Failed to teleport after 10 attempts!")
            print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")

    def teleport_3d(self, position, rpy, pos_in_airsim=True, fast=False):
        pos_as = position if pos_in_airsim else self.units.pos3d_to_as(
            position)
        # TODO: This is broken. p and r should also be converted ideally
        if not pos_in_airsim:
            rpy[2] = self.units.yaw_to_as(rpy[2])

        tele_rot = self.client.toQuaternion(rpy[0], rpy[1], rpy[2])
        self.send_local_velocity_command([0, 0, 0])
        self.rate.sleep_n_intervals(1)
        tele_pos = Vector3r()
        tele_pos.x_val = pos_as[0]
        tele_pos.y_val = pos_as[1]
        tele_pos.z_val = pos_as[2]

        self.client.simSetPose(tele_pos, tele_rot)
        self.send_local_velocity_command([0, 0, 0])
        if not fast:
            time.sleep(0.2)
        self.client.simSetPose(tele_pos, tele_rot)
        self.send_local_velocity_command([0, 0, 0])
        if not fast:
            time.sleep(0.2)

    def get_state(self, depth=False, segmentation=False):
        # Get images
        request = [ImageRequest(0, AirSimImageType.Scene, False, False)]
        if depth:
            request.append(ImageRequest(0, AirSimImageType.DepthPlanner, True))
        if segmentation:
            request.append(
                ImageRequest(0, AirSimImageType.Segmentation, False, False))

        response = self.client.simGetImages(request)

        pos_dict = response[0].camera_position
        rot_dict = response[0].camera_orientation

        cam_pos = [pos_dict[b"x_val"], pos_dict[b"y_val"], pos_dict[b"z_val"]]
        cam_rot = [
            rot_dict[b"w_val"], rot_dict[b"x_val"], rot_dict[b"y_val"],
            rot_dict[b"z_val"]
        ]

        img_data = np.frombuffer(response[0].image_data_uint8, np.uint8)
        image_raw = img_data.reshape(response[0].height, response[0].width, 4)
        image_raw = image_raw[:, :, 0:3]

        concat = [image_raw]

        if depth:
            # Depth is cast to uint8, because otherwise it takes up a lot of space and we don't need such fine-grained
            # resolution
            depth_data = np.asarray(response[1].image_data_float)
            depth_raw = depth_data.reshape(response[1].height,
                                           response[1].width, 1)
            depth_raw = np.clip(depth_raw, 0, 254 / DEPTH_SCALE)
            depth_raw *= DEPTH_SCALE
            depth_raw = depth_raw.astype(np.uint8)
            concat.append(depth_raw)

        if segmentation:
            seg_data = np.frombuffer(response[2].image_data_uint8, np.uint8)
            seg_raw = seg_data.reshape(response[2].height, response[2].width,
                                       4)
            concat.append(seg_raw)

        img_state = np.concatenate(concat, axis=2)

        # Get drone's physical location, orientation and velocity
        pos = self.client.getPosition()
        vel = self.client.getVelocity()
        o = self.client.getOrientation()
        # Turn it into a nice 9-D vector with euler angles
        r_as, p_as, y_as = euler.quat2euler(
            [o.w_val, o.x_val, o.y_val, o.z_val])
        roll, pitch, yaw = self.units.euler_from_as(r_as, p_as, y_as)
        pos_3d_as = np.asarray([pos.x_val, pos.y_val, pos.z_val])
        pos_state = self.units.pos3d_from_as(pos_3d_as)
        vel_state = self.units.vel3d_from_as(
            np.asarray([vel.x_val, vel.y_val, vel.z_val]))
        ori_state = [roll, pitch, yaw]

        drone_state = np.concatenate(
            (pos_state, ori_state, vel_state, cam_pos, cam_rot), axis=0)

        return drone_state, img_state

    def set_current_env_from_config(self, config, instance_id=None):
        """
        Store the provided dict representation of a random_config.json into the
        correct folder for instance_id simulator instance to read it when resetting it's pomdp.
        :param config: Random pomdp configuration to store
        :param instance_id: Simulator instance for which to store it.
        """
        self._set_config(config, "", "random_config", instance_id=instance_id)

    def set_current_env_id(self, env_id, instance_id=None):
        # TODO: This was used before to render the path in the simulator, but now that feature is unused anyways
        env_confs = ["config"]  # , "random_curve"]
        folders = ["configs"]  # , "paths"]

        #for env_conf, folder in zip(env_confs, folders):
        self._load_drone_config(env_id, instance_id)
        print("set_current_env_id env_id:", env_id)
        gc.collect()

    def reset_environment(self):
        self._start_call()
        self.client.simResetEnv()
        self._start_call()