Exemplo n.º 1
0
    def __init__(self,init,obst):
        """
        (Perform quadcopter initialization)
        Inputs:
            init, a dict defining the swarm's initial conditions with keys
                x, position, m, shape=(3,N)
                v, linear velocity, m/s, shape=(3,N)
                q, quaternion [i,j,k,w], shape=(4,N)
                w, angular velocity, rad/s, shape=(3,N)
            obst, a list of arrays denoting obstacles
=
        """
        self.Quadrotor = Quadrotor(quad_params)
        self.Control = Control(quad_params)
        self.T_control = 1/500 # in seconds, determines control loop frequency
        self.states = copy.deepcopy(init)
        self.init_states = copy.deepcopy(init)
        self.reward = 0
        self.done = False
        self.obstacles = obst
Exemplo n.º 2
0
    def __init__(self, init):
        """
        (Perform swarm initialization)
        Inputs:
            init, a dict defining the swarm's initial conditions with keys
                x, position, m, shape=(3,N)
                v, linear velocity, m/s, shape=(3,N)
                q, quaternion [i,j,k,w], shape=(4,N)
                w, angular velocity, rad/s, shape=(3,N)
=
        """
        self.N = len(init)
        self.Quadrotors = [Quadrotor(quad_params) for i in range(self.N)]
        self.Controls = [Control(quad_params) for i in range(self.N)]
        self.T_control = 1 / 500  # in seconds, determines control loop frequency
        self.states = copy.deepcopy(init)
        self.init_states = copy.deepcopy(init)
Exemplo n.º 3
0
def test_mission(waypoint_traj_cls, se3_control_cls, points, initial_state):
    """
    Test the provided trajectory class and control class against a set of
    waypoints and a specific initial state. Return the simulation results and
    the performance metrics.
    """

    # Student code to test.
    my_traj = waypoint_traj_cls(points)
    my_se3_control = se3_control_cls(quad_params)

    # Simulation options.
    quadrotor = Quadrotor(quad_params)
    t_final = 60

    # Run simulation.
    (time, state, control, flat, exit) = simulate(initial_state, quadrotor,
                                                  my_se3_control, my_traj,
                                                  t_final)
    results = {
        'time': time,
        'state': state,
        'control': control,
        'flat': flat,
        'exit': exit
    }

    # Evaluate results.
    metrics = {}
    # Must come to rest at goal.
    metrics['stopped_at_goal'] = (results['exit'] == ExitStatus.COMPLETE)
    metrics['time'] = time[-1]
    # Must pass within minimum distance of each waypoint.
    dist = cdist(points, results['state']['x'])
    min_dist = np.min(dist, axis=1)
    metrics['reached_waypoints'] = bool(np.max(min_dist) < 1.0)
    # Details about why the simulation ended (success, failure, timeout).
    metrics['sim_exit'] = results['exit'].value

    return (results, metrics)
Exemplo n.º 4
0
def test_mission(traj_cls, se3_control_cls, world, start, goal):
    """
    Test the provided graph_search function against a world, start, and goal.
    Return the simulation results and the performance metrics.
    """

    # Student code to test.
    start_time = time.time()
    my_traj = traj_cls(world, start, goal)
    planning_time = round(time.time() - start_time, 2)
    my_se3_control = se3_control_cls(quad_params)

    # Simulation options.
    quadrotor = Quadrotor(quad_params)
    t_final = 60

    # Run simulation and collect results.
    initial_state = {
        'x': start,
        'v': (0, 0, 0),
        'q': (0, 0, 0, 1),  # [i,j,k,w]
        'w': (0, 0, 0)
    }
    (sim_time, state, control, flat, exit) = simulate(initial_state, quadrotor,
                                                      my_se3_control, my_traj,
                                                      t_final)
    results = {
        'time': sim_time,
        'state': state,
        'control': control,
        'flat': flat,
        'exit': exit,
        'planning_time': planning_time
    }

    # Evaluate metrics.
    metrics = calculate_metrics(results, world, goal)

    return results, metrics
import inspect
import matplotlib.pyplot as plt
from pathlib import Path
from flightsim.axes3ds import Axes3Ds
from flightsim.crazyflie_params import quad_params
from flightsim.simulate import Quadrotor, simulate, ExitStatus
from flightsim.world import World 
from flightsim.world import ExpectTimeout 
import numpy as np


quadrotor = Quadrotor(quad_params)
robot_radius = 0.25

fig = plt.figure('A* Path, Waypoints, and Trajectory')
ax = Axes3Ds(fig)
for _ in range(20):
    try:
        with ExpectTimeout(3):
            world = World.fixed_block(lower_bounds=(-2,-2,0),upper_bounds=(3,2,2),block_width=0.5,block_height=1.5,num_blocks=4,robot_radii=robot_radius,margin=0.2)
            break
    except TimeoutError:
        pass
    
world.draw(ax)
start=world.world['start']
goal=world.world['goal']
ax.plot([start[0]], [start[1]], [start[2]], 'go', markersize=5, markeredgewidth=3, markerfacecolor='none')
ax.plot([goal[0]], [goal[1]], [goal[2]], 'ro', markersize=5, markeredgewidth=3, markerfacecolor='none')
plt.show()
Exemplo n.º 6
0
def sandbox(world, start, goal):
    # Load the test example.
    # file = Path(inspect.getsourcefile(lambda:0)).parent.resolve() / '..' / 'util' / filename
    # world = World.from_file(file)          # World boundary and obstacles.
    # start  = world.world['start']          # Start point, shape=(3,)
    # goal   = world.world['goal']           # Goal point, shape=(3,)

    # This object defines the quadrotor dynamical model and should not be changed.
    quadrotor = Quadrotor(quad_params)
    robot_radius = 0.25

    # Your SE3Control object (from project 1-1).
    my_se3_control = SE3Control(quad_params)

    # Your MapTraj object. This behaves like the trajectory function you wrote in
    # project 1-1, except instead of giving it waypoints you give it the world,
    # start, and goal.
    planning_start_time = time.time()
    my_world_traj = WorldTraj(world, start, goal)
    planning_end_time = time.time()

    # Help debug issues you may encounter with your choice of resolution and margin
    # by plotting the occupancy grid after inflation by margin. THIS IS VERY SLOW!!
    # fig = plt.figure('world')
    # ax = Axes3Ds(fig)
    # world.draw(ax)
    # fig = plt.figure('occupancy grid')
    # ax = Axes3Ds(fig)
    # resolution = SET YOUR RESOLUTION HERE
    # margin = SET YOUR MARGIN HERE
    # oc = OccupancyMap(world, resolution, margin)
    # oc.draw(ax)
    # ax.plot([start[0]], [start[1]], [start[2]], 'go', markersize=10, markeredgewidth=3, markerfacecolor='none')
    # ax.plot( [goal[0]],  [goal[1]],  [goal[2]], 'ro', markersize=10, markeredgewidth=3, markerfacecolor='none')
    # plt.show()

    # Set simulation parameters.
    t_final = 60
    initial_state = {
        'x': start,
        'v': (0, 0, 0),
        'q': (0, 0, 0, 1),  # [i,j,k,w]
        'w': (0, 0, 0)
    }

    # Perform simulation.
    #
    # This function performs the numerical simulation.  It returns arrays reporting
    # the quadrotor state, the control outputs calculated by your controller, and
    # the flat outputs calculated by you trajectory.

    print()
    print('Simulate.')
    (sim_time, state, control, flat, exit) = simulate(initial_state, quadrotor,
                                                      my_se3_control,
                                                      my_world_traj, t_final)
    print(exit.value)

    # Print results.
    #
    # Only goal reached, collision test, and flight time are used for grading.

    collision_pts = world.path_collisions(state['x'], robot_radius)

    stopped_at_goal = (exit == ExitStatus.COMPLETE
                       ) and np.linalg.norm(state['x'][-1] - goal) <= 0.05
    no_collision = collision_pts.size == 0
    flight_time = sim_time[-1]
    flight_distance = np.sum(
        np.linalg.norm(np.diff(state['x'], axis=0), axis=1))
    planning_time = planning_end_time - planning_start_time

    print()
    print(f"Results:")
    print(f"  No Collision:    {'pass' if no_collision else 'FAIL'}")
    print(f"  Stopped at Goal: {'pass' if stopped_at_goal else 'FAIL'}")
    print(f"  Flight time:     {flight_time:.1f} seconds")
    print(f"  Flight distance: {flight_distance:.1f} meters")
    print(f"  Planning time:   {planning_time:.1f} seconds")
    if not no_collision:
        print()
        print(f"  The robot collided at location {collision_pts[0]}!")

    # Plot Results
    #
    # You will need to make plots to debug your quadrotor.
    # Here are some example of plots that may be useful.

    # Visualize the original dense path from A*, your sparse waypoints, and the
    # smooth trajectory.
    fig = plt.figure('A* Path, Waypoints, and Trajectory')
    ax = Axes3Ds(fig)
    world.draw(ax)
    ax.plot([start[0]], [start[1]], [start[2]],
            'go',
            markersize=16,
            markeredgewidth=3,
            markerfacecolor='none')
    ax.plot([goal[0]], [goal[1]], [goal[2]],
            'ro',
            markersize=16,
            markeredgewidth=3,
            markerfacecolor='none')
    if hasattr(my_world_traj, 'path'):
        if my_world_traj.path is not None:
            world.draw_line(ax, my_world_traj.path, color='red', linewidth=1)
    else:
        print("Have you set \'self.path\' in WorldTraj.__init__?")
    if hasattr(my_world_traj, 'points'):
        if my_world_traj.points is not None:
            world.draw_points(ax,
                              my_world_traj.points,
                              color='purple',
                              markersize=8)
    else:
        print("Have you set \'self.points\' in WorldTraj.__init__?")
    world.draw_line(ax, flat['x'], color='black', linewidth=2)
    ax.legend(handles=[
        Line2D([], [], color='red', linewidth=1, label='Dense A* Path'),
        Line2D([], [],
               color='purple',
               linestyle='',
               marker='.',
               markersize=8,
               label='Sparse Waypoints'),
        Line2D([], [], color='black', linewidth=2, label='Trajectory')
    ],
              loc='upper right')

    # Position and Velocity vs. Time
    (fig, axes) = plt.subplots(nrows=2,
                               ncols=1,
                               sharex=True,
                               num='Position vs Time')
    x = state['x']
    x_des = flat['x']
    ax = axes[0]
    ax.plot(sim_time, x_des[:, 0], 'r', sim_time, x_des[:, 1], 'g', sim_time,
            x_des[:, 2], 'b')
    ax.plot(sim_time, x[:, 0], 'r.', sim_time, x[:, 1], 'g.', sim_time,
            x[:, 2], 'b.')
    ax.legend(('x', 'y', 'z'), loc='upper right')
    ax.set_ylabel('position, m')
    ax.grid('major')
    ax.set_title('Position')
    v = state['v']
    v_des = flat['x_dot']
    ax = axes[1]
    ax.plot(sim_time, v_des[:, 0], 'r', sim_time, v_des[:, 1], 'g', sim_time,
            v_des[:, 2], 'b')
    ax.plot(sim_time, v[:, 0], 'r.', sim_time, v[:, 1], 'g.', sim_time,
            v[:, 2], 'b.')
    ax.legend(('x', 'y', 'z'), loc='upper right')
    ax.set_ylabel('velocity, m/s')
    ax.set_xlabel('time, s')
    ax.grid('major')

    # Orientation and Angular Velocity vs. Time
    (fig, axes) = plt.subplots(nrows=2,
                               ncols=1,
                               sharex=True,
                               num='Orientation vs Time')
    q_des = control['cmd_q']
    q = state['q']
    ax = axes[0]
    ax.plot(sim_time, q_des[:, 0], 'r', sim_time, q_des[:, 1], 'g', sim_time,
            q_des[:, 2], 'b', sim_time, q_des[:, 3], 'k')
    ax.plot(sim_time, q[:, 0], 'r.', sim_time, q[:, 1], 'g.', sim_time,
            q[:, 2], 'b.', sim_time, q[:, 3], 'k.')
    ax.legend(('i', 'j', 'k', 'w'), loc='upper right')
    ax.set_ylabel('quaternion')
    ax.set_xlabel('time, s')
    ax.grid('major')
    w = state['w']
    ax = axes[1]
    ax.plot(sim_time, w[:, 0], 'r.', sim_time, w[:, 1], 'g.', sim_time,
            w[:, 2], 'b.')
    ax.legend(('x', 'y', 'z'), loc='upper right')
    ax.set_ylabel('angular velocity, rad/s')
    ax.set_xlabel('time, s')
    ax.grid('major')

    # Commands vs. Time
    (fig, axes) = plt.subplots(nrows=3,
                               ncols=1,
                               sharex=True,
                               num='Commands vs Time')
    s = control['cmd_motor_speeds']
    ax = axes[0]
    ax.plot(sim_time, s[:, 0], 'r.', sim_time, s[:, 1], 'g.', sim_time,
            s[:, 2], 'b.', sim_time, s[:, 3], 'k.')
    ax.legend(('1', '2', '3', '4'), loc='upper right')
    ax.set_ylabel('motor speeds, rad/s')
    ax.grid('major')
    ax.set_title('Commands')
    M = control['cmd_moment']
    ax = axes[1]
    ax.plot(sim_time, M[:, 0], 'r.', sim_time, M[:, 1], 'g.', sim_time,
            M[:, 2], 'b.')
    ax.legend(('x', 'y', 'z'), loc='upper right')
    ax.set_ylabel('moment, N*m')
    ax.grid('major')
    T = control['cmd_thrust']
    ax = axes[2]
    ax.plot(sim_time, T, 'k.')
    ax.set_ylabel('thrust, N')
    ax.set_xlabel('time, s')
    ax.grid('major')

    # # 3D Paths
    # fig = plt.figure('3D Path')
    # ax = Axes3Ds(fig)
    # world.draw(ax)
    # ax.plot([start[0]], [start[1]], [start[2]], 'go', markersize=16, markeredgewidth=3, markerfacecolor='none')
    # ax.plot( [goal[0]],  [goal[1]],  [goal[2]], 'ro', markersize=16, markeredgewidth=3, markerfacecolor='none')
    # world.draw_line(ax, flat['x'], color='black', linewidth=2)
    # world.draw_points(ax, state['x'], color='blue', markersize=4)
    # if collision_pts.size > 0:
    #     ax.plot(collision_pts[0,[0]], collision_pts[0,[1]], collision_pts[0,[2]], 'rx', markersize=36, markeredgewidth=4)
    # ax.legend(handles=[
    #     Line2D([], [], color='black', linewidth=2, label='Trajectory'),
    #     Line2D([], [], color='blue', linestyle='', marker='.', markersize=4, label='Flight')],
    #     loc='upper right')

    # Animation (Slow)
    #
    # Instead of viewing the animation live, you may provide a .mp4 filename to save.

    # R = Rotation.from_quat(state['q']).as_dcm()
    # animate(sim_time, state['x'], R, world=world, filename=None, show_axes=True)

    # plt.show()

    data = np.hstack(
        (sim_time.reshape(-1, 1), x, x_des, v, v_des, q, q_des, w, s, M, T))
    columns = [
        'time', 'x[1]', 'x[2]', 'x[3]', 'x_des[1]', 'x_des[2]', 'x_des[3]',
        'v[1]', 'v[2]', 'v[3]', 'v_des[1]', 'v_des[2]', 'v_des[3]', 'q[1]',
        'q[2]', 'q[3]', 'q[4]', 'q_des[1]', 'q_des[2]', 'q_des[3]', 'q_des[4]',
        'w[1]', 'w[2]', 'w[3]', 's[1]', 's[2]', 's[3]', 's[4]', 'M[1]', 'M[2]',
        'M[3]', 'T[1]', 'T[2]', 'T[3]', 'T[4]'
    ]

    df = pd.DataFrame(data, columns=columns)

    init_state = {'x': x[0], 'v': v[0], 'q': q[0], 'w': w[0]}

    return df, init_state
