In the previous lesson, we explained how to perform galvanometer calibration using Ubuntu + Qt (click for details → Laser Galvanometer Calibration under Ubuntu + Qt with Open Laser Galvanometer Motion Controller). This lesson's text marking is implemented on the premise of galvanometer calibration.
Before we begin our formal learning, let's first understand the ZMC408SCAN-V22 motion controller from Zheng Motion Technology. The ZMC408SCAN-V22 supports development and use in a Linux environment.
01ZMC408SCAN-V22 Hardware Introduction
The ZMC408SCAN-V22 is a high-performance dual-galvanometer motion controller from Zheng Motion Technology. It integrates two 100Mbps Ethernet ports, supporting EtherCAT, EtherNET, CAN, RS232, RS485, 24 general-purpose digital inputs, 20 general-purpose digital outputs, 2 general-purpose analog outputs, 2 general-purpose analog inputs, 4 local differential pulse axis interfaces, 1 MPG handwheel encoder interface, 2 galvanometer interfaces with feedback, 1 LASER interface, and 1 FIBER interface. The open system block diagram is shown below:
The ZMC408SCAN-V22 bus controller supports EtherCAT bus connection, a refresh cycle of up to 500μs, and motion control of up to 16 axes. It supports linear interpolation, arbitrary circular interpolation, spatial circular interpolation, helical interpolation, electronic cam, electronic gear, synchronous following, virtual axis setting, etc.; and can achieve real-time motion control by using an optimized network communication protocol.
The ZMC408SCAN-V22 supports communication interfaces such as ETHERNET, EtherCAT, USB, CAN, RS485, and RS232. Various expansion modules can be connected via CAN and EtherCAT buses to expand digital, analog, or motion axes. It can be developed for various operating systems including Windows, Linux, Mac, Android, and WinCE, and provides DLL libraries for various environments such as VC, C#, VB.NET, and LabVIEW, as shown in the figure below. For upper-computer software programming, refer to the "ZMotion PC Function Library Programming Manual".
02 Developing a Text Marking Project using Ubuntu + Qt
(I) Creating a new Qt project and adding a function library 1. In the Qt Creator menu, select "File" → "New File or Project..." to open the project creation wizard. Select the Application project set to create a Qt Widgets Application project, and set the project name and save location.
2. Import the relevant function libraries and header files provided by the manufacturer.
(1) Copy zmotion.h, zmcaux.h, zmcaux.cpp and libzmotion.so library to the newly created project folder.
(2) In Qt Creator, right-click on the newly created Qt project and select "Add Library..." → "External Library". Click Next to import the libzmotion.so library file that you just copied to the project folder into the project.
(3) In Qt Creator, right-click the newly created Qt project, select "Add existing file...", and add libzmotion.so, zmotion.h, zmcaux.cpp and zmcaux.h that were previously copied to the project file to the project.
(4) After the function library is successfully added, you can open the .pro file to see the relevant function library and header file information. At this point, the function library and header file required by the routine have been added to the project. Next, we will start implementing the routine.
(II) Installing the Linux font engine library
1. Installing the FreeType font engine library
There are many font engine libraries available; in this example, we'll use the FreeType font engine library for character outline parsing. First, we need to download the FreeType library in our Ubuntu environment. Install the FreeType library online by entering the commands `sudo apt-get update` and `sudo apt-get install libfreetype6 libfreetype6-dev` in the terminal command line, as shown in the image below:
After installation, simply include the `#include` header file when using it. The text marking example requires a font engine library to parse characters; otherwise, the key coordinates of the characters cannot be obtained, making marking and drawing impossible.
2. Configure font files
The FreeType library does not have the function of scanning system font library files; font files need to be passed in when performing outline parsing. Therefore, before starting the example, you need to place the pre-downloaded font files in the project folder for easy use during font parsing. Create a new font folder in the current project and copy the pre-downloaded fonts into the folder, as shown in the following image:
03 Introduction to Text Marking Process and Related Functions
1. Text drawing process
The first step in text processing is to parse the text outline and decompose the outline information. The outline information includes the outline type. Text outlines are divided into line segments, quadratic Bézier curves, and cubic Bézier curves. For Bézier curves, the curve needs to be decomposed into small line segments for processing. The precision of the decomposition can be controlled. Once all the outlines have been processed, the drawing of the current character is considered complete.
2. Introduction to relevant function interfaces
(1) Load and initialize font files
(2) Calculate the quadratic coefficient of the Bézier curve.
A Bézier curve is a curve shape defined by control points. A key property of Bézier curves is that they are composed of a set of control points and binomial basis functions. The binomial coefficients determine the weight of each control point in the Bézier curve. When calculating the contribution of a point on a Bézier curve, the contribution of each control point is obtained by multiplying its corresponding binomial coefficient by the corresponding basis function. Bézier curves can achieve various complex curve shapes by adjusting the positions of the control points and the binomial coefficients.
(3) Obtain the coordinates of the points on the Bézier curve
(4) Three-stage file initialization
(5) Generate empty string
(6) Generate the consecration string
(7) Generate the off-light string
(8) Generate the mark string
(9) Download the file three times
(10) General command execution interface
04 Implementation Example of Text Marking
The text marking routine first needs to acquire the text data. After acquiring the external input text, the text is parsed individually to generate character outline data. The next step is to transform the outline data, converting all the Bézier curve data into small line segments for processing. Finally, the small line segments are connected to generate a cubic file string, which is downloaded to the controller. Executing the marking command will then complete the text marking.
(1) Parse the text into outline data. When parsing text, the FreeType library needs to process each character individually and parse the outline of each character.
·
// Initialize contour data FT_Init_FreeType(&library); const char* fontFilePath = gainFontFilePath(text_data.type); FT_New_Face(library, fontFilePath, 0, &face); // Get character index FT_UInt glyphIndex = FT_Get_Char_Index(face, charCode); // Load character contour information FT_Int32 loadFlags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP; FT_Load_Glyph(face, glyphIndex, loadFlags); // Get glyph slot FT_GlyphSlot glyphSlot = face->glyph; // Get glyph contour information FT_Outline* outline = &glyphSlot->outline;
(2) Convert the contour data into small line segments to generate cubic file strings. For line segment data, cubic file strings can be generated directly by coordinate position. For Bézier curve data, it is necessary to loop through and convert all curve data into small line segment data, and finally generate cubic file strings.
·
// Iterate through all contour data and process different types of data differently for(int n=0;n < outline->n_contours;n++){ LaserScan_z3p_EmptyMove(strFile3,startX,startY,markPara.JumpSpeed,corrJumpDelay);// Move to the starting point LaserScan_z3p_OpenLight(strFile3,markPara.Io_value.emit_io,markPara.OpenDelay,markPara.MarkSpeed);// Open the light tag = FT_CURVE_TAG(tags[0]); // Determine the type of the current contour data switch(tag) { case FT_CURVE_TAG_ON: // Line segment { LaserScan_z3p_Mark(strFile3,markPara.CorDelay,line,2); } case FT_CURVE_TAG_CONIC: // Double Bézier curve { 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());//marking} default: //cubic Bezier curve { 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());//Marking} } LaserScan_z3p_CloseLight(strFile3,markPara.Io_value.emit_io,markPara.CloseDelay,corrJumpDelay);//turn off the light}
(3) The contour coordinates generated by parsing using the FreeType library are determined according to the pixel position of the internal matrix. There is currently no relevant function to adjust the starting point coordinate position. However, when using text marking, it is necessary to determine the starting point position of the marking. Therefore, the implementation method in the example is to compare the parsed coordinate positions, obtain the minimum X and Y coordinates, and offset all contour coordinates to the minimum coordinate position to ensure that the starting point starts from the origin position. The relative position can be determined by changing the starting point position later.
(4) After the three file strings are appended, the three files are downloaded to the controller for text marking.
·
// Initialize the three file strings LaserScan_z3p_Init(); // Generate the text mark string Z3p_process(); // Return to the origin, enable the emergency stop signal, and disable the laser enable LaserScan_z3p_EmptyMove(strFile3,0,0,markPara.JumpSpeed,corrJumpDelay); // Move back to the origin // Download the three file strings to the controller ZMC_DownMem3File(g_handle,strFile3.toLatin1().data(),strFile3.length(),"Zmc_text.z3p"); QString filePath = "Zmc_text.z3p"; QFile file(filePath); // Generate the three files in the current project if (file.open(QIODevice::WriteOnly | QIODevice::Text)){ QTextStream stream(&file); stream << strFile3; file.close(); QMessageBox::warning(this,"Prompt","File generation successful 3 times!");}
05. Implementation effect of text marking
1. Establish controller connection and set laser parameters and process parameters.
2. Enter the text to be marked. You can set the relevant text properties as needed. Below is the text drawn using QPaint.
3. You can change the font, the text start position, and set the italic attribute. Below is the effect after setting.
4. Click to generate three files, select the marking pattern. The following image shows the marking data captured by the oscilloscope.
Full code download address
▼
That concludes our presentation on text marking using the open-source laser galvanometer motion controller from Zhengdong Technology under Ubuntu + Qt.
For more exciting content, please follow the "Zheng Motion Assistant" WeChat official account. For related development environment and example code, please contact Zheng Motion's technical sales engineer: 400-089-8936.
This article is original content from Zheng Motion Technology. We welcome everyone to reprint it for mutual learning and to jointly improve China's intelligent manufacturing level. Copyright belongs to Zheng Motion Technology. Please indicate the source if you reprint this article.