Executing multiple Guided flights in a row

I am attempting to run multiple Guided flights in a row using the .moveByRelativeLocation(…) function

My first try was:

self.pilotItf?.moveToRelativePosition(..., downwardComponent: -3, ...)
self.pilotItf?.moveToRelativePosition(..., downwardComponent: 2, ...)
self.pilotItf?.moveToRelativePosition(..., downwardComponent: -3, ...)
self.pilotItf?.moveToRelativePosition(..., downwardComponent: 2, ...)

I thought this code would make the drone go up and down and up and down. In this case the downward components seemed to be summed causing the drone to only go up 2 meters in one motion.

I found this .currentDirective attribute which shows “Current guided flight directive if there’s a guided flight in progress, nil otherwise.” So I tried this:

self.pilotItf?.moveToRelativePosition(..., downwardComponent: -3, ...)
while self.pilotItf?.currentDirective != nil {}
self.pilotItf?.moveToRelativePosition(..., downwardComponent: 2, ...)
while self.pilotItf?.currentDirective != nil {}
self.pilotItf?.moveToRelativePosition(..., downwardComponent: -3, ...)
while self.pilotItf?.currentDirective != nil {}
self.pilotItf?.moveToRelativePosition(..., downwardComponent: 2, ...)

I thought the loop would run until the previous command completed, then continue to the next command. This was not the case, as it looped infinitely.

How can I execute Guided commands in sequence?

1 Like

Hi,

GuidedPilotingItf doesn’t store guided flights.
If moveToLocation or moveToRelativePosition are called while a guided flight is still in progress, the current guided flight will be stopped immediately and the new guided flight is started.

If the main thread is blocked, GroundSdk can’t work and can’t update its states.

To wait for a change of state on a piloting interface, you should use getPilotingItf(_:observer:).

Working code should be :

// Keep the reference to the interface :
private var guidedItfRef: Ref<GuidedPilotingItf>?
private var goUp: Bool
...
guidedItfRef = provider.getPilotingItf(PilotingItfs.guided) { [weak self] guidedItf in
	if let guidedItf = guidedItf, let self = self, guidedItf.currentDirective == nil {
		self.goUp = !self.goUp
		guidedItf.moveToRelativePosition(forwardComponent: 0, rightComponent: 0,
				downwardComponent: self.goUp ? 2.0 : -3.0 , headingRotation: 0)
	}
}

Regards,
Maxime

Hi Maxime,

Thanks for the response! Ultimately, I converged on a similar solution. I was wondering if i could ask a follow-up question. Currently this is my setup.

Note: Waypoint is just a struct that has lat/long/alt/orientation, for my own convenience.

My question is: I would like to take a photo after I stop at each point. I have the “mainCamera.startPhotoCapture()” This doesn’t seem to work. Any suggestions on this?

public func executeWaypointMission(mission: [Waypoint]?) {
        // Update local instance of mission. We need it stored locally as
        // we pass a reference to self into the piloting closure
        self.mission = mission
        
        self.guidedPilotingItf = self.drone?.getPilotingItf(PilotingItfs.guided) { [weak self] pilotingItf in
            
            // On each update of the piloting interface, determine whether the drone has completed previous mission
            if let pilotingItf = pilotingItf {
                if pilotingItf.currentDirective == nil && self?.mission != nil {
                    if self?.mission?.count ?? 0 > 0 {
                        let waypoint = (self!.mission?.removeFirst())!
                        
                        self!.mainCamera?.startPhotoCapture()
                        pilotingItf.moveToLocation(latitude: waypoint.latitude,
                                                   longitude: waypoint.longitude,
                                                   altitude: waypoint.altitude,
                                                   orientation: waypoint.orientation)
                    }
                }
            }
        }
    }

I do set up my camera in the following way, previous to the mission execution

self.mainCamera = drone?.getPeripheral(Peripherals.mainCamera)
self.mainCamera?.autoRecordSetting?.value = false
self.mainCamera?.photoSettings.mode = .single

This does execute the entire mission, but doesn’t take any photos

Hi,

Before to try to take a photo you can check if canStartPhotoCapture is true.
To be able to take a photo modeSetting mode must be set to photo.

Regards,
Maxime