Struggle to set servo with lua

I upgraded to the latest MP beta and loaded ardurover 4.1 dev on my Pixhawk 2.4.8. Ambition is to test Lua scripts. For now using REPL to get the syntax right.

My boat has dual motors, skid steerer (ch 1 and 3). And in addition remote controlled switches for lights (ch 2), a Kogger transducer (ch 4), a battery backup (ch 5) and a Raymarine fish finder (ch 6). Plus two servos controlling dual bait trays (ch 9 and 10). Everything works, using a flysky remote, Mission Planner or my own Carp Pilot app.

I want to create some new abilities and decided to test out Lua scripts. As a start I would like my lights to blink to give a visual indication when I open my bait trays.

The problem is that I cannot get the remote control switches nor the bait trays to respond to the Lua commands. The only thing I am successful at is getting motors to spin (also when boat is not armed) using:
SRV_Channels:set_output_pwm_chan_timeout(channel - 1, pwm value, timeout in ms)

Motors spinning: No problem at all. But using similar commands for the switches or the Servos gives no result (also no error in REPL).
As stated, all switches and Servos work fine using the remote. And also works perfect using the set servo abilities in Mission Planner and Carp Pilot.

Reading through the bindings I cannot find other abilities available for Lua than SRV_Channels. Either I have misunderstood something, or the abilities matching the set servo in MP are not (yet?) available for Lua.

Anyone that have some ideas?

You might want to set up the script to read the switch PWM and have the script do both actions of flash lights and move the servos. Your syntax for set_output_pwm_chan_timeout is correct. What happens if you run the script in SITL?

Thanks, Charlie!

Script now running and displaying messages. Added a ā€œhello worldā€ as well.

The end result is identical to REPL, script is sadly NOT able to turn my switches on or off, neither to control my servos as far as I can see. I simplified my code and tried the SRV_Channels:set_output_pwm(servo function, pwm) instead. But to no helpā€¦

The switches I use are of the type GT Power Switch. These passes through power if the PWM level rise slightly above 1500, and cuts the power if PWM level drops slightly below 1500. As stated, these work as expected using transmitter switches or gimbals. And work equally well when using set servo in MP or Carp Pilot. But not with the LUA script options as far as I can see.

To debug I added some additional text to see that the correct part of my script actually runs as expected. And when I now use my remote and open the left bait tray (function 59 according my settings, aka the rc in of channel 9) I get the desired text outcome in Mission Planner ā€œMessagesā€ tab:

29.12.2020 08.30.46 : LUA: Left bait tray open, lights on
29.12.2020 08.30.46 : LUA: Left bait tray open, lights off
29.12.2020 08.30.46 : LUA: Left bait tray open, lights on
29.12.2020 08.30.46 : LUA: Left bait tray open, lights off
29.12.2020 08.30.45 : LUA: Left bait tray open, lights on
29.12.2020 08.30.45 : LUA: Left bait tray open, lights off
29.12.2020 08.30.38 : hello, world
29.12.2020 08.30.28 : hello, world

So the script runs, and the logic works, but lights does not respond. Hereā€™s my current script:

-- Specify boat servo functions
local lights = 52
local kogger = 54
local battery = 55
local raymarine = 56
local left_bait = 59
local rigth_bait = 60

-- Additional variables
local first_run = true
local lights_on = true

function update() -- this is the loop which periodically runs
  if first_run then
    gcs:send_text(0, "LUA: My blinking lights script just started...")
    first_run = false
  end
  if SRV_Channels:get_output_pwm(left_bait) < 1500 then
    if  lights_on then
      SRV_Channels:set_output_pwm(lights,2000)
      gcs:send_text(0, "LUA: Left bait tray open, lights on")
      lights_on = false
    else
      SRV_Channels:set_output_pwm(lights,1024)
      gcs:send_text(0, "LUA: Left bait tray open, lights off")
      lights_on = true
    end
  end
  if SRV_Channels:get_output_pwm(rigth_bait) > 1500 then
    if  lights_on then
      SRV_Channels:set_output_pwm(lights,2000)
      gcs:send_text(0, "LUA: Right bait tray open, lights on")
      lights_on = false
    else
      SRV_Channels:set_output_pwm(lights,1024)
      gcs:send_text(0, "LUA: Right bait tray open, lights off")
      lights_on = true
    end
  end
  return update, 250
end

return update()

Hit a dead end here I am afraid.

1 Like

I observe that the function ā€œSRV_Channels:get_output_pwm(function)ā€ retrieves the output correctly not only when using the remote control but also when a servo is set by the MP Servo/Relay panel.

The only thing missing for this to work is then probably:

  • LUA support for mavlink command: mav_cmd_do_set_servo

How do I go about to achieve this? I have a vague understanding that there is a need for an update of LUA ā€œbindingsā€, but I never built a custom fw version for ArduPilot before. Any tips?

Your trying to set the pwm for the lights with function 52 this is RC2 passthroguh so its getting constantly over written by the main code for is pass-through functionality. For this reason we have dedicated scripting output functions. 94 - 109.

You script as above should have local lights = 94 then set the SERVOx_FUNCTION to 94 for the channel your trying to control.

No promise it will then work perfectly, I have not tested but that issue jumped out at me.

Thanks!
Your assumptions were spot on. Updated the function for my lights servo, verified with REPL and then updated the script to use function 94 for the lights instead.

And this works very well, so the script does its job. With one big caveat:
It is no longer possible to use the remote to turn these lights on or off. I might not have thought it fully through. Perhaps I could add a servo Y connector and connect an additional servo output for the purpose. It would only work if the lights were not turned on initially of courseā€¦

I assume it is still possible to override with set_servo from a GCS, but Mission Planner that I currently use for these tests does not offer the set servo for channels below 5. Anyway, the desired solution is still to have a fully operational remote (even though I hardly use it).

I guess the set_servo is perhaps a feature dedicated for GCSā€™ to override the regular controls. Is it technically possible to offer this ability within LUA?

I wouldnā€™t Y 2 servo outputs together. That will only make the PWM signals extra funky.

I believe what you are looking for is rc:get_pwm() for your if statements. Then set the servo outputs for the lights and bait traps. Youā€™re essentially doing your own RC mixing in the script.

Using a GCS or other means for set_servo for the AETRF channels is why I wrote set_output_pwm_chan_timeout. Also it adds a nice set-and-forget feature.

Great, and thanks again.

Utilizing ā€˜rc:get_pwmā€™ to ā€œlistenā€ for my remote switch and then turning lights permanent on or off using ā€˜SRV_Channels:set_output_pwmā€™ solves the remote control issue. Just combining it with having the lights blink ā€œlisteningā€ to my bait trays with ā€˜SRV_Channels:get_output_pwmā€™ and then blinking the same lights with ā€˜SRV_Channels:set_output_pwm_chan_timeoutā€™.

Script grew slightly in complexity due to the lack on an override ability. But this was fun. Highly appreciate the help from @iampete and @TunaLobster, thanks guys :slightly_smiling_face:

2 Likes