示例#1
0
def get_step_trajectories(x0_, p_, ground_heights_=None):

    if ground_heights_ is None:
        total_leg_length = p_['spring_resting_length']
        total_leg_length += p_['actuator_resting_length']
        ground_heights_ = np.linspace(0, -0.5*total_leg_length, 10)
    x0_ = sys.reset_leg(x0_, p_)
    trajectories_ = list()
    for height in ground_heights_:
        x0_[-1] = height
        trajectories_.append(sys.step(x0_, p_))
    x0_[-1] = 0.0  # reset x0 back to 0
    return trajectories_
示例#2
0
def get_step_trajectories(x0, p, ground_heights=None):
    '''
    helper function to apply a battery of ground-height perturbations.
    returns a list of trajectories.
    '''

    if ground_heights is None:
        total_leg_length = p['resting_length']
        total_leg_length += p['actuator_resting_length']
        ground_heights = np.linspace(0, -0.5 * total_leg_length, 10)
    x0 = model.reset_leg(x0, p)
    trajectories = list()
    for height in ground_heights:
        x0[-1] = height
        trajectories.append(model.step(x0, p))
    x0[-1] = 0.0  # reset x0 back to 0
    return trajectories
示例#3
0
def get_step_trajectories(x0, p, ground_heights=None):
    '''
    helper function to apply a battery of ground-height perturbations.
    returns a list of trajectories.
    '''

    if ground_heights is None:
        total_leg_length = p['resting_length']
        total_leg_length += p['actuator_resting_length']
        ground_heights = np.linspace(0, -0.5 * total_leg_length, 10)
    x0 = model.reset_leg(x0, p)

    # start_idx = np.argwhere(~np.isclose(p['actuator_force'][1], 0))[0]
    # time_to_activation = p['actuator_force'][0, start_idx]

    trajectories = list()
    for height in ground_heights:
        x0[-1] = height
        # time_to_touchdown = np.sqrt(2*(x0[5] - x0[-1])/p['gravity'])
        # p['activation_delay'] = time_to_touchdown - time_to_activation
        trajectories.append(model.step(x0, p))
    x0[-1] = 0.0  # reset x0 back to 0
    return trajectories
示例#4
0
     'actuator_resting_length': 0.1,      # m
     'actuator_force': [],                # * 2 x M matrix of time and force
     'actuator_force_period': 10,         # * s
     'activation_amplification': 1,
     'activation_delay': 0.0,  # * a delay for when to start activation
     'constant_normalized_damping': 0.75,          # *    s : D/K : [N/m/s]/[N/m]
     'linear_normalized_damping_coefficient': 3.5,  # * A: s/m : D/F : [N/m/s]/N : 0.0035 N/mm/s -> 3.5 1/m/s from Kirch et al. Fig 12
     'linear_minimum_normalized_damping': 0.05,    # *   1/A*(kg*N/kg) :
     'swing_leg_norm_angular_velocity':  0,  # [1/s]/[m/s] (omega/(vx/lr))
     'swing_velocity': 0,   # rad/s (set by calculation)
     'angle_of_attack_offset': 0}        # rad   (set by calculation)
# * linear_normalized_damping_coefficient:
# * A: s/m : D/F : [N/m/s]/N : 0.0035 N/mm/s -> 3.5 1/m/s (Kirch et al. Fig 12)

x0 = np.array([0, 1.00, 5.5, 0, 0, 0, p['actuator_resting_length'], 0, 0, 0])
x0 = model.reset_leg(x0, p)
p['total_energy'] = model.compute_total_energy(x0, p)
x0, p = model.create_open_loop_trajectories(x0, p)
p['x0'] = x0
p['activation_amplification'] = 1.5
# initialize default x0_daslip

p_map = model.poincare_map
p_map.p = p
p_map.x = x0
p_map.sa2xp = model.sa2xp_y_xdot_timedaoa
# p_map.sa2xp = model.sa2xp_y_xdot_aoa
p_map.xp2s = model.xp2s_y_xdot

s_grid_height = np.linspace(0.5, 1.5, 7)
s_grid_velocity = np.linspace(3, 8, 7)
示例#5
0
def plot_ground_perturbations(ax,
                              trajectories,
                              S_M,
                              grids,
                              p,
                              v_threshold=0.1,
                              col_offset=0.65,
                              col_norm=1.0,
                              draw_ground=True,
                              draw_LC=False,
                              Q_M=None,
                              colormap=None,
                              norm=1):
    '''
    Plot a series of trajectories, centered around level-ground as nominal
    inputs:
    trajectories: list of traj objects (sol to scipy.integrate.solve_ivp)
    v_threshold: minimum safety, otherwise don't plot it
    '''

    # TODO redo this with trajectories colored by measure
    print(" ")
    # * plot step-ups
    up_cmap = plt.get_cmap("Blues")
    down_cmap = plt.get_cmap("Reds")
    idx0 = -1
    pert_min = 0
    pert_max = 0
    lc_viab = 0
    for idx in range(len(trajectories)):
        traj = trajectories[idx]
        x = traj.y[:, -1]  # ground
        s = sys.xp2s_y_xdot(x, p)
        sbin = vibly.digitize_s(s, grids['states'])
        s_m = interp_measure(sbin, S_M, grids)

        if s_m >= v_threshold:
            if np.isclose(x[-1], 0):  # limit cycle
                # print afterwards, so it's on top of other circles
                idx0 = idx
                # keep track of max viability at LC
                lc_viab = s_m
                continue
            elif x[-1] < 0:
                col = down_cmap(col_offset - np.abs(x[-1]) / col_norm)
                # col = down_cmap(np.abs(x[-1])/col_norm)
                zod = 2
                # keep track of min and max perturbations
                if x[-1] < pert_min:
                    pert_min = x[-1]
            elif x[-1] > 0:
                col = up_cmap(col_offset - np.abs(x[-1]) / col_norm)
                # col = up_cmap(np.abs(x[-1])/col_norm)
                zod = 1
                if x[-1] > pert_max:
                    pert_max = x[-1]
            ax.plot(traj.y[0], traj.y[1], color=col, linewidth=2, zorder=zod)
            # and plot ground
            td_index = np.abs(traj.t - traj.t_events[1]).argmin()
            to_index = np.abs(traj.t - traj.t_events[3]).argmin()
            ax.plot(traj.y[0, td_index:to_index],
                    traj.y[-1, td_index:to_index],
                    color=col,
                    linewidth=2)
        if idx0 > 0:
            zod = 3
            traj = trajectories[idx0]
            ax.plot(traj.y[0],
                    traj.y[1],
                    linewidth=2.5,
                    color='black',
                    zorder=zod)
            ax.plot(traj.y[0], traj.y[-1], color='black', zorder=zod)

    print("Min perturbation: " + str(pert_min))
    print("Max perturbation: " + str(pert_max))
    print("Viability Measure at Limit Cycle: " + str(lc_viab))

    if draw_LC:
        if idx0 <= 0:
            print("WARNING: no LC fond.")
        x_next = trajectories[idx0].y[:, -1]
        # plot pointmass
        ax.scatter(x_next[0], x_next[1], s=300, color='black', zorder=3)
        # plot leg
        ax.plot([x_next[0], x_next[4]], [x_next[1], x_next[5]],
                linewidth=3,
                color='black',
                zorder=3)
        if Q_M is not None:
            # pick out the correct slice
            s_next = sys.xp2s_y_xdot(x_next, p)
            sbin = vibly.digitize_s(s_next, grids['states'])
            A_slice = np.copy(Q_M[tuple(sbin) + (slice(None), )])
            viable_actions = grids['actions'][0][np.nonzero(A_slice)]
            viable_action_M = A_slice[np.nonzero(A_slice)]
            # color = plt.cm.hsv(viable_action_M)
            # create an array of foot-points
            foot_x = np.zeros_like(viable_actions)
            foot_y = np.zeros_like(viable_actions)
            for i, a in np.ndenumerate(viable_actions):
                p['angle_of_attack'] = a
                xtemp = sys.reset_leg(x_next, p)
                foot_x[i] = xtemp[4]
                foot_y[i] = xtemp[5]
            cmap = plt.get_cmap("viridis")
            color = cmap(norm(interp_measure(sbin, S_M, grids)))
            ax.plot(foot_x, foot_y, zorder=2, color=color)
            ax.plot([x_next[0], foot_x[0]], [x_next[1], foot_y[0]],
                    zorder=2,
                    color=color)
            ax.plot([x_next[0], foot_x[-1]], [x_next[1], foot_y[-1]],
                    zorder=2,
                    color=color)
            ax.grid = True

    add_title(p)