From ebc5e36532b8945ea5de7ae76e97ba75a9e08108 Mon Sep 17 00:00:00 2001 From: Shital Shah Date: Sat, 8 Jul 2017 21:46:06 -0700 Subject: [PATCH] gaussian pose generator, no eye adaptation, docs update and other stereo gen tweaks --- .../common/common_utils/RandomGenerator.hpp | 5 +++ Examples/PoseGenerators.hpp | 42 +++++++++--------- Examples/StereoImageGenerator.hpp | 36 ++++++++++----- Examples/main.cpp | 6 +-- PythonClient/camera.py | 2 +- PythonClient/navigate.py | 2 +- .../Content/Blueprints/BP_PIPCamera.uasset | Bin 19990 -> 20910 bytes .../Source/SimMode/SimModeWorldMultiRotor.cpp | 2 + docs/apis.md | 25 +++++++++-- docs/camera_views.md | 8 ++-- docs/python.md | 2 +- 11 files changed, 84 insertions(+), 46 deletions(-) diff --git a/AirLib/include/common/common_utils/RandomGenerator.hpp b/AirLib/include/common/common_utils/RandomGenerator.hpp index cadd3ce1..fe977b89 100644 --- a/AirLib/include/common/common_utils/RandomGenerator.hpp +++ b/AirLib/include/common/common_utils/RandomGenerator.hpp @@ -19,6 +19,11 @@ public: { } + void seed(int val) + { + rand_.seed(val); + } + TReturn next() { return dist_(rand_); diff --git a/Examples/PoseGenerators.hpp b/Examples/PoseGenerators.hpp index 63ad759f..a4a9413c 100644 --- a/Examples/PoseGenerators.hpp +++ b/Examples/PoseGenerators.hpp @@ -13,40 +13,38 @@ STRICT_MODE_ON class RandomPointPoseGenerator { public: - RandomPointPoseGenerator(msr::airlib::RpcLibClient* client) + RandomPointPoseGenerator(msr::airlib::RpcLibClient* client, int random_seed) : client_(client), - rand_xy_(-500.0f, 500.0f), rand_z_(-10.0f, -1.0f), rand_pitch_(-M_PIf / 2, M_PIf / 2), - rand_yaw_(-M_PIf, M_PIf) + rand_xy_(0.0f, 150.0f), rand_z_(2.0f, 3.0f), rand_pitch_(0.0f, M_PIf / 2), + rand_yaw_(0.0f, M_PIf) { + rand_xy_.seed(random_seed); + rand_z_.seed(random_seed); + rand_pitch_.seed(random_seed); + rand_yaw_.seed(random_seed); } void next() { - const auto& collision_info = client_->getCollisionInfo(); - auto position = client_->getPosition(); - auto orientation = client_->getOrientation(); + Vector3r position; + Quaternionr orientation; - if (collision_info.has_collided) { - position = collision_info.position + collision_info.normal*2 + collision_info.normal * collision_info.penetration_depth * 2; - } - else { - position.x() = rand_xy_.next(); - position.y() = rand_xy_.next(); - position.z() = rand_z_.next(); + position.x() = rand_xy_.next(); + position.y() = rand_xy_.next(); + position.z() = Utils::clip(rand_z_.next(), -10.0f, 0.0f); - float pitch, roll, yaw; - VectorMath::toEulerianAngle(orientation, pitch, roll, yaw); - pitch = rand_pitch_.next(); - yaw = rand_yaw_.next(); - - orientation = VectorMath::toQuaternion(pitch, 0, yaw); - } + float pitch, roll, yaw; + VectorMath::toEulerianAngle(orientation, pitch, roll, yaw); + pitch = rand_pitch_.next(); + yaw = rand_yaw_.next(); + orientation = VectorMath::toQuaternion(pitch, 0, yaw); + client_->simSetPosition(position); client_->simSetOrientation(orientation); } private: - typedef common_utils::RandomGeneratorF RandomGeneratorF; + typedef common_utils::RandomGeneratorGaussianF RandomGeneratorGaussianF; typedef msr::airlib::Vector3r Vector3r; typedef msr::airlib::Quaternionr Quaternionr; typedef common_utils::Utils Utils; @@ -54,7 +52,7 @@ private: msr::airlib::RpcLibClient* client_; - RandomGeneratorF rand_xy_, rand_z_, rand_pitch_, rand_yaw_; + RandomGeneratorGaussianF rand_xy_, rand_z_, rand_pitch_, rand_yaw_; }; class RandomWalkPoseGenerator { diff --git a/Examples/StereoImageGenerator.hpp b/Examples/StereoImageGenerator.hpp index cfbeb5a6..ba164622 100644 --- a/Examples/StereoImageGenerator.hpp +++ b/Examples/StereoImageGenerator.hpp @@ -29,20 +29,34 @@ public: client.confirmConnection(); } - void generate(int num_samples) + int generate(int num_samples) { msr::airlib::ClockBase* clock = msr::airlib::ClockFactory::get(); - RandomPointPoseGenerator pose_generator(& client); - std::ofstream file_list(FileSystem::combine(storage_dir_, "files_list.txt")); + RandomPointPoseGenerator pose_generator(& client, static_cast(clock->nowNanos())); + std::fstream file_list(FileSystem::combine(storage_dir_, "files_list.txt"), + std::ios::out | std::ios::in | std::ios_base::app); - for (int i = 0; i < num_samples; ++i) { + int sample = 0; + std::string line; + while (std::getline(file_list, line)) + ++sample; + if (file_list.eof()) + file_list.clear(); //otherwise we can't do any further I/O + else if (file_list.bad()) { + std::cout << "Error occured while reading files_list.txt"; + return 1; + } + + while(sample < num_samples) { const auto& collision_info = client.getCollisionInfo(); if (collision_info.has_collided) { - std::cout << "Collison. Moving to next pose." << std::endl; + std::cout << "Collison at " << VectorMath::toString(collision_info.position) + << "Moving to next pose." << std::endl; + pose_generator.next(); - --i; continue; } + ++sample; auto start_nanos = clock->nowNanos(); @@ -57,9 +71,9 @@ public: continue; } - std::string left_file_name = Utils::stringf("left_%06d.png", i); - std::string right_file_name = Utils::stringf("right_%06d.png", i); - std::string disparity_file_name = Utils::stringf("disparity_%06d.pfm", i); + std::string left_file_name = Utils::stringf("left_%06d.png", sample); + std::string right_file_name = Utils::stringf("right_%06d.png", sample); + std::string disparity_file_name = Utils::stringf("disparity_%06d.pfm", sample); saveImageToFile(response.at(0).image_data, FileSystem::combine(storage_dir_, right_file_name)); saveImageToFile(response.at(1).image_data, @@ -84,10 +98,12 @@ public: file_list << left_file_name << "," << right_file_name << "," << disparity_file_name << std::endl; - std::cout << "Image #" << i << " done in " << (clock->nowNanos() - start_nanos) / 1.0E6f << "ms" << std::endl; + std::cout << "Image #" << sample << " done in " << (clock->nowNanos() - start_nanos) / 1.0E6f << "ms" << std::endl; pose_generator.next(); } + + return 0; } private: diff --git a/Examples/main.cpp b/Examples/main.cpp index 37c0842f..b41455f4 100644 --- a/Examples/main.cpp +++ b/Examples/main.cpp @@ -51,14 +51,14 @@ int runStandAlonePhysics(int argc, const char *argv[]) return 0; } -void runSteroImageGenerator(int num_samples) +void runSteroImageGenerator(int num_samples, std::string storage_path) { - StereoImageGenerator gen("c:\\temp\\stig"); + StereoImageGenerator gen(storage_path); gen.generate(num_samples); } int main(int argc, const char *argv[]) { - runSteroImageGenerator(argc < 2 ? 50000 : std::stoi(argv[1])); + runSteroImageGenerator(argc < 2 ? 50000 : std::stoi(argv[1]), argc < 3 ? "c:\\temp\\stig" : std::string(argv[2])); } diff --git a/PythonClient/camera.py b/PythonClient/camera.py index e8b68469..50350d66 100644 --- a/PythonClient/camera.py +++ b/PythonClient/camera.py @@ -42,7 +42,7 @@ fps = 0 while True: # because this method returns std::vector, msgpack decides to encode it as a string unfortunately. - rawImage = client.getImageForCamera(0, cameraTypeMap[cameraType]) + rawImage = client.simGetImage(0, cameraTypeMap[cameraType]) if (rawImage == None): print("Camera is not returning image, please check airsim for error messages") sys.exit(0) diff --git a/PythonClient/navigate.py b/PythonClient/navigate.py index 72543923..eeb3247a 100644 --- a/PythonClient/navigate.py +++ b/PythonClient/navigate.py @@ -22,7 +22,7 @@ help = False while True: # this will return png width= 256, height= 144 - result = client.getImageForCamera(0, AirSimImageType.Depth) + result = client.simGetImage(0, AirSimImageType.Depth) if (result == "\0"): if (not help): help = True diff --git a/Unreal/Plugins/AirSim/Content/Blueprints/BP_PIPCamera.uasset b/Unreal/Plugins/AirSim/Content/Blueprints/BP_PIPCamera.uasset index 09afd2af195d3657cd2a1d1c200dfabb5c4fd7fc..ee3e3c162dd34fe67fa7b604b74c510f0d4023a5 100644 GIT binary patch literal 20910 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 diff --git a/Unreal/Plugins/AirSim/Source/SimMode/SimModeWorldMultiRotor.cpp b/Unreal/Plugins/AirSim/Source/SimMode/SimModeWorldMultiRotor.cpp index 74b75c99..28460933 100644 --- a/Unreal/Plugins/AirSim/Source/SimMode/SimModeWorldMultiRotor.cpp +++ b/Unreal/Plugins/AirSim/Source/SimMode/SimModeWorldMultiRotor.cpp @@ -85,6 +85,8 @@ void ASimModeWorldMultiRotor::setupVehiclesAndCamera() } } + if (usage_scenario == kUsageScenarioComputerVision) + fpv_vehicle_pawn_->EnablePassthroughOnCollisons = true; fpv_vehicle_pawn_->initializeForBeginPlay(); CameraDirector->initializeForBeginPlay(getInitialViewMode(), fpv_vehicle_pawn_, external_camera); } diff --git a/docs/apis.md b/docs/apis.md index 0e96d434..8f84ccf2 100644 --- a/docs/apis.md +++ b/docs/apis.md @@ -62,8 +62,7 @@ Note: We would not recommend interrupting takeoff/land on a real drone, of cours ## How to get images from drone? -Here's a sample code. For more information, please see [DroneControlBase](https://github.com/Microsoft/AirSim/blob/master/AirLib/include/controllers/DroneControllerBase.hpp) class. -See [Camera Views](camera_views.md) for information on the camera views and how to change them. +Here's a sample code to get a single image: ``` int playWithImages() @@ -73,11 +72,31 @@ int playWithImages() msr::airlib::RpcLibClient client; - vector image = client.getImageForCamera(0, DroneControlBase::ImageType::Depth); + vector image = client.simGetImage(0, DroneControlBase::ImageType::Depth); //do something with images } ``` +You can also get multiple images using API `simGetImages` which is slighly more complex to use than `simGetImage`. For example, you can get left camera view, right camera view and depth image from left camera - all at once! For sample code please see [sample code in HelloDrone project](https://github.com/Microsoft/AirSim/blob/master/HelloDrone/main.cpp). We also have [complete code](https://github.com/Microsoft/AirSim/blob/master/Examples/StereoImageGenerator.hpp) that generates specified number of stereo images and ground truth depth with normalization to camera plan, computation of disparity image and saving it to pfm format. + +Unlike `simGetImage`, the `simGetImages` API also allows you to get uncompressed images as well as floating point single channel images (instead of 3 channel (RGB), each 8 bit). + +You can also use Python to get images. For sample code please see [PythonClient project](https://github.com/Microsoft/AirSim/tree/master/PythonClient) and [Python example doc](python.md). + +Furthermore, if your work involves computer vision experiments and if you don't care about drone dynamics then you can use our so called "ComputerVision" mode. Please see next section for the details. + +## Can I use AirSim just for computer vision? I don't care about drones, physics etc. +Yes, now you can! Simply go to settings.json that you can find in your Documents\AirSim folder (or ~/Documents/AirSim on Linux). Add following setting at root level: + +``` +{ + "FpvVehicleName": "SimpleFlight", + "UsageScenario": "ComputerVision" +} +``` + +Now when you start AirSim, you won't be able to move drone using remote control, there is no drone dynamics and physics engine is disabled in this mode. Think of this mode as that justs you move around cameras, not drone. You can use keyboard to move around (use F1 to see help on keys) and call APIs to get images. You can also use two additional APIs `simSetPosition` and `simGetPosition` to set position of drone programatically. Then use can image APIs as described in above section to get images for your desired pose. Please see [complete code](https://github.com/Microsoft/AirSim/blob/master/Examples/StereoImageGenerator.hpp) that generates specified number of stereo images and ground truth depth with normalization to camera plan, computation of disparity image and saving it to pfm format in this mode. + ## Can I run above code on real quadrotors as well? Absolutely! The AirLib is self-contained library that you can put on an offboard computing module such as the Gigabyte barebone Mini PC. This module then can talk to the flight controllers such as Pixhawk using exact same code and MavLink protocol (or DJI protocol). diff --git a/docs/camera_views.md b/docs/camera_views.md index 8c577895..7c3a5914 100644 --- a/docs/camera_views.md +++ b/docs/camera_views.md @@ -1,12 +1,10 @@ # Camera Views -The camera views that are shown on screen are the camera views you can fetch via the DroneControllerBase::getImageTypeForCamera API. -Note that getImageForCamera returns .png compressed images. +The camera views that are shown on screen are the camera views you can fetch via the [simGetImage API](apis.md). ![Cameras](images/cameras.png) -From left to right is the depth view, segmentation view and the FPV view. These views must be visible in order for -getImageForCamera to work. In fact getImageForCamera will make them visible if they are not already. +From left to right is the depth view, segmentation view and the FPV view. ## Depth View @@ -30,7 +28,7 @@ main game view if the user presses '[' or ']'. ## Performance -Now rendering these views does impact the FPS performance of the game, since this is additional work for the GPU. The following shows the impact on FPS when you open these views. The impact is higher when fetching the images via python calling getImageForCamera because this is an additional render request for each frame. +Now rendering these views does impact the FPS performance of the game, since this is additional work for the GPU. The following shows the impact on FPS when you open these views. ![fps](images/fps_views.png) diff --git a/docs/python.md b/docs/python.md index 8375b548..6d47474e 100644 --- a/docs/python.md +++ b/docs/python.md @@ -103,7 +103,7 @@ help = False while True: # because this method returns std::vector, msgpack decides to encode it as a string unfortunately. - result = client.getImageForCamera(0, AirSimImageType.Depth) + result = client.simGetImage(0, AirSimImageType.Depth) if (result == "\0"): if (not help): help = True