def callback_torques():
    global v_prev, solo, stop, q

    jointStates = p.getJointStates(robotId,
                                   revoluteJointIndices)  # State of all joints
    baseState = p.getBasePositionAndOrientation(robotId)
    baseVel = p.getBaseVelocity(robotId)

    # Info about contact points with the ground
    contactPoints_FL = p.getContactPoints(robotId, planeId,
                                          linkIndexA=2)  # Front left  foot
    contactPoints_FR = p.getContactPoints(robotId, planeId,
                                          linkIndexA=5)  # Front right foot
    contactPoints_HL = p.getContactPoints(robotId, planeId,
                                          linkIndexA=8)  # Hind  left  foot
    contactPoints_HR = p.getContactPoints(robotId, planeId,
                                          linkIndexA=11)  # Hind  right foot

    # Sort contacts points to get only one contact per foot
    contactPoints = []
    contactPoints.append(getContactPoint(contactPoints_FL))
    contactPoints.append(getContactPoint(contactPoints_FR))
    contactPoints.append(getContactPoint(contactPoints_HL))
    contactPoints.append(getContactPoint(contactPoints_HR))

    # Joint vector for Pinocchio
    q = np.vstack(
        (np.array([baseState[0]]).transpose(), np.array([baseState[1]
                                                         ]).transpose(),
         np.array([[
             jointStates[i_joint][0] for i_joint in range(len(jointStates))
         ]]).transpose()))
    v = np.vstack(
        (np.array([baseVel[0]]).transpose(), np.array([baseVel[1]
                                                       ]).transpose(),
         np.array([[
             jointStates[i_joint][1] for i_joint in range(len(jointStates))
         ]]).transpose()))
    v_dot = (v - v_prev) / h
    v_prev = v.copy()

    # Update display in Gepetto-gui
    solo.display(q)

    ########################################################################

    ### Space mouse configuration
    # return the next event if there is any
    event = sp.poll()

    # if event signals the release of the first button
    # exit condition : the button 0 is pressed and released
    if type(event) is sp.ButtonEvent \
        and event.button == 0 and event.pressed == 0:
        # set exit condition
        stop = True

    # matching the mouse signals with the position of Solo's basis
    if type(event) is sp.MotionEvent:
        Vroll = -event.rx / 100.0  #velocity related to the roll axis
        Vyaw = event.ry / 100.0  #velocity related to the yaw axis
        Vpitch = -event.rz / 100.0  #velocity related to the pitch axis
        rpy[0] += Vroll * dt  #roll
        rpy[1] += Vpitch * dt  #pitch
        rpy[2] += Vyaw * dt  #yaw
        # adding saturation to prevent unlikely configurations
        for i in range(2):
            if rpy[i] > 0.175 or rpy[i] < -0.175:
                rpy[i] = np.sign(rpy[i]) * 0.175
        # convert rpy to quaternion
        quatMat = pin.utils.rpyToMatrix(np.matrix(rpy).T)
        # add the modified component to the quaternion
        q[3] = Quaternion(quatMat)[0]
        q[4] = Quaternion(quatMat)[1]
        q[5] = Quaternion(quatMat)[2]
        q[6] = Quaternion(quatMat)[3]

    ### Stack of Task : feet on the ground and posture

    # compute/update all joints and frames
    pin.forwardKinematics(solo.model, solo.data, q)
    pin.updateFramePlacements(solo.model, solo.data)

    # Getting the current height (on axis z) of each foot
    hFL = solo.data.oMf[ID_FL].translation[2]
    hFR = solo.data.oMf[ID_FR].translation[2]
    hHL = solo.data.oMf[ID_HL].translation[2]
    hHR = solo.data.oMf[ID_HR].translation[2]

    # Computing the error in the world frame
    err_FL = np.concatenate((np.zeros([2, 1]), hFL))
    err_FR = np.concatenate((np.zeros([2, 1]), hFR))
    err_HL = np.concatenate((np.zeros([2, 1]), hHL))
    err_HR = np.concatenate((np.zeros([2, 1]), hHR))

    # Error of posture
    err_post = q - qdes

    # Computing the error in the local frame
    oR_FL = solo.data.oMf[ID_FL].rotation
    oR_FR = solo.data.oMf[ID_FR].rotation
    oR_HL = solo.data.oMf[ID_HL].rotation
    oR_HR = solo.data.oMf[ID_HR].rotation

    # Getting the different Jacobians
    fJ_FL3 = pin.frameJacobian(solo.model, solo.data, q,
                               ID_FL)[:3,
                                      -8:]  #Take only the translation terms
    oJ_FL3 = oR_FL * fJ_FL3  #Transformation from local frame to world frame
    oJ_FLz = oJ_FL3[2, -8:]  #Take the z_component

    fJ_FR3 = pin.frameJacobian(solo.model, solo.data, q, ID_FR)[:3, -8:]
    oJ_FR3 = oR_FR * fJ_FR3
    oJ_FRz = oJ_FR3[2, -8:]

    fJ_HL3 = pin.frameJacobian(solo.model, solo.data, q, ID_HL)[:3, -8:]
    oJ_HL3 = oR_HL * fJ_HL3
    oJ_HLz = oJ_HL3[2, -8:]

    fJ_HR3 = pin.frameJacobian(solo.model, solo.data, q, ID_HR)[:3, -8:]
    oJ_HR3 = oR_HR * fJ_HR3
    oJ_HRz = oJ_HR3[2, -8:]

    # Displacement and posture error
    nu = np.vstack(
        [err_FL[2], err_FR[2], err_HL[2], err_HR[2], omega * err_post[7:]])

    # Making a single z-row Jacobian vector plus the posture Jacobian
    J = np.vstack([oJ_FLz, oJ_FRz, oJ_HLz, oJ_HRz, omega * J_post])

    # Computing the velocity
    vq_act = -Kp * pinv(J) * nu
    vq = np.concatenate((np.zeros([6, 1]), vq_act))

    # Computing the updated configuration
    q = pin.integrate(solo.model, q, vq * dt)

    #hist_err.append(np.linalg.norm(nu))
    #hist_err.append(err_post[7:])

    ########################################################################

    # PD Torque controller
    Kp_PD = 0.05
    Kd_PD = 80 * Kp_PD
    #Kd = 2 * np.sqrt(2*Kp) # formula to get a critical damping
    torques = Kd_PD * (qdes[7:] - q[7:]) - Kp_PD * v[6:]

    # Saturation to limit the maximal torque
    t_max = 5
    torques = np.maximum(np.minimum(torques, t_max * np.ones((8, 1))),
                         -t_max * np.ones((8, 1)))

    return torques, stop
