メインコンテンツへスキップ

05. 位置制御

Inverse3 からカーソルを移動させます set_cursor_position 目的の位置へ。 インタラクションモデルは、プログラミング言語によって異なります。 — C++ では一度きりのランダムなターゲット位置が使用されるのに対し、Python ではキーボード操作による連続的な移動が使用されます。

学習内容:

  • の使用 set_cursor_position 位置制御モードでの制御用
  • 同じ基本コマンドに対する2つの異なるインタラクションモデル
  • 目標を作業空間内の球体に限定すること — 『Minverse 』では、これよりも小さい半径が使用されている。Inverse3
  • 作業空間のプリセットを設定し、原点を作業空間の中心に位置させる

手順​

C++(ランダム目標モデル)​

  1. 行単位でバッファリングされたキー入力を処理するバックグラウンド入力スレッドを起動します(n, +, -, q) stdin から読み込む。
  2. WebSocket を開きます。最初のステータスフレームで、 会議概要 そして、次のように設定してください configure.preset: arm_front_centered. 球体内から最初のランダムな目標点を生成します(リジェクション・サンプリング、半径 0.08 m)。
  3. ティックが発生するたびに、 set_cursor_position-現在のターゲットへのコマンド。カーソルはそれに均一に追従します。このサービスはレートを制限し、補間を行います。
  4. ユーザーが n + ENTER を入力すると、入力スレッドは新しいランダムなターゲットを生成します。 + / - 速度を調整してください; q プログラムを終了します。

Python(ボタンを押し続けると動くモデル)​

  1. WebSocket を開きます。最初のステータスフレームで以下を確認してください。 status.calibrated — デバイスがまだ校正されていない場合は、ユーザーに校正を行うよう指示してください。
  2. こちらをご覧ください config.type 作業領域の半径を決定するために(minverse = 0.04 m、その他の値はすべて = 0.10 m)。
  3. これを登録してください 会議概要 そして、次のように設定してください configure.preset: arm_front_centered.
  4. 各ティックごとに:キーボードの状態を取得する (W/A/S/D/Q/E), 目標位置を SPEED 押されている各軸に沿って更新し、作業領域の球体に制限して、 set_cursor_position 送信。 R 目標を起点に戻します。

パラメータ​

名称標準値 (C++)標準値(Python)Zweck
workspace_radius / RADIUS_INVERSE30.08 m0.10 m (Inverse3) / 0.04 m (Minverse)標的球の半径
speed_step / SPEED0.01 / キーを押す0.00005 m / ティック1回の操作あたりのステップ数
PRINT_EVERY_MS—100テレメトリの制限(Python)
会議概要co.haply.inverse.tutorials:position-controlgleichHaply Hubで特定されました
校正テスト(Python)

Pythonのバリエーションでは、以下を確認します status.calibrated 最初のステートフレームで、デバイスがキャリブレーションされていない場合はユーザーにキャリブレーションを行うよう促します。C++版では、キャリブレーションがすでに完了していることを前提としています。

読み取り済みステータスフィールド​

  • data.inverse3[0].device_id — コマンドの作成について
  • data.inverse3[0].state.cursor_position — テレメトリー
  • (Python、最初のフレームのみ) data.inverse3[0].config.type — 「Inverse3 」と「Minverse 」の半径のいずれかを選択します
  • (Python、最初のフレームのみ) data.inverse3[0].status.calibrated — 値が false の場合、ユーザーに次のように促します

送信/受信​

コミュニケーションの流れ​

  • C++ バックグラウンドのstdinスレッドを実行し、そのスレッドは std::atomic<float>-Zieleが書き込みを行い、WebSocketスレッドは各ティックごとにこれを読み取ります。 n + ENTER を入力すると、入力スレッドが新しいランダムなターゲットを生成します。 q 両方のスレッドが終了します。
  • Python これはシングルスレッドかつ非同期です。WebSocketのループは、各ティックごとにキーボードの状態を照会し、更新を行います。 position direkt。

Inverse-APIのペイロードデータは同一です。最初のティックにはセッションプロファイルが含まれています + configure.preset, 以下のティックには以下の内容のみが含まれています set_cursor_position.

単一の非同期ループ。キーボードのポーリング(handle_keys) は、各ティックごとにインラインで実行されます — スレッドを使用せずに。 config.type und status.calibrated は、最初の状態フレームから一度だけ読み込まれます。

async with websockets.connect(URI) as websocket:
while True:
msg = await websocket.recv()
data = json.loads(msg)

if first_message:
first_message = False
device_id = data["inverse3"][0]["device_id"]
radius = get_workspace_radius(data["inverse3"][0].get("config", {}))
# Handshake: profile + preset (one-shot)
request_msg = {
"session": {"configure": {"profile": {"name": SLUG}}},
"inverse3": [{
"device_id": device_id,
"configure": {"preset": {"preset": "arm_front_centered"}},
}],
}
else:
# Per tick: update position from keyboard (classic polling, not shown), send command
position = handle_keys(position, radius)
request_msg = {
"inverse3": [{
"device_id": device_id,
"commands": {"set_cursor_position": {"position": position}},
}],
}

await websocket.send(json.dumps(request_msg))
SDKインストーラーに含まれています

チュートリアル 05 は、SDK とともにローカルにもインストールされます。以下の場所に保存されています。 tutorials/05-haply-inverse-position-control/ サービスのインストールディレクトリ内。

出典: Python·C++·C++ Glaze

関連項目: ステューアコマンド (set_cursor_position) ・ モンタージュと作業スペース(デフォルト設定) ・ 型 (vec3) ・ チュートリアル 06(複合)