Este es el manual de Studio 1.1.0, una versión anterior. El manual de la última versión

Documentación 1.1.0 Referencia

Formatos de archivo

_Borrador (ronda 14): el texto se está escribiendo; las secciones aún pueden crecer._

Programas

Un programa es un archivo de texto de código G en el dialecto de Grbl 1.1, que habla el núcleo propio de Twinwright. Studio lee cualquier archivo de este tipo. Los programas que escribe su CAM tienen este aspecto:

(Sensor bracket)
(tool T1 flat 6 n3 L20, 6061-T6: S13263, F836, plunge F279, depth of cut 1.20 mm, stepover 2.40 mm)
(program zero: on the blank's top; the machine's top first; T1 is the length reference)
G21 G90 G17 G94 G54
G53 G0 Z0
T1 M6
G53 G0 Z0
M3 S13263
G4 P3 (up to speed)
(face X-2..62 Y-2..42, 0.3 mm deep: 1 layer of 12 passes)
...
M5
M9
G53 G0 Z0
M30
ParteQué es
CabeceraComentarios: el título del trabajo; la primera herramienta, el material y los datos de corte principales; dónde está el cero del programa
ModosG21 G90 G17 G94 G54: milímetros, absoluto, el plano XY, avance por minuto, decalaje de origen G54
G53 G0 Z…Un movimiento al extremo superior de Z, en coordenadas de máquina: al principio, en cada cambio de herramienta y al final. La altura es aquella en la que Z queda al hacer la referencia.
T… M6Un cambio de herramienta. El controlador mide la herramienta nueva en el sensor de longitud de herramienta.
M3 S…, G4 P…El husillo en marcha y después un tiempo de espera mientras alcanza la velocidad. La bomba de un husillo refrigerado por agua (M8) va primero.
Comentarios de elementoCada elemento empieza con un comentario que dice qué corta
MovimientosG0, G1 y arcos G2/G3 con I y J. El taladrado usa G81, o G83 con descargas, con su plano R 1 mm por encima de la parte superior.
FinalM5, M9, el movimiento al extremo superior, M30

Los comentarios van entre paréntesis. Las líneas no llevan números.

Studio guarda cada versión de un programa en la carpeta de programas (Documentos/Twinwright Studio/programs), en una carpeta con el nombre del programa:

ArchivoQué contiene
v0001.ncEl texto del programa, tal como se guardó
v0001.jsonSu versión, la hora (UTC), quién lo hizo, por qué, la versión de la que procede, su hash y sus líneas
v0001.ops.jsonEn qué se convirtió cada elemento (operación, estrategia, herramienta, líneas, velocidad, avance): lo lee una hoja de amarre

Trabajos y amarres

Un trabajo es la descripción de una pieza a partir de la cual el CAM genera programas. Es un objeto JSON:

ClaveSignificado
nameEl nombre del programa, por ejemplo bracket.nc
title, descriptionTextos para la cabecera del programa y la hoja de amarre
materialEl material, por ejemplo 6061-T6; se entienden los nombres de otras normas
toolLa herramienta del husillo, como especificación (flat 6 n3 L20)
toolsLa tabla de herramientas: {"1": "flat 6 n3 L20", "2": "drill 3.4 118 L20"}. Si se omite: la de la máquina.
cuttingValores que sustituyen a los elegidos: rpm, feed, ap, ae, finish_ap; corner_steps (true o false: las esquinas interiores de una pared se cortan primero por escalones)
safe_zLa altura a la que se hacen los movimientos de traslado, en milímetros sobre el origen de pieza
zeroDónde está el origen de pieza: front-left-top (el valor por defecto) o center-top
featuresLos elementos, en el orden en que se cortan. Consulte Crear programas.
setupsEn lugar de features: un objeto por cada amarre
nestEn lugar de features: piezas anidadas en una placa

Un amarre tiene sus propios features y dice cómo llega la pieza a él desde el amarre anterior:

