Concepts#

Camera 1#

Camera1 peripherals are used like any other peripheral in GroundSdk to monitor and change settings and to trigger specific actions.

Camera parameters and actions are accessible through settings organized by features:

Feature

Description

Peripheral Method

Type

Camera Mode

Switch between photo capture and video recording modes

mode()

EnumSetting<Mode>

Photo

Configure photo mode, format and file format parameters

photo()

CameraPhoto.Setting

Monitor photo function state

photoState()

CameraPhoto.State

Video Recording

Configure recording mode, resolution and framerate parameters

recording()

CameraRecording.Setting

Auto start and stop recording

autoRecord()

OptionalBooleanSetting

Monitor recording function state

recordingState()

CameraRecording.State

Exposure

Configure exposure mode, shutter speed iso sensitivity and maximum iso sensitivity

exposure()

CameraExposure.Setting

Exposure lock

exposureLock()

CameraExposureLock

EV (Exposure Value) compensation

exposureCompensation()

EnumSetting<CameraEvCompensation>

White balance

Configure white balance mode and temperatures

whiteBalance()

CameraWhiteBalance.Setting

White balance lock

whiteBalanceLock()

CameraWhiteBalanceLock

HDR

Configure High Dynamic Range

autoHdr()

OptionalBooleanSetting

Image styles

Set image style and customize its parameters

style()

CameraStyle.Setting

Zoom

Zoom control

zoom()

CameraZoom

Alignment

Configure camera alignment

alignment()

CameraAlignment.Setting

With Camera1 peripheral when the user changes the value of a the setting, this value is immediately sent to the drone, if the drone is connected.

Camera 2#

Camera2 introduces the new concept of sub-components and a new way to configure camera parameters.

Sub-components are provided by the camera peripheral. They are used to perform some specific actions and monitor some specific information. For instance, there is a sub-component to start and stop photo capture and another sub-component to monitor photo capture progress. The user can register a listener to get notified every time a sub-component changes.

The camera peripheral provides a single interface Camera.Config that is used to monitor camera configuration. The camera configuration groups all camera parameters.

This Camera.Config interface comes with a configuration editor Camera.Config.Editor that is used to modify the configuration. With this configuration editor, the user can modify multiple camera parameters locally on application side before sending the new configuration to the drone. The configuration editor ensures the consistency of parameters between them before sending them to the drone. This mechanism reduces transactions between the application and the drone and simplifies management of parameters consistency by the application.

This is a major difference with Camera1 API. Unlike Camera1, when a configuration parameter is modified by the user, the new configuration is not sent immediately. It is only sent when the user calls the method Camera.Config.Editor.commit().

The following table shows camera2 features and the corresponding configuration parameters and sub-components:

Feature

Description

Configuration Parameter(s)

Sub-components

Camera Mode

Switch between photo capture and video recording modes

MODE

Photo

Configure photo capture

PHOTO_MODE, PHOTO_DYNAMIC_RANGE, PHOTO_RESOLUTION, PHOTO_FORMAT, PHOTO_FILE_FORMAT, PHOTO_BRACKETING, PHOTO_BURST, PHOTO_TIME_LAPSE_INTERVAL, PHOTO_GPS_LAPSE_INTERVAL, PHOTO_STREAMING_MODE PHOTO_DIGITAL_SIGNATURE

Start/stop photo capture and monitor photo capture state

Camera.PhotoCapture

Monitor remaining time or distance before next capture

Camera.PhotoProgressIndicator

Video Recording

Configure video recording

VIDEO_RECORDING_MODE, VIDEO_RECORDING_DYNAMIC_RANGE, VIDEO_RECORDING_CODEC, VIDEO_RECORDING_RESOLUTION, VIDEO_RECORDING_FRAMERATE, VIDEO_RECORDING_BITRATE, VIDEO_RECORDING_HYPERLAPSE

Audio recording

AUDIO_RECORDING_MODE

Auto start and stop recording and monitor recording state

AUTO_RECORD_MODE

Start/stop recording

Camera.Recording

Streaming

Configure video stream

STREAMING_MODE, STREAMING_VIDEO_CODEC

Exposure

Configure exposure

EXPOSURE_MODE, MAX_ISO_SENSITIVITY, ISO_SENSITIVITY, SHUTTER_SPEED, EXPOSURE_COMPENSATION, EXPOSURE_METERING

Exposure lock

Camera.ExposureLock

Monitor effective exposure

Camera.ExposureIndicator

White balance

Configure white balance balance

