Beispiel #1
0
def legODE1D(state, t, params):
    """
    This function defines the simpleModels axial leg as an ODE. It can be used
    to simulate the behavior.

    Parameters
    ----------

        state : *array* (1x3)
            State of the system: [x1, x2, x3] alias [l, \dot{l} and l_d]

        t : *float*
            the time. This is ignored since the system is time-independent.

        params : *dict*
            a dictionary

    Returns
    -------

        dx/dt : *array* (1x3)
            The derivative of the state as a function of the state: dx/dt = f(x) 


    """

    P = mi.Struct(params)  # allow struct-style access to keys
    x1, x2, x3 = state

    x1_dot = x2
    #    F_S = -1. * P.k * (x1 - x3 - P.ls0)
    x2_dot = -1. * P.k / P.m * (x1 - x3 - P.ls0) + P.g
    x3_dot = -1. / P.d * (-1. * P.k * (x1 - x3 - P.ls0) + P.kd * (x3 - P.ld0))

    return array([x1_dot, x2_dot, x3_dot])
Beispiel #2
0
def VLO_event_refine(t, state, pars):
    """
    calcualtes the vertical leg orientation instant - refinement
    """
    P = mi.Struct(pars)
    x, y, phi, vx, vy, vphi = state
    hip = (x + np.sin(phi) * P.r_hip, y - np.cos(phi) * P.r_hip)

    return hip[0] - P.x_foot1
Beispiel #3
0
def VLO_event(t, states, traj, pars):
    """
    calcualtes the vertical leg orientation instant
    """
    P = mi.Struct(pars)
    x1, y1, phi1, vx1, vy1, vphi1 = states[0]
    x2, y2, phi2, vx2, vy2, vphi2 = states[1]

    hip1 = (x1 + np.sin(phi1) * P.r_hip, y1 - np.cos(phi1) * P.r_hip)
    hip2 = (x2 + np.sin(phi2) * P.r_hip, y2 - np.cos(phi2) * P.r_hip)

    return hip1[0] < P.x_foot1 and hip2[0] >= P.x_foot1
Beispiel #4
0
def td_event_spring_refine(t, state, pars):
    """
    refinement function for SLIP 2nd leg touchdown event.

    This function returns some value whose zero-crossing indicates the event to
    be detected.
    """
    x, y, phi, vx, vy, vphi = state
    P = mi.Struct(pars)

    hip = (x + np.sin(phi) * P.r_hip, y - np.cos(phi) * P.r_hip)
    y_foot = hip[1] - np.sin(P.legpars2['alpha']) * P.legpars2['l0']
    return -y_foot
Beispiel #5
0
def to_event_spring_refine(t, state, pars):
    """
    refinement function for SLIP 2nd leg takeoff event.

    This function returns some value whose zero-crossing indicates the event to
    be detected.
    """
    P = mi.Struct(pars)
    x, y, phi, vx, vy, vphi = state

    hip = (x + np.sin(phi) * P.r_hip, y - np.cos(phi) * P.r_hip)
    l = np.sqrt((hip[0] - P.x_foot2)**2 + hip[1]**2)
    return l - P.legpars2['l0']
Beispiel #6
0
def roi(d, Params):
    """
    a root for this expression has to be found!

    THIS IS A SIMPLIFICATION OF THE ABOVE EXPRESSION WITH k = 3*kd

    """

    P = mi.Struct(Params)

    res = (((P.kd / P.m - 16 * P.kd**2 / (9 * d**2))**3 +
            (-P.kd**2 / (d * P.m) + 128 * P.kd**3 /
             (27 * d**3))**2 / 4.)**(1 / 2) - P.kd**2 / (2 * d * P.m) +
           64 * P.kd**3 / (27. * d**3))**(1. / 3.)

    return res
Beispiel #7
0
def remTerm(d, Params):
    """
    test function to visualize if there are any roots possible

    """

    P = mi.Struct(Params)

    kd = P.k / 3.

    res = (((P.k / (3. * P.m) - (P.k + kd)**2 / (9. * d**2))**3 +
            (P.k * kd / (d * P.m) - P.k * (P.k + kd) / (3. * d * P.m) + 2. *
             (P.k + kd)**3 / (27. * d**3))**2 / 4.)**(1. / 2.) + P.k * kd /
           (2. * d * P.m) - P.k * (P.k + kd) / (6. * d * P.m) + (P.k + kd)**3 /
           (27. * d**3))**(1. / 3.) - (P.k + kd) / (3. * d)

    return res
