Airsim添加API总结
大概前后看了几天,也对照着官方文档。添加了一个能够让距离传感器根据给定角度绕自身Z轴旋转的的API。
官方文档对于multirotor只给了get类型的一个示例说明。
而我是要添加一个修改传感器中某个参数值的函数,所以其实还是有些许不符。于是就自己琢磨了一下Airsim的代码。
首先我参考的是getDistanceSensordata这个API,同时也在学习Airsim的整体架构。
Airsim的各个功能架构,大部都是以UpdatableObject为最底层,然后上一层是某个模块的Base,比如SensorBase,VehicleApiBase这些,
之后再根据是car还是multirotor,是IMU还是distanceSensor细分到更多的具体base类。在vehicleApiBase中也能调用搭载于其上的各种SensorBase。
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文件再放到目标文件夹中,这样才行。
|