зеркало из https://github.com/microsoft/AirSim.git
gaussian pose generator, no eye adaptation, docs update and other stereo gen tweaks
This commit is contained in:
Родитель
b2db2e0e31
Коммит
ebc5e36532
|
@ -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
|
||||
|
|
Двоичные данные
Unreal/Plugins/AirSim/Content/Blueprints/BP_PIPCamera.uasset
Двоичные данные
Unreal/Plugins/AirSim/Content/Blueprints/BP_PIPCamera.uasset
Двоичный файл не отображается.
|
@ -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);
|
||||
}
|
||||
|
|
25
docs/apis.md
25
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<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
|
||||
|
|
Загрузка…
Ссылка в новой задаче