Files
Loongson_2k0300_SmartCar/AGENTS.md
T

152 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.md — SmartCar Demo
## Project overview
龙芯 2K0300 嵌入式自动驾驶智能车,OpenCV + Mild v12 魔改 YOLO 模型。
板端运行,x86 Linux 交叉编译。
## Build
```sh
# On the build host (x86 Linux/WSL):
mkdir build && cd build
cmake ..
make -j$(nproc)
```
- **Cross-compilation target**: LoongArch64 (`-march=loongarch64 -mtune=loongarch64`)
- **Toolchain**: `/opt/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6`
- **C++ standard**: 17
- **OpenCV path** (device-side): `D:\PPPProgram\smartcar\opencv_device\` (mounted as `/mnt/d/...` in WSL)
- `cross.cmake` is included **before** `cmake_minimum_required` — intentional, to set compiler before project().
## Project structure
| Directory | Purpose |
|-----------|---------|
| `src/` | Source → compiled into `common_lib` (static lib) |
| `lib/` | Public headers only (no .cpp) |
| `main/` | Entry point → executable `smartcar_demo1` |
| `docs/` | Architecture docs (`ARCHITECTURE.md` is the design reference) |
| `build/` | CMake build output (gitignored) |
**Executable name**: `smartcar_demo1` (CMake project name `smartcar_demo2` ≠ executable name).
## Excluded modules
These source files exist but are **excluded from build**:
- `vl53l0x.cpp` — laser ranging module, hardware not connected
- `zebra_detect.cpp` — classic zebra-crossing detection (replaced by Mild model)
## Device-side operation
Controlled via `ctl.sh` (writes to text files, no CLI args):
```sh
# On device:
sh ctl.sh init # initialize GPIO/PWM pins + write default config files
sh ctl.sh start # start the demo in background
sh ctl.sh stop # stop and zero PWM
```
`ctl.sh` sets default config values by writing to files like `./speed`, `./kp`, `./steer_gain`, etc. The running binary reads these files at startup and optionally re-reads them every 7 frames (when `./debug` = 1).
`start.sh` is an alternative launcher using `LD_PRELOAD=./gpio_fix_final.so` for the GPIO 74 workaround.
## Configuration system
All config is via single-value text files in the working directory:
### Steering
- `./speed` (double) — target speed (duty cycle %)
- `./deadband` — steering deadband (pixels)
- `./steer_gain` — steering gain multiplier
- `./center_bias` — midline offset correction
- `./foresee` — look-ahead row for steering
### Debug / Display
- `./start` (0/1) — motor enable switch
- `./showImg` (0/1) — LCD display toggle
- `./debug` (0/1) — when 1, reloads all config files every 7 frames
- `./destfps` — target framerate
- `./saveImg` — when written as 1 (in debug mode), saves current frame
### Zebra crossing
- `./zebrasee` — zebra crossing near-threshold (cy > this = near)
### Cone avoidance
- `./cone_avoid_gain` — midline deformation push amount (normalized)
- `./cone_avoid_range` — deformation ramp steepness
- `./cone_speed` — speed multiplier when cone triggered
- `./cone_min_frames` — consecutive confirmation frames
- `./cone_margin` — 0=center point, 1=box edge
- `./cone_thresh` — confidence threshold
- `./cone_hold_frames` — hold deformation frames after cone disappears
### Encoder brake
- `./brake_scale` — speed (pps) → brake duty cycle (ns) scaling factor
- `./brake_max` — maximum brake duty cycle (ns)
### PID gains (reserved, motor is open-loop)
- `./kp`, `./ki`, `./kd` — steering PID (currently not used)
- `./mortor_kp`, `./mortor_ki`, `./mortor_kd` — motor encoder PID (note: spelling `mortor` is intentional)
## Architecture
### Per-frame pipeline in `CameraHandler()` ([`src/camera.cpp`](file:///D:\PPPProgram\smartcar\smartcar2\src\camera.cpp))
CameraHandler 现已拆分为多个函数,主函数 ~40 行仅做编排:
```cpp
CameraHandler()
├── capture_frame() // 1. MJPG 取帧 → 1/4解码 320×240 BGR
├── save_image_if_requested() // 2. 保存帧 (debug)
├── image_main() // 3. 视觉巡线 (80×60 HSV-Otsu-FloodFill)
├── run_model_inference() // 4. Mild v12 每2帧推理 (160×120, 4类)
├── zebra_process() // 5a. 斑马线去抖 + Z_STOP(4s)/Z_COOLDOWN(5s)
├── traffic_light_process() // 5b. 红绿灯 TL_NORMAL→TL_STOP→TL_WAIT_GREEN
├── cone_detect_and_deform() // 5c. 锥桶检测 + 中线变形 + 保持衰减
├── steering_update() // 6. 舵机比例控制 (deadband过滤)
├── motor_update() // 7. 电机开环PWM + 编码器刹车 + 弯道减速
├── lcd_render() // 8. LCD RGB565渲染 (边界线+检测框+状态)
└── fps_log() // 9. 每15帧打印分步耗时
```
### Motor control details
- **Open-loop**: `MotorController::updateduty(spd)` — direct PWM duty cycle, no encoder feedback in normal driving.
- **Encoder brake**: When `zebra_block=true` (red light or zebra stop), reads `g_enc_speed` from the encoder thread and applies reverse braking proportional to current speed.
- **Encoder thread** ([`control.cpp:32`](file:///D:\PPPProgram\smartcar\smartcar2\src\control.cpp#L32)): polls GPIO67 (LSB pulse) + GPIO72 (direction) at ~2kHz, 100ms window speed calculation → `g_enc_speed` (pulses/sec). Now includes 500µs sleep to prevent CPU starvation.
- **Curve slowdown**: `speed *= (1.0 - |deviation| × 0.4)`, clamped to ≥ 60%.
### Model: Mild v12
- **Architecture**: 3→9→9→13→13→19→19→19→44→44→64→64 → head(64→64,dw) → out(64→9)
- **Input**: 160×120 BGR
- **Output**: 4 classes (cone / red light / green light / zebra) + background
- **Classes used in decision logic**:
- cls=0 (cone) → midline deformation avoidance
- cls=1 (red light) → traffic light state machine stop
- cls=2 (green light) → traffic light state machine resume
- cls=3 (zebra) → zebra crossing state machine stop
- **Per-class thresholds**: `{0.90, 0.75, 0.80, 0.90}` (cone/red/green/zebra)
- **Weight file**: `mild_v12.bin` (105KB custom binary format)
- **Inference engine**: `src/model_v10.{hpp,cpp}` (names kept as `model_v10_*` for compatibility, internally Mild v3)
### Vision pipeline details
- Processing resolution: 80×60 (optimal balance for 2K0300 CPU)
- HSV dual-channel Otsu: H channel (blue hue) + S channel (saturation) → bitwise AND → track region
- FloodFill: seed at bottom center (40, 50), 8-connected, extracts connected track
- Per-row longest-run search on floodFill result → left/right boundaries
- Missing-line recovery: propagate downward midline + virtual boundaries
## Style and conventions
- C++ files have **no copyright headers** — comments are ascii-box-style block comments when present
- Header guards use `#ifndef FILENAME_H_` / `#define FILENAME_H_` format (with some exceptions: `#pragma once` in model files)
- Global state uses `extern` globals (e.g., `g_cfg`, `g_steer_deviation`, `g_boxes`)
- `lib/` contains .h files only; `src/` contains .cpp files only
- No unit tests, no CI, no linting — this is embedded code tested on-device