Exemple #2
0
    return np.matrix([x, z])


# Getting the frame index of each foot
ID_FL = solo.model.getFrameId("FL_FOOT")
ID_FR = solo.model.getFrameId("FR_FOOT")
ID_HL = solo.model.getFrameId("HL_FOOT")
ID_HR = solo.model.getFrameId("HR_FOOT")

hist_err = []  #history of the error

# loop over space navigator events
while not stop:
    ### Space mouse configuration : exit the loop when 0 is pressed and released
    # return the next event if there is any
    event = sp.poll()

    # if event signals the release of the first button
    if type(event) is sp.ButtonEvent \
     and event.button == 0 and event.pressed == 0:
        # set exit condition
        stop = True

    ### Stack of Task : walking
    pin.forwardKinematics(solo.model, solo.data, q)
    pin.updateFramePlacements(solo.model, solo.data)

    # Getting the current height (on axis z) and the x-coordinate of the front left foot
    xz_FL = solo.data.oMf[ID_FL].translation[0::2]
    xz_FR = solo.data.oMf[ID_FR].translation[0::2]
    xz_HL = solo.data.oMf[ID_HL].translation[0::2]
Exemple #3
0
def callback_torques():
    global v_prev, solo, stop, q, qdes, t

    t_start = time()

    jointStates = p.getJointStates(robotId,
                                   revoluteJointIndices)  # State of all joints
    baseState = p.getBasePositionAndOrientation(robotId)
    baseVel = p.getBaseVelocity(robotId)

    # Info about contact points with the ground
    contactPoints_FL = p.getContactPoints(robotId, planeId,
                                          linkIndexA=2)  # Front left  foot
    contactPoints_FR = p.getContactPoints(robotId, planeId,
                                          linkIndexA=5)  # Front right foot
    contactPoints_HL = p.getContactPoints(robotId, planeId,
                                          linkIndexA=8)  # Hind  left  foot
    contactPoints_HR = p.getContactPoints(robotId, planeId,
                                          linkIndexA=11)  # Hind  right foot

    # Sort contacts points to get only one contact per foot
    contactPoints = []
    contactPoints.append(getContactPoint(contactPoints_FL))
    contactPoints.append(getContactPoint(contactPoints_FR))
    contactPoints.append(getContactPoint(contactPoints_HL))
    contactPoints.append(getContactPoint(contactPoints_HR))

    # Joint vector for Pinocchio
    q = np.vstack(
        (np.array([baseState[0]]).transpose(), np.array([baseState[1]
                                                         ]).transpose(),
         np.array([[
             jointStates[i_joint][0] for i_joint in range(len(jointStates))
         ]]).transpose()))
    v = np.vstack(
        (np.array([baseVel[0]]).transpose(), np.array([baseVel[1]
                                                       ]).transpose(),
         np.array([[
             jointStates[i_joint][1] for i_joint in range(len(jointStates))
         ]]).transpose()))
    v_dot = (v - v_prev) / h
    v_prev = v.copy()

    # Update display in Gepetto-gui
    solo.display(q)

    ########################################################################

    ### Space mouse configuration : exit the loop when 0 is pressed and released

    event = sp.poll()  # return the next event if there is any

    # if event signals the release of the first button
    # exit condition : the button 0 is pressed and released
    if type(event
            ) is sp.ButtonEvent and event.button == 0 and event.pressed == 0:
        # set exit condition
        stop = True

    ### Stack of Task : walking
    #compute/update all the joints and frames
    pin.forwardKinematics(solo.model, solo.data, qdes)
    pin.updateFramePlacements(solo.model, solo.data)

    # Getting the current height (on axis z) and the x-coordinate of the front left foot
    xz_FL = solo.data.oMf[ID_FL].translation[0::2]
    xz_FR = solo.data.oMf[ID_FR].translation[0::2]
    xz_HL = solo.data.oMf[ID_HL].translation[0::2]
    xz_HR = solo.data.oMf[ID_HR].translation[0::2]

    # Desired foot trajectory
    t1 = t  #previous time
    t += dt
    t2 = t  #current time
    xzdes_FL = ftraj(t, xF0, zF0)
    xzdes_HR = ftraj(t, xH0, zH0)
    xzdes_FR = ftraj(t + T / 2, xF0, zF0)
    xzdes_HL = ftraj(t + T / 2, xH0, zH0)

    # Calculating the error
    err_FL = xz_FL - xzdes_FL
    err_FR = xz_FR - xzdes_FR
    err_HL = xz_HL - xzdes_HL
    err_HR = xz_HR - xzdes_HR

    # Computing the local Jacobian into the global frame
    oR_FL = solo.data.oMf[ID_FL].rotation
    oR_FR = solo.data.oMf[ID_FR].rotation
    oR_HL = solo.data.oMf[ID_HL].rotation
    oR_HR = solo.data.oMf[ID_HR].rotation

    # Getting the different Jacobians
    fJ_FL3 = pin.frameJacobian(solo.model, solo.data, qdes,
                               ID_FL)[:3,
                                      -8:]  #Take only the translation terms
    oJ_FL3 = oR_FL * fJ_FL3  #Transformation from local frame to world frame
    oJ_FLxz = oJ_FL3[0::2, -8:]  #Take the x and z components

    fJ_FR3 = pin.frameJacobian(solo.model, solo.data, qdes, ID_FR)[:3, -8:]
    oJ_FR3 = oR_FR * fJ_FR3
    oJ_FRxz = oJ_FR3[0::2, -8:]

    fJ_HL3 = pin.frameJacobian(solo.model, solo.data, qdes, ID_HL)[:3, -8:]
    oJ_HL3 = oR_HL * fJ_HL3
    oJ_HLxz = oJ_HL3[0::2, -8:]

    fJ_HR3 = pin.frameJacobian(solo.model, solo.data, qdes, ID_HR)[:3, -8:]
    oJ_HR3 = oR_HR * fJ_HR3
    oJ_HRxz = oJ_HR3[0::2, -8:]

    # Displacement error
    nu = np.vstack([err_FL, err_FR, err_HL, err_HR])

    # Making a single x&z-rows Jacobian vector
    J = np.vstack([oJ_FLxz, oJ_FRxz, oJ_HLxz, oJ_HRxz])

    # Computing the velocity
    vq_act = -Kp * pinv(J) * nu
    vq = np.concatenate((np.zeros([6, 1]), vq_act))

    # Computing the updated configuration
    qdes = pin.integrate(solo.model, qdes, vq * dt)

    #hist_err.append(np.linalg.norm(nu))

    ########################################################################

    # PD Torque controller
    Kp_PD = 0.05
    Kd_PD = 120 * Kp_PD
    #Kd = 2 * np.sqrt(2*Kp) # formula to get a critical damping
    torques = Kd_PD * (qdes[7:] - q[7:]) - Kp_PD * v[6:]

    # Saturation to limit the maximal torque
    t_max = 5
    torques = np.maximum(np.minimum(torques, t_max * np.ones((8, 1))),
                         -t_max * np.ones((8, 1)))

    # Control loop of 1/dt Hz
    while (time() - t_start) < dt:
        sleep(10e-6)

    return torques, stop