简介:面向电赛参赛者与嵌入式视觉学习者,资料对应2023年电赛E题“运动目标控制与自动追踪系统”的工程实现,包含STM32控制端源码、Jetson Nano上的OpenCV识别源码及电路板PCB原理图设计。STM32部分按摇杆、二维云台舵机、蓝牙通信、蜂鸣器、LED、UART、定时器和PWM等模块组织;OpenCV部分覆盖铅笔识别、A4纸识别与红绿激光识别。压缩包共550个文件,约21.07MB,以C/H源码、Python脚本、工程配置与编译产物、图片及硬件设计文件为主,目录按控制、视觉和硬件分块,便于检索复现。代码注释较详尽,标注资源使用与管脚连接,函数风格接近HAL库,可帮助读者理解赛题控制链路、视觉识别流程和硬件连接关系,适合具备一定STM32与OpenCV基础的学习者拆解参考。已有1675人学习下载。
1. 运动目标控制与自动追踪系统的反直觉之处
2023年电赛E题(运动目标控制与自动追踪系统)最反直觉的一点是:图像识别做得再花哨,只要云台闭环慢半拍,分数照样上不去。这道题实际是两道题叠在一起——一道是OpenCV的颜色阈值与光斑质心提取,一道是STM32驱动二维云台做PID追踪,中间靠一条串口帧协议把两边缝起来。配套的STM32部分源码、Jetson Nano上的OpenCV源码和电路板PCB原理图,正好对应赛场上要交的三样东西:控制、视觉、硬件。下面从考点分布一路拆到高频考点、真题答法和易错点,适合已经动过手、但说不清自己丢分丢在哪的人。
2. 考点分布:E题分值背后到底在考哪四块能力
2.1 题面拆解:基本要求和发挥部分各盯什么
E题的主线就两条:一条是「红光按轨迹走」,一条是「绿光追红光」。基本要求这一侧,通常是让红色激光笔在板上按正方形、圆形这类设定轨迹运动,并且能在指定点停住;发挥部分才把难度拉起来,要求绿色激光笔自动跟上红色光斑,还要跟得快、跟得稳。很多队伍一上来就扑在OpenCV调阈值上,结果基本要求里「轨迹走不直、拐角画成圆弧」这一项先丢分,因为基本分几乎全压在云台的运动精度和重复定位上,而不是识别有多准。
命题人真正想看的,是你有没有把一个「看得见」的问题拆成「看得见 + 算得出 + 动得准」三段。红光轨迹那一半,考的是开环或半闭环的轨迹规划,本质是把一条几何路径离散成角度序列;绿光追踪那一半,考的是视觉闭环,本质是把像素偏差吃成角度增量。两半共用同一套云台、同一块板子,谁能把两套逻辑在代码里解耦成两个模式,谁在赛场上就不会手忙脚乱地改一行编译一次。
给分习惯上,基本要求的每一小项通常都能单独测、单独给分,发挥部分则是阶梯式的——做出来就有,做不出来一分不给。这个结构决定了策略:先把基本项全部拿满,再去碰追踪的速度指标。我见过不止一个队伍,追踪算法调得挺花,结果红光走正方形时四个角全是圆的,基本项直接掉一截,最后总分还不如一个只会走直线的方案。
还有一层容易被忽略:题目里「运动目标控制」和「自动追踪」是两个动作,前者可以预先编排,后者必须实时响应。有些队伍把两者写成同一套闭环,导致红光轨迹完全依赖视觉反馈,摄像头一丢帧轨迹就断。正确做法是把轨迹模式做成查表或插值,视觉只在追踪模式里介入,这个边界划清楚了,代码结构会干净很多。
2.2 三块系统的分工:视觉、控制、硬件各管一段
STM32管的是「手」:两路PWM驱动二维云台的水平轴和俯仰轴舵机,外加按键、OLED状态显示、串口收帧和模式切换。Jetson Nano(或者OpenMV、树莓派这类板子)管的是「眼」:拿摄像头图像,做颜色分割和质心提取,把光斑的像素坐标解算成偏差量发给控制板。PCB和原理图管的是「骨架」:电源分配、舵机供电、摄像头接口、板间连接。
这三段最容易出问题的地方不在段内,而在段与段之间的接口。视觉板算出来的是像素坐标,控制板要的是角度增量,中间少一个标定环节,整套系统就变成玄学——调参数全凭手感,换个光照、换个距离就崩。把接口定义清楚,比把每一段单独写到极致更重要。接口里至少要约定三件事:坐标系方向(图像x向右、y向下,对应的云台角度是增还是减)、单位(像素还是度)、帧率与超时行为。
分工上还有个现实问题:舵机是大电流负载,和主控共地不共电源是常识,但赛场上时间紧,不少人直接拿主控板上的5V给舵机供电,舵机一动、MCU复位。这类硬件级翻车往往在最后一天才暴露,前面几天都以为是代码写错了,调到最后才发现是电压塌了。原理图里给舵机单独一路稳压、加大电容、做好地线回流路径,这些工作在画板阶段只多花半小时,在赛场能救回一整天。
2.3 现场评分看的不是代码,是稳定复现
赛场上真正被反复测的是「重复性」。红光走同一个正方形,第一次和第十次落点差多少;绿光追同一个静止光斑,稳定之后抖不抖;断电重启之后还能不能一键进入工作状态。评委不会去读你的代码写得优不优雅,他只会按按键、看现象、掐秒表。
所以备战重心应该往「可复现」上倾斜:上电自检、模式切换、异常恢复、参数掉电保存,这些东西代码量不大,但直接决定现场演示能不能一次过。反过来,识别算法里的自适应阈值、卡尔曼滤波这类加分项,如果会让系统在某种光照下突然不工作,不如老老实实用固定阈值加物理遮光——遮光罩的成本是几块钱,调参的成本是一整夜。
提示:把这题当成一场「稳定性考试」来准备,它的分数结构和算法竞赛完全不同,能跑通十次比能跑通一次重要得多。
2.4 硬件选型也在考点里:云台、镜头、供电
云台结构上,两轴舵机的转轴要尽量正交,俯仰轴的负载要配平,否则舵机长期堵转发热,跑十几分钟就开始漂。摄像头的安装位置要么和激光笔共轴,要么就必须在软件里补偿一个固定偏置——不共轴意味着光斑在图像里的位置随目标距离变化,近距离和远距离的偏差不一样,这个视差是个深坑,能共轴尽量共轴。
镜头焦距决定视场角。视场角太小,光斑跑出画面就丢了目标;视场角太大,光斑只占几个像素,质心精度掉得厉害,抖动被放大。640×480分辨率配六十度左右的水平视场,是这类题比较常见的折中——光斑能占到十几到几十个像素,质心算出来比较稳。另外要确认摄像头是不是走USB2.0,带宽不够时帧率会掉到15fps以下,追踪会明显滞后,这个滞后在参数上是补不回来的。
供电按堵转电流算,不按空载电流算。舵机标称空载几十毫安,堵转能到一安以上,电池容量和稳压芯片的余量都要按最坏情况留。板上最好留一个总开关和一路独立的舵机使能,调试时能单独断电,避免舵机乱抖打断烧录。
3. 视觉考点:OpenCV光斑识别的四个必答环节
3.1 为什么先转HSV:颜色空间是识别的第一道分水岭
用RGB做颜色阈值几乎是新手的统一动作,也是统一翻车点。RGB三个通道都随光照强度变化,白板上的红色光斑在灯亮时是(255,80,80),灯暗一点就变成(150,45,45),阈值区间要写得很宽才覆盖得住,一宽就把白板反光、红色标记物一起收进来。HSV把色调、饱和度、明度拆开,H通道只跟「是什么颜色」有关,光照变化主要影响V,阈值可以写得窄而稳。
红色的麻烦在于H在色环上跨了0度,所以要开两段区间再合并:一段0到10,一段170到180。这一点不写进去,稍微偏紫一点的光斑就漏检。
import cv2 import numpy as np # Jetson Nano 光斑识别主流程:HSV 双区间阈值 -> 形态学 -> 最大连通域质心 cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) cap.set(cv2.CAP_PROP_FPS, 30) def find_spot(frame, hsv_lo1, hsv_hi1, hsv_lo2, hsv_hi2, min_area=20): hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # BGR->HSV,色调与亮度解耦 mask1 = cv2.inRange(hsv, hsv_lo1, hsv_hi1) # 红色低色相段 0~10 mask2 = cv2.inRange(hsv, hsv_lo2, hsv_hi2) # 红色高色相段 170~180 mask = cv2.bitwise_or(mask1, mask2) # 两段合并,缺一段就漏检偏紫光斑 kernel = np.ones((5, 5), np.uint8) # 5x5 对应 640x480 下的光斑尺度 mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) # 开运算去孤立噪点 mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) # 闭运算补光斑内部空洞 cnts, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not cnts: return None, mask c = max(cnts, key=cv2.contourArea) # 取面积最大的连通域 if cv2.contourArea(c) < min_area: # 面积过小视为噪声 return None, mask M = cv2.moments(c) if M["m00"] == 0: # 防止除零,单像素轮廓会踩到 return None, mask cx = int(M["m10"] / M["m00"]) # 质心 x cy = int(M["m01"] / M["m00"]) # 质心 y return (cx, cy), mask # 阈值起点:H 取两段,S/V 下限用来压掉白板反光 LO1, HI1 = np.array([0, 120, 120]), np.array([10, 255, 255]) LO2, HI2 = np.array([170, 120, 120]), np.array([180, 255, 255])这段代码里三个参数决定成败。S下限压的是「白得发灰」的反光,白板反光的饱和度低,把S下限抬到120左右,大部分反光会被挡掉;V下限压的是暗处的杂色,太低会把阴影里的红色物体收进来。min_area这个面积门限按光斑实际像素面积取,光斑远时面积小,门限设高了会频繁丢目标,设低了噪声全进来了。实际调的时候先把mask窗口打开,一边晃激光笔一边看二值图,比盲调阈值快得多。
3.2 形态学与连通域:怎么把光斑从噪声里捞出来
开运算先腐蚀后膨胀,作用是去掉比核小的孤立亮点,比如传感器噪点、板面上的小反光;闭运算先膨胀后腐蚀,作用是补上光斑内部因为过曝产生的空洞——激光笔打在白板上中心往往过曝成白色,HSV里V到顶、S掉下来,中间会出现一个洞,不补的话质心会被拉偏。
核的大小要跟分辨率匹配。640×480下5×5比较通用,分辨率上到1280×720,核也要相应放大,不然去噪不干净。核太大会把光斑本身啃掉一圈,质心还在,但面积判定会误伤,小目标直接消失。
连通域筛选除了面积,还可以加两个判据:圆度和长宽比。激光光斑在板上近似圆形,长宽比接近1;白板边缘的反光、红色胶带这类干扰往往是细长条。加上圆度过滤以后,误识别的概率会明显下降。代价是计算量增加,在Jetson Nano上要控制在一帧几十毫秒以内,超了就把这部分放到只对候选框做二次判断。
干扰源要提前想清楚:白板反光、显示器、红色衣物、别人的红色激光笔。前三个靠阈值和形态学能挡掉大半,最后一个只能靠策略——当画面里有两个红色连通域时,取面积最大的、取最亮的、或者取离上一帧位置最近的。第三种最稳,因为它引入了时间连续性先验,代价是要维护一个历史位置。
3.3 质心提取与坐标标定:像素坐标怎么变成云台角度
质心用图像矩算,(m10/m00, m01/m00)就是一阶矩归一化,本质是亮度加权或者掩膜加权的重心。想要亚像素精度,就用mask当权重做加权平均,比直接取轮廓质心平滑得多,抖动小一半。
真正决定追踪精度的不是质心,是标定。像素坐标到角度的映射有两种做法:一种是几何法,用焦距像素值f,角度偏差 = arctan(Δx / f),Δx是光斑x减去图像中心x;另一种是两点线性标定,把光斑分别放在画面左边缘和右边缘,记下对应的舵机角度,中间线性插值。几何法在小角度下准、大角度受畸变影响;线性标定简单粗暴,但要考虑镜头畸变是不是已经让线性关系不成立了。
标定里最容易漏的是摄像头和激光笔的相对位置。两者不共轴时,光斑在图像中的位置不仅取决于目标位置,还取决于目标距离,做一次标定只在某一个距离上成立。赛场上如果目标距离固定,问题不大;如果要求在不同距离追踪,就必须做视差补偿,或者干脆把摄像头和激光笔装在同一根轴上。
注意:标定要在最终装配完成之后做。调试阶段随手放的位置和最终结构差几毫米,标定表就废了,这类返工很常见。
3.4 答辩常问:帧率、误识别和光照变化怎么答
测评现场和答辩环节,围绕视觉的问题高度集中,提前准备好答案能省很多临场组织语言的时间。
被问「系统延迟多少」时,别只答摄像头帧率。延迟等于曝光时间加传输加处理加串口加舵机响应,逐段报出来才有说服力。Jetson Nano上跑这套流程,单帧处理通常在十毫秒量级,加上30fps的采集周期,端到端延迟在几十毫秒,这个数字要自己实测,不要估。
被问「光照变化怎么办」时,回答分两层:HSV已经把色调和亮度解耦,阈值对亮度不敏感;在此之上加一个现场标定按键,按下后采样当前画面里光斑的H均值,自动收窄阈值区间。只答第一层会显得没考虑实际,答第二层才像做过现场调试的人。
被问「画面里有多个红色目标怎么办」时,把筛选策略说清楚:面积优先、位置连续性优先、亮度优先,三者可以串起来用。再补一句「如果干扰目标和真实光斑特征完全一致,单目视觉无法区分,需要靠时序或者外加调制」,这句能体现你知道方法的边界在哪。
4. 控制考点:STM32驱动二维云台的三个闭环
4.1 舵机PWM:定时器参数怎么算才不抖
舵机的控制信号是50Hz的PWM,周期20ms,高电平宽度0.5ms到2.5ms对应0到180度。算定时器参数的时候,先定计数时钟再定周期:主频72MHz,预分频给72,计数时钟就是1MHz,一个计数1微秒;周期寄存器填20000减1,正好20ms。这样比较寄存器的值直接就是微秒数,写起来直观。
// STM32 定时器 PWM:50Hz / 20ms 周期,500~2500us 对应 0~180 度 void Servo_Init(void) { // 72MHz / 72 = 1MHz 计数时钟,1 个计数 = 1us,Period=20000-1 即 20ms htim3.Init.Prescaler = 72 - 1; htim3.Init.Period = 20000 - 1; HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 水平舵机 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // 俯仰舵机 } // 角度转比较值:500us 对应 0 度,2500us 对应 180 度,约 11.1us/度 void Servo_SetAngle(TIM_HandleTypeDef *htim, uint32_t ch, float angle) { if (angle < 0.0f) angle = 0.0f; // 限幅,防止超程顶死舵机 if (angle > 180.0f) angle = 180.0f; uint32_t ccr = (uint32_t)(500.0f + angle * 2000.0f / 180.0f); __HAL_TIM_SET_COMPARE(htim, ch, ccr); }参数含义要讲清楚:预分频决定时间分辨率,周期决定频率,比较值决定占空。11.1微秒每度意味着角度分辨率理论上能到零点几度,但舵机本身的机械死区和齿轮间隙远大于这个数,所以代码里再加一道死区判断——角度变化小于0.5度就不更新比较寄存器,能明显减少静止时的嗡嗡声和微抖。
舵机抖动的来源通常是四个:电源塌陷、PWM抖动、机械间隙、控制环振荡。排查顺序从电源开始,示波器看舵机供电在动作瞬间掉不掉;电源没问题再看PWM波形稳不稳;都正常再怀疑控制参数。反过来先调PID,往往越调越乱。
4.2 串口帧协议:两块板子怎么对上话
视觉板和控制板之间最常见的做法是串口,115200波特率够用。问题不在波特率,在帧同步。直接发两个字节的坐标,一旦丢一个字节,后面所有数据全部错位,现象是云台突然抽风转到底,过几秒又好了,这种偶发故障最难查。
稳妥的做法是定长帧加帧头加校验,接收端用状态机解析,任何时候收到帧头就重置状态。这样即使中间丢字节,下一帧到来时能自动重新对齐。
// 帧格式:0xAA 0x55 | cx_H cx_L | cy_H cy_L | flag | sum // sum = 前 6 字节累加和低 8 位,接收端校验失败直接丢帧 typedef struct { uint16_t cx; uint16_t cy; uint8_t flag; // bit0: 找到目标 bit1: 追踪模式 } VisionFrame; void Vision_Parse(uint8_t byte, VisionFrame *out) { static uint8_t buf[8]; static uint8_t idx = 0; if (idx == 0 && byte != 0xAA) return; // 等帧头1 if (idx == 1 && byte != 0x55) { idx = 0; return; } // 帧头2不对就复位 buf[idx++] = byte; if (idx >= 8) { uint8_t sum = 0; for (uint8_t i = 0; i < 7; i++) sum += buf[i]; if (sum == buf[7]) { // 校验通过才更新,坏帧不污染控制量 out->cx = (buf[2] << 8) | buf[3]; out->cy = (buf[4] << 8) | buf[5]; out->flag = buf[6]; } idx = 0; // 无论对错都复位,准备下一帧 } }协议里还要加一条超时规则:超过100ms没收到有效帧,控制板就把目标速度清零、舵机保持当前位置,而不是继续执行上一帧的旧数据。这条规则能避免摄像头掉线后云台还在朝一个方向猛转。flag字段里带上「是否找到目标」也很关键,没找到目标时不应该继续追零坐标。
4.3 PID闭环:位置式、增量式怎么选,参数从哪起
舵机位置环用增量式更顺手,输出是本次的增量,天然带积分,抗积分饱和也容易做。位置式直接输出绝对角度,参数直观但要对积分项单独限幅,写漏了就会出现「越追越偏、松手不回中」的经典现象。
| 对比项 | 位置式 PID | 增量式 PID |
|---|---|---|
| 输出含义 | 直接是控制量(角度) | 本次控制量的增量 |
| 积分饱和 | 需要单独限幅 | 结构上不易饱和 |
| 手自动切换 | 切换时冲击大 | 冲击小 |
| 参数调试 | 直观,易理解 | 需要累积,观察稍绕 |
| 适用场景 | 稳态精度要求高 | 舵机位置环、有积分风险 |
参数起点可以按这个顺序:先把Ki和Kd清零,Kp从很小往上加,加到系统能跟上但略有超调;然后把Kp往回退一点,加Kd压超调;最后加一点点Ki消静差。舵机系统里Ki通常给得很小,因为舵机本身有死区,积分攒起来容易过头。采样周期要和视觉帧率对齐,视觉30fps就按33ms算,别用1ms去跑PID,那是自找振荡。
// 增量式 PID:输出为本次增量,适合舵机位置环,带输出限幅 typedef struct { float kp, ki, kd; float err[3]; // err[0]=本次 err[1]=上次 err[2]=上上次 float out; // 累积输出(角度) } PID_Inc; float PID_Calc(PID_Inc *p, float target, float actual) { p->err[0] = target - actual; float delta = p->kp * (p->err[0] - p->err[1]) + p->ki * p->err[0] + p->kd * (p->err[0] - 2 * p->err[1] + p->err[2]); p->err[2] = p->err[1]; p->err[1] = p->err[0]; p->out += delta; if (p->out > 180.0f) p->out = 180.0f; // 输出限幅,防止舵机顶死发热 if (p->out < 0.0f) p->out = 0.0f; return p->out; }这段代码的关键在最后三行。限幅不只是保护舵机,也是防止积分项在目标长时间不可达时无限累积——虽然增量式结构上不容易饱和,但out本身会一直涨,限幅等于给累积量加了硬边界。另外err数组的更新顺序不能错,先移位再赋值,写反了微分项就变成常数,现象是系统对快速变化完全不敏感。
5. 易错点:五个让分数白白溜走的坑
5.1 识别环节的两个经典错误
第一个坑:阈值写死在代码里,现场不标定。错在哪——调试时的灯光和测评现场的灯光不是一回事,白板的反光角度也变了,写死的阈值一到现场要么漏检要么满屏噪点。为什么错——HSV对色调稳定,但对饱和度和明度仍然敏感,而这两个量恰好最受现场光照影响。怎么答对——加一个「一键标定」:按住按键,系统连续采若干帧,统计画面中心区域光斑的H/S/V均值,把阈值区间按均值上下浮动一个范围写进RAM,同时存一份到Flash,下次上电直接读。这个功能代码不到五十行,赛场上能救命。
第二个坑:用灰度阈值找光斑。错在哪——白板本身就是高灰度,光斑打上去只是更亮一点,灰度阈值一低就把整块板子收进来。为什么错——激光光斑的可分性来自颜色而不是亮度,选了错误的特征维度,后面怎么调都调不出来。怎么答对——坚持HSV,把「颜色」当第一判据,亮度只用来做辅助筛选(比如取V最高的连通域)。如果现场确实有强反光,加物理遮光罩比改算法快。
5.2 控制环节的两个经典错误
第三个坑:舵机和主控共用一路5V。错在哪——舵机启动瞬间的浪涌电流把电压拉低,MCU欠压复位,现象是云台动一下就重启,串口断连。为什么错——舵机是感性负载加大电流,和数字电路共用稳压器时,稳压器的瞬态响应根本跟不上。怎么答对——原理图上给舵机单独一路稳压,输入端加大电容,地线走星型单点汇聚;代码上加一个上电延时,先让舵机回中再开视觉,减少同时冲击。
第四个坑:PID输出不限幅,或者限幅了但没做死区。错在哪——目标跑出视场时误差一直很大,输出累积到极限,舵机顶在机械限位上堵转发烫,等目标回来要好几秒才转回来。为什么错——控制量没有边界,积分项就把「追不上」这件事记成了「要一直往死里转」。怎么答对——输出限幅加死区判断双管齐下:限幅挡住超程,死区(角度变化小于0.5度不更新)挡住静止抖动。再加一条「目标丢失超过200ms就清空积分」,专门治丢目标后的暴冲。
5.3 联调与演示环节的一个致命错误
第五个坑:视觉板和控制板之间不做丢帧判断,收到就用。错在哪——串口偶尔丢字节,解析出的坐标是错的,云台猛地一跳,看起来像算法崩了,实际是协议没对齐。为什么错——没有帧头、没有校验、没有超时,任何一次传输异常都会变成控制异常。为什么难查——它偶发,重启就好,调试时很难复现。怎么答对——定长帧、帧头、校验和、超时复位四件套全上;再加一个调试手段:控制板每隔一秒通过OLED显示「最近一秒收到的有效帧数」,帧数掉到个位数就说明链路有问题,不用猜。
另外提一个演示环节的习惯:上电流程要固化。先自检(舵机小幅摆动确认行程、摄像头出图确认、串口通信确认),全部通过再进入待机;任何一个环节失败就停在报警状态而不是带病运行。评委看到你按一下按钮系统自己走完自检,和你手忙脚乱插拔线,印象分差得很远。
6. 答题技巧:现场答辩怎么把做过的事讲成分数
测评现场的提问有套路,回答也有套路。评委不缺技术,他想确认的是「这东西是不是你们自己做的」「你们知不知道自己方案的边界在哪」。所以答的时候先给结论再给依据,主动说出局限,比硬撑「我们的方案没有问题」可信得多。
| 评委常问 | 他想确认什么 | 建议答法 |
|---|---|---|
| 这个追踪延迟大概多少 | 你有没有量化意识 | 分段报:曝光+传输+处理+串口+舵机,给实测值,说明怎么测的 |
| 光照变了怎么办 | 有没有考虑现场鲁棒性 | HSV解耦+一键标定,说清标定触发方式和保存位置 |
| 为什么用两块板 | 分工是否合理 | 实时性分离:控制环跑在MCU上不被图像处理阻塞 |
| 精度靠什么保证 | 有没有标定环节 | 两点线性标定+共轴安装,说明视差怎么处理 |
| 这套东西还能怎么改 | 有没有反思能力 | 说一个具体短板,比如帧率受限,给出下一步方案 |
押题思路也简单:把题目拆成「识别、解算、驱动、联调」四块,每一块准备一个「我们怎么做的 + 我们踩过什么坑 + 如果重来会怎么改」的三句话版本。三句话讲完,评委基本不会再深挖,因为他要的信息已经拿到了。反过来,讲一大段原理却不说自己做了什么,评委会继续追问,越问越虚。
四天三夜的排法上,我的经验是第一天必须把硬件通路打通——舵机能转、摄像头能出图、串口能收发,哪怕算法是空的;第二天做红光轨迹模式,把基本分锁死;第三天再做绿光追踪,先追静止目标再追运动目标;第四天全部用来做稳定性测试和答辩准备,不碰新功能。这个顺序看着保守,但它保证了任何一天出问题,你手上都有一个能演示的完整系统。
从那以后我每次带这类题,都强制走一遍「上电自检—模式切换—异常恢复」三件事,做完才允许调参数。参数可以慢慢磨,流程塌了就全没了。希望帮到你。
本文还有配套的精品资源,点击获取