Skip to content

Conversation

@nznaza
Copy link

@nznaza nznaza commented Nov 6, 2021

Sets bAlwaysPersistRenderingState to true. This fixes bugs related to capture while on NoDisplay.
Sets bCaptureOnMovement and bCaptureEveryFrame to true only when they are going to be viewed on a subwindow

Fixes: #1724
Fixes: #2967
Fixes: #3504
Fixes: #3070

Partially fixes #4112

Should fix most of the FPS while capturing problems.

About

This PR fixes the NoDisplay/Headless bug by setting bAlwaysPersistRenderingState to true.

Setting bCaptureOnMovement and bCaptureEveryFrame to true only while it's on an active subwindow camera improves the performance of image capture/recording and python simGetImages

How Has This Been Tested?

A python script was used to display the captured images to corroborate the accurate capture of the desired captures; the same script was used for all captures using ComputerVision.

import airsim
from cv2 import data
import numpy as np
from airsim import *
import cv2 
import datetime

def ImageResponsetoImage(selected):
    isFloat = selected.pixels_as_float
    if isFloat:
        img1d = np.array(selected.image_data_float)
    else:
        img1d = np.frombuffer(selected.image_data_uint8, dtype=np.uint8)

    width = selected.width
    height = selected.height
    channels = int(img1d.size / (height * width))
    img = img1d.reshape(height, width, channels)
    if (isFloat):
        depthinmm = img*1000
        depth_16bit =  np.clip(depthinmm, 0,65535) 
        return depth_16bit.astype(np.uint16)

    else:
        return img.astype(np.uint8)

if __name__ == "__main__":
    client = MultirotorClient()
    client.confirmConnection()

    i = 0
    inc = True
    while True:
        responses = client.simGetImages(
            [
                ImageRequest("front_left", ImageType.Scene, False, False),
                ImageRequest("front_left", ImageType.DepthPerspective, True, False),
                ImageRequest("front_left", ImageType.Segmentation, False, False),
                
                ImageRequest("front_center", ImageType.Scene, False, False),
                ImageRequest("front_center", ImageType.DepthPerspective, True, False),
                ImageRequest("front_center", ImageType.Segmentation, False, False),
                
                ImageRequest("front_right", ImageType.Scene, False, False),
                ImageRequest("front_right", ImageType.DepthPerspective, True, False),
                ImageRequest("front_right", ImageType.Segmentation, False, False),
                
                ImageRequest("bottom_center", ImageType.Scene, False, False),
                ImageRequest("bottom_center", ImageType.DepthPerspective, True, False),
                ImageRequest("bottom_center", ImageType.Segmentation, False, False),

                ImageRequest("back_center", ImageType.Scene, False, False),
                ImageRequest("back_center", ImageType.DepthPerspective, True, False),
                ImageRequest("back_center", ImageType.Segmentation, False, False),
                
            ]
        )
        tm = datetime.datetime.now().second % 10
        
        if tm % 2 == 0 :
            if inc:
                i += 1
            inc = False
        else:
            inc = True   
        if i >= len(responses):
            i = 0
        selected = responses[i]

        cv2.imshow("", ImageResponsetoImage(selected))
        cv2.waitKey(1)

Performance goes back up after stopping capture while on NoDisplay, but stays the same after recording or using the python simGetImages, but this can be fixed by displaying and hiding a subwindow.

settings.json

{
  "SeeDocsAt": "https://github.com/Microsoft/AirSim/blob/master/docs/settings.md",
  "SettingsVersion": 1.2,
  "ViewMode": "NoDisplay",
  "SimMode": "ComputerVision",
  "Recording": {
    "RecordOnMove": true,
    "RecordInterval": 0.05,
    "Folder": "",
    "Enabled": false,
    "Cameras": [
        { "CameraName": "0", "ImageType": 0, "PixelsAsFloat": false,  "VehicleName": "ComputerVision", "Compress": true },
        { "CameraName": "0", "ImageType": 1, "PixelsAsFloat": false,  "VehicleName": "ComputerVision", "Compress": true },
        { "CameraName": "0", "ImageType": 2, "PixelsAsFloat": false,  "VehicleName": "ComputerVision", "Compress": true },
        { "CameraName": "0", "ImageType": 7, "PixelsAsFloat": false,  "VehicleName": "ComputerVision", "Compress": true }
    ]
  },
  "CameraDefaults": {
    "CaptureSettings": [
      {
        "ImageType": 0,
        "Width": 640,
        "Height": 480
      },
      {
        "ImageType": 2,
        "Width": 640,
        "Height": 480
      },
      {
        "ImageType": 7,
        "Width": 640,
        "Height": 480
      },
      {
        "ImageType": 8,
        "Width": 640,
        "Height": 480
      },
      {
        "ImageType": 9,
        "Width": 640,
        "Height": 480
      },
      {
        "ImageType": 5,
        "Width": 640,
        "Height": 480
      }
    ],
    "NoiseSettings": [
      {
        "Enabled": false,
        "ImageType": 7,

        "RandContrib": 0.2,
        "RandSpeed": 100000.0,
        "RandSize": 500.0,
        "RandDensity": 2,

        "HorzWaveContrib":0.03,
        "HorzWaveStrength": 0.08,
        "HorzWaveVertSize": 1.0,
        "HorzWaveScreenSize": 1.0,

        "HorzNoiseLinesContrib": 1.0,
        "HorzNoiseLinesDensityY": 0.01,
        "HorzNoiseLinesDensityXY": 0.5,

        "HorzDistortionContrib": 1.0,
        "HorzDistortionStrength": 0.002
      }
    ]
  },
  "SegmentationSettings": {
    "InitMethod": "",
    "MeshNamingMethod": "StaticMeshName",
    "OverrideExisting": true
  }
}

