自律移動ロボットのソフトウェアは、それを載せる車体があって初めて意味を持つ。ここではnewbotのハードウェア構成——車体、駆動系、電源系統、センサー——を記す。
車体
アルミフレームを組んだ3階建て構造(縦横高さ約300×200×200mm)で、各段に桐板の棚板を渡している。3層に分けているのは、駆動系・制御用コンピュータ・センサー類を物理的に分離して配線と放熱の見通しを良くするためである。
駆動系
2輪差動駆動方式で、エンコーダ付きギヤモーター(12V、100RPM、ホイール径65mm)を左右に1基ずつ搭載し、旋回・安定性のためのキャスターを1つ加えている。モーターの駆動には専用のモータードライバ(Cytron MDD10A)を使い、上位から受け取った速度指令をPWM信号に変換してモーターへ伝える。
左右のモーターは車体に鏡写しで取り付けられているため、同じDIR論理(HIGH/LOW)を両輪にそのまま与えると片方が前進・もう片方が後退してしまう。実機確認では、同一速度指令(左右とも同じ値)を送ったにもかかわらず直進せずその場で旋回する、という形で発覚した。右モーターだけDIR論理を反転させるソフトウェア側の補正で解消しているが、これは機構が左右対称でも電気的には対称でないという、ハードウェアとファームウェアの境界に落ちる典型的な不具合だった。
エンコーダの信号線には、ESP32のGPIOのうちENC_L_A/B(GPIO32/33)とENC_R_A/B(GPIO18/19)を割り当てている。
| 信号 | GPIO | 備考 |
|---|---|---|
| MOTOR_L_PWM | 25 | Cytron MDD10A 左PWM |
| MOTOR_L_DIR | 26 | 左DIR |
| MOTOR_R_PWM | 27 | 右PWM |
| MOTOR_R_DIR | 14 | 右DIR |
| ENC_L_A | 32 | 割り込み・内部プルアップ有 |
| ENC_L_B | 33 | 内部プルアップ有 |
| ENC_R_A | 18 | 割り込み・内部プルアップ有(当初34を割り当て、後述の理由で変更) |
| ENC_R_B | 19 | 内部プルアップ有(当初35を割り当て、後述の理由で変更) |
エンコーダのGPIO割り当ては当初34/35番だったが、ESP32のGPIO34〜39は入力専用ピンであり、内部プルアップ/プルダウン抵抗が物理的に存在しないという制約に後から気づいた。INPUT_PULLUPを指定してもエラーにならず無言で無視されるため、右エンコーダの信号線がフローティング状態のまま動作しているように見えるという厄介な症状になった。気づいてから18/19番(ストラッピングピンでもフラッシュ接続ピンでもUARTピンでもない、通常のプルアップ対応GPIO)へ配線を変更している。
センサー
主センサーはLivox Mid-360(3D LiDAR、6軸IMUを内蔵)で、周囲の3次元形状の取得と自己位置推定の両方を担う。補助的に、USBカメラ(Logitech C920)を搭載しており、視覚的な特徴を使った地図生成のループクロージャや、障害物までの距離推定に使っている。
制御コンピュータ
車体には2つの計算資源を搭載している。メインの制御はRaspberry Pi 5が担い、自己位置推定・安全監督・センサー取得といったエッジ側の処理を行う。より低レベルな処理(エンコーダの読み取り、モーターのPWM制御)はESP32が専任で担当する。役割分担の詳細は「ESP32ファームウェアと通信プロトコルの仕組み」の記事を参照。
電源系統
電源には、電動工具でも使われる汎用の18Vバッテリーパックを採用した。専用のバッテリーを新規に用意するのではなく、汎用規格のものを使うことで、予備バッテリーの入手や充電の運用を簡略化している。18Vの電圧はそのままでは使えないため、DC-DCコンバータで12V(モーター・モータードライバ系統)と5V(Raspberry Pi 5系統)にそれぞれ降圧して供給している。
バッテリー電圧の監視は、ESP32のADC入力で行う設計にしているが、18Vをそのまま入力すればESP32のADCピン(耐圧3.3V)を破壊する。そのため、分圧回路を挟んで電圧を下げ、analogSetPinAttenuationでADCの減衰設定を合わせた上で、実測に基づく校正を必ず行うことにしている。この分圧回路の配線を後回しにしたまま走行テストを行った際、ADC入力ピン(GPIO39)がフローティング状態になり、モーター駆動時のノイズを拾って5〜13Vという出鱈目な電圧値を返す事態が発生した。この偽の電圧値をバッテリー監視ノードが「危険域」と誤判定し、走行中に非常停止が発動するという実害まで出ている。対処として、分圧回路が未配線の間はテレメトリの電圧値に「未計測」を表す値を送り、監視ノード側でその値を無効サンプルとして無視する形にした。電圧が読めないなら「危険な値が読めた」ことにしないという、単純だが踏むまで気づきにくい設計上の教訓である。
Raspberry Pi 5側の電源にも実機で問題が出ている。走行検証の最中、原因不明のまま2回突然再起動した事象があり、うち1回はビルド処理の最中に発生してインストール成果物が破損し、関連サービスが起動失敗を繰り返す事態を招いた。Pi5にはアンダーボルテージ(電圧不足)を検知するハードウェアフラグがあり、これを確認する運用を以後の立ち上げ手順に組み込んでいる。フラグが立っていれば、電源・配線の物理的な点検を先に済ませてからでないと自律走行の検証を始めない、というゲート条件にしている。
実機立ち上げ・校正の手順
ハードウェアは組み上げて終わりではなく、エンコーダやモーター駆動の特性を実測して校正して初めて、上位のソフトウェアが正しく扱える。実機に触れられる時間は限られているため、後戻りしないよう手順を1枚のチェックリストにまとめ、上から順に「合格条件を満たしてから次へ進む」運用にしている。
エンコーダの配線と極性確認
エンコーダの信号線は、ESP32の入力専用ピン(内部プルアップを持たないGPIO)を避けて配線する必要がある。この制約に気づかず入力専用ピンに配線し、プルアップが効かず信号が不安定になった箇所を後から配線変更で修正した経緯がある。極性確認は「片輪を前進方向に手で回してtickカウントが正方向に増えるか」を目視で確認し、逆であればソフトウェア側で符号を反転させる。
1回転あたりのパルス数(PPR)の実測
エンコーダの理論分解能(ギヤ比×エンコーダ生分解能×逓倍数)は、実際の機械的なバックラッシュやギヤの遊びの影響を受けるため、片輪をちょうど10回転手で回してカウント数を積算し、実測値をソフトウェア側の設定に反映している。この実測値は、後述する「安全な速度制御の仕組み」の記事で扱った低速域のカウント相殺の問題とも関わっており、手回しでの実測値は真値の下限にとどまることを踏まえた上で使っている。
速度指令とPWMデューティの校正
車体を持ち上げた状態(または空転できる台の上)で、既知の速度指令(mm/s)を送り、エンコーダから逆算した実測速度と比較しながら、速度指令からPWMデューティへの変換係数を線形補正する。低速・中速・高速の複数点で確認し、低速域でモーターが実際には回転しない不感帯(デッドバンド)の範囲も把握した上でソフトウェアに反映している。
車体寸法の実測
左右タイヤの接地中心間距離、タイヤの実測直径(公称値は荷重や摩耗で変わる)、センサーの取り付け角度など、走行に直結する寸法は実測して反映する。この実測を怠ったことが、後述する自律走行の初回成立を長く妨げていた要因の一つでもあった(詳細は「地図生成と自律ナビゲーションの仕組み」の記事を参照)。
具体的には、車体後端のオーバーハング量が設定上0.16mとされていたのに対し実測は0.30mあり、その場旋回に必要な掃引半径も設定上0.22mに対し実測0.327mだった。いずれも「未実測」の暫定値が本番の安全判定にそのまま使われ続けていたケースで、実測して初めて衝突判定の見逃しにつながる誤差だったと判明している。
ファームウェア書き込み時の注意
ESP32へのファームウェア書き込みにはesptoolを使うが、パッケージ管理システム経由でインストールされる版は内蔵の高速書き込みモード(stub)を持たないため、--no-stubオプションを明示的に付ける必要がある。この違いに気づかず標準的な書き込み手順をそのまま試して失敗した経緯がある。
LiDARの実機と型番の食い違い
導入時、当初想定していたLiDARの型番(Mid-360)と、実際に届いた実機の型番(Mid-360S)が異なっていたことが、通信のディスカバリ応答から判明した。型番が違うと、対応する設定ファイルで起動してもドライバは無言のまま(エラーを出さずに)停止し、ネットワーク障害と誤診しやすい。型番不一致はハードウェア調達の見落としとして記録に残している。