☰
视觉引导SCARA自动锁螺丝方案:从手眼标定到主流程实战解析
2026/10/22 6:06:49 网站建设 项目流程

把一颗螺丝拧到扭矩合格,这件事听着不起眼,上了产线才知道有多麻烦。操作工左手扶工件、右手端着电批,一天重复上千次动作,扭矩忽大忽小、螺丝打歪、滑牙、漏锁,不良率全靠人来扛。两年前我参与一个项目,客户就为这事找上门,要求把人工锁付改成自动化。我们最终选用的方案是雅马哈SCARA机械手加2D视觉引导,写了一套锁螺丝程序,把整道工序从人工改成自动。今天这篇就把这套程序的完整思路拆开讲:为什么这么搭、视觉和机械手的坐标怎么对齐、主流程怎么写、调试时又踩了哪些坑。内容偏实战,适合准备上视觉锁螺丝但没有现成经验的工程师参考。

1. 为什么锁螺丝这道工序必须上机械手和视觉

1.1 人工锁螺丝的品质瓶颈

先说现场的真实情况。客户的产品是某电子设备外壳,一块壳体上有6颗螺丝,分布在四角和两个腰位,产品来料位置有偏差,螺丝孔位也有一点加工公差。人工锁付时,工人为了保证速度,常常不垂直下压,电批一斜,螺丝刀头就把螺纹打坏了;有时候螺丝没对准孔位就直接往下压,丝滑了也不知道,直接当良品流下去。更麻烦的是扭矩,人手拧出来的扭矩离散度非常大,同一批货里有的松有的紧,到了客户整机装配时才发现问题。

这就是典型的"看起来简单、做起来要命"的工序。锁螺丝的自动化不只是把电批装到一个机械臂上那么简单,难点在于三个层面:一是位置要准,螺丝刀中心必须对准螺丝孔中心,偏差超过0.5毫米就可能打歪螺纹;二是力度要可控,锁紧扭矩必须精确落在工艺窗口内;三是过程要可追溯,每一颗螺丝锁没锁住、扭矩多少,都要有数据留档。这三个层面靠人工是靠不住的,必须上设备。

1.2 方案选型:为什么是雅马哈SCARA而不是别的

我们当时对比过几类方案。第一类是全气动/伺服滑台加固定电批,工件靠治具定位,电批只做上下动作,这种方案只适合产品单一、来料位置非常稳的情况,客户的产品经常换型,治具成本太高,直接排除。第二类是六轴关节机器人,柔性好,但价格高、编程复杂,锁螺丝这种平面位移加垂直下压的动作,六轴的冗余能力用不上。第三类就是现在的方案:四轴SCARA机械手加视觉引导。

SCARA机器人在Z方向刚性很好,下压锁螺丝时不容易晃动,而且只能做XY平面运动和Z轴升降、绕Z旋转,正好匹配锁螺丝的三个关键动作:平面找位、垂直下压、旋向调整。雅马哈的SCARA在这个领域用得非常广,控制器编程相对直接,IO和通讯接口齐全,和视觉系统、伺服电批对接都比较省事。我们最后选了一台工作半径400毫米左右、负载3公斤级的机型,末端加装电批组件后负载余量仍然充足。选型时要注意的是:不要把负载项目只算电批重量,还要算上下浮动机构、传感器支架、线缆拖链的重量,这些加起来往往比电批本身还重,负载余量不足会导致Z轴下压时定位抖动。

1.3 视觉在这里解决的核心问题:位置偏差补偿

有人会问:既然有治具,为什么不能把工件固定死?道理很简单,固定死也需要治具定位精度和产品加工精度都足够高。实际来料外壳是注塑加CNC加工出来的,定位边本身就有公差,再加上治具磨损、人工放料时没推到位,螺丝孔中心相对于机器人世界坐标的偏差经常超过1毫米。没有视觉的话,要么花大价钱做高精度气动夹紧治具,要么就眼睁睁看着打歪。

视觉在这套系统里做的事情就是"眼睛":拍照找到工件的真实位置和角度,计算出每一个螺丝孔当前的实际坐标,然后把坐标发给机械手,让电批对准后再锁。我们采用的是眼在手外(固定相机)方案,相机装在工作位上方,光源用低角度环形光,每次工件到位后拍一张图,同时识别两个基准孔和一个目标螺丝孔,通过基准孔解算工件偏移和旋转角度。这样做的兼容性特别好——换产品的时候,只需要更换拍照模板和螺丝孔位配方,机械结构完全不用动。

2. 系统构成与通信链路:各部件如何各司其职

2.1 硬件清单与选型理由

整套系统主要包含以下几个部分:

  • 雅马哈SCARA机械手一套:负责带动电批组件在XY平面移动、Z轴下压锁付。
  • RCX系列控制器:运行机械手程序,处理IO与通讯,内置SEL语言编程环境。
  • 200万像素黑白工业相机:负责拍摄工件定位孔和螺丝孔,黑白相机在边缘提取方面比彩色相机更稳。
  • 8毫米到12毫米定焦工业镜头:根据视野范围选型,保证一个画面覆盖全部6颗螺丝孔。
  • 低角度环形光源:让螺丝孔边缘和平面形成鲜明对比,减少壳体表面反光干扰。
  • 伺服电批(拧紧轴):转速可调、扭矩可设定,支持扭矩和角度数据回传。
  • 振动盘加吹气送钉器:把散装螺丝排序吹送到电批吸钉嘴。
  • PLC一套:汇总各设备状态、控制传送带和治具气缸。

这个配置里最容易被人忽略的是光源。很多第一次做视觉螺丝锁付的人喜欢用高角度环形光,结果壳体表面反光一片白,螺丝孔特征完全提不出来。我们最后改成了低角度环形光,让光几乎贴着工件表面打,孔洞处不反光所以呈黑色,平面处有反光呈白色,二值化之后特征非常干净。光源的亮度也需要现场调,太亮了会把小毛刺也当成孔边,太暗了孔边会断裂。

2.2 通信拓扑设计

机械手、相机、电批、PLC四者之间的通信决定了系统的响应速度和稳定性。我见过很多项目在这里栽跟头,通信协议没理清,联机后互相等,节拍直接崩掉。我们的拓扑是这样:

  • PLC与机械手:关键信号用硬IO,比如"工件到位"、"请求拍照"、"锁付完成"、"NG报警",硬IO延迟稳定,适合做互锁逻辑;非实时数据用TCP/IP或RS-232传。
  • 机械手与相机:用TCP/IP Socket通信。机械手程序里发起拍照请求,相机采集并处理后把结果(基准孔像素坐标、螺丝孔像素坐标)以字符串格式返回。
  • 机械手与电批:电批通过以太网与控制器通信,锁付完成后把扭矩峰值、最终扭矩、锁付角度、OK/NG结果返回。电批也可以直接通过IO给PLC一个完成信号,但为了拿扭矩数据做追溯,必须走网络。

这里有一个非常关键的经验:拍照触发不要用软触发。所谓软触发是机械手在程序里给相机发一条"拍照"命令,等相机把整个图像采集处理完再返回。这样做的延迟不稳定,有时快有时慢,机械手等得越久节拍越慢。我们后来改成硬件触发:机械手运动到拍照位之前先发一个IO脉冲给相机,相机的曝光和识别与机械手的运动并行进行,等机械手到位时,坐标运算结果已经在缓冲区里等着了。

2.3 程序运行的整体轮廓

整套程序是一个典型的状态机,大致循环是:等待工件到位——治具夹紧——机械手移动到拍照位——触发相机拍照并接收坐标——计算机械手目标坐标——依次锁付6颗螺丝——复检所有螺丝——打开治具——放行工件。任何一个环节报警都会中断循环并跳到异常处理子程序。这个主循环逻辑我会在第4章详细展开,这里先记住一个原则:整个流程中只有拍照和锁付是时间消耗大头,其他步骤都应该尽量叠加,这是后面优化节拍的关键。

3. 手眼标定:像素坐标与机器人坐标的灵魂一步

3.1 为什么标定这么重要

视觉识别出来的螺丝孔位置,单位是像素,而机械手要走的坐标,单位是毫米。像素坐标系和机器人坐标系之间不仅有倍率缩放,还有旋转、平移,镜头本身的畸变也会造成非线性偏差。如果直接用固定倍率去换算,视野边缘的位置误差可能达到好几毫米,螺丝百分之百打歪。手眼标定要做的就是求出一个数学变换关系,把图像中的任意像素坐标精确映射到机器人坐标系中。

我习惯这样解释给新同事听:相机看到的是一个扁平的画面,画面里的"一厘米"和机械手实际走的"一厘米"不是一回事,而且在画面不同位置比例也不完全一样,就像你看远处的人和近处的人大小不一样。标定就是给机械手装一把"量好的尺子",让它知道画面里的每个点对应自己坐标系下的真实位置。

3.2 九点标定的实操流程

我们用的是最常见的眼在手外九点标定法,流程如下:

  1. 在机械手末端安装一根尖锐的标定针,针尖长度为已知值。
  2. 在相机视野中心区域摆放一张标定板(圆点阵列或棋盘格),保证标定板平整且与机械手XY平面平行。
  3. 在示教器上手动移动机械手,让针尖依次对准标定板上的9个特征点,记录下每个点的机器人坐标。
  4. 每到一点时,用相机拍一张图,记录该特征点的像素坐标。
  5. 将9组机器人坐标和9组像素坐标成对输入标定程序,计算出变换矩阵。

实际操作中有一点容易被忽略:机械手移动到每个标定点时,Z轴高度必须固定,而且这个高度要尽量接近实际锁螺丝时相机拍照的平面。因为固定相机方案里,工件表面高度不同时,成像比例会轻微变化。我们第一次标定就是随意设了一个Z高度,结果到了正式锁螺丝的时候,由于产品叠了两个零件导致表面高了10毫米,位置偏了0.5毫米以上,幸好验证阶段发现得早。

雅马哈控制器里做标定有两种方式:一是利用RCX Studio自带的视觉标定向导,它会在画面上显示十字光标,机械手末端针尖对准特征点后保存坐标,走完规定点位后自动生成变换参数;二是自己在SEL程序里写仿射变换计算,把9组点代入线性最小二乘法求出矩阵。第一种省事,第二种灵活,建议调试初期先用自带向导跑通流程,再根据实际需要决定是否定制。

3.3 标定精度验证与误差排查

标定结束不是直接开始锁螺丝,一定要先验证。验证方法是:在标定板之外随机选几个点,机械手移动到该点,看针尖是否准确落在特征点中心。正常情况下整体误差应该小于0.3毫米,我们实际做出来在0.15毫米左右。误差超过0.5毫米就必须排查,常见原因有三个:

  • 标定针本身不垂直于末端法兰,针尖位置在旋转时发生偏移。
  • 相机镜头光轴与机械手Z轴不平行,成像平面和运动平面有夹角。
  • 标定板不平整,贴在了有翘边的台面上。

排查的时候,先用水平仪确认相机和机械手底座的水平度,再检查标定针的安装,最后换一块更平整的标定板重新走一遍。记住一个原则:标定误差在根源上解决,不要靠程序里加固定补偿硬凑。硬凑换一个位置就露馅。

4. 锁螺丝主程序的逻辑拆解

4.1 拍照定位与坐标补偿的计算

这是整个程序里最核心的一段。工件到位后,机械手先移动到预设的拍照位,这个位置保证相机能拍到两个基准孔和当前要锁的那颗螺丝孔。拍照结果返回的是基准孔A、B和螺丝孔P的像素坐标,接着程序要做的是:

  1. 根据基准孔A、B的像素坐标换算它们在机器人坐标系下的位置。
  2. 计算机实际来料位置相对示教标准位置的偏移量(deltaX、deltaY)和旋转角度theta。
  3. 把示教好的螺丝孔标准机器人坐标,加上偏移量和旋转量,得到当前实际目标坐标。

数学上等效于一个坐标变换:目标坐标 = 标准坐标乘以旋转矩阵,再加平移量。如果拍照时工件有微小旋转,螺丝孔和基准孔之间的相对位置关系虽然不是绝对固定,但可以通过旋转角度补偿来逼近。这个模型在工件是刚体、螺丝孔位置相对基准孔稳定的时候成立。

SEL程序里的逻辑大致是:

' 相机返回字符串: 基准A_X,基准A_Y,基准B_X,基准B_Y,螺丝孔P_X,螺丝孔P_Y ' 例如 "123.4,567.8,223.4,567.8,345.6,678.9" S1 = NET_WAIT(相机通道) ' 读取相机结果字符串 PARSE S1 INTO A_PIX_X, A_PIX_Y, B_PIX_X, B_PIX_Y, P_PIX_X, P_PIX_Y ' 把像素坐标映射到机器人坐标(使用标定矩阵) A_ROB_X = CAL_X(A_PIX_X, A_PIX_Y) A_ROB_Y = CAL_Y(A_PIX_X, A_PIX_Y) B_ROB_X = CAL_X(B_PIX_X, B_PIX_Y) B_ROB_Y = CAL_Y(B_PIX_X, B_PIX_Y) P_ROB_X = CAL_X(P_PIX_X, P_PIX_Y) P_ROB_Y = CAL_Y(P_PIX_X, P_PIX_Y) ' 计算偏移和旋转 OFFSET_X = A_ROB_X - STD_A_X OFFSET_Y = A_ROB_Y - STD_A_Y ' 计算绕基准点旋转角度 THETA = ATAN2(B_ROB_Y - A_ROB_Y, B_ROB_X - A_ROB_X) - STD_THETA ' 把标准螺丝孔坐标先绕基准点旋转,再平移 TMP_X = STD_P_X - STD_A_X TMP_Y = STD_P_Y - STD_A_Y ROT_X = TMP_X * COS(THETA) - TMP_Y * SIN(THETA) ROT_Y = TMP_X * SIN(THETA) + TMP_Y * COS(THETA) FINAL_X = ROT_X + A_ROB_X FINAL_Y = ROT_Y + A_ROB_Y

这段代码看着简单,但里面的门道不少。首先,旋转基准点我选用基准孔A,不用相机视野中心,原因是A点离目标螺丝孔更近,角度补偿的误差更小。其次,ATAN2函数的象限判断要小心,角度差要归一化到正负180度以内,否则旋转补偿会反方向。最后,这个变换基于刚体假设,如果产品自身存在较大形变,比如壳体翘曲导致某个螺丝孔相对基准孔跑了0.5毫米以上,那就需要单独对该孔再做一次视觉定位,而不是只用一次基准偏移推算所有孔。我们最后为了稳妥,把程序设计成每颗螺丝锁付前单独拍一次照,这样每颗孔都是独立定位,代价是节拍长了,但良率好很多。

4.2 电批锁付工艺参数的设定

锁螺丝不是电批一下压到底就完事。螺丝要锁得稳,电批必须在不同阶段用不同转速和扭矩。我们的参数设置大致是:

阶段转速控制方式动作说明
快速接近800-1000 rpm位置控制电批下降,批头接触螺丝头部
低速寻牙60-120 rpm位置控制批头带动螺丝旋转,找到螺纹入口
锁紧阶段200-300 rpm扭矩控制拧入螺纹,扭矩上升到设定值
扭矩保持停止扭矩保持保持设定扭矩0.1-0.3秒

这里的核心是寻牙阶段。如果一开始就用高速,螺丝没对准螺纹就直接切削进去,轻则螺纹损伤,重则滑牙。寻牙速度慢下来之后,螺丝会顺着螺纹自然咬合。锁紧阶段的速度也不能太快,太快了扭矩信号采样容易过冲,电批已经停下来了扭矩才升上去,实际锁紧状态和设定值不一致。

扭矩窗口设置也要讲道理。扭矩设定过低,螺丝没锁紧,产品装箱运输后松动;设定过高,螺纹滑牙、壳体开裂。我们当时根据客户提供的工艺文件把窗口设为1.8到2.2牛米,电批设定目标值2.0牛米。浮锁和滑牙的判定逻辑是:如果最终扭矩小于1.5牛米,判为浮锁,说明螺丝没咬合到底;如果锁付过程中扭矩超过上限且角度持续增大,判为滑牙。这些判定阈值不能拍脑袋,要找供应商要数据,或者自己做一批破坏性试验标定。

4.3 主循环的程序流程

整个主程序我用SEL语言实现,状态机结构大概如下:

MAIN_LOOP: WAIT 治具夹紧信号 = ON 延时 0.2 ' 等工件稳定 MOVE 到拍照位1 ' 第一颗螺丝孔的拍照位置 PULSE 相机触发IO ' 硬件触发拍照 RECEIVE 相机结果1 计算 实际目标坐标1 MOVE 到目标坐标1上方 ' 先水平移过去 MOVE 到锁付高度 ' Z轴下降 执行电批锁付 接收 电批结果1 IF 电批结果 = NG THEN GOTO NG_HANDLE ' 依次处理第2到第6颗螺丝 ... 发送 锁付完成信号给PLC MOVE 到安全高度 GOTO MAIN_LOOP

这段流程里有一个细节:机械手必须水平移动到目标坐标上方,再垂直下降,不要斜着下降。斜向运动时电批头会有水平分力,碰到螺丝孔边缘就会带偏。另外,Z轴下降到锁付高度的速度也要分两段,快速接近到距表面10毫米处,再慢速下压,防止批头直接把螺丝压偏。

电批锁付期间机械手应该做什么?很多人让机械手保持Z轴位置不变,电批在批头内部做浮动压紧,这样是正确的。我们的电批组件带一个弹簧浮动机构,电批固定在浮动轴上,下压时弹簧压缩给螺丝一个预压力,拧紧时电批可以随螺纹进给方向微小上下浮动。有了这个机构,机械手Z轴的绝对定位精度要求可以适当放宽,但要保证浮动行程内,否则会压坏螺纹。

4.4 异常处理与防呆逻辑

锁螺丝程序里最不能少的是异常处理。每种异常都要有明确的响应动作,不能一个报警跳出来就停在那里等人来。我们梳理出的主要异常类型和处理策略如下:

  • 滑牙:电批反馈扭矩超过上限且角度异常增加。处理:机械手退回安全高度,报警并标记该螺丝NG,该工件强制进入复检工位。
  • 浮锁:最终扭矩低于下限。处理:分两种情况,若只是浮锁,允许程序自动再锁一次;若复锁后仍不合格,报警隔离。
  • 漏锁:某颗螺丝未执行。程序通过计数器保证6颗螺丝都走完流程后才能放行,漏了任何一颗都不能继续。
  • 送钉失败:吸钉嘴传感器检测到没有螺丝。处理:自动重新请求送钉一次,再次失败则报警暂停,等待人工处理。
  • 视觉定位失败:相机找不到基准孔或螺丝孔。处理:重新拍照一次,若仍失败,报警提示可能来料异常。

防呆方面,每个产品的螺丝孔位和锁付参数都存放在独立配方里,程序运行时从配方读取点位坐标,而不是把所有点位硬编码在主程序里。换型时只要选择对应配方,主程序逻辑不需要改。配方里还要加一个校验字段,防止选错配方导致把长螺丝锁进短孔。这个校验字段可以在示教时手动录入,锁付前程序再检查一次。

5. 调试现场踩过的坑与优化记录

5.1 视觉误判:反光、油污和曝光博弈

第一次联机跑的时候,良率只有六成,大量锁付位置偏差。排查到最后发现是视觉把螺丝孔特征识别错了。原因有三层:一是壳体表面有一层油污,低角度环形光打在油污上产生了局部高光,二值化后高光区域比螺丝孔还亮,算法把高光当成了孔;二是曝光时间过长,视野边缘的孔位出现了过曝,孔边缘向外扩了一圈,中心坐标偏移;三是温度影响,设备运行半小时后光源亮度衰减,图像整体变暗,阈值没有自适应。

解决办法是:把曝光时间压下来,让高光区域不过曝;光源亮度做软件可调,每隔一段时间自动校准一次;识别算法里增加圆度约束,只接受圆度在0.85到1之间的特征作为螺丝孔。这里最实用的建议是:调试视觉的时候必须拿着产线实际工件测,不能只用干净的良品件。脏污、油污、划痕甚至不同批次的颜色差异,都会影响视觉稳定性。我们后来专门收集了一筐各种状态的不良品工件,放在调试工位上随时用来验证算法改动。

5.2 坐标漂移:治具磨损和机械间隙的缓慢累积

运行两周后,客户反映个别螺丝有轻微划痕,我们的第一反应是视觉识别变差了,但重新标定之后问题依旧。仔细排查发现,工件治具的定位销磨损了,人工放料时工件没有完全靠紧定位面。视觉定位补偿确实做了,但补偿的前提是工件不发生大的翘曲,而定位销磨损导致工件一端翘起,相机是二维成像,无法感知Z方向高度变化,实际锁付点的XY就会偏。

这个问题在固定相机方案里是硬伤。我们的处理分两步:一是增加治具定位销的更换频次,把它列为易损件管理;二是在程序中加入"基准孔相对位置合理性检查",如果两个基准孔的实测距离和标定标准距离偏差超过0.5毫米,就判定来料可能翘曲,报警不再继续锁付。这套检查逻辑很便宜,但能拦住一大批不良来料。

5.3 节拍优化:让拍照和锁付重叠起来

初版程序节拍是每件8秒出头,客户嫌慢。分析时间构成发现,6颗螺丝每颗都是"先停稳再拍照、算完再移动",其实运动过程中有大把空闲时间被浪费掉了。我们做的第一版优化是重叠拍照:机械手在运动到某一孔的途中先发拍照脉冲给相机,让相机提前拍照和处理,等机械手到位时结果刚好出来,省掉"到位后等待拍照结果"的时间。第二版优化是电批结果异步读取:锁付完成信号通过IO到达后,程序立刻切换去移动下一颗螺丝的位置,同时电批把扭矩数据通过以太网慢慢传回来,不阻塞主流程。第三版优化是Z轴回程与后续水平移动合并,用圆弧过渡指令让机械手从锁付高度直接斜向运动到下一拍照位,少了一次"提到安全高度再平移"。

三版优化做完,节拍压到5秒出头,良率没有下降。这里想提醒一句:节拍优化一定要建立在异常处理完备的前提下进行。我们第一版重叠拍照之后出现过一次情况:相机处理结果传晚了,机械手已经到位但没有数据,程序傻等了0.3秒,比原来还慢。后来加了超时重发机制,超过50毫秒没收到结果就自动重新请求,才稳定下来。

5.4 换型防呆与数据追溯

客户的产品有两个型号,螺丝数量和位置不一样。换型时操作工需要选择配方、更换工件治具。一开始发生过一次事故:操作工选择配方后忘了确认,结果机械手按照旧配方把一颗长螺丝锁进了短孔,螺纹卡死,把孔位直接顶裂。我们的对策是在每个配方里增加了"螺丝编码"和"孔深上限"两个字段,机械手从料盘抓取螺丝时会先读一下螺丝的编码,如果和配方不匹配,程序强制停止。同时,锁付参数里加入Z轴下压深度上限,如果电批下压超过该孔的安全深度,立即判定为过压,停止锁付。这两道防线加进去之后,再也没有出现过换型打错的情况。

数据追溯方面,电批每次锁付都会记录扭矩峰值和最终扭矩,PLC把这些数据和产品条码绑定,存入本地数据库。客户后续做质量分析时可以直接导出每一颗螺丝的锁付曲线。我在项目里额外做了一件事:把视觉识别到的每颗螺丝孔坐标也一并保存。别小看这个数据,后续如果连续出现位置偏移趋势,通过分析坐标偏差的走向就能提前发现治具磨损或定位销松动,比单纯看锁付结果敏感得多。

做了这套视觉锁螺丝系统之后,我最大的体会是:机械手、相机、电批,单独拿出来都是成熟设备,难的不是某一个部件,而是把它们的逻辑拧到同一根轴上。视觉给的是"眼睛",机械臂给的是"手",而真正的灵魂在于程序里那套坐标变换和异常处理。整台设备调试过程中,我和团队最受益的一条经验是:所有参数都要建立"验证闭环"。标定完要验证、视觉识别完要验证、锁付完要验证,验证不是走个过场,而是每一个环节都要用产线上的真实工件去测,测不过就停下来查根因,不要用临时补丁往下拖。如果你正在做类似的视觉锁螺丝项目,建议从手眼标定和异常流程设计这两个地方多花心思,这两块做好了,后面联调会顺很多。最后分享一个实用的小技巧:设备正式交付前,用一批人为制造的不良品(模拟滑牙、浮锁、视觉识别失败)走一遍完整流程,确认设备每一条异常分支都按预期动作,这比试产跑一百件良品更能体现设备的成熟度。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询