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()