betaflight / betaflight-configurator

Cross platform configuration tool for the Betaflight firmware
GNU General Public License v3.0
2.52k stars 895 forks source link

Allow Preset Options to be conditional on Betaflight variables #2867

Closed MythicLionMan closed 5 months ago

MythicLionMan commented 2 years ago

Is your feature request related to a problem? Please describe

There is currently no way for one preset to affect another, or for an optional portion of a preset to affect a later portion.

Communicating Between Presets

Several presets require that the same information be entered in their configuration. This is error prone and complicates setup. For instance some presets setup a different configuration if DShot is enabled or not. If the user supplies the wrong information about the state of DShot on the drone then the preset will not be applied properly.

Likewise, if a preset includes another preset it's complicated to pass parameters from the first preset to the second. (I believe that there is a way to do this, but haven't figured out the syntax yet :-). If the first preset sets a variable it's very easy for the included preset to read it. This allows the included preset to be used as an include or on its own.

Communication Within A Preset

A single preset can also specify multiple options, but there is no (easy) way to combine these options. For example if I have a preset that optionally sets up a Crossfire receiver and that also optionally sets up failsafe options, I only want to set the Crossfire RSSI channel to hold on failsafe if I'm also setting up failsafe, since it's a failsafe option that is affected by my receiver type.

Describe the solution you'd like

Define a new 'OPTION' type: #$ VARIABLE_OPTION BEGIN: <variableName> <operator> <value>. Instead of creating a checkbox for the user to select, the option would be evaluated by comparing the value of an existing variable to the preset.

For example, the following will setup a GPS OSD if the GPS feature has been enabled elsewhere in this preset, in another preset, or manually by the user.

#$ VARIABLE_OPTION BEGIN: feature CONTAINS GPS
    set osd_gps_speed_pos = 2105
    # ... more variables
#$ VARIABLE_OPTION END

This will turn on per cell voltage reporting if the radio protocol is Crossfire since Crossfire telemetry doesn't have an option to report the cell voltage the way FrSky does.

#$ VARIABLE_OPTION BEGIN: serialrx_provider == CRSF
    set report_cell_voltage = ON
#$ VARIABLE_OPTION END

Operators may include:

Challenges

The biggest risk I see with this is that presets would need to be applied in order. For example, I have a personal preset that just does all of the setup I normally do on a quad, like enabling DSHOT, etc. If a tune preset was run after this preset it would pick up the DSHOT setting, but if it were run before it would not.

Presets could have an order enforced based on their category, or a dependency system could be run to detect presets that were testing variables that were modified by other presets and warn if things were set out of order. But both of those have limitations.

A simpler solution would be to show all of the variable options to the user just like the regular options, but make the variable value the default. This would make the user aware of the dependency, and allow them to override the variable preset when needed. It would get more complicated with includes and when the same variable is checked multiple times.

Describe alternatives you've considered

Initially I thought of defining local or global variables.

Local variables are defined for the duration of executing the preset (or all selected presets). The preset could set a local value when a user OPTION was detected, and then check the local later to allow multiple user OPTIONS to be combined.

Global variables would be like local variables, but they would be saved at the end of applying the preset, so that they could be queried in the future. This would allow one preset to communicate with another, as well as give the preset a place to store its name and options for future reference. The real downside of this approach is that storage for these extra variables would be required and would not be limited, so they could grow indefinitely. I can't imagine this being easy to implement. It would also require defining a new namespace for these variables to allow different presets to communicate.

Using the existing CLI variables is essentially treating them as globals, but no new variables need to be implemented, the namespace is already well defined, and it solves more problems since it can handle setup done outside of the preset system.

Another limited solution would be to store the state of all user options and allow them all to be queried later on in other option blocks. This still doesn't solve as many problems as using the existing variables.

Another option would be to not implement conditionals as a preset option, but build it into the regular CLI syntax. That would enable it to be used in any CLI script. This would result in a simpler syntax which would be slightly more flexible, but may be more difficult to implement since it would have to be implemented in the CLI parser as opposed to the preset parser.

Other information

No response

MythicLionMan commented 2 years ago

I believe I've figured out how the current preset system handles options passed to included scripts (but I may be missing some details). In short, include files apply with all options deselected, unless you specify 'dummy' options in the preset that is including the child. The dummy option has the same definition as the option in the included preset, but it doesn't implement anything. Multiple included presets may reference the same 'dummy' option.

In a sense, this mechanism is similar to the local variables I considered above. It does solve some of the problems that this proposal does, but not all (I can now make a single preset that includes all of the presets that I use when setting up a quad now that I understand this mechanism). The dummy option system still has the following limitations:

In light of my better understanding of 'dummy options' I can see that this request is less compelling, but it still does simplify the configuration process in some useful ways by using the existing well defined variables as opposed to the options that are at the mercy of preset authors. The decision on whether or not this is an interesting idea to pursue depends on how the preset system is shaped in the future. I can see several possible directions for presets, and I think this would be more useful in some than others.