Project:RELaserSoftware/MOL file format

From London Hackspace Wiki

< Project:RELaserSoftware

Revision as of 20:58, 8 July 2011 by Wonko (talk | contribs) (Added everything I know so far about cutting straight lines in a MOL file)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Looking at: /Solexious/MarioBoxes/MINIMARIO.MOL

No ASCII strings (looking using strings)

Does not appear to be compressed (too many zeroes)

0x000 Header
0x200 One set of information What?
0x400 Another set of information.
0xa10 Likely co-ordinate data. Quite repetitive. Analysis document was mario boxes, with many repetitions of sub boxes, so that makes sense. It looks like possible 16bit number co-oords as the numbers range from a few thousands to hundreds. 32bits are in unrealistic ranges (huge in negative ranges).

Projects/RELaserSoftware/Compilation traces


DESCRIPTION

ABOUT

The .MOL files are generated from CAD drawings (dxf import) using a proprietary library from Leetro from within LaserCut. The mol file can be stored on a USB stick and is automatically loaded into the CNC-Laser where it can be selected and run from the keypad.

There is also a USB protocol that connects the CNC machine to a PC to directly control basic functions and manage file up- and download. This protocol is not documented here!

STATUS

we have a pretty good understanding of the file format to the point that we can generate new MOL files from a dxf drawing, at least for cutting patterns on the test machine. This is for cutting only, no raster engraving and other features yet!

THE FILE FORMAT

The file format is binary, using LSB 4-byte words. The floating point format is not IEEE, so a conversion is required. All files have four chunks at fixed locations:

  • the header chunk starts at 0 and contains 32 words, followed by 0's
  • the config chunk is at 0x00000200 and contains informations about the total artwork
  • the test chunk is at 0x00000400 and moves the laser head on the bounding box of the artwork
  • the draw chunk is at 0x00000A00 contains all commands to output the actual drawing and cutting commands
  • the file is then patched to the next 512 byte boundary

THE HEADER

The header chunk contains the parameters of the destination machine, version numbers, and general information including file size. All data is at fixed positions.

THE CONFIG CHUNK

This block has all the information about the position and size of the artwork. It uses, like the following chunks, a number of binary commands, most of them deciphered below.

THE TEST CHUNK

This is called when the "Test" button is pressed on the panel. It moves the laser head around the bounding box of the artwork and is a great help for positioning the material. In this file, it is simply a bunch of line drawing commands.

THE DRAW CHUNK

This is called when the "Play" button is pressed and contains a setup part followed by a list of machine control commands that cut and draw the artwork.

BINARY COMMANDS

Every command starts with three bytes describing the command itself, plus one byte containing the number of parameters following. The parameters are always 4-byte words in LSB integer or floating point format, or four individual bytes. The FP format differs slightly from the IEEE standard, but can be converted by shifting a few bits around.

The same command can have a different number of arguments!

The size byte can be 0x80 in which case, the actual number of arguments is give in the 4-byte integer that follows.

A special command (0x46 0x09 0x00 0x80 0xnnnnnnnn) encapsulates n motion commands. The motion commands follow the same scheme as all other binary commands. This is likely used for multiple prints of the same drawing in a matrix layout.

SAMPLE FILE

Header

The header describes the parameters of the machine for which the data was created. We find information about the file size and the stepper resolution. There should not be any information how to map channels to motors, etc., as that is likely done in a separate configuration file.

Size of entire file in bytes

  • 00000000: 0x00001000 Size of file in bytes

Unknown, fixed value

  • 00000004: 0x00000022 34d ?

File Version Number

  • 00000008: 0x02 0x02 0x01 0x04 ?

Unknown, fixed value

  • 0000000c: 0x00000001 ?

This word changes when the size of the file changes, i.e. when lines are added This line corresponds to the number of "move relative" commands in the entire file counting "unknown 07" and "unknown 09" as well. Is that coincidence? What would this value be good for?

  • 00000010: 0x00000029 somehow related to the file size or the number of commands

Unknown, fixed value

  • 00000014: 0x00000001 ?

Unknown, fixed value

  • 00000018: 0x00000000

Unknown, fixed value

  • 0000001c: 0x00000000

Describing the stepper resolution in x and y

  • 00000020: -20833 steps per 100mm in x direction
  • 00000024: -20833 steps per 100mm in y direction

Unknown, fixed value

  • 00000028: 0x00481095 ?

Unknown, fixed value

  • 0000002c: 0x471a0000 ?

Unknown bunch of zeros, likely reserved for later use

  • 00000030 - 0000006c

Unknown, fixed value

  • 00000070: 0x00000001 ?

Unknown, fixed value

  • 00000074: 0x00000002 ?

Unknown, fixed value, maybe the number of blocks in this file?

  • 00000078: 0x00000003 ?

Unknown, fixed value

  • 0000007c: 0x00000005 ?

Data Block at 0x00000200

The configuration chunk still has a bunch of unknown commands, few of them seem to change for a single machine configuration.

Unknown, fixed value

  • 00000200: : unknown 01

Unknown, fixed value, the default driver for the X-axis is #4 (maybe related?)

  • 00000204: : unknown 02: 4, 4.00

Unknown, fixed value, the default driver for the Y-axis is #3 (maybe related?)

  • 00000214: : unknown 02: 3, 3.00

Unknown, fixed value

  • 00000224: : unknown 03

Unknown, fixed value

  • 00000228: : unknown 04

Unknown

  • arg1 is unknown, but repeats in 'unknown 11'
  • arg2 is the start speed for all head movements as describen in the settings
  • arg3 is the maximum speed for moving around "quickly"
  • arg4 is the acceleration value to get to the above speed (space acc)
  • arg5 is the value for acceleration from the settings
  • arg6 is unknown and nowhere to be found, probably the slow acceleration default
  • 0000022c: : unknown 05: 603, 1041(5.00%), 41666(200.00%), 145833(700.00%), 104166(500.00%), 72916(350.00%)

Set the Stepper sizes

  • arg1 is the number of steps required in X direction
  • arg2 is the same for Y
  • arg3 is likely the same in Z direction
  • TODO: find out how we can move in Z
  • 0000024c: : step size x:208.333/mm y:208.333/mm z:800/mm

Unknown, fixed value, maybe explicitly switching the laser off?

  • 0000025c: : unknown 06: 0

Object origin. Cutting a 100x100 object on a 900x600 table would move the laser head to the top right corner of a centered work piece. (772 see "move rel")

  • 00000264: : unknown 07: 772, x:500.005mm, y:350.002mm

Motion parameters:

  • arg1 is the initial speed
  • arg2 is the maximum speed
  • arg3 is the acceleration
  • 00000274: : unknown 08 a:1041(5%), b:41666(200%), c:145833(700%)

Object size. Our test object is 100x100, so this command moves to the bottom left corner.

  • 00000284: : unknown 09: 772, x:-100mm, y:-100mm

Unknown, fixed value

  • 00000294: : unknown 10: 3, 2.000000, 2.000000

Unknown, fixed value, 603 also appears at 0x0000022c

  • 000002a8: : unknown 11: 603

Unknown, fixed value

  • 000002b4: : unknown 12

Data Block at 0x00000400

This is the block that is called when the user presses "Test" on the panel. It moves the laser head on the bounding box around the artwork.

Begin of the subroutine. I don't know if the ID has a specific meaning, or if the file position of this block is sufficient to make it the test block. Just don't change it.

  • 00000400: : begin subroutine 1

See above

  • 00000408: : unknown 05: 603, 1041(5.00%), 41666(200.00%), 145833(700.00%), 104166(500.00%), 72916(350.00%)

This command encloses all following draw commands. It may be used for multiple rendering of the drawing commands at different location to keep file size small. The commands inside the block follow the same scheme as those outside.

  • 00000428: : command block follows, 112 words (form 00000430 to 000005f0)
  • move relative -100, 0

The next 8 commands are needed to draw a single line. There are three phases: acceleration, constant speed(optional), deceleration. All three put together move the head from a to b along a straight line. If the angle of two consecutive lines is below some threshold, the end speed of the previous line and the initial speed of the current line may be significantly higher.

TODO: Curves are probably done differently, but also from line segments? Future.

Accelerate: the following command will accelerate the head along the given line

  • 00000430: : accelerate

Set the initial speed, the maximum speed, and the acceleration.

  • 00000438: : set speeds a:1041(5%), b:41666(200%), c:145833(700%)

Move the head on a straight line to the new position. The position is given in steps relative to the current position. The meaning of 772 (0x0304) is unknown but could very well be the index of the stepper that is requested to move (3=Y, 4=X - remember that this is LSB, so in the binary file, we see 0x04 0x03 0x00 0x00 - maybe we can move Z as well, or even up to four axes at the same time? (2=Z))

TODO: is 722 the axes parameter? If so, can we move Z?

  • 00000448: : move rel 772, x:-28.5509mm, y:0mm

Even though we still are in acceleration mode, setting the initial speed equal to the maximum speed will make this a constant speed motion

  • 00000458: : set speeds a:41666(200%), b:41666(200%), c:145833(700%)
  • 00000468: : move rel 772, x:-42.9175mm, y:0mm

Set the next speed parameters so that they are used for deceleration from the maximum speed (b) to the ending speed (a), using the deceleration parameter (c)

  • 00000478: : decelerate
  • 00000480: : set speeds a:1473.12(7%), b:41666(200%), c:145833(700%)
  • 00000490: : move rel 772, x:-28.5317mm, y:0mm

This is the end of the move command. All the following commands use the same scheme.

move relative 0, -100

  • 000004a0: : accelerate
  • 000004a8: : set speeds a:1473.12(7%), b:41666(200%), c:145833(700%)
  • 000004b8: : move rel 772, x:0mm, y:-28.5317mm
  • 000004c8: : set speeds a:41666(200%), b:41666(200%), c:145833(700%)
  • 000004d8: : move rel 772, x:0mm, y:-42.9367mm
  • 000004e8: : decelerate
  • 000004f0: : set speeds a:1473.12(7%), b:41666(200%), c:145833(700%)
  • 00000500: : move rel 772, x:0mm, y:-28.5317mm

move relative 100, 0

  • 00000510: : accelerate
  • 00000518: : set speeds a:1473.12(7%), b:41666(200%), c:145833(700%)
  • 00000528: : move rel 772, x:28.5317mm, y:0mm
  • 00000538: : set speeds a:41666(200%), b:41666(200%), c:145833(700%)
  • 00000548: : move rel 772, x:42.9367mm, y:0mm
  • 00000558: : decelerate
  • 00000560: : set speeds a:1473.12(7%), b:41666(200%), c:145833(700%)
  • 00000570: : move rel 772, x:28.5317mm, y:0mm

move relative 0, 100

  • 00000580: : accelerate
  • 00000588: : set speeds a:1473.12(7%), b:41666(200%), c:145833(700%)
  • 00000598: : move rel 772, x:0mm, y:28.5317mm
  • 000005a8: : set speeds a:41666(200%), b:41666(200%), c:145833(700%)
  • 000005b8: : move rel 772, x:0mm, y:42.9175mm
  • 000005c8: : decelerate
  • 000005d0: : set speeds a:1041(5%), b:41666(200%), c:145833(700%)
  • 000005e0: : move rel 772, x:0mm, y:28.5509mm

This is where the block ends

This is the end of subroutine 1

  • 000005f0: : end subroutine 1

Data Block at 0x00000a00

This is the block that cuts the actual artwork.

This is another subroutine ID

  • 00000a00: : begin subroutine 3

Unknown, fixed

  • 00000a08: : unknown 13: 3000

Unknown, fixed, 4 is the X axis controller, maybe a direction flag

  • 00000a10: : unknown 14: 4, 0

Unknown, fixed, maybe flags for that axis: direction, microstepping, power?

  • 00000a1c: : unknown 15: 516(0x04, 0x02)

Unknown, fixed, 3 is the Y axis

  • 00000a24: : unknown 14: 3, 0

Unknown, fixed, flags?

  • 00000a30: : unknown 15: 515(0x03, 0x02)

Short version of the basic parameters (single laser?)

  • arg1 is the corner power (similar to the stepper acceleration, this is the starting power)
  • arg2 is the maximum power
  • arg3 is the cutting start speed
  • arg4 is the maximum cutting speed
  • arg5 is unknown
  • 00000a38: : laser power corner:40.00%, straight:40.00%, start speed:1041(5.00%), speed:20833(100.00%), ??:0

Long version of the basic parameters (dual laser? or just floating point precision?)

  • arg3 seems to be the initial power of the second laser
  • arg4 seems to be the maximum power
  • 00000a50: : laser power corner:40.00%, straight:40.00%, p3:30.00%, p4:50.00%, startspeed:1041(5.00%), speed:20833(100.00%), ??:0

Command block used for repetition. Interestingly, the blower commands are inside the block.

  • 00000a70: : command block follows, 290 words (form 00000a78 to 00000f00)

Switch on the blower. The numerical values here probably correspond to the output ports on the controller board. If we find the pattern, we can control additional devices, like switching the Y axis to control a rotary device, or starting the roller of a laser sintering setup.

  • TODO: find the command-to-port mapping for this
  • TODO: verify that this really is the blower, since our machine has no switched blower
  • 00000a78: : blower on

Now is the time for all danger seekers to put on their goggles… .

  • 00000a80: : laser on

cut relative to -100, 0

  • 00000a88: : accelerate
  • 00000a90: : set speeds a:1041(5%), b:20833(100%), c:104166(500%)
  • 00000aa0: : move rel 772, x:9.97456mm, y:0mm
  • 00000ab0: : set speeds a:20833(100%), b:20833(100%), c:104166(500%)
  • 00000ac0: : move rel 772, x:80.0461mm, y:0mm
  • 00000ad0: : decelerate
  • 00000ad8: : set speeds a:936.9(4%), b:20833(100%), c:104166(500%)
  • 00000ae8: : move rel 772, x:9.97936mm, y:0mm

Switch the laser off already. Even though the next line requires no repositioning, LaserCut has switched off the laser, just to turn it right back on. This does no harm, but makes the file bigger then needed. It also explains why we should always "connect lines" in LaserCut. If lines are connected, we would simply add movement commands here until we reach the end of the cut.

  • 00000af8: : laser off

cut relative to 0, -100

  • 00000b00: : laser on
  • 00000b08: : accelerate
  • 00000b10: : set speeds a:936.9(4%), b:20833(100%), c:104166(500%)
  • 00000b20: : move rel 772, x:0mm, y:9.97936mm
  • 00000b30: : set speeds a:20833(100%), b:20833(100%), c:104166(500%)
  • 00000b40: : move rel 772, x:0mm, y:80.0413mm
  • 00000b50: : decelerate
  • 00000b58: : set speeds a:936.9(4%), b:20833(100%), c:104166(500%)
  • 00000b68: : move rel 772, x:0mm, y:9.97936mm
  • 00000b78: : laser off

(...)

Leaves the head just where it's at. In case of a repetition, the controller will likely know where to move next and continue with the next cutout.

  • 00000ef0: : blower off
  • 00000ef8: : blower off

This is where the block ends

  • 00000f00: : end subroutine 3

The rest of the file is filled with 0x00 to the next 512 byte boundary, probably to avoid reading errors when buffering from the USB stick to internal RAM.