95 lines
3.8 KiB
Markdown
95 lines
3.8 KiB
Markdown
# AGENTS.md — SmartCar Demo
|
||
|
||
## Project overview
|
||
|
||
LoongArch64 embedded autonomous smart car using OpenCV + NanoDet V10 model.
|
||
Runs on-device (Loongson board) with cross-compilation from x86 Linux.
|
||
|
||
## Build
|
||
|
||
```sh
|
||
# On the build host (x86 Linux):
|
||
mkdir build && cd build
|
||
cmake ..
|
||
make
|
||
```
|
||
|
||
- **Cross-compilation target**: LoongArch64 (`-march=loongarch64`)
|
||
- **Toolchain**: `/opt/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6`
|
||
- **C++ standard**: 17
|
||
- **OpenCV path** (device-side): `/mnt/d/PPPProgram/smartcar/opencv_device/`
|
||
- `cross.cmake` is included **before** `cmake_minimum_required` — this is intentional.
|
||
|
||
## 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` (the CMake project name `smartcar_demo2` is different — don't assume they match).
|
||
|
||
## 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 NanoDet model
|
||
- `encoder.cpp` — referenced in exclusion list but file does **not** exist in repo
|
||
|
||
## Device-side operation
|
||
|
||
The onboard binary is controlled via text files in the working directory — no CLI args.
|
||
|
||
```sh
|
||
# On device:
|
||
sh ctl.sh init # initialize GPIO/PWM pins
|
||
sh ctl.sh start # start the demo
|
||
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. `start.sh` uses `LD_PRELOAD=./gpio_fix_final.so` (GPIO workaround).
|
||
|
||
## Configuration system
|
||
|
||
All config is via single-value text files in the working directory:
|
||
|
||
- `./speed` (double) — target speed
|
||
- `./start` (0/1) — motor enable switch
|
||
- `./debug` (0/1) — when 1, reloads all config files every 7 frames
|
||
- `./showImg` (0/1) — LCD display toggle
|
||
- `./deadband`, `./steer_gain`, `./center_bias` — steering tuning
|
||
- `./foresee` — look-ahead row for steering
|
||
- `./zebrasee` — zebra crossing near-threshold
|
||
- `./destfps` — target framerate
|
||
- `./kp`, `./ki`, `./kd` — PID gains (currently **not used**; motor is open-loop)
|
||
- `./mortor_kp`, `./mortor_ki`, `./mortor_kd` — motor encoder PID (spelling `mortor` is intentional)
|
||
|
||
## Architecture
|
||
|
||
9-step per-frame pipeline in `CameraHandler()` (`src/camera.cpp`):
|
||
1. Capture frame (640×480 MJPEG → BGR)
|
||
2. Optionally save image
|
||
3. Vision line tracking (80×60 downscale → HSV+Otsu → floodFill → mid_line[60])
|
||
4. Model inference every 2nd frame (NanoDet V10, 4 classes: cone/red/green/zebra)
|
||
5. Zebra crossing state machine (NORMAL→STOP(4s)→COOLDOWN(5s))
|
||
6. Steering servo control (PWM, deadband-filtered)
|
||
7. Motor control (open-loop duty cycle, curve-based slowdown in turns)
|
||
8. LCD rendering (`/dev/fb0` mmap)
|
||
9. FPS logging
|
||
|
||
**Key detail**: Motor control is **open-loop** — `MotorController::updateSpeed()` and encoder PID exist in code but are never called from the main loop. Only `updateduty()` (direct PWM) is used.
|
||
|
||
Currently **cones (cls=0), red lights (cls=1), and green lights (cls=2)** are detected by the model but ignored in decision logic.
|
||
|
||
## Style and conventions
|
||
|
||
- C++ files have **no copyright headers** and **minimal comments** — comments are ascii-box-style block comments when present
|
||
- Header guards use the form `#ifndef FILENAME_H_` / `#define FILENAME_H_`
|
||
- 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
|