From ffdf41addf82c588ba772746f5b0bacc7e7f028f Mon Sep 17 00:00:00 2001 From: xubeyb Date: Tue, 17 May 2022 14:25:32 +0300 Subject: [PATCH 1/2] Improving pythonclient, rpc and unreal apis to allow independent control of each gimbal angle --- AirLib/include/api/RpcLibClientBase.hpp | 3 ++ AirLib/include/api/WorldSimApiBase.hpp | 3 ++ AirLib/src/api/RpcLibClientBase.cpp | 15 ++++++++ AirLib/src/api/RpcLibServerBase.cpp | 12 ++++++ PythonClient/airsim/client.py | 40 ++++++++++++++++++++ Unreal/Plugins/AirSim/Source/PIPCamera.cpp | 39 +++++++++++++++++++ Unreal/Plugins/AirSim/Source/PIPCamera.h | 3 ++ Unreal/Plugins/AirSim/Source/WorldSimApi.cpp | 30 +++++++++++++++ Unreal/Plugins/AirSim/Source/WorldSimApi.h | 3 ++ docs/image_apis.md | 7 ++++ 10 files changed, 155 insertions(+) diff --git a/AirLib/include/api/RpcLibClientBase.hpp b/AirLib/include/api/RpcLibClientBase.hpp index fd90824524..04d32dd44c 100644 --- a/AirLib/include/api/RpcLibClientBase.hpp +++ b/AirLib/include/api/RpcLibClientBase.hpp @@ -145,6 +145,9 @@ namespace airlib void simSetDistortionParam(const std::string& camera_name, const std::string& param_name, float value, const std::string& vehicle_name = "", bool external = false); std::vector simGetDistortionParams(const std::string& camera_name, const std::string& vehicle_name = "", bool external = false); void simSetCameraPose(const std::string& camera_name, const Pose& pose, const std::string& vehicle_name = "", bool external = false); + void simSetCameraPitch(const std::string& camera_name, float pitch, const std::string& vehicle_name = "", bool external = false); + void simSetCameraRoll(const std::string& camera_name, float roll, const std::string& vehicle_name = "", bool external = false); + void simSetCameraYaw(const std::string& camera_name, float yaw, const std::string& vehicle_name = "", bool external = false); void simSetCameraFov(const std::string& camera_name, float fov_degrees, const std::string& vehicle_name = "", bool external = false); bool simCreateVoxelGrid(const Vector3r& position, const int& x_size, const int& y_size, const int& z_size, const float& res, const std::string& output_file); diff --git a/AirLib/include/api/WorldSimApiBase.hpp b/AirLib/include/api/WorldSimApiBase.hpp index 833e590d7d..cabccb7087 100644 --- a/AirLib/include/api/WorldSimApiBase.hpp +++ b/AirLib/include/api/WorldSimApiBase.hpp @@ -96,6 +96,9 @@ namespace airlib // Camera APIs virtual CameraInfo getCameraInfo(const CameraDetails& camera_details) const = 0; virtual void setCameraPose(const msr::airlib::Pose& pose, const CameraDetails& camera_details) = 0; + virtual void setCameraPitch(float pitch, const CameraDetails& camera_details) = 0; + virtual void setCameraRoll(float roll, const CameraDetails& camera_details) = 0; + virtual void setCameraYaw(float yaw, const CameraDetails& camera_details) = 0; virtual void setCameraFoV(float fov_degrees, const CameraDetails& camera_details) = 0; virtual void setDistortionParam(const std::string& param_name, float value, const CameraDetails& camera_details) = 0; virtual std::vector getDistortionParams(const CameraDetails& camera_details) const = 0; diff --git a/AirLib/src/api/RpcLibClientBase.cpp b/AirLib/src/api/RpcLibClientBase.cpp index 891c5155d6..55d856f790 100644 --- a/AirLib/src/api/RpcLibClientBase.cpp +++ b/AirLib/src/api/RpcLibClientBase.cpp @@ -549,6 +549,21 @@ __pragma(warning(disable : 4239)) pimpl_->client.call("simSetCameraPose", camera_name, RpcLibAdaptorsBase::Pose(pose), vehicle_name, external); } + void RpcLibClientBase::simSetCameraPitch(const std::string& camera_name, float pitch, const std::string& vehicle_name, bool external) + { + pimpl_->client.call("simSetCameraPitch", camera_name, pitch, vehicle_name, external); + } + + void RpcLibClientBase::simSetCameraRoll(const std::string& camera_name, float roll, const std::string& vehicle_name, bool external) + { + pimpl_->client.call("simSetCameraRoll", camera_name, roll, vehicle_name, external); + } + + void RpcLibClientBase::simSetCameraYaw(const std::string& camera_name, float yaw, const std::string& vehicle_name, bool external) + { + pimpl_->client.call("simSetCameraYaw", camera_name, yaw, vehicle_name, external); + } + void RpcLibClientBase::simSetCameraFov(const std::string& camera_name, float fov_degrees, const std::string& vehicle_name, bool external) { pimpl_->client.call("simSetCameraFov", camera_name, fov_degrees, vehicle_name, external); diff --git a/AirLib/src/api/RpcLibServerBase.cpp b/AirLib/src/api/RpcLibServerBase.cpp index 0710bd8d5a..2ae64bbcf5 100644 --- a/AirLib/src/api/RpcLibServerBase.cpp +++ b/AirLib/src/api/RpcLibServerBase.cpp @@ -352,6 +352,18 @@ namespace airlib getWorldSimApi()->setCameraPose(pose.to(), CameraDetails(camera_name, vehicle_name, external)); }); + pimpl_->server.bind("simSetCameraPitch", [&](const std::string& camera_name, float pitch, const std::string& vehicle_name, bool external) -> void { + getWorldSimApi()->setCameraPitch(pitch, CameraDetails(camera_name, vehicle_name, external)); + }); + + pimpl_->server.bind("simSetCameraRoll", [&](const std::string& camera_name, float roll, const std::string& vehicle_name, bool external) -> void { + getWorldSimApi()->setCameraRoll(roll, CameraDetails(camera_name, vehicle_name, external)); + }); + + pimpl_->server.bind("simSetCameraYaw", [&](const std::string& camera_name, float yaw, const std::string& vehicle_name, bool external) -> void { + getWorldSimApi()->setCameraYaw(yaw, CameraDetails(camera_name, vehicle_name, external)); + }); + pimpl_->server.bind("simSetCameraFov", [&](const std::string& camera_name, float fov_degrees, const std::string& vehicle_name, bool external) -> void { getWorldSimApi()->setCameraFoV(fov_degrees, CameraDetails(camera_name, vehicle_name, external)); }); diff --git a/PythonClient/airsim/client.py b/PythonClient/airsim/client.py index 4f139ac552..11c7a06250 100644 --- a/PythonClient/airsim/client.py +++ b/PythonClient/airsim/client.py @@ -778,6 +778,46 @@ def simSetCameraPose(self, camera_name, pose, vehicle_name = '', external = Fals #TODO : below str() conversion is only needed for legacy reason and should be removed in future self.client.call('simSetCameraPose', str(camera_name), pose, vehicle_name, external) + def simSetCameraPitch(self, camera_name, pitch, vehicle_name = '', external = False): + """ + - Control the pitch angle of a selected camera + + Args: + camera_name (str): Name of the camera to be controlled + pitch (float): Pitch value (in degrees) representing the desired orientation of the camera + vehicle_name (str, optional): Name of vehicle which the camera corresponds to + external (bool, optional): Whether the camera is an External Camera + """ +#TODO : below str() conversion is only needed for legacy reason and should be removed in future + self.client.call('simSetCameraPitch', str(camera_name), pitch, vehicle_name, external) + + def simSetCameraRoll(self, camera_name, roll, vehicle_name = '', external = False): + """ + - Control the roll angle of a selected camera + + Args: + camera_name (str): Name of the camera to be controlled + roll (float): Roll value (in degrees) representing the desired roll angle of the camera + vehicle_name (str, optional): Name of vehicle which the camera corresponds to + external (bool, optional): Whether the camera is an External Camera + """ +#TODO : below str() conversion is only needed for legacy reason and should be removed in future + self.client.call('simSetCameraRoll', str(camera_name), roll, vehicle_name, external) + + def simSetCameraYaw(self, camera_name, yaw, vehicle_name = '', external = False): + """ + - Control the yaw angle of a selected camera + + Args: + camera_name (str): Name of the camera to be controlled + yaw (float): Yaw value (in degrees) representing the desired yaw angle of the camera + vehicle_name (str, optional): Name of vehicle which the camera corresponds to + external (bool, optional): Whether the camera is an External Camera + """ +#TODO : below str() conversion is only needed for legacy reason and should be removed in future + self.client.call('simSetCameraYaw', str(camera_name), yaw, vehicle_name, external) + + def simSetCameraFov(self, camera_name, fov_degrees, vehicle_name = '', external = False): """ - Control the field of view of a selected camera diff --git a/Unreal/Plugins/AirSim/Source/PIPCamera.cpp b/Unreal/Plugins/AirSim/Source/PIPCamera.cpp index 946cd9b753..d5957602d1 100644 --- a/Unreal/Plugins/AirSim/Source/PIPCamera.cpp +++ b/Unreal/Plugins/AirSim/Source/PIPCamera.cpp @@ -316,6 +316,45 @@ void APIPCamera::setCameraPose(const msr::airlib::Pose& relative_pose) } } +void APIPCamera::setCameraPitch(float pitch) +{ + FRotator rotator = this->GetActorRotation(); + rotator.Pitch = pitch; + + if (gimbal_stabilization_ > 0) { + gimbald_rotator_.Pitch = rotator.Pitch; + } + else { + this->SetActorRelativeRotation(rotator); + } +} + +void APIPCamera::setCameraRoll(float roll) +{ + FRotator rotator = this->GetActorRotation(); + rotator.Roll = roll; + + if (gimbal_stabilization_ > 0) { + gimbald_rotator_.Roll = rotator.Roll; + } + else { + this->SetActorRelativeRotation(rotator); + } +} + +void APIPCamera::setCameraYaw(float yaw) +{ + FRotator rotator = this->GetActorRotation(); + rotator.Yaw = yaw; + + if (gimbal_stabilization_ > 0) { + gimbald_rotator_.Yaw = rotator.Yaw; + } + else { + this->SetActorRelativeRotation(rotator); + } +} + void APIPCamera::setCameraFoV(float fov_degrees) { int image_count = static_cast(Utils::toNumeric(ImageType::Count)); diff --git a/Unreal/Plugins/AirSim/Source/PIPCamera.h b/Unreal/Plugins/AirSim/Source/PIPCamera.h index a50fefe552..b4fff7eee5 100644 --- a/Unreal/Plugins/AirSim/Source/PIPCamera.h +++ b/Unreal/Plugins/AirSim/Source/PIPCamera.h @@ -69,6 +69,9 @@ class AIRSIM_API APIPCamera : public ACineCameraActor //CinemAirSim void setupCameraFromSettings(const CameraSetting& camera_setting, const NedTransform& ned_transform); void setCameraPose(const msr::airlib::Pose& relative_pose); + void setCameraPitch(float pitch); + void setCameraRoll(float roll); + void setCameraYaw(float yaw); void setCameraFoV(float fov_degrees); msr::airlib::CameraInfo getCameraInfo() const; std::vector getDistortionParams() const; diff --git a/Unreal/Plugins/AirSim/Source/WorldSimApi.cpp b/Unreal/Plugins/AirSim/Source/WorldSimApi.cpp index 11e7b6cf97..dc2e432cff 100644 --- a/Unreal/Plugins/AirSim/Source/WorldSimApi.cpp +++ b/Unreal/Plugins/AirSim/Source/WorldSimApi.cpp @@ -864,6 +864,36 @@ void WorldSimApi::setCameraPose(const msr::airlib::Pose& pose, const CameraDetai true); } +void WorldSimApi::setCameraPitch(float pitch, const CameraDetails& camera_details) +{ + APIPCamera* camera = simmode_->getCamera(camera_details); + + UAirBlueprintLib::RunCommandOnGameThread([camera, pitch]() { + camera->setCameraPitch(pitch); + }, + true); +} + +void WorldSimApi::setCameraRoll(float roll, const CameraDetails& camera_details) +{ + APIPCamera* camera = simmode_->getCamera(camera_details); + + UAirBlueprintLib::RunCommandOnGameThread([camera, roll]() { + camera->setCameraRoll(roll); + }, + true); +} + +void WorldSimApi::setCameraYaw(float yaw, const CameraDetails& camera_details) +{ + APIPCamera* camera = simmode_->getCamera(camera_details); + + UAirBlueprintLib::RunCommandOnGameThread([camera, yaw]() { + camera->setCameraYaw(yaw); + }, + true); +} + void WorldSimApi::setCameraFoV(float fov_degrees, const CameraDetails& camera_details) { APIPCamera* camera = simmode_->getCamera(camera_details); diff --git a/Unreal/Plugins/AirSim/Source/WorldSimApi.h b/Unreal/Plugins/AirSim/Source/WorldSimApi.h index a65a8187ef..3ea971c25a 100644 --- a/Unreal/Plugins/AirSim/Source/WorldSimApi.h +++ b/Unreal/Plugins/AirSim/Source/WorldSimApi.h @@ -87,6 +87,9 @@ class WorldSimApi : public msr::airlib::WorldSimApiBase // Camera APIs virtual msr::airlib::CameraInfo getCameraInfo(const CameraDetails& camera_details) const override; virtual void setCameraPose(const msr::airlib::Pose& pose, const CameraDetails& camera_details) override; + virtual void setCameraPitch(float pitch, const CameraDetails& camera_details) override; + virtual void setCameraRoll(float roll, const CameraDetails& camera_details) override; + virtual void setCameraYaw(float yaw, const CameraDetails& camera_details) override; virtual void setCameraFoV(float fov_degrees, const CameraDetails& camera_details) override; virtual void setDistortionParam(const std::string& param_name, float value, const CameraDetails& camera_details) override; virtual std::vector getDistortionParams(const CameraDetails& camera_details) const override; diff --git a/docs/image_apis.md b/docs/image_apis.md index 963f24702e..c718e90bdf 100644 --- a/docs/image_apis.md +++ b/docs/image_apis.md @@ -175,6 +175,13 @@ camera_pose = airsim.Pose(airsim.Vector3r(0, 0, 0), airsim.to_quaternion(0.26179 client.simSetCameraPose(0, camera_pose); ``` +- `simSetCameraPitch` allows controlling camera pitch independent of the other angles +- `simSetCameraRoll` allows controlling camera roll independent of the other angles +- `simSetCameraYaw` allows controlling camera yaw independent of the other angles +``` +client.simSetCameraPitch(0, pitch) # in degrees +``` + - `simSetCameraFov` allows changing the Field-of-View of the camera at runtime. - `simSetDistortionParams`, `simGetDistortionParams` allow setting and fetching the distortion parameters K1, K2, K3, P1, P2 From e017998643c1ddf16814f13215c69021ba93129f Mon Sep 17 00:00:00 2001 From: Xubeyb <42241276+xubeyb@users.noreply.github.com> Date: Tue, 17 May 2022 14:33:17 +0300 Subject: [PATCH 2/2] Indentation fix --- AirLib/src/api/RpcLibClientBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AirLib/src/api/RpcLibClientBase.cpp b/AirLib/src/api/RpcLibClientBase.cpp index 55d856f790..ab0487994a 100644 --- a/AirLib/src/api/RpcLibClientBase.cpp +++ b/AirLib/src/api/RpcLibClientBase.cpp @@ -549,7 +549,7 @@ __pragma(warning(disable : 4239)) pimpl_->client.call("simSetCameraPose", camera_name, RpcLibAdaptorsBase::Pose(pose), vehicle_name, external); } - void RpcLibClientBase::simSetCameraPitch(const std::string& camera_name, float pitch, const std::string& vehicle_name, bool external) + void RpcLibClientBase::simSetCameraPitch(const std::string& camera_name, float pitch, const std::string& vehicle_name, bool external) { pimpl_->client.call("simSetCameraPitch", camera_name, pitch, vehicle_name, external); }