Basic Camera Function

2022-08-09
No Rating

Camera functions

Overview

To meet the developer's control requirements for camera-like payloads, PSDK provides interfaces for controlling the camera to perform functions such as taking pictures, recordings, zooming, and focusing. Light and other functions, and then by registering the PSDK camera interface, a fully functional camera payload device is developed. By using DJI Pilot and the Mobile App developed based on MSDK, users can control the camera payload device developed with PSDK to execute the specified Action to obtain information and resources in the payload device.

  • Basic functions: set camera mode, take pictures, video, get camera status, SD card management
  • Advanced functions: zoom, metering, focus, video streaming, playback download, media library management

Introduction to basic concepts

Camera Mode

Before using the camera class function, you need to set the mode of the camera class load device. Different modes specify the working logic of the camera class load device when performing a certain task.

  • Take a photo: In this mode, the user can trigger the camera-like payload device to take a photo.
  • Recording: In this mode, users can trigger camera-like payload devices to record images.
  • Video playback: In this mode, users can play or download media files on the load device on the Mobile App.

Note: The camera can only perform corresponding operations in one mode, such as in video mode only video recording but not taking pictures.

Photo Mode

The camera class payload device developed with PSDK supports the following photo modes:

  • Single shot: After issuing the photo command, the camera takes a single photo.
  • Continuous shooting: After issuing the photo command, the camera will continuously shoot the specified number of photos; currently supports 2/3/5/7/10/14 continuous shooting.
  • Timing photo: When a photo command is issued, the camera will take a specified number of photos at a specified time interval.
  • Currently supports 2/3/5/7/10 second intervals;
  • Currently, the maximum number of pictures can be specified to be 254. When the number of pictures is 255, the camera will take pictures continuously.

Focus Mode

  • Auto focus: Auto Focus, referred to as AF. In the autofocus mode, the camera-like load device calculates the focusing result according to the image state (diffuse emission) obtained by the photoelectric sensor to realize the focusing function and obtain a clear image.
  • Manual focus: Manual Focus, referred to as MF. In manual focus mode, users can get clear images by adjusting the focus ring.

Focus point

Note: The focus point of the camera-like payload is the center of the sensor by default.

When controlling the focus of a camera-like load device, you need to set the focus point first. The value of the focus point is the aspect ratio coefficient of the current focus point in the camera screen, as shown in Figure 1. Focus point.

  • In AF mode, the developer needs to formulate the camera focusing strategy and set the focus point (the focus point is also called "target point").
  • In manual focus mode, users can adjust the focus point according to actual needs to obtain the desired image.

Figure 1. Focus point

Focus Ring

A camera-like payload device with a zoom ring (optical zoom) developed using PSDK can set the value of the focus ring by calling the SetFocusRingValue interface:

  • The value of the focus ring defaults to 0, which means infinity and the closest possible focal length.
  • When the value of the focus ring is not 0, the user can set the value of the focus ring according to the actual parameters of the camera.

Focus Assistant

In AF and MF modes, the focus assistant can zoom in the focus area specified by the user by means of digital zoom, and call the SetFocusAssistantSettings interface to set the state of the focus assistant. Using the focus assistant, the user can check the focus quality of the current camera-like load device .

Zoom Mode

  • Optical zoom, by changing the structure of the optical lens to achieve zoom, the larger the optical zoom ratio, the farther the scene can be shot, and vice versa;
  • Digital zoom, the processor uses a specific algorithm to achieve digital zoom by changing the area of each pixel on the sensor;
  • Continuous zoom, the camera-like load device controls the lens to move in a specified direction at a specified speed, the camera-like load device first controls the lens to perform optical zoom, and when the optical zoom reaches the upper limit, the camera-like load device then performs digital zoom, so as to achieve Continuous zoom function. Current zoom factor = current optical zoom factor × current digital zoom factor;
  • Pointing to zoom, after the user specifies a certain target point, the camera-like payload device developed based on PSDK can control the gimbal to rotate, so that the specified target is in the center of the screen, and control the camera-like payload device to enlarge the image according to the preset zoom factor.

zoom direction

  • ZOOM_IN: The zoom factor is reduced, and the image is from far to near
  • ZOOM_OUT: The zoom factor is increased, and the image is from near to far

zoom speed

  • SLOWEST: Zoom at the slowest speed
  • SLOW: Zoom at a slower speed
  • MODERATELY_SLOW: zoom at a slightly slower speed than normal
  • NORMAL: Lens zooms at normal speed
  • MODERATELY_FAST: zoom slightly faster than normal
  • FAST : Zoom at a faster speed
  • FASTEST: zoom at the fastest speed

Metering Mode

  • Average metering, through the analysis of the overall brightness of the picture, the average brightness value of the picture is calculated, which is suitable for shooting scenes with uniform lighting;
  • Center-weighted metering, metering only the middle area of the image sensor, suitable for taking photos with framed composition;
  • Spot metering, for metering within the range centered on the "specified point", as shown in Figure 1. Spot metering area, this method can obtain accurate metering results and ensure that the specified object can be exposed correctly , suitable for shooting scenes with complex lighting.

Figure 1. Spot metering area

The image sensor is divided into 96 dot areas defined by 12 columns and 8 rows. The row index range is [0, 7], where values increase from top to bottom on the image; the column index range is [0, 11], where values increase from left to right.

Zoom Mode

  • Optical zoom, by changing the structure of the optical lens to achieve zoom, the larger the optical zoom ratio, the farther the scene can be shot, and vice versa;
  • Digital zoom, the processor uses a specific algorithm to achieve digital zoom by changing the area of each pixel on the sensor;
  • Continuous zoom, the camera-like load device controls the lens to move in a specified direction at a specified speed, the camera-like load device first controls the lens to perform optical zoom, and when the optical zoom reaches the upper limit, the camera-like load device then performs digital zoom, so as to achieve Continuous zoom function. Current zoom factor = current optical zoom factor × current digital zoom factor;
  • Pointing to zoom, after the user specifies a certain target point, the camera-like payload device developed based on PSDK can control the gimbal to rotate, so that the specified target is in the center of the screen, and control the camera-like payload device to enlarge the image according to the preset zoom factor.

zoom direction

  • ZOOM_IN: The zoom factor is reduced, and the image is from far to near
  • ZOOM_OUT: The zoom factor is increased, and the image is from near to far

zoom speed

  • SLOWEST: Zoom at the slowest speed
  • SLOW: Zoom at a slower speed
  • MODERATELY_SLOW: zoom at a slightly slower speed than normal
  • NORMAL: Lens zooms at normal speed
  • MODERATELY_FAST: zoom slightly faster than normal
  • FAST: zoom at a faster speed
  • FASTEST: zoom at the fastest speed

Media file management

The camera-like payload device developed with PSDK can perform operations such as file deletion or download according to the user's instructions.

Media file preview function

The camera payload device developed with PSDK allows users to preview the media files in the payload device using DJI Pilot or the Mobile App developed based on MSDK.

  • Static preview: preview a single file or a list of files
  • Thumbnail, preview file list
  • Image: The load device generates a thumbnail in the original proportion of the file, please set the width of the preview image to 100 pixels
  • Video: Capture a frame of the video
  • Screenshots, preview individual files
  • Image: at the original ratio, it is recommended to scale the image into a preview image with a width of 600 pixels
  • Video: Capture a frame of the video
  • Original files, if you want to get the original media files in the camera-like load device, please use the download function to obtain the specified media files.
  • Dynamic preview (video preview): play, pause, stop, jump (fast forward, rewind and progress drag)

Description: Supported file formats for dynamic preview: MP4, JPG, DNG and MOV, please refer to Video Standardopen in new window.

Implement the basic functions of the camera class

Developers are requested to construct functions for setting camera mode, taking photos and recordings, etc. for camera-like load devices according to the structure T_DjiCameraCommonHandler in PSDK according to the selected development platform and the actual use requirements of industrial applications, and use the camera function After the functions of the DJI are registered to the interface specified in the PSDK, the user can control the camera-based payload device developed based on the PSDK to perform the corresponding actions by using DJI Pilot or the Mobile App developed based on the MSDK.

// Get the current state of the load device system
s_commonHandler.GetSystemState = GetSystemState;
// Implement the function of setting the camera class load device mode
s_commonHandler.SetMode = SetMode;
s_commonHandler.GetMode = DjiTest_CameraGetMode;
// Implement the function to start or stop recording
s_commonHandler.StartRecordVideo = StartRecordVideo;
s_commonHandler.StopRecordVideo = StopRecordVideo;
// Implement the function to start or stop taking pictures
s_commonHandler.StartShootPhoto = StartShootPhoto;
s_commonHandler.StopShootPhoto = StopShootPhoto;
// Realize the camera function of setting the camera class load device
s_commonHandler.SetShootPhotoMode = SetShootPhotoMode;
s_commonHandler.GetShootPhotoMode = GetShootPhotoMode;
s_commonHandler.SetPhotoBurstCount = SetPhotoBurstCount;
s_commonHandler.GetPhotoBurstCount = GetPhotoBurstCount;
s_commonHandler.SetPhotoTimeIntervalSettings = SetPhotoTimeIntervalSettings;
s_commonHandler.GetPhotoTimeIntervalSettings = GetPhotoTimeIntervalSettings;
// Implement SD card management function
s_commonHandler.GetSDCardState = GetSDCardState;
s_commonHandler.FormatSDCard = FormatSDCard;

Basic function initialization

When using the PSDK to develop the camera function of the payload device, it is necessary to initialize the camera module and register the functions of the camera class.

1. Camera class function module initialization

Before using the camera class function, you must call the interface DjiPayloadCamera_Init to initialize the camera class payload device to ensure that the camera class payload device can work normally.

T_PsdkReturnCode returnCode;

returnCode = DjiPayloadCamera_Init();
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("payload camera init error:0x%08llX", returnCode);
}

2. Register camera class basic functions

Developers need to register the basic functions of the camera class through DjiPayloadCamera_RegCommonHandler after implementing functions such as setting the camera mode, taking pictures, and recording the camera class load device.

returnCode = DjiPayloadCamera_RegCommonHandler(&s_commonHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register common handler error:0x%08llX", returnCode);
}

Using SD card management function

Description

  • Camera-like payload devices developed using X-Port need to implement the function of storing media files and register this function in the interface specified by PSDK. The memory card on the X-Port only supports storing the X-Port log information, and cannot store the media files generated by the load device;
  • This tutorial takes the simulation SD card management function as an example to introduce how to use the PSDK SD card management function. If you need to develop a load device with SD card management function, please call the interface of the load device system to implement the SD card management functions.

1. SD card module initialization

use the SD card management function, the developer needs to first develop and register the function to operate the SD card function, and obtain the status information of the SD card by initializing the SD card management module.

s_cameraSDCardState.isI0nserted = true;
s_cameraSDCardState.totalSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB;
s_cameraSDCardState.remainSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB;
s_cameraSDCardState.availableCaptureCount = SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_PHOTO_SPACE_IN_MB;
s_cameraSDCardState.availableRecordingTimeInSeconds = SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB;

2. Get the current status of the SD card

The load device control program developed based on PSDK can call the GetSDCardState interface to obtain the current state of the SD card on the load device. Users can use DJI Pilot and the APP developed based on MSDK to view the status information of the SD card in the load device.

// The function of estimating the number of pictures that can be taken and the duration of video recording.
if (s_cameraState.isRecording) {
s_cameraState.currentVideoRecordingTimeInSeconds++;
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB;
if (s_cameraSDCardState.remainSpaceInMB > SDCARD_TOTAL_SPACE_IN_MB) {
s_cameraSDCardState.remainSpaceInMB = 0;
s_cameraSDCardState.isFull = true;
}
}
// Get the status of the SD card
static T_DjiReturnCode GetSDCardState(T_DjiCameraSDCardState *sdCardState)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

memcpy(sdCardState, &s_cameraSDCardState, sizeof(T_DjiCameraSDCardState));

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

3. Use SD card format function

The payload device control program developed based on PSDK can control the payload device to execute SD card formatting by calling the FormatSDCard interface. Users can use DJI Pilot and the APP developed based on MSDK to obtain the status information of the SD card in the payload device and control the payload device to execute the SD card format. Formatting function, as shown in Figure 1. SD card management function.

static T_DjiReturnCode FormatSDCard(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

USER_LOG_INFO("format sdcard");

memset(&s_cameraSDCardState, 0, sizeof(T_DjiCameraSDCardState));
s_cameraSDCardState.isInserted = true;
s_cameraSDCardState.totalSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB;
s_cameraSDCardState.remainSpaceInMB = SDCARD_TOTAL_SPACE_IN_MB;
s_cameraSDCardState.availableCaptureCount = SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_PHOTO_SPACE_IN_MB;
s_cameraSDCardState.availableRecordingTimeInSeconds =
SDCARD_TOTAL_SPACE_IN_MB / SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB;

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

Figure 1. SD card management function

Using the mode setting function

The payload device control program developed based on PSDK calls the SetMode and GetMode interfaces to set the camera mode, and the user can switch the working mode of the camera-type payload device using DJI Pilot, as shown in Figure 2. Setting the camera mode.

static T_DjiReturnCode GetSystemState(T_DjiCameraSystemState *systemState)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

*systemState = s_cameraState;

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode SetMode(E_DjiCameraMode mode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

s_cameraState.cameraMode = mode;
USER_LOG_INFO("set camera mode:%d", mode);

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

T_DjiReturnCode DjiTest_CameraGetMode(E_DjiCameraMode *mode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

*mode = s_cameraState.cameraMode;

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

Figure 2. Setting the mode of the camera-like payload

Using the camera function

Description

  • Before using the camera function, the user needs to set the working mode of the camera-like payload device to the camera mode on DJI Pilot or the Mobile App developed based on MSDK.
  • When taking a photo, the payload device developed with PSDK will return the photo status to DJI Pilot or the Mobile App developed based on MSDK (for triggering functions such as shooting sound in the Mobile App).

1. Set the camera mode of the camera payload

The payload device control program developed based on PSDK can call the SetShootPhotoMode and GetShootPhotoMode interfaces to set and get the mode of the camera payload device. Users can use DJI Pilot and the Mobile App developed based on MSDK to set and get the photos of the camera payload device. model.

static T_DjiReturnCode SetShootPhotoMode(E_DjiCameraShootPhotoMode mode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

s_cameraShootPhotoMode = mode;
USER_LOG_INFO("set shoot photo mode:%d", mode);

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetShootPhotoMode(E_DjiCameraShootPhotoMode *mode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

*mode = s_cameraShootPhotoMode;

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);\
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

2. Control the camera to take a single shot

The payload device control program developed based on PSDK calls the StartShootPhoto and StopShootPhoto interfaces to control the camera payload device to take a single photo. Users can use DJI Pilot and the Mobile App developed based on MSDK to control the camera payload device to take a single photo.

static T_DjiReturnCode StartShootPhoto(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

USER_LOG_INFO("start shoot photo");
s_cameraState.isStoring = true;

if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_SINGLE) {
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_SINGLE_PHOTO;
} else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_BURST) {
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_BURST_PHOTO;
} else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL) {
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_INTERVAL_PHOTO;
s_cameraState.isShootingIntervalStart = true;
s_cameraState.currentPhotoShootingIntervalTimeInSeconds = s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds;
}

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode StopShootPhoto(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

USER_LOG_INFO("stop shoot photo");
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
s_cameraState.isStoring = false;
s_cameraState.isShootingIntervalStart = false;

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

3. Control camera burst

The payload device control program developed based on PSDK calls the SetPhotoBurstCount and GetPhotoBurstCount interfaces to control the continuous shooting of the camera payload device. Users can use DJI Pilot and the Mobile App developed based on MSDK to set the number of continuous shots of the camera payload device, control the A camera-like payload device takes a specified number of photos.

static T_DjiReturnCode SetPhotoBurstCount(E_DjiCameraBurstCount burstCount)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

s_cameraBurstCount = burstCount;
USER_LOG_INFO("set photo burst count:%d", burstCount);

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetPhotoBurstCount(E_DjiCameraBurstCount *burstCount)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

*burstCount = s_cameraBurstCount;

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

4. Control the camera to take pictures regularly

The payload device control program developed based on PSDK calls the SetPhotoTimeIntervalSettings and GetPhotoTimeIntervalSettings interfaces to control the camera payload device to take pictures regularly. Users can use DJI Pilot and the Mobile App developed based on MSDK to set the photographing interval of the camera payload device and control the camera payload. The load device takes pictures at specified time intervals.

static T_DjiReturnCode SetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings settings)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

s_cameraPhotoTimeIntervalSettings.captureCount = settings.captureCount;
s_cameraPhotoTimeIntervalSettings.timeIntervalSeconds = settings.timeIntervalSeconds;
USER_LOG_INFO("set photo interval settings count:%d seconds:%d", settings.captureCount,
settings.timeIntervalSeconds);
s_cameraState.currentPhotoShootingIntervalCount = settings.captureCount;

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetPhotoTimeIntervalSettings(T_DjiCameraPhotoTimeIntervalSettings *settings)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

memcpy(settings, &s_cameraPhotoTimeIntervalSettings, sizeof(T_DjiCameraPhotoTimeIntervalSettings));

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

5. Photo status management

After clicking the "Photo" button in DJI Pilot and the Mobile App developed with MSDK, the camera-like payload device developed with PSDK will take pictures, store photos and update memory status in the thread within a custom time (such as 0.5s). operate.

1. Confirm the photo status

After the camera-like payload developed with PSDK performs the photographing action, it needs to obtain the photographing status of the payload.

if (s_cameraState.shootingState != PSDK_CAMERA_SHOOTING_PHOTO_IDLE &&
photoCnt++ > TAKING_PHOTO_SPENT_TIME_MS_EMU / (1000 / PAYLOAD_CAMERA_EMU_TASK_FREQ)) {
s_cameraState.isStoring = false;
s_cameraState.shootingState = PSDK_CAMERA_SHOOTING_PHOTO_IDLE;
photoCnt = 0;
}

2. Store photos

After the camera-like payload device finishes taking pictures, it uses the camera-like payload device developed by PSDK to store the photos taken by the camera in the memory card on the camera-like payload device.

  • Store photos taken by camera-like payload devices in single-shot mode
if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_SINGLE) {
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB;
s_cameraState.isStoring = false;
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
}
  • Store photos taken by camera-like payload devices in burst mode
else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_BURST) {
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB * s_cameraBurstCount;
s_cameraState.isStoring = false;
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
}
  • Store photos taken by camera-like payload devices in timed photo mode
else if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL) {
if (isStartIntervalPhotoAction == true) {
s_cameraState.isStoring = false;
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB;
}
}

3. Check storage space

To ensure that the SD card in the camera-type payload device has sufficient storage space to store photos or videos after the camera-type payload device performs a photo-taking action, it is recommended to add the function of checking the storage space of the SD card to the camera-type payload device developed with PSDK.

  • Check the remaining storage space of the SD card after the camera-like payload performs single shooting and continuous shooting.
if (s_cameraSDCardState.remainSpaceInMB > SDCARD_TOTAL_SPACE_IN_MB) {
s_cameraSDCardState.remainSpaceInMB = 0;
s_cameraSDCardState.isFull = true;
}
  • Check the remaining storage space of the SD card after the camera-like load device performs timed photography
if (s_cameraShootPhotoMode == DJI_CAMERA_SHOOT_PHOTO_MODE_INTERVAL) {
if (isStartIntervalPhotoAction == true) {
s_cameraState.isStoring = false;
s_cameraState.shootingState = DJI_CAMERA_SHOOTING_PHOTO_IDLE;
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_PHOTO_SPACE_IN_MB;
}
}

Using the remote control, you can control the camera-like load device to take pictures, as shown in Figure 3. Take pictures.

Figure 3. Take a photo

In single-shot mode, you can take pictures, as shown in Figure 4. Single-shot.

Figure 4. Single shot

In the continuous shooting mode, after setting the number of continuous shots of the camera-loaded device, the camera-loaded device can perform continuous shooting, as shown in Figure 5. Continuous shooting.

Figure 5. Continuous shooting

In the timed photo mode, set the interval time for taking pictures by the camera-type payload device, and the camera-type payload device can perform the timed photo-taking action, as shown in Figure 6. Timed Photo.

Figure 6. Timing photo

Use the recording function

Description

  • Camera-type payload devices cannot take pictures and meters during the recording process;
  • Developers can set the default values of parameters such as ISO, exposure and focus when recording camera-like payloads according to user needs;
  • Before using the video recording function of the camera-based payload device, the user needs to set the camera-based payload device's mode to the video recording mode on DJI Pilot or the Mobile App developed based on MSDK.

1. Control the camera to record

The payload device control program developed based on PSDK calls the StartRecordVideo and StopRecordVideo interfaces to control the video recording of the camera payload device. Users can use DJI Pilot and the Mobile App developed based on MSDK to control the camera payload device recording.

static T_DjiReturnCode StartRecordVideo(void)
{
T_DjiReturnCode djiStat;
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

djiStat = osalHandler->MutexLock(s_commonMutex);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", djiStat);
return djiStat;
}

if (s_cameraState.isRecording != false) {
USER_LOG_ERROR("camera is already in recording state");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE;
goto out;
}

s_cameraState.isRecording = true;
USER_LOG_INFO("start record video");

out:
djiStat = osalHandler->MutexUnlock(s_commonMutex);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", djiStat);
return djiStat;
}

return returnCode;
}

static T_DjiReturnCode StopRecordVideo(void)
{
T_DjiReturnCode djiStat;
T_DjiReturnCode returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

djiStat = osalHandler->MutexLock(s_commonMutex);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", djiStat);
return djiStat;
}

if (s_cameraState.isRecording != true) {
USER_LOG_ERROR("camera is not in recording state");
returnCode = DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE;
goto out;
}

s_cameraState.isRecording = false;
s_cameraState.currentVideoRecordingTimeInSeconds = 0;
USER_LOG_INFO("stop record video");

out:
djiStat = osalHandler->MutexUnlock(s_commonMutex);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", djiStat);
return djiStat;
}

return returnCode;
}

2. Recording status update

The camera class load device control program developed with PSDK updates the status of the camera at a frequency of 10Hz by default.

Note: After the camera starts recording, DJI Pilot and the Mobile App developed based on MSDK will display the current recording time. When the camera stops recording, the time will return to 0.

if (s_cameraState.isRecording) {
s_cameraState.currentVideoRecordingTimeInSeconds++;
s_cameraSDCardState.remainSpaceInMB =
s_cameraSDCardState.remainSpaceInMB - SDCARD_PER_SECONDS_RECORD_SPACE_IN_MB;
if (s_cameraSDCardState.remainSpaceInMB > SDCARD_TOTAL_SPACE_IN_MB) {
s_cameraSDCardState.remainSpaceInMB = 0;
s_cameraSDCardState.isFull = true;
}
}

static T_DjiReturnCode GetSystemState(T_DjiCameraSystemState *systemState)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

*systemState = s_cameraState;

returnCode = osalHandler->MutexUnlock(s_commonMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

After sending a video recording command to the payload device on DJI Pilot or a Mobile App developed based on MSDK (you can also send a video recording command to the payload device through the remote control), the camera-type payload device controls the payload device to record video according to the command sent by the user, as shown in Figure 7. Camera video as shown.

Figure 7. Camera video

Implement the focus function

Developers are requested to construct a function to realize the focusing function of a camera-like load device according to the structure T_DjiCameraFocusHandler in the PSDK according to the selected development platform and the actual use requirements of the industry application, and register the function of the focusing function in the PSDK to specify After the interface, the user can control the focus of the camera-like payload developed based on PSDK by using DJI Pilot or the Mobile App developed based on MSDK.

// Implement the function of setting the focus mode
s_focusHandler.SetFocusMode = SetFocusMode;
s_focusHandler.GetFocusMode = GetFocusMode;
// Implement the function of setting the focus point
s_focusHandler.SetFocusTarget = SetFocusTarget;
s_focusHandler.GetFocusTarget = GetFocusTarget;
// Implement the function of setting the focus assistant
s_focusHandler.SetFocusAssistantSettings = SetFocusAssistantSettings;
s_focusHandler.GetFocusAssistantSettings = GetFocusAssistantSettings;
// Implement the function of setting the focus ring
s_focusHandler.SetFocusRingValue = SetFocusRingValue;
s_focusHandler.GetFocusRingValue = GetFocusRingValue;
s_focusHandler.GetFocusRingValueUpperBound = GetFocusRingValueUpperBound;

Using the focus function

1. Register the focus function

After the developer implements the focusing function of the camera-like payload, it is necessary to register the focusing function through DjiPayloadCamera_RegFocusHandler, which is convenient for users to control the focusing of the camera-like payload by using DJI Pilot and the Mobile App developed based on MSDK.

returnCode = DjiPayloadCamera_RegFocusHandler(&s_focusHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register adjustable focal point handler error:0x%08llX", returnCode);
return returnCode;
}

2. Set focus mode

The payload control program developed based on PSDK can call the SetFocusMode and GetFocusMode interfaces to set the focus mode of the camera payload. Users can use DJI Pilot to switch the focus mode of the camera payload.

static T_DjiReturnCode SetFocusMode(E_DjiCameraFocusMode mode)
{
USER_LOG_INFO("set focus mode:%d", mode);
s_cameraFocusMode = mode;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetFocusMode(E_DjiCameraFocusMode *mode)
{
*mode = s_cameraFocusMode;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

3. Set the focus point

based on PSDK can call the SetFocusTarget and GetFocusTarget interfaces to set the focus point of the camera payload device. Users can use DJI Pilot and the Mobile App developed based on MSDK to set or get the focus point of the camera payload device.

static T_DjiReturnCode SetFocusTarget(T_DjiCameraPointInScreen target)
{
USER_LOG_INFO("set focus target x:%.2f y:%.2f", target.focusX, target.focusY);
memcpy(&s_cameraFocusTarget, &target, sizeof(T_DjiCameraPointInScreen));

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetFocusTarget(T_DjiCameraPointInScreen *target)
{
memcpy(target, &s_cameraFocusTarget, sizeof(T_DjiCameraPointInScreen));

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

4. Set the focus ring

The payload device control program developed based on PSDK can call the SetFocusRingValue, GetFocusRingValueUpperBound and GetFocusRingValueUpperBound interfaces to set the focus ring value of the camera class payload device. Users can set or get the camera class using DJI Pilot and the Mobile App developed based on MSDK Loads the current and maximum values of the device's focus ring.

static T_DjiReturnCode SetFocusRingValue(uint32_t value)
{
USER_LOG_INFO("set focus ring value:%d", value);
s_cameraFocusRingValue = value;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetFocusRingValue(uint32_t *value)
{
*value = s_cameraFocusRingValue;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetFocusRingValueUpperBound(uint32_t *value)
{
*value = FOCUS_MAX_RINGVALUE;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

5. Use Focus Assistant

The payload device control program developed based on PSDK can call the SetFocusAssistantSettings and GetFocusAssistantSettings interfaces to set the focus ring value of the camera payload device. Users can use DJI Pilot and the Mobile App developed based on MSDK to set or get the camera payload device focus assistant. status.

static T_DjiReturnCode SetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings settings)
{
USER_LOG_INFO("set focus assistant setting MF:%d AF:%d", settings.isEnabledMF, settings.isEnabledAF);
memcpy(&s_cameraFocusAssistantSettings, &settings, sizeof(T_DjiCameraFocusAssistantSettings));

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetFocusAssistantSettings(T_DjiCameraFocusAssistantSettings *settings)
{
memcpy(settings, &s_cameraFocusAssistantSettings, sizeof(T_DjiCameraFocusAssistantSettings));

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

After realizing the focusing function of the camera-type load device, in the auto-focus mode, the camera-type load device needs to set the focus point as shown in Figure 2. Auto focus; in the manual focus mode, the user can adjust the focus point according to actual needs, as shown in the figure 3. Manual focus as shown.

Description: If the button is yellow, it means that the metering function is currently used. After clicking, it can be switched to focus mode.

Figure 2. Autofocus

Figure 3. Manual focus

Implement metering function

Developers are requested to construct a function to realize the metering function of the camera-like load device according to the structure T_DjiCameraExposureMeteringHandler in the PSDK according to the selected development platform and the actual use requirements of the industry application, and register the function of the metering function to the PSDK. After the interface is specified in , the user can control the metering of the camera-like payload by using DJI Pilot or the Mobile App developed based on MSDK.

// Implement the function of setting the metering mode
s_exposureMeteringHandler.SetMeteringMode = SetMeteringMode;
s_exposureMeteringHandler.GetMeteringMode = GetMeteringMode;
// Implement the function of controlling the metering of the load device
s_exposureMeteringHandler.SetSpotMeteringTarget = SetSpotMeteringTarget;
s_exposureMeteringHandler.GetSpotMeteringTarget = GetSpotMeteringTarget;

Using the metering function

1. Register the metering function

After the developer implements the metering function of the camera-type payload device, he needs to register the metering function through PsdkPayloadCamera_RegExposureMeteringHandler; after calling the specified interface, the user can control the camera-type payload device measurement by using DJI Pilot and the Mobile App developed based on MSDK. light, as shown in Figure 2. Metering function

returnCode = DjiPayloadCamera_RegExposureMeteringHandler(&s_exposureMeteringHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register exposure metering handler error:0x%08llX", returnCode);
return returnCode;
}

2. Set metering mode

The payload device control program developed based on PSDK can call the SetMeteringMode and GetMeteringMode interfaces to set or get the metering mode of the camera-like payload device. Users can use DJI Pilot and the APP developed based on MSDK to view the metering mode of the payload device, such as Figure 3. Spot metering and Figure 4. Center-weighted metering is shown.

static T_DjiReturnCode SetMeteringMode(E_DjiCameraMeteringMode mode)
{
USER_LOG_INFO("set metering mode:%d", mode);
s_cameraMeteringMode = mode;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetMeteringMode(E_DjiCameraMeteringMode *mode)
{
*mode = s_cameraMeteringMode;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

3. Set metering target

After calling the SetSpotMeteringTarget and GetSpotMeteringTarget interfaces, the camera-type payload device can use DJI Pilot and the Mobile App developed based on MSDK to set or obtain the light metering object of the camera-type payload device.

static T_DjiReturnCode SetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget target)
{
USER_LOG_INFO("set spot metering area col:%d row:%d", target.col, target.row);
memcpy(&s_cameraSpotMeteringTarget, &target, sizeof(T_DjiCameraSpotMeteringTarget));

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetSpotMeteringTarget(T_DjiCameraSpotMeteringTarget *target)
{
memcpy(target, &s_cameraSpotMeteringTarget, sizeof(T_DjiCameraSpotMeteringTarget));

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

Figure 2. Metering function

Figure 3. Center-weighted metering

Figure 4. Point metering

Note: When using the metering function of a camera-like payload on the DJI Pilot, if the button is green, it means that the focus function is currently active. After clicking, it can be switched to the metering mode.

Implement the zoom function

Developers are requested to construct a function to realize the zoom function of the camera-like load device according to the structure T_DjiCameraTapZoomHandler in the PSDK according to the selected development platform and the actual use requirements of the industry application, and register the zoom function in the PSDK to specify After the interface, the user can control the zoom of the camera-like payload by using DJI Pilot or the Mobile App developed based on MSDK.

// Realize the function of controlling the load device to perform digital zoom
s_digitalZoomHandler.SetDigitalZoomFactor = SetDigitalZoomFactor;
s_digitalZoomHandler.GetDigitalZoomFactor = GetDigitalZoomFactor;
// Implement the function of controlling the load device to perform optical zoom
s_opticalZoomHandler.SetOpticalZoomFocalLength = SetOpticalZoomFocalLength;
s_opticalZoomHandler.GetOpticalZoomFocalLength = GetOpticalZoomFocalLength;
s_opticalZoomHandler.GetOpticalZoomFactor = GetOpticalZoomFactor;
s_opticalZoomHandler.GetOpticalZoomSpec = GetOpticalZoomSpec;
s_opticalZoomHandler.StartContinuousOpticalZoom = StartContinuousOpticalZoom;
s_opticalZoomHandler.StopContinuousOpticalZoom = StopContinuousOpticalZoom;
// Realize the function of controlling the load device to perform pointing and zooming
s_tapZoomHandler.GetTapZoomState = GetTapZoomState;
s_tapZoomHandler.SetTapZoomEnabled = SetTapZoomEnabled;
s_tapZoomHandler.GetTapZoomEnabled = GetTapZoomEnabled;
s_tapZoomHandler.SetTapZoomMultiplier = SetTapZoomMultiplier;
s_tapZoomHandler.GetTapZoomMultiplier = GetTapZoomMultiplier;
s_tapZoomHandler.TapZoomAtTarget = TapZoomAtTarget;

Using the zoom function

1. Register the zoom function

After the developer realizes the zoom function of the camera-type payload device, it is necessary to register the functions of each zoom function through the registration interface; the payload device developed based on PSDK can control the camera-type payload device to perform zooming by calling the specified interface, which is convenient Users can control the zoom of camera-like payloads by using DJI Pilot and the Mobile App developed based on MSDK.

  • Register the digital zoom function
returnCode = DjiPayloadCamera_RegDigitalZoomHandler(&s_digitalZoomHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register digital zoom handler error:0x%08llX", returnCode);
return returnCode;
}
  • Register the optical zoom function
returnCode = DjiPayloadCamera_RegOpticalZoomHandler(&s_opticalZoomHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register optical zoom handler error:0x%08llX", returnCode);
return returnCode;
}
  • Register the pointing and zoom function
returnCode = DjiPayloadCamera_RegTapZoomHandler(&s_tapZoomHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("camera register tap zoom handler error:0x%08llX", returnCode);
return returnCode;
}

2. Using the digital zoom function

The payload device control program developed based on PSDK can call the SetDigitalZoomFactor and GetDigitalZoomFactor interfaces to control the payload device to perform digital zoom. Users can use DJI Pilot and the Mobile App developed based on MSDK to control the camera-like payload device to perform digital zoom, and get the factor for the digital zoom of the load device.

static T_DjiReturnCode SetDigitalZoomFactor(dji_f32_t factor)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

USER_LOG_INFO("set digital zoom factor:%.2f", factor);
s_cameraDigitalZoomFactor = factor;

returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

T_DjiReturnCode DjiTest_CameraGetDigitalZoomFactor(dji_f32_t *factor)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

*factor = s_cameraDigitalZoomFactor;

returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

3. Using the optical zoom function

The payload device control program developed based on PSDK can control the payload device to perform optical zoom by calling the SetOpticalZoomFocalLength and GetOpticalZoomFocalLength interfaces. Users can use DJI Pilot and the Mobile App developed based on MSDK to control the camera-like payload device to perform optical zoom, and get the payload at the same time. The factor for the optical zoom of the device.

  • Set the focal length of the optical zoom camera
static T_DjiReturnCode SetOpticalZoomFocalLength(uint32_t focalLength)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

USER_LOG_INFO("set optical zoom focal length:%d", focalLength);
s_isOpticalZoomReachLimit = false;
s_cameraDigitalZoomFactor = ZOOM_DIGITAL_BASE_FACTOR;
s_cameraOpticalZoomFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH;

returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

T_DjiReturnCode DjiTest_CameraGetOpticalZoomFactor(dji_f32_t *factor)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

//Formula:factor = currentFocalLength / minFocalLength
*factor = (dji_f32_t) s_cameraOpticalZoomFocalLength / ZOOM_OPTICAL_FOCAL_MIN_LENGTH;

returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
  • Get the zoom factor of the camera class load device After obtaining the current optical focal length of the camera-like payload, the current zoom factor of the camera-like payload can be calculated according to the formula for calculating the zoom factor (zoom factor = current focal length ÷ shortest focal length).
T_DjiReturnCode DjiTest_CameraGetOpticalZoomFactor(dji_f32_t *factor)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

//Formula:factor = currentFocalLength / minFocalLength
*factor = (dji_f32_t) s_cameraOpticalZoomFocalLength / ZOOM_OPTICAL_FOCAL_MIN_LENGTH;

returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
  • Get the range of optical zoom
static T_DjiReturnCode GetOpticalZoomSpec(T_DjiCameraOpticalZoomSpec *spec)
{
spec->maxFocalLength = ZOOM_OPTICAL_FOCAL_MAX_LENGTH;
spec->minFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH;
spec->focalLengthStep = ZOOM_OPTICAL_FOCAL_LENGTH_STEP;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

4. Using the continuous zoom function

The payload device control program developed based on PSDK calls the StartContinuousOpticalZoom and StopContinuousOpticalZoom interfaces to control the payload device to start or stop performing continuous zooming. Users can use DJI Pilot and the Mobile App developed based on MSDK to control the camera-like payload device to perform continuous zooming.

  • Control the camera-like payload to start zooming
static T_DjiReturnCode StartContinuousOpticalZoom(E_DjiCameraZoomDirection direction, E_DjiCameraZoomSpeed speed)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

USER_LOG_INFO("start continuous optical zoom direction:%d speed:%d", direction, speed);
s_isStartContinuousOpticalZoom = true;
s_cameraZoomDirection = direction;
s_cameraZoomSpeed = speed;

returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
  • Control the camera-like load device to stop zooming
static T_DjiReturnCode StopContinuousOpticalZoom(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

USER_LOG_INFO("stop continuous optical zoom");
s_isStartContinuousOpticalZoom = false;
s_cameraZoomDirection = DJI_CAMERA_ZOOM_DIRECTION_OUT;
s_cameraZoomSpeed = DJI_CAMERA_ZOOM_SPEED_NORMAL;

returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
  • Control the camera to zoom continuously
if (s_isStartContinuousOpticalZoom == true) {
tempDigitalFactor = s_cameraDigitalZoomFactor;
tempFocalLength = (int32_t) s_cameraOpticalZoomFocalLength;
if (s_isOpticalZoomReachLimit == false) {
if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_IN) {
tempFocalLength += ((int) s_cameraZoomSpeed - DJI_CAMERA_ZOOM_SPEED_SLOWEST + 1) * ZOOM_OPTICAL_FOCAL_LENGTH_CTRL_STEP;
} else if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_OUT) {
tempFocalLength -= ((int) s_cameraZoomSpeed - DJI_CAMERA_ZOOM_SPEED_SLOWEST + 1) * ZOOM_OPTICAL_FOCAL_LENGTH_CTRL_STEP;
}

if (tempFocalLength > ZOOM_OPTICAL_FOCAL_MAX_LENGTH) {
s_isOpticalZoomReachLimit = true;
tempFocalLength = ZOOM_OPTICAL_FOCAL_MAX_LENGTH;
}

if (tempFocalLength < ZOOM_OPTICAL_FOCAL_MIN_LENGTH) {
tempFocalLength = ZOOM_OPTICAL_FOCAL_MIN_LENGTH;
}
} else {
if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_IN) {
tempDigitalFactor += (dji_f32_t) ZOOM_DIGITAL_STEP_FACTOR;
} else if (s_cameraZoomDirection == DJI_CAMERA_ZOOM_DIRECTION_OUT) {
tempDigitalFactor -= (dji_f32_t) ZOOM_DIGITAL_STEP_FACTOR;
}

if (tempDigitalFactor > (dji_f32_t) ZOOM_DIGITAL_MAX_FACTOR) {
tempDigitalFactor = (dji_f32_t) ZOOM_DIGITAL_MAX_FACTOR;
}

if (tempDigitalFactor < (dji_f32_t) ZOOM_DIGITAL_BASE_FACTOR) {
s_isOpticalZoomReachLimit = false;
tempDigitalFactor = ZOOM_DIGITAL_BASE_FACTOR;
}
}
s_cameraOpticalZoomFocalLength = (uint16_t) tempFocalLength;
s_cameraDigitalZoomFactor = tempDigitalFactor;
}

Keep pressing the zoom button to change the zoom factor, as shown in Figure 1. Continuous zoom.

  • T : Enlarged focal length (enlarged zoom factor)
  • W : zoom out (reduce zoom factor)
  • R : restore the focal length of the camera

Note: According to the actual needs, you can set the default zoom factor of the camera-like load device, which is currently 1.0.

Figure 1. Continuous zoom

5. Implement the pointing zoom function

When the user starts to use the "pointing and zooming" function, the camera-like payload device developed using PSDK will first control the rotation of the gimbal according to the target point position and the current focal length specified by the user, place the target object in the center of the screen, and then control the payload device zoom.

Pointing and zooming are implemented by registering a callback function
  • Set the zoom factor of the pointing zoom
static T_DjiReturnCode SetTapZoomMultiplier(uint8_t multiplier)
{
USER_LOG_INFO("set tap zoom multiplier: %d.", multiplier);
s_tapZoomMultiplier = multiplier;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

static T_DjiReturnCode GetTapZoomMultiplier(uint8_t *multiplier)
{
*multiplier = s_tapZoomMultiplier;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
  • Get the object of pointing and zooming The camera class payload device developed with PSDK obtains the zoom object specified by the user in the Mobile App through the TapZoomAtTarget interface. After confirming that the pointing zoom function is enabled, calculate the rotation angle of the gimbal and control the camera rotation according to the target point position and the mixed focal length.
static T_DjiReturnCode TapZoomAtTarget(T_DjiCameraPointInScreen target)
{
T_DjiReturnCode returnCode;
E_DjiGimbalRotationMode rotationMode;
T_DjiGimbalRotationProperty rotationProperty = {0};
T_DjiAttitude3d rotationValue = {0};
float hybridFocalLength = 0; // unit: 0.1mm
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();

USER_LOG_INFO("tap zoom at target: x %f, y %f.", target.focusX, target.focusY);

if (s_isTapZoomEnabled != true) {
USER_LOG_WARN("tap zoom is not enabled.");
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}

if (s_isTapZooming || s_isStartTapZoom) {
USER_LOG_WARN("The last tap zoom process is not over.");
return DJI_ERROR_SYSTEM_MODULE_CODE_NONSUPPORT_IN_CURRENT_STATE;
}

rotationMode = DJI_GIMBAL_ROTATION_MODE_RELATIVE_ANGLE;
rotationProperty.relativeAngleRotation.actionTime = TAP_ZOOM_DURATION / 10;

returnCode = osalHandler->MutexLock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

/* Calculation formula: rotation angle = arctan((coordinate of target in sensor - coordinate of center point in
* sensor) / hybrid focal length). Here, suppose that images of all pixels of sensor are displayed on screen,
* and that center of the image sensor coincides with center of rotation of the gimbal, and that optical axis of
* camera coincides with x-axis of gimbal. */
hybridFocalLength = (dji_f32_t) s_cameraOpticalZoomFocalLength * s_cameraDigitalZoomFactor;

returnCode = osalHandler->MutexUnlock(s_zoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

rotationValue.pitch = (int32_t) (
atan2f((target.focusY - CENTER_POINT_IN_SCREEN_Y_VALUE) * IMAGE_SENSOR_Y_SIZE, hybridFocalLength) * 1800 /
DJI_PI);
rotationValue.yaw = (int32_t) (
atan2f((target.focusX - CENTER_POINT_IN_SCREEN_X_VALUE) * IMAGE_SENSOR_X_SIZE, hybridFocalLength) * 1800 /
DJI_PI);

returnCode = osalHandler->MutexLock(s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

s_tapZoomNewestGimbalRotationArgument.rotationMode = rotationMode;
s_tapZoomNewestGimbalRotationArgument.rotationProperty = rotationProperty;
s_tapZoomNewestGimbalRotationArgument.rotationValue = rotationValue;
s_tapZoomNewestTargetHybridFocalLength = (uint32_t) (hybridFocalLength * (float) s_tapZoomMultiplier);

returnCode = osalHandler->MutexUnlock(s_tapZoomMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}

s_isStartTapZoom = true;

return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
Implement the pointing and zooming function in the thread

To avoid blocking the main thread of the payload device control program when the payload device rotates the gimbal and controls the zoom, please implement the pointing zoom function in the thread.

if (s_isStartTapZoom) {
s_isStartTapZoom = false;
s_isTapZooming = true;

returnCode = osalHandler->GetTimeMs(&s_tapZoomStartTime);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get start time error: 0x%08llX.", returnCode);
}

returnCode = DjiTest_CameraRotationGimbal(s_tapZoomNewestGimbalRotationArgument);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
USER_LOG_ERROR("rotate gimbal error: 0x%08llX.", returnCode);
else
s_cameraTapZoomState.isGimbalMoving = true;

returnCode = DjiTest_CameraHybridZoom(s_tapZoomNewestTargetHybridFocalLength);
if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
s_cameraTapZoomState.zoomState = (dji_f32_t) s_tapZoomNewestTargetHybridFocalLength >
((dji_f32_t) s_cameraOpticalZoomFocalLength *
s_cameraDigitalZoomFactor)
? DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_IN
: DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_OUT;
} else if (returnCode == DJI_ERROR_SYSTEM_MODULE_CODE_OUT_OF_RANGE) {
USER_LOG_ERROR("hybrid zoom focal length beyond limit.");
s_cameraTapZoomState.zoomState = DJI_CAMERA_TAP_ZOOM_STATE_ZOOM_LIMITED;
} else {
USER_LOG_ERROR("hybrid zoom error: 0x%08llX.", returnCode);
}
} else if (s_isTapZooming) {
returnCode = osalHandler->GetTimeMs(&currentTime);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get start time error: 0x%08llX.", returnCode);
}

if ((currentTime - s_tapZoomStartTime) >= TAP_ZOOM_DURATION) {
s_cameraTapZoomState.zoomState = DJI_CAMERA_TAP_ZOOM_STATE_IDLE;
s_cameraTapZoomState.isGimbalMoving = false;
s_isTapZooming = false;
}
}