def parseLine(line, i):
    # check that line starts with joint_states
    if line [0] != 'joint_states':
        raise RuntimeError('line {} does not start by keyword "joint_states"'
                            .format(i))
    # look for keyword
    ilg = irg = None
    # make sure that one and only one of 'left_gripper' and 'right_gripper'
    # is specified in the current line.
    try:
        ilg = line.index('left_gripper')
    except ValueError as exc:
        pass
    try:
        irg = line.index('right_gripper')
    except ValueError as exc:
        pass
    if irg is None and ilg is None:
        raise SyntaxError \
           ('line {} contains neither "left_gripper" nor "right_gripper" tag.'
             .format(i+1))
    if not irg is None and not ilg is None:
        raise SyntaxError \
           ('line {} contains both "left_gripper" and "right_gripper" tags.'
             .format(i+1))
    measurement = dict()
    if ilg:
        try:
            measurement['joint_states'] = map(float, line [1:ilg])
        except ValueError as exc:
            raise SyntaxError\
           ('line {}, tag "joint_states": could not convert list {} to array'.
                               format(i+1, line [1:ilg]))
        try:
            v = map(float, line [ilg+1:])
            p = Quaternion(x=v[3], y=v[4], z=v[5], w=v[6])
            t = np.array(v[0:3]).reshape(3,1)
            measurement ['left_gripper'] = SE3(p,t)
        except ValueError as exc:
            raise SyntaxError\
           ('line {}, tag "left_gripper": could not convert list {} to array'.
                               format(i+1, line [ilg+1:]))
    if irg:
        try:
            measurement ['joint_states'] = map(float, line [1:irg])
        except ValueError as exc:
            raise SyntaxError\
           ('line {}, tag "joint_states": could not convert list {} to float'.
                               format(i+1, line [1:irg]))
        try:
            v = map(float, line [irg+1:])
            p = Quaternion(x=v[3], y=v[4], z=v[5], w=v[6])
            t = np.array(v[0:3]).reshape(3,1)
            measurement ['right_gripper'] =  SE3(p,t)
        except ValueError as exc:
            raise SyntaxError\
           ('line {}, tag "right_gripper": could not convert list {} to float'.
                               format(i+1, line [irg+1:]))
    return measurement
Beispiel #2
0
    def createArm3DOF(self,
                      rootId=0,
                      prefix='',
                      jointPlacement=SE3.Identity()):
        color = [red, green, blue, transparency] = [1, 1, 0.78, 1.0]
        colorred = [1.0, 0.0, 0.0, 1.0]

        jointId = rootId

        jointName = prefix + "shoulder_joint"
        joint = JointModelRX()
        jointId = self.model.addJoint(jointId, joint, jointPlacement,
                                      jointName)
        self.model.appendBodyToJoint(jointId, Inertia.Random(), SE3.Identity())
        self.viewer.viewer.gui.addSphere('world/' + prefix + 'shoulder', 0.3,
                                         colorred)
        self.visuals.append(
            Visual('world/' + prefix + 'shoulder', jointId, SE3.Identity()))
        self.viewer.viewer.gui.addBox('world/' + prefix + 'upperarm', .1, .1,
                                      .5, color)
        self.visuals.append(
            Visual('world/' + prefix + 'upperarm', jointId,
                   SE3(eye(3), np.array([0., 0., .5]))))

        jointName = prefix + "elbow_joint"
        jointPlacement = SE3(eye(3), np.array([0, 0, 1.0]))
        joint = JointModelRX()
        jointId = self.model.addJoint(jointId, joint, jointPlacement,
                                      jointName)
        self.model.appendBodyToJoint(jointId, Inertia.Random(), SE3.Identity())
        self.viewer.viewer.gui.addSphere('world/' + prefix + 'elbow', 0.3,
                                         colorred)
        self.visuals.append(
            Visual('world/' + prefix + 'elbow', jointId, SE3.Identity()))
        self.viewer.viewer.gui.addBox('world/' + prefix + 'lowerarm', .1, .1,
                                      .5, color)
        self.visuals.append(
            Visual('world/' + prefix + 'lowerarm', jointId,
                   SE3(eye(3), np.array([0., 0., .5]))))

        jointName = prefix + "wrist_joint"
        jointPlacement = SE3(eye(3), np.array([0, 0, 1.0]))
        joint = JointModelRX()
        jointId = self.model.addJoint(jointId, joint, jointPlacement,
                                      jointName)
        self.model.appendBodyToJoint(jointId, Inertia.Random(), SE3.Identity())
        self.viewer.viewer.gui.addSphere('world/' + prefix + 'wrist', 0.3,
                                         colorred)
        self.visuals.append(
            Visual('world/' + prefix + 'wrist', jointId, SE3.Identity()))
        self.viewer.viewer.gui.addBox('world/' + prefix + 'hand', .1, .1, .25,
                                      color)
        self.visuals.append(
            Visual('world/' + prefix + 'hand', jointId,
                   SE3(eye(3), np.array([0., 0., .25]))))
Beispiel #3
0
    def __init__(self, debug: bool = False, **kwargs):
        # Get the urdf and mesh paths
        data_root_dir = resource_filename("gym_jiminy.envs",
                                          "data/bipedal_robots/cassie")
        urdf_path = os.path.join(data_root_dir, "cassie.urdf")

        # Initialize the walker environment
        super().__init__(
            **{
                **dict(urdf_path=urdf_path,
                       mesh_path=data_root_dir,
                       simu_duration_max=SIMULATION_DURATION,
                       step_dt=STEP_DT,
                       reward_mixture=REWARD_MIXTURE,
                       std_ratio=STD_RATIO,
                       avoid_instable_collisions=False,
                       debug=debug),
                **kwargs
            })

        # Add missing pushrod close kinematic chain constraint
        M_pushrod_tarsus_right = SE3(np.eye(3), np.array([-0.12, 0.03,
                                                          -0.005]))
        M_pushrod_hip_right = SE3(np.eye(3), np.array([0.0, 0.0, -0.045]))
        self.robot.add_frame("right_pushrod_tarsus", "right_tarsus",
                             M_pushrod_tarsus_right)
        self.robot.add_frame("right_pushrod_hip", "hip_flexion_right",
                             M_pushrod_hip_right)
        pushrod_right = DistanceConstraint("right_pushrod_tarsus",
                                           "right_pushrod_hip", 0.5012)
        self.robot.add_constraint("pushrod_right", pushrod_right)
        M_pushrod_tarsus_left = SE3(np.eye(3), np.array([-0.12, 0.03, 0.005]))
        M_pushrod_hip_left = SE3(np.eye(3), np.array([0.0, 0.0, 0.045]))
        self.robot.add_frame("left_pushrod_tarsus", "left_tarsus",
                             M_pushrod_tarsus_left)
        self.robot.add_frame("left_pushrod_hip", "hip_flexion_left",
                             M_pushrod_hip_left)
        pushrod_left = DistanceConstraint("left_pushrod_tarsus",
                                          "left_pushrod_hip", 0.5012)
        self.robot.add_constraint("pushrod_left", pushrod_left)

        # Replace knee to shin spring by fixed joint constraint
        right_spring_knee_to_shin = JointConstraint("knee_to_shin_right")
        self.robot.add_constraint("right_spring_knee_to_shin",
                                  right_spring_knee_to_shin)
        left_spring_knee_to_shin = JointConstraint("knee_to_shin_left")
        self.robot.add_constraint("left_spring_knee_to_shin",
                                  left_spring_knee_to_shin)
Beispiel #4
0
    def setCameraTransform(self,
                           translation=np.zeros(3),
                           rotation=np.zeros(3),
                           relative=False):
        # translation : [Px, Py, Pz],
        # rotation : [Roll, Pitch, Yaw]

        R_pnc = rpyToMatrix(np.array(rotation))
        if Viewer.backend == 'gepetto-gui':
            H_abs = SE3(R_pnc, np.array(translation))
            if relative:
                H_orig = XYZQUATToSe3(
                    self._client.getCameraTransform(self._window_id))
                H_abs = H_abs * H_orig
            self._client.setCameraTransform(self._window_id,
                                            se3ToXYZQUAT(H_abs).tolist())
        else:
            if relative:
                raise RuntimeError(
                    "'relative'=True not available with meshcat.")
            import meshcat.transformations as tf
            # Transformation of the camera object
            T_meshcat = tf.translation_matrix(translation)
            self._client.viewer[
                "/Cameras/default/rotated/<object>"].set_transform(T_meshcat)
            # Orientation of the camera object
            Q_pnc = Quaternion(R_pnc).coeffs()
            Q_meshcat = np.roll(Q_pnc, shift=1)
            R_meshcat = tf.quaternion_matrix(Q_meshcat)
            self._client.viewer["/Cameras/default"].set_transform(R_meshcat)
Beispiel #5
0
def transQuatToSE3(p):
    from pinocchio import SE3, Quaternion
    from numpy import matrix
    if len(p) != 7:
        raise ValueError("Cannot convert {} to SE3".format(p))
    return SE3(
        Quaternion(p[6], p[3], p[4], p[5]).matrix(),
        matrix(p[0:3]).transpose())
 def __call__(self, T, nu):
     """
     Integrate se3 velocity from SE3 element T
       - T: instance of SE3
       - nu: numpy array of dimension 6 (v,omega)
     """
     q0 = np.array(7*[0.])
     q0[0:3] = T.translation
     q0[3:7] = Quaternion(T.rotation).coeffs()
     q = integrate(self.model,q0,nu)
     return SE3(Quaternion(x=q[3], y=q[4], z=q[5], w=q[6]), q[0:3])
Beispiel #7
0
 def jacobian(self, q):
     self.robot.mass(q)
     com_p = self.robot.com(q)
     cXi= SE3.Identity()
     oXi = self.robot.data.oMi[1]
     cXi.rotation = oXi.rotation
     cXi.translation = oXi.translation - com_p
     M_ff = self.robot.data.M[:6,:]
     M_com = cXi.inverse().np.T * M_ff
     L_dot = M_com[3:,:]
     wXc  = SE3(eye(3),self.robot.position(q,1).inverse()*self.robot.com(q))
     Jang = wXc.action.T[3:,:]*self.robot.mass(q)[:6,:]
     return self._coeff * L_dot[self._mask,:] 
Beispiel #8
0
    def setCameraTransform(self, translation, rotation):
        # translation : [Px, Py, Pz],
        # rotation : [Roll, Pitch, Yaw]

        R_pnc = rpyToMatrix(np.array(rotation))
        if Viewer.backend == 'gepetto-gui':
            T_pnc = np.array(translation)
            T_R = SE3(R_pnc, T_pnc)
            self._client.setCameraTransform(self._window_id,
                                            se3ToXYZQUAT(T_R).tolist())
        else:
            import meshcat.transformations as tf
            # Transformation of the camera object
            T_meshcat = tf.translation_matrix(translation)
            self._client.viewer[
                "/Cameras/default/rotated/<object>"].set_transform(T_meshcat)
            # Orientation of the camera object
            Q_pnc = Quaternion(R_pnc).coeffs()
            Q_meshcat = np.roll(Q_pnc, shift=1)
            R_meshcat = tf.quaternion_matrix(Q_meshcat)
            self._client.viewer["/Cameras/default"].set_transform(R_meshcat)
 def testJacobian(self):
     # Derivatives with respect to q_off
     nj = len(self.joints)
     dq = 1e-6
     self.computeValueAndJacobian()
     J = self.jacobian.copy()
     q_off0 = self.variable.q_off.copy()
     for i in range(nj):
         self.variable.q_off[i] = q_off0[i]-dq
         self.computeValueAndJacobian()
         v0 = self.value.copy()
         self.variable.q_off[i] = q_off0[i]+dq
         self.computeValueAndJacobian()
         v1 = self.value.copy()
         error = (v1 - v0)/(2*dq) - J[:,i:i+1]
         print ("||error|| = {}".format(norm(error)))
     self.variable.q_off = q_off0
     # Derivatives wrt hTc
     hTc0 = SE3(self.variable.hTc)
     for i in range(6):
         nu = np.zeros((6,1))
         nu[i] = -dq
         self.variable.hTc = self.integrate(hTc0, nu)
         self.computeValueAndJacobian()
         v0 = self.value.copy()
         nu[i] = dq
         self.variable.hTc = self.integrate(hTc0, nu)
         self.computeValueAndJacobian()
         v1 = self.value.copy()
         error = (v1 - v0)/(2*dq) - J[:,nj+i:nj+i+1]
         print ("||error|| = {}".format(norm(error)))
     self.variable.hTc = hTc0
     # Derivatives with respect to lwTls
     lwTls0 = SE3(self.variable.lwTls)
     for i in range(6):
         nu = np.zeros((6,1))
         nu[i] = -dq
         self.variable.lwTls = self.integrate(lwTls0, nu)
         self.computeValueAndJacobian()
         v0 = self.value.copy()
         nu[i] = dq
         self.variable.lwTls = self.integrate(lwTls0, nu)
         self.computeValueAndJacobian()
         v1 = self.value.copy()
         error = (v1 - v0)/(2*dq) - J[:,nj+6+i:nj+6+i+1]
         print ("||error|| = {}".format(norm(error)))
     self.variable.lwTls = lwTls0
     # Derivatives with respect to rwTrs
     rwTrs0 = SE3(self.variable.rwTrs)
     for i in range(6):
         nu = np.zeros((6,1))
         nu[i] = -dq
         self.variable.rwTrs = self.integrate(rwTrs0, nu)
         self.computeValueAndJacobian()
         v0 = self.value.copy()
         nu[i] = dq
         self.variable.rwTrs = self.integrate(rwTrs0, nu)
         self.computeValueAndJacobian()
         v1 = self.value.copy()
         error = (v1 - v0)/(2*dq) - J[:,nj+12+i:nj+12+i+1]
         print ("||error|| = {}".format(norm(error)))
     self.variable.rwTrs = rwTrs0
Beispiel #10
0
        print('===CBK=== {0:4d}   {1: 3.2f}   {2: 3.2f}'.format(
            self.nfeval, q[0], q[1]))
        q = np.matrix(q).T
        robot.display(q)
        # place('world/blue', robot.placement(q, robot.rh))
        self.nfeval += 1
        time.sleep(self.dt)


# Question 1-2-3
rh = np.matrix([1.5, 0.1, 1.5]).T  # x,y,z
rf = np.matrix([0., -0.1, 0.0]).T  # x,y,z
lf = np.matrix([0., 0.1, 0.0]).T  # x,y,z
com = np.matrix([0.0, 0.0, 0.5]).T  # x,y,z

place('world/red', SE3(eye(3), rh))
place('world/blue', SE3(eye(3), rf))
place('world/green', SE3(eye(3), lf))
place('world/yellow', SE3(eye(3), com))

cost = Cost(rh, rf, lf, com)

# If the quaternion is not unitary, it does not correspond a valid rotation. The
# behavior is then not mathematically valid and is implementation dependant. In
# our implementation, quaternions with norm larger than one are interpreted as
# rotation+scaling.
print('Optimize with any (non unitary) quaternion')
cost.weightQuat = 0.0
qopt = fmin_bfgs(cost, robot.q0, callback=CallbackLogger(.1))

# We implement the constraint as a cost with high weight. The quaternion is now unitary.
def build_cs_from_sl1m_l1(fb, q_ref, root_end, pb, RF, allfeetpos, use_orientation, use_interpolated_orientation,
                       q_init = None, first_phase = None):
    """
    Build a multicontact_api.ContactSequence from the SL1M outputs, when not using the MIP formulation
    :param fb: an instance of rbprm.Fullbody
    :param q_ref: the reference wholebody configuration of the robot
    :param root_end: the final base position
    :param pb: the SL1M problem dictionary, containing all the contact surfaces and data
    :param RF: the Id of the right feet in the SL1M formulation
    :param allfeetpos: the list of all foot position for each phase, computed by SL1M
    :param use_orientation: if True, change the contact yaw rotation to match the orientation of the base in the guide
    :param use_interpolated_orientation: if True, the feet yaw orientation will 'anticipate' the base orientation
    of the next phase
    :param q_init: the initial wholebody configuration (either this or first_phase should be provided)
    :param first_phase: the first multicontact_api.ContactPhase object (either this or q_init should be provided)
    :return: the multicontact_api.ContactSequence, with all ContactPhase created at the correct placement
    """
    # init contact sequence with first phase : q_ref move at the right root pose and with both feet in contact
    # FIXME : allow to customize that first phase
    cs = ContactSequence(0)
    if q_init:
        addPhaseFromConfig(fb, cs, q_init, [fb.rLegId, fb.lLegId])
    elif first_phase:
        cs.append(first_phase)
    else:
        raise ValueError("build_cs_from_sl1m should have either q_init or first_phase argument defined")

    # loop over all phases of pb and add them to the cs :
    for pId in range(2, len(pb["phaseData"])):  # start at 2 because the first two ones are already done in the q_init
        prev_contactPhase = cs.contactPhases[-1]
        #n = normal(pb["phaseData"][pId])
        phase = pb["phaseData"][pId]
        moving = phase["moving"]
        movingID = fb.lfoot
        if moving == RF:
            movingID = fb.rfoot
        pos = allfeetpos[pId]  # array, desired position for the feet movingID
        pos[2] += EPS_Z  # FIXME it shouldn't be required !!
        # compute desired foot rotation :
        if use_orientation:
            rot = compute_orientation_for_feet_placement(fb, pb, pId, moving, RF, prev_contactPhase, use_interpolated_orientation)
        else:
            rot = Quaternion.Identity()
        placement = SE3()
        placement.translation = np.array(pos).T
        placement.rotation = rot.matrix()
        cs.moveEffectorToPlacement(movingID, placement)

    # final phase :
    # fixme : assume root is in the middle of the last 2 feet pos ...
    q_end = q_ref.tolist() + [0] * 6
    #p_end = (allfeetpos[-1] + allfeetpos[-2]) / 2.
    #for i in range(3):
    #    q_end[i] += p_end[i]
    q_end[0:7] = root_end
    feet_height_end = allfeetpos[-1][2]
    logger.info("feet height final = %s", feet_height_end)
    q_end[2] = feet_height_end + q_ref[2]
    q_end[2] += EPS_Z
    fb.setCurrentConfig(q_end)
    com = fb.getCenterOfMass()
    setFinalState(cs, com, q=q_end)

    return cs
