Files

120 lines
6.0 KiB
Markdown
Raw Permalink 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 交叉编译。No unit tests, no CI, no linting — tested on-device only.
## 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** (WSL): `/home/ilikara/loongson/opencv-4.13.0/loongson` (v4.13.0, 无 SIMD)
- **OpenCV 设备库**: `opencv_libs/` 目录下 `.so.413` 文件,部署到设备 `/home/root/opencv/lib/` 并更新 `.so` 符号链接
- `cross.cmake` is included **before** `cmake_minimum_required` — intentional, to set compiler before project().
- Set `CROSS_COMPILE` to `0` in `cross.cmake` for native x86 builds.
## Project structure
| Directory | Purpose |
|-----------|---------|
| `src/` | Source (.cpp + .hpp) → compiled into `common_lib` (static lib) |
| `lib/` | Public headers (.h only) + `vl53l0x/` C API sources |
| `main/` | Entry points → `smartcar_demo1` (main) + `lidar_test` (standalone test) |
| `docs/` | Design docs (ARCHITECTURE, CONE_DESIGN, ENCODER_BRAKE, LIDAR_AVOID, TRAFFIC_LIGHT) |
| `build/` | CMake build output (gitignored) |
**Executable name**: `smartcar_demo1` (CMake project name is `smartcar_demo2` — mismatch is intentional).
## Excluded modules
These source files exist in `src/` but are **excluded from build** via CMakeLists.txt `FILTER EXCLUDE`:
- `zebra_detect.cpp` — classic zebra-crossing detection (replaced by Mild model)
- `PIDController.cpp` — unused (motor is open-loop direct drive)
- `serial.cpp` — Vofa/serial image streaming, unused
Note: `vl53l0x.cpp` IS compiled (lidar ranging is active).
## 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 # init_pins + start the demo in background
sh ctl.sh stop # stop and zero PWM
```
`ctl.sh` writes default config values to text files (`./speed`, `./steer_gain`, etc.). The binary reads them at startup via `cfg_load_all()` and re-reads every 30 frames when `./debug` = 1.
**Bug**: `start.sh` references binary as `smartcar_demo` but actual executable is `smartcar_demo1` — use `ctl.sh` instead.
## Configuration system
All config is via single-value text files in the working directory. The full list of parameters and defaults is in `lib/global.h` (struct `CfgCache`). Config is loaded by `cfg_load_all()` in `src/global.cpp`.
Key groups:
- **Steering**: `speed`, `deadband`, `steer_gain`, `center_bias`, `foresee`
- **Debug**: `start` (0/1), `showImg` (0/1), `debug` (0/1), `destfps`, `saveImg`
- **Zebra**: `zebrasee`
- **Cone avoidance**: `cone_avoid_gain`, `cone_avoid_range`, `cone_speed`, `cone_min_frames`, `cone_margin`, `cone_thresh`, `cone_hold_frames`, `cone_return_gain`, `cone_return_frames`
- **Curve slowdown**: `curve_slope` (default 0.4), `curve_min` (default 0.8)
- **Encoder brake**: `brake_scale`, `brake_max`
- **Lidar avoidance**: `lidar_enable`, `lidar_thresh`, `lidar_pre`, `lidar_near`, `lidar_far`, `lidar_near_start`, `lidar_near_end`, `lidar_far_span`, `lidar_min_frames`, `lidar_avoid_gain`, `lidar_avoid_range`, `lidar_speed`, `lidar_hold_frames`
## Architecture
### Per-frame pipeline in `CameraHandler()` (`src/camera.cpp:755`)
```
CameraHandler()
├── capture_frame() // 1. MJPG 取帧 → 1/4解码 320×240 BGR
├── save_image_if_requested() // 2. 保存帧 (debug)
├── image_main() // 3. 视觉巡线 (80×60 HSV-Otsu-FloodFill)
├── lidar_avoid_process() // 4. VL53L0X 激光避障 (每2帧) + 中线变形
├── run_model_inference() // 5. Mild v12 每2帧推理 (160×120, 4类)
├── zebra_process() // 6a. 斑马线去抖 + Z_STOP/Z_COOLDOWN
├── traffic_light_process() // 6b. 红绿灯 TL_NORMAL→TL_STOP→TL_WAIT_GREEN
├── cone_detect_and_deform() // 6c. 锥桶检测 + 中线变形 + 保持衰减
├── steering_update() // 7. 舵机比例控制 (deadband过滤)
├── motor_update() // 8. 电机开环PWM + 编码器刹车 + 弯道减速
├── lcd_render() // 9. LCD RGB565渲染 (边界线+检测框+状态)
└── fps_log() // 10. 分步耗时日志
```
Also: `malloc_trim(0)` every 150 frames to return freed memory to OS (embedded optimization).
### Motor control
- **Open-loop**: `MotorController::updateduty(spd)` — direct PWM, no encoder feedback in normal driving.
- **Encoder brake**: When `zebra_block || tl_block`, reads `g_enc_speed` from encoder thread and applies reverse braking.
- **Encoder thread** (`control.cpp`): polls GPIO67 (pulse) + GPIO72 (direction), 100ms window → `g_enc_speed` (pulses/sec). 500µs sleep to prevent CPU starvation.
- **Curve slowdown**: `speed *= (1.0 - |deviation| × curve_slope)`, clamped to ≥ `curve_min`.
- **Cone/lidar speed reduction**: Code exists but is currently **commented out** in `motor_update()`.
### Model: Mild v12
- **Input**: 160×120 BGR, **Output**: 4 classes + background
- **Class indices**: 0=cone, 1=red light, 2=green light, 3=zebra
- **Per-class thresholds**: `{0.65, 0.75, 0.80, 0.82}` (cone/red/green/zebra)
- **Weight file**: `mild_v12.bin` (105KB custom binary format)
- **Inference engine**: `src/model_v10.{hpp,cpp}` (file names say v10, internally Mild v3 — historical naming)
## Style and conventions
- No copyright headers — comments use ascii-box-style block dividers
- Header guards: `#ifndef FILENAME_H_` / `#define FILENAME_H_` (some model files use `#pragma once`)
- Global state via `extern` globals (e.g., `g_cfg`, `g_steer_deviation`, `g_boxes`)
- `lib/` has `.h` headers; `src/` has `.cpp` implementations + `.hpp` model headers
- No unit tests, no CI, no linting — do not add comments to code unless asked