1台のPC(2モニタ)でPi Zero 2 WのUSB HIDを使い、同じPCの2ndモニターを自動操作する

---

## **はじめに**

通常は、「HDMIキャプチャデバイス + Pi Zero 2 WのUSB HID」構成を想定すると、**“別のPC”** を物理的に制御するケースが多いです。しかし、実際に開発・デバッグする際には、以下のような問題があります。

- 別PCを常に用意する手間  
- 実機でのトライ＆エラーを何度も繰り返すのが面倒  
- シンプルに**1台のWindows PCの2ndモニター**を“別画面”として扱い、その画面をキャプチャ＆自動操作すればデバッグが捗る

そこで本記事では、**1台のPC**に**2つ目のモニター**を接続し、その2ndモニター上の画面を「HDMIキャプチャ」または「画面キャプチャソフト」等で取り込み、さらに**Pi Zero 2 W**を同じPCにUSB接続して「仮想マウス/キーボード入力」を行う形で**自分自身の環境を自動操作・デバッグ**する方法を紹介します。

---

## **構成イメージ**

1. **Windows PC**  
   - メインモニター (開発用)  
   - 2ndモニター (デバッグ用画面。ここを“別端末画面”のように見立てる)  
   - HDMIキャプチャデバイス or 画面キャプチャソフト（OBS / SikuliX 2ndモニタ取得など）  
   - **Pi Zero 2 W をUSB接続し、Windows上で“HIDデバイス”として認識**  
2. **Raspberry Pi Zero 2 W**  
   - USBガジェットモードでキーボード/マウスエミュレート  
   - Windows PC上のPython / gRPCサーバー or HTTPサーバーを動かしてもOK（同じPC内通信も可）  
   - 物理的には同じPCに挿すだけで実際に「マウス操作やキー入力」が行われる  

### **HDMIキャプチャ vs. ソフトウェアキャプチャ**
- **HDMIキャプチャデバイス**を、2ndモニターの出力をループバックして取得する方法  
  - 2ndモニター出力 → HDMIキャプチャ → Windowsに取り込み  
  - Pi Zeroでなく、Windows上で映像を解析する  
- あるいは、**OBS Studio等のソフトウェアキャプチャ**や**SikuliXのマルチモニタ対応**で2ndモニターの画面を直接取得する手法  
  - こちらの方が物理配線が不要で、2ndモニタの内容をそのままWindowsがソフト的に取り込める  

今回は「とにかく1台のPC内で完結したい」前提なので、**ソフトウェアキャプチャ** (OBS / 画面共有ツールなど) で2ndモニターを取得→SikuliXが解析、が実用的です。

---

## **具体的手順 (概要)**

1. **2ndモニターを接続**  
   - Windowsがマルチディスプレイとして認識（拡張モード）  
2. **Pi Zero 2 W** をUSBケーブルで同じWindows PCに接続し、**HIDガジェットモード**を設定  
   - Windowsが「仮想マウス/キーボード」として認識する  
3. **SikuliX**等で2ndモニターの画面をキャプチャする設定  
   - 例: SikuliXだと`Screen(1)`で2ndモニタを指定できる場合がある  
   - またはOBSで2ndモニタ映像をプレビュー → SikuliXがそのプレビューウィンドウを解析  
4. **Windows上にPi Zero向けのgRPCサーバー or HTTPサーバー**を動かす  
   - あるいはPi Zeroがサーバー、Windowsがクライアントでも可。同じマシン内でlocalhost通信 or 127.0.0.1  
   - Pi Zero が USB HIDを送るために、**どちらがサーバーか**はデザイン次第  
5. **自分自身のPCがPi Zeroからのマウス/キーボード入力を受け取り**、2ndモニター画面上でクリックや入力が行われる  
   - これにより、「別PC」を用意しなくても同じPCの2ndモニターを“テスト対象画面”として自動操作できる

---

## **1. Pi Zero 2 WのHIDガジェットモード設定**

(※ 詳細は**別記事**を参照)

- `dtoverlay=dwc2` や `modules-load=dwc2,g_ether,g_hid` 等を `config.txt`, `cmdline.txt` で設定  
- Pi ZeroがUSB接続されると、Windowsが「HIDデバイス：キーボード/マウス」として認識  

---

## **2. WindowsでSikuliXが2ndモニターを解析する設定**

### **2-1. SikuliX + 2画面環境**

- SikuliXの `Screen()` クラスで、 `Screen(0)` がメインモニター, `Screen(1)` が2ndモニター になる場合が多い  
- 例: `screen_img = capture(Screen(1))` で2ndモニタをキャプチャ  
- もしSikuliXのバージョンやWindows設定でうまくいかない場合は、**OBS**で2ndモニター映像のプレビューを1stモニターに表示し、そのウィンドウを解析する方法も

### **2-2. OBSなどソフトウェアキャプチャ例**

- 2ndモニターをOBSで`Display Capture`し、プレビューウィンドウをSikuliXが `find()` / `capture()`  
- これによりフルHD以上の画面を小ウィンドウに落として負荷軽減  
- いずれにせよ、**1台のPCで2画面** → **SikuliXが2nd画面のUIを解析** という流れを実装可能

---

## **3. Pi Zeroから同じPCへのマウス・キーボード入力**

- WindowsはPi Zeroを「USBマウス＆キーボードデバイス」として受け取る  
- Pi Zero側のPythonスクリプト (`hid_emulate.py`) が `mouse_move`, `click`, `type_text` などのHIDレポートを送る  
- 同じPCに対して操作が乗っ取られるため、**自動化デバッグ**ができる  
- ただし操作ミスでウィンドウを閉じたりOSをログアウトさせたりすると、同じPCが操作不能になる危険があるので注意

---

## **4. サンプル：SikuliXループ + ChatGPT Vision + Pi Zero HID (1台PC上で2モニタデバッグ)**

下記は簡易的に、「2ndモニター上の“login_button”をSikuliXが探索→Pi Zeroクリック」を行う例。**ChatGPT Vision**や音声コマンドを入れるなら前回記事のサンプルを組み合わせればOKです。

```python
# sikuli_main.py (SikuliX Pythonモード)
"""
1) 2ndモニターの画面をキャプチャ
2) "login_button.png" を見つけたら Pi Zero (USB HID) でクリック
   (同じPCにマウス/キーボード入力が送られる)
"""

from sikuli import *
import time
import sys

# Pi Zero HIDを操作する gRPCクライアント (別記事参照)
sys.path.append(r"C:\path\to\voice_autopilot\windows_side")
import grpc_client
client = grpc_client.HIDClient()

def main_loop():
    # 2ndモニターをScreen(1)と仮定
    # ループで"login_button.png"検出
    while True:
        screen_img = capture(Screen(1))  # 2ndモニタキャプチャ
        # あるいは find(Pattern("login_button.png")) on Screen(1)
        try:
            region = Screen(1).find("login_button.png")
            center_pt = region.getCenter()
            x, y = center_pt.x, center_pt.y
            print("[Info] Found login_button on 2nd monitor at:", x, y)

            # Pi Zeroにクリック指示
            resp = client.click(float(x), float(y))
            print("[Info] Pi Zero response:", resp.message)
        except FindFailed:
            print("[Debug] login_button not found yet.")

        time.sleep(3)  # 3秒おきに探索

def main():
    print("Starting loop for 2nd monitor debugging with Pi Zero HID.")
    main_loop()

if __name__ == "__main__":
    main()
```

**解説**:

- `Screen(1).find("login_button.png")` → 2ndモニターをSikuliXが直接パターンマッチ  
- 見つかったら `client.click(x, y)` で Pi Zeroが同じPCにマウス操作を送信→**自分自身のPC**がクリックを受け付ける  
- こうして**外部PC不要**で、2ndモニター画面を仮想的に“別端末画面”として扱える

---

## **5. 追加Tips**

1. **Pi Zeroで相対座標操作**  
   - 実際にはWindows OS上のマウスカーソルとの折り合い(加速設定等)があるため、相対モードのHIDレポートを送る場合はカスタマイズが必要。  
2. **キャリブレーション**  
   - 2ndモニターのスクリーン座標 (SikuliX) と Pi Zero が想定するマウス座標にズレが生じるかもしれません。**別記事**のキャリブレーション手順を参照。  
3. **OBS Studio**  
   - 2ndモニターを OBS でプレビューウィンドウに出し、**SikuliX**がそのウィンドウを解析するやり方もある  
4. **1台PCでのデバッグ**  
   - システムが実際に動くかを確かめやすい  
   - ただしPi Zeroが操作を誤ってメイン画面に干渉し、制御不能になる可能性もあるので、**要注意**  
5. **本番運用に移行**  
   - 本番では物理的に2nd PCにHDMI接続 & Pi Zeroで操作… という構成になるが、**基本ロジックを1台で開発・検証**するメリットは大きい

---

## **Q&A**

**Q1. なぜ2ndモニターを“別端末画面”として扱うの？**  

A1. 実機(別PC)を常に用意しなくても、**1台PC＋マルチモニタ**で同様のUI操作をデバッグできるためです。あたかも「別画面を操作している」かのようにSikuliX＋Pi Zeroを試せます。

  
**Q2. HDMIキャプチャデバイスは物理的にどう接続する？**  

A2. 2ndモニターへの出力をHDMIキャプチャに回す→Windowsに取り込み、という形も可能ですが、実際には**OBSのソフトキャプチャ**や**SikuliXのマルチモニタ機能**で済む場合が多いです。物理キャプチャは配線が煩雑なので、最初はソフトウェアキャプチャで十分かもしれません。

  
**Q3. Pi Zeroを同じPCにUSB接続するときのgRPCサーバ/クライアント構成は？**  

A3. （1）WindowsがサーバーになってPi Zeroがクライアントでもいいし、（2）Pi ZeroがサーバーでWindowsがクライアントでもいいです。USBはあくまで「ヒューマンインタフェースデバイス」として認識させるだけなので、通信自体は localhost か LAN/Wi-Fiを使います。「同じPCでlocalhost:50051」にアクセスする構成でも動かせます。

  
**Q4. 同じPCを操作していると誤クリックでメイン画面が閉じてしまうリスク…**  

A4. そうです。**2ndモニターで完結**するよう注意するか、単純なUI操作だけに限定し、万一操作が暴走してもCtrl+Cで止められるようにしましょう。  
（完全に独立した2nd PCで試すのが最終的には安全です。）

  
**Q5. キャリブレーションが必要ですか？**  

A5. 場合によります。SikuliXが「Screen(1)」の解像度を正しく取得し、Pi Zeroでの座標と一致すれば不要かもしれません。ただし、**一部Windows設定や拡大縮小設定**でズレが出る場合、**別記事**で紹介のキャリブレーション手順を参照してください。

---

## **まとめ**

- **1台のPC（2モニター）を使って**「2ndモニター画面」をキャプチャ（SikuliXやOBS）し、**Pi Zero 2 W (HID)** をUSB接続して「同じPCのマウス/キーボードを動かす」形で**自動化デバッグ**が可能。  
- これにより、**別PCを用意せず**とも、「まるで別端末を操作しているかのようなUI自動化」を**1台環境**で開発・検証できる。  
- 実際の本番運用（2台PC）に移行する前に、**大部分のロジックをこの方法でデバッグ**すると効率的。  
- **注意点**: 誤クリックでメインモニター操作に干渉してしまうリスクがあるため、作業時は**段階的に動作チェック**を行うのがおすすめ。

これで、**同じPC上の2ndモニターをあたかも“別端末”に見立てて** Pi Zero 2 WがUSB HIDで操作する開発・デバッグ手法が確立します。**音声コマンド**や**ChatGPT Vision**との連携など、すべて1台で組み上げ、十分にテストしてから最終的に「本番(2台PC)」に移す形をお試しください！

---

## **参考リンク**

- **SikuliX公式サイト**: [https://sikulix.com/](https://sikulix.com/)  
- **OBS Studio**: [https://obsproject.com/](https://obsproject.com/) （ソフトウェアキャプチャに便利）  
- **Raspberry Pi Zero 2 W でのHIDガジェットモード**（別記事）  
- **gRPCサーバー／クライアント実装**（別記事）  
- **キャリブレーション詳細**（別記事）  
- **ChatGPT Vision**（OpenAI公式）  
- **Google Cloud Speech-to-Text** (音声コマンド連携する場合)

---

以上