ARTICLE DETAIL

资讯详情

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

电力机车高原单线铁路运行仿真:从牵引计算到区间占用

电力机车高原单线铁路运行仿真:从牵引计算到区间占用 之前在一个铁路场景仿真项目里需要模拟三台电力机车在高原单线铁路上各自牵引列车运行。最开始的版本只做了平直道匀速逻辑换到带大坡道、隧道和限速区间的高原线路后列车频繁出现爬坡速度掉零、区间占用判断错乱、对向列车在车站无法合理会让等问题网上资料也比较零散。这篇文章就围绕“电力机车牵引列车通过高原单线铁路”这个场景整理一套从线路建模、牵引计算到单线区间占用的闭环仿真方案包含完整的 Python 实现和排错思路做铁路场景仿真、交通运输课程设计或者模拟火车类项目开发的同学都可以直接参考。1. 背景与核心概念1.1 高原铁路与单线铁路的特点铁路线路按照正线数目可以分为单线铁路、双线铁路和多线铁路。单线铁路是指区间只有一条正线的铁路对向行驶的列车不能在区间内交会必须在设有配线的车站进行会让。我国西南、西北很多山区和高原铁路采用单线形式一方面是因为地形条件限制了路基宽度和车站选址另一方面是初期运量未达到双线标准时单线加预留双线是更经济的方案。高原铁路和普通山区铁路相比有几个非常典型的特点海拔高空气密度下降内燃机功率折减明显所以高原铁路普遍倾向于电力牵引。线路纵断面复杂长大坡道多部分区段坡度达到 20‰ 甚至 30‰。隧道占比高隧道内附加阻力显著同时隧道内散热条件差对列车制动和通风要求更高。冬季冰雪覆盖轨面粘着系数下降牵引力发挥受限。在这个背景下电力机车牵引列车的运行计算就不能简单套用平直道的匀速模型必须把坡道附加阻力、隧道附加阻力、基本阻力、限速和车站会让逻辑一起纳入仿真。1.2 电力机车牵引列车的基本过程电力机车通过受电弓从接触网获取电能经过牵引变流器驱动牵引电机再通过齿轮传动驱动轮对转动。轮轨之间的粘着产生牵引力牵引列车克服各种阻力向前运动。列车的纵向运动方程可以简化表示为[ F - R (1 \gamma) \cdot m \cdot a ]其中(F) 是机车输出的牵引力N(R) 是列车运行总阻力N(\gamma) 是回转质量系数通常取 0.06 到 0.10(m) 是列车总质量kg(a) 是列车加速度m/s²。从这个公式可以看出同样的牵引力下列车质量越大、线路阻力越大加速度就越小。当线路阻力等于甚至大于机车最大牵引力时列车就无法继续加速严重时速度会持续下降直到停在坡道上。1.3 为什么需要做列车运行仿真列车运行仿真在实际工程和教学研究中用途很广设计阶段验证线路纵断面是否合理比如某个长大坡道是否会导致列车速度过低。运行阶段制定列车操纵策略比如何时满功率牵引、何时惰行、何时制动。信号系统设计时验证闭塞分区划分是否满足追踪间隔要求。单线铁路调度模拟时验证车站会让方案是否可行、列车是否会在区间内冲突。用代码做仿真最大的好处是可以快速调整线路参数、机车参数和列车编组几秒钟内看到运行结果不需要在真实线路上做风险很高的试验。本文实现的仿真虽然做了数据简化但完整保留了牵引计算、区间占用、会让逻辑这几个核心环节可以直接作为教学项目或进一步开发的基础。2. 环境准备与版本说明2.1 运行环境本文示例使用 Python 实现依赖库较少只需要以下几个基础库依赖库用途matplotlib绘制速度-距离曲线、牵引力变化曲线numpy数组和数值计算csv / json加载线路数据与列车数据标准库版本方面本文示例在 Python 3.9 及以上版本验证通过matplotlib 使用 3.x 版本。如果你的环境版本不同问题不大本示例没有使用某个版本的唯一特性核心逻辑都是通用的。建议在项目目录下创建一个独立虚拟环境避免和系统 Python 环境冲突python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate pip install numpy matplotlib2.2 版本与参数说明的边界必须说明的是真实的电力机车牵引计算需要用到机车出厂牵引特性曲线、电制动特性曲线、列车编组质量、轮径、传动比、粘着限制等一系列参数不同车型差异很大。本文示例使用教学简化模型牵引力按照“恒力启动 恒功率运行”两段式近似制动力按照恒定最大减速度近似。这种简化在课程设计、方案预研层面完全够用。如果要做实际的列车运行图编制或线路能力计算需要替换为真实参数这个会在后文“最佳实践与工程建议”中单独说明。2.3 示例项目结构本文代码建议按照下面的目录结构组织train_simulation/ ├── requirements.txt ├── data/ │ ├── route_kalang.csv # 线路纵断面数据 │ └── trains.json # 列车编组与机车参数 ├── train_model.py # 列车模型与阻力计算 ├── route_model.py # 线路模型与区间占用 ├── simulation.py # 主仿真循环 └── result/ └── curves.png # 输出可视化曲线如果只是跑通示例将代码放在同一个.py文件里也可以。下面的实战部分为了便于阅读按模块拆开讲解。3. 核心原理拆解3.1 列车运行阻力计算列车运行阻力是仿真中最核心的计算模块。通常分为基本阻力和附加阻力两大类。基本阻力包括轴承摩擦阻力、滚动阻力、轮轨滑动阻力、冲击和振动阻力、空气阻力等经验公式常用下面的形式单位 N/kN[ w_0 a b \cdot v c \cdot v^2 ]其中 (v) 是列车速度km/h(a)、(b)、(c) 是与车辆类型有关的经验系数。我国常用货运列车的单位基本阻力公式为[ w_0 0.92 0.0048 \cdot v 0.000125 \cdot v^2 ]客运列车会略有差异但形式相同。附加阻力主要包括坡道附加阻力、曲线附加阻力和隧道附加阻力。其中坡道附加阻力在高原铁路中影响最大。工程上通常用坡度千分数 (i) 来表示坡道附加阻力单位阻力值近似等于[ w_i i ]也就是说列车在 20‰ 的上坡道上每千牛重力需要额外承担约 20 牛顿的坡道阻力。这个换算关系非常直观也是做牵引计算最常用的经验简化。隧道附加阻力与隧道长度、列车长度、隧道净空面积、列车速度等因素有关近似计算时可以按隧道长度折算为等效坡道阻力。本文示例中用简化方案隧道区段单位阻力额外增加 0.1 N/kN数值上相当于 0.1‰ 的附加坡度。总阻力计算时需要把它们换算为绝对阻力单位 N[ R \frac{m \cdot g}{1000} \cdot (w_0 w_i w_r w_t) ]其中 (m) 是列车总质量kg(g) 是重力加速度9.81 m/s²(w_0) 是单位基本阻力N/kN(w_i) 是单位坡道阻力N/kN(w_r) 和 (w_t) 分别是曲线和隧道附加阻力。3.2 电力机车牵引力特性简化真实的机车牵引力特性是一条受粘着限制、牵引电机能力和功率限制共同决定的曲线。在低速区牵引力受粘着限制基本上是一个恒定值随着速度升高牵引电机功率达到额定值后牵引力按功率/速度关系下降形成恒功率区。为了做教学仿真可以把牵引力简化成两段式[ F(v) \begin{cases} F_{\max}, v \le v_{base} \ \min\left(F_{\max}, \frac{P_{max} \cdot \eta}{v \cdot 1000 / 3600}\right), v v_{base} \end{cases} ]其中 (v_{base}) 是恒力/恒功率转折速度(P_{max}) 是机车最大功率kW(\eta) 是传动效率。在仿真循环中每个时间步都根据当前速度计算当前可用的最大牵引力再结合司机操纵策略满功率、部分功率或惰行确定实际牵引力输出。3.3 单线铁路区间占用与会让逻辑单线铁路列车运行与双线最大的区别在于区间不能对向交会。常见的单线行车组织方式是“站间区间闭塞”即一个区间在同一时刻只允许一列车占用。如果两列对向列车需要交会必须一列在车站停车等待另一列通过后再进入区间。用程序实现时需要抽象两个对象车站具有到发线和信号设备列车可以在此停车、会让、通过。区间车站之间的闭塞分区同一时间最多只能有一列车占用。例如线路中有 A、B 两个车站从 A 到 B 的列车和从 B 到 A 的列车不能同时处于 A—B 区间内。如果一列车已经进入区间则对向列车必须在车站等待直到区间空闲且对方到达车站后方可发车。在本文的三列车场景中三台机车分别牵引三列车在同一单线铁路上运行但方向不同、出发时间不同因此需要根据单线闭塞规则决定是否允许列车进入区间。这个过程用事件驱动或时间步长扫描都可以实现本文的示例采用时间步长扫描每个时间步检查区间占用状态逻辑更直观。4. 完整实战案例三列车通过喀兰—鲁斯芙娅单线下面构建一个简化版仿真场景模拟“拉普兰德”“德克萨斯”“普罗旺斯”三台电力机车牵引各自列车通过一段包含多个车站和长大坡道的单线高原铁路。为了规避真实地名和真实机车参数带来的不必要争议本示例将线路命名为“喀兰—鲁斯芙娅单线”在仿真数据中以代号表示。机车和列车参数均为教学简化模型不代指任何真实车型。4.1 线路数据设计首先定义线路纵断面数据。用 CSV 表示线路上的离散坡段和特征点每一行包含里程、坡度、限速、是否为隧道、是否为车站。# 文件路径data/route_kalang.csv # 字段说明pos(里程,m), grade(坡度千分数,上坡为正), speed_limit(限速km/h), tunnel(是否隧道), station(车站名或空) 0,2.0,80,0, 2500,10.0,70,0, 6000,18.0,60,0, 10000,25.0,50,1, 15000,18.0,60,1, 19000,8.0,70,0, 23000,-6.0,80,0, 27000,-12.0,80,0, 31000,0.0,60,鲁斯芙娅这个 CSV 模拟了一段全长 31 km 的高原单线铁路中间包含大坡道、隧道区段末段有车站。实际使用中你可以替换为自己的线路纵断面数据。读取线路数据的函数如下# 文件路径route_model.py import csv from dataclasses import dataclass dataclass class RoutePoint: pos: float # 里程单位 m grade: float # 坡度千分数上坡为正 speed_limit: float # 限速单位 km/h tunnel: bool # 是否隧道 station: str # 车站名空表示非车站 def load_route(csv_path: str): points [] with open(csv_path, r, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: points.append( RoutePoint( posfloat(row[pos]), gradefloat(row[grade]), speed_limitfloat(row[speed_limit]), tunnelrow[tunnel].strip() 1, stationrow[station].strip(), ) ) return points def get_current_route_info(route: list[RoutePoint], pos: float): 根据列车当前位置返回当前所在坡段的线路参数 current route[0] for point in route: if point.pos pos: current point else: break return current这里需要注意get_current_route_info假设线路是按里程升序排列的并且列车位置不会超过最后一个特征点。仿真时如果列车跑出线路终点应该触发终止条件。4.2 列车参数与阻力计算列车参数使用 JSON 文件保存方便后续扩展为多组列车。// 文件路径data/trains.json [ { name: Raphael, train_id: T001, locomotive_count: 1, locomotive_weight_ton: 88, trailer_count: 18, trailer_weight_ton: 80, locomotive_power_kw: 7200, max_traction_kN: 400, max_brake_kN: 300, base_speed_kmh: 40, efficiency: 0.85, length_m: 500, start_pos: 0, direction: 1, depart_time: 0, start_station: 喀兰, end_station: 鲁斯芙娅 }, { name: Teksas, train_id: T002, locomotive_count: 1, locomotive_weight_ton: 88, trailer_count: 16, trailer_weight_ton: 80, locomotive_power_kw: 6400, max_traction_kN: 360, max_brake_kN: 280, base_speed_kmh: 40, efficiency: 0.85, length_m: 460, start_pos: 31000, direction: -1, depart_time: 300, start_station: 鲁斯芙娅, end_station: 喀兰 }, { name: Provence, train_id: T003, locomotive_count: 1, locomotive_weight_ton: 80, trailer_count: 20, trailer_weight_ton: 75, locomotive_power_kw: 6800, max_traction_kN: 380, max_brake_kN: 290, base_speed_kmh: 42, efficiency: 0.85, length_m: 540, start_pos: 0, direction: 1, depart_time: 600, start_station: 喀兰, end_station: 鲁斯芙娅 } ]其中direction1表示往里程增大方向运行direction-1表示往里程减小方向运行。depart_time表示相对仿真起始时刻的出发时间秒用于模拟不同列车的发车时刻。列车总质量、基本阻力和附加阻力的计算封装为Train类# 文件路径train_model.py import json import math G 9.81 def unit_basic_resistance(v_kmh: float) - float: 货运列车单位基本阻力 N/kN return 0.92 0.0048 * v_kmh 0.000125 * v_kmh ** 2 class Train: def __init__(self, cfg: dict): self.name cfg[name] self.train_id cfg[train_id] self.locomotive_count cfg[locomotive_count] self.locomotive_weight_ton cfg[locomotive_weight_ton] self.trailer_count cfg[trailer_count] self.trailer_weight_ton cfg[trailer_weight_ton] self.power_kw cfg[locomotive_power_kw] self.max_traction_kN cfg[max_traction_kN] self.max_brake_kN cfg[max_brake_kN] self.base_speed_kmh cfg[base_speed_kmh] self.efficiency cfg[efficiency] self.length_m cfg[length_m] self.start_pos cfg[start_pos] self.direction cfg[direction] self.depart_time cfg[depart_time] self.start_station cfg[start_station] self.end_station cfg[end_station] self.mass_kg ( self.locomotive_count * self.locomotive_weight_ton self.trailer_count * self.trailer_weight_ton ) * 1000 def total_weight_kN(self) - float: return self.mass_kg * G / 1000.0 def max_traction(self, v_kmh: float) - float: 根据速度返回当前最大可用牵引力N f_max self.max_traction_kN * 1000.0 v_ms v_kmh / 3.6 if v_kmh self.base_speed_kmh: return f_max p_limited (self.power_kw * 1000.0 * self.efficiency) / v_ms return min(f_max, p_limited) def calc_traction_force(self, v_kmh: float, power_ratio: float) - float: 根据司机手柄位计算实际牵引力 return self.max_traction(v_kmh) * power_ratio def calc_brake_force(self, brake_ratio: float) - float: 根据制动手柄位计算制动力N return self.max_brake_kN * 1000.0 * brake_ratio def calc_resistance(self, v_kmh: float, grade: float, tunnel: bool) - float: 计算列车总阻力N unit_w0 unit_basic_resistance(v_kmh) unit_wg grade unit_wt 0.1 if tunnel else 0.0 total_unit unit_w0 unit_wg unit_wt total_resistance self.total_weight_kN() * total_unit return total_resistance牵引力的计算中恒功率区的功率限制公式要特别注意单位换算。(P F \cdot v)速度使用 m/s 时牵引力单位是 N功率单位是 W。示例代码中v_ms由v_kmh / 3.6得到功率power_kw * 1000转为 W计算得到的力单位就是 N逻辑上是自洽的。4.3 单线区间占用与会让逻辑在只有两个车站的简化线路上整条线路可以视为一个单线区间。列车发车前必须检查区间是否被占用到达对方站后释放区间。为了支持更复杂的多车站场景这里实现一个简单的LineSection类记录区间起点、终点和当前占用列车 ID# 文件路径route_model.py class LineSection: def __init__(self, start_pos: float, end_pos: float, name: str): self.start_pos start_pos self.end_pos end_pos self.name name self.occupied_by None def can_enter(self, train_id: str) - bool: return self.occupied_by is None or self.occupied_by train_id def enter(self, train_id: str): if self.occupied_by is not None and self.occupied_by ! train_id: raise RuntimeError(f区间 {self.name} 已被 {self.occupied_by} 占用) self.occupied_by train_id def release(self, train_id: str): if self.occupied_by train_id: self.occupied_by None在单线双方向运营中occupied_by不仅用于防止同向列车追尾也用于防止对向列车进入区间。对向列车到达车站后如果区间仍被占用就需要在站内等待。4.4 主仿真循环主仿真循环使用固定时间步长dt 1秒模拟时长total_time 1800秒30分钟。列车位置速度积分使用简单的欧拉法虽然精度一般但教学演示足够。# 文件路径simulation.py import json import math import matplotlib.pyplot as plt from route_model import load_route, LineSection, get_current_route_info from train_model import Train DT 1.0 TOTAL_TIME 1800 def check_limit(v_kmh: float, limit_kmh: float) - bool: return v_kmh limit_kmh 0.5 def run_simulation(): route load_route(data/route_kalang.csv) with open(data/trains.json, r, encodingutf-8) as f: train_cfgs json.load(f) trains [Train(cfg) for cfg in train_cfgs] section LineSection(0, 31000, 喀兰—鲁斯芙娅单线) records {t.train_id: {pos: [], speed: [], time: []} for t in trains} # 状态控制 departed {t.train_id: False for t in trains} arrived {t.train_id: False for t in trains} current_pos {t.train_id: t.start_pos for t in trains} current_speed {t.train_id: 0.0 for t in trains} for t_sec in range(0, TOTAL_TIME 1, int(DT)): for train in trains: if arrived[train.train_id]: continue # 发车逻辑到发车时刻且区间空闲 if not departed[train.train_id]: if t_sec train.depart_time and section.can_enter(train.train_id): section.enter(train.train_id) departed[train.train_id] True else: records[train.train_id][pos].append(current_pos[train.train_id]) records[train.train_id][speed].append(current_speed[train.train_id]) records[train.train_id][time].append(t_sec) continue # 未到达时列车在区间内移动 if section.occupied_by train.train_id: info get_current_route_info(route, current_pos[train.train_id]) v_kmh current_speed[train.train_id] limit info.speed_limit # 限速控制超过限速必须制动 if v_kmh limit: brake_force train.calc_brake_force(0.5) total_force -brake_force elif v_kmh limit: total_force train.calc_traction_force(v_kmh, power_ratio0.8) else: total_force 0.0 resistance train.calc_resistance(v_kmh, info.grade, info.tunnel) net_force total_force - resistance # 考虑回转质量系数 acc net_force / (train.mass_kg * 1.06) new_speed v_kmh acc * DT * 3.6 # 速度不为负 if new_speed 0: new_speed 0.0 # 新位置 new_pos current_pos[train.train_id] train.direction * new_speed / 3.6 * DT # 到达判断位置越过终点站 end_pos 31000 if train.direction 1 else 0 if (train.direction 1 and new_pos end_pos) or ( train.direction -1 and new_pos end_pos ): new_pos end_pos section.release(train.train_id) arrived[train.train_id] True current_pos[train.train_id] new_pos current_speed[train.train_id] new_speed records[train.train_id][pos].append(current_pos[train.train_id]) records[train.train_id][speed].append(current_speed[train.train_id]) records[train.train_id][time].append(t_sec) # 绘图 fig, ax plt.subplots(2, 1, figsize(10, 8)) for train in trains: rec records[train.train_id] ax[0].plot(rec[pos], rec[speed], labelf{train.name} {train.train_id}) ax[0].set_xlabel(里程 (m)) ax[0].set_ylabel(速度 (km/h)) ax[0].legend() ax[0].set_title(列车速度-距离曲线) for train in trains: rec records[train.train_id] # 因为如果列车在区间外等待位置记录不变时间线会出现台阶 ax[1].plot(rec[time], rec[pos], labelf{train.name} {train.train_id}) ax[1].set_xlabel(时间 (s)) ax[1].set_ylabel(位置 (m)) ax[1].legend() ax[1].set_title(列车位置-时间曲线) plt.tight_layout() plt.savefig(result/curves.png, dpi150) plt.close() print(仿真完成结果已保存到 result/curves.png) if __name__ __main__: run_simulation()这个仿真循环的逻辑分为三部分发车阶段检查发车时刻和区间占用状态。运行阶段根据当前线路坡道、限速和速度计算牵引力、制动力和阻力再计算加速度和速度变化。到达阶段列车位置越过终点站后释放区间。4.5 运行与验证在项目目录下执行python simulation.py正常情况下会输出仿真完成结果已保存到 result/curves.png如果三列车的发车顺序和方向设计合理可以观察到“拉普兰德”号列车先发车进入区间后向上坡方向运行在大坡道段速度下降但仍能维持运行。“德克萨斯”号列车从对向出发在部分时段会在车站或区间外等待直到区间空闲。“普罗旺斯”号列车在二者之间的时间窗内发车利用前面的列车已到达、区间释放的空档通行。通过调整depart_time或机车参数可以模拟不同的运行场景观察单线铁路的瓶颈在哪里。4.6 限速控制与惰行策略的改进上面代码中的调速策略非常简单超过限速就施加固定 50% 的制动力低于限速就满功率牵引等于限速就惰行。这种策略在实际仿真中会出现速度在限速附近反复震荡的“锯齿”现象因为制动力和牵引力都不是连续微调的。更平滑的方式是采用比例控制。设定限速为 (v_{lim})当前速度为 (v)当速度接近限速时将牵引力按比例降低完整代码如下def speed_control_force(self, v_kmh: float, limit: float) - float: # 比例带 1 km/h if v_kmh limit - 1.0: return self.calc_traction_force(v_kmh, power_ratio0.8) elif v_kmh limit: return -self.calc_brake_force(0.3) else: ratio (limit - v_kmh) / 1.0 return self.calc_traction_force(v_kmh, power_ratio0.8 * ratio)这种控制策略对应司机“接近限速时逐渐回手柄”的操纵方式。在课程设计中可以进一步改进为 PID 控制器使速度更平滑地贴合限速曲线。5. 常见问题与排查思路在编写和运行这个仿真项目的过程中有几个问题非常典型。下面按问题现象、可能原因、解决思路的顺序整理。问题现象常见原因解决思路列车在大坡道上速度持续下降最终停在坡上牵引力不足以克服坡道阻力与基本阻力之和增大机车功率或最大牵引力减少列车编组或降低坡道限速让列车有更高初速度冲坡列车速度在限速附近反复震荡调速策略使用了开关式牵引/制动切换改为比例控制或 PID 控制增加牵引力平滑过渡对向列车同时出现在区间内发生冲突单线区间占用判断只检查了同向列车单线区间必须检查所有方向列车区间同一时刻只能被一列车占用列车到达终点后仍不释放区间到达判断条件没有覆盖反向运行用direction * new_pos direction * end_pos统一判断速度曲线在到达前突然跳变欧拉积分步长过大减小DT到 0.1 秒或 0.5 秒或采用改进欧拉法Heun恒功率区牵引力计算异常速度单位或功率单位换算错误检查v_ms v_kmh / 3.6功率用 W 和机车轮周牵引力对应5.1 列车停在坡道上怎么排查遇到列车停在坡道上首先要确认是不是线路设计本身的问题。可以采用下面的排查顺序在列车速度降为零的位置读取当前坡度值和线路限速。用公式计算该坡道上列车需要的总单位阻力 ((w_0 w_i))。计算机车在该速度下能提供的最大单位牵引力 (f_{max} F_{max} / (m \cdot g / 1000))。如果 (f_{max} w_0 w_i)说明列车无法在该坡道上稳定运行需要调整编组、增加补机或减小坡度。5.2 单线会让逻辑的边界条件一个容易忽略的边界是列车在区间内尚未到达终点站时对向列车是否可以进入区间等待从真实信号系统角度不行。但在仿真代码里如果使用“出发站 → 到达站”这种粗粒度的区间占用可能出现两列车在车站两端同时等待、区间空闲但谁也无法先发车的死锁。一种稳妥的简化方法是在仿真开始前给定发车顺序或设置优先权。例如设定上行列车优先级高于下行列车冲突时下行列车必须等待。实际工程中车站值班员同样按照列车运行图规定的会让方案指挥行车不会出现两列对向列车同时申请进入同一个区间的情况。6. 最佳实践与工程建议6.1 线路数据与程序分离在仿真项目中线路数据、列车参数应该以外部文件形式存在不要写死在代码里。原因有三点便于批量替换不同线路和车型做对比实验。避免改动数据时误改逻辑代码。后续可以对接 Excel 或数据库中的实际线路纵断面数据。本文示例中使用了CSV和JSON两种格式实际项目中也可以统一使用数据库或配置文件管理。6.2 参数标定不能靠拍脑袋仿真的可信度完全取决于参数。即使做教学项目参数也应有依据列车质量可以从实际编组和车辆自重估算。机车功率和牵引力可以从公开的产品手册或论文中获得。阻力公式优先选用《列车牵引计算规程》或相关教材中的经验公式。如果参数来源存疑建议在代码注释中标注参数用途和参考来源方便他人复核。6.3 安全余量的考虑真实列车运行中不会让列车恰好以限速值贴着线路运行而是会留出 35 km/h 的安全余量。仿真代码中将限速判断改为v_kmh limit - 3可以模拟这种安全策略。同样在坡道起动校核时应保留 20% 的牵引力余量避免因轨面潮湿、粘着下降导致坡停。6.4 单线铁路仿真的进阶方向当前示例只是单线铁路列车运行仿真的最小闭环。进一步扩展的方向包括多车站、多区间的自动闭塞逻辑。列车运行图的编制与冲突检测。车站到发线占用管理。结合真实线路纵断面和 GIS 数据。使用遗传算法或强化学习优化列车操纵策略。其中“多车站自动闭塞”是最值得优先做的方向。把LineSection从单一区间扩展为多个相邻区间每列车进入下一个区间前检查该区间是否空闲就可以模拟更真实的追踪运行。7. 总结与后续建议本文围绕电力机车牵引列车通过高原单线铁路的场景完整实现了从线路建模、阻力计算、牵引力计算到单线区间占用判断的全流程仿真。核心内容包括三部分列车纵向运动方程和阻力计算原理明确了坡道在高原铁路中的决定性影响。电力机车牵引力的两段式简化模型区分了恒力区与恒功率区。单线铁路的区间占用与会让逻辑实现了多列车在同一单线区间内安全运行的基本约束。在此基础上你可以继续补充更精细的牵引特性曲线、车站到发线管理、运行图冲突检测等内容。建议先把本文的代码跑通再逐步替换线路数据、调整列车参数观察不同坡度、不同编组对运行时分的影响。动手调参和画图是理解列车牵引计算最快的路径如果过程中遇到新的问题欢迎在评论区一起讨论。
返回列表