メインコンテンツへ移動

06. コンビネーション(Inverse3 +Wireless VerseGrip)

2台のデバイスを使ったチュートリアル:ハンドルを向けてボタンを押し続けると、Inverse3 のカーソルがその方向に移動します。カーソルは球形の作業領域内に制限されます。

学習内容:

  • 同じステートフレーム内で 2 種類のデバイスを読み取る(inverse3 et wireless_verse_grip)
  • ハンドルの向きを、その位置から抽出する 四元数 (axe local +Y)
  • 利用 set_cursor_position カーソルを計算されたターゲットの位置に移動させるには
  • ターゲットを安全な作業領域の球体に限定する —Minverse では、これよりも小さい半径が使用されています。Inverse3
  • 定義する ワークスペースのプリセット (arm_front_centered) 五線譜の中心に音符の原点が来るように

進行​

  1. 2台のデバイスを検出する:
    • バリエーション C++ 質問者 GET /devices 起動時にHTTP経由で接続し、その後、キャリブレーションのプロンプトを表示して、ユーザーがEnterキーを押すのを待ちます。
    • Pythonは、WebSocketの最初のステータスフレームから、2台のデバイスの識別子を読み取りました。
  2. を登録してください セッションプロファイル そして、以下のように設定してください configure.preset: arm_front_centered 最初のメッセージ(一度限りの連絡)において。
  3. 各サイクルごとに、以下のorientation 取っ手の状態と buttons.{a, b}.
  4. 移動ボタンが押されている場合、ワールド空間におけるハンドルの方向を計算します(R(q) · ĵ — 回転させた単位軸 +Y)を、これに SPEED そして、それを目的の位置に追加してください。
  5. ターゲットを作業領域の球体内に限定し、以下を通じて送信してください。 set_cursor_position.
  6. (Pythonのみ)状況に応じて球の半径を調整してください。 config.type 本機の — minverse = 0.04 m、それ以外はすべて = 0.10 m。

パラメータ​

ノムデフォルト値役割
SPEED0.01 m/cycleボタンが押されている間は移動しない
RADIUS_INVERSE30.10 mInverse3 /Inverse3x のワークスペースの制約半径
RADIUS_MINVERSE0.04 mMinverse のワークスペースの制約範囲(Pythonのみ — C++は修正済み) 0.10 (ハード)
PRINT_EVERY_MS200テレメトリのデータ転送速度の制限
セッションプロファイル名co.haply.inverse.tutorials:combinedHaply Hub でこのシミュレーションを特定してください
実行前にキャリブレーションを行う
  • Inverse3 が自動的にキャリブレーションを行うのを待ちます(または、グリップをインク壺の上に置き、LEDが点灯したままになるまで待ちます)。
  • インク壺の取っ手を取り外してください。
  • A または B を押し続けながらハンドルを回してください。カーソルは、ハンドルが向いている方向に移動します。

よく読まれている記事​

各サイクルの状態トレースに基づいて:

  • data.inverse3[0].state.cursor_position — vec3
  • data.wireless_verse_grip[0].state.orientation — quaternion
  • data.wireless_verse_grip[0].state.buttons.{a, b, c} — ブール値
  • (Python、最初のフレームのみ) data.inverse3[0].config.type — 「Inverse3 」の半径、または「Minverse
  • (Python、最初のフレームのみ) data.inverse3[0].status.calibrated — 値が誤っている場合、ユーザーにキャリブレーションを行うよう促す

送信と受信​

四元数からの方向の計算(回転) +Y par R(q)) および球面への制約は、古典的な線形代数の範囲に属します — ソースファイルを参照してください。Inverse API に関しては、これは初期の接触処理と set_cursor_position 各サイクルごとに。

一意の非同期ループ。Pythonは最初のステータスフレームから2つのデバイスの識別子を読み取り、接続確立時にプロファイルを結合し、 configure.preset: arm_front_centered au premier set_cursor_position.

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

if first_message:
first_message = False
inverse3_id = data["inverse3"][0]["device_id"]
grip_id = data["wireless_verse_grip"][0]["device_id"]
radius = get_workspace_radius(data["inverse3"][0].get("config", {}))

# Handshake: profile + preset + first position command
request_msg = {
"session": {"configure": {"profile": {"name": SLUG}}},
"inverse3": [{
"device_id": inverse3_id,
"configure": {"preset": {"preset": "arm_front_centered"}},
"commands": {"set_cursor_position": {"position": position}},
}],
}
else:
# Per tick: update position from grip pointing direction (classic math, not shown), send
request_msg = {
"inverse3": [{
"device_id": inverse3_id,
"commands": {"set_cursor_position": {"position": position}},
}],
}

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

チュートリアル 06 も SDK とともにローカルにインストールされています。詳しくは tutorials/06-haply-inverse-combined/ サービスのインストールディレクトリ内。

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

関連項目: 制御コマンド (set_cursor_position) ・ 型 (quaternion, vec3) ・ モンタージュと作業スペース(プリセット) ・ チュートリアル 03(ワイヤレス VG) ・ チュートリアル 05(位置制御)