Compare commits

..

7 Commits

7 changed files with 597 additions and 39 deletions

View File

@ -234,6 +234,126 @@
"name": "r_safe_region03", "name": "r_safe_region03",
"retain": false, "retain": false,
"type": "bool" "type": "bool"
},
{
"addr": 40100,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_0",
"retain": false,
"type": "bool"
},
{
"addr": 40101,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_1",
"retain": false,
"type": "bool"
},
{
"addr": 40102,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_2",
"retain": false,
"type": "bool"
},
{
"addr": 40103,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_3",
"retain": false,
"type": "bool"
},
{
"addr": 40104,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_4",
"retain": false,
"type": "bool"
},
{
"addr": 40105,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_5",
"retain": false,
"type": "bool"
},
{
"addr": 40106,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_6",
"retain": false,
"type": "bool"
},
{
"addr": 40107,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_7",
"retain": false,
"type": "bool"
},
{
"addr": 40108,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_8",
"retain": false,
"type": "bool"
},
{
"addr": 40109,
"addr_1st": 0,
"addr_2nd": 0,
"bit_bias": 0,
"byte_bias": 0,
"function": "",
"len": 1,
"name": "signal_9",
"retain": false,
"type": "bool"
} }
], ],
"rdwr": [ "rdwr": [

View File

@ -361,6 +361,196 @@
<c name="value"/> <c name="value"/>
<c name="value_single" type="10" value=""/> <c name="value_single" type="10" value=""/>
</l> </l>
<l>
<c name="addr" type="2" value="40100"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40100"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_0"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40101"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40101"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_1"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40102"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40102"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_2"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40103"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40103"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_3"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40104"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40104"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_4"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40105"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40105"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_5"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40106"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40106"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_6"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40107"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40107"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_7"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40108"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40108"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_8"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l>
<c name="addr" type="2" value="40109"/>
<c name="addr_1st" type="2" value="0"/>
<c name="addr_2nd" type="2" value="0"/>
<c name="bit_bias" type="2" value="0"/>
<c name="byte_bias" type="4" value="0"/>
<c name="description" type="10" value=""/>
<c name="dev_name" type="10" value="autotest"/>
<c name="dev_type" type="10" value="MODBUS"/>
<c name="end_addr" type="2" value="40109"/>
<c name="function" type="10" value=""/>
<c name="len" type="2" value="1"/>
<c name="name" type="10" value="signal_9"/>
<c name="retain" type="1" value="false"/>
<c name="rw" type="10" value="rd"/>
<c name="type" type="10" value="bool"/>
<c name="value"/>
<c name="value_single" type="10" value=""/>
</l>
<l> <l>
<c name="addr" type="2" value="40500"/> <c name="addr" type="2" value="40500"/>
<c name="addr_1st" type="2" value="0"/> <c name="addr_1st" type="2" value="0"/>

View File

@ -0,0 +1,3 @@
loguru==0.7.2
paramiko==3.5.0
pymodbus==3.7.2

View File

@ -16,6 +16,7 @@ password = "luoshi2019" # for real robot
xService_port = 6666 xService_port = 6666
external_port = 8080 external_port = 8080
modbus_port = 502 modbus_port = 502
upgrade_port = 4567
interval = 0.5 # interval after actions being triggered, such as modbus/socket/external communication operations interval = 0.5 # interval after actions being triggered, such as modbus/socket/external communication operations
heartbeat_interval = 2 heartbeat_interval = 2
RADIAN = 57.3 # 180 / 3.1415926 RADIAN = 57.3 # 180 / 3.1415926

View File

@ -1,7 +1,13 @@
import os.path
import socket
import time import time
import openapi import openapi
import json import json
import clibs import clibs
from socket import *
from ctypes import *
import hashlib
import struct
def initialization(): def initialization():
@ -28,7 +34,7 @@ def initialization():
pd.push_file_to_server(config_file, f"{user_settings}/{filename}") pd.push_file_to_server(config_file, f"{user_settings}/{filename}")
pd.push_file_to_server(config_file, f"{interactive_data}/{filename}") pd.push_file_to_server(config_file, f"{interactive_data}/{filename}")
io_device_autotest = {'ai_num': 0, 'ao_num': 0, 'di_num': 16, 'do_num': 16, 'extend_attr': {'mode': 'slaver', 'name': 'autotest', 'type': 'MODBUS'}, 'id': 7, 'name': 'autotest', 'type': 6} io_device_autotest = {"ai_num": 0, "ao_num": 0, "di_num": 16, "do_num": 16, "extend_attr": {"mode": "slaver", "name": "autotest", "type": "MODBUS"}, "id": 7, "name": "autotest", "type": 6}
io_device_file_local = f"..\\assets\\configs\\{io_device_file}" io_device_file_local = f"..\\assets\\configs\\{io_device_file}"
io_device_file_local_tmp = f"..\\assets\\configs\\{io_device_file}_tmp" io_device_file_local_tmp = f"..\\assets\\configs\\{io_device_file}_tmp"
io_device_file_remote = f"{user_settings}/{io_device_file}" io_device_file_remote = f"{user_settings}/{io_device_file}"
@ -66,6 +72,10 @@ def initialization():
# 关闭缩减模式 # 关闭缩减模式
md.r_reduced_mode(0) md.r_reduced_mode(0)
# 打开软限位
clibs.logger.info("打开软限位开关...")
hr.set_soft_limit_params(enable=True)
# 关闭安全区域 # 关闭安全区域
clibs.logger.info("正在关闭所有的安全区,并关闭总使能开关...") clibs.logger.info("正在关闭所有的安全区,并关闭总使能开关...")
hr.set_safety_area_overall(False) hr.set_safety_area_overall(False)
@ -73,13 +83,16 @@ def initialization():
for i in range(10): for i in range(10):
hr.set_safety_area_enable(i, False) hr.set_safety_area_enable(i, False)
# 打开外部通信 # 打开外部通信,并设置控制器时间同步
clibs.logger.info("配置并打开外部通信默认服务器8080端口后缀为 \"\\r\"...") clibs.logger.info("配置并打开外部通信默认服务器8080端口后缀为 \"\\r\"...")
hr.set_socket_params(True, "8080", "\r", 1) hr.set_socket_params(True, "8080", "\r", 1)
ec = openapi.ExternalCommunication()
ec.modify_system_time(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))
# 关闭拖动 # 关闭拖动
clibs.logger.info("关闭拖动模式...") if robot_type.upper()[:2] not in ["XB", "NB"]:
hr.set_drag_params(False, 1, 2) clibs.logger.info("关闭拖动模式...")
hr.set_drag_params(False, 1, 2)
# 关闭碰撞检测 # 关闭碰撞检测
clibs.logger.info("关闭碰撞检测...") clibs.logger.info("关闭碰撞检测...")
@ -108,4 +121,190 @@ def initialization():
md.r_clear_alarm() md.r_clear_alarm()
initialization() def fw_updater(local_file_path):
fw_size = os.path.getsize(local_file_path)
if fw_size > 10000000:
# get previous version of xCore
hr = openapi.HmiRequest()
version_previous = hr.get_robot_params["version"]
hr.close()
# var def
remote_file_path = './upgrade/lircos.zip'
fw_content = bytearray()
package_data = bytearray()
package_data_with_head = bytearray()
# socket connect
clibs.logger.info(f"正在连接 {clibs.ip_addr}:{clibs.upgrade_port}...")
try:
tcp_socket = socket(AF_INET, SOCK_STREAM)
tcp_socket.connect((clibs.ip_addr, clibs.upgrade_port))
tcp_socket.setblocking(True)
except Exception as Err:
clibs.logger.error(f"{Err} | 连接 {clibs.ip_addr}:{clibs.upgrade_port} 失败...")
exit(1)
# get firmware content of binary format
clibs.logger.info(f"正在读取 {local_file_path} 文件内容...")
with open(local_file_path, 'rb') as f_fw:
fw_content += f_fw.read()
# construct package data: http://confluence.i.rokae.com/pages/viewpage.action?pageId=15634148
clibs.logger.info("正在构造数据包,以及包头...")
# 1 protocol id
protocol_id = c_ushort(htons(0)) # 2 bytes
package_data += protocol_id
# 2 write type
write_type = c_ubyte(0)
package_data += bytes(write_type)
# 3 md5
md5_hash = hashlib.md5()
md5_hash.update(fw_content)
fw_md5 = md5_hash.hexdigest()
i = 0
while i < len(fw_md5):
_ = (fw_md5[i:i + 2])
package_data += bytes.fromhex(_)
i += 2
# 4 remote path len
remote_file_path_len = c_ushort(htons(len(remote_file_path)))
package_data += remote_file_path_len
# 5 remote path
package_data += remote_file_path.encode("ascii")
# 6 file
package_data += fw_content
# construct communication protocol: http://confluence.i.rokae.com/pages/viewpage.action?pageId=15634045
# 1 get package data with header
package_size = c_uint(htonl(len(package_data)))
package_type = c_ubyte(1) # 0-无协议 1-文件 2-json
package_reserve = c_ubyte(0) # 预留位
package_data_with_head += package_size
package_data_with_head += package_type
package_data_with_head += package_reserve
package_data_with_head += package_data
# 2 send data to server
clibs.logger.info("正在发送数据到 xCore升级控制器无需重启升级配置文件会自动软重启...")
start = 0
len_of_package = len(package_data_with_head)
while start < len_of_package:
end = 10240 + start
if end > len_of_package:
end = len_of_package
sent = tcp_socket.send((package_data_with_head[start:end]))
time.sleep(0.01)
if sent == 0:
raise RuntimeError("socket connection broken")
else:
start += sent
waited = 5 if fw_size > 10000000 else 25
time.sleep(waited)
if fw_size > 10000000:
# get current version of xCore
hr = openapi.HmiRequest()
version_current = hr.get_robot_params["version"]
hr.close()
clibs.logger.info(f"控制器升级成功from {version_previous} to {version_current} :)")
else:
clibs.logger.info(f"配置文件升级成功 :)")
tcp_socket.close()
class UpgradeJsonCmd(object):
def __init__(self):
self.__c = None
self.__sock_conn()
def __sock_conn(self):
# socket connect
clibs.logger.info(f"正在连接 {clibs.ip_addr}:{clibs.upgrade_port}...")
try:
self.__c = socket(AF_INET, SOCK_STREAM)
self.__c.connect((clibs.ip_addr, clibs.upgrade_port))
self.__c.setblocking(True)
self.__c.settimeout(3)
except Exception as Err:
clibs.logger.error(f"{Err} | 连接 {clibs.ip_addr}:{clibs.upgrade_port} 失败...")
exit(1)
@staticmethod
def __do_package(cmd):
package_size = struct.pack('!I', len(cmd))
package_type = struct.pack('B', 2)
reserved_byte = struct.pack('B', 0)
return package_size + package_type + reserved_byte + cmd
def __recv_result(self, cmd):
time.sleep(2)
try:
res = self.__c.recv(10240).decode()
except timeout:
res = "ResponseNone"
clibs.logger.info(f"请求命令 {cmd.decode()} 的返回信息:\n{res[8:]}")
self.__c.close()
time.sleep(2)
def __exec(self, command: dict):
try:
self.__c.recv(10240)
except timeout:
pass
cmd = json.dumps(command, separators=(",", ":")).encode("utf-8")
self.__c.sendall(self.__do_package(cmd))
self.__recv_result(cmd)
def erase_cfg(self):
# 一键抹除机器人配置(.rc_cfg)、交互数据配置(interactive_data),但保留用户日志
# 场景如果xCore版本升级跨度过大配置文件可能不兼容导致无法启动可以使用该功能抹除配置重新生成配置。
# 机器人参数、零点等会丢失!
self.__exec({"cmd": "erase"})
def clear_rubbish(self):
self.__exec({"cmd": "clearRubbish"})
def soft_reboot(self):
self.__exec({"cmd": "soft_reboot"})
def version_query(self):
self.__exec({"query": "version"})
def robot_reboot(self):
self.__exec({"cmd": "reboot"})
def reset_passwd(self):
# 不生效,有问题
self.__exec({"cmd": "passwd"})
def backup_origin(self):
# xCore
# .rc_cfg /
# interactive_data /
# module /
# demo_project /
# robot_cfg /
# dev_eni.xml
# ecat_license
# libemllI8254x.so & libemllI8254x_v3.so
# set_network_parameters
self.__exec({"cmd": "backup_origin"})
def origin_recovery(self):
self.__exec({"cmd": "recover"})
if __name__ == "__main__":
# initialization()
# fw_updater()
pass

View File

@ -8,6 +8,8 @@ from time import time, sleep, strftime, localtime
from pymodbus.client.tcp import ModbusTcpClient from pymodbus.client.tcp import ModbusTcpClient
# from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder # from pymodbus.payload import BinaryPayloadDecoder, BinaryPayloadBuilder
# from pymodbus.constants import Endian # from pymodbus.constants import Endian
from functools import wraps
from inspect import getcallargs
from paramiko import SSHClient, AutoAddPolicy from paramiko import SSHClient, AutoAddPolicy
import clibs import clibs
@ -137,6 +139,13 @@ class ModbusRequest(object):
clibs.logger.info(f"40018-{action} 执行{actions}安全区 safe region 03") clibs.logger.info(f"40018-{action} 执行{actions}安全区 safe region 03")
sleep(clibs.interval) sleep(clibs.interval)
def r_write_signals(self, addr: int, value): # OK | 40100 - 40109: signal_0 ~ signal_9
if -1 < addr < 10 and addr.is_integer():
self.__c.write_register(40100+addr, value)
clibs.logger.info(f"{40100+addr}-{value} 将寄存器 signal_{addr} 赋值为 {value}")
else:
clibs.logger.error(f"{40100+addr}-{value} 地址错误,无法赋值!")
@property @property
def w_alarm_state(self): # OK def w_alarm_state(self): # OK
res = self.__c.read_holding_registers(40500, 1).registers[0] res = self.__c.read_holding_registers(40500, 1).registers[0]
@ -338,7 +347,8 @@ class HmiRequest(object):
# 尝试连续三次发送心跳包,确认建联成功 # 尝试连续三次发送心跳包,确认建联成功
self.__error_code = 0 self.__error_code = 0
for i in range(3): for i in range(3):
self.execution("controller.heart") self.execution.__wrapped__(self, "controller.heart")
# self.execution("controller.heart")
sleep(clibs.interval/5) sleep(clibs.interval/5)
if not self.__error_code: if not self.__error_code:
self.__is_connected = True self.__is_connected = True
@ -412,12 +422,15 @@ class HmiRequest(object):
for _ in range(3): for _ in range(3):
res = find_response(clibs.log_data_debug) res = find_response(clibs.log_data_debug)
if res is not None: if res is not None:
return res["data"] return res.get("data", f"{msg_id} has no data item")
sleep(clibs.interval*2) sleep(clibs.interval*2)
else: # 尝试在上一次分割的日志中查找,只做一次 else: # 尝试在上一次分割的日志中查找,只做一次
res = find_response("".join([clibs.log_path, listdir(clibs.log_path)[0]])) try:
res = find_response("".join([clibs.log_path, sorted(listdir(clibs.log_path))[-3]]))
except IndexError:
res = None
if res is not None: if res is not None:
return res["data"] return res.get("data", f"{msg_id} has no data item")
elif flag == 1: elif flag == 1:
for _ in range(3): for _ in range(3):
res = find_response_xs(clibs.log_data_debug) res = find_response_xs(clibs.log_data_debug)
@ -425,14 +438,18 @@ class HmiRequest(object):
return res return res
sleep(clibs.interval*2) sleep(clibs.interval*2)
else: else:
res = find_response_xs("".join([clibs.log_path, listdir(clibs.log_path)[0]])) try:
res = find_response_xs("".join([clibs.log_path, sorted(listdir(clibs.log_path))[-3]]))
except IndexError:
res = None
if res is not None: if res is not None:
return res return res
self.__sth_wrong(11, f"无法找到请求 {msg_id} 的返回结果") self.__sth_wrong(11, f"无法找到请求 {msg_id} 的返回结果")
def __msg_storage(self, response, flag=0): def __msg_storage(self, response, flag=0):
# response是解码后的字符串 # response是解码后的字符串
clibs.logger.debug(f"{loads(response)}") if "move.monitor" not in response:
clibs.logger.debug(f"{loads(response)}")
messages = self.c_msg if flag == 0 else self.c_msg_xs messages = self.c_msg if flag == 0 else self.c_msg_xs
if "move.monitor" in response: if "move.monitor" in response:
pass pass
@ -596,7 +613,7 @@ class HmiRequest(object):
@staticmethod @staticmethod
def __package_xs(cmd): def __package_xs(cmd):
return f"{dumps(cmd, separators=(",", ":"))}\r".encode() return "".join([dumps(cmd, separators=(",", ":")), "\r"]).encode()
def __unpackage(self, sock): def __unpackage(self, sock):
def to_read(conn, mask): def to_read(conn, mask):
@ -644,6 +661,17 @@ class HmiRequest(object):
except Exception as Err: except Exception as Err:
self.__sth_wrong(8, f"错误信息:{Err}") self.__sth_wrong(8, f"错误信息:{Err}")
@staticmethod
def validate_req(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
all_args = getcallargs(func, self, *args, **kwargs)
_id = func(self, *args, **kwargs)
self.get_from_id(_id, flag=all_args["protocol_flag"])
return _id
return wrapper
@validate_req
def execution(self, command, protocol_flag=0, **kwargs): def execution(self, command, protocol_flag=0, **kwargs):
def log_reqs(request): def log_reqs(request):
with open(clibs.log_data_reqs, mode="a", encoding="utf-8") as f_log: with open(clibs.log_data_reqs, mode="a", encoding="utf-8") as f_log:
@ -1052,7 +1080,7 @@ class HmiRequest(object):
def set_diagnosis_params(self, display_pdo_params: list, frequency: int = 50, version: str = "1.4.1"): # OK def set_diagnosis_params(self, display_pdo_params: list, frequency: int = 50, version: str = "1.4.1"): # OK
""" """
设置诊断功能显示参数 设置诊断功能显示参数 [{"name": "hw_joint_vel_feedback", "channel": 0}, ]
:param display_pdo_params: 指定要采集的曲线名称,具体可通过 get_diagnosis_params 函数功能获取所有目前已支持的曲线 :param display_pdo_params: 指定要采集的曲线名称,具体可通过 get_diagnosis_params 函数功能获取所有目前已支持的曲线
:param frequency: 采样频率,默认 50ms :param frequency: 采样频率,默认 50ms
:param version: xDiagnose的版本号 :param version: xDiagnose的版本号
@ -1742,7 +1770,7 @@ class HmiRequest(object):
:return: None :return: None
""" """
origin_code_list = self.get_filtered_error_code["g"]["log_code.data"]["code_list"] origin_code_list = self.get_filtered_error_code["g"]["log_code.data"]["code_list"]
# [{'id': 10000, 'title': 'HMI请求包解析错误'}, {'id': 10002, 'title': '快速调整启动失败'}] # [{"id": 10000, "title": "HMI请求包解析错误"}, {"id": 10002, "title": "快速调整启动失败"}]
if action == "clear": if action == "clear":
code_list = [] code_list = []
elif action == "add": elif action == "add":
@ -1799,10 +1827,14 @@ class ExternalCommunication(object):
self.__c.send(order.encode()) self.__c.send(order.encode())
sleep(clibs.interval) sleep(clibs.interval)
def r_string(self): def r_string(self, directive):
result, char = "", "" result, char = "", ""
while char != self.suffix: while char != self.suffix:
char = self.__c.recv(1).decode(encoding="unicode_escape") try:
char = self.__c.recv(1).decode(encoding="unicode_escape")
except TimeoutError:
clibs.logger.error(f"获取请求指令 {directive} 的返回数据超时,需确认指令发送格式以及内容正确!")
exit(101)
result = "".join([result, char]) result = "".join([result, char])
sleep(clibs.interval) sleep(clibs.interval)
return result return result
@ -1847,10 +1879,10 @@ class ExternalCommunication(object):
def load_program(self, program_name): # OK def load_program(self, program_name): # OK
return self.__exec_cmd(f"load_prog:{program_name}", "加载工程", self.exec_desc) return self.__exec_cmd(f"load_prog:{program_name}", "加载工程", self.exec_desc)
def estop_reset(self): def estop_reset(self): # OK | 复原外部 IO 急停和安全门急停,前提是硬件已复原
return self.__exec_cmd("estop_reset", "急停复位", self.exec_desc) return self.__exec_cmd("estop_reset", "急停复位", self.exec_desc)
def estopreset_and_clearalarm(self): def estopreset_and_clearalarm(self): # OK | 外部 IO/安全门急停/安全碰撞告警都可以清除,前提是硬件已复原
return self.__exec_cmd("estopreset_and_clearalarm", "急停复位并清除报警", self.exec_desc) return self.__exec_cmd("estopreset_and_clearalarm", "急停复位并清除报警", self.exec_desc)
def motoron_pp2main_start(self): # OK def motoron_pp2main_start(self): # OK
@ -1862,7 +1894,7 @@ class ExternalCommunication(object):
def pause_motoroff(self): # OK def pause_motoroff(self): # OK
return self.__exec_cmd("pause_motoroff", "暂停程序并下电", self.exec_desc) return self.__exec_cmd("pause_motoroff", "暂停程序并下电", self.exec_desc)
def set_program_speed(self, speed: int): # OK def set_program_speed(self, speed: int): # OK | 1-100
return self.__exec_cmd(f"set_program_speed:{speed}", "设置程序运行速率(滑块)", self.exec_desc) return self.__exec_cmd(f"set_program_speed:{speed}", "设置程序运行速率(滑块)", self.exec_desc)
def set_soft_estop(self, enable: str): # OK def set_soft_estop(self, enable: str): # OK
@ -1871,10 +1903,10 @@ class ExternalCommunication(object):
def switch_auto_motoron(self): # OK def switch_auto_motoron(self): # OK
return self.__exec_cmd("switch_auto_motoron", "切换自动模式并上电", self.exec_desc) return self.__exec_cmd("switch_auto_motoron", "切换自动模式并上电", self.exec_desc)
def open_safe_region(self, number: int): # OK def open_safe_region(self, number: int): # OK | 1-10
return self.__exec_cmd(f"open_safe_region:{number}", f"打开第 {number} 个安全区域(1-10信号控制开关需打开不限操作模式)", self.exec_desc) return self.__exec_cmd(f"open_safe_region:{number}", f"打开第 {number} 个安全区域(1-10信号控制开关需打开不限操作模式)", self.exec_desc)
def close_safe_region(self, number: int): # OK def close_safe_region(self, number: int): # OK | 1-10
return self.__exec_cmd(f"close_safe_region:{number}", f"关闭第 {number} 个安全区域(1-10信号控制开关需打开不限操作模式)", self.exec_desc) return self.__exec_cmd(f"close_safe_region:{number}", f"关闭第 {number} 个安全区域(1-10信号控制开关需打开不限操作模式)", self.exec_desc)
def open_reduced_mode(self): # OK def open_reduced_mode(self): # OK
@ -1883,11 +1915,11 @@ class ExternalCommunication(object):
def close_reduced_mode(self): # OK def close_reduced_mode(self): # OK
return self.__exec_cmd("close_reduced_mode", "关闭缩减模式(不限操作模式)", self.exec_desc) return self.__exec_cmd("close_reduced_mode", "关闭缩减模式(不限操作模式)", self.exec_desc)
def setdo_value(self, do_name, do_value): def setdo_value(self, do_name: str, do_value: str): # OK | do_value 为 true/false
return self.__exec_cmd(f"setdo:{do_name}, {do_value}", f"设置 {do_name} 的值为 {do_value}", self.exec_desc) return self.__exec_cmd(f"setdo:{do_name},{do_value}", f"设置 {do_name} 的值为 {do_value} ", self.exec_desc)
def modify_system_time(self, robot_time): def modify_system_time(self, robot_time): # OK
return self.__exec_cmd(f"set_robot_time:{robot_time}", f"修改控制器和示教器的时间为 {robot_time}", self.exec_desc) return self.__exec_cmd(f"set_robot_time:{robot_time}", f"修改控制器和示教器的时间为 {robot_time}", self.exec_desc)
# -------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------
@property @property
@ -1899,7 +1931,7 @@ class ExternalCommunication(object):
return self.__exec_cmd("robot_running_state", "获取程序运行状态", " :--: 返回 true 表示正在运行false 未运行") return self.__exec_cmd("robot_running_state", "获取程序运行状态", " :--: 返回 true 表示正在运行false 未运行")
@property @property
def estop_state(self): def estop_state(self): # OK | 只表示外部急停,安全门触发不会返回 true只要有急停标识 E 字母,就会返回 true
return self.__exec_cmd("estop_state", "急停状态", " :--: 返回 true 表示处于急停状态false 非急停") return self.__exec_cmd("estop_state", "急停状态", " :--: 返回 true 表示处于急停状态false 非急停")
@property @property
@ -1907,16 +1939,16 @@ class ExternalCommunication(object):
return self.__exec_cmd("operating_mode", "获取工作模式", " :--: 返回 true 表示自动模式false 手动模式") return self.__exec_cmd("operating_mode", "获取工作模式", " :--: 返回 true 表示自动模式false 手动模式")
@property @property
def home_state(self): # NG def home_state(self): # OK | 需要设置一下 "HMI 设置->快速调整"
return self.__exec_cmd("home_state", "获取 HOME 输出状态", " :--: 返回 true 表示处于 HOME 点false 未处于 HOME 点") return self.__exec_cmd("home_state", "获取 HOME 输出状态", " :--: 返回 true 表示法兰中心处于 HOME 点false 未处于 HOME 点")
@property @property
def fault_state(self): # OK def fault_state(self): # OK
return self.__exec_cmd("fault_state", "获取 故障状态", " :--: 返回 true 表示处于故障状态false 非故障状态") return self.__exec_cmd("fault_state", "获取 故障状态", " :--: 返回 true 表示处于故障状态false 非故障状态")
@property @property
def collision_state(self): # NG def collision_state(self): # OK | 但是触发后,无法清除?
return self.__exec_cmd("collision_state", "获取碰撞检测状态", " :--: 返回 true 表示碰撞检测打开false 未打开") return self.__exec_cmd("collision_state", "获取碰撞触发状态", " :--: 返回 true 表示碰撞已触发false 未触发")
@property @property
def task_state(self): # OK def task_state(self): # OK
@ -1950,8 +1982,8 @@ class ExternalCommunication(object):
return self.__exec_cmd("alarm_state", "获取报警状态", " :--: 返回 true 表示当前有告警false 没有告警") return self.__exec_cmd("alarm_state", "获取报警状态", " :--: 返回 true 表示当前有告警false 没有告警")
@property @property
def collision_alarm_state(self): def collision_alarm_state(self): # OK
return self.__exec_cmd("collision_alarm_state", "获取碰撞检测报警状态", " :--: 返回 true 表示碰撞检测已触发false 未触发") return self.__exec_cmd("collision_alarm_state", "获取碰撞报警状态", " :--: 返回 true 表示碰撞告警false 没有碰撞告警")
@property @property
def collision_open_state(self): # OK def collision_open_state(self): # OK
@ -1970,8 +2002,21 @@ class ExternalCommunication(object):
return self.__exec_cmd("robot_error_code", "获取机器人错误码") return self.__exec_cmd("robot_error_code", "获取机器人错误码")
@property @property
def rl_pause_state(self): def rl_pause_state(self): # OK
return self.__exec_cmd("program_full", "获取 RL 的暂停状态") # 0 -- 初始化状态,刚开机上电时
# 1 -- RL 运行中
# 2 -- HMI 暂停
# 3 -- 系统 IO 暂停
# 4 -- 寄存器功能码暂停
# 5 -- 外部通讯暂停
# 6 --
# 7 -- Pause 指令暂停
# 8 --
# 9 --
# 10 -- 外部 IO 急停
# 11 -- 安全门急停
# 12 -- 其他因素停止,比如碰撞检测
return self.__exec_cmd("program_full", "获取 RL 的暂停状态", " :--: 返回值含义详见功能定义")
@property @property
def program_reset_state(self): # OK def program_reset_state(self): # OK
@ -1982,15 +2027,15 @@ class ExternalCommunication(object):
return self.__exec_cmd("program_speed", "获取程序运行速度") return self.__exec_cmd("program_speed", "获取程序运行速度")
@property @property
def robot_is_busy(self): def robot_is_busy(self): # OK | 触发条件为 pp2main/重载工程/推送到控制器,最好测试工程大一些,比较容易触发
return self.__exec_cmd("robot_is_busy", "获取程序忙碌状态", " :--: 返回 true 表示控制器忙碌,false 非忙碌状态") return self.__exec_cmd("robot_is_busy", "获取程序忙碌状态", " :--: 返回 1 表示控制器忙碌,0 非忙碌状态")
@property @property
def robot_is_moving(self): # OK def robot_is_moving(self): # OK
return self.__exec_cmd("robot_is_moving", "获取程序运行状态", " :--: 返回 true 表示机器人正在运动false 未运动") return self.__exec_cmd("robot_is_moving", "获取程序运行状态", " :--: 返回 true 表示机器人正在运动false 未运动")
@property @property
def safe_door_state(self): def safe_door_state(self): # OK
return self.__exec_cmd("safe_door_state", "获取安全门状态", " :--: 返回 true 表示安全门已触发false 未触发") return self.__exec_cmd("safe_door_state", "获取安全门状态", " :--: 返回 true 表示安全门已触发false 未触发")
@property @property
@ -2027,8 +2072,8 @@ class ExternalCommunication(object):
def __exec_cmd(self, directive, description, more_desc=""): def __exec_cmd(self, directive, description, more_desc=""):
self.s_string(directive) self.s_string(directive)
result = self.r_string().strip() result = self.r_string(directive).strip()
clibs.logger.info(f"执行{description}指令 {directive},返回值为 {result}{more_desc}") clibs.logger.info(f"执行{description}指令 {directive},返回值为 {result}{more_desc}")
return result return result