first of all i know that what i am doing is out of the scope for the intended ardupilot use.
I basically want to program a LUA script that includes RC-Failsafe functionality with defined servo positions. (Details what i want to do at the end, as well as an example LUA code)
I have a servo set to function 57 (RCIN7) to just output the input 7 from the rc receiver.
I am using a LUA script to detect a failsave event. ( rc:has_valid_input() )
I this happens to be false for more than 1.5 seconds, i want the servo to get to a defined PWM value → Failsave functionality like we know from classic rc systems.
I tried 3 options but none are working for my needs.
local elevator_channel = SRV_Channels:find_channel(57)
SRV_Channels:set_output_pwm_chan_timeout(elevator_channel, 1700, 300)
this does not work. There is no error message, but it just does not do anything. Same problem when using the RCIN7_scaled (146) function instead of 57.
if i change the servo to an autopilot actuated servo function like 21 (Rudder) it works immediately. BUT i don’t want to have any commands comming in from the autopilot. → not working for my case
local RC7 = rc:get_channel(7)
This basically works like i need it. It “simulates” a different incomming rc channel value and changes the servo to the desired position.
The problem is that the rc:has_valid_input() function sees this as a valid rc input. → Lua Failsafe off → Servo goes to last position → still no real RC-input → Lua Failsafe on … just a loop and NOT staying at the desired FS position while no RC signal is comming.
Can i somehow + reliable access the REAL Failsafe state from the RC input?
(even the native ardupilot failsafe function does not realize this input is not really from RC receiver. However this might be by design and as intended for other usecases.)
Possible other ideas i did not try yet but it should work:
I could have the servos each on a scripting funtion (94-109) and forward the inputs to the servo via the lua script all the time but if a failsafe event happens.
BUT I’m hessitant to have all functions controlled only via a LUA script all the time. I’m not sure about the speed, and especially reliability.
Is it simpler + more reliable to make an ardupilot C-code change that forwards all RCIN values to the scripting servo functions (94-109) if there is no failsafe state? (and failsafe values if there is a failsafe state?)
Thank you so much for helping me!
What i want to achieve:
I want to have my multi flaped model using an ELRS RC system and an ardupilot for logging.
The complex mixing of these wings is theoretically possible by using an axtensive LUA script or heavily modifying the C-Code.
On the other hand last minute servo modifications are easier done on the transmitter during a competition.
→ Mixing is done in Transmitter
Then the data is sent up via ELRS 3.
I want to use an ardupilot FC to log all position and attitude data for later evaluation of the aircraft performance. (+ GPS, airspeed,…)
Since it is already there it makes sense to use it as a converter for ELRS to Servo PWM as well + all autopilot functions and telemetry are available to play around outside of competitions.
Everything works like i hoped but the failsafe functionality.
exemplary LUA code: yes i can reduce some lines.
-- start LUA script and send start message to GCS gcs:send_text(5, 'LUA: Failsave script started') -- initialize all used variables local elevator_channel = SRV_Channels:find_channel(57) local rudder_channel = SRV_Channels:find_channel(21) local lost_signal_time = 0 local current_time = 0 local time_difference = 0 local RC7 = rc:get_channel(7) -- function update that does all the failsave action function update() -- check if the RC has a valid input if rc:has_valid_input() then -- if valid signal: do nothing except set the variable to zero -- this variable saves the last time the rc input was not valid lost_signal_time = 0 else -- if the input is not valid = no signal from RC if lost_signal_time == 0 then -- save the first time when no signal was comming in lost_signal_time = millis() end -- get current time current_time = millis() -- calculate the time differrence from initial lost contact to now time_difference = current_time - lost_signal_time if time_difference >= 1500 then -- if this time difference is bigger than 1.5 seconds go into failsave condition gcs:send_text(5, 'LUA: NOT a valid rc input. set failsave position') -- Set the rudder channel to a fixed pwm. This is with servo function 21 Example 2) -> works SRV_Channels:set_output_pwm_chan_timeout(rudder_channel, 1700, 300) -- Set the elevator channel to a fixed pwm. This is with servo function 57 or 146 Example 1) -> Does NOT work!!! SRV_Channels:set_output_pwm_chan_timeout(elevator_channel, 1700, 300) -- Optional test. This works, but oscillates between failsafe state and non-failsafe state. Example 3) -- RC7:set_override(1200) end end -- Repeat function every 200ms. This is more frequent than the timeout -> As long as rc input is invalid, the pwm outputs should stay in FS position. return update, 200 end -- start function update return update()