Hope someone can help me with a lua scripting problem.
I am running ardurover V4.6.0 on a Holybro kakute H7, i have a 32gb SD card inserted in the slot. What I want to achieve is that the RC5 stick when pushed to the left the LH servo must swing to drop bait from boat, the same for the RHS. when pushing stick left RH servo must not move and when pushing stick to right LH servo should not move.
I have enabled lua scripting and i am able to succesfully write baitdrop left, bait drop right in the messages in missionplanner but it seems like the script cant control the servo outputs for some reason. if i go to servo outputs tab there is no movement when i set the servos to run from script1. if i map the servos directly to the rc channel it works and servos move.
What am I missing? I am very new to this so it might be a simple fix.
I confirmed wiring as it works when set directly to rc5
LUA is working as it gives correct (expected messages).
Here is the code I use:
– Independent bait drop control from RC channel 4 (rudder)
– Left servo on SERVO3, Right servo on SERVO6
– Set SERVO3_FUNCTION = 94, SERVO6_FUNCTION = 94
– Requires: SCR_ENABLE = 1
local left_dropped = false
local right_dropped = false
function update()
local rc4 = RC:channel(4) -- RC4 input (rudder)
if rc4 == nil then
gcs:send_text(6, "RC4 is nil")
return update, 100
end
local pwm = rc4:pwm()
-- Drop left bait if rudder pushed left
if pwm < 1300 and not left_dropped then
SRV_Channels:set_output_pwm(3, 2000) -- Extend left servo
gcs:send_text(6, "Left bait dropped")
left_dropped = true
elseif pwm >= 1300 and left_dropped then
SRV_Channels:set_output_pwm(3, 1000) -- Retract left servo
left_dropped = false
end
-- Drop right bait if rudder pushed right
if pwm > 1700 and not right_dropped then
SRV_Channels:set_output_pwm(6, 2000) -- Extend right servo
gcs:send_text(6, "Right bait dropped")
right_dropped = true
elseif pwm <= 1700 and right_dropped then
SRV_Channels:set_output_pwm(6, 1000) -- Retract right servo
right_dropped = false
end
return update, 100 -- Repeat every 100 ms
Due to the fact that i use LUA script to drop the LH and RH bait buckets (I have to control via LUA because i use a single throttle stick on remote to drop both, one when stick is left the other when stick is right).
What I need is when there is a RTL condition triggered the first step must be both bait buckets must drop before the RTL starts (I managed to get this working).
Secondly I must be able to manually drop both buckets independently (This is also working fine from LUA script).
The third function I need is to be able to plan a drop at a certain point when sending the boat on a mission. I started by using the DO_SET_SERVO command but if failed to trigger the drop due to the fact that the servos is controlled by the script and commands is not recognised (Or so I assume). I now tried adding virtual pins via relay 1 and 2 to the script so I can use DO_SET_RELAY in planning and trigger the drop as such but I am failing to accomplish this. Is there an easier way to achieve this?
I will attach my script for more information.
-- RC4 stick + RTL + DO_SET_RELAY (via PWM) bait dropper
local left_dropped = false
local right_dropped = false
local rtl_dropped = false
local last_mode = -1
local relay1_last_pwm = 0
local relay2_last_pwm = 0
function update()
local pwm = rc:get_pwm(4)
if pwm == nil then
gcs:send_text(6, "RC4 not available")
return update, 100
end
local mode = vehicle:get_mode()
-- === Auto RTL Drop ===
if mode == 11 and last_mode ~= 11 and not rtl_dropped then
SRV_Channels:set_output_pwm(95, 1000)
SRV_Channels:set_output_pwm(94, 1000)
gcs:send_text(6, "Auto RTL: Dropped both bait buckets")
rtl_dropped = true
elseif mode ~= 11 then
rtl_dropped = false
end
last_mode = mode
-- === Manual RC Stick Drop ===
if pwm < 1300 and not left_dropped then
SRV_Channels:set_output_pwm(95, 1000)
gcs:send_text(6, "Manual: Left bait dropped")
left_dropped = true
elseif pwm >= 1300 and left_dropped then
SRV_Channels:set_output_pwm(95, 1500)
left_dropped = false
end
if pwm > 1700 and not right_dropped then
SRV_Channels:set_output_pwm(94, 1000)
gcs:send_text(6, "Manual: Right bait dropped")
right_dropped = true
elseif pwm <= 1700 and right_dropped then
SRV_Channels:set_output_pwm(94, 1500)
right_dropped = false
end
-- === Mission DO_SET_RELAY (via PWM detection) ===
local pwm_relay1 = SRV_Channels:get_output_pwm(9)
Relay 0
local pwm_relay2 = SRV_Channels:get_output_pwm(10)
if pwm_relay1 ~= nil and pwm_relay1 > 1800 and relay1_last_pwm <= 1800 then
SRV_Channels:set_output_pwm(95, 1000)
gcs:send_text(6, "Mission: Left bait dropped")
end
relay1_last_pwm = pwm_relay1 or relay1_last_pwm
if pwm_relay2 ~= nil and pwm_relay2 > 1800 and relay2_last_pwm <= 1800 then
SRV_Channels:set_output_pwm(94, 1000)
gcs:send_text(6, "Mission: Right bait dropped")
end
relay2_last_pwm = pwm_relay2 or relay2_last_pwm
return update, 100
end
return update()
Thanks for the info, I wrote a seperate LUA script for the dropping when on a mission. I cant get the mission to enter the scrypt as it goes into the mission but does not display the set messages and also dont activate the servos.
I think I am setting up the program incorrectly, see screenshot of plan.
-- Mission-only bait dropper, triggered via DO_SEND_SCRIPT_MESSAGE
function handle_script_message(cmd_id)
if cmd_id == 101 then
SRV_Channels:set_output_pwm(95, 1000) -- Left drop
gcs:send_text(6, "Mission: Left bait dropped")
elseif cmd_id == 102 then
SRV_Channels:set_output_pwm(94, 1000) -- Right drop
gcs:send_text(6, "Mission: Right bait dropped")
end
end
return nil, handle_script_message
I also kept the original manual drop and rtl drop as a seperate scipt if that makes any difference.
-- RC4 Stick-controlled + Auto drop on RTL (mode 11)
local left_dropped = false
local right_dropped = false
local rtl_dropped = false
local last_mode = -1
function update()
local pwm = rc:get_pwm(4)
if pwm == nil then
gcs:send_text(6, "RC4 not available")
return update, 100
end
local mode = vehicle:get_mode()
-- Detect switch to RTL mode
if mode == 11 and last_mode ~= 11 and not rtl_dropped then
-- Drop both bait buckets before RTL action
SRV_Channels:set_output_pwm(95, 1000) -- Left drop
SRV_Channels:set_output_pwm(94, 1000) -- Right drop
gcs:send_text(6, "Auto RTL: Dropped both bait buckets")
rtl_dropped = true
elseif mode ~= 11 then
rtl_dropped = false
end
last_mode = mode
-- Manual Left bait drop (turn left)
if pwm < 1300 and not left_dropped then
SRV_Channels:set_output_pwm(95, 1000)
gcs:send_text(6, "Manual: Left bait dropped")
left_dropped = true
elseif pwm >= 1300 and left_dropped then
SRV_Channels:set_output_pwm(95, 1500)
left_dropped = false
end
-- Manual Right bait drop (turn right)
if pwm > 1700 and not right_dropped then
SRV_Channels:set_output_pwm(94, 1000)
gcs:send_text(6, "Manual: Right bait dropped")
right_dropped = true
elseif pwm <= 1700 and right_dropped then
SRV_Channels:set_output_pwm(94, 1500)
right_dropped = false
end
return update, 100
end
return update()
Thanks, is it possible to do them separate as when i combine them I screw up even the manual and rtl functions (maybe something I can do after I get it to actually work). Am I setting the script up correctly in missionplanner on the planning tab?
function update()
-- check for scripting DO commands in the mission
local time_ms, p1, p2, p3, p4 = mission_receive()
if time_ms then
gcs:send_text(6, string.format("Mission CMD: p1=%d", p1))
if p1 == 101 then
-- Drop left bait
SRV_Channels:set_output_pwm(95, 1000)
gcs:send_text(6, "Mission: Dropped LEFT bait")
elseif p1 == 102 then
-- Drop right bait
SRV_Channels:set_output_pwm(94, 1000)
gcs:send_text(6, "Mission: Dropped RIGHT bait")
end
end
return update, 100
end
return update()