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

07. ベース&マウント・プレイグラウンド

インタラクティブに制御します マウント変換 デバイスの…を示し、その方法を説明しています。 configure.basis, configure.preset und configure.mount プロトコルレベルで連携する。configure コマンドへのインタラクティブな焦点を維持するため、固定された水平ベースが維持される。

学習内容:

  • 設定 基底の順列 ("XZY" → Y軸が上向きの適用範囲)
  • の選択 プリセット (arm_front) および、それが何を設定しているのかを理解する
  • 実行時に回転クォータニオンを用いてマウントを上書きする(キーボード操作による)
  • 相互排他性の法則: mount und preset 同じブロックの デバイスの設定 発生
  • 一回限りの configure-セマンティクス:キーが押されるたびに、正確に1つのconfigureメッセージが送信される
  • (C++ Glaze) 相互に排他的なフィールドのモデリング std::optional

手順​

  1. 最初のメッセージでは、以下を送信してください: セッション概要, configure.basis: "XZY" und configure.preset: arm_front. 固い地面のために始めましょう set_cursor_force 送信する。
  2. 各ティックごとに:Cursor-Yを読み取り、 force_y = max(0, (floor_pos - y) * stiffness) 計算して送信する。
  3. ユーザーがマウントローテーションボタンを押した場合は、 pending_configure = true.
  4. 次のティックで、次のものを作成してください。 configure.mount-変換を含むブロックで、その rotation これは単位クォータニオンです(現在のピッチ値とヨー値のZ→X順の合成)。では、 preset weg – これら2つはプロトコルレベルにおいて互いに排他的である。
  5. リセットボタン(R) 上書きを解除します。次の configure 命令では、再び preset 戻る。

パラメータ​

名称標準Zweck
BASIS"XZY"軸の配置変更— Y軸が上向きになる適用フレーム
DEVICE_PRESET / DEVICE_CONFIG_PRESET"arm_front"指定プリセット— デバイス本体に由来
FLOOR_POS_Y0.0 m固定床面(アプリケーションY)
STIFFNESS1000 単位なし土壌のフェダー定数
MOUNT_STEP_DEG10°ボタン操作による回転
PRINT_EVERY_MS200テレメトリの制限

制御​

味アクション
W / S装置の+X軸を中心に±10°回転させる(ピッチ)
A / D装置の+Z軸を中心に±10°回転させる(ヨー)
Rリセット – プリセットに戻る
H制御を表示
Q終了
mount und preset 互いに排他的である

同サービスは、以下のブロックを拒否しています。 デバイスの設定 ab(両方を含む)。ユーザーがマウントを上書きすると、チュートリアルは preset 以降のすべての configure ステートメントから削除されます。を押すと R wird preset 次の configure コマンドで再び有効化され、 mount 却下された。

さまざまな入力モデル

C++ バージョンでは、バックグラウンドの stdin スレッドで行単位の入力を受け付けます(各文字の入力後に Enter キーを押してください)。Python では、パッケージ keyboard 非同期のメインループにおけるリアルタイムのキー入力検出用――ENTERキーは不要です。同じキー、同じコマンドです。

読み込まれた状態フィールド​

Aus data.inverse3[i].state:

  • cursor_position.y — vec3, は地中浸透率の算出に使用される
  • current_cursor_force — テレメトリとして報告される

送信/受信​

ペイロードの構造はすべてのバリエーションで同じですが、興味深いのは、各バリエーションが互いに排他的な分岐をどのように扱っているかという点です。 mount / preset 構築される仕組みと、入力スレッドがWebSocketスレッドにどのようにシグナルを送るか。

パッケージを介したリアルタイムのキー入力を備えた単一の非同期ループ keyboard. pending_configure これは、キーボードハンドラによって設定され、 configure-ブロックが送信されます。

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"]
# Handshake: profile + basis + preset
request_msg = {
"session": {"configure": {"profile": {"name": SLUG}}},
"inverse3": [{
"device_id": device_id,
"configure": build_configure_block(first_handshake=True),
# -> {"basis": {"permutation": "XZY"},
# "preset": {"preset": "arm_front"}}
}],
}
else:
handle_key_inputs() # may set pending_configure = True (classic, not shown)

y = data["inverse3"][0]["state"]["cursor_position"]["y"]
force_y = 0.0 if y > FLOOR_POS_Y else (FLOOR_POS_Y - y) * STIFFNESS

entry = {
"device_id": device_id,
"commands": {"set_cursor_force":
{"vector": {"x": 0.0, "y": force_y, "z": 0.0}}},
}
if pending_configure:
entry["configure"] = build_configure_block(first_handshake=False)
# -> {"mount": {...}} OR {"preset": {...}} (never both)
pending_configure = False

request_msg = {"inverse3": [entry]}

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

チュートリアル 07 も SDK とともにローカルにインストールされています。以下の場所にあります。 tutorials/07-haply-inverse-basis-and-mount/ サービスのインストールディレクトリ内。

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

関連項目: 基底の順列 ・ マウントとワークスペース ・ デバイスの設定 ・ ステューアコマンド (set_cursor_force) ・ タイプ(変換) ・ チュートリアル 04(Hello Floor)