开放式激光振镜运动控制器在Ubuntu+Qt下的文本标刻
上节课程我们讲述了如何通过Ubuntu+Qt进行振镜校正(详情点击→开放式激光振镜运动控制器在Ubuntu+Qt下的激光振镜校正),本节文本标刻是在振镜校正的前提下实现的。
在正式学习之前,我们先了解一下正运动技术的ZMC408SCAN-V22运动控制器,ZMC408SCAN-V22支持在Linux环境进行开发使用。
01 ZMC408SCAN-V22硬件介绍
ZMC408SCAN-V22是正运动技术推出的高性能双振镜运动控制器,集成了2个百兆以太网口,支持EtherCAT、EtherNET、CAN、RS232、RS485、24路通用数字输入、20路通用数字输出、2路通用模拟量输出、2路通用模拟量输入、4个本地差分脉冲轴接口、1个MPG手轮编码器接口、2个带反馈振镜接口、1个LASER激光专用接口、1个FIBER激光器接口。开放式系统框图如下所示:
ZMC408SCAN-V22总线控制器支持EtherCAT总线连接,支持最快500μs的刷新周期,支持最多达16轴运动控制,支持直线插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、同步跟随、虚拟轴设置等;采用优化的网络通讯协议可以实现实时的运动控制。
ZMC408SCAN-V22支持ETHERNET、EtherCAT、USB、CAN、RS485、RS232等通讯接口,通过CAN、EtherCAT总线可以连接各个扩展模块,从而扩展数字量、模拟量或运动轴。可以在windows,linux,Mac,Android,wince各种操作系统下开发,提供vc,c#,vb.net,labview等各种环境的dll库,如下图。上位机软件编程参考《ZMotion PC函数库编程手册》。
02 Ubuntu+Qt进行文本标刻项目的开发
(一)新建Qt项目并添加函数库
1.在Qt Creator菜单选择“文件”→“新建文件或项目…”,打开创建项目向导。选择Application项目集,创建Qt Widgets Application项目,设置项目名称和保存位置。
2.导入厂家提供的相关函数库及头文件。
(1)将zmotion.h和zmcaux.h、zmcaux.cpp以及libzmotion.so库复制到新建的项目文件夹中。
(2)在Qt Creator选择新建的Qt项目右击选择“添加库…”→“外部库”点击下一步,将刚才复制到项目文件夹上的libzmotion.so库文件导入到项目中。
(3)在Qt Creator下右击新建的Qt项目,选择“添加现有文件…”,将之前复制到项目文件下的libzmotion.so、zmotion.h、zmcaux.cpp以及zmcaux.h添加到项目中。
(4)函数库添加成功后,打开pro文件可以看到相关的函数库和头文件信息。此时已经将例程需要用到的函数库和头文件都加入到项目中了,接下来开始实现例程。
(二)安装Linux下字体引擎库
1.FreeType字体引擎库的安装
字体引擎库有很多,在例程中我们选择使用FreeType字体引擎库来进行字符轮廓解析。首先我们需要在Ubuntu环境中下载FreeType库,在终端命令行中输入sudo apt-get update和sudo apt-get install libfreetype6 libfreetype6-dev命令在线安装FreeType库,如下图所示:
安装完成后只需要在使用时引入#include <ft2build.h>头文件即可。实现文本标刻的例程必须安装字体引擎库来解析字符,否则无法得到字符的关键点坐标,就无法完成标刻和绘制。
2.设置字体文件
FreeType库没有扫描系统字体库文件的功能,在进行轮廓解析时,需要将字体文件传入。所以在正式开始例程前,需要把提前下载好的字体文件放在项目文件下,方便解析字体时直接使用。在当前项目下新建一个字体文件夹,将提前下载好的字体复制到文件夹中,如下图所示:
03 文本标刻流程以及相关函数介绍
(一)文本绘制流程
文本的处理首先是需要将文本轮廓进行解析,对轮廓信息进行分解,轮廓信息中包含轮廓的类型,文本轮廓分为线段、二次贝塞尔曲线、三次贝塞尔曲线,对于贝塞尔曲线类型需要将曲线分解为小线段进行处理,可以控制分解的精度,将所有的轮廓线处理完即代表已经完成当前字符的绘制。
(二)相关函数接口介绍
1.加载和初始化字体文件
2.计算贝塞尔曲线的二次项系数
贝塞尔曲线是通过控制点来定义的一种曲线形状,贝塞尔曲线的一个关键性质是它是由一组控制点和二项式基函数组合而成的。二项式系数确定了每个控制点在贝塞尔曲线中的权重。在计算贝塞尔曲线上的点时,每个控制点的贡献由其对应的二项式系数乘以相应的基函数得出。贝塞尔曲线通过调整控制点的位置和二项式系数来实现各种复杂的曲线形状。
3.获取贝塞尔曲线的点坐标
4.三次文件初始化
5.生成空移字符串
6.生成开光字符串
7.生成关光字符串
8.生成标刻点字符串
9.下载三次文件
10.通用命令执行接口
04 文本标刻的实现例程
文本标刻例程首先需要获取到文本数据,获取到外部输入文本后,将文本进行单个解析,生成字符轮廓数据,接下来的处理就是对轮廓数据进行转换,将贝塞尔曲线数据全部转换为小线段来处理,最后将小线段相连接,生成三次文件字符串,下载到控制器中,执行标刻命令即可完成文本的标刻。
(1)将文本解析为轮廓数据,FreeType库解析文本时需要对字符进行单个处理,将每个字符都进行解析轮廓。
//初始化轮廓数据
FT_Init_FreeType(&library);
const char* fontFilePath = gainFontFilePath(text_data.type);
FT_New_Face(library, fontFilePath, 0, &face);
// 获取字符的索引
FT_UInt glyphIndex = FT_Get_Char_Index(face, charCode);
// 加载字符的轮廓信息
FT_Int32 loadFlags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP;
FT_Load_Glyph(face, glyphIndex, loadFlags);
// 获取字形槽
FT_GlyphSlot glyphSlot = face->glyph;
// 获取字形的轮廓信息
FT_Outline* outline = &glyphSlot->outline;
(2)将轮廓数据转换为小线段生成三次文件字符串,对于线段数据可以直接通过坐标位置生成三次文件字符串,对于贝塞尔曲线数据,需要循环遍历,将所有曲线数据转换为小线段数据,最后生成三次文件字符串。
//将所有轮廓数据遍历,对不同类型的数据进行不同的处理
for(int n=0;n < outline->n_contours;n++)
{
LaserScan_z3p_EmptyMove(strFile3,startX,startY,markPara.JumpSpeed,corrJumpDelay);//空移到起点
LaserScan_z3p_OpenLight(strFile3,markPara.Io_value.emit_io,markPara.OpenDelay,markPara.MarkSpeed);//开光
tag = FT_CURVE_TAG(tags[0]); //判断当前轮廓数据的类型
switch(tag)
{
case FT_CURVE_TAG_ON: //线段
{
LaserScan_z3p_Mark(strFile3,markPara.CorDelay,line,2);
}
case FT_CURVE_TAG_CONIC: //两次贝塞尔曲线
{
ZPointF *pointData = new ZPointF[myVector.size()];
for (unsigned long i = 0; i <= myVector.size() - 1; ++i)
{
pointData[i] = myVector[i];
}
LaserScan_z3p_Mark(strFile3,markPara.CorDelay,pointData,myVector.size());//标刻
}
default: //三次贝塞尔曲线
{
ZPointF *pointData = new ZPointF[myVector.size()];
for (unsigned long i = 0; i <= myVector.size() - 1; ++i)
{
pointData[i] = myVector[i];
}
LaserScan_z3p_Mark(strFile3,markPara.CorDelay,pointData,myVector.size());//标刻
}
}
LaserScan_z3p_CloseLight(strFile3,markPara.Io_value.emit_io,markPara.CloseDelay,corrJumpDelay);//关光
}
(3)使用Free Type库解析生成的轮廓坐标点,是按照内部矩阵的像素位置决定,暂时没有相关的函数来调整起始点坐标位置,但是在使用文本标刻时,必须要确定标刻的起点位置,所以在例程中的实现方法是将解析出的的坐标位置进行比较,得到最小的X和Y坐标,将所有的轮廓坐标偏移最小坐标位置,保证起始点是在原点位置开始,后续可以通过更改起点位置来确定相对位置。
(4)三次文件字符串追加完成后,将三次文件下载到控制器中,进行文本标刻。
//初始化三次文件字符串
LaserScan_z3p_Init();
//生成文本标刻字符串
Z3p_process();
//回原点,打开急停信号,关闭激光器使能
LaserScan_z3p_EmptyMove(strFile3,0,0,markPara.JumpSpeed,corrJumpDelay);//空移到原点
//将三次文件字符串下载到控制器中
ZMC_DownMem3File(g_handle,strFile3.toLatin1().data(),strFile3.length(),"Zmc_text.z3p");
QString filePath = "Zmc_text.z3p";
QFile file(filePath);
//在当前项目下生成三次文件
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream stream(&file);
stream << strFile3;
file.close();
QMessageBox::warning(this,"提示","3次文件生成成功!");
}
05 文本标刻的实现效果
1.建立控制器连接,设置激光器参数和工艺参数。
2.输入需要标刻的文本,可以根据需要设置相关的文字属性,下面是输入文字通过QPaint绘制的文本。
3.可以更改字体,文本开始位置以及设置倾斜属性,下面是设置后的效果。
4.点击生成三次文件,选择标刻图形,下图是通过示波器抓取的标刻数据。
5.文本标刻效果演示。
开放式激光振镜运动控制器在Ubuntu+Qt下的文本标刻