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()
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))
def __init__(self, body, local_vec, des, weight): """ :type body: pydart.BodyNode :param des: :param weight: """ super().__init__() self.body = body self.local_vec = np.asarray(mm.normalize(local_vec)) self.des = np.asarray(mm.normalize(des)) self.weight = weight self.cur = np.dot(self.body.world_transform()[:3, :3], self.local_vec)
def simulateCallback(frame): curTime = time.time() if frame % 30 == 1: pt[0] = time.time() global g_initFlag global forceShowFrame global forceApplyFrame global JsysPre global JsupPreL global JsupPreR global JsupPre global softConstPoint global stage global contactRendererName global desCOMOffset motionModel.update(motion[0]) Kt, Kk, Kl, Kh, Ksc, Bt, Bl, Bh, B_CM, B_CMSd, B_Toe = viewer.GetParam( ) Dt = 2 * (Kt**.5) Dk = 2 * (Kk**.5) Dl = 2 * (Kl**.5) Dh = 2 * (Kh**.5) Dsc = 2 * (Ksc**.5) # tracking th_r_ori = motion.getDOFPositions(frame) th_r = copy.copy(th_r_ori) ############################ #Reference motion modulation dCM_k = 10. linkVelocities = controlModel.getBodyVelocitiesGlobal() dCM = yrp.getCM(linkVelocities, linkMasses, totalMass) dCM_plane = copy.copy(dCM) dCM_plane[1] = 0. global leftHipTimer if viewer.objectInfoWnd.onLeftHip: leftHipTimer = 60 viewer.objectInfoWnd.onLeftHip = False if leftHipTimer > 0: viewer.objectInfoWnd.comOffsetX.value( 0.08 * np.sin(2 * 3.14 * leftHipTimer / 60.)) #viewer.objectInfoWnd.comOffsetZ.value(0.04*np.cos(2*3.14*leftHipTimer/90.)) #B_Hipd = viewer.objectInfoWnd.labelLeftHip.value() #newR1 = mm.exp(mm.v3(0.0,1.0,0.0), 3.14*0.5*B_Hipd/100.) #idx = motion[0].skeleton.getJointIndex('LeftUpLeg') #th_r[idx] = np.dot(th_r[idx], newR1) #idx = motion[0].skeleton.getJointIndex('RightUpLeg') #th_r[idx] = np.dot(th_r[idx], newR1) leftHipTimer -= 1 timeReport[0] += time.time() - curTime curTime = time.time() 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) ddth_c = controlModel.getDOFAccelerations() ype.flatten(ddth_des, ddth_des_flat) ype.flatten(dth, dth_flat) ype.flatten(ddth_c, ddth_c_flat) # jacobian refFootL = motionModel.getBodyPositionGlobal(supL) refFootR = motionModel.getBodyPositionGlobal(supR) positionFootL = [None] * footPartNum positionFootR = [None] * footPartNum for i in range(footPartNum): positionFootL[i] = controlModel.getBodyPositionGlobal( indexFootL[i]) positionFootR[i] = controlModel.getBodyPositionGlobal( indexFootR[i]) 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. linkPositions_ref = motionModel.getBodyPositionsGlobal() linkVelocities_ref = motionModel.getBodyVelocitiesGlobal() linkAngVelocities_ref = motionModel.getBodyAngVelocitiesGlobal() linkInertias_ref = motionModel.getBodyInertiasGlobal() CM_ref = yrp.getCM(linkPositions_ref, linkMasses, totalMass) CM_plane_ref = copy.copy(CM_ref) CM_plane_ref[1] = 0. P = ymt.getPureInertiaMatrix(TO, linkMasses, linkPositions, CM, linkInertias) dP = ymt.getPureInertiaMatrixDerivative(dTO, linkMasses, linkVelocities, dCM, linkAngVelocities, linkInertias) timeReport[1] += time.time() - curTime curTime = time.time() yjc.computeJacobian2(Jsys, DOFs, jointPositions, jointAxeses, linkPositions, allLinkJointMasks) timeReport[2] += time.time() - curTime curTime = time.time() # yjc.computeJacobianDerivative2(dJsys, DOFs, jointPositions, jointAxeses, linkAngVelocities, linkPositions, allLinkJointMasks) if frame > 0: dJsys = (Jsys - JsysPre) * 30. else: dJsys = (Jsys - Jsys) JsysPre = Jsys.copy() timeReport[3] += time.time() - curTime curTime = time.time() bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce( bodyIDsToCheck, mus, Ks, Ds) CP = yrp.getCP(contactPositions, contactForces) if CP != None: CP[1] = 0. for i in range(len(bodyIDsToCheck)): controlModel.SetBodyColor(bodyIDsToCheck[i], 0, 0, 0, 255) contactFlagFootL = [0] * footPartNum contactFlagFootR = [0] * footPartNum for i in range(len(bodyIDs)): controlModel.SetBodyColor(bodyIDs[i], 255, 105, 105, 200) index = controlModel.id2index(bodyIDs[i]) for j in range(len(indexFootL)): if index == indexFootL[j]: contactFlagFootL[j] = 1 for j in range(len(indexFootR)): if index == indexFootR[j]: contactFlagFootR[j] = 1 for j in range(0, footPartNum): jFootR[j] = Jsys[6 * indexFootR[j]:6 * indexFootR[j] + 6] #.copy() jFootL[j] = Jsys[6 * indexFootL[j]:6 * indexFootL[j] + 6] #.copy() dJFootR[j] = dJsys[6 * indexFootR[j]:6 * indexFootR[j] + 6] #.copy() dJFootL[j] = dJsys[6 * indexFootL[j]:6 * indexFootL[j] + 6] #.copy() if footPartNum == 1: desFCL = (controlModel.getBodyPositionGlobal(supL)) desFCR = (controlModel.getBodyPositionGlobal(supR)) else: r = .5 + desCOMOffset desFCL = (controlModel.getBodyPositionGlobal(indexFootL[0]) * r + controlModel.getBodyPositionGlobal(indexFootL[1]) * (1.0 - r) ) #controlModel.getBodyPositionGlobal(indexFootL[1]) desFCR = (controlModel.getBodyPositionGlobal(indexFootR[0]) * r + controlModel.getBodyPositionGlobal(indexFootR[1]) * (1.0 - r) ) #controlModel.getBodyPositionGlobal(indexFootR[1]) desFC = desFCL + (desFCR - desFCL) / 2.0 desFC[1] = 0 rd_footCenter_des[0] = desFC.copy() curRelCMVec = CM_plane - desFC vecRatio = mm.length(curRelCMVec) * 0. #print(frame, vecRatio) footCenter = desFC - curRelCMVec * (vecRatio) #/10.0 footCenter = ( getBodyGlobalPos(controlModel, motion, 'LeftCalcaneus_1') + getBodyGlobalPos(controlModel, motion, 'LeftPhalange_1') + getBodyGlobalPos(controlModel, motion, 'RightCalcaneus_1') + getBodyGlobalPos(controlModel, motion, 'RightPhalange_1')) / 4. #footCenter = (getBodyGlobalPos(controlModel, motion, 'LeftCalcaneus_1') + getBodyGlobalPos(controlModel, motion, 'LeftTalus_1') + getBodyGlobalPos(controlModel, motion, 'RightCalcaneus_1') + getBodyGlobalPos(controlModel, motion, 'RightTalus_1'))/4. footCenter_ref = refFootL + (refFootR - refFootL) / 2.0 #footCenter_ref[1] = 0. footCenter[1] = 0. footCenterOffset = np.array([ viewer.objectInfoWnd.comOffsetX.value(), 0, viewer.objectInfoWnd.comOffsetZ.value() ]) #footCenter += footCenterOffset vecRatio = mm.length(curRelCMVec) * 0. softConstPointOffset = -curRelCMVec * (vecRatio) #/10.0 #print(frame, vecRatio, softConstPointOffset) desForeSupLAcc = [0, 0, 0] desForeSupRAcc = [0, 0, 0] totalNormalForce = [0, 0, 0] for i in range(len(contactForces)): totalNormalForce[0] += contactForces[i][0] totalNormalForce[1] += contactForces[i][1] totalNormalForce[2] += contactForces[i][2] #print((totalMass*mm.s2v(wcfg.gravity))[1]) footCenterOffset = np.array([ viewer.objectInfoWnd.comOffsetX.value(), viewer.objectInfoWnd.comOffsetY.value(), viewer.objectInfoWnd.comOffsetZ.value() ]) ###################### # optimization terms ###################### # linear momentum CM_ref_plane = footCenter + footCenterOffset dL_des_plane = Kl * totalMass * (CM_ref_plane - CM_plane) - Dl * totalMass * dCM_plane dL_des_plane[1] = Kl * totalMass * (CM_ref[1] + footCenterOffset[1] - CM[1]) - Dl * totalMass * dCM[1] #dL_des_plane[1] = 0. #print 'dL_des_plane', dL_des_plane # angular momentum CP_ref = footCenter + footCenterOffset CP_ref[1] = 0. timeStep = 30. if CP_old[0] == None or CP == None: dCP = None else: dCP = (CP - CP_old[0]) * timeStep CP_old[0] = CP if CP != None and dCP != None: ddCP_des = Kh * (CP_ref - CP) - Dh * (dCP) CP_des = CP + dCP * (1 / timeStep) + .5 * ddCP_des * ( (1 / timeStep)**2) #print 'dCP: ', dCP #print 'ddCP_des: ', ddCP_des #print 'CP_des: ', CP_des #dH_des = np.cross((CP_des - CM), (dL_des_plane + totalMass*mm.s2v(wcfg.gravity))) dH_des = np.cross( (CP_des - CM_plane), (dL_des_plane + totalMass * mm.s2v(wcfg.gravity))) else: dH_des = None # 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) flagContact = True if dH_des == None or np.any(np.isnan(dH_des)) == True: flagContact = False #viewer.doc.showRenderer('rd_grf_des', False) #viewer.motionViewWnd.update(1, viewer.doc) #else: #viewer.doc.showRenderer('rd_grf_des', True) #viewer.motionViewWnd.update(1, viewer.doc) ''' 0 : initial 1 : contact 2 : fly 3 : landing ''' #MOTION = FORWARD_JUMP if mit.MOTION == mit.FORWARD_JUMP: frame_index = [136, 100] #frame_index = [100000, 100000] elif mit.MOTION == mit.TAEKWONDO: frame_index = [130, 100] #frame_index = [100000, 100000] elif mit.MOTION == mit.TAEKWONDO2: frame_index = [130 + 40, 100] elif mit.MOTION == mit.WALK: frame_index = [10000, 60] elif mit.MOTION == mit.TIPTOE: frame_index = [1000000, 1000000] #frame_index = [10000, 165] else: frame_index = [1000000, 1000000] #MOTION = TAEKWONDO #frame_index = [135, 100] if frame > frame_index[0]: if stage != POWERFUL_BALANCING: print("#", frame, "-POWERFUL_BALANCING") stage = POWERFUL_BALANCING Kk = Kk * 2 Dk = 2 * (Kk**.5) elif frame > frame_index[1]: if stage != MOTION_TRACKING: print("#", frame, "-MOTION_TRACKING") stage = MOTION_TRACKING trackingW = w #if checkAll(contactFlagFootR, 0) != 1 : if 0: #stage == MOTION_TRACKING: trackingW = w2 #stage = POWERFUL_BALANCING Bt = Bt * 2 # optimization mot.addTrackingTerms(problem, totalDOF, Bt, trackingW, ddth_des_flat) #mot.addSoftPointConstraintTerms(problem, totalDOF, Bsc, ddP_des1, Q1, q_bias1) if flagContact == True: if stage != MOTION_TRACKING + 10: mot.addLinearTerms(problem, totalDOF, Bl, dL_des_plane, R, r_bias) #mot.addAngularTerms(problem, totalDOF, Bh, dH_des, S, s_bias) # using || dH ||^2 instead mot.addAnotherTerms(problem, totalDOF, Bh, S, -(s_bias + Kh * np.dot(S, dth_flat))) a_sup_2 = None Jsup_2 = None dJsup_2 = None ############################## # Hard constraint Kk2 = Kk * 4.0 Dk2 = 2 * (Kk2**.5) ankleW = 0 ankleOffset = ankleW * curRelCMVec[2] metatarW = 0 metatarOffset = metatarW * curRelCMVec[2] ############################## ############################## # Additional constraint if stage != MOTION_TRACKING and frame > 5: # ankle strategy idx = 0 #LEFT/RIGHT_TOES if mit.FOOT_PART_NUM == 1: yOffset = 0.03 else: yOffset = 0.069 #yOffset = 0.06 # ankleOffset = (footCenter - CM_plane)*4. ankleOffset = footCenterOffset * 10. ankleOffset[1] = 0. #ankleOffset[2] = 0. ankleOffset[2] = ankleOffset[2] * 20. ankleOffsetL = ankleOffset.copy() ankleOffsetR = ankleOffset.copy() #ankleOffset= np.array((0,0,0)) if footCenterOffset[0] > 0.0: ankleOffsetL[0] = 0. else: ankleOffsetR[0] = 0. # print 'ankleOffset=', ankleOffset desLinearAccL, desPosL = getDesFootLinearAcc( motionModel, controlModel, indexFootL[idx], ModelOffset, CM_ref, CM, Kk, Dk, yOffset) #0.076) #0.14) desLinearAccR, desPosR = getDesFootLinearAcc( motionModel, controlModel, indexFootR[idx], ModelOffset, CM_ref, CM, Kk, Dk, yOffset) ax = [0, 0, -1] aaa = getBodyGlobalOri(controlModel, motion, 'RightFoot') #print np.dot(aaa, ax) if mit.FOOT_PART_NUM == 1: ax = [0, 1, 0] desAngularAccL = getDesFootAngularAcc( motionModel, controlModel, indexFootL[idx], Kk, Dk, ax, mm.normalize([0, 1, 0] + ankleOffsetL)) desAngularAccR = getDesFootAngularAcc( motionModel, controlModel, indexFootR[idx], Kk, Dk, ax, mm.normalize([0, 1, 0] + ankleOffsetR)) a_sup_2 = np.hstack((np.hstack((desLinearAccL, desAngularAccL)), np.hstack((desLinearAccR, desAngularAccR)))) Jsup_2 = np.vstack((jFootL[idx], jFootR[idx])) dJsup_2 = np.vstack((dJFootL[idx], dJFootR[idx])) #mot.addConstraint(problem, totalDOF, Jsup_2, dJsup_2, dth_flat, a_sup_2) #mot.addConstraint(problem, totalDOF, Jsup_2[:1], dJsup_2[:1], dth_flat, a_sup_2[:1]) #mot.addConstraint(problem, totalDOF, Jsup_2[2:], dJsup_2[2:], dth_flat, a_sup_2[2:]) #mot.addConstraint(problem, totalDOF, Jsup_2[3:], dJsup_2[3:], dth_flat, a_sup_2[3:]) mot.addAnotherTerms(problem, totalDOF, viewer.objectInfoWnd.Bc.value(), Jsup_2[3:], a_sup_2[3:] - np.dot(dJsup_2[3:], dth_flat)) #mot.addAnotherTerms(problem, totalDOF, viewer.objectInfoWnd.Bc.value(), Jsup_2, a_sup_2 - np.dot(dJsup_2, dth_flat)) #mot.addAnotherTerms(problem, totalDOF, 1.*viewer.objectInfoWnd.Bc.value(), Jsup_2[0:1], a_sup_2[0:1] - np.dot(dJsup_2[0:1] , dth_flat)) #mot.addAnotherTerms(problem, totalDOF, 1.*viewer.objectInfoWnd.Bc.value(), Jsup_2[2:], a_sup_2[2:] - np.dot(dJsup_2[2:] , dth_flat)) desCOMOffset = 0.0 rd_DesPosL[0] = desPosL.copy() rd_DesPosR[0] = desPosR.copy() if stage == STATIC_BALANCING and frame > 10: # and False: del rd_desPoints[:] # foot strategy #Kk2 = Kk * 2.5 #Kk2 = Kk * .2 #Dk2 = 2*(Kk2**.5) desForePosL = [0, 0, 0] desForePosR = [0, 0, 0] desRearPosL = [0, 0, 0] desRearPosR = [0, 0, 0] footPartPos = [] footPartPos.append( controlModel.getBodyPositionGlobal( motion[0].skeleton.getJointIndex('LeftCalcaneus_1'))) footPartPos.append( controlModel.getBodyPositionGlobal( motion[0].skeleton.getJointIndex('LeftPhalange_1'))) footPartPos.append( controlModel.getBodyPositionGlobal( motion[0].skeleton.getJointIndex('RightCalcaneus_1'))) footPartPos.append( controlModel.getBodyPositionGlobal( motion[0].skeleton.getJointIndex('RightPhalange_1'))) for i in range(1, footPartNum): contactFlagFootL[i] = 1 contactFlagFootR[i] = 1 SupPts = np.vstack( (np.array((footPartPos[0][0], footPartPos[1][0], footPartPos[2][0], footPartPos[3][0])), np.array( (footPartPos[0][2], footPartPos[1][2], footPartPos[2][2], footPartPos[3][2])), np.array((1., 1., 1., 1.)))) coordWidthLen = 2. coordLengthLen = 1.5 SupUV = np.vstack( (np.array((-coordWidthLen, -coordWidthLen, coordWidthLen, coordWidthLen)), np.array((-coordLengthLen, coordLengthLen, -coordLengthLen, coordLengthLen)), np.array((1., 1., 1., 1.)))) SupMap = np.dot(np.dot(SupUV, SupUV.T), np.linalg.inv(np.dot(SupPts, SupUV.T))) #print SupMap desFootCenter = footCenter + footCenterOffset footCenterPts = np.array((desFootCenter[0], desFootCenter[2], 1)) #print np.dot(SupMap, footCenterPts) #print np.dot(getBodyGlobalOri(controlModel, motion, 'LeftMetatarsal_1'), np.array((0,1,0))) CM_plane_2D = np.array((CM[0], CM[2], 1)) # CM_plane_UV = np.dot(SupMap, CM_plane_2D) CM_plane_UV = np.dot(SupMap, footCenterPts) # print CM_plane_UV # for i in range(1, footPartNum): if CM_plane_UV[1] > .5: # com is in front for i in range(1, 5): contactFlagFootL[i] = 0 contactFlagFootR[i] = 0 elif CM_plane_UV[1] < -.5: # com is back for i in range(3, footPartNum): contactFlagFootL[i] = 0 contactFlagFootR[i] = 0 else: # com is in middle position for i in range(3, 5): contactFlagFootL[i] = 0 contactFlagFootR[i] = 0 contactFlagFoot = contactFlagFootL if CM_plane_UV[0] < 0.: contactFlagFoot = contactFlagFootR # CM_plane_UV[0] = -CM_plane_UV[0] if abs(CM_plane_UV[0]) > 1.: for j in range(0, 3): contactFlagFoot[2 * j + 2] = 0 # print 'footL : ',contactFlagFootL # print 'footR : ',contactFlagFootR for i in range(1, footPartNum): axis = [0, 0, 1] if i == 1 or i == 2: axis = [0, 0, -1] desAng = [0, 0, 1] if i == 1 or i == 2: desAng = [0, 0, -1] desY = 0.029 if contactFlagFootL[i] == 1: desLinearAccL, desForePosL = getDesFootLinearAcc( motionModel, controlModel, indexFootL[i], ModelOffset, CM_ref, CM, Kk2, Dk2, desY) desAngularAccL = getDesFootAngularAcc( motionModel, controlModel, indexFootL[i], Kk2, Dk2, axis, desAng) a_sup_2 = np.hstack((desLinearAccL, desAngularAccL)) Jsup_2 = jFootL[i].copy() dJsup_2 = dJFootL[i].copy() mot.addConstraint(problem, totalDOF, Jsup_2, dJsup_2, dth_flat, a_sup_2) #mot.addAnotherTerms(problem, totalDOF, viewer.objectInfoWnd.Bc.value(), Jsup_2, a_sup_2 - np.dot(dJsup_2, dth_flat)) #mot.addAnotherTerms(problem, totalDOF, viewer.objectInfoWnd.Bc.value(), Jsup_2[3:], a_sup_2[3:] - np.dot(dJsup_2[3:] , dth_flat)) rd_desPoints.append(desForePosL.copy()) if contactFlagFootR[i] == 1: desLinearAccR, desForePosR = getDesFootLinearAcc( motionModel, controlModel, indexFootR[i], ModelOffset, CM_ref, CM, Kk2, Dk2, desY) desAngularAccR = getDesFootAngularAcc( motionModel, controlModel, indexFootR[i], Kk2, Dk2, axis, desAng) a_sup_2 = np.hstack((desLinearAccR, desAngularAccR)) Jsup_2 = jFootR[i].copy() dJsup_2 = dJFootR[i].copy() mot.addConstraint(problem, totalDOF, Jsup_2, dJsup_2, dth_flat, a_sup_2) #mot.addAnotherTerms(problem, totalDOF, viewer.objectInfoWnd.Bc.value(), Jsup_2, a_sup_2 - np.dot(dJsup_2, dth_flat)) #mot.addAnotherTerms(problem, totalDOF, viewer.objectInfoWnd.Bc.value(), Jsup_2[3:], a_sup_2[3:] - np.dot(dJsup_2[3:], dth_flat)) rd_desPoints.append(desForePosR.copy()) rd_DesForePosL[0] = desForePosL rd_DesForePosR[0] = desForePosR rd_DesRearPosL[0] = desRearPosL rd_DesRearPosR[0] = desRearPosR ############################## #if Jsup_2 != None: # mot.addConstraint(problem, totalDOF, Jsup_2, dJsup_2, dth_flat, a_sup_2) timeReport[4] += time.time() - curTime curTime = time.time() #print np.NAN r = problem.solve() #print frame #Ashape = np.shape(problem.A) #if len(Ashape) >0 : # for i in range(0, Ashape[0]): # print problem.A[i] #print problem.A[] #print problem.b #print r problem.clear() #print r['x'] ype.nested(r['x'], ddth_sol) #print ddth_sol rootPos[0] = controlModel.getBodyPositionGlobal(selectedBody) localPos = [[0, 0, 0]] ########################################### ##Jacobian Transpose control # COM Position control #fCom = Wcp*(pHatComDes - pHatCom) + Wcv*(vComDes - vCom) + Wcm*(footCenter_plane - CM_plane) w1 = 10 #10.1 w2 = 1 #1#2*(w1**.5) if frame > 100: w1 = 10.1 #10.1 w2 = 1 footToCMVec = CM - footCenter desCMPos = [footCenter[0], mm.length(footToCMVec), footCenter[2]] #print("desCMPos", desCMPos) #print("CM", CM) fCom = w1 * (desCMPos - CM) + w2 * (-dCM) #print("fCom", fCom) #fCom[0] = 0. #fCom[1] = 0 #fCom[2] = 0 rd_virtualForce[0] = fCom.copy() #hipPos = controlModel.getBodyPositionGlobal(rootB) headPos = controlModel.getBodyPositionGlobal(selectedBody) hipPos = controlModel.getBodyPositionGlobal(rootB) yjc.computeJacobian2(Jcom, DOFs, jointPositions, jointAxeses, [headPos], comUpperJointMasks) #yjc.computeJacobianDerivative2(dJcom, DOFs, jointPositions, jointAxeses, linkAngVelocities, [CM], comUpperJointMasks, False) JcomT = Jcom.T TauJT = np.dot(JcomT, fCom) # Angular Momentum Hc = ymt.getAngularMomentum(CM, linkInertias, linkAngVelocities, linkPositions, linkMasses, linkVelocities) Href = ymt.getAngularMomentum(CM_ref, linkInertias_ref, linkAngVelocities_ref, linkPositions_ref, linkMasses, linkVelocities_ref) Wam = .05 Tam = Wam * (Href - Hc) #print("Tam", Tam) yjc.computeAngJacobian2(JcomAng, DOFs, jointPositions, jointAxeses, [headPos], comUpperJointMasks) TauAM = np.dot(JcomAng.T, Tam) timeReport[5] += time.time() - curTime curTime = time.time() for i in range(stepsPerFrame): # apply penalty force bodyIDs, contactPositions, contactPositionLocals, contactForces = vpWorld.calcPenaltyForce( bodyIDsToCheck, mus, Ks, Ds) #print frame, bodyIDs, contactPositions, contactPositionLocals, contactForces vpWorld.applyPenaltyForce(bodyIDs, contactPositionLocals, contactForces) extraForce[0] = viewer.GetForce() if (extraForce[0][0] != 0 or extraForce[0][1] != 0 or extraForce[0][2] != 0): forceApplyFrame += 1 #vpWorld.applyPenaltyForce(selectedBodyId, localPos, extraForce) controlModel.applyBodyForceGlobal(selectedBody, extraForce[0]) applyedExtraForce[0] = extraForce[0] if forceApplyFrame * wcfg.timeStep > 0.1: viewer.ResetForce() forceApplyFrame = 0 #print ddth_sol controlModel.setDOFAccelerations(ddth_sol) controlModel.solveHybridDynamics() ''' if (frame > 5): tau = controlModel.getJointTorqueLocal(indexFootL[3]) tau2 = controlModel.getJointTorqueLocal(indexFootL[4]) tau3 = controlModel.getJointTorqueLocal(indexFootR[3]) tau4 = controlModel.getJointTorqueLocal(indexFootR[4]) torques = controlModel.getInternalJointTorquesLocal() if (frame > 100 and frame < 110) or (frame > 165 and frame < 190): Wcal1 = 0.05 Wcal2 = 0.05 dC = fCom[2]*Wcal1-dCM[2]*Wcal2 print("dC", dC) torques[indexFootL[5]-1]+= (dC, 0.0, 0.0) torques[indexFootR[5]-1]+= (dC, 0.0, 0.0) if (frame > 50 and frame < 75) or (frame > 110 and frame <140) or (frame > 185 and frame < 220): metatarR = [controlModel.getBodyOrientationGlobal(indexFootL[1])] phalangeR = [controlModel.getBodyOrientationGlobal(indexFootL[3])] metatarR2 = np.dot(metatarR, np.array([0,0,1])) phalangeR2 = np.dot(phalangeR, np.array([0,0,1])) metatarRZ = mm.normalize(metatarR2[0]) phalangeRZ = mm.normalize(phalangeR2[0]) lean = np.dot(metatarRZ, phalangeRZ) Wlean = 2 dt = -0.02*(lean)*Wlean torques[indexFootL[3]-1]+= (dt, 0.0, 0.0) torques[indexFootL[4]-1]+= (dt, 0.0, 0.0) torques[indexFootR[3]-1]+= (dt, 0.0, 0.0) torques[indexFootR[4]-1]+= (dt, 0.0, 0.0) i = 0 t = 6 while t < len(TauJT) : torques[i] += (TauJT[t]+TauAM[t], TauJT[t+1]+TauAM[t+1], TauJT[t+2]+TauAM[t+2]) i+=1 t+=3 #totalTorques = [a + b for a, b in zip(torques, TauJT)] #print("torques2", torques) #print("TauJT", TauJT[16], TauJT[17], TauJT[18]) #print("torques", torques[16]) #print("totalTorques", totalTorques[16]) controlModel.setInternalJointTorquesLocal(torques) ''' ''' extraForce[0] = viewer.GetForce() if (extraForce[0][0] != 0 or extraForce[0][1] != 0 or extraForce[0][2] != 0) : forceApplyFrame += 1 vpWorld.applyPenaltyForce(selectedBodyId, localPos, extraForce) applyedExtraForce[0] = extraForce[0] if forceApplyFrame*wcfg.timeStep > 0.1: viewer.ResetForce() forceApplyFrame = 0 ''' vpWorld.step() if frame % 30 == 0: print 'elapsed time for 30 frames:', time.time() - pt[0] # rendering rd_footCenter[0] = footCenter rd_CM[0] = CM.copy() rd_CM_plane[0] = CM_plane.copy() rd_footCenter_ref[0] = footCenter_ref rd_CM_plane_ref[0] = CM_ref.copy() rd_CM_ref[0] = CM_ref.copy() rd_CM_ref_vec[0] = (CM_ref - footCenter_ref) * 3. rd_CM_vec[0] = (CM - CM_plane) rd_CM_des[0] = CM_ref_plane.copy() rd_CM_des[0][1] = .01 #rd_CM_plane[0][1] = 0. if CP != None and dCP != None: rd_CP[0] = CP rd_CP_des[0] = CP_des rd_dL_des_plane[0] = dL_des_plane rd_dH_des[0] = dH_des rd_grf_des[ 0] = totalNormalForce # - totalMass*mm.s2v(wcfg.gravity)#dL_des_plane - totalMass*mm.s2v(wcfg.gravity) rd_exf_des[0] = applyedExtraForce[0] rd_root_des[0] = rootPos[0] rd_CMP[0] = softConstPoint rd_soft_const_vec[0] = controlModel.getBodyPositionGlobal( constBody) - softConstPoint #indexL = motion[0].skeleton.getJointIndex('Hips') #indexR = motion[0].skeleton.getJointIndex('Spine1') indexL = indexFootL[0] indexR = indexFootR[0] curAng = [controlModel.getBodyOrientationGlobal(indexL)] curAngY = np.dot(curAng, np.array([0, 0, 1])) rd_footL_vec[0] = np.copy(curAngY[0]) rd_footCenterL[0] = controlModel.getBodyPositionGlobal(indexL) curAng = [controlModel.getBodyOrientationGlobal(indexR)] curAngY = np.dot(curAng, np.array([0, 0, 1])) rd_footR_vec[0] = np.copy(curAngY[0]) rd_footCenterR[0] = controlModel.getBodyPositionGlobal(indexR) if (forceApplyFrame == 0): applyedExtraForce[0] = [0, 0, 0] timeReport[6] += time.time() - curTime
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 frame == 0: setParamVal('com Y offset', 0.02) sphere_radius = 0.03 vpWorld.set_sphere_bump( 0, sphere_radius, (1.6361 + (frame % 60) * 0.001, -sphere_radius + 0.02, -0.2209)) vpWorld.set_sphere_bump( 1, sphere_radius, (1.4043 + (frame % 60) * 0.001, -sphere_radius + 0.02, -0.2201)) 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 # 1. calculate desired up vector of each contacting body. # 1.1 find closest sphere bump_sphere_list = vpWorld.get_sphere_bump_list() def find_closest_bump_sphere(pos): closest_idx = -1 dist = pos[1] for i in range(len(bump_sphere_list)): bump_sphere = bump_sphere_list[i] temp_dist = np.linalg.norm(pos - bump_sphere[1]) - bump_sphere[0] if temp_dist < dist: dist = temp_dist closest_idx = i return closest_idx closest_bump_sphere = list( map(find_closest_bump_sphere, contact_body_pos)) # 1.2. set des_up_vec to normal direction des_up_vec = [ mm.normalize(contact_body_pos[i] - bump_sphere_list[closest_bump_sphere[i]][1]) if closest_bump_sphere[i] != -1 else mm.unitY() for i in range(len(contact_ids)) ] des_pos = [ bump_sphere_list[closest_bump_sphere[i]][1] + np.asarray(des_up_vec[i]) * bump_sphere_list[closest_bump_sphere[i]][0] if closest_bump_sphere[i] != -1 else 0. for i in range(len(contact_ids)) ] # 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)) ])) # 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]]), np.asarray(des_up_vec[i]))), 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 / 5., kt_sup, kt_sup / 5.]) # 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)) ] # a_sups = [np.append(np.dot(KT_SUP, (des_pos[i]-contact_body_pos[i])) - dt_sup * contact_body_vel[i], # 10.*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 * des_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 body_id in range(controlModel.getBodyNum()): control_model_renderer.body_colors[body_id] = (255, 240, 255) control_model_renderer.geom_colors[body_id] = [ (255, 240, 255) ] * controlModel.getBodyGeomNum(body_id) for i in range(len(geomIDs)): control_model_renderer.geom_colors[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 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))