Adding parameters via scripting

Did you know that you can fairly easily add your own parameters to ArduPilot?!

It’s actually a fairly well documented yet seldom used feature that I just discovered myself after some excellent discussions with the dev team.

As described in the wiki (linked above), parameters added by scripting must be explicitly initialized on each boot cycle by a script, otherwise, they will not be made available for script access or editing across a MAVLink connection.

What’s very cool is that the values will be retained in EEPROM even if a script has not activated them, so you have a non-volatile, unambiguous mechanism to store and retrieve script data at will, and your scripts can interact with these values just like any other parameter. You are not always bound to use the SCR_USERx parameter set!

The wiki covers things reasonably well, but I can understand a little bit of confusion when it comes to implementing custom parameters in your own scripts. To ease the pain, I’ve written a function that takes care of it somewhat cleanly. Here’s a snippet from my rover-TerrainDetector.lua script that will likely be merged with libraries/AP_Scripting/examples in the near future:

local PARAM_TABLE_KEY = 117  -- unique index value between 0 and 200

-- create custom parameter set
local function add_params(key, prefix, tbl)
    assert(param:add_table(key, prefix, #tbl), string.format('Could not add %s param table.', prefix))
    for num = 1, #tbl do
        assert(param:add_param(key, num,  tbl[num][1], tbl[num][2]), string.format('Could not add %s%s.', prefix, tbl[num][1]))

-- edit this function call to suit your use case
add_params(PARAM_TABLE_KEY, 'ROUGH_', {
    --  { name, default value },
        { 'SPEED',        0.7 },
        { 'GZ_MAX',      1.33 },
        { 'RATE_MAX',      28 },
        { 'GZ_GAIN',      0.9 },
        { 'RATE_GAIN',    0.8 },
        { 'TIMEOUT_MS',  7500 }

This snippet adds ROUGH_SPEED, ROUGH_GZ_MAX, etc parameters for access by any active script and allows a user to tune script behavior without editing the script or restarting the scripting engine.

It’s important to note that the default value for each parameter must be specified during script initialization, regardless of whether that parameter already exists in EEPROM, but the value WILL NOT be overwritten by the specified default if the parameter already exists (again, a non-volatile mechanism).

I hope that’s helpful!


This is really nice.

1 Like

Hellow, i am new to lua scripting!
First of all thank’s for this example, i tried the example on github but i had an error, yours example works great!
I just want to ask @Yuri_Rage how can i read the value of a new parameter for example(ROUGH_SPEED) in the “QUICK” tab, is it possible?
Thank you for your time!

gcs:send_named_float() is what you’re looking for.

Thank you very much for that tip @Yuri_Rage

I will attach also an example that i found in examples in github, i hope to help someone else!

Thanks for all of your scripting discussions @Yuri_Rage . I’m hoping to learn more about this soon, and have in mind a particular application for a script. Based on your post I would imagine it would work, but would it be possible to “swap” parameters based on a script trigger? I have a copter that I can fly on 3 or 4S, but when switching between those batteries, naturally I need to change some parameters. Do you know if this would be a viable use for a script?

Certainly possible. Just need to establish said trigger as something available within the scripting bindings.

Good news! Thank you. I’ll start doing some reading up in the wiki on this.