列控仿真系统C#源码解析:从周期安全逻辑到制动模型调参避坑

简介:这份资源是面向计算机、自动化等专业学生及从业者的C#列控仿真系统完整源码,源自个人毕业设计项目,评审得分95分,调试运行正常。项目以CTCS-2级列控仿真系统为核心,包含完整的sln解决方案与工程配置,适合作为期末课程设计、课程大作业或毕业设计的参考模板,也便于基础较好的学习者在原有框架上修改扩展,实现类似功能。压缩包共16个文件,以8个cs源码文件为主体,配合3个resx资源文件、1个sln解决方案、1个csproj工程文件及settings、config等配置项,整体约33KB,结构紧凑、层次清晰,便于快速定位程序入口与界面逻辑。目前已有246人学习下载,读者可从中获取完整的项目组织方式、窗体与资源设计思路以及可运行的仿真逻辑,对理解列控仿真系统的实现路径与C#桌面应用开发具有较高的借鉴价值。

1. 列控仿真系统到底在仿真什么:从一份 C# 源码方案说起

很多人第一次接触列控仿真,会以为它就是个"跑起来看列车动"的动画程序。真上手一份基于 C# 开发的列控仿真系统完整源码加 sln 解决方案,才会发现核心根本不在画面,而在周期性的安全逻辑计算:车载设备按固定周期读地面信息、算允许速度、比超速阈值、触发制动,这一整套闭环才是仿真对象。它解决的是"没有真实线路和真实车载设备时,怎么验证控车逻辑对不对"的问题,适合做信号相关开发、教学演示、算法预研的从业者。这份方案的价值在于把整套工程拆成了可编译、可调试的 sln,你能直接断点进每一帧的控车决策,而不是对着一个黑匣子猜它为什么减速。下面按"先立概念、再跑起来、再调参、再避坑"的顺序讲透。

2. 先搞懂列控仿真的运行骨架:周期、速度曲线与制动模型

在动手编译之前,得先明白这套系统内部是怎么转起来的。列控仿真的本质是一个离散时间步进的闭环:每个仿真周期,系统采集列车当前位置和速度,结合线路限速和前方障碍,算出当前允许速度,再和实际速度比较决定是否输出制动。这个循环的周期、速度积分方式、制动减速度模型,直接决定了仿真结果像不像真的。

2.1 仿真主循环与时间步长怎么定

常见做法是把主循环写成一个固定步长的定时器或 while 循环,每个 tick 推进一次状态。步长选大了,制动曲线会呈阶梯状,超速判断失真;选小了,计算量上去了但精度提升有限。我一般会先用 100ms 起步,跑通后再根据曲线平滑度调整。

// 仿真主循环骨架:固定步长推进 public class SimulationEngine { private double _timeStep = 0.1; // 仿真步长,单位秒,100ms 起步 private double _simTime = 0.0; // 累计仿真时间 private bool _running = false; public void Start() { _running = true; while (_running) { // 1. 采集当前状态(位置、速度) var state = CollectState(); // 2. 计算允许速度(核心安全逻辑) double permittedSpeed = CalculatePermittedSpeed(state); // 3. 超速判断与制动决策 var decision = EvaluateBraking(state.Speed, permittedSpeed); // 4. 按步长积分更新速度与位置 UpdateMotion(decision, _timeStep); _simTime += _timeStep; Thread.Sleep((int)(_timeStep * 1000)); // 实时仿真时按步长休眠 } } }

这段代码里_timeStep是最关键的参数,它同时影响仿真精度和实时性。CollectState负责从列车模型取数据,CalculatePermittedSpeed是安全逻辑入口,EvaluateBraking做阈值比较,UpdateMotion用最简单的欧拉积分更新速度。逻辑说明:整个循环是串行的,保证每个周期内"采集—计算—决策—更新"顺序不被打乱,这是安全逻辑的基本要求。参数说明:_timeStep建议 0.05~0.2 秒之间;Thread.Sleep只在需要实时对齐时用,纯离线跑批可以去掉。

2.2 允许速度曲线是怎么算出来的

允许速度不是单一限速,而是取多个约束的最小值:线路静态限速、临时限速、前方停车点、制动距离约束。常见做法是先把线路离散成若干区段,每段带一个限速值,再结合当前速度反推"从现在开始全力制动能否停在目标点前"。

// 允许速度计算:多约束取最小 public double CalculatePermittedSpeed(TrainState state) { // 约束1:当前所在区段的静态限速 double staticLimit = _track.GetSpeedLimit(state.Position); // 约束2:前方最近限速变化点的目标速度 double targetLimit = _track.GetNextTargetSpeed(state.Position); // 约束3:制动距离约束——按当前减速度反推允许速度 double distanceToTarget = _track.GetDistanceToTarget(state.Position); double brakeLimit = Math.Sqrt( targetLimit * targetLimit + 2 * _brakeDecel * distanceToTarget); // 取三者最小值作为最终允许速度 return Math.Min(staticLimit, Math.Min(targetLimit, brakeLimit)); }

逻辑说明:brakeLimit用的是运动学公式 v² = v₀² + 2as 的变形,_brakeDecel是制动减速度(正值表示减速能力)。参数说明:_brakeDecel一般取 0.8~1.2 m/s²,取值越大允许速度越高,但安全余量越小;distanceToTarget必须包含一个安全防护距离,不能直接用几何距离。这里最容易翻车的是把targetLimit和staticLimit搞混,导致限速切换点附近速度跳变。

2.3 制动模型:为什么你的减速曲线是阶梯状

制动模型决定了速度怎么降下来。最简单的做法是恒定减速度,但真实系统里制动建立有延迟、减速度随速度变化。仿真里如果只用恒定减速度,曲线会很"理想",和实测对不上。

模型类型减速度处理适用场景注意点
恒定减速度固定值快速验证逻辑曲线过于理想
分段减速度按速度区间取值教学演示区间边界要平滑
延迟+恒定加制动建立时间接近实测延迟参数需标定

我一般先用恒定减速度把逻辑跑通,再换成带延迟的模型做对比。延迟参数通常设 0.5~1.5 秒,具体看车型。这一步不做,后面调参时会发现怎么调都对不上真实数据。

3. 把 sln 跑起来:环境、编译与最小可运行路径

拿到一份完整源码加 sln,第一件事不是读代码,是让它先编译通过、能跑出一个结果。这一步能帮你快速判断工程完整度和依赖情况。

3.1 环境准备与依赖还原

常见做法是用 Visual Studio 打开 sln,先看解决方案配置管理器里的目标框架。列控仿真这类工程通常依赖 .NET Framework 或 .NET,还可能引用第三方图表库、数学库。

# 用命令行还原依赖并编译,快速暴露缺失引用 dotnet restore YourSolution.sln dotnet build YourSolution.sln -c Release # 如果目标是 .NET Framework,用 msbuild msbuild YourSolution.sln /p:Configuration=Release

逻辑说明:restore先把 NuGet 包拉齐,build再编译。参数说明:-c Release用发布配置,能暴露一些只在优化下出现的问题;如果报找不到包,先检查 NuGet 源配置。这一步最常见的翻车是目标框架版本和本机 SDK 不匹配,报一堆"找不到类型",其实只是框架选错了。

3.2 找到入口工程并跑出第一条速度曲线

sln 里通常有多个工程:仿真引擎、界面、数据模型、测试。入口一般是界面工程或控制台工程。先跑控制台版本,输出一段速度-时间数据,比直接开界面更容易定位问题。

// 最小可运行入口:跑 60 秒仿真并打印速度 static void Main(string[] args) { var engine = new SimulationEngine(); engine.LoadTrack("track_config.xml"); // 加载线路配置 engine.LoadTrain("train_config.xml"); // 加载列车参数 engine.OnTick += (t, speed) => { // 每 1 秒打印一次,避免刷屏 if (Math.Abs(t % 1.0) < 0.001) Console.WriteLine($"t={t:F1}s speed={speed:F2}m/s"); }; engine.RunFor(60.0); // 跑 60 秒仿真 }

逻辑说明:LoadTrack和LoadTrain把外部配置读进来,OnTick是每周期回调,RunFor控制仿真时长。参数说明:track_config.xml里至少要有区段限速和坡度;train_config.xml里要有质量、牵引特性、制动减速度。跑通后你会看到一条速度曲线,如果它一路平直没有任何变化,多半是线路配置没加载成功。

3.3 用断点验证一次完整的制动触发

编译跑通只是第一步,真正要确认的是安全逻辑有没有生效。做法是在EvaluateBraking里下断点,手动构造一个超速场景,看它是否按预期输出制动。

// 制动决策:带阈值和迟滞,避免临界点抖动 public BrakeDecision EvaluateBraking(double currentSpeed, double permittedSpeed) { double overspeed = currentSpeed - permittedSpeed; if (overspeed > _emergencyThreshold) // 超过紧急制动阈值 return BrakeDecision.Emergency; if (overspeed > _serviceThreshold) // 超过常用制动阈值 return BrakeDecision.Service; if (overspeed < -_releaseHysteresis) // 低于释放阈值才缓解 return BrakeDecision.Release; return BrakeDecision.Hold; // 保持当前状态 }

逻辑说明:用_emergencyThreshold和_serviceThreshold两级阈值区分制动等级,_releaseHysteresis做迟滞,防止速度在阈值附近来回抖动导致制动反复触发。参数说明:常用制动阈值一般 2~5 km/h,紧急制动阈值 5~10 km/h,迟滞量取阈值的 20%~30%。这里不加迟滞,仿真里会出现制动灯疯狂闪烁的玄学现象。

4. 参数怎么调:步长、减速度与阈值的联动关系

参数不是孤立调的,改一个往往要连带改另一个。这一章讲清楚几个核心参数的联动,避免你调了步长忘了减速度。

4.1 步长与减速度的匹配

步长决定了每个周期速度变化多少。如果步长 0.1 秒、减速度 1 m/s²,每周期速度降 0.1 m/s,曲线还算平滑;如果步长 1 秒,每周期降 1 m/s,曲线就是台阶。经验是:步长 × 减速度 ≤ 0.2 m/s,曲线才够细。

// 参数自检:步长与减速度匹配检查 double stepSpeedChange = _timeStep * _brakeDecel; if (stepSpeedChange > 0.2) { Console.WriteLine($"警告:每步速度变化 {stepSpeedChange:F3} m/s 过大," + "建议减小步长或降低减速度"); }

逻辑说明:这是一个启动时的自检,提前暴露参数不匹配。参数说明:0.2 m/s 是经验阈值,要求更高可以压到 0.1。这个检查加上之后,能省掉大量"曲线为什么这么丑"的排查时间。

4.2 阈值设置与安全余量

制动阈值设太紧,正常波动就触发制动;设太松,真超速了不动作。常见做法是常用制动阈值留 3~5 km/h 余量,紧急制动留 8~10 km/h。同时要保证允许速度本身已经含了安全余量,两层余量不要重复叠加太多,否则列车会一直跑不到目标速度。

参数典型值调大影响调小影响
常用制动阈值3~5 km/h更安全但易误触发响应迟钝
紧急制动阈值8~10 km/h保护更早可能来不及
释放迟滞阈值的 20%~30%缓解慢抖动
制动减速度0.8~1.2 m/s²允许速度高曲线保守

4.3 用对比跑批验证参数合理性

单次跑看不出问题,做两组参数对比跑批,把速度曲线叠在一起看差异,是最有效的验证方式。

// 对比跑批:两组参数各跑一次,输出到不同文件 var configs = new[] { "config_a.xml", "config_b.xml" }; foreach (var cfg in configs) { var engine = new SimulationEngine(); engine.LoadConfig(cfg); var log = new List<string>(); engine.OnTick += (t, s) => log.Add($"{t:F2},{s:F3}"); engine.RunFor(120.0); File.WriteAllLines($"result_{cfg}.csv", log); }

逻辑说明:把两组配置分别跑 120 秒,结果写成 CSV,用表格工具画图对比。参数说明:RunFor时长要覆盖完整的加速—巡航—制动过程,太短看不到制动段。这一步做完,参数合不合理一目了然,比盯着单条曲线猜靠谱得多。

5. 避坑与排查:列控仿真里最容易翻车的五件事

这一章全是血泪经验,每条按现象、原因、解决写,照着排查能省不少时间。

5.1 速度曲线在限速切换点跳变

现象:列车经过限速变化点时,允许速度瞬间从高跳到低,速度曲线出现垂直段。原因:允许速度计算里直接取了下一区段限速,没有做制动距离预判,导致切换点前没有提前减速。解决:在CalculatePermittedSpeed里加入前方目标点的制动距离约束,让列车提前开始减速,而不是到了切换点才降。检查方法是把distanceToTarget打印出来,看它是否在切换点前就小于制动距离。

5.2 制动反复触发导致速度抖动

现象:速度在阈值附近来回震荡,制动状态频繁切换。原因:没有加释放迟滞,或者迟滞量太小。解决:在EvaluateBraking里加_releaseHysteresis,并确保释放阈值低于触发阈值。迟滞量取触发阈值的 20%~30% 起步,还抖就继续加大。这个坑很典型,本质是控制系统里的抖振问题。

5.3 仿真跑得比实际快或慢

现象:仿真里 60 秒跑完的过程,实际感觉只花了几秒,或者反过来卡顿。原因:主循环里Thread.Sleep的时长和步长不一致,或者干脆没加休眠。解决:实时仿真时Thread.Sleep要按_timeStep换算成毫秒;离线跑批则去掉休眠,追求速度。两者不要混用,混用就会出现时间对不上的玄学。

5.4 配置文件加载失败但程序不报错

现象:程序正常启动,但速度曲线一路平直,没有任何限速变化。原因:配置文件路径不对或格式错误,加载函数吞掉了异常,返回了默认值。解决:在LoadTrack和LoadTrain里加显式校验,文件不存在或解析失败直接抛异常并打印路径。默认值这种东西在仿真里是后悔药,能不用就不用。

5.5 多线程更新导致状态不一致

现象:偶尔出现速度为负或者位置倒退。原因:界面线程和仿真线程同时读写列车状态,没有加锁。解决:仿真状态更新放在单线程里,界面只读快照;必须跨线程时用锁或不可变对象。列控仿真对状态一致性要求高,能单线程就别多线程。

6. 进阶:把仿真结果和真实数据对齐的验证方法

跑通、调好参数之后,真正决定这套仿真有没有价值的一步,是拿它和真实数据对齐。我一般会做三件事:先对齐静态限速曲线,再对齐制动距离,最后对齐整段运行时间。

对齐静态限速最简单,把仿真里的允许速度曲线和线路限速表叠在一起,看每个区段是否一致。这一步能暴露配置错误。对齐制动距离,是让列车从某个速度开始全力制动,看仿真停下来的距离和实测差多少,差超过 10% 就要回头查减速度模型和延迟参数。对齐整段运行时间,是跑一条完整线路,比较仿真总时间和实际运行时间,这个指标综合反映牵引和制动模型。

// 制动距离对齐:从指定速度全力制动,记录停止距离 public double MeasureBrakeDistance(double initialSpeed) { var state = new TrainState { Speed = initialSpeed, Position = 0 }; while (state.Speed > 0.01) // 速度接近零视为停止 { double decel = _brakeModel.GetDecel(state.Speed); state.Speed -= decel * _timeStep; if (state.Speed < 0) state.Speed = 0; state.Position += state.Speed * _timeStep; } return state.Position; }

逻辑说明:从初速度开始,每步按当前减速度降速并累加位置,直到速度归零。参数说明:_brakeModel.GetDecel可以返回恒定值或按速度查表;0.01是停止判据,太小会多跑很多步。把不同初速度下的制动距离列成表,和实测对比,就能判断模型偏差在哪个速度段最大。

一个具体技巧:如果发现低速段制动距离偏短,多半是没考虑制动建立延迟;如果高速段偏长,多半是减速度取值偏小。分开调,别一起改。我自己踩过的坑是拿一组实测数据反复调参数,调到最后参数只对那一组数据好,换一组就崩。后来养成习惯,至少留两组数据,一组调参一组验证,绝不混用。这个习惯比任何调参技巧都值钱。

希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

技能习得底层逻辑:从知识到肌肉记忆的刻意练习路径

技能习得底层逻辑:从知识到肌肉记忆的刻意练习路径

1. 从“skills”这个标题说起&#xff1a;一个被严重低估的硬核话题“skills”这个词&#xff0c;单独拎出来看&#xff0c;信息量几乎为零。它不像“分布式锁”“图像分割”“家庭收纳”那样自带场景&#xff0c;也不像“副业”“跳槽”那样自带情绪。但恰恰是这种极简的标题&…

2026/10/20 21:27:39 阅读更多 →
GPT-4o权重存档:为何模型参数比API更关键

GPT-4o权重存档:为何模型参数比API更关键

1. 一场没有官方通告的“退役”&#xff1a;GPT-4o权重开放请愿背后的现实逻辑“GPT-4o退役8个月”这个说法&#xff0c;乍看像一则突发新闻&#xff0c;实则是一次社区自发形成的集体认知校准。它并非来自任何技术公告或产品日志&#xff0c;而是开发者、研究者与开源实践者在…

2026/10/20 21:27:39 阅读更多 →
Kafka NoBrokersAvailable异常排查实战指南

Kafka NoBrokersAvailable异常排查实战指南

kafka.errors.NoBrokersAvailable: NoBrokersAvailable这个异常&#xff0c;只要是写过 Python Kafka 客户端的人&#xff0c;联调和上云阶段大概率都撞见过。我第一次遇到它是在一个数据同步任务里&#xff0c;消费者刚启动日志就刷出这个异常&#xff0c;看起来像整个集群挂了…

2026/10/20 21:27:39 阅读更多 →

最新新闻

知识蒸馏进阶:变分信息蒸馏VID原理与实战

知识蒸馏进阶:变分信息蒸馏VID原理与实战

1. 从知识蒸馏的瓶颈说起如果你这两年一直在跟进模型压缩和知识蒸馏方向&#xff0c;大概率会有一种感觉&#xff1a;传统KD&#xff08;Knowledge Distillation&#xff09;那套“软标签KL散度”的玩法&#xff0c;在早期分类任务上确实好使&#xff0c;但一旦碰到特征维度高、…

2026/10/20 22:18:29 阅读更多 →
5秒进3秒出片:AI视频风格化与V2V技术实测解析

5秒进3秒出片:AI视频风格化与V2V技术实测解析

1. 这个标题背后的需求&#xff0c;其实没你想的那么简单先问一句&#xff1a;你说的“出片”&#xff0c;到底是哪种“出片”&#xff1f;我拿这个标题去问了一圈做短视频的朋友&#xff0c;得到的答案五花八门。有人说我要的是“我拍一段真人视频&#xff0c;AI直接给我变成动…

2026/10/20 22:18:29 阅读更多 →
Notepad++下载安装与配置全攻略:避坑指南与效率提升技巧

Notepad++下载安装与配置全攻略:避坑指南与效率提升技巧

我电脑里常年躺着好几个文本编辑器&#xff0c;但要说最顺手、打开最快、从大学写代码到现在写博客都离不开的那个&#xff0c;还得是Notepad。这软件太出名了&#xff0c;以至于很多人觉得“下载安装还有什么好说的&#xff0c;官网一搜不就有了吗”。但我在实际工作和帮朋友弄…

2026/10/20 22:18:29 阅读更多 →
零代码打造机械臂遥控器:智能体开发实录与硬件控制边界探索

零代码打造机械臂遥控器:智能体开发实录与硬件控制边界探索

1. 从"一行代码没写"说起&#xff1a;这个标题到底在讲什么第一次看到"我一行代码没写&#xff0c;机械臂遥控器做出来了"这个标题&#xff0c;我的反应是&#xff1a;要么是标题党&#xff0c;要么背后有一套相当成熟的智能体开发范式在支撑。仔细拆解之后…

2026/10/20 22:18:29 阅读更多 →
AMD收购Xilinx后Vivado工具链稳定性与迁移策略解析

AMD收购Xilinx后Vivado工具链稳定性与迁移策略解析

1. 从一句调侃说起&#xff1a;AMD与Vivado之间到底什么关系“AMD Ross没有介入Vivado的私生活”这句话第一次看到的时候&#xff0c;我正蹲在一个FPGA开发群里看人吐槽工具链。乍一看像八卦标题&#xff0c;实际上是个技术梗——它调侃的是AMD收购Xilinx之后&#xff0c;很多人…

2026/10/20 22:18:29 阅读更多 →
多Agent系统架构设计与工程实践:从单Agent瓶颈到Agent蜂群

多Agent系统架构设计与工程实践:从单Agent瓶颈到Agent蜂群

1. 多Agent系统到底在解决什么问题1.1 从单Agent的瓶颈说起做过Agent项目的人大概都有这种体会&#xff1a;单个Agent在简单任务上表现还行&#xff0c;一旦任务链路变长、涉及的工具变多、需要同时处理的信息源超过三四个&#xff0c;它就开始“犯糊涂”了。具体表现包括&…

2026/10/20 22:17:20 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →