Alexander Poletaev 2ec05d2e9d Add UDS protocol support (ISO 14229) for ECU emulator
Implement UDS Service 0x22 (Read Data By Identifier) with support for:
- Engine ECU (0x7E0): boost pressure, fuel rail pressure, lambda, torque,
  wastegate position, ignition timing, knock correction per cylinder
- DSG Transmission (0x7E1): current gear, selector position, oil temp
- Instrument Cluster (0x714): RPM, ambient light sensor

Also adds ECU_EMULATOR_SPEC.md with full protocol documentation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 16:28:55 +03:00
2026-01-29 17:16:42 +03:00
2026-01-29 17:17:14 +03:00

OBD2 Emulator

Эмулятор ECU для тестирования бортовых компьютеров через CAN-шину. Поддерживает стандарт SAE J1979 (OBD-II PIDs) поверх ISO 15765-4 (CAN).

Возможности

  • Динамическая симуляция — реалистичное поведение автомобиля
  • Множество PIDs — поддержка основных OBD2 параметров
  • Сценарии движения — холостой ход, город, трасса, прогрев
  • Автонастройка CAN — автоматическое поднятие физических и виртуальных интерфейсов

Поддерживаемые PIDs (Mode 01)

PID Название Единицы
04 Engine Load %
05 Coolant Temperature °C
0C Engine RPM rpm
0D Vehicle Speed km/h
0F Intake Air Temperature °C
10 MAF Air Flow Rate g/s
11 Throttle Position %
1F Run Time s
2F Fuel Tank Level %
46 Ambient Temperature °C
5C Oil Temperature °C
5E Fuel Rate L/h
... и другие

Установка

# Клонирование
cd obd2_emulator

# Виртуальное окружение
python3 -m venv venv
source venv/bin/activate  # Linux

# Зависимости
pip install -r requirements.txt

Использование

Базовый запуск (виртуальный CAN)

# Запуск с vcan0 (автоматически создаётся)
python src/main.py --interface vcan0 --scenario city

Физический CAN интерфейс

# Использование can1 (например, второй канал 2CH CAN HAT)
python src/main.py --interface can1 --bitrate 500000 --scenario highway

Параметры командной строки

-i, --interface     CAN интерфейс (can0, can1, vcan0) [default: vcan0]
-b, --bitrate       Скорость CAN в bps [default: 500000]
-s, --scenario      Сценарий (idle, warmup, city, highway, acceleration)
--status-interval   Интервал обновления статуса [default: 1.0]
--no-status         Отключить вывод статуса
--debug             Включить отладочный вывод

Сценарии

Сценарий Описание
idle Холостой ход, машина стоит
warmup Прогрев холодного двигателя
city Городской цикл (разгон/торможение, 0-50 км/ч)
highway Трасса (круиз 110-120 км/ч)
acceleration Тест ускорения (полный газ)
dynamic_city Продвинутый городской цикл
manual Ручное управление

Архитектура

┌─────────────────────────────────────────────────────────────┐
│                      OBD2 Emulator                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    │
│   │    CAN      │◄──►│   OBD2      │◄──►│  Vehicle    │    │
│   │  Interface  │    │  Protocol   │    │  Simulator  │    │
│   └─────────────┘    └─────────────┘    └─────────────┘    │
│         │                                      ▲           │
│         │                                      │           │
│         ▼                              ┌───────┴───────┐   │
│   ┌─────────────┐                      │   Scenario    │   │
│   │  can0/can1  │                      │   Manager     │   │
│   │   vcan0     │                      └───────────────┘   │
│   └─────────────┘                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Тестирование с бортовым компьютером

Настройка на Raspberry Pi 5 с 2CH CAN HAT

# Терминал 1: Запуск эмулятора на can1
python src/main.py -i can1 -s city

# Терминал 2: Запуск бортового компьютера на can0
# (ваш проект can_sniffer или OBD2 клиент)

Тест с виртуальным CAN

# Терминал 1: Эмулятор
python src/main.py -i vcan0 -s highway

# Терминал 2: Тестовый запрос RPM
cansend vcan0 7DF#0201 0C 00 00 00 00 00 00

# Терминал 3: Мониторинг ответов
candump vcan0 | grep 7E8

OBD2 протокол

Формат запроса (CAN ID: 0x7DF)

Byte 0: Length (количество значащих байт)
Byte 1: Mode (01 = текущие данные)
Byte 2: PID
Bytes 3-7: Padding (0x00)

Пример запроса RPM: 7DF#02 01 0C 00 00 00 00 00

Формат ответа (CAN ID: 0x7E8)

Byte 0: Length
Byte 1: Mode + 0x40 (41 для Mode 01)
Byte 2: PID
Bytes 3+: Data

Пример ответа RPM 3000: 7E8#04 41 0C 2E E0 00 00 00
  RPM = (0x2E * 256 + 0xE0) / 4 = 3000

Лицензия

MIT

Description
No description provided
Readme 86 KiB
Languages
Python 97.9%
Shell 2.1%