ドキュメント リファレンス

ファイル形式

_草稿(ラウンド 14):本文は執筆中で、節が増える可能性があります。_

プログラム

プログラムは、Twinwright 独自カーネルが扱う Grbl 1.1 方言の G コードテキストファイルです。Studio は、そのようなファイルであればどれでも読み込めます。Studio の CAM が書き出すプログラムは、次のような形をしています。

(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
要素内容
ヘッダーコメント:ジョブのタイトル、最初の工具・材質・主な切削条件、プログラムの原点の位置
モードG21 G90 G17 G94 G54:ミリメートル、絶対指令、XY 平面、毎分送り、ワーク座標オフセット G54
G53 G0 Z…機械座標での Z の上端への移動:開始時、工具交換のたび、終了時。その高さは、原点復帰を終えた時点での Z の位置です。
T… M6工具交換。コントローラが新しい工具をツールセッターで測定します。
M3 S…、G4 P…主軸をオンにし、そのあと回転数に達するまでドウェルします。水冷主軸のポンプ(M8)が先に入ります。
フィーチャのコメント各フィーチャは、何を削るかを書いたコメントで始まります
移動G0、G1、および I と J を使う円弧 G2/G3。穴あけには G81、またはペックを使う G83 を使い、その R 平面は上面より 1 mm 上にあります。
終了M5、M9、上端への移動、M30

コメントは括弧の中に書きます。行に番号は付きません。

Studio は、プログラムの各バージョンを、プログラムフォルダー(ドキュメント/Twinwright Studio/programs)の中の、プログラム名のフォルダーに保存します。

ファイル内容
v0001.nc保存されたときのままのプログラムのテキスト
v0001.jsonそのバージョン、時刻(UTC)、作成者、理由、元になったバージョン、ハッシュ、行数
v0001.ops.json各フィーチャが変換された結果(加工工程、加工方式、工具、行、回転数、送り):段取りシートがこれを読み込みます

ジョブと段取り

ジョブは、CAM がそこからプログラムを作る、部品の記述です。JSON オブジェクトです。

キー意味
nameプログラムの名前。たとえば bracket.nc
title、descriptionプログラムのヘッダーと段取りシートに入れる文言
material材質。たとえば 6061-T6。他の規格での名称も認識されます
tool主軸に付いている工具。仕様の書式で書きます(flat 6 n3 L20)
tools工具テーブル:{"1": "flat 6 n3 L20", "2": "drill 3.4 118 L20"}。省略すると、機械のものを使います。
cutting選ばれた値を上書きする値:rpm、feed、ap、ae、finish_ap、corner_steps(true または false:壁の入隅を先に段階的に削る)
safe_z部品の上を横切って移動するときの高さ。ワーク原点からの高さをミリメートルで表します
zeroワーク原点の位置:front-left-top(デフォルト)または center-top
featuresフィーチャ。削る順に並べます。プログラムの作成を参照してください。
setupsfeatures の代わりに使います:段取りごとに 1つのオブジェクト
nestfeatures の代わりに使います:板材にネスティングした部品

段取りには独自の features があり、前の段取りから部品がどのように渡されるかを指定します。

キー意味
turnu:X 軸まわりに裏返す(前と後ろが入れ替わる)。v:Y 軸まわり(左と右が入れ替わる)
fixtureこの段取り以降、部品を別の方法で保持します(vise、clamps、tape …)
zeroワーク原点を取り直します:front-left-top または center-top。省略した場合、裏返した後や治具を変えた後は front-left-top、それ以外は前の段取りの原点になります。
name、tool、tools、cutting、safe_z段取り固有のもの。ジョブのものより優先されます
{"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}]}

ジョブの各バージョンは、それが作ったプログラムの隣に job-v0001.json として保存されます。内容は、そのバージョン、時刻(UTC)、作成者(operator または ai:<client>)、メモ、それが作ったプログラムのバージョン、そしてジョブそのものです。setups を使ったジョブには、各段取りのプログラム、作られたバージョン、そのハッシュも記録されます。

記録(MCAP)

--mcap FILE は、実行を MCAP ファイル(mcap.dev、フォーマットのバージョン 0)に記録します。データの種類ごとにチャンネルがあり、メッセージは JSON で、各チャンネルに JSON スキーマが付きます。チャンク化も圧縮もされておらず、末尾に統計と CRC を含むサマリーが付きます。Studio のテストは、記録したファイルを MCAP 仕様と突き合わせて読み戻します。PlotJuggler や Foxglove のような MCAP を読み込むツールで開けることを想定していますが、まだ試していません。

  • --rec-period MS は、サンプリング対象のチャンネルを書き込む間隔を設定します(指定しなければ 1 ms)。
  • 記録は実行に何も影響しません。記録した実行と、記録しない同じ実行は、ビット単位で同一です。
  • --play FILE.mcap は、Studio で記録を再生します。タイムラインがあり、再生、一時停止、シーク、0.25–10倍の速度に対応します。再生中は何もシミュレートされません。

時刻

各メッセージのログ時刻は、ツインの仮想時間で、電源投入からのナノ秒です。ほとんどのチャンネルには、同じ時刻を秒で表した t も入っています。サンプリング対象のチャンネルは、その中の何かが変わったときだけメッセージを書き込みます。

ヘッダー

mc1sim という名前のメタデータレコードに、その実行が何であったかが書かれています。

キー意味
machine機械の名前
drive_model実行に使ったドライバモデル:L0、L1、L2、L2/3(3つの質量)、L3
f_cpuコントローラのクロック(Hz)
nvs実行開始時のコントローラの保存設定のハッシュ(16進数 16桁)
sample_period_msサンプリング周期
timevirtual, ns from power-on

チャンネル

チャンネル書き込みフィールド型単位意味
/machineサンプリングposnumber[3]mm各軸の実際の位置:機構そのものの位置で、コントローラが把握している位置ではありません
mposnumber[3] または nullmmコントローラの機械位置(MPos)。コントローラがオフの間は null
lostnumber[3]各軸が失ったステップ数
feednumbermm/minコントローラの現在の送り速度
tipnumber[3]mmワークに対する工具先端の位置:ツインの誤差モデルがオンの場合は、その誤差の分だけずれた位置。オフの場合は pos と同じ
/drivesサンプリング(L1 以上のドライバモデルがある場合)ferr_umnumber[3]µm各ドライバの追従誤差
statestring[3]各ドライバの状態
km1booleanコンタクタ KM1 が閉じている
bus48booleanドライバの 48 V 電源がオン
/spindleサンプリング(主軸インバータがある場合)f_outnumberHzドライバの出力周波数
rpmnumbermin⁻¹主軸の回転数
ampsnumberAドライバの出力電流
load_pctnumber%ドライバが報告する負荷
torque_nmnumberN·mモーターのトルク
bus_vnumberVドライバの DC バス電圧
cmd_rpmnumbermin⁻¹コントローラが指令する回転数
run、pumpbooleanドライバが運転中、ポンプがオン
powerstringドライバ自身の電源:ready、boot、off
faultstringドライバのフォルト。ドライバの表示どおり
/controller変化時statestringコントローラの状態(オフの間は Off)
alarminteger発生中のアラーム(0:なし)
homedinteger原点復帰済みの軸。1 ビットずつ:X が 1、Y が 2、Z が 4
limitsintegerアクティブなリミット入力。1 ビットずつ
probe、estop、motor_fault、doorbooleanプローブ、非常停止、モーター異常、安全扉の各入力(MC-1 に安全扉はありません)
onbooleanコントローラに電源が入っている
/power変化時mains、v24、mcu、km1、bus48boolean商用電源、24 V 電源、コントローラの動作、KM1、48 V 電源
vfd_mains、vfd、pumpboolean、string、boolean主軸インバータの商用電源、その状態(none、ready、boot、off)、ポンプ
/serial/in届いたときtextstringコントローラが受信したバイト。制御文字は \u エスケープで表します
/serial/out届いたときlinestringコントローラが書き出した各行
/events発生時textstringイベントログの各エントリ:マーク、電源、ドライバ、主軸インバータ、衝突、断線
/cutサンプリング(素材がある場合)cuttingboolean材料が除去されている。除去されていない間は、rpm と removed_mm3 以外の下の値は 0
mrr_mm3_snumbermm³/s材料除去率
ap_mm、ae_mmnumbermm軸方向の切込み深さと、半径方向の切込み幅
fz_mmnumbermm1刃あたりの送り
rpmnumbermin⁻¹主軸の回転数
fx_n、fy_n、fz_nnumberN機械の各軸方向の切削抵抗
torque_nm、power_wnumberN·m、W切削トルクと切削動力
kc_j_mm3numberJ/mm³比切削エネルギー
removed_mm3numbermm³ここまでに除去された材料の量
/input届いたときlinestringセッションの入力。--record が書き出すとおりに、1行ずつ(セッションログを参照)
/shadow届いたとき(シャドーモード)host_snumbersコンピューターの時刻
dirstringt は実機へ、r は実機から
datastringバイト列。各バイトを U+0000–U+00FF の 1文字で表します。1メッセージあたり最大 1 KB
/ui/state、/soundプレーヤー用ビューの状態フレーム(変化している間は毎秒 30回)と、サウンドのフレーム(変化したとき、仮想時間で 10 ms ごと)。Studio 独自のもので、フィールドはバージョンによって変わることがあります。

ピントレース(VCD)

--vcd FILE は、コントローラのピンを VCD ファイル(IEEE 1364)として書き出します。VCD は GTKWave や PulseView で読み込めます。スコープ mcu にはコントローラのピンが入り、各変化はそれが起きたクロックティックに記録されます(ステップピンは $0 マイクロ秒のパルスとして記録)。スコープ machine には、コントローラの外にある信号が入ります:電源、KM1、主軸インバータ、ポンプ、非常停止ボタン、ツールセッター、5つのスイッチ。タイムスケールは 1 ns です。

セッションログ

--record FILE は、セッションの入力を、それぞれの仮想時間とともに書き出します。送信ソフトが送ったもの、リアルタイムコマンド、ビューのコマンドが対象です。--replay FILE は、同じバージョンの Studio と同じ機械ファイルを使って、そのセッションをビット単位で同一に再実行します。--replay FILE --branch S は、S 秒まで再生し、そこから先はライブで続けます。--record と併用すると、分岐は独自のログを持ち、そのログは親のログから始まります(# branch <parent> <ticks>)。ログはテキストで、その行は Studio 独自のものであり、バージョンによって変わることがあります。

ワールドアーカイブ

ツインがセッションの間も保持するもの。実機の電源を切って入れ直したときと同じです:軸の位置、切削済みの部分を含む素材、主軸の工具、コントローラのメモリとボードの時計、そして熱(機械の電源が切れている間に冷めます)。コントローラは、コールドスタートで起動します。機械は、あらためて原点復帰します。

ウィンドウは、機械ごとのワールドを状態フォルダー(Windows では %LOCALAPPDATA%\Twinwright\Studio)に保存します。最初の機械のものは world、それ以外の機械のものは machines\<id>\world です。--world DIR は別のフォルダーを使います。--world-reset は工場出荷時の状態から始めます。バッチ実行、テスト、リプレイ、再生される記録、AI のバックグラウンドの機械は、--world を指定しない限り、ワールドを保持しません。ワールドを開けるのは、一度に 1つのプロセスだけです。2つ目のプロセスは工場出荷時の状態から始まり、何も保存しません。

ファイル内容
world.jsonセッション終了時の状態(下記)。まず world.json.tmp に書き込み、その後で名前を変更します
stock.snap素材のセル(削った部分も含む)(バイナリ、TWSTOCK1)
eeprom.binコントローラの保存メモリ:設定、オフセット、工具データ。変更のたびに即座に書き込まれます

world.json:

キー意味
worldフォーマットのバージョン:1
saved_at、saved_epoch保存された時刻:UTC、および 1970年からの秒数
version保存した Studio のバージョン
pos軸の位置、mm(X、Y、Z)
tool主軸にある工具(仕様の書式で。flat 6 n3 L20)
tool_tableジョブの工具テーブル:{"1": "flat 6 n3 L20", ...}
tool_autoツインが工具交換のときにオペレータの役を務めます:テーブルから工具を取り付け、サイクルスタートを押します
setupワークの保持方法と素材。ウィンドウの「段取りを保存」が書き出す形式(null:なし)
cellsstock.snap が素材のセルを保持している
thermal熱の状態:screws(各ねじのフレームを超える分)、frame(20 °C を超える分)、ambient(室温の 20 °C を超える分)、part_heat と part_offset(ワークのフレームを超える分:切削で加わった熱と、与えられたオフセット)はいずれも K、spindle_um は主軸の伸びで µm
rtcボードの時計の読み値(秒)
probe_cal最後に校正されたときのタッチプローブ:ボールの直径、有効半径、ロビングとその位相、リングゲージの直径、最大偏差、校正の日時と実施者(校正済みの場合のみ)
odometer各軸の travel_mm と reversals、spindle_h(主軸の運転時間)と on_h(プログラムの稼働時間)を、セッションをまたいで累計した値

次の起動時には、軸は前回の位置にあります。同じ素材がセルごと戻り、工具と工具テーブルも戻ります。熱は、機械の電源が切れていた時間の分だけ冷め、各部分はそれぞれの時定数で平衡状態に向かいます。ボードの時計は進み続けています。--world-off S は、機械が電源オフだった時間を指定します(テスト用。指定しない場合は、保存からの経過時間)。起動時に指定した --pos、--tool、--stock、--setup、--part は、アーカイブより優先されます。

ライセンスファイル

ライセンスファイル(.twlic)は、UTF-8 の JSON オブジェクトで、Ed25519 で署名されています。Studio は、ネットワークを使わずに、コンピューター上でこれを検証します。ファイルの置き場所と使い方:ライセンス、シート、アクティベーション。

この例は、共有のテストベクターからのものです。テスト用の鍵(kid が test)で署名されており、リリースビルドはこれを受け付けません。

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

フィールド

フィールド型意味
v整数フォーマットのバージョン:1。Studio は、ほかのバージョンのファイルを無効として扱います。
kid文字列ファイルに署名した Twinwright の鍵のうちどれか
id文字列ライセンスの番号:TWL- に英数字 10文字が続きます。更新のときに送信されます。
edition文字列maker または pro
kind文字列subscription、perpetual(買い切り)、owner(MC-1 オーナー)
seats整数シート数
holder文字列ライセンスの名義人:個人または組織。メールアドレスは決して入りません。
issued日時ファイルが署名された時刻。UTC、YYYY-MM-DDTHH:MM:SSZ
valid_until日時、または nullサブスクリプション:支払い済み期間の終わり。買い切り:最初のファイルでは返金期間の終わり、恒久的なファイルでは null。
renew_after日時、または nullStudio がファイルの更新を試み始める時刻
updates_until日付、または null買い切り、MC-1 オーナー:この日までにリリースされたバージョンで、有料機能が使えます
fp文字列の配列ライセンスが紐づけられているコンピューター:そのフィンガープリントのハッシュ。1シートにつき最大 3台
mc1_serial文字列、または nullMC-1 オーナー:機械のシリアル番号。Studio は、実行時に機械を確認しません。
sig文字列ほかのフィールドの Ed25519 署名。パディングなしの base64url

Studio が知らないフィールドも署名対象のバイト列に含まれます。Studio は、その意味を無視します。

署名されるバイト列

署名の対象は、sig を除いたファイルを、次の正規形で書き出したものです。

  • キーは Unicode コードポイント順。
  • 空白なし。
  • 文字列は JSON の最短のエスケープ。
  • 整数は小数点なし。それ以外の数値は使わず、同じキーを 2回使わない。

Studio は、署名を検証する前に、ファイルをこの形式で書き出します。そのため、ファイル内のスペース、改行、キーの順序は関係ありません。値が変更されると、検証は失敗します。

フィンガープリントのハッシュ

ハッシュは、twinwright-fp-v1 というバイト列、ゼロバイト、コンピューターの ID をこの順に並べたものの SHA-256 の、先頭の 16進数 32桁です。

システムコンピューターの ID
WindowsHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography の下の値 MachineGuid
Linux/etc/machine-id

どちらもない場合、Studio はランダムな ID を作り、ライセンスフォルダーに保存します(machine.id)。これを削除すると、そのコンピューターは別のコンピューターになります。ID 自体がコンピューターの外に出ることはありません。

たとえば、ID 8b1c3a0e-5f2d-4c7a-9e61-2d0f4b7a1c55 からは、ハッシュ 0a2d31bb82176516415efa7b3a340562 が得られます。

要求コード

オフラインアクティベーション用の要求コードは、正規形の UTF-8 JSON {"fp": <the hash>, "version": <Studio's version>} を、= パディングなしの base64url にしたものです。たとえば、ハッシュ 0123456789abcdef0123456789abcdef とバージョン 1.0.0 からは、次のコードが得られます。

eyJmcCI6IjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmIiwidmVyc2lvbiI6IjEuMC4wIn0

TwinwrightStudio.exe --licence-request は、このコンピューターの要求コードを出力します。

試用ファイル

試用はライセンスファイルの一種で、ほかのものと同じく Twinwright のライセンスサーバーが署名します:"kind": "trial"、fp にこのコンピューターのハッシュ、valid_until は試用の開始から 30 日後です。更新されることはありません。手で書き換えられた試用ファイルは、有効ではなくなります。

機械アーカイブ

機械のアーカイブのすべてのキーと、MC-1 の値:機械プロファイルのスキーマ。