用户自定义变量¶
1. 功能介绍¶
1.1 简介¶
支持通过API触发仿真场景内的交通元素执行对应的行为规划,实现 OpenSCENARIO 未覆盖的复杂或自定义条件判断,扩展场景逻辑灵活性。
1.2 适用范围¶
交通元素:主车预设、动态元素、静态元素。
2. 使用示例¶
首先在用例内预设一个或多个变量(例:TruckController0、TruckController1),用于控制对应的交通元素。
然后通过API设置对应变量的值(例:设置TruckController0为Drive0.1、Drive10),可以用于触发用例内预设好的动作(例:速度),速度动作是由变速距离来控制变速过程的,通过两个变速动作,先加速后减速,合起来的变速距离为期望的运动距离,即达到指定运动距离的目的。
2.1 行为定义¶
2.1.1 添加交通元素¶
进入 动态元素->商用车 ,拖入 白色卡车01 到2D预览面板。
2.1.2 添加行为规划¶
选中 白色卡车01 ,切换到 行为规划,点击 添加事件。
点击 添加动作 ,选择 专属动作 。
选择 速度 。
设置动作的参数,变速维度设为‘距离’,这样可以控制变速距离;变速形态这个不限制,建议设置为‘线性’,方便计算目标速度;设置需要的变速距离,比如是0.01m,绝对目标速度由加速时间和加速度决定,截图中设置的是0.01m/s,运动时间就是1s,加速度是1。
设置触发条件,点击 添加条件 , 选择 user-defined-values。
第一个用户自定义值为name,第二个用户自定义值为value,这两个值接下来会通过API来对应主要需要注意的是,规则为‘=’,条件边界为‘上升’,这样可以保证动作一次触发,只执行一次。
事件默认只能执行一次,通过API再次调用时将不会再被执行。如果需要执行多次,可打开 文本编辑器,设置最大可执行次数。
调整步骤:1、修改事件名;2、打开文本编辑器;3、Ctrl+F,搜索事件;4、调整最大可执行次数maximumExecutionCount。
保存并运行用例,然后通过API调用的方式来触发 事件1 开始执行。
2.2 API 调用¶
Linux通过C/C++接口调用API
集卡控制的接口:SCENARIO_API bool SetUserDefinedValueCondition(char* name, char* value)
依赖于SimOneTransAPI的动态库,linux下,库所在位置:SimOneAPI\lib\Linux64\libSimOneTransAPI.so,头文件位置:SimOneAPI\include\SimOneScenarioTransAPI.h,这个库有很多依赖,可以参考:SimOneAPI\SimOneTrans\CMakeLists.txt
在SimOneAPI的SimOneTrans下有对应的Sample工程,这个接口的调用可以不依赖SimOneAPI,在单独的工程中调用
2.2.1 触发事件执行¶
控制接口调用示例如下:
#include "SimOneScenarioTransAPI.h"
#include<thread>
int main(int argc, char* argv[])
{
while (1)
{
auto in = getchar();
if (in == '1')
{
SimOneAPI::SetUserDefinedValueCondition("TruckController0", "DRIVE0.1");
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return 0;
}
可根据示例进行扩展,通过不同的输入,来控制发送不同的值,从而触发用例里不同的动作。
2.2.2 获取事件状态¶
通过SetScenarioEventCB,设置一个回调函数,当用户自定义事件发出时,会执行设置的回调函数,拿到用户自定义指令
#include "SimOneServiceAPI.h"
#include "SimOnePNCAPI.h"
void handleScenarioEvent(const char* source, const char* target, const char* type, const char* content) {
std::cout << "event " << content << std::endl;
}
int main(int argc, char* argv[])
{
bool isJoinTimeLoop = false;
const char* MainVehicleId = "0";
SimOneAPI::InitSimOneAPI(MainVehicleId, isJoinTimeLoop, "127.0.0.1");
SimOneAPI::SetScenarioEventCB(handleScenarioEvent);
while (1)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return 0;
}







