Omnet++、Veins、Sumo中如何获取多车辆整体CO2排放数据
Omnet++ 统计多车辆/全场景整体CO₂排放数据实现方法
默认逐节点输出CO₂数据是车联网仿真框架(最常用的是Veins+SUMO组合)的基础输出逻辑,不需要修改框架底层核心代码,通过三种常用方案就可以实现指定车辆组、全场景的排放聚合统计。
方案1:内置信号统计聚合(推荐,零额外代码量)
Omnet++本身的信号-统计机制原生支持跨模块的数值聚合,不需要自己写累加逻辑:
- 第一步:在仿真场景的根网络模块(一般是
Scenario.ned里定义的顶层网络)中声明聚合统计规则,直接通过内置的聚合语法指定统计范围:// 声明和车辆模块一致的CO2排放信号 @signal[co2emitted](type=double); // 统计全场景所有车辆的CO2排放总和,自动记录时序向量、最终标量值 @statistic[totalScenarioCo2]( title="Full scenario total CO2 emission"; source="sum(co2emitted from all)"; record=vector, scalar, timeavg ); // 统计指定车辆的CO2排放总和,括号内直接写目标车辆的模块路径即可 @statistic[targetVehiclesCo2]( title="Selected vehicles CO2 emission"; source="sum(co2emitted from (*.v[2],*.v[7],*.v[15],*.v[22]))"; record=vector, scalar ); - 第二步:正常运行仿真,生成的结果文件(
.sca/.vec)里会直接输出聚合完成的总排放数据,不需要逐节点导出后手动加和。如果要按规则批量匹配车辆,直接在from()里写模块匹配通配符即可,比如from(*.v[0..20])就是统计ID0到20的所有车辆。 - 注意提前确认车辆模块抛出CO₂数据的信号名和这里监听的信号名一致,Veins框架默认的CO₂排放信号名就是
co2emitted,如果是自定义排放模型对应修改信号名即可。
方案2:自定义监听模块(适合动态筛选统计场景)
如果需要按动态规则统计(比如统计某一时刻进入特定区域、某一车道的车辆总排放),可以通过自定义监听器实现灵活统计:
- 在场景管理模块中自定义一个继承自
cListener的监听器类,重写receiveSignal方法做数值累加; - 仿真初始化阶段,遍历所有符合筛选规则的车辆模块,给这些模块绑定CO₂信号的监听器;
- 仿真运行中可以按固定周期输出当前累计排放值,仿真结束时调用
recordScalar()把最终总结果写入结果文件。
核心代码片段参考:
// 自定义CO2聚合监听器 class Co2SumListener : public cListener { public: double totalCo2 = 0; void receiveSignal(cComponent *src, simsignal_t sigId, double val, cObject *det) override { totalCo2 += val; // 每次收到车辆上报的CO2增量就累加 } }; // 场景模块初始化阶段绑定监听 void ScenarioManager::initialize() { co2Listener = new Co2SumListener(); // 遍历需要统计的目标车辆,比如按动态筛选的车辆ID列表绑定 for (int id : dynamicSelectedVehIds) { cModule* veh = getModuleByPath(("node[" + to_string(id) + "]").c_str()); if (veh) veh->subscribe("co2emitted", co2Listener); } // 要统计全场景就遍历所有车辆节点全部订阅即可 } // 仿真结束时记录统计结果 void ScenarioManager::finish() { recordScalar("Dynamic selected vehicles total CO2", co2Listener->totalCo2); delete co2Listener; }
方案3:结果文件后处理(适合已完成仿真的场景)
如果已经跑完仿真、生成了逐节点的排放结果,不想重新跑仿真改配置,可以直接对结果文件做后处理:
- 用Omnet++自带的
scavetool工具把结果文件导出为CSV格式:scavetool x results/*.sca results/*.vec -o co2_raw.csv - 导出后用表格工具或者脚本,按时间步筛选出目标车辆的CO₂字段做求和,就能得到指定车辆组、全场景的总排放时序和累计值。
注意:如果你的CO₂数据是SUMO侧计算后同步到Omnet++的,要先确认同步的数值是单次时间步的排放增量,还是从仿真开始的累计值。如果是累计值不要直接累加,要先计算每个时间步的差值再求和,避免重复统计。
内容的提问来源于stack exchange,提问作者Oshadhi Gunathileke
相关产品推荐
相关产品推荐