ClaveSignificado
turnu: volteada alrededor de X (el frente y la parte trasera se intercambian); v: alrededor de Y (izquierda y derecha)
fixtureSe sujeta de otro modo a partir de este amarre (vise, clamps, tape …)
zeroEl origen de pieza, determinado de nuevo: front-left-top o center-top. Si se omite tras un volteo o un nuevo utillaje: front-left-top; en otro caso, el origen del amarre anterior.
name, tool, tools, cutting, safe_zLos propios del amarre, por encima de los del trabajo
{"name": "bracket.nc", "title": "Sensor bracket", "material": "6061-T6",
 "tools": {"1": "flat 6 n3 L20", "2": "drill 3.4 118 n2 L20"},
 "features": [
  {"op": "face", "x0": -2, "y0": -2, "x1": 62, "y1": 42, "depth": 0.3, "tool": 1},
  {"op": "pocket", "shape": "rect", "x0": 6, "y0": 6, "x1": 28, "y1": 34, "r": 3, "depth": 4, "tool": 1},
  {"op": "pocket", "shape": "circle", "cx": 44, "cy": 20, "d": "Ø12 H7", "depth": 6, "tool": 1},
  {"op": "drill", "points": [[44, 6], [44, 34]], "depth": 8, "tool": 2}]}

Cada versión de un trabajo se guarda junto al programa que generó, como job-v0001.json: su versión, la hora (UTC), quién lo hizo (operator o ai:<client>), una nota, la versión del programa que generó y el propio trabajo. Un trabajo descrito en amarres lista además el programa de cada amarre, la versión generada y su hash.

Grabaciones (MCAP)

--mcap FILE graba una ejecución en un archivo MCAP (mcap.dev, formato versión 0): un canal para cada tipo de datos, mensajes JSON, cada canal con su esquema JSON, sin fragmentar ni comprimir, y un resumen al final con las estadísticas y un CRC. Las pruebas de Studio vuelven a leer los archivos y los comparan con la especificación de MCAP; las herramientas que leen MCAP, como PlotJuggler y Foxglove, están pensadas para abrirlos, pero todavía no se ha probado.

  • --rec-period MS fija con qué frecuencia se escriben los canales muestreados (1 ms si no se indica).
  • Una grabación no cambia nada en la ejecución: una ejecución grabada y la misma ejecución sin grabar son idénticas bit a bit.
  • --play FILE.mcap reproduce una grabación en Studio, con una línea de tiempo: reproducir, pausar, buscar, 0.25–10 veces la velocidad. No se simula nada mientras se reproduce.

Tiempo

La hora de registro de cada mensaje es el tiempo virtual del gemelo, en nanosegundos desde el encendido. La mayoría de los canales llevan además t, el mismo tiempo en segundos. Un canal muestreado escribe un mensaje solo cuando algo en él ha cambiado.

La cabecera

Un registro de metadatos llamado mc1sim dice en qué consistió la ejecución:

ClaveSignificado
machineEl nombre de la máquina
drive_modelEl modelo de accionamiento de la ejecución: L0, L1, L2, L2/3 (tres masas) o L3
f_cpuEl reloj del controlador, Hz
nvsUn hash de los ajustes guardados del controlador al comenzar la ejecución, 16 dígitos hexadecimales
sample_period_msEl periodo de muestreo
timevirtual, ns from power-on

Canales

