Skip to content

胶条拐点高度及平面度检测

项目简介

项目背景

随着汽车厂商对轮胎质量愈来愈严格的要求,轮胎制造厂家迫切需要速度快、操作简单、精度高的测量装置,可以在线使用,减少停机时间停机时间,可以最大程度地避免错误不良品的发生。

本地图片

相机选型

LMI激光线扫相机 Gocator2350

检测要求

测量精度 ≤ 0.03mm
测量重复性 ≤ 0.02mm
测量周期 ≤ 3s

解决方案

AI-Vision同时可以处理轮廓与点云,通过点云图找到拐点位置从而计算体积,测量高度;提取截面轮廓进行截面积测量。

设计思路

本地图片

执行效果展示

  • 工程结果展示:

    本地图片

    本地图片

  • HMI结果展示:

    本地图片

项目流程

一、初始化

  1. 选择Lua脚本语言工具,全局变量初始化,创建待接收数据的csv文件。
  • 初始化全局变量分别用于循环计数,高度平面度结果保存字符串

  • 拼接表头字符串,保存初始化csv文件

经验

.. 用于string类型字符串拼接

part1 = "Hello, "
part2 = "world!"
result = part1 .. part2
print(result) # 输出: Hello, world!

,作为分隔符,分割每个数据项

lua
--初始化全局变量
SetIntVariable("pinCount" , 0)
SetIntVariable("pinCount1" , 0)
SetStringVariable("HeightSave" , "")
SetStringVariable("PlaneSave" , "")

--生成用于拼接的字符串
write = ""

--如果该文件不存在,生成该文件
if FileExists("./Height.csv") == false then  
    --生成表头
    write = write .. "Time,"  
    for i = 1,30,1 do    
        write = write .. "h" .. i
        write = write .. ","
    end
    write = write .. "OK/NG" .. "\n"   
end

--将时间拼接入表头中
write = write .. os.date("%Y_%m_%d %H:%M;%S") .. ","  
--将表头写入文件中
WriteToFile("./Height.csv",write)

--生成用于拼接的字符串
write = ""

--如果该文件不存在,生成该文件
if FileExists("./Plane.csv") == false then  
    --生成表头
    write = write .. "Time," 
    for i = 1,30,1 do    
        write = write .. "Plane" .. i
        write = write .. ","
    end
    write = write .. "OK/NG" .. "\n"   
end
--将时间拼接入表头中
write = write .. os.date("%Y_%m_%d %H:%M;%S") .. ","   
--将表头写入文件中
WriteToFile("./Plane.csv",write)
  1. 选择加载点云工具,获取点云。

二、预处理

本地图片

位置调整

选择3D方形探针工具和3D位置调整工具,通过选取底面上边坐标进行x,y方向位置的调整。

拟合平面

  1. 选择3D区域工具,选取底面19块不同的区域进行拟合平面。

本地图片

  1. 选择3D平面工具,绑定上一步的算子输出变量作为基准区域来拟合平面,并将拟合出来的平面作为零平面。

本地图片

图像预处理

选择3D裁切工具,将IM1图像复制到IM2上用于平面度测量。

提示

使用并行调用子程序时,每个子程序需要在不同的IM执行。

三、平面度高度测量

本地图片

高度测量

  1. 选择切换配方工具,将配方切换至Height。

  2. 选择标记工具,设置循环起点。

  3. 选择lua脚本语言工具,从配方文件获取当前待测点的坐标并计算待测区域范围设置box到脚本输出。

lua
--根据当前循环数读取配方中指定序号的数据
Result = GetRecipeSet(count)

--将配方中的数据赋值给x,y,z
x = Result.PinPositionX
y = Result.PinPositionY
z = Result.PinHight

--计算得出待测区域范围
sx = x-0.5 
sy = y-0.5
sz = z-0.5

ex = x+0.5 
ey = y+0.5
ez = z+0.5

--将待测区域设置为box到脚本输出
SetBox("box",sx,sy,sz,ex,ey,ez)

--将待测区域的Box显示在IM1上
DrawBox(1,"green",sx,sy,sz,ex,ey,ez)
  1. 选择3D高度工具,绑定上一步lua脚本语言工具输出的box作为输入区域测量高度。

本地图片

  1. 选择lua脚本语言工具,保存测量内容,判断循环是否结束并设定增加循环次数。
  • 绑定当前循环计数值,3D高度工具高度测量值,用于拼接保存高度值的字符串,用于保存高度值的float数组

  • 拼接高度值到字符串,保存字符串到全局变量(用于保存到csv)

  • 插入当前测量高度到用于保存高度值的float数组(用于结果判断),保存数组到全局变量

  • 判断循环是否结束

经验

string.format 用于格式化字符串 %.nf表示将浮点数格式化为保留 n 位小数。

pi = 3.14159 str = string.format("Pi is approximately %.3f", pi) print(str) -- 输出: Pi is approximately 3.141

lua
count = count + 1

--将此次测量的高度拼接入write字符串中
write = write ..  string.format("%.3f", height) .. ","

--保存当前已测量高度至全局变量中
SetStringVariable("HeightSave" , write)

--保存当前测量的高度至全局变量中
table.insert(Height, math.floor(1000*height)/1000)
SetFloatArrayVariable("Height", Height)
-- SetFloatVariable("Height" .. count , math.floor(1000*height)/1000 )

--保存当前循环数至全局变量中
SetIntVariable("pinCount",count)


--判断循环
if count < 30 then
   Jump("Start")
elseif count == 30 then
   Jump("End")
end
  1. 选择标记工具,设置循环终点。

  2. 选择lua脚本语言工具,将高度测量结果写入csv文件中。

  • 绑定保存高度的数组全局变量,绑定拼接高度值的字符串全局变量

  • 循环对高度数组进行判断,将判断结果拼接到绑定的字符串后

  • 保存拼接字符串到csv文件

lua
-- 高度判断
Judge = true
for i = 1, 30, 1 do
    -- 获取指定序号的配方值
    currentPin = GetRecipeSet(i)
    -- 对测量结果进行判断
    if currentPin.PinHight - 0.3 > Height[i] or Height[i] > currentPin.PinHight + 0.1 then
       Judge = false
       break
    end
end

-- 对结果进行判断,根据判断的结果拼接数据至字符串中
if Judge == true then
    write = write .. "OK\n"
    DrawText3D(1,"green",30,-13,35,20,"检测结果:OK")
elseif Judge == false then
    write = write .. "NG\n"
    DrawText3D(1,"red",30,-13,35,20,"检测结果:NG")
end

-- 保存csv文件
WriteToFile("./Height.csv",write)

平面度测量

  1. 选择切换配方工具,将配方切换至Plane。

  2. 选择标记工具,设置循环起点。

  3. 选择lua脚本语言工具,从配方文件获取当前待测点的坐标并设置box到脚本输出。

lua
--获取指定序号的配方值
Result = GetRecipeSet(count)

--将配方值赋值给x,y,z
x = Result.PinPositionX
y = Result.PinPositionY
z = Result.PinHight

--计算得出待测区域范围
sx = x-0.5 
sy = y-0.5
sz = z-1

ex = x+0.5 
ey = y+0.5
ez = z+1

--将待测区域输出到寄存器中用于后续调用
SetBox("box1",sx,sy,sz,ex,ey,ez)

--将待测区域的Box显示在IM2上
DrawBox(2,"green",sx,sy,sz,ex,ey,ez)
  1. 选择3D平面度工具,绑定上一步输出的box作为输入区域测量平面度。

  2. 选择lua脚本语言工具,保存测量内容,并设定循环次数。

lua
--因为已经测量过一次平面度,所以当前循环数需要+1
count = count + 1

--将当前测量的平面度结果拼接入存储已经测量的平面度的字符串中
write = write ..  string.format("%.3f", plane) .. ","

--更新已经测量的平面度至全局变量中
SetStringVariable("PlaneSave" , write)

--存储当前测量的平面度至全局变量中
table.insert(Plane, math.floor(1000*plane)/1000)
SetFloatArrayVariable("Plane", Plane)
-- SetFloatVariable("Plane" .. count ,  math.floor(1000*plane)/1000 )

--更新当前循环数至全局变量中
SetIntVariable("pinCount1",count)

--判断循环
if count < 30 then
    Jump("Start1")
else
    Jump("End1")
end
  1. 选择标记工具,设置循环终点。

  2. 选择lua脚本语言工具,将结果写入csv文件中。

lua
-- 平面度判断
Judge = true
for i = 1,30,1 do
    if 0.08 < Plane[i] or Plane[i] < 0 then
       Judge = false
       break
    end
end

-- 对结果进行判断,根据判断的结果拼接数据至字符串中
if Judge == true then
    write = PlaneSave .. "OK\n"
    DrawText3D(2,"green",30,-13,35,20,"检测结果:OK")
elseif Judge == false then
    write = PlaneSave .. "NG\n"
    DrawText3D(2,"red",30,-13,35,20,"检测结果:NG")
end

-- 保存csv文件
WriteToFile("./Plane.csv",write)

经验提炼

核心步骤:

  1. 根据配方获取待测位置并推送box

  2. 测量尺寸

AI-Vision,让3D测量更简单