Skip to content

Add support for fixed external cameras - #3320

Merged
David Zimmermann (zimmy87) merged 29 commits into
microsoft:masterfrom
rajat2004:external-camera
Jul 26, 2021
Merged

Add support for fixed external cameras#3320
David Zimmermann (zimmy87) merged 29 commits into
microsoft:masterfrom
rajat2004:external-camera

Conversation

@rajat2004

@rajat2004 Rajat Singhal (rajat2004) commented Jan 19, 2021

Copy link
Copy Markdown
Contributor

Fixes: #3208
Fixes: #1896,
Fixes: #1709,
Fixes: #610,
Fixes: #599

About

This PR adds the capability to create a fixed camera separate from the cameras on the vehicle, such as a CCTV camera. I'm not aware of any simple way to go about doing this currently, and therefore thought to try it out. I haven't checked the issues very thoroughly, so please let me know if there are other related issues and ways to go about doing this.

PR has been opened to get ideas and suggestions and whether this is actually required. This will likely become a big PR, so it can be split into parts for easier review also.

Currently have added a boolean field external in the getCameraInfo API, went for this since there are currently 7 camera related APIs, which could increase later on as well. Having completely separate APIs will duplicate the code in many places, the new API while doesn't look the cleanest felt like the better choice to me. Do comment if splitting into a different API or some other way is more preferred.

TODO (Comment if something's missing) -

  • Camera APIs implementation
    • getImages
    • set/getDistortionParams
    • getCameraInfo
    • setCameraFov
    • setCameraPose
    • Detection APIs
  • Allow External Cameras in -
  • Documentation updates
  • Docstrings update
  • Unity fixes to preserve earlier behaviour (No external camera implementation currently)

Also removes the simSetCameraOrientation API kept around for backward compatibility

The last commit to add an internal CameraDetails struct is a NFC commit, just to clean up the multiple parameters being passed everywhere. If it's not desirable then the coomit can be dropped easily. Any suggestions on the struct naming are welcome!

How Has This Been Tested?

Example Settings
{
    "SettingsVersion": 1.2,
    "SimMode": "Car",
    "ExternalCameras": {
        "fixed1": {
            "X": 0, "Y": 0, "Z": -10,
            "Pitch": -90, "Roll": 0, "Yaw": 0
        },

        "fixed2": {
            "CaptureSettings": [
                {
                  "ImageType": 0,
                  "Width": 256,
                  "Height": 144,
                  "FOV_Degrees": 90,
                  "AutoExposureSpeed": 100,
                  "AutoExposureBias": 0,
                  "AutoExposureMaxBrightness": 0.64,
                  "AutoExposureMinBrightness": 0.03,
                  "MotionBlurAmount": 0,
                  "TargetGamma": 1.0,
                  "ProjectionMode": "",
                  "OrthoWidth": 5.12
                }
            ],
            "NoiseSettings": [
              {
                "Enabled": false,
                "ImageType": 0,

                "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
              }
            ],
            "X": 10, "Y": 0, "Z": 0,
            "Pitch": 0, "Roll": 0, "Yaw": 0
        }
    }
}

Example API Call -

client.simGetCameraInfo("fixed1", external=True)

An example Python script has been added, the FoV change will be reflected in the info only after #3278

Script Output
$ python external_camera.py
Connected!
Client Ver:1 (Min Req: 1), Server Ver:1 (Min Req: 1)

Saving images to /tmp/airsim_cv_mode
Camera: fixed1, External = True
<CameraInfo> {   'fov': 90.0,
    'pose': <Pose> {   'orientation': <Quaternionr> {   'w_val': 0.7071067094802856,
    'x_val': 0.0,
    'y_val': -0.7071067690849304,
    'z_val': 0.0},
    'position': <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}},
    'proj_mat': <ProjectionMatrix> {   'matrix': [   [   0.0,
                      1.0,
                      0.0,
                      0.0],
                  [   0.0,
                      0.0,
                      -1.7777777910232544,
                      0.0],
                  [   0.0,
                      0.0,
                      0.0,
                      10.0],
                  [   -1.0,
                      0.0,
                      0.0,
                      0.0]]}}
Press any key to get images
Type 0, size 39292, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Type 1, size 3514, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Type 3, size 4443, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Type 5, size 983, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Type 6, size 8761, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Press any key to change FoV and get images
Type 0, size 34747, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Type 1, size 2437, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Type 3, size 6756, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Type 5, size 983, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Type 6, size 4360, pos <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}
Old FOV: 90.0, New FOV: 90.0
Type 0, size 46250, pos <Vector3r> {   'x_val': -10.0,
    'y_val': -5.0,
    'z_val': -5.0}
Type 1, size 7357, pos <Vector3r> {   'x_val': -10.0,
    'y_val': -5.0,
    'z_val': -5.0}
Type 3, size 2015, pos <Vector3r> {   'x_val': -10.0,
    'y_val': -5.0,
    'z_val': -5.0}
Type 5, size 1840, pos <Vector3r> {   'x_val': -10.0,
    'y_val': -5.0,
    'z_val': -5.0}
Type 6, size 12998, pos <Vector3r> {   'x_val': -10.0,
    'y_val': -5.0,
    'z_val': -5.0}
Old Pose: <Pose> {   'orientation': <Quaternionr> {   'w_val': 0.7071067094802856,
    'x_val': 0.0,
    'y_val': -0.7071067690849304,
    'z_val': 0.0},
    'position': <Vector3r> {   'x_val': 0.0,
    'y_val': 0.0,
    'z_val': -5.0}}, New Pose: <Pose> {   'orientation': <Quaternionr> {   'w_val': 0.9975020885467529,
    'x_val': -0.002497921697795391,
    'y_val': 0.04991671442985535,
    'z_val': 0.049916788935661316},
    'position': <Vector3r> {   'x_val': -10.0,
    'y_val': -5.0,
    'z_val': -5.0}}
Distortion Params: [0.0, 0.0, 0.0, 0.0, 0.0]
Setting distortion params as {'K1': 0.1, 'K2': 0.01, 'K3': 0.0, 'P1': 0.0, 'P2': 0.0}
Distortion Params: [0.10000000149011612, 0.009999999776482582, 0.0, 0.0, 0.0]

Subwindws Testing:

Subwindow Settings
{
    "SettingsVersion": 1.2,
    "SimMode": "Car",
    "ExternalCameras": {
        "fixed1": {
            "X": 0, "Y": 0, "Z": -5,
            "Pitch": -90, "Roll": 0, "Yaw": 0
        },
        "fixed2": {
            "X": -10, "Y": 0, "Z": -5,
            "Pitch": -45, "Roll": 0, "Yaw": 0
        }
    },
    "SubWindows": [
        {"WindowID": 0, "ImageType": 0, "CameraName": "fixed1", "Visible": true, "External": true},
        {"WindowID": 1, "ImageType": 0, "CameraName": "fixed2", "Visible": true, "External": true},
        {"WindowID": 2, "ImageType": 0, "CameraName": "0", "Visible": true}
    ]
}

The external_camera.py can be easily used for testing all the camera APIs, as well as vehicle cameras by setting the flag. The detection.py script has also been tested to be working after these changes.

Screenshots (if appropriate):

Old FoV (90):
old_fov_0

New Fov (120):
new_fov_0

Subwindows:
Screenshot from 2021-02-11 18-23-44

airsim_cv_mode.zip

@zimmy87

Copy link
Copy Markdown
Contributor

It seems that you have a lot of conflicts. This is most likely due to conflicts with autoformatted code in master. Please follow these steps to resolve this:

  1. check out your pull request
  2. run git checkout master .clang-format in your repo's root folder
  3. if you don't have npm installed, download it from https://www.npmjs.com/get-npm
  4. run npm install -g clang-format
  5. run clang-format -i path/to/file for each conflicting file
  6. run git add -u to track all style changes
  7. run git commit -am "apply style from clang-format"
  8. run git merge master
  9. resolve other non-style conflicts if you have any
  10. push changes

Thanks for helping us with these style changes!

@rajat2004

Copy link
Copy Markdown
Contributor Author

David Zimmermann (@zimmy87) Yeah, there are major conflicts with this one, will be a pretty painful one. I'll try to get this done today, but I think it would be best to get #3472 in first since that API will also need to be adapted. This PR was just intended to see if the feature is feasible and useful. Any review regarding the code and the current API modification would be very much appreciated!

@rajat2004
Rajat Singhal (rajat2004) force-pushed the external-camera branch 3 times, most recently from 763ea44 to e8bc584 Compare June 12, 2021 18:23
@rajat2004
Rajat Singhal (rajat2004) force-pushed the external-camera branch 4 times, most recently from 39d82a4 to 5689b05 Compare June 24, 2021 19:33

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

a few comments, plus I'm having an issue running the external_camera.py script

Comment thread AirLib/include/api/WorldSimApiBase.hpp Outdated
Comment thread PythonClient/computer_vision/external_camera.py
Comment thread PythonClient/computer_vision/external_camera.py
@rajat2004

Copy link
Copy Markdown
Contributor Author

I skipped testing this earlier since I generally keep my GPU disabled, and launching UE4 Editor often causes my laptop to give up. Using the subwindow settings in the description -

Screenshot from 2021-07-02 00-16-28

@alonfaraj

Copy link
Copy Markdown
Contributor

Rajat Singhal (@rajat2004) great feature! thank you for the great work.
Do you think it's worth adding a method to get all the external cameras in the scene?
Similar to listVehicles?

@rajat2004

Copy link
Copy Markdown
Contributor Author

Hmm, don't have any real preference either way, pretty straightforward to add that API. The listVehicles API itself becomes more useful with the addVehicle API.

@zimmy87

David Zimmermann (zimmy87) commented Jul 26, 2021

Copy link
Copy Markdown
Contributor

PR looks good to me; moving ahead with merging; thanks for the contribution Rajat Singhal (@rajat2004)!

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

Projects

None yet

4 participants