CAM scripting/es

Introducción

El Entorno de Trabajo CAM ofrece herramientas para importar, crear, manipular y exportar trayectorias de herramientas de máquinas G-code en FreeCAD. Con este, el usuario puede importar, visualizar y modificar programas G-code existentes, generar trayectorias de herramientas a partir de formas 3D y exportarlas a G-code.

Este entorno se encuentra actualmente en fase de desarrollo inicial y no ofrece todas las funciones avanzadas presentes en algunas alternativas comerciales. Sin embargo, su interfaz de programación en Python facilita la modificación y el desarrollo de herramientas más potentes.

Inicio rapido

Los objetos Path de FreeCAD se componen de una secuencia de comandos de movimiento. Un uso típico sería el siguiente:

>>> import Path
>>> c1 = Path.Command("g1x1")
>>> c2 = Path.Command("g1y4")
>>> c3 = Path.Command("g1 x2 y2") # spaces end newlines are ignored
>>> p = Path.Path([c1,c2,c3])
>>> o = App.ActiveDocument.addObject("Path::Feature","mypath")
>>> o.Path = p
>>> print (p.toGCode())

Formato interno del código G de FreeCAD

Es importante comprender un concepto preliminar. La mayor parte de la implementación que se muestra a continuación se basa en comandos de movimiento con nombres idénticos a los de los comandos de código G, pero que no están diseñados para ser idénticos a la implementación de un controlador específico. Se eligieron nombres como G0 para representar el movimiento rápido o G1 para representar el movimiento de avance, con el fin de optimizar el rendimiento (ahorro eficiente de archivos) y minimizar el trabajo necesario para la conversión a/desde otros formatos de código G. Dado que el mundo del CNC utiliza miles de dialectos de código G, se seleccionó un subconjunto muy simplificado. El formato de código G de FreeCAD podría describirse como una forma de código G independiente de la máquina.

Dentro de los archivos .FCStd, los datos de ruta se guardan directamente en ese formato de código G.

Todas las traducciones de dialectos a código G de FreeCAD se realizan mediante scripts previos y posteriores. Esto significa que si desea trabajar con una máquina que utiliza un controlador LinuxCNC, Fanuc, Mitsubishi o HAAS específico, deberá usar (o escribir, si no existe) un posprocesador para ese controlador en particular (consulte la sección Importación y exportación de código G a continuación).

Referencia de código G

Las siguientes reglas y directrices definen el subconjunto de código G utilizado internamente en FreeCAD:

Los datos de código G, dentro de los objetos de ruta de FreeCAD, se dividen en comandos. Un comando se define mediante un nombre que debe comenzar con G o M y (opcionalmente) argumentos, que tienen el formato letra seguida de un número decimal, por ejemplo X 0.02, Y 3.5 o F 300. Estos son ejemplos de comandos típicos de código G en FreeCAD:

G0 X2.5 Y0 (El nombre del comando es G0, los argumentos son X=2.5 e Y=0)
G1 X30 (El nombre del comando es G1, el único argumento es X=30)
G90 (El comando se llama G90 y no tiene argumentos)

Se admiten comandos de código G distintos de los que aparecen en la tabla siguiente; es decir, se guardan dentro de los datos de la trayectoria (siempre que cumplan las reglas anteriores, por supuesto), pero no producirán ningún resultado visible en pantalla. Por ejemplo, se puede añadir un comando G81; se almacenará, pero no se mostrará.

Lista de comandos G-code compatibles actualmente

Comando Descrición Argumentos soportados Mostrado
G0 movimiento rápido X,Y,Z,A,B,C Rojo
G1 movimiento normal X,Y,Z,A,B,C Verde
G2 arco en sentido horario X,Y,Z,A,B,C,I,J,K Verde
G3 arco en sentido antihorario X,Y,Z,A,B,C,I,J,K Verde
G81, G82, G83 Perforar X,Y,Z,R,Q Rojo/verde
G38.2 Movimiento recto de la sonda (utilizado en el funcionamiento de la sonda) Z,F Amarillo
G90 Coordenadas absolutas
G91 Coordenadas relativas
(Message) comentario

El Comando objeto

El comando objeto representa un comando de código G. Tiene tres atributos: Nombre, Parámetros y Posición, y dos métodos: toGCode() y setFromGCode(). Internamente, solo contiene un nombre y un diccionario de parámetros. El resto (posición y código G) se calcula a partir de estos datos.

>>> import Path
>>> c=Path.Command()
>>> c
Command  ( )
>>> c.Name = "G1"
>>> c
Command G1 ( )
>>> c.Parameters= {"X":1,"Y":0}
>>> c
Command G1 ( X:1 Y:0 )
>>> c.Parameters
{'Y': 0.0, 'X': 1.0}
>>> c.Parameters= {"X":1,"Y":0.5}
>>> c
Command G1 ( X:1 Y:0.5 )
>>> c.toGCode()
'G1X1Y0.5'
>>> c2=Path.Command("G2")
>>> c2
Command G2 ( )
>>> c3=Path.Command("G1",{"X":34,"Y":1.2})
>>> c3
Command G1 ( X:34 Y:1.2 )
>>> c3.Placement
Placement [Pos=(34,1.2,0), Yaw-Pitch-Roll=(0,0,0)]
>>> c3.toGCode()
'G1X34Y1.2'
>>> c3.setFromGCode("G1X1Y0")
>>> c3
Command G1 [ X:1 Y:0 ]
>>> c4 = Path.Command("G1X4Y5")
>>> c4
Command G1 [ X:4 Y:5 ]
>>> p1 = App.Placement()
>>> p1.Base = App.Vector(3,2,1)
>>> p1
Placement [Pos=(3,2,1), Yaw-Pitch-Roll=(0,0,0)]
>>> c5=Path.Command("g1",p1)
>>> c5
Command G1 [ X:3 Y:2 Z:1 ]
>>> p2=App.Placement()
>>> p2.Base = App.Vector(5,0,0)
>>> c5
Command G1 [ X:3 Y:2 Z:1 ]
>>> c5.Placement=p2
>>> c5
Command G1 [ X:5 ]
>>> c5.x
5.0
>>> c5.x=10
>>> c5
Command G1 [ X:10 ]
>>> c5.y=2
>>> c5
Command G1 [ X:10 Y:2 ]

El objeto Trayectoria

El objeto Trayectoria (Path) contiene una lista de comandos.

>>> import Path
>>> c1=Path.Command("g1",{"x":1,"y":0})
>>> c2=Path.Command("g1",{"x":0,"y":2})
>>> p=Path.Path([c1,c2])
>>> p
Path [ size:2 length:3 ]
>>> p.Commands
[Command G1 [ X:1 Y:0 ], Command G1 [ X:0 Y:2 ]]
>>> p.Length
3.0
>>> p.addCommands(c1)
Path [ size:3 length:4 ]
>>> p.toGCode()
'G1X1G1Y2G1X1'

lines = """
G0X-0.5905Y-0.3937S3000M03
G0Z0.125
G1Z-0.004F3
G1X0.9842Y-0.3937F14.17
G1X0.9842Y0.433
G1X-0.5905Y0.433
G1X-0.5905Y-0.3937
G0Z0.5
"""

slines = lines.split('\n')
p = Path.Path()
for line in slines:
    p.addCommands(Path.Command(line))

o = App.ActiveDocument.addObject("Path::Feature","mypath")
o.Path = p

# but you can also create a path directly form a piece of G-code.
# The commands will be created automatically:

p = Path.Path()
p.setFromGCode(lines)

Como atajo, también se puede crear un objeto Path directamente a partir de una secuencia completa de código G. Este se dividirá automáticamente en una secuencia de comandos.

>>> p = Path.Path("G0 X2 Y2 G1 X0 Y2")
>>> p
Path [ size:2 length:2 ]

La caracteristica Trayectoria

