一次airsim添加传感器类型api尝试的总结

Airsim添加API总结

大概前后看了几天,也对照着官方文档。添加了一个能够让距离传感器根据给定角度绕自身Z轴旋转的的API。

官方文档对于multirotor只给了get类型的一个示例说明。

而我是要添加一个修改传感器中某个参数值的函数,所以其实还是有些许不符。于是就自己琢磨了一下Airsim的代码。

首先我参考的是getDistanceSensordata这个API,同时也在学习Airsim的整体架构。

Airsim的各个功能架构,大部都是以UpdatableObject为最底层,然后上一层是某个模块的Base,比如SensorBaseVehicleApiBase这些,

之后再根据是car还是multirotor,是IMU还是distanceSensor细分到更多的具体base类。在vehicleApiBase中也能调用搭载于其上的各种SensorBase
在这里插入图片描述
图中最上面的RpcClientBase如果不是用c++api的话其实用不到。

api调用最先是由rpclib从client端传输到server的,需要在server端和client端都写好接收的函数,server需要bind住,而client我用的是python端,只需要模仿其他api写一个发送函数就好。

//RpcLibServerBase.cpp
pimpl_->server.bind("setYaw_distance", [&](const std::string& distance_sensor_name, const std::string& vehicle_name, double Zangle) -> bool {
            getVehicleApi(vehicle_name)->setYaw_distance(distance_sensor_name, Zangle);
            return true;
        });

因为sensor的实例都是和vehicle绑定的,所以想找到指向传感器实例的指针,就要在getVehicleApiBase中添加方法,这里我就模仿getDistanceSensorData自己写了一个,但是因为最终是要改变值的,所以这里模仿其他set型函数设置了一个bool setYaw_distance函数,中间会有很多const类型的报错,在非常担心会有野指针出现的情况下紧张地删掉了好多const,或者直接复制一些函数写一个删去const的专供型。

// Distance Sensor API
virtual const DistanceSensorData& getDistanceSensorData(const std::string& distance_sensor_name)
        {
            auto* distance_sensor = static_cast<const DistanceBase*>(findSensorByName(distance_sensor_name, SensorBase::SensorType::Distance));
            if (distance_sensor == nullptr)//throw VehicleControllerException(Utils::stringf("No distance sensor with name %s exist on vehicle", distance_sensor_name.c_str()));    
                throw VehicleControllerException("No distance sensor with name %s exist on vehicle");

            return distance_sensor->getOutput();
        }
virtual bool setYaw_distance(const std::string& distance_sensor_name, double Zangle)
        {   
            printf("VehicleApiBase setYaw is running!");
            //auto* distance_sensor = static_cast<const DistanceSimple*>(findSensorByName(distance_sensor_name, SensorBase::SensorType::Distance));
            auto* distance_sensor = static_cast<DistanceBase*>(findSensorByName_Distance(distance_sensor_name, SensorBase::SensorType::Distance)); //不知道能不能找到参数呢
            //*distance_sensor = static_cast<DistanceSimple> (distance_sensor);
            if (distance_sensor == nullptr)
                throw VehicleControllerException("set Yaw failed!");
                //throw VehicleControllerException(Utils::stringf("No distance sensor with name %s exist on vehicle", distance_sensor_name.c_str()));   
            
            return distance_sensor->setYaw_distance(Zangle);
        }

这里如果顺利就能正常得到指向distancesensor实例的指针了。

我觉得可以简单表示为:

DistanceBase *distance_sensor = DistanceSimple distance_sensor_simple

一个父类指针指向了其子类。

而想要修改DistanceSimple中的值,可以使用虚函数重写。虚函数中直接调用DistanceSimple中的**params_**进行修改就好。

到这里基本就完成了一个api的设计和实现。接下来需要使用它了。

这里有一个问题,也是在看官方文档的时候没注意的地方。我没有source built整个airlib,而只是简单地在vs2019中debug了它。

这里的问题其实是在于rpclib

rpclib的debug要求的是c++17,而UE4的运行环境是c++14,这就导致其实际上不能在vs2019上被debug,而是被注释掉了。

airsim调用这个模块是用lib文件的,也就是让rpclib在工程外进行编译,生成了compiled binary后,直接作为静态库导入,所以不能简单debug就进行测试!

需要在airsim-master目录用build.cmd命令进行编译,成功后把这个Plugin文件再放到目标文件夹中,这样才行。


版权声明:本文为weixin_40733121原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。