Files
Loongson_2k0300_SmartCar/docs/ENCODER_BRAKE.md
T

3.4 KiB
Raw Blame History

编码器刹车 — 设计与实现

1. 硬件

编码器2,引脚:

信号 引脚 模式
LSB 脉冲 GPIO 67 输入
DIR 方向 GPIO 72 输入

两引脚均属 gpiochip64GPA64base=6416 pins)。

2. 触发条件

ControlUpdate(speed, zebra_block)zebra_block == true 时进入刹车流程。zebra_blockCameraHandler Step 5 斑马线状态机传入——当 g_zstate == Z_STOP 时为 true。

3. 刹车状态机

                 ┌──────────┐
   正常行驶 ───→ │ IDLE     │
                 └────┬─────┘
                      │ zebra_block==true
                      ▼
                 ┌──────────┐
                 │ BRAKING  │ ← 施加 -30% 占空比
                 │          │    每帧读 GPIO 67
                 └────┬─────┘
          ┌───────────┴───────────┐
          │ 脉冲变化               │ 脉冲不变
          ▼                       ▼
   轮子在转 → 继续刹车        g_brake_still++
   重置计数器                        │
                            连续 5 帧无变化?
                            或超时 60 帧?
                                    │
                                    ▼
                              ┌──────────┐
                              │ HOLDING  │ ← duty=0,保持静止
                              └──────────┘
                                    │
                            zebra_block==false
                                    │
                                    ▼
                              ┌──────────┐
                              │ IDLE     │
                              └──────────┘

4. 参数

定义在 src/control.cpp

常量 含义
BRAKE_STILL_THRESH 5 连续无脉冲帧数阈值,超过即判停
BRAKE_TIMEOUT 60 最长刹车帧数(~2s @30fps),强制释放
BRAKE_DUTY -30 刹车占空比(-100~100,负值=反转)

5. 读取方式

GPIO 67 通过 sysfs 文件描述符轮询(GPIO::readValue()),每帧 lseek + read 一次。不依赖中断。

为什么轮询够用: 30fps 帧率 = 33ms 间隔。编码器假设 100+ 脉冲/转,即使 1 转/秒的极慢速度也有 3+ 脉冲/帧间隔,不会漏判。

6. 刹车强度

motor[i]->updateduty(-30)

MotorController::updateduty() 内:

  • 占空比:period * |duty| / 100 = 50000 * 30 / 100 = 15000 ns
  • 方向:duty < 0directionGPIO.setValue(false) → 反转

即 30% 占空比的反向驱动,足够刹停但不会让车向后猛冲。

7. 编码器生效范围

  • 仅在斑马线 STOP 时使用编码器
  • 正常行驶时编码器处于"打开但未使用"状态(fd 保持 open,但不 read
  • 锥桶避障不使用编码器
  • g_cfg.start == 0 时刹车状态机重置

8. 关键代码路径

main.cpp
  └── while(running)
        └── CameraHandler()
              └── ControlUpdate(target_speed, g_zstate == Z_STOP)
                    └── if (zebra_block) → 刹车状态机
                              └── encoderLSB.readValue()  ← GPIO 67