Skip to content

Commit b252664

Browse files
committed
Merge branch 'main' of https://github.com/thuasta/thuei-2
2 parents acf2146 + 00b9ceb commit b252664

79 files changed

Lines changed: 5651 additions & 13 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

thuei-1/LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

thuei-1/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# thuei-1
2+
Platform for the 1st Tsinghua University Embodied Intelligence Challenge
3+
4+
## Installation
5+
```sh
6+
git clone https://github.com/thuasta/thuei-1.git /root/thuei-1
7+
```
8+
9+
## Notice
10+
1. 请把thuei-1整个文件夹放到香橙派/root下,否则由于文件路径问题,代码会无法运行
11+
2. 由于OPi.GPIO与扩展板不适配,扩展板rgb灯无法操作,请注释掉相关函数
12+
3. 报错显示cv2不存在或者cv2中的函数不存在,请重装opencv
16 KB
Binary file not shown.
16 KB
Binary file not shown.
16 KB
Binary file not shown.
16 KB
Binary file not shown.
16 KB
Binary file not shown.
16 KB
Binary file not shown.
16 KB
Binary file not shown.
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#!/usr/bin/env python3
2+
# encoding:utf-8
3+
import sys
4+
sys.path.append('/root/thuei-1/sdk-python/')
5+
import time
6+
import numpy as np
7+
from math import sqrt
8+
import matplotlib.pyplot as plt
9+
from ArmIK.InverseKinematics import *
10+
from ArmIK.Transform import getAngle
11+
from mpl_toolkits.mplot3d import Axes3D
12+
from HiwonderSDK.Board import setBusServoPulse,getBusServoPulse, setPWMServoPulse, getPWMServoPulse
13+
14+
#机械臂根据逆运动学算出的角度进行移动
15+
ik = IK('arm')
16+
#设置连杆长度
17+
l1 = ik.l1
18+
l4 = ik.l4
19+
ik.setLinkLength(L1=l1+1.3, L4=l4)
20+
21+
class ArmIK:
22+
servo3Range = (500, 2500.0, 0, 180.0) #脉宽, 角度
23+
servo4Range = (500, 2500.0, 0, 180.0)
24+
servo5Range = (500, 2500.0, 0, 180.0)
25+
servo6Range = (500, 2500.0, 0, 180.0)
26+
27+
def __init__(self):
28+
self.setServoRange()
29+
30+
def setServoRange(self, servo3_Range=servo3Range, servo4_Range=servo4Range, servo5_Range=servo5Range, servo6_Range=servo6Range):
31+
# 适配不同的舵机
32+
self.servo3Range = servo3_Range
33+
self.servo4Range = servo4_Range
34+
self.servo5Range = servo5_Range
35+
self.servo6Range = servo6_Range
36+
self.servo3Param = (self.servo3Range[1] - self.servo3Range[0]) / (self.servo3Range[3] - self.servo3Range[2])
37+
self.servo4Param = (self.servo4Range[1] - self.servo4Range[0]) / (self.servo4Range[3] - self.servo4Range[2])
38+
self.servo5Param = (self.servo5Range[1] - self.servo5Range[0]) / (self.servo5Range[3] - self.servo5Range[2])
39+
self.servo6Param = (self.servo6Range[1] - self.servo6Range[0]) / (self.servo6Range[3] - self.servo6Range[2])
40+
41+
def transformAngelAdaptArm(self, theta3, theta4, theta5, theta6):
42+
#将逆运动学算出的角度转换为舵机对应的脉宽值
43+
servo3 = int(round(theta3 * self.servo3Param + (self.servo3Range[1] + self.servo3Range[0])/2))
44+
if servo3 > self.servo3Range[1] or servo3 < self.servo3Range[0]:
45+
logger.info('servo3(%s)超出范围(%s, %s)', servo3, self.servo3Range[0], self.servo3Range[1])
46+
return False
47+
48+
servo4 = int(round(theta4 * self.servo4Param + (self.servo4Range[1] + self.servo4Range[0])/2))
49+
if servo4 > self.servo4Range[1] or servo4 < self.servo4Range[0]:
50+
logger.info('servo4(%s)超出范围(%s, %s)', servo4, self.servo4Range[0], self.servo4Range[1])
51+
return False
52+
53+
servo5 = int(round((self.servo5Range[1] + self.servo5Range[0])/2 + (90.0 - theta5) * self.servo5Param))
54+
if servo5 > ((self.servo5Range[1] + self.servo5Range[0])/2 + 90*self.servo5Param) or servo5 < ((self.servo5Range[1] + self.servo5Range[0])/2 - 90*self.servo5Param):
55+
logger.info('servo5(%s)超出范围(%s, %s)', servo5, self.servo5Range[0], self.servo5Range[1])
56+
return False
57+
58+
if theta6 < -(self.servo6Range[3] - self.servo6Range[2])/2:
59+
servo6 = int(round(((self.servo6Range[3] - self.servo6Range[2])/2 + (90 + (180 + theta6))) * self.servo6Param))
60+
else:
61+
servo6 = int(round(((self.servo6Range[3] - self.servo6Range[2])/2 - (90 - theta6)) * self.servo6Param)) + self.servo6Range[0]
62+
if servo6 > self.servo6Range[1] or servo6 < self.servo6Range[0]:
63+
logger.info('servo6(%s)超出范围(%s, %s)', servo6, self.servo6Range[0], self.servo6Range[1])
64+
return False
65+
return {"servo3": servo3, "servo4": servo4, "servo5": servo5, "servo6": servo6}
66+
67+
def servosMove(self, servos, movetime=None):
68+
#驱动3,4,5,6号舵机转动
69+
time.sleep(0.02)
70+
if movetime is None:
71+
max_d = 0
72+
for i in range(0, 4):
73+
d = abs(getPWMServoPulse(i + 3) - servos[i])
74+
if d > max_d:
75+
max_d = d
76+
movetime = int(max_d*1)
77+
setPWMServoPulse(3, servos[0], movetime)
78+
setPWMServoPulse(4, servos[1], movetime)
79+
setPWMServoPulse(5, servos[2], movetime)
80+
setPWMServoPulse(6, servos[3], movetime)
81+
82+
# setPWMServosPulse(movetime, 4, 3,servos[0], 4,servos[1], 5,servos[2], 6,servos[3])
83+
84+
return movetime
85+
86+
def setPitchRange(self, coordinate_data, alpha1, alpha2, da = 1):
87+
#给定坐标coordinate_data和俯仰角的范围alpha1,alpha2, 自动在范围内寻找到的合适的解
88+
#如果无解返回False,否则返回对应舵机角度,俯仰角
89+
#坐标单位cm, 以元组形式传入,例如(0, 5, 10)
90+
#da为俯仰角遍历时每次增加的角度
91+
x, y, z = coordinate_data
92+
if alpha1 >= alpha2:
93+
da = -da
94+
for alpha in np.arange(alpha1, alpha2, da):#遍历求解
95+
result = ik.getRotationAngle((x, y, z), alpha)
96+
if result:
97+
theta3, theta4, theta5, theta6 = result['theta3'], result['theta4'], result['theta5'], result['theta6']
98+
servos = self.transformAngelAdaptArm(theta3, theta4, theta5, theta6)
99+
if servos != False:
100+
return servos, alpha
101+
102+
return False
103+
104+
def setPitchRangeMoving(self, coordinate_data, alpha, alpha1, alpha2, movetime = None):
105+
#给定坐标coordinate_data和俯仰角alpha,以及俯仰角范围的范围alpha1, alpha2,自动寻找最接近给定俯仰角的解,并转到目标位置
106+
#如果无解返回False,否则返回舵机角度、俯仰角、运行时间
107+
#坐标单位cm, 以元组形式传入,例如(0, 5, 10)
108+
#alpha为给定俯仰角
109+
#alpha1和alpha2为俯仰角的取值范围
110+
#movetime为舵机转动时间,单位ms, 如果不给出时间,则自动计算
111+
x, y, z = coordinate_data
112+
result1 = self.setPitchRange((x, y, z), alpha, alpha1)
113+
result2 = self.setPitchRange((x, y, z), alpha, alpha2)
114+
if result1 != False:
115+
data = result1
116+
if result2 != False:
117+
if abs(result2[1] - alpha) < abs(result1[1] - alpha):
118+
data = result2
119+
else:
120+
if result2 != False:
121+
data = result2
122+
else:
123+
return False
124+
servos, alpha = data[0], data[1]
125+
movetime = self.servosMove((servos["servo3"], servos["servo4"], servos["servo5"], servos["servo6"]), movetime)
126+
return servos, alpha, movetime
127+
128+
if __name__ == "__main__":
129+
AK = ArmIK()
130+
#setPWMServoPulse(1, 1450, 1500)
131+
#AK.setPitchRangeMoving((-5,0,2), -90,-90, 90, 1200)
132+
# print(ik.getLinkLength())
133+
print(AK.setPitchRangeMoving((0,6,18),0,-90, 90))
134+
time.sleep(2)
135+
#print(AK.setPitchRangeMoving((-4.8, 15, 1.5), 0, -90, 0, 2000))
136+
#AK.drawMoveRange2D(-10, 10, 0.2, 10, 30, 0.2, 2.5, -90, 90, 1)

0 commit comments

Comments
 (0)