La característica Ruta o Trayectoria es un objeto del documento de FreeCAD que contiene una ruta y la representa en la vista 3D.

>>> pf = App.ActiveDocument.addObject("Path::Feature","mypath")
>>> pf
<Document object>
>>> pf.Path = p
>>> pf.Path
Path [ size:2 length:2 ]

La característica Trayectoria también incluye una propiedad de Posicionamiento. Al cambiar el valor de esta propiedad, se modificará la posición de la función en la vista 3D, aunque la información de la trayectoria en sí no se verá afectada. La transformación es puramente visual. Esto permite, por ejemplo, crear una trayectoria alrededor de una cara con una orientación específica en el modelo, distinta a la que tendrá el material de corte en la máquina CNC.

Sin embargo, las Trayectorias Compuestas pueden utilizar la ubicación de sus hijos (ver más abajo).

Los objetos Herramienta y Tabla de Herramientas

NOTA: Este tipo de uso de herramientas está obsoleto desde la versión oficial 0.19. En la versión 0.19 se implementó el nuevo sistema de herramientas ToolBit para reemplazar este sistema anterior. Por lo tanto, el código ha cambiado con respecto a lo que se muestra a continuación. Visite la página Herramientas de CAM para obtener más información.

Scripting en versiones anteriores o iguales a la 0.18

El objeto Herramienta contiene las definiciones de una herramienta CNC. El objeto Tabla de herramientas contiene una lista ordenada de herramientas. Las tablas de herramientas se adjuntan como una propiedad a las funciones de Proyecto de trayectoria y también se pueden editar a través de la interfaz gráfica de usuario (GUI), haciendo doble clic en un proyecto en la Vista de árbol y haciendo clic en el botón Editar tabla de herramientas en las vistas de tareas que se abren.

Desde ese cuadro de diálogo, se pueden importar tablas de herramientas desde los formatos .xml de FreeCAD y .tooltable de HeeksCad, y exportarlas al formato .xml de FreeCAD.

>>> import Path
>>> t1=Path.Tool()
>>> t1
Tool Default tool
>>> t1.Name = "12.7mm Drill Bit"
>>> t1
Tool 12.7mm Drill Bit
>>> t1.ToolType
'Undefined'
>>> t1.ToolType = "Drill"
>>> t1.Diameter= 12.7
>>> t1.LengthOffset = 127
>>> t1.CuttingEdgeAngle = 59
>>> t1.CuttingEdgeHeight = 50.8
>>> t2 = Path.Tool("my other tool",tooltype="EndMill",diameter=10)
>>> t2
Tool my other tool
>>> t2.Diameter
10.0
>>> table = Path.Tooltable()
>>> table
Tooltable containing 0 tools
>>> table.addTools(t1)
Tooltable containing 1 tools
>>> table.addTools(t2)
Tooltable containing 2 tools
>>> table.Tools
{1: Tool 12.7mm Drill Bit, 2: Tool my other tool}
>>>

Características

La función Trayectoria Compuesta

El objetivo de esta función es agrupar una o más trayectorias de herramienta y asociarlas a una tabla de herramientas. La función Compuesto se comporta como un grupo estándar de FreeCAD, por lo que puede añadir o eliminar objetos directamente desde la Vista de árbol. También puede reordenar los elementos haciendo doble clic en el objeto Compuesto en la Vista de árbol y reordenar sus elementos en la Vista de tareas que se abre.

>>> import Path
>>> p1 = Path.Path("G1X1")
>>> o1 = App.ActiveDocument.addObject("Path::Feature","path1")
>>> o1.Path=p1
>>> p2 = Path.Path("G1Y1")
>>> o2 = App.ActiveDocument.addObject("Path::Feature","path2")
>>> o2.Path=p2
>>> o3 = App.ActiveDocument.addObject("Path::FeatureCompound","compound")
>>> o3.Group=[o1,o2]

Una característica importante de los compuestos de trayectoria es la posibilidad de tener en cuenta o no la ubicación de sus rutas secundarias, configurando su propiedad UsePlacements como verdadera o falsa. Si no se establece en falso, los datos de ruta de sus rutas secundarias se añadirán secuencialmente. Si se establece en verdadero, cada comando de las rutas secundarias, si contiene información de posición (G0, G1, etc.), se transformará primero según la ubicación antes de añadirse.

Por lo tanto, al crear un compuesto con una sola ruta secundaria, se puede hacer que la ubicación de dicha ruta secundaria sea "real" (afecta a los datos de la ruta).

Función del proyecto Trayectoria

El proyecto Trayectoria (Path) es una versión extendida de Compuesto (Compound), que incluye algunas propiedades adicionales relacionadas con la máquina, como una tabla de herramientas. Está diseñado principalmente para ser el tipo de objeto principal que querrá exportar a código G una vez que tenga lista la configuración completa de la trayectoria. El objeto Proyecto ahora está programado en Python, por lo que su mecanismo de creación es ligeramente diferente:

>>> from PathScripts import PathProject
>>> o4 = App.ActiveDocument.addObject("Path::FeatureCompoundPython","prj")
>>> PathProject.ObjectPathProject(o4)
>>> o4.Group = [o3]
>>> o4.Tooltable
Tooltable containing 0 tools

El módulo Trayectoria también incluye un editor de Tabla de Herramientas GUI que se puede llamar desde Python, proporcionándole un objeto que tiene una propiedad ToolTable:

>>> from PathScripts import TooltableEditor
>>> TooltableEditor.edit(o4)

Obtención de la ruta a partir de la forma

Asigne la forma de una pieza de alambre a un objeto Trayecto normal mediante la función de script Path.fromShape() (o la más potente Path.fromShapes()). Al proporcionar como parámetro un objeto de pieza de alambre, su ruta se calculará automáticamente a partir de la forma. Tenga en cuenta que, en este caso, la posición se establece automáticamente en el primer punto del alambre, por lo que el objeto ya no se puede mover modificando su posición. Para moverlo, es necesario mover la forma subyacente.

>>> import Part
>>> import Path
>>> v1 = FreeCAD.Vector(0,0,0)
>>> v2 = FreeCAD.Vector(0,2,0)
>>> v3 = FreeCAD.Vector(2,2,0)
>>> v4 = FreeCAD.Vector(3,3,0)
>>> wire = Part.makePolygon([v1,v2,v3,v4])
>>> o = FreeCAD.ActiveDocument.addObject("Path::Feature","myPath2")
>>> o.Path = Path.fromShape(wire)
>>> FreeCAD.ActiveDocument.recompute()
>>> p =  o.Path
>>> print(p.toGCode())

Características de Python

Las características Path::Feature y Path::FeatureShape tienen una versión en Python, denominada respectivamente Path::FeaturePython y Path::FeatureShapePython, que se puede utilizar en código Python para crear objetos paramétricos más avanzados derivados de ellas.

Importar y exportar código G

Formato nativo

Los archivos de código G se pueden importar y exportar directamente a través de la interfaz gráfica de usuario (GUI), utilizando las opciones de menú Abrir, Insertar o Exportar. Una vez obtenido el nombre del archivo, aparece un cuadro de diálogo que pregunta qué script de procesamiento se debe utilizar. También se puede hacer desde Python.

La información de la trayectoria se almacena en objetos Path mediante un subconjunto del código G descrito en la sección anterior Formato interno del código G de FreeCAD. Este subconjunto se puede importar o exportar tal cual, o bien convertir a/desde una versión específica del código G compatible con su equipo.

Si dispone de un programa de código G muy simple y estándar que cumpla con las reglas descritas en la sección anterior Formato de código G interno de FreeCAD, por ejemplo el boomerang de cnccookbook, puede importarlo directamente a un objeto Path, sin traducción (esto equivale a utilizar la opción Ninguno del cuadro de diálogo de la GUI):

import Path
f = open("/path/to/boomerangv4.ncc")
s = f.read()
p = Path.Path(s)
o = App.ActiveDocument.addObject("Path::Feature","boomerang")
o.Path = p

De la misma manera, puede obtener la información de la ruta como código G "agnóstico" y almacenarla manualmente en un archivo:

text = o.Path.toGCode()
print text
myfile = open("/path/to/newfile.ngc")
myfile.write(text)
myfile.close()

Si necesita un formato de salida diferente, tendrá que convertir ese código G genérico a un formato compatible con su máquina. Esa es la función de los scripts de posprocesamiento.

Uso de scripts de preprocesamiento y posprocesamiento

Si dispone de un archivo de código G escrito para una máquina específica, que no cumple con las reglas internas de FreeCAD, descritas en la sección anterior Formato interno de código G de FreeCAD, es posible que no se importe o no se visualice correctamente en la vista 3D. Para solucionar este problema, debe utilizar un script de preprocesamiento que convierta el archivo del formato específico de su máquina al formato de FreeCAD.

Si conoce el nombre del script de preprocesamiento que debe usar, puede importar su archivo usándolo desde la consola de Python de esta manera:

import example_pre
example_pre.insert("/path/to/myfile.ncc","DocumentName")

De la misma manera, puede generar un objeto Trayectoria (Path) en código G, utilizando un script posprocessor como este:

import example_post
example_post.export (myObjectName,"/path/to/outputFile.ncc")

Escritura de scripts de procesamiento

Los scripts de preprocesamiento y posprocesamiento funcionan como las importaciones y exportaciones habituales de FreeCAD. Al seleccionar un script de preprocesamiento o posprocesamiento en el cuadro de diálogo, el proceso de importación o exportación se redirigirá al script especificado. Los scripts de preprocesamiento deben contener, como mínimo, los métodos open(filename) e insert(filename, docname). Los scripts de posprocesamiento deben implementar el método export(objectslist, filename).

Los scripts se colocan en la carpeta Mod/Path/Path/Post/scripts o en el directorio de macros del usuario. Puede darles el nombre que desee, pero por convenio, y para que la interfaz gráfica los seleccione, los nombres de los scripts de preprocesamiento deben terminar en "_pre" y los de los scripts de posprocesamiento en "_post" (asegúrese de usar el guion bajo, no el guion normal, de lo contrario Python no podrá importarlo). Este es un ejemplo de un preprocesador muy sencillo. Encontrará ejemplos más complejos en la carpeta Mod/Path/Path/Post/scripts.

def open(filename):
    gfile = __builtins__.open(filename)
    inputstring = gfile.read()
    # the whole gcode program will come in as one string,
    # for example: "G0 X1 Y1\nG1 X2 Y2"
    output = ""
    # we add a comment
    output += "(This is my first parsed output!)\n"
    # we split the input string by lines
    lines = inputstring.split("\n")
    for line in lines:
        output += line
        # we must insert the "end of line" character again
        # because the split removed it
        output += "\n"
    # another comment
    output += "(End of program)"
    import Path
    p = Path.Path(output)
    myPath = FreeCAD.ActiveDocument.addObject("Path::Feature","Import")
    myPath.Path = p
    FreeCAD.ActiveDocument.recompute()

Los preprocesadores y postprocesadores funcionan exactamente igual. Simplemente hacen lo contrario: los preprocesadores convierten el código G específico al código G "agnóstico" de FreeCAD, mientras que los posprocesadores convierten el código G "agnóstico" de FreeCAD al código G específico de la máquina.

Agregar todas las caras de un ShapeString a la lista de BaseFeature de una operación ProfileFromFaces

Este ejemplo se basa en una discusión en el foro alemán.

Requisitos previos

El código

El siguiente código agregará todas las caras de ShapeString y creará las rutas:

doc = App.ActiveDocument
list_of_all_element_faces = []
for i, face in enumerate(doc.ShapeString.Shape.Faces):
    list_of_all_element_faces.append('Face' + str(i + 1))

doc.Profile_Faces.Base = [(doc.ShapeString, tuple(list_of_all_element_faces))]
doc.recompute()