Code and documentation cleanup of rc calibration.

Note: since it didn't actually calibrate anything it has been renamed to
rxrange.

Added ability to reset rxranges using `rxrange reset` - this follows the
same pattern as other cli commands.
This commit is contained in:
Dominic Clifton 2015-08-04 00:23:38 +01:00
parent 27f8223de7
commit 9d3276b222
9 changed files with 103 additions and 87 deletions

View File

@ -92,7 +92,7 @@ Re-apply any new defaults as desired.
| `play_sound` | index, or none for next |
| `profile` | index (0 to 2) |
| `rateprofile` | index (0 to 2) |
| `rccal` | Set R/C channel calibration (stick end points) |
| `rxrange` | configure rx channel ranges (end-points) |
| `save` | save and reboot |
| `set` | name=value or blank or * for list |
| `status` | show system status |

View File

@ -217,21 +217,23 @@ Set the RX for 'No Pulses'. Turn OFF TX and RX, Turn ON RX. Press and release
Set failsafe on channels 1-4 set to OFF in the receiver settings (via transmitter menu).
## Receiver Calibration.
## Receiver Channel Range Configuration.
If you have a transmitter/receiver, that output a non-standard pulse range (i.e. 1070-1930 as some Spektrum receivers)
you could use rc calibration to map actual range of your transmitter to 1000-2000 as expected by Cleanflight.
you could use rx channel range configuration to map actual range of your transmitter to 1000-2000 as expected by Cleanflight.
To do this you should figure out what range your transmitter outputs and feed these values to rc calibration control.
The low and high value of a channel range are often referred to as 'End-points'. e.g. 'End-point adjustments / EPA'.
All attempts should be made to configure your transmitter/receiver to use the range 1000-2000 *before* using this feature
as you will have less preceise control if it is used.
To do this you should figure out what range your transmitter outputs and use these values for rx range configuration.
You can do this in a few simple steps:
If you have used rc calibration previously you should reset it to prevent it from altering rc input. Do so
by entering the following commands in CLI:
If you have used rc range configuration previously you should reset it to prevent it from altering rc input. Do so
by entering the following command in CLI:
```
rccal 0 1000 2000
rccal 1 1000 2000
rccal 2 1000 2000
rccal 3 1000 2000
rxrange reset
save
```
@ -241,11 +243,11 @@ a time.
Go to CLI and set the min and max values with the following command:
```
rccal <channel_number> <min> <max>
rxrange <channel_number> <min> <max>
```
For example, if you got 1070-1930 range for roll channel. Roll is `channel 0` so you should type `rccal 0 1070 1930` in
For example, if you have the range 1070-1930 for the first channel you should use `rxrange 0 1070 1930` in
the CLI. Be sure to enter the `save` command to save the settings.
Use sub-trim on your transmitter to set the middle point of pitch, roll, yaw and throttle.
After configuring channel ranges use the sub-trim on your transmitter to set the middle point of pitch, roll, yaw and throttle.

View File

@ -414,11 +414,7 @@ static void resetConf(void)
masterConfig.rxConfig.rssi_scale = RSSI_SCALE_DEFAULT;
masterConfig.rxConfig.rssi_ppm_invert = 0;
// set default calibration to full range and 1:1 mapping
for (i = 0; i < MAX_CALIBRATED_RX_CHANNELS; i++) {
masterConfig.rxConfig.calibration[i].minrc = PWM_RANGE_MIN;
masterConfig.rxConfig.calibration[i].maxrc = PWM_RANGE_MAX;
}
resetAllRxChannelRangeConfigurations(masterConfig.rxConfig.channelRanges);
masterConfig.inputFilteringMode = INPUT_FILTERING_DISABLED;

View File

@ -106,7 +106,6 @@ ppmDevice_t ppmDev;
#define PPM_STABLE_FRAMES_REQUIRED_COUNT 25
#define PPM_IN_MIN_NUM_CHANNELS 4
#define PPM_IN_MAX_NUM_CHANNELS PWM_PORTS_OR_PPM_CAPTURE_COUNT
#define PPM_RCVR_TIMEOUT 0
bool isPPMDataBeingReceived(void)

