2026寒假练 - 用人工智能硬件实验套件制作AI视觉巡迹避障小车
该项目使用了ESP32‑S3 Sense,实现了AI视觉巡迹避障小车的设计,它的主要功能为:自动巡迹,实时避障,紧急停车。
标签
Arduino
AI
摄像头
Edge Impulse
ESP32S3 Sense
小车
TetraPak
更新2026-03-24
61

项目介绍

本项目构建了一个基于 ESP32-S3 的智能循迹避障小车。它以强大的 ESP32-S3 Sense 开发板为核心,集成摄像头、六轴传感器和超声波传感器,并通过感知扩展底板与机器人小车底座相连,实现复杂的环境感知与自主运动控制。小车的核心任务是利用Edge Impulse模型进行视觉导航,在预设赛道上自主行驶。为确保运行的稳定性和安全性,项目设计了双重安全保障机制:一是利用超声波传感器作为视觉系统的补充,实现主动防撞功能;二是利用六轴传感器实时监测车身姿态,在发生碰撞、倾覆等极端情况时立即触发紧急制动。

硬件介绍

该项目以 Seeed Studio XIAO ESP32S3 Sense 开发板为核心,它集成了摄像头麦克风,提供了机器视觉和语音识别的基础。为了实现运动和环境交互,项目配备了:

  • 两个带编码器的直流电机来驱动设备移动。
  • 一个超声波传感器用于测量距离和避障。
  • 一个六轴传感器(IMU)来感知设备的姿态和运动。
  • 一个蜂鸣器用于声音反馈。

设计思路

此项目没有采用传统的PID,而是利用在Edge Impulse平台上训练的轻量级图像分类模型,让小车能够识别摄像头画面中的四种状态:“赛道中心”、“左转标记”、“右转标记”和“背景”。控制逻辑并非在看到标记时立即转弯,而是采用一种更稳定和精确的“通过后执行”策略。具体来说,系统会持续追踪识别标签的变化,例如,当识别结果从“左转标记”变为“赛道中心”时,系统判定小车已完全通过转弯区域的入口,此时才触发一个预设的组合动作——先短暂直行一小段距离以调整姿态,再执行一个固定时长的左转。

在edge impulse设置标签:

考虑到电机驱动板与超声波传感器在板上共用了GPIO引脚,通过ESP32-S3的硬件定时器,系统以固定的时间间隔自动触发中断。在中断服务程序中,电机会被瞬间暂停,同时被共用的引脚会从电机驱动的输出模式动态切换为超声波传感器的输入模式以完成一次测距。测距结束后,无论成功与否,引脚都会立即恢复为电机驱动模式,电机继续执行原有的循迹任务。这个过程速度极快,对小车的正常行驶影响微乎其微。当超声波传感器检测到前方近距离存在障碍物时,它会触发保护机制,使小车减速或停车,并发出蜂鸣警示。

MPU6500六轴传感器不间断地监测其加速度和姿态。当小车因撞击发生侧翻导致姿态严重倾斜时,无论当前AI的决策是什么,电机都会被强制停止输出,实现立即停车。同时,蜂鸣器会发出长鸣,以提示发生了严重的异常状况。

软件框图:


主要代码介绍

本项目的开发工具是Arduino IDE,在Edge Impulse上训练模型,将生成的模型库文件导入Arduino进行开发,使用的是C++语言。

程序流程图:

1. 系统初始化与主循环架构

系统启动后,setup()函数负责完成所有硬件的初始化,包括电机驱动、摄像头模块、MPU6500六轴传感器,并检测超声波传感器是否存在。其中,针对超声波传感器与电机驱动的引脚复用问题,系统在setup()阶段会进行一次探测,若传感器存在,则会配置一个硬件定时器和GPIO外部中断,为后续的分时复用测距做准备。

void setup() {
// ... 初始化电机、摄像头、MPU6500 ...
motor_control.motor_init();
ei_camera_init();
mpu.begin();

// 检测超声波并配置分时复用中断
ultrasonicConnected = detectUltrasonic();
if (ultrasonicConnected) {
// ... 配置引脚、挂载中断和定时器 ...
attachInterrupt(digitalPinToInterrupt(echoPin), echoISR, CHANGE);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &timerISR, true);
timerAlarmWrite(timer, 100000, true); // 100ms 周期
timerAlarmEnable(timer);
}
// ...
}

void loop() {
// 若正在执行预设动作(如转弯),则专注于完成该动作
if (is_performing_action) {
performAction();
return;
}

// ... 捕获图像并分配内存 ...

// 运行AI分类器
ei_impulse_result_t result = { 0 };
run_classifier(&signal, &result, debug_nn);

// 根据AI结果更新状态和决策
TrackLabel detected_label = getDetectedLabelFromResult(result);
updateLabel(detected_label);

// 读取传感器数据并执行安全检查
if (mpu.read()) {
controlLED(); // 包含MPU和超声波的安全检查逻辑
}

// ... 处理超声波测距结果 ...
}


2. 基于状态转换的AI视觉决策逻辑

小车的循迹核心是AI视觉决策,其智能之处在于并非简单响应当前的识别结果,而是基于“状态转换”来触发动作。updateLabel()函数是这一逻辑的实现核心,它会比较当前帧的识别标签current_label与上一帧的last_label。只有当标签发生特定的、符合逻辑的序列变化时,系统才会启动一个动作。例如,当识别结果从“左转标记”变为“赛道中心”时,系统判定小车已经驶过转弯点,此时才将状态机切换至STATE_TURN_LEFT并启动转弯动作。

void updateLabel(TrackLabel new_label) {
last_label = current_label;
current_label = new_label;

// 只有当标签发生变化时才进行判断
if(last_label == current_label) {
return;
}

// 如果未处于预设动作执行期间,则根据状态转换触发新动作
if (!is_performing_action) {
// 当从 "左转标记" 变为 "赛道中心" 时,触发左转动作
if (last_label == LABEL_CENTER_LEFT && current_label == LABEL_CENTER) {
current_state = STATE_TURN_LEFT;
is_performing_action = true; // 标记开始执行动作
action_start_time = millis();
controlMotor(SPEED_STRAIGHT, SPEED_STRAIGHT); // 先短暂直行
}
// ... 类似地处理右转等其他情况 ...
else if (last_label == LABEL_CENTER_RIGHT && current_label == LABEL_CENTER) {
current_state = STATE_TURN_RIGHT;
// ...
}
}
}


3. 时间驱动的精确动作执行

一旦视觉决策模块触发了一个动作,控制权就交由performAction()函数。该函数实现了一个基于时间的、非阻塞的状态机,用于执行精确的、分阶段的动作序列。它通过millis()记录动作开始时间,并计算已用时间elapsed,根据预设的时间常量来切换电机的状态。例如,一个左转动作被分解为“先短暂直行一小段”和“再执行标准左转”两个阶段。这种方式确保了每次转弯的角度和姿态都相对一致,使小车的运动轨迹更加规范和可预测,并在动作完成后自动恢复到常规巡线模式。

void performAction() {
if (!is_performing_action) return;

unsigned long current_time = millis();
unsigned long elapsed = current_time - action_start_time;

switch (current_state) { // 根据当前状态执行不同动作
case STATE_TURN_LEFT:
if (elapsed < SHORT_FORWARD_TIME) {
// 阶段一:短暂直行
controlMotor(SPEED_STRAIGHT, SPEED_STRAIGHT);
} else if (elapsed < SHORT_FORWARD_TIME + TURN_TIME) {
// 阶段二:左转
controlMotor(SPEED_TURN_LEFT, -SPEED_TURN_LEFT);
} else {
// 动作完成,停止并恢复正常状态
stopAction();
}
break;

// ... STATE_TURN_RIGHT 的类似逻辑 ...
}
}

void stopAction() {
is_performing_action = false;
controlMotor(0, 0);
delay(500); // 短暂停止以稳定姿态
controlMotor(SPEED_STRAIGHT, SPEED_STRAIGHT); // 恢复直行
}

4. 基于中断的引脚分时复用机制

为了解决超声波传感器与电机驱动共用引脚的冲突,代码采用了一套精密的、基于硬件中断的分时复用方案。硬件定时器以100ms的周期触发timerISR()中断服务程序(ISR)。在该ISR中,系统会立即停止电机,并通过IRAM_ATTR修饰的函数iram_prepareEchoForInput()将共用引脚从输出(电机控制)切换为输入(超声波接收),然后发出超声波脉冲。当回波信号到来时,会触发echoISR(),该ISR负责计算距离并调用iram_restoreEchoOutput()将引脚恢复为电机驱动模式,并重启电机。整个过程在中断中快速完成,对小车的正常行驶影响极小,实现了传感和控制的无缝切换。

// 定时器中断服务程序:启动一次测距
void IRAM_ATTR timerISR() {
portENTER_CRITICAL_ISR(&mux);

if (!measurementInProgress) {
controlMotor(0, 0); // 1. 暂停电机
iram_prepareEchoForInput(); // 2. 切换引脚为输入
iram_triggerUltrasonic(); // 3. 触发超声波
measurementInProgress = true;
// ...
}

portEXIT_CRITICAL_ISR(&mux);
}

// 外部中断服务程序:接收回波并结束测距
void IRAM_ATTR echoISR() {
// ... 计算回波时长 ...

if (level == false && echoStart != 0) { // 检测到下降沿
// ... 保存测距结果 ...
measurementDone = true;
measurementInProgress = false;
iram_restoreEchoOutput(); // 4. 恢复引脚为输出并重启电机
}
// ...
}

5. 多传感器融合的紧急安全制动

项目的安全性由一个统一的、高优先级的急停机制保障。controlLED()函数(实际功能远超控制LED)是安全决策中心,它融合了来自六轴传感器和超声波传感器的数据。当检测到剧烈碰撞、倾倒或前方有近距离障碍物时,会立即设置全局布尔变量wrong_flagtrue。这个标志位在最底层的电机控制函数controlMotor()中被首先检查。一旦wrong_flag为真,无论上层AI的决策是什么,电机都会被强制停止,同时蜂鸣器报警,实现了最直接、最可靠的紧急制动,确保了小车在极端情况下的安全。

void controlLED() {
// 融合IMU和超声波数据进行安全判断
if ((mpu.getAccelX_g() > 0.8) && (c100_distance > 8)) {
// 状态正常
wrong_flag = false;
stop_beep();
// ...
} else {
// 检测到异常姿态或障碍物
wrong_flag = true;
start_beep();
motor_control.motor(0, 0); // 直接停车
}
}

void controlMotor(int8_t motor_a, int8_t motor_b) {
// wrong_flag 具有最高优先级,可覆盖任何电机指令
if(wrong_flag)
motor_control.motor(0, 0);
else
motor_control.motor(motor_a, motor_a);
}


演示效果

模型训练效果

实物图

轨迹图

具体效果请观看演示视频

总结

在整个开发过程中,最大的收获是掌握了端侧AI应用的完整工作流程。学习了如何使用Edge Impulse平台收集图像数据、设计网络模型、训练并最终将其部署到ESP32-S3这样的资源受限的微控制器上,实现了实时的图像分类与决策。项目仍有值得优化的空间。可以将其升级为闭环控制,即在执行转弯动作时,持续利用摄像头检测赛道线,直到识别到赛道重新回到“中心”状态时才结束转弯,这将使小车的动作更加自适应和精准。



附件下载
trajectory.zip
Arduino实现代码
ei-car-trajectory-arduino-1.0.20.zip
edge impulse视觉模型
团队介绍
团队成员
TetraPak
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号