查阅AirSim的文档可知,AirSim支持通过simSetDistortionParams设置K1, K2, K3, P1, P2这5个畸变系数。UE镜头畸变模拟:OpenCV Lens Distortion一文提及过,Unreal的OpenCV Lens Distortion插件是通过生成的Post Process Material对UV坐标施加偏移来模拟镜头畸变。那么,AirSim又是如何处理的呢?
基本流程探究 打开任意集成了AirSim插件的Unreal工程,用Visual Studio翻阅工程源码,重点是AirSim插件的cpp代码。
在整个项目中搜索simSetDistortionParams,找到RPC客户端和服务端的实现。客户端:
// <path-to-project>\Plugins\AirSim\Source\AirLib\src\api\RpcLibClientBase.cpp void RpcLibClientBase::simSetDistortionParam(const std::string& camera_name, const std::string& param_name, float value, const std::string& vehicle_name, bool external) { pimpl_->client.call("simSetDistortionParam", camera_name, param_name, value, vehicle_name, external); } 服务端:
// <path-to-project>\Plugins\AirSim\Source\AirLib\src\api\RpcLibServerBase.cpp // 省略其余binding... pimpl_->server.bind("simSetDistortionParam", [&](const std::string& camera_name, const std::string& param_name, float value, const std::string& vehicle_name, bool external) -> void { getWorldSimApi()->setDistortionParam(param_name, value, CameraDetails(camera_name, vehicle_name, external)); }); // ... 顺藤摸瓜,找到WorldSimApi::setDistortionParam:
void WorldSimApi::setDistortionParam(const std::string& param_name, float value, const CameraDetails& camera_details) { APIPCamera* camera = simmode_->getCamera(camera_details); UAirBlueprintLib::RunCommandOnGameThread([camera, ¶m_name, &value]() { camera->setDistortionParam(param_name, value); }, true); } 再看APIPCamera::setDistortionParam:
void APIPCamera::setDistortionParam(const std::string& param_name, float value) { distortion_param_instance_->SetScalarParameterValue(FName(param_name.c_str()), value); } 查看APIPCamera类的声明,重点关注带“distortion”字样的成员:
// <path-to-project>\Plugins\AirSim\Source\PIPCamera.h UCLASS() class AIRSIM_API APIPCamera : public ACineCameraActor //CinemAirSim { // 省略了其余代码... private: UPROPERTY() TArray<USceneCaptureComponent2D*> captures_; // ... UPROPERTY() UCineCameraComponent* camera_; // ... UPROPERTY() TArray<UMaterialInstanceDynamic*> distortion_materials_; UPROPERTY() UMaterial* distortion_material_static_; // ... }; 可以猜测AirSim也是通过设置Post Process Material来模拟的畸变。查找distortion_materials_和distortion_material_static_的引用,找到:
...