Exemplo n.º 7
0
class Quadcopter(gym.Env):
    def __init__(self,init,obst):
        """
        (Perform quadcopter initialization)
        Inputs:
            init, a dict defining the swarm's initial conditions with keys
                x, position, m, shape=(3,N)
                v, linear velocity, m/s, shape=(3,N)
                q, quaternion [i,j,k,w], shape=(4,N)
                w, angular velocity, rad/s, shape=(3,N)
            obst, a list of arrays denoting obstacles
=
        """
        self.Quadrotor = Quadrotor(quad_params)
        self.Control = Control(quad_params)
        self.T_control = 1/500 # in seconds, determines control loop frequency
        self.states = copy.deepcopy(init)
        self.init_states = copy.deepcopy(init)
        self.reward = 0
        self.done = False
        self.obstacles = obst


    def step(self, action, point, r=0.15):
        c = self.Control.update(self.states, action)
        self.states = self.Quadrotor.step(self.states, c['cmd_motor_speeds'], self.T_control)

        self.reward += np.linalg.norm(self.states['x']-point)
        if self.collision_detection(self.states['x']):
            self.done = True
            self.reward += 1000

        return self.states,self.reward,self.done


    def reset(self):
        self.states = copy.deepcopy(self.init_states)
        self.reward = 0
        self.done = False

    def render(self, mode='human'):
        pass


    def close(self):
        pass

    # --------------------------------------------

    def collision_detection(self,p):
        for obs in self.obstacles:
            if Polygon(obs).contains(Point(p)):
                return 1
        return 0

    def plot_obstacles(self):
        for obst in self.obstacles:
            plt.fill(*Polygon(obst).exterior.xy, 'grey')

    def in_bounds(self,p, space):
        return Polygon(space).contains(Point(p))
