iOS How to write code to let the drone fly with a pre-defined journey


#1

Hi,
I want to build an app that user can define a journey, then let the drone fly following that. For example, a journey as:
Take off -> Move forward for 5 seconds -> Landing
I already wrote code successfully for this simple journey as below, but the code is not good for reuse and customizes the journey. The function that starts the journey is “startJourney”.

- (void)startJourney {
    
    // 1: take off
    [self takeoff];
    
    double delayInSeconds = 1.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        // 2: start move forward
        [self startMoveForward];
        
        double delayInSeconds = 5.0;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            // 3: stop move forward
            [self stopMoveForward];
            
            double delayInSeconds = 1.0;
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
            dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
                // 4: landing
                [self land];
            });
        });
    });
}

#pragma mark - Build single commands

- (void)takeoff {
    NSLog(@"%@", @"Call takeoff");
    eARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE state = [_miniDrone flyingState];
    if (state ==  ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_LANDED) {
        [_miniDrone takeOff];
    }
}

- (void)land {
    NSLog(@"%@", @"==== Call land");
    eARCOMMANDS_MINIDRONE_PILOTINGSTATE_FLYINGSTATECHANGED_STATE state = [_miniDrone flyingState];
    NSLog(@"state %d", state);
    if (state == ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_FLYING
        || state == ARCOMMANDS_ARDRONE3_PILOTINGSTATE_FLYINGSTATECHANGED_STATE_HOVERING) {
        NSLog(@"%@", @"Land");
        [_miniDrone land];
    } else {
        NSLog(@"%@", @"Not land");
    }
    
}

- (void)startMoveForward {
    [_miniDrone setFlag:1];
    [_miniDrone setPitch:50];
}

- (void)stopMoveForward {
    [_miniDrone setFlag:0];
    [_miniDrone setPitch:0];
}

- (void)startMoveBackward {
    [_miniDrone setFlag:1];
    [_miniDrone setPitch:-50];
}

- (void)stopMoveBackward {
    [_miniDrone setFlag:0];
    [_miniDrone setPitch:0];
}

I want to re-write the code of the function “startJourney” so that I can easily add or remove commands as “rollLeft”, “rollRight”, “flip”, “takePicture”. For current code, it’s not good as it use ‘dispatch_after’ block, and commands are written nested.

Please help or give me some idea. Thank you.


#2

Hi, now I write the code like this. I think it’s ok

- (void)startJourney {
    dispatch_queue_t command_queue = dispatch_queue_create("command_queue", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(command_queue, ^{
        NSLog(@"%@", @"== takeoff");
        [self takeoff];
        sleep(2);
    });
    
    dispatch_sync(command_queue, ^{
        NSLog(@"%@", @"== startGoForward");
        [self startGoForward];
        sleep(2);
        NSLog(@"%@", @"== stopGoForward");
        [self stopGoForward];
        sleep(1);
    });
    
    dispatch_sync(command_queue, ^{
        NSLog(@"%@", @"== land");
        [self land];
    });
}

Thanks