Leak detection with ArduRover on BlueBoat

Hello folks! We’ve received some requests to support leak detection on the BlueBoat, and now have a solution!
Simply copy the leak.lua file into the directory shown in the screenshot below, with the BlueOS File Browser. Once you restart the autopilot or reboot the vehicle, you’ll be all set! The SCR_ENABLE parameter needs to be set to LuaScripts as well - this is its default value in the BlueBoat parameters.
leak.lua (199 Bytes)

If an SOS leak sensor connected to the Navigator gets wet and closes the circuit, you’ll get a warning in QGround Control or Cockpit.

We’ll be rolling this into BlueOS to make it easier to select and use in the future!

Works charmingly! Thanks Tony!

Is the script only sending the Leak Detected event? or is it also adding any mission hold or other actions?

Hi @iSENSYS -
The script only sends the message to the alert console. You could easily modify it to add actions! You can see some examples of how to do this in the script from this thread - loiter mode may be better than hold, as better to stay put then drift away?

For what it’s worth, there’s an open Issue about adding leak sensor failsafe support to ArduRover, which is likely the preferred solution for longer term, and can make use of the existing AP_LeakDetector library code instead of having to re-implement that as well as the failsafe behaviour in a Lua script.

Agreed that this is a valuable feature.

Eliot - bingo! Was hoping for the re-implementation…

Tony - I’ll play around and add it for Loiter (yea, they should just remove HOLD).

Haha, fair enough - I did take a look (as mentioned in the Issue comments), but it was a bit more comprehension work than I have time for at the moment. If it had been a direct transfer then I would have just made the pull request, but alas, we’ve got some structure catchups to do for Sub before such transfers are so straightforward.

I did some poking around ArduRover parameters and couldn’t find the leak alert setting. Has this been implemented?

Hi @gcelec,

It’s not released, but it is in progress (under review).

I believe at this point it just needs a rebase and some testing. I’ll see if I can push for it to be included in 4.7 before the stable release.

Thanks @EliotBR,

Is there any way to implement it manually?

Hmm, as a one-off hardware-specific approach, it could potentially be implemented via a Lua script?

Here’s a bare-bones example (which I’ve just confirmed works):

-- Leak detection/failsafe functionality for the Navigator
-- Useful for custom behaviour and/or when not running ArduSub

local navigator_leak_pin = 27
gpio:pinMode(navigator_leak_pin,0)  -- configure as a digital input

local active_leak = false

-- define the loop
function update()
    if gpio:read(navigator_leak_pin) then
        gcs:send_text(2, "Leak detected!")  -- critical level announcement
        -- change modes, disarm, or whatever extra behaviour you want
    end

    return update, 1000  -- repeat after 1s
end

-- start the loop (immediately)
return update()

And here’s a more involved one for the BlueBoat specifically (which I’ve just lightly tested):

-- Leak detection/failsafe functionality for the Navigator
-- Intended for use with ArduRover (e.g. on a BlueBoat)

---- USER CONFIG ----
local warning_interval_ms = uint32_t(15000)  -- warn every 15s

-- specify 1-2 failsafe modes for desired behaviour
RoverMode = {
    Hold = 4,
    Loiter = 5,
    RTL = 11,
    SmartRTL = 12,
}
local failsafe_mode = {RoverMode.Loiter, RoverMode.Hold}  -- try to loiter, otherwise hold
---------------------

-- perform setup
local navigator_leak_pin = 27
gpio:pinMode(navigator_leak_pin,0)  -- configure as a digital input
local warning_last_sent = uint32_t()

-- define the loop
function update()
    if gpio:read(navigator_leak_pin) then
        -- warn the operator, if they haven't been warned recently
        if millis() - warning_last_sent > warning_interval_ms then
            gcs:send_text(2, "Leak detected!")  -- critical level announcement
            warning_last_sent = millis()
        end
        -- change mode, with an optional fallback
        local current_mode = vehicle:get_mode()
        if (
          current_mode ~= failsafe_mode[1] and current_mode ~= failsafe_mode[2]  -- not already changed
          and not vehicle:set_mode(failsafe_mode[1])  -- AND first change doesn't work
          and failsafe_mode[2]  -- AND backup mode provided
        ) then
            vehicle:set_mode(failsafe_mode[2])
        end
    end

    return update, 1000  -- check again after 1s
end

-- start the loop (immediately)
return update()