去年夏天,我在自家后院用树莓派和玩具车搭建的自动驾驶系统成功绕过了所有障碍物。这套成本不到800元的系统,核心是运行在树莓派4B上的TensorFlow Lite模型。与工业级方案不同,这种轻量级实现特别适合教育场景和创客开发,能直观展示自动驾驶的核心技术链条。
这个项目完整覆盖了从环境搭建、数据采集、模型训练到边缘部署的全流程。不同于云端方案,我们要解决的关键挑战包括:如何在仅有1GB内存的设备上运行神经网络、怎样用单目摄像头实现距离感知、以及应对实时性要求下的帧率优化。通过量化技术和模型裁剪,最终将MobileNetV2压缩到仅3.2MB,在树莓派上达到8FPS的推理速度。
我的测试平台采用以下配置,所有部件均来自常见电商平台:
关键提示:摄像头安装高度建议距地面15-20cm,俯角约30度。这个角度能兼顾近处障碍和远方路径识别。
电机驱动模块的连接需要特别注意:
code复制L298N IN1 → GPIO17
IN2 → GPIO18
IN3 → GPIO22
IN4 → GPIO23
ENA → GPIO12
ENB → GPIO13
超声波模块若使用,Trig接GPIO24,Echo接GPIO25。所有电源共地是关键,我曾因接地不良导致PWM信号异常。
推荐使用Raspberry Pi OS Lite版本(32位),安装后需执行:
bash复制sudo apt install -y python3-pip libatlas-base-dev
pip3 install --upgrade tensorflow==2.8.0
特别注意:完整版TensorFlow在树莓派上运行效率极低,建议直接使用预编译的TensorFlow Lite运行时:
bash复制pip3 install tflite-runtime
创建requirements.txt包含:
code复制numpy==1.19.5
opencv-python-headless==4.5.3.56
picamera==1.13
gpiozero==1.6.2
我开发了一个实时采集脚本,通过键盘控制小车移动并同步保存图像和操作指令:
python复制import cv2
from gpiozero import Robot
robot = Robot(left=(17,18), right=(22,23))
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
key = cv2.waitKey(1)
if key == ord('w'):
robot.forward(0.3)
label = 0 # 前进
elif key == ord('s'):
robot.backward(0.3)
label = 1 # 后退
# 其他按键处理...
cv2.imwrite(f"data/{time.time()}.jpg", frame)
with open("labels.csv", "a") as f:
f.write(f"{frame_path},{label}\n")
在树莓派上训练时,我采用以下实时增强策略:
这使2000张原始图片等效扩展到约15000训练样本。
基于MobileNetV2的改进架构:
python复制base_model = tf.keras.applications.MobileNetV2(
input_shape=(160,120,3),
alpha=0.35,
include_top=False,
weights='imagenet'
)
model = tf.keras.Sequential([
base_model,
tf.keras.layers.GlobalAveragePooling2D(),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(3, activation='softmax') # 前进/停止/转向
])
使用迁移学习时冻结前80层,训练配置:
python复制model.compile(
optimizer=tf.keras.optimizers.Adam(0.0001),
loss='categorical_crossentropy',
metrics=['accuracy']
)
history = model.fit(
train_dataset,
epochs=30,
validation_data=val_dataset,
callbacks=[
tf.keras.callbacks.EarlyStopping(patience=5)
]
)
使用动态范围量化保持精度:
python复制converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with open('model_quant.tflite', 'wb') as f:
f.write(tflite_model)
实测发现,设置线程数为4时推理速度最佳:
python复制interpreter = tf.lite.Interpreter(
model_path="model_quant.tflite",
num_threads=4
)
interpreter.allocate_tensors()
采用有限状态机管理驾驶行为:
python复制class AutoDrive:
def __init__(self):
self.state = "FORWARD"
def update(self, prediction):
if prediction == 0: # 前进
self.forward()
elif prediction == 1: # 左转
self.left_turn()
# 其他状态处理...
def obstacle_avoid(self, distance):
if distance < 30: # 单位:厘米
self.emergency_stop()
return True
return False
转向控制采用简易PID:
python复制class PIDController:
def __init__(self, Kp=0.8, Ki=0.1, Kd=0.05):
self.Kp, self.Ki, self.Kd = Kp, Ki, Kd
self.last_error = 0
self.integral = 0
def update(self, error, dt):
self.integral += error * dt
derivative = (error - self.last_error) / dt
output = self.Kp*error + self.Ki*self.integral + self.Kd*derivative
self.last_error = error
return output
通过以下优化将处理速度从2FPS提升到8FPS:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 电机抖动 | PWM频率过高 | 调整频率至500Hz以下 |
| 摄像头延迟 | USB带宽不足 | 使用picamera库替代USB采集 |
| 模型误判 | 训练数据偏差 | 增加夜间/强光场景样本 |
当前系统可进一步扩展:
我在实际部署中发现,当环境光照剧烈变化时,建议增加自动曝光控制逻辑。另外,用热熔胶固定所有线缆能有效避免行驶中的连接松动问题。