notes
Control

モータ電流を使った壁 (endstop) 検出

追加センサなしでエンドストップ / 原点 homing を実現する方法。指令モードの選び方と誤検出防御

要点#

モータの実電流を「壁に当たった」信号として使う ことで、リミットスイッチや ADC しきい値センサを増やさずに原点 homing / エンドストップ検出ができる。

条件:

  1. モータへの指令が VELOCITY (速度) モードであること。トルク / duty モードでは原理的に検出しにくい (後述)
  2. 壁到達時に電流が 持続的に上がる (瞬時ピークではなくステップ) こと。ゴム緩衝材が挟まっているとこの前提が崩れる
  3. モータの電流フィードバックが host 側に届いていること (feedback msg / ADC ADC etc.)

なぜ VELOCITY が必要か#

指令モードで壁到達時に電流がどう振る舞うかは firmware の regulate 対象で決まる。

指令モードfirmware が何を維持する壁到達時の電流
VELOCITY (速度)速度速度 0 になっても指令速度を維持しようとして電流を吐き上げる → スパイク発火
TORQUE / CURRENT (トルク・電流)電流指令電流に regulate されるだけで、実電流は指令値のまま → スパイク発火せず
DUTY (RoboMaster MD の場合)電流 (実質)RoboMaster C610/C620 の DUTY は「±10000 = ±10A の正規化電流指令」なので TORQUE と同じ挙動 → スパイク発火せず
PWM DUTY (純粋 PWM 出力)PWM duty 比端子電圧一定 → 逆起電力ゼロで電流最大 → スパイク発火するがピークが飽和しやすい (電源電流上限で頭打ち)

MD の「DUTY」が PWM duty ではなく実質電流指令なのは firmware 仕様の話で、他の MD (ODrive / RobStride 等) は名前が同じでも中身が違うことがある。「壁検出の可否は指令モードの名前ではなく、firmware が何を regulate しているか」 で決まる。

2 条件 OR で停止判定#

電流スパイクの検出は 1 条件だと環境依存になりやすい。実運用では 2 条件 OR が頑丈:

[A] I > I_move + k * σ_move    (統計ベース、cap を知らなくてよい)
[B] |I| ≥ ratio * I_cap         (飽和検出、cap を知っている時に速い)
  • [A] sigma ベース: 走行中 (CRUISE) に電流の平均 I_move と標準偏差 σ_move を数百 ms 蓄積し、I > I_move + k * σ_move (k=3 くらい) で「異常に高い」を判定
  • [B] cap 飽和: 電流制限値 I_cap (config or firmware から取得) を知っているなら、|I| ≥ 0.9 * I_cap で「限界まで吐き上げてる」を検出

どちらか成立で over-current 扱い。両方使うことで:

  • 静音下 (σ 退化) にも強い ([B] が拾う)
  • cap 不明の機構にも使える ([A] が使える)

引っかかりと壁の区別#

一度でも over-current 条件が成立したら即停止、だと途中で引っかかったときに「壁到達」と誤認する。持続時間 stall_hold_ms (例 100 ms) を挟むと、瞬時ピーク (引っかかり) を除外できる。

raw over-current: [==pulse==] . . [======step======]
                    (30 ms)         (200 ms 継続)
判定:              チャタリング      壁確定

条件が落ちたらタイマー reset。連続で成立し続けた場合のみ壁確定。

完了までのシーケンス例 (6 状態)#

S0 BASELINE   (100-150 ms)    motor OFF、offset / sigma_off / v_min を測る
S1 SOFT_START (200 ms)        velocity 0 -> velocity_home へ ramp、current 無視
S2 MOVE_GATE  (~100 ms)       ramp 完了後、|v| > v_min が hold_ms 継続 → S3
                              超過 → LIMIT_AT_START (最初から壁の可能性)
S3 CRUISE     (100 ms)        I_move / sigma_move をサンプリング
S4 WATCH      (timeout まで)   2 条件 OR で over-current 判定、stall_hold_ms 継続で LIMIT_HIT
S5 BACKOFF    (~backoff)      逆方向 velocity で backoff 距離動かして停止
DONE                          reset_encoder で「壁 = 0」を確定

S0 の baseline 測定と S2 の gate は「最初から壁に押し付けられている状態で reset_encoder しない」ための安全弁。gate が失敗しても encoder を reset しない選択肢 (reset_on_limit_at_start) を残すと運用上安全。

3 パターン比較 (電流 / 収束 / 外部センサ)#

同じ「壁到達を検出したい」でも、観測量が違う 3 パターンがある。全部 VELOCITY 指令で走らせる (指令モードは共通)。

電流ベース収束ベース外部センサ (limit sw / ADC)
観測量電流 I速度 v と 位置 Δpセンサの topic (true/false)
検出条件I > threshold を hold_ms 継続`v
ハード追加不要不要センサ + 配線
電流 feedback要不要不要
壁 vs 引っかかり の区別できる (瞬時ピーク vs 持続ステップ)❌ できない (引っかかりでも v ≈ 0)❌ できない (センサ側の位置でしか判定できない)
時間コストstall_hold_ms (~150ms)stability_interval_ms (~200ms) × 判定成立までエッジ検出は瞬時
検出精度数 ms×v 分の overshoot (backoff で戻す)同上エッジ跨ぎ 1 パルス
調整コストbaseline / margin の tunev_th と p_th の tunetrue/false 判定、調整レス
誤検出耐性摩擦・引っかかり対策のロジック必要引っかかりが誤検出になるセンサ正常前提、強い

選び方:

  • 精度 1 パルス欲しい / 機構が固定 / センサ配線 OK: 外部センサ
  • 配線を増やしたくない / 電流 feedback がある / 引っかかりを判別したい: 電流ベース
  • 配線 なし / 電流 feedback なし (encoder だけ) / 単純さ優先: 収束ベース

両者混在も可能 (electrical endstop で粗く止めた後に電流で押し付けて微調整、等)。

関連#

  • [[robomaster-normalization]] — RoboMaster MD の DUTY 単位系
  • [[rc27-mech-calibration-history]] — rc26 (BT + 外部センサ) → rc27 (電流ベース C++ node) への移行
最終更新:

On this page