网站开发(定制)合同 模板,wordpress9,网站建设 展滔科技大厦,网易企业邮箱密码格式PythonPycharm实战#xff1a;5步搞定睿尔曼机械臂医疗工作站Demo#xff08;附完整代码#xff09; 在医疗自动化领域#xff0c;机械臂的应用正从传统的工业场景向更精细、更智能的方向拓展。睿尔曼超轻量仿人机械臂凭借其高精度、易集成的特点#xff0c;成为构建智慧医…PythonPycharm实战5步搞定睿尔曼机械臂医疗工作站Demo附完整代码在医疗自动化领域机械臂的应用正从传统的工业场景向更精细、更智能的方向拓展。睿尔曼超轻量仿人机械臂凭借其高精度、易集成的特点成为构建智慧医疗工作站的热门选择。对于开发者而言如何快速上手并实现一个完整的医疗工作站Demo是打通从理论到实践的关键一步。这篇文章将带你从零开始基于Python和PyCharm用五个清晰的步骤构建一个功能完整的医疗工作站控制程序。无论你是医疗自动化领域的工程师还是对机器人编程感兴趣的开发者这套流程都能帮你避开常见的坑高效完成项目搭建。1. 环境准备与项目初始化在开始编写控制代码之前一个稳定、兼容的开发环境是成功的第一步。睿尔曼机械臂的Python SDK对系统环境有一定要求特别是Windows 10下的Python版本和网络配置。1.1 系统与软件版本选择我推荐使用Windows 10作为开发平台它的网络配置和驱动支持相对成熟。Python版本的选择上经过实际测试Python 3.11.2与睿尔曼的SDK兼容性最好能避免一些新版本可能出现的库依赖问题。IDE方面PyCharm Community Edition就完全够用它的代码提示和调试功能对机器人开发特别友好。注意机械臂的控制器软件和SDK会不定期更新如果你在开发过程中遇到接口不匹配或协议错误第一反应应该是检查官方文档或联系技术支持获取最新版本。我遇到过几次因为SDK版本过旧导致的连接失败升级后问题就解决了。1.2 PyCharm项目创建与依赖安装打开PyCharm点击File → New Project选择一个合适的目录比如D:\Projects\MedicalRobotDemo。在创建项目时确保Python解释器指向3.11.2版本。项目创建完成后我们需要安装几个必要的依赖包。在项目根目录下创建一个requirements.txt文件内容如下numpy1.24.0 pyserial3.5 requests2.28.0然后在PyCharm的终端中运行pip install -r requirements.txt这些库虽然不是机械臂SDK的直接依赖但在数据处理和网络通信中非常有用。接下来从睿尔曼官方获取Python SDK包通常是一个名为robotic_arm_package的文件夹将其复制到你的项目目录下。1.3 网络环境配置医疗工作站通常部署在局域网内机械臂通过以太网与上位机通信。你需要确保开发电脑和机械臂控制器在同一个网段。睿尔曼机械臂的默认IP通常是192.168.1.18左臂和192.168.1.19右臂但实际环境中可能需要根据网络规划调整。检查IP连通性的简单方法是在命令提示符中ping一下机械臂的IPping 192.168.1.18如果收到回复说明网络通路正常。如果超时可能需要检查防火墙设置或网线连接。有些医院的网络策略比较严格可能需要IT部门协助开放相关端口。2. 机械臂基础连接与状态验证成功连接机械臂是控制的前提。睿尔曼的Python SDK提供了简洁的API但理解其连接机制和状态管理对后续开发至关重要。2.1 建立TCP连接机械臂控制器通常通过TCP端口8080提供通信服务。我们需要创建一个稳定的连接类来处理指令发送和状态接收。下面是一个基础的连接管理器实现import socket import time import json class RobotController: def __init__(self, ip_address192.168.1.18, port8080): self.ip ip_address self.port port self.socket None self.connected False def connect(self): 建立与机械臂的TCP连接 try: self.socket socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.settimeout(5.0) # 5秒超时 self.socket.connect((self.ip, self.port)) self.connected True print(f成功连接到机械臂 {self.ip}:{self.port}) return True except socket.error as e: print(f连接失败: {e}) return False def send_command(self, command): 发送JSON格式的指令 if not self.connected: print(未连接到机械臂) return None try: # 确保命令以回车换行结束 if not command.endswith(\r\n): command \r\n self.socket.send(command.encode(utf-8)) time.sleep(0.1) # 给控制器处理时间 # 接收响应 response self.socket.recv(1024).decode(utf-8) return response except socket.error as e: print(f发送指令失败: {e}) return None def disconnect(self): 断开连接 if self.socket: self.socket.close() self.connected False print(已断开连接)这个类封装了基本的连接管理功能。在实际医疗场景中你可能需要添加重连机制和心跳检测确保长时间运行的稳定性。2.2 机械臂状态查询与验证连接建立后首先要验证机械臂的当前状态。睿尔曼机械臂提供了丰富的状态查询接口我们可以通过以下命令获取基本信息def get_robot_status(controller): 获取机械臂系统信息 status_commands [ {command:get_system_info}\r\n, {command:get_joint_status}\r\n, {command:get_tcp_position}\r\n ] results {} for cmd in status_commands: response controller.send_command(cmd) if response: try: data json.loads(response) cmd_type json.loads(cmd)[command] results[cmd_type] data except json.JSONDecodeError: print(f解析响应失败: {response}) return results执行这个函数后你会得到类似下面的输出系统信息: {model: RM65-B, firmware: V1.5.3, api_version: 0.2.9} 关节状态: {joint1: 0.0, joint2: 0.0, joint3: 0.0, joint4: 0.0, joint5: 0.0, joint6: 0.0} TCP位置: {x: 0.0, y: 0.0, z: 0.0, rx: 0.0, ry: 0.0, rz: 0.0}这些信息对于后续的轨迹规划和安全控制非常重要。特别是API版本号它决定了哪些功能可用。2.3 常见连接问题排查在实际部署中你可能会遇到各种连接问题。下面是一个快速排查表问题现象可能原因解决方案连接超时网络不通或IP错误检查网线、确认IP地址、关闭防火墙连接被拒绝端口被占用或服务未启动重启机械臂控制器、检查8080端口是否监听指令无响应指令格式错误检查JSON格式、确保以\r\n结尾响应解析失败编码问题或数据损坏检查编码格式、增加接收缓冲区大小我遇到过最棘手的问题是在某些Windows版本上防火墙会静默拦截8080端口的出站连接。解决方案是在Windows Defender防火墙中添加入站和出站规则允许Python解释器通过。3. 医疗工作站核心功能实现医疗工作站Demo通常包含几个关键动作样本夹取、试管开盖、液体分装、扫码识别等。每个动作都需要精确的轨迹规划和末端工具控制。3.1 双机械臂协同控制在医疗场景中经常需要双臂协同工作。比如一只手臂负责夹取样本管另一只手臂负责开盖操作。下面是一个双臂协同的示例框架class DualArmMedicalWorkstation: def __init__(self, left_arm_ip192.168.1.18, right_arm_ip192.168.1.19): self.left_arm RobotController(left_arm_ip) self.right_arm RobotController(right_arm_ip) self.sample_positions {} # 样本位置映射 self.gripper_states {left: open, right: open} def initialize_arms(self): 初始化双臂包括回零和夹爪校准 print(正在初始化左臂...) if not self.left_arm.connect(): return False print(正在初始化右臂...) if not self.right_arm.connect(): self.left_arm.disconnect() return False # 双臂回零位 self._send_to_both({command:movej,joint:[0,0,0,0,0,0],v:10,r:0}) time.sleep(2) # 初始化夹爪 self._initialize_grippers() return True def _send_to_both(self, command): 向双臂发送相同指令 left_resp self.left_arm.send_command(command) right_resp self.right_arm.send_command(command) return left_resp, right_resp def sample_pick_and_place(self, sample_id, from_position, to_position): 样本转移流程 print(f开始处理样本 {sample_id}) # 左臂移动到样本上方 self._move_arm_to(self.left_arm, from_position, approach) # 左臂下降并夹取 self._move_arm_to(self.left_arm, from_position, pick) self._control_gripper(self.left_arm, close) # 左臂抬起并移动到目标区域 self._move_arm_to(self.left_arm, from_position, retreat) self._move_arm_to(self.left_arm, to_position, approach) # 左臂下降并放置 self._move_arm_to(self.left_arm, to_position, place) self._control_gripper(self.left_arm, open) # 左臂返回安全位置 self._move_arm_to(self.left_arm, to_position, retreat) print(f样本 {sample_id} 处理完成)这个类封装了双臂协同的基本逻辑。在实际医疗工作站中你还需要考虑碰撞检测、异常处理和紧急停止机制。3.2 末端工具控制夹爪与灵巧手医疗工作站常用的末端工具包括平行夹爪、三指灵巧手等。睿尔曼机械臂通过Modbus RTU协议控制这些工具。下面是一个夹爪控制的完整示例class GripperController: def __init__(self, robot_controller, modbus_port0, device_id9): self.robot robot_controller self.port modbus_port self.device device_id def initialize(self): 初始化夹爪 init_cmd f{{command:write_registers,port:{self.port},address:1000,num:1,data:[0,0],device:{self.device}}}\r\n response self.robot.send_command(init_cmd) time.sleep(0.5) return response def activate(self): 激活夹爪上使能 activate_cmd f{{command:write_registers,port:{self.port},address:1000,num:1,data:[0,1],device:{self.device}}}\r\n response self.robot.send_command(activate_cmd) time.sleep(0.5) return response def set_speed(self, speed_percentage): 设置夹爪速度0-100% # 将百分比转换为实际寄存器值 speed_value int(speed_percentage * 255 / 100) speed_cmd f{{command:write_registers,port:{self.port},address:1002,num:1,data:[{speed_value},0],device:{self.device}}}\r\n return self.robot.send_command(speed_cmd) def open(self, speed100): 全速张开夹爪 self.set_speed(speed) open_cmd f{{command:write_registers,port:{self.port},address:1000,num:3,data:[0,9,0,0,255,255],device:{self.device}}}\r\n response self.robot.send_command(open_cmd) time.sleep(1) # 等待动作完成 return response def close(self, speed100, force50): 闭合夹爪可控制力和速度 self.set_speed(speed) # 力控制参数转换 force_value int(force * 255 / 100) close_cmd f{{command:write_registers,port:{self.port},address:1000,num:1,data:[4,{force_value}],device:{self.device}}}\r\n response self.robot.send_command(close_cmd) time.sleep(1) return response def get_status(self): 读取夹爪状态 status_cmd f{{command:read_registers,port:{self.port},address:1000,num:2,device:{self.device}}}\r\n return self.robot.send_command(status_cmd)对于医疗应用夹爪的力控制特别重要。处理试管、培养皿等易碎物品时需要精确控制夹持力。上面的close方法提供了力控制参数你可以根据实际物品调整。3.3 轨迹规划与运动控制医疗操作对运动轨迹的平滑性和精确性要求很高。睿尔曼机械臂支持多种运动模式下面是一个完整的运动控制类class MotionPlanner: def __init__(self, robot_controller): self.robot robot_controller self.safe_positions { home: [0, 0, 0, 0, 0, 0], scan_ready: [-46458, 38633, -129434, 855, 87540, -63], injection_ready: [102384, -99187, 99769, -64241, 89869, -30038] } def move_joint(self, joint_angles, velocity50, acceleration0): 关节空间运动 cmd { command: movej, joint: joint_angles, v: velocity, r: acceleration, trajectory_connect: 0 } return self.robot.send_command(json.dumps(cmd) \r\n) def move_linear(self, pose, velocity50): 直线运动到指定位姿 cmd { command: movel, pose: pose, v: velocity, r: 0 } return self.robot.send_command(json.dumps(cmd) \r\n) def move_circular(self, via_pose, target_pose, velocity50): 圆弧运动 cmd { command: movec, via_pose: via_pose, target_pose: target_pose, v: velocity, r: 0 } return self.robot.send_command(json.dumps(cmd) \r\n) def safe_move_to(self, position_name, approach_height50): 安全移动到目标位置带抬升高度 if position_name not in self.safe_positions: print(f未知位置: {position_name}) return None target self.safe_positions[position_name] # 首先移动到安全高度 approach target.copy() if len(approach) 3: # 如果有位置信息 approach[2] approach_height # Z轴抬升 print(f移动到安全高度: {approach}) result1 self.move_joint(approach, velocity30) time.sleep(0.5) # 然后移动到目标位置 print(f移动到目标位置: {target}) result2 self.move_joint(target, velocity10) return result1, result2 def generate_liquid_dispensing_path(self, start_pose, end_pose, waypoints5): 生成液体分装的轨迹点 import numpy as np # 线性插值生成路径点 start np.array(start_pose[:3]) # 只取位置部分 end np.array(end_pose[:3]) path [] for i in range(waypoints 1): t i / waypoints position start t * (end - start) # 保持姿态不变 pose list(position) start_pose[3:] # 添加姿态 path.append(pose) return path在医疗应用中运动轨迹的平滑性直接影响操作成功率。特别是液体分装操作需要避免急加速导致的液体溅出。上面的generate_liquid_dispensing_path方法提供了轨迹插值功能你可以根据需要调整插值点数。4. 完整医疗工作站Demo集成现在我们把所有模块整合起来构建一个完整的医疗工作站Demo。这个Demo模拟了从样本管夹取到液体分装的完整流程。4.1 Demo主程序架构class MedicalWorkstationDemo: def __init__(self): self.left_arm RobotController(192.168.1.18) self.right_arm RobotController(192.168.1.19) self.left_gripper GripperController(self.left_arm, modbus_port1) self.right_gripper GripperController(self.right_arm, modbus_port0) self.motion_planner_left MotionPlanner(self.left_arm) self.motion_planner_right MotionPlanner(self.right_arm) # 定义工作站关键位置单位关节角度单位0.001度 self.positions { left_home: [0, 30000, -120000, 0, 90000, 0], right_home: [90000, -90000, 90000, -90000, 90000, -30000], sample_rack: [671, 20176, -140953, 31515, 86934, -87], # 样本架位置 scan_position: [-46458, 38633, -129434, 855, 87540, -63], # 扫码位置 tube_cap_open: [-29267, -7683, -115002, 32150, 87448, -506], # 开盖位置 injection_point: [129148, -99191, 103572, -95559, 92741, -30526] # 注射位置 } def run_full_demo(self): 运行完整的医疗工作站演示 print( 医疗工作站Demo启动 ) # 步骤1初始化系统 if not self._initialize_system(): print(系统初始化失败) return False try: # 步骤2左臂夹取样本管 print(\n--- 步骤1: 样本夹取 ---) self._pick_sample_tube() # 步骤3移动到扫码位置 print(\n--- 步骤2: 样本扫码 ---) self._scan_sample() # 步骤4右臂准备注射器 print(\n--- 步骤3: 注射器准备 ---) self._prepare_syringe() # 步骤5左臂开盖 print(\n--- 步骤4: 试管开盖 ---) self._open_tube_cap() # 步骤6右臂进行液体分装 print(\n--- 步骤5: 液体分装 ---) self._dispense_liquid() # 步骤7左臂关盖并放回 print(\n--- 步骤6: 试管关盖与归位 ---) self._close_and_return() # 步骤8系统复位 print(\n--- 步骤7: 系统复位 ---) self._return_to_home() print(\n Demo执行完成 ) return True except Exception as e: print(fDemo执行出错: {e}) self._emergency_stop() return False def _initialize_system(self): 初始化机械臂和末端工具 print(正在初始化左臂...) if not self.left_arm.connect(): return False print(正在初始化右臂...) if not self.right_arm.connect(): self.left_arm.disconnect() return False # 初始化夹爪 print(初始化左臂夹爪...) self.left_gripper.initialize() self.left_gripper.activate() time.sleep(1) print(初始化右臂夹爪...) self.right_gripper.initialize() self.right_gripper.activate() time.sleep(1) # 移动到初始位置 print(移动到安全初始位置...) self.motion_planner_left.move_joint(self.positions[left_home], velocity30) self.motion_planner_right.move_joint(self.positions[right_home], velocity30) time.sleep(2) return True4.2 关键操作步骤实现每个医疗操作都需要精细的控制逻辑。下面是样本夹取和液体分装两个核心功能的实现def _pick_sample_tube(self): 左臂夹取样本管 print(1. 移动到样本架上方) self.motion_planner_left.safe_move_to(sample_rack, approach_height50) print(2. 张开夹爪) self.left_gripper.open(speed80) time.sleep(0.5) print(3. 下降到夹取位置) pick_pose self.positions[sample_rack].copy() self.motion_planner_left.move_joint(pick_pose, velocity5) time.sleep(0.5) print(4. 闭合夹爪夹取样本管) self.left_gripper.close(speed60, force30) # 较小力度避免压碎试管 time.sleep(0.5) print(5. 抬起到安全高度) retreat_pose pick_pose.copy() retreat_pose[2] 5000 # Z轴抬升5度 self.motion_planner_left.move_joint(retreat_pose, velocity5) def _dispense_liquid(self): 右臂进行液体分装 print(1. 移动到注射准备位置) self.motion_planner_right.safe_move_to(injection_point, approach_height30) print(2. 控制灵巧手吸取液体) # 发送灵巧手控制指令 syringe_down {command:set_hand_seq,seq_num:2}\r\n self.right_arm.send_command(syringe_down) time.sleep(1) print(3. 执行精确注射轨迹) # 生成平滑的注射路径 start_pose self.positions[injection_point] end_pose start_pose.copy() end_pose[2] - 5000 # 向下移动5度 path self.motion_planner_right.generate_liquid_dispensing_path( start_pose, end_pose, waypoints10 ) for i, pose in enumerate(path): print(f 注射点 {i1}/{len(path)}) self.motion_planner_right.move_joint(pose, velocity2) # 低速精确运动 time.sleep(0.1) print(4. 抬起注射器) syringe_up {command:set_hand_seq,seq_num:1}\r\n self.right_arm.send_command(syringe_up) time.sleep(0.5) print(5. 返回准备位置) self.motion_planner_right.safe_move_to(injection_point, approach_height30)4.3 安全与异常处理医疗应用对安全性要求极高。我们需要在Demo中加入完善的异常检测和恢复机制def _emergency_stop(self): 紧急停止所有机械臂运动 print(!!! 紧急停止 !!!) emergency_cmd {command:stop}\r\n try: self.left_arm.send_command(emergency_cmd) self.right_arm.send_command(emergency_cmd) except: pass # 即使发送失败也要继续执行 # 释放夹爪 try: self.left_gripper.open(speed100) self.right_gripper.open(speed100) except: pass print(系统已进入安全状态) def _check_collision_risk(self, arm, target_pose): 检查目标位置是否可能发生碰撞 # 获取当前关节角度 status_cmd {command:get_joint_status}\r\n response arm.send_command(status_cmd) if response: try: current_joints json.loads(response).get(joint, []) # 简单的碰撞检测逻辑 # 在实际应用中这里应该使用更复杂的碰撞检测算法 collision_risk False # 检查关节限位 joint_limits [ (-180000, 180000), # J1 (-120000, 120000), # J2 (-150000, 150000), # J3 (-180000, 180000), # J4 (-120000, 120000), # J5 (-180000, 180000) # J6 ] for i, (current, target, (min_limit, max_limit)) in enumerate( zip(current_joints, target_pose, joint_limits) ): if target min_limit or target max_limit: print(f警告: 关节{i1}目标位置{target}超出限位[{min_limit}, {max_limit}]) collision_risk True # 检查关节速度是否过大 delta abs(target - current) if delta 30000: # 30度 print(f警告: 关节{i1}运动幅度过大: {delta}度) collision_risk True return collision_risk except: return True # 解析失败时保守起见认为有风险 return True # 获取状态失败时认为有风险5. 调试技巧与性能优化即使代码逻辑正确在实际运行中也可能遇到各种问题。下面分享一些我在开发医疗工作站Demo时积累的调试经验和优化技巧。5.1 常见问题与解决方案医疗工作站开发中常见的问题可以分为几类连接问题、运动控制问题、末端工具问题。下面这个表格整理了我遇到的一些典型问题及解决方法问题类别具体现象可能原因解决方案连接类频繁断开连接网络干扰或带宽不足使用专用网络交换机、优化心跳包频率运动类轨迹不流畅速度参数设置不当降低运动速度、增加加速度渐变精度类重复定位精度差机械臂未校准或温度影响定期进行零点校准、预热机械臂工具类夹爪动作异常Modbus通信干扰增加指令间隔、添加错误重试机制同步类双臂动作不同步网络延迟或指令时序问题使用时间戳同步、添加等待确认机制5.2 性能优化建议医疗工作站对实时性和可靠性要求很高以下优化措施能显著提升系统性能网络通信优化class OptimizedRobotController(RobotController): def __init__(self, ip_address, port8080): super().__init__(ip_address, port) self.command_buffer [] self.max_buffer_size 10 self.last_send_time 0 self.min_interval 0.02 # 50Hz最大发送频率 def send_command_optimized(self, command): 优化后的指令发送避免网络拥塞 current_time time.time() # 检查发送间隔 if current_time - self.last_send_time self.min_interval: time.sleep(self.min_interval - (current_time - self.last_send_time)) # 发送指令 result self.send_command(command) self.last_send_time time.time() return result def send_batch_commands(self, commands): 批量发送指令减少网络往返 if not commands: return [] # 将多个指令打包发送如果协议支持 batch_cmd { command: batch, commands: commands } return self.send_command(json.dumps(batch_cmd) \r\n)运动轨迹平滑处理def smooth_trajectory(waypoints, smoothing_factor0.3): 使用滑动平均平滑轨迹点 if len(waypoints) 3: return waypoints smoothed [waypoints[0]] # 保持起点不变 for i in range(1, len(waypoints)-1): prev waypoints[i-1] curr waypoints[i] next_pt waypoints[i1] # 加权平均 smoothed_pt [] for j in range(len(curr)): value (prev[j] * smoothing_factor curr[j] * (1 - 2*smoothing_factor) next_pt[j] * smoothing_factor) smoothed_pt.append(int(value)) smoothed.append(smoothed_pt) smoothed.append(waypoints[-1]) # 保持终点不变 return smoothed5.3 日志记录与监控完善的日志系统对于调试和故障排查至关重要。我建议实现一个分级的日志系统import logging from datetime import datetime class MedicalWorkstationLogger: def __init__(self, log_levellogging.INFO): self.logger logging.getLogger(MedicalWorkstation) self.logger.setLevel(log_level) # 文件处理器 file_handler logging.FileHandler( fmedical_workstation_{datetime.now().strftime(%Y%m%d_%H%M%S)}.log ) file_handler.setLevel(logging.DEBUG) # 控制台处理器 console_handler logging.StreamHandler() console_handler.setLevel(log_level) # 格式化器 formatter logging.Formatter( %(asctime)s - %(name)s - %(levelname)s - %(message)s ) file_handler.setFormatter(formatter) console_handler.setFormatter(formatter) self.logger.addHandler(file_handler) self.logger.addHandler(console_handler) def log_command(self, arm_name, command, response, successTrue): 记录指令执行情况 level logging.INFO if success else logging.ERROR self.logger.log(level, f{arm_name} - 指令: {command[:50]}...) self.logger.log(level, f{arm_name} - 响应: {response[:100] if response else 无响应}) def log_motion(self, arm_name, from_pose, to_pose, duration): 记录运动信息 self.logger.info( f{arm_name} - 从 {from_pose} 移动到 {to_pose}, 耗时: {duration:.2f}秒 ) def log_error(self, error_msg, traceback_infoNone): 记录错误信息 self.logger.error(f错误: {error_msg}) if traceback_info: self.logger.error(f堆栈跟踪: {traceback_info}) def log_system_status(self, left_arm_status, right_arm_status): 记录系统状态 status_msg ( f系统状态 - 左臂: {left_arm_status}, f右臂: {right_arm_status}, f时间: {datetime.now().strftime(%H:%M:%S)} ) self.logger.info(status_msg)5.4 实际部署注意事项当Demo开发完成后准备在实际医疗工作站部署时还需要考虑以下几个实际问题环境适应性医疗环境可能有电磁干扰建议使用屏蔽网线并在代码中添加抗干扰重试机制。安全冗余除了软件急停必须配置硬件急停按钮。我在每个机械臂工作区域都安装了物理急停开关。校准维护制定定期校准计划。机械臂的零点会随时间漂移建议每周进行一次快速校准每月进行一次完整校准。操作员培训开发一个简化的操作界面让医疗人员能够安全地启动、停止和监控系统。可以考虑用PyQt或Web界面实现。数据备份所有运动轨迹、操作记录和系统日志都应该自动备份。我通常设置每天凌晨自动备份到网络存储。在代码层面我习惯添加一个配置管理系统让医院的技术人员能够调整参数而不需要修改代码import json import os class WorkstationConfig: def __init__(self, config_fileconfig/workstation_config.json): self.config_file config_file self.default_config { network: { left_arm_ip: 192.168.1.18, right_arm_ip: 192.168.1.19, port: 8080, timeout: 5.0, retry_count: 3 }, motion: { default_velocity: 50, precision_velocity: 10, acceleration: 0, jerk: 0 }, grippers: { left_port: 1, right_port: 0, default_speed: 80, default_force: 50, max_force: 80 }, safety: { collision_check: True, emergency_stop_delay: 0.1, max_joint_speed: 100, min_safe_distance: 50 }, positions: { home_left: [0, 30000, -120000, 0, 90000, 0], home_right: [90000, -90000, 90000, -90000, 90000, -30000], sample_pick: [671, 20176, -140953, 31515, 86934, -87] } } def load_config(self): 加载配置文件如果不存在则创建默认配置 if os.path.exists(self.config_file): with open(self.config_file, r, encodingutf-8) as f: return json.load(f) else: self.save_config(self.default_config) return self.default_config def save_config(self, config): 保存配置到文件 os.makedirs(os.path.dirname(self.config_file), exist_okTrue) with open(self.config_file, w, encodingutf-8) as f: json.dump(config, f, indent4, ensure_asciiFalse) def update_config(self, section, key, value): 更新特定配置项 config self.load_config() if section in config and key in config[section]: config[section][key] value self.save_config(config) return True return False这个配置系统让现场工程师能够通过修改JSON文件来调整系统参数而不需要接触Python代码大大降低了维护难度。最后记得在实际运行前进行充分的测试。我通常按照这个顺序进行测试单轴运动测试 → 多轴协调测试 → 末端工具测试 → 完整流程测试。每个测试阶段都要记录数据特别是重复定位精度和运动时间这些数据对优化工作流程很有帮助。