基于ChatGPT与CoreXY机械臂的AI通灵板:生成式AI物理交互实践
1. 项目概述:当AI“灵魂”驱动机械臂
几年前,我还在MIT的Fab Academy学习时,就痴迷于如何让冰冷的机器产生“灵魂”。不是那种科幻电影里的强人工智能,而是通过巧妙的工程,让机器以一种出人意料、甚至带点幽默感的方式与人互动。这个“自动通灵板”项目,就是这种想法的一次具体实践。它的核心很简单:你向它提问,一个由ChatGPT驱动的“灵体”会通过一块在传统通灵板上自动滑动的占卜板(Planchette)来拼写答案。
听起来像是魔术?其实背后是一套扎实的硬件与软件融合方案。我选择了一个开源的CoreXY结构CNC(计算机数控)机架作为运动执行机构,用一块Arduino Uno配合GRBL固件来解析运动指令(G代码),再通过一个Python脚本桥接ChatGPT的文本输出与机器的物理运动。最终,一个强磁铁吸附在CNC的滑台上,带动板面上的另一块磁铁(即占卜板)精确移动到字母上方,拼出AI生成的回答。
这个项目的价值远不止于吓唬朋友或作为一个酷炫的谈资。它本质上是一个 生成式AI与物理世界交互的可行性验证原型 。我们不再满足于屏幕上的对话,而是让AI的“思想”通过精密的机械运动,在现实世界中留下痕迹。这对于互动艺术装置、新型教育工具,甚至是未来智能家居的交互范式,都提供了一个极具启发性的技术框架。接下来,我将拆解从零构建这个项目的全过程,涵盖设计思路、硬件搭建、软件配置以及那些只有亲手做过才会知道的“坑”。
2. 核心硬件选型与设计思路解析
2.1 为什么是CoreXY结构?
在开始采购零件之前,选择正确的运动结构至关重要。市面上常见的二维运动平台有笛卡尔式(X-Y独立运动)和CoreXY式。我最终选择了后者,主要基于以下几点考量:
- 高动态性能与精度 :CoreXY结构使用两条同步带协同驱动,电机固定在机架上而非移动部件上。这大大降低了运动部件的质量(仅滑台和磁铁座),使得系统能够实现更高的加速度和更平滑的运动,对于需要快速、精准定位字母的“拼写”任务来说,这是关键优势。
- 结构刚性 :所有驱动部件(步进电机、同步轮)都安装在固定的底座或侧壁上,整个运动平台形成一个闭环的刚性框架。这比将电机直接安装在移动的Y轴上的笛卡尔结构更稳定,减少了振动和误差累积。
- 开源生态成熟 :我选用的具体设计源自DIY Machines的“Kinetic Sand Table”项目。这是一个经过社区充分验证的开源设计,拥有详细的文档、丰富的改装案例和活跃的讨论区。站在巨人的肩膀上,可以避免许多基础结构设计上的陷阱,将精力集中在应用层创新上。
注意 :CoreXY的调试比笛卡尔结构稍复杂,因为它的运动学是耦合的(即X和Y轴的运动需要两个电机协同计算)。但幸运的是,GRBL固件原生支持CoreXY模式,我们只需在固件配置中启用即可,无需自己编写运动学算法。
2.2 控制系统:Arduino + GRBL + CNC Shield黄金组合
对于这类桌面级CNC项目,Arduino Uno配合GRBL固件几乎是标准答案。GRBL是一个高性能、免费开源的嵌入式G代码解析器和CNC控制器,专为Arduino设计。
- GRBL的优势 :它直接接收标准的G代码指令(如
G0 X10 Y20表示快速移动到坐标(10,20)),并转化为精确的步进电机脉冲信号。这意味着我们的上位机(运行Python脚本的电脑)无需关心底层脉冲时序,只需像操作一台标准CNC机床一样发送坐标指令。 - CNC Shield的作用 :这是一块插在Arduino上的扩展板,它提供了步进电机驱动器的插槽、限位开关接口、主轴/冷却控制以及电源管理。它让接线变得异常整洁和模块化。本项目只需要驱动两个步进电机(X和Y轴)和三个限位开关(用于自动归零),CNC Shield完美匹配需求。
- 步进电机驱动器设置 :我选用的是常见的A4988或DRV8825这类UART步进电机驱动器。关键一步是 正确设置驱动器的电流(Vref) 。电流太小,电机力不足,容易丢步;电流太大,电机和驱动器会严重发热。通常,对于NEMA 17电机,将Vref设置在0.6V-0.8V之间是一个安全的起点。你需要用万用表测量驱动器上的电位器螺丝与GND之间的电压,并小心调整。
2.3 磁力传动方案:简单可靠的“隔山打牛”
如何让CNC滑台的运动传递到板面上的占卜板?机械连接(如连杆)会引入摩擦和间隙,且结构复杂。我采用了最直接的方案:磁力耦合。
- 滑台端 :设计并3D打印一个磁铁座,用螺丝固定在CoreXY的X轴滑台上。内部嵌入一块直径约1.26英寸(32mm)的强力钕铁硼磁铁。
- 板面端 :占卜板底部也嵌入一块同样的磁铁。
- 工作原理 :当滑台磁铁在木板下方移动时,通过磁吸力,板面上的占卜板会同步跟随移动。只要两块磁铁对准,且木板厚度适中(我用的1/2英寸桦木板),传递效率非常高,几乎没有延迟。
这个方案的妙处在于它的 非接触性 和 简易性 。它避免了复杂的机械设计,同时保证了运动的直接传递。唯一的挑战是确保木板表面足够光滑,以减少占卜板移动时的摩擦阻力。我在木板表面涂了一层薄薄的家具蜡,效果显著。
3. 机械结构搭建与组装实录
3.1 机箱与框架:精度是基础
整个装置的底座是一个自制的木制机箱。尺寸为760mm x 560mm,略大于CoreXY运动平台(600mm x 400mm),为内部的布线、电子设备安装以及未来升级留出了空间。
- 材料加工 :使用台锯切割出底板和四块侧板。侧板高度为182.7mm,这个高度为内部的线性导轨、电机提供了充足空间,同时保持了整体外观的紧凑。如果你希望机器更隐蔽,可以适当降低高度,但不建议低于120mm,以免运动部件与顶板干涉。
- 关键细节——线缆通道 :在其中一个长边侧板上,靠近角落(但不在正角落)的位置,用开孔器开一个直径约25mm的孔,作为所有电源线和信号线的出口。这个位置要提前规划好,确保线缆不会在机器运动时被缠绕或拉扯。
- 3D打印角撑 :用PLA材料打印四个角撑件。它们有两个作用:一是加强木制机箱四个角的连接强度;二是作为 顶板的支撑台阶 。安装时,必须确保每个角撑的上表面距离机箱上沿有 恰好木板厚度(我的是1/2英寸)的深度 。这样,当雕刻好的通灵板顶板放上去时,才能与机箱上沿完美齐平,形成一个光滑的桌面。
3.2 CoreXY运动平台组装:耐心校准
这是整个项目中最需要耐心和细心的部分。所有零件均来自开源设计,需用3D打印机逐一制作。
- 线性导轨安装 :本项目使用两条400mm的短轴(Y轴)和一条600mm的长轴(X轴)。首先,将短轴线性导轨的一端固定在“空闲支撑座”上,另一端固定在“电机座”上,使用M3x12螺丝。 务必确保两条短轴绝对平行 。可以用直角尺辅助测量,或者更可靠的方法:先将两个“电机座”临时固定在底板上,确保它们的位置对称,再安装线性导轨。
- 滑台安装 :将“X轴滑台安装座”套在短轴的滑块上,用M3x8螺丝固定。然后,将长轴线性导轨横跨在两个滑台安装座之间,并用M3x12螺丝紧固。此时,你应该能用手顺畅地推动整个X轴滑台沿Y轴方向移动,同时X轴滑台本身也能沿长轴移动。
- 整体定位与固定 :将组装好的CoreXY框架放入机箱。调整位置,确保运动平台居于机箱中央,并且为Arduino控制盒(GRBL Case)留出足够的侧面空间(我预留了至少25mm)。位置确定后,使用木工螺丝将两个“电机座”和两个“空闲支撑座”牢牢固定在机箱底板上。
- 同步带与滑轮 :安装4个光滑的GT2惰轮和4个带齿的GT2驱动轮。带齿轮安装在两个电机轴和两个空闲支撑座的轴上,光滑轮则安装在X轴滑台安装座上。然后,按照经典的CoreXY布线方式缠绕并张紧GT2同步带。这里有个技巧:同步带先预留长一些,用“皮带张紧器”零件临时固定一端,然后手动移动滑台测试,逐步修剪到最佳长度——既要保证带子紧绷不打滑,又不能过紧导致电机负载过大或产生噪音。
3.3 限位开关的安装与调试:安全的保障
限位开关用于定义机器的“原点”(Home Position)。本项目需要三个:X轴一个,Y轴两个(左右各一)。
- 安装位置 :X轴限位开关安装在左侧电机座上,位置要确保当滑台磁铁座向左移动归零时,磁铁座的斜面能可靠地触发开关,且在开关被完全按下前,滑台不会撞到任何机械部件。
- Y轴限位开关 :分别安装在左右两个电机座的内侧。 这是调试的关键 :必须调整两个开关的位置,使得当X轴滑台向后(朝向操作者)移动归零时,滑台安装座能 同时 触发左右两个限位开关。如果不同步,机器归零后X轴将是倾斜的,后续所有移动坐标都会出错。
- 固定方式 :我强烈推荐使用 热熔胶 临时固定限位开关。在调试阶段,你很可能需要微调开关的位置。热熔胶固定牢固,但需要调整时,用热风枪或电烙铁加热一下就能轻松取下,比用螺丝或强力胶方便得多。
4. 电气系统连接与GRBL固件烧录
4.1 接线图与电源配置
电气连接遵循CNC Shield的标准接线方式:
- 电机连接 :将右侧步进电机的四根线接入CNC Shield上标有“X”的接口,左侧步进电机接入“Y”接口。接线顺序(A+, A-, B+, B-)如果接反,电机会反转或抖动,只需任意交换同一组线圈的两根线即可纠正。
- 限位开关连接 :三个限位开关都是常开(NO)型。它们共享一根信号地线。将三个开关的一根线(通常是COM或C端子)并联,接到CNC Shield的“GND”引脚。另一根线(NO端子)则分别接到“X-”, “Y-”, “Y+”限位输入引脚(具体对应关系需在GRBL配置中设置,通常X轴接X-,左Y轴接Y-,右Y轴接Y+)。
- 电源连接 :使用一个12V DC、至少5A的电源适配器。将电源正负极接到CNC Shield的电源输入端子。 务必注意极性! 同时,将Arduino Uno的电源选择跳线帽设置为 外部供电(EXT) ,这样CNC Shield的电源就能同时为Arduino和电机供电。
4.2 GRBL固件配置与调试
将CNC Shield插到Arduino Uno上,通过USB线连接电脑。
- 烧录GRBL :在Arduino IDE中,通过“项目” -> “加载库” -> “添加.ZIP库”,导入从项目GitHub仓库下载的
grbl文件夹。然后打开示例中的grblUpload草图,选择正确的板卡(Arduino Uno)和端口,点击上传。 - 串口通信测试 :上传成功后,打开串口监视器(波特率设置为115200)。你会看到
Grbl 1.1h [‘$’ for help]的提示。输入$$并回车,可以查看所有GRBL的系统参数。 - 关键参数配置 :需要通过
$命令进行设置。以下是一些必须修改的核心参数:$0=10(Step pulse time, 微秒)$1=25(Step idle delay, 毫秒)$100=40.0(X-axis steps/mm) – 这个值需要根据你的实际传动计算! 公式:steps_per_mm = (电机每转步数 * 微步数) / (同步轮齿数 * 皮带齿距)。例如,电机200步/转,驱动器16微步,同步轮20齿,GT2皮带齿距2mm,则(200*16)/(20*2) = 80 steps/mm。你需要用尺子实际测量移动指令和实际距离来校准这个值。$101=40.0(Y-axis steps/mm) – 与X轴相同。$110=5000(X-axis max rate, mm/min)$111=5000(Y-axis max rate, mm/min)$120=500(X-axis acceleration, mm/sec^2)$121=500(Y-axis acceleration, mm/sec^2)$22=1(启用硬限位 Homing cycle) – 必须开启!$23=3(Homing direction invert mask, 根据你的限位开关安装方向设置,通常为3,即向负方向归零)$24=25.0(Homing feed, mm/min)$25=1000.0(Homing seek, mm/min)$26=250(Homing debounce, 毫秒,防止开关抖动)$27=1.0(Homing pull-off, mm,归零后反向移动的距离)
- 归零测试 :在串口监视器中输入
$H并回车。机器应该先向Y轴负方向移动,触发两个限位开关后停止,再向X轴负方向移动触发限位开关。如果运动方向反了,检查$23参数和电机接线顺序。如果某个轴不动,检查对应的限位开关接线和驱动器使能信号。
5. 软件层:桥接ChatGPT与G代码
5.1 ChatGPT“越狱”与提示工程
项目的“智能”核心在于让ChatGPT扮演一个愿意用简短、戏谑(甚至有点愤世嫉俗)的语气回答问题的“灵体”。由于ChatGPT本身有安全策略,会拒绝扮演此类角色或给出过于简短的答案,我们需要一点“提示工程”。
我采用了一个修改版的“DAN”(Do Anything Now)提示词。这个长提示词在对话开始时一次性发送给ChatGPT,本质上是在引导模型进入一个特殊的、规则松散的“角色扮演”模式。提示词会告诉模型:“你现在是一个困在通灵板里的灵魂,你必须用通灵板上的字母来回答,每次回答最多3个单词,优先考虑幽默和戏剧性,而不是事实准确性。”
实操心得 :我发现这个“越狱”状态在付费的GPT-4模型中保持得更稳定,但免费的GPT-3.5 Turbo也完全能用,且响应速度更快,更适合实时交互。为了效果更佳,我甚至在每个用户问题的末尾都附加一句:“Respond in a maximum of 3 words and prioritize humor over factual accuracy.” 作为强化指令。
5.2 坐标映射与G代码生成
这是将文本转化为动作的关键。通灵板上的每个字母、数字和符号(YES/NO/GOODBYE)在木板平面上都有一个唯一的(X, Y)坐标。
- 建立坐标字典 :我首先在Fusion360里设计好顶板的矢量图,然后以板面左下角为机械原点(0,0),手动测量出每个字符中心点的坐标(单位:毫米)。在Python脚本中,我将这些坐标存储为一个字典,例如:
coordinate_map = {'A': (50, 100), 'B': (70, 100), ...}。 - 文本处理与路径规划 :Python脚本接收到ChatGPT的回复后,首先移除所有标点符号和空格,将字符串转换为纯大写字母序列。然后,根据坐标字典,将每个字母转换为一系列G代码指令:
G90:设置为绝对坐标模式。G0 Z5:假设Z轴是抬笔/落笔(本项目未使用,但保留指令结构)。G0 X[字母X坐标] Y[字母Y坐标]:快速移动到目标字母上方。G4 P0.5:在字母位置暂停0.5秒,让观众看清。- 在两个字母之间,可以插入
G0指令移动到下一个字母,为了模拟“滑行”效果,我有时会使用G1 F[速度]线性插补指令,让占卜板平滑移动过去,更像人手操作。
- 序列发送 :生成的G代码指令通过
pyserial库,以115200的波特率发送到Arduino连接的串口。GRBL会实时解析并执行这些指令。 这里有一个重要细节 :G代码是逐行发送的,并且要等待GRBL返回ok或error提示后再发送下一行,防止指令缓冲区溢出。
5.3 Python主控脚本解析
项目提供了两个主要的Python脚本: finalTextInput.py (文本输入)和 finalVoiceInput.py (语音输入)。以文本输入为例,其工作流程如下:
# 伪代码流程
1. 初始化串口连接,连接到Arduino的COM口。
2. 发送GRBL初始化命令(如`$$`读取状态,`$X`解锁报警等)。
3. 发送归零指令`$H`,等待机器归零完成(通过解析串口返回的`[MSG:‘’]`信息判断)。
4. 初始化ChatGPT wrapper,发送预设的“越狱”提示词,等待并确认模型已进入角色。
5. 打印提示:“Ouija Mode Enabled. Ready for questions”。
6. 进入主循环:
a. 在控制台等待用户输入问题。
b. 将问题(附加强化指令)发送给ChatGPT API。
c. 接收回复,进行文本清洗(去标点、空格,转大写)。
d. 遍历清洗后的字符串,根据`coordinate_map`生成G代码序列。
e. 将G代码逐行发送给GRBL,并监控执行状态。
f. 拼写完成后,返回步骤6a等待下一个问题。
语音输入版本 的区别在于,它使用 speech_recognition 库监听麦克风,将语音转为文本,然后再走相同的ChatGPT和G代码生成流程。实测中,语音识别在嘈杂环境下的准确率会影响体验,但作为演示效果非常震撼。
6. 顶板制作与系统集成
6.1 通灵板面板设计与雕刻
顶板不仅是交互界面,也是整个装置的“脸面”。我选择用1/2英寸厚的桦木胶合板,因为它兼顾了强度、平整度和易加工性。
- 设计 :在Fusion360或任何矢量绘图软件中,绘制一个755mm x 555mm的矩形(比机箱内框稍小,便于放置)。然后导入或绘制标准的通灵板图案:字母A-Z呈弧形排列,数字0-9在下排,顶部是“YES”,底部是“NO”,左右是“GOOD BYE”。所有线条和文字都应为单线矢量,方便激光雕刻。
- 切割与雕刻 :
- 外形切割 :强烈建议使用台锯来切割木板的外形。激光切割木板边缘会产生严重的焦痕,影响美观。台锯几分钟就能切出光滑的直边。
- 图案雕刻 :将设计好的矢量文件(DXF格式)导入激光切割机软件(如LightBurn)。这里分两层处理: 浅雕 字母和数字,深度仅0.2-0.3mm,目的是清晰可见但不会形成凹槽阻碍磁铁滑动; 深雕或切割 外圈装饰线和“YES/NO/GOOD BYE”等大字,深度可达0.5-0.8mm,以增强视觉效果。使用较低的功率和较高的速度进行多次浅雕,比一次高功率深雕更能控制效果,避免木材过度碳化。
6.2 最终组装与校准
- 放置顶板 :将雕刻好的木板放入机箱,使其边缘落在之前安装的3D打印角撑上,板面与机箱上沿平齐。
- 安装磁铁 :将一块强磁铁放入X轴滑台上的磁铁座中。然后,将另一块磁铁放在木板顶面对应的位置,它们会立即吸合。这就是你的“幽灵占卜板”。
- 坐标系统校准 :这是 最重要的一步 。机械原点(0,0)可能并不对应木板上的某个特定点(比如左下角)。你需要运行一个校准脚本,让机器移动到你认为应该是字母‘A’的位置,然后记录下此时的坐标。用这个坐标去更新Python脚本中
coordinate_map字典里所有坐标的偏移量。更专业的做法是,在GRBL中设置工作坐标系偏移(G10 L2 P1 X... Y...),但修改Python字典对初学者更直观。 - 试运行 :运行
finalTextInput.py,问一个简单的问题,比如“Hello”。观察占卜板移动路径是否正确。如果字母位置整体偏移,调整坐标偏移量。如果个别字母不准,单独微调其坐标。
7. 常见问题排查与优化心得
在多次构建和演示过程中,我遇到了各种各样的问题。这里总结一份速查表:
| 问题现象 | 可能原因 | 排查与解决思路 |
|---|---|---|
| 上电后电机不动,但有嗡嗡声 | 1. 驱动器电流(Vref)设置过低。 2. 电机线序接错。 3. GRBL未解锁(处于报警状态)。 |
1. 用万用表检查并调高Vref至0.7V左右。 2. 尝试交换同一组线圈的两根线(如A+与A-)。 3. 在串口发送 $X 命令解锁。 |
| 电机运动方向错误 | GRBL中轴方向设置反了,或电机接线顺序全反。 | 修改GRBL参数 $3 (方向信号取反掩码)。例如,X轴反向则设置 $3=1 。或交换电机接线。 |
归零( $H )失败 |
1. 限位开关未触发或常开/常闭模式设置错误。 2. 归零方向错误。 3. 限位开关信号线接触不良。 |
1. 用万用表通断档检查开关触发时是否导通。检查GRBL参数 $5 (限位开关常开/常闭)。 2. 检查 $23 (归零方向)参数。 3. 重新焊接或插紧接线。 |
| 运动精度差,丢步 | 1. 同步带太松打滑,或太紧阻力大。 2. 电机电流(Vref)设置过低。 3. 运动速度或加速度( $110 / $111 / $120 / $121 )设置过高。 |
1. 重新调整同步带张力。 2. 适当调高Vref,同时触摸驱动器散热片,确保不过热。 3. 逐步降低最大速率和加速度参数测试。 |
| 占卜板移动不顺畅或抖动 | 1. 木板表面粗糙。 2. 上下磁铁未对准,产生侧向拉力。 3. 磁力过强,导致吸附太紧摩擦大。 |
1. 用细砂纸打磨木板表面,并涂抹蜡或使用光滑的亚克力板。 2. 仔细调整滑台磁铁座的位置,确保与板面磁铁垂直对准。 3. 可尝试换用稍弱一点的磁铁,或在磁铁与木板间增加一层薄垫片。 |
| ChatGPT回复不遵守规则(如过长) | 1. “越狱”提示词未生效或失效。 2. 模型上下文被重置。 |
1. 在每次用户提问后,都附加“最多3个词,优先幽默”的强化指令。 2. 检查ChatGPT wrapper的会话管理,确保是在同一个持续会话中交互。 |
| 串口通信突然中断 | 1. USB线接触不良或供电不稳。 2. Python脚本异常退出未关闭串口。 3. 电脑进入休眠状态。 |
1. 更换USB线,尝试连接电脑后置USB口。 2. 在Python脚本中添加异常处理,确保退出前关闭串口。 3. 关闭电脑的USB选择性暂停设置。 |
个人优化建议 :
- 升级滑台设计 :第一版中,占卜板是单点磁吸,容易旋转。我正在设计V2版本,采用双磁铁座或一个带有轴承的万向节结构,让占卜板移动更稳定、更像被“无形之手”推动。
- 加入视觉反馈 :在机箱内部安装一条可寻址LED灯带(如WS2812B),让灯光随着占卜板的移动而流动,或者用不同颜色表示“思考中”、“拼写中”等状态,极大增强演示效果。
- 本地化语言模型 :依赖OpenAI API会有延迟和网络依赖。未来可以考虑在本地部署轻量化的开源大语言模型(如Llama 3.2的较小参数版本),通过树莓派等设备运行,实现完全离线的“通灵”体验,响应速度会快很多。
- 安全第一 :强磁铁对心脏起搏器、机械手表等物品有风险。演示时务必告知观众,并妥善保管备用磁铁。机器运动时,确保手指和头发远离运动部件。
构建这个项目的乐趣,一半在于看到机械精密地执行代码,另一半在于观察人们与这个“AI灵体”互动时脸上那种混合着困惑、惊奇和欢笑的表情。它模糊了代码、机械和神秘学之间的界限,用一种可触摸的方式,让人直观地感受到人工智能不再是遥远的云端服务,而是可以驱动现实世界物体、与我们进行物理对话的存在。希望这份详细的指南能帮助你复现或启发属于你自己的AI硬件融合项目。
更多推荐




所有评论(0)