Screenshots (if appropriate)

NoDisplay

RGB
Previous:
PreFixRGB

FixRGB

Depth:
Previous:
PreFixDepth

After:
FixDepth

Segmentation
Previous:
PreFixSegmentation

After:
FixSegmentation

Performance captures

Recording previous to fix
Recording prefix

After recording and showing and hiding subwindow (small gain)
Recording preFix aSubwindows

Recording after fix (Lower timings, )
Recording after fix

After recording and showing and hiding subwindow (Back to normal)
Recording after Fix Subwindows

Python capture before fix
python capture before

Python capture post fix
python capture

Python capture before fix (Only front_center)
python before only front

Python capture after fix (Only front_center)
python after only front

Python capture before fix (Only front_center Scene)
only RGB

Python capture after fix (Only front_center Scene)
after only RGB

While capturing with python's simGetImages the performance after the fix are lower, but measurable: 205 ms vs 185ms, 70ms vs 54, single images are within margin error, but fix is still lower

For comparison here are the timings of all cameras and NoDIsplay

While capturing
capture python ND

After stopping capturing, the levels go back to normal without needing to enable a subwindow.
After capture python ND

Sets bAlwaysPersistRenderingState to true. This fixes bugs of capture
Sets bCaptureOnMovement and bCaptureEveryFrame to true only when they are going to be viewed on as subwindow
@ghost
Copy link

ghost commented Nov 6, 2021

CLA assistant check
All CLA requirements met.

Copy link
Contributor

@rajat2004 rajat2004 left a comment

Choose a reason for hiding this comment

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

Still need to test, but any idea why the performance for simGetImages dropped?

else {
gameViewport->bDisableWorldRendering = 0;
}
gameViewport->bDisableWorldRendering = (uint32)mode_;
Copy link
Contributor

Choose a reason for hiding this comment

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

You can just use the nodisplay variable instead of casting mode_

Copy link
Author

Choose a reason for hiding this comment

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

Correct, I was removing the branch assignation and used the wrong variable, will issue a commit to address this, thanks.

}

onViewModeChanged(false);
onViewModeChanged(true);
Copy link
Contributor

Choose a reason for hiding this comment

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

So in the beginning, we set all cameras to NoDisplay mode to improve performance?
Would be great if you could add some comments in the code also as to why this helps

Copy link
Author

Choose a reason for hiding this comment

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

We initialize all cameras with bCaptureOnMovement and bCaptureEveryFrame to false.

This improves performance because the capture components are no longer updating every frame and only update while requesting an image (and are set to true while we are showing them on a sub-window because sub-window captures don’t count as a request)

@nznaza
Copy link
Author

nznaza commented Nov 30, 2021

Still need to test, but any idea why the performance for simGetImages dropped?

Sorry I don’t quite get the question, if you mean why is performance still drops while simGetImages is called: it’s because we still need to acquire the images (this is what causes the performance drop) this will commit will only drop while there is a request for the camera instead of having all of them updating every frame

nznaza added 2 commits November 30, 2021 13:24
Fixed gameViewport->bDisableWorldRendering assignation
Added comments explaining the reasons behind setting cameras to nodisplay
@rajat2004
Copy link
Contributor

Ah, I think I misunderstood the issue, I thought the FPS of simGetImages itself dropped, rather than the viewport. If possible, could you try the image_benchmarker.py script with and without your fix, just to get a sense of performance improvement?

@zimmy87
Copy link
Contributor

zimmy87 commented Dec 1, 2021

Thanks for submitting this fix @nznaza! Tested this locally using the repro steps for #1724 and #2967. Confirmed #1724 and #3504 (which is a duplicate of #1724) are fixed now. Unfortunately, I was still able to repro #2967 and I didn't see any significant performance change using the image_benchmarker.py script (I was getting around 40 fps for the Blocks map both with and without this fix), so I suspect #3070 still repros. Considering this does fix some of the issues, I'm going to go ahead and merge this, we can address the other issues in a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants