Ceci est le manuel de Studio 1.0.2, une version antérieure. Le manuel de la dernière version

Documentation 1.0.2 Référence

Formats de fichiers

_Brouillon (itération 14) : le texte est en cours de rédaction ; les sections peuvent encore s’allonger._

Programmes

Un programme est un fichier texte G-code dans le dialecte de Grbl 1.1, que parle le noyau propre à Twinwright. Studio lit n’importe quel fichier de ce genre. Les programmes que sa FAO écrit ressemblent à ceci :

(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
ÉlémentCe que c’est
En-têteDes commentaires : le titre du travail ; le premier outil, la matière et les principales données de coupe ; l’emplacement du zéro du programme
ModesG21 G90 G17 G94 G54 : millimètres, absolu, plan XY, avance par minute, décalage d’origine G54
G53 G0 Z…Un déplacement vers le haut de Z, en coordonnées machine : au début, à chaque changement d’outil et à la fin. Cette hauteur est celle où la prise d’origine laisse Z.
T… M6Un changement d’outil. Le contrôleur mesure le nouvel outil sur le capteur de longueur d’outil.
M3 S…, G4 P…La broche en marche, puis une temporisation pendant qu’elle monte en vitesse. La pompe d’une broche refroidie par eau (M8) passe en premier.
Commentaires d’entitéChaque entité commence par un commentaire qui dit ce qu’elle usine
DéplacementsG0, G1, et les arcs G2/G3 avec I et J. Le perçage utilise G81, ou G83 avec débourrage, son plan R à 1 mm au-dessus de la face supérieure.
FinM5, M9, le déplacement vers le haut, M30

Les commentaires sont entre parenthèses. Les lignes ne sont pas numérotées.

Studio conserve chaque version d’un programme dans le dossier des programmes (Documents/Twinwright Studio/programs), dans un dossier portant le nom du programme :

FichierCe qu’il contient
v0001.ncLe texte du programme, tel qu’il a été enregistré
v0001.jsonSa version, l’heure (UTC), qui l’a créé, pourquoi, la version dont il provient, son hachage et ses lignes
v0001.ops.jsonCe que chaque entité est devenue (opération, stratégie, outil, lignes, vitesse, avance) : une fiche de bridage le lit

Travaux et phases

Un travail est la description d’une pièce à partir de laquelle la FAO produit des programmes. C’est un objet JSON :

CléSignification
nameLe nom du programme, par exemple bracket.nc
title, descriptionLes textes de l’en-tête du programme et de la fiche de bridage
materialLa matière, par exemple 6061-T6 ; les désignations d’autres normes sont comprises
toolL’outil dans la broche, sous forme de spécification (flat 6 n3 L20)
toolsLa table d’outils : {"1": "flat 6 n3 L20", "2": "drill 3.4 118 L20"}. Si elle est omise : celle de la machine.
cuttingDes valeurs qui remplacent les valeurs choisies : rpm, feed, ap, ae, finish_ap
safe_zLa hauteur à laquelle se font les déplacements de transit, en millimètres au-dessus de l’origine pièce
zeroL’emplacement de l’origine pièce : front-left-top (par défaut) ou center-top
featuresLes entités, dans l’ordre où elles sont usinées. Voir Créer des programmes.
setupsÀ la place de features : un objet par phase
nestÀ la place de features : des pièces imbriquées sur une plaque

Une phase a ses propres features et indique comment la pièce y arrive depuis la phase précédente :

CléSignification
turnu : retournée autour de X (l’avant et l’arrière changent de place) ; v : autour de Y (la gauche et la droite)
fixtureMaintenue autrement à partir de cette phase (vise, clamps, tape …)
zeroL’origine pièce retrouvée : front-left-top ou center-top. Si elle est omise après un retournement ou un nouveau montage : front-left-top ; sinon, l’origine de la phase précédente.
name, tool, tools, cutting, safe_zCeux propres à la phase, prioritaires sur ceux du travail
{"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}]}

Chaque version d’un travail est conservée à côté du programme qu’elle a produit, sous le nom job-v0001.json : sa version, l’heure (UTC), qui l’a créée (operator ou ai:<client>), une note, la version du programme qu’elle a produit et le travail lui-même. Un travail décrit en phases liste aussi, pour chaque phase, son programme, la version produite et son hachage.

Enregistrements (MCAP)

--mcap FILE enregistre une exécution dans un fichier MCAP (mcap.dev, format version 0) : un canal pour chaque type de données, des messages JSON, chaque canal avec son schéma JSON, sans découpage en blocs et sans compression, et un résumé à la fin avec les statistiques et un CRC. Les tests de Studio relisent les fichiers selon la spécification MCAP ; les outils qui lisent MCAP, comme PlotJuggler et Foxglove, sont censés les ouvrir, mais cela n’a pas encore été essayé.

  • --rec-period MS règle la fréquence d’écriture des canaux échantillonnés (1 ms si l’option n’est pas donnée).
  • Un enregistrement ne change rien à l’exécution : une exécution enregistrée et la même exécution non enregistrée sont identiques bit à bit.
  • --play FILE.mcap relit un enregistrement dans Studio, avec une ligne de temps : lecture, pause, positionnement, de 0,25 à 10 fois la vitesse. Rien n’est simulé pendant la relecture.

Temps

L’horodatage d’enregistrement de chaque message est le temps virtuel du jumeau, en nanosecondes depuis la mise sous tension. La plupart des canaux portent aussi t, le même temps en secondes. Un canal échantillonné n’écrit un message que lorsque quelque chose y a changé.

L’en-tête

Un enregistrement de métadonnées nommé mc1sim décrit l’exécution :

CléSignification
machineLe nom de la machine
drive_modelLe modèle de variateur de l’exécution : L0, L1, L2, L2/3 (trois masses) ou L3
f_cpuL’horloge du contrôleur, en Hz
nvsUn hachage des réglages mémorisés du contrôleur au début de l’exécution, 16 chiffres hexadécimaux
sample_period_msLa période d’échantillonnage
timevirtual, ns from power-on

Canaux

CanalÉcritureChampTypeUnitéSignification
/machineéchantillonnéposnombre[3]mmOù se trouve chaque axe : la mécanique, non la position que le contrôleur s’en fait
mposnombre[3] ou nullmmLa position machine du contrôleur (MPos) ; null tant que le contrôleur est éteint
lostnombre[3]Les pas perdus par chaque axe
feednombremm/minLa vitesse d’avance du contrôleur à l’instant présent
tipnombre[3]mmLa pointe de l’outil par rapport à la pièce : avec le modèle d’erreurs du jumeau activé, déplacée par ses erreurs ; désactivé, identique à pos
/driveséchantillonné, avec un modèle de variateur à partir de L1ferr_umnombre[3]µmL’erreur de poursuite de chaque variateur
statechaîne[3]L’état de chaque variateur
km1booléenLe contacteur KM1 est fermé
bus48booléenL’alimentation 48 V des variateurs est active
/spindleéchantillonné, avec un variateur de brochef_outnombreHzLa fréquence de sortie du variateur
rpmnombretr/minLa vitesse de la broche
ampsnombreALe courant de sortie du variateur
load_pctnombre%La charge telle que le variateur la rapporte
torque_nmnombreN·mLe couple du moteur
bus_vnombreVLa tension du bus continu du variateur
cmd_rpmnombretr/minLa vitesse que demande le contrôleur
run, pumpbooléenLe variateur en marche ; la pompe en marche
powerchaîneL’alimentation propre du variateur : ready, boot ou off
faultchaîneLe défaut du variateur, tel que son afficheur l’indique
/controllerà chaque changementstatechaîneL’état du contrôleur (Off tant qu’il est éteint)
alarmentierL’alarme dans laquelle il se trouve (0 : aucune)
homedentierLes axes dont la prise d’origine est faite, un bit chacun : X 1, Y 2, Z 4
limitsentierLes entrées de fin de course qui sont actives, un bit chacune
probe, estop, motor_fault, doorbooléenLes entrées du palpeur, de l’arrêt d’urgence, du défaut moteur et de la porte (la MC-1 n’a pas de porte)
onbooléenLe contrôleur est sous tension
/powerà chaque changementmains, v24, mcu, km1, bus48booléenLe secteur ; l’alimentation 24 V ; le contrôleur en marche ; KM1 ; l’alimentation 48 V
vfd_mains, vfd, pumpbooléen, chaîne, booléenLe secteur du variateur de broche ; son état (none, ready, boot, off) ; la pompe
/serial/inà l’arrivéetextchaîneLes octets que le contrôleur a reçus ; les caractères de contrôle sous forme d’échappements \u
/serial/outà l’arrivéelinechaîneChaque ligne que le contrôleur a écrite
/eventsau fil des événementstextchaîneChaque entrée du journal d’événements : repères, alimentation, variateurs, variateur de broche, collisions, fils rompus
/cutéchantillonné, avec un brutcuttingbooléenDe la matière est enlevée ; sinon, les valeurs ci-dessous valent 0, sauf rpm et removed_mm3
mrr_mm3_snombremm³/sLe débit d’enlèvement de matière
ap_mm, ae_mmnombremmLa profondeur axiale et la largeur radiale de la coupe
fz_mmnombremmL’avance par dent
rpmnombretr/minLa vitesse de la broche
fx_n, fy_n, fz_nnombreNL’effort de coupe selon les axes de la machine
torque_nm, power_wnombreN·m, WLe couple et la puissance de coupe
kc_j_mm3nombreJ/mm³L’énergie spécifique de coupe
removed_mm3nombremm³La matière enlevée jusqu’ici
/inputà l’arrivéelinechaîneLes entrées de la session, ligne par ligne telles que --record les écrit (voir Journaux de session)
/shadowà l’arrivée, en mode ombrehost_snombresLe temps de l’ordinateur
dirchaînet vers la machine réelle, r depuis elle
datachaîneLes octets, chacun sous forme d’un caractère U+0000–U+00FF, jusqu’à 1 Ko par message
/ui/state, /soundpour le lecteurLa trame d’état des vues (30 par seconde tant qu’elle change) et la trame du son (toutes les 10 ms de temps virtuel quand elle change). Propres à Studio : leurs champs peuvent changer d’une version à l’autre.

Traces de pins (VCD)

--vcd FILE écrit les pins du contrôleur dans un fichier VCD (IEEE 1364), que lisent GTKWave et PulseView : le scope mcu contient les pins du contrôleur, chaque changement au tick d’horloge où il se produit (les pins de pas sous forme d’impulsions de $0 microsecondes) ; le scope machine contient les lignes extérieures au contrôleur : les alimentations, KM1, le variateur de broche, la pompe, le bouton d’arrêt d’urgence, le capteur de longueur d’outil, les cinq capteurs. L’échelle de temps est de 1 ns.

Journaux de session

--record FILE écrit les entrées d’une session, chacune avec son temps virtuel : ce qu’ont envoyé les logiciels d’envoi, les commandes temps réel, les commandes des vues. --replay FILE rejoue la session, bit à bit, avec la même version de Studio et les mêmes fichiers machine. --replay FILE --branch S la rejoue jusqu’à S secondes, puis continue en direct à partir de là ; avec --record, la branche a un journal à elle, qui part de celui de son parent (# branch <parent> <ticks>). Un journal est un texte ; ses lignes sont propres à Studio et peuvent changer d’une version à l’autre.

L’archive du monde

Ce que le jumeau conserve entre deux sessions, comme le fait une machine réelle quand on l’éteint puis la rallume : la position des axes, le brut avec ses usinages, l’outil dans la broche, la mémoire du contrôleur et l’horloge de la carte, et la chaleur, qui retombe pendant que la machine est éteinte. Le contrôleur démarre à froid : la prise d’origine de la machine est à refaire.

La fenêtre conserve le monde de chaque machine dans le dossier d’état (sous Windows %LOCALAPPDATA%\Twinwright\Studio) : celui de la première machine dans world, celui des autres dans machines\<id>\world. --world DIR utilise un autre dossier ; --world-reset repart de l’état d’usine. Les exécutions par lots, les tests, les rejeux, les enregistrements relus et les machines d’arrière-plan de l’IA ne conservent aucun monde si --world n’est pas donné. Un seul processus à la fois ouvre un monde ; un deuxième repart de l’état d’usine et n’enregistre rien.

FichierCe qu’il contient
world.jsonLa fin de la session (ci-dessous), écrite d’abord dans world.json.tmp, puis renommée
stock.snapLes cellules du brut, usinées ou non (binaire, TWSTOCK1)
eeprom.binLa mémoire conservée du contrôleur : ses réglages, ses décalages et ses données d’outils, écrits au fil de leurs changements

world.json :

CléSignification
worldLa version du format : 1
saved_at, saved_epochQuand il a été enregistré : en UTC, et en secondes depuis 1970
versionLa version de Studio qui l’a enregistré
posOù se trouvaient les axes, en mm (X, Y, Z)
toolL’outil dans la broche, sous forme de spécification (flat 6 n3 L20)
tool_tableLa table d’outils du travail : {"1": "flat 6 n3 L20", ...}
tool_autoLe jumeau joue l’opérateur lors d’un changement d’outil : il met en place l’outil de la table et appuie sur départ cycle
setupLe bridage et le brut, tels que les écrit le bouton Enregistrer le bridage de la fenêtre (null : aucun)
cellsstock.snap contient les cellules du brut
thermalLa chaleur : screws (chaque vis au-dessus du bâti), frame (le bâti au-dessus de 20 °C), ambient (la salle au-dessus de 20 °C), part_heat et part_offset (la pièce au-dessus du bâti : ce que les coupes y apportent, et un décalage donné), tous en K ; spindle_um, la croissance de la broche en µm
rtcLa lecture de l’horloge de la carte, en s
probe_calLe palpeur tel qu’il a été étalonné en dernier : le diamètre de la bille, son rayon effectif, les lobes triples et leur phase, le diamètre de la bague étalon, l’écart maximal, quand et par qui (seulement une fois qu’il a été étalonné)
odometertravel_mm et reversals de chaque axe, spindle_h (les heures de la broche) et on_h (les heures du logiciel), cumulés sur les sessions

Au démarrage suivant, les axes sont là où ils se trouvaient ; le même brut revient avec ses cellules, ainsi que l’outil et la table ; la chaleur a diminué pendant le temps où la machine était éteinte, chaque élément vers son repos selon sa propre constante de temps ; l’horloge de la carte a continué de tourner. --world-off S indique combien de temps la machine est restée éteinte (pour les tests ; sinon, le temps écoulé depuis l’enregistrement). --pos, --tool, --stock, --setup et --part donnés au démarrage l’emportent sur l’archive.

Fichiers de licence

Un fichier de licence (.twlic) est un objet JSON en UTF-8, signé avec Ed25519. Studio le vérifie sur l’ordinateur, sans le réseau. Où se trouvent les fichiers et comment ils sont utilisés : Licences, postes et activation.

Cet exemple provient des vecteurs de test partagés. Il est signé avec la clé de test (kid test), que les versions publiées n’acceptent pas :

{"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"}

Champs

ChampTypeSignification
ventierLa version du format : 1. Studio considère comme non valide un fichier d’une autre version.
kidchaîneLaquelle des clés de Twinwright a signé le fichier
idchaîneLe numéro de la licence : TWL- suivi de 10 lettres et chiffres. Le renouvellement l’envoie.
editionchaînemaker ou pro
kindchaînesubscription, perpetual (achat définitif) ou owner (propriétaire d’une MC-1)
seatsentierLe nombre de postes
holderchaîneLe titulaire de la licence : une personne ou une organisation. Jamais une adresse e-mail.
issueddate et heureQuand le fichier a été signé, en UTC, YYYY-MM-DDTHH:MM:SSZ
valid_untildate et heure, ou nullAbonnement : la fin de la période payée. Achat définitif : la fin de la période de remboursement dans le premier fichier, null dans le fichier permanent.
renew_afterdate et heure, ou nullÀ partir de quand Studio essaie de renouveler le fichier
updates_untildate, ou nullAchat définitif, propriétaire d’une MC-1 : les versions publiées jusqu’à ce jour ont les fonctions payantes
fptableau de chaînesLes ordinateurs auxquels la licence est liée : les hachages de leurs empreintes, jusqu’à trois par poste
mc1_serialchaîne, ou nullPropriétaire d’une MC-1 : le numéro de série de la machine. Studio ne vérifie pas la machine lorsqu’il s’exécute.
sigchaîneLa signature Ed25519 des autres champs, en base64url sans remplissage

Un champ que Studio ne connaît pas fait partie des octets signés, et Studio ignore ce qu’il signifie.

Les octets signés

La signature couvre le fichier sans sig, écrit sous une forme canonique :

  • les clés dans l’ordre des points de code Unicode ;
  • aucun espace blanc ;
  • des chaînes avec les échappements les plus courts de JSON ;
  • des entiers sans point décimal ; aucun autre nombre, et aucune clé en double.

Studio écrit le fichier sous cette forme avant de vérifier la signature. Les espaces, les sauts de ligne et l’ordre des clés dans le fichier n’ont donc pas d’importance. Une valeur modifiée fait échouer la vérification.

Le hachage de l’empreinte

Le hachage est formé des 32 premiers chiffres hexadécimaux du SHA-256 calculé sur les octets twinwright-fp-v1, un octet nul, et l’identifiant de l’ordinateur :

SystèmeIdentifiant de l’ordinateur
WindowsLa valeur MachineGuid sous HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
Linux/etc/machine-id

À défaut de l’un comme de l’autre, Studio crée un identifiant aléatoire et le conserve dans le dossier des licences (machine.id) ; le supprimer fait de l’ordinateur un autre ordinateur. L’identifiant lui-même ne quitte jamais l’ordinateur.

Par exemple, l’identifiant 8b1c3a0e-5f2d-4c7a-9e61-2d0f4b7a1c55 donne le hachage 0a2d31bb82176516415efa7b3a340562.

Le code de demande

Le code de demande pour l’activation hors ligne est le JSON canonique en UTF-8 {"fp": <the hash>, "version": <Studio's version>}, en base64url sans remplissage =. Par exemple, le hachage 0123456789abcdef0123456789abcdef et la version 1.0.0 donnent :

eyJmcCI6IjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmIiwidmVyc2lvbiI6IjEuMC4wIn0

TwinwrightStudio.exe --licence-request affiche le code de demande de cet ordinateur.

Fichiers d’essai

Un essai est un fichier de licence comme les autres, signé par le serveur de licences de Twinwright : "kind": "trial", le hachage de cet ordinateur dans fp, et valid_until 30 jours après le début de l’essai. Il n’est jamais renouvelé. Un fichier d’essai modifié à la main n’est plus valable.

L’archive de la machine

Chaque clé de l’archive d’une machine, avec les valeurs de la MC-1 : Schéma du profil de machine.