2026年5月頃、Claude.ai(チャット)を使って趣味で作ったツールの開発記録です。AIが出力したコードを手元にコピーして実行する形で進めました。
はじめに
UDSでDIDを1つ読み出すだけでも手間がかかるので、手軽に使えるツールを自分で作ることにしました。
自分はPythonをほとんど書いたことがありません。そこでClaude.aiを使って開発しました。
本シリーズでは、AIを使いながら設計とテストをどう進めたか、どこでつまずいたかを書きます。
| 回 | 内容 |
|---|---|
| #1(本記事) | 作った理由・使った技術 |
| #2 | 最初のプロンプトとレイヤー設計 |
| #3 | テストとECUシミュレータ |
| #4 | 振り返り |
何が不便だったのか
確認したいDIDが変わるたびに、次の作業が発生していました。
確認したいDIDが変わる
↓
Cコードを書き直す
↓
ビルドする
↓
実行する
↓
また変わる → 最初に戻る
「ちょっと確認したい」用途には手間がかかりすぎます。
また、UDSはEthernet(DoIP)だけでなくCAN上でも使われます。そこで、次の2点を満たすツールを目標にしました。
- コマンド1つでDIDを読み出せる
- 通信方式(DoIP / CAN)を差し替えられる
UDS・DoIP・UDS on CANとは
UDS(診断サービス:ISO 14229)
├── DoIP(Ethernetで運ぶ:ISO 13400)
│ └── TCP/IP
└── UDS on CAN(CANで運ぶ)
└── ISO-TP(ISO 15765-2)← CANの8バイト制約を吸収
└── CAN
DoIP はECUとTCP接続し、DoIPフレームにUDSのデータを載せて送受信します。接続時にルーティングアクティベーションというハンドシェイクが必要です。
UDS on CAN はCAN上でUDSを送受信する方式です。CANフレームは最大8バイトなので、長いメッセージはISO-TPで分割・結合します。
補足:J1939はトラック・建設機械向けのCAN上位プロトコルで、独自のトランスポートプロトコルを持ちます。J1939のバス上でUDSを使う場合も、UDSの転送にはISO-TPを使います。
今回実装したのはDoIPのみです。UDS on CANは、後から差し替えられる設計にとどめました。
実装済み:ECU ──Ethernet──→ DoIP ──→ UDS
設計のみ:ECU ──CAN──→ ISO-TP ──→ UDS
なぜPythonとClaude.aiか
| 選択 | 理由 |
|---|---|
| Python | 学習したかった。UDS/DoIPのライブラリがある。テスト自動化を学べる |
| Claude.ai | 使い慣れていた。長い会話の中で設計を相談できる |
「AIに頼めばPythonを知らなくても作れるのでは」と考えていましたが、そう単純ではありませんでした。詳しくは#4で書きます。
使ったライブラリ・ツール
| 種別 | 名前 | 用途 |
|---|---|---|
| 言語 | Python 3.12 | 開発言語 |
| テスト | pytest | 単体・結合テスト |
| UDS | udsoncan | フレーム生成・解析 |
| DoIP | doipclient | DoIP通信・TCP管理 |
| データモデル | pydantic | 型付きのデータクラス |
| ログ | structlog | JSON形式のログ出力 |
| CLI | click | コマンドライン引数 |
| GUI | PySide6 | デスクトップGUI |
| AI | Claude.ai | 設計・実装の支援 |
| VCS | GitHub | リポジトリ管理 |
作ったもの
DoIP経由でUDSサービスを実行するツールです。CLIとGUIの両方から使えます。
[GUI (PySide6)] [CLI (click)]
│ │
└────────┬────────┘
│
[DiagnosticService] ← GUI/CLI共通のロジック
│
[UDSサービス群] ← 0x22, 0x10 などのリクエスト生成・応答解析
│
[ProtocolBase] ← ここを差し替えると通信方式が変わる
┌────┴────┐
[DoIPProtocol] [UDSonCANProtocol](未実装)
│
Ethernet → ECU
CLIの実行例です。
# DIDを読み出す
$ python main.py --ip 192.168.0.10 rdbi F190
[OK] DID=0xF190 Data=53 49 4D 56 49 4E 30 30 30 30 30 30 30 30 30 30 31
# NRC応答の場合
$ python main.py --ip 192.168.0.10 rdbi 9999
[NRC] DID=0x9999 NRC=0x31 (Request Out Of Range)
# セッション切り替え
$ python main.py --ip 192.168.0.10 session 03
[OK] Session=0x03
# DTC読み出し
$ python main.py --ip 192.168.0.10 read-dtc --subfn 02
[OK] ReadDTC subfn=0x02 件数=2
DTC=0x012345 status=0x08
対応しているUDSサービスは次のとおりです。
| SID | サービス |
|---|---|
| 0x10 | DiagnosticSessionControl |
| 0x11 | ECUReset |
| 0x14 | ClearDiagnosticInformation |
| 0x19 | ReadDTCInformation |
| 0x22 | ReadDataByIdentifier |
| 0x2E | WriteDataByIdentifier |
| 0x31 | RoutineControl |
| 0x3E | TesterPresent |
次回
#2では、最初にAIへ渡したプロンプトと、レイヤー設計について書きます。