def generateContactSequence():
    #RF,root_init,pb, coms, footpos, allfeetpos, res = runLPScript()
    RF, root_init, root_end, pb, coms, footpos, allfeetpos, res = runLPFromGuideScript(
    )
    multicontact_api.switchToNumpyArray()
    # load scene and robot
    fb, v = initScene(cfg.Robot, cfg.ENV_NAME, True)
    q_init = cfg.IK_REFERENCE_CONFIG.tolist() + [0] * 6
    q_init[0:7] = root_init
    feet_height_init = allfeetpos[0][2]
    print("feet height initial = ", feet_height_init)
    q_init[2] = feet_height_init + cfg.IK_REFERENCE_CONFIG[2]
    q_init[2] += EPS_Z
    #q_init[2] = fb.referenceConfig[2] # 0.98 is in the _path script
    if v:
        v(q_init)

    # init contact sequence with first phase : q_ref move at the right root pose and with both feet in contact
    # FIXME : allow to customize that first phase
    cs = ContactSequence(0)
    addPhaseFromConfig(fb, cs, q_init, [fb.rLegId, fb.lLegId])

    # loop over all phases of pb and add them to the cs :
    for pId in range(
            2, len(pb["phaseData"])
    ):  # start at 2 because the first two ones are already done in the q_init
        prev_contactPhase = cs.contactPhases[-1]
        #n = normal(pb["phaseData"][pId])
        phase = pb["phaseData"][pId]
        moving = phase["moving"]
        movingID = fb.lfoot
        if moving == RF:
            movingID = fb.rfoot
        pos = allfeetpos[pId]  # array, desired position for the feet movingID
        pos[2] += EPS_Z  # FIXME it shouldn't be required !!
        # compute desired foot rotation :
        if cfg.SL1M_USE_ORIENTATION:
            quat0 = Quaternion(pb["phaseData"][pId]["rootOrientation"])
            if pId < len(pb["phaseData"]) - 1:
                quat1 = Quaternion(pb["phaseData"][pId + 1]["rootOrientation"])
            else:
                quat1 = Quaternion(pb["phaseData"][pId]["rootOrientation"])
            if cfg.SL1M_USE_INTERPOLATED_ORIENTATION:
                rot = quat0.slerp(0.5, quat1)
                # check if feets do not cross :
                if moving == RF:
                    qr = rot
                    ql = Quaternion(
                        prev_contactPhase.contactPatch(
                            fb.lfoot).placement.rotation)
                else:
                    ql = rot
                    qr = Quaternion(
                        prev_contactPhase.contactPatch(
                            fb.rfoot).placement.rotation)
                rpy = matrixToRpy((qr * (ql.inverse())).matrix(
                ))  # rotation from the left foot pose to the right one
                if rpy[2, 0] > 0:  # yaw positive, feet are crossing
                    rot = quat0  # rotation of the root, from the guide
            else:
                rot = quat0  # rotation of the root, from the guide
        else:
            rot = Quaternion.Identity()
        placement = SE3()
        placement.translation = np.array(pos).T
        placement.rotation = rot.matrix()
        cs.moveEffectorToPlacement(movingID, placement)

    # final phase :
    # fixme : assume root is in the middle of the last 2 feet pos ...
    q_end = cfg.IK_REFERENCE_CONFIG.tolist() + [0] * 6
    #p_end = (allfeetpos[-1] + allfeetpos[-2]) / 2.
    #for i in range(3):
    #    q_end[i] += p_end[i]
    q_end[0:7] = root_end
    feet_height_end = allfeetpos[-1][2]
    print("feet height final = ", feet_height_end)
    q_end[2] = feet_height_end + cfg.IK_REFERENCE_CONFIG[2]
    q_end[2] += EPS_Z
    fb.setCurrentConfig(q_end)
    com = fb.getCenterOfMass()
    setFinalState(cs, com, q=q_end)
    if cfg.DISPLAY_CS_STONES:
        displaySteppingStones(cs, v.client.gui, v.sceneName, fb)

    return cs, fb, v
 def get_transform(origin):
     from pinocchio import SE3, rpy
     _xyz = [float(v) for v in origin.attrib.get('xyz', '0 0 0').split(' ')]
     _rpy = [float(v) for v in origin.attrib.get('rpy', '0 0 0').split(' ')]
     return SE3(rpy.rpyToMatrix(*_rpy), np.array(_xyz))
 def __init__(self):
     self.model = Model()
     self.model.addJoint(0, JointModelFreeFlyer(), SE3(), "SE3")
Beispiel #15
0
def XYZRPYToSe3(xyzrpy):
    return SE3(rpyToMatrix(xyzrpy[3:]), xyzrpy[:3])