Beispiel #8
0
def to_event_spring(t, states, traj, pars):
    """
    triggers the takeoff of the 2nd leg.
    *Note* it is assumed that *always* the 2nd leg is the trailing leg. This
    has to be ensured by appropriate transitions.

    Condition is: rest length is reached.
    *Note* There could be further conditions: e.g., leg *must* be behind CoM,
    behind hip, ... whatever (useful for more detailled model investigations)
    """
    P = mi.Struct(pars)
    x1, y1, phi1, vx1, vy1, vphi1 = states[0]
    x2, y2, phi2, vx2, vy2, vphi2 = states[1]

    hip1 = (x1 + np.sin(phi1) * P.r_hip, y1 - np.cos(phi1) * P.r_hip)
    l1 = np.sqrt((hip1[0] - P.x_foot2)**2 + hip1[1]**2)
    hip2 = (x2 + np.sin(phi2) * P.r_hip, y2 - np.cos(phi2) * P.r_hip)
    l2 = np.sqrt((hip2[0] - P.x_foot2)**2 + hip2[1]**2)
    return l1 < P.legpars2['l0'] and l2 >= P.legpars2['l0']
Beispiel #9
0
def VPP_steps(IC, pars, n=2, count_only=False):
    """
    performs up to n steps of the VPP model

    :args:
        IC (1x6 float): initial condition
        pars (dict): parameters for VPP model
        n (int): steps to perform at most
        count_only (bool): return only the number of successful steps

    :returns:
        t, y: the time and the state of the model, or
           n: the number of steps reached before falling down

    """

    localpars = deepcopy(pars)
    niter = 0
    t, y = [0], [IC]
    last_t0 = 0
    while niter < n:
        # on update: DO NOT FORGET TO UPDATE THE FEET LOCATIONS
        tt, yy, feet = VPP_step(IC, localpars, return_traj=True)
        localpars['x_foot1'] = feet[0]
        localpars['x_foot2'] = feet[1]
        # skip first element - this is just the IC
        y.append(yy[1:])
        t.append(tt[1:] + last_t0)
        last_t0 = t[-1][-1]
        niter += 1
        # check if touchdown is possible (foot position above ground):
        P = mi.Struct(pars)
        hip_y = yy[-1, 1] - np.cos(yy[-1, 2]) * P.r_hip
        if hip_y - np.sin(P.legpars2['alpha']) * P.legpars2['l0'] <= 0:
            print "no touchdown possible (n=", niter, ")"
            print "hip_y: ", hip_y
            break
        IC = yy[-1, :]
    if not count_only:
        return np.hstack(t), np.vstack(y)
    else:
        return niter
Beispiel #10
0
def td_event_spring(t, states, traj, pars):
    """
    triggers the touchdown event for leg 2 (which will become leg 1 at
    touchdown)

    Condition is: the leg touches ground (here, a fixed angle w.r.t. world is
    assumed. To change this, edit (a) this trigger and (b) the appropriate
    touchdown transitions.
    """

    P = mi.Struct(pars)
    x1, y1, phi1, vx1, vy1, vphi1 = states[0]
    x2, y2, phi2, vx2, vy2, vphi2 = states[1]

    hip1 = (x1 + np.sin(phi1) * P.r_hip, y1 - np.cos(phi1) * P.r_hip)
    hip2 = (x2 + np.sin(phi2) * P.r_hip, y2 - np.cos(phi2) * P.r_hip)

    y_foot1 = hip1[1] - P.legpars2['l0'] * np.sin(P.legpars2['alpha'])
    y_foot2 = hip2[1] - P.legpars2['l0'] * np.sin(P.legpars2['alpha'])
    return y_foot1 > 0 and y_foot2 <= 0
Beispiel #11
0
def dy(t, state, pars, output_forces=False):
    """
    equations of motion for single- and double stance

    :args:
        t (float): absolute simulation time
        state (array): system state: x, y, phi, vx, vy, vphi
        pars (dict): system parameters. required keys:
            legfun1(function: t, l, l_dot, legpars -> float): the leg force law
            legpars1(dict): the parameters for the leg force law
            legfun2(function: t, l, l_dot, legpars -> float): the leg force law
                for the 2nd leg. Can be (None) if not present
            legpars2(dict): the parameters for the leg force law
            J (float): inertia of trunk
            m (float): mass of trunk
            r_h (float): distance hip-CoM
            r_vpp1 (float): distance CoM-vpp, for leg 1
            a_vpp1 (float): angle between trunk and line CoM-VPP, for leg  1
            r_vpp2 (float): distance CoM-vpp, for leg 2
            a_vpp2 (float): angle between trunk and line CoM-VPP, for leg  2
            x_foot1 (float): x-position of foot 1, or None
            x_foot2 (float): x-position of foot 2, or None
            g (1x2 float): acceleration due to gravity (e.g. [0, -9.81])
        output_foces (bool): if True, output the forces and torques

    """
    P = mi.Struct(pars)
    x, y, phi, vx, vy, vphi = state
    hip = (x + np.sin(phi) * P.r_hip, y - np.cos(phi) * P.r_hip)
    vhip = (vx + np.cos(phi) * vphi * P.r_hip,
            vy + np.sin(phi) * vphi * P.r_hip)
    # calculate (axial) force for first leg, if present
    Fleg1 = 0
    if (P.x_foot1 is not None) and P.legfun1:
        l1 = np.sqrt((hip[0] - P.x_foot1)**2 + hip[1]**2)
        ldot1 = .5 / np.sqrt(l1) * (2. * (hip[0] - P.x_foot1) * vhip[0] +
                                    2. * hip[1] * vhip[1])
        Fleg1 = P.legfun1(t, l1, ldot1, P.legpars1)

    # calculate (axial) force for second leg, if present
    Fleg2 = 0
    if (P.x_foot2 is not None) and P.legfun2:
        l2 = np.sqrt((hip[0] - P.x_foot2)**2 + hip[1]**2)
        ldot2 = .5 / np.sqrt(l2) * (2. * (hip[0] - P.x_foot2) * vhip[0] +
                                    2. * hip[1] * vhip[1])
        Fleg2 = P.legfun2(t, l2, ldot2, P.legpars2)

    # calculate required torques at each hip (1 & 2)
    T1 = 0
    F1 = np.array([0, 0])
    if Fleg1:
        vpp1 = (x - P.r_vpp1 * np.sin(P.a_vpp1 + phi),
                y + P.r_vpp1 * np.cos(P.a_vpp1 + phi))
        dir_f1 = np.array([vpp1[0] - P.x_foot1, vpp1[1]])
        dir_f1 = dir_f1 / li.norm(dir_f1)
        F1 = Fleg1 * dir_f1
        dir_l1 = np.array([P.x_foot1 - hip[0], -hip[1]])
        dir_l1 = dir_l1 / li.norm(dir_l1)
        leg1 = l1 * dir_l1
        T1_T = leg1[0] * F1[1] - leg1[1] * F1[0]
        # don't forget the torque created by Fxr_hip
        T1_F = (hip[0] - x) * F1[1] - (hip[1] - y) * F1[0]
        T1 = T1_T + T1_F

    T2 = 0
    F2 = np.array([0, 0])
    if Fleg2:
        # trunk leg angle
        vpp2 = (x - P.r_vpp2 * np.sin(P.a_vpp2 + phi),
                y + P.r_vpp2 * np.cos(P.a_vpp2 + phi))
        dir_f2 = np.array([vpp2[0] - P.x_foot2, vpp2[1]])
        dir_f2 = dir_f2 / li.norm(dir_f2)
        F2 = Fleg2 * dir_f2
        dir_l2 = np.array([P.x_foot2 - hip[0], -hip[1]])
        dir_l2 = dir_l2 / li.norm(dir_l2)
        leg2 = l2 * dir_l2
        T2_T = leg2[0] * F2[1] - leg2[1] * F2[0]
        # don't forget the torque created by Fxr_hip
        T2_F = (hip[0] - x) * F2[1] - (hip[1] - y) * F2[0]
        T2 = T2_T + T2_F

    F = F1 + F2
    if not output_forces:
        return [
            vx, vy, vphi, F[0] / P.m + P.g[0], F[1] / P.m + P.g[1],
            (T1 + T2) / P.J
        ]
    else:
        return [F1, F2, T1, T2]