电驴骑到 35续航为什么腰斩我把这件事算成了一道可复算的二次函数一键开通华为云 码道 CodeArts 代码智能体https://developer.huaweicloud.com/codeartsco.html?sourcedmzntgwatomgit1sourceaddmzntgwatomgithd作品是什么仓库叫ebike-range-physics开源在 atomgitMIT 协议地址我放在文末。它干的事一句话能说清把电动自行车的续航算成一道物理题。拖一下速度滑块读数区实时给你当前速度下的总功率、每米能耗、续航以及相对 25km/h 还剩百分之几画布上叠一条新国标限速线让你亲眼看见 25 和 35 之间那截落差有多大再把厂商标称的48V12Ah 跑 45 公里拿去反解风阻面积 CdA用解出来的数预测超速后的续航看它自己能不能闭环。开发工具是华为云码道 CodeArts Agent账号 ZuoDa01。这里我得把立场先摆明白后面全文都按这个口径写仓库里每一行代码都是码道生成的包括package.json里那行test: node --test。我干的活是选题、把提示词钉到函数签名一级、自己写独立脚本算锚点、再写一份互不引用的参考实现跑差分对拍、跑测试复核以及——被纠错纠我自己的错也被它纠。为什么做这个起因特别不高级。前几个月身边有人把电动车限速解到 35骑了两周开始骂街说标称六十公里的车实际跑不到四十。几个人凑一块儿猜有人说电池被撑坏了有人说电机效率掉了还有人说速度涨四成电耗涨四成那不就是打个七折嘛。最后这句把我说住了。它听着最讲道理可对不上账真要是打七折那 45 km/h 就该剩一半多一点可实际感受是随便骑骑就没电。谁也给不出一个能照着算第二遍的解释。网上的回答基本停在速度越快风阻越大越费电这种正确的废话上它既不能告诉你 35 该剩多少也不能告诉你为什么不是七折。我当时就想这不就一道高二物理题吗。滚阻是速度的线性函数风阻是速度的三次方函数两个加起来除以速度得到每米能耗——一个干净的二次函数。续航是能量除以每米能耗所以整个曲线一根式子就写完了。要解释为什么不是打七折只要把那个二次函数摆出来代三个数进去。于是有了这个项目。核心结论我一会儿全列出来每个数字你都能自己按计算器复算不是我拟合出来的也不是我抄厂商宣传页的。先跑起来看页面长这样。场景默认通勤标准车加人 120 kg、滚阻系数 0.015、CdA 0.55 m²、48V12Ah 也就是 576 Wh、2073600 焦耳。滑块停在 25总功率 235.4 W每米能耗 33.9 J/m续航 61.2 km相对 25km/h 是 100.0%。往左拖到 15 km/h。功率掉到 97.9 W每米能耗 23.5 J/m续航 88.2 km相对 25km/h 是 144.2%。注意这个数慢骑十公里每小时续航多出四成——这是同一条二次函数的另一侧。外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传回到 25。这张是拖完滑块再拖回来的样子圆点重新压住那条蓝色点线读数 61.2 km、100.0%。限速线两侧怎么差就靠这一来一回看。速度 25.0 km/h滑块焦点态读数 235.4 W / 33.9 J/m / 61.2 km / 100.0%然后是那个让人不舒服的档位35 km/h。总功率 481.2 W每米能耗 49.5 J/m续航 41.9 km相对 25km/h 只剩 68.5%。速度涨 40%续航不是掉 31.5% 吗——对就是掉了 31.5%跟打七折看着接近可这是撞出来的不是设计出来的。你没法提前知道它是 68.5%因为每米能耗里那两项的比例在变。速度 35.0 km/h读数 481.2 W / 49.5 J/m / 41.9 km / 68.5%结论行写着提速至 35km/h 续航下降 31.5%再狠一点45 km/h。功率 878.6 W每米能耗 70.3 J/m续航 29.5 km相对 25km/h 剩 48.2%。腰斩字面意义上的一半都剩不到。拖到底50 km/h。功率 1147.7 W——已经超过一千瓦每米能耗 82.6 J/m续航 25.1 km。从 25 到 50速度翻倍续航掉到四成出头。一个二次函数就是全部答案src/physics.js里真正管事的就四行exportfunctionrollPower(v,m,Crr){returnm*G*Crr*v;}exportfunctiondragPower(v,CdA,rho){return0.5*rho*CdA*v**3;}exportfunctioncostOfTransport(v,p){returntotalPower(v,p)/v;}滚阻功率线性于 v风阻功率立方于 v。两者相加再除以 v得到每米能耗COT(v) m·g·Crr ½·ρ·CdA·v²三次方项被 v 约掉一次剩下一个纯二次函数。没有指数、没有分段、没有拟合参数。通勤标准场景代进去常数项 m·g·Crr 17.651970 J/m二次项系数 ½ρCdA 0.336879 J·s²/m³。九个采样点的实测值cot(10) 20.251341 cot(30) 41.046313 cot(50) 82.636256 cot(15) 23.500556 cot(35) 49.494270 cot(20) 28.049456 cot(40) 59.241913 cot(25) 33.898041 cot(45) 70.289242拿 20 和 40 两个点反解 a、b再回头预测 30、50、25、45最大偏差 1.42e-14 J/m。这就是纯二次的意思——它不是拟合得好它本来就是。续航比更直接。能量固定续航与每米能耗成反比所以25 km/h61.171676 km35 km/h41.895759 km45 km/h29.500959 km15 km/h88.236211 km50 km/h25.093102 km35/25 0.684888续航掉 31.5112%页面上显示 31.5%45/25 0.482265掉 51.7735%。这两个比值分别等于 33.898041/49.494270 和 33.898041/70.289242你按计算器就能对上。为什么打七折这个直觉会错因为功率里那项 v³ 才是主角。风阻功率占总功率的比例25 km/h 时是 47.93%35 km/h 涨到 64.34%45 km/h 是 74.89%50 km/h 到 78.64%。低速时你多骑五公里每小时多出来的电基本是给滚阻交的高速时多出来的电几乎全喂了风。所以曲线的弯法不是越往后越贵一点点是越往后风阻占比越高、于是掉得越凶。反解闭环是我最想要的那部分。假设某车标称576 Wh 25 km/h 跑 45 km把 45 km 当已知反解 CdAexportfunctionsolveCdA({energyJ,v,rangeM,m,Crr,rho}){return2*(energyJ/rangeM-m*G*Crr)/(rho*v*v);}解出 CdA 0.962412 m²。这个数比骑行者典型值 0.55 大了七成我第一眼看觉得它不靠谱——但它的含义很实在厂商那个 45 公里是在含起步停车、低速、可能还带点顺风的工况下测的硬套到匀速模型上模型只能把这笔账全算到风阻头上。用 0.962412 再预测25 km/h 精确还原 45.000000 km这是恒等式必须还原35 km/h → 28.261882 km45 km/h → 18.892337 km35/25 0.62804245/25 0.419830。也就是说一个只承认标称 45 公里的模型预测出你解限速到 35 只能跑 28.3 公里。第三方拿这几个公式能一路复算到底中间没有任何一步需要问我。提示词钉到函数级五份提示词四轮真交付中间夹一轮空转。第一轮r1.txt的开头和函数清单禁止在对话里贴任何代码正文你的输出只能是仓库里的文件。不要推导直接建文件、跑测试、提交。 每建完一个文件单独 commit最后 push。push 要凭据就停下告诉我不要向用户要 token。 仓库 ZuoDa01/ebike-range-physics 已绑定不要新建仓库、不要碰设置。本轮只建 2 个文件。 【2】src/physics.js —— 纯函数无 IO 无依赖。文件顶部写死常量并注明出处 airDensity(T ISA_T0, p ISA_P0) // p / (R_SPEC * T)由常量导出不许写死 1.225 rollPower(v, m, Crr) // m*G*Crr*v dragPower(v, CdA, rho) // 0.5*rho*CdA*v^3 totalPower(v, { m, Crr, CdA, rho, eta 1 }) // (rollPower dragPower) / eta costOfTransport(v, p) // totalPower / v单位 J/m即每米能耗 rangeMeters(energyJ, v, p) // energyJ / costOfTransport(v, p) rangeByIntegration(energyJ, v, p, dt 0.01) // 独立路径按时间步累加 totalPower*dt 直到耗尽返回 v*t solveCdA({ energyJ, v, rangeM, m, Crr, rho }) // CdA 2*(energyJ/rangeM - m*G*Crr) / (rho*v^2)签名、单位、公式、不许写死什么全给死。测试那一节更狠期望值一个个列出来让它照抄B. 功率锚点绝对容差 1e-4 W v25km/h: rollPower122.583125 dragPower112.819941 totalPower235.403066 v35km/h: rollPower171.616375 dragPower309.577917 totalPower481.194292 v50km/h: rollPower245.166250 dragPower902.559526 totalPower1147.725776禁止在对话里贴代码正文这条是省钱用的也是防抄用的——我要的是仓库里的文件不是聊天记录里一段看着挺对的代码。让它每建一个文件单独 commit是为了事后能用git log的时间戳还原每一轮真实花了多久。Agent 对话侧栏工作区按仓库分组ZuoDa01 下挂着 ebike-range-physics 等三个仓库右侧是同一格式的交付回执末尾带耗时与输入输出 token 计数这一屏跑的是隔壁 lamp-cct-audit 那一轮架构物理公式只许出现在一个文件里三层。src/physics.js只有纯函数和 SI 导出常量无 IO、无随机、无时间戳。src/range.js是场景预设和派生分析只 import physics导出SCENARIOS、sweep、speedImpact、sensitivityCdA、solveCdAFromNominal、headline。src/ui.js只做 canvas 和格式化index.html只做 DOM 和事件。分层这件事在提示词里是一条硬约束【2】src/ui.js —— 只做 DOM 与绘制数值一律 import src/physics.js 与 src/range.js本文件内不得出现物理公式。它确实守住了。ui.js里出现的数字只有布局常量padL 52、xMin 10、xMax 50和颜色一个公式都没有。量程取整那个函数是纯算术functionniceTop(maxR){if(!(maxR0))return1;constpMath.pow(10,Math.floor(Math.log10(maxR)));returnMath.ceil(maxR/p)*p;}采样点固定 81 个10 到 50 每 0.5 一档走range.sweep不许在 ui 里自己写公式。这个不许是有代价的代价我放在坑二里讲。切场景的截图两个都拖到 35 km/h 方便对比。轻载小轮490.7 W、50.5 J/m、41.1 km、69.1%。带人载货584.2 W、60.1 J/m、34.5 km、74.0%。注意这里有个反直觉的点——重车相对百分比反而更高74.0% 对 68.5%因为它的滚阻基数大、风阻占比小二次函数里那个弯就浅。顺手记一个真实的毛病切场景时质量与滚阻跟着换但电压、容量、CdA 三个输入框不会被重置所以这两张图里跑的其实是轻载/载货的质量 通勤标准的 48V12Ah 与 CdA 0.55这个混合参数。页面上没写清楚算个小 bug。常量为什么不查表exportconstG9.80665;// 标准重力加速度 m/s²SI 定义值exportconstR_UNIV8.31446261815324;// 通用气体常数 J/(mol·K)2019 SI 由 k·N_A 精确定义exportconstM_AIR0.028965221;// 干空气摩尔质量 kg/molexportconstR_SPECR_UNIV/M_AIR;// 比气体常数导出值exportconstISA_T0288.15,ISA_P0101325;exportfunctionairDensity(TISA_T0,pISA_P0){returnp/(R_SPEC*T);}g 取 9.80665 是因为它是 SI 的定义值不是量出来的。R_UNIV 后面那十四位小数是 2019 年 SI 重新定义之后由 k·N_A 精确算出来的写全了以后所有温度下的密度都能追溯到同一处。空气密度我坚持不写死 1.225——那是个查表值查到的还是四舍五入过的。走 ρ p·M/(R·T) 导出实算 1.225013 kg/m³对上 ISA 海平面标准 1.22525 ℃ 是 1.1839260 ℃ 是 1.292284。R_SPEC 导出值 287.049859 J/(kg·K)。这个数我后面要再提一次因为它差点被我写错。独立参考实现与 84003 组差分测试全绿只能说明代码和测试同意彼此不能说明代码和物理同意。要打破这个闭环得有一份不共享任何代码、也不共享任何数学路径的参照实现。ref/bike-ref.mjs是手写的跟仓库互不 import四条路径全部故意走得不一样// 干空气摩尔分数 - 摩尔质量 g/molconstDRY_AIR[[0.78084,28.0134],// N2[0.20946,31.9988],// O2[0.00934,39.948],// Ar[0.00040,44.0095],// CO2];exportconstmolarMassAir()DRY_AIR.reduce((s,[x,M])sx*M,0)/1000;exportconstrhoRef()(ISA_P0*molarMassAir())/(R_UNIV*ISA_T0);exportconstcotRef(v,{m,Crr,CdA,rho})m*G*Crr0.5*rho*CdA*v*v;// 直接是阻力N J/m被测那边空气密度走 p/(R_SPEC·T)参照这边从气体组分加权算摩尔质量再走 p·M/(R_UNIV·T)被测那边每米能耗是 totalPower/v参照这边直接写阻力式量纲是牛顿表达式也不一样续航被测走 E/COT参照解二次式 E/(ab·v²)能量累加另开一条 RK4 步进。随机数用 mulberry32 定种子 20261010跑 20000 组质量 60260 kg、Crr 0.0080.038、CdA 0.31.1、v 220 m/s 的随机参数每组撞四个量再加 2000 组尺度律与分项恒等、3 个场景的反解闭环一共 84003 组。差分驱动ref/bike-diff.mjs的容差是这样定的// 密度差是可解释的系统差不是 bug组分表缺痕量气体相对差约 6.7e-5constDENS_RELMath.abs(rhoRef()/airDensity()-1);// 容差密度相关的量按 DENS_REL 的 3 倍放宽纯代数恒等式用极紧容差constTOL_DMath.max(DENS_REL*3,1e-9);跑出来的存档输出evidence-w3-diff.txt我本地重跑一遍一模一样空气密度两条路径相对差 6.729e-5来自干空气组分表缺痕量气体可解释 M_air: 组分加权 0.028967170 vs 常数 0.028965221 对拍组数: 84003 一致除可解释的密度系统差外零分歧敢于报告一个能解释的非零差上面那行 6.729e-5 是全文我最想写的一段。两条路径算出来的空气密度不一样。组分加权得到的摩尔质量是 0.028967170 kg/mol常数表里那个是 0.028965221差在第四位有效数字上。原因很朴素我那张 DRY_AIR 表只列了 N2、O2、Ar、CO2 四种把氖、氦、氪这些痕量气体漏了而它们的摩尔质量比表里平均值高。所以这不是 bug是我参照实现的组分表比常数粗糙。那正确的处理是什么把密度相关量的容差按这个系统差的 3 倍放宽然后把差写出来。纯代数恒等式另开一路用 1e-9 到 1e-12 的紧容差单独把关P/v 与 COT 逐位相等、dragPower(2v)/dragPower(v) 严格等于 8、totalPower 严格等于 rollPower dragPower、反解出来的 CdA 代回去必须精确还原标称续航。// 纯代数恒等式P/v COT与被测自己的两个函数对撞必须逐位if(Math.abs(totalPower(v,p)/v-costOfTransport(v,p))1e-12)note(P/vCOT,v${v});报一个零差读者只能选择信你报一个能解释清楚来源、量级对得上、还顺手给了容差依据的非零差读者可以自己去查那张组分表、自己算那个 6.7e-5、自己判断解释成不成立。前者是表态后者是可验证。我宁可留这个刺眼的非零。测试锚点 不变式npm test跑node --test36 个用例physics 与 range 两套全绿。ℹ tests 36 ℹ pass 36 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0分两类。锚点类是 A 到 F 六组A 组常量导出R_SPEC、三个温度下的空气密度相对差 1e-6B 组功率C 组九个点的每米能耗绝对容差 1e-5 J/mE 组反解闭环F 组单位换算kmhToMs(36) 10用的是整数换算就该逐位相等不许带容差。不变式类 I1 到 I6 才是骨架。最核心那条test(I1 COT 是 v 的纯二次函数,(){constv20kmhToMs(20),v40kmhToMs(40);constc20costOfTransport(v20,p),c40costOfTransport(v40,p);constb(c40-c20)/(v40*v40-v20*v20);constac20-b*v20*v20;assert.ok(Math.abs(a-m*G*Crr)1e-9);assert.ok(Math.abs(b-0.5*airDensity()*0.55)1e-9);两个点反解出 a、b然后要求 a 就是 m·g·Crr、b 就是 ½ρCdA容差 1e-9。这条断言的意义在于它不检查数值对不对它检查函数形状对不对。数值错了是笔误形状错了是模型错了。I2 拿闭式续航和数值积分续航对撞七个速度档相对差要求小于 5e-6实测最大 2.50e-6出现在 40 km/hdt0.01 的步长截断。I4 是尺度律I5 是零速极限——v 取 1e-6 m/s 时 COT 必须回到 m·g·Crr这条断言在防把 v 当分母写出个奇点。range 那套里 I3 要求headwindDragPower(v, 0) dragPower(v/3.6)逐位相等防止逆风函数自己偷偷改了定义。有一处我得如实交代。test/range.test.js里钉的比值是 0.684887 和 0.482212容差 1e-4今天直接跑代码speedImpact返回的是 0.684888 和 0.482265。前者是我发提示词前用锚点脚本算的后者是仓库里现在的真值两个都在 1e-4 容差内所以测试一直绿。0.684887 那位是第六位小数上的舍入无所谓0.482212 和 0.482265 差了 5.3e-5是我锚点脚本当时算到中途抄错了位。这个坑我在坑一里讲因为它就是坑一的延续。三个真实的坑坑一我自己脑补了锚点第一版提示词里我写的期望值是rollPower(25km/h) 122.597还有R_SPEC 287.052645。现在仓库里那份r1.txt已经是改过的了改成了 122.583125 和 287.049859。两个都是从中间结果看着像填进去的。当时那个脚本只打印一位小数我看到 122.6 就顺手补了三位补成 122.597287.05 那个我记成 287.052645。真实值是 122.583125 和 287.049859。发现方式很无聊发提示词之前我闲得慌把脚本改成toFixed(6)重跑了一遍。这数字搁谁都得信啊——一位小数的 122.6 和 122.597 对得上谁看得出问题。我看了直摇头。这两条要是发出去码道会把它们当权威期望值写进测试然后要么把正确的实现修正成符合我错值的样子要么老老实实报错我再花半小时去查一个根本不存在的 bug。更糟的是第一种它会生成一套自洽但错误的测试全绿骗过所有人包括我。递给 AI 的期望值必须能被唯一复现。做不到就重跑脚本、按六位小数打印、逐字照抄别凭印象。从那以后我的规矩是锚点脚本必须能一键重跑输出位数写死在toFixed(n)里提示词里每个数字都对应脚本的某一行输出。bike-anchor2.mjs就是为这个改的它只干一件事——把要进提示词的数全打出来。坑二UI 规格太重码道直接空转第一轮界面提示词r3.txt我写了三栏布局、三条曲线、双纵轴、逆风输入、坡度输入、Crr 输入、恢复默认按钮还要求纵轴量程按数据自动取整到好看的数1/2/5×10^n并把刻度画出来。结果它空转了。工具调用数从第 150 秒开始冻住一直冻到第 360 秒一个文件都没建正文一路涨到 13 万字。零产出。我第一反应是上下文脏了开了个新会话把同一条提示词原样重发。还是空转工具数冻在 289 不动正文又 13 万字。这才想明白不是上下文问题是规格问题。自动好看刻度加双纵轴加三条曲线这三样凑一块等于把一堆没有唯一解的设计决策扔给它每条线的量程、每个刻度的取整、两套坐标轴怎么对齐全得自己定。它就在想方案里出不来了。我把界面砍成一句话能说完的样子r3b.txtcanvas 只画**两条**曲线共用横轴 10~50 km/h纵轴统一用续航 km一个量程 实线 续航 range(v) 虚线 相对 25km/h 的续航百分比把 % 除以 10 画在同一量程上图例写清楚这个换算 ... 不要做逆风、坡度、Crr 输入、自动好看刻度、双纵轴、第三条曲线、动画。这些一律不要。不要做那一行是我后来加的专门用来堵它自己发挥的口子。百分比除以 10 共量程这个 trick 有点丑但它把双纵轴这个没有唯一解的问题变成了一个纯算术问题。6 分 24 秒两个文件交付测试仍然全绿。判据我记下来了工具调用数长时间不变 正文持续增长 空转这时候改提示词别改会话。代价也要如实写逆风和坡度控件就是在这次砍规格时没的。range.js里headwindDragPower和gradePower两个函数还在测试也还在测它们但页面上没有输入口。这是取舍不是遗漏——我知道少了什么我不打算用一次空转换它回来。坑三我的差分脚本先崩了bike-diff.mjs第一版 import 了rangeRefCheck。这名字是我想象出来的src/range.js里根本没有这个导出直接 SyntaxError。修完能跑了参照实现的 RK4 那一段又写错——步进里对 x、e 的更新混进了不该有的项跑出来的能量累加跟闭式对不上差分报了一堆分歧。那半小时我一度以为被测代码有问题翻physics.js翻了个底朝天。后来把 RK4 那几行手算了一遍才发现是我参照写崩了。差分报分歧的时候先假设是自己的参照错了。参照实现不是权威它只是另一个人写的另一份猜测两份猜测不一致的时候它没有优先权。真正有优先权的是能独立复算的锚点。诚实边界README 里有一节叫这套数值能信到什么程度我在提示词里写了不许删。这里重申一遍三个场景的 mass、Crr、CdA、电压容量全是典型量级假设值非某品牌实测。换你自己的车参数得自己改改完数就变了。模型是准稳态匀速假设。不含加速与制动回收不含电池容量随放电率和温度的衰减不含轮胎形变滞后不含灯光和控制器发热这些附件功耗不含红绿灯与路况。逆风只改相对速度这一项不模拟侧风和阵风。有坡度的时候匀速假设根本不成立——爬坡时速度会掉、电机工作点会变所以页面的设计是显式提示坡道工况下续航模型不适用匀速假设而不是给一个假装精确的数字。目前这个提示还没上页面因为坡度控件在坑二里被砍掉了。CdA 反解依赖标称续航是在 25 km/h 匀速下测得这个假设。厂商要是用含起步停车的工况循环标的那个数字反解值会系统性偏大——前面 0.962412 对 0.55 那七成的差基本就是这么来的。执行中的一轮码道在核对提示词里诚实边界的几条说法指出 index.html 无坡度控件、无此提示写吹然后按仓库实际状态如实改写 README下方 Write 与 Bash 提交记录末尾结论无 84003 组差分对拍/参考实现按’如实不许吹’写 README这张图是我最愿意贴的一张。我在 r4 的提示词里写有坡度时页面会显式提示……它去翻了index.html发现页面上压根没有坡度控件也没有那个提示直接回了两个字吹。然后按仓库真实状态改写 README把计划中、尚未落地单独标出来还顺手指出 test 里只有代数恒等式锚点、没有 84003 组差分对拍那会儿参考实现确实还在我本地不在仓库。写进 README 的东西被工具按事实驳回这一下省了我一次自嗨。提效数据时间戳全部来自git log最后一列是我本地干了什么。码道回执耗时只有截图里那两轮有记录没截图的我标未截图不猜。轮次提示词交付git log 首末 commit 间隔码道回执耗时本地复核r1p-bike/r1.txtpackage.json、src/physics.js、test/physics.test.js15:09:42 → 15:11:131 分 31 秒未截图重跑bike-anchor2.mjsA~F 六组共 30 个锚点逐字比对r2p-bike/r2.txtsrc/range.js、test/range.test.js15:19:45 → 15:20:3752 秒未截图node --test36 全绿r3p-bike/r3.txt空转零文件无 commit无回执判据工具数从第 150 秒冻到第 360 秒正文 13 万字r3-重发同一条r3.txt仍然空转零文件无 commit冻在 289 不动由此确认是规格问题不是上下文问题r3bp-bike/r3b.txtsrc/ui.js、index.html15:46:13 → 15:47:1259 秒6 分 24 秒浏览器逐档拖滑块读数对锚点r4p-bike/r4.txtscripts/serve.mjs、package.json的 start、LICENSE、README.md15:52:49 → 15:55:593 分 10 秒5 分 41 秒输入 206.3K tok / 输出 3.7K toknpm testcurl -sI拿 200从Initial commit14:18:12到最后一个 commit15:55:5912 个 commit1 小时 37 分 47 秒中间包含一轮空转返工和我自己的验算。还没做完的没有真车路测校验。一个数据点都没有全文的数都是模型推的。这个我还没做。不含电池模型。电压-容量非线性、内阻、低温衰减一概没有。不含电机效率 MAP。eta参数留了口子默认 1全项目没有任何地方给它传过非 1 的值。不能保存、不能分享一组参数。没有 URL 状态没有 localStorage刷新回默认。坡度只给提示不给修正模型而且那个提示目前只在 README 里页面上没有。没有顺风回收、下坡充电。界面上没有逆风与坡度控件。库层函数和测试都在就差三个输入框和一次重画。前面说了这是坑二砍掉的不是没想起来。84003 组差分的参考实现与差分脚本在ref/下不在仓库里。要不要一起提交我还在犹豫——它不是产品代码但它才是这篇文章的证据。本地怎么跑git clone https://atomgit.com/ZuoDa01/ebike-range-physics cd ebike-range-physics npm test npm start零依赖Node 18 以上npm test就是裸的node --test。npm start起scripts/serve.mjs默认端口 8133只监听 127.0.0.1。静态服务器那几十行里有一段路径校验我挺喜欢if(decoded.split(/).includes(..)){returnsend(res,404,404 Not Found\n);}constresolvedpath.resolve(root,.decoded);if(resolved!root!resolved.startsWith(rootpath.sep)){returnsend(res,403,403 Forbidden\n);}先解码再拼根拼完还要验一次前缀——因为解码后的..和编码过的%2e%2e是两条路。打开 http://127.0.0.1:8133/ 拖滑块。想验我全文的数最直接的办法是照前面那三个式子自己按一遍计算器m·g·Crr 17.651970、½ρCdA 0.336879、E 2073600代 v 25/3.6、35/3.6、45/3.6六个小数位全能对上。我那两份验算脚本不在仓库里前面还没做完的最后一条说过也不建议直接跑——它们按ref/与代码目录同级这个布局写的bike-diff.mjs里 import 的路径是硬编码的node ref/bike-anchor2.mjs # 六个小数位的锚点全文数字的出处 node ref/bike-diff.mjs # 84003 组差分含那个 6.729e-5要跑就把这两行的路径改成你自己的布局或者把ref/拷到仓库同级。输出应该是 84003 组和那行 6.729e-5别的都不该有。写在最后这道题的答案就是一行每米能耗是速度的二次函数续航是能量的反比。25 到 35 掉 31.5112%25 到 45 掉 51.7735%都不是打个七折因为风阻在总功耗里的占比从 47.93% 一路涨到 74.89%那个弯是越骑越陡的。这个项目里 AI 一行代码都没让我改错写出来的东西分层干净、测试全绿。真正耗时间的是三件它替我干不了的事想清楚要什么、算出它该得什么、以及判断它给的东西对不对。锚点是我算的差分参照是我写的被纠错的是我说吹的也是它。代码在 https://atomgit.com/ZuoDa01/ebike-range-physics MIT随便复算。算出来跟我不一样的话欢迎拿脚本砸我。
阅读完成 · 觉得有帮助?