21| 12
|
[项目] 【Arduino 动手做】我制作了一个魔方解算器,5秒解开它... |
## 立方体适配器 我设计这台机器的首要目标是找到一种方法来转动魔方的每一面。考虑到魔方需要精确的转动,使用步进电机驱动是必须的。我还知道,为了快速还原,每一面都需要独立转动,换句话说,魔方的每一面都需要一个独立的步进电机。最合理的方案是制作一个转接件连接到魔方每面的中心。我用美工刀从每个面的中心切下瓷砖,然后设计了魔方转接件。魔方转接件的轮廓与瓷砖相同,以便它们可以连接到魔方上。您会注意到,转接件有两种类型:一种是四面封闭的,另一种是带开口的。这样做是为了方便将魔方放入机器或从机器中取出。 ![]() ![]() |
步进电机/驱动器 该机器使用6个额定电压为24V的Nema-17 59Ncm步进电机。我使用6个TMC2208步进驱动器来驱动电机。这些驱动器非常安静。它们通常可以在3D打印机的静音主板上找到。事实上,它们和我的3D打印机中使用的是一样的。对于这些驱动器,我使用的是最低的微步进级别,即1/2微步进(400步/转)。这些驱动器最高可以达到1/16微步进(3200步/转),但精度越高,最高速度就越慢。由于这些步进电机每次只能旋转90°或180°,因此400步/转就足够了。 ![]() ![]() |
## 编程(Arduino IDE) 编程解算器主要包含三个部分。首先,需要有一种方式从用户那里获取魔方的配置。其次,也是最重要的,计算机需要能够解算魔方并保存步骤。最后,需要有一种方式将这些步骤转换成一系列步进电机动作来解算魔方。 Web 服务器 最初,我想利用摄像头视觉来检测魔方上每个方块的颜色,但我当时的 pixy2 摄像头准确率并非 100%,更不用说用单个摄像头扫描魔方六个面的挑战了。于是,我转而开发一个 Web 服务器。使用 Teensy 4.1 的另一个优势是它支持以太网。购买 Teensy 4.1 以太网套件后,我创建了一个 HTML Web 服务器,它配备了以下功能: 立方体所有侧面的显示均带有按钮,允许用户手动设置每个图块的颜色。 能够旋转魔方的某一面,并实时更新魔方显示。此功能可用于对魔方进行打乱。 重置立方体显示以显示完全解决的立方体的选项。 一个按钮用于配置,然后显示在当前配置下解决魔方所需的总移动次数。 解决物理魔方的开始按钮。 显示解决物理魔方所用的时间(不实时更新) 如果用户定义的立方体配置不合理,则可防止输入错误。每个立方体在任意时刻都恰好包含每种颜色的 9 个方块。如果用户定义的立方体否定了此参数,则“开始”和“配置”按钮将无法点击。 ![]() ![]() ![]() |
魔方求解算法。 整个项目的关键在于魔方解题算法的有效性。创建这个算法实际上是我做这个项目的第一件事,花了几周时间才完成。魔方有430亿亿种不同的解题方法。计算机需要能够解出其中任何一种解题方法。难点在于,在算法每个步骤都有多种可能的情况下,找到绝对最快的解题方法。 虚拟立方体和符号 为了分析和操作魔方,计算机需要一个物理魔方的虚拟表示。由于每个魔方有 6 条边,每条边有 9 个方块,因此虚拟魔方被表示为一个 6 x 9 的矩阵。矩阵中的每个元素都是一个字符,代表该方块的颜色(例如,红色 = 'R',白色 = 'W',等等)。我还创建了自己的符号,用于表示矩阵中的哪些行对应于魔方的哪些面,以及矩阵中的哪些列对应于特定面上的方块位置。例如,如果魔方已完全解开,则打印数组中元素[2][5]的字符将返回“W”,因为正面(第 2 行)位置 5(第 5 列)的方块是白色的。同样,打印元素[0][7]将返回“R”,因为该方块是红色的。 旋转虚拟立方体 算法必须能够翻转虚拟魔方的某一面才能解开它。计算机通过变换矩阵来实现这一点。编写代码来实现这一点类似于向人们描述翻转实体魔方时会发生什么。你很可能会告诉他们以下观察结果: 立方体的 4 个侧面失去 3 个方块,并从另一侧面获取 3 个方块。 被转动的一侧保留其所有瓷砖,但重新排序。 被转动一侧的正对面没有任何变化。 每面的中心瓷砖都不会离开其位置。这就是为什么这些面都以中心瓷砖的颜色来标记。例如,黄色面就是黄色瓷砖位于中心的那一面。 ![]() ![]() |
这四条规则适用于任何翻转魔方的面的情况。算法中有一组指令,用于确定翻转某一面时哪一面应该丢失哪些方块,以及哪一面应该使用哪些方块。每当虚拟魔方需要翻转某一面时,都会参考这些规则,并根据需要重新排序矩阵。 算法尝试 #1(初学者方法) 我最初的算法是用初学者的方法解开了魔方,这也是我学习解魔方的方法。这个方法有8个步骤: 第一步:制作雏菊 第 2 步:创建白色十字架 步骤3:解决第一层 步骤 4:解决第二层 步骤5:创建黄色十字 第六步:解决黄色面 步骤 7:定位角 步骤 8:定位边缘 虽然这个算法有效,但我最终没有使用它,原因有二。首先,它平均每次解开魔方需要超过100步。与那些能在60步以内解开魔方的速成魔方玩家相比,这个速度相当高。其次,我用来创建雏菊图案的方法并不有效。我没有使用具体的操作,而是简单地编写了算法,让它在魔方的随机侧面进行数千种策略性旋转的组合,希望能将所有四个棱块移动到位。这种方法有效,但有时需要花费几秒钟的计算时间,因为它无法找到一组可以立即奏效的移动方式。 算法尝试 #2(CFOP 方法) 我决定研究一下速解魔方的真正技巧,然后偶然发现了CFOP方法。这个方法只包含4个步骤: 第一步:白十字 第 2 步:F2L(前 2 层) 步骤3:OLL(黄脸) 步骤4:PLL(最后一层) 使用这种方法,魔方爱好者每次解题平均移动不到60步。这主要是因为CFOP方法构建前两层的方式与初学者方法不同。初学者方法按顺序构建第一层和第二层,而CFOP方法则同时构建这两层。我决定自己学习这种方法,然后创建第二个更有效的算法。CFOP算法的效果符合预期,平均每次解题移动约75步。在解完CFOP方法的每个步骤后,算法会将移动记录到一个数组中。 步进电机控制 创建步进电机控制相当简单。解算过程中的每一次移动都会使魔方的一侧向相反方向旋转一次、两次或一次。我使用 AccelStepper Arduino 库来控制步进电机。代码中的一个函数会遍历每个移动,确定要启动哪个步进电机,然后启动该步进电机,最后继续下一步移动。每次只移动一个步进电机。 通用代码概述 事件的大致流程如下: 用户在网络服务器上手动定义多维数据集。 当用户点击开始时,魔方解决算法会在一瞬间解决魔方并记录所采取的移动。 每次移动都会被输入到步进电机控制函数中,该函数决定移动哪个步进电机。这个过程一直持续到魔方被解开。 ![]() |
结果 最快解题速度:4.56 秒内 50 步(≈10.87 步/秒) 步进电机最高速度:1380 步/秒 平均求解时间(以最快速度进行 11 次试验):5.66 秒 20 次试验中每次求解的平均移动次数:75 世界纪录(用于背景) 人类世界纪录(截至 2023 年 3 月):3.47 秒(由杜宇胜于 2018 年创造) 机器世界纪录(截至 2023 年 3 月):0.38 秒(由麻省理工学院的 Ben Katz 和 Jared Di Carlo 制造的机器) 顶级职业魔方玩家可以在10秒内解开一个魔方,平均每秒旋转10圈。考虑到这一点,我可以肯定地说,我的魔方虽然不是最快的,但也和顶级速解魔方玩家一样好。 前进 总的来说,我对这个项目的成果非常满意。我绝对计划将来再重新审视这个项目,因为还有很多可以改进的地方。我预计,如果修改得当,这台机器可以在 2 秒内解开魔方。以下是我希望在未来的迭代中改进的地方(按优先级排序): 更好的算法:我目前的算法缺乏预见性:无法判断以某种方式解开某个步骤是否会影响后续的总步数。更强大的算法应该能够运行多种解开魔方的组合,然后进行比较。或许也值得研究其他解魔方方法,例如 ZZ 或 ROUX。更强大的算法本身就能减少每次解魔方所需的时间。 自动立方体配置:我想使用摄像头或某种颜色检测传感器,这样就不必手动配置立方体了。每次输入这些信息都很麻烦,尤其是在测试的时候。 魔方:这个版本我没有用魔方,这可能是我经常卡住的原因。魔方的设计初衷是高速旋转,并且还具有切角功能,即使魔方没有完全对准,也能防止卡住。 更好的步进电机/驱动器: CNC 级步进电机和更优质的驱动器将使这个项目更上一层楼。更大的扭矩和更高的速度,让我能够提升机器的物理极限。更大的扭矩尤其有利于减少卡机现象。 ![]() |
© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed