Lua script - requesting recommandations

Hi,
I would appreciate some comments on what i have designed using lua script for drone excitation by commanding velocities. I have tested out this script and the drone flew nicely, but extremely slow. I have no experience in lua scripts nor Arducopter controller interface, but I am learning. Your help will prevent me to crash my drone.

I have re-written the script such that it fly faster and in a horizontal circular manner (sort of lissajou pattern). The script is shown below along with the list of hardware I am using to fly my drone. Who ever got knowledge in lua scripts, could you please give me some comments on what I coded in order to ensure that the maneuver is safe to be applied?

Hardware:
X500 V2 holybro
Pixhawk 6X
11 inch props
ESC Telemetery is used (AM60 Skystar)

Script:

-- copter-fly-lissajous-fast.lua
--
-- Increases Lissajous pattern frequency for faster horizontal speeds.
-- Vehicle will:
--   1) Wait for armed + RC6 > 1800
--   2) Switch to Guided
--   3) Take off to 15m
--   4) Once at altitude, fly a Lissajous pattern
--   5) Then switch to RTL after 'pattern_duration' seconds

local takeoff_alt_above_home = 15
local copter_guided_mode_num = 4
local copter_rtl_mode_num = 6

-- Lissajous parameters: increased freq for more speed
local freq_x    = 1.0     -- [Hz] horizontal frequency in X (was 0.5)
local freq_y    = 2.0     -- [Hz] horizontal frequency in Y (was 1.0)
local amp_x     = 3       -- [m] amplitude along X
local amp_y     = 3       -- [m] amplitude along Y
local phase_x   = 0
local phase_y   = 0

-- Fly the pattern for this many seconds before switching to RTL
local pattern_duration = 30  -- [s]

-- Script update rate: 0.1s (10 Hz)
local time_step = 0.1    

local stage  = 0
local time_s = 0

local yaw_cos = 0
local yaw_sin = 0

function update()
    if not arming:is_armed() then
        -- reset if disarmed
        stage  = 0
        time_s = 0
        return update, 100
    end

    local pwm6 = rc:get_pwm(6)
    if pwm6 and pwm6 > 1800 then
        if stage == 0 then
            -- Stage 0: switch to Guided mode
            if vehicle:set_mode(copter_guided_mode_num) then
                local yaw_rad = ahrs:get_yaw()
                yaw_cos = math.cos(yaw_rad)
                yaw_sin = math.sin(yaw_rad)
                stage = 1
                gcs:send_text(0, "Script: Switching to GUIDED")
            end

        elseif stage == 1 then
            -- Stage 1: take off to 15m
            if vehicle:start_takeoff(takeoff_alt_above_home) then
                stage = 2
                gcs:send_text(0, "Script: Takeoff initiated to 15m")
            end

        elseif stage == 2 then
            -- Stage 2: wait for altitude
            local home = ahrs:get_home()
            local curr_loc = ahrs:get_location()
            if home and curr_loc then
                local vec_from_home = home:get_distance_NED(curr_loc)
                local alt_above_home = -vec_from_home:z()  -- negative Z is up

                gcs:send_text(0, string.format("Current alt: %.1f / 15.0", alt_above_home))
                if math.abs(takeoff_alt_above_home - alt_above_home) < 1 then
                    stage = 3
                    gcs:send_text(0, "Script: Reached ~15m, starting fast Lissajous")
                end
            end

        elseif stage == 3 then
            -- Stage 3: Fly Lissajous pattern
            if time_s >= pattern_duration then
                stage = 4
            else
                time_s = time_s + time_step

                -- Derivatives for x(t)=amp_x*sin(freq_x*t + phase_x)
                local dx_local = amp_x * freq_x * math.cos(freq_x * time_s + phase_x)
                -- Derivatives for y(t)=amp_y*sin(freq_y*t + phase_y)
                local dy_local = amp_y * freq_y * math.cos(freq_y * time_s + phase_y)

                -- rotate local velocity by initial yaw
                local target_vel = Vector3f()
                target_vel:x(yaw_cos * dx_local - yaw_sin * dy_local)
                target_vel:y(yaw_sin * dx_local + yaw_cos * dy_local)
                target_vel:z(0)

                if not vehicle:set_target_velocity_NED(target_vel) then
                    gcs:send_text(0, "Script: Failed fast Lissajous velocity command")
                end
            end

        elseif stage == 4 then
            -- Stage 4: switch to RTL
            vehicle:set_mode(copter_rtl_mode_num)
            stage = 5
            gcs:send_text(0, "Script: Lissajous done → Switching to RTL")
        end
    end

    return update, 100  -- 0.1 seconds
end

return update()

no one got any recommendations how can i safely test it?

I can’t offer any help in the script, but you can test it in SITL. Load the simulator in Mission Planner and then you can load the script and run it just as you would on your drone.

I have never used SITL before from ardupilot. Ill give it a try by read the docs. Thank you for pointing it out

Hi again, so i had the chance to test on sitl and fly it in real life. Everything wen fine however, i am trying to achieve a higher speed maneuver.
Do you know what commands or functionality i shall code to control the speed using lua script?

Thank you in advance.

You could try

vehicle:set_desired_speed(param1)
1 Like