1
0
Fork 0
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:
Konstantin Sharlaimov 2016-07-25 15:06:31 +03:00 committed by GitHub
parent 68ab7d4213
commit 394a28824f
6 changed files with 62 additions and 11 deletions

View file

@ -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

View file

@ -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];

View file

@ -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);
}
}
}
}
}

View file

@ -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 {

View file

@ -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 },

View file

@ -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);