Moving a servo depending on the flight mode

Hello, I built a VTOL tailsitter and am trying to use Q_WVANE with side into wind vtol modes. The problem is that I cannot get a heading since the gps is looking towards the sky so the heading is wrong or doesn’t really change.
What I want to do to correct this is to put the gps on a servo so that when the tailsitter transitions to VTOL the gps is still parallel to the ground thus giving a heading.
This is the code that I’ve written for this action:

local SERVO_CHANNEL = 9 – Canal utilisé par le servo
local PWM_VTOL = 1700 – Valeur PWM pour le mode VTOL (weathervaning actif)
local PWM_AVION = 1300 – Valeur PWM pour le mode avion

– Initialise le servo à la position avion
SRV_Channels:set_output_pwm(SERVO_CHANNEL, PWM_AVION)

function update_gps_mount()
local mode = vehicle:get_mode() – Récupère le mode de vol

if mode == nil then
    gcs:send_text(6, "Erreur: mode de vol non défini")
    return
end

-- Affiche le mode actuel
gcs:send_text(6, "Mode actuel: " .. tostring(mode))

if mode == 17 or mode == 19 then  -- QSTABILIZE = 17, QRTL = 19
    gcs:send_text(6, "Passage en VTOL, servo en position VTOL")
    -- Envoi PWM pour le mode VTOL
    SRV_Channels:set_output_pwm(SERVO_CHANNEL, PWM_VTOL)
elseif mode == 5 then  -- FBWA = 5
    gcs:send_text(6, "Passage en avion, servo en position avion")
    -- Envoi PWM pour le mode avion
    SRV_Channels:set_output_pwm(SERVO_CHANNEL, PWM_AVION)
else
    gcs:send_text(6, "Mode non pris en charge: " .. tostring(mode))
end

end

function update()
update_gps_mount()
return update, 100 – Réexécute toutes les 100 ms
end

gcs:send_text(6, “gps_mount.lua est en cours d’exécution”)
return update()

Note: the servo is not a control surface, it is not linked to any RC channel and SERVO_FUNCTION9 is set to 0. I tried to set it to script1 or other but without change. It’s like the servo isn’t getting any power, but when I toggle SERVO9 manually it moves just fine.

As I can see in the messages window the lua script runs just fine, it detects the flight mode correctly.

What I think is happening is happening is that the command SRV_Channels:set_output_pwm doesn’t work. I tried using the servo.set_output function which is what is recommended on the ardupilot documentation, but when I do it gives me this error:

x a nil value (global ‘servo’)
11/03/2025 00:51:24 : Lua: /APM/scripts/gps_mount.lua:6: attempt to inde

I am using a Matek H743 V3 running Arduplane 4.5.1 and I don’t understand why the ‘servo’ isn’t recognised.

Thank you for any help.

You might want to test this manually before you get too far because if you move the GPS relative to the flight controller you will get EKF errors.

1 Like

Heed @Allister’s advice.

But if you want to continue with this project, try SRV_Channels:set_output_pwm_chan (or SRV_Channels:set_output_pwm_chan_timeout if you have an RC channel assigned to the servo).

you would probably be better using 2 GPS receivers with one in each orientation, I think there is a blend mode that will smooth the transition between them.

This was a topic of discussion with the Aerobatic plane guy flying inverted. That was one suggestion.

Thank you for all your responses, I think that I will go with the 2 gps option and write a lua script to help prioritise everything.