Beispiel #16
0
def createMultiphaseShootingProblem(rmodel, rdata, csw, timeStep):
    """
  Create a Multiphase Shooting problem from the output of the centroidal solver.

  :params rmodel: robot model of type pinocchio::model
  :params rdata: robot data of type pinocchio::data
  :params csw: contact sequence wrapper of type ContactSequenceWrapper
  :params timeStep: Scalar timestep between nodes.

  :returns list of IntegratedActionModels
  """

    # -----------------------
    # Define Cost weights
    class Weights:
        com = 1e1
        regx = 1e-3
        regu = 0.
        swing_patch = 1e6
        forces = 0.
        contactv = 1e3
        # Define state cost vector for WeightedActivation
        ff_orientation = 1e1
        xweight = np.array([0] * 3 + [ff_orientation] * 3 + [1.] * (rmodel.nv - 6) + [1.] * rmodel.nv)
        xweight[range(18, 20)] = ff_orientation
        # for patch in swing_patch:  w.swing_patch.append(100.);
        # Define weights for the impact costs.
        imp_state = 1e2
        imp_com = 1e2
        imp_contact_patch = 1e6
        imp_act_com = m2a([0.1, 0.1, 3.0])

        # Define weights for the terminal costs
        term_com = 1e8
        term_regx = 1e4

    w = Weights()
    # ------------------------

    problem_models = []
    actuationff = ActuationModelFreeFloating(rmodel)
    State = StatePinocchio(rmodel)

    active_contact_patch = set()
    active_contact_patch_prev = set()
    for nphase, phase in enumerate(csw.cs.contact_phases):
        t0 = phase.time_trajectory[0]
        t1 = phase.time_trajectory[-1]
        N = int(round((t1 - t0) / timeStep)) + 1
        contact_model = ContactModelMultiple(rmodel)

        # Add contact constraints for the active contact patches.
        # Add SE3 cost for the non-active contact patches.
        swing_patch = []
        active_contact_patch_prev = active_contact_patch.copy()
        active_contact_patch.clear()
        for patch in csw.ee_map.keys():
            if getattr(phase, patch).active:
                active_contact_patch.add(patch)
                active_contact = ContactModel6D(rmodel,
                                                frame=rmodel.getFrameId(csw.ee_map[patch]),
                                                ref=getattr(phase, patch).placement)
                contact_model.addContact(patch, active_contact)
                # print nphase, "Contact ",patch," added at ", getattr(phase,patch).placement.translation.T
            else:
                swing_patch.append(patch)

        # Check if contact has been added in this phase. If this phase is not zero,
        # add an impulse model to deal with this contact.
        new_contacts = active_contact_patch.difference(active_contact_patch_prev)
        if nphase != 0 and len(new_contacts) != 0:
            # print nphase, "Impact ",[p for p in new_contacts]," added"
            imp_model = ImpulseModelMultiple(
                rmodel, {
                    "Impulse_" + patch: ImpulseModel6D(rmodel, frame=rmodel.getFrameId(csw.ee_map[patch]))
                    for patch in new_contacts
                })
            # Costs for the impulse of a new contact
            cost_model = CostModelSum(rmodel, nu=0)
            # State
            cost_regx = CostModelState(rmodel,
                                       State,
                                       ref=rmodel.defaultState,
                                       nu=actuationff.nu,
                                       activation=ActivationModelWeightedQuad(w.xweight))
            cost_model.addCost("imp_regx", cost_regx, w.imp_state)
            # CoM
            cost_com = CostModelImpactCoM(rmodel, activation=ActivationModelWeightedQuad(w.imp_act_com))
            cost_model.addCost("imp_CoM", cost_com, w.imp_com)
            # Contact Frameplacement
            for patch in new_contacts:
                cost_contact = CostModelFramePlacement(rmodel,
                                                       frame=rmodel.getFrameId(csw.ee_map[patch]),
                                                       ref=SE3(np.identity(3), csw.ee_splines[patch].eval(t0)[0]),
                                                       nu=actuationff.nu)
                cost_model.addCost("imp_contact_" + patch, cost_contact, w.imp_contact_patch)

            imp_action_model = ActionModelImpact(rmodel, imp_model, cost_model)
            problem_models.append(imp_action_model)

        # Define the cost and action models for each timestep in the contact phase.
        # untill [:-1] because in contact sequence timetrajectory, the end-time is
        # also included. e.g., instead of being [0.,0.5], time trajectory is [0,0.5,1.]
        for t in np.linspace(t0, t1, N)[:-1]:
            cost_model = CostModelSum(rmodel, actuationff.nu)

            # For the first node of the phase, add cost v=0 for the contacting foot.
            if t == 0:
                for patch in active_contact_patch:
                    cost_vcontact = CostModelFrameVelocity(rmodel,
                                                           frame=rmodel.getFrameId(csw.ee_map[patch]),
                                                           ref=m2a(Motion.Zero().vector),
                                                           nu=actuationff.nu)
                    cost_model.addCost("contactv_" + patch, cost_vcontact, w.contactv)

            # CoM Cost
            cost_com = CostModelCoM(rmodel, ref=m2a(csw.phi_c.com_vcom.eval(t)[0][:3, :]), nu=actuationff.nu)
            cost_model.addCost("CoM", cost_com, w.com)

            # Forces Cost
            for patch in contact_model.contacts.keys():
                cost_force = CostModelForce(rmodel,
                                            contactModel=contact_model.contacts[patch],
                                            ref=m2a(csw.phi_c.forces[patch].eval(t)[0]),
                                            nu=actuationff.nu)
                cost_model.addCost("forces_" + patch, cost_force, w.forces)
            # Swing patch cost
            for patch in swing_patch:
                cost_swing = CostModelFramePlacement(rmodel,
                                                     frame=rmodel.getFrameId(csw.ee_map[patch]),
                                                     ref=SE3(np.identity(3), csw.ee_splines[patch].eval(t)[0]),
                                                     nu=actuationff.nu)
                cost_model.addCost("swing_" + patch, cost_swing, w.swing_patch)
                # print t, "Swing cost ",patch," added at ", csw.ee_splines[patch].eval(t)[0][:3].T

            # State Regularization
            cost_regx = CostModelState(rmodel,
                                       State,
                                       ref=rmodel.defaultState,
                                       nu=actuationff.nu,
                                       activation=ActivationModelWeightedQuad(w.xweight))
            cost_model.addCost("regx", cost_regx, w.regx)
            # Control Regularization
            cost_regu = CostModelControl(rmodel, nu=actuationff.nu)
            cost_model.addCost("regu", cost_regu, w.regu)

            dmodel = DifferentialActionModelFloatingInContact(rmodel, actuationff, contact_model, cost_model)
            imodel = IntegratedActionModelEuler(dmodel, timeStep=timeStep)
            problem_models.append(imodel)

    # Create Terminal Model.
    contact_model = ContactModelMultiple(rmodel)
    # Add contact constraints for the active contact patches.
    swing_patch = []
    t = t1
    for patch in csw.ee_map.keys():
        if getattr(phase, patch).active:
            active_contact = ContactModel6D(rmodel,
                                            frame=rmodel.getFrameId(csw.ee_map[patch]),
                                            ref=getattr(phase, patch).placement)
            contact_model.addContact(patch, active_contact)
    cost_model = CostModelSum(rmodel, actuationff.nu)
    # CoM Cost
    cost_com = CostModelCoM(rmodel, ref=m2a(csw.phi_c.com_vcom.eval(t)[0][:3, :]), nu=actuationff.nu)
    cost_model.addCost("CoM", cost_com, w.term_com)

    # State Regularization
    cost_regx = CostModelState(rmodel,
                               State,
                               ref=rmodel.defaultState,
                               nu=actuationff.nu,
                               activation=ActivationModelWeightedQuad(w.xweight))
    cost_model.addCost("regx", cost_regx, w.term_regx)

    dmodel = DifferentialActionModelFloatingInContact(rmodel, actuationff, contact_model, cost_model)
    imodel = IntegratedActionModelEuler(dmodel)
    problem_models.append(imodel)
    problem_models.append
    return problem_models
def contactSequenceFromRBPRMConfigs(fb, configs, beginId, endId):
    print "generate contact sequence from planning : "
    global i_sphere
    i_sphere = 0
    #print "MR offset",MRsole_offset
    #print "ML offset",MLsole_offset
    n_double_support = len(configs)
    # config only contains the double support stance
    n_steps = n_double_support * 2 - 1
    # Notice : what we call double support / simple support are in fact the state with all the contacts and the state without the next moving contact
    cs = ContactSequenceHumanoid(n_steps)
    unusedPatch = cs.contact_phases[0].LF_patch.copy()
    unusedPatch.placement = SE3.Identity()
    unusedPatch.active = False

    # for each contact state we must create 2 phase (one with all the contact and one with the next replaced contact(s) broken)
    for stateId in range(beginId, endId + 1):
        # %%%%%%%%%  all the contacts : %%%%%%%%%%%%%
        cs_id = (stateId - beginId) * 2
        config_id = stateId - beginId
        phase_d = cs.contact_phases[cs_id]
        fb.setCurrentConfig(configs[config_id])
        """
        init_guess_for_phase = init_guess_provided
        if init_guess_for_phase:
            c_init_guess = curves_initGuess[config_id]
            t_init_guess = timings_initGuess[config_id]
            init_guess_for_phase = isinstance(c_init_guess,bezier)
            if init_guess_for_phase:
                print "bezier curve provided for config id : "+str(config_id)
        """

        # compute MRF and MLF : the position of the contacts
        q_rl = fb.getJointPosition(fb.rfoot)
        q_ll = fb.getJointPosition(fb.lfoot)
        q_rh = fb.getJointPosition(fb.rhand)
        q_lh = fb.getJointPosition(fb.lhand)

        # feets
        MRF = SE3.Identity()
        MLF = SE3.Identity()
        MRF.translation = np.matrix(q_rl[0:3]).T
        MLF.translation = np.matrix(q_ll[0:3]).T
        if not cfg.FORCE_STRAIGHT_LINE:
            rot_rl = quatFromConfig(q_rl)
            rot_ll = quatFromConfig(q_ll)
            MRF.rotation = rot_rl.matrix()
            MLF.rotation = rot_ll.matrix()

        # apply the transform ankle -> center of contact
        MRF *= fb.MRsole_offset
        MLF *= fb.MLsole_offset

        # hands
        MRH = SE3()
        MLH = SE3()
        MRH.translation = np.matrix(q_rh[0:3]).T
        MLH.translation = np.matrix(q_lh[0:3]).T
        rot_rh = quatFromConfig(q_rh)
        rot_lh = quatFromConfig(q_lh)
        MRH.rotation = rot_rh.matrix()
        MLH.rotation = rot_lh.matrix()

        MRH *= fb.MRhand_offset
        MLH *= fb.MLhand_offset

        phase_d.RF_patch.placement = MRF
        phase_d.LF_patch.placement = MLF
        phase_d.RH_patch.placement = MRH
        phase_d.LH_patch.placement = MLH

        # initial state : Set all new contacts patch (either with placement computed below or unused)
        if stateId == beginId:
            # FIXME : for loop ? how ?
            if fb.isLimbInContact(fb.rLegId, stateId):
                phase_d.RF_patch.active = True
            else:
                phase_d.RF_patch.active = False
            if fb.isLimbInContact(fb.lLegId, stateId):
                phase_d.LF_patch.active = True
            else:
                phase_d.LF_patch.active = False
            if fb.isLimbInContact(fb.rArmId, stateId):
                phase_d.RH_patch.active = True
            else:
                phase_d.RH_patch.active = False
            if fb.isLimbInContact(fb.lArmId, stateId):
                phase_d.LH_patch.active = True
            else:
                phase_d.LH_patch.active = False
        else:
            # we need to copy the unchanged patch from the last simple support phase (and not create a new one with the same placement)
            phase_d.RF_patch = phase_s.RF_patch
            phase_d.RF_patch.active = fb.isLimbInContact(fb.rLegId, stateId)
            phase_d.LF_patch = phase_s.LF_patch
            phase_d.LF_patch.active = fb.isLimbInContact(fb.lLegId, stateId)
            phase_d.RH_patch = phase_s.RH_patch
            phase_d.RH_patch.active = fb.isLimbInContact(fb.rArmId, stateId)
            phase_d.LH_patch = phase_s.LH_patch
            phase_d.LH_patch.active = fb.isLimbInContact(fb.lArmId, stateId)

            # now we change the contacts that have moved :
            variations = fb.getContactsVariations(stateId - 1, stateId)
            if len(variations) != 1:
                print "Several contact changes between states " + str(
                    stateId -
                    1) + " and " + str(stateId) + " : " + str(variations)
            assert len(
                variations
            ) == 1, "Several changes of contacts in adjacent states, not implemented yet !"
            for var in variations:
                # FIXME : for loop in variation ? how ?
                if var == fb.lLegId:
                    phase_d.LF_patch.placement = MLF
                if var == fb.rLegId:
                    phase_d.RF_patch.placement = MRF
                if var == fb.lArmId:
                    phase_d.LH_patch.placement = MLH
                if var == fb.rArmId:
                    phase_d.RH_patch.placement = MRH

        # retrieve the COM position for init and final state (equal for double support phases)
        init_state = np.matrix(np.zeros(9)).T
        init_state[0:3] = np.matrix(fb.getCenterOfMass()).transpose()
        init_state[3:6] = np.matrix(configs[config_id][-6:-3]).transpose()
        final_state = init_state.copy()
        #phase_d.time_trajectory.append((fb.getDurationForState(stateId))*cfg.DURATION_n_CONTACTS/cfg.SPEED)
        phase_d.init_state = init_state
        phase_d.final_state = final_state
        phase_d.reference_configurations.append(
            np.matrix((configs[config_id])).T)
        #print "done for double support"

        if stateId < endId:
            # %%%%%% simple support : %%%%%%%%
            phase_s = cs.contact_phases[cs_id + 1]
            # copy previous placement :
            phase_s.RF_patch = phase_d.RF_patch
            phase_s.LF_patch = phase_d.LF_patch
            phase_s.RH_patch = phase_d.RH_patch
            phase_s.LH_patch = phase_d.LH_patch
            # find the contact to break :
            variations = fb.getContactsVariations(stateId, stateId + 1)
            if len(variations) != 1:
                print "Several contact changes between states " + str(
                    stateId) + " and " + str(stateId +
                                             1) + " : " + str(variations)
            assert len(
                variations
            ) == 1, "Several changes of contacts in adjacent states, not implemented yet !"
            for var in variations:
                if var == fb.lLegId:
                    phase_s.LF_patch.active = False
                if var == fb.rLegId:
                    phase_s.RF_patch.active = False
                if var == fb.lArmId:
                    phase_s.LH_patch.active = False
                if var == fb.rArmId:
                    phase_s.RH_patch.active = False
            # retrieve the COM position for init and final state

            phase_s.reference_configurations.append(
                np.matrix((configs[config_id])).T)
            init_state = phase_d.init_state.copy()
            final_state = phase_d.final_state.copy()
            fb.setCurrentConfig(configs[config_id + 1])
            final_state[0:3] = np.matrix(fb.getCenterOfMass()).transpose()
            final_state[3:6] = np.matrix(configs[config_id +
                                                 1][-6:-3]).transpose()
            #phase_s.time_trajectory.append((fb.getDurationForState(stateId))*(1-cfg.DURATION_n_CONTACTS)/cfg.SPEED)
            phase_s.init_state = init_state.copy()
            phase_s.final_state = final_state.copy()
            #print "done for single support"

    # assign contact models :
    # only used by muscod ?? But we need to fill it otherwise the serialization fail
    for k, phase in enumerate(cs.contact_phases):
        RF_patch = phase.RF_patch
        cm = RF_patch.contactModel
        cm.mu = cfg.MU
        cm.ZMP_radius = 0.01
        RF_patch.contactModelPlacement = SE3.Identity()
        LF_patch = phase.LF_patch
        cm = LF_patch.contactModel
        cm.mu = cfg.MU
        cm.ZMP_radius = 0.01
        LF_patch.contactModelPlacement = SE3.Identity()
        LH_patch = phase.LH_patch
        cm = LH_patch.contactModel
        cm.mu = cfg.MU
        cm.ZMP_radius = 0.01
        LH_patch.contactModelPlacement = SE3.Identity()
        RH_patch = phase.RH_patch
        cm = RH_patch.contactModel
        cm.mu = cfg.MU
        cm.ZMP_radius = 0.01
        RH_patch.contactModelPlacement = SE3.Identity()

    return cs
Beispiel #18
0
    '''
    This function load a UR5 robot n a new model, move the basis to placement <M0>
    and add the corresponding visuals in gepetto viewer with name prefix given by string <name>.
    It returns the robot wrapper (model,data).
    '''
    robot = RobotWrapper(urdf, [PKG])
    robot.model.jointPlacements[1] = M0 * robot.model.jointPlacements[1]
    robot.visual_model.geometryObjects[0].placement = M0 * robot.visual_model.geometryObjects[0].placement
    robot.visual_data.oMg[0] = M0 * robot.visual_data.oMg[0]
    robot.initDisplay(loadModel=True, viewerRootNodeName="world/" + name)
    return robot


robots = []
# Load 4 Ur5 robots, placed at 0.3m from origin in the 4 directions x,y,-x,-y.
Mt = SE3(eye(3), np.matrix([.3, 0, 0]).T)  # First robot is simply translated
for i in range(4):
    robots.append(loadRobot(SE3(rotate('z', np.pi / 2 * i), zero(3)) * Mt, "robot%d" % i))

# Set up the robots configuration with end effector pointed upward.
q0 = np.matrix([np.pi / 4, -np.pi / 4, -np.pi / 2, np.pi / 4, np.pi / 2, 0]).T
for i in range(4):
    robots[i].display(q0)

# Add a new object featuring the parallel robot tool plate.
gepettoViewer = robots[0].viewer.gui
w, h, d = 0.25, 0.25, 0.005
color = [red, green, blue, transparency] = [1, 1, 0.78, 1.0]
gepettoViewer.addBox('world/toolplate', w, h, d, color)
Mtool = SE3(rotate('z', 1.268), np.matrix([0, 0, .77]).T)
gepettoViewer.applyConfiguration('world/toolplate', se3ToXYZQUATtuple(Mtool))
Beispiel #19
0
def generateContactSequence():
    RF, root_init, pb, coms, footpos, allfeetpos, res = runLPScript()

    # load scene and robot
    fb, v = initScene(cfg.Robot, cfg.ENV_NAME, False)
    q_init = fb.referenceConfig[::] + [0] * 6
    q_init[0:7] = root_init
    #q_init[2] += fb.referenceConfig[2] - 0.98 # 0.98 is in the _path script
    v(q_init)

    # init contact sequence with first phase : q_ref move at the right root pose and with both feet in contact
    # FIXME : allow to customize that first phase
    cs = ContactSequenceHumanoid(0)
    addPhaseFromConfig(fb, v, cs, q_init, [fb.rLegId, fb.lLegId])

    # loop over all phases of pb and add them to the cs :
    for pId in range(
            2, len(pb["phaseData"])
    ):  # start at 2 because the first two ones are already done in the q_init
        prev_contactPhase = cs.contact_phases[-1]
        #n = normal(pb["phaseData"][pId])
        phase = pb["phaseData"][pId]
        moving = phase["moving"]
        movingID = fb.lfoot
        if moving == RF:
            movingID = fb.rfoot
        pos = allfeetpos[pId]  # array, desired position for the feet movingID
        pos[2] += 0.005  # FIXME it shouldn't be required !!
        # compute desired foot rotation :
        if USE_ORIENTATION:
            if pId < len(pb["phaseData"]) - 1:
                quat0 = Quaternion(pb["phaseData"][pId]["rootOrientation"])
                quat1 = Quaternion(pb["phaseData"][pId + 1]["rootOrientation"])
                rot = quat0.slerp(0.5, quat1)
                # check if feets do not cross :
                if moving == RF:
                    qr = rot
                    ql = Quaternion(
                        prev_contactPhase.LF_patch.placement.rotation)
                else:
                    ql = rot
                    qr = Quaternion(
                        prev_contactPhase.RF_patch.placement.rotation)
                rpy = matrixToRpy((qr * (ql.inverse())).matrix(
                ))  # rotation from the left foot pose to the right one
                if rpy[2, 0] > 0:  # yaw positive, feet are crossing
                    rot = Quaternion(phase["rootOrientation"]
                                     )  # rotation of the root, from the guide
            else:
                rot = Quaternion(phase["rootOrientation"]
                                 )  # rotation of the root, from the guide
        else:
            rot = Quaternion.Identity()
        placement = SE3()
        placement.translation = np.matrix(pos).T
        placement.rotation = rot.matrix()
        moveEffectorToPlacement(fb,
                                v,
                                cs,
                                movingID,
                                placement,
                                initStateCenterSupportPolygon=True)
    # final phase :
    # fixme : assume root is in the middle of the last 2 feet pos ...
    q_end = fb.referenceConfig[::] + [0] * 6
    p_end = (allfeetpos[-1] + allfeetpos[-2]) / 2.
    for i in range(3):
        q_end[i] += p_end[i]
    setFinalState(cs, q=q_end)

    displaySteppingStones(cs, v.client.gui, v.sceneName, fb)

    return cs, fb, v
Beispiel #20
0
def transQuatToSE3(p):
    from pinocchio import SE3, Quaternion
    from numpy import matrix
    return SE3(
        Quaternion(p[6], p[3], p[4], p[5]).matrix(),
        matrix(p[0:3]).transpose())
    def histogram(self):
        # Build and display an histogram of the measurement errors stored
        # in self.value
        # the output is stored in self.errors
        import matplotlib.pyplot as plt
        self.errors = np.zeros(len(self.value)/6)
        for i in range(len(self.errors)):
            self.errors[i] = norm(self.value[6*i:6*i+6])
        fig,axs = plt.subplots(1,1)
        axs.hist(self.errors, bins=20)
        fig.show()

if __name__ == '__main__':
    filename = os.getenv('DEVEL_HPP_DIR') + \
               '/install/share/talos_data/urdf/pyrene.urdf'

    nj = len(ComputeCalibration.joints)
    q_off = np.array(nj*[0.]).reshape(nj, 1)
    hTc = SE3(Quaternion(x=-0.500, y=0.500, z=-0.500, w=0.500),
              np.array([0.066, 0.013, 0.198]).reshape(3,1))
    lwTls = SE3(Quaternion(x=0, y=0, z=0, w=1),
                np.array([0.000, 0.000, -0.092]).reshape(3,1))
    rwTrs = SE3(Quaternion(x=0, y=0, z=1, w=0),
                np.array([0.000, 0.000, -0.092]).reshape(3,1))
    cc=ComputeCalibration(filename, Variable(q_off,hTc,lwTls,rwTrs))
    cc.readData('data/measurements-pyrene-20200819-1-filtered.csv')

    for i in range (20):
        cc.solve()
        print ("||error|| = {}".format(norm(cc.value)))