View File

@ -22,6 +22,9 @@ typedef enum {
INPUT_FILTERING_ENABLED
} inputFilteringMode_e;
#define PPM_RCVR_TIMEOUT 0
void ppmInConfig(const timerHardware_t *timerHardwarePtr);
void ppmAvoidPWMTimerClash(const timerHardware_t *timerHardwarePtr, TIM_TypeDef *sharedPwmTimer);

View File

@ -117,7 +117,7 @@ static void cliSet(char *cmdline);
static void cliGet(char *cmdline);
static void cliStatus(char *cmdline);
static void cliVersion(char *cmdline);
static void cliRxCalibration(char *cmdline);
static void cliRxRange(char *cmdline);
#ifdef GPS
static void cliGpsPassthrough(char *cmdline);
@ -258,8 +258,8 @@ const clicmd_t cmdTable[] = {
"[<index>]", cliProfile),
CLI_COMMAND_DEF("rateprofile", "change rate profile",
"[<index>]", cliRateProfile),
CLI_COMMAND_DEF("rxrange", "configure rx channel ranges", NULL, cliRxRange),
CLI_COMMAND_DEF("rxfail", "show/set rx failsafe settings", NULL, cliRxFail),
CLI_COMMAND_DEF("rxcal", "rc calibration", NULL, cliRxCalibration),
CLI_COMMAND_DEF("save", "save and reboot", NULL, cliSave),
CLI_COMMAND_DEF("serial", "configure serial ports", NULL, cliSerial),
#ifdef USE_SERVOS
@ -929,42 +929,47 @@ static void cliMotorMix(char *cmdline)
#endif
}
static void cliRxCalibration(char *cmdline)
static void cliRxRange(char *cmdline)
{
int i, check = 0;
int i, validArgumentCount = 0;
char *ptr;
if (isEmpty(cmdline)) {
for (i = 0; i < MAX_CALIBRATED_RX_CHANNELS; i++) {
printf("rccal %u %u %u\r\n", i, masterConfig.rxConfig.calibration[i].minrc, masterConfig.rxConfig.calibration[i].maxrc);
for (i = 0; i < NON_AUX_CHANNEL_COUNT; i++) {
rxChannelRangeConfiguration_t *channelRangeConfiguration = &masterConfig.rxConfig.channelRanges[i];
printf("rxrange %u %u %u\r\n", i, channelRangeConfiguration->min, channelRangeConfiguration->max);
}
} else if (strcasecmp(cmdline, "reset") == 0) {
resetAllRxChannelRangeConfigurations(masterConfig.rxConfig.channelRanges);
} else {
ptr = cmdline;
i = atoi(ptr);
if (i >= 0 && i < MAX_CALIBRATED_RX_CHANNELS) {
int minrc, maxrc;
if (i >= 0 && i < NON_AUX_CHANNEL_COUNT) {
int rangeMin, rangeMax;
ptr = strchr(ptr, ' ');
if (ptr) {
minrc = atoi(++ptr);
check++;
rangeMin = atoi(++ptr);
validArgumentCount++;
}
ptr = strchr(ptr, ' ');
if (ptr) {
maxrc = atoi(++ptr);
check++;
rangeMax = atoi(++ptr);
validArgumentCount++;
}
if (check != 2) {
printf("Wrong number of arguments, needs idx min max\r\n");
}
else if (minrc < 750 || minrc > 2250 || maxrc < 750 || maxrc > 2250 || minrc >= maxrc) {
printf("Parameters error. Should be: 750 <= minrc < maxrc <= 2250\r\n");
}
else {
masterConfig.rxConfig.calibration[i].minrc = minrc;
masterConfig.rxConfig.calibration[i].maxrc = maxrc;
if (validArgumentCount != 2) {
cliShowParseError();
} else if (rangeMin < PWM_PULSE_MIN || rangeMin > PWM_PULSE_MAX || rangeMax < PWM_PULSE_MIN || rangeMax > PWM_PULSE_MAX || rangeMin >= rangeMax) {
cliShowParseError();
} else {
rxChannelRangeConfiguration_t *channelRangeConfiguration = &masterConfig.rxConfig.channelRanges[i];
channelRangeConfiguration->min = rangeMin;
channelRangeConfiguration->max = rangeMax;
}
} else {
printf("Invalid R/C channel: must be > 0 and < %u\r\n", MAX_CALIBRATED_RX_CHANNELS);
cliShowArgumentRangeError("channel", 0, NON_AUX_CHANNEL_COUNT - 1);
}
}
}
@ -1509,9 +1514,9 @@ static void cliDump(char *cmdline)
cliAdjustmentRange("");
printf("\r\n# rccal\r\n");
printf("\r\n# rxrange\r\n");
cliRxCalibration("");
cliRxRange("");
cliPrint("\r\n# servo\r\n");

View File

@ -116,6 +116,14 @@ STATIC_UNIT_TESTED void rxUpdateFlightChannelStatus(uint8_t channel, uint16_t pu
}
}
void resetAllRxChannelRangeConfigurations(rxChannelRangeConfiguration_t *rxChannelRangeConfiguration) {
// set default calibration to full range and 1:1 mapping
for (int i = 0; i < NON_AUX_CHANNEL_COUNT; i++) {
rxChannelRangeConfiguration->min = PWM_RANGE_MIN;
rxChannelRangeConfiguration->max = PWM_RANGE_MAX;
rxChannelRangeConfiguration++;
}
}
void rxInit(rxConfig_t *rxConfig)
{
@ -339,14 +347,14 @@ static uint16_t getRxfailValue(uint8_t channel)
}
STATIC_UNIT_TESTED uint16_t applyRxCalibration(int sample, int minrc, int maxrc)
STATIC_UNIT_TESTED uint16_t applyRxChannelRangeConfiguraton(int sample, rxChannelRangeConfiguration_t range)
{
// Check special condition sample = PPM_RCVR_TIMEOUT, allow no signal value to avoid being corrupted by calibration
if (sample == 0) {
return 0;
// Avoid corruption of channel with a value of PPM_RCVR_TIMEOUT
if (sample == PPM_RCVR_TIMEOUT) {
return PPM_RCVR_TIMEOUT;
}
sample = scaleRange(sample, minrc, maxrc, PWM_RANGE_MIN, PWM_RANGE_MAX);
sample = scaleRange(sample, range.min, range.max, PWM_RANGE_MIN, PWM_RANGE_MAX);
sample = MIN(MAX(PWM_PULSE_MIN, sample), PWM_PULSE_MAX);
return sample;
@ -375,8 +383,8 @@ void processRxChannels(void)
uint16_t sample = rcReadRawFunc(&rxRuntimeConfig, rawChannel);
// apply the rx calibration
if (chan < MAX_CALIBRATED_RX_CHANNELS) {
sample = applyRxCalibration(sample, rxConfig->calibration[chan].minrc, rxConfig->calibration[chan].maxrc);
if (chan < NON_AUX_CHANNEL_COUNT) {
sample = applyRxChannelRangeConfiguraton(sample, rxConfig->channelRanges[chan]);
}
rxUpdateFlightChannelStatus(chan, sample);

View File

@ -76,7 +76,6 @@ extern const char rcChannelLetters[];
extern int16_t rcData[MAX_SUPPORTED_RC_CHANNEL_COUNT]; // interval [1000;2000]
#define MAX_MAPPABLE_RX_INPUTS 8
#define MAX_CALIBRATED_RX_CHANNELS NON_AUX_CHANNEL_COUNT
#define RSSI_SCALE_MIN 1
#define RSSI_SCALE_MAX 255
@ -92,10 +91,10 @@ typedef struct rxFailsafeChannelConfiguration_s {
uint8_t step;
} rxFailsafeChannelConfiguration_t;
typedef struct rxCalibration_s {
uint16_t minrc;
uint16_t maxrc;
} rxCalibration_t;
typedef struct rxChannelRangeConfiguration_s {
uint16_t min;
uint16_t max;
} rxChannelRangeConfiguration_t;
typedef struct rxConfig_s {
uint8_t rcmap[MAX_MAPPABLE_RX_INPUTS]; // mapping of radio channels to internal RPYTA+ order
@ -112,7 +111,7 @@ typedef struct rxConfig_s {
uint16_t rx_max_usec;
rxFailsafeChannelConfiguration_t failsafe_aux_channel_configurations[MAX_AUX_CHANNEL_COUNT];
rxCalibration_t calibration[MAX_CALIBRATED_RX_CHANNELS];
rxChannelRangeConfiguration_t channelRanges[NON_AUX_CHANNEL_COUNT];
} rxConfig_t;
#define REMAPPABLE_CHANNEL_COUNT (sizeof(((rxConfig_t *)0)->rcmap) / sizeof(((rxConfig_t *)0)->rcmap[0]))
@ -137,3 +136,5 @@ void parseRcChannels(const char *input, rxConfig_t *rxConfig);
uint8_t serialRxFrameStatus(rxConfig_t *rxConfig);
void updateRSSI(uint32_t currentTime);
void resetAllRxChannelRangeConfigurations(rxChannelRangeConfiguration_t *rxChannelRangeConfiguration);

View File

@ -32,52 +32,54 @@ extern "C" {
#include "gtest/gtest.h"
extern "C" {
extern uint16_t applyRxCalibration(int sample, int minrc, int maxrc);
extern uint16_t applyRxChannelRangeConfiguraton(int sample, rxChannelRangeConfiguration_t range);
}
TEST(RcCalibrationUnittest, TestRcCalibration)
#define RANGE_CONFIGURATION(min, max) (rxChannelRangeConfiguration_t) {min, max}
TEST(RxChannelRangeTest, TestRxChannelRanges)
{
// No signal, special condition
EXPECT_EQ(applyRxCalibration(0, 1000, 2000), 0);
EXPECT_EQ(applyRxCalibration(0, 1300, 1700), 0);
EXPECT_EQ(applyRxCalibration(0, 900, 2100), 0);
EXPECT_EQ(applyRxChannelRangeConfiguraton(0, RANGE_CONFIGURATION(1000, 2000)), 0);
EXPECT_EQ(applyRxChannelRangeConfiguraton(0, RANGE_CONFIGURATION(1300, 1700)), 0);
EXPECT_EQ(applyRxChannelRangeConfiguraton(0, RANGE_CONFIGURATION(900, 2100)), 0);
// Exact mapping
EXPECT_EQ(applyRxCalibration(1000, 1000, 2000), 1000);
EXPECT_EQ(applyRxCalibration(1500, 1000, 2000), 1500);
EXPECT_EQ(applyRxCalibration(2000, 1000, 2000), 2000);
EXPECT_EQ(applyRxCalibration(700, 1000, 2000), 750);
EXPECT_EQ(applyRxCalibration(2500, 1000, 2000), 2250);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1000, RANGE_CONFIGURATION(1000, 2000)), 1000);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1500, RANGE_CONFIGURATION(1000, 2000)), 1500);
EXPECT_EQ(applyRxChannelRangeConfiguraton(2000, RANGE_CONFIGURATION(1000, 2000)), 2000);
EXPECT_EQ(applyRxChannelRangeConfiguraton(700, RANGE_CONFIGURATION(1000, 2000)), 750);
EXPECT_EQ(applyRxChannelRangeConfiguraton(2500, RANGE_CONFIGURATION(1000, 2000)), 2250);
// Shifted range
EXPECT_EQ(applyRxCalibration(900, 900, 1900), 1000);
EXPECT_EQ(applyRxCalibration(1400, 900, 1900), 1500);
EXPECT_EQ(applyRxCalibration(1900, 900, 1900), 2000);
EXPECT_EQ(applyRxCalibration(600, 900, 1900), 750);
EXPECT_EQ(applyRxCalibration(2500, 900, 1900), 2250);
EXPECT_EQ(applyRxChannelRangeConfiguraton(900, RANGE_CONFIGURATION(900, 1900)), 1000);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1400, RANGE_CONFIGURATION(900, 1900)), 1500);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1900, RANGE_CONFIGURATION(900, 1900)), 2000);
EXPECT_EQ(applyRxChannelRangeConfiguraton(600, RANGE_CONFIGURATION(900, 1900)), 750);
EXPECT_EQ(applyRxChannelRangeConfiguraton(2500, RANGE_CONFIGURATION(900, 1900)), 2250);
// Narrower range than expected
EXPECT_EQ(applyRxCalibration(1300, 1300, 1700), 1000);
EXPECT_EQ(applyRxCalibration(1500, 1300, 1700), 1500);
EXPECT_EQ(applyRxCalibration(1700, 1300, 1700), 2000);
EXPECT_EQ(applyRxCalibration(700, 1300, 1700), 750);
EXPECT_EQ(applyRxCalibration(2500, 1300, 1700), 2250);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1300, RANGE_CONFIGURATION(1300, 1700)), 1000);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1500, RANGE_CONFIGURATION(1300, 1700)), 1500);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1700, RANGE_CONFIGURATION(1300, 1700)), 2000);
EXPECT_EQ(applyRxChannelRangeConfiguraton(700, RANGE_CONFIGURATION(1300, 1700)), 750);
EXPECT_EQ(applyRxChannelRangeConfiguraton(2500, RANGE_CONFIGURATION(1300, 1700)), 2250);
// Wider range than expected
EXPECT_EQ(applyRxCalibration(900, 900, 2100), 1000);
EXPECT_EQ(applyRxCalibration(1500, 900, 2100), 1500);
EXPECT_EQ(applyRxCalibration(2100, 900, 2100), 2000);
EXPECT_EQ(applyRxCalibration(600, 900, 2100), 750);
EXPECT_EQ(applyRxCalibration(2700, 900, 2100), 2250);
EXPECT_EQ(applyRxChannelRangeConfiguraton(900, RANGE_CONFIGURATION(900, 2100)), 1000);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1500, RANGE_CONFIGURATION(900, 2100)), 1500);
EXPECT_EQ(applyRxChannelRangeConfiguraton(2100, RANGE_CONFIGURATION(900, 2100)), 2000);
EXPECT_EQ(applyRxChannelRangeConfiguraton(600, RANGE_CONFIGURATION(900, 2100)), 750);
EXPECT_EQ(applyRxChannelRangeConfiguraton(2700, RANGE_CONFIGURATION(900, 2100)), 2250);
// extreme out of range
EXPECT_EQ(applyRxCalibration(1, 1000, 2000), 750);
EXPECT_EQ(applyRxCalibration(1, 1300, 1700), 750);
EXPECT_EQ(applyRxCalibration(1, 900, 2100), 750);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1, RANGE_CONFIGURATION(1000, 2000)), 750);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1, RANGE_CONFIGURATION(1300, 1700)), 750);
EXPECT_EQ(applyRxChannelRangeConfiguraton(1, RANGE_CONFIGURATION(900, 2100)), 750);
EXPECT_EQ(applyRxCalibration(10000, 1000, 2000), 2250);
EXPECT_EQ(applyRxCalibration(10000, 1300, 1700), 2250);
EXPECT_EQ(applyRxCalibration(10000, 900, 2100), 2250);
EXPECT_EQ(applyRxChannelRangeConfiguraton(10000, RANGE_CONFIGURATION(1000, 2000)), 2250);
EXPECT_EQ(applyRxChannelRangeConfiguraton(10000, RANGE_CONFIGURATION(1300, 1700)), 2250);
EXPECT_EQ(applyRxChannelRangeConfiguraton(10000, RANGE_CONFIGURATION(900, 2100)), 2250);
}