gaussian pose generator, no eye adaptation, docs update and other stereo gen tweaks

This commit is contained in:
Shital Shah 2017-07-08 21:46:06 -07:00
Родитель b2db2e0e31
Коммит ebc5e36532
11 изменённых файлов: 84 добавлений и 46 удалений

Просмотреть файл

@ -19,6 +19,11 @@ public:
{
}
void seed(int val)
{
rand_.seed(val);
}
TReturn next()
{
return dist_(rand_);

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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<int>(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:

Просмотреть файл

@ -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]));
}

Просмотреть файл

@ -42,7 +42,7 @@ fps = 0
while True:
# because this method returns std::vector<uint8>, 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)

Просмотреть файл

@ -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

Двоичный файл не отображается.

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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<uint8_t> image = client.getImageForCamera(0, DroneControlBase::ImageType::Depth);
vector<uint8_t> 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).

Просмотреть файл

@ -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)

Просмотреть файл

@ -103,7 +103,7 @@ help = False
while True:
# because this method returns std::vector<uint8>, 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