Raster Engraving
Rastering an image
I have seen recommendations the PNG files be used for this purpose, but because the raster functionality uses the Python Image Library for all image processing, it seems as if any image format readable by PIL should be useable.
The O145 subroutine is used to trigger the Raster function in Ben Jackson's configuration for driving the Buildlog 2.x lasercutter. Because Linux CNC only allows numeric values to be passed to external programs, the filename of the image is expected to be of the format "*-xxxx.ext" where "xxxx" is any integer value and "ext" is an image file extension. For automatic file location to work, the image file must exist in "/home/jamesbond/Desktop/Gcode" and it must, at the very least, include the hyphen. Some valid filename: "pestes-555.png", "a-12.gif", "-890198283.jpg", "555-12345.gif". Invalid filenames: "555.png", "pestes.gif", "joe456.jpg".
If the file cannot be located in the mandatory location, a GUI window will popup asking the user to select the image file.
There may be a way to make some changes to the way the image file is located to allow it to be found in the same directory as the G-Code file it is called from, but some testing will need to be performed. So for now, you could either place it in the ~jamesbond/Desktop/Gcode directory or use an arbitrary number and then find it with the GUI window.
The following is an example of making a call to the O145 subroutine which drives the raster engraving function:
O145 call [777] [8] [190] [100] [182] [0.085] [0.423] [8]
Note that the brackets are required.
The parameters here are:
- 777 - The image file number as described above
- 8 - The X axis starting position
- 190 - The Y axis starting position
- 100 - The height of the actual engraving in current units (mm or inches depending on the mode of the Laser cutter)
- 182 - The width of the actual engraving in current units
- 0.085 - The "xscangap", effectively determines the X axis DPI resolution, more details below
- 0.423 - The "yscangap", effectively determines the Y axis DPI resolution, more details below
- 8 - The overscan amount in current units
Starting Positions
The X and Y starting positions are the upper left corner of the actual engraved image. The image will be engraved below and to the right of this point. Note that unless the overscan value is set to 0, the X position can not be 0. That would result in an overscan that is outside of the physical bounds of the machine. Additionally, the Y starting position must be at least the size of the Y axis or else the rastered image would technically run below the physical bounds of the machine's Y axis.
Height and Width
These are exactly what they sound like - the actual width and height of the engraving. Units will be in mm if G21 has been executed. Units will be in inches if G20 has been executed.
xscangap and yscangap
These values determine the DPI (or DPmm as it were) for the image. In actuality, this value is the inverse of DPI or DPmm. It is units per pixel. In the example above, which was done in mm units, the 0.085 = 300 DPI:
( 25.4 mm / 1 Inch ) x ( 1 Inch / 300 Dots ) = 0.8467 mm per dot
Note that increasing density of the etching on the Y-axis will increase the amount of time that it takes to engrave the image. Increasing density on the X-axis, however, simply changes how frequently the laser firing can be modulated and does not affect the time it takes to engrave. In the example above, I used a lower resolution on the Y-axis in order to increase the speed of the engraving, with a high resolution on the X-axis. For the yscangap shown above (0.423), we can work backwards to determine the resolution:
( 1 Dot / 0.423 mm ) x ( 25.4 mm / 1 Inch ) = ~60 DPI
Overscan
If the laser simply scanned back and forth across the dimensions of the image, the sides of the image would be burned darker due to the fact that the laser mirror gantry must decelerate, stop, reverse and accelerate at each scan line. The overscan is how many units to scan past the left and right edges of the image in order for the y-axis to be moving at full speed before it hits the edge of the image. Ben Jackson gives a formula for this, which for the values of our laser seemed to indicate about 15mm. However this seems to be a very large amount and I suspect that our configuration is conservative and that 15mm is not really required here. I have done a couple images with 8mm overscan without any noticeable darkness along the edges. As more testing is performed, this value can be updated. The larger this is, of course, the longer an engraving will take, so finding a minimum here will be a timesaver but should be fairly constant for the machine.
Example G-Code
Here is an example of a working G-Code program to raster an image:
% M63 P0 (Turn off synchronized motion) M65 P0 (Turn off digital output immediately) G00 Z0.000001 (Z-Magic output off) G21 (All units in mm) M68 E0 Q0.16 (Set the laser to fire at 0.16) F3000 (Feedrate 3000 mm/minute) M3 (Enable the spindle) S0.000001 (Set the spindle to the slowest rate that LinuxCNC sees as being on) O145 call [777] [8] [190] [100] [182] [0.085] [0.423] [8] ( pic x y w h xscangap yscangap overscan ) M5 %
Notes
The spindle must be enabled, as the 2x_Laser.hal ties the spindle to a master laser disable/enable function. However, the fact that the spindle is enabled also allows laser pulses to fire aside from the rastering. So I have used the lowest possible spindle speed which LinuxCNC seems to interpret as the spindle actually still being enabled.
You also need to disable digital output 0 with the "M63 P0" and "M65 P0" codes so that the laser does not otherwise fire during scanning.
I have thus far only done raster engraving using the highest feedrate the KM laser is currently set to allow -- 3000 mm/s. It may be possible that slower rates might be required for other materials. I have thus far only used 3mm plywood.
I have also not experimented yet with different laser strengths. This will most definitely need to change depending on the material being engraved.
It should also be possible to include the above into the beginning of an existing G-Code file to mix raster engraving with vector cut and engrave operations. Specific feed rates and spindle speeds would need to be included in between, but would likely already be present in a file generated for vector operations, such as from the KMLaser Inkscape plugin.
Raster Operational Flow (Gritty details)
The O145 subroutine is actually defined in the "145.ngc" file. All of the parameters specified in the "O145 call" command are passed to this G-Code subroutine.
The O145 subroutine then runs the M144 command. In LinuxCNC, M100-M199 commands run external scripts. Unfortunately, only 2 parameters are allowed to be passed to external scripts, P and Q, both of which are floating point numbers. When the M144 command is executed, it is simply passed the "pic" value from the "O145 call" command which represents the number in the filename of the image to be rastered.
The M144 script opens the image file, prompting with a window if it cannot be found in the default location (/home/jamesbond/Desktop/GCode). It also opens a UNIX pipe and waits for additional parameters to be passed in through this pipe. Meanwhile, the O145 subroutine has executed 3 M145 commands. The external M145 command is a Python script which simply takes the P and Q parameters passed to it and sends them to a UNIX pipe. The original M144 script receives the other parameters it requires from the UNIX pipe -- x, y, w, h, xscangap, yscangap and overscan.
Now that the M144 command has all of the parameters it requires, it used the Python Image Library to resize the image to the required width and height as well as convert it to a 2 tone image.
Two things happen in conjunction at this point of the flow -- the O145 subroutine moves to the start location and simply scans back and forth across the raster image location.
The M144 script goes line by line through each pixel in the image. It determines when pixel changes occur and produces output indicating at which x values those changes occur. It produces output consisting of 2 boolean values and a floating point value: raster-fire, raster-rev, and raster-pos.
Raster-fire indicates whether or not the laser should start or stop firing at the given position. Raster-rev indicates whether the particular scan line is moving forward or backward in the x direction. Raster-pos is the x position where a change in firing status occurs.
So, rather than telling the laser to fire a series of pulses, the script determines at which x positions the laser should be turned on, and at which x positions the laser should be turned off. For any lines with no pixels to be burned, it will still include output with the raster-rev set to indicate a blank line.
The output of the M144 script is sent through the LinuxCNC "halstream" command. This ties in with a "stream" object defined in the 2x_Laser.hal file. There is logic within the HAL file which ultimately results in using the 3 raster-* output values of the script to determine when a value which indicates that the laser should be on due to the raster function (laser-raster).
The HAL file also includes overall logic that ties in all of the modes which can be used to fire the 2x_Laser in LinuxCNC. For example, the laser can be explicitly fired/disabled with the M64/M65 commmands, or fired in coordination with a move via the M62/M63 commands. And turning off the spindle by setting a spindle speed of "S0" or explicitly disabling the spindle with "M5" serves as a master control over the laser, preventing it from firing from any purpose.
The HAL file using a LinuxCNC logical construct which ultimately declares boolean logic for when pin 17 on the parallel port triggers the laser:
laser-final <= laser-master & (laser-raster | ((laser-magic-z | laser-dout) & laser-pulsed))
The ((laser-magic-z | laser-dout) & laser-pulsed))
portion is for normal G-code operation using the Z-Position, M3/M5, M62/M63 and M64/M65 commands. For raster engraving, you do not want these functions to interfere and trigger extra laser pulses. To make sure that does not happen, the Z position needs to be kept at 0 or higher and digital output pin #0 needs to be kept off -- via the M63 and M64 commands.
The laser-master is tied to whether or not the spindle is turning. So, if the spindle is not turning, the laser will never fire. Therefore, you can't simply set the spindle speed to 0 in the hopes that "laser-pulsed" will have fire 0 pulses per unit.
Tuesday night rastering presentation
Link to Powerpoint slides here: File:Goldfinger Raster Etching.pptx