Android Tutorial DJI virtual stick-tutorial, waypoint- and hotpoint-mission for DJI Mini- and Air-series

After the release of the new grandiose DJI library and the preliminary work of freedom2000 and JordiCP in this thread

https://www.b4x.com/android/forum/threads/dji-virtual-joystick-almost-not-working.128412/#content

i decided to deal a little bit more with dji’s virtual stick and it wasn't as complicated as initially thought. There are a few things which must be taken into account for safety reasons, so it is better to make a tutorial instead of simple code snippets.

First it is important to understand the differences between missions and virtual stick and use them to evaluate the pros and cons:

Missions are executed on the aircraft itself. Once, a mission was planned, it will be uploaded to the drone where it will be executed without any command from the controller.
Theoretically, the missions are executed even if the connection to the controller is lost. (In practice, however, dji has integrated security scenarios with the behavior when signal lost.)

When using virtual stick, all control inputs comes from the controller. Each calculation is done by the software on the controller and only the control correction, which normaly is done from the pilot in manual mode, is send to the drone. To do that, your software has to check first the aircraft-data, for example getting the location, calculate the right correction and send this up to the aircraft.
This already shows the first disadvantage: There is a certain latency by constantly comparing the data.

Another disadvantage is, that once the virtual stick mode has been activated, the drone is no longer controllable over the real sticks. So you have to make sure, that you first could get control back at any time.
Also you have to set the emergency regulations like smart return home etc. which are almost part of the preconfigured dji missions.

On the other side, using virtual stick brings us a lot of advantages:

Virtual stick seems to be available for all drones which are supported from the used sdk and the code is always the same.
With virtual stick, we could currently make ‘waypoint-‘ and ‘follow me-missions’ for drones like

- DJI Mavic Air 2
- DJI Mavic Mini
- DJI Mini SE
- DJI Mini 2


even if they boards don’t support waypoint-missions.

We could use the same code also on

- DJI Mavic Pro
- DJI Mavic 2 (Zoom und Dual) etc.,


which board supports the missions.

I have testet it successfully on Mini 2, Air 2 and Mavic 2 Zoom.

Another advantage is, that virtual stick not only works in 'p-mode' like waypoint. It works in all modes, like 'sport' or 'tripod' with a maximum speed of 15 m/s. In vs-mode, the aircraft makes no difference between flight-modes. In this context it is important to know, that on the devices, which I have tested, the virtual stick mode will be stopped when changing the flightmode with the controller's hardwarebutton. You have to start the virtual stick-mode again in the new settings.
Otherwise the mode is very stable. For example, the normal followme-mission for the Mavic 2 will be interrupted, when the following gps-position is more then 30m removed from the last position. This is not the case in virtual stick mode which offers us numerous advantages because the object, which will be followed, could reach higher speeds.

To start virtual stick, we could use the following code. Erel’s dji-example is a very good base to start. The subs will refer to this example:

https://www.b4x.com/android/forum/threads/dji-drones.75244/#content

B4X:
Sub Process_Globals
    ...
    Public sdk As DJISDKManager
    Private aircraft As DJIAircraft
    Private controller As DJIFlightController
    Private camera As DJICamera
 
    'We make an instance of the aircraft and flightcontroller for the later used javaobjects
    Dim AircraftInstance As JavaObject
    Dim FlightControllerInstance As JavaObject
    ….
    ..
End Sub

Sub AfterAircraftConnected
    ....
    ..
    'initialize it in this sub of Erel’s example:
    AircraftInstance=aircraft
    FlightControllerInstance=AircraftInstance.RunMethod("getFlightController", Null)
    ..
    ....
End Sub

Private Sub StartVirtualStick
    Dim callback As Object = FlightControllerInstance.CreateEventFromUI("dji.common.util.CommonCallbacks$CompletionCallback", "setvirtualstickcallback", Null)
    FlightControllerInstance.RunMethod("setVirtualStickModeEnabled",Array(True, callback))    'switch on/off the virtual joysticks

    Wait For (FlightControllerInstance) setvirtualstickcallback_Event (MethodName As String, args() As Object)
    If args(0) = Null Then
        Log("VirtualStickMode enabled!")
        SetParameterVirtualStick
    Else
        Log("Error SetVirtualStickMode: " & args(0))
    End If
End Sub

It is nessecary to know, that it is possible to activate the vs-mode, when the drone is on the ground and the motors are off. This could be difficult, because you noticed it first after starting the motors manually. The drone starts and works autark emediatly. So it is nesseccary to make some checks first:

For example we could first check, if the aircraft is flying:

B4X:
If controller.IsInitialized Then
    Dim St As DJIFlightControllerCurrentState = controller.CurrentState
    If St.Flying Then StartVirtualStick
End if

If we want to start a mission from the ground with only in 'switched-on'- state, we could first start the motors and after that we activate the virtual stick-mode. The drone will be started and follows the virtual stick commands:

B4X:
Private Sub TurnMotorsOn
    Dim callback As Object = FlightControllerInstance.CreateEventFromUI("dji.common.util.CommonCallbacks$CompletionCallback", "motorsoncallback", Null)
    FlightControllerInstance.RunMethod("turnOnMotors",Array(callback))

    Wait For (FlightControllerInstance) motorsoncallback_Event (MethodName As String, args() As Object)
    If args(0) = Null Then
        Log("Motors on!")
        StartVirtualStick
    Else
        Log("Error motors on: " & args(0))
    End If
End Sub

Now, after starting the virtual stick-mode, we have to set the needed parameter to this mode. The most important thing to handle this mode as easy as possible is to set the virtual stick-advancedmode to 'true'. Under this mode, the aircraft is stabilized with the use of the flightsensors like gps etc. Wind and gusts are automatically compensated to hold the aircraft's position. Otherwise the effort will be too great for a stable fly.

After that we check, if the modes are available respectively activated. If that is the case, we set the different flightmodes for 'roll' and 'pitch', 'yaw' and 'vertical control'. There are different modes available with different effects. To lern more about the 'roll pitch control mode' and especially about 'virtual stick coordinate system', read the dji documentation under

https://developer.dji.com/mobile-sd...duction/component-guide-flightController.html

I decided to use the 'rollpitch-mode' in 'VELOCITY' to make the settings in m/s, the yaw to 'ANGLE' and the vertical mode to 'POSITION' to set the aircrafts hight easily in meters. It is also very important to set 'rollpitchcoordinatesystem' to ‘BODY’, if you want to control the drone with the following subs. Some settings are the default settings of the aircraft, but to be sure and to show the way to switch the modes, I set and check them all in the following sub:

B4X:
...
dim virtualStickAvailable, virtualStickAdvancedEnabled as boolean
..
Private Sub SetParameterVirtualStick
    FlightControllerInstance.RunMethod("setVirtualStickAdvancedModeEnabled", Array(True))
 
    virtualStickAvailable = FlightControllerInstance.RunMethod("isVirtualStickControlModeAvailable", Null)
    virtualStickAdvancedEnabled = FlightControllerInstance.RunMethod("isVirtualStickAdvancedModeEnabled", Null)
 
    Log($"virtual stick available: ${virtualStickAvailable}"$)
    Log($"virtual stick advanced enabled: ${virtualStickAdvancedEnabled}"$)
    If virtualStickAvailable And virtualStickAdvancedEnabled Then
  
        'Modes mit set manuell setzen und Ergebnis mit get zur Kontrolle auslesen :
        FlightControllerInstance.RunMethod("setRollPitchControlMode", Array("VELOCITY"))    'Roll und Nick in Meter pro Sekunden eingeben: Bereich -15m/s bis +15m/s (0=Stop)
        FlightControllerInstance.RunMethod("setYawControlMode", Array("ANGLE"))                'Richtung in Abhängigkeit vom Norden in Grad eingeben: Bereich -180 bis +180 (0=Nord)
        FlightControllerInstance.RunMethod("setVerticalControlMode", Array("POSITION"))        'Höhe in Meter eingeben!
        FlightControllerInstance.RunMethod("setRollPitchCoordinateSystem", Array("BODY"))    'Koordinatensystem von der Lage der Drohne abhängig machen, da ansonsten Roll und Pitch von Nord anhängig sind!
  
        Dim RollPitchControlMode As String = FlightControllerInstance.RunMethod("getRollPitchControlMode", Null)
        Log("RollPitchControlMode: "& RollPitchControlMode)
  
        Dim YawControlMode As String = FlightControllerInstance.RunMethod("getYawControlMode", Null)
        Log("YawControlMode: " & YawControlMode)
  
        Dim VerticalControlMode As String = FlightControllerInstance.RunMethod("getVerticalControlMode", Null)
        Log("VerticalControlMode: " & VerticalControlMode)
  
        Dim RollPitchCoordinateSystem As String = FlightControllerInstance.RunMethod("getRollPitchCoordinateSystem", Null)
        Log("RollPitchCoordinateSystem: " & RollPitchCoordinateSystem)
  
        TimerVirtualStick.enabled = True
    Else
        TimerVirtualStick.enabled = False
    End If
End Sub

To send the virtual stick command to our aircraft, we start a timer. DJI says, virtual stick commands should be sent to the aircraft between 5 Hz and 25 Hz. I testet it successful with a timer of 50 ms.

B4X:
TimerVirtualStick.Initialize("TimerVirtualStick", 50)

Before we get to the real mission, we need to do some more saftey settings. To stop the vs-mode as fast as possible we check, if there is an real stick input from the pilot. If so, we stop the vs-mode. It is also possible to make a stop-button, but you can’t get back the control better than over the real sticks. In der HardwareState_Event, i stop the vs-mode by actuation of the right stick:

B4X:
Sub CreateHardwareStateListener
    Dim RemoteController As JavaObject = aircraft
    RemoteController = RemoteController.RunMethod("getRemoteController", Null)
    Dim callback As Object = RemoteController.CreateEventFromUI("dji.common.remotecontroller.HardwareState$HardwareStateCallback", "HardwareState", Null)
    RemoteController.RunMethod("setHardwareStateCallback", Array(callback))
End Sub

Sub HardwareState_Event (MethodName As String, Args() As Object) As Object
    Dim HardwareState As JavaObject = Args(0)
    Dim c1button As JavaObject = HardwareState.RunMethod("getC1Button", Null)
    Dim IsClicked As Boolean = c1button.RunMethod("isPresent", Null) 'ignore

    If TimerVirtualStick.Enabled=True Then
        Dim Lstick As JavaObject = HardwareState.RunMethod("getLeftStick", Null)
        Dim Lhoriz As Int = Lstick.RunMethod("getHorizontalPosition", Null)
        Dim Lvert As Int = Lstick.RunMethod("getVerticalPosition", Null)
        Log($"left stick H value: ${Lhoriz}"$)    '-660 bis +660
        Log($"left stick V value: ${Lvert}"$)    '-660 bis +660
  
        Dim Rstick As JavaObject = HardwareState.RunMethod("getRightStick", Null)
        Dim Rhoriz As Int = Rstick.RunMethod("getHorizontalPosition", Null)
        Dim Rvert As Int = Rstick.RunMethod("getVerticalPosition", Null)
        Log($"right stick H value: ${Rhoriz}"$)
        Log($"right stick V value: ${Rvert}"$)
  
        If Rhoriz<>0 Or Rvert<>0 Then StopVirtualStick    'Beim Betätigen des rechten Sticks VS aufheben!
 
    End If

    Return Null
End Sub

In my tests, the stop works all the time, but it is also possible to make a callback and check, if the vs-mode is realy stopped. If not, you can stop it again and again.

B4X:
Private Sub StopVirtualStick
    FlightControllerInstance.RunMethod("setVirtualStickModeEnabled",Array(False, Null))    'switch on/off the virtual joysticks
    FlightControllerInstance.RunMethod("setVirtualStickAdvancedModeEnabled", Array(False))
    TimerVirtualStick.enabled = False
End Sub

Then we need more security settings: With the following subs, we could check and set the failsafe-behavior of the aircraft. This is impossible, if the controller looses the signal to the aitcraft. We could set the following modes:

HOVER
LANDING
GO_HOME


If we set it to HOVER, we have to try to get back the signal. If that doesn’t work, the aircraft will land if the battery is emty. So the safest solution is to GO_HOME. It is a mater of taste and depending on the purpose:

B4X:
..
SetConnectionFailSafeBehavior("GO_HOME")
...
Private Sub SetConnectionFailSafeBehavior(FailSafeMode As String)
    Dim callback As Object = FlightControllerInstance.CreateEventFromUI("dji.common.util.CommonCallbacks$CompletionCallback", "failsafebehaviorcallback", Null)
    FlightControllerInstance.RunMethod("setConnectionFailSafeBehavior", Array(FailSafeMode,callback))

    Wait For (FlightControllerInstance) failsafebehaviorcallback_Event (MethodName As String, args() As Object)
    If args(0) = Null Then
        SignalverlustState=FailSafeMode
        Log("Set FailSafeBehavior to: " & FailSafeMode)
    Else
        Log("Error setting FailSafeBehavior: " & args(0))
    End If
End Sub

'Check the failsafe-settings with this sub:
Private Sub GetConnectionFailSafeBehavior
    Dim callback As Object = FlightControllerInstance.CreateEventFromUI("dji.common.util.CommonCallbacks$CompletionCallbackWith", "getfailsafebehaviorcallback", Null)
    FlightControllerInstance.RunMethod("getConnectionFailSafeBehavior", Array(callback))
 
    Wait For (FlightControllerInstance) getfailsafebehaviorcallback_Event (MethodName As String, args() As Object)
    Dim GetFailSafeBehavior As String =args(0)
    Log("GetFailSafeBehavior: " & GetFailSafeBehavior)
End Sub

Next is the smartreturnhome-feature: If smart-rth is set to 'true', the aircraft comes back to the home postion, if the battery capacity is just enough for the fly back home. This feature is supported by mavic 2, air2 etc., but seems not to be available under the mini 2.

I also did not have checked yet, if the smart-rth is triggered in the virtual stick-mode, after signal is lost and the failsavebehavior is set to 'HOVER'.

In this context, don’t forget to set the gohome-height:

B4X:
If controller.IsInitialized Then
        'RTH-Höhe setzen:
        Dim sf As Object = controller.SetGoHomeHeightInMeters(manager.GetString("flytoalt"))
        Wait For (sf) controller_Result (Success As Boolean, ErrorMessage As String)
        If Success Then
            Dim currentstate As DJIFlightControllerCurrentState
            currentstate=controller.CurrentState
            Log("RTH-Höhe:" & currentstate.GoHomeHeight)
            RTHHoeheState=currentstate.GoHomeHeight
        Else
            Log("Error: " & ErrorMessage)
        End If
End if

Now, we made all settings and we could send the vs-commands to fly to a waypoint:

B4X:
Dim AutoFLightSpeed As Int = 15  'max speed in vs-mode
Dim VSLocation As Location
VSLocation.Initialize2(gmap.CameraPosition.Target.Latitude, gmap.CameraPosition.Target.Longitude)     'We could fly to a point of the map
VSLocation.Altitude=45

Sub TimerVirtualStick_Tick
    WayPointVirtualStick(VSLocation)
End Sub

This sub is constructed in such a way that the aircraft will first get the approach height before making a roll or pitch move to protect the aircraft against collisions. During the ascent, the drone will correct the direction to the waypoint. After reaching the height, the drone will roll with the autoflight speed (max. 15m/s) to the waypoint while always correcting the direction to the target. So as not to fly over the target, we have to reduce the speed in time. If the distance to the target is smaller than 60 meters, the maximum speed may only be a quarter of the distance. If the distance is near than 2 meters, we set the speed to 0 an stop the vs-mode. I made several tests with strong headwind and crosswind and all testet aircrafts have always reached the targets exactly.

B4X:
Sub WayPointVirtualStick(WPLocation As Location)
 
    Dim mRoll As Float = 0
    Dim mYaw As Float = 0
 
    Dim St As DJIFlightControllerCurrentState = controller.CurrentState
 
    Dim DroneLocation As Location
    DroneLocation.Initialize2(St.AircraftLocation.Latitude, St.AircraftLocation.Longitude)
    DroneLocation.Altitude=St.AircraftLocation.Altitude
 
    Dim VirtualStickBearing As Float = DroneLocation.BearingTo(WPLocation)
    Dim VirtualStickDistance As Float = DroneLocation.DistanceTo(WPLocation)
    Dim VirtualStickAltitudeDifference As Double = Abs(Round(DroneLocation.Altitude)-WPLocation.Altitude)
 
    Select True
        Case VirtualStickAltitudeDifference>1
            mYaw=VirtualStickBearing
  
        Case Abs(St.Attitude.Yaw-VirtualStickBearing)>5
            mYaw=VirtualStickBearing
      
        Case VirtualStickDistance>60
            mYaw=VirtualStickBearing
            mRoll=AutoFLightSpeed
      
        Case VirtualStickDistance>2 And VirtualStickDistance<=60
            mYaw=VirtualStickBearing
            mRoll=Min(VirtualStickDistance/4, AutoFLightSpeed)
      
        Case Else
            mYaw=VirtualStickBearing
            mRoll=0
            StopVirtualStick
            'Do, what ever you want after reaching the waypoint:
            AddWayPointAction("GIMBAL_PITCH", "-90")
      
    End Select
    sendVirtualStickFlightControlData(0,mRoll, mYaw, WPLocation.Altitude)
End Sub

Sub sendVirtualStickFlightControlData(Pitch As Float, Roll As Float, Yaw As Float, Throttle As Float)
    Try
        Dim FlightControlData As JavaObject
        FlightControlData.InitializeNewInstance("dji.common.flightcontroller.virtualstick.FlightControlData", Array(Pitch, Roll, Yaw, Throttle) )
        FlightControllerInstance.RunMethod("sendVirtualStickFlightControlData",Array( FlightControlData, Null) )
    Catch
        Log(LastException)
    End Try
End Sub

After reaching the waypoint, it is easy to add a waypoint-action like 'go home', 'next waypoint' or some else.

In the same way, you can make an easy followme-mission by changing the VSLocation in the VirtualStick-timer dynamically. It is very impressive to see the mini 2 or air 2 following your position with an maximum speed of 54km/h.

The next thing to do is to make a hotpoint-mission. The first tests shows, that it is not realy simple. With constant speed and pitch , we could fly a beautiful circle in the simulator and with no wind. With wind, we have to adjust the speed and pitch. The parameter 'getmayangularvelocity',

B4X:
Dim callback As Object=HotPointMissionControl.CreateEventFromUI("dji.common.util.CommonCallbacks$CompletionCallbackWith", "getmaxangularvelocitycallback", Null)
HotPointMissionControl.RunMethod("getMaxAngularVelocityForRadius", Array(RadiusAufklaerung,callback))
Wait For (HotPointMissionControl) getmaxangularvelocitycallback_Event (MethodName As String, args() As Object)
Dim MaxAngularVelocity As Float = args(0)

, which is only available inside the dji hotpointmission-control suggests, that dji seems to include the weight of each aircraft. So i don’t know, if it is possible to do it only with virtual stick commands.

To test all the features, the simulator is still a good solution before flying outdoor.

I hope that the subject of drones will continue to be promoted here, because the future range of dji is very impressive.
 
Last edited:

schimanski

Well-Known Member
Licensed User
Longtime User
Having a Mini 2 which seems unable to work with waypoints, this is promising but I failed in constructing a complete app just by adding the subs to Erel's example. Is it possible to publish a complete example (just to go to a waypoint, after the bird is airborne) ?
Thanks !
I think I can do it over the weekend
 

schimanski

Well-Known Member
Licensed User
Longtime User
The attached example is a modified version of Erel's DJI-example to show the functions of virtual sticks. But be careful, it's just a rudimentary version to show the waypoint-, hotpoint- and followme-mission. I did not have implemented all security features out of this thread.

To start a mission, choose one of the three radio-buttons and press START, after you have chosen a location in the google map. 'Waypoint' and 'hotpoint' always takes the location in the center of the map (=target). 'Followme' takes your own location with a distance of 20 meters. Don't use 'followme' with your location directly (see post #2).

To use the code, you first have to set your own DJI-app-key under
B4X:
AddReplacement($DJI_KEY$, ec3xxxxxxxxxxx)

and your googlemaps-api-key under
B4X:
AddApplicationText(
<meta-data
  android:name="com.google.android.geo.API_KEY"
  android:value="AIxxxxxxxxxxxxxxxxxxxxxxx"/>
)
in the manifest-editor.

Under Process_Globals, you can change the flight parameters:
B4X:
   'flight parameters:
    Dim AutoFLightSpeed As Int = 15              'in m/s
    Dim GoHomeAltitude As Int= 40                'in meters
    Dim WaypointAltitude As Int = 40              'in meters
    Dim HotpointAltitude As Int = 40               'in meters
    Dim HotpointRadius As Int = 50                 'in meters (diameter=100 meters)
    Dim FollowMeAltitude As Float = 40          'in meters
    Dim FollowMeDistance As Int = 20             'in meters
    Dim FailSafeBehavior As String = "GO_HOME"    'choose HOVER, LANDING or GO_HOME

To stop the virtual sticks-mode immediately, press the STOP-Button or move one of the two controller-sticks.

It is tested with the DJI mini 2!
 

Attachments

  • VirtualSticks.zip
    8.3 KB · Views: 140
Last edited:

derez

Expert
Licensed User
Longtime User
Got the setup OK for the dji and map, now I have to find an area to fly ...

1660921254826.png
 

derez

Expert
Licensed User
Longtime User
I tested it in flight this morning, without modifications. The response in all missions is very good, the drone does what it should do.
Problem - I can't see the staus of the camera.
Is it possible to give gimbal commands and "take picture" or "start video"by the program ?
 
Last edited:

schimanski

Well-Known Member
Licensed User
Longtime User
I tested it in flight this morning, without modifications. The response in all missions is very good, the drone does what it should do.
Problem - I can't see the staus of the camera.
Is it possible to give gimbal commands and "take picture" or "start video"by the program ?
All you need for that is posted in #10 and #16.

Copy the code of post #10 and #16 into the example and activate the lines with 'camerainstance and 'AddwaypointAction. That's it.
 

schimanski

Well-Known Member
Licensed User
Longtime User
Yes, that's right. At the moment, photo works, but video doesn't with my mini 2. It seems, that there exists dependencies, which need more testing. The code only works completly on the mavic...
 

derez

Expert
Licensed User
Longtime User
With startvideo sub I can start recording of the video but there is no stop video command. How to stop the vide recording ?
From the first part of startvideo I get
Failed to set camera mode: The command is not supported by the current firmware version.(255)
And from the second sometimes I get "Aircraft is recording!!!" and other time the same error.
 

derez

Expert
Licensed User
Longtime User
Yes, that's right. At the moment, photo works, but video doesn't with my mini 2. It seems, that there exists dependencies, which need more testing. The code only works completly on the mavic...
How do I take a picture by code ? (not by waypoint.addaction - it does not work on the mini 2)
 
Last edited:

derez

Expert
Licensed User
Longtime User
I found this tutorial , https://developer.dji.com/mobile-sdk/documentation/ios-tutorials/index.html , including this, maybe you know how to deal with it. I think that the video does record but never closed so it is corruptd :
Next, add the following codes to the recordAction IBAction method as follows:

- (IBAction)recordAction:(id)sender {

DJICamera* camera = [self fetchCamera];
if (camera) {
WeakRef(target);
if (self.isRecording) {
[camera stopRecordVideoWithCompletion:^(NSError * _Nullable error) {
WeakReturn(target);
if (error) {
[target showAlertViewWithTitle:mad:"Stop Record Video Error" withMessage:error.description];
}
}];
}else
{
[camera startRecordVideoWithCompletion:^(NSError * _Nullable error) {
WeakReturn(target);
if (error) {
[target showAlertViewWithTitle:mad:"Start Record Video Error" withMessage:error.description];
}
}];
}
}
}
In the code above, we implement the startRecordVideoWithCompletion and stopRecordVideoWithCompletion methods of the DJICamera class based on the isRecording property value. And show an alertView when an error occurs.
 

schimanski

Well-Known Member
Licensed User
Longtime User
With startvideo sub I can start recording of the video but there is no stop video command. How to stop the vide recording ?
From the first part of startvideo I get

And from the second sometimes I get "Aircraft is recording!!!" and other time the same error.

To stop record video, use this code:
B4X:
Dim callback2 As Object= CameraInstance.CreateEventFromUI("dji.common.util.CommonCallbacks$CompletionCallback", "recordcallback", Null)
CameraInstance.RunMethod("stopRecordVideo", Array(callback2))
Wait For (CameraInstance) recordcallback_Event (MethodName As String, Args() As Object)
If Args(0) = Null Then
  Log("Stop Recording")
Else
  Log("Failed to stop recording: " & Args(0))
End If
After that, a new start should not fail.

To make a photo, you have to use this code:
B4X:
If CameraInstance.IsInitialized Then
  Dim callback As Object = CameraInstance.CreateEventFromUI("dji.common.util.CommonCallbacks$CompletionCallback", "setmodecallback", Null)
  CameraInstance.RunMethod("setMode", Array("SHOOT_PHOTO", callback))

  Wait For (CameraInstance) setmodecallback_Event (MethodName As String, Args() As Object)
  If Args(0) = Null Then
    Log("Camera mode set to SHOOT_PHOTO")
  Else
    Log("Failed to set camera mode:" & Args(0))
  End If
  Sleep(0)
 
  Dim callback2 As Object= CameraInstance.CreateEventFromUI("dji.common.util.CommonCallbacks$CompletionCallback", "photocallback", Null)
  CameraInstance.RunMethod("startShootPhoto", Array(callback2))
 
  Wait For (CameraInstance) photocallback_Event (MethodName As String, Args() As Object)
  If Args(0) = Null Then
    Log("Shot photo!")
  Else
    Log("Failed to shoot photo: " & Args(0))
  End If
 
End If

I don't know, why it doesn't work all the time. Try to use another mode and see here:

https://developer.dji.com/api-refer...html#djicamera_djicamerashootphotomode_inline

There are the following modes available. You have to try some other mode.
Perhaps there is one mode, which works better with the mini 2:
SINGLESets the camera to take a single photo.
HDRSets the camera to take an HDR photo. X5 camera, X5R camera, XT camera, Z30 camera, Phantom 4 Pro camera, X4S camera and X5S camera do not support HDR mode.
BURSTSet the camera to take multiple photos at once. XT camera does not support Burst mode.
AEBAutomatic Exposure Bracketing (AEB) capture. In this mode you can quickly take multiple shots (the default is 3) at different exposures without having to manually change any settings between frames. XT camera and Z30 camera does not support AEB mode.
INTERVALSets the camera to take a picture (or multiple pictures) continuously at a set time interval. The minimum interval for JPEG format of any quality is 2s. For all cameras except X4S, X5S and Phantom 4 Pro camera: The minimum interval for RAW or RAW+JPEG format is 10s. For the X4S, X5S and Phantom 4 Pro cameras the minimum interval for RAW or RAW+JPEG dformat is 5s.
TIME_LAPSESets the camera to take a picture (or multiple pictures) continuously at a set time interval. The camera will merge the photo sequence and the output is a video. The minimum interval for Video only format is 1 s. The minimum interval for Video+Photo format is 2 s. For the new Osmo firmware version, no video feed will be received if the camera is shooting photos with Time-lapse mode. Instead, user can receive a sequence of preview images using the delegate method onGenerate. Supported only by Osmo camera (Z3 and X3).
PANORAMAIn panorama mode, the aircraft takes a series of photos with different gimbal and aircraft heading positions. The photos can be stitched with a third-party library. It is supported by Spark, Mavic Air, Mavic 2, Mavic 2 Pro, Mavic 2 Zoom, Mavic 2 Eneterprise, Mavic 2 Enterprise Dual.
EHDRSets the camera to take an enhanced-HDR photo. It blends a sequence of photos for ghost-free high dynamic range photos. It is supported by Mavic 2 Zoom and Mavic 2 Pro.
HYPER_LIGHTSets the camera to take photos in HyperLight mode. It is a setting for low-light environment to enhance the photo quality while reducing noise significantly. It is supported by Mavic 2 Zoom and Mavic 2 Pro.
HIGH_RESOLUTIONIndicates that the photo was taken in high resolution mode(48 MP 8000×6000 pixel). Supported by Mavic Air 2.
RAW_BURSTSets the camera to take a burst of RAW photos. Use getRAWPhotoBurstCount to check how many photos have been shot. Only supported by X5S.
SHALLOW_FOCUSSets the camera to take a series of photos while the aircraft moves up and down automatically. The image's depth of field can be computed with a third-party library to produce a photo with the bokeh effect. Note:
1. It is only suitable for shooting still scenes.
2. The aircraft will ascend about 20cm before shooting. Ensure that there is no obstacle about the aircraft.
3. The suitable range of shooting is within 30m.
It is only supported by Spark.
UNKNOWNThe shoot photo mode is unknown.
 
Last edited:

derez

Expert
Licensed User
Longtime User
All the following worked yesterday, today no photos are taken at all !
With this error: "Failed to set camera mode: The command is not supported by the current firmware version.(255)"
Problem solved, see #37

I attach here a modified version of schimanski's posted code in #22.
I added the following :
1. flying waypoints plan of several waypoint which are added on the map. Flight is performed by the waypoints order until the last, where the VS mode stops.
2. Selection of map types - normal, satelites and terrain.
3. showing important data bellow and under the camera's view , including heading, bearing and range to the user's point.
4. A button to shoot photo during flight.
5. Taking photos automatically during mission flight every 3 seconds.
6. selection of auto photo or auto video during mission, however video does not work 🙁
7. Go Home - the function on the controller works well, no need for a button on the screen.
8. Setting the mission parameters on a setup panel and saving them for next activation. The altitude for waypoints, hotspot and followme were united to one parameter but this is not a limitation since it can be changed easily before changing of the mission.
9. A violet marker shows the drone's position on the map during the mission.

Not working still is the video (probably on mini2 only) and automatic setting of the gimbal. the camera gimbal works manually from the controller. I left commented lines for where and how it should be set for the various missions.
I'll be glad to hear your comments.
The pictures show the screens and a series of photos taken in a followme mission. The designer variant is set for my Pixel4a so it may require adaptations to other devices (sorry...).
Don't forget to insert your codes for dji developer and google map.
 

Attachments

  • Virtual_stick.zip
    21 KB · Views: 126
  • cam.png
    cam.png
    451.9 KB · Views: 129
  • setup.png
    setup.png
    255.6 KB · Views: 123
  • DJI_0362.JPG
    DJI_0362.JPG
    77.7 KB · Views: 125
  • DJI_0363.JPG
    DJI_0363.JPG
    77.9 KB · Views: 112
  • DJI_0364.JPG
    DJI_0364.JPG
    79 KB · Views: 112
  • DJI_0365.JPG
    DJI_0365.JPG
    83.4 KB · Views: 122
  • DJI_0366.JPG
    DJI_0366.JPG
    81.6 KB · Views: 118
  • DJI_0367.JPG
    DJI_0367.JPG
    79.2 KB · Views: 118
  • DJI_0368.JPG
    DJI_0368.JPG
    72.2 KB · Views: 108
  • DJI_0369.JPG
    DJI_0369.JPG
    69.7 KB · Views: 112
  • DJI_0370.JPG
    DJI_0370.JPG
    72.4 KB · Views: 116
Last edited:

PABLO2013

Well-Known Member
Licensed User
Longtime User
Greetings Derez, I'm not an expert , 6. - it could be due to the version of the sdk

I'll test your app over the weekend, thanks.
 

derez

Expert
Licensed User
Longtime User
An improved version of post #35:
The time between succesive photos is calculated for each mission for the worst case of vertical gimbal.
For Waypoints - each photo is advanced by half frame. For Hotpoint - advance of ~30 degrees, for Followme - 3 seconds.
Photo mode settings and shooting is split to two subs.
A red circle shows for 1 sec in the top right corner of the video view when a picture is (successfully) taken.
The problem of not shootin photos is solved.

Video is still not working and gimbal is still just manual.

Edit:
Updated version 6 atttached.
Setup panel re-arranged,
FollowMe altitude can be defined separately from mission altitude.
Added Bearing display as small triangle around the compass, showing direction from the drone to the control box.
"Stop Mission" button is removed since touching any of the two stick does it.
 

Attachments

  • vs6.png
    vs6.png
    250.4 KB · Views: 117
  • VirtualStick6.zip
    22.2 KB · Views: 120
Last edited:

derez

Expert
Licensed User
Longtime User
As video does not work on the mini 2 I think maybe to record the video which is displayed on the phone, to the phone.
Does anyone know how to get it from the videoview which shows the camera, or get it from the stream coming down from the drone?
 
Last edited:
Top