1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-24 08:45:36 +03:00

Self-level modes expo

Adds angle setpoint roll/pitch expo for self-level modes.

Previously the angle setpoint was a simple linear calculation based on the stick deflection percentage and the angle limit. This makes control very jumpy around center stick and people would often resort to adding expo in their radios to compensate. This then adds the complication of wanting expo in the radio when in self-level but not when in acro - leading to complicated mixes, virtual switches, etc.

This PR adds separate self-level expo settings for roll/pitch so the user can customize the axis behavior. Yaw is excluded because this axis uses normal rates and expo controlling the rotational rate around the yaw axis and not an angle setpoint. The roll/pitch expo can range from 0 (off) to 100 (max) like other RC expo settings. For example:
```
set roll_level_expo = 30
set pitch_level_expo = 40
```
The default values are 0 which disables any expo and behaves as before.

The settings are available in the CMS rate profile menu.
This commit is contained in:
Bruce Luckcuck 2021-01-25 11:35:02 -05:00
parent 34614231d3
commit 87f322927a
7 changed files with 51 additions and 5 deletions

View file

@ -34,18 +34,21 @@ int16_t debug[DEBUG16_VALUE_COUNT];
uint8_t debugMode;
extern "C" {
#include "platform.h"
#include "build/debug.h"
#include "common/axis.h"
#include "common/maths.h"
#include "common/filter.h"
#include "config/config.h"
#include "config/config_reset.h"
#include "pg/pg.h"
#include "pg/pg_ids.h"
#include "drivers/sound_beeper.h"
#include "drivers/time.h"
#include "fc/controlrate_profile.h"
#include "fc/core.h"
#include "fc/rc.h"
@ -59,6 +62,9 @@ extern "C" {
#include "io/gps.h"
#include "pg/pg.h"
#include "pg/pg_ids.h"
#include "sensors/gyro.h"
#include "sensors/acceleration.h"
@ -66,6 +72,7 @@ extern "C" {
attitudeEulerAngles_t attitude;
PG_REGISTER(accelerometerConfig_t, accelerometerConfig, PG_ACCELEROMETER_CONFIG, 0);
PG_REGISTER(systemConfig_t, systemConfig, PG_SYSTEM_CONFIG, 2);
bool unitLaunchControlActive = false;
launchControlMode_e unitLaunchControlMode = LAUNCH_CONTROL_MODE_NORMAL;
@ -87,6 +94,7 @@ extern "C" {
UNUSED(currentPidSetpoint);
return value;
}
void initRcProcessing(void) { }
}
pidProfile_t *pidProfile;
@ -179,6 +187,10 @@ void resetTest(void) {
unitLaunchControlActive = false;
pidProfile->launchControlMode = unitLaunchControlMode;
pidInit(pidProfile);
loadControlRateProfile();
currentControlRateProfile->levelExpo[FD_ROLL] = 0;
currentControlRateProfile->levelExpo[FD_PITCH] = 0;
// Run pidloop for a while after reset
for (int loop = 0; loop < 20; loop++) {
@ -379,6 +391,19 @@ TEST(pidControllerTest, testPidLevel) {
EXPECT_FLOAT_EQ(0, currentPidSetpoint);
currentPidSetpoint = pidLevel(FD_PITCH, pidProfile, &angleTrim, currentPidSetpoint);
EXPECT_FLOAT_EQ(0, currentPidSetpoint);
// Test level mode expo
enableFlightMode(ANGLE_MODE);
attitude.values.roll = 0;
attitude.values.pitch = 0;
setStickPosition(FD_ROLL, 0.5f);
setStickPosition(FD_PITCH, -0.5f);
currentControlRateProfile->levelExpo[FD_ROLL] = 50;
currentControlRateProfile->levelExpo[FD_PITCH] = 26;
currentPidSetpoint = pidLevel(FD_ROLL, pidProfile, &angleTrim, currentPidSetpoint);
EXPECT_FLOAT_EQ(85.9375, currentPidSetpoint);
currentPidSetpoint = pidLevel(FD_PITCH, pidProfile, &angleTrim, currentPidSetpoint);
EXPECT_FLOAT_EQ(-110.6875, currentPidSetpoint);
}