Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Recording to multiple vehicles #2861

Merged
merged 11 commits into from
Mar 1, 2021

Conversation

rajat2004
Copy link
Contributor

@rajat2004 rajat2004 commented Jul 18, 2020

Replaces #2847 (branch got messed up)

Closes #3029
Closes #3123
Closes #3214

Other related issues - #2307

New Additions -

  1. Info of all vehicles is recorded (with additional column VehicleName), VehicleName parameter in Cameras field to specify specific vehicle to use the camera from
  2. Folder field in settings to change the directory to store data in
  3. Allow Recording with no images (just pose, etc data) (I want to know how to record without imageFile. #3123)
  4. Enabled parameter for starting recording when AirSim starts without needing to press R or call API (How to start recording when game begins? #3029) (Any naming suggestions are welcome)
  5. Add method to write PPM file (for uncompressed images) (Invalid uncomressed images when recording from Unreal editor #3214)

Also fixes a bug when pressing Esc and Play multiple times causes requests to add in the vector and save multiple images (#1414 (comment))

Example settings -

{
    "SettingsVersion": 1.2,
    "SimMode": "Car",

    "Vehicles": {
        "Car1": {
          "VehicleType": "PhysXCar",
          "AutoCreate": true
        },
        "Car2": {
          "VehicleType": "PhysXCar",
          "AutoCreate": true,
          "X": 0, "Y": 10, "Z": 0
        }
    },
    "Recording": {
        "RecordOnMove": false,
        "RecordInterval": 1,
        "Cameras": [
            { "CameraName": "0", "ImageType": 0, "PixelsAsFloat": false, "VehicleName": "Car1", "Compress": true },
            { "CameraName": "0", "ImageType": 5, "PixelsAsFloat": false, "VehicleName": "Car1", "Compress": true },
            { "CameraName": "0", "ImageType": 0, "PixelsAsFloat": false, "VehicleName": "Car2", "Compress": true }
        ]
    }

}

Recording - 2020-07-11-11-48-51.zip

Testing -

  • Multiple Vehicles, with no recording settings (Scene image from each vehicle)
  • Multiple Vehicles, specific sensor settings (Settings above)
  • Single vehicle, no settings (Scene from that vehicle, former behaviour)

TODO:

  • Update docs
  • Unity implementation

Further possible additions -

  • Allow user to specify directory to store recordings in (Replacement for Documents)
  • Currently saving no images is not possible (For some reason this leads to an error in writing to file, even though the file has been created, and there are lines in it already)
    - I suspect this might be a race condition for the first write, since there are no images, no rendering and saving of images is required, so writing of pose data is happening almost instantaneously, but the file to write the data in hasn't still been created.(Haven't confirmed this though, just a thought)
    - Fixed (set is_ready flag at the end)

Any testing (especially of Folder on Windows) or suggestions would be great!

Came to mind when working on #2841
Related older issue #1346, Also includes the fix proposed in #1414

@rajat2004 rajat2004 force-pushed the multi-vehicle-recording2 branch 2 times, most recently from b8f983d to d9593dc Compare July 19, 2020 15:51
@madratman
Copy link
Contributor

/azp run microsoft.AirSim

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rajat2004
Copy link
Contributor Author

rajat2004 commented Jul 26, 2020

The last commit fixes a bug in the PR which causes it to not save any images when VehicleName wasn't specified.
Example settings -

{
    "SettingsVersion": 1.2,
    "SimMode": "Car",
    "Recording": {
        "RecordOnMove": false,
        "RecordInterval": 1,
        "Cameras": [
            { "CameraName": "0", "ImageType": 0, "PixelsAsFloat": false, "Compress": true }
        ]
    }
}

And here, if we change Compress to false, the images are corrupted and can't be opened, which is what I had mentioned in #2683 (comment)

Edit: So images are not corrupted, I'm able to save them by using cv2.imshow to PNG files, the problem's in displaying using cv2.imshow (lol, just forgot cv2.waitKey(1)) and in recording (which is probably due to them being written as values directly without say PNG file header or something)

For compressed images, UE is doing the conversion to PNG format, and then we're just writing it as a binary file. For uncompressed, writing array values as binary doesn't work. I can see 2 options, either go for an external library such as libpng which will do the conversion and all (format's complex, so doesn't seem to be possible to write it ourselves), or use a different format such as PPM which is much simpler and can be written in a much simpler way, similar to how PFM file is being written

recording_setting.requests.clear();
// Add Scene image for each vehicle
for (const auto& vehicle : vehicles) {
recording_setting.requests[vehicle.first].push_back(ImageCaptureBase::ImageRequest(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The strange part which I'll take a look at later, vehicles map here doesn't contain a single vehicle when no vehicles are specified, but instead 3 (one for each simmode), and why I added getDefaultVehicleName, rather than using the first vehicle in the map.
Not sure why it's being done like this, shouldn't a single default vehicle be created in initializeVehicleSettings() instead of 3?

Can be seen by adding a line here, like Utils::log(vehicle.first).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to how ASimModeBase::setupVehiclesAndCamera() is defined, only vehicles that match the current simmode get instantiated. The only other place where the vehicles map gets read is in AirSimSettings::getVehicleSetting(), which only gets called in VehicleSimApiBase, and VehicleSimApiBase objects have a 1:1 relationship with the vehicles that get instantiated. As a result, I am confident the change to initializeVehicleSettings() to only initialize a single default vehicle is a safe change to make.

Copy link
Contributor

@zimmy87 zimmy87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for submitting this PR @rajat2004! I have a few small comments mostly dealing with naming and style conventions that I'd like to see addressed before merging.

AirLib/include/common/AirSimSettings.hpp Outdated Show resolved Hide resolved
AirLib/include/common/common_utils/Utils.hpp Outdated Show resolved Hide resolved
@rajat2004 rajat2004 force-pushed the multi-vehicle-recording2 branch 3 times, most recently from 5ce5c9b to 0c5abba Compare February 1, 2021 19:25
@zimmy87
Copy link
Contributor

zimmy87 commented Feb 3, 2021

Hey @rajat2004, the 2 failing checks are due to a build break caused by a different PR. The fix for this build break was committed yesterday, can you rebase this PR to pick up the fix and rerun all the checks?

Copy link
Contributor

@zimmy87 zimmy87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested this locally and it looks good to me; will discuss with my team about merging

recording_setting.requests.clear();
// Add Scene image for each vehicle
for (const auto& vehicle : vehicles) {
recording_setting.requests[vehicle.first].push_back(ImageCaptureBase::ImageRequest(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to how ASimModeBase::setupVehiclesAndCamera() is defined, only vehicles that match the current simmode get instantiated. The only other place where the vehicles map gets read is in AirSimSettings::getVehicleSetting(), which only gets called in VehicleSimApiBase, and VehicleSimApiBase objects have a 1:1 relationship with the vehicles that get instantiated. As a result, I am confident the change to initializeVehicleSettings() to only initialize a single default vehicle is a safe change to make.

@zimmy87 zimmy87 merged commit 4a91e0c into microsoft:master Mar 1, 2021
@zimmy87
Copy link
Contributor

zimmy87 commented Mar 1, 2021

Thank you for the contribution @rajat2004!

@rajat2004 rajat2004 deleted the multi-vehicle-recording2 branch March 1, 2021 17:14
@rajat2004
Copy link
Contributor Author

Glad to help! Contributing to AirSim has definitely helped me improve my skills, and hope that this will be useful to others as well :)

@Ryton
Copy link

Ryton commented Mar 25, 2021

Bug report
At my end following minimal example causes corrupted png file(s) for uncompressed images,
i assume that the data is generated and stored, as it scales with the pixel size, but currently it'not stored away in correct format (and/or with missing header)?

Example settings.json
{
"SettingsVersion": 1.2,
"SimMode": "Car",
"Recording": {
"RecordOnMove": false,
"RecordInterval": 1,
"Cameras": [
{ "CameraName": "0", "ImageType": 0, "PixelsAsFloat": false, "Compress": true},
{ "CameraName": "0", "ImageType": 0, "PixelsAsFloat": false, "Compress": false}
]
}
}

Versions:
AirSim Version/#commit: tested with 1.2 and 1.4
UE/Unity version: 4.24.4
Autopilot version: N/A
OS Version: 64bit Win10 Pro
Used map "Default".

What's the issue you encountered?
When running in a standalone game window, and pressing "R", two images are generated, yet while the first is OK, the second one is corrupted.

uncompressed_corrupt_img_0_0_1616710947452891700
compressed_OK_img_0_0_1616710947446439600

"pngcheck -v uncompressed_corrupt_img_0_0_1616710947452891700.png" returns:
File: uncompressed_corrupt_img_0_0_1616710947452891700.png (110592 bytes)
this is neither a PNG or JNG image nor a MNG stream

@rajat2004
Copy link
Contributor Author

@Ryton This PR hasn't been included in the 1.4 release, you'll have to use the latest master

@Ryton
Copy link

Ryton commented Mar 29, 2021

Ah ok, thanks! i was not aware of this.
Will do then!

@Ryton
Copy link

Ryton commented Apr 19, 2021

Fixed now, using the latest master
AND
using the correct field name/structure in the json...
the capturesettings for the camera should NOT be directly alongside their position,

so NOT:

... ,
   "Cameras": {
        "Camera1": {
  "X": 0.135, "Y": -2.15,"Z": -4.50,
            "Width": 1920 ,
            "Height": 1200 
},

But rather, within CameraSettings:

...,
"Cameras": {
 "Camera1": {
			"CaptureSettings": [
      {
          "SensorType": 0,
          "Enabled": true,
          "Width": 1920 ,
          "Height": 1200 
	  }],
            "X": 0.135, "Y": -2.15,"Z": -4.50,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants