Notes

之前参加了 中国大学生工程实践与创新能力大赛 的 智能物流机器人的竞赛,因为我们刚开始做的是一个6自由度的机械臂。。调参调的简直要命。为了方便提高 测试机械臂关键帧舵机的参数,我写了个 基于串口的 机械臂实时控制软件。


0. 功能:

  1. 通过串口通信协议实时控制机械臂,并显示当前的舵机参数。
  2. 将当前的舵机参数保存到 机械臂关键帧-录取表.xlsx 表格里。
  3. 可以完整的测试 机械臂关键帧-确认表.xlsx 的所有动作帧。
  4. 可以单独测试 机械臂关键帧-确认表.xlsx 的单个动作帧。

1. 软件展示 及 相关源码地址:

Github源码地址:https://github.com/Panzer-Jack/SerialHelperfor_SIX-DOF_manipulator

2. 功能实现:

这边只展示 主函数(功能实现的代码),图形化代码可以到我的GitHub的仓库里查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
import sys
import time
from robArm import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import serial
import threading
import numpy as np
import xlwt
import xlrd

res1 = "34"
res2 = "104"
res3 = "106"
res4 = "166"
res5 = "100"
res6 = "157"
com = ""
msgGlobal = ""
msgGlobalOld = ""
gjzText = 0


class serial_frameGJZ(QThread):
def __init__(self, parent=None, ser=None):
super(serial_frameGJZ, self).__init__(parent)
self.ser = ser

def serial_C(self):
worksheet2 = xlrd.open_workbook("机械臂关键帧-确认表.xlsx")
sheet = worksheet2.sheet_by_index(0)
# self.ser = serial.Serial(com, 9600, timeout=0.5)

while 1:
i = int(gjzText)
print(i)
if i == -1:
break
self.ser.write(
f"{str(sheet.row_values(i)[0])} {str(sheet.row_values(i)[1])} {str(sheet.row_values(i)[2])} {str(sheet.row_values(i)[3])} {str(sheet.row_values(i)[4])} {str(sheet.row_values(i)[5])} 90".encode())
msg = self.ser.readlines()
# print()
if msg:
print(msg)
# break
time.sleep(2)
pass

def run(self):
self.serial_C()


class serial_frameTest(QThread):
def __init__(self, parent=None, ser=None):
super(serial_frameTest, self).__init__(parent)
self.ser = ser

def serial_C(self):
worksheet2 = xlrd.open_workbook("机械臂关键帧-确认表.xlsx")
sheet = worksheet2.sheet_by_index(0)
# self.ser = serial.Serial(com, 9600, timeout=0.5)

for i in range(0, sheet.nrows):
while 1:
self.ser.write(
f"{str(sheet.row_values(i)[0])} {str(sheet.row_values(i)[1])} {str(sheet.row_values(i)[2])} {str(sheet.row_values(i)[3])} {str(sheet.row_values(i)[4])} {str(sheet.row_values(i)[5])} 90".encode())
msg = self.ser.readlines()
if msg:
print(msg)
break
time.sleep(5)
print(sheet.row_values(i))
pass

def run(self):
self.serial_C()


class serial_control(QThread):
update_date = pyqtSignal(str)

def __init__(self, parent=None, ser=None):
super(serial_control, self).__init__(parent)
self.ser = ser

def serial_C(self, ser):
global res1, res2, res3, res4, res5, res6, msgGlobal, msgGlobalOld
while 1:
ser.write(
f"{res1} {res2} {res3} {res4} {res5} {res6} 90".encode())
msg = ser.readlines()
if msg:
msgGlobal = msg
print(msg)
if msgGlobal != msgGlobalOld:
msgGlobalOld = msgGlobal
self.update_date.emit('update')
break
time.sleep(0.1)

def run(self):
# ser = serial.Serial(com, 9600, timeout=0.5)
while 1:
self.serial_C(self.ser)


class mainWin(QMainWindow, Ui_ETC_UI_main):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowFlags(QtCore.Qt.WindowType.FramelessWindowHint)
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
self.setWindowIcon(QIcon('qtMain.ico'))

# 主程序按钮
self.button_close.clicked.connect(self.evt_close)
self.button_small.clicked.connect(self.evt_small)
self.button_testFrame.clicked.connect(self.run_frameTable)
self.button_run.clicked.connect(self.run)
self.recordButton.clicked.connect(self.recordFrame)
self.gjz_button.clicked.connect(self.gjz_step)
self.recordButton_2.clicked.connect(self.oc_serial)
self.flag = 0
self.row = 0
self.gjzText = 0
self.ser = None
self.workbook = xlwt.Workbook(encoding='utf-8')
self.worksheet = self.workbook.add_sheet("机械臂关键帧-sheet1")

