これは以前のバージョン、Studio 1.0.2 のマニュアルです。 最新バージョンのマニュアル
ドキュメント 1.0.2 リファレンス
ファイル形式
_草稿(ラウンド 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 |
safe_z | 部品の上を横切って移動するときの高さ。ワーク原点からの高さをミリメートルで表します |
zero | ワーク原点の位置:front-left-top(デフォルト)または center-top |
features | フィーチャ。削る順に並べます。プログラムの作成を参照してください。 |
setups | features の代わりに使います:段取りごとに 1つのオブジェクト |
nest | features の代わりに使います:板材にネスティングした部品 |
段取りには独自の features があり、前の段取りから部品がどのように渡されるかを指定します。
| キー | 意味 |
|---|---|
turn | u: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 | サンプリング周期 |
time | virtual, ns from power-on |
チャンネル
| チャンネル | 書き込み | フィールド | 型 | 単位 | 意味 |
|---|---|---|---|---|---|
/machine | サンプリング | pos | number[3] | mm | 各軸の実際の位置:機構そのものの位置で、コントローラが把握している位置ではありません |
mpos | number[3] または null | mm | コントローラの機械位置(MPos)。コントローラがオフの間は null | ||
lost | number[3] | 各軸が失ったステップ数 | |||
feed | number | mm/min | コントローラの現在の送り速度 | ||
tip | number[3] | mm | ワークに対する工具先端の位置:ツインの誤差モデルがオンの場合は、その誤差の分だけずれた位置。オフの場合は pos と同じ | ||
/drives | サンプリング(L1 以上のドライバモデルがある場合) | ferr_um | number[3] | µm | 各ドライバの追従誤差 |
state | string[3] | 各ドライバの状態 | |||
km1 | boolean | コンタクタ KM1 が閉じている | |||
bus48 | boolean | ドライバの 48 V 電源がオン | |||
/spindle | サンプリング(主軸インバータがある場合) | f_out | number | Hz | ドライバの出力周波数 |
rpm | number | min⁻¹ | 主軸の回転数 | ||
amps | number | A | ドライバの出力電流 | ||
load_pct | number | % | ドライバが報告する負荷 | ||
torque_nm | number | N·m | モーターのトルク | ||
bus_v | number | V | ドライバの DC バス電圧 | ||
cmd_rpm | number | min⁻¹ | コントローラが指令する回転数 | ||
run、pump | boolean | ドライバが運転中、ポンプがオン | |||
power | string | ドライバ自身の電源:ready、boot、off | |||
fault | string | ドライバのフォルト。ドライバの表示どおり | |||
/controller | 変化時 | state | string | コントローラの状態(オフの間は Off) | |
alarm | integer | 発生中のアラーム(0:なし) | |||
homed | integer | 原点復帰済みの軸。1 ビットずつ:X が 1、Y が 2、Z が 4 | |||
limits | integer | アクティブなリミット入力。1 ビットずつ | |||
probe、estop、motor_fault、door | boolean | プローブ、非常停止、モーター異常、安全扉の各入力(MC-1 に安全扉はありません) | |||
on | boolean | コントローラに電源が入っている | |||
/power | 変化時 | mains、v24、mcu、km1、bus48 | boolean | 商用電源、24 V 電源、コントローラの動作、KM1、48 V 電源 | |
vfd_mains、vfd、pump | boolean、string、boolean | 主軸インバータの商用電源、その状態(none、ready、boot、off)、ポンプ | |||
/serial/in | 届いたとき | text | string | コントローラが受信したバイト。制御文字は \u エスケープで表します | |
/serial/out | 届いたとき | line | string | コントローラが書き出した各行 | |
/events | 発生時 | text | string | イベントログの各エントリ:マーク、電源、ドライバ、主軸インバータ、衝突、断線 | |
/cut | サンプリング(素材がある場合) | cutting | boolean | 材料が除去されている。除去されていない間は、rpm と removed_mm3 以外の下の値は 0 | |
mrr_mm3_s | number | mm³/s | 材料除去率 | ||
ap_mm、ae_mm | number | mm | 軸方向の切込み深さと、半径方向の切込み幅 | ||
fz_mm | number | mm | 1刃あたりの送り | ||
rpm | number | min⁻¹ | 主軸の回転数 | ||
fx_n、fy_n、fz_n | number | N | 機械の各軸方向の切削抵抗 | ||
torque_nm、power_w | number | N·m、W | 切削トルクと切削動力 | ||
kc_j_mm3 | number | J/mm³ | 比切削エネルギー | ||
removed_mm3 | number | mm³ | ここまでに除去された材料の量 | ||
/input | 届いたとき | line | string | セッションの入力。--record が書き出すとおりに、1行ずつ(セッションログを参照) | |
/shadow | 届いたとき(シャドーモード) | host_s | number | s | コンピューターの時刻 |
dir | string | t は実機へ、r は実機から | |||
data | string | バイト列。各バイトを 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:なし) |
cells | stock.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 | 日時、または null | Studio がファイルの更新を試み始める時刻 |
updates_until | 日付、または null | 買い切り、MC-1 オーナー:この日までにリリースされたバージョンで、有料機能が使えます |
fp | 文字列の配列 | ライセンスが紐づけられているコンピューター:そのフィンガープリントのハッシュ。1シートにつき最大 3台 |
mc1_serial | 文字列、または null | MC-1 オーナー:機械のシリアル番号。Studio は、実行時に機械を確認しません。 |
sig | 文字列 | ほかのフィールドの Ed25519 署名。パディングなしの base64url |
Studio が知らないフィールドも署名対象のバイト列に含まれます。Studio は、その意味を無視します。
署名されるバイト列
署名の対象は、sig を除いたファイルを、次の正規形で書き出したものです。
- キーは Unicode コードポイント順。
- 空白なし。
- 文字列は JSON の最短のエスケープ。
- 整数は小数点なし。それ以外の数値は使わず、同じキーを 2回使わない。
Studio は、署名を検証する前に、ファイルをこの形式で書き出します。そのため、ファイル内のスペース、改行、キーの順序は関係ありません。値が変更されると、検証は失敗します。
フィンガープリントのハッシュ
ハッシュは、twinwright-fp-v1 というバイト列、ゼロバイト、コンピューターの ID をこの順に並べたものの SHA-256 の、先頭の 16進数 32桁です。
| システム | コンピューターの ID |
|---|---|
| Windows | HKEY_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 の値:機械プロファイルのスキーマ。