构建一个能解决数学题的机械臂:使用PaddleOCR进行识别
1. 我为何构建这个系统
我希望打造一个紧凑的演示项目,同时整合三方面内容:计算机视觉、机器人操作以及少量“推理”功能。手写数学题是一个理想的测试对象——人类书写起来方便,光学字符识别(OCR)处理起来有趣,输出结果还能直接映射为一个单一数字,对应一个拾取与放置动作。
我特意选择了MyPalletizer 260,因为它是一款四自由度的托盘堆垛机械臂。它的腕部仅围绕Z轴旋转,因此不存在需要特别处理的腕部翻转奇点问题。对于俯视式拾取与放置任务而言,这实际上比通用的六自由度机械臂更容易操作——逆向运动学(IK)始终不会出错。
2. 工作原理(方框图)
• 区域A — 手写区域。机械臂以观察姿势停靠,摄像头读取输入文本,PaddleOCR返回带有置信度分数的字符框,Python根据运算优先级(*、/、//)计算表达式。
• 区域B — 数字卡托盘。机械臂以第二个观察姿势停靠,PaddleOCR定位目标数字,通过同源变换将像素中心转换为机械臂坐标,随后泵体抓取该数字。
3. 实现该方法的关键技巧:像素 → 手臂坐标
核心问题在于:给定相机图像中的一个像素点 (u, v),该点在机械臂的基坐标系中位于何处?
由于工作空间是平面的(平坦的垫板),且相机姿态固定,因此映射关系是一个二维同源变换——每个区域对应一个3×3矩阵H:
[x_robot] [u]
[y_robot] = H × [v]
[ 1 ][1]
我通过在每个区域放置棋盘格、使机械臂移动到四个已知角落,并在每个角落输入机械臂的XY读数,来对矩阵H进行一次校准。在我的设备上,残差小于2毫米,这完全符合30毫米数字卡和吸盘的公差范围。
[图片 — 棋盘格放置在工作台上,机械臂悬停在其中一个角落上方]
4. 硬件设置
1. 将 MyPalletizer 260 安装在前方有空隙的坚固表面上。
2. 将吸泵连接到末端执行器上。调整气管路径,避免在运动过程中拉动臂部。
3. 将泵的控制线路连接到臂的输入/输出端口:
– –第5针 — 阀门(0 = 打开,1 = 关闭)
– –第2针 — 释放脉冲(使卡片完全落下)
4. 将USB摄像头安装在三脚架上,位置距离工作区约35厘米,朝下直视。固定对焦非常重要——自动对焦会破坏你在校准和运行时的同构映射关系。
5. 将工作区分为左侧的A区(手写)和右侧的B区(数字卡片)。
5. 软件安装
在 Windows 上,ARM 设备会显示为 COM 端口;在 Linux 和树莓派上通常为 /dev/ttyUSB0 或 /dev/ttyAMA0。
6. 标定
相机内参 — 一次性操作。打印一个棋盘格,以不同角度拍摄约15张图像,并使用OpenCV的cv2.calibrateCamera函数将mtx和dist保存到camera_params.npz文件中。
平面映射(区域A和区域B)——这是关键部分。对于棋盘格的四个外角中的每一个:
1. 将手臂移动,使末端执行器位于角落上方。
2. 从终端读取手臂当前的XY坐标。
3. 点击相机窗口中的相同角落。
脚本使用 cv2.findHomography 求解 H,并将其写入 plane_mapping.json(区域 A)或 plane_mapping_B.json(区域 B)。对两个区域重复此操作。
7. 代码解析
7.1 连接与配置
7.2 吸气泵(与MyCobot版本相同的I/O)
7.3 带超时的运动辅助功能
SDK中的is_moving()有时会在轨迹结束时报告“仍在移动”。通过设置超时回退机制,可防止状态机卡住:
7.4 OCR — 读取手写方程式
然后构建表达式并进行求值:
(在生产系统中,我会用合适的分词器替换eval。对于演示平台的白名单[0-9+\-*/],这是可以接受的。)
7.5 像素 → 手臂坐标
7.6 取放循环(托盘机形式)
7.7 主循环
8. 挑战与经验教训
• 自动对焦是大敌。我的第一台相机在标定和运行时反复重新对焦,无声地导致了H值无效。固定对焦的USB相机值得多花那10美元。
• 操作员符号是OCR的薄弱环节。例如:− vs 一 vs −,× vs x。detect_and_recognize中的字符规范化模块确实物有所值。
• 四自由度(4-DOF)是一种优势,而非限制。没有手腕翻转的奇异点,也没有逆向运动(IK)卡顿问题。对于俯视式拾取放置,托盘分拣机比六自由度机械臂更易于操作。
• 始终添加运动超时功能。is_moving()有时会在轨迹末端出现假阳性;使用wait_move_safe()可防止状态机冻结。
• 两个区域胜过一个。将手写区和卡片区合并为单一摄像头视野看似优雅,但为整个空间统一校准同一线性变换后,边缘处残差反而变差。两个独立区域各自拥有独立的H矩阵,方案更简单且更精确。
9. 下一步
• 支持括号和最多三位数的多数字答案(链式选择——上方循环已实现2位数)。
• 用合适的分词器替换 eval。
• 对儿童手写文本对 PaddleOCR 进行微调。
• 在机械臂移动前添加一个小屏幕,显示解析后的方程式——便于演示,并可在机械臂执行前发现 OCR 错误。
本文编译自hackster.io





