资讯动态

2025电赛G题方案:模块化代码骨架+传感器滤波+PID调参,从跑通到跑稳

发布时间:2026/10/20 8:06:52 来源:尧图企业网站定制
简介一份面向2025年全国大学生电子设计竞赛G题《电路模型探究装置》的代码方案包适合信号类赛题备赛选手参考。方案按基础与发挥两部分展开基础部分覆盖传递函数计算、RMS有效值检测、VGA增益控制等关键实现发挥部分引入LMS算法学习未知电路传递函数结合FIR数字滤波器与查表法完成滤波器类型判断和信号重建体现了从算法选型到代码落地的完整思路。同时保留了2020—2023年经典电赛题目复盘与实战评审突发问题记录对理解出题趋势和临场应对很有帮助。压缩包共3个文件包含inscode项目文件、index.html说明页面及.gitignore配置整体仅13KB轻量便携HTML页面可作为方案索引入口inscode文件承载核心代码示例。目前已有379人学习下载。借助这份代码包可快速理清电路模型探究的难点突破顺序节省环境配置与算法验证时间尤其适合需要在短时间内搭建可运行框架的参赛者。1. 2025电赛G题方案先别急着写算法先把代码骨架立住每年电赛题目公布之后G题这个位置几乎都是一道综合控制类大题载体可能是车模、云台或者某种运动平台但内核逃不出「感知—决策—执行」这条链路。很多队伍拿到题目之后前三天耗在机械结构和硬件选型上最后一天赶出一份顺序执行的代码一上电就翻车。真正的问题往往不在PID公式记没记住、卡尔曼滤波会不会推而在代码从第一秒起就没有骨架传感器数据在一个循环里挤成一团模式切换靠if嵌套现场改一个参数要重新编译烧录改三次就不知道哪版能用。这套2025电赛G题方案要讲的就是怎么把这类题目拆成分层结构用一套模块化骨架把代码组织起来再给出滤波、PID、状态机这些核心模块的直接可抄代码和参数设定。适合正在备赛的队伍和带队指导新手能照着把工程搭起来熟手能直接替换自己的算法模块而不动整体结构。2. 先搭骨架G题代码的模块化组织与主循环设计2.1 文件怎么分把「驱动」「算法」「调度」拆成三个独立模块G题代码最常见的一种死法就是所有东西都写在main.c里。传感器初始化、中断服务、PID计算、显示刷新、模式切换全在一个文件里挤着到了比赛现场想改一个滤波参数得先翻几百行代码找到那个藏在角落的宏定义改完还不确定有没有别的模块引用。这种「单文件大循环」的结构在跑通demo阶段没问题但G题要求的是一个能在现场快速迭代调试的系统代码组织的混乱会在最后三天集中爆发。我一般会把工程按三个目录拆开driver目录放芯片外设和传感器驱动algorithm目录放滤波、PID、卡尔曼这类纯算法task目录放状态机调度和主循环。驱动层有硬件依赖算法层完全独立不依赖任何外设调度层负责把「什么时候调用谁」管起来。这样拆之后工程结构大致是这样目录典型文件职责依赖driver/encoder.c、imu.c、motor.c、display.c读传感器、输出PWM、刷新屏幕芯片寄存器、外设库algorithm/filter.c、pid.c、kalman.c数据处理与控制计算无纯C语言task/fsm.c、main.c状态切换、任务调度、初始化依赖上面两层这样拆有两个实际好处。第一个是可替换性比赛现场发现陀螺仪数据异常只需要换driver层对应驱动算法层完全不用动想从位置式PID换成增量式PID也只需要改algorithm层不用去中断里翻代码。第二个是可测试性algorithm层的代码是纯C不依赖任何硬件可以拿到电脑上编一个测试程序用模拟数据验证滤波效果和PID响应不需要等硬件就绪。这两个好处在比赛现场的价值非常大因为G题的调试时间永远不够用任何一次「改一处坏三处」都是致命的。另外建议文件命名直接按功能走别用gpio.c、utils.c这种名字。motor_ctrl.c、line_vision.c这种命名在三天之后你还认得出是干嘛的test1.c就没有任何线索了。2.2 状态机做主循环从顺序执行到模式切换G题装置一般都要经历明显的阶段变化——上电自检、待机等待、正常运行、急停保护。用一个大while循环加if判断也能跑但一旦有十几个标志位互相置位调试的时候就会变成「改一处、坏三处」。状态机写法最大的优势是当前状态只有一个活跃分支转移条件集中写在一起查看状态、修改转移条件都方便。用一个典型的控制装置举例它的状态至少要分四个上电自检、待机、运行、急停。代码如下typedef enum { ST_BOOT, // 上电自检 ST_STANDBY, // 待机等待启动信号 ST_RUNNING, // 正常运行 ST_EMERGENCY, // 急停保护 } sys_state_t; static sys_state_t g_state ST_BOOT; void fsm_run(void) { switch (g_state) { case ST_BOOT: if (boot_self_check() 0) { // 自检不通过停在自检态 break; } g_state ST_STANDBY; // 自检通过进入待机 break; case ST_STANDBY: if (start_signal_received()) { // 收到启动指令 g_state ST_RUNNING; } break; case ST_RUNNING: if (any_fault_detected()) { // 任意故障直接切急停 g_state ST_EMERGENCY; break; } control_loop_running(); // 正常运行时的控制计算 break; case ST_EMERGENCY: set_motor_duty(0); // 输出强制清零 break; default: g_state ST_BOOT; // 未知状态兜底回到自检 break; } }这个结构里有几个关键点。ST_RUNNING状态下先检查故障再执行控制任务——故障检测优先级必须高于控制计算因为任何一拍的失控都可能让装置冲出赛道或者损坏机械结构。ST_EMERGENCY状态下只做一件事就是输出清零不要在这里再调用任何控制算法或者显示刷新急停操作必须在最快路径里完成。g_state是静态全局变量整个task模块内可见但外部只能通过fsm_run()推进状态不要让中断服务函数直接改写状态机——否则主循环还没处理完急停中断又把它切回运行态急停就失效了。这里不推荐上实时操作系统G题的代码规模通常在几千行量级裸机状态机完全够用。RTOS的优先级调度反而会引入调试复杂度现场出问题时排查面更大。裸机加状态机是G题里控制类题目最可靠的做法。2.3 中断里只做采集主循环里只做决策这是G题代码骨架里最重要的一条分工原则。很多队伍把编码器读数、陀螺仪融合、PID计算全放在定时器中断里理由是控制周期要准。但中断服务函数越长主循环越容易被饿死一旦某个中断里跑了一个耗时不确定的运算整个系统的实时性就崩了。而且中断里调用浮点运算还有一个隐藏问题浮点单元在处理高精度运算时会被长时间占用其他中断进来只能干等延迟抖动加大。常见做法是中断里只做三件事读寄存器、存变量、置标志位。滤波、PID、状态机全部放在主循环里执行。代码结构如下// 定时器中断只负责标记数据就绪 volatile uint32_t g_sensor_ready 0; void TIM_IRQHandler(void) { enc_read_raw(); // 读编码器计数值存入全局变量 imu_read_raw(); // 读IMU原始值存入全局结构体 g_sensor_ready 1; // 置标志位不在中断里做滤波 } // 主循环等标志位再统一处理 while (1) { if (g_sensor_ready) { g_sensor_ready 0; filter_update(); // 低通/卡尔曼在这里执行 pid_update(); // PID在这里执行 motor_output_update();// 更新PWM输出 } fsm_run(); // 状态机放在最后推进 }这个结构的关键在于中断里只做「读寄存器→存变量→置标志」耗时是微秒级的符合中断处理函数要短的原则。滤波和PID放在主循环里计算耗时可以浮动只要控制周期基本稳定就没问题。g_sensor_ready必须用volatile修饰否则编译器很可能把这个变量优化到寄存器里主循环读到的永远是旧值系统就会变成「时灵时不灵」的玄学bug。控制周期的选择也有讲究。常见做法是速度环和电流环这类内环跑1kHz左右位置环和视觉处理这类外环跑50到200Hz。如果主循环里还有其他耗时任务比如屏幕刷新或者串口打印可以单独用一个低速定时器置标志位控制循环里只响应控制周期标志不然显示刷新会拖垮控制频率。实测下来这种改动往往比调任何PID参数都有效——因为系统的实时性不稳控制算法算得再准也白搭。3. 数据是控制的地基传感器预处理与融合参数3.1 三种数据的典型病编码器毛刺、陀螺仪零漂、视觉跳变G题控制对象的传感器组合无外乎编码器测速度和位移、IMU测姿态、摄像头做目标识别与定位。直接把这些原始数据喂给控制器系统一加反馈就会抖起来。三种数据各有各的毛病处理方式完全不同先认清症状再选方案。编码器的典型毛病是低速毛刺。电机堵转或者正反转切换瞬间AB相在临界位置会有反复跳变计数结果出现±1的抖动。这个抖动经过速度微分计算之后会被放大一帧速度值可能从0跳到几倍于正常值速度环碰到这种数据直接振荡。陀螺仪的典型毛病是零漂。静止时角速度输出并不严格为0而且这个零偏会随温度缓慢变化直接积分之后姿态角就开始往一个方向飘几分钟之内就能飘出好几度。视觉的典型毛病是跳变。目标被遮挡几帧后重新出现或者背景里有颜色相近的干扰物闪过检测输出的目标坐标会瞬间跳到一个不合理的位置这时候执行机构会猛地抽动一下。这三类问题的处理思路不一样。编码器毛刺用低通滤波或者滑动中值滤波消掉代价是速度环的相位滞后陀螺仪零漂需要启动时静态校准运行中用互补滤波让加速度计来纠正长期漂移视觉跳变则要靠限幅和预测——上一帧和这一帧的目标位置差超过一个阈值就认为当前帧检测异常暂时用上一拍的值替代。很多队伍把这三类问题混在一起想用一个「高级滤波」全解决结果每个方向都没处理好。3.2 一阶低通滤波截止频率到底设多少一阶低通滤波是消毛刺性价比最高的手段代码就几行参数就一个alpha。但alpha拍脑袋设要么滤不干净要么滞后太大。一阶低通的核心公式是当前输出等于上一次输出乘以alpha加上当前输入乘以一减alpha。alpha越大平滑效果越强跟踪越慢。typedef struct { float y_prev; // 上一次滤波输出 float alpha; // 滤波系数 0~1越大越平滑 } lp_filter_t; float lowpass_update(lp_filter_t *f, float x) { // 一阶低通新输出 alpha×旧输出 (1-alpha)×新输入 f-y_prev f-alpha * f-y_prev (1.0f - f-alpha) * x; return f-y_prev; }alpha和截止频率之间有明确对应关系不要靠蒙。alpha exp(-2π·fc/fs)其中fc是目标截止频率fs是采样频率。举个例子编码器采样周期是1ms也就是fs1000Hz想让速度环只保留20Hz以下的成分alpha exp(-2π×20/1000)算出来约等于0.88。从这个值起步再观察实际响应做微调比随机试alpha高效得多。实际调试时针对不同数据源的起步参考值如下应用对象采样率截止频率建议说明编码器速度1kHz15~30Hz滤毛刺频率太高滤不干净太低速度环滞后IMU角速度200Hz20~50Hz保留动态响应滤电路高频噪声视觉坐标30Hz2~5Hz视觉本身帧率低以压制跳动为主这里有一个血泪经验值得强调低通滤波带来的滞后对控制系统是坏事。如果系统出现等幅振荡先把滤波截止频率往高调一个量级看振荡是不是来自滤波滞后。很多人一看到振荡就动PID实际上数据链路没洗干净PID怎么调都压不住。我在帮A同学调一台云台装置时遇到过类似情况速度环加低通之后系统出现2Hz左右的等幅振荡换了三组PID参数都没解决最后把编码器滤波截止频率从10Hz调到50Hz振荡直接消失——数据环节的滞后被错怪成了控制器的问题。3.3 一维卡尔曼裁剪版在单片机上跑起来低通滤波只能处理单一数据源的高频噪声但G题里经常要做多传感器融合——比如用加速度计和陀螺仪融合出姿态角或者用编码器和视觉融合出位置。卡尔曼滤波是标准答案但完整版矩阵运算在主流Cortex-M系列单片机上有点重而且状态维数一高调试难度成倍增加。这里我给一个一维裁剪版适用于对单个测量量的最优平滑也可以作为多源融合的基础组件。typedef struct { float x; // 状态估计值 float p; // 估计误差协方差 float q; // 过程噪声协方差越大越信测量 float r; // 测量噪声协方差越大越信预测 } kalman_1d_t; void kalman_1d_init(kalman_1d_t *k, float init_x) { k-x init_x; k-p 1.0f; k-q 0.01f; // 起步值按实际响应调 k-r 0.1f; // 起步值按实际响应调 } float kalman_1d_update(kalman_1d_t *k, float z) { // 预测系统模型为静态协方差加上过程噪声 k-p k-p k-q; // 卡尔曼增益权衡预测和测量的置信度 float kgain k-p / (k-p k-r); // 更新状态用新测量修正预测 k-x k-x kgain * (z - k-x); // 更新协方差 k-p (1.0f - kgain) * k-p; return k-x; }这段代码去掉了矩阵运算和状态转移矩阵只剩下加减乘除在常见的Cortex-M系列单片机上跑完全没问题。参数里q和r的比值决定一切q/r越大滤波器越相信测量值响应快但噪声大q/r越小越相信预测值平滑但滞后明显。建议先固定r不动只调q等曲线形态满意了再整体缩放q和r来调整收敛速度。一个实用的现场调试方法给滤波器输入一段有明显阶跃的原始数据观察融合输出。如果曲线平滑但阶跃处明显跟不上说明r偏大把r缩小一半再试如果曲线还有明显毛刺说明r偏小把r加大一倍。注意q和r同时变动是调参大忌你永远不会知道是哪边起的作用。另外这个一维卡尔曼的定位是「对单一测量源做最优平滑」如果要做编码器和视觉的位置融合正确做法是分别对两个源做一维卡尔曼然后按各自r值的反比做加权合成——两个r值分别代表两个传感器各自的信任度比值越小越值得被相信。4. PID不玄学调参顺序与代码落法4.1 位置式还是增量式G题场景里怎么选PID的代码网上到处都是真正拉开差距的是「知道选哪种形式」和「知道先调哪个参数」。位置式PID输出的是执行机构的绝对值适合需要明确给定位置的场合比如舵机打角、云台角度控制——输出直接对应到一个绝对角度。增量式PID输出的是本次应该增加的量适合本身带积分性质的执行机构比如直流电机的PWM调速——上一拍的输出加上增量就是这一拍的输出电机这个对象天然就是一个积分器。两种形式的对比一张表能说清楚比较项位置式增量式输出含义当前执行量绝对值本次增量是否需要保存历史输出不需要每拍独立算需要输出累加对积分饱和的敏感度高必须加抗饱和低但输出累积误差需关注典型场景舵机、云台角度、倒立摆角度电机速度环、循迹差速G题里最常见的运动控制场景速度环用增量式比较稳因为执行机构是电机PWM的累加效应天然存在位置式反而容易因为一拍的异常输出造成电机猛冲。云台这类角度控制则用位置式增量式在目标角度附近会因为累积误差来回震荡。一个快速判断方法看执行器有没有记忆效应。舵机和云台的角度是保持性的用位置式电机转速不给定PWM就掉下来用增量式更顺。无论选哪种输出限幅都是必须的。G题现场任何一个坏数据进来如果没有输出限幅执行机构会直接打到极限位置——轻则装置冲出赛道重则损坏机械结构。这行保护代码是整个PID里性价比最高的一行。4.2 先P再I最后D一个不翻车的调参顺序PID调参翻车九成是因为「三个参数一起动出了问题时不知道是谁的锅」。我带的队伍我要求严格按P到I再到D的顺序走每一步只动一个参数并且记录当时的响应特征。第一步把I和D设成0只保留P项。从一个很小的值开始慢慢加大观察对象的响应P太小响应慢、到不了目标P适中系统有轻微超调但能稳定P过大系统开始持续等幅振荡。记下开始出现持续振荡的那个P值这是后续所有调参的基准。第二步在P的基础上加I。I的作用是消除稳态误差观察目标只有两个静态误差有没有被吃掉、系统有没有出现低频慢振荡。如果出现低频振荡说明I偏大积分项在目标附近反复积累过冲——这时候要么降低I要么加积分限幅。G题里强烈建议加积分限幅因为起步阶段目标差值大积分项一秒就能累积到很大的值目标到达之后积分回退慢超调一大截。第三步加D。D的作用是抑制超调但微分项对测量噪声极其敏感速度环里经常是D一加系统就高频抖动。所以D项必须在前面章节讲到的传感器滤波完成之后再调——否则你压的其实不是超调而是噪声经过微分放大之后的高频分量。这里有一个关键认知G题里如果P能调到系统不振荡优先不加D或者给很小的D。微分项是双刃剑它带来的高频噪声放大问题在比赛现场的电磁环境下会比实验室严重得多。现场环境的电机干扰、电源纹波、传感器线缆串扰都会让微分项变成噪声放大器。4.3 输出限幅、积分限幅、微分滤波三个必调的保护参数一个裸的PID公式在实验室的干净数据下跑没问题但比赛现场一个意外的大误差就能让积分饱和或者输出打满。一个带全套保护的PID实现才是G题现场能用的版本。typedef struct { float kp, ki, kd; // 三个增益 float out_max; // 输出限幅 float integral_max; // 积分限幅 float d_filter_alpha; // 微分低通系数 0.2~0.5 float integral; // 积分累计值 float prev_error; // 上一拍误差 float d_filted; // 滤波后的微分项 } pid_t; float pid_update(pid_t *p, float target, float current) { float error target - current; // 比例项直接输出 float p_out p-kp * error; // 积分项累加后限幅防止积分饱和 p-integral error; if (p-integral p-integral_max) p-integral p-integral_max; if (p-integral -p-integral_max) p-integral -p-integral_max; float i_out p-ki * p-integral; // 微分项先差分再低通防止噪声放大 float d_raw error - p-prev_error; p-d_filted p-d_filter_alpha * p-d_filted (1.0f - p-d_filter_alpha) * d_raw; float d_out p-kd * p-d_filted; p-prev_error error; // 总输出限幅 float out p_out i_out d_out; if (out p-out_max) out p-out_max; if (out -p-out_max) out -p-out_max; return out; }这段代码把所有容易翻车的位置全部保护住了。积分限幅误差持续偏大时积分项被限幅挡住不会积累到几百几千目标到达之后超调幅度可控。微分低通直接用error差做微分误差一跳微分项就巨大加一个低通系数让微分项平滑下来这个系数一般取0.2到0.5越大越平滑。输出限幅总输出一旦超过out_max直接截断这行代码在正常调试时好像无所谓但现场一个坏数据进来时就是靠它兜底。调参锚点可以给一组我常用的起步值外环位置环kp取0.5到2.0内环速度环kp取5到15ki取kp的十分之一到五分之一kd最后加且从小值起步。但这些只是起步锚点不是万能参数真正的调参方法还得回到上一节说的P到I到D顺序。另一个建议是把每次调参的结果记录下来包括目标值、增益、现象——不带记录的调参就是原地打转调了一晚上第二天全忘光。5. 常见问题排查现场最容易翻车的五个坑5.1 上电瞬间执行机构猛冲一下现象代码烧录后一上电电机或者舵机猛动一下有的装置直接冲出起始区域。原因上电瞬间PID内部状态没有初始化prev_error默认值不确定如果当前误差刚好很大第一拍比例项就会输出巨大值另外电机驱动芯片在供电建立过程中PWM引脚电平不确定也可能输出一个短暂的异常占空比。解决分两步处理。第一步在所有外设初始化和传感器校准完成之后再启动控制任务main函数开头只做初始化不要一进来就调用control_loop_running第二步在电机驱动接口加一个使能门初始化期间PWM输出强制为0所有初始化完成之后再打开使能。这个使能门的实现很简单就是初始化结束前让设备处于输出封锁状态初始化结束后切到正常状态对可靠性提升非常明显。5.2 陀螺仪零漂让装置慢慢自己转起来现象静止状态下装置状态正常运行一两分钟后缓慢偏向一侧越来越明显。原因陀螺仪的零漂不是固定值温度升高之后零偏会缓慢变化纯积分姿态估计必然漂移也可能是启动时静态校准采集帧数太少平均值偏差没校干净。解决启动时增加至少一秒钟的静态数据采集取平均值写进校准参数运行中加一个轻量高通滤波把低频漂移压掉或者直接用互补滤波把加速度计作为长期校正源。加速度计在静止时的长期精度远高于陀螺仪积分陀螺仪短期精度高互补滤波结合起来就是G题里性价比最高的姿态方案。注意互补滤波的融合系数也是需要现场调的——加速度计权重太大会引入高频抖动太小又校正不住漂移一般从0.02起步调整。5.3 中断里跑浮点运算控制周期一抖一抖现象系统时而灵敏时而迟钝用示波器看PWM占空比波形偶尔出现一个异常跳动控制效果不稳定。原因中断服务函数里直接调用了卡尔曼或浮点PID运算。这些函数执行时间会因数据内容不同而浮动如果碰上浮点单元被其他运算占用中断时长远超设定周期主循环里的标志位被反复置位控制节奏全乱。更要命的是这种问题很难复现排查起来非常耗时。解决把滤波和PID计算全部移到主循环中断里只留读寄存器、存变量、置标志位。这个改动是这个章节里价值最高的一条——它不增加任何算法复杂度只是重新划分了任务的执行位置但系统实时性会立刻变稳。判断方法很简单把中断服务函数里的代码全部注释掉换成标志位如果系统变好了说明问题就在中断里。5.4 摄像头在实验室好好的赛场识别率掉一半现象实验室里用一套固定的曝光和阈值参数对目标识别率很高到了赛场换了一个环境光照和背景颜色识别率断崖式下降目标偶尔丢失。原因视觉参数是依据实验室光照条件调的赛场的光线色温、窗户反光、地面颜色都会改变像素分布固定曝光参数在亮度差异大的环境下会过曝或欠曝目标颜色特征直接失真。解决在视觉代码里至少加两个保护第一曝光参数改自动模式或者按场景预置两套参数通过串口命令切换第二目标识别不要用单一硬阈值做二值化改用相对统计的方法——在目标颜色附近做一个概率加权的质心计算降低对绝对阈值的依赖。这一步对于G题里大量依赖摄像头找目标的题目是保命级的很多队伍在赛场上挂掉不是机械或控制问题而是视觉数据本身不可靠。5.5 现场改了一个参数程序「变慢」了现象现场把PID增益调大之后整个控制循环明显变慢液晶刷新开始卡顿反应迟钝。原因增益变大导致系统进入振荡控制输出频繁到达限幅值陷入深度饱和同时振荡让误差信号变化剧烈微分项持续输出较大值运算路径变长另外现场的调试器连接和屏幕刷新本身就占用了CPU周期被误判为程序变慢。解决第一步拔掉调试器和显示屏确认「慢」是否来自外部因素第二步检查输出是否频繁等于out_max——如果输出几乎每一拍都顶着限幅跑说明系统已经深度饱和不是程序变慢了是控制失效了要从限幅值和积分限幅重新调。这里有一个容易忽略的细节G题现场很多人插着屏幕跑到最后显示屏的刷新对控制周期的影响在慢速场景下不明显但在高速运动控制中可能直接吃掉三分之一的主循环时间紧急时刻果断拔屏。6. 从「跑通」到「跑稳」最后一公里只做三件事方案分享到这里骨架、滤波、PID和坑都讲完了最后说一个大多数队伍都没做的事——鲁棒性验证。跑通和跑稳之间差距很大一个能走完完整流程的装置和一个能在现场环境下稳定重复的装置是两种完全不同的调试深度。比赛前的最后一周值得把精力全放在三件事上。第一件连续运行测试。每天至少让装置完整运行30分钟以上记录每次运行中出现的异常——不管是一个小小的抖动还是偶发的温度漂移全部记下来。很多问题需要长时间运行才会暴露陀螺仪温度零漂、电机发热导致摩擦系数变化、电池电压下降之后PWM响应差异。只跑三分钟验证不出任何一个。我印象很深的一次某支队伍在现场的第三轮测试中突然出现大幅度漂移排查到最后是电池从满电状态掉到某个电压区间后电机响应变得迟钝——这在三分钟短测里完全发现不了。第二件真值回放。把传感器原始数据录下来回放时用同一份数据反复测试算法。这样改一次滤波参数、调整一次PID都能用相同输入对比输出差异。没有这样一套离线调参工具现场每次改参数都靠肉眼和经验判断来回折腾半天也还原不了「昨天那个参数」。回放工具不用做得多复杂串口把原始数据发给电脑存成文件电脑读取文件逐帧喂给算法就行。第三件参数热切换。G题现场的时间是按分钟算的每改一个参数重新编译烧录一次一天就没了。在代码里加一个串口命令解析通过特定格式的报文在线修改PID参数和滤波系数现场反馈调试效率能提升一个量级。我习惯在每次训练结束后把当天调过的所有参数和现象记录写进代码文件头注释里比赛现场翻一下就知道哪组参数在什么条件下出现过什么表现——不然第二天醒来只剩一句「昨天调得还行」。这个习惯帮我省了很多重复劳动也推荐给你。这套方案的每一块从模块化代码骨架到传感器数据预处理再到PID的完整保护和鲁棒性验证都是G题备赛里最常规也最可靠的做法。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