Appearance
胶条拐点高度及平面度检测
项目简介
项目背景
随着汽车厂商对轮胎质量愈来愈严格的要求,轮胎制造厂家迫切需要速度快、操作简单、精度高的测量装置,可以在线使用,减少停机时间停机时间,可以最大程度地避免错误不良品的发生。
相机选型
LMI激光线扫相机 Gocator2350
检测要求
测量精度 ≤ 0.03mm
测量重复性 ≤ 0.02mm
测量周期 ≤ 3s
解决方案
AI-Vision同时可以处理轮廓与点云,通过点云图找到拐点位置从而计算体积,测量高度;提取截面轮廓进行截面积测量。
设计思路
执行效果展示
工程结果展示:
HMI结果展示:
项目流程
一、初始化
- 选择
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)
- 选择
加载点云
工具,获取点云。
二、预处理
位置调整
选择3D方形探针
工具和3D位置调整
工具,通过选取底面上边坐标进行x,y方向位置的调整。
拟合平面
- 选择
3D区域
工具,选取底面19块不同的区域进行拟合平面。
- 选择
3D平面
工具,绑定上一步的算子输出变量作为基准区域来拟合平面,并将拟合出来的平面作为零平面。
图像预处理
选择3D裁切
工具,将IM1图像复制到IM2上用于平面度测量。
提示
使用并行调用子程序时,每个子程序需要在不同的IM执行。
三、平面度高度测量
高度测量
选择
切换配方
工具,将配方切换至Height。选择
标记
工具,设置循环起点。选择
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)
- 选择
3D高度
工具,绑定上一步lua脚本语言
工具输出的box作为输入区域测量高度。
- 选择
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
选择
标记
工具,设置循环终点。选择
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)
平面度测量
选择
切换配方
工具,将配方切换至Plane。选择
标记
工具,设置循环起点。选择
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)
选择
3D平面度
工具,绑定上一步输出的box作为输入区域测量平面度。选择
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
选择
标记
工具,设置循环终点。选择
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)
经验提炼
核心步骤:
根据配方获取待测位置并推送box
测量尺寸