예제 #1
0
    def get_deep_reward(self):
        r_q = mm.square_sum(self.get_q() - self.reset_q)
        # r_com = mm.square_sum(self.getCOM() - self.com_des)

        com_plane = self.getCOM()
        com_plane[1] = 0.
        com_des_plane = self.body_foot_R.com() + self.body_foot_L.com()
        com_des_plane[1] = 0.

        r_com = mm.square_sum(com_plane - com_des_plane)
        r_foot = mm.square_sum([
            self.body_foot_L.to_world()[1],
            self.body_foot_R.to_world()[1], 0.
        ])
        # r_foot_ori = mm.square_sum([self.body_foot_L.world_transform(), self.body_foot_R.to_world()[1], 0.])
        foot_L_cos_ang = np.dot(self.body_foot_L.world_transform()[:3, 1],
                                mm.unitY())
        foot_R_cos_ang = np.dot(self.body_foot_L.world_transform()[:3, 1],
                                mm.unitY())
        if foot_L_cos_ang > 1.:
            foot_L_cos_ang = 0.999999
        elif foot_L_cos_ang < -1.:
            foot_L_cos_ang = -0.999999
        if foot_R_cos_ang > 1.:
            foot_R_cos_ang = 0.999999
        elif foot_R_cos_ang < -1.:
            foot_R_cos_ang = -0.999999
        foot_L_ang = math.acos(foot_L_cos_ang)
        foot_R_ang = math.acos(foot_R_cos_ang)
        r_foot_ori = foot_L_ang * foot_L_ang + foot_R_ang * foot_R_ang
        return self.w_alive + self.w_com * math.exp(-self.w_com_exp * r_com) \
               + self.w_q * math.exp(-self.w_q_exp * r_q) \
               + self.w_foot * math.exp(-self.w_foot_exp * r_foot) \
               + self.w_foot_ori * math.exp(-self.w_foot_ori_exp * r_foot_ori)
예제 #2
0
    def update_goal_in_local_frame(self, reset=False):
        if not reset:
            self.prev_goal = self.goal.copy()
        body_transform = self.skel.body(0).world_transform()
        goal_vector_in_world_frame = self.goal_in_world_frame - body_transform[:
                                                                               3,
                                                                               3]
        goal_vector_in_world_frame[1] = 0.
        radius = mm.length(goal_vector_in_world_frame)
        unit_goal_vector_in_world_frame = mm.normalize(
            goal_vector_in_world_frame)
        root_x_in_world_plane = body_transform[:3, 0]
        root_x_in_world_plane[1] = 0.
        unit_root_x_in_world_plane = mm.seq2Vec3(
            mm.normalize(root_x_in_world_plane))
        unit_root_z_in_world_plane = mm.cross(unit_root_x_in_world_plane,
                                              mm.unitY())
        # angle = atan2(np.dot(unit_root_x_in_world_plane, unit_goal_vector_in_world_frame), np.dot(unit_root_z_in_world_plane, unit_goal_vector_in_world_frame))

        self.goal = radius * np.array([
            np.dot(unit_root_x_in_world_plane,
                   unit_goal_vector_in_world_frame),
            np.dot(unit_root_z_in_world_plane, unit_goal_vector_in_world_frame)
        ])
        if reset:
            self.prev_goal = self.goal.copy()
예제 #3
0
def fix_motion_data_by_foot(motion, skel, SEGMENT_FOOT_RAD):
    """

    :param motion:
    :type motion: ym.JointMotion
    :param skel:
    :type skel: pydart.Skeleton
    :param SEGMENT_FOOT_RAD:
    :type SEGMENT_FOOT_RAD: float
    :return:
    """
    for i in range(len(motion)):
        skel.set_positions(motion.get_q(i))
        min_joint_y = np.inf
        for body in skel.bodynodes:
            for shapenode in body.shapenodes:
                if shapenode.has_collision_aspect():
                    joint_y = np.dot(body.world_transform(),
                                     shapenode.relative_transform())[1, 3]
                    if min_joint_y > joint_y:
                        min_joint_y = joint_y

        if min_joint_y < SEGMENT_FOOT_RAD:
            motion[i].translateByOffset(
                (SEGMENT_FOOT_RAD - min_joint_y) * mm.unitY())
예제 #4
0
    def preFrameCallback_Always(frame):
        # print(mm.rad2Deg(math.pi/6.*math.sin((frame-30)*math.pi/180.)))
        if frame <= start_frame:
            vpWorld.set_plane(0, mm.unitY(), np.zeros(3))
        if frame > start_frame:
            if math.sin((frame - start_frame) / 360. * math.pi) > 0.:
                if frame < start_frame + 50:
                    setParamVal(
                        'com Z offset', 0.02 *
                        math.sin(2. * (frame - start_frame) / 360. * math.pi))
                else:
                    setParamVal('com Z offset', 0.0)

                if math.sin((frame - start_frame) / 360. * math.pi) > 0.:
                    foot_viewer.check_not_all_seg()
                    foot_viewer.check_tiptoe_all()
                    setParamVal(
                        'tiptoe angle',
                        mm.deg2Rad(10.) * math.sin(
                            (frame - start_frame) / 360. * math.pi))
                    # foot_viewer.check_h_l.value(False)
                    # foot_viewer.check_h_r.value(False)
                else:
                    foot_viewer.check_all_seg()
                    # foot_viewer.check_tiptoe_all()
                    # foot_viewer.check_h_l.value(True)
                    # foot_viewer.check_h_r.value(True)
                vpWorld.set_plane(
                    0,
                    np.dot(
                        mm.exp(
                            -mm.unitX(),
                            mm.deg2Rad(10.) * math.sin(
                                (frame - start_frame) / 360. * math.pi)),
                        mm.unitY()), np.zeros(3))
        plane_list = vpWorld.get_plane_list()
        plane_normal = plane_list[0][0]
        plane_origin = plane_list[0][1]
        viewer.motionViewWnd.glWindow.pOnPlaneshadow = plane_origin + plane_normal * 0.001
        viewer.motionViewWnd.glWindow.normalshadow = plane_normal
    def fix_dofs(_DOFs, nested_dof_values, _mcfg, _joint_names):
        fixed_nested_dof_values = list()
        fixed_nested_dof_values.append(nested_dof_values[0])
        for i in range(1, len(_DOFs)):
            dof = _DOFs[i]
            if dof == 1:
                node = _mcfg.getNode(_joint_names[i])
                axis = mm.unitZ()
                if node.jointAxes[0] == 'X':
                    axis = mm.unitX()
                elif node.jointAxes[0] == 'Y':
                    axis = mm.unitY()
                fixed_nested_dof_values.append(np.array([np.dot(nested_dof_values[i], axis)]))
            else:
                fixed_nested_dof_values.append(nested_dof_values[i])

        return fixed_nested_dof_values
예제 #6
0
def fix_motion_data_by_foot(motion, control_model, world):
    """

    :param motion:
    :type motion: ym.JointMotion
    :param control_model:
    :type control_model: cvm.VpControlModel
    :param world:
    :type world: cvw.VpWorld
    :return:
    """
    for i in range(len(motion)):
        control_model.set_q(motion.get_q(i))
        bodyIDsToCheck = list(range(world.getBodyNum()))
        mus = [.5]*len(bodyIDsToCheck)
        bodyIDs, contactPositions, contactPositionLocals, contactForces = world.calcPenaltyForce(bodyIDsToCheck, mus, 0., 0.)
        min_joint_y = min([contactPosition[1] for contactPosition in contactPositions]) if contactPositions else 0.
        if min_joint_y < 0.:
            motion[i].translateByOffset(-min_joint_y * mm.unitY())
    def simulateCallback(frame):
        # print(frame)
        # print(motion[frame].getJointOrientationLocal(footIdDic['RightFoot_foot_0_1_0']))
        # hfi.footAdjust(motion[frame], idDic, SEGMENT_FOOT_MAG=.03, SEGMENT_FOOT_RAD=.015, baseHeight=0.02)

        if abs(getParamVal('tiptoe angle')) > 0.001:
            tiptoe_angle = getParamVal('tiptoe angle')
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot_foot_0_0_0'],
                mm.exp(mm.unitX(), -math.pi * tiptoe_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot_foot_0_1_0'],
                mm.exp(mm.unitX(), -math.pi * tiptoe_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot_foot_0_0_0'],
                mm.exp(mm.unitX(), -math.pi * tiptoe_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot_foot_0_1_0'],
                mm.exp(mm.unitX(), -math.pi * tiptoe_angle))
            # motion[frame].mulJointOrientationLocal(idDic['LeftFoot'], mm.exp(mm.unitX(), math.pi * tiptoe_angle * 0.95))
            # motion[frame].mulJointOrientationLocal(idDic['RightFoot'], mm.exp(mm.unitX(), math.pi * tiptoe_angle * 0.95))
            # motion[frame].mulJointOrientationLocal(idDic['LeftFoot'], mm.exp(mm.unitX(), math.pi * tiptoe_angle))
            # motion[frame].mulJointOrientationLocal(idDic['RightFoot'], mm.exp(mm.unitX(), math.pi * tiptoe_angle))

        if getParamVal('left tilt angle') > 0.001:
            left_tilt_angle = getParamVal('left tilt angle')
            if motion[0].skeleton.getJointIndex(
                    'LeftFoot_foot_0_1') is not None:
                motion[frame].mulJointOrientationLocal(
                    idDic['LeftFoot_foot_0_1'],
                    mm.exp(mm.unitZ(), -math.pi * left_tilt_angle))
            else:
                motion[frame].mulJointOrientationLocal(
                    idDic['LeftFoot_foot_0_1_0'],
                    mm.exp(mm.unitZ(), -math.pi * left_tilt_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot'], mm.exp(mm.unitZ(),
                                          math.pi * left_tilt_angle))

        elif getParamVal('left tilt angle') < -0.001:
            left_tilt_angle = getParamVal('left tilt angle')
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot_foot_0_0'],
                mm.exp(mm.unitZ(), -math.pi * left_tilt_angle))
            if motion[0].skeleton.getJointIndex(
                    'LeftFoot_foot_0_1') is not None:
                motion[frame].mulJointOrientationLocal(
                    idDic['LeftFoot_foot_0_1'],
                    mm.exp(mm.unitZ(), math.pi * left_tilt_angle))
            else:
                motion[frame].mulJointOrientationLocal(
                    idDic['LeftFoot_foot_0_1_0'],
                    mm.exp(mm.unitZ(), math.pi * left_tilt_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot'], mm.exp(mm.unitZ(),
                                          math.pi * left_tilt_angle))

        if getParamVal('right tilt angle') > 0.001:
            right_tilt_angle = getParamVal('right tilt angle')
            if motion[0].skeleton.getJointIndex(
                    'RightFoot_foot_0_1') is not None:
                motion[frame].mulJointOrientationLocal(
                    idDic['RightFoot_foot_0_1'],
                    mm.exp(mm.unitZ(), math.pi * right_tilt_angle))
            else:
                motion[frame].mulJointOrientationLocal(
                    idDic['RightFoot_foot_0_1_0'],
                    mm.exp(mm.unitZ(), math.pi * right_tilt_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot'],
                mm.exp(mm.unitZ(), -math.pi * right_tilt_angle))
        elif getParamVal('right tilt angle') < -0.001:
            right_tilt_angle = getParamVal('right tilt angle')
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot_foot_0_0'],
                mm.exp(mm.unitZ(), math.pi * right_tilt_angle))
            if motion[0].skeleton.getJointIndex(
                    'RightFoot_foot_0_1') is not None:
                motion[frame].mulJointOrientationLocal(
                    idDic['RightFoot_foot_0_1'],
                    mm.exp(mm.unitZ(), -math.pi * right_tilt_angle))
            # else:
            #     motion[frame].mulJointOrientationLocal(idDic['RightFoot_foot_0_1_0'], mm.exp(mm.unitZ(), -math.pi * right_tilt_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot'],
                mm.exp(mm.unitZ(), -math.pi * right_tilt_angle))

        motionModel.update(motion[frame])
        motionModel.translateByOffset(
            np.array([
                getParamVal('com X offset'),
                getParamVal('com Y offset'),
                getParamVal('com Z offset')
            ]))
        controlModel_ik.set_q(controlModel.get_q())

        global g_initFlag
        global forceShowTime

        global JsysPre
        global JsupPreL
        global JsupPreR

        global JconstPre

        global preFootCenter
        global maxContactChangeCount
        global contactChangeCount
        global contact
        global contactChangeType

        Kt, Kl, Kh, Bl, Bh, kt_sup = getParamVals(
            ['Kt', 'Kl', 'Kh', 'Bl', 'Bh', 'SupKt'])
        Dt = 2 * (Kt**.5)
        Dl = 2 * (Kl**.5)
        Dh = 2 * (Kh**.5)
        dt_sup = 2 * (kt_sup**.5)

        # tracking
        th_r = motion.getDOFPositions(frame)
        th = controlModel.getDOFPositions()
        dth_r = motion.getDOFVelocities(frame)
        dth = controlModel.getDOFVelocities()
        ddth_r = motion.getDOFAccelerations(frame)
        ddth_des = yct.getDesiredDOFAccelerations(th_r, th, dth_r, dth, ddth_r,
                                                  Kt, Dt)

        # ype.flatten(fix_dofs(DOFs, ddth_des, mcfg, joint_names), ddth_des_flat)
        # ype.flatten(fix_dofs(DOFs, dth, mcfg, joint_names), dth_flat)
        ype.flatten(ddth_des, ddth_des_flat)
        ype.flatten(dth, dth_flat)

        #################################################
        # jacobian
        #################################################

        contact_des_ids = list()  # desired contact segments
        if foot_viewer.check_om_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_0_0'))
        if foot_viewer.check_op_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_0_0_0'))
        if foot_viewer.check_im_l is not None and foot_viewer.check_im_l.value(
        ):
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_0_1'))
        if foot_viewer.check_ip_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_0_1_0'))
        if foot_viewer.check_h_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_1_0'))

        if foot_viewer.check_om_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_0_0'))
        if foot_viewer.check_op_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_0_0_0'))
        if foot_viewer.check_im_r is not None and foot_viewer.check_im_r.value(
        ):
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_0_1'))
        if foot_viewer.check_ip_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_0_1_0'))
        if foot_viewer.check_h_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_1_0'))

        contact_ids = list()  # temp idx for balancing
        contact_ids.extend(contact_des_ids)

        contact_joint_ori = list(
            map(controlModel.getJointOrientationGlobal, contact_ids))
        contact_joint_pos = list(
            map(controlModel.getJointPositionGlobal, contact_ids))
        contact_body_ori = list(
            map(controlModel.getBodyOrientationGlobal, contact_ids))
        contact_body_pos = list(
            map(controlModel.getBodyPositionGlobal, contact_ids))
        contact_body_vel = list(
            map(controlModel.getBodyVelocityGlobal, contact_ids))
        contact_body_angvel = list(
            map(controlModel.getBodyAngVelocityGlobal, contact_ids))

        ref_joint_ori = list(
            map(motion[frame].getJointOrientationGlobal, contact_ids))
        ref_joint_pos = list(
            map(motion[frame].getJointPositionGlobal, contact_ids))
        ref_joint_vel = [
            motion.getJointVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_joint_angvel = [
            motion.getJointAngVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_body_ori = list(
            map(motionModel.getBodyOrientationGlobal, contact_ids))
        ref_body_pos = list(map(motionModel.getBodyPositionGlobal,
                                contact_ids))
        # ref_body_vel = list(map(controlModel.getBodyVelocityGlobal, contact_ids))
        ref_body_angvel = [
            motion.getJointAngVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_body_vel = [
            ref_joint_vel[i] +
            np.cross(ref_joint_angvel[i], ref_body_pos[i] - ref_joint_pos[i])
            for i in range(len(ref_joint_vel))
        ]

        is_contact = [1] * len(contact_ids)
        contact_right = len(set(contact_des_ids).intersection(rIDlist)) > 0
        contact_left = len(set(contact_des_ids).intersection(lIDlist)) > 0

        contMotionOffset = th[0][0] - th_r[0][0]

        linkPositions = controlModel.getBodyPositionsGlobal()
        linkVelocities = controlModel.getBodyVelocitiesGlobal()
        linkAngVelocities = controlModel.getBodyAngVelocitiesGlobal()
        linkInertias = controlModel.getBodyInertiasGlobal()

        CM = yrp.getCM(linkPositions, linkMasses, totalMass)
        dCM = yrp.getCM(linkVelocities, linkMasses, totalMass)
        CM_plane = copy.copy(CM)
        CM_plane[1] = 0.
        dCM_plane = copy.copy(dCM)
        dCM_plane[1] = 0.

        P = ymt.getPureInertiaMatrix(TO, linkMasses, linkPositions, CM,
                                     linkInertias)
        dP = ymt.getPureInertiaMatrixDerivative(dTO, linkMasses,
                                                linkVelocities, dCM,
                                                linkAngVelocities,
                                                linkInertias)

        # calculate jacobian
        Jsys, dJsys = controlModel.computeCom_J_dJdq()
        J_contacts = []  # type: list[np.ndarray]
        dJ_contacts = []  # type: list[np.ndarray]
        for contact_id in contact_ids:
            J_contacts.append(Jsys[6 * contact_id:6 * contact_id + 6, :])
            dJ_contacts.append(dJsys[6 * contact_id:6 * contact_id + 6])

        # calculate footCenter
        footCenter = sum(contact_body_pos) / len(contact_body_pos) if len(contact_body_pos) > 0 \
                        else .5 * (controlModel.getBodyPositionGlobal(supL) + controlModel.getBodyPositionGlobal(supR))
        footCenter[1] = 0.
        # if len(contact_body_pos) > 2:
        #     hull = ConvexHull(contact_body_pos)

        footCenter_ref = sum(ref_body_pos) / len(ref_body_pos) if len(ref_body_pos) > 0 \
            else .5 * (motionModel.getBodyPositionGlobal(supL) + motionModel.getBodyPositionGlobal(supR))
        footCenter_ref = footCenter_ref + contMotionOffset
        # if len(ref_body_pos) > 2:
        #     hull = ConvexHull(ref_body_pos)
        footCenter_ref[1] = 0.

        # footCenter[0] = footCenter[0] + getParamVal('com X offset')
        # footCenter[1] = footCenter[0] + getParamVal('com Y offset')
        # footCenter[2] = footCenter[2] + getParamVal('com Z offset')

        # initialization
        if g_initFlag == 0:
            preFootCenter[0] = footCenter.copy()
            g_initFlag = 1

        # if contactChangeCount == 0 and np.linalg.norm(footCenter - preFootCenter[0]) > 0.01:
        #     contactChangeCount += 30
        if contactChangeCount > 0:
            # change footcenter gradually
            footCenter = preFootCenter[0] + (
                maxContactChangeCount - contactChangeCount) * (
                    footCenter - preFootCenter[0]) / maxContactChangeCount
        else:
            preFootCenter[0] = footCenter.copy()

        # linear momentum
        # TODO:
        # We should consider dCM_ref, shouldn't we?
        # add getBodyPositionGlobal and getBodyPositionsGlobal in csVpModel!
        # to do that, set joint velocities to vpModel
        CM_ref_plane = footCenter
        # CM_ref_plane = footCenter_ref
        CM_ref = footCenter + np.array([
            getParamVal('com X offset'),
            motionModel.getCOM()[1] + getParamVal('com Y offset'),
            getParamVal('com Z offset')
        ])
        dL_des_plane = Kl * totalMass * (CM_ref - CM) - Dl * totalMass * dCM
        # dL_des_plane = Kl * totalMass * (CM_ref_plane - CM_plane) - Dl * totalMass * dCM_plane
        # dL_des_plane[1] = 0.
        # print('dCM_plane : ', np.linalg.norm(dCM_plane))

        # angular momentum
        CP_ref = footCenter
        # CP_ref = footCenter_ref
        bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce(
            bodyIDsToCheck, mus, Ks, Ds)
        CP = yrp.getCP(contactPositions, contactForces)
        if CP_old[0] is None or CP is None:
            dCP = None
        else:
            dCP = (CP - CP_old[0]) / (1 / 30.)
        CP_old[0] = CP

        if CP is not None and dCP is not None:
            ddCP_des = Kh * (CP_ref - CP) - Dh * dCP
            dCP_des = dCP + ddCP_des * (1 / 30.)
            CP_des = CP + dCP_des * (1 / 30.)
            # CP_des = footCenter
            CP_des = CP + dCP * (1 / 30.) + .5 * ddCP_des * ((1 / 30.)**2)
            dH_des = np.cross(
                (CP_des - CM),
                (dL_des_plane + totalMass * mm.s2v(wcfg.gravity)))
            if contactChangeCount > 0:  # and contactChangeType == 'DtoS':
                dH_des *= (maxContactChangeCount -
                           contactChangeCount) / maxContactChangeCount
        else:
            dH_des = None

        # convex hull
        contact_pos_2d = np.asarray([
            np.array([contactPosition[0], contactPosition[2]])
            for contactPosition in contactPositions
        ])
        p = np.array([CM_plane[0], CM_plane[2]])
        # hull = None  # type: Delaunay
        # if contact_pos_2d.shape[0] > 0:
        #     hull = Delaunay(contact_pos_2d)
        #     print(hull.find_simplex(p) >= 0)

        # set up equality constraint
        # TODO:
        # logSO3 is just q'', not acceleration.
        # To make a_oris acceleration, q'' -> a will be needed
        # body_ddqs = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(body_ori, mm.unitY()), mm.unitY()) for body_ori in contact_body_ori]))
        # body_ddqs = list(map(mm.logSO3, [np.dot(contact_body_ori[i].T, np.dot(ref_body_ori[i], mm.getSO3FromVectors(np.dot(ref_body_ori[i], mm.unitY()), mm.unitY()))) for i in range(len(contact_body_ori))]))
        # body_ddqs = list(map(mm.logSO3, [np.dot(contact_body_ori[i].T, np.dot(ref_body_ori[i], mm.getSO3FromVectors(np.dot(ref_body_ori[i], up_vec_in_each_link[contact_ids[i]]), mm.unitY()))) for i in range(len(contact_body_ori))]))
        a_oris = list(
            map(mm.logSO3, [
                np.dot(
                    contact_body_ori[i].T,
                    np.dot(
                        ref_body_ori[i],
                        mm.getSO3FromVectors(
                            np.dot(ref_body_ori[i],
                                   up_vec_in_each_link[contact_ids[i]]),
                            mm.unitY()))) for i in range(len(contact_body_ori))
            ]))
        a_oris = list(
            map(mm.logSO3, [
                np.dot(
                    np.dot(
                        ref_body_ori[i],
                        mm.getSO3FromVectors(
                            np.dot(ref_body_ori[i],
                                   up_vec_in_each_link[contact_ids[i]]),
                            mm.unitY())), contact_body_ori[i].T)
                for i in range(len(contact_body_ori))
            ]))
        body_qs = list(map(mm.logSO3, contact_body_ori))
        body_angs = [
            np.dot(contact_body_ori[i], contact_body_angvel[i])
            for i in range(len(contact_body_ori))
        ]
        body_dqs = [
            mm.vel2qd(body_angs[i], body_qs[i]) for i in range(len(body_angs))
        ]
        # a_oris = [np.dot(contact_body_ori[i], mm.qdd2accel(body_ddqs[i], body_dqs[i], body_qs[i])) for i in range(len(contact_body_ori))]

        # body_ddq = body_ddqs[0]
        # body_ori = contact_body_ori[0]
        # body_ang = np.dot(body_ori.T, contact_body_angvel[0])
        #
        # body_q = mm.logSO3(body_ori)
        # body_dq = mm.vel2qd(body_ang, body_q)
        # a_ori = np.dot(body_ori, mm.qdd2accel(body_ddq, body_dq, body_q))

        KT_SUP = np.diag([kt_sup / 10., kt_sup, kt_sup / 10.])
        # KT_SUP = np.diag([kt_sup, kt_sup, kt_sup])

        # a_oris = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(body_ori, mm.unitY()), mm.unitY()) for body_ori in contact_body_ori]))
        # a_oris = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(contact_body_ori[i], up_vec_in_each_link[contact_ids[i]]), mm.unitY()) for i in range(len(contact_body_ori))]))
        # a_sups = [np.append(kt_sup*(ref_body_pos[i] - contact_body_pos[i] + contMotionOffset) + dt_sup*(ref_body_vel[i] - contact_body_vel[i]),
        #                     kt_sup*a_oris[i]+dt_sup*(ref_body_angvel[i]-contact_body_angvel[i])) for i in range(len(a_oris))]
        # a_sups = [np.append(kt_sup*(ref_body_pos[i] - contact_body_pos[i] + contMotionOffset) - dt_sup * contact_body_vel[i],
        #                     kt_sup*a_oris[i] - dt_sup * contact_body_angvel[i]) for i in range(len(a_oris))]
        a_sups = [
            np.append(
                np.dot(KT_SUP,
                       (ref_body_pos[i] - contact_body_pos[i] +
                        contMotionOffset)) - dt_sup * contact_body_vel[i],
                kt_sup * a_oris[i] - dt_sup * contact_body_angvel[i])
            for i in range(len(a_oris))
        ]
        # for i in range(len(a_sups)):
        #     a_sups[i][1] = -kt_sup * contact_body_pos[i][1] - dt_sup * contact_body_vel[i][1]

        # momentum matrix
        RS = np.dot(P, Jsys)
        R, S = np.vsplit(RS, 2)

        # rs = np.dot((np.dot(dP, Jsys) + np.dot(P, dJsys)), dth_flat)
        rs = np.dot(dP, np.dot(Jsys, dth_flat)) + np.dot(P, dJsys)
        r_bias, s_bias = np.hsplit(rs, 2)

        #######################################################
        # optimization
        #######################################################
        # if contact == 2 and footCenterR[1] > doubleTosingleOffset/2:
        if contact_left and not contact_right:
            config['weightMap']['RightUpLeg'] = .8
            config['weightMap']['RightLeg'] = .8
            config['weightMap']['RightFoot'] = .8
        else:
            config['weightMap']['RightUpLeg'] = .1
            config['weightMap']['RightLeg'] = .25
            config['weightMap']['RightFoot'] = .2

        # if contact == 1 and footCenterL[1] > doubleTosingleOffset/2:
        if contact_right and not contact_left:
            config['weightMap']['LeftUpLeg'] = .8
            config['weightMap']['LeftLeg'] = .8
            config['weightMap']['LeftFoot'] = .8
        else:
            config['weightMap']['LeftUpLeg'] = .1
            config['weightMap']['LeftLeg'] = .25
            config['weightMap']['LeftFoot'] = .2

        w = mot.getTrackingWeight(DOFs, motion[0].skeleton,
                                  config['weightMap'])

        mot.addTrackingTerms(problem, totalDOF, Bt, w, ddth_des_flat)
        if dH_des is not None:
            mot.addLinearTerms(problem, totalDOF, Bl, dL_des_plane, R, r_bias)
            mot.addAngularTerms(problem, totalDOF, Bh, dH_des, S, s_bias)

            if True:
                for c_idx in range(len(contact_ids)):
                    mot.addConstraint2(problem, totalDOF, J_contacts[c_idx],
                                       dJ_contacts[c_idx], dth_flat,
                                       a_sups[c_idx])

        if contactChangeCount > 0:
            contactChangeCount = contactChangeCount - 1
            if contactChangeCount == 0:
                maxContactChangeCount = 30
                contactChangeType = 0

        r = problem.solve()
        problem.clear()
        ddth_sol_flat = np.asarray(r['x'])
        # ddth_sol_flat[foot_seg_dofs] = np.array(ddth_des_flat)[foot_seg_dofs]
        ype.nested(ddth_sol_flat, ddth_sol)

        rootPos[0] = controlModel.getBodyPositionGlobal(selectedBody)
        localPos = [[0, 0, 0]]

        for i in range(stepsPerFrame):
            # apply penalty force
            bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce(
                bodyIDsToCheck, mus, Ks, Ds)
            # bodyIDs, contactPositions, contactPositionLocals, contactForces, contactVelocities = vpWorld.calcManyPenaltyForce(0, bodyIDsToCheck, mus, Ks, Ds)
            vpWorld.applyPenaltyForce(bodyIDs, contactPositionLocals,
                                      contactForces)

            controlModel.setDOFAccelerations(ddth_sol)
            # controlModel.setDOFAccelerations(ddth_des)
            # controlModel.set_ddq(ddth_sol_flat)
            # controlModel.set_ddq(ddth_des_flat)
            controlModel.solveHybridDynamics()

            if forceShowTime > viewer.objectInfoWnd.labelForceDur.value():
                forceShowTime = 0
                viewer_ResetForceState()

            forceforce = np.array([
                viewer.objectInfoWnd.labelForceX.value(),
                viewer.objectInfoWnd.labelForceY.value(),
                viewer.objectInfoWnd.labelForceZ.value()
            ])
            extraForce[0] = getParamVal('Fm') * mm.normalize2(forceforce)
            if viewer_GetForceState():
                forceShowTime += wcfg.timeStep
                vpWorld.applyPenaltyForce(selectedBodyId, localPos, extraForce)

            vpWorld.step()

        controlModel_ik.set_q(controlModel.get_q())

        if foot_viewer is not None:
            foot_viewer.foot_pressure_gl_window.refresh_foot_contact_info(
                frame, vpWorld, bodyIDsToCheck, mus, Ks, Ds)
            foot_viewer.foot_pressure_gl_window.goToFrame(frame)

        # rendering
        for foot_seg_id in footIdlist:
            control_model_renderer.body_colors[foot_seg_id] = (255, 240, 255)

        for contact_id in contact_ids:
            control_model_renderer.body_colors[contact_id] = (255, 0, 0)

        rd_footCenter[0] = footCenter
        rd_footCenter_ref[0] = footCenter_ref

        rd_CM[0] = CM

        rd_CM_plane[0] = CM.copy()
        rd_CM_plane[0][1] = 0.

        if CP is not None and dCP is not None:
            rd_CP[0] = CP
            rd_CP_des[0] = CP_des

            rd_dL_des_plane[0] = [
                dL_des_plane[0] / 100, dL_des_plane[1] / 100,
                dL_des_plane[2] / 100
            ]
            rd_dH_des[0] = dH_des

            rd_grf_des[0] = dL_des_plane - totalMass * mm.s2v(wcfg.gravity)

        del rd_foot_ori[:]
        del rd_foot_pos[:]
        # for seg_foot_id in footIdlist:
        #     rd_foot_ori.append(controlModel.getJointOrientationGlobal(seg_foot_id))
        #     rd_foot_pos.append(controlModel.getJointPositionGlobal(seg_foot_id))
        rd_foot_ori.append(controlModel.getJointOrientationGlobal(supL))
        rd_foot_ori.append(controlModel.getJointOrientationGlobal(supR))
        rd_foot_pos.append(controlModel.getJointPositionGlobal(supL))
        rd_foot_pos.append(controlModel.getJointPositionGlobal(supR))

        rd_root_des[0] = rootPos[0]
        rd_root_ori[0] = controlModel.getBodyOrientationGlobal(0)
        rd_root_pos[0] = controlModel.getBodyPositionGlobal(0)

        del rd_CF[:]
        del rd_CF_pos[:]
        for i in range(len(contactPositions)):
            rd_CF.append(contactForces[i] / 400)
            rd_CF_pos.append(contactPositions[i].copy())

        if viewer_GetForceState():
            rd_exfen_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exf_des[0] = [0, 0, 0]
        else:
            rd_exf_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exfen_des[0] = [0, 0, 0]

        # extraForcePos[0] = controlModel.getBodyPositionGlobal(selectedBody)
        extraForcePos[0] = controlModel.getBodyPositionGlobal(
            selectedBody) - 0.1 * np.array([
                viewer.objectInfoWnd.labelForceX.value(), 0.,
                viewer.objectInfoWnd.labelForceZ.value()
            ])

        # render contact_ids

        # render skeleton
        if SKELETON_ON:
            Ts = dict()
            Ts['pelvis'] = controlModel.getJointTransform(idDic['Hips'])
            Ts['thigh_R'] = controlModel.getJointTransform(idDic['RightUpLeg'])
            Ts['shin_R'] = controlModel.getJointTransform(idDic['RightLeg'])
            Ts['foot_R'] = controlModel.getJointTransform(idDic['RightFoot'])
            Ts['foot_heel_R'] = controlModel.getJointTransform(
                idDic['RightFoot'])
            Ts['heel_R'] = np.eye(4)
            Ts['outside_metatarsal_R'] = controlModel.getJointTransform(
                idDic['RightFoot_foot_0_0'])
            Ts['outside_phalanges_R'] = controlModel.getJointTransform(
                idDic['RightFoot_foot_0_0_0'])
            # Ts['inside_metatarsal_R'] = controlModel.getJointTransform(idDic['RightFoot_foot_0_1'])
            Ts['inside_metatarsal_R'] = np.eye(4)
            Ts['inside_phalanges_R'] = controlModel.getJointTransform(
                idDic['RightFoot_foot_0_1_0'])
            Ts['spine_ribs'] = controlModel.getJointTransform(idDic['Spine'])
            Ts['head'] = controlModel.getJointTransform(idDic['Spine1'])
            Ts['upper_limb_R'] = controlModel.getJointTransform(
                idDic['RightArm'])
            Ts['lower_limb_R'] = controlModel.getJointTransform(
                idDic['RightForeArm'])
            Ts['thigh_L'] = controlModel.getJointTransform(idDic['LeftUpLeg'])
            Ts['shin_L'] = controlModel.getJointTransform(idDic['LeftLeg'])
            Ts['foot_L'] = controlModel.getJointTransform(idDic['LeftFoot'])
            Ts['foot_heel_L'] = controlModel.getJointTransform(
                idDic['LeftFoot'])
            Ts['heel_L'] = np.eye(4)
            Ts['outside_metatarsal_L'] = controlModel.getJointTransform(
                idDic['LeftFoot_foot_0_0'])
            Ts['outside_phalanges_L'] = controlModel.getJointTransform(
                idDic['LeftFoot_foot_0_0_0'])
            # Ts['inside_metatarsal_L'] = controlModel.getJointTransform(idDic['LeftFoot_foot_0_1'])
            Ts['inside_metatarsal_L'] = np.eye(4)
            Ts['inside_phalanges_L'] = controlModel.getJointTransform(
                idDic['LeftFoot_foot_0_1_0'])
            Ts['upper_limb_L'] = controlModel.getJointTransform(
                idDic['LeftArm'])
            Ts['lower_limb_L'] = controlModel.getJointTransform(
                idDic['LeftForeArm'])

            skeleton_renderer.appendFrameState(Ts)
예제 #8
0
def main():
    np.set_printoptions(precision=4, linewidth=200)
    # np.set_printoptions(precision=4, linewidth=1000, threshold=np.inf)

    pydart.init()
    dartModel = cdm.DartModel(None, None, None, None, 'cart_pole_blade.skel')
    dartMotionModel = cdm.DartModel(None, None, None, None,
                                    'cart_pole_blade.skel')

    footIdlist = list(
        dartMotionModel.skeleton.body('h_' + name).index_in_skeleton()
        for name in ['blade_left', 'blade_right'])
    up_vec_in_each_link = dict()
    for foot_id in footIdlist:
        up_vec_in_each_link[
            foot_id] = dartMotionModel.getBodyOrientationGlobal(foot_id)[1, :]

    pelvis_pos = dartMotionModel.skeleton.dof_indices(
        (["j_pelvis_pos_x", 'j_pelvis_pos_y', 'j_pelvis_pos_z']))
    pelvis_x = dartMotionModel.skeleton.dof_indices((["j_pelvis_rot_x"]))
    pelvis = dartMotionModel.skeleton.dof_indices(
        (["j_pelvis_rot_y", "j_pelvis_rot_z"]))
    upper_body = dartMotionModel.skeleton.dof_indices(
        ["j_abdomen_1", "j_abdomen_2"])
    right_leg = dartMotionModel.skeleton.dof_indices([
        "j_thigh_right_x", "j_thigh_right_y", "j_thigh_right_z", "j_shin_right"
    ])
    left_leg = dartMotionModel.skeleton.dof_indices(
        ["j_thigh_left_x", "j_thigh_left_y", "j_thigh_left_z", "j_shin_left"])
    arms = dartMotionModel.skeleton.dof_indices(
        ["j_bicep_left_x", "j_bicep_right_x"])
    foot = dartMotionModel.skeleton.dof_indices(
        ["j_heel_left_1", "j_heel_left_2", "j_heel_right_1", "j_heel_right_2"])
    leg_y = dartMotionModel.skeleton.dof_indices(
        ["j_thigh_right_y", "j_thigh_left_y"])

    s0q = np.zeros(dartMotionModel.skeleton.ndofs)
    s0q[pelvis_pos] = 0., .95, 0.
    # s0q[pelvis] = 0., -0.
    # s0q[upper_body] = 0.3, -0.
    s0q[right_leg] = -0., -0., 0.9, -1.5
    # s0q[left_leg] = 0., 0., 0.0, -0.1
    # s0q[leg_y] = -0.785, 0.785
    s0q[arms] = 1.5, -1.5

    dartModel.set_q(s0q)
    dartMotionModel.set_q(s0q)

    frame_step_size = 1. / 40.
    stepsPerFrame = 25
    time_step = dartModel.world.time_step()

    # wcfg.lockingVel = 0.01
    # dartModel.initializeHybridDynamics()

    #controlToMotionOffset = (1.5, -0.02, 0)
    controlToMotionOffset = (0, 0, 2.0)
    dartModel.translateByOffset(controlToMotionOffset)

    totalDOF = dartModel.getTotalDOF()
    DOFs = dartModel.getDOFs()

    # parameter
    Kt = 25.
    Dt = 2. * (Kt**.5)

    Kl = 100.
    Dl = 2. * (Kt**.5)

    Kh = 100.
    Dh = 2. * (Kt**.5)

    Ks = 20000.
    Ds = 2. * (Kt**.5)

    Bt = 1.
    Bl = 0.1
    Bh = 0.13

    supL = dartModel.skeleton.body('h_blade_left').index_in_skeleton()
    supR = dartModel.skeleton.body('h_blade_right').index_in_skeleton()

    selectedBody = dartModel.skeleton.body('h_head').index_in_skeleton()

    # momentum matrix
    linkMasses = dartModel.getBodyMasses()
    print([body.name for body in dartModel.skeleton.bodynodes])
    print(linkMasses)
    totalMass = dartModel.getTotalMass()
    TO = ymt.make_TO(linkMasses)
    dTO = ymt.make_dTO(len(linkMasses))

    # optimization
    problem = yac.LSE(totalDOF, 12)
    #a_sup = (0,0,0, 0,0,0) #ori
    #a_sup = (0,0,0, 0,0,0) #L
    a_supL = (0, 0, 0, 0, 0, 0)
    a_supR = (0, 0, 0, 0, 0, 0)
    a_sup_2 = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
    CP_old = [mm.v3(0., 0., 0.)]
    CP_des = [None]
    dCP_des = [np.zeros(3)]

    # penalty method
    # bodyIDsToCheck = range(dartModel.getBodyNum())
    bodyIDsToCheck = [supL, supR]
    #mus = [1.]*len(bodyIDsToCheck)
    mus = [.5] * len(bodyIDsToCheck)

    # flat data structure
    # ddth_des_flat = ype.makeFlatList(totalDOF)
    # dth_flat = ype.makeFlatList(totalDOF)
    # ddth_sol = ype.makeNestedList(DOFs)

    config = dict()
    config['weightMap'] = {
        'j_scapula_left': .2,
        'j_bicep_left': .2,
        'j_forearm_left': .2,
        'j_hand_left': .2,
        'j_scapula_right': .2,
        'j_bicep_right': .2,
        'j_forearm_right': .2,
        'j_hand_right': .2,
        'j_abdomen': .6,
        'j_spine': .6,
        'j_head': .6,
        'j_heel_right': .2,
        'j_heel_left': .2,
        'j_pelvis': 0.5,
        'j_thigh_left': .1,
        'j_shin_left': .3,
        'j_thigh_right': .1,
        'j_shin_right': .3
    }

    # viewer
    rd_footCenter = [None]
    rd_footCenterL = [None]
    rd_footCenterR = [None]
    rd_CM_plane = [None]
    rd_CM = [None]
    rd_CP = [None]
    rd_CP_des = [None]
    rd_dL_des_plane = [None]
    rd_dH_des = [None]
    rd_grf_des = [None]

    rd_exf_des = [None]
    rd_exfen_des = [None]
    rd_root_des = [None]

    rd_CF = [None]
    rd_CF_pos = [None]

    rootPos = [None]
    selectedBodyId = [selectedBody]
    extraForce = [None]
    extraForcePos = [None]

    rightFootVectorX = [None]
    rightFootVectorY = [None]
    rightFootVectorZ = [None]
    rightFootPos = [None]

    rightVectorX = [None]
    rightVectorY = [None]
    rightVectorZ = [None]
    rightPos = [None]

    # viewer = ysv.SimpleViewer()
    viewer = hsv.hpSimpleViewer(viewForceWnd=False)
    viewer.setMaxFrame(1000)
    #viewer.record(False)
    # viewer.doc.addRenderer('motion', yr.JointMotionRenderer(motion, (0,255,255), yr.LINK_BONE))
    # viewer.doc.addObject('motion', motion)
    # viewer.doc.addRenderer('motionModel', cvr.VpModelRenderer(motionModel, (150,150,255), yr.POLYGON_FILL))
    # viewer.doc.addRenderer('controlModel', cvr.VpModelRenderer(controlModel, (255,240,255), yr.POLYGON_LINE))
    #viewer.doc.addRenderer('controlModel', cvr.VpModelRenderer(controlModel, (255,240,255), yr.POLYGON_FILL))

    viewer.doc.addRenderer(
        'motionModel',
        yr.DartRenderer(dartMotionModel.world, (255, 240, 255),
                        yr.POLYGON_FILL))
    viewer.doc.addRenderer(
        'controlModel',
        yr.DartRenderer(dartModel.world, (150, 150, 255), yr.POLYGON_FILL))
    viewer.doc.addRenderer('rd_footCenter', yr.PointsRenderer(rd_footCenter))
    viewer.doc.addRenderer('rd_CM_plane',
                           yr.PointsRenderer(rd_CM_plane, (255, 255, 0)))
    viewer.doc.addRenderer('rd_CP', yr.PointsRenderer(rd_CP, (0, 255, 0)))
    viewer.doc.addRenderer('rd_CP_des',
                           yr.PointsRenderer(rd_CP_des, (255, 0, 255)))
    viewer.doc.addRenderer(
        'rd_dL_des_plane',
        yr.VectorsRenderer(rd_dL_des_plane, rd_CM, (255, 255, 0)))
    viewer.doc.addRenderer('rd_dH_des',
                           yr.VectorsRenderer(rd_dH_des, rd_CM, (0, 255, 0)))
    #viewer.doc.addRenderer('rd_grf_des', yr.ForcesRenderer(rd_grf_des, rd_CP_des, (0,255,0), .001))
    viewer.doc.addRenderer('rd_CF',
                           yr.VectorsRenderer(rd_CF, rd_CF_pos, (255, 0, 0)))

    viewer.doc.addRenderer(
        'extraForce', yr.VectorsRenderer(rd_exf_des, extraForcePos,
                                         (0, 255, 0)))
    viewer.doc.addRenderer(
        'extraForceEnable',
        yr.VectorsRenderer(rd_exfen_des, extraForcePos, (255, 0, 0)))

    #viewer.doc.addRenderer('right_foot_oriX', yr.VectorsRenderer(rightFootVectorX, rightFootPos, (255,0,0)))
    #viewer.doc.addRenderer('right_foot_oriY', yr.VectorsRenderer(rightFootVectorY, rightFootPos, (0,255,0)))
    #viewer.doc.addRenderer('right_foot_oriZ', yr.VectorsRenderer(rightFootVectorZ, rightFootPos, (0,0,255)))

    #viewer.doc.addRenderer('right_oriX', yr.VectorsRenderer(rightVectorX, rightPos, (255,0,0)))
    #viewer.doc.addRenderer('right_oriY', yr.VectorsRenderer(rightVectorY, rightPos, (0,255,0)))
    #viewer.doc.addRenderer('right_oriZ', yr.VectorsRenderer(rightVectorZ, rightPos, (0,0,255)))

    #success!!
    #initKt = 50
    #initKl = 10.1
    #initKh = 3.1

    #initBl = .1
    #initBh = .1
    #initSupKt = 21.6

    #initFm = 100.0

    #success!! -- 2015.2.12. double stance
    #initKt = 50
    #initKl = 37.1
    #initKh = 41.8

    #initBl = .1
    #initBh = .13
    #initSupKt = 21.6

    #initFm = 165.0

    #single stance
    #initKt = 25
    #initKl = 80.1
    #initKh = 10.8

    #initBl = .1
    #initBh = .13
    #initSupKt = 21.6

    #initFm = 50.0

    #single stance -> double stance
    #initKt = 25
    #initKl = 60.
    #initKh = 20.

    #initBl = .1
    #initBh = .13
    #initSupKt = 21.6

    #initFm = 50.0

    initKt = 25.
    # initKl = 11.
    # initKh = 22.
    initKl = 100.
    initKh = 100.

    initBl = .1
    initBh = .13
    initSupKt = 17.
    # initSupKt = 2.5

    initFm = 50.0

    initComX = 0.
    initComY = 0.
    initComZ = 0.

    viewer.objectInfoWnd.add1DSlider("Kt", 0., 300., 1., initKt)
    viewer.objectInfoWnd.add1DSlider("Kl", 0., 300., 1., initKl)
    viewer.objectInfoWnd.add1DSlider("Kh", 0., 300., 1., initKh)
    viewer.objectInfoWnd.add1DSlider("Bl", 0., 1., .001, initBl)
    viewer.objectInfoWnd.add1DSlider("Bh", 0., 1., .001, initBh)
    viewer.objectInfoWnd.add1DSlider("SupKt", 0., 100., 0.1, initSupKt)
    viewer.objectInfoWnd.add1DSlider("Fm", 0., 1000., 10., initFm)
    viewer.objectInfoWnd.add1DSlider("com X offset", -1., 1., 0.01, initComX)
    viewer.objectInfoWnd.add1DSlider("com Y offset", -1., 1., 0.01, initComY)
    viewer.objectInfoWnd.add1DSlider("com Z offset", -1., 1., 0.01, initComZ)

    viewer.force_on = False

    def viewer_SetForceState(object):
        viewer.force_on = True

    def viewer_GetForceState():
        return viewer.force_on

    def viewer_ResetForceState():
        viewer.force_on = False

    viewer.objectInfoWnd.addBtn('Force on', viewer_SetForceState)
    viewer_ResetForceState()

    offset = 60

    viewer.objectInfoWnd.begin()
    viewer.objectInfoWnd.labelForceX = Fl_Value_Input(20, 30 + offset * 9, 40,
                                                      20, 'X')
    viewer.objectInfoWnd.labelForceX.value(0)

    viewer.objectInfoWnd.labelForceY = Fl_Value_Input(80, 30 + offset * 9, 40,
                                                      20, 'Y')
    viewer.objectInfoWnd.labelForceY.value(0)

    viewer.objectInfoWnd.labelForceZ = Fl_Value_Input(140, 30 + offset * 9, 40,
                                                      20, 'Z')
    viewer.objectInfoWnd.labelForceZ.value(1)

    viewer.objectInfoWnd.labelForceDur = Fl_Value_Input(
        220, 30 + offset * 9, 40, 20, 'Dur')
    viewer.objectInfoWnd.labelForceDur.value(0.1)

    viewer.objectInfoWnd.end()

    #self.sliderFm = Fl_Hor_Nice_Slider(10, 42+offset*6, 250, 10)

    pdcontroller = PDController(dartModel, dartModel.skeleton,
                                dartModel.world.time_step(), Kt, Dt)

    def getParamVal(paramname):
        return viewer.objectInfoWnd.getVal(paramname)

    def getParamVals(paramnames):
        return (getParamVal(name) for name in paramnames)

    ik_solver = hikd.numIkSolver(dartMotionModel)

    body_num = dartModel.getBodyNum()
    # dJsys = np.zeros((6*body_num, totalDOF))
    # dJsupL = np.zeros((6, totalDOF))
    # dJsupR = np.zeros((6, totalDOF))
    # Jpre = [np.zeros((6*body_num, totalDOF)), np.zeros((6, totalDOF)), np.zeros((6, totalDOF))]

    l_idx = [dartModel.skeleton.body("h_blade_left").index_in_skeleton()]
    r_idx = [dartModel.skeleton.body("h_blade_right").index_in_skeleton()]
    up_vec_in_each_link = {supL: mm.unitY(), supR: mm.unitY()}
    mbc = DartMomentumBalanceController(dartModel.skeleton,
                                        dartMotionModel.skeleton,
                                        config['weightMap'],
                                        up_vec_in_each_link)

    ###################################
    #simulate
    ###################################
    def simulateCallback(frame):
        # print()
        # print(dartModel.getJointVelocityGlobal(0))
        # print(dartModel.getDOFVelocities()[0])
        # print(dartModel.get_dq()[:6])
        # dartMotionModel.update(motion[frame])

        global g_initFlag
        global forceShowTime

        global preFootCenter
        global maxContactChangeCount
        global contactChangeCount
        global contact
        global contactChangeType
        # print('contactstate:', contact, contactChangeCount)

        Kt, Kl, Kh, Bl, Bh, kt_sup = getParamVals(
            ['Kt', 'Kl', 'Kh', 'Bl', 'Bh', 'SupKt'])
        mbc.set_parameters(Kt, Kl, Kh, Bl, Bh, kt_sup)

        pdcontroller.setKpKd(Kt, Dt)

        footHeight = dartModel.getBody(supL).shapenodes[0].shape.size()[1] / 2.

        doubleTosingleOffset = 0.15
        singleTodoubleOffset = 0.30

        com_offset_x, com_offset_y, com_offset_z = getParamVals(
            ['com X offset', 'com Y offset', 'com Z offset'])
        footOffset = np.array((com_offset_x, com_offset_y, com_offset_z))

        # tracking
        th_r_flat = dartMotionModel.get_q()
        dth_flat = dartModel.get_dq()
        ddth_des_flat = pdcontroller.compute_flat(th_r_flat)

        bodyIDs, contactPositions, contactPositionLocals, contactForces = dartModel.calcPenaltyForce(
            bodyIDsToCheck, mus, Ks, Ds)
        CP = yrp.getCP(contactPositions, contactForces)
        ddth_sol = mbc.solve(
            ddth_des_flat,
            # [dartModel.skeleton.body('h_blade_left').index_in_skeleton(), dartModel.skeleton.body('h_blade_right').index_in_skeleton()],
            [dartModel.skeleton.body('h_blade_left').index_in_skeleton()],
            footOffset + np.array([0.9]),
            r_idx,
            l_idx,
            CP,
            None)

        localPos = np.zeros(3)
        inv_h = 1. / time_step

        for i in range(stepsPerFrame):
            ddq, tau, bodyIDs, contactPositions, contactPositionLocals, contactForces = hqp.calc_QP(
                dartModel.skeleton, ddth_sol, inv_h)
            # ddq, tau, bodyIDs, contactPositions, contactPositionLocals, contactForces = hqp.calc_QP(dartModel.skeleton, ddth_des_flat, inv_h)
            # print(frame, i, tau)
            dartModel.applyPenaltyForce(bodyIDs, contactPositionLocals,
                                        contactForces)

            dartModel.skeleton.set_forces(tau)

            if forceShowTime > viewer.objectInfoWnd.labelForceDur.value():
                forceShowTime = 0
                viewer_ResetForceState()

            forceforce = np.array([
                viewer.objectInfoWnd.labelForceX.value(),
                viewer.objectInfoWnd.labelForceY.value(),
                viewer.objectInfoWnd.labelForceZ.value()
            ])
            extraForce[0] = getParamVal('Fm') * mm.normalize2(forceforce)
            if viewer_GetForceState():
                forceShowTime += time_step
                dartModel.applyPenaltyForce(selectedBodyId, localPos,
                                            extraForce)

            dartModel.step()

        # rendering
        rd_CM[0] = dartModel.skeleton.com()

        rd_CM_plane[0] = dartModel.skeleton.com().copy()
        rd_CM_plane[0][1] = 0.

        rd_root_des[0] = rootPos[0]

        del rd_CF[:]
        del rd_CF_pos[:]
        for i in range(len(contactPositions)):
            rd_CF.append(contactForces[i] / 100)
            rd_CF_pos.append(contactPositions[i].copy())

        if viewer_GetForceState():
            rd_exfen_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exf_des[0] = [0, 0, 0]
        else:
            rd_exf_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exfen_des[0] = [0, 0, 0]

        extraForcePos[0] = dartModel.getBodyPositionGlobal(selectedBody)

    viewer.setSimulateCallback(simulateCallback)

    viewer.startTimer(1 / 30.)
    viewer.show()

    Fl.run()
예제 #9
0
def main():
    # np.set_printoptions(precision=4, linewidth=200)
    np.set_printoptions(precision=5,
                        threshold=np.inf,
                        suppress=True,
                        linewidth=3000)

    motion, mcfg, wcfg, stepsPerFrame, config = mit.create_biped_zygote()

    vpWorld = cvw.VpWorld(wcfg)
    vpWorld.SetGlobalDamping(0.999)
    motionModel = cvm.VpMotionModel(vpWorld, motion[0], mcfg)
    controlModel = cvm.VpControlModel(vpWorld, motion[0], mcfg)
    # controlModel_shadow_for_ik = cvm.VpControlModel(vpWorld, motion[0], mcfg)
    vpWorld.initialize()
    controlModel.initializeHybridDynamics()

    # controlToMotionOffset = (1.5, -0.02, 0)
    controlToMotionOffset = (1.5, 0., 0)
    controlModel.translateByOffset(controlToMotionOffset)
    # controlModel_shadow_for_ik.set_q(controlModel.get_q())
    # controlModel_shadow_for_ik.computeJacobian(0, np.array([0., 0., 0.]))

    wcfg_ik = copy.deepcopy(wcfg)
    vpWorld_ik = cvw.VpWorld(wcfg_ik)
    controlModel_ik = cvm.VpControlModel(vpWorld_ik, motion[0], mcfg)
    vpWorld_ik.initialize()
    controlModel_ik.set_q(np.zeros_like(controlModel.get_q()))

    totalDOF = controlModel.getTotalDOF()
    DOFs = controlModel.getDOFs()

    print(totalDOF)
    print(controlModel.getTotalMass())

    foot_dofs = []
    left_foot_dofs = []
    right_foot_dofs = []

    foot_seg_dofs = []
    left_foot_seg_dofs = []
    right_foot_seg_dofs = []

    # for joint_idx in range(motion[0].skeleton.getJointNum()):
    for joint_idx in range(controlModel.getJointNum()):
        joint_name = controlModel.index2name(joint_idx)
        # joint_name = motion[0].skeleton.getJointName(joint_idx)
        if 'Foot' in joint_name:
            foot_dofs_temp = controlModel.getJointDOFIndexes(joint_idx)
            foot_dofs.extend(foot_dofs_temp)
            if 'Left' in joint_name:
                left_foot_dofs.extend(foot_dofs_temp)
            elif 'Right' in joint_name:
                right_foot_dofs.extend(foot_dofs_temp)

        if 'foot' in joint_name:
            foot_dofs_temp = controlModel.getJointDOFIndexes(joint_idx)
            foot_seg_dofs.extend(foot_dofs_temp)
            if 'Left' in joint_name:
                left_foot_seg_dofs.extend(foot_dofs_temp)
            elif 'Right' in joint_name:
                right_foot_seg_dofs.extend(foot_dofs_temp)

    # parameter
    Kt = config['Kt']
    Dt = config['Dt']  # tracking gain
    Kl = config['Kl']
    Dl = config['Dl']  # linear balance gain
    Kh = config['Kh']
    Dh = config['Dh']  # angular balance gain
    Ks = config['Ks']
    Ds = config['Ds']  # penalty force spring gain

    Bt = config['Bt']
    Bl = config['Bl']
    Bh = config['Bh']

    # selectedBody = motion[0].skeleton.getJointIndex(config['end'])
    selectedBody = motion[0].skeleton.getJointIndex('Spine')
    constBody = motion[0].skeleton.getJointIndex('RightFoot')

    supL = motion[0].skeleton.getJointIndex('LeftFoot')
    supR = motion[0].skeleton.getJointIndex('RightFoot')

    # momentum matrix
    linkMasses = controlModel.getBodyMasses()
    totalMass = controlModel.getTotalMass()
    TO = ymt.make_TO(linkMasses)
    dTO = ymt.make_dTO(len(linkMasses))

    # optimization
    problem = yac.LSE(totalDOF, 12)
    # a_sup = (0,0,0, 0,0,0) #ori
    # a_sup = (0,0,0, 0,0,0) #L
    CP_old = [mm.v3(0., 0., 0.)]

    # penalty method
    bodyIDsToCheck = list(range(vpWorld.getBodyNum()))
    # mus = [1.]*len(bodyIDsToCheck)
    mus = [.5] * len(bodyIDsToCheck)

    # flat data structure
    ddth_des_flat = ype.makeFlatList(totalDOF)
    dth_flat = ype.makeFlatList(totalDOF)
    ddth_sol = ype.makeNestedList(DOFs)

    # viewer
    rd_footCenter = [None]
    rd_footCenter_ref = [None]
    rd_footCenterL = [None]
    rd_footCenterR = [None]
    rd_CM_plane = [None]
    rd_CM = [None]
    rd_CP = [None]
    rd_CP_des = [None]
    rd_dL_des_plane = [None]
    rd_dH_des = [None]
    rd_grf_des = [None]

    rd_exf_des = [None]
    rd_exfen_des = [None]
    rd_root_des = [None]

    rd_foot_ori = [None]
    rd_foot_pos = [None]

    rd_root_ori = [None]
    rd_root_pos = [None]

    rd_CF = [None]
    rd_CF_pos = [None]

    rootPos = [None]
    selectedBodyId = [controlModel.index2vpid(selectedBody)]
    extraForce = [None]
    extraForcePos = [None]

    rightFootVectorX = [None]
    rightFootVectorY = [None]
    rightFootVectorZ = [None]
    rightFootPos = [None]

    rightVectorX = [None]
    rightVectorY = [None]
    rightVectorZ = [None]
    rightPos = [None]

    def makeEmptyBasicSkeletonTransformDict(init=None):
        Ts = dict()
        Ts['pelvis'] = init
        Ts['spine_ribs'] = init
        Ts['head'] = init
        Ts['thigh_R'] = init
        Ts['shin_R'] = init
        Ts['foot_heel_R'] = init
        Ts['foot_R'] = init
        Ts['heel_R'] = init
        Ts['outside_metatarsal_R'] = init
        Ts['outside_phalanges_R'] = init
        Ts['inside_metatarsal_R'] = init
        Ts['inside_phalanges_R'] = init
        Ts['upper_limb_R'] = init
        Ts['lower_limb_R'] = init
        Ts['thigh_L'] = init
        Ts['shin_L'] = init
        Ts['foot_heel_L'] = init
        Ts['foot_L'] = init
        Ts['heel_L'] = init
        Ts['outside_metatarsal_L'] = init
        Ts['outside_phalanges_L'] = init
        Ts['inside_metatarsal_L'] = init
        Ts['inside_phalanges_L'] = init

        Ts['upper_limb_L'] = init
        Ts['lower_limb_L'] = init

        return Ts

    # viewer = ysv.SimpleViewer()
    # viewer = hsv.hpSimpleViewer(rect=[0, 0, 1024, 768], viewForceWnd=False)
    viewer = hsv.hpSimpleViewer(rect=[0, 0, 960 + 300, 1 + 1080 + 55],
                                viewForceWnd=False)
    # viewer.record(False)
    # viewer.doc.addRenderer('motion', yr.JointMotionRenderer(motion, (0,255,255), yr.LINK_BONE))
    viewer.doc.addObject('motion', motion)
    viewer.doc.addRenderer(
        'motionModel',
        yr.VpModelRenderer(motionModel, (150, 150, 255), yr.POLYGON_FILL))
    viewer.doc.setRendererVisible('motionModel', False)
    viewer.doc.addRenderer(
        'ikModel',
        yr.VpModelRenderer(controlModel_ik, (150, 150, 255), yr.POLYGON_LINE))
    viewer.doc.setRendererVisible('ikModel', False)
    # viewer.doc.addRenderer('controlModel', cvr.VpModelRenderer(controlModel, (255,240,255), yr.POLYGON_LINE))
    control_model_renderer = yr.VpModelRenderer(controlModel, (255, 240, 255),
                                                yr.POLYGON_FILL)
    viewer.doc.addRenderer('controlModel', control_model_renderer)
    skeleton_renderer = None
    if SKELETON_ON:
        # skeleton_renderer = yr.BasicSkeletonRenderer(makeEmptyBasicSkeletonTransformDict(np.eye(4)), offset_Y=-0.08)
        # skeleton_renderer = yr.BasicSkeletonRenderer(makeEmptyBasicSkeletonTransformDict(np.eye(4)), color=(230, 230, 230), offset_draw=(0.8, -0.02, 0.))
        skeleton_renderer = yr.BasicSkeletonRenderer(
            makeEmptyBasicSkeletonTransformDict(np.eye(4)),
            color=(230, 230, 230),
            offset_draw=(0., -0.0, 0.))
        viewer.doc.addRenderer('skeleton', skeleton_renderer)
    viewer.doc.addRenderer('rd_footCenter', yr.PointsRenderer(rd_footCenter))
    viewer.doc.setRendererVisible('rd_footCenter', False)
    viewer.doc.addRenderer('rd_footCenter_ref',
                           yr.PointsRenderer(rd_footCenter_ref))
    viewer.doc.setRendererVisible('rd_footCenter_ref', False)
    viewer.doc.addRenderer('rd_CM_plane',
                           yr.PointsRenderer(rd_CM_plane, (255, 255, 0)))
    viewer.doc.setRendererVisible('rd_CM_plane', False)
    viewer.doc.addRenderer('rd_CP', yr.PointsRenderer(rd_CP, (0, 255, 0)))
    viewer.doc.setRendererVisible('rd_CP', False)
    viewer.doc.addRenderer('rd_CP_des',
                           yr.PointsRenderer(rd_CP_des, (255, 0, 255)))
    viewer.doc.setRendererVisible('rd_CP_des', False)
    viewer.doc.addRenderer(
        'rd_dL_des_plane',
        yr.VectorsRenderer(rd_dL_des_plane, rd_CM, (255, 255, 0)))
    viewer.doc.setRendererVisible('rd_dL_des_plane', False)
    viewer.doc.addRenderer('rd_dH_des',
                           yr.VectorsRenderer(rd_dH_des, rd_CM, (0, 255, 0)))
    viewer.doc.setRendererVisible('rd_dH_des', False)
    # viewer.doc.addRenderer('rd_grf_des', yr.ForcesRenderer(rd_grf_des, rd_CP_des, (0,255,0), .001))
    viewer.doc.addRenderer('rd_CF',
                           yr.VectorsRenderer(rd_CF, rd_CF_pos, (255, 255, 0)))
    # viewer.doc.setRendererVisible('rd_CF', False)
    viewer.doc.addRenderer(
        'rd_foot_ori',
        yr.OrientationsRenderer(rd_foot_ori, rd_foot_pos, (255, 255, 0)))
    # viewer.doc.setRendererVisible('rd_foot_ori', False)

    viewer.doc.addRenderer(
        'rd_root_ori',
        yr.OrientationsRenderer(rd_root_ori, rd_root_pos, (255, 255, 0)))
    viewer.doc.setRendererVisible('rd_root_ori', False)

    viewer.doc.addRenderer(
        'extraForce', yr.VectorsRenderer(rd_exf_des, extraForcePos,
                                         (0, 255, 0)))
    viewer.doc.setRendererVisible('extraForce', False)
    # viewer.doc.addRenderer('extraForceEnable', yr.VectorsRenderer(rd_exfen_des, extraForcePos, (255,0,0)))
    viewer.doc.addRenderer(
        'extraForceEnable',
        yr.WideArrowRenderer(rd_exfen_des,
                             extraForcePos, (255, 0, 0),
                             lineWidth=.05,
                             fromPoint=False))

    # viewer.doc.addRenderer('right_foot_oriX', yr.VectorsRenderer(rightFootVectorX, rightFootPos, (255,0,0)))
    # viewer.doc.addRenderer('right_foot_oriY', yr.VectorsRenderer(rightFootVectorY, rightFootPos, (0,255,0)))
    # viewer.doc.addRenderer('right_foot_oriZ', yr.VectorsRenderer(rightFootVectorZ, rightFootPos, (0,0,255)))

    # viewer.doc.addRenderer('right_oriX', yr.VectorsRenderer(rightVectorX, rightPos, (255,0,0)))
    # viewer.doc.addRenderer('right_oriY', yr.VectorsRenderer(rightVectorY, rightPos, (0,255,0)))
    # viewer.doc.addRenderer('right_oriZ', yr.VectorsRenderer(rightVectorZ, rightPos, (0,0,255)))

    # foot_viewer = FootWindow(viewer.x() + viewer.w() + 20, viewer.y(), 300, 400, 'foot contact modifier', controlModel)
    foot_viewer = None  # type: FootWindow

    initKt = 25.
    # initKt = 60.
    initKl = 100.
    initKh = 100.

    initBl = .1
    initBh = .13
    # initSupKt = 17
    # initSupKt = 32.
    initSupKt = 28.

    initFm = 45.0

    initComX = 0.
    initComY = 0.
    initComZ = 0.

    viewer.objectInfoWnd.add1DSlider("Kt", 0., 300., 1., initKt)
    viewer.objectInfoWnd.add1DSlider("Kl", 0., 300., 1., initKl)
    viewer.objectInfoWnd.add1DSlider("Kh", 0., 300., 1., initKh)
    viewer.objectInfoWnd.add1DSlider("Bl", 0., 1., .001, initBl)
    viewer.objectInfoWnd.add1DSlider("Bh", 0., 1., .001, initBh)
    viewer.objectInfoWnd.add1DSlider("SupKt", 0., 300., 0.1, initSupKt)
    viewer.objectInfoWnd.add1DSlider("Fm", 0., 1000., 1., initFm)
    viewer.objectInfoWnd.add1DSlider("com X offset", -1., 1., 0.01, initComX)
    viewer.objectInfoWnd.add1DSlider("com Y offset", -1., 1., 0.01, initComY)
    viewer.objectInfoWnd.add1DSlider("com Z offset", -1., 1., 0.01, initComZ)
    viewer.objectInfoWnd.add1DSlider("tiptoe angle", -0.5, .5, 0.001, 0.)
    viewer.objectInfoWnd.add1DSlider("left tilt angle", -0.5, .5, 0.001, 0.)
    viewer.objectInfoWnd.add1DSlider("right tilt angle", -0.5, .5, 0.001, 0.)

    viewer.force_on = False

    def viewer_SetForceState(object):
        viewer.force_on = True

    def viewer_GetForceState():
        return viewer.force_on

    def viewer_ResetForceState():
        viewer.force_on = False

    viewer.objectInfoWnd.addBtn('Force on', viewer_SetForceState)
    viewer_ResetForceState()

    offset = 60

    viewer.objectInfoWnd.begin()
    viewer.objectInfoWnd.labelForceX = Fl_Value_Input(20, 30 + offset * 9, 40,
                                                      20, 'X')
    viewer.objectInfoWnd.labelForceX.value(0)

    viewer.objectInfoWnd.labelForceY = Fl_Value_Input(80, 30 + offset * 9, 40,
                                                      20, 'Y')
    viewer.objectInfoWnd.labelForceY.value(0)

    viewer.objectInfoWnd.labelForceZ = Fl_Value_Input(140, 30 + offset * 9, 40,
                                                      20, 'Z')
    viewer.objectInfoWnd.labelForceZ.value(-1)

    viewer.objectInfoWnd.labelForceDur = Fl_Value_Input(
        220, 30 + offset * 9, 40, 20, 'Dur')
    viewer.objectInfoWnd.labelForceDur.value(0.4)

    viewer.objectInfoWnd.end()

    # self.sliderFm = Fl_Hor_Nice_Slider(10, 42+offset*6, 250, 10)

    def getParamVal(paramname):
        return viewer.objectInfoWnd.getVal(paramname)

    def getParamVals(paramnames):
        return (getParamVal(name) for name in paramnames)

    def setParamVal(paramname, val):
        viewer.objectInfoWnd.setVal(paramname, val)

    idDic = dict()
    for i in range(motion[0].skeleton.getJointNum()):
        idDic[motion[0].skeleton.getJointName(i)] = i

    # extendedFootName = ['Foot_foot_0_0', 'Foot_foot_0_1', 'Foot_foot_0_0_0', 'Foot_foot_0_1_0', 'Foot_foot_1_0']
    extendedFootName = ['Foot']
    lIDdic = {
        'Left' + name: motion[0].skeleton.getJointIndex('Left' + name)
        for name in extendedFootName
    }
    rIDdic = {
        'Right' + name: motion[0].skeleton.getJointIndex('Right' + name)
        for name in extendedFootName
    }
    footIdDic = lIDdic.copy()
    footIdDic.update(rIDdic)

    lIDlist = [
        motion[0].skeleton.getJointIndex('Left' + name)
        for name in extendedFootName
    ]
    rIDlist = [
        motion[0].skeleton.getJointIndex('Right' + name)
        for name in extendedFootName
    ]
    footIdlist = []
    footIdlist.extend(lIDlist)
    footIdlist.extend(rIDlist)
    print(footIdlist)

    joint_names = [
        motion[0].skeleton.getJointName(i)
        for i in range(motion[0].skeleton.getJointNum())
    ]

    def fix_dofs(_DOFs, nested_dof_values, _mcfg, _joint_names):
        fixed_nested_dof_values = list()
        fixed_nested_dof_values.append(nested_dof_values[0])
        for i in range(1, len(_DOFs)):
            dof = _DOFs[i]
            if dof == 1:
                node = _mcfg.getNode(_joint_names[i])
                axis = mm.unitZ()
                if node.jointAxes[0] == 'X':
                    axis = mm.unitX()
                elif node.jointAxes[0] == 'Y':
                    axis = mm.unitY()
                fixed_nested_dof_values.append(
                    np.array([np.dot(nested_dof_values[i], axis)]))
            else:
                fixed_nested_dof_values.append(nested_dof_values[i])

        return fixed_nested_dof_values

    start_frame = 200

    up_vec_in_each_link = dict()
    for foot_id in footIdlist:
        up_vec_in_each_link[
            foot_id] = controlModel_ik.getBodyOrientationGlobal(foot_id)[1, :]
        up_vec_in_each_link[foot_id] = mm.unitY()
    controlModel_ik.set_q(controlModel.get_q())

    ###################################
    # simulate
    ###################################
    def simulateCallback(frame):
        # print(frame)
        # print(motion[frame].getJointOrientationLocal(footIdDic['RightFoot_foot_0_1_0']))
        if frame == start_frame:
            viewer.force_on = True
        if False:
            if frame == start_frame:
                setParamVal('Fm', 35)
                viewer.force_on = True
            if frame == start_frame + 150:
                setParamVal('Fm', 40)
                viewer.force_on = True
            if frame == start_frame + 300:
                setParamVal('Fm', 45)
                viewer.force_on = True
            if frame == start_frame + 450:
                setParamVal('Fm', 50)
                viewer.force_on = True
            if frame == start_frame + 600:
                setParamVal('Fm', 55)
                viewer.force_on = True
            if frame == start_frame + 750:
                setParamVal('Fm', 60)
                viewer.force_on = True

        # hfi.footAdjust(motion[frame], idDic, SEGMENT_FOOT_MAG=.03, SEGMENT_FOOT_RAD=.015, baseHeight=0.02)

        if abs(getParamVal('tiptoe angle')) > 0.001:
            tiptoe_angle = getParamVal('tiptoe angle')
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot_foot_0_0_0'],
                mm.exp(mm.unitX(), -math.pi * tiptoe_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot_foot_0_1_0'],
                mm.exp(mm.unitX(), -math.pi * tiptoe_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot_foot_0_0_0'],
                mm.exp(mm.unitX(), -math.pi * tiptoe_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot_foot_0_1_0'],
                mm.exp(mm.unitX(), -math.pi * tiptoe_angle))
            # motion[frame].mulJointOrientationLocal(idDic['LeftFoot'], mm.exp(mm.unitX(), math.pi * tiptoe_angle * 0.95))
            # motion[frame].mulJointOrientationLocal(idDic['RightFoot'], mm.exp(mm.unitX(), math.pi * tiptoe_angle * 0.95))
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot'], mm.exp(mm.unitX(), math.pi * tiptoe_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot'], mm.exp(mm.unitX(), math.pi * tiptoe_angle))

        if getParamVal('left tilt angle') > 0.001:
            left_tilt_angle = getParamVal('left tilt angle')
            if motion[0].skeleton.getJointIndex(
                    'LeftFoot_foot_0_1') is not None:
                motion[frame].mulJointOrientationLocal(
                    idDic['LeftFoot_foot_0_1'],
                    mm.exp(mm.unitZ(), -math.pi * left_tilt_angle))
            else:
                motion[frame].mulJointOrientationLocal(
                    idDic['LeftFoot_foot_0_1_0'],
                    mm.exp(mm.unitZ(), -math.pi * left_tilt_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot'], mm.exp(mm.unitZ(),
                                          math.pi * left_tilt_angle))

        elif getParamVal('left tilt angle') < -0.001:
            left_tilt_angle = getParamVal('left tilt angle')
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot_foot_0_0'],
                mm.exp(mm.unitZ(), -math.pi * left_tilt_angle))
            if motion[0].skeleton.getJointIndex(
                    'LeftFoot_foot_0_1') is not None:
                motion[frame].mulJointOrientationLocal(
                    idDic['LeftFoot_foot_0_1'],
                    mm.exp(mm.unitZ(), math.pi * left_tilt_angle))
            else:
                motion[frame].mulJointOrientationLocal(
                    idDic['LeftFoot_foot_0_1_0'],
                    mm.exp(mm.unitZ(), math.pi * left_tilt_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['LeftFoot'], mm.exp(mm.unitZ(),
                                          math.pi * left_tilt_angle))

        if getParamVal('right tilt angle') > 0.001:
            right_tilt_angle = getParamVal('right tilt angle')
            if motion[0].skeleton.getJointIndex(
                    'RightFoot_foot_0_1') is not None:
                motion[frame].mulJointOrientationLocal(
                    idDic['RightFoot_foot_0_1'],
                    mm.exp(mm.unitZ(), math.pi * right_tilt_angle))
            else:
                motion[frame].mulJointOrientationLocal(
                    idDic['RightFoot_foot_0_1_0'],
                    mm.exp(mm.unitZ(), math.pi * right_tilt_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot'],
                mm.exp(mm.unitZ(), -math.pi * right_tilt_angle))
        elif getParamVal('right tilt angle') < -0.001:
            right_tilt_angle = getParamVal('right tilt angle')
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot_foot_0_0'],
                mm.exp(mm.unitZ(), math.pi * right_tilt_angle))
            if motion[0].skeleton.getJointIndex(
                    'RightFoot_foot_0_1') is not None:
                motion[frame].mulJointOrientationLocal(
                    idDic['RightFoot_foot_0_1'],
                    mm.exp(mm.unitZ(), -math.pi * right_tilt_angle))
            # else:
            #     motion[frame].mulJointOrientationLocal(idDic['RightFoot_foot_0_1_0'], mm.exp(mm.unitZ(), -math.pi * right_tilt_angle))
            motion[frame].mulJointOrientationLocal(
                idDic['RightFoot'],
                mm.exp(mm.unitZ(), -math.pi * right_tilt_angle))

        motionModel.update(motion[frame])
        motionModel.translateByOffset(
            np.array([
                getParamVal('com X offset'),
                getParamVal('com Y offset'),
                getParamVal('com Z offset')
            ]))
        controlModel_ik.set_q(controlModel.get_q())

        global g_initFlag
        global forceShowTime

        global JsysPre
        global JsupPreL
        global JsupPreR

        global JconstPre

        global preFootCenter
        global maxContactChangeCount
        global contactChangeCount
        global contact
        global contactChangeType

        Kt, Kl, Kh, Bl, Bh, kt_sup = getParamVals(
            ['Kt', 'Kl', 'Kh', 'Bl', 'Bh', 'SupKt'])
        Dt = 2 * (Kt**.5)
        Dl = 2 * (Kl**.5)
        Dh = 2 * (Kh**.5)
        dt_sup = 2 * (kt_sup**.5)

        # tracking
        th_r = motion.getDOFPositions(frame)
        th = controlModel.getDOFPositions()
        dth_r = motion.getDOFVelocities(frame)
        dth = controlModel.getDOFVelocities()
        ddth_r = motion.getDOFAccelerations(frame)
        ddth_des = yct.getDesiredDOFAccelerations(th_r, th, dth_r, dth, ddth_r,
                                                  Kt, Dt)

        # ype.flatten(fix_dofs(DOFs, ddth_des, mcfg, joint_names), ddth_des_flat)
        # ype.flatten(fix_dofs(DOFs, dth, mcfg, joint_names), dth_flat)
        ype.flatten(ddth_des, ddth_des_flat)
        ype.flatten(dth, dth_flat)

        #################################################
        # jacobian
        #################################################

        contact_des_ids = list()  # desired contact segments
        if foot_viewer.check_h_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot'))

        if foot_viewer.check_h_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot'))

        contact_ids = list()  # temp idx for balancing
        contact_ids.extend(contact_des_ids)

        contact_joint_ori = list(
            map(controlModel.getJointOrientationGlobal, contact_ids))
        contact_joint_pos = list(
            map(controlModel.getJointPositionGlobal, contact_ids))
        contact_body_ori = list(
            map(controlModel.getBodyOrientationGlobal, contact_ids))
        contact_body_pos = list(
            map(controlModel.getBodyPositionGlobal, contact_ids))
        contact_body_vel = list(
            map(controlModel.getBodyVelocityGlobal, contact_ids))
        contact_body_angvel = list(
            map(controlModel.getBodyAngVelocityGlobal, contact_ids))

        ref_joint_ori = list(
            map(motion[frame].getJointOrientationGlobal, contact_ids))
        ref_joint_pos = list(
            map(motion[frame].getJointPositionGlobal, contact_ids))
        ref_joint_vel = [
            motion.getJointVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_joint_angvel = [
            motion.getJointAngVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_body_ori = list(
            map(motionModel.getBodyOrientationGlobal, contact_ids))
        ref_body_pos = list(map(motionModel.getBodyPositionGlobal,
                                contact_ids))
        # ref_body_vel = list(map(controlModel.getBodyVelocityGlobal, contact_ids))
        ref_body_angvel = [
            motion.getJointAngVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_body_vel = [
            ref_joint_vel[i] +
            np.cross(ref_joint_angvel[i], ref_body_pos[i] - ref_joint_pos[i])
            for i in range(len(ref_joint_vel))
        ]

        is_contact = [1] * len(contact_ids)
        contact_right = len(set(contact_des_ids).intersection(rIDlist)) > 0
        contact_left = len(set(contact_des_ids).intersection(lIDlist)) > 0

        contMotionOffset = th[0][0] - th_r[0][0]

        linkPositions = controlModel.getBodyPositionsGlobal()
        linkVelocities = controlModel.getBodyVelocitiesGlobal()
        linkAngVelocities = controlModel.getBodyAngVelocitiesGlobal()
        linkInertias = controlModel.getBodyInertiasGlobal()

        CM = yrp.getCM(linkPositions, linkMasses, totalMass)
        dCM = yrp.getCM(linkVelocities, linkMasses, totalMass)
        CM_plane = copy.copy(CM)
        CM_plane[1] = 0.
        dCM_plane = copy.copy(dCM)
        dCM_plane[1] = 0.

        P = ymt.getPureInertiaMatrix(TO, linkMasses, linkPositions, CM,
                                     linkInertias)
        dP = ymt.getPureInertiaMatrixDerivative(dTO, linkMasses,
                                                linkVelocities, dCM,
                                                linkAngVelocities,
                                                linkInertias)

        # calculate jacobian
        Jsys, dJsys = controlModel.computeCom_J_dJdq()
        J_contacts = []  # type: list[np.ndarray]
        dJ_contacts = []  # type: list[np.ndarray]
        for contact_id in contact_ids:
            J_contacts.append(Jsys[6 * contact_id:6 * contact_id + 6, :])
            dJ_contacts.append(dJsys[6 * contact_id:6 * contact_id + 6])

        # calculate footCenter
        footCenter = sum(contact_body_pos) / len(contact_body_pos) if len(contact_body_pos) > 0 \
            else .5 * (controlModel.getBodyPositionGlobal(supL) + controlModel.getBodyPositionGlobal(supR))
        footCenter[1] = 0.
        # if len(contact_body_pos) > 2:
        #     hull = ConvexHull(contact_body_pos)

        footCenter_ref = sum(ref_body_pos) / len(ref_body_pos) if len(ref_body_pos) > 0 \
            else .5 * (motionModel.getBodyPositionGlobal(supL) + motionModel.getBodyPositionGlobal(supR))
        footCenter_ref = footCenter_ref + contMotionOffset
        # if len(ref_body_pos) > 2:
        #     hull = ConvexHull(ref_body_pos)
        footCenter_ref[1] = 0.

        # footCenter[0] = footCenter[0] + getParamVal('com X offset')
        # footCenter[1] = footCenter[0] + getParamVal('com Y offset')
        # footCenter[2] = footCenter[2] + getParamVal('com Z offset')

        # initialization
        if g_initFlag == 0:
            preFootCenter[0] = footCenter.copy()
            g_initFlag = 1

        # if contactChangeCount == 0 and np.linalg.norm(footCenter - preFootCenter[0]) > 0.01:
        #     contactChangeCount += 30
        if contactChangeCount > 0:
            # change footcenter gradually
            footCenter = preFootCenter[0] + (
                maxContactChangeCount - contactChangeCount) * (
                    footCenter - preFootCenter[0]) / maxContactChangeCount
        else:
            preFootCenter[0] = footCenter.copy()

        # linear momentum
        # TODO:
        # We should consider dCM_ref, shouldn't we?
        # add getBodyPositionGlobal and getBodyPositionsGlobal in csVpModel!
        # to do that, set joint velocities to vpModel
        CM_ref_plane = footCenter
        # CM_ref_plane = footCenter_ref
        CM_ref = footCenter + np.array([
            getParamVal('com X offset'),
            motionModel.getCOM()[1] + getParamVal('com Y offset'),
            getParamVal('com Z offset')
        ])
        dL_des_plane = Kl * totalMass * (CM_ref - CM) - Dl * totalMass * dCM
        # dL_des_plane = Kl * totalMass * (CM_ref_plane - CM_plane) - Dl * totalMass * dCM_plane
        # dL_des_plane[1] = 0.
        # print('dCM_plane : ', np.linalg.norm(dCM_plane))

        # angular momentum
        CP_ref = footCenter
        # CP_ref = footCenter_ref
        bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce(
            bodyIDsToCheck, mus, Ks, Ds)
        CP = yrp.getCP(contactPositions, contactForces)
        if CP_old[0] is None or CP is None:
            dCP = None
        else:
            dCP = (CP - CP_old[0]) / (1 / 30.)
        CP_old[0] = CP

        if CP is not None and dCP is not None:
            ddCP_des = Kh * (CP_ref - CP) - Dh * dCP
            dCP_des = dCP + ddCP_des * (1 / 30.)
            CP_des = CP + dCP_des * (1 / 30.)
            # CP_des = footCenter
            CP_des = CP + dCP * (1 / 30.) + .5 * ddCP_des * ((1 / 30.)**2)
            dH_des = np.cross(
                (CP_des - CM),
                (dL_des_plane + totalMass * mm.s2v(wcfg.gravity)))
            if contactChangeCount > 0:  # and contactChangeType == 'DtoS':
                dH_des *= (maxContactChangeCount -
                           contactChangeCount) / maxContactChangeCount
        else:
            dH_des = None

        # convex hull
        contact_pos_2d = np.asarray([
            np.array([contactPosition[0], contactPosition[2]])
            for contactPosition in contactPositions
        ])
        p = np.array([CM_plane[0], CM_plane[2]])
        # hull = None  # type: Delaunay
        # if contact_pos_2d.shape[0] > 0:
        #     hull = Delaunay(contact_pos_2d)
        #     print(hull.find_simplex(p) >= 0)

        # set up equality constraint
        # TODO:
        # logSO3 is just q'', not acceleration.
        # To make a_oris acceleration, q'' -> a will be needed
        # body_ddqs = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(body_ori, mm.unitY()), mm.unitY()) for body_ori in contact_body_ori]))
        # body_ddqs = list(map(mm.logSO3, [np.dot(contact_body_ori[i].T, np.dot(ref_body_ori[i], mm.getSO3FromVectors(np.dot(ref_body_ori[i], mm.unitY()), mm.unitY()))) for i in range(len(contact_body_ori))]))
        # body_ddqs = list(map(mm.logSO3, [np.dot(contact_body_ori[i].T, np.dot(ref_body_ori[i], mm.getSO3FromVectors(np.dot(ref_body_ori[i], up_vec_in_each_link[contact_ids[i]]), mm.unitY()))) for i in range(len(contact_body_ori))]))
        a_oris = list(
            map(mm.logSO3, [
                np.dot(
                    contact_body_ori[i].T,
                    np.dot(
                        ref_body_ori[i],
                        mm.getSO3FromVectors(
                            np.dot(ref_body_ori[i],
                                   up_vec_in_each_link[contact_ids[i]]),
                            mm.unitY()))) for i in range(len(contact_body_ori))
            ]))
        a_oris = list(
            map(mm.logSO3, [
                np.dot(
                    np.dot(
                        ref_body_ori[i],
                        mm.getSO3FromVectors(
                            np.dot(ref_body_ori[i],
                                   up_vec_in_each_link[contact_ids[i]]),
                            mm.unitY())), contact_body_ori[i].T)
                for i in range(len(contact_body_ori))
            ]))
        body_qs = list(map(mm.logSO3, contact_body_ori))
        body_angs = [
            np.dot(contact_body_ori[i], contact_body_angvel[i])
            for i in range(len(contact_body_ori))
        ]
        body_dqs = [
            mm.vel2qd(body_angs[i], body_qs[i]) for i in range(len(body_angs))
        ]
        # a_oris = [np.dot(contact_body_ori[i], mm.qdd2accel(body_ddqs[i], body_dqs[i], body_qs[i])) for i in range(len(contact_body_ori))]

        # body_ddq = body_ddqs[0]
        # body_ori = contact_body_ori[0]
        # body_ang = np.dot(body_ori.T, contact_body_angvel[0])
        #
        # body_q = mm.logSO3(body_ori)
        # body_dq = mm.vel2qd(body_ang, body_q)
        # a_ori = np.dot(body_ori, mm.qdd2accel(body_ddq, body_dq, body_q))

        KT_SUP = np.diag([kt_sup / 10., kt_sup, kt_sup / 10.])
        # KT_SUP = np.diag([kt_sup, kt_sup, kt_sup])

        # a_oris = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(body_ori, mm.unitY()), mm.unitY()) for body_ori in contact_body_ori]))
        # a_oris = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(contact_body_ori[i], up_vec_in_each_link[contact_ids[i]]), mm.unitY()) for i in range(len(contact_body_ori))]))
        # a_sups = [np.append(kt_sup*(ref_body_pos[i] - contact_body_pos[i] + contMotionOffset) + dt_sup*(ref_body_vel[i] - contact_body_vel[i]),
        #                     kt_sup*a_oris[i]+dt_sup*(ref_body_angvel[i]-contact_body_angvel[i])) for i in range(len(a_oris))]
        # a_sups = [np.append(kt_sup*(ref_body_pos[i] - contact_body_pos[i] + contMotionOffset) - dt_sup * contact_body_vel[i],
        #                     kt_sup*a_oris[i] - dt_sup * contact_body_angvel[i]) for i in range(len(a_oris))]
        a_sups = [
            np.append(
                np.dot(KT_SUP,
                       (ref_body_pos[i] - contact_body_pos[i] +
                        contMotionOffset)) - dt_sup * contact_body_vel[i],
                kt_sup * a_oris[i] - dt_sup * contact_body_angvel[i])
            for i in range(len(a_oris))
        ]
        # for i in range(len(a_sups)):
        #     a_sups[i][1] = -kt_sup * contact_body_pos[i][1] - dt_sup * contact_body_vel[i][1]

        # momentum matrix
        RS = np.dot(P, Jsys)
        R, S = np.vsplit(RS, 2)

        # rs = np.dot((np.dot(dP, Jsys) + np.dot(P, dJsys)), dth_flat)
        rs = np.dot(dP, np.dot(Jsys, dth_flat)) + np.dot(P, dJsys)
        r_bias, s_bias = np.hsplit(rs, 2)

        #######################################################
        # optimization
        #######################################################
        # if contact == 2 and footCenterR[1] > doubleTosingleOffset/2:
        if contact_left and not contact_right:
            config['weightMap']['RightUpLeg'] = .8
            config['weightMap']['RightLeg'] = .8
            config['weightMap']['RightFoot'] = .8
        else:
            config['weightMap']['RightUpLeg'] = .1
            config['weightMap']['RightLeg'] = .25
            config['weightMap']['RightFoot'] = .2

        # if contact == 1 and footCenterL[1] > doubleTosingleOffset/2:
        if contact_right and not contact_left:
            config['weightMap']['LeftUpLeg'] = .8
            config['weightMap']['LeftLeg'] = .8
            config['weightMap']['LeftFoot'] = .8
        else:
            config['weightMap']['LeftUpLeg'] = .1
            config['weightMap']['LeftLeg'] = .25
            config['weightMap']['LeftFoot'] = .2

        w = mot.getTrackingWeight(DOFs, motion[0].skeleton,
                                  config['weightMap'])

        mot.addTrackingTerms(problem, totalDOF, Bt, w, ddth_des_flat)
        if dH_des is not None:
            mot.addLinearTerms(problem, totalDOF, Bl, dL_des_plane, R, r_bias)
            mot.addAngularTerms(problem, totalDOF, Bh, dH_des, S, s_bias)

            if True:
                for c_idx in range(len(contact_ids)):
                    mot.addConstraint2(problem, totalDOF, J_contacts[c_idx],
                                       dJ_contacts[c_idx], dth_flat,
                                       a_sups[c_idx])

        if contactChangeCount > 0:
            contactChangeCount = contactChangeCount - 1
            if contactChangeCount == 0:
                maxContactChangeCount = 30
                contactChangeType = 0

        r = problem.solve()
        problem.clear()
        ddth_sol_flat = np.asarray(r['x'])
        # ddth_sol_flat[foot_seg_dofs] = np.array(ddth_des_flat)[foot_seg_dofs]
        ype.nested(ddth_sol_flat, ddth_sol)

        rootPos[0] = controlModel.getBodyPositionGlobal(selectedBody)
        localPos = [[0, 0, 0]]

        for i in range(stepsPerFrame):
            # apply penalty force
            bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce(
                bodyIDsToCheck, mus, Ks, Ds)
            # bodyIDs, contactPositions, contactPositionLocals, contactForces, contactVelocities = vpWorld.calcManyPenaltyForce(0, bodyIDsToCheck, mus, Ks, Ds)
            vpWorld.applyPenaltyForce(bodyIDs, contactPositionLocals,
                                      contactForces)

            controlModel.setDOFAccelerations(ddth_sol)
            # controlModel.setDOFAccelerations(ddth_des)
            # controlModel.set_ddq(ddth_sol_flat)
            # controlModel.set_ddq(ddth_des_flat)
            controlModel.solveHybridDynamics()

            if forceShowTime > viewer.objectInfoWnd.labelForceDur.value():
                forceShowTime = 0
                viewer_ResetForceState()

            forceforce = np.array([
                viewer.objectInfoWnd.labelForceX.value(),
                viewer.objectInfoWnd.labelForceY.value(),
                viewer.objectInfoWnd.labelForceZ.value()
            ])
            extraForce[0] = getParamVal('Fm') * mm.normalize2(forceforce)
            if viewer_GetForceState():
                forceShowTime += wcfg.timeStep
                vpWorld.applyPenaltyForce(selectedBodyId, localPos, extraForce)

            vpWorld.step()

        controlModel_ik.set_q(controlModel.get_q())

        # rendering
        bodyIDs, geomIDs, positionLocalsForGeom = vpWorld.getContactInfoForcePlate(
            bodyIDsToCheck)
        for foot_seg_id in footIdlist:
            control_model_renderer.body_colors[foot_seg_id] = (255, 240, 255)
            control_model_renderer.geom_colors[foot_seg_id] = [
                (255, 240, 255)
            ] * controlModel.getBodyGeomNum(foot_seg_id)

        for i in range(len(geomIDs)):
            if controlModel.vpid2index(bodyIDs[i]) in footIdlist:
                control_model_renderer.geom_colors[controlModel.vpid2index(
                    bodyIDs[i])][geomIDs[i]] = (255, 0, 0)
        # for foot_seg_id in footIdlist:
        #     control_model_renderer.body_colors[foot_seg_id] = (255, 240, 255)
        #
        # for contact_id in contact_ids:
        #     control_model_renderer.body_colors[contact_id] = (255, 0, 0)

        rd_footCenter[0] = footCenter
        rd_footCenter_ref[0] = footCenter_ref

        rd_CM[0] = CM

        rd_CM_plane[0] = CM.copy()
        rd_CM_plane[0][1] = 0.

        if CP is not None and dCP is not None:
            rd_CP[0] = CP
            rd_CP_des[0] = CP_des

            rd_dL_des_plane[0] = [
                dL_des_plane[0] / 100, dL_des_plane[1] / 100,
                dL_des_plane[2] / 100
            ]
            rd_dH_des[0] = dH_des

            rd_grf_des[0] = dL_des_plane - totalMass * mm.s2v(wcfg.gravity)

        del rd_foot_ori[:]
        del rd_foot_pos[:]
        # for seg_foot_id in footIdlist:
        #     rd_foot_ori.append(controlModel.getJointOrientationGlobal(seg_foot_id))
        #     rd_foot_pos.append(controlModel.getJointPositionGlobal(seg_foot_id))
        rd_foot_ori.append(controlModel.getJointOrientationGlobal(supL))
        rd_foot_ori.append(controlModel.getJointOrientationGlobal(supR))
        rd_foot_pos.append(controlModel.getJointPositionGlobal(supL))
        rd_foot_pos.append(controlModel.getJointPositionGlobal(supR))

        rd_root_des[0] = rootPos[0]
        rd_root_ori[0] = controlModel.getBodyOrientationGlobal(0)
        rd_root_pos[0] = controlModel.getBodyPositionGlobal(0)

        del rd_CF[:]
        del rd_CF_pos[:]
        for i in range(len(contactPositions)):
            rd_CF.append(contactForces[i] / 400)
            rd_CF_pos.append(contactPositions[i].copy())

        if viewer_GetForceState():
            rd_exfen_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exf_des[0] = [0, 0, 0]
        else:
            rd_exf_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exfen_des[0] = [0, 0, 0]

        # extraForcePos[0] = controlModel.getBodyPositionGlobal(selectedBody)
        extraForcePos[0] = controlModel.getBodyPositionGlobal(
            selectedBody) - 0.1 * np.array([
                viewer.objectInfoWnd.labelForceX.value(), 0.,
                viewer.objectInfoWnd.labelForceZ.value()
            ])

        # render contact_ids

        # render skeleton
        if SKELETON_ON:
            Ts = dict()
            Ts['pelvis'] = controlModel.getJointTransform(idDic['Hips'])
            Ts['thigh_R'] = controlModel.getJointTransform(idDic['RightUpLeg'])
            Ts['shin_R'] = controlModel.getJointTransform(idDic['RightLeg'])
            Ts['foot_R'] = controlModel.getJointTransform(idDic['RightFoot'])
            Ts['foot_heel_R'] = controlModel.getJointTransform(
                idDic['RightFoot'])
            Ts['heel_R'] = np.eye(4)
            Ts['outside_metatarsal_R'] = controlModel.getJointTransform(
                idDic['RightFoot_foot_0_0'])
            Ts['outside_phalanges_R'] = controlModel.getJointTransform(
                idDic['RightFoot_foot_0_0_0'])
            # Ts['inside_metatarsal_R'] = controlModel.getJointTransform(idDic['RightFoot_foot_0_1'])
            Ts['inside_metatarsal_R'] = np.eye(4)
            Ts['inside_phalanges_R'] = controlModel.getJointTransform(
                idDic['RightFoot_foot_0_1_0'])
            Ts['spine_ribs'] = controlModel.getJointTransform(idDic['Spine'])
            Ts['head'] = controlModel.getJointTransform(idDic['Spine1'])
            Ts['upper_limb_R'] = controlModel.getJointTransform(
                idDic['RightArm'])
            Ts['lower_limb_R'] = controlModel.getJointTransform(
                idDic['RightForeArm'])
            Ts['thigh_L'] = controlModel.getJointTransform(idDic['LeftUpLeg'])
            Ts['shin_L'] = controlModel.getJointTransform(idDic['LeftLeg'])
            Ts['foot_L'] = controlModel.getJointTransform(idDic['LeftFoot'])
            Ts['foot_heel_L'] = controlModel.getJointTransform(
                idDic['LeftFoot'])
            Ts['heel_L'] = np.eye(4)
            Ts['outside_metatarsal_L'] = controlModel.getJointTransform(
                idDic['LeftFoot_foot_0_0'])
            Ts['outside_phalanges_L'] = controlModel.getJointTransform(
                idDic['LeftFoot_foot_0_0_0'])
            # Ts['inside_metatarsal_L'] = controlModel.getJointTransform(idDic['LeftFoot_foot_0_1'])
            Ts['inside_metatarsal_L'] = np.eye(4)
            Ts['inside_phalanges_L'] = controlModel.getJointTransform(
                idDic['LeftFoot_foot_0_1_0'])
            Ts['upper_limb_L'] = controlModel.getJointTransform(
                idDic['LeftArm'])
            Ts['lower_limb_L'] = controlModel.getJointTransform(
                idDic['LeftForeArm'])

            skeleton_renderer.appendFrameState(Ts)

    def postFrameCallback_Always(frame):
        pass
        # if foot_viewer is not None:
        #     foot_viewer.foot_pressure_gl_window.refresh_foot_contact_info(frame, vpWorld, bodyIDsToCheck, mus, Ks, Ds)
        #     foot_viewer.foot_pressure_gl_window.goToFrame(frame)

    viewer.setPostFrameCallback_Always(postFrameCallback_Always)
    viewer.setSimulateCallback(simulateCallback)
    viewer.startTimer(1 / 30.)
    # viewer.play()
    viewer.show()

    foot_viewer = FootWindow(viewer.x() + viewer.w() + 20, viewer.y(), 300,
                             500, 'foot contact modifier', controlModel)
    foot_viewer.show()
    foot_viewer.check_all_seg()
    viewer.motionViewWnd.goToFrame(0)

    Fl.run()
예제 #10
0
def footAdjust(posture_ori, touch_body_indices, SEGMENT_FOOT_MAG, SEGMENT_FOOT_RAD, baseHeight=0.):
    """

    :param posture_ori:
    :type posture_ori: ym.JointPosture
    :param touch_body_indices:
    :type touch_body_indices: list[str]
    :param SEGMENT_FOOT_MAG:
    :type SEGMENT_FOOT_MAG: float
    :param SEGMENT_FOOT_RAD:
    :type SEGMENT_FOOT_RAD: float
    :param baseHeight:
    :type baseHeight: float
    :return:
    """
    if len(touch_body_indices) == 0:
        return

    # idDic: name to idx
    idDic = dict()
    for i in range(posture_ori.skeleton.getJointNum()):
        idDic[posture_ori.skeleton.getJointName(i)] = i

    # nameDic: index to name
    nameDic = dict()
    for i in range(posture_ori.skeleton.getJointNum()):
        nameDic[i] = posture_ori.skeleton.getJointName(i)

    # specified
    foot_name = "LeftFoot"
    # side_touch_body_indices: left or right foot touch body indices
    side_touch_body_indices = [touch_body_idx for touch_body_idx in touch_body_indices if foot_name in nameDic[touch_body_idx]]
    # foot_joint_pos: ankle joint position
    foot_joint_pos = posture_ori.getJointPositionGlobal(idDic[foot_name])
    seg_joint_ori = [posture_ori.getJointOrientationGlobal(touch_body_idx) for touch_body_idx in side_touch_body_indices]
    seg_joint_pos = []
    for touch_body_idx in side_touch_body_indices:
        if nameDic[touch_body_idx] == foot_name+'_foot_0_0':
            seg_joint_pos.append(posture_ori.getJointPositionGlobal(touch_body_idx) + SEGMENT_FOOT_MAG*np.dot(seg_joint_ori, -1.936*mm.unitY()).flatten())
        else:
            seg_joint_pos.append(posture_ori.getJointPositionGlobal(touch_body_idx))

    if len(side_touch_body_indices) == 0:
        pass
    elif len(side_touch_body_indices) == 1:
        seg_idx = side_touch_body_indices[0]

        # seg joint y pos to 0
        ankle_to_joint_vec = seg_joint_pos[0] - foot_joint_pos
        joint_vec_rot_axis, temp_angle = mm.getRotAxisAngleFromVectors(ankle_to_joint_vec, -mm.unitY())
        joint_y_to_zero_angle = temp_angle - math.acos((foot_joint_pos[1] - SEGMENT_FOOT_RAD - baseHeight)/np.linalg.norm(ankle_to_joint_vec))
        posture_ori.mulJointOrientationGlobal(idDic[foot_name], mm.exp(joint_vec_rot_axis, joint_y_to_zero_angle))

        ###############################################################
        # TODO:
        ###############################################################
        # rotate seg to parallel ground
        seg_ori = posture_ori.getJointOrientationGlobal(seg_idx)
        posture_ori.mulJointOrientationGlobal(seg_idx, seg_ori.T)

    elif len(side_touch_body_indices) == 2:
        seg_idx = [side_touch_body_indices[0], side_touch_body_indices[1]]

        ankle_to_joint_vecs = [seg_joint_pos[i] - foot_joint_pos for i in range(len(seg_idx))]
        ankle_to_joint_vec = .5*(ankle_to_joint_vecs[0] + ankle_to_joint_vecs[1])
        joint_vec_rot_axis, temp_angle = mm.getRotAxisAngleFromVectors(ankle_to_joint_vec, -mm.unitY())
        joint_y_to_zero_angle = temp_angle - math.acos((foot_joint_pos[1] - SEGMENT_FOOT_RAD - baseHeight)/np.linalg.norm(ankle_to_joint_vec))
        posture_ori.mulJointOrientationGlobal(idDic[foot_name], mm.exp(joint_vec_rot_axis, joint_y_to_zero_angle))



    seg_contact_pos = []
    for touch_body_idx in side_touch_body_indices:
        ith_seg_contact_pos = []
        if nameDic[touch_body_idx] == foot_name+'_foot_0_0_0':
            ith_seg_contact_pos.append(seg_joint_pos)
            ith_seg_contact_pos.append(seg_joint_pos + np.dot(seg_joint_ori, mm.unitZ()))
            ith_seg_contact_pos.append(seg_joint_pos + np.dot(seg_joint_ori, mm.unitX()))
        if nameDic[touch_body_idx] == foot_name+'_foot_0_1_0':
            ith_seg_contact_pos.append(seg_joint_pos + np.dot(seg_joint_ori, np.array([0., 0., 0.])))
            pass
        if nameDic[touch_body_idx] == foot_name+'_foot_0_0':
            pass
        if nameDic[touch_body_idx] == foot_name+'_foot_1_0':
            pass


    # unspecified
    pass
예제 #11
0
    def simulateCallback(frame):
        # print(frame)
        # print(motion[frame].getJointOrientationLocal(footIdDic['RightFoot_foot_0_1_0']))
        if False and viewer_GetForceState():
            # print('force on, frame: ', frame)
            motion[frame].mulJointOrientationLocal(
                footIdDic['LeftFoot_foot_0_0_0'],
                mm.exp(mm.unitX(), -math.pi * mm.SCALAR_1_6))
            motion[frame].mulJointOrientationLocal(
                footIdDic['LeftFoot_foot_0_1_0'],
                mm.exp(mm.unitX(), -math.pi * mm.SCALAR_1_6))
            motion[frame].mulJointOrientationLocal(
                footIdDic['RightFoot_foot_0_0_0'],
                mm.exp(mm.unitX(), -math.pi * mm.SCALAR_1_6))
            motion[frame].mulJointOrientationLocal(
                footIdDic['RightFoot_foot_0_1_0'],
                mm.exp(mm.unitX(), -math.pi * mm.SCALAR_1_6))
        # print(motion[frame].getJointOrientationLocal(footIdDic['RightFoot_foot_0_1_0']))
        motionModel.update(motion[frame])
        controlModel_ik.set_q(controlModel.get_q())

        global g_initFlag
        global forceShowTime

        global JsysPre
        global JsupPreL
        global JsupPreR

        global JconstPre

        global preFootCenter
        global maxContactChangeCount
        global contactChangeCount
        global contact
        global contactChangeType

        # Kt, Kl, Kh, Bl, Bh, kt_sup = viewer.GetParam()
        Kt, Kl, Kh, Bl, Bh, kt_sup = getParamVals(
            ['Kt', 'Kl', 'Kh', 'Bl', 'Bh', 'SupKt'])
        Dt = 2 * (Kt**.5)
        Dl = 2 * (Kl**.5)
        Dh = 2 * (Kh**.5)
        dt_sup = 2 * (kt_sup**.5)

        doubleTosingleOffset = 0.15
        singleTodoubleOffset = 0.30
        # doubleTosingleOffset = 0.09
        doubleTosingleVelOffset = 0.0

        # tracking
        th_r = motion.getDOFPositions(frame)
        th = controlModel.getDOFPositions()
        dth_r = motion.getDOFVelocities(frame)
        dth = controlModel.getDOFVelocities()
        ddth_r = motion.getDOFAccelerations(frame)
        ddth_des = yct.getDesiredDOFAccelerations(th_r, th, dth_r, dth, ddth_r,
                                                  Kt, Dt)

        ype.flatten(ddth_des, ddth_des_flat)
        # ddth_des_flat = Kt * (motion.get_q(frame) - np.array(controlModel.get_q())) - Dt * np.array(controlModel.get_dq())
        ype.flatten(dth, dth_flat)
        # dth_flat = np.array(controlModel.get_dq())

        #################################################
        # jacobian
        #################################################

        contact_des_ids = list()  # desired contact segments
        if foot_viewer.check_om_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_0_0'))
        if foot_viewer.check_op_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_0_0_0'))
        if foot_viewer.check_im_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_0_1'))
        if foot_viewer.check_ip_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_0_1_0'))
        if foot_viewer.check_h_l.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('LeftFoot_foot_1_0'))

        if foot_viewer.check_om_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_0_0'))
        if foot_viewer.check_op_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_0_0_0'))
        if foot_viewer.check_im_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_0_1'))
        if foot_viewer.check_ip_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_0_1_0'))
        if foot_viewer.check_h_r.value():
            contact_des_ids.append(
                motion[0].skeleton.getJointIndex('RightFoot_foot_1_0'))

        contact_ids = list()  # temp idx for balancing
        contact_ids.extend(contact_des_ids)

        contact_joint_ori = list(
            map(controlModel.getJointOrientationGlobal, contact_ids))
        contact_joint_pos = list(
            map(controlModel.getJointPositionGlobal, contact_ids))
        contact_body_ori = list(
            map(controlModel.getBodyOrientationGlobal, contact_ids))
        contact_body_pos = list(
            map(controlModel.getBodyPositionGlobal, contact_ids))
        contact_body_vel = list(
            map(controlModel.getBodyVelocityGlobal, contact_ids))
        contact_body_angvel = list(
            map(controlModel.getBodyAngVelocityGlobal, contact_ids))

        ref_joint_ori = list(
            map(motion[frame].getJointOrientationGlobal, contact_ids))
        ref_joint_pos = list(
            map(motion[frame].getJointPositionGlobal, contact_ids))
        ref_joint_vel = [
            motion.getJointVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_joint_angvel = [
            motion.getJointAngVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_body_ori = list(
            map(motionModel.getBodyOrientationGlobal, contact_ids))
        ref_body_pos = list(map(motionModel.getBodyPositionGlobal,
                                contact_ids))
        # ref_body_vel = list(map(controlModel.getBodyVelocityGlobal, contact_ids))
        ref_body_angvel = [
            motion.getJointAngVelocityGlobal(joint_idx, frame)
            for joint_idx in contact_ids
        ]
        ref_body_vel = [
            ref_joint_vel[i] +
            np.cross(ref_joint_angvel[i], ref_body_pos[i] - ref_joint_pos[i])
            for i in range(len(ref_joint_vel))
        ]

        J_contacts = [
            yjc.makeEmptyJacobian(DOFs, 1) for i in range(len(contact_ids))
        ]
        dJ_contacts = [
            yjc.makeEmptyJacobian(DOFs, 1) for i in range(len(contact_ids))
        ]
        joint_masks = [
            yjc.getLinkJointMask(motion[0].skeleton, joint_idx)
            for joint_idx in contact_ids
        ]

        # caution!! body orientation and joint orientation of foot are totally different!!
        footOriL = controlModel.getJointOrientationGlobal(supL)
        footOriR = controlModel.getJointOrientationGlobal(supR)

        # desire footCenter[1] = 0.041135
        # desire footCenter[1] = 0.0197
        footCenterL = controlModel.getBodyPositionGlobal(supL)
        footCenterR = controlModel.getBodyPositionGlobal(supR)
        footBodyOriL = controlModel.getBodyOrientationGlobal(supL)
        footBodyOriR = controlModel.getBodyOrientationGlobal(supR)
        footBodyVelL = controlModel.getBodyVelocityGlobal(supL)
        footBodyVelR = controlModel.getBodyVelocityGlobal(supR)
        footBodyAngVelL = controlModel.getBodyAngVelocityGlobal(supL)
        footBodyAngVelR = controlModel.getBodyAngVelocityGlobal(supR)

        refFootL = motionModel.getBodyPositionGlobal(supL)
        refFootR = motionModel.getBodyPositionGlobal(supR)
        refFootVelL = motionModel.getBodyVelocityGlobal(supL)
        refFootVelR = motionModel.getBodyVelocityGlobal(supR)
        refFootAngVelL = motionModel.getBodyAngVelocityGlobal(supL)
        refFootAngVelR = motionModel.getBodyAngVelocityGlobal(supR)

        refFootJointVelR = motion.getJointVelocityGlobal(supR, frame)
        refFootJointAngVelR = motion.getJointAngVelocityGlobal(supR, frame)
        refFootJointR = motion.getJointPositionGlobal(supR, frame)
        refFootVelR = refFootJointVelR + np.cross(refFootJointAngVelR,
                                                  (refFootR - refFootJointR))

        refFootJointVelL = motion.getJointVelocityGlobal(supL, frame)
        refFootJointAngVelL = motion.getJointAngVelocityGlobal(supL, frame)
        refFootJointL = motion.getJointPositionGlobal(supL, frame)
        refFootVelL = refFootJointVelL + np.cross(refFootJointAngVelL,
                                                  (refFootL - refFootJointL))

        is_contact = [1] * len(contact_ids)
        contactR = 1
        contactL = 1
        if refFootVelR[1] < 0 and refFootVelR[1] / 30. + refFootR[
                1] > singleTodoubleOffset:
            contactR = 0
        if refFootVelL[1] < 0 and refFootVelL[1] / 30. + refFootL[
                1] > singleTodoubleOffset:
            contactL = 0
        if refFootVelR[1] > 0 and refFootVelR[1] / 30. + refFootR[
                1] > doubleTosingleOffset:
            contactR = 0
        if refFootVelL[1] > 0 and refFootVelL[1] / 30. + refFootL[
                1] > doubleTosingleOffset:
            contactL = 0
        # contactR = 1

        contMotionOffset = th[0][0] - th_r[0][0]

        linkPositions = controlModel.getBodyPositionsGlobal()
        linkVelocities = controlModel.getBodyVelocitiesGlobal()
        linkAngVelocities = controlModel.getBodyAngVelocitiesGlobal()
        linkInertias = controlModel.getBodyInertiasGlobal()

        CM = yrp.getCM(linkPositions, linkMasses, totalMass)
        dCM = yrp.getCM(linkVelocities, linkMasses, totalMass)
        CM_plane = copy.copy(CM)
        CM_plane[1] = 0.
        dCM_plane = copy.copy(dCM)
        dCM_plane[1] = 0.

        P = ymt.getPureInertiaMatrix(TO, linkMasses, linkPositions, CM,
                                     linkInertias)
        dP = ymt.getPureInertiaMatrixDerivative(dTO, linkMasses,
                                                linkVelocities, dCM,
                                                linkAngVelocities,
                                                linkInertias)

        # calculate contact state
        # if g_initFlag == 1 and contact == 1 and refFootR[1] < doubleTosingleOffset and footCenterR[1] < 0.08:
        if g_initFlag == 1:
            # contact state
            # 0: flying 1: right only 2: left only 3: double
            # if contact == 2 and refFootR[1] < doubleTosingleOffset:
            if contact == 2 and contactR == 1:
                contact = 3
                maxContactChangeCount += 30
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'StoD'

            # elif contact == 3 and refFootL[1] < doubleTosingleOffset:
            elif contact == 1 and contactL == 1:
                contact = 3
                maxContactChangeCount += 30
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'StoD'

            # elif contact == 3 and refFootR[1] > doubleTosingleOffset:
            elif contact == 3 and contactR == 0:
                contact = 2
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'DtoS'

            # elif contact == 3 and refFootL[1] > doubleTosingleOffset:
            elif contact == 3 and contactL == 0:
                contact = 1
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'DtoS'
            else:
                contact = 0
                # if refFootR[1] < doubleTosingleOffset:
                if contactR == 1:
                    contact += 1
                # if refFootL[1] < doubleTosingleOffset:
                if contactL == 1:
                    contact += 2

        # initialization
        if g_initFlag == 0:
            # JsysPre = Jsys.copy()
            JconstPre = Jconst.copy()
            softConstPoint = footCenterR.copy()
            # yjc.computeJacobian2(JsysPre, DOFs, jointPositions, jointAxeses, linkPositions, allLinkJointMasks)
            # yjc.computeJacobian2(JconstPre, DOFs, jointPositions, jointAxeses, [softConstPoint], constJointMasks)

            footCenter = footCenterL + (footCenterR - footCenterL) / 2.0
            footCenter[1] = 0.
            preFootCenter = footCenter.copy()
            # footToBodyFootRotL = np.dot(np.transpose(footOriL), footBodyOriL)
            # footToBodyFootRotR = np.dot(np.transpose(footOriR), footBodyOriR)

            if refFootR[1] < doubleTosingleOffset:
                contact += 1
            if refFootL[1] < doubleTosingleOffset:
                contact += 2

            g_initFlag = 1

        # calculate jacobian
        Jsys, dJsys = controlModel.computeCom_J_dJdq()
        for i in range(len(J_contacts)):
            J_contacts[i] = Jsys[6 * contact_ids[i]:6 * contact_ids[i] + 6, :]
            dJ_contacts[i] = dJsys[6 * contact_ids[i]:6 * contact_ids[i] + 6]

        # calculate footCenter
        footCenter = sum(contact_body_pos) / len(contact_body_pos) if len(contact_body_pos) > 0 \
                        else .5 * (controlModel.getBodyPositionGlobal(supL) + controlModel.getBodyPositionGlobal(supR))
        # if len(contact_body_pos) > 2:
        #     hull = ConvexHull(contact_body_pos)

        footCenter_ref = sum(ref_body_pos) / len(ref_body_pos) if len(ref_body_pos) > 0 \
            else .5 * (motionModel.getBodyPositionGlobal(supL) + motionModel.getBodyPositionGlobal(supR))
        footCenter_ref = footCenter_ref + contMotionOffset
        # if len(ref_body_pos) > 2:
        #     hull = ConvexHull(ref_body_pos)
        footCenter_ref[1] = 0.

        # footCenter = footCenterL + (footCenterR - footCenterL)/2.0
        # if refFootR[1] >doubleTosingleOffset:
        # if refFootR[1] > doubleTosingleOffset or footCenterR[1] > 0.08:
        # if contact == 1 or footCenterR[1] > 0.08:
        # if contact == 2 or footCenterR[1] > doubleTosingleOffset/2:
        if contact == 2:
            footCenter = footCenterL.copy()
        # elif contact == 1 or footCenterL[1] > doubleTosingleOffset/2:
        if contact == 1:
            footCenter = footCenterR.copy()
        footCenter[1] = 0.

        footCenter[0] = footCenter[0] + getParamVal('com X offset')

        if contactChangeCount > 0 and contactChangeType == 'StoD':
            # change footcenter gradually
            footCenter = preFootCenter + (
                maxContactChangeCount - contactChangeCount) * (
                    footCenter - preFootCenter) / maxContactChangeCount

        preFootCenter = footCenter.copy()

        # linear momentum
        # TODO:
        # We should consider dCM_ref, shouldn't we?
        # add getBodyPositionGlobal and getBodyPositionsGlobal in csVpModel!
        # to do that, set joint velocities to vpModel
        CM_ref_plane = footCenter
        # CM_ref_plane = footCenter_ref
        dL_des_plane = Kl * totalMass * (CM_ref_plane -
                                         CM_plane) - Dl * totalMass * dCM_plane
        # dL_des_plane[1] = 0.
        # print('dCM_plane : ', np.linalg.norm(dCM_plane))

        # angular momentum
        CP_ref = footCenter
        # CP_ref = footCenter_ref
        bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce(
            bodyIDsToCheck, mus, Ks, Ds)
        # bodyIDs, contactPositions, contactPositionLocals, contactForces, contactVelocities = vpWorld.calcManyPenaltyForce(0, bodyIDsToCheck, mus, Ks, Ds)
        CP = yrp.getCP(contactPositions, contactForces)
        if CP_old[0] is None or CP is None:
            dCP = None
        else:
            dCP = (CP - CP_old[0]) / (1 / 30.)
        CP_old[0] = CP

        if CP is not None and dCP is not None:
            ddCP_des = Kh * (CP_ref - CP) - Dh * dCP
            dCP_des = dCP + ddCP_des * (1 / 30.)
            CP_des = CP + dCP_des * (1 / 30.)
            # CP_des = footCenter
            CP_des = CP + dCP * (1 / 30.) + .5 * ddCP_des * ((1 / 30.)**2)
            dH_des = np.cross(
                (CP_des - CM),
                (dL_des_plane + totalMass * mm.s2v(wcfg.gravity)))
            if contactChangeCount > 0:  # and contactChangeType == 'DtoS':
                dH_des *= (maxContactChangeCount -
                           contactChangeCount) / maxContactChangeCount
        else:
            dH_des = None

        # convex hull
        contact_pos_2d = np.asarray([
            np.array([contactPosition[0], contactPosition[2]])
            for contactPosition in contactPositions
        ])
        p = np.array([CM_plane[0], CM_plane[2]])
        # hull = None  # type: Delaunay
        # if contact_pos_2d.shape[0] > 0:
        #     hull = Delaunay(contact_pos_2d)
        #     print(hull.find_simplex(p) >= 0)

        # set up equality constraint
        # TODO:
        # logSO3 is just q'', not acceleration.
        # To make a_oris acceleration, q'' -> a will be needed
        # body_ddqs = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(body_ori, mm.unitY()), mm.unitY()) for body_ori in contact_body_ori]))
        body_ddqs = list(
            map(mm.logSO3, [
                np.dot(
                    contact_body_ori[i].T,
                    np.dot(
                        ref_body_ori[i],
                        mm.getSO3FromVectors(
                            np.dot(ref_body_ori[i], mm.unitY()), mm.unitY())))
                for i in range(len(contact_body_ori))
            ]))
        body_qs = list(map(mm.logSO3, contact_body_ori))
        body_angs = [
            np.dot(contact_body_ori[i], contact_body_angvel[i])
            for i in range(len(contact_body_ori))
        ]
        body_dqs = [
            mm.vel2qd(body_angs[i], body_qs[i]) for i in range(len(body_angs))
        ]
        a_oris = [
            np.dot(contact_body_ori[i],
                   mm.qdd2accel(body_ddqs[i], body_dqs[i], body_qs[i]))
            for i in range(len(contact_body_ori))
        ]

        # body_ddq = body_ddqs[0]
        # body_ori = contact_body_ori[0]
        # body_ang = np.dot(body_ori.T, contact_body_angvel[0])
        #
        # body_q = mm.logSO3(body_ori)
        # body_dq = mm.vel2qd(body_ang, body_q)
        # a_ori = np.dot(body_ori, mm.qdd2accel(body_ddq, body_dq, body_q))

        # a_oris = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(body_ori, mm.unitY()), mm.unitY()) for body_ori in contact_body_ori]))
        a_sups = [
            np.append(
                kt_sup *
                (ref_body_pos[i] - contact_body_pos[i] + contMotionOffset) +
                dt_sup * (ref_body_vel[i] - contact_body_vel[i]),
                kt_sup * a_oris[i] + dt_sup *
                (ref_body_angvel[i] - contact_body_angvel[i]))
            for i in range(len(a_oris))
        ]

        # momentum matrix
        RS = np.dot(P, Jsys)
        R, S = np.vsplit(RS, 2)

        # rs = np.dot((np.dot(dP, Jsys) + np.dot(P, dJsys)), dth_flat)
        rs = np.dot(dP, np.dot(Jsys, dth_flat)) + np.dot(P, dJsys)
        r_bias, s_bias = np.hsplit(rs, 2)

        #######################################################
        # optimization
        #######################################################
        # if contact == 2 and footCenterR[1] > doubleTosingleOffset/2:
        if contact == 2:
            config['weightMap']['RightUpLeg'] = .8
            config['weightMap']['RightLeg'] = .8
            config['weightMap']['RightFoot'] = .8
        else:
            config['weightMap']['RightUpLeg'] = .1
            config['weightMap']['RightLeg'] = .25
            config['weightMap']['RightFoot'] = .2

        # if contact == 1 and footCenterL[1] > doubleTosingleOffset/2:
        if contact == 1:
            config['weightMap']['LeftUpLeg'] = .8
            config['weightMap']['LeftLeg'] = .8
            config['weightMap']['LeftFoot'] = .8
        else:
            config['weightMap']['LeftUpLeg'] = .1
            config['weightMap']['LeftLeg'] = .25
            config['weightMap']['LeftFoot'] = .2

        w = mot.getTrackingWeight(DOFs, motion[0].skeleton,
                                  config['weightMap'])

        # if contact == 2:
        #     mot.addSoftPointConstraintTerms(problem, totalDOF, Bsc, ddP_des1, Q1, q_bias1)

        mot.addTrackingTerms(problem, totalDOF, Bt, w, ddth_des_flat)
        if dH_des is not None:
            mot.addLinearTerms(problem, totalDOF, Bl, dL_des_plane, R, r_bias)
            mot.addAngularTerms(problem, totalDOF, Bh, dH_des, S, s_bias)

            # mot.setConstraint(problem, totalDOF, Jsup, dJsup, dth_flat, a_sup)
            # mot.addConstraint(problem, totalDOF, Jsup, dJsup, dth_flat, a_sup)
            # if contact & 1 and contactChangeCount == 0:
            if True:
                for c_idx in range(len(contact_ids)):
                    # mot.addConstraint(problem, totalDOF, J_contacts[c_idx], dJ_contacts[c_idx], dth_flat, a_sups[c_idx])
                    mot.addConstraint2(problem, totalDOF, J_contacts[c_idx],
                                       dJ_contacts[c_idx], dth_flat,
                                       a_sups[c_idx])

        if contactChangeCount > 0:
            contactChangeCount = contactChangeCount - 1
            if contactChangeCount == 0:
                maxContactChangeCount = 30
                contactChangeType = 0

        r = problem.solve()
        problem.clear()
        ddth_sol_flat = np.asarray(r['x'])
        # ddth_sol_flat[foot_seg_dofs] = np.array(ddth_des_flat)[foot_seg_dofs]
        ype.nested(ddth_sol_flat, ddth_sol)

        rootPos[0] = controlModel.getBodyPositionGlobal(selectedBody)
        localPos = [[0, 0, 0]]

        for i in range(stepsPerFrame):
            # apply penalty force
            bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce(
                bodyIDsToCheck, mus, Ks, Ds)
            # bodyIDs, contactPositions, contactPositionLocals, contactForces, contactVelocities = vpWorld.calcManyPenaltyForce(0, bodyIDsToCheck, mus, Ks, Ds)
            vpWorld.applyPenaltyForce(bodyIDs, contactPositionLocals,
                                      contactForces)

            controlModel.setDOFAccelerations(ddth_sol)
            # controlModel.setDOFAccelerations(ddth_des)
            # controlModel.set_ddq(ddth_sol_flat)
            # controlModel.set_ddq(ddth_des_flat)
            controlModel.solveHybridDynamics()

            if forceShowTime > viewer.objectInfoWnd.labelForceDur.value():
                forceShowTime = 0
                viewer_ResetForceState()

            forceforce = np.array([
                viewer.objectInfoWnd.labelForceX.value(),
                viewer.objectInfoWnd.labelForceY.value(),
                viewer.objectInfoWnd.labelForceZ.value()
            ])
            extraForce[0] = getParamVal('Fm') * mm.normalize2(forceforce)
            if viewer_GetForceState():
                forceShowTime += wcfg.timeStep
                vpWorld.applyPenaltyForce(selectedBodyId, localPos, extraForce)

            vpWorld.step()

        controlModel_ik.set_q(controlModel.get_q())

        if foot_viewer is not None:
            foot_viewer.foot_pressure_gl_window.refresh_foot_contact_info(
                frame, vpWorld, bodyIDsToCheck, mus, Ks, Ds)
            foot_viewer.foot_pressure_gl_window.goToFrame(frame)

        # rendering
        for foot_seg_id in footIdlist:
            control_model_renderer.body_colors[foot_seg_id] = (255, 240, 255)

        for contact_id in contact_ids:
            control_model_renderer.body_colors[contact_id] = (255, 0, 0)

        rightFootVectorX[0] = np.dot(footOriL, np.array([.1, 0, 0]))
        rightFootVectorY[0] = np.dot(footOriL, np.array([0, .1, 0]))
        rightFootVectorZ[0] = np.dot(footOriL, np.array([0, 0, .1]))
        rightFootPos[0] = footCenterL

        rightVectorX[0] = np.dot(footBodyOriL, np.array([.1, 0, 0]))
        rightVectorY[0] = np.dot(footBodyOriL, np.array([0, .1, 0]))
        rightVectorZ[0] = np.dot(footBodyOriL, np.array([0, 0, .1]))
        rightPos[0] = footCenterL + np.array([.1, 0, 0])

        rd_footCenter[0] = footCenter
        rd_footCenter_ref[0] = footCenter_ref
        rd_footCenterL[0] = footCenterL
        rd_footCenterR[0] = footCenterR

        rd_CM[0] = CM

        rd_CM_plane[0] = CM.copy()
        rd_CM_plane[0][1] = 0.

        if CP is not None and dCP is not None:
            rd_CP[0] = CP
            rd_CP_des[0] = CP_des

            rd_dL_des_plane[0] = [
                dL_des_plane[0] / 100, dL_des_plane[1] / 100,
                dL_des_plane[2] / 100
            ]
            rd_dH_des[0] = dH_des

            rd_grf_des[0] = dL_des_plane - totalMass * mm.s2v(wcfg.gravity)

        rd_root_des[0] = rootPos[0]
        rd_root_ori[0] = controlModel.getBodyOrientationGlobal(0)
        rd_root_pos[0] = controlModel.getBodyPositionGlobal(0)

        del rd_CF[:]
        del rd_CF_pos[:]
        for i in range(len(contactPositions)):
            rd_CF.append(contactForces[i] / 400)
            rd_CF_pos.append(contactPositions[i].copy())

        if viewer_GetForceState():
            rd_exfen_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exf_des[0] = [0, 0, 0]
        else:
            rd_exf_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exfen_des[0] = [0, 0, 0]

        extraForcePos[0] = controlModel.getBodyPositionGlobal(selectedBody)

        # render contact_ids

        # render skeleton
        if SKELETON_ON:
            Ts = dict()
            Ts['pelvis'] = controlModel.getJointTransform(0)
            Ts['thigh_R'] = controlModel.getJointTransform(1)
            Ts['shin_R'] = controlModel.getJointTransform(2)
            Ts['foot_R'] = controlModel.getJointTransform(3)
            Ts['spine_ribs'] = controlModel.getJointTransform(9)
            Ts['head'] = controlModel.getJointTransform(10)
            Ts['upper_limb_R'] = controlModel.getJointTransform(13)
            Ts['lower_limb_R'] = controlModel.getJointTransform(14)
            Ts['thigh_L'] = controlModel.getJointTransform(15)
            Ts['shin_L'] = controlModel.getJointTransform(16)
            Ts['foot_L'] = controlModel.getJointTransform(17)
            Ts['upper_limb_L'] = controlModel.getJointTransform(11)
            Ts['lower_limb_L'] = controlModel.getJointTransform(12)

            skeleton_renderer.appendFrameState(Ts)
예제 #12
0
    def simulateCallback(frame):
        # print(frame)
        # print(motion[frame].getJointOrientationLocal(footIdDic['RightFoot_foot_0_1_0']))

        # hfi.footAdjust(motion[frame], idDic, SEGMENT_FOOT_MAG=.03, SEGMENT_FOOT_RAD=.015, baseHeight=0.02)

        # motionModel.update(motion[frame])
        motionModel.translateByOffset(
            np.array([
                getParamVal('com X offset'),
                getParamVal('com Y offset'),
                getParamVal('com Z offset')
            ]))
        # controlModel_ik.set_q(controlModel.get_q())

        global g_initFlag
        global forceShowTime

        global JsysPre
        global JsupPreL
        global JsupPreR

        global JconstPre

        global preFootCenter
        global maxContactChangeCount
        global contactChangeCount
        global contact
        global contactChangeType

        Kt, Kl, Kh, Bl, Bh, kt_sup = getParamVals(
            ['Kt', 'Kl', 'Kh', 'Bl', 'Bh', 'SupKt'])
        Dt = 2 * (Kt**.5)
        Dl = 2 * (Kl**.5)
        Dh = 2 * (Kh**.5)
        dt_sup = 2 * (kt_sup**.5)

        # tracking
        # # th_r = motion.getDOFPositions(frame)
        # th_r = motionModel.getDOFPositions()
        # th = controlModel.getDOFPositions()
        # # dth_r = motion.getDOFVelocities(frame)
        # dth = controlModel.getDOFVelocities()
        # # ddth_r = motion.getDOFAccelerations(frame)
        # ddth_des = yct.getDesiredDOFAccelerations(th_r, th, None, dth, None, Kt, Dt)
        #
        # # ype.flatten(fix_dofs(DOFs, ddth_des, mcfg, joint_names), ddth_des_flat)
        # # ype.flatten(fix_dofs(DOFs, dth, mcfg, joint_names), dth_flat)
        # # print(ddth_des)
        # ype.flatten(ddth_des, ddth_des_flat)
        # ype.flatten(dth, dth_flat)

        th_r_flat = motionModel.get_q()
        th_flat = controlModel.get_q()
        dth_flat = controlModel.get_dq()
        joint_dof_info = controlModel.getJointDOFInfo()

        ddth_des_flat = yct.getDesiredDOFAccelerations_flat(
            th_r_flat, th_flat, None, dth_flat, None, Kt, Dt, joint_dof_info)
        # print(controlModel.getCoriAndGrav())

        #################################################
        # jacobian
        #################################################

        contact_des_ids = list()  # desired contact segments
        contact_des_ids.append(supL)
        # if foot_viewer.check_h_l.value():
        #     contact_des_ids.append(motion[0].skeleton.getJointIndex('LeftFoot'))
        #
        # if foot_viewer.check_h_r.value():
        #     contact_des_ids.append(motion[0].skeleton.getJointIndex('RightFoot'))

        contact_ids = list()  # temp idx for balancing
        contact_ids.extend(contact_des_ids)

        contact_joint_ori = list(
            map(controlModel.getJointOrientationGlobal, contact_ids))
        contact_joint_pos = list(
            map(controlModel.getJointPositionGlobal, contact_ids))
        contact_body_ori = list(
            map(controlModel.getBodyOrientationGlobal, contact_ids))
        contact_body_pos = list(
            map(controlModel.getBodyPositionGlobal, contact_ids))
        contact_body_vel = list(
            map(controlModel.getBodyVelocityGlobal, contact_ids))
        contact_body_angvel = list(
            map(controlModel.getBodyAngVelocityGlobal, contact_ids))

        ref_joint_ori = list(
            map(motionModel.getJointOrientationGlobal, contact_ids))
        ref_joint_pos = list(
            map(motionModel.getJointPositionGlobal, contact_ids))
        ref_joint_vel = [
            motionModel.getJointVelocityGlobal(joint_idx)
            for joint_idx in contact_ids
        ]
        ref_joint_angvel = [
            motionModel.getJointAngVelocityGlobal(joint_idx)
            for joint_idx in contact_ids
        ]
        ref_body_ori = list(
            map(motionModel.getBodyOrientationGlobal, contact_ids))
        ref_body_pos = list(map(motionModel.getBodyPositionGlobal,
                                contact_ids))
        # ref_body_vel = list(map(controlModel.getBodyVelocityGlobal, contact_ids))
        ref_body_angvel = [
            motionModel.getJointAngVelocityGlobal(joint_idx)
            for joint_idx in contact_ids
        ]
        ref_body_vel = [
            ref_joint_vel[i] +
            np.cross(ref_joint_angvel[i], ref_body_pos[i] - ref_joint_pos[i])
            for i in range(len(ref_joint_vel))
        ]

        is_contact = [1] * len(contact_ids)
        contact_right = len(set(contact_des_ids).intersection(rIDlist)) > 0
        contact_left = len(set(contact_des_ids).intersection(lIDlist)) > 0

        # contMotionOffset = th_flat[0:3] - th_r_flat[0:3]
        contMotionOffset = np.array((1.5, 0., 0.))

        linkPositions = [
            controlModel.getBodyComPositionGlobal(i)
            for i in range(controlModel.getBodyNum())
        ]
        linkVelocities = [
            controlModel.getBodyComVelocityGlobal(i)
            for i in range(controlModel.getBodyNum())
        ]
        linkAngVelocities = [
            controlModel.getBodyAngVelocityGlobal(i)
            for i in range(controlModel.getBodyNum())
        ]
        linkInertias = [
            controlModel.getBodyInertiaGlobal(i)
            for i in range(controlModel.getBodyNum())
        ]

        CM = yrp.getCM(linkPositions, linkMasses, totalMass)
        dCM = yrp.getCM(linkVelocities, linkMasses, totalMass)
        CM_plane = copy.copy(CM)
        CM_plane[1] = 0.
        dCM_plane = copy.copy(dCM)
        dCM_plane[1] = 0.

        P = ymt.getPureInertiaMatrix(TO, linkMasses, linkPositions, CM,
                                     linkInertias)
        dP = ymt.getPureInertiaMatrixDerivative(dTO, linkMasses,
                                                linkVelocities, dCM,
                                                linkAngVelocities,
                                                linkInertias)

        # calculate jacobian
        Jsys, dJsys = controlModel.computeCom_J_dJdq()
        J_contacts = []  # type: list[np.ndarray]
        dJ_contacts = []  # type: list[np.ndarray]
        for contact_id in contact_ids:
            J_contacts.append(Jsys[6 * contact_id:6 * contact_id + 6, :])
            dJ_contacts.append(dJsys[6 * contact_id:6 * contact_id + 6])

        # calculate footCenter
        footCenter = sum(contact_body_pos) / len(contact_body_pos) if len(contact_body_pos) > 0 \
            else .5 * (controlModel.getBodyComPositionGlobal(supL) + controlModel.getBodyComPositionGlobal(supR))
        footCenter[1] = 0.
        # if len(contact_body_pos) > 2:
        #     hull = ConvexHull(contact_body_pos)

        footCenter_ref = sum(ref_body_pos) / len(ref_body_pos) if len(ref_body_pos) > 0 \
            else .5 * (motionModel.getBodyComPositionGlobal(supL) + motionModel.getBodyComPositionGlobal(supR))
        footCenter_ref = footCenter_ref + contMotionOffset
        # if len(ref_body_pos) > 2:
        #     hull = ConvexHull(ref_body_pos)
        footCenter_ref[1] = 0.

        # footCenter[0] = footCenter[0] + getParamVal('com X offset')
        # footCenter[1] = footCenter[0] + getParamVal('com Y offset')
        # footCenter[2] = footCenter[2] + getParamVal('com Z offset')

        # initialization
        if g_initFlag == 0:
            preFootCenter[0] = footCenter.copy()
            g_initFlag = 1

        # if contactChangeCount == 0 and np.linalg.norm(footCenter - preFootCenter[0]) > 0.01:
        #     contactChangeCount += 30
        if contactChangeCount > 0:
            # change footcenter gradually
            footCenter = preFootCenter[0] + (
                maxContactChangeCount - contactChangeCount) * (
                    footCenter - preFootCenter[0]) / maxContactChangeCount
        else:
            preFootCenter[0] = footCenter.copy()

        # linear momentum
        # TODO:
        # We should consider dCM_ref, shouldn't we?
        # add getBodyPositionGlobal and getBodyPositionsGlobal in csVpModel!
        # to do that, set joint velocities to vpModel
        CM_ref_plane = footCenter
        # CM_ref_plane = footCenter_ref
        CM_ref = footCenter + np.array([
            getParamVal('com X offset'),
            motionModel.getCOM()[1] + getParamVal('com Y offset'),
            getParamVal('com Z offset')
        ])
        dL_des_plane = Kl * totalMass * (CM_ref - CM) - Dl * totalMass * dCM
        # dL_des_plane = Kl * totalMass * (CM_ref_plane - CM_plane) - Dl * totalMass * dCM_plane
        # dL_des_plane[1] = 0.
        # print('dCM_plane : ', np.linalg.norm(dCM_plane))

        # angular momentum
        CP_ref = footCenter
        # CP_ref = footCenter_ref
        bodyIDs, contactPositions, contactPositionLocals, contactForces = controlModel.calcPenaltyForce(
            bodyIDsToCheck, mus, Ks, Ds)
        CP = yrp.getCP(contactPositions, contactForces)
        if CP_old[0] is None or CP is None:
            dCP = None
        else:
            dCP = (CP - CP_old[0]) / (1 / 30.)
        CP_old[0] = CP

        if CP is not None and dCP is not None:
            ddCP_des = Kh * (CP_ref - CP) - Dh * dCP
            dCP_des = dCP + ddCP_des * (1 / 30.)
            CP_des = CP + dCP_des * (1 / 30.)
            # CP_des = footCenter
            CP_des = CP + dCP * (1 / 30.) + .5 * ddCP_des * ((1 / 30.)**2)
            dH_des = np.cross(
                (CP_des - CM),
                (dL_des_plane + totalMass * controlModel.getGravity()))
            if contactChangeCount > 0:  # and contactChangeType == 'DtoS':
                dH_des *= (maxContactChangeCount -
                           contactChangeCount) / maxContactChangeCount
        else:
            dH_des = None

        # set up equality constraint
        # TODO:
        # logSO3 is just q'', not acceleration.
        # To make a_oris acceleration, q'' -> a will be needed
        # body_ddqs = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(body_ori, mm.unitY()), mm.unitY()) for body_ori in contact_body_ori]))
        # body_ddqs = list(map(mm.logSO3, [np.dot(contact_body_ori[i].T, np.dot(ref_body_ori[i], mm.getSO3FromVectors(np.dot(ref_body_ori[i], mm.unitY()), mm.unitY()))) for i in range(len(contact_body_ori))]))
        # body_ddqs = list(map(mm.logSO3, [np.dot(contact_body_ori[i].T, np.dot(ref_body_ori[i], mm.getSO3FromVectors(np.dot(ref_body_ori[i], up_vec_in_each_link[contact_ids[i]]), mm.unitY()))) for i in range(len(contact_body_ori))]))
        a_oris = list(
            map(mm.logSO3, [
                np.dot(
                    contact_body_ori[i].T,
                    np.dot(
                        ref_body_ori[i],
                        mm.getSO3FromVectors(
                            np.dot(ref_body_ori[i],
                                   up_vec_in_each_link[contact_ids[i]]),
                            mm.unitY()))) for i in range(len(contact_body_ori))
            ]))
        a_oris = list(
            map(mm.logSO3, [
                np.dot(
                    np.dot(
                        ref_body_ori[i],
                        mm.getSO3FromVectors(
                            np.dot(ref_body_ori[i],
                                   up_vec_in_each_link[contact_ids[i]]),
                            mm.unitY())), contact_body_ori[i].T)
                for i in range(len(contact_body_ori))
            ]))
        body_qs = list(map(mm.logSO3, contact_body_ori))
        body_angs = [
            np.dot(contact_body_ori[i], contact_body_angvel[i])
            for i in range(len(contact_body_ori))
        ]
        body_dqs = [
            mm.vel2qd(body_angs[i], body_qs[i]) for i in range(len(body_angs))
        ]
        # a_oris = [np.dot(contact_body_ori[i], mm.qdd2accel(body_ddqs[i], body_dqs[i], body_qs[i])) for i in range(len(contact_body_ori))]

        # body_ddq = body_ddqs[0]
        # body_ori = contact_body_ori[0]
        # body_ang = np.dot(body_ori.T, contact_body_angvel[0])
        #
        # body_q = mm.logSO3(body_ori)
        # body_dq = mm.vel2qd(body_ang, body_q)
        # a_ori = np.dot(body_ori, mm.qdd2accel(body_ddq, body_dq, body_q))

        KT_SUP = np.diag([kt_sup / 10., kt_sup, kt_sup / 10.])
        # KT_SUP = np.diag([kt_sup, kt_sup, kt_sup])

        # a_oris = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(body_ori, mm.unitY()), mm.unitY()) for body_ori in contact_body_ori]))
        a_oris = list(
            map(mm.logSO3, [
                mm.getSO3FromVectors(
                    np.dot(contact_body_ori[i],
                           up_vec_in_each_link[contact_ids[i]]), mm.unitY())
                for i in range(len(contact_body_ori))
            ]))
        # a_sups = [np.append(kt_sup*(ref_body_pos[i] - contact_body_pos[i] + contMotionOffset) + dt_sup*(ref_body_vel[i] - contact_body_vel[i]),
        #                     kt_sup*a_oris[i]+dt_sup*(ref_body_angvel[i]-contact_body_angvel[i])) for i in range(len(a_oris))]
        # a_sups = [np.append(kt_sup*(ref_body_pos[i] - contact_body_pos[i] + contMotionOffset) - dt_sup * contact_body_vel[i],
        #                     kt_sup*a_oris[i] - dt_sup * contact_body_angvel[i]) for i in range(len(a_oris))]
        a_sups = [
            np.append(
                np.dot(KT_SUP,
                       (ref_body_pos[i] - contact_body_pos[i] +
                        contMotionOffset)) - dt_sup * contact_body_vel[i],
                kt_sup * a_oris[i] - dt_sup * contact_body_angvel[i])
            for i in range(len(a_oris))
        ]
        # for i in range(len(a_sups)):
        #     a_sups[i][1] = -kt_sup * contact_body_pos[i][1] - dt_sup * contact_body_vel[i][1]

        # momentum matrix
        RS = np.dot(P, Jsys)
        R, S = np.vsplit(RS, 2)

        # rs = np.dot((np.dot(dP, Jsys) + np.dot(P, dJsys)), dth_flat)
        rs = np.dot(dP, np.dot(Jsys, dth_flat)) + np.dot(P, dJsys)
        r_bias, s_bias = np.hsplit(rs, 2)

        #######################################################
        # optimization
        #######################################################
        if LEG_FLEXIBLE:
            if contact == 2:
                config['weightMap']['h_thigh_right'] = .8
                config['weightMap']['h_shin_right'] = .8
                config['weightMap']['h_heel_right'] = .8
            else:
                config['weightMap']['h_thigh_right'] = .1
                config['weightMap']['h_shin_right'] = .25
                config['weightMap']['h_heel_right'] = .2

            if contact == 1:
                config['weightMap']['h_thigh_left'] = .8
                config['weightMap']['h_shin_left'] = .8
                config['weightMap']['h_heel_left'] = .8
            else:
                config['weightMap']['h_thigh_left'] = .1
                config['weightMap']['h_shin_left'] = .25
                config['weightMap']['h_heel_left'] = .2

        w = mot.getTrackingWeight(DOFs, controlModel, config['weightMap'])

        mot.addTrackingTerms(problem, totalDOF, Bt, w, ddth_des_flat)
        if dH_des is not None:
            mot.addLinearTerms(problem, totalDOF, Bl, dL_des_plane, R, r_bias)
            mot.addAngularTerms(problem, totalDOF, Bh, dH_des, S, s_bias)

            if True:
                for c_idx in range(len(contact_ids)):
                    mot.addConstraint2(problem, totalDOF, J_contacts[c_idx],
                                       dJ_contacts[c_idx], dth_flat,
                                       a_sups[c_idx])

        if contactChangeCount > 0:
            contactChangeCount = contactChangeCount - 1
            if contactChangeCount == 0:
                maxContactChangeCount = 30
                contactChangeType = 0

        r = problem.solve()
        problem.clear()
        ddth_sol_flat = np.asarray(r['x'])
        # ddth_sol_flat[foot_seg_dofs] = np.array(ddth_des_flat)[foot_seg_dofs]
        # ype.nested(ddth_sol_flat, ddth_sol)

        rootPos[0] = controlModel.getBodyPositionGlobal(selectedBody)
        localPos = [[0, 0, 0]]

        for _ in range(stepsPerFrame):
            bodyIDs, contactPositions, contactPositionLocals, contactForces = controlModel.calcPenaltyForce(
                bodyIDsToCheck, mus, Ks, Ds)
            controlModel.applyPenaltyForce(bodyIDs, contactPositionLocals,
                                           contactForces)

            # apply penalty force
            # controlModel.setDOFAccelerations(ddth_sol)
            # controlModel.setDOFAccelerations(ddth_des)
            controlModel.set_ddq(ddth_sol_flat)
            # controlModel.set_ddq(ddth_des_flat)
            controlModel.solveHybridDynamics()

            if forceShowTime > viewer.objectInfoWnd.labelForceDur.value():
                forceShowTime = 0
                viewer_ResetForceState()

            forceforce = np.array([
                viewer.objectInfoWnd.labelForceX.value(),
                viewer.objectInfoWnd.labelForceY.value(),
                viewer.objectInfoWnd.labelForceZ.value()
            ])
            extraForce[0] = getParamVal('Fm') * mm.normalize2(forceforce)
            if viewer_GetForceState():
                forceShowTime += controlModel.getTimeStep()
                controlModel.applyPenaltyForce(selectedBodyId, localPos,
                                               extraForce)

            controlModel.step()

        # rendering
        # bodyIDs, geomIDs, positionLocalsForGeom = vpWorld.getContactInfoForcePlate(bodyIDsToCheck)
        # for foot_seg_id in footIdlist:
        #     control_model_renderer.body_colors[foot_seg_id] = (255, 240, 255)
        #     control_model_renderer.geom_colors[foot_seg_id] = [(255, 240, 255)] * controlModel.getBodyGeomNum(foot_seg_id)

        # for i in range(len(geomIDs)):
        #     if controlModel.vpid2index(bodyIDs[i]) in footIdlist:
        #         control_model_renderer.geom_colors[controlModel.vpid2index(bodyIDs[i])][geomIDs[i]] = (255, 0, 0)
        # for foot_seg_id in footIdlist:
        #     control_model_renderer.body_colors[foot_seg_id] = (255, 240, 255)
        #
        # for contact_id in contact_ids:
        #     control_model_renderer.body_colors[contact_id] = (255, 0, 0)

        rd_footCenter[0] = footCenter
        rd_footCenter_ref[0] = footCenter_ref

        rd_CM[0] = CM

        rd_CM_plane[0] = CM.copy()
        rd_CM_plane[0][1] = 0.

        if CP is not None and dCP is not None:
            rd_CP[0] = CP
            rd_CP_des[0] = CP_des

            rd_dL_des_plane[0] = [
                dL_des_plane[0] / 100, dL_des_plane[1] / 100,
                dL_des_plane[2] / 100
            ]
            rd_dH_des[0] = dH_des

            rd_grf_des[
                0] = dL_des_plane - totalMass * controlModel.getGravity()

        del rd_foot_ori[:]
        del rd_foot_pos[:]
        # for seg_foot_id in footIdlist:
        #     rd_foot_ori.append(controlModel.getJointOrientationGlobal(seg_foot_id))
        #     rd_foot_pos.append(controlModel.getJointPositionGlobal(seg_foot_id))
        rd_foot_ori.append(controlModel.getJointOrientationGlobal(supL))
        rd_foot_ori.append(controlModel.getJointOrientationGlobal(supR))
        rd_foot_pos.append(controlModel.getJointPositionGlobal(supL))
        rd_foot_pos.append(controlModel.getJointPositionGlobal(supR))

        del rd_body_ori[:]
        del rd_body_pos[:]
        # for body_idx in range(dartModel.getBodyNum()):

        rd_root_des[0] = rootPos[0]
        rd_root_ori[0] = controlModel.getBodyOrientationGlobal(0)
        rd_root_pos[0] = controlModel.getBodyPositionGlobal(0)

        del rd_CF[:]
        del rd_CF_pos[:]
        for i in range(len(contactPositions)):
            rd_CF.append(contactForces[i] / 400)
            rd_CF_pos.append(contactPositions[i].copy())

        if viewer_GetForceState():
            rd_exfen_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exf_des[0] = [0, 0, 0]
        else:
            rd_exf_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exfen_des[0] = [0, 0, 0]

        # extraForcePos[0] = controlModel.getBodyPositionGlobal(selectedBody)
        extraForcePos[0] = controlModel.getBodyPositionGlobal(
            selectedBody) - 0.1 * np.array([
                viewer.objectInfoWnd.labelForceX.value(), 0.,
                viewer.objectInfoWnd.labelForceZ.value()
            ])
예제 #13
0
    def simulateCallback(frame):
        # print()
        # print(dartModel.getJointVelocityGlobal(0))
        # print(dartModel.getDOFVelocities()[0])
        # print(dartModel.get_dq()[:6])
        dartMotionModel.update(motion[frame])

        global g_initFlag
        global forceShowTime

        global preFootCenter
        global maxContactChangeCount
        global contactChangeCount
        global contact
        global contactChangeType
        # print('contactstate:', contact, contactChangeCount)

        Kt, Kl, Kh, Bl, Bh, kt_sup = getParamVals(['Kt', 'Kl', 'Kh', 'Bl', 'Bh', 'SupKt'])
        Dt = 2.*(Kt**.5)
        Dl = (Kl**.5)
        Dh = (Kh**.5)
        dt_sup = 2.*(kt_sup**.5)
        # Dt = .2*(Kt**.5)
        # Dl = .2*(Kl**.5)
        # Dh = .2*(Kh**.5)
        # dt_sup = .2*(kt_sup**.5)

        pdcontroller.setKpKd(Kt, Dt)

        footHeight = dartModel.getBody(supL).shapenodes[0].shape.size()[1]/2.

        doubleTosingleOffset = 0.15
        singleTodoubleOffset = 0.30
        #doubleTosingleOffset = 0.09
        doubleTosingleVelOffset = 0.0

        com_offset_x, com_offset_y, com_offset_z = getParamVals(['com X offset', 'com Y offset', 'com Z offset'])
        footOffset = np.array((com_offset_x, com_offset_y, com_offset_z))
        des_com = dartMotionModel.getCOM() + footOffset

        footCenterL = dartMotionModel.getBodyPositionGlobal(supL)
        footCenterR = dartMotionModel.getBodyPositionGlobal(supR)
        footBodyOriL = dartMotionModel.getBodyOrientationGlobal(supL)
        footBodyOriR = dartMotionModel.getBodyOrientationGlobal(supR)

        torso_pos = dartMotionModel.getBodyPositionGlobal(4)
        torso_ori = dartMotionModel.getBodyOrientationGlobal(4)

        # tracking
        # th_r = motion.getDOFPositions(frame)
        th_r = dartMotionModel.getDOFPositions()
        th = dartModel.getDOFPositions()
        th_r_flat = dartMotionModel.get_q()
        # dth_r = motion.getDOFVelocities(frame)
        # dth = dartModel.getDOFVelocities()
        # ddth_r = motion.getDOFAccelerations(frame)
        # ddth_des = yct.getDesiredDOFAccelerations(th_r, th, dth_r, dth, ddth_r, Kt, Dt)
        dth_flat = dartModel.get_dq()
        # dth_flat = np.concatenate(dth)
        # ddth_des_flat = pdcontroller.compute(dartMotionModel.get_q())
        # ddth_des_flat = pdcontroller.compute(th_r)
        ddth_des_flat = pdcontroller.compute_flat(th_r_flat)

        # ype.flatten(ddth_des, ddth_des_flat)
        # ype.flatten(dth, dth_flat)


        #################################################
        # jacobian
        #################################################

        footOriL = dartModel.getJointOrientationGlobal(supL)
        footOriR = dartModel.getJointOrientationGlobal(supR)

        footCenterL = dartModel.getBodyPositionGlobal(supL)
        footCenterR = dartModel.getBodyPositionGlobal(supR)
        footBodyOriL = dartModel.getBodyOrientationGlobal(supL)
        footBodyOriR = dartModel.getBodyOrientationGlobal(supR)
        footBodyVelL = dartModel.getBodyVelocityGlobal(supL)
        footBodyVelR = dartModel.getBodyVelocityGlobal(supR)
        footBodyAngVelL = dartModel.getBodyAngVelocityGlobal(supL)
        footBodyAngVelR = dartModel.getBodyAngVelocityGlobal(supR)

        refFootL = dartMotionModel.getBodyPositionGlobal(supL)
        refFootR = dartMotionModel.getBodyPositionGlobal(supR)
        # refFootAngVelL = motion.getJointAngVelocityGlobal(supL, frame)
        # refFootAngVelR = motion.getJointAngVelocityGlobal(supR, frame)
        refFootAngVelL = np.zeros(3)
        refFootAngVelR = np.zeros(3)

        refFootJointVelR = motion.getJointVelocityGlobal(supR, frame)
        refFootJointAngVelR = motion.getJointAngVelocityGlobal(supR, frame)
        refFootJointR = motion.getJointPositionGlobal(supR, frame)
        # refFootVelR = refFootJointVelR + np.cross(refFootJointAngVelR, (refFootR-refFootJointR))
        refFootVelR = np.zeros(3)

        refFootJointVelL = motion.getJointVelocityGlobal(supL, frame)
        refFootJointAngVelL = motion.getJointAngVelocityGlobal(supL, frame)
        refFootJointL = motion.getJointPositionGlobal(supL, frame)
        # refFootVelL = refFootJointVelL + np.cross(refFootJointAngVelL, (refFootL-refFootJointL))
        refFootVelL = np.zeros(3)

        contactR = 1
        contactL = 1
        if refFootVelR[1] < 0 and refFootVelR[1]*frame_step_size + refFootR[1] > singleTodoubleOffset:
            contactR = 0
        if refFootVelL[1] < 0 and refFootVelL[1]*frame_step_size + refFootL[1] > singleTodoubleOffset:
            contactL = 0
        if refFootVelR[1] > 0 and refFootVelR[1]*frame_step_size + refFootR[1] > doubleTosingleOffset:
            contactR = 0
        if refFootVelL[1] > 0 and refFootVelL[1]*frame_step_size + refFootL[1] > doubleTosingleOffset:
            contactL = 0
        # contactR = 0

        # contMotionOffset = th[0][0] - th_r[0][0]
        # contMotionOffset = dartModel.getBodyPositionGlobal(0) - dartMotionModel.getBodyPositionGlobal(0)
        contMotionOffset = np.asarray(controlToMotionOffset)

        linkPositions = dartModel.getBodyPositionsGlobal()
        linkVelocities = dartModel.getBodyVelocitiesGlobal()
        linkAngVelocities = dartModel.getBodyAngVelocitiesGlobal()
        linkInertias = dartModel.getBodyInertiasGlobal()

        CM = dartModel.skeleton.com()
        dCM = dartModel.skeleton.com_velocity()
        CM_plane = copy.copy(CM)
        CM_plane[1]=0.
        dCM_plane = copy.copy(dCM)
        dCM_plane[1]=0.

        P = ymt.getPureInertiaMatrix(TO, linkMasses, linkPositions, CM, linkInertias)
        dP = ymt.getPureInertiaMatrixDerivative(dTO, linkMasses, linkVelocities, dCM, linkAngVelocities, linkInertias)

        #calculate contact state
        #if g_initFlag == 1 and contact == 1 and refFootR[1] < doubleTosingleOffset and footCenterR[1] < 0.08:
        if g_initFlag == 1:
            #contact state
            # 0: flying 1: right only 2: left only 3: double
            #if contact == 2 and refFootR[1] < doubleTosingleOffset:
            if contact == 2 and contactR==1:
                contact = 3
                maxContactChangeCount+=30
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'StoD'

            #elif contact == 3 and refFootL[1] < doubleTosingleOffset:
            elif contact == 1 and contactL==1:
                contact = 3
                maxContactChangeCount+=30
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'StoD'

            #elif contact == 3 and refFootR[1] > doubleTosingleOffset:
            elif contact == 3 and contactR == 0:
                contact = 2
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'DtoS'

            #elif contact == 3 and refFootL[1] > doubleTosingleOffset:
            elif contact == 3 and contactL == 0:
                contact = 1
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'DtoS'

            else:
                contact = 0
                #if refFootR[1] < doubleTosingleOffset:
                if contactR == 1:
                    contact +=1
                #if refFootL[1] < doubleTosingleOffset:
                if contactL == 1:
                    contact +=2

        #initialization
        if g_initFlag == 0:
            softConstPoint = footCenterR.copy()

            footCenter = footCenterL + (footCenterR - footCenterL)/2.0
            footCenter[1] = 0.
            preFootCenter = footCenter.copy()
            #footToBodyFootRotL = np.dot(np.transpose(footOriL), footBodyOriL)
            #footToBodyFootRotR = np.dot(np.transpose(footOriR), footBodyOriR)

            # if refFootR[1] < doubleTosingleOffset:
            #     contact +=1
            # if refFootL[1] < doubleTosingleOffset:
            #     contact +=2
            if refFootR[1] < footHeight:
                contact +=1
            if refFootL[1] < footHeight:
                contact +=2

            g_initFlag = 1
        contact = 2

        #calculate jacobian
        body_num = dartModel.getBodyNum()
        Jsys = np.zeros((6*body_num, totalDOF))
        dJsys = np.zeros((6*body_num, totalDOF))
        for i in range(dartModel.getBodyNum()):
            Jsys[6*i:6*i+6, :] = dartModel.getBody(i).world_jacobian()[range(-3, 3), :]
            dJsys[6*i:6*i+6, :] = dartModel.getBody(i).world_jacobian_classic_deriv()[range(-3, 3), :]
        # dJsys = (Jsys - Jpre[0])/frame_step_size
        # Jpre[0] = Jsys.copy()

        JsupL = dartModel.getBody(supL).world_jacobian()[range(-3, 3), :]
        dJsupL = dartModel.getBody(supL).world_jacobian_classic_deriv()[range(-3, 3), :]
        # dJsupL = np.zeros_like(JsupL)
        # dJsupL =  (JsupL - Jpre[1])/frame_step_size
        # Jpre[1] = JsupL.copy()

        JsupR = dartModel.getBody(supR).world_jacobian()[range(-3, 3), :]
        dJsupR = dartModel.getBody(supR).world_jacobian_classic_deriv()[range(-3, 3), :]
        # dJsupR = np.zeros_like(JsupR)
        # dJsupR =  (JsupR - Jpre[2])/frame_step_size
        # Jpre[2] = JsupR.copy()

        #calculate footCenter
        footCenter = .5 * (footCenterL + footCenterR) + footOffset
        #if refFootR[1] >doubleTosingleOffset:
        #if refFootR[1] > doubleTosingleOffset or footCenterR[1] > 0.08:
        #if contact == 1 or footCenterR[1] > 0.08:
        #if contact == 2 or footCenterR[1] > doubleTosingleOffset/2:
        if contact == 2:
            footCenter = footCenterL.copy() + footOffset
        #elif contact == 1 or footCenterL[1] > doubleTosingleOffset/2:
        if contact == 1:
            footCenter = footCenterR.copy() + footOffset
        footCenter[1] = 0.

        if contactChangeCount > 0 and contactChangeType == 'StoD':
            #change footcenter gradually
            footCenter = preFootCenter + (maxContactChangeCount - contactChangeCount)*(footCenter-preFootCenter)/maxContactChangeCount

        preFootCenter = footCenter.copy()


        # linear momentum
        #TODO:
        # We should consider dCM_ref, shouldn't we?
        # add getBodyPositionGlobal and getBodyPositionsGlobal in csVpModel!
        # todo that, set joint velocities to vpModel

        CM_ref_plane = footCenter
        dL_des_plane = Kl*totalMass*(CM_ref_plane - CM_plane) - Dl*totalMass*dCM_plane
        dL_des_plane[1] = 0.

        CM_ref = footCenter.copy()
        CM_ref[1] = dartMotionModel.getCOM()[1]
        # CM_ref += np.array((0., com_offset_y, 0.))
        dL_des_plane = Kl*totalMass*(CM_ref - CM) - Dl*totalMass*dCM

        # angular momentum
        CP_ref = footCenter

        bodyIDs, contactPositions, contactPositionLocals, contactForces = [], [], [], []
        if DART_CONTACT_ON:
            bodyIDs, contactPositions, contactPositionLocals, contactForces = dartModel.get_dart_contact_info()
        else:
            bodyIDs, contactPositions, contactPositionLocals, contactForces = dartModel.calcPenaltyForce(bodyIDsToCheck, mus, Ks, Ds)
        #bodyIDs, contactPositions, contactPositionLocals, contactForces, contactVelocities = vpWorld.calcManyPenaltyForce(0, bodyIDsToCheck, mus, Ks, Ds)

        CP = yrp.getCP(contactPositions, contactForces)
        if CP_old[0] is None or CP is None:
            dCP = None
        else:
            dCP = (CP - CP_old[0])/frame_step_size
        CP_old[0] = CP

        CP_des[0] = None
        # if CP_des[0] is None:
        #     CP_des[0] = footCenter

        if CP is not None and dCP is not None:
            ddCP_des = Kh*(CP_ref - CP) - Dh*(dCP)
            CP_des[0] = CP + dCP * frame_step_size + .5 * ddCP_des*(frame_step_size**2)
            # dCP_des[0] += ddCP_des * frame_step_size
            # CP_des[0] += dCP_des[0] * frame_step_size + .5 * ddCP_des*(frame_step_size ** 2)
            dH_des = np.cross(CP_des[0] - CM, dL_des_plane + totalMass*mm.s2v(wcfg.gravity))
            if contactChangeCount > 0:# and contactChangeType == 'DtoS':
                #dH_des *= (maxContactChangeCount - contactChangeCount)/(maxContactChangeCount*10)
                dH_des *= (maxContactChangeCount - contactChangeCount)/(maxContactChangeCount)
                #dH_des *= (contactChangeCount)/(maxContactChangeCount)*.9+.1
        else:
            dH_des = None

        # set up equality constraint
        a_oriL = mm.logSO3(mm.getSO3FromVectors(np.dot(footBodyOriL, mm.unitY()), mm.unitY()))
        a_oriR = mm.logSO3(mm.getSO3FromVectors(np.dot(footBodyOriR, mm.unitY()), mm.unitY()))

        footErrorL = refFootL.copy()
        footErrorL[1] = dartModel.getBody(supL).shapenodes[0].shape.size()[1]/2.
        footErrorL += -footCenterL + contMotionOffset
        print(footErrorL)

        footErrorR = refFootR.copy()
        footErrorR[1] = dartModel.getBody(supR).shapenodes[0].shape.size()[1]/2.
        footErrorR += -footCenterR + contMotionOffset

        a_supL = np.append(kt_sup*footErrorL + dt_sup*(refFootVelL - footBodyVelL), kt_sup*a_oriL+dt_sup*(refFootAngVelL-footBodyAngVelL))
        a_supR = np.append(kt_sup*footErrorR + dt_sup*(refFootVelR - footBodyVelR), kt_sup*a_oriR+dt_sup*(refFootAngVelR-footBodyAngVelR))

        if contactChangeCount > 0 and contactChangeType == 'DtoS':
            a_supL = np.append(kt_sup*(refFootL - footCenterL + contMotionOffset) + dt_sup*(refFootVelL - footBodyVelL), 4*kt_sup*a_oriL+2*dt_sup*(refFootAngVelL-footBodyAngVelL))
            a_supR = np.append(kt_sup*(refFootR - footCenterR + contMotionOffset) + dt_sup*(refFootVelR - footBodyVelR), 4*kt_sup*a_oriR+2*dt_sup*(refFootAngVelR-footBodyAngVelR))
        elif contactChangeCount > 0 and contactChangeType == 'StoD':
            linkt = (13.*contactChangeCount)/(maxContactChangeCount)+1.
            lindt = 2*(linkt**.5)
            angkt = (13.*contactChangeCount)/(maxContactChangeCount)+1.
            angdt = 2*(angkt**.5)
            a_supL = np.append(linkt*kt_sup*(refFootL - footCenterL + contMotionOffset) + lindt*dt_sup*(refFootVelL - footBodyVelL), angkt*kt_sup*a_oriL+angdt*dt_sup*(refFootAngVelL-footBodyAngVelL))
            a_supR = np.append(linkt*kt_sup*(refFootR - footCenterR + contMotionOffset) + lindt*dt_sup*(refFootVelR - footBodyVelR), angkt*kt_sup*a_oriR+angdt*dt_sup*(refFootAngVelR-footBodyAngVelR))

        # momentum matrix
        RS = np.dot(P, Jsys)
        R, S = np.vsplit(RS, 2)

        rs = np.dot((np.dot(dP, Jsys) + np.dot(P, dJsys)), dth_flat)
        r_bias, s_bias = np.hsplit(rs, 2)

        #######################################################
        # optimization
        #######################################################
        #if contact == 2 and footCenterR[1] > doubleTosingleOffset/2:
        if contact == 2:
            config['weightMap']['RightUpLeg'] = .8
            config['weightMap']['RightLeg'] = .8
            config['weightMap']['RightFoot'] = .8
        else:
            config['weightMap']['RightUpLeg'] = .1
            config['weightMap']['RightLeg'] = .25
            config['weightMap']['RightFoot'] = .2

        #if contact == 1 and footCenterL[1] > doubleTosingleOffset/2:
        if contact == 1:
            config['weightMap']['LeftUpLeg'] = .8
            config['weightMap']['LeftLeg'] = .8
            config['weightMap']['LeftFoot'] = .8
        else:
            config['weightMap']['LeftUpLeg'] = .1
            config['weightMap']['LeftLeg'] = .25
            config['weightMap']['LeftFoot'] = .2


        w = mot.getTrackingWeight(DOFs, motion[0].skeleton, config['weightMap'])

        #if contact == 2:
            #mot.addSoftPointConstraintTerms(problem, totalDOF, Bsc, ddP_des1, Q1, q_bias1)
        mot.addTrackingTerms(problem, totalDOF, Bt, w, ddth_des_flat)
        mot.addLinearTerms(problem, totalDOF, Bl, dL_des_plane, R, r_bias)
        if dH_des is not None:
            mot.addAngularTerms(problem, totalDOF, Bh, dH_des, S, s_bias)

            if contact == 1 or contact == 3:
                mot.addConstraint(problem, totalDOF, JsupR, dJsupR, dth_flat, a_supR)
            if contact == 2 or contact == 3:
                mot.addConstraint(problem, totalDOF, JsupL, dJsupL, dth_flat, a_supL)

        if contactChangeCount > 0:
            contactChangeCount -= 1
            if contactChangeCount == 0:
                maxContactChangeCount = 30
                contactChangeType = 0

        r = problem.solve()
        problem.clear()
        # ype.nested(r['x'], ddth_sol)
        ddth_sol = np.asarray(r['x'])
        # ddth_sol[:6] = np.zeros(6)

        rootPos[0] = dartModel.getBodyPositionGlobal(selectedBody)
        localPos = [[0, 0, 0]]

        for i in range(stepsPerFrame):
            # apply penalty force
            if not DART_CONTACT_ON:
                bodyIDs, contactPositions, contactPositionLocals, contactForces = dartModel.calcPenaltyForce(bodyIDsToCheck, mus, Ks, Ds)
                dartModel.applyPenaltyForce(bodyIDs, contactPositionLocals, contactForces)
            #bodyIDs, contactPositions, contactPositionLocals, contactForces, contactVelocities = vpWorld.calcManyPenaltyForce(0, bodyIDsToCheck, mus, Ks, Ds)

            for joint_idx in range(dartModel.skeleton.num_joints()):
                joint = dartModel.skeleton.joint(joint_idx)  # type: pydart.Joint
                if joint.num_dofs() == 3:
                    dof_start_idx = joint.dofs[0].index_in_skeleton()
                    joint.set_acceleration(ddth_sol[dof_start_idx:dof_start_idx+3])

            # dartModel.skeleton.set_accelerations(ddth_sol)
            # dartModel.skeleton.set_forces(np.zeros(totalDOF))

            if forceShowTime > viewer.objectInfoWnd.labelForceDur.value():
                forceShowTime = 0
                viewer_ResetForceState()

            forceforce = np.array([viewer.objectInfoWnd.labelForceX.value(), viewer.objectInfoWnd.labelForceY.value(), viewer.objectInfoWnd.labelForceZ.value()])
            extraForce[0] = getParamVal('Fm') * mm.normalize2(forceforce)
            if viewer_GetForceState():
                forceShowTime += wcfg.timeStep
                dartModel.applyPenaltyForce(selectedBodyId, localPos, extraForce)

            dartModel.step()

        if DART_CONTACT_ON:
            bodyIDs, contactPositions, contactPositionLocals, contactForces = dartModel.get_dart_contact_info()
        else:
            bodyIDs, contactPositions, contactPositionLocals, contactForces = dartModel.calcPenaltyForce(bodyIDsToCheck, mus, Ks, Ds)

        # rendering
        rightFootVectorX[0] = np.dot(footOriL, np.array([.1, 0, 0]))
        rightFootVectorY[0] = np.dot(footOriL, np.array([0, .1, 0]))
        rightFootVectorZ[0] = np.dot(footOriL, np.array([0,  0,.1]))
        rightFootPos[0] = footCenterL

        rightVectorX[0] = np.dot(footBodyOriL, np.array([.1,0,0]))
        rightVectorY[0] = np.dot(footBodyOriL, np.array([0,.1,0]))
        rightVectorZ[0] = np.dot(footBodyOriL, np.array([0,0,.1]))
        rightPos[0] = footCenterL + np.array([.1,0,0])

        rd_footCenter[0] = footCenter
        rd_footCenterL[0] = footCenterL
        rd_footCenterR[0] = footCenterR

        rd_CM[0] = CM

        rd_CM_plane[0] = CM.copy()
        rd_CM_plane[0][1] = 0.

        if CP is not None and dCP is not None:
            rd_CP[0] = CP
            rd_CP_des[0] = CP_des[0]

            rd_dL_des_plane[0] = [dL_des_plane[0]/100, dL_des_plane[1]/100, dL_des_plane[2]/100]
            rd_dH_des[0] = dH_des

            rd_grf_des[0] = dL_des_plane - totalMass*mm.s2v(wcfg.gravity)

        rd_root_des[0] = rootPos[0]

        del rd_CF[:]
        del rd_CF_pos[:]
        for i in range(len(contactPositions)):
            rd_CF.append( contactForces[i]/100)
            rd_CF_pos.append(contactPositions[i].copy())

        if viewer_GetForceState():
            rd_exfen_des[0] = [extraForce[0][0]/100, extraForce[0][1]/100, extraForce[0][2]/100]
            rd_exf_des[0] = [0,0,0]
        else:
            rd_exf_des[0] = [extraForce[0][0]/100, extraForce[0][1]/100, extraForce[0][2]/100]
            rd_exfen_des[0] = [0,0,0]

        extraForcePos[0] = dartModel.getBodyPositionGlobal(selectedBody)
    def simulateCallback(frame):
        if frame == 200:
            viewer.force_on = True

        motionModel.update(motion[frame])

        global g_initFlag
        global forceShowTime

        global JsysPre
        global JsupPreL
        global JsupPreR
        global JsupPre

        global JconstPre

        global preFootCenter
        global maxContactChangeCount
        global contactChangeCount
        global contact
        global contactChangeType

        # Kt, Kl, Kh, Bl, Bh, kt_sup = viewer.GetParam()
        Kt, Kl, Kh, Bl, Bh, kt_sup = getParamVals(
            ['Kt', 'Kl', 'Kh', 'Bl', 'Bh', 'SupKt'])
        Dt = 2 * (Kt**.5)
        Dl = 2 * (Kl**.5)
        Dh = 2 * (Kh**.5)
        dt_sup = 2 * (kt_sup**.5)

        doubleTosingleOffset = 0.15
        singleTodoubleOffset = 0.30
        # doubleTosingleOffset = 0.09
        doubleTosingleVelOffset = 0.0

        # tracking
        th_r = motion.getDOFPositions(frame)
        th = controlModel.getDOFPositions()
        dth_r = motion.getDOFVelocities(frame)
        dth = controlModel.getDOFVelocities()
        ddth_r = motion.getDOFAccelerations(frame)
        ddth_des = yct.getDesiredDOFAccelerations(th_r, th, dth_r, dth, ddth_r,
                                                  Kt, Dt)

        ype.flatten(ddth_des, ddth_des_flat)
        ype.flatten(dth, dth_flat)

        #################################################
        # jacobian
        #################################################

        # desire footCenter[1] = 0.041135
        # desire footCenter[1] = 0.0197
        footCenterL = controlModel.getBodyPositionGlobal(supL)
        footCenterR = controlModel.getBodyPositionGlobal(supR)
        footBodyOriL = controlModel.getBodyOrientationGlobal(supL)
        footBodyOriR = controlModel.getBodyOrientationGlobal(supR)
        footBodyVelL = controlModel.getBodyVelocityGlobal(supL)
        footBodyVelR = controlModel.getBodyVelocityGlobal(supR)
        footBodyAngVelL = controlModel.getBodyAngVelocityGlobal(supL)
        footBodyAngVelR = controlModel.getBodyAngVelocityGlobal(supR)

        refFootL = motionModel.getBodyPositionGlobal(supL)
        refFootR = motionModel.getBodyPositionGlobal(supR)
        refFootVelL = motionModel.getBodyVelocityGlobal(supL)
        refFootVelR = motionModel.getBodyVelocityGlobal(supR)
        refFootAngVelL = motionModel.getBodyAngVelocityGlobal(supL)
        refFootAngVelR = motionModel.getBodyAngVelocityGlobal(supR)
        refFootOriL = motionModel.getBodyOrientationGlobal(supL)
        refFootOriR = motionModel.getBodyOrientationGlobal(supR)

        refFootJointVelR = motion.getJointVelocityGlobal(supR, frame)
        refFootJointAngVelR = motion.getJointAngVelocityGlobal(supR, frame)
        refFootJointR = motion.getJointPositionGlobal(supR, frame)
        refFootVelR = refFootJointVelR + np.cross(refFootJointAngVelR,
                                                  (refFootR - refFootJointR))

        refFootJointVelL = motion.getJointVelocityGlobal(supL, frame)
        refFootJointAngVelL = motion.getJointAngVelocityGlobal(supL, frame)
        refFootJointL = motion.getJointPositionGlobal(supL, frame)
        refFootVelL = refFootJointVelL + np.cross(refFootJointAngVelL,
                                                  (refFootL - refFootJointL))

        contactR = 1
        contactL = 1
        if refFootVelR[1] < 0 and refFootVelR[1] / 30. + refFootR[
                1] > singleTodoubleOffset:
            contactR = 0
        if refFootVelL[1] < 0 and refFootVelL[1] / 30. + refFootL[
                1] > singleTodoubleOffset:
            contactL = 0
        if refFootVelR[1] > 0 and refFootVelR[1] / 30. + refFootR[
                1] > doubleTosingleOffset:
            contactR = 0
        if refFootVelL[1] > 0 and refFootVelL[1] / 30. + refFootL[
                1] > doubleTosingleOffset:
            contactL = 0
        # if 32 < frame < 147:
        #     contactR = 0

        contMotionOffset = th[0][0] - th_r[0][0]

        linkPositions = controlModel.getBodyPositionsGlobal()
        linkVelocities = controlModel.getBodyVelocitiesGlobal()
        linkAngVelocities = controlModel.getBodyAngVelocitiesGlobal()
        linkInertias = controlModel.getBodyInertiasGlobal()

        jointPositions = controlModel.getJointPositionsGlobal()
        jointAxeses = controlModel.getDOFAxeses()

        CM = yrp.getCM(linkPositions, linkMasses, totalMass)
        dCM = yrp.getCM(linkVelocities, linkMasses, totalMass)
        CM_plane = copy.copy(CM)
        CM_plane[1] = 0.
        dCM_plane = copy.copy(dCM)
        dCM_plane[1] = 0.

        P = ymt.getPureInertiaMatrix(TO, linkMasses, linkPositions, CM,
                                     linkInertias)
        dP = ymt.getPureInertiaMatrixDerivative(dTO, linkMasses,
                                                linkVelocities, dCM,
                                                linkAngVelocities,
                                                linkInertias)

        # calculate jacobian
        Jsys, dJsys = controlModel.computeCom_J_dJdq()
        JsupL = Jsys[6 * supL:6 * supL + 6, :]
        dJsupL = dJsys[6 * supL:6 * supL + 6]
        JsupR = Jsys[6 * supR:6 * supR + 6, :]
        dJsupR = dJsys[6 * supR:6 * supR + 6]

        # calculate contact state
        # if g_initFlag == 1 and contact == 1 and refFootR[1] < doubleTosingleOffset and footCenterR[1] < 0.08:
        if g_initFlag == 1:
            # contact state
            # 0: flying 1: right only 2: left only 3: double
            # if contact == 2 and refFootR[1] < doubleTosingleOffset:
            if contact == 2 and contactR == 1:
                contact = 3
                maxContactChangeCount += 30
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'StoD'

            # elif contact == 3 and refFootL[1] < doubleTosingleOffset:
            elif contact == 1 and contactL == 1:
                contact = 3
                maxContactChangeCount += 30
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'StoD'

            # elif contact == 3 and refFootR[1] > doubleTosingleOffset:
            elif contact == 3 and contactR == 0:
                contact = 2
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'DtoS'

            # elif contact == 3 and refFootL[1] > doubleTosingleOffset:
            elif contact == 3 and contactL == 0:
                contact = 1
                contactChangeCount += maxContactChangeCount
                contactChangeType = 'DtoS'

            else:
                contact = 0
                # if refFootR[1] < doubleTosingleOffset:
                if contactR == 1:
                    contact += 1
                # if refFootL[1] < doubleTosingleOffset:
                if contactL == 1:
                    contact += 2

        # initialization
        if g_initFlag == 0:
            JsysPre = Jsys.copy()
            JsupPreL = JsupL.copy()
            JsupPreR = JsupR.copy()
            JconstPre = Jconst.copy()
            softConstPoint = footCenterR.copy()
            # yjc.computeJacobian2(JsysPre, DOFs, jointPositions, jointAxeses, linkPositions, allLinkJointMasks)
            # yjc.computeJacobian2(JsupPreL, DOFs, jointPositions, jointAxeses, [footCenterL], supLJointMasks)
            # yjc.computeJacobian2(JsupPreR, DOFs, jointPositions, jointAxeses, [footCenterR], supRJointMasks)
            # yjc.computeJacobian2(JconstPre, DOFs, jointPositions, jointAxeses, [softConstPoint], constJointMasks)

            footCenter = footCenterL + (footCenterR - footCenterL) / 2.0
            footCenter[1] = 0.
            preFootCenter = footCenter.copy()
            # footToBodyFootRotL = np.dot(np.transpose(footOriL), footBodyOriL)
            # footToBodyFootRotR = np.dot(np.transpose(footOriR), footBodyOriR)

            if refFootR[1] < doubleTosingleOffset:
                contact += 1
            if refFootL[1] < doubleTosingleOffset:
                contact += 2

            g_initFlag = 1

        # calculate footCenter
        footCenter = footCenterL + (footCenterR - footCenterL) / 2.0
        # if refFootR[1] >doubleTosingleOffset:
        # if refFootR[1] > doubleTosingleOffset or footCenterR[1] > 0.08:
        # if contact == 1 or footCenterR[1] > 0.08:
        # if contact == 2 or footCenterR[1] > doubleTosingleOffset/2:
        if contact == 2:
            footCenter = footCenterL.copy()
        # elif contact == 1 or footCenterL[1] > doubleTosingleOffset/2:
        if contact == 1:
            footCenter = footCenterR.copy()
        footCenter[1] = 0.

        if contactChangeCount > 0 and contactChangeType == 'StoD':
            # change footcenter gradually
            footCenter = preFootCenter + (
                maxContactChangeCount - contactChangeCount) * (
                    footCenter - preFootCenter) / maxContactChangeCount

        preFootCenter = footCenter.copy()

        # linear momentum
        # TODO:
        # We should consider dCM_ref, shouldn't we?
        # add getBodyPositionGlobal and getBodyPositionsGlobal in csVpModel!
        # todo that, set joint velocities to vpModel
        CM_ref_plane = footCenter
        # CM_ref_plane[1] += motionModel.getCOM()[1]
        CM_ref = footCenter + np.array([
            getParamVal('com X offset'),
            motionModel.getCOM()[1] + getParamVal('com Y offset'),
            getParamVal('com Z offset')
        ])
        # dL_des_plane = Kl*totalMass*(CM_ref_plane - CM_plane) - Dl*totalMass*dCM_plane
        dL_des_plane = Kl * totalMass * (CM_ref - CM) - Dl * totalMass * dCM
        # dL_des_plane[1] = 0.

        # angular momentum
        CP_ref = footCenter
        bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce(
            bodyIDsToCheck, mus, Ks, Ds)
        # bodyIDs, contactPositions, contactPositionLocals, contactForces, contactVelocities = vpWorld.calcManyPenaltyForce(0, bodyIDsToCheck, mus, Ks, Ds)
        CP = yrp.getCP(contactPositions, contactForces)
        if CP_old[0] is None or CP is None:
            dCP = None
        else:
            dCP = (CP - CP_old[0]) / (1 / 30.)
        CP_old[0] = CP

        if CP is not None and dCP is not None:
            ddCP_des = Kh * (CP_ref - CP) - Dh * dCP
            CP_des = CP + dCP * (1 / 30.) + .5 * ddCP_des * ((1 / 30.)**2)
            dH_des = np.cross(
                (CP_des - CM),
                (dL_des_plane + totalMass * mm.s2v(wcfg.gravity)))
            if contactChangeCount > 0:  # and contactChangeType == 'DtoS':
                # dH_des *= (maxContactChangeCount - contactChangeCount)/(maxContactChangeCount*10)
                dH_des *= (maxContactChangeCount -
                           contactChangeCount) / (maxContactChangeCount)
                # dH_des *= (contactChangeCount)/(maxContactChangeCount)*.9+.1
        else:
            dH_des = None
        # H = np.dot(P, np.dot(Jsys, dth_flat))
        # dH_des = -Kh* H[3:]

        # soft point constraint
        #softConstPoint = refFootR.copy()
        ##softConstPoint[0] += 0.2
        #Ksc = 50
        #Dsc = 2*(Ksc**.5)
        #Bsc = 1.

        #P_des = softConstPoint
        #P_cur = controlModel.getBodyPositionGlobal(constBody)
        #dP_des = [0, 0, 0]
        #dP_cur = controlModel.getBodyVelocityGlobal(constBody)
        #ddP_des1 = Ksc*(P_des - P_cur) + Dsc*(dP_des - dP_cur)

        #r = P_des - P_cur
        #I = np.vstack(([1,0,0],[0,1,0],[0,0,1]))
        #Z = np.hstack((I, mm.getCrossMatrixForm(-r)))

        #yjc.computeJacobian2(Jconst, DOFs, jointPositions, jointAxeses, [softConstPoint], constJointMasks)
        #dJconst = (Jconst - Jconst)/(1/30.)
        #JconstPre = Jconst.copy()
        ##yjc.computeJacobianDerivative2(dJconst, DOFs, jointPositions, jointAxeses, linkAngVelocities, [softConstPoint], constJointMasks, False)

        #JL, JA = np.vsplit(Jconst, 2)
        #Q1 = np.dot(Z, Jconst)

        #q1 = np.dot(JA, dth_flat)
        #q2 = np.dot(mm.getCrossMatrixForm(q1), np.dot(mm.getCrossMatrixForm(q1), r))
        #q_bias1 = np.dot(np.dot(Z, dJconst), dth_flat) + q2

        #set up equality constraint
        L_ddq = mm.logSO3(
            np.dot(
                footBodyOriL.T,
                np.dot(
                    refFootOriL,
                    mm.getSO3FromVectors(np.dot(refFootOriL, mm.unitY()),
                                         mm.unitY()))))
        R_ddq = mm.logSO3(
            np.dot(
                footBodyOriR.T,
                np.dot(
                    refFootOriR,
                    mm.getSO3FromVectors(np.dot(refFootOriR, mm.unitY()),
                                         mm.unitY()))))
        L_q = mm.logSO3(footBodyOriL)
        R_q = mm.logSO3(footBodyOriR)
        L_ang = np.dot(footBodyOriL, footBodyAngVelL)
        R_ang = np.dot(footBodyOriR, footBodyAngVelR)
        L_dq = mm.vel2qd(L_ang, L_q)
        R_dq = mm.vel2qd(R_ang, R_q)
        a_oriL = np.dot(footBodyOriL, mm.qdd2accel(L_dq, L_dq, L_q))
        a_oriR = np.dot(footBodyOriR, mm.qdd2accel(R_dq, R_dq, R_q))

        # body_ddqs = list(map(mm.logSO3, [np.dot(contact_body_ori[i].T, np.dot(ref_body_ori[i], mm.getSO3FromVectors(np.dot(ref_body_ori[i], up_vec_in_each_link[contact_ids[i]]), mm.unitY()))) for i in range(len(contact_body_ori))]))
        # body_qs = list(map(mm.logSO3, contact_body_ori))
        # body_angs = [np.dot(contact_body_ori[i], contact_body_angvel[i]) for i in range(len(contact_body_ori))]
        # body_dqs = [mm.vel2qd(body_angs[i], body_qs[i]) for i in range(len(body_angs))]
        # a_oris = [np.dot(contact_body_ori[i], mm.qdd2accel(body_ddqs[i], body_dqs[i], body_qs[i])) for i in range(len(contact_body_ori))]
        #
        a_oriL = mm.logSO3(
            mm.getSO3FromVectors(np.dot(footBodyOriL, mm.unitY()), mm.unitY()))
        a_oriR = mm.logSO3(
            mm.getSO3FromVectors(np.dot(footBodyOriR, mm.unitY()), mm.unitY()))

        #if contact == 3 and contactChangeCount < maxContactChangeCount/4 and contactChangeCount >=1:
        #kt_sup = 30
        #viewer.objectInfoWnd.labelSupKt.value(kt_sup)
        #viewer.objectInfoWnd.sliderSupKt.value(initSupKt*10)

        # a_supL = np.append(kt_sup*(refFootL - footCenterL + contMotionOffset) + dt_sup*(refFootVelL - footBodyVelL), kt_sup*a_oriL+dt_sup*(refFootAngVelL-footBodyAngVelL))
        # a_supR = np.append(kt_sup*(refFootR - footCenterR + contMotionOffset) + dt_sup*(refFootVelR - footBodyVelR), kt_sup*a_oriR+dt_sup*(refFootAngVelR-footBodyAngVelR))
        a_supL = np.append(
            kt_sup * (refFootL - footCenterL + contMotionOffset) -
            dt_sup * footBodyVelL, kt_sup * a_oriL - dt_sup * footBodyAngVelL)
        # a_supL[1] = kt_sup*(0.028-footCenterL[1]) -dt_sup*footBodyVelL[1]
        a_supL[1] = kt_sup * (0.0 - footCenterL[1]) - dt_sup * footBodyVelL[1]
        a_supR = np.append(
            kt_sup * (refFootR - footCenterR + contMotionOffset) -
            dt_sup * footBodyVelR, kt_sup * a_oriR - dt_sup * footBodyAngVelR)
        # a_supR[1] = kt_sup*(0.028-footCenterR[1]) -dt_sup*footBodyVelR[1]
        a_supR[1] = kt_sup * (0.0 - footCenterR[1]) - dt_sup * footBodyVelR[1]

        ##if contact == 2:
        #if refFootR[1] <doubleTosingleOffset :
        #Jsup = np.vstack((JsupL, JsupR))
        #dJsup = np.vstack((dJsupL, dJsupR))
        #a_sup = np.append(a_supL, a_supR)
        #else:
        #Jsup = JsupL.copy()
        #dJsup = dJsupL.copy()
        #a_sup = a_supL.copy()

        # momentum matrix
        RS = np.dot(P, Jsys)
        R, S = np.vsplit(RS, 2)

        # rs = np.dot((np.dot(dP, Jsys) + np.dot(P, dJsys)), dth_flat)
        rs = np.dot(dP, np.dot(Jsys, dth_flat)) + np.dot(P, dJsys)
        r_bias, s_bias = np.hsplit(rs, 2)

        #######################################################
        # optimization
        #######################################################
        #if contact == 2 and footCenterR[1] > doubleTosingleOffset/2:
        if contact == 2:
            config['weightMap']['RightUpLeg'] = .8
            config['weightMap']['RightLeg'] = .8
            config['weightMap']['RightFoot'] = .8
        else:
            config['weightMap']['RightUpLeg'] = .1
            config['weightMap']['RightLeg'] = .25
            config['weightMap']['RightFoot'] = .2

        #if contact == 1 and footCenterL[1] > doubleTosingleOffset/2:
        if contact == 1:
            config['weightMap']['LeftUpLeg'] = .8
            config['weightMap']['LeftLeg'] = .8
            config['weightMap']['LeftFoot'] = .8
        else:
            config['weightMap']['LeftUpLeg'] = .1
            config['weightMap']['LeftLeg'] = .25
            config['weightMap']['LeftFoot'] = .2

        w = mot.getTrackingWeight(DOFs, motion[0].skeleton,
                                  config['weightMap'])

        #if contact == 2:
        #mot.addSoftPointConstraintTerms(problem, totalDOF, Bsc, ddP_des1, Q1, q_bias1)
        mot.addTrackingTerms(problem, totalDOF, Bt, w, ddth_des_flat)
        if dH_des is not None:
            mot.addLinearTerms(problem, totalDOF, Bl, dL_des_plane, R, r_bias)
            mot.addAngularTerms(problem, totalDOF, Bh, dH_des, S, s_bias)

            #if contact & 1 and contactChangeCount == 0:
            if contact & 1:
                #if refFootR[1] < doubleTosingleOffset:
                mot.addConstraint2(problem, totalDOF, JsupR, dJsupR, dth_flat,
                                   a_supR)
            if contact & 2:
                #if refFootL[1] < doubleTosingleOffset:
                mot.addConstraint2(problem, totalDOF, JsupL, dJsupL, dth_flat,
                                   a_supL)

        if contactChangeCount > 0:
            contactChangeCount -= 1
            if contactChangeCount == 0:
                maxContactChangeCount = 30
                contactChangeType = 0

        r = problem.solve()
        problem.clear()
        ype.nested(r['x'], ddth_sol)

        rootPos[0] = controlModel.getBodyPositionGlobal(selectedBody)
        localPos = [[0, 0, 0]]

        for i in range(stepsPerFrame):
            # apply penalty force
            bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce(
                bodyIDsToCheck, mus, Ks, Ds)
            # print(contactForces)
            #bodyIDs, contactPositions, contactPositionLocals, contactForces, contactVelocities = vpWorld.calcManyPenaltyForce(0, bodyIDsToCheck, mus, Ks, Ds)
            vpWorld.applyPenaltyForce(bodyIDs, contactPositionLocals,
                                      contactForces)

            controlModel.setDOFAccelerations(ddth_sol)
            controlModel.solveHybridDynamics()

            if forceShowTime > viewer.objectInfoWnd.labelForceDur.value():
                forceShowTime = 0
                viewer_ResetForceState()

            forceforce = np.array([
                viewer.objectInfoWnd.labelForceX.value(),
                viewer.objectInfoWnd.labelForceY.value(),
                viewer.objectInfoWnd.labelForceZ.value()
            ])
            extraForce[0] = getParamVal('Fm') * mm.normalize2(forceforce)
            # extraForce[0] = viewer.objectInfoWnd.labelFm.value() * mm.normalize2(forceforce)
            if viewer_GetForceState():
                forceShowTime += wcfg.timeStep
                vpWorld.applyPenaltyForce(selectedBodyId, localPos, extraForce)

            vpWorld.step()

        # rendering
        rightVectorX[0] = np.dot(footBodyOriL, np.array([.1, 0, 0]))
        rightVectorY[0] = np.dot(footBodyOriL, np.array([0, .1, 0]))
        rightVectorZ[0] = np.dot(footBodyOriL, np.array([0, 0, .1]))
        rightPos[0] = footCenterL + np.array([.1, 0, 0])

        rd_footCenter[0] = footCenter
        rd_footCenterL[0] = footCenterL
        rd_footCenterR[0] = footCenterR

        rd_CM[0] = CM

        rd_CM_plane[0] = CM.copy()
        rd_CM_plane[0][1] = 0.

        if CP is not None and dCP is not None:
            rd_CP[0] = CP
            rd_CP_des[0] = CP_des

            rd_dL_des_plane[0] = [
                dL_des_plane[0] / 100, dL_des_plane[1] / 100,
                dL_des_plane[2] / 100
            ]
            rd_dH_des[0] = dH_des

            rd_grf_des[0] = dL_des_plane - totalMass * mm.s2v(wcfg.gravity)

        rd_root_des[0] = rootPos[0]

        del rd_foot_ori[:]
        del rd_foot_pos[:]
        rd_foot_ori.append(controlModel.getBodyOrientationGlobal(supL))
        rd_foot_ori.append(controlModel.getBodyOrientationGlobal(supR))
        rd_foot_pos.append(controlModel.getBodyPositionGlobal(supL))
        rd_foot_pos.append(controlModel.getBodyPositionGlobal(supR))

        del rd_CF[:]
        del rd_CF_pos[:]
        for i in range(len(contactPositions)):
            rd_CF.append(contactForces[i] / 400)
            rd_CF_pos.append(contactPositions[i].copy())

        if viewer_GetForceState():
            rd_exfen_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exf_des[0] = [0, 0, 0]
        else:
            rd_exf_des[0] = [
                extraForce[0][0] / 100, extraForce[0][1] / 100,
                extraForce[0][2] / 100
            ]
            rd_exfen_des[0] = [0, 0, 0]

        extraForcePos[0] = controlModel.getBodyPositionGlobal(
            selectedBody) - 0.1 * np.array([
                viewer.objectInfoWnd.labelForceX.value(), 0.,
                viewer.objectInfoWnd.labelForceZ.value()
            ])
예제 #15
0
def footAdjust(posture_ori,
               footIdDic,
               SEGMENT_FOOT_MAG,
               SEGMENT_FOOT_RAD,
               baseHeight=0.):
    """
    :return:
    """
    def getJointChildPositionGlobal(posture, jointNameOrIdx):
        """

        :type posture: ym.JointPosture
        :type jointNameOrIdx: str | int
        :return: np.array
        """
        idx = jointNameOrIdx
        if type(jointNameOrIdx) == str:
            idx = posture.skeleton.getJointIndex(jointNameOrIdx)
        effectorOffset = posture.skeleton.getJoint(idx).children[0].offset
        return posture.getJointPositionGlobal(idx) + np.dot(
            posture.getJointOrientationGlobal(idx), effectorOffset)

    def makeTwoContactPos(posture,
                          jointNameOrIdx,
                          isLeftFoot=True,
                          isOutside=True,
                          baseHeight=None):
        """

        :type posture: ym.JointPosture
        :type jointNameOrIdx: str | int
        :return: np.array, np.array
        """
        idx = jointNameOrIdx
        if type(jointNameOrIdx) == str:
            idx = posture.skeleton.getJointIndex(jointNameOrIdx)

        insideOffset = SEGMENT_FOOT_MAG * np.array((0., 0., 2.5))
        outsideOffset = SEGMENT_FOOT_MAG * np.array((1.2, 0., 2.5))
        if isLeftFoot ^ isOutside:
            # if not isOutside:
            # if it is not outside phalange,
            outsideOffset[0] = -1.2 * SEGMENT_FOOT_MAG

        origin = posture.getJointPositionGlobal(idx)
        inside = posture.getJointPositionGlobal(idx, insideOffset)
        outside = posture.getJointPositionGlobal(idx, outsideOffset)

        length = SEGMENT_FOOT_MAG * 2.5

        RotVec1_tmp1 = inside - origin
        RotVec1_tmp2 = inside - origin
        RotVec1_tmp2[1] = 0.
        RotVec1 = np.cross(RotVec1_tmp1, RotVec1_tmp2)
        inner = (origin[1] - SEGMENT_FOOT_RAD) / length

        angle1_1 = math.acos(inner if inner < 1.0 else 1.0)
        if baseHeight is not None:
            angle1_1 = math.acos(
                (origin[1] - (baseHeight + SEGMENT_FOOT_RAD)) / length)
        angle1_2 = math.acos((origin[1] - inside[1]) / length)
        footRot1 = mm.exp(RotVec1, angle1_1 - angle1_2)
        footOri1 = posture.getJointOrientationGlobal(idx)
        posture.setJointOrientationGlobal(idx, np.dot(footRot1, footOri1))

        inside_new = posture.getJointPositionGlobal(idx, insideOffset)
        outside_new_tmp = posture.getJointPositionGlobal(idx, outsideOffset)

        # RotVec2 = inside_new - origin
        width = np.linalg.norm(outside - inside)
        widthVec_tmp = np.cross(RotVec1_tmp1, np.array((0., 1., 0.))) if isLeftFoot ^ isOutside \
            else np.cross(np.array((0., 1., 0.)), RotVec1_tmp1)

        widthVec = width * widthVec_tmp / np.linalg.norm(widthVec_tmp)
        outside_new = inside_new + widthVec

        footRot2 = mm.getSO3FromVectors(outside_new_tmp - inside_new, widthVec)
        footOri2 = posture.getJointOrientationGlobal(idx)
        # print footRot2, footOri2
        newFootOri = np.dot(footRot2, footOri2)
        # posture.setJointOrientationGlobal(idx, np.dot(footRot2, footOri2))

        return newFootOri, inside_new, outside_new

    def makeFourContactPos(posture,
                           jointNameOrIdx,
                           isLeftFoot=True,
                           isOutside=True):
        """

        :type posture: ym.JointPosture
        :type jointNameOrIdx: str | int
        :return: np.array, np.array, np.array
        """
        idx = jointNameOrIdx
        if type(jointNameOrIdx) == str:
            idx = posture.skeleton.getJointIndex(jointNameOrIdx)

        insideOffset = SEGMENT_FOOT_MAG * np.array((0., 0., 2.5))
        outsideOffset = SEGMENT_FOOT_MAG * np.array((1.2, 0., 2.5))
        if isLeftFoot ^ isOutside:
            # if it is not outside phalange,
            outsideOffset[0] = -1.2 * SEGMENT_FOOT_MAG

        origin = posture.getJointPositionGlobal(idx)
        inside = posture.getJointPositionGlobal(idx, insideOffset)
        outside = posture.getJointPositionGlobal(idx, outsideOffset)

        length = SEGMENT_FOOT_MAG * 2.5

        RotVec1_tmp1 = inside - origin
        RotVec1_tmp2 = inside - origin
        RotVec1_tmp2[1] = 0.
        RotVec1 = np.cross(RotVec1_tmp1, RotVec1_tmp2)
        angle1_1 = math.acos((origin[1] - SEGMENT_FOOT_RAD) / length)
        angle1_2 = math.acos((origin[1] - inside[1]) / length)
        footRot1 = mm.exp(RotVec1, angle1_1 - angle1_2)
        footOri1 = posture.getJointOrientationGlobal(idx)
        posture.setJointOrientationGlobal(idx, np.dot(footRot1, footOri1))

        inside_new = posture.getJointPositionGlobal(idx, insideOffset)
        outside_new_tmp = posture.getJointPositionGlobal(idx, outsideOffset)

        # RotVec2 = inside_new - origin
        width = np.linalg.norm(outside - inside)
        widthVec_tmp = np.cross(RotVec1_tmp1, np.array((0., 1., 0.))) if isLeftFoot ^ isOutside \
            else np.cross(np.array((0., 1., 0.)), RotVec1_tmp1)

        widthVec = width * widthVec_tmp / np.linalg.norm(widthVec_tmp)
        outside_new = inside_new + widthVec

        footRot2 = mm.getSO3FromVectors(outside_new_tmp - inside_new, widthVec)
        footOri2 = posture.getJointOrientationGlobal(idx)
        # print footRot2, footOri2
        posture.setJointOrientationGlobal(idx, np.dot(footRot2, footOri2))
        return

    def getFootSegNormal(posture,
                         jointNameOrIdx,
                         isLeftFoot=True,
                         isOutside=True):
        """

        :type posture: ym.JointPosture
        :type jointNameOrIdx: str | int
        :return: np.array, np.array, np.array
        """
        idx = jointNameOrIdx
        if type(jointNameOrIdx) == str:
            idx = posture.skeleton.getJointIndex(jointNameOrIdx)

        insideOffset = SEGMENT_FOOT_MAG * np.array((0., 0., 2.5))
        outsideOffset = SEGMENT_FOOT_MAG * np.array((1.2, 0., 2.5))
        if isLeftFoot ^ isOutside:
            # if it is not outside phalange,
            outsideOffset[0] = -1.2 * SEGMENT_FOOT_MAG

        origin = posture.getJointPositionGlobal(idx)
        inside = posture.getJointPositionGlobal(idx, insideOffset)
        outside = posture.getJointPositionGlobal(idx, outsideOffset)

        if isLeftFoot ^ isOutside:
            return mm.normalize(-np.cross(inside - origin, outside - origin))
        else:
            return mm.normalize(np.cross(inside - origin, outside - origin))

    # get collision info
    collide = dict()  # type: dict[str, bool]

    for side in ['Left', 'Right']:
        for sideInFoot in ['outside', 'inside']:  # outside first!
            isLeftFoot = True if side == 'Left' else False
            isOutside = True if sideInFoot == 'outside' else False
            footPrefix = 'Foot_foot_0_' + ('0' if isOutside else '1')

            collide[side+footPrefix+'_0_Effector'] = \
                getJointChildPositionGlobal(posture_ori, side+footPrefix+'_0')[1] < SEGMENT_FOOT_RAD + baseHeight
            collide[side+footPrefix+'_0'] = \
                posture_ori.getJointPositionGlobal(footIdDic[side+footPrefix+'_0'])[1] < SEGMENT_FOOT_RAD + baseHeight
            collide[side+footPrefix+''] = \
                posture_ori.getJointPositionGlobal(footIdDic[side+footPrefix])[1] < SEGMENT_FOOT_RAD + baseHeight

            if collide[side + footPrefix + '_0_Effector'] and collide[
                    side + footPrefix + '_0'] and collide[side + footPrefix +
                                                          '']:
                # all segment contact
                footVec = getFootSegNormal(posture_ori,
                                           side + footPrefix + '',
                                           isLeftFoot=isLeftFoot,
                                           isOutside=isOutside)
                footRot = mm.getSO3FromVectors(footVec, np.array((0., 1., 0.)))
                footIdx = posture_ori.skeleton.getJointIndex(side +
                                                             footPrefix + '')
                footOri = posture_ori.getJointOrientationGlobal(footIdx)
                posture_ori.setJointOrientationGlobal(footIdx,
                                                      np.dot(footRot, footOri))

            elif collide[side + footPrefix +
                         '_0_Effector'] and collide[side + footPrefix + '_0']:
                # toe fully, phalange partially
                newFootOri, _inside, _outside = makeTwoContactPos(
                    posture_ori,
                    side + footPrefix + '',
                    isLeftFoot=isLeftFoot,
                    isOutside=isOutside,
                    baseHeight=baseHeight)
                posture_ori.setJointOrientationGlobal(
                    footIdDic[side + footPrefix + ''], newFootOri)

                footVec = getFootSegNormal(posture_ori,
                                           side + footPrefix + '_0',
                                           isLeftFoot=isLeftFoot,
                                           isOutside=isOutside)
                footRot = mm.getSO3FromVectors(footVec, np.array((0., 1., 0.)))
                footIdx = posture_ori.skeleton.getJointIndex(side +
                                                             footPrefix + '_0')
                footOri = posture_ori.getJointOrientationGlobal(footIdx)
                posture_ori.setJointOrientationGlobal(footIdx,
                                                      np.dot(footRot, footOri))

                outsideOffset = np.array(
                    (-1., 0., 0.)) if isLeftFoot ^ isOutside else np.array(
                        (1., 0., 0.))
                inside_tmp = posture_ori.getJointPositionGlobal(
                    footIdDic[side + footPrefix + '_0'])
                outside_tmp = posture_ori.getJointPositionGlobal(
                    footIdDic[side + footPrefix + '_0'], outsideOffset)
                footRot2 = mm.getSO3FromVectors(outside_tmp - inside_tmp,
                                                _outside - _inside)
                posture_ori.setJointOrientationGlobal(
                    footIdx, np.dot(footRot2, np.dot(footRot, footOri)))

            elif collide[side + footPrefix + '_0_Effector']:
                # toe partially
                footPoint = posture_ori.getJointPositionGlobal(
                    footIdDic[side + footPrefix + '_0'])

                newFootOri, _inside, _outside = makeTwoContactPos(
                    posture_ori,
                    side + footPrefix + '',
                    isLeftFoot=isLeftFoot,
                    isOutside=isOutside,
                    baseHeight=footPoint[1] - SEGMENT_FOOT_RAD)
                posture_ori.setJointOrientationGlobal(
                    posture_ori.skeleton.getJointIndex(side + footPrefix + ''),
                    newFootOri)
                footVec = getFootSegNormal(posture_ori,
                                           side + footPrefix + '_0',
                                           isLeftFoot=isLeftFoot,
                                           isOutside=isOutside)
                footRot = mm.getSO3FromVectors(footVec, np.array((0., 1., 0.)))
                footIdx = posture_ori.skeleton.getJointIndex(side +
                                                             footPrefix + '_0')
                footOri = posture_ori.getJointOrientationGlobal(footIdx)
                posture_ori.setJointOrientationGlobal(footIdx,
                                                      np.dot(footRot, footOri))

                outsideOffset = np.array(
                    (-1., 0., 0.)) if isLeftFoot ^ isOutside else np.array(
                        (1., 0., 0.))
                inside_tmp = posture_ori.getJointPositionGlobal(
                    footIdDic[side + footPrefix + '_0'])
                outside_tmp = posture_ori.getJointPositionGlobal(
                    footIdDic[side + footPrefix + '_0'], outsideOffset)
                footRot2 = mm.getSO3FromVectors(outside_tmp - inside_tmp,
                                                _outside - _inside)
                posture_ori.setJointOrientationGlobal(
                    footIdx, np.dot(footRot2, np.dot(footRot, footOri)))

            elif getJointChildPositionGlobal(
                    posture_ori, side + footPrefix +
                    '_0')[1] < SEGMENT_FOOT_RAD * 1.5 + baseHeight:
                # In case of posibility of contact
                # if 1 radius <  toe height < 3/2 radius, this routine is working.
                toeHeight = getJointChildPositionGlobal(
                    posture_ori, side + footPrefix + '_0')[1]
                ratio = (SEGMENT_FOOT_RAD * 1.5 + baseHeight -
                         toeHeight) / SEGMENT_FOOT_RAD * 2.

                footPoint = posture_ori.getJointPositionGlobal(
                    footIdDic[side + footPrefix + '_0'])
                newFootOri, _inside, _outside = makeTwoContactPos(
                    posture_ori,
                    side + footPrefix + '',
                    isLeftFoot=isLeftFoot,
                    isOutside=isOutside,
                    baseHeight=footPoint[1] - SEGMENT_FOOT_RAD)

                oldFootOri = posture_ori.getJointOrientationGlobal(
                    footIdDic[side + footPrefix + ''])
                posture_ori.setJointOrientationGlobal(
                    footIdDic[side + footPrefix + ''],
                    mm.slerp(oldFootOri, newFootOri, ratio))

                oldFootOri2 = posture_ori.getJointOrientationGlobal(
                    footIdDic[side + footPrefix + '_0'])
                footVec = getFootSegNormal(posture_ori,
                                           side + footPrefix + '_0',
                                           isLeftFoot=isLeftFoot,
                                           isOutside=isOutside)
                footRot = mm.getSO3FromVectors(footVec, np.array((0., 1., 0.)))
                footIdx = posture_ori.skeleton.getJointIndex(side +
                                                             footPrefix + '_0')
                footOri = posture_ori.getJointOrientationGlobal(footIdx)
                posture_ori.setJointOrientationGlobal(footIdx,
                                                      np.dot(footRot, footOri))

                outsideOffset = np.array(
                    (-1., 0., 0.)) if isLeftFoot ^ isOutside else np.array(
                        (1., 0., 0.))
                inside_tmp = posture_ori.getJointPositionGlobal(
                    footIdDic[side + footPrefix + '_0'])
                outside_tmp = posture_ori.getJointPositionGlobal(
                    footIdDic[side + footPrefix + '_0'], outsideOffset)
                footRot2 = mm.getSO3FromVectors(outside_tmp - inside_tmp,
                                                _outside - _inside)
                posture_ori.setJointOrientationGlobal(
                    footIdx,
                    mm.slerp(oldFootOri2,
                             np.dot(footRot2, np.dot(footRot, footOri)),
                             ratio))

        if True:  # back side
            isLeftFoot = True if side == 'Left' else False
            footPrefix = 'Foot_foot_1'

            collide[side+footPrefix+'_0_Effector'] = \
                getJointChildPositionGlobal(posture_ori, side+footPrefix+'_0')[1] < SEGMENT_FOOT_RAD + baseHeight
            collide[side+footPrefix+'_0'] = \
                posture_ori.getJointPositionGlobal(footIdDic[side+footPrefix+'_0'])[1] < SEGMENT_FOOT_RAD + baseHeight

            # if collide[side+footPrefix+'_0_Effector'] and collide[side+footPrefix+'_0']:
            if collide[side + footPrefix + '_0_Effector']:
                # heel contact partially or fully
                heel_idx = footIdDic[side + footPrefix + '_0']
                R_cur = posture_ori.getJointOrientationGlobal(heel_idx)

                insideOffset = SEGMENT_FOOT_MAG * np.array((-.6, 0., 1.2))
                outsideOffset = SEGMENT_FOOT_MAG * np.array((.6, 0., 1.2))

                origin = posture_ori.getJointPositionGlobal(heel_idx)
                inside = posture_ori.getJointPositionGlobal(
                    heel_idx, insideOffset)
                outside = posture_ori.getJointPositionGlobal(
                    heel_idx, outsideOffset)

                # rot_vec = mm.normalize(np.cross(inside - origin, origin - outside if side == 'Left' else outside - origin))
                rot_vec = mm.normalize(
                    np.cross(inside - origin, outside - origin))

                rot_to_y = mm.getSO3FromVectors(rot_vec, mm.unitY())

                posture_ori.setJointOrientationGlobal(heel_idx,
                                                      np.dot(rot_to_y, R_cur))
    def simulateCallback(frame):
        # print()
        # print(dartModel.getJointVelocityGlobal(0))
        # print(dartModel.getDOFVelocities()[0])
        # print(dartModel.get_dq()[:6])
        dartMotionModel.update(motion[frame])

        global g_initFlag
        global forceShowTime

        global preFootCenter
        global maxContactChangeCount
        global contactChangeCount
        global contact
        global contactChangeType
        # print('contactstate:', contact, contactChangeCount)

        Kt, Kl, Kh, Bl, Bh, kt_sup = getParamVals(['Kt', 'Kl', 'Kh', 'Bl', 'Bh', 'SupKt'])
        Dt = 2.*(Kt**.5)
        Dl = (Kl**.5)
        Dh = (Kh**.5)
        dt_sup = 2.*(kt_sup**.5)
        # Dt = .2*(Kt**.5)
        # Dl = .2*(Kl**.5)
        # Dh = .2*(Kh**.5)
        # dt_sup = .2*(kt_sup**.5)

        pdcontroller.setKpKd(Kt, Dt)

        footHeight = dartModel.getBody(supL).shapenodes[0].shape.size()[1]/2.

        doubleTosingleOffset = 0.15
        singleTodoubleOffset = 0.30
        #doubleTosingleOffset = 0.09
        doubleTosingleVelOffset = 0.0

        com_offset_x, com_offset_y, com_offset_z = getParamVals(['com X offset', 'com Y offset', 'com Z offset'])
        footOffset = np.array((com_offset_x, com_offset_y, com_offset_z))
        des_com = dartMotionModel.getCOM() + footOffset

        footCenterL = dartMotionModel.getBodyPositionGlobal(supL)
        footCenterR = dartMotionModel.getBodyPositionGlobal(supR)
        footBodyOriL = dartMotionModel.getBodyOrientationGlobal(supL)
        footBodyOriR = dartMotionModel.getBodyOrientationGlobal(supR)

        torso_pos = dartMotionModel.getBodyPositionGlobal(4)
        torso_ori = dartMotionModel.getBodyOrientationGlobal(4)

        # tracking
        # th_r = motion.getDOFPositions(frame)
        th_r = dartMotionModel.getDOFPositions()
        th = dartModel.getDOFPositions()
        th_r_flat = dartMotionModel.get_q()
        # dth_r = motion.getDOFVelocities(frame)
        dth = dartModel.getDOFVelocities()
        # ddth_r = motion.getDOFAccelerations(frame)
        # ddth_des = yct.getDesiredDOFAccelerations(th_r, th, None, dth, None, Kt, Dt)
        dth_flat = dartModel.get_dq()
        # dth_flat = np.concatenate(dth)
        # ddth_des_flat = pdcontroller.compute(dartMotionModel.get_q())
        # ddth_des_flat = pdcontroller.compute(th_r)
        ddth_des_flat = pdcontroller.compute_flat(th_r_flat)

        # ype.flatten(ddth_des, ddth_des_flat)
        # ype.flatten(dth, dth_flat)

        #################################################
        # jacobian
        #################################################
        contact_des_ids = [dartModel.skeleton.bodynode_index("LeftFoot")]
        contact_ids = list()  # temp idx for balancing
        contact_ids.extend(contact_des_ids)

        contact_joint_ori = list(map(dartModel.getJointOrientationGlobal, contact_ids))
        contact_joint_pos = list(map(dartModel.getJointPositionGlobal, contact_ids))
        contact_body_ori = list(map(dartModel.getBodyOrientationGlobal, contact_ids))
        contact_body_pos = list(map(dartModel.getBodyPositionGlobal, contact_ids))
        contact_body_vel = list(map(dartModel.getBodyVelocityGlobal, contact_ids))
        contact_body_angvel = list(map(dartModel.getBodyAngVelocityGlobal, contact_ids))

        ref_joint_ori = list(map(motion[frame].getJointOrientationGlobal, contact_ids))
        ref_joint_pos = list(map(motion[frame].getJointPositionGlobal, contact_ids))
        ref_joint_vel = [motion.getJointVelocityGlobal(joint_idx, frame) for joint_idx in contact_ids]
        ref_joint_angvel = [motion.getJointAngVelocityGlobal(joint_idx, frame) for joint_idx in contact_ids]
        ref_body_ori = list(map(dartMotionModel.getBodyOrientationGlobal, contact_ids))
        ref_body_pos = list(map(dartMotionModel.getBodyPositionGlobal, contact_ids))

        for idx in range(len(ref_body_pos)):
            ref_body_pos[idx] = dartModel.skeleton.body("RightFoot").shapenodes[0].shape.size()[1]/2.
        # ref_body_vel = list(map(controlModel.getBodyVelocityGlobal, contact_ids))
        ref_body_angvel = [motion.getJointAngVelocityGlobal(joint_idx, frame) for joint_idx in contact_ids]
        ref_body_vel = [ref_joint_vel[i] + np.cross(ref_joint_angvel[i], ref_body_pos[i] - ref_joint_pos[i])
                        for i in range(len(ref_joint_vel))]

        is_contact = [1] * len(contact_ids)
        contact_right = len(set(contact_des_ids).intersection(rIDlist)) > 0
        contact_left = len(set(contact_des_ids).intersection(lIDlist)) > 0

        footOriL = dartModel.getJointOrientationGlobal(supL)
        footOriR = dartModel.getJointOrientationGlobal(supR)

        footCenterL = dartModel.getBodyPositionGlobal(supL)
        footCenterR = dartModel.getBodyPositionGlobal(supR)
        footBodyOriL = dartModel.getBodyOrientationGlobal(supL)
        footBodyOriR = dartModel.getBodyOrientationGlobal(supR)
        footBodyVelL = dartModel.getBodyVelocityGlobal(supL)
        footBodyVelR = dartModel.getBodyVelocityGlobal(supR)
        footBodyAngVelL = dartModel.getBodyAngVelocityGlobal(supL)
        footBodyAngVelR = dartModel.getBodyAngVelocityGlobal(supR)

        refFootL = dartMotionModel.getBodyPositionGlobal(supL)
        refFootR = dartMotionModel.getBodyPositionGlobal(supR)
        # refFootAngVelL = motion.getJointAngVelocityGlobal(supL, frame)
        # refFootAngVelR = motion.getJointAngVelocityGlobal(supR, frame)
        refFootAngVelL = np.zeros(3)
        refFootAngVelR = np.zeros(3)

        refFootJointVelR = motion.getJointVelocityGlobal(supR, frame)
        refFootJointAngVelR = motion.getJointAngVelocityGlobal(supR, frame)
        refFootJointR = motion.getJointPositionGlobal(supR, frame)
        # refFootVelR = refFootJointVelR + np.cross(refFootJointAngVelR, (refFootR-refFootJointR))
        refFootVelR = np.zeros(3)

        refFootJointVelL = motion.getJointVelocityGlobal(supL, frame)
        refFootJointAngVelL = motion.getJointAngVelocityGlobal(supL, frame)
        refFootJointL = motion.getJointPositionGlobal(supL, frame)
        # refFootVelL = refFootJointVelL + np.cross(refFootJointAngVelL, (refFootL-refFootJointL))
        refFootVelL = np.zeros(3)

        contactR = 1
        contactL = 1

        # contMotionOffset = th[0][0] - th_r[0][0]
        contMotionOffset = dartModel.getBodyPositionGlobal(0) - dartMotionModel.getBodyPositionGlobal(0)
        contMotionOffset = np.zeros(3)

        linkPositions = dartModel.getBodyPositionsGlobal()
        linkVelocities = dartModel.getBodyVelocitiesGlobal()
        linkAngVelocities = dartModel.getBodyAngVelocitiesGlobal()
        linkInertias = dartModel.getBodyInertiasGlobal()

        CM = dartModel.skeleton.com()
        dCM = dartModel.skeleton.com_velocity()
        CM_plane = copy.copy(CM)
        CM_plane[1]=0.
        dCM_plane = copy.copy(dCM)
        dCM_plane[1]=0.

        P = ymt.getPureInertiaMatrix(TO, linkMasses, linkPositions, CM, linkInertias)
        dP = ymt.getPureInertiaMatrixDerivative(dTO, linkMasses, linkVelocities, dCM, linkAngVelocities, linkInertias)

        #calculate jacobian
        body_num = dartModel.getBodyNum()
        Jsys = np.zeros((6*body_num, totalDOF))
        dJsys = np.zeros((6*body_num, totalDOF))
        Jsys_, dJsysdq = compute_J_dJdq(dartModel.skeleton)
        # dJsys = np.zeros((6*body_num, totalDOF))
        for i in range(dartModel.getBodyNum()):
            Jsys[6*i:6*i+6, :] = dartModel.getBody(i).world_jacobian()[range(-3, 3), :]
            dJsys[6*i:6*i+6, :] = dartModel.getBody(i).world_jacobian_classic_deriv()[range(-3, 3), :]
        dJsysdq = np.dot(dJsys, dartModel.skeleton.dq)
        # print(Jsys_ - Jsys)
        # print(Jsys_.dot(dth_flat))
        # print(Jsys.dot(dth_flat))
        # print(dartModel.getBody(0).world_linear_velocity())
        # print(np.dot(Jsys[:3, :3], Jsys[0:3, 3:6].T))
        print('dq', np.asarray(dartModel.skeleton.dq)[6:9])
        print('joint vel', dartModel.skeleton.joint(1).velocity())
        # print('bjoint', mm.exp(dartModel.skeleton.q[6:9]).dot(get_bjoint_jacobian(dartModel.skeleton.q[6:9]).dot(np.asarray(dartModel.skeleton.dq)[6:9])))
        # print('not bjoint', mm.exp(dartModel.skeleton.q[6:9]).dot(np.asarray(dartModel.skeleton.dq)[6:9]))
        print('frombody', dartModel.getJointOrientationGlobal(1).T.dot(dartModel.getJointAngVelocityGlobal(1) - dartModel.getJointAngVelocityGlobal(0)))

        print('ddq', np.asarray(dartModel.skeleton.ddq)[6:9])
        # print('bjoint', mm.exp(dartModel.skeleton.q[6:9]).dot(get_bjoint_jacobian(dartModel.skeleton.q[6:9]).dot(np.asarray(dartModel.skeleton.dq)[6:9])))
        # print('not bjoint', mm.exp(dartModel.skeleton.q[6:9]).dot(np.asarray(dartModel.skeleton.dq)[6:9]))

        bodybody = dartModel.skeleton.body(1)
        joint_trans = dartModel.skeleton.joint(1).get_world_frame_after_transform()
        joint_pos = bodybody.to_local(joint_trans[:3, 3])
        print('com spati', dartModel.getJointOrientationGlobal(1).T.dot(
            dartModel.skeleton.body(1).world_angular_acceleration() - dartModel.skeleton.body(0).world_angular_acceleration()))

        J_contacts = []  # type: list[np.ndarray]
        dJ_contacts = []  # type: list[np.ndarray]
        for contact_id in contact_ids:
            J_contacts.append(Jsys[6*contact_id:6*contact_id + 6, :])
            dJ_contacts.append(dJsysdq[6*contact_id:6*contact_id + 6])

        #calculate footCenter
        footCenter = .5 * (footCenterL + footCenterR) + footOffset
        if contact == 2:
            footCenter = footCenterL.copy() + footOffset
        #elif contact == 1 or footCenterL[1] > doubleTosingleOffset/2:
        if contact == 1:
            footCenter = footCenterR.copy() + footOffset
        footCenter[1] = 0.

        if contactChangeCount > 0 and contactChangeType == 'StoD':
            # change footcenter gradually
            footCenter = preFootCenter + (maxContactChangeCount - contactChangeCount)*(footCenter-preFootCenter)/maxContactChangeCount

        preFootCenter = footCenter.copy()

        # linear momentum
        # CM_ref_plane = footCenter
        # dL_des_plane = Kl*totalMass*(CM_ref_plane - CM_plane) - Dl*totalMass*dCM_plane
        # dL_des_plane[1] = 0.

        CM_ref_plane = footCenter
        CM_ref_plane[1] = dartMotionModel.skeleton.com()[1]
        dL_des_plane = Kl*totalMass*(CM_ref_plane - CM) - Dl*totalMass*dCM
        # dL_des_plane[1] = 0.

        # angular momentum
        CP_ref = footCenter

        CP = yrp.getCP(contactPositions, contactForces)
        if CP_old[0] is None or CP is None:
            dCP = None
        else:
            dCP = (CP - CP_old[0])/frame_step_size
        CP_old[0] = CP

        CP_des[0] = None

        if CP is not None and dCP is not None:
            ddCP_des = Kh*(CP_ref - CP) - Dh*(dCP)
            CP_des[0] = CP + dCP * frame_step_size + .5 * ddCP_des*(frame_step_size**2)
            dH_des = mm.cross(CP_des[0] - CM, dL_des_plane + totalMass*mm.s2v(wcfg.gravity))
        else:
            dH_des = None

        # set up equality constraint
        a_oris = list(map(mm.logSO3, [mm.getSO3FromVectors(np.dot(contact_body_ori[i], mm.unitY()), mm.unitY()) for i in range(len(contact_body_ori))]))
        KT_SUP = np.diag([kt_sup/10., kt_sup, kt_sup/10.])
        a_sups = [np.append(np.dot(KT_SUP, (ref_body_pos[i] - contact_body_pos[i] + contMotionOffset)) - dt_sup * contact_body_vel[i],
                            kt_sup*a_oris[i] - dt_sup * contact_body_angvel[i]) for i in range(len(a_oris))]
        # print(a_sups)
        # print(np.asarray(dartModel.skeleton.dq)[0:3])
        # print(dartModel.getJointAngVelocityGlobal(0))
        # print(dartModel.getJointAngVelocityLocal(0))

        # momentum matrix
        RS = np.dot(P, Jsys)
        R, S = np.vsplit(RS, 2)

        # rs = np.dot((np.dot(dP, Jsys) + np.dot(P, dJsys)), dth_flat)
        rs = np.dot(dP, np.dot(Jsys, dth_flat)) + np.dot(P, dJsysdq)
        r_bias, s_bias = np.hsplit(rs, 2)

        #######################################################
        # optimization
        #######################################################
        #if contact == 2 and footCenterR[1] > doubleTosingleOffset/2:
        if contact == 2:
            config['weightMap']['RightUpLeg'] = .8
            config['weightMap']['RightLeg'] = .8
            config['weightMap']['RightFoot'] = .8
        else:
            config['weightMap']['RightUpLeg'] = .1
            config['weightMap']['RightLeg'] = .25
            config['weightMap']['RightFoot'] = .2

        #if contact == 1 and footCenterL[1] > doubleTosingleOffset/2:
        if contact == 1:
            config['weightMap']['LeftUpLeg'] = .8
            config['weightMap']['LeftLeg'] = .8
            config['weightMap']['LeftFoot'] = .8
        else:
            config['weightMap']['LeftUpLeg'] = .1
            config['weightMap']['LeftLeg'] = .25
            config['weightMap']['LeftFoot'] = .2

        # print('vel2', np.dot(dartModel.getJointOrientationGlobal(0).T, dartModel.skeleton.body(0).world_linear_velocity()))
        w = mot.getTrackingWeight(DOFs, motion[0].skeleton, config['weightMap'])

        #if contact == 2:
            #mot.addSoftPointConstraintTerms(problem, totalDOF, Bsc, ddP_des1, Q1, q_bias1)
        mot.addTrackingTerms(problem, totalDOF, Bt, w, ddth_des_flat)
        mot.addLinearTerms(problem, totalDOF, Bl, dL_des_plane, R, r_bias)
        if dH_des is not None:
            mot.addAngularTerms(problem, totalDOF, Bh, dH_des, S, s_bias)

            if True:
                for c_idx in range(len(contact_ids)):
                    mot.addConstraint2(problem, totalDOF, J_contacts[c_idx], dJ_contacts[c_idx], a_sups[c_idx])

        if contactChangeCount > 0:
            contactChangeCount -= 1
            if contactChangeCount == 0:
                maxContactChangeCount = 30
                contactChangeType = 0

        r = problem.solve()
        problem.clear()
        ddth_sol_flat = np.asarray(r['x'])
        # ype.nested(r['x'], ddth_sol)
        # ddth_sol[:6] = np.zeros(6)

        rootPos[0] = dartModel.getBodyPositionGlobal(selectedBody)
        localPos = [[0, 0, 0]]
        inv_h = 1./time_step

        _bodyIDs, _contactPositions, _contactPositionLocals, _contactForces = [], [], [], []
        for i in range(stepsPerFrame):
            # apply penalty force
            _ddq, _tau, _bodyIDs, _contactPositions, _contactPositionLocals, _contactForces = hqp.calc_QP(dartModel.skeleton, ddth_sol_flat, inv_h)
            # _bodyIDs, _contactPositions, _contactPositionLocals, _contactForces = dartModel.calcPenaltyForce(bodyIDsToCheck,mus, Ks, Ds)
            dartModel.applyPenaltyForce(_bodyIDs, _contactPositionLocals, _contactForces)
            dartModel.skeleton.set_forces(_tau)
            # dartModel.setDOFAccelerations(ddth_sol)

            if forceShowTime > viewer.objectInfoWnd.labelForceDur.value():
                forceShowTime = 0
                viewer_ResetForceState()

            forceforce = np.array([viewer.objectInfoWnd.labelForceX.value(), viewer.objectInfoWnd.labelForceY.value(), viewer.objectInfoWnd.labelForceZ.value()])
            extraForce[0] = getParamVal('Fm') * mm.normalize2(forceforce)
            if viewer_GetForceState():
                forceShowTime += wcfg.timeStep
                dartModel.applyPenaltyForce(selectedBodyId, localPos, extraForce)

            dartModel.step()

        del bodyIDs[:]
        del contactPositions[:]
        del contactPositionLocals[:]
        del contactForces[:]
        bodyIDs.extend(_bodyIDs)
        contactPositions.extend(_contactPositions)
        contactPositionLocals.extend(_contactPositionLocals)
        contactForces.extend(_contactForces)

        # rendering
        rightFootVectorX[0] = np.dot(footOriL, np.array([.1, 0, 0]))
        rightFootVectorY[0] = np.dot(footOriL, np.array([0, .1, 0]))
        rightFootVectorZ[0] = np.dot(footOriL, np.array([0,  0,.1]))
        rightFootPos[0] = footCenterL

        rightVectorX[0] = np.dot(footBodyOriL, np.array([.1,0,0]))
        rightVectorY[0] = np.dot(footBodyOriL, np.array([0,.1,0]))
        rightVectorZ[0] = np.dot(footBodyOriL, np.array([0,0,.1]))
        rightPos[0] = footCenterL + np.array([.1,0,0])

        rd_footCenter[0] = footCenter
        rd_footCenterL[0] = footCenterL
        rd_footCenterR[0] = footCenterR

        rd_CM[0] = CM

        rd_CM_plane[0] = CM.copy()
        rd_CM_plane[0][1] = 0.

        if CP is not None and dCP is not None:
            rd_CP[0] = CP
            rd_CP_des[0] = CP_des[0]

            rd_dL_des_plane[0] = [dL_des_plane[0]/100, dL_des_plane[1]/100, dL_des_plane[2]/100]
            rd_dH_des[0] = dH_des

            rd_grf_des[0] = dL_des_plane - totalMass*mm.s2v(wcfg.gravity)

        rd_root_des[0] = rootPos[0]

        del rd_CF[:]
        del rd_CF_pos[:]
        for i in range(len(contactPositions)):
            rd_CF.append( contactForces[i]/100)
            rd_CF_pos.append(contactPositions[i].copy())

        if viewer_GetForceState():
            rd_exfen_des[0] = [extraForce[0][0]/100, extraForce[0][1]/100, extraForce[0][2]/100]
            rd_exf_des[0] = [0,0,0]
        else:
            rd_exf_des[0] = [extraForce[0][0]/100, extraForce[0][1]/100, extraForce[0][2]/100]
            rd_exfen_des[0] = [0,0,0]

        extraForcePos[0] = dartModel.getBodyPositionGlobal(selectedBody)
예제 #17
0
def calc_penalty_force(skel, mus=.5, Ks=15000., Ds=245., locking_vel=.05):
    """

    :type skel: pydart.Skeleton
    :param mus:
    :param Ks:
    :param Ds:
    :param locking_vel:
    :return:
    """
    def _calcPenaltyForce(pBody, position, velocity, mu, lockingVel):
        """
        :type pBody: pydart.BodyNode
        :type position: np.ndarray
        :type velocity: np.ndarray
        :type mu: float
        """
        if position[1] >= 0.:
            return False, np.zeros(3)
        else:
            vNormalRelVel = np.array((0., velocity[1], 0.))
            vTangentialRelVel = velocity - vNormalRelVel
            tangentialRelVel = np.linalg.norm(vNormalRelVel)

            # Ds = 0.
            normalForce = max(0., -Ks * position[1] - Ds * velocity[1])
            vNormalForce = np.array((0., normalForce, 0.))
            frictionForce = mu * normalForce

            if tangentialRelVel < lockingVel:
                frictionForce *= tangentialRelVel / lockingVel
            vFrictionForce = -frictionForce * (
                mm.normalize2(vTangentialRelVel))
            force = vNormalForce + vFrictionForce
            return True, force

    bodyIDs, positions, positionLocals, velocities, forces = [], [], [], [], []
    for i in range(skel.num_bodynodes()):
        body = skel.body(i)
        for shapeNode in body.shapenodes:
            if shapeNode.has_collision_aspect():
                geomType = shapeNode.shape.shape_type_name()
                geomT = np.dot(body.world_transform(),
                               shapeNode.relative_transform())
                geom_point = list()

                if geomType == 'SphereShape':
                    shape = shapeNode.shape  # type: pydart.SphereShape
                    geom_point.append(geomT[:3, 3] -
                                      shape.radius() * mm.unitY())

                elif geomType == 'BoxShape':
                    shape = shapeNode.shape  # type: pydart.BoxShape
                    data = shape.size() / 2.  # type: np.ndarray
                    for perm in itertools.product([1, -1], repeat=3):
                        position_local = np.multiply(
                            np.array((data[0], data[1], data[2])),
                            np.array(perm))
                        geom_point.append(position_local)

                for posIdx in range(len(geom_point)):
                    position_global = np.dot(geomT[:3, :3],
                                             geom_point[posIdx]) + geomT[:3, 3]
                    if position_global[1] < 0.:
                        velocity = body.world_linear_velocity(
                            body.to_local(position_global))
                        is_penetrated, force = _calcPenaltyForce(
                            body, position_global, velocity, mus, locking_vel)
                        if is_penetrated:
                            bodyIDs.append(body.index_in_skeleton())
                            positions.append(position_global)
                            positionLocals.append(
                                body.to_local(position_global))
                            velocities.append(velocity)
                            forces.append(force)

    return bodyIDs, positions, positionLocals, forces