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

06. 組み合わせ(Inverse3 +Wireless VerseGrip)

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

学習内容:

  • 同一の状態フレームから2種類のデバイスを読み出す(inverse3 und wireless_verse_grip)
  • ハンドルの向きを、その クォータニオン (ローカル +Y-軸)
  • 「Verwenden von」の使用 set_cursor_position、カーソルを計算された目標位置に移動させるために
  • 目標点を安全な作業領域の球体に限定する――Minverse では、より小さな半径が使用されている。Inverse3
  • の指定 作業スペースのプリセット (arm_front_centered), これにより、原点が射程範囲の中央に位置するようにする

手順​

  1. 両方のデバイスが認識します:
    • C++-起動時にHTTP経由でバリエーションを問い合わせる GET /devices ab、その後、キャリブレーションの要求を表示し、ENTERキーの入力待ちとなります。
    • Pythonは、WebSocketの最初のステータスフレームから両方のデバイスIDを読み取ります。
  2. これを登録してください 会議概要 そして、最初のメッセージに configure.preset: arm_front_centered (1回限りの握手)。
  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。

パラメータ​

名称標準値Zweck
SPEED0.01 m/tickキーが押されている間のステップ幅
RADIUS_INVERSE30.10 mInverse3 /Inverse3x の作業領域の境界半径
RADIUS_MINVERSE0.04 mMinverse の作業領域の境界半径(Python のみ。C++ は固定で 0.10 (符号化)
PRINT_EVERY_MS200テレメトリの制限
セッションプロファイル名co.haply.inverse.tutorials:combinedHaply Hubでこのシミュレーションをマークする
起動前にキャリブレーションを行う
  • Inverse3 に自動キャリブレーションを行わせてください(または、グリップをInkwellに置いて、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} — Booleans
  • (Python、最初のブロック内のみ) data.inverse3[0].config.type — 「Inverse3 」の半径を選択するか、Minverse
  • (Python、最初のブロック内のみ) data.inverse3[0].status.calibrated — 値が false の場合、ユーザーに次のように促します

送信/受信​

クォータニオンからの方向の計算(回転の +Y mit R(q)) および球面への制限は、古典的な線形代数の範囲です――ソースファイルを参照してください。逆APIの側面は、ハンドシェイクと、1サイクルごとに送信される set_cursor_position.

たった1つの非同期ループです。Pythonは最初のステータスフレームから両方のデバイスIDを読み取ります。ハンドシェイクはプロファイルと configure.preset: arm_front_centered 最初の 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) ・ 型 (クォータニオン、vec3) ・ モンタージュ&ワークスペース(プリセット) ・ チュートリアル 03(ワイヤレス VG) ・ チュートリアル 05(位置制御)