self.slider.valueChanged.connect(self.valueChange)
self.slider_2.valueChanged.connect(self.valueChange)
self.slider_3.valueChanged.connect(self.valueChange)
self.slider_4.valueChanged.connect(self.valueChange)
self.slider_5.valueChanged.connect(self.valueChange)
self.slider_6.valueChanged.connect(self.valueChange)

self.textSlider.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res1}</span></p>')
self.textSlider_2.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res2}</span></p>')
self.textSlider_3.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res3}</span></p>')
self.textSlider_4.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res4}</span></p>')
self.textSlider_5.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res5}</span></p>')
self.textSlider_6.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res6}</span></p>')

# 窗口可拖动
self.mouse_x = self.mouse_y = self.origin_x = self.origin_y = None
QMessageBox.about(self, '天父的博爱',
'“凡事都不可亏欠人,惟有彼此相爱,当常以为亏欠,因为爱人的,就完全了律法。'
'像那不可奸淫,不可杀人,不可偷盗,不可贪婪,或有别的诫命,都包在爱人如己这一句话之内的。'
'爱是不加害于人的,所以爱就完全了律法。” \n ------------(《新约·罗马书》第十三章)\n'
'所以你们也要爱我,所以当出现新的bug时 先别急着找@我去debug。神是爱你们的,要先想想如何找到天父为你们放置的另一个接口,'
'神曰:当上帝关了这扇门,一定会为你打开另一扇门。\n ------------ 天父 · Panzer_Jack')

# # 1.鼠标点击事件
# def mousePressEvent(self, evt):
# # 获取鼠标当前的坐标
# self.mouse_x = evt.globalX()
# self.mouse_y = evt.globalY()
#
# # 获取窗体当前坐标
# self.origin_x = self.x()
# self.origin_y = self.y()
#
# # 2.鼠标移动事件
# def mouseMoveEvent(self, evt):
# # 计算鼠标移动的x,y位移
# move_x = evt.globalX() - self.mouse_x
# move_y = evt.globalY() - self.mouse_y
#
# # 计算窗体更新后的坐标:更新后的坐标 = 原本的坐标 + 鼠标的位移
# dest_x = self.origin_x + move_x
# dest_y = self.origin_y + move_y
#
# # 移动窗体
# self.move(dest_x, dest_y)

def oc_serial(self):
global com
com = self.lineEdit_7.text()
self.ser = serial.Serial(com, 9600, timeout=0.5)
self.serial_runFrameTest = serial_frameTest(ser=self.ser)
self.serial_runFrameGJZ = serial_frameGJZ(ser=self.ser)
self.serial_run = serial_control(ser=self.ser)
self.serial_run.update_date.connect(self.get_Info)

def gjz_step(self):
global gjzText, com
com = self.lineEdit_7.text()
gjzText = self.gjz_line.text()
print(gjzText)
if not self.flag:
self.flag = 1
self.serial_runFrameGJZ.start()

def get_Info(self):
msg = ""
for i in range(0, len(msgGlobal)):
msg += msgGlobal[i].decode()
self.showTable.append(f"{msg}")

def run_frameTable(self):
global com
com = self.lineEdit_7.text()
self.serial_runFrameTest.start()

def recordFrame(self):
self.worksheet.write(self.row, 0, str(res1))
self.worksheet.write(self.row, 1, str(res2))
self.worksheet.write(self.row, 2, str(res3))
self.worksheet.write(self.row, 3, str(res4))
self.worksheet.write(self.row, 4, str(res5))
self.worksheet.write(self.row, 5, str(res6))
self.worksheet.write(self.row, 6, "90")
self.row += 1

def valueChange(self):
global res1, res2, res3, res4, res5, res6
time.sleep(0.1)
res1 = self.slider.value()
res2 = self.slider_2.value()
res3 = self.slider_3.value()
res4 = self.slider_4.value()
res5 = self.slider_5.value()
res6 = self.slider_6.value()
# com = self.lineEdit_7.text()

# print("test:", res1, res2, res3, res4, res5, res6)
self.textSlider.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res1}</span></p>')
self.textSlider_2.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res2}</span></p>')
self.textSlider_3.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res3}</span></p>')
self.textSlider_4.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res4}</span></p>')
self.textSlider_5.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res5}</span></p>')
self.textSlider_6.setText(f'<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; '
'margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" '
f'font-size:18pt; font-weight:100; color:#00ff00;">{res6}</span></p>')

def run(self):
# global com
# com = self.lineEdit_7.text()
self.serial_run.start()

def go_CV_thread(self):
self.evt_run.start()

def evt_small(self):
self.showMinimized()

def evt_close(self):
self.workbook.save("机械臂关键帧-录取表.xlsx")
sys.exit(app.exec_())


if __name__ == '__main__':
app = QApplication(sys.argv)
main_win = mainWin()
main_win.show()
sys.exit(app.exec_())