--via-stride を足しました。変更は pi05/run_policy_client.py の 1 ファイルのみ(未コミット、91 insertions / 12 deletions)。 変えた行 行: 7-8 変更: docstring の流れに「--via-stride N で途中の姿勢も中継点として順に送る」 ──────────────────────────────────────── 行: 239-272 変更: plan_vias() を新設。stride=0 なら [used] のみ、N>0 なら range(N-1, used, N) + [used]。apply_limits は直前の中継点の目標から測る(最初だけ実測角 q から)。戻り値は [{"step","raw","target","notes","delta"}] ──────────────────────────────────────── 行: 397-399 変更: --via-stride(既定 0)を追加 ──────────────────────────────────────── 行: 519-522 変更: plan_chunk の結果を plan_vias に渡し、target / notes は最終中継点のものを使う(rec["target"] / rec["notes"] / 既存の Δ 表示の意味は変えていません) ──────────────────────────────────────── 行: 534-547 変更: rec["vias"] の初期化(step / raw / target / notes / sent / arrived / actual_after)、[VIA ] 中継点 N 点: step … の一覧、中継点ごとの [LIMIT]、ドライランでは中継点ごとの Δ 行 ──────────────────────────────────────── 行: 549-556 変更: 安全検査を全中継点に対して実施(stride>0 のときメッセージに step k: を付ける)。引っかかったら従来と同じ扱い([ABORT] → 記録 → flush → exit_code=1 → h の選択 → break) ──────────────────────────────────────── 行: 599-629 変更: 送信を中継点のループに変更。各点で Δ ≤ 0.5° なら送らない(既存ガード)、_send_and_wait_arrival(..., 3.0) → read_angles() で actual_after を記録 → [VIA ] 行に着いたか。rec["arrived"] と settle は最後の中継点だけ。未到達+--auto の停止も従来どおり _send_and_wait_arrival 本体・HOME・SPEED・SEND_WAIT・J4_SAFE・J1_SAFE_MAX・max_move の値・plan_chunk の used の選び方・settle・Enter/s/h/q(チャンクごとに 1 回)は未変更です。 設計上の判断を 1 つ: 安全検査は送り始める前に全中継点をまとめて行い、1 つでも引っかかったらどれも送りません。apply_limits が直前の「目標」から測るので計画は送信前に全部確定でき、途中まで動いて止まる状 態を作らずに済みます(「今と同じ扱い=送る前に止まる」も保てます)。 確認結果(偽の daemon・7 ケースすべて OK) ┌───────────────────────────────────┬──────────────────────────────────────┐ │ ケース │ 結果 │ ├───────────────────────────────────┼──────────────────────────────────────┤ │ 1 --via-stride 0 │ 送信 1 回(pi05_chunk000)、vias │ │ │ キーなし = 従来どおり │ ├───────────────────────────────────┼──────────────────────────────────────┤ │ 2 N=3 / used=9 │ 送信 4 回を via02 → via05 → via08 → │ │ │ via09 の順 │ ├───────────────────────────────────┼──────────────────────────────────────┤ │ 3 7 番目(index 6)で開閉 → used=6 │ 中継点は 2, 5, 6。送信は via02 → │ │ │ via05 の 2 回、最後に爪を閉じる │ ├───────────────────────────────────┼──────────────────────────────────────┤ │ 3b 8 番目(index 7)で開閉 → used=7 │ 中継点 2, 5, 7 を 3 │ │ │ 回送ってから爪を閉じる │ ├───────────────────────────────────┼──────────────────────────────────────┤ │ 4 中継点の 1 つが検査に引っかかる │ 送信 0 回・[ABORT] step 5: │ │ │ …・終了コード 1(残りも送らない) │ ├───────────────────────────────────┼──────────────────────────────────────┤ │ 5 │ 送信 0 回・4 点すべての [ABORT] │ │ アームが範囲外から開始(j4=+100) │ を表示して停止 │ ├───────────────────────────────────┼──────────────────────────────────────┤ │ 6 ドライラン │ 送信 0 回、中継点の一覧と各 Δ を表示 │ └───────────────────────────────────┴──────────────────────────────────────┘ max_move が「直前の中継点から」かかっていることは plan_vias 単体でも確認しました(max_move=5 のとき): step 2: raw j1= -4.0 → target -4.0 Δ -4.0 (直前の目標 +0.0) step 5: raw j1= -10.0 → target -9.0 Δ -5.0 (直前の目標 -4.0) j1 移動量 -6.0° を ±5° に制限 step 8: raw j1= -16.0 → target -14.0 Δ -5.0 (直前の目標 -9.0) j1 移動量 -7.0° を ±5° に制限 step 9: raw j1= -18.0 → target -18.0 Δ -4.0 (直前の目標 -14.0) ケース 3 について補足: used=6(index 6 で開閉)のとき plan_chunk の目標は acts[5] なので、中継点 step 6 の目標は step 5 と同じ値になります。既存の「Δ 0.5° 以下は送らない」ガードでこの 1 回は省かれ、画面は 送らず (0.5° 以下)、ログは "sent": false になります(中継点の一覧には 2, 5, 6 の 3 点が残ります)。step 7 で開閉する 3b では 3 点とも送られるので、重複するのは「開閉ステップの 1 つ前が中継点と一致したとき」だけです。この挙動でよければこのまま、毎回必ず最後 も送るほうがよければ変えます。