mirror of
https://github.com/iNavFlight/inav.git
synced 2025-07-21 23:35:30 +03:00
Allow ANDing of multiple channel ranges in mode activation conditions (#364)
* Allow ANDing of multiple channel ranges in mode activation conditions (CLI: set and_mode_conditions=ON) * Moved mode logic operator to Profile (modeActivationConditions are part of profile already); Created a lookup table for logic operator * Closes #212
This commit is contained in:
parent
68ab7d4213
commit
394a28824f
6 changed files with 62 additions and 11 deletions
|
@ -578,6 +578,8 @@ static void resetConf(void)
|
|||
|
||||
currentProfile->mag_declination = 0;
|
||||
|
||||
currentProfile->modeActivationOperator = MODE_OPERATOR_OR; // default is to OR multiple-channel mode activation conditions
|
||||
|
||||
resetBarometerConfig(&masterConfig.barometerConfig);
|
||||
|
||||
// Radio
|
||||
|
|
|
@ -26,6 +26,7 @@ typedef struct profile_s {
|
|||
// For example, -6deg 37min, = -637 Japan, format is [sign]dddmm (degreesminutes) default is zero.
|
||||
|
||||
modeActivationCondition_t modeActivationConditions[MAX_MODE_ACTIVATION_CONDITION_COUNT];
|
||||
modeActivationOperator_e modeActivationOperator;
|
||||
|
||||
adjustmentRange_t adjustmentRanges[MAX_ADJUSTMENT_RANGE_COUNT];
|
||||
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
#include "common/axis.h"
|
||||
#include "common/maths.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "config/runtime_config.h"
|
||||
|
||||
#include "drivers/system.h"
|
||||
#include "drivers/sensor.h"
|
||||
#include "drivers/accgyro.h"
|
||||
|
@ -55,6 +52,9 @@
|
|||
#include "flight/navigation_rewrite.h"
|
||||
#include "flight/failsafe.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "config/runtime_config.h"
|
||||
|
||||
#include "blackbox/blackbox.h"
|
||||
|
||||
#include "mw.h"
|
||||
|
@ -303,17 +303,53 @@ bool isRangeActive(uint8_t auxChannelIndex, channelRange_t *range) {
|
|||
channelValue < 900 + (range->endStep * 25));
|
||||
}
|
||||
|
||||
void updateActivatedModes(modeActivationCondition_t *modeActivationConditions)
|
||||
void updateActivatedModes(modeActivationCondition_t *modeActivationConditions, modeActivationOperator_e modeActivationOperator)
|
||||
{
|
||||
rcModeActivationMask = 0;
|
||||
uint8_t modeIndex;
|
||||
|
||||
uint8_t index;
|
||||
// Unfortunately for AND logic it's not enough to simply check if any of the specified channel range conditions are valid for a mode.
|
||||
// We need to count the total number of conditions specified for each mode, and check that all those conditions are currently valid.
|
||||
|
||||
for (index = 0; index < MAX_MODE_ACTIVATION_CONDITION_COUNT; index++) {
|
||||
modeActivationCondition_t *modeActivationCondition = &modeActivationConditions[index];
|
||||
uint8_t specifiedConditionCountPerMode[CHECKBOX_ITEM_COUNT];
|
||||
uint8_t validConditionCountPerMode[CHECKBOX_ITEM_COUNT];
|
||||
|
||||
memset(specifiedConditionCountPerMode, 0, CHECKBOX_ITEM_COUNT);
|
||||
memset(validConditionCountPerMode, 0, CHECKBOX_ITEM_COUNT);
|
||||
|
||||
for (modeIndex = 0; modeIndex < MAX_MODE_ACTIVATION_CONDITION_COUNT; modeIndex++) {
|
||||
modeActivationCondition_t *modeActivationCondition = &modeActivationConditions[modeIndex];
|
||||
|
||||
// Increment the number of specified conditions for this mode
|
||||
specifiedConditionCountPerMode[modeActivationCondition->modeId]++;
|
||||
|
||||
if (isRangeActive(modeActivationCondition->auxChannelIndex, &modeActivationCondition->range)) {
|
||||
ACTIVATE_RC_MODE(modeActivationCondition->modeId);
|
||||
// Increment the number of valid conditions for this mode
|
||||
validConditionCountPerMode[modeActivationCondition->modeId]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable all modes to begin with
|
||||
rcModeActivationMask = 0;
|
||||
|
||||
// Now see which modes should be enabled
|
||||
for (modeIndex = 0; modeIndex < CHECKBOX_ITEM_COUNT; modeIndex++) {
|
||||
// only modes with conditions specified are considered
|
||||
if (specifiedConditionCountPerMode[modeIndex] > 0) {
|
||||
// For AND logic, the specified condition count and valid condition count must be the same.
|
||||
// For OR logic, the valid condition count must be greater than zero.
|
||||
|
||||
if (modeActivationOperator == MODE_OPERATOR_AND) {
|
||||
// AND the conditions
|
||||
if (validConditionCountPerMode[modeIndex] == specifiedConditionCountPerMode[modeIndex]) {
|
||||
ACTIVATE_RC_MODE(modeIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// OR the conditions
|
||||
if (validConditionCountPerMode[modeIndex] > 0) {
|
||||
ACTIVATE_RC_MODE(modeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,6 +144,11 @@ typedef struct modeActivationCondition_s {
|
|||
|
||||
#define IS_RANGE_USABLE(range) ((range)->startStep < (range)->endStep)
|
||||
|
||||
typedef enum {
|
||||
MODE_OPERATOR_OR,
|
||||
MODE_OPERATOR_AND
|
||||
} modeActivationOperator_e;
|
||||
|
||||
typedef struct controlRateConfig_s {
|
||||
uint8_t rcExpo8;
|
||||
uint8_t thrMid8;
|
||||
|
@ -170,7 +175,7 @@ throttleStatus_e calculateThrottleStatus(rxConfig_t *rxConfig, uint16_t deadband
|
|||
rollPitchStatus_e calculateRollPitchCenterStatus(rxConfig_t *rxConfig);
|
||||
void processRcStickPositions(rxConfig_t *rxConfig, throttleStatus_e throttleStatus, bool disarm_kill_switch);
|
||||
|
||||
void updateActivatedModes(modeActivationCondition_t *modeActivationConditions);
|
||||
void updateActivatedModes(modeActivationCondition_t *modeActivationConditions, modeActivationOperator_e modeActivationOperator);
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -423,6 +423,10 @@ static const char * const lookupTableNavRthAltMode[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static const char * const lookupTableAuxOperator[] = {
|
||||
"OR", "AND"
|
||||
};
|
||||
|
||||
typedef struct lookupTableEntry_s {
|
||||
const char * const *values;
|
||||
const uint8_t valueCount;
|
||||
|
@ -457,6 +461,7 @@ typedef enum {
|
|||
TABLE_NAV_USER_CTL_MODE,
|
||||
TABLE_NAV_RTH_ALT_MODE,
|
||||
#endif
|
||||
TABLE_AUX_OPERATOR,
|
||||
} lookupTableIndex_e;
|
||||
|
||||
static const lookupTableEntry_t lookupTables[] = {
|
||||
|
@ -488,6 +493,7 @@ static const lookupTableEntry_t lookupTables[] = {
|
|||
{ lookupTableNavControlMode, sizeof(lookupTableNavControlMode) / sizeof(char *) },
|
||||
{ lookupTableNavRthAltMode, sizeof(lookupTableNavRthAltMode) / sizeof(char *) },
|
||||
#endif
|
||||
{ lookupTableAuxOperator, sizeof(lookupTableAuxOperator) / sizeof(char *) },
|
||||
};
|
||||
|
||||
#define VALUE_TYPE_OFFSET 0
|
||||
|
@ -725,6 +731,7 @@ const clivalue_t valueTable[] = {
|
|||
{ "servo_lowpass_enable", VAR_INT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.mixerConfig.servo_lowpass_enable, .config.lookup = { TABLE_OFF_ON }, 0 },
|
||||
#endif
|
||||
|
||||
{ "mode_range_logic_operator", VAR_UINT8 | PROFILE_VALUE | MODE_LOOKUP, &masterConfig.profile[0].modeActivationOperator, .config.lookup = { TABLE_AUX_OPERATOR }, 0 },
|
||||
{ "default_rate_profile", VAR_UINT8 | PROFILE_VALUE , &masterConfig.profile[0].defaultRateProfileIndex, .config.minmax = { 0, MAX_CONTROL_RATE_PROFILE_COUNT - 1 }, 0 },
|
||||
{ "rc_expo", VAR_UINT8 | CONTROL_RATE_VALUE, &masterConfig.controlRateProfiles[0].rcExpo8, .config.minmax = { 0, 100 }, 0 },
|
||||
{ "rc_yaw_expo", VAR_UINT8 | CONTROL_RATE_VALUE, &masterConfig.controlRateProfiles[0].rcYawExpo8, .config.minmax = { 0, 100 }, 0 },
|
||||
|
|
|
@ -336,7 +336,7 @@ void processRx(void)
|
|||
|
||||
processRcStickPositions(&masterConfig.rxConfig, throttleStatus, masterConfig.disarm_kill_switch);
|
||||
|
||||
updateActivatedModes(currentProfile->modeActivationConditions);
|
||||
updateActivatedModes(currentProfile->modeActivationConditions, currentProfile->modeActivationOperator);
|
||||
|
||||
if (!cliMode) {
|
||||
updateAdjustmentStates(currentProfile->adjustmentRanges);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue