跳转至

用户自定义变量

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;
}