ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

电磁循迹小车的PID控制:归一化与增量式算法实战

电磁循迹小车的PID控制:归一化与增量式算法实战 1. 项目概述为什么电磁循迹小车必须从“控制算法”开始啃硬骨头在智能车竞赛圈里有句老话“摄像头组拼硬件电磁组拼算法。”这话不是贬低谁而是实打实的行业共识——电磁传感器不直接输出图像它只给你一根随磁场强度变化的模拟电压曲线没有视觉特征可提取没有边缘可识别你手里唯一的“眼睛”就是那根抖动的、带噪声的、非线性的电压信号。我带过三届校队每年都有学生拿着新焊好的电磁板兴奋地跑来“老师传感器接上了电压能读出来”结果一上赛道小车像喝醉一样左右乱晃要么猛冲出界要么原地画圈。问题从来不在传感器本身而在于——你根本没想清楚这根电压曲线到底该怎么翻译成电机该转多快、舵机该打多少角度这就是“控制算法”的本质它不是代码堆砌而是把物理世界的连续变化磁场强度→电压→位置偏差映射成执行机构的精准动作PWM占空比→电机转速→小车轨迹的数学桥梁。标题里那个“基本”二字恰恰是最容易被轻视的陷阱。很多人以为PID就是调三个数调顺了就完事但真正跑过21届、22届全国大学生智能车竞赛电磁组赛道的人都知道一个没归一化的PID在直道上稳如泰山进弯道瞬间就发散一个没考虑采样周期与电机机械惯性的增量式算法再好的参数也扛不住坡道减速时的积分饱和。所以这篇内容不讲高大上的LQR或MPC预测控制就死磕最底层、最真实、最常被忽略的“基本”如何让PID在电磁循迹这个特定场景里真正活起来、稳下来、跑得准。它适合所有刚接触电磁循迹的新手也适合那些调参调到怀疑人生的“老手”——因为很多坑不是你不够努力而是你从一开始就没把算法和物理系统真正对齐。2. 核心思路拆解为什么电磁循迹不能照搬温度控制或电机转速控制的PID2.1 电磁循迹的物理本质一个强耦合、非线性、带延迟的动态系统先抛开代码回到小车本身。一辆典型的电磁三轮智能小车核心反馈来自安装在车头下方的几路电感线圈。当线圈靠近赛道中心的导线时交变磁场引起线圈感应电动势变化经检波、滤波后输出一个直流电压。这个电压值理论上应该与线圈到导线中心的横向距离即“偏差”呈某种函数关系。但现实是残酷的非线性严重在中心附近±5mm电压变化平缓灵敏度低靠近边界±15mm电压陡升极易饱和。我用示波器实测过某款常用LC谐振电路其输出电压与实际偏差的关系曲线根本不是一条直线而是一条S型曲线中间段斜率接近0.3V/mm两端却飙升到2.5V/mm以上。强耦合前轮转向角不仅影响横向位置还直接影响前进速度转向阻力增大电机转速变化又会改变电感线圈切割磁场的速度从而影响感应电压幅值。这意味着你单独调好转向PID一加上速度闭环转向响应立刻变慢甚至震荡。固有延迟从传感器采样、AD转换、算法计算、PWM更新再到电机响应、车体运动、偏差反馈回来整个环路存在至少15ms的纯延迟。这个延迟在高速3m/s下意味着小车已经向前移动了45mm才“意识到”自己偏了——这足以让它冲出弯道。这些特性决定了你绝不能把工业温控里那套“PB20, TI180s, TD10s”的经验值或者电机转速控制里“Kp1.2, Ki0.05, Kd0.1”的参数直接搬过来。温控对象是热容大、惯性大的炉膛响应以秒计电机转速控制面对的是转动惯量明确的转子模型相对干净。而电磁小车是一个在毫秒级时间尺度上剧烈变化、且模型处处“打补丁”的系统。2.2 “基本控制算法”的真正含义从开环到闭环从位置式到增量式所谓“基本”是指构建一个稳定、可靠、可调试的控制骨架。这个骨架必须包含三个不可省略的环节偏差获取与归一化Preprocessing这是整个算法的“输入端”。原始AD值比如0-4095毫无物理意义必须转换成有单位的偏差如-20mm到20mm并进行归一化处理消除不同传感器、不同赛道、不同供电电压带来的量纲差异。网络热词里反复出现的“归一化”、“正交归一化极差”指的就是这个环节。它不是锦上添花而是雪中送炭。没有它Kp参数永远在“试”有了它Kp的物理意义就变成了“每毫米偏差应产生多少度的转向角”。核心控制器选型Core ControllerPID是基石但怎么用大有讲究。位置式PID输出的是绝对控制量如舵机目标角度对积分项的累积非常敏感一旦小车短暂失迹偏差极大积分项会疯狂累积导致恢复后严重超调。而增量式PID输出的是本次控制量相对于上次的“增量”天然抗积分饱和更适合电磁小车这种可能频繁进出磁场的场景。这也是为什么“增量式pid算法”在热词中高频出现。执行机构适配Actuator Interface控制器的输出比如-30°到30°的转向角必须安全、线性地映射到执行器舵机或差速电机。这里涉及死区设置避免微小偏差引起舵机高频抖动、输出限幅防止舵机打满撞坏、以及最重要的——内外环设计。热词里提到的“级联pid控制”、“内外环的作用及时间间隔”正是解决强耦合问题的关键。外环位置环负责根据偏差计算出期望的转向角内环速度环或电流环则负责让舵机以最快、最平稳的方式到达那个角度。两个环的采样周期必须错开通常外环10ms内环2ms否则会引发高频震荡。这三步环环相扣。跳过归一化PID就是无源之水用错位置式调试就是一场灾难不设内外环系统就是一盘散沙。这才是“基本”的分量。2.3 为什么“预测控制算法”和“LQR”在此刻是干扰项看到热词里有“预测控制算法”、“LQR控制算法”很多新手会跃跃欲试。我必须坦诚地说在你还没把基础PID跑稳之前去碰这些99%的概率是给自己挖一个更深的坑。LQR需要精确的系统状态空间模型而电磁小车的模型连资深教授都还在研究预测控制依赖准确的未来轨迹预测但在未知弯道、不同摩擦系数的赛道上预测本身就是个伪命题。卓晴老师21届智能车权威指导者在多次分享中都强调“能把PID调到‘稳、准、快’就已经超越了80%的参赛队。” 把精力聚焦在理解偏差、吃透归一化、掌握增量式PID的离散化实现才是通往更高阶算法的唯一正途。就像学游泳必须先学会漂浮和划水再去研究蝶泳的流体力学。3. 核心细节解析归一化、增量式PID与内外环的实操要点3.1 归一化让算法摆脱硬件束缚的“翻译官”归一化不是简单的“除以最大值”。它的目标是让控制器的输入偏差和输出控制量都落在一个标准、无量纲、易于理解和调试的区间内通常是[-1.0, 1.0]或[0.0, 1.0]。对于电磁循迹我们采用“双点标定法”这是最稳健、最贴近物理实际的方法。实操步骤物理标定将小车静止放置在赛道上。用游标卡尺精确测量当车头电感线圈中心与赛道导线中心完全重合时偏差0mm记录此时AD采样值记为AD_center。边界标定将小车向左平移直到线圈中心刚好到达赛道最左边界此时小车即将脱线记录AD值记为AD_left。同理向右平移到最右边界记录AD_right。计算归一化系数AD_range (AD_right - AD_left) / 2.0// 理论上左右边界到中心的距离应相等normalized_error (AD_value - AD_center) / AD_range// 这就是最终输入给PID的偏差值为什么这个方法有效它自动补偿了传感器的零点漂移AD_center可能不是2048、增益不一致AD_range因线圈Q值、电容精度而异以及供电电压波动所有AD值同比例缩放AD_range也同比例缩放比值不变。我曾用同一块板子在不同电池电压7.2V vs 8.4V下测试未归一化时Kp需从1.5调整到2.1归一化后Kp稳定在1.85误差小于5%。提示标定必须在赛道上进行不能在实验室用信号源模拟。因为实际磁场分布受赛道材质、埋线深度、周围金属干扰影响巨大实验室环境无法复现。3.2 增量式PID的离散化实现告别积分饱和的“安全阀”位置式PID的离散化公式是u(k) Kp * e(k) Ki * T * Σe(i) Kd * (e(k)-e(k-1))/T。其中u(k)是第k次的控制输出。问题在于Σe(i)即所有历史偏差的累加。当小车在直道上完美居中时e(k)≈0u(k)稳定但一旦进入一个长弯道e(k)持续为负比如-0.3Σe(i)就会像滚雪球一样越积越大。当小车终于驶出弯道e(k)突然变为0.1巨大的负积分项会让u(k)瞬间变成一个很大的负值舵机猛打小车剧烈甩尾。增量式PID完美规避了这个问题。它的核心思想是我不关心“应该打多少度”我只关心“这次比上次多打多少度”。其离散化公式为Δu(k) Kp * [e(k) - e(k-1)] Ki * T * e(k) Kd * [e(k) - 2*e(k-1) e(k-2)] / T最终的控制输出为u(k) u(k-1) Δu(k)关键参数解释与选择Kp比例增益决定响应速度。值越大转向越“激进”。电磁小车典型值0.8 ~ 1.5。过大则直道振荡过小则弯道迟钝。Ki积分增益用于消除静态偏差比如小车总是在中心右侧1mm处稳定。但必须极其谨慎电磁系统静态偏差本就不大Ki稍大就会引发低频振荡。建议初始值设为0待Kp、Kd调稳后再以0.001为步进缓慢增加。Kd微分增益提供阻尼抑制超调和振荡。它对噪声极其敏感因此Kd项的输入必须是经过强滤波的偏差。典型值0.05 ~ 0.2。Kd过大会让小车在路面不平时“发飘”。注意T是采样周期单位为秒。如果你的主循环是10ms一次则T 0.01。这个值必须精确否则Ki和Kd的物理意义全乱。我见过太多人因为T写成10导致Ki放大了100倍系统直接崩溃。3.3 内外环级联解开转向与速度耦合的“金钥匙”单环PID无论怎么调都无法同时兼顾“转向快”和“转向稳”。因为舵机本身就是一个二阶系统有固有的上升时间和超调。当你用一个PID直接驱动舵机PWMKp大了响应快但超调大Kp小了超调小但响应慢小车在弯道里“拖着走”。解决方案是级联。外环是“位置环”它的任务是根据归一化后的偏差e计算出一个“理想的舵机目标角度θ_target”。内环是“角度环”它的任务是接收θ_target并驱动舵机以最快、最平稳的方式到达那里。外环位置环实现输入e normalized_error控制器一个独立的增量式PID输出Δθ。输出θ_target θ_target_prev Δθ关键θ_target必须做限幅比如-30° θ_target 30°防止舵机打满。内环角度环实现输入e_angle θ_target - θ_actual其中θ_actual由舵机自带的电位器或编码器读取。控制器另一个增量式PID但参数完全不同。它的Kp可以很大比如5~10因为目标是快速跟踪Ki和Kd则较小。输出舵机PWM信号。时间间隔设计外环运行在10ms周期足够捕捉赛道变化内环必须更快通常设为2ms。这意味着每10ms外环算一次θ_target在这10ms内内环会执行5次不断修正舵机的实际角度。这种设计让外环专注于“我要去哪里”内环专注于“我怎么快速、平稳地到那里”彻底解耦了路径规划与执行机构动力学。4. 实操过程从零开始搭建一个可运行的电磁循迹PID框架4.1 硬件与软件环境准备硬件清单最低配置主控STM32F103C8T6“蓝 pill”开发板成本10元性能绰绰有余传感器3路LC谐振电磁传感器推荐使用卓晴老师开源的“电磁三轮”方案频率100kHz执行器MG90S舵机转向、TB6612FNG电机驱动驱动直流电机调试工具ST-Link V2仿真器、USB-TTL串口模块用于printf调试软件环境IDESTM32CubeIDE免费图形化配置强大关键库HAL库官方稳定、CMSIS-DSP库用于后续的FFT滤波初始化关键步骤时钟树配置系统时钟72MHzAPB2GPIO, ADC, TIM172MHzAPB1TIM2, TIM336MHz。这是保证定时精度的基础。ADC配置使用ADC1通道1、2、3分别接三路传感器。开启扫描模式、连续转换、DMA传输。采样时间设为239.5个ADC周期约17us确保精度。定时器配置TIM2作为主控制循环更新周期10ms72000000/7200 10000Hz → 10ms中断。这是外环的节拍器。TIM3作为内环节拍器更新周期2ms72000000/36000 2000Hz → 2ms中断。TIM1高级定时器用于生成互补PWM驱动TB6612FNG。串口配置USART1波特率115200用于打印调试信息。务必开启DMA发送避免printf阻塞主循环。实操心得很多新手卡在第一步——ADC读数不准。原因90%是电源。电磁传感器对电源纹波极其敏感。必须给传感器供电单独加一级LC滤波10uH电感 100uF电解电容并且ADC的VREF引脚要接一个100nF陶瓷电容到地。我曾为一个0.5V的读数偏差排查了三天最后发现是共用的5V电源上电机启动时的瞬态压降干扰了ADC参考电压。4.2 核心代码框架与关键函数实现以下为main.c中的核心逻辑框架所有函数均需在对应中断服务程序ISR中调用。// 全局变量定义 float ad_values[3]; // 三路ADC原始值 float normalized_error; // 归一化后的横向偏差 float theta_target 0.0f; // 外环输出的目标舵机角度 float theta_actual 0.0f; // 内环读取的实际舵机角度 float pwm_output 0.0f; // 最终输出给电机的PWM占空比 // 外环PID结构体 typedef struct { float Kp, Ki, Kd; float T; // 采样周期单位秒 float e_prev[2]; // 存储e(k-1), e(k-2) float u_prev; // 存储u(k-1) } PID_Controller_t; PID_Controller_t outer_pid {1.2f, 0.005f, 0.1f, 0.01f, {0}, 0}; // 内环PID结构体参数不同 PID_Controller_t inner_pid {8.0f, 0.01f, 0.05f, 0.002f, {0}, 0}; // 主控制循环TIM2中断10ms void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim-Instance TIM2) { // 1. 读取最新ADC值DMA已自动搬运到缓冲区 for(int i0; i3; i) { ad_values[i] (float)adc_buffer[i]; } // 2. 计算归一化偏差使用3路值取中位数滤波 float median_ad get_median(ad_values[0], ad_values[1], ad_values[2]); normalized_error (median_ad - AD_center) / AD_range; // 限幅防止异常值 if(normalized_error 1.0f) normalized_error 1.0f; if(normalized_error -1.0f) normalized_error -1.0f; // 3. 外环PID计算 float delta_theta pid_incremental_calculate(outer_pid, normalized_error); theta_target delta_theta; // 舵机角度限幅 if(theta_target 30.0f) theta_target 30.0f; if(theta_target -30.0f) theta_target -30.0f; // 4. 更新电机速度简单比例控制后续可升级为速度环 pwm_output 0.5f 0.3f * (1.0f - fabsf(normalized_error)); // 直道全速弯道降速 if(pwm_output 0.2f) pwm_output 0.2f; // 保底速度 set_motor_pwm(pwm_output); } } // 内环控制TIM3中断2ms void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim-Instance TIM3) { // 1. 读取舵机实际角度通过ADC读取电位器电压 theta_actual read_servo_potentiometer(); // 此函数需自行实现 // 2. 计算角度偏差 float e_angle theta_target - theta_actual; // 3. 内环PID计算 float delta_pwm pid_incremental_calculate(inner_pid, e_angle); float servo_pwm 1500.0f delta_pwm * 100.0f; // 将-1~1映射到1400~1600us set_servo_pwm(servo_pwm); // 此函数需自行实现 } } // 增量式PID核心计算函数 float pid_incremental_calculate(PID_Controller_t* pid, float e_now) { float delta_u; float e_prev pid-e_prev[0]; float e_prev2 pid-e_prev[1]; // 增量式PID公式 delta_u pid-Kp * (e_now - e_prev) pid-Ki * pid-T * e_now pid-Kd * (e_now - 2.0f * e_prev e_prev2) / pid-T; // 更新历史值 pid-e_prev[1] e_prev; pid-e_prev[0] e_now; pid-u_prev delta_u; return delta_u; }代码关键点解析中位数滤波三路传感器数据取中位数是电磁组最经典、最有效的抗脉冲干扰方法。比均值滤波更能抵抗单路传感器的瞬间失效。外环与内环分离TIM2和TIM3的中断是完全独立的互不干扰。theta_target是它们之间唯一的共享变量且无需加锁因为TIM3只读TIM2只写且TIM3频率更高不会读到“半写”状态。set_motor_pwm()与set_servo_pwm()这两个函数必须是原子操作即在设置PWM寄存器时禁止相关中断防止被其他中断打断导致波形畸变。4.3 参数整定从“瞎蒙”到“有据可依”的调参四步法调参不是玄学而是一门需要耐心和记录的工程实践。我总结了一套适用于电磁小车的“四步法”比传统的“先Kp再Ki最后Kd”更高效、更安全。第一步冻结Ki和Kd只调Kp找临界稳定点将Ki0,Kd0Kp从0.1开始每次增加0.2。在直道上运行观察小车行为Kp0.5小车缓慢蠕动几乎不转向偏差很大。Kp1.0小车能大致跟线但有轻微左右摇摆。Kp1.4摇摆加剧出现明显“蛇形”。Kp1.6摇摆频率加快幅度变大接近临界振荡。记录下这个临界Kp_cr比如1.6和对应的振荡周期T_cr用示波器或高速摄像机测比如0.8秒。第二步应用Ziegler-Nichols经验公式获得初始参数Kp 0.6 * Kp_cr 0.96Ki 1.2 * Kp_cr / T_cr 1.2 * 1.6 / 0.8 2.4Kd 0.075 * Kp_cr * T_cr 0.075 * 1.6 * 0.8 0.096注意这里的Ki和Kd是针对位置式PID的。对于我们的增量式需要按公式换算但更重要的是这个Ki2.4是绝对不能直接用的它太大了会导致严重积分饱和。我们把它当作一个“上限”然后从Ki0.001开始逐步试探。第三步精细调节Kd抑制振荡固定Kp0.96Ki0.001将Kd从0.05开始每次增加0.02。观察弯道表现Kd0.05时入弯略有超调Kd0.09时超调消失但出弯略显迟钝Kd0.11时出弯干脆利落且直道振荡被完全抑制。选定Kd0.11。第四步微调Ki消除残余偏差固定Kp0.96,Kd0.11Ki从0.001开始每次增加0.0005。运行长直道10米观察最终稳定位置。Ki0.0025时小车稳定在中心线右侧0.3mmKi0.003时稳定在中心线上Ki0.0032时开始出现缓慢的左右漂移低频振荡。最终选定Ki0.003。终极技巧制作“参数-赛道”对照表不同赛道PVC、木板、水泥的摩擦系数、磁场强度不同最优参数也不同。我要求所有队员每次换赛道必须记录下当时的Kp/Ki/Kd并拍照留存赛道照片。一年下来我们积累了20组数据形成了自己的“参数地图”。下次遇到类似赛道参数就有了80%的把握。5. 常见问题与排查技巧实录那些让你熬夜到凌晨三点的“幽灵Bug”5.1 问题速查表症状、原因与一招制敌的解决方案症状可能原因快速排查与解决方案小车在直道上左右高频抖动频率5HzKd过大或Kd项输入未滤波放大了传感器噪声1. 立即将Kd减半2. 在pid_incremental_calculate函数入口对e_now进行一阶低通滤波e_now 0.8f * e_now 0.2f * e_prev_filter; e_prev_filter e_now;小车入弯时严重超调冲出赛道Kp过大或Kd过小缺乏阻尼1. 检查Kp是否超过1.52. 尝试将Kd提高50%3.最关键的检查归一化标定。AD_range是否太小导致normalized_error被过度放大。用万用表实测AD_left和AD_right重新计算。小车在长直道末端总是稳定在一个固定偏差如2mmKi过小积分作用不足以消除静态偏差或存在机械死区如舵机齿轮间隙1. 缓慢增加Ki步进0.00012. 在set_servo_pwm()函数中加入死区补偿if(fabsf(e_angle) 0.5f) { servo_pwm 1500; } else { ... }小车在坡道上速度明显下降且转向响应变慢电机供电电压下降导致舵机扭矩不足内环跟踪能力下降或外环Kp未随速度自适应1. 测量坡道上电池电压若低于7.0V需更换电池或加装稳压模块2.高级技巧将Kp改为速度自适应Kp_adaptive base_Kp * (1.0f 0.5f * (base_speed - current_speed)/base_speed);串口打印的normalized_error值在0附近疯狂跳变±0.3传感器供电不稳或PCB布线不合理数字地与模拟地未单点连接1. 用示波器看VCC_sensor纹波若50mV加LC滤波2. 检查PCB确保AGND和DGND仅在ADC芯片的GND引脚处连接一点。5.2 那些“教科书上不会写”的独家避坑经验经验一“采样时刻”比“采样频率”重要一百倍很多教程只告诉你“10ms采样一次”但没说“在哪一刻采样”。电磁传感器的输出电压是LC谐振电路的包络线它本身就有周期性波动。如果ADC的采样时刻恰好每次都落在包络线的波峰或波谷那么你的AD_value就会系统性地偏高或偏低导致归一化失效。我的做法是在TIM2中断里不立即启动ADC而是先延时一个随机的微秒数比如100us再触发ADC转换。这个微秒级的抖动能有效打散采样点与包络线的相位关系让长期平均值回归真实。经验二“舵机打满”不是故障是算法在报警当theta_target频繁达到±30°限幅值时不要第一反应去修舵机。这说明外环的控制力已经到了极限它在拼命“拉”小车回中心但物理上做不到。此时真正的病根往往在Kp或赛道本身。Kp过大会让小车对微小偏差反应过度导致舵机频繁打满赛道磁场过弱如埋线太深也会让传感器灵敏度下降同样导致舵机打满。解决方法降低Kp或用信号发生器给传感器注入一个更强的测试信号确认是硬件问题还是算法问题。经验三永远相信你的“眼睛”而不是你的“代码”我见过最离谱的一个Bug小车在赛道上跑得好好的但串口打印的normalized_error始终是0。排查了两天最后发现是printf函数里的格式化字符串写错了printf(error: %f\n, normalized_error);而normalized_error是float但%f在ARM Cortex-M3上默认期望double导致栈错乱printf后面的所有变量都被污染。解决方案在printf前加一句__NOP();用调试器单步亲眼看到normalized_error的值是否真的为0。很多时候“现象”和“日志”不一致问题就出在日志本身。经验四给你的PID加一个“紧急刹车”在高速比赛中任何意外都可能发生传感器被灰尘覆盖、赛道上有水渍、电机突然堵转。一个没有保护的PID会在错误的偏差信号下输出毁灭性的控制量。我在所有PID输出后都加了一层“安全网”// 在计算完theta_target后 if(fabsf(theta_target - theta_target_prev) 5.0f) { // 本次舵机角度变化超过5度视为异常强制平滑过渡 theta_target theta_target_prev 5.0f * sign(theta_target - theta_target_prev); } theta_target_prev theta_target;这行代码救了我们队三次。它让小车在遭遇突变时不是“猛打”而是“缓打”给了你宝贵的几毫秒反应时间。6. 总结与延伸当PID成为肌肉记忆之后写到这里你应该已经明白标题里的“【智能车学习】电磁循迹中的基本控制算法”远不止是“调三个数”那么简单。它是一整套从物理世界感知传感器、到信息抽象归一化、再到决策执行PID、最后到机械落实内外环的完整闭环。每一个环节都浸透着工程实践的智慧与妥协。我个人在带队过程中最大的体会是最“基本”的东西往往最难精通。一个能稳定跑完全场、不靠运气、不靠“玄学”的PID参数背后是几十次赛道测试、上百次参数微调、以及对传感器噪声、电机惯性、舵机响应等无数物理细节的深刻理解。它不像LQR那样炫酷但它扎实、可靠、可复现是所有高阶算法的地基。这个内容后续还可以这样扩展当你把这套PID框架跑稳之后下一步自然就是“让它更聪明”。比如用卡尔曼滤波融合陀螺仪数据让偏差估计更鲁棒用查表法Look-Up Table替代线性归一化精确拟合S型曲线或者把外环的PID升级为一个基于赛道曲率预测的前馈反馈复合控制器。但所有这些都建立在一个前提之上——你已经把“基本”二字刻进了自己的肌肉记忆里。最后再分享一个小技巧每次调参成功后不要只保存代码。用手机录一段小车跑动的视频把当时的参数、赛道照片、电池电压、甚至当天的室温都记在一个文本文件里和视频一起打包。一年之后当你看到这个包你会清晰地看到自己技术成长的每一步脚印。
返回列表