如何在 Veins 4.4 中正确使用 "moduleDisplayString"?
How to properly use "moduleDisplayString" in Veins 4.4?
我用过Veins 4.4,模拟运行正常
但是,我想在图形模式下更改车辆的外观。通过分析代码,我注意到 "moduleDisplayString" 参数用于执行此操作,但即使使用 OMNeT 的默认 DisplayString 值,我也总是会遇到映射错误。
[...]
*.manager.moduleType = "sdvn.nodes.Car"
*.manager.moduleName = "vehicle"
*.manager.moduleDisplayString = "i=misc/sun;is=vs"
[...]
错误信息:
invalid syntax for mapping "i=misc/sun;is=vs" for parameter "moduleDisplayString"
有没有人能正确使用这个参数?
这实际上是一个错误。在最新版本中,Veins 得到了扩展,可以为不同的 SUMO 车辆类型实例化不同的模块类型。例如你可以使用
*.manager.moduleType = "vtypeauto=Car vtypehuman=HumanCar"
*.manager.moduleName = "vtypeauto=node vtypehuman=human"
用Car.ned
模块实例化SUMO vtype vtypeauto
并在配置中用node
引用它(例如,*.node[*].mobility.z = 1.895
),同时实例化vtype vtypehuman
与 HumanCar.ned
模块并允许您使用 human
.
配置它
错误是由语法引起的,因为此功能使用 =
符号在键和值对之间进行拆分。 moduleDisplayString
参数也是如此,因此解析器不起作用。
我准备了一个补丁,其中可以使用单引号 ('
) 来保护显示字符串。在您的具体情况下,您的配置变为
*.manager.moduleDisplayString = "'i=misc/sun;is=vs'"
所以解析器知道如何正确读取参数。我也试过这个配置
*.manager.moduleType = "vtypeauto=Car vtypehuman=HumanCar"
*.manager.moduleName = "vtypeauto=node vtypehuman=human"
*.manager.moduleDisplayString = "vtypeauto='i=misc/sun;is=vs' vtypehuman='i=abstract/penguin'"
这是结果
您可以看到一种车辆的太阳图像和另一种车辆的企鹅图像。正如您正确指出的那样,Veins 目前显示一个框来突出显示汽车。这很可能很快就会被删除,或者用更好的图标进行更改(例如,实际的汽车图标)。
我会准备一个补丁,它应该很快会在 Veins 的 github 存储库上在线发布。同时,我将代码片段复制粘贴到这里,这样您就可以继续工作而无需等待正式发布。您需要做的是在 TraCIScenarioManager.cpp
.
中的函数 TraCIScenarioManager::parseMappings
之前添加以下函数
std::vector<std::string> getMapping(std::string el) {
//search for string protection characters '
char protection = '\'';
size_t first = el.find(protection);
size_t second;
size_t eq;
std::string type, value;
std::vector<std::string> mapping;
if (first == std::string::npos) {
//there's no string protection, simply split by '='
cStringTokenizer stk(el.c_str(), "=");
mapping = stk.asVector();
}
else {
//if there's string protection, we need to find a matching delimiter
second = el.find(protection, first + 1);
//ensure that a matching delimiter exists, and that it is at the end
if (second == std::string::npos || second != el.size() - 1)
throw cRuntimeError("invalid syntax for mapping \"%s\"", el.c_str());
//take the value of the mapping as the text within the quotes
value = el.substr(first + 1, second - first - 1);
if (first == 0) {
//if the string starts with a quote, there's only the value
mapping.push_back(value);
}
else {
//search for the equal sign
eq = el.find('=');
//this must be the character before the quote
if (eq == std::string::npos || eq != first - 1) {
throw cRuntimeError("invalid syntax for mapping \"%s\"", el.c_str());
}
else {
type = el.substr(0, eq);
}
mapping.push_back(type);
mapping.push_back(value);
}
}
return mapping;
}
然后在TraCIScenarioManager::parseMappings
函数里面改下面两行
cStringTokenizer typeMappingTz(typeMapping.c_str(), "=");
std::vector<std::string> mapping = typeMappingTz.asVector();
和
std::vector<std::string> mapping = getMapping(typeMapping);
我用过Veins 4.4,模拟运行正常
但是,我想在图形模式下更改车辆的外观。通过分析代码,我注意到 "moduleDisplayString" 参数用于执行此操作,但即使使用 OMNeT 的默认 DisplayString 值,我也总是会遇到映射错误。
[...]
*.manager.moduleType = "sdvn.nodes.Car"
*.manager.moduleName = "vehicle"
*.manager.moduleDisplayString = "i=misc/sun;is=vs"
[...]
错误信息:
invalid syntax for mapping "i=misc/sun;is=vs" for parameter "moduleDisplayString"
有没有人能正确使用这个参数?
这实际上是一个错误。在最新版本中,Veins 得到了扩展,可以为不同的 SUMO 车辆类型实例化不同的模块类型。例如你可以使用
*.manager.moduleType = "vtypeauto=Car vtypehuman=HumanCar"
*.manager.moduleName = "vtypeauto=node vtypehuman=human"
用Car.ned
模块实例化SUMO vtype vtypeauto
并在配置中用node
引用它(例如,*.node[*].mobility.z = 1.895
),同时实例化vtype vtypehuman
与 HumanCar.ned
模块并允许您使用 human
.
错误是由语法引起的,因为此功能使用 =
符号在键和值对之间进行拆分。 moduleDisplayString
参数也是如此,因此解析器不起作用。
我准备了一个补丁,其中可以使用单引号 ('
) 来保护显示字符串。在您的具体情况下,您的配置变为
*.manager.moduleDisplayString = "'i=misc/sun;is=vs'"
所以解析器知道如何正确读取参数。我也试过这个配置
*.manager.moduleType = "vtypeauto=Car vtypehuman=HumanCar"
*.manager.moduleName = "vtypeauto=node vtypehuman=human"
*.manager.moduleDisplayString = "vtypeauto='i=misc/sun;is=vs' vtypehuman='i=abstract/penguin'"
这是结果
您可以看到一种车辆的太阳图像和另一种车辆的企鹅图像。正如您正确指出的那样,Veins 目前显示一个框来突出显示汽车。这很可能很快就会被删除,或者用更好的图标进行更改(例如,实际的汽车图标)。
我会准备一个补丁,它应该很快会在 Veins 的 github 存储库上在线发布。同时,我将代码片段复制粘贴到这里,这样您就可以继续工作而无需等待正式发布。您需要做的是在 TraCIScenarioManager.cpp
.
TraCIScenarioManager::parseMappings
之前添加以下函数
std::vector<std::string> getMapping(std::string el) {
//search for string protection characters '
char protection = '\'';
size_t first = el.find(protection);
size_t second;
size_t eq;
std::string type, value;
std::vector<std::string> mapping;
if (first == std::string::npos) {
//there's no string protection, simply split by '='
cStringTokenizer stk(el.c_str(), "=");
mapping = stk.asVector();
}
else {
//if there's string protection, we need to find a matching delimiter
second = el.find(protection, first + 1);
//ensure that a matching delimiter exists, and that it is at the end
if (second == std::string::npos || second != el.size() - 1)
throw cRuntimeError("invalid syntax for mapping \"%s\"", el.c_str());
//take the value of the mapping as the text within the quotes
value = el.substr(first + 1, second - first - 1);
if (first == 0) {
//if the string starts with a quote, there's only the value
mapping.push_back(value);
}
else {
//search for the equal sign
eq = el.find('=');
//this must be the character before the quote
if (eq == std::string::npos || eq != first - 1) {
throw cRuntimeError("invalid syntax for mapping \"%s\"", el.c_str());
}
else {
type = el.substr(0, eq);
}
mapping.push_back(type);
mapping.push_back(value);
}
}
return mapping;
}
然后在TraCIScenarioManager::parseMappings
函数里面改下面两行
cStringTokenizer typeMappingTz(typeMapping.c_str(), "=");
std::vector<std::string> mapping = typeMappingTz.asVector();
和
std::vector<std::string> mapping = getMapping(typeMapping);