底层控制接口基本完成,部分功能待力控层完成后测试

This commit is contained in:
ziwei.he 2025-04-28 18:11:35 +08:00
parent 1584f567ab
commit f56944f573
28 changed files with 49934 additions and 0 deletions

View File

@ -0,0 +1,96 @@
from dobot_api import DobotApiFeedBack,DobotApiDashboard
import threading
from time import sleep
import re
class DobotDemo:
def __init__(self, ip):
self.ip = ip
self.dashboardPort = 29999
self.feedPortFour = 30004
self.dashboard = None
self.feedInfo = []
self.__globalLockValue = threading.Lock()
class item:
def __init__(self):
self.robotMode = -1 #
self.robotCurrentCommandID = 0
self.MessageSize = -1
self.DigitalInputs =-1
self.DigitalOutputs = -1
# 自定义添加所需反馈数据
self.feedData = item() # 定义结构对象
def start(self):
# 启动机器人并使能
self.dashboard = DobotApiDashboard(self.ip, self.dashboardPort)
self.feedFour = DobotApiFeedBack(self.ip, self.feedPortFour)
if self.parseResultId(self.dashboard.EnableRobot())[0] != 0:
print("使能失败: 检查29999端口是否被占用")
return
print("使能成功")
# 启动状态反馈线程
feed_thread = threading.Thread(
target=self.GetFeed) # 机器状态反馈线程
feed_thread.daemon = True
feed_thread.start()
# 定义两个目标点
point_a = [146.3759,-283.4321,332.3956,177.7879,-1.8540,147.5821]
point_b = [146.3759,-283.4321,432.3956,177.7879,-1.8540,147.5821]
# 走点循环
while True:
print("DI:", self.feedData.DigitalInputs,"2DI:", bin(self.feedData.DigitalInputs),"--16:",hex(self.feedData.DigitalInputs))
print("DO:", self.feedData.DigitalOutputs,"2DO:" ,bin(self.feedData.DigitalOutputs),"--16:",hex(self.feedData.DigitalOutputs))
print("robomode",self.feedData.robotMode)
sleep(2)
def GetFeed(self):
# 获取机器人状态
while True:
feedInfo = self.feedFour.feedBackData()
with self.__globalLockValue:
if feedInfo is not None:
if hex((feedInfo['TestValue'][0])) == '0x123456789abcdef':
# 基础字段
self.feedData.MessageSize = feedInfo['len'][0]
self.feedData.robotMode = feedInfo['RobotMode'][0]
self.feedData.DigitalInputs = feedInfo['DigitalInputs'][0]
self.feedData.DigitalOutputs = feedInfo['DigitalOutputs'][0]
# 自定义添加所需反馈数据
'''
self.feedData.DigitalOutputs = int(feedInfo['DigitalOutputs'][0])
self.feedData.RobotMode = int(feedInfo['RobotMode'][0])
self.feedData.TimeStamp = int(feedInfo['TimeStamp'][0])
'''
def RunPoint(self, point_list):
# 走点指令
recvmovemess = self.dashboard.MovJ(*point_list, 0)
print("MovJ:", recvmovemess)
print(self.parseResultId(recvmovemess))
currentCommandID = self.parseResultId(recvmovemess)[1]
print("指令 ID:", currentCommandID)
#sleep(0.02)
while True: #完成判断循环
print(self.feedData.robotMode)
if self.feedData.robotMode == 5 and self.feedData.robotCurrentCommandID == currentCommandID:
print("运动结束")
break
sleep(0.1)
def parseResultId(self, valueRecv):
# 解析返回值,确保机器人在 TCP 控制模式
if "Not Tcp" in valueRecv:
print("Control Mode Is Not Tcp")
return [1]
return [int(num) for num in re.findall(r'-?\d+', valueRecv)] or [2]
def __del__(self):
del self.dashboard
del self.feedFour

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,346 @@
from dobot_api import DobotApiFeedBack,DobotApiDashboard
import threading
from time import sleep
import re
class dobot_nova5:
def __init__(self,ip):
self.ip = ip
self.dashboardPort = 29999 ## 一发一收-设置-控制及运动端口号
self.feedFourPort = 30004 ## 第四实时反馈(8ms)反馈数据端口号
self.dashboard = None ## 初始化控制及运动端口实例
self.feedFour = None ## 初始化数据反馈端口实例
self.feedInfo = []
self.__globalLockValue = threading.Lock() # 多线程安全
class feedbackItem:
def __init__(self):
self.robotMode = -1
self.robotCurrentCommandID = 0
self.MessageSize = -1
self.DigitalInputs = -1
self.DigitalOutputs = -1
# ... 自定义反馈数据
self.feedbackData = feedbackItem() # 自定义反馈数据结构体
def parseResultId(self,valueRecv):
# 解析返回值
if "Not Tcp" in valueRecv:
print("Control Mode is not TCP")
print("机械臂不在二次开发模式下")
return [1]
return [int(num) for num in re.findall(r'-?\d+',valueRecv)] or [2]
def GetFeedback(self):
while True:
feedInfo = self.feedFour.feedBackData()
with self.__globalLockValue:
if feedInfo is not None:
if hex((feedInfo['TestValue'][0]))=='0x123456789abcdef': ## DOBOT官方的数据魔数验证
# 基础字段
self.feedbackData.MessageSize = feedInfo['len'][0]
self.feedbackData.robotMode = feedInfo['RobotMode'][0]
self.feedbackData.DigitalInputs = feedInfo['DigitalInputs'][0]
self.feedbackData.DigitalOutputs = feedInfo['DigitalOutputs'][0]
self.feedbackData.robotCurrentCommandID = feedInfo['CurrentCommandId'][0]
# 自定义添加所需反馈数据
'''
self.feedData.DigitalOutputs = int(feedInfo['DigitalOutputs'][0])
self.feedData.RobotMode = int(feedInfo['RobotMode'][0])
self.feedData.TimeStamp = int(feedInfo['TimeStamp'][0])
'''
def start(self):
self.dashboard = DobotApiDashboard(self.ip,self.dashboardPort)
self.feedFour = DobotApiFeedBack(self.ip,self.feedFourPort)
if self.parseResultId(self.dashboard.EnableRobot())[0] != 0:
print("使能失败:检查29999端口是否被占用")
return
print("机械臂使能成功")
# 状态反馈线程
feedback_thread = threading.Thread(
target=self.GetFeedback # 机器状态反馈线程
)
feedback_thread.daemon = True
feedback_thread.start()
def RunPoint_P_inPose(self,poses_list):
'''
RUNPOINT_P 以关节运动方式运动到目标点
MovJ flag = 0 通过位姿走点输入为[X Y Z RX RY RZ] unit: mm/deg
'''
# 走点
recvmovemess = self.dashboard.MovJ(*poses_list,0)
print("MovJ:",recvmovemess)
print(self.parseResultId(recvmovemess))
currentCommandID = self.parseResultId(recvmovemess)[1]
print("指令 ID:", currentCommandID)
# sleep(0.02)
while True: # 完成判断循环
########## 调试注释 #############
# print("robot mode",self.feedbackData.robotMode)
# print("feedback current ID", self.feedbackData.robotCurrentCommandID)
# print("指令 ID:", currentCommandID)
########## 调试注释 #############
currentCommandID = self.parseResultId(self.dashboard.GetCurrentCommandID())[1]
if self.feedbackData.robotMode == 5 and self.feedbackData.robotCurrentCommandID == currentCommandID:
print("该次运动完成")
break
sleep(0.1)
def RunPoint_P_inJoint(self,joints_list):
'''
RUNPOINT_P 以关节运动方式运动到目标点
MovJ flag = 1 通过关节角度走点输入为[J1 J2 J3 J4 J5 J6] unit: deg
'''
# 走点
recvmovemess = self.dashboard.MovJ(*joints_list,1)
print("MovJ:",recvmovemess)
print(self.parseResultId(recvmovemess))
currentCommandID = self.parseResultId(recvmovemess)[1]
print("指令 ID:", currentCommandID)
# sleep(0.02)
while True: # 完成判断循环
########## 调试注释 #############
# print("robot mode",self.feedbackData.robotMode)
# print("feedback current ID", self.feedbackData.robotCurrentCommandID)
# print("指令 ID:", currentCommandID)
# print("30004",self.dashboard.GetCurrentCommandID())
########## 调试注释 #############
currentCommandID = self.parseResultId(self.dashboard.GetCurrentCommandID())[1]
if self.feedbackData.robotMode == 5 and self.feedbackData.robotCurrentCommandID == currentCommandID:
print("该次运动完成")
break
sleep(0.1)
def RunPoint_L_inPose(self,poses_list):
'''
RUNPOINT_L 以直线运动方式运动到目标点
MovJ flag = 0 通过位姿走点输入为[X Y Z RX RY RZ] unit: mm/deg
'''
# 走点
recvmovemess = self.dashboard.MovL(*poses_list,0)
print("MovL:",recvmovemess)
print(self.parseResultId(recvmovemess))
currentCommandID = self.parseResultId(recvmovemess)[1]
print("指令 ID:", currentCommandID)
while True:
currentCommandID = self.parseResultId(self.dashboard.GetCurrentCommandID())[1]
if self.feedbackData.robotMode == 5 and self.feedbackData.robotCurrentCommandID == currentCommandID:
print("该次运动完成")
break
sleep(0.1)
def RunPoint_L_inJoint(self,joints_list):
'''
RUNPOINT_L 以直线运动方式运动到目标点
MovJ flag = 0 通过位姿走点输入为[X Y Z RX RY RZ] unit: mm/deg
'''
# 走点
recvmovemess = self.dashboard.MovL(*joints_list,0)
print("MovL:",recvmovemess)
print(self.parseResultId(recvmovemess))
currentCommandID = self.parseResultId(recvmovemess)[1]
print("指令 ID:", currentCommandID)
while True:
currentCommandID = self.parseResultId(self.dashboard.GetCurrentCommandID())[1]
if self.feedbackData.robotMode == 5 and self.feedbackData.robotCurrentCommandID == currentCommandID:
print("该次运动完成")
break
sleep(0.1)
def ServoJoint(self,joints_list,t=-1,aheadtime=-1,gain=-1):
# 关节空间伺服
recvmovemess = self.dashboard.ServoJ(*joints_list,t,aheadtime,gain)
print("ServoJ:",recvmovemess)
print(self.parseResultId(recvmovemess))
currentCommandID = self.parseResultId(recvmovemess)[1]
print("指令 ID", currentCommandID)
while True:
currentCommandID = self.parseResultId(self.dashboard.GetCurrentCommandID())[1]
if self.feedbackData.robotMode == 5 and self.feedbackData.robotCurrentCommandID == currentCommandID:
print("完成一次伺服动作")
break
def ServoPose(self,poses_list,t=-1,aheadtime=-1,gain=-1):
# 位姿伺服
recvmovemess = self.dashboard.ServoP(*poses_list,t,aheadtime,gain)
print("ServoP:",recvmovemess)
print(self.parseResultId(recvmovemess))
currentCommandID = self.parseResultId(recvmovemess)[1]
print("指令 ID", currentCommandID)
while True:
currentCommandID = self.parseResultId(self.dashboard.GetCurrentCommandID())[1]
if self.feedbackData.robotMode == 5 and self.feedbackData.robotCurrentCommandID == currentCommandID:
print("完成一次伺服动作")
break
def setEndEffector(self,i,tool_i):
'''
设置工具坐标系在索引i. i!=0
tool_i 需要以字符串形式输入 "{x,y,z,rx,ry,rz}"
'''
if i == 0:
print("不可修改工具0(初始法兰坐标系)")
return
if i not in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}:
print("工具坐标系序号超出范围")
return
code = self.dashboard.SetTool(i,tool_i)
if code == 0:
print(f"设置工具坐标系{i}的偏移量成功")
else:
print(f"设置工具坐标系{i}失败")
return
def chooseEndEffector(self,i):
'''
切换工具坐标系, 0~9
'''
if i not in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}:
print("工具坐标系序号超出范围")
return
code = self.dashboard.Tool(i)
if code == 0:
print(f"切换为工具坐标系{i}成功")
else:
print("切换工具坐标系失败")
return
def setBaseFrame(self,i,base_i):
'''
设置工具坐标系在索引i. i!=0
base_i 修改后的用户坐标系(非偏移量!) 需要以字符串形式输入 "{x,y,z,rx,ry,rz}"
'''
if i == 0:
print("不可修改用户坐标系0(初始基坐标系)")
return
if i not in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}:
print("用户坐标系序号超出范围")
return
code = self.dashboard.SetUser(i,base_i)
if code == 0:
print(f"设置用户坐标系{i}成功")
else:
print(f"设置用户坐标系{i}失败")
return
def chooseBaseFrame(self,i):
'''
切换用户基坐标系, 0~9
'''
if i not in {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}:
print("工具坐标系序号超出范围")
return
code = self.dashboard.User(i)
if code == 0:
print(f"切换为用户基坐标系{i}成功")
else:
print("切换用户基坐标系失败")
return
def getPose(self,user=-1,tool=-1):
if (user == -1) != (tool == -1): ## XOR 必须同时设置或者同时不设置
print("必须同时设置或同时不设置坐标系参数")
res = self.dashboard.GetPose(user,tool) # 返回字符串
code = int(res[0]) # 拿到的是字符串
if code == 0:
pass
# print("success")
else:
print("获取位姿失败")
return
# 处理字符串
start = res.find("{")+1
end = res.find("}")
pose_str = res[start:end]
pose = [float(x.strip()) for x in pose_str.split(",")]
return pose
def getAngel(self):
res = self.dashboard.GetAngle()
code = int(res[0])
if code == 0:
pass
# print("success")
else:
print("获取关节角度失败")
return
# 处理字符串
start = res.find("{")+1
end = res.find("}")
angle_str = res[start:end]
angle = [float(x.strip()) for x in angle_str.split(",")]
return angle
def getForwardKin(self,joints_list,user=-1,tool=-1):
res = self.dashboard.PositiveKin(*joints_list,user,tool)
code = int(res[0])
if code == 0:
pass
# print("success")
else:
print("获取正向运动学解失败")
return
# 处理字符串
start = res.find("{")+1
end = res.find("}")
pose_str = res[start:end]
pose = [float(x.strip()) for x in pose_str.split(",")]
return pose
def getInverseKin(self,poses_list,user=-1,tool=-1,useJointNear=-1,JointNear=''):
'''
poses_list X Y Z RX RY RZ
useJointNear 0 或不携带 表示 JointNear无效
1 表示根据JointNear就近选解
jointNear string "{j1,j2,j3,j4,j5,j6}"
'''
res = self.dashboard.InverseKin(*poses_list,user,tool,useJointNear,JointNear)
code = int(res[0])
if code == 0:
pass
# print("success")
else:
print("获取逆向运动学解失败")
return
# 处理字符串
start = res.find("{")+1
end = res.find("}")
joint_str = res[start:end]
joint = [float(x.strip()) for x in joint_str.split(",")]
return joint
def disableRobot(self):
code = self.dashboard.DisableRobot()
if code == 0:
print("下使能机械臂成功")
else:
print("下使能机械臂失败")
return
def __del__(self):
del self.dashboard
del self.feedFour
if __name__ == "__main__":
dobot = dobot_nova5("192.168.5.1")
dobot.start()
posJ = [0,30,-120,0,90,0]
sleep(1)
dobot.RunPoint_P_inJoint(posJ)
############### 测试 #################
# curAngle = dobot.getAngel()
# curPose = dobot.getPose()
# res1 = dobot.getForwardKin(curAngle)
# res2 = dobot.getInverseKin(curPose)
# print(res1)
# print(res2)
# dobot.disableRobot()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
from DobotDemo import DobotDemo
if __name__ == '__main__':
dobot = DobotDemo("192.168.5.1")
dobot.start()

View File

@ -0,0 +1,6 @@
from ui import RobotUI
robot_ui = RobotUI()
robot_ui.pack()
robot_ui.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,494 @@
# -*- coding: utf-8 -*-
from threading import Thread
import time
from tkinter import *
from tkinter import ttk, messagebox
from tkinter.scrolledtext import ScrolledText
from dobot_api import *
import json
from files.alarmController import alarm_controller_list
from files.alarmServo import alarm_servo_list
LABEL_JOINT = [["J1-", "J2-", "J3-", "J4-", "J5-", "J6-"],
["J1:", "J2:", "J3:", "J4:", "J5:", "J6:"],
["J1+", "J2+", "J3+", "J4+", "J5+", "J6+"]]
LABEL_COORD = [["X-", "Y-", "Z-", "Rx-", "Ry-", "Rz-"],
["X:", "Y:", "Z:", "Rx:", "Ry:", "Rz:"],
["X+", "Y+", "Z+", "Rx+", "Ry+", "Rz+"]]
LABEL_ROBOT_MODE = {
1: "ROBOT_MODE_INIT",
2: "ROBOT_MODE_BRAKE_OPEN",
3: "",
4: "ROBOT_MODE_DISABLED",
5: "ROBOT_MODE_ENABLE",
6: "ROBOT_MODE_BACKDRIVE",
7: "ROBOT_MODE_RUNNING",
8: "ROBOT_MODE_RECORDING",
9: "ROBOT_MODE_ERROR",
10: "ROBOT_MODE_PAUSE",
11: "ROBOT_MODE_JOG"
}
class RobotUI(object):
def __init__(self):
self.root = Tk()
self.root.title("Python demo V4")
# fixed window size
self.root.geometry("900x850")
# set window icon
# self.root.iconbitmap("images/robot.ico")
# global state dict
self.global_state = {}
# all button
self.button_list = []
# all entry
self.entry_dict = {}
# Robot Connect
self.frame_robot = LabelFrame(self.root, text="Robot Connect",
labelanchor="nw", bg="#FFFFFF", width=870, height=120, border=2)
self.label_ip = Label(self.frame_robot, text="IP Address:")
self.label_ip.place(rely=0.2, x=10)
ip_port = StringVar(self.root, value="8.209.98.146")
self.entry_ip = Entry(self.frame_robot, width=12, textvariable=ip_port)
self.entry_ip.place(rely=0.2, x=90)
self.label_dash = Label(self.frame_robot, text="Dashboard Port:")
self.label_dash.place(rely=0.2, x=210)
dash_port = IntVar(self.root, value=29999)
self.entry_dash = Entry(
self.frame_robot, width=7, textvariable=dash_port)
self.entry_dash.place(rely=0.2, x=320)
self.label_feed = Label(self.frame_robot, text="Feedback Port:")
self.label_feed.place(rely=0.2, x=420)
feed_port = IntVar(self.root, value=30004)
self.entry_feed = Entry(
self.frame_robot, width=7, textvariable=feed_port)
self.entry_feed.place(rely=0.2, x=520)
# Connect/DisConnect
self.button_connect = self.set_button(master=self.frame_robot,
text="Connect", rely=0.6, x=630, command=self.connect_port)
self.button_connect["width"] = 10
self.global_state["connect"] = False
# Dashboard Function
self.frame_dashboard = LabelFrame(self.root, text="Dashboard Function",
labelanchor="nw", bg="#FFFFFF", pady=10, width=870, height=120, border=2)
# Enable/Disable
self.button_enable = self.set_button(master=self.frame_dashboard,
text="Enable", rely=0.1, x=10, command=self.enable)
self.button_enable["width"] = 7
self.global_state["enable"] = False
self.set_button(master=self.frame_dashboard,
text="ClearError", rely=0.1, x=200, command=self.clear_error)
# Speed Ratio
self.label_speed = Label(self.frame_dashboard, text="Speed Ratio:")
self.label_speed.place(rely=0.1, x=430)
s_value = StringVar(self.root, value="50")
self.entry_speed = Entry(self.frame_dashboard,
width=6, textvariable=s_value)
self.entry_speed.place(rely=0.1, x=520)
self.label_cent = Label(self.frame_dashboard, text="%")
self.label_cent.place(rely=0.1, x=550)
self.set_button(master=self.frame_dashboard,
text="Confirm", rely=0.1, x=586, command=self.confirm_speed)
# DO:Digital Outputs
self.label_digitial = Label(
self.frame_dashboard, text="Digital Outputs: Index:")
self.label_digitial.place(rely=0.55, x=10)
i_value = IntVar(self.root, value="1")
self.entry_index = Entry(
self.frame_dashboard, width=5, textvariable=i_value)
self.entry_index.place(rely=0.55, x=160)
self.label_status = Label(self.frame_dashboard, text="Status:")
self.label_status.place(rely=0.55, x=220)
self.combo_status = ttk.Combobox(self.frame_dashboard, width=5)
self.combo_status["value"] = ("On", "Off")
self.combo_status.current(0)
self.combo_status["state"] = "readonly"
self.combo_status.place(rely=0.55, x=275)
self.set_button(self.frame_dashboard, "Confirm",
rely=0.55, x=350, command=self.confirm_do)
# Move Function
self.frame_move = LabelFrame(self.root, text="Move Function", labelanchor="nw",
bg="#FFFFFF", width=870, pady=10, height=130, border=2)
self.set_move(text="X:", label_value=10,
default_value="600", entry_value=40, rely=0.1, master=self.frame_move)
self.set_move(text="Y:", label_value=110,
default_value="-260", entry_value=140, rely=0.1, master=self.frame_move)
self.set_move(text="Z:", label_value=210,
default_value="380", entry_value=240, rely=0.1, master=self.frame_move)
self.set_move(text="Rx:", label_value=310,
default_value="170", entry_value=340, rely=0.1, master=self.frame_move)
self.set_move(text="Ry:", label_value=410,
default_value="12", entry_value=440, rely=0.1, master=self.frame_move)
self.set_move(text="Rz:", label_value=510,
default_value="140", entry_value=540, rely=0.1, master=self.frame_move)
self.set_button(master=self.frame_move, text="MovJ",
rely=0.05, x=610, command=self.movj)
self.set_button(master=self.frame_move, text="MovL",
rely=0.05, x=700, command=self.movl)
self.set_move(text="J1:", label_value=10,
default_value="0", entry_value=40, rely=0.5, master=self.frame_move)
self.set_move(text="J2:", label_value=110,
default_value="-20", entry_value=140, rely=0.5, master=self.frame_move)
self.set_move(text="J3:", label_value=210,
default_value="-80", entry_value=240, rely=0.5, master=self.frame_move)
self.set_move(text="J4:", label_value=310,
default_value="30", entry_value=340, rely=0.5, master=self.frame_move)
self.set_move(text="J5:", label_value=410,
default_value="90", entry_value=440, rely=0.5, master=self.frame_move)
self.set_move(text="J6:", label_value=510,
default_value="120", entry_value=540, rely=0.5, master=self.frame_move)
self.set_button(master=self.frame_move,
text="MovJ", rely=0.45, x=610, command=self.joint_movj)
self.frame_feed_log = Frame(
self.root, bg="#FFFFFF", width=870, pady=10, height=400, border=2)
# Feedback
self.frame_feed = LabelFrame(self.frame_feed_log, text="Feedback", labelanchor="nw",
bg="#FFFFFF", width=550, height=150)
self.frame_feed.place(relx=0, rely=0, relheight=1)
# Current Speed Ratio
self.set_label(self.frame_feed,
text="Current Speed Ratio:", rely=0.05, x=10)
self.label_feed_speed = self.set_label(
self.frame_feed, "", rely=0.05, x=145)
self.set_label(self.frame_feed, text="%", rely=0.05, x=175)
# Robot Mode
self.set_label(self.frame_feed, text="Robot Mode:", rely=0.1, x=10)
self.label_robot_mode = self.set_label(
self.frame_feed, "", rely=0.1, x=95)
# 点动及获取坐标
self.label_feed_dict = {}
self.set_feed(LABEL_JOINT, 9, 52, 74, 117)
self.set_feed(LABEL_COORD, 165, 209, 231, 272)
# Digitial I/O
self.set_label(self.frame_feed, "Digital Inputs:", rely=0.8, x=11)
self.label_di_input = self.set_label(
self.frame_feed, "", rely=0.8, x=100)
self.set_label(self.frame_feed, "Digital Outputs:", rely=0.85, x=10)
self.label_di_output = self.set_label(
self.frame_feed, "", rely=0.85, x=100)
# Error Info
self.frame_err = LabelFrame(self.frame_feed, text="Error Info", labelanchor="nw",
bg="#FFFFFF", width=180, height=50)
self.frame_err.place(relx=0.65, rely=0, relheight=0.7)
self.text_err = ScrolledText(
self.frame_err, width=170, height=50, relief="flat")
self.text_err.place(rely=0, relx=0, relheight=0.7, relwidth=1)
self.set_button(self.frame_feed, "Clear", rely=0.71,
x=487, command=self.clear_error_info)
# Log
self.frame_log = LabelFrame(self.frame_feed_log, text="Log", labelanchor="nw",
bg="#FFFFFF", width=300, height=150)
self.frame_log.place(relx=0.65, rely=0, relheight=1)
self.text_log = ScrolledText(
self.frame_log, width=270, height=140, relief="flat")
self.text_log.place(rely=0, relx=0, relheight=1, relwidth=1)
# initial client
self.client_dash = None
self.client_feed = None
self.alarm_controller_dict = self.convert_dict(alarm_controller_list)
self.alarm_servo_dict = self.convert_dict(alarm_servo_list)
def convert_dict(self, alarm_list):
alarm_dict = {}
for i in alarm_list:
alarm_dict[i["id"]] = i
return alarm_dict
def read_file(self, path):
# 读json文件耗时大选择维护两个变量alarm_controller_list alarm_servo_list
# self.read_file("files/alarm_controller.json")
with open(path, "r", encoding="utf8") as fp:
json_data = json.load(fp)
return json_data
def mainloop(self):
self.root.mainloop()
def pack(self):
self.frame_robot.pack()
self.frame_dashboard.pack()
self.frame_move.pack()
self.frame_feed_log.pack()
def set_move(self, text, label_value, default_value, entry_value, rely, master):
self.label = Label(master, text=text)
self.label.place(rely=rely, x=label_value)
value = StringVar(self.root, value=default_value)
self.entry_temp = Entry(master, width=6, textvariable=value)
self.entry_temp.place(rely=rely, x=entry_value)
self.entry_dict[text] = self.entry_temp
def move_jog(self, text):
if self.global_state["connect"]:
if text[0] == "J":
self.client_dash.MoveJog(text)
else:
self.client_dash.MoveJog(text,coordtype=1,user=0,tool=0)
def move_stop(self, event):
if self.global_state["connect"]:
self.client_dash.MoveJog("")
def set_button(self, master, text, rely, x, **kargs):
self.button = Button(master, text=text, padx=5,
command=kargs["command"])
self.button.place(rely=rely, x=x)
if text != "Connect":
self.button["state"] = "disable"
self.button_list.append(self.button)
return self.button
def set_button_bind(self, master, text, rely, x, **kargs):
self.button = Button(master, text=text, padx=5)
self.button.bind("<ButtonPress-1>",
lambda event: self.move_jog(text=text))
self.button.bind("<ButtonRelease-1>", self.move_stop)
self.button.place(rely=rely, x=x)
if text != "Connect":
self.button["state"] = "disable"
self.button_list.append(self.button)
return self.button
def set_label(self, master, text, rely, x):
self.label = Label(master, text=text)
self.label.place(rely=rely, x=x)
return self.label
def connect_port(self):
if self.global_state["connect"]:
print("断开成功")
self.client_dash.close()
self.client_feed.close()
self.client_dash = None
self.client_feed = None
for i in self.button_list:
i["state"] = "disable"
self.button_connect["text"] = "Connect"
else:
try:
print("连接成功")
self.client_dash = DobotApiDashboard(
self.entry_ip.get(), int(self.entry_dash.get()), self.text_log)
self.client_feed = DobotApiFeedBack(
self.entry_ip.get(), int(self.entry_feed.get()), self.text_log)
except Exception as e:
messagebox.showerror("Attention!", f"Connection Error:{e}")
return
for i in self.button_list:
i["state"] = "normal"
self.button_connect["text"] = "Disconnect"
self.global_state["connect"] = not self.global_state["connect"]
self.set_feed_back()
def set_feed_back(self):
if self.global_state["connect"]:
thread = Thread(target=self.feed_back)
thread.setDaemon(True)
thread.start()
def enable(self):
if self.global_state["enable"]:
self.client_dash.DisableRobot()
self.button_enable["text"] = "Enable"
else:
self.client_dash.EnableRobot()
# if need time sleep
# time.sleep(0.5)
self.button_enable["text"] = "Disable"
self.global_state["enable"] = not self.global_state["enable"]
def clear_error(self):
self.client_dash.ClearError()
def confirm_speed(self):
self.client_dash.SpeedFactor(int(self.entry_speed.get()))
def movj(self):
self.client_dash.MovJ(float(self.entry_dict["X:"].get()), float(self.entry_dict["Y:"].get()), float(self.entry_dict["Z:"].get()),
float(self.entry_dict["Rx:"].get()), float(self.entry_dict["Ry:"].get()), float(self.entry_dict["Rz:"].get()),0)
def movl(self):
self.client_dash.MovL(float(self.entry_dict["X:"].get()), float(self.entry_dict["Y:"].get()), float(self.entry_dict["Z:"].get()),
float(self.entry_dict["Rx:"].get()), float(self.entry_dict["Ry:"].get()), float(self.entry_dict["Rz:"].get()),0)
def joint_movj(self):
self.client_dash.MovJ(float(self.entry_dict["J1:"].get()), float(self.entry_dict["J2:"].get()), float(self.entry_dict["J3:"].get()),
float(self.entry_dict["J4:"].get()), float(self.entry_dict["J5:"].get()), float(self.entry_dict["J6:"].get()),1)
def confirm_do(self):
if self.combo_status.get() == "On":
print("高电平")
self.client_dash.DO(int(self.entry_index.get()), 1)
else:
print("低电平")
self.client_dash.DO(int(self.entry_index.get()), 0)
def set_feed(self, text_list, x1, x2, x3, x4):
self.set_button_bind(
self.frame_feed, text_list[0][0], rely=0.2, x=x1, command=lambda: self.move_jog(text_list[0][0]))
self.set_button_bind(
self.frame_feed, text_list[0][1], rely=0.3, x=x1, command=lambda: self.move_jog(text_list[0][1]))
self.set_button_bind(
self.frame_feed, text_list[0][2], rely=0.4, x=x1, command=lambda: self.move_jog(text_list[0][2]))
self.set_button_bind(
self.frame_feed, text_list[0][3], rely=0.5, x=x1, command=lambda: self.move_jog(text_list[0][3]))
self.set_button_bind(
self.frame_feed, text_list[0][4], rely=0.6, x=x1, command=lambda: self.move_jog(text_list[0][4]))
self.set_button_bind(
self.frame_feed, text_list[0][5], rely=0.7, x=x1, command=lambda: self.move_jog(text_list[0][5]))
self.set_label(self.frame_feed, text_list[1][0], rely=0.21, x=x2)
self.set_label(self.frame_feed, text_list[1][1], rely=0.31, x=x2)
self.set_label(self.frame_feed, text_list[1][2], rely=0.41, x=x2)
self.set_label(self.frame_feed, text_list[1][3], rely=0.51, x=x2)
self.set_label(self.frame_feed, text_list[1][4], rely=0.61, x=x2)
self.set_label(self.frame_feed, text_list[1][5], rely=0.71, x=x2)
self.label_feed_dict[text_list[1][0]] = self.set_label(
self.frame_feed, " ", rely=0.21, x=x3)
self.label_feed_dict[text_list[1][1]] = self.set_label(
self.frame_feed, " ", rely=0.31, x=x3)
self.label_feed_dict[text_list[1][2]] = self.set_label(
self.frame_feed, " ", rely=0.41, x=x3)
self.label_feed_dict[text_list[1][3]] = self.set_label(
self.frame_feed, " ", rely=0.51, x=x3)
self.label_feed_dict[text_list[1][4]] = self.set_label(
self.frame_feed, " ", rely=0.61, x=x3)
self.label_feed_dict[text_list[1][5]] = self.set_label(
self.frame_feed, " ", rely=0.71, x=x3)
self.set_button_bind(
self.frame_feed, text_list[2][0], rely=0.2, x=x4, command=lambda: self.move_jog(text_list[2][0]))
self.set_button_bind(
self.frame_feed, text_list[2][1], rely=0.3, x=x4, command=lambda: self.move_jog(text_list[2][0]))
self.set_button_bind(
self.frame_feed, text_list[2][2], rely=0.4, x=x4, command=lambda: self.move_jog(text_list[2][0]))
self.set_button_bind(
self.frame_feed, text_list[2][3], rely=0.5, x=x4, command=lambda: self.move_jog(text_list[2][0]))
self.set_button_bind(
self.frame_feed, text_list[2][4], rely=0.6, x=x4, command=lambda: self.move_jog(text_list[2][0]))
self.set_button_bind(
self.frame_feed, text_list[2][5], rely=0.7, x=x4, command=lambda: self.move_jog(text_list[2][0]))
def feed_back(self):
while True:
print("self.global_state(connect)", self.global_state["connect"])
if not self.global_state["connect"]:
break
self.client_feed.socket_dobot.setblocking(True) # 设置为阻塞模式
data = bytes()
temp = self.client_feed.socket_dobot.recv(144000)
if len(temp) > 1440:
temp = self.client_feed.socket_dobot.recv(144000)
data = temp[0:1440]
a = np.frombuffer(data, dtype=MyType)
print("robot_mode:", a["RobotMode"][0])
print("TestValue:", hex((a['TestValue'][0])))
if hex((a['TestValue'][0])) == '0x123456789abcdef':
# print('tool_vector_actual',
# np.around(a['tool_vector_actual'], decimals=4))
# print('QActual', np.around(a['q_aQActualctual'], decimals=4))
# Refresh Properties
self.label_feed_speed["text"] = a["SpeedScaling"][0]
self.label_robot_mode["text"] = LABEL_ROBOT_MODE[a["RobotMode"][0]]
self.label_di_input["text"] = bin(a["DigitalInputs"][0])[
2:].rjust(64, '0')
self.label_di_output["text"] = bin(a["DigitalOutputs"][0])[
2:].rjust(64, '0')
# Refresh coordinate points
self.set_feed_joint(LABEL_JOINT, a["QActual"])
self.set_feed_joint(LABEL_COORD, a["ToolVectorActual"])
# check alarms
if a["RobotMode"] == 9:
self.display_error_info()
def display_error_info(self):
error_list = self.client_dash.GetErrorID().split("{")[1].split("}")[0]
error_list = json.loads(error_list)
print("error_list:", error_list)
if error_list[0]:
for i in error_list[0]:
self.form_error(i, self.alarm_controller_dict,
"Controller Error")
for m in range(1, len(error_list)):
if error_list[m]:
for n in range(len(error_list[m])):
self.form_error(n, self.alarm_servo_dict, "Servo Error")
def form_error(self, index, alarm_dict: dict, type_text):
if index in alarm_dict.keys():
date = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
error_info = f"Time Stamp:{date}\n"
error_info = error_info + f"ID:{index}\n"
error_info = error_info + \
f"Type:{type_text}\nLevel:{alarm_dict[index]['level']}\n" + \
f"Solution:{alarm_dict[index]['en']['solution']}\n"
self.text_err.insert(END, error_info)
def clear_error_info(self):
self.text_err.delete("1.0", "end")
def set_feed_joint(self, label, value):
array_value = np.around(value, decimals=4)
self.label_feed_dict[label[1][0]]["text"] = array_value[0][0]
self.label_feed_dict[label[1][1]]["text"] = array_value[0][1]
self.label_feed_dict[label[1][2]]["text"] = array_value[0][2]
self.label_feed_dict[label[1][3]]["text"] = array_value[0][3]
self.label_feed_dict[label[1][4]]["text"] = array_value[0][4]
self.label_feed_dict[label[1][5]]["text"] = array_value[0][5]