当前位置:首页 > 工业控制 > 电路设计项目集锦
[导读]上一次我输掉井字棋时,还是七岁。昨天我又输了一次——这次是输给了一只成本不到一把普通办公椅的四轴机器人手臂。这就是我如何教会我的myPalletizer 260识别纸板、决定最佳落子位置,并在没有任何位置传感器、棋子本身没有固定标记、也没有作弊的情况下,拿起自己的棋子并放入正确位置的故事。仅需一台摄像头、几个ArUco标记和大约200行Python代码。

上一次我输掉井字棋时,还是七岁。昨天我又输了一次——这次是输给了一只成本不到一把普通办公椅的四轴机器人手臂。这就是我如何教会我的myPalletizer 260识别纸板、决定最佳落子位置,并在没有任何位置传感器、棋子本身没有固定标记、也没有作弊的情况下,拿起自己的棋子并放入正确位置的故事。仅需一台摄像头、几个ArUco标记和大约200行Python代码。

我们构建的内容

一个完全自主的井字棋对手。设置很简单:myPalletizer 260放置在一张打印好的3×3棋盘旁边,一台网络摄像头朝下拍摄桌面,一侧还放着一小堆木制棋子。人类玩家执X(手动将棋子放在棋盘上),机器人玩家执O——它通过摄像头观察棋盘,利用最小极大算法计算出最佳回应,然后拿起自己的棋子并放入正确的格子中。

这个项目之所以有趣,主要有两点原因:

1. 这是一个完整的流程。视觉、规划和运动必须协同工作,这能让你了解到每一层可能出现问题的具体位置。

2. 令人满足。当手臂将棋子放在你预想的位置,挡住你的必胜走法时,那种“机器知道我在做什么”的瞬间总是让人回味无穷。

工作原理

该系统分为三层,每一层都值得单独理解:

1. 愿景——将相机画面转换为3×3的棋盘状态

2. 脑 — 使用极小极大算法选择最佳走法

3. 移动——拿起一块并放入目标细胞

让我们逐一说明。

1. 愿景:使用ArUco标记识别棋盘

任何实体游戏最困难的部分就是:棋子在哪里?颜色检测不可靠(如阴影、红色棋子出现在红色方格上),而模板匹配又难以应对旋转问题。因此,我干脆跳过了“检测棋子”的难题——我在每个木制棋子的顶部粘贴了一个小型印刷的ArUco标记。X和O分别采用不同的标记ID,这样一来,检测问题便迎刃而解。

OpenCV的ArUco模块在正常光照条件下可提供亚像素级精度,无需考虑旋转,并能报告每个标记的ID。这意味着只需一次函数调用,就能同时知道棋盘上有哪些棋子以及它们各自的位置。

但等等——代码是如何确定每个棋子所在的具体格子的呢?我采用了一步小型校准。启动时,我会将9个标记精确放置在棋盘对应位置,按“s”键,脚本便会记录下这些标记的像素位置。从此之后,每个被检测到的棋子都会被分配到最近的“虚拟槽位”。这样,物理校准板就可以清空,替换为打印好的网格,而像素位置则会锁定在内存中。

这个技巧对于任何“棋盘游戏”项目都值得借鉴。它无需使用完整的角点同构变换,可与任何可打印的网格配合使用。

2. 大脑:20行代码的极小极大算法

极小极大(Minimax)是双人零和博弈的经典算法。用通俗的话来说:机器人假设人类总是会做出最优选择,然后选择那个最坏结果最好的行动。

井字棋仅有约25.5万个可能的游戏状态,因此我们可以在毫秒内搜索完整个树状结构。无需剪枝,也无需启发式方法。以下是完整的实现:

从上到下阅读:在每个终止状态下,如果机器人获胜返回+1,如果人类获胜返回-1,平局返回0。在每个内部节点,我们递归处理——机器人回合时取最大值,人类回合时取最小值。机器人所选的行动就是极小极大得分最高的那一步。仅此而已。这就是整个AI系统。

3. 运动:四自由度拾取与放置

myPalletizer 260 是一个四轴托盘堆垛臂,包含 X、Y、Z 和 yaw 四个轴。这实际上非常适合本项目,因为井字棋棋子不需要复杂的腕部姿态调整,只需将设备移动到格子上方,然后垂直向下放置即可。

九个板面格子和拾取堆叠位置的坐标均为我手动测量后硬编码的值。我使用真空泵(通过树莓派 GPIO 引脚 20 和 21 控制)来抓取棋子。每次移动的运动顺序如下:

1. 将鼠标悬停在拾取堆上方

2. 下降,打开泵

3. 将部件抬起至移动高度

4. 移动到目标单元格上方的悬停位置

5. 下降,关闭泵

6. 返回悬停状态

我用亲身经历学到了一件事:不要急于入睡。当机械臂尚未完全就位,而你提前关闭泵时,部件就会在板子上滑动。比起快速且剧烈的动作,可靠和缓慢的处理方式更稳妥。

组装全部内容

主循环最乏味的部分就是:从相机读取棋盘信息,检查胜平局,运行最小极大值算法,执行拾取放置,等待人类回合(通过检测“棋盘上有新的X”来识别),然后重复。

这就是整个游戏流程。

让我出错的地方

标记尺寸与相机距离的问题。我的初始零件标记为8毫米,而相机在40厘米外无法分辨它们。将标记调整为15毫米后,检测立即变得稳定。如果你遇到检测不准确的情况,不要调整HSV参数——只需打印更大的标记即可。

硬编码坐标漂移。如果棋盘移动哪怕几毫米,机械臂都会将零件放置在格子之间的线上。未来可以改进的是使用像素到毫米的仿射变换,使代码能适应棋盘位置变化——但对于固定设置而言,硬编码已经足够。

泵的定时问题。见上文。真的,再增加500毫秒的时间。

“机械臂总是停留在泵上。”在260型号中,泵会卡在最后一个关节处。如果你发送了一个Z值较低的坐标,却忘了当前偏航方向不正确,机械臂就会自动调整。务必先缓慢测试每一个新坐标。

亲测体验

所有代码都托管在GitHub上。克隆代码,安装pymycobot和OpenCV,30分钟内你就能拥有一台会玩井字棋的机器人了。即使你没有自己的myPalletizer 260,视觉识别和最小极大值算法代码也能直接应用于任何4个以上自由度的机械臂——只需替换send_coords调用和泵的开关即可。

如果你自己动手制作了一台,记得给我打标签——我很期待看到你的作品。而且,如果机器人战胜了你,至少你输给了你自己造出来的机器。

本文编译自hackster.io

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