WHITE_BALANCE_MODE, WHITE_BALANCE_TEMPERATURE

White balance lock

Camera.WhiteBalanceLock

Image styles

Configure image style and its parameters

IMAGE_STYLE, IMAGE_CONTRAST, IMAGE_SATURATION, IMAGE_SHARPNESS

Zoom

Configure zoom

ZOOM_MAX_SPEED, ZOOM_VELOCITY_CONTROL_QUALITY_MODE

Control zoom

Camera.Zoom

Alignment

Configure camera alignment

ALIGNMENT_OFFSET_PITCH, ALIGNMENT_OFFSET_ROLL, ALIGNMENT_OFFSET_YAW

Storage

Configure media storage

STORAGE_POLICY

Metadata

Define custom fields saved in media metadata

Camera.MediaMetadata.Copyright Camera.MediaMetadata.CustomId

Sub-components#

Components are accessed with the method Camera.component(). A listener can be passed to this method to get notified every time the component changes.

// get reference to ExposureLock component
val exposureLockRef = component<Camera.ExposureLock> { exposureLock ->
    // called at every component change
    exposureLock?.let {
        println("ExposureLock mode " + exposureLock.mode)
    } ?: run {
        println("ExposureLock unavailable")
    }
}

Important: The peripheral listener is not notified when a sub-component changes. Therefore, listeners on the sub-components have to be registered to get notified of sub-components changes.

Configuration#

All camera parameters are accessible through Camera.Config interface.

Supported parameters are listed in Camera.Config.supportedParams.

The current camera configuration can be accessed as follows:

// get exposure compensation configuration parameter
val exposureCompensation = camera.config[Camera.Config.EXPOSURE_COMPENSATION]
// current exposure compensation value
val value = exposureCompensation.value
// exposure compensation values supported by the drone
val overallSupportedValues = exposureCompensation.supportedValues(onlyCurrent = false)
// exposure compensation values available in the current configuration
val currentSupportedValues = exposureCompensation.supportedValues(onlyCurrent = true)
println("Exposure compensation $value $overallSupportedValues $currentSupportedValues")

The camera configuration can be modified with Camera.Config.Editor.

The camera configuration can be edited starting from an empty configuration:

val editor = camera.config.edit(fromScratch = true)

It can also be edited starting from current configuration:

val editor = camera.config.edit(fromScratch = false)

The value of a parameter can be changed as follows:

editor[Camera.Config.EXPOSURE_COMPENSATION].value = Camera.ExposureValue.EV_1

Trying to set a parameter value at a value not contained in supportedValues(onlyCurrent = false) will have no effect.

The configuration editor ensures the configuration consistency. It ensures that configuration parameters are not conflicting between them. So when setting a parameter value at a value not contained in supportedValues(onlyCurrent = true), the configuration editor will unset other parameters conflicting with the new value.

The configuration can automatically complete missing parameters in a configuration with method autoComplete():

editor.autoComplete()

The configuration is sent to the drone when method commit() is called:

editor.commit()

Note that only complete configuration can be sent to the drone.

Below, a sample code to modify exposure compensation value:

// start camera configuration edition starting from current configuration;
// when starting from current configuration, the edited configuration is
// considered as `complete`
val editor = camera.config.edit(fromScratch = false)

// get exposure compensation configuration parameter
val exposureCompensation = editor[Camera.Config.EXPOSURE_COMPENSATION]

// new exposure compensation value to apply
val newValue = Camera.ExposureValue.EV_1

when {
    // the new value is not supported by the camera
    !exposureCompensation.supportedValues(onlyCurrent = false).contains(newValue) ->
        print("exposureCompensation value not supported by the drone: $newValue")

    // the new value is available in the currently edited configuration,
    // meaning that the new value does not conflict with other parameters
    exposureCompensation.supportedValues(onlyCurrent = true).contains(newValue) -> {
        // apply new value, this will not change other parameters as there is no
        // conficting parameter
        exposureCompensation.value = newValue

        // at this point, the edited configuration is `complete`, so no need to
        // call `autoComplete` method

        // send new configuration to drone
        editor.commit()
    }

    // the new value is not available in the currently edited configuration,
    // meaning that the new value conflicts with some other parameters
    else -> {
        // apply new value, this will unset conflicting parameters,
        // therefore the edited configuration will not be `complete` anymore
        exposureCompensation.value = newValue

        // complete configuration, by automatically setting missing parameters values
        editor.autoComplete()

        // send new configuration to drone
        editor.commit()
    }
}