09. WebSocket ワークスペースナビゲーター
ナビゲート デバイスの作業領域の位置(リアルタイム) コマンドを継続的に送信することで set_transform WebSocketチャネル上で。このチュートリアルでは、セッションとデバイスを検出するためにHTTPを使用しています(まさに チュートリアル 08)、その後、WebSocket接続を開き、各サイクルごとに位置情報の更新を送信します。
これは、2つの変換操作の違いを例示しています:
| オペレーション | チュートリアル | 代表的な用途 |
|---|---|---|
configure.mount — 永続的なマウント変換 | 08 | 装置の物理的な構成を説明するために、一度だけ(あるいはごくまれに)定義される |
set_transform — ワークスペースの永続的な変換 | 09(このチュートリアル) | これも永続的ですが、ワークスペース内をリアルタイムでナビゲートできるよう、各サイクルごとに継続的に送信される可能性があります。 |
これら2つのコマンドは、以下の方法で利用できます。 HTTP と WebSocket、そしてその2つはいずれも 常緑 : このサービスは、ユーザーが最後に送信した値を記憶します。違いは、更新の目的と頻度にあります: configure.mount 更新頻度が低い場合(物理的なインストール)に最適化されていますが、一方で set_transform 高頻度でのストリーミング(シーン内ナビゲーション)に最適化されています。
「Utilisez」を使用してください set_transform ワークスペースの原点が、実行時に変化する何かに追従する必要がある場合:手の動きを追跡したり、手続き型オフセットをアニメーション化したり、オペレーターが仮想ワークスペースをリアルタイムで移動できるようにしたりする場合などです。
個別に購入する場合は、 configure.mount et set_transform 一見同じ効果をもたらしているように見えるが、実際には 互いに重なり合った : 座標パイプラインにおいて、作業空間の変換が適用されます par-dessus 編集(device → basis → mount → workspace → application). 参照 組立と作業スペース パイプライン全体について。
ユースケース
- ワークスペース内でのリアルタイムナビゲーション。ハプティックシーンを中断することなく、デバイスのカーソル(エフェクターが到達する範囲)のワークスペースを移動できます。
- オペレーターによる位置合わせ。メインのハプティックアプリケーションが動作している間、別の端末で誰かに矢印キーを押し続けさせ、ワークスペースを移動させます。これは、ライブセッション中のワークステーションでのキャリブレーションに役立ちます。
- ワークスペースの手続き型移動。スクリプト(オーディオに反応する、物理演算による制御など)からワークスペースの位置を制御し、各サイクルごとに位置のみに影響する変換補正値を送信します。
前提条件
チュートリアル09では、アクティブなWebSocketセッションが必要です。つまり、実行中のハプティックループ内でInverse3 がすでに設定されているクライアントが必要です。チュートリアル09は、このセッションに接続し、そのワークスペースをリアルタイムでシフトさせます。
Haply Hubを開き、Orbのデモを起動してください。これにより、即座にターゲット設定が可能な持続的なハプティックセッションが開始されます:
./09-haply-inverse-ws-remote-control --session co.haply.hub::demo-orb
python 09-haply-inverse-ws-remote-control.py --session "co.haply.hub::demo-orb"
「Orb」シーンでは、ワークスペースの原点に球体が表示されます。チュートリアル09の手順に従ってワークスペースを移動させると、シーン全体がリアルタイムで移動するため、即座に視覚的なフィードバックを得ることができます。
ハプティックループを実行するその他のチュートリアル(01~07)も同様に動作します。まず1つ目のターミナルでそれを実行し、次に2つ目のターミナルでチュートリアル09を起動して、インタラクティブにセッションを探索させてください。
利用状況
# Discover session interactively, use first detected device
./09-haply-inverse-ws-remote-control
python 09-haply-inverse-ws-remote-control.py
# Target the Haply Hub Orb demo directly
./09-haply-inverse-ws-remote-control --session co.haply.hub::demo-orb
python 09-haply-inverse-ws-remote-control.py --session "co.haply.hub::demo-orb"
# Target a session directly, specify device
./09-haply-inverse-ws-remote-control --session :my_profile:0 --device A14
python 09-haply-inverse-ws-remote-control.py --session "#42" --device A14
コマンド
- Python
- C++
ボタンを長押しすると、連続して移動します。指を離すと停止します。
| その通り | アクション |
|---|---|
→ / ← | +X / −X |
↑ / ↓ | +Y / −Y |
Page Up / Page Down | +Z / −Z |
= / - | 閲覧速度を上げる/下げる |
0 | ワークスペースを初期状態にリセットする |
H | ヘルプを表示 |
Esc | クィッター (Ctrl+C (これも動作します) |
行ごと:コマンドを入力し、Enterキーを押してください。
| 注文 | アクション |
|---|---|
x+[N] / x-[N] | X軸の速度を±N mm/フレームに設定する(x+ (ソウルは現在のデフォルトの速度のみを使用します) |
y+[N] / y-[N] | Y軸の速度を±N mm/フレームに設定する |
z+[N] / z-[N] | Z軸の速度を±N mm/フレームに設定する |
s+[N] / s-[N] | デフォルトの速度を±N mm/フレームに調整する |
stop | すべての速度をゼロにリセットする |
reset | 速度をゼロに戻し、原点に戻る |
h | ヘルプを表示 |
Ctrl+C(またはCtrl+D/EOF)を押して終了してください。
仕組み
ステップ 1 — HTTP:セッションとデバイスの検出
このチュートリアルでは、同じユーティリティ関数が再利用されています discover_session() / discover_device() que le チュートリアル 08 : GET /sessions (ou GET /sessions/<selector> avec --session), その後 GET /devices (または直接利用) --device). どちらの関数も、同じCLIオプションを受け付けますが、テキストは SESSION_HELP 同じです:チュートリアル00または08で紹介されたセレクタは、ここでは変更を加えることなく動作します。
ステップ 2 — WebSocket セッション、最初のメッセージでのネゴシエーション
このチュートリアルでは、WebSocketを ws://localhost:10001. Au 「受信した最初のメッセージのみ」, セッションプロファイルの記録を送信します:
{
"session": {"configure": {"profile": {"name": "co.haply.inverse.tutorials:ws-remote-control"}}},
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0, "y": 0, "z": 0}}}}}]
}
以下のティックは省略されます session — 操作盤のみ inverse3 送信されます。
ステップ3 — set_transform 各ティックごとに
set_transform 受け入れる 部分変換 — 変更したいフィールドのみ。このチュートリアルでは位置のみを送信します。回転とスケールは、セッションのデフォルト値( configure.mount(該当する場合)。
{
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0.02, "y": 0.0, "z": 0.01}}}}}]
}
ポジションはティックごとに積み上がっていきます。約1 kHzで、サービスは再適用を行います。 set_transform 各ティックごとに(ゼロオーダーを維持し)、作業領域が最後に送信された位置のままになるようにします。
set_transform ou configure.mountどちらのコマンドも、セッションごとに永続的な変換を記録しますが、ワークスペースの変換は par-dessus パイプラインでの編集(参照: 組立と作業スペース). チュートリアル09が配信されている間 set_transform 各ティックごとに、新しいWebSocketフレームが、以前に配信されたワークスペースの変換情報を上書きします。したがって、他のクライアントが配信を行うと set_transform 同じ銘柄に対する注文は、次のティックで上書きされます。 configure.mount 独立しており、その価値を維持しています。実際には、懸念事項ごとに1つのチャネルを選択してください。物理的な構成については「セットアップ」チャネルを、 set_transform ライブナビゲーション用。
スレッドのモデル(C++)
このC++のチュートリアルでは、位置の蓄積値を共有する2つのスレッドを使用しています:
| スレッド | 役割 |
|---|---|
| スレッドの主体 | 点灯中 std::getline(std::cin, ...), トークンを分析し、更新する nav_vel[] et default_step |
| WebSocketのリコールスレッド | 前進させた nav_pos[] avec nav_vel[] * dt, シリアライズ set_transform そしてそれを送る |
std::mutex nav_mutex プロテージュ nav_pos[], nav_vel[] et default_step. タイムスタンプ last_tick そして、その指標は first_ws_msg これらはWSの呼び出し内でローカルであり、ミューテックスを必要としません。
ws.onmessage = [&](const std::string &) {
float pos_snap[3];
{
std::lock_guard<std::mutex> lk(nav_mutex);
for (int i = 0; i < 3; ++i) nav_pos[i] += nav_vel[i] * 0.001f; // mm/frame → m
for (int i = 0; i < 3; ++i) pos_snap[i] = nav_pos[i];
}
// build and send set_transform with pos_snap
};
出典
チュートリアル 09 は SDK とともにローカルにインストールされています — 詳細については tutorials/09-haply-inverse-ws-remote-control/ サービスのインストールディレクトリ内。
関連項目: 注文 set_transform ・ セッション — 最初のメッセージでの交渉 ・ 組立と作業スペース ・ セレクター ・ チュートリアル 08 — リモートでの HTTP 設定 ・ チュートリアル 07 — 基礎と編集