Exemplo n.º 8
0
    def forward_simulate(self, x0, J0, tau, D, return_Rs, return_cc):
        # TODO
        '''
        Given the desired trajectory run a forward simulation to identify
        if the desired trajectory can be followed and identify the dynamic 
        feasibilty based on the ability of the controller to follow the trajectory 
        

        Input:
        x0 = 1 X 17 array of initial state [x0, v0, a0, q0, w0]
            p0 = 1 X 3 -- postion in m
            v0 = 1 X 3 -- velocity in m/s
            a0 = 1 X 3 -- acceleration in m/s^2
            q0 = 1 X 4 -- quaternion 
            w0 = 1 X 3 -- angular velocity in 1/s^2
        tau = Duration of planner

        Output:
        Rs =  3 X 3 np array of state at the end of the period after the simulation
        err_cs = M X 1 np array of the cost of the trajectory based on the controller's
                 ability to follow the trajectory
        '''

        t_final = tau
        initial_state = {
            'x': tuple(x0[0:3]),
            'v': tuple(x0[3:6]),
            'q': tuple(x0[9:13]),
            'w': tuple(x0[13:16])
        }

        quadrotor = Quadrotor(quad_params)
        my_se3_controller = SE3Control(quad_params)

        # Traj object has been created to main tain consistency with the simulator which
        # needs the trajectory  to be an ibject with an update function
        traj = trajectory(D)
        (sim_time, state, control, flat, exit,
         col_c) = simulate(initial_state, quadrotor, my_se3_controller, traj,
                           t_final, self.occ_map)

        # TODO: Exit state check. Taking flat outputs
        if True:
            err = np.array(
                flat['x'][-1].shape
            )  # TODO check if order is stored in the same order in both dictionary
            err_cs = np.sum(np.absolute(err))
            Rsx = flat['x'][-1]
            Rsv = flat['x_dot'][-1]
            # Rsx=state['x'][-1]
            # Rsv=state['v'][-1]
            Rsa = flat['x_ddot'][-1].reshape(729, 3)
            Rsq = np.zeros((729, 4))
            Rsw = np.zeros((729, 3))
            # pdb.set_trace()
            Rs = np.hstack((Rsx, Rsv, Rsa, Rsq, Rsw))
            # pdb.set_trace()

        else:
            err_cs = np.inf
            Rs = None

        return_Rs = Rs
        return_cc = return_cc + err_cs + col_c.reshape(729, 1)
        return return_Rs, return_cc