diff --git a/README.md b/README.md index a1ad3e8..bd7236f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,17 @@ ## 一、功能 +### 1. Modbus 通信 + + +### 2. 外部通信 + + +### 3. HMI socket 通信 + + +### 4. HMI xService 通信 + + ## 三、相关文件以及路径 ``` @@ -30,8 +42,8 @@ sys_io_1.cfg ## 五、待办 -- [ ] socket 断开后触发软急停,并恢复,目的是让所有运动的指令,停止运行防止意外发生 -- [ ] 外部通信实现 +- ## 九、目前存在问题 +- diff --git a/assets/json/modbus.get_values.json b/assets/json/modbus.get_values.json new file mode 100644 index 0000000..d356362 --- /dev/null +++ b/assets/json/modbus.get_values.json @@ -0,0 +1,8 @@ +{ + "id": "xxxxxxxxxxx", + "module": "fieldbus", + "command": "modbus.get_values", + "data": { + "mode": "all" + } +} \ No newline at end of file diff --git a/assets/json/modbus.set_params.json b/assets/json/modbus.set_params.json new file mode 100644 index 0000000..46a651e --- /dev/null +++ b/assets/json/modbus.set_params.json @@ -0,0 +1,12 @@ +{ + "id": "xxxxxxxxxxx", + "module": "fieldbus", + "command": "modbus.set_params", + "data": { + "enable_slave": true, + "ip": "192.168.0.160", + "port": 502, + "slave_id": 0, + "enable_master": false + } +} \ No newline at end of file diff --git a/assets/json/soft_limit.set_params.json b/assets/json/soft_limit.set_params.json index de23404..a0a3844 100644 --- a/assets/json/soft_limit.set_params.json +++ b/assets/json/soft_limit.set_params.json @@ -2,9 +2,8 @@ "id": "xxxxxxxxxxx", "module": "safety", "command": "soft_limit.set_params", - "data": - { - "enable": true + "data": { + "enable": true, "upper": [0,0,0,0,0,0,0], "lower": [0,0,0,0,0,0,0], "reduced_upper": [0,0,0,0,0,0,0], diff --git a/code/common.py b/code/common.py index 7a11560..f1f02b1 100644 --- a/code/common.py +++ b/code/common.py @@ -75,7 +75,7 @@ def initialization(): # 打开外部通信 clibs.logger.info("配置并打开外部通信,默认服务器,8080端口,后缀为 \"\\r\"...") - hr.set_socket_params(True, "", "name", "8080", "\r", 1, True, True, 0, 10) + hr.set_socket_params(True, "8080", "\r", 1) # 关闭拖动 clibs.logger.info("关闭拖动模式...") diff --git a/code/openapi.py b/code/openapi.py index 97122a9..adae436 100644 --- a/code/openapi.py +++ b/code/openapi.py @@ -218,7 +218,7 @@ class ModbusRequest(object): @property def w_robot_is_moving(self): # OK res = self.__c.read_holding_registers(40513, 1).registers[0] - clibs.logger.info(f"40513 获取机器人是否处于运动状态,结果为 {res} :--: 0 表示为运动,1 表示正在运动") + clibs.logger.info(f"40513 获取机器人是否处于运动状态,结果为 {res} :--: 0 表示未运动,1 表示正在运动") return res @property @@ -319,7 +319,7 @@ class HmiRequest(object): self.__silence = False first_time = True - sleep(clibs.interval*10) + sleep(clibs.interval*6) def close(self): self.__close_hmi = True @@ -689,24 +689,12 @@ class HmiRequest(object): case "diagnosis.save": req["data"]["save"] = kwargs["save"] case "socket.set_params": - req["data"]["enable"] = kwargs["enable"] - req["data"]["ip"] = kwargs["ip"] - req["data"]["name"] = kwargs["name"] - req["data"]["port"] = kwargs["port"] - req["data"]["suffix"] = kwargs["suffix"] - req["data"]["type"] = kwargs["type"] - req["data"]["reconnect_flag"] = kwargs["reconnect_flag"] - req["data"]["disconnection_triggering_behavior"] = kwargs["disconnection_triggering_behavior"] - req["data"]["disconnection_detection_time"] = kwargs["disconnection_detection_time"] + req["data"] = kwargs["data"] case "fieldbus_device.set_params": req["data"]["device_name"] = kwargs["device_name"] req["data"]["enable"] = kwargs["enable"] case "soft_limit.set_params": - req["data"]["enable"] = kwargs["enable"] - req["data"]["upper"] = kwargs["upper"] - req["data"]["lower"] = kwargs["lower"] - req["data"]["reduced_upper"] = kwargs["reduced_upper"] - req["data"]["reduced_lower"] = kwargs["reduced_lower"] + req["data"] = kwargs["data"] case "move.set_quickturn_pos": req["data"]["enable_home"] = kwargs["enable_home"] req["data"]["enable_drag"] = kwargs["enable_drag"] @@ -740,7 +728,7 @@ class HmiRequest(object): case "move.set_monitor_cfg": req["data"]["ref_coordinate"] = kwargs["ref_coordinate"] case "move.set_params": - req["data"] = kwargs["data"] + req["data"]["MOTION"] = kwargs["data"] case "move.set_quickstop_distance": req["data"]["distance"] = kwargs["distance"] case "collision.set_params": @@ -798,7 +786,7 @@ class HmiRequest(object): # =================================== ↓↓↓ specific functions ↓↓↓ =================================== - def switch_motor_state(self, state: str): + def switch_motor_state(self, state: str): # OK """ 切换上电/下电的状态 :param state: on/off @@ -812,7 +800,7 @@ class HmiRequest(object): case _: clibs.logger.error(f"switch_motor_state 参数错误 {state}: 非法参数,只接受 on/off") - def switch_operation_mode(self, mode: str): + def switch_operation_mode(self, mode: str): # OK """ 切换自动/手动操作模式 :param mode: auto/manual @@ -826,7 +814,7 @@ class HmiRequest(object): case _: clibs.logger.error("switch_operation_mode 参数错误 非法参数,只接受 auto/manual") - def reload_project(self, prj_name: str, tasks: list): + def reload_project(self, prj_name: str, tasks: list): # OK """ 重新加载指定工程 :param prj_name: 工程名,也即 zip 文件的名字 @@ -836,7 +824,7 @@ class HmiRequest(object): prj_path = f"{prj_name}/_build/{prj_name}.prj" self.execution("overview.reload", prj_path=prj_path, tasks=tasks) - def set_project_auto_reload(self, prj_name: str): + def set_project_auto_reload(self, prj_name: str): # OK """ 将指定工程设置为开机自动加载,也即默认工程 :param prj_name: 工程名,也即 zip 文件的名字 @@ -845,7 +833,7 @@ class HmiRequest(object): autoload_prj_path = f"{prj_name}/_build/{prj_name}.prj" self.execution("overview.set_autoload", autoload_prj_path=autoload_prj_path) - def pp_to_main(self, tasks: list): + def pp_to_main(self, tasks: list): # OK """ 将指定的任务列表的指针,指向 main 函数 :param tasks: 任务列表 @@ -853,7 +841,7 @@ class HmiRequest(object): """ self.execution("rl_task.pp_to_main", tasks=tasks) - def program_start(self, tasks: list): + def program_start(self, tasks: list): # OK """ 开始执行程序任务,必须是自动模式下执行 :param tasks: 任务列表 @@ -861,7 +849,7 @@ class HmiRequest(object): """ self.execution("rl_task.run", tasks=tasks) - def program_stop(self, tasks: list): + def program_stop(self, tasks: list): # OK """ 停止执行程序任务 :param tasks: 人物列表 @@ -869,7 +857,7 @@ class HmiRequest(object): """ self.execution("rl_task.stop", tasks=tasks) - def set_program_loop_speed(self, loop_mode: bool, override: float): + def set_program_loop_speed(self, loop_mode: bool = True, override: float = 0.5): # OK """ :param loop_mode: True为循环模式,False为单次模式 :param override: HMI 左下方的速度滑块,取值范围 [0, 1] @@ -877,14 +865,14 @@ class HmiRequest(object): """ self.execution("rl_task.set_run_params", loop_mode=loop_mode, override=override) - def clear_alarm(self): + def clear_alarm(self): # OK """ 清除伺服告警 :return: None """ self.execution("servo.clear_alarm") - def reboot_robot(self): + def reboot_robot(self): # OK """ 重启控制器 :return: None @@ -916,7 +904,7 @@ class HmiRequest(object): self.execution("io_device.load_cfg") @property - def get_quickturn_pos(self): + def get_quickturn_pos(self): # OK """ 获取机器人的home位姿、拖动位姿和发货位姿,轴关节角度,end_posture 取值如下: 0 法兰平面与地面平行 @@ -940,7 +928,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "move.get_quickturn_pos") - def set_quickturn_pos(self, enable_home: bool = False, enable_drag: bool = False, enable_transport: bool = False, end_posture: int = 0): + def set_quickturn_pos(self, enable_home: bool = False, enable_drag: bool = False, enable_transport: bool = False, end_posture: int = 0): # OK """ 设置机器人的home位姿、拖动位姿、发货位姿,轴关节角度,Home点误差范围,详见上一个 get_quickturn_pos 功能实现 :param enable_home: 是否开启 home 点快速调整 @@ -951,7 +939,7 @@ class HmiRequest(object): """ self.execution("move.set_quickturn_pos", enable_home=enable_home, enable_drag=enable_drag, enable_transport=enable_transport, end_posture=end_posture) - def move2quickturn(self, name: str): + def move2quickturn(self, name: str): # OK """ 运动到指定的快速调整位姿 :param name: 指定快速调整的名称,home/drag/transport @@ -959,7 +947,7 @@ class HmiRequest(object): """ self.execution("move.quick_turn", name=name) - def stop_move(self, stoptype=0): + def stop_move(self, stoptype=0): # OK """ 停止运动 TS_READY | TS_JOG | TS_LOADIDENTIFY | TS_DYNAMICIDENTIFY | TS_DRAG | TS_PROGRAM | TS_DEMO | TS_RCI | TS_DEBUG | TS_FRICTIONIDENTIFY @@ -969,7 +957,7 @@ class HmiRequest(object): self.execution("move.stop", stoptype=stoptype) @property - def get_jog_params(self): + def get_jog_params(self): # OK """ 获取JOG的参数 世界坐标系 WORLD_COORDINATE 0 @@ -987,7 +975,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "jog.get_params") - def set_jog_params(self, step, override, space): + def set_jog_params(self, step, override, space): # OK """ 设置JOG的参数,包含步长,空间,速度倍率 :param step: [1000-连续] [10/1/0.1/0.001-点动] @@ -997,7 +985,7 @@ class HmiRequest(object): """ self.execution("jog.set_params", step=step, override=override, space=space) - def start_jog(self, index: int, direction: bool = False, is_ext: bool = False): + def start_jog(self, index: int, direction: bool = False, is_ext: bool = False): # OK """ 开始 JOG 运动 :param index: 0-6,若选轴空间,则 0-6 对应 1-7 轴,若选笛卡尔空间,则 0-6 对应 xyzabc elb @@ -1008,91 +996,61 @@ class HmiRequest(object): self.execution("jog.start", index=index, direction=direction, is_ext=is_ext) @property - def get_socket_params(self): + def get_socket_params(self): # OK """ 获取socket参数 :return: { - "auto_connect": true, - "disconnection_detection_time": 10, - "disconnection_triggering_behavior": 0, - "enable": true, - "ip": "", - "name": "name", - "port": "8080", - "reconnect_flag": true, - "suffix": "\r", - "type": 1 + "auto_connect": true, // True 开机启动,False 不开机启动 + "disconnection_detection_time": 10, // 链接断开检测周期(s) + "disconnection_triggering_behavior": 0, // 断开连接触发行为 0无动作 1暂停程序 2暂停并下电 + "enable": true, // True 开启或者 False 关闭 + "ip": "", // 仅限于客户端,用于指定服务端 IP;当作为服务端时,该参数设置为空字符串,否则会报错!!! + "name": "name", // 连接名称 + "port": "8080", // 连接端口 + "reconnect_flag": true, // True 自动重连,False 不自动重连 + "suffix": "\r", // 指定发送分隔符 + "type": 1 // 连接类型 0 client | 1 server } """ return self.__get_data(currentframe().f_code.co_name, "socket.get_params") - def set_socket_params(self, enable: bool, ip: str, name: str, port: str, suffix: str, type: int, reconnect_flag: bool, auto_connect: bool, disconnection_triggering_behavior: int, disconnection_detection_time: int): + def set_socket_params(self, enable: bool, port: str, suffix: str, type: int = 1, **kwargs): # OK """ - 设置 socket 参数 + 设置 socket 参数,一般作为服务器使用 :param enable: True 开启或者 False 关闭 - :param ip: 仅限于客户端,用于指定服务端 IP;当作为服务端时,该参数设置为空字符串,否则会报错!!! - :param name: 连接名字 :param port: 连接端口 :param suffix: 指定发送分隔符 :param type: 0 client | 1 server - :param reconnect_flag: True 自动重连,False 不自动重连 - :param auto_connect: True 开机启动,False 不开机启动 - :param disconnection_triggering_behavior: 断开连接触发行为 0无动作 1暂停程序 2暂停并下电 - :param disconnection_detection_time: 链接断开检测周期(s) :return: None """ - self.execution("socket.set_params", enable=enable, ip=ip, name=name, port=port, suffix=suffix, type=type, reconnect_flag=reconnect_flag, auto_connect=auto_connect, disconnection_triggering_behavior=disconnection_triggering_behavior, disconnection_detection_time=disconnection_detection_time) + data = self.get_socket_params + keys = data.keys() + kwargs.update({"enable": enable, "port": port, "suffix": suffix, "type": type}) + for _ in keys: + if _ in kwargs.keys(): + data[_] = kwargs[_] + self.execution("socket.set_params", data=data) @property - def get_diagnosis_params(self, version="1.4.1"): + def get_diagnosis_params(self, version="1.4.1"): # OK """ 获取诊断功能开启状态,以及相应其他信息 :param version: 指定诊断工具版本 :return: { - "state": true, - "display_open": false, - "display_pdo_params": [ - { - "name": "count", - "channel": 0 - }, - { - "name": "servo_error_code", - "channel": 5 - }, - { - "name": "rci_data05", - "channel": 11 - } - ], - "frequency": 50, - "pdo_params": [ - { - "name": "count", - "array": 1 - }, - { - "name": "current_A", - "array": 7 - }, - { - "name": "keypad_status", - "array": 1 - }, - { - "name": "rci_data05", - "array": 12 - } - ], - "overrun": true, - "turn_area": true + "delay_motion": false, // - + "display_open": false, // 诊断显示功能开启状态 + "ecat_diagnosis_state": false, // - + "overrun": false, // 是否开启实时线程超时监控上报 + "pdo_params": [...], // 指定版本支持的所有曲线信息 + "state": true, // 诊断功能的开启状态 + "turn_area": false // 转弯区是否上报 } """ return self.__get_data(currentframe().f_code.co_name, "diagnosis.get_params", version=version) - def set_diagnosis_params(self, display_pdo_params: list, frequency: int = 50, version: str = "1.4.1"): + def set_diagnosis_params(self, display_pdo_params: list, frequency: int = 50, version: str = "1.4.1"): # OK """ 设置诊断功能显示参数 :param display_pdo_params: 指定要采集的曲线名称,具体可通过 get_diagnosis_params 函数功能获取所有目前已支持的曲线 @@ -1102,11 +1060,11 @@ class HmiRequest(object): """ self.execution("diagnosis.set_params", display_pdo_params=display_pdo_params, frequency=frequency, version=version) - def open_diagnosis(self, open: bool, display_open: bool, overrun: bool, turn_area: bool, delay_motion: bool): + def open_diagnosis(self, open: bool, display_open: bool, overrun: bool = False, turn_area: bool = False, delay_motion: bool = False): # OK """ 打开或者关闭诊断曲线,并定义其他功能的开关(调试相关功能,比如是否开启线程超时监控和上报,转弯区以及运动延迟等) - :param open: 诊断功能 - :param display_open: 诊断显示功能 + :param open: 诊断功能,控制HMI->日志->诊断设置->私服诊断开关,一般设置成 True + :param display_open: 诊断显示功能,指的是在线诊断插件中的打开 switch 的状态,需要诊断数据的情况,设置成 True :param overrun: 实时线程超时监控上报 :param turn_area: 转弯区上报 :param delay_motion: 延迟运动 @@ -1114,16 +1072,16 @@ class HmiRequest(object): """ self.execution("diagnosis.open", open=open, display_open=display_open, overrun=overrun, turn_area=turn_area, delay_motion=delay_motion) - def save_diagnosis(self, save: bool): + def save_diagnosis(self, save: bool = True): # OK """ - 保存诊断数据 - :param save: 保存数据开关,对应诊断曲线内容的 switch 开关 + 保存诊断数据,也就是主动写诊断动作,HMI日志->诊断设置->保存诊断数据 + :param save: 保存数据开关 :return: None """ self.execution("diagnosis.save", save=save) @property - def qurry_system_io_configuration(self): + def qurry_system_io_configuration(self): # OK """ 系统IO配置的查询协议,trigger 参数取值参照如下: FLANKS 0, //边缘触发 @@ -1156,7 +1114,7 @@ class HmiRequest(object): return self.__get_data(currentframe().f_code.co_name, "system_io.query_configuration") @property - def qurry_system_io_event_configuration(self): + def qurry_system_io_event_configuration(self): # OK """ 查询当前系统支持的系统IO事件列表,包括事件key、名称、支持的触发方式等配置 :return: @@ -1203,7 +1161,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "system_io.query_configuration") - def update_system_io_configuration(self, i_funcs, o_funcs, i_signals, o_signals, trig_types): + def update_system_io_configuration(self, i_funcs: list, o_funcs: list, i_signals: list, o_signals: list, trig_types: list): # OK """ 配置系统 IO :param i_funcs: 输入,只写功能码列表 @@ -1223,9 +1181,9 @@ class HmiRequest(object): self.execution("system_io.update_configuration", input_system_io=input_system_io, output_system_io=output_system_io) @property - def get_fieldbus_device_params(self): + def get_fieldbus_device_params(self): # OK """ - 获取设备列表的开关状态 + 获取的是 HMI通讯->总线设备列表的信息,以及开关状态 :return: { "device_list": [ @@ -1241,16 +1199,16 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "fieldbus_device.get_params") - def set_fieldbus_device_params(self, device_name: str, enable: bool): + def set_fieldbus_device_params(self, device_name: str, enable: bool): # OK """ 定义开关设备的协议,一次只能打开一个设备 :param device_name: 设备列表中的名称 - :param enable: 是否开启 + :param enable: 是否开启,这里操作的是 HMI通信->IO设备里面的开关状态 :return: None """ self.execution("fieldbus_device.set_params", device_name=device_name, enable=enable) - def reload_fieldbus(self): + def reload_fieldbus(self): # OK """ 触发控制器重新加载总线设备 :return: None @@ -1258,23 +1216,25 @@ class HmiRequest(object): self.execution("fieldbus_device.load_cfg") @property - def get_modbus_params(self): + def get_modbus_params(self): # OK """ 获取modbus参数 :return: { - "enable_slave":true, - "ip":"192.168.0.160", - "port":502, - "slave_id":0, - "enable_master":false + "connect_state": true, + "enable_master": false, + "enable_slave": false, + "ip": "192.168.0.160", + "is_convert": true, + "port": 502, + "slave_id": 1 } """ return self.__get_data(currentframe().f_code.co_name, "modbus.get_params") - def set_modbus_params(self, enable_slave: bool, ip: str, port: int, slave_id: int, enable_master): + def set_modbus_params(self, enable_slave: bool, ip: str, port: int, slave_id: int, enable_master: bool): # OK """ - 设置modbus参数 + 设置modbus参数,相当于新建 :param enable_slave: Modbus从站是否自动开启 :param ip: ip 地址 :param port: 端口 @@ -1284,14 +1244,14 @@ class HmiRequest(object): """ self.execution("modbus.set_params", enable_slave=enable_slave, ip=ip, port=port, slave_id=slave_id, enable_master=enable_master) - def reload_registers(self): + def reload_registers(self): # OK """ 触发控制器重新加载寄存器列表 :return: None """ self.execution("modbus.load_cfg") - def get_modbus_values(self, mode): + def get_modbus_values(self, mode: str = "all"): # OK """ 用于获取 modbus 寄存器变量值的更新信息,展示在状态监控界面 :param mode: all/change @@ -1300,7 +1260,7 @@ class HmiRequest(object): return self.__get_data(currentframe().f_code.co_name, "modbus.get_values", mode=mode) @property - def get_soft_limit_params(self): + def get_soft_limit_params(self): # OK """ 获取软限位参数 :return: @@ -1314,20 +1274,25 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "soft_limit.get_params") - def set_soft_limit_params(self, enable: bool, upper: list, lower: list, reduced_upper: list, reduced_lower: list): + def set_soft_limit_params(self, **kwargs): # OK """ - 设定软限位参数 - :param enable: 是否启用软限位 - :param upper: 软限位上限 - :param lower: 软限位下限 - :param reduced_upper: 缩减模式软限位上限 - :param reduced_lower: 缩减模式软限位下限 + 设定软限位参数 enable: bool, upper: list, lower: list, reduced_upper: list, reduced_lower: list + :enable: 是否启用软限位 + :upper: 软限位上限 + :lower: 软限位下限 + :reduced_upper: 缩减模式软限位上限 + :reduced_lower: 缩减模式软限位下限 :return: None """ - self.execution("soft_limit.set_params", enable=enable, upper=upper, lower=lower, reduced_upper=reduced_upper, reduced_lower=reduced_lower) + data = self.get_soft_limit_params + keys = data.keys() + for _ in keys: + if _ in kwargs.keys(): + data[_] = kwargs[_] + self.execution("soft_limit.set_params", data=data) @property - def get_device_params(self): + def get_device_params(self): # OK """ 获取设备信息 :return: @@ -1335,7 +1300,7 @@ class HmiRequest(object): return self.__get_data(currentframe().f_code.co_name, "device.get_params") @property - def get_cart_pos(self): + def get_cart_pos(self): # OK """ 获取机器人的当前位姿:包括轴关节角度,笛卡尔关节角度,四元数,欧拉角(臂角) :return: @@ -1351,7 +1316,7 @@ class HmiRequest(object): return self.__get_data(currentframe().f_code.co_name, "move.get_pos") @property - def get_joint_pos(self): + def get_joint_pos(self): # OK """ 获取机器人的当前关节角度:包括内部轴和外部轴 :return: @@ -1363,7 +1328,7 @@ class HmiRequest(object): return self.__get_data(currentframe().f_code.co_name, "move.get_joint_pos") @property - def get_monitor_cfg(self): + def get_monitor_cfg(self): # OK """ 获取机器人的监控配置参数,RefCoordinateType 类型数据,表示当前控制器位置监测的相对坐标系 基坐标系 REF_COORDINATE_BASE 0 @@ -1376,7 +1341,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "move.get_monitor_cfg") - def set_monitor_cfg(self, ref_coordinate): + def set_monitor_cfg(self, ref_coordinate): # OK """ 设置机器人的监控配置参数 :ref_coordinate: RefCoordinateType类型数据,用来设置当前控制器位置监测的相对坐标系 @@ -1385,7 +1350,7 @@ class HmiRequest(object): self.execution("move.set_monitor_cfg", ref_coordinate=ref_coordinate) @property - def get_move_params(self): + def get_move_params(self): # OK """ 获取机器人的运动参数:包括减速比、耦合比、最大速度、加速度、加加速度、acc ramp time、规划步长等信息 :return: @@ -1415,20 +1380,22 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "move.get_params") - def set_move_params(self, **kwargs): + def set_move_params(self, **kwargs): # OK """ 设置机器人的运动参数:轴最大速度、轴最大加加速度、速度、加加速度、加速度、加加速度、acc ramp time、规划步长等信息 - :return: + 可选参数:参考 get_move_params 函数返回值 MOTION 里面的选项 + :return: None """ - res = self.get_move_params - keys = res.keys() + data = self.get_move_params["MOTION"] + print(f"res = {data}") + keys = data.keys() for _ in keys: if _ in kwargs.keys(): - res[_] = kwargs[_] - self.execution("move.set_params", data=res) + data[_] = kwargs[_] + self.execution("move.set_params", data=data) @property - def get_quick_stop_distance(self): + def get_quick_stop_distance(self): # OK """ 获取机器人 search 指令最大停止距离 :return: @@ -1438,7 +1405,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "move.get_quickstop_distance") - def set_quick_stop_distance(self, distance): + def set_quick_stop_distance(self, distance: float): # OK """ 设置机器人 search 指令最大停止距离 :param distance: 停止距离,单位 mm @@ -1447,7 +1414,7 @@ class HmiRequest(object): self.execution("move.set_quickstop_distance", distance=distance) @property - def get_collision_params(self): + def get_collision_params(self): # OK """ 获取碰撞检测相关参数 :return: @@ -1467,7 +1434,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "collision.get_params") - def set_collision_params(self, enable, mode, action, percent, **kwargs): + def set_collision_params(self, enable, mode, action, percent, **kwargs): # OK """ 设置碰撞检测相关参数 :param enable: 功能使能开关 @@ -1484,16 +1451,16 @@ class HmiRequest(object): data[_] = kwargs[_] self.execution("collision.set_params", data=data) - def set_collision_state(self, collision_state: bool): + def set_collision_state(self, collision_state: bool): # NG """ - 开启或者关闭碰撞检测,测试该函数功能无效!!! + 开启或者关闭虚拟墙碰撞检测,测试该函数功能无效!!! :param collision_state: 碰撞检测的开关状态 :return: None """ self.execution("collision.set_state", collision_state=collision_state) @property - def get_robot_state(self): + def get_robot_state(self): # OK """ { "rc_state":"normal", # "fatal" 、"error"、"block"、"normal" @@ -1507,7 +1474,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "state.get_state") - def set_controller_params(self, robot_time: str): + def set_controller_params(self, robot_time: str): # OK """ 设置控制器系统时间 :param robot_time: 系统时间,"2020-02-28 15:28:30" @@ -1516,7 +1483,7 @@ class HmiRequest(object): self.execution("controller.set_params", time=robot_time) @property - def get_robot_params(self): + def get_robot_params(self): # OK """ "alias": "", "auth_state": @@ -1539,7 +1506,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "controller.get_params") - def switch_tp_mode(self, mode: str): + def switch_tp_mode(self, mode: str): # OK """ 切换示教器模式 :param mode: with/without @@ -1554,7 +1521,7 @@ class HmiRequest(object): clibs.logger.error("switch_tp_mode 参数错误 非法参数,只接受 with/without") @property - def get_tp_mode(self): + def get_tp_mode(self): # OK """ 获取示教器连接状态 :return: @@ -1565,7 +1532,7 @@ class HmiRequest(object): return self.__get_data(currentframe().f_code.co_name, "state.get_tp_mode") @property - def get_drag_params(self): + def get_drag_params(self): # OK """ 获取拖动模式参数 :return: @@ -1577,7 +1544,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "drag.get_params") - def set_drag_params(self, enable: bool, space: int, type: int): + def set_drag_params(self, enable: bool, space: int = 1, type: int = 2): # OK """ 设置拖动模式开关以及参数 :param enable: 是否启用拖动 @@ -1587,7 +1554,7 @@ class HmiRequest(object): """ self.execution("drag.set_params", enable=enable, space=space, type=type) - def set_safety_area_signal(self, signal: bool): + def set_safety_area_signal(self, signal: bool): # OK """ 设置安全区域信号控制使能开关 :param signal: True 打开 False 关闭 @@ -1595,7 +1562,7 @@ class HmiRequest(object): """ self.execution("safety.safety_area.signal_enable", protocol_flag=1, signal=signal) - def set_safety_area_overall(self, enable: bool): + def set_safety_area_overall(self, enable: bool): # OK """ 设置安全区域整体控制使能开关 :param enable: True 打开 False 关闭 @@ -1604,7 +1571,7 @@ class HmiRequest(object): self.execution("safety.safety_area.overall_enable", protocol_flag=1, enable=enable) @property - def get_safety_area_params(self): + def get_safety_area_params(self): # OK """ 获取安全区所有的配置信息 :return: @@ -1712,7 +1679,7 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "safety_area_data", flag=1) - def set_safety_area_enable(self, id: int, enable: bool): + def set_safety_area_enable(self, id: int, enable: bool): # OK """ 设置每个安全区域的开关 :param id: 安全区域开关,0-9 @@ -1721,7 +1688,7 @@ class HmiRequest(object): """ self.execution("safety.safety_area.safety_area_enable", protocol_flag=1, id=id, enable=enable) - def set_safety_area_param(self, id: int, enable: bool, **kwargs): + def set_safety_area_param(self, id: int, enable: bool, **kwargs): # OK """ 设定单独安全区的参数 :param id: 安全区 id @@ -1739,7 +1706,7 @@ class HmiRequest(object): self.execution("safety.safety_area.safety_area_enable", protocol_flag=1, id=id, enable=enable) @property - def get_filtered_error_code(self): + def get_filtered_error_code(self): # OK """ 获取已设定的错误码过滤列表 :return: @@ -1767,7 +1734,13 @@ class HmiRequest(object): """ return self.__get_data(currentframe().f_code.co_name, "log_code.data", flag=1) - def set_filtered_error_code(self, action: str, code_list: list): + def set_filtered_error_code(self, action: str, code_list: list): # OK + """ + 清空,增加,删除错误过滤码 + :param action: 支持 add/remove/clear,当为 clear 时,code_list 可为任意列表 + :param code_list: 需要添加/删除的过滤码列表 + :return: None + """ origin_code_list = self.get_filtered_error_code["g"]["log_code.data"]["code_list"] # [{'id': 10000, 'title': 'HMI请求包解析错误'}, {'id': 10002, 'title': '快速调整启动失败'}] if action == "clear": @@ -1810,6 +1783,7 @@ class ExternalCommunication(object): self.__c = None self.suffix = "\r" self.socket_client() + self.exec_desc = " :--: 返回 true 表示执行成功,false 失败" def socket_client(self): self.__c = socket(AF_INET, SOCK_STREAM) @@ -1834,227 +1808,227 @@ class ExternalCommunication(object): return result # =================================== ↓↓↓ specific functions ↓↓↓ =================================== - def motor_on(self): - return self.__exec_cmd("motor_on", "电机上电") + def motor_on(self): # OK + return self.__exec_cmd("motor_on", "电机上电", self.exec_desc) - def motor_off(self): - return self.__exec_cmd("motor_off", "电机下电") + def motor_off(self): # OK + return self.__exec_cmd("motor_off", "电机下电", self.exec_desc) - def pp_to_main(self): - return self.__exec_cmd("pp_to_main", "程序指针到") + def pp_to_main(self): # OK + return self.__exec_cmd("pp_to_main", "程序指针到", self.exec_desc) - def program_start(self): - return self.__exec_cmd("start", "程序启动") + def program_start(self): # OK + return self.__exec_cmd("start", "程序启动(可能需先清告警)", self.exec_desc) - def program_stop(self): - return self.__exec_cmd("stop", "程序停止") + def program_stop(self): # OK + return self.__exec_cmd("stop", "程序停止", self.exec_desc) - def clear_alarm(self): - return self.__exec_cmd("clear_alarm", "清除伺服报警") + def clear_alarm(self): # OK + return self.__exec_cmd("clear_alarm", "清除伺服报警", self.exec_desc) - def switch_operation_auto(self): - return self.__exec_cmd("switch_mode:auto", "切换到自动模式") + def switch_operation_auto(self): # OK + return self.__exec_cmd("switch_mode:auto", "切换到自动模式", self.exec_desc) - def switch_operation_manual(self): - return self.__exec_cmd("switch_mode:manual", "切换到手动模式") + def switch_operation_manual(self): # OK + return self.__exec_cmd("switch_mode:manual", "切换到手动模式", self.exec_desc) - def open_drag_mode(self): - return self.__exec_cmd("open_drag", "打开拖动") + def open_drag_mode(self): # OK + return self.__exec_cmd("open_drag", "打开拖动", self.exec_desc) - def close_drag_mode(self): - return self.__exec_cmd("close_drag", "关闭拖动") + def close_drag_mode(self): # OK + return self.__exec_cmd("close_drag", "关闭拖动", self.exec_desc) - def get_program_list(self): + def get_program_list(self): # OK return self.__exec_cmd("list_prog", "获取工程列表") - def get_current_program(self): + def get_current_program(self): # OK return self.__exec_cmd("current_prog", "当前工程") - def load_program(self, program_name): - return self.__exec_cmd(f"load_prog:{program_name}", "加载工程") + def load_program(self, program_name): # OK + return self.__exec_cmd(f"load_prog:{program_name}", "加载工程", self.exec_desc) def estop_reset(self): - return self.__exec_cmd("estop_reset", "急停复位") + return self.__exec_cmd("estop_reset", "急停复位", self.exec_desc) def estopreset_and_clearalarm(self): - return self.__exec_cmd("estopreset_and_clearalarm", "急停复位并清除报警") + return self.__exec_cmd("estopreset_and_clearalarm", "急停复位并清除报警", self.exec_desc) - def motoron_pp2main_start(self): - return self.__exec_cmd("motoron_pptomain_start", "依次执行上电,程序指针到main,启动程序") + def motoron_pp2main_start(self): # OK + return self.__exec_cmd("motoron_pptomain_start", "依次执行上电,程序指针到main,启动程序(可以是手动模式,必要时需清告警)", self.exec_desc) - def motoron_start(self): - return self.__exec_cmd("motoron_start", "依次执行上电,启动程序") + def motoron_start(self): # OK + return self.__exec_cmd("motoron_start", "依次执行上电,启动程序(可以是手动模式,必要时需清告警)", self.exec_desc) - def pause_motoroff(self): - return self.__exec_cmd("pause_motoroff", "暂停程序并下电") + def pause_motoroff(self): # OK + return self.__exec_cmd("pause_motoroff", "暂停程序并下电", self.exec_desc) - def set_program_speed(self, speed: int): - return self.__exec_cmd(f"set_program_speed:{speed}", "设置程序运行速率") + def set_program_speed(self, speed: int): # OK + return self.__exec_cmd(f"set_program_speed:{speed}", "设置程序运行速率(滑块)", self.exec_desc) - def set_soft_estop(self, enable: str): - return self.__exec_cmd(f"set_soft_estop:{enable}", "触发(true)/解除(false)机器人软急停") + def set_soft_estop(self, enable: str): # OK + return self.__exec_cmd(f"set_soft_estop:{enable}", "触发(true)/解除(false)机器人软急停", self.exec_desc) - def switch_auto_motoron(self): - return self.__exec_cmd("switch_auto_motoron", "切换自动模式并上电") + def switch_auto_motoron(self): # OK + return self.__exec_cmd("switch_auto_motoron", "切换自动模式并上电", self.exec_desc) - def open_safe_region(self, number: int): - return self.__exec_cmd(f"open_safe_region:{number}", f"打开第 {number} 个安全区域") + def open_safe_region(self, number: int): # OK + return self.__exec_cmd(f"open_safe_region:{number}", f"打开第 {number} 个安全区域(1-10,信号控制开关需打开,不限操作模式)", self.exec_desc) - def close_safe_region(self, number: int): - return self.__exec_cmd(f"close_safe_region:{number}", f"关闭第 {number} 个安全区域") + def close_safe_region(self, number: int): # OK + return self.__exec_cmd(f"close_safe_region:{number}", f"关闭第 {number} 个安全区域(1-10,信号控制开关需打开,不限操作模式)", self.exec_desc) - def open_reduced_mode(self): - return self.__exec_cmd("open_reduced_mode", "开启缩减模式") + def open_reduced_mode(self): # OK + return self.__exec_cmd("open_reduced_mode", "开启缩减模式(不限操作模式)", self.exec_desc) - def close_reduced_mode(self): - return self.__exec_cmd("close_reduced_mode", "关闭缩减模式") + def close_reduced_mode(self): # OK + return self.__exec_cmd("close_reduced_mode", "关闭缩减模式(不限操作模式)", self.exec_desc) def setdo_value(self, do_name, do_value): - return self.__exec_cmd(f"setdo:{do_name}, {do_value}", f"设置 {do_name} 的值为 {do_value}") + 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): - return self.__exec_cmd(f"set_robot_time:{robot_time}", f"修改控制器和示教器的时间为 {robot_time}") + return self.__exec_cmd(f"set_robot_time:{robot_time}", f"修改控制器和示教器的时间为 {robot_time}", self.exec_desc) # -------------------------------------------------------------------------------------------------- @property - def motor_on_state(self): - return self.__exec_cmd("motor_on_state", "电机上电状态") + def motor_on_state(self): # OK + return self.__exec_cmd("motor_on_state", "获取上电状态", " :--: 返回 true 表示已上电,false 已下电") @property - def robot_running_state(self): - return self.__exec_cmd("robot_running_state", "程序运行状态") + def robot_running_state(self): # OK + return self.__exec_cmd("robot_running_state", "获取程序运行状态", " :--: 返回 true 表示正在运行,false 未运行") @property def estop_state(self): - return self.__exec_cmd("estop_state", "急停状态") + return self.__exec_cmd("estop_state", "急停状态", " :--: 返回 true 表示处于急停状态,false 非急停") @property - def operation_mode(self): - return self.__exec_cmd("operating_mode", "工作模式") + def operation_mode(self): # OK + return self.__exec_cmd("operating_mode", "获取工作模式", " :--: 返回 true 表示自动模式,false 手动模式") @property - def home_state(self): - return self.__exec_cmd("home_state", "HOME 输出状态") + def home_state(self): # NG + return self.__exec_cmd("home_state", "获取 HOME 输出状态", " :--: 返回 true 表示处于 HOME 点,false 未处于 HOME 点") @property - def fault_state(self): - return self.__exec_cmd("fault_state", "故障状态") + def fault_state(self): # OK + return self.__exec_cmd("fault_state", "获取 故障状态", " :--: 返回 true 表示处于故障状态,false 非故障状态") @property - def collision_state(self): - return self.__exec_cmd("collision_state", "碰撞检测状态") + def collision_state(self): # NG + return self.__exec_cmd("collision_state", "获取碰撞检测状态", " :--: 返回 true 表示碰撞检测打开,false 未打开") @property - def task_state(self): - return self.__exec_cmd("task_state", "获取机器人运行任务状态") + def task_state(self): # OK + return self.__exec_cmd("task_state", "获取机器人运行任务状态", " :--: 返回 program 表示任务正在运行,ready 未运行") @property - def get_cart_pos(self): # cart_pos/cart_pos_name 都可以正常返回,区别在返回的前缀,可测试辨别 + def get_cart_pos(self): # OK | cart_pos/cart_pos_name 都可以正常返回,区别在返回的前缀,可测试辨别 return self.__exec_cmd("cart_pos", "获取笛卡尔位置") @property - def get_joint_pos(self): # jnt_pos/jnt_pos_name 都可以正常返回,区别在返回的前缀,可测试辨别 + def get_joint_pos(self): # OK | jnt_pos/jnt_pos_name 都可以正常返回,区别在返回的前缀,可测试辨别 return self.__exec_cmd("jnt_pos", "获取轴位置") @property - def get_axis_vel(self): # jnt_vel/jnt_vel_name 都可以正常返回,区别在返回的前缀,可测试辨别 + def get_axis_vel(self): # OK | jnt_vel/jnt_vel_name 都可以正常返回,区别在返回的前缀,可测试辨别 return self.__exec_cmd("jnt_vel", "获取轴速度") @property - def get_axis_trq(self): # jnt_trq/jnt_trq_name 都可以正常返回,区别在返回的前缀,可测试辨别 + def get_axis_trq(self): # OK | jnt_trq/jnt_trq_name 都可以正常返回,区别在返回的前缀,可测试辨别 return self.__exec_cmd("jnt_trq", "获取轴力矩") @property - def reduced_mode_state(self): - return self.__exec_cmd("reduced_mode_state", "获取缩减模式状态") + def reduced_mode_state(self): # OK + return self.__exec_cmd("reduced_mode_state", "获取缩减模式状态", " :--: 返回 true 表示缩减模式,false 非缩减模式") - def get_io_state(self, io_list: str): # DO0_0,DI1_3,DO2_5,不能有空格 + def get_io_state(self, io_list: str): # OK | DO0_0,DI1_3,DO2_5,不能有空格 return self.__exec_cmd(f"io_state:{io_list}", "获取 IO 状态值") @property - def alarm_state(self): - return self.__exec_cmd("alarm_state", "获取报警状态") + def alarm_state(self): # OK + return self.__exec_cmd("alarm_state", "获取报警状态", " :--: 返回 true 表示当前有告警,false 没有告警") @property def collision_alarm_state(self): - return self.__exec_cmd("collision_alarm_state", "获取碰撞检测报警状态") + return self.__exec_cmd("collision_alarm_state", "获取碰撞检测报警状态", " :--: 返回 true 表示碰撞检测已触发,false 未触发") @property - def collision_open_state(self): - return self.__exec_cmd("collision_open_state", "获取碰撞检测开启状态") + def collision_open_state(self): # OK + return self.__exec_cmd("collision_open_state", "获取碰撞检测开启状态", " :--: 返回 true 表示已开启碰撞检测,false 未开启") @property - def controller_is_running(self): - return self.__exec_cmd("controller_is_running", "判断控制器是否开机") + def controller_is_running(self): # OK + return self.__exec_cmd("controller_is_running", "判断控制器是否开机", " :--: 返回 true 表示控制器正在运行,false 未运行") @property - def encoder_low_battery_state(self): - return self.__exec_cmd("encoder_low_battery_state", "编码器低电压报警状态") + def encoder_low_battery_state(self): # OK + return self.__exec_cmd("encoder_low_battery_state", "编码器低电压报警状态", " :--: 返回 true 表示编码器处于低电压状态,false 电压正常") @property - def robot_error_code(self): + def robot_error_code(self): # OK return self.__exec_cmd("robot_error_code", "获取机器人错误码") @property - def get_rl_pause_state(self): + def rl_pause_state(self): return self.__exec_cmd("program_full", "获取 RL 的暂停状态") @property - def program_reset_state(self): - return self.__exec_cmd("program_reset_state", "获取程序复位状态") + def program_reset_state(self): # OK + return self.__exec_cmd("program_reset_state", "获取程序复位状态", " :--: 返回 true 表示指针指向 main,false 未指向 main") @property - def program_speed(self): + def program_speed_value(self): # OK | 速度滑块 return self.__exec_cmd("program_speed", "获取程序运行速度") @property def robot_is_busy(self): - return self.__exec_cmd("robot_is_busy", "获取程序忙碌状态") + return self.__exec_cmd("robot_is_busy", "获取程序忙碌状态", " :--: 返回 true 表示控制器忙碌,false 非忙碌状态") @property - def robot_is_moving(self): - return self.__exec_cmd("robot_is_moving", "获取程序运行状态") + def robot_is_moving(self): # OK + return self.__exec_cmd("robot_is_moving", "获取程序运行状态", " :--: 返回 true 表示机器人正在运动,false 未运动") @property def safe_door_state(self): - return self.__exec_cmd("safe_door_state", "获取安全门状态") + return self.__exec_cmd("safe_door_state", "获取安全门状态", " :--: 返回 true 表示安全门已触发,false 未触发") @property - def soft_estop_state(self): - return self.__exec_cmd("soft_estop_state", "获取软急停状态") + def soft_estop_state(self): # OK + return self.__exec_cmd("soft_estop_state", "获取软急停状态", " :--: 返回 true 表示软急停已触发,false 未触发") @property - def get_cart_vel(self): + def get_cart_vel(self): # OK return self.__exec_cmd("cart_vel", "获取笛卡尔速度") @property - def get_tcp_pos(self): - return self.__exec_cmd("tcp_pos", "获取 TCP 位姿") + def get_tcp_pos(self): # OK + return self.__exec_cmd("tcp_pose", "获取 TCP 位姿") @property - def get_tcp_vel(self): + def get_tcp_vel(self): # OK return self.__exec_cmd("tcp_vel", "获取 TCP 速度") @property - def get_tcp_vel_mag(self): + def get_tcp_vel_mag(self): # OK return self.__exec_cmd("tcp_vel_mag", "获取 TCP 合成线速度") @property - def ext_estop_state(self): - return self.__exec_cmd("ext_estop_state", "获取外部轴急停状态") + def ext_estop_state(self): # OK + return self.__exec_cmd("ext_estop_state", "获取外部轴急停状态", " :--: 返回 true 表示外部轴急停已触发,false 未触发") @property - def hand_estop_state(self): - return self.__exec_cmd("hand_estop_state", "获取手持急停状态") + def hand_estop_state(self): # OK + return self.__exec_cmd("hand_estop_state", "获取手持急停状态", " :--: 返回 true 表示手持急停已触发,false 未触发") @property - def collaboration_state(self): # TBD - return self.__exec_cmd("collaboration_state", "获取协作模式状态") + def collaboration_state(self): # OK + return self.__exec_cmd("collaboration_state", "获取协作模式状态(其实就是缩减模式)", " :--: 返回 true 表示协作模式,false 非协作模式") - def __exec_cmd(self, directive, description): + def __exec_cmd(self, directive, description, more_desc=""): self.s_string(directive) result = self.r_string().strip() - clibs.logger.info(f"外部通信:执行{description} {directive} 指令,返回值为 {result}") + clibs.logger.info(f"执行{description}指令 {directive},返回值为 {result}{more_desc}") return result