CanalEscrituraCampoTipoUnidadSignificado
/machinemuestreadoposnúmero[3]mmDónde está cada eje: la mecánica, no la idea que tiene de ello el controlador
mposnúmero[3] o nullmmLa posición de máquina del controlador (MPos); null mientras el controlador está apagado
lostnúmero[3]Los pasos que ha perdido cada eje
feednúmeromm/minLa velocidad de avance del controlador ahora
tipnúmero[3]mmLa punta de la herramienta respecto a la pieza: con el modelo de errores del gemelo activado, desplazada por sus errores; desactivado, igual que pos
/drivesmuestreado, con un modelo de accionamiento desde L1ferr_umnúmero[3]µmEl error de seguimiento de cada accionamiento
statecadena[3]El estado de cada accionamiento
km1booleanoEl contactor KM1 cerrado
bus48booleanoLa alimentación de 48 V de los accionamientos activada
/spindlemuestreado, con un variador del husillof_outnúmeroHzLa frecuencia de salida del variador
rpmnúmerorpmLa velocidad del husillo
ampsnúmeroALa corriente de salida del variador
load_pctnúmero%La carga tal como la indica el variador
torque_nmnúmeroN·mEl par del motor
bus_vnúmeroVLa tensión del bus de CC del variador
cmd_rpmnúmerorpmLa velocidad que pide el controlador
run, pumpbooleanoEl variador en marcha; la bomba encendida
powercadenaLa alimentación propia del variador: ready, boot u off
faultcadenaEl fallo del variador, tal como lo muestra su pantalla
/controlleral cambiarstatecadenaEl estado del controlador (Off mientras está apagado)
alarmenteroLa alarma en la que está (0: ninguna)
homedenteroLos ejes con la referencia hecha, un bit cada uno: X 1, Y 2, Z 4
limitsenteroLas entradas de límite que están activas, un bit cada una
probe, estop, motor_fault, doorbooleanoLas entradas del palpador, de la parada de emergencia, del fallo de motor y de la puerta (el MC-1 no tiene puerta)
onbooleanoEl controlador encendido
/poweral cambiarmains, v24, mcu, km1, bus48booleanoLa red eléctrica; la alimentación de 24 V; el controlador en marcha; KM1; la alimentación de 48 V
vfd_mains, vfd, pumpbooleano, cadena, booleanoLa red del variador del husillo; su estado (none, ready, boot, off); la bomba
/serial/insegún llegatextcadenaLos bytes que recibió el controlador; los caracteres de control como secuencias de escape \u
/serial/outsegún llegalinecadenaCada línea que escribió el controlador
/eventssegún ocurrentextcadenaCada entrada del registro de eventos: marcas, la alimentación, los accionamientos, el variador del husillo, colisiones, cables rotos
/cutmuestreado, con un brutocuttingbooleanoSe arranca material; mientras no es así, las cifras siguientes valen 0, salvo rpm y removed_mm3
mrr_mm3_snúmeromm³/sLa tasa de arranque de material
ap_mm, ae_mmnúmerommLa profundidad axial y el ancho radial del corte
fz_mmnúmerommEl avance por diente
rpmnúmerorpmLa velocidad del husillo
fx_n, fy_n, fz_nnúmeroNLa fuerza de corte a lo largo de los ejes de la máquina
torque_nm, power_wnúmeroN·m, WEl par y la potencia de corte
kc_j_mm3númeroJ/mm³La energía de corte específica
removed_mm3númeromm³El material arrancado hasta ahora
/inputsegún llegalinecadenaLas entradas de la sesión, línea a línea tal como las escribe --record (consulte Registros de sesión)
/shadowsegún llega, en modo sombrahost_snúmerosLa hora del equipo
dircadenat hacia la máquina real, r desde ella
datacadenaLos bytes, cada uno como un carácter U+0000–U+00FF, hasta 1 KB por mensaje
/ui/state, /soundpara el reproductorLa trama de estado de las vistas (30 por segundo mientras cambia) y la trama del sonido (cada 10 ms de tiempo virtual cuando cambia). Son propias de Studio: sus campos pueden cambiar de una versión a otra.

Trazas de pines (VCD)

--vcd FILE escribe los pines del controlador como un archivo VCD (IEEE 1364), que leen GTKWave y PulseView: el ámbito mcu contiene los pines del controlador, cada cambio en el tic de reloj en que ocurre (los pines de paso como pulsos de $0 microsegundos); el ámbito machine contiene las líneas ajenas al controlador: las alimentaciones, KM1, el variador del husillo, la bomba, el botón de parada de emergencia, el sensor de longitud de herramienta, los cinco interruptores. La escala de tiempo es 1 ns.

Registros de sesión

--record FILE escribe las entradas de una sesión, cada una con su tiempo virtual: lo que enviaron los programas de envío, los comandos en tiempo real, los comandos de las vistas. --replay FILE ejecuta la sesión de nuevo, bit a bit, con la misma versión de Studio y los mismos archivos de máquina. --replay FILE --branch S la reproduce hasta S segundos y continúa en vivo desde ahí; con --record, la rama tiene un registro propio, que parte del registro de origen (# branch <parent> <ticks>). Un registro es texto; sus líneas son propias de Studio y pueden cambiar de una versión a otra.

El archivo del mundo

Lo que el gemelo conserva entre sesiones, como hace una máquina real cuando se apaga y se vuelve a encender: dónde están los ejes, el bruto con sus cortes, la herramienta del husillo, la memoria del controlador y el reloj de la placa, y el calor, que se enfría mientras la máquina está apagada. El controlador arranca en frío: se vuelve a hacer la referencia de la máquina.

La ventana guarda el mundo de cada máquina en la carpeta de estado (en Windows %LOCALAPPDATA%\Twinwright\Studio): el de la primera máquina en world, los de las demás en machines\<id>\world. --world DIR usa otra carpeta; --world-reset parte del estado de fábrica. Las ejecuciones por lotes, las pruebas, las reproducciones, las grabaciones reproducidas y las máquinas en segundo plano de la IA no guardan ningún mundo, salvo que se indique --world. Un solo programa a la vez abre un mundo; un segundo parte del estado de fábrica y no guarda nada.

ArchivoQué contiene
world.jsonEl final de la sesión (más abajo), escrito primero en world.json.tmp y luego renombrado
stock.snapLas celdas del bruto, cortadas o no (binario, TWSTOCK1)
eeprom.binLa memoria guardada del controlador: sus ajustes, decalajes y datos de herramienta, escrita de inmediato a medida que cambia

world.json:

ClaveSignificado
worldLa versión del formato: 1
saved_at, saved_epochCuándo se guardó: UTC, y segundos desde 1970
versionLa versión de Studio que lo guardó
posDónde estaban los ejes, mm (X, Y, Z)
toolLa herramienta del husillo, como especificación (flat 6 n3 L20)
tool_tableLa tabla de herramientas del trabajo: {"1": "flat 6 n3 L20", ...}
tool_autoEl gemelo hace de operador en un cambio de herramienta: pone la herramienta de la tabla y pulsa inicio de ciclo
setupLa sujeción y el bruto, tal como los escribe Guardar amarre en la ventana (null: ninguno)
cellsstock.snap contiene las celdas del bruto
thermalEl calor: screws (cada husillo de bolas por encima del bastidor), frame (por encima de 20 °C), ambient (la sala por encima de 20 °C), part_heat y part_offset (la pieza por encima del bastidor: lo que aportan los cortes y un decalaje indicado), todo en K; spindle_um, el crecimiento del husillo en µm
rtcLa lectura del reloj de la placa, s
probe_calEl palpador tal como se calibró por última vez: el diámetro de la bola, su radio efectivo, la lobulación y su fase, el diámetro del anillo patrón, la mayor desviación, cuándo y por quién (solo una vez calibrado)
odometertravel_mm y reversals de cada eje, spindle_h (las horas del husillo) y on_h (las horas del programa), acumulados a lo largo de las sesiones

En el siguiente arranque los ejes están donde estaban; vuelve el mismo bruto con sus celdas, y la herramienta y la tabla; el calor se ha enfriado durante el tiempo que la máquina estuvo apagada, cada parte hacia su estado de reposo con su propia constante de tiempo; el reloj de la placa ha seguido avanzando. --world-off S indica cuánto tiempo estuvo apagada la máquina (para pruebas; de lo contrario, el tiempo transcurrido desde que se guardó). --pos, --tool, --stock, --setup y --part indicados al arrancar prevalecen sobre el archivo.

Archivos de licencia

Un archivo de licencia (.twlic) es un objeto JSON en UTF-8, firmado con Ed25519. Studio lo comprueba en el equipo, sin red. Dónde están los archivos y cómo se usan: Licencias, puestos y activación.

Este ejemplo procede de los vectores de prueba compartidos. Está firmado con la clave de prueba (kid test), que las compilaciones publicadas no aceptan:

{"v": 1, "kid": "test", "id": "TWL-TEST000001", "edition": "pro", "kind": "subscription", "seats": 1,
 "holder": "Weber Lab, TU Example", "issued": "2026-11-02T10:00:00Z", "valid_until": "2027-11-02T10:00:00Z",
 "renew_after": "2027-10-28T10:00:00Z", "updates_until": null, "fp": ["0123456789abcdef0123456789abcdef"],
 "mc1_serial": null,
 "sig": "h3FTqZnDYtq8Q7_0ZuELLeDrTfyZnkTPgvDWSywTyl7BCJJxGIyhrBQUjYHJiE1_WOWaFarqbveFiMLrEfUyCA"}

Campos

CampoTipoSignificado
venteroLa versión del formato: 1. Studio trata un archivo de otra versión como no válido.
kidcadenaCuál de las claves de Twinwright firmó el archivo
idcadenaEl número de la licencia: TWL- y 10 letras y dígitos. La renovación lo envía.
editioncadenamaker o pro
kindcadenasubscription, perpetual (compra perpetua) o owner (propietario del MC-1)
seatsenteroEl número de puestos
holdercadenaA quién corresponde la licencia: una persona o una organización. Nunca una dirección de correo electrónico.
issuedfecha y horaCuándo se firmó el archivo, UTC, YYYY-MM-DDTHH:MM:SSZ
valid_untilfecha y hora, o nullUna suscripción: el final del periodo pagado. Compra perpetua: el final del periodo de reembolso en el primer archivo, null en el permanente.
renew_afterfecha y hora, o nullDesde cuándo intenta Studio renovar el archivo
updates_untilfecha, o nullCompra perpetua, propietario del MC-1: las versiones publicadas hasta este día tienen las funciones de pago
fplista de cadenasLos equipos a los que está vinculada la licencia: los hashes de sus huellas, hasta tres por puesto
mc1_serialcadena, o nullPropietario del MC-1: el número de serie de la máquina. Studio no comprueba la máquina cuando se ejecuta.
sigcadenaLa firma Ed25519 de los demás campos, en base64url sin relleno

Un campo que Studio no conoce forma parte de los bytes firmados, y Studio ignora lo que significa.

Los bytes firmados

La firma cubre el archivo sin sig, escrito en una forma canónica:

  • claves en el orden de los puntos de código Unicode;
  • sin espacios en blanco;
  • cadenas con las secuencias de escape más cortas de JSON;
  • enteros sin punto decimal; ningún otro número, y ninguna clave repetida.

Studio escribe el archivo en esta forma antes de comprobar la firma. Por tanto, los espacios, los saltos de línea y el orden de las claves del archivo no importan. Un valor cambiado hace fallar la comprobación.

El hash de la huella

El hash son los primeros 32 dígitos hexadecimales de SHA-256 sobre los bytes twinwright-fp-v1, un byte cero y el ID del equipo:

SistemaEl ID del equipo
WindowsEl valor MachineGuid en HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
Linux/etc/machine-id

Si no hay ninguno de los dos, Studio crea un ID aleatorio y lo guarda en la carpeta de licencias (machine.id); al borrarlo, el equipo pasa a ser otro distinto. El ID en sí nunca sale del equipo.

Por ejemplo, el ID 8b1c3a0e-5f2d-4c7a-9e61-2d0f4b7a1c55 da el hash 0a2d31bb82176516415efa7b3a340562.

El código de solicitud

El código de solicitud para la activación sin conexión es el JSON canónico en UTF-8 {"fp": <the hash>, "version": <Studio's version>}, en base64url sin relleno =. Por ejemplo, el hash 0123456789abcdef0123456789abcdef y la versión 1.0.0 dan:

eyJmcCI6IjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmIiwidmVyc2lvbiI6IjEuMC4wIn0

TwinwrightStudio.exe --licence-request imprime el código de solicitud de este equipo.

Archivos de prueba

Una prueba es un archivo de licencia como los demás, firmado por el servidor de licencias de Twinwright: "kind": "trial", el hash de este equipo en fp y valid_until 30 días después de empezar la prueba. Nunca se renueva. Un archivo de prueba modificado a mano deja de ser válido.

El archivo de la máquina

Todas las claves del archivo de una máquina, con los valores del MC-1: Esquema del perfil de máquina.