85 lines
3.0 KiB
Python
85 lines
3.0 KiB
Python
|
import lcm
|
|||
|
import sys
|
|||
|
import os
|
|||
|
import time
|
|||
|
from threading import Thread, Lock
|
|||
|
|
|||
|
from robot_control_cmd_lcmt import robot_control_cmd_lcmt
|
|||
|
from robot_control_response_lcmt import robot_control_response_lcmt
|
|||
|
from localization_lcmt import localization_lcmt
|
|||
|
|
|||
|
import toml
|
|||
|
import copy
|
|||
|
import math
|
|||
|
from file_send_lcmt import file_send_lcmt
|
|||
|
class Vec3:
|
|||
|
def __init__(self, x=0, y=0, z=0):
|
|||
|
self.x = x
|
|||
|
self.y = y
|
|||
|
self.z = z
|
|||
|
|
|||
|
def __getitem__(self, key):
|
|||
|
if key == 0:
|
|||
|
return self.x
|
|||
|
elif key == 1:
|
|||
|
return self.y
|
|||
|
elif key == 2:
|
|||
|
return self.z
|
|||
|
else:
|
|||
|
raise IndexError("Vec3 index out of range")
|
|||
|
|
|||
|
def __setitem__(self, key, value):
|
|||
|
if key == 0:
|
|||
|
self.x = value
|
|||
|
elif key == 1:
|
|||
|
self.y = value
|
|||
|
elif key == 2:
|
|||
|
self.z = value
|
|||
|
else:
|
|||
|
raise IndexError("Vec3 index out of range")
|
|||
|
|
|||
|
class Motor_Ctrl(object):
|
|||
|
def InverseKinematic(quad, leg, p):
|
|||
|
# 假设quad是一个Quadruped实例,包含必要的属性
|
|||
|
# p是一个Vec3实例或任何可以通过索引访问x, y, z的类似对象
|
|||
|
|
|||
|
l1 = quad.abad_link_length_
|
|||
|
l2 = quad.hip_link_length_
|
|||
|
l3 = quad.knee_link_length_
|
|||
|
l4 = quad.knee_link_y_offset_
|
|||
|
|
|||
|
x, y, z = p.x, p.y, p.z
|
|||
|
|
|||
|
if abs(y) < 0.0001:
|
|||
|
y = 0.0001
|
|||
|
|
|||
|
ss1 = math.sqrt(z**2 + y**2)
|
|||
|
|
|||
|
side_sign = quad.GetSideSign(leg) # 假设Quadruped类有一个GetSideSign方法
|
|||
|
|
|||
|
if side_sign * y >= 0:
|
|||
|
q_des_0 = side_sign * (math.acos((z**2 + ss1**2 - y**2) / (2 * abs(z) * ss1)) +
|
|||
|
math.acos((l1 + l4) / ss1) - math.pi / 2)
|
|||
|
else:
|
|||
|
q_des_0 = side_sign * (-math.acos((z**2 + ss1**2 - y**2) / (2 * abs(z) * ss1)) +
|
|||
|
math.acos((l1 + l4) / ss1) - math.pi / 2)
|
|||
|
|
|||
|
ss2 = math.sqrt(ss1**2 - (l1 + l4)**2 + x**2)
|
|||
|
|
|||
|
q_des_2 = math.acos((l2**2 + l3**2 - ss2**2) / (2 * l2 * l3))
|
|||
|
q_des_2 = math.pi - q_des_2
|
|||
|
|
|||
|
if z <= 0:
|
|||
|
q_des_1 = -math.acos((l2**2 + ss2**2 - l3**2) / (2 * l2 * ss2)) + math.asin(x / ss2)
|
|||
|
else:
|
|||
|
q_des_1 = -math.acos((l2**2 + ss2**2 - l3**2) / (2 * l2 * ss2)) + (math.pi - math.asin(x / ss2))
|
|||
|
|
|||
|
# 检查NaN值(虽然Python的math函数通常不会直接返回NaN,但这里为了完整性还是检查)
|
|||
|
if math.isnan(q_des_0) or math.isnan(q_des_1) or math.isnan(q_des_2):
|
|||
|
# print(f"[LegController] leg {leg} IK result contains NaN!")
|
|||
|
return None # 或者可以选择抛出异常
|
|||
|
|
|||
|
return Vec3(q_des_0, q_des_1, q_des_2)
|
|||
|
|
|||
|
# 注意:这里需要Quadruped类的定义,以及它包含必要的属性和方法,如abad_link_length_, hip_link_length_等
|
|||
|
# 以及GetSideSign(leg)方法
|