産業用ロボット統合制御システム 構築レポート

Claude Desktop → Claude Code Opus 4.7 (1M context) を用いたゼロからのシステム構築記録 / 2026年4月26日 16:00〜22:30
使用AI
Claude Desktop
→ Claude Code
Opus 4.7
総作業時間
4h 30m
コンテキスト消費
〜25%
接続ハードウェア数
5台

1. 構築したシステムの概要

産業用6軸ロボット(DENSO)を中心に、電動ハンド・産業用カメラ・Webカメラ・ゲームパッドを統合し、 Webブラウザから遠隔操作できるリアルタイム制御システムをゼロから構築した。 バックエンドはPython/Flask、フロントエンドはサイバーパンク風カスタムUI。

🦾
DENSO 6軸ロボット
b-CAP TCP (192.168.127.13:5007)
スレーブモード + robot_move 制御
IAI 電動ハンド
Modbus RTU (38400bps, RS-485)
/dev/cu.usbserial-0001
📷
Basler GigE カメラ
a2A3840-13gcBAS (4K)
pypylon / 192.168.127.100
🎥
USB Webカメラ
OpenCV / AVFoundation
MJPEG ~30fps ストリーミング
🎮
PS5 DualSense
pygame HID (Bluetooth/USB)
macOS 17buttons / 6axes
🌐
Flask Web アプリ
Python 3.12 / ポート8080
サイバーパンク UI + REST API

最終アーキテクチャ

Browser (192.168.1.76:8080)
    │ REST API / MJPEG stream
    ▼
Flask App (app.py)
    ├── DensoRobot ─── b-CAP TCP ──▶ DENSO RC8 コントローラー
    │     ├── Normal mode: robot_move() (PCボタン操作)
    │     └── Slave mode:  slvMove 125Hz (Gamepad)
    │           └── Velocity Buffer (gamepadスレッド分離)
    ├── IAIHand ────── Modbus RTU ─▶ IAI 電動シリンダー
    │     └── Hand Control Thread (Modbusブロッキング分離)
    ├── BaslerCamera ─ pypylon GigE ▶ Basler 4K カメラ
    ├── USBCamera ──── OpenCV ──────▶ USB Webカメラ
    └── GamepadDriver ─ pygame HID ─▶ PS5 DualSense
          └── 125Hz ポーリング → Velocity Buffer 書き込み

2. 作業タイムライン(主要フェーズ)

前半フェーズ(16:00〜)は Claude Desktop で実施。 要件定義書の読み込み・初期コード生成・Basler カメラ IP 設定などを完了後、 Claude Code CLI (Opus 4.7) へ引き継ぎ。

Phase 0-1 — Claude Desktop / 16:00〜
要件定義書の読み込みと全ファイルの自動生成
PDF 要件定義書を読み込み、システム全体の構成を把握。 app.py / config.py / requirements.txt / hardware/*.py / templates/index.html 計 9 ファイルをゼロから一括生成。初期の Flask バックエンドと ダークテーマ Web UI のベースを完成させた。
Phase 0-2 — Claude Desktop
ネットワーク通信確認(DENSO / Basler)
DENSO ロボットコントローラー (192.168.127.13) への PING / b-CAP UDP(5007) 疎通確認 → OK
Basler カメラは config の IP (192.168.1.100) に疎通できず。 GigE Vision の GVCP Discovery ブロードキャストを複数サブネットへ送信し、 実際のカメラ IP が 192.168.3.3 であることを発見
Phase 0-3 — Claude Desktop(難関)
Basler カメラ IP アドレス変更(GVCP プロトコル直接操作)
pypylon の通常手順では IP 変更不可。GigE Vision 仕様書に基づき GVCP レジスタ を Python ソケットで直接操作:
① 192.168.3.3 に一時 IP エイリアス追加(sudo / AppleScript)
② CCP レジスタで排他制御権取得
③ PersistentIP (0x064C)・SubnetMask (0x065C)・GW (0x066C) へ 192.168.127.100 を書き込み
④ IPConfig を PersistentIP モード (bit2=1) に変更
⑤ ForceIP コマンドをユニキャスト送信で即時適用
⑥ pypylon で 3840×2160px (4K) フレーム取得成功を確認

ただし ForceIP は揮発性のため、電源再投入後に永続 IP が反映されることを確認して引き継ぎ。 カメラの config アドレスを 192.168.127.100 に更新済み。
▶ Claude Code CLI (Opus 4.7) へ引き継ぎ
— 以下は Claude Code での作業 —
Phase 1 — 初期確認
既存コードの動作確認・プロセス衝突の解決
app.py の初回起動確認。Basler カメラが「他のアプリが使用中」エラー。 lsof で前回の残留プロセス(PID 87376)を特定・kill して解決。
Phase 2 — Gamepad 初期化
PS5 DualSense の検出とボタンマッピング
起動前にコントローラーが未接続 → 検出失敗。再起動で解決。
macOS 固有の HID ボタンインデックスが想定と相違。 デバッグログで全ボタン押下を記録し実測でマッピングを確定: L1=10, R1=9, PS=7(一般的な文書と異なる)
Phase 3 — IAI ハンド制御(難関①)
Modbus 通信と状態不整合の解決
原点復帰後にハンドが開かない問題。原因:原点復帰完了時点の物理位置(全開)と ソフトウェア状態(_hand_open=True)が一致していたが、 初回 toggle で「閉じる」コマンドが来ていた。
原点復帰後に明示的に open_pos(3900) を書き込み、物理・ソフト状態を同期。
Phase 4 — b-CAP スレーブモード(最大の難関)
DENSO ロボット通信の根本的な問題解決
以下の問題が連続発生し、最も多くの時間を費やしたフェーズ。
Phase 5 — ハイブリッドモード設計
PCモード(robot_move) × Gamepadモード(slvMove) の分離
ユーザーの指摘「根本的に間違っている」を受け、参照コードを分析。 離散ステップ操作には robot_move()、連続追従にはスレーブモードと使い分ける ハイブリッド設計を採用し、モード切替APIを実装。
Phase 6 — 制御品質の改善
ガタつき解消:デルタバッファ → 速度バッファへの転換
ゲームパッドで動かすとロボットがガタガタする問題。 原因:積み上げ型デルタバッファの周期ずれによる二重加算。 上書き型速度バッファに変更し、毎サイクル一定ステップが適用されるよう修正。
Phase 7 — UI 構築
サイバーパンク風インターフェースの構築
カメラ2画面・座標値大表示・タブ切替・方向ボタン・グラデーション・効果音を実装。

3. 行き詰まった問題と解決策の詳細

問題 エラーコード / 現象 難易度 根本原因 解決策
【前半】
Basler カメラの IP 未設定・発見不可
PING 不達
GigE Discovery 無応答
カメラ出荷時 IP 未設定のためリンクローカル (169.254.x.x) で起動。 pypylon では変更 API なし GVCP プロトコルで PersistentIP レジスタ (0x064C) を直接書き込み。 ForceIP コマンドで 192.168.127.100 に即時適用。 電源再投入で永続化
Basler カメラが起動しない (引き継ぎ後) 0xE1018006
Controlled by another app
前回セッションの残留プロセスが GigE バスを占有 lsof / kill で残留プロセスを強制終了
slvMove API 呼び出しエラー AttributeError:
int has no attribute slvMove
self._h_robot は int ハンドル。
直接メソッド呼び出し不可
bcap_client.robot_execute(handle, "slvMove", pos) に修正
初期位置[0,0,0]への急動作 ロボットが起動直後に
原点へ急移動(危険)
target_pos のデフォルト値が [0,0,0,0,0,0]
初期化時に CurPos を取得していなかった
connect() で Motor ON 直後に CurPos を取得し
target_pos の初期値として設定
スレーブモード速度違反
(スティック即クラッシュ)
0x83500121
0x84201482
最高 デフォルト座標系(Tool0)で rx≈180, ry≈0 → 手首特異点近傍
微小な TCP 移動でも関節速度が爆発
robot_change(HRobot, "Tool1") をTakeArm直後に追加。
Tool1 では ry≈−0.15, rz≈90° で特異点回避
gamepad ガタガタ問題 ロボットが断続的にガタつく
(可聴レベルの振動)
デルタバッファ(積み上げ方式)はgampad/slaveの
周期ずれで二重加算・ゼロ加算が交互発生
速度バッファ(上書き方式)に変更。
gamepad は "今この速度" を毎フレーム書くだけ
IAI ハンドの応答遅延 ボタンを離してから
ハンドが止まるまでに遅延
Modbus RTU write (~15ms) がgamepadスレッドを
ブロックし、ボタン離し検出が遅延
hand-ctrl 専用スレッドを分離。
gamepad は velocity 変数を書くだけ。即停止
L1/R1 ボタンが無反応 RX 軸が全く動かない macOS DualSense の実際のマッピングが文書と相違。
デバッグログで確認: L1=10, R1=9
全ボタン押下ログを仕込み実測でインデックス特定。
BTN_L1=10, BTN_R1=9 に修正

4. Claude Code を用いた産業機器システム構築の考察

✅ Claude Code が特に有効だった場面

⚠️ 行き詰まりやすかった点・改善余地

💡 産業機器 × AI アシスタントの効果的な活用法

参照コードを必ず共有する
動作実績のあるコード(今回の robot_control.py, robot_move_main.py)を提示することで、 AIは暗黙の仕様・座標系・API作法を学習し、正確な実装に大幅に近づける。 「うまくいかない」だけの説明より、「このコードでは動く」を見せる方が 10倍速い。
エラーコードをそのまま渡す
0x83500121 のような16進数エラーコードを省略せず渡すことで、 AI は製造メーカーのエラー体系を解析し、仮説を絞り込める。 「エラーが出る」より「0x83500121 が出る」の方が根本原因に辿り着くのが早い。
段階的な動作確認をAIに指示する
「全部動かして」ではなく「まずロボットだけ、次にカメラ、最後に統合」のように 段階分割することで、AI も問題の切り分けと解決が容易になる。 今回も、動作確認コマンドを逐次実行する形で品質を確保した。

📊 作業効率の定量的評価

4.5h
総作業時間
16:00〜22:30
5台
統合ハードウェア数
7個
解決した主要バグ
〜600
生成コード行数 (Python)
25%
コンテキスト消費
(1M tokens中)

熟練エンジニアが同等のシステムを単独で構築する場合、 仕様書解読・ドライバ実装・デバッグを含めると 2〜4週間 を要すると想定される。 Claude Code との協業により 4時間30分(16:00〜22:30) での完成を実現。 ただし、実機フィードバックと参照コードの提供が解決の鍵であり、 「AIが知識を持ち、人間が現場情報を提供する」協業モデルが最も効率的だった。

5. 主要な技術的成果

速度バッファによるガタつき解消(最も重要な発見)

積み上げ型デルタバッファはgamepadとslaveのサイクルずれで二重加算が起きる。 上書き型速度バッファに変えることで、どちらが速くても「今この速度」が常に正確に伝わる。

# NG: 積み上げ → 周期ずれで二重加算・ゼロ加算
delta_buf[i] += delta[i]   # gamepadが書く
pos[i] += delta_buf[i]     # slaveが消費

# OK: 上書き → 常に最新の速度コマンドが適用
velocity[i] = delta[i]     # gamepadが書く (+=ではない)
pos[i] += velocity[i]      # slaveが毎サイクル読む

Tool1 座標系選択による特異点回避

DENSO RC8 でスレーブモードを使う際、robot_change(HRobot, "Tool1") を TakeArm の直後に呼ばないと、デフォルト座標系(Tool0)で rx≈180°, ry≈0° の 手首特異点近傍に配置される。この状態では微小な TCP 移動で関節速度が発散し、 スレーブモードが即座にエラー終了する。

# この一行を入れないとスレーブモードが即クラッシュ
m_bcapclient.robot_change(HRobot, "Tool1")   # ← 必須
cur_pos = m_bcapclient.robot_execute(HRobot, "CurPos")
# slvChangeMode(0x201) へ続く

Modbus / b-CAP のスレッド分離

Python の GIL 環境で複数の通信プロトコルが競合するとタイミングが不安定になる。 各ハードウェアを専用スレッドに隔離し、共有変数(速度バッファ)のみで通信する設計が 最もガタつきが少なく、応答性も高かった。

6. 結論

本プロジェクトは Claude Code Opus 4.7 が産業用システム構築において 実用的な開発パートナーとなれることを示した。 b-CAP・Modbus RTU・GigE Vision など専門性の高いプロトコルを短時間で実装し、 リアルタイム制御の設計問題(特異点・周期ずれ・スレッド競合)を技術的に解決した。

最大の教訓は、「AIと人間の役割分担の明確化」だ。 AI はプロトコル実装・コード生成・エラー分析・設計提案を高速に行う。 人間は実機の現場フィードバック・参照コードの提供・最終判断を担う。 この協業モデルにより、従来の開発期間を大幅に短縮できることが実証された。

一方で、ハードウェア固有の暗黙仕様(座標系・ボタンマッピング・通信タイミング)は 実機テストなしには解決できない壁であり、AI はあくまで「現場情報を持つ専門家と協働する 高速なコーディングパートナー」として機能することが本質だと理解された。