This documentation is not finished. Please help and contribute documentation.
GuiCommand model explains how commands should be documented. Browse Category:UnfinishedDocu to see more incomplete pages like this one. See Category:Command Reference for all commands.
See WikiPages to learn about editing the wiki pages, and go to Help FreeCAD to learn about other ways in which you can contribute.
FreeCAD uses as internal representation for the generated paths, so called G-codes. They can describe such things as: speed and feed rates, stopping the motor etc... But the most important thing is the movements they describe. These movements are rather simple: They can be straight lines or they can be circular arcs. More sophisticated curves such as B-splines are already approximated by FreeCAD's CAM Workbench.
Many mills use G-codes as well to control the milling process. They may look almost like the internal codes, but there may be some differences:
Furthermore there are other languages to control a mill, such as HPGL, DXF, or others.
The postprocessor is a program which translates the internal codes into a complete file, that can be uploaded to your machine.
You may start with a very simple model showing how your machine reads straight lines and arcs. Prepare it with any program suitable for your machine.
A file for such paths starting at (0,0,0) and going towards Y would be helpful. Make sure it is the tool itself moving along this path, i.e. no tool radius compensation must be applied.
The path in FreeCAD would look like this. Please note the small blue arrow, it indicates the starting direction. For a very first go you may provide only one level in the XY-plane.
You can then have a look at the file and compare it to the output of existing postprocessors such as linux_cnc_post.py or grbl_post.py and try yourself to adapt them or you upload your to the Path/CAM forum to get some help.
The postprocessor can be placed in your FreeCAD macro directory. For a prefix <filename> the postprocessor should get the name <filename>_post.py. Please note that the postfix and extension, _post.py, have to be lower case.
The new name should be reflected at the head of the parser arguments list in the <filename>_post.py file, e.g.:
parser = argparse.ArgumentParser(prog="grbl", add_help=False)
If you are testing, place it in your macro directory. If it functions well, please consider providing it for others to benefit (post it to the FreeCAD Path/CAM forum) so that it can be included in the FreeCAD distribution going forward.
For comparison you may look at the postprocessors which come with your FreeCAD installation. They are located under the directory <path_to_your_FreeCAD_distro>/Mod/CAM/Path/Post/scripts. Widely used are the linuxcnc and the grbl postprocessors. Studying their code can give helpful insights.
This post discusses some internals from the linuxcnc postprocessors. The same strucure is used in other postprocessors as well.
Looking at linux_cnc_post.py, you'll see the export function (as of 0.19.20514 it's at line 156)
def export(objectslist, filename, argstring):
# pylint: disable=global-statement
...
gcode = ""
...
...
it collects step by step in the variable "gcode" the processed G-codes and handles the overall exporting of post-processable objects (operations, tools, jobs ,etc). Export handles the high level stuff like comments and coolant but any objects that have multiple CAM commands (tool changes and operations) it delegates to the parse function (as of 0.19.20514 it's at line 288).
def parse(pathobj):
...
out = ""
lastcommand = None
...
...
Similarly to the "export" function collects parse the G-codes in the variable "out". In the variable "command" the commands as seen in the CAM workbench's "inspect G-code" function are stored and can be investigated for further processing.
for c in pathobj.Path.Commands:
command = c.Name
It recognizes the different G, M, F, S, and other G-codes. By remembering the last command in the variable "lastcommand" it can suppress subsequent repetitions of modal commands.
Both parse and export are just formatting strings and concatenating them together into what will be the final output.
You'll see that both functions also call the "linenumber()" function. If the user wants line numbers, the linenumber function returns the string to stick in to the appropriate spot, otherwise it returns an empty string so nothing is added.