本文档简要描述了如何向 SUMO 中添加新的跟驰模型。我们将通过实现一个名为 "smartSK" 的测试模型来完成此过程。在实现您自己的模型时,您也应该查找(grep)我们在此处使用的名称的出现。
跟驰模型的类#
最好从一个已存在的模型开始。模型位于 <SUMO_HOME>/src/microsim/cfmodels,新添加的模型也应该放在这里。复制 MSCFModel_KraussOrig1.h 和 MSCFModel_KraussOrig1.cpp 并重命名它们。名称应为 "MSCFModel_<您的模型名称>",在我们的例子中是 "MSCFModel_SmartSK"。
Convention
跟驰模型的实现位于 <SUMO_HOME>/src/microsim/cfmodels。
Convention
跟驰类的名称应以 "MSCFModel_" 开头。
现在,打开这两个文件,并将所有出现的 MSCFModel_KraussOrig1 重命名为您的类名。
将文件添加到 <SUMO_HOME>/src/microsim/cfmodels/CMakeLists.txt。
加载到仿真中#
我们现在添加 XML 元素,以允许我们定义和解析模型的参数。扩展位于 <SUMO_HOME>/src/utils/xml/SUMOXMLDefinitions.cpp 中的已知元素列表 "SUMOXMLDefinitions::tags"。 在 SUMOXMLDefinitions.h 中:
SUMO_TAG_CF_SMART_SK,
在 SUMOXMLDefinitions.cpp 中:
{ "carFollowing-SmartSK", SUMO_TAG_CF_SMART_SK },
此外,您还需要在 SUMOXMLDefinitions.cpp 中的 SUMOXMLDefinitions::carFollowModelValues[] 中添加一个条目:
{ "SmartSK", SUMO_TAG_CF_SMART_SK },
跟驰模型在 <SUMO_HOME>/src/microsim/MSVehicleType.cpp 中的 MSVehicleType::build(...) 实例化。您会在这里找到一个 switch 语句,您必须将调用模型构造函数的代码放入其中。
case SUMO_TAG_CF_SMART_SK:
model = new MSCFModel_SmartSK(vtype,
from.getCFParam(SUMO_ATTR_ACCEL, SUMOVTypeParameter::getDefaultAccel(from.vehicleClass)),
from.getCFParam(SUMO_ATTR_DECEL, SUMOVTypeParameter::getDefaultDecel(from.vehicleClass)),
from.getCFParam(SUMO_ATTR_SIGMA, SUMOVTypeParameter::getDefaultImperfection(from.vehicleClass)),
from.getCFParam(SUMO_ATTR_TAU, 1.),
from.getCFParam(SUMO_ATTR_TMP1, 1.),
from.getCFParam(SUMO_ATTR_TMP1, 1.),
from.getCFParam(SUMO_ATTR_TMP1, 1.),
from.getCFParam(SUMO_ATTR_TMP1, 1.),
from.getCFParam(SUMO_ATTR_TMP1, 1.));
您可能会注意到,构造函数是从 "from" 中读取值的。第一个参数以 SUMO_ATTR_ 开头,表示命名参数的 XML 属性。如果这些属性是新的,则必须将它们添加到 <SUMO_HOME> 中。在 SUMOXMLDefinitions.h 中:
SUMO_ATTR_TMP1,
SUMO_ATTR_TMP2,
SUMO_ATTR_TMP3,
SUMO_ATTR_TMP4,
SUMO_ATTR_TMP5,
在 SUMOXMLDefinitions.cpp 中:
{ "tmp1", SUMO_ATTR_TMP1 },
{ "tmp2", SUMO_ATTR_TMP2 },
{ "tmp3", SUMO_ATTR_TMP3 },
{ "tmp4", SUMO_ATTR_TMP4 },
{ "tmp5", SUMO_ATTR_TMP5 },
第二个参数表示默认值。有两种不同的机制来定义默认值。要么它们与车辆类别无关(例如,对于乘用车和卡车是相同的),那么您可以在这里简单地声明数字;要么您希望为不同的车辆类别设置不同的默认值,那么请将相关代码插入 <SUMO_HOME>/src/utils/vehicle/SUMOVTypeParameter.cpp。目前,您只能将浮点值作为模型参数。
您还必须在 <SUMO_HOME>/src/utils/vehicle/SUMOVehicleParserHelper.cpp 中的 getAllowedCFModelAttrs() 方法中定义必须读取哪些参数:
std::set<SumoXMLAttr> smartSKParams;
smartSKParams.insert(SUMO_ATTR_ACCEL);
smartSKParams.insert(SUMO_ATTR_DECEL);
smartSKParams.insert(SUMO_ATTR_SIGMA);
smartSKParams.insert(SUMO_ATTR_TAU);
smartSKParams.insert(SUMO_ATTR_TMP1);
smartSKParams.insert(SUMO_ATTR_TMP2);
smartSKParams.insert(SUMO_ATTR_TMP3);
smartSKParams.insert(SUMO_ATTR_TMP4);
smartSKParams.insert(SUMO_ATTR_TMP5);
allowedCFModelAttrs[SUMO_TAG_CF_SMART_SK] = smartSKParams;
请注意,我们必须调整构造函数以检索额外的参数 (tmp1-tmp5)。我们还必须调整位于我们类中的 MSCFModel_SmartSK::duplicate(...) 中的拷贝构造函数。
为了进一步交互,您还必须在模型的 .h 类中调整模型的 "id":
virtual int getModelID() const {
return SUMO_TAG_CF_SMART_SK;
}
通过 TraCI 使用自定义参数#
一个 carFollowModel 可以重写从 MSCFModel 继承的 getParameter 和 setParameter 函数。
任何对 'traci.vehicle.setParameter' 和 'traci.vehicle.getParameter' 的调用,如果键以 "carFollowModel." 开头,都将被转发到这些方法(不带前缀)。
调用
traci.vehicle.setParameter(vehID, "carFollowModel.XYZ", "42")
将被映射到调用
MSCFModel::setParameter(MSVehicle* veh, "XYZ" , "42"),该调用在车辆的当前 carFollowModel 上执行。
XML 验证#
Sumo 执行 xml 验证。如果您添加了新的 XML 元素或属性,您要么需要调整 <SUMO_HOME>/data/xsd 中的 XML 模式文件,要么添加选项
--xml-validation never
