Code to release glider at set altitude. Trigger relay pin?

As the title says, I have a glider I’d like to detach from a balloon. I’ve been messing around with APM codebase for a while, but this my first foray into the px4 flight stack, so bear with me.

After reading most of the dev.px4.io guide, it seems that the proper way to do this is as an app. I’ve been able to (I think) read in the global altitude, but now I’m left wondering how I should trigger the relay to release the glider.

I know from poking around drivers/camera_trigger that there has to be some relatively simple way to send a signal out a GPIO pin, but at the present I have no idea to do it.

I’ve found this thread which talks about setting the FMU mode. According to a link in that thread
mode_pwm_gpio – Enables SRV1-SRV4 and GPIO_EXT1 and GPIO_EXT2
So as I understand it, calling
fmu mode_pwm_gpio
will set the first the first four pins as regular PWM outputs, and the next two aux pins as gpio outputs. Of course I have no idea where one might go about calling this, so this has been a bit of a dead end as well.

So to summarize, how can I trigger a relay pin in an app?

__EXPORT int px4_balloon_control_main(int argc, char *argv[]);

int px4_balloon_control_main(int argc, char *argv[])
{
    PX4_INFO("Starting Balloon Controller.");

    // subscribe to global position to get altitude
    int vehicle_global_position_sub = orb_subscribe(ORB_ID(vehicle_global_position));
    struct vehicle_global_position_s _global_pos; // to store the global position

    bool _task_should_exit; // if true, the task should exit 

    // loops until the task should exit
    while (!_task_should_exit) {
        // get the new global position
        orb_check(vehicle_global_position_sub, &updated);
        if (updated) {
            /* copy global position */
            orb_copy(ORB_ID(vehicle_global_position), vehicle_global_position_sub, &_global_pos);
        }
        if (_global_pos.timestamp == 0) {
            continue;
        }

        // _global_pos.alt // the global altitude in meters. how do I get the relative alt from this?
    }

    // fmu mode_pwm_gpio
    // https://pixhawk.org/firmware/apps/fmu
    // set pins 1-4 as servos and 5 and 6 as relays?

    /*
    TODO:
     - Create a parameter to store the set the detach altitude
     - Disable servo output on startup? maybe just set the flight mode to manual to not waste power on ascent
     - If the vehicle is above this altitude for x consecutive seconds, turn on the relay pin for some amount of time
     - Change the flight mode to AUTO (re-enable servo output)
    */

    return 0;
}

Hi @ibrand, those are options passed to the fmu command at startup. Take a look at FMU modes in the init script (rcS) here - https://github.com/PX4/Firmware/blob/master/ROMFS/px4fmu_common/init.d/rcS#L553

camera_trigger is a good example to see writing to gpio - https://github.com/PX4/Firmware/blob/master/src/drivers/camera_trigger/interfaces/src/relay.cpp#L49

I hope you’ll have some interesting video to share!

@ibrand Glad to see someone else is trying to do similar tasks. Looks like @dagar answered most of your question. One thing I recently learned though, is that mode_pwm_gpio is only available for the fmu v1 hardware and not the v2 hardware. See: https://github.com/PX4/Firmware/blob/master/src/drivers/px4fmu/fmu.cpp#L2913

Not sure what you have, but for the v2 hardware you can have PWM or GPIO, but not both. Best of luck on your project!