1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-24 16:55:20 +03:00

Merge branch '2.3' into 3djc/review-about

This commit is contained in:
3djc 2020-12-04 16:06:56 +01:00 committed by GitHub
commit e17ca05c2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 1510 additions and 836 deletions

View file

@ -96,6 +96,14 @@ bool menuModelLimits(event_t event)
uint32_t sub = menuVerticalPosition;
if (sub < MAX_OUTPUT_CHANNELS) {
#if defined(PPM_CENTER_ADJUSTABLE) || defined(PPM_UNIT_US)
lcdDrawNumber(LCD_W / 2, MENU_TITLE_TOP + 1, PPM_CH_CENTER(sub)+channelOutputs[sub]/2, MENU_TITLE_COLOR, 0, "", STR_US);
#else
lcdDrawNumber(LCD_W / 2, MENU_TITLE_TOP + 1, calcRESXto1000(channelOutputs[sub]), PREC1 | MENU_TITLE_COLOR);
#endif
}
if (sub<MAX_OUTPUT_CHANNELS && menuHorizontalPosition>=0) {
drawColumnHeader(STR_LIMITS_HEADERS, NULL, menuHorizontalPosition);
}

View file

@ -35,8 +35,8 @@ enum NavigationDirection {
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_LEFT) && IS_SHIFT_PRESSED())
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_LONG(KEY_RIGHT) && IS_SHIFT_PRESSED())
#elif defined(NAVIGATION_X7_TX12)
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_UP))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_DOWN))
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEUP))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_FIRST(KEY_PAGEDN))
#elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D)
#define EVT_KEY_PREVIOUS_VIEW(evt) (evt == EVT_KEY_LONG(KEY_PAGE))
#define EVT_KEY_NEXT_VIEW(evt) (evt == EVT_KEY_BREAK(KEY_PAGE))

View file

@ -539,14 +539,25 @@ int getStickTrimValue(int stick, int stickValue)
return trim;
}
int getSourceTrimValue(int source, int stickValue=0)
int getSourceTrimOrigin(int source)
{
if (source >= MIXSRC_Rud && source <= MIXSRC_Ail)
return getStickTrimValue(source - MIXSRC_Rud, stickValue);
return source - MIXSRC_Rud;
else if (source >= MIXSRC_FIRST_INPUT && source <= MIXSRC_LAST_INPUT)
return getStickTrimValue(virtualInputsTrims[source - MIXSRC_FIRST_INPUT], stickValue);
return virtualInputsTrims[source - MIXSRC_FIRST_INPUT];
else
return -1;
}
int getSourceTrimValue(int source, int stickValue=0)
{
auto origin = getSourceTrimOrigin(source);
if (origin >= 0) {
return getStickTrimValue(origin, stickValue);
}
else {
return 0;
}
}
uint8_t mixerCurrentFlightMode;
@ -741,13 +752,16 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms)
}
if (applyOffsetAndCurve) {
//========== TRIMS ================
if (!(mode & e_perout_mode_notrims)) {
if (md->carryTrim == 0) {
v += getSourceTrimValue(md->srcRaw, v);
bool applyTrims = !(mode & e_perout_mode_notrims);
if (!applyTrims && g_model.thrTrim) {
auto origin = getSourceTrimOrigin(md->srcRaw);
if (origin == g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM) {
applyTrims = true;
}
}
if (applyTrims && md->carryTrim == 0) {
v += getSourceTrimValue(md->srcRaw, v);
}
}
int32_t weight = GET_GVAR_PREC1(MD_WEIGHT(md), GV_RANGELARGE_NEG, GV_RANGELARGE, mixerCurrentFlightMode);

View file

@ -1119,7 +1119,7 @@ void checkTrims()
else {
phase = getTrimFlightMode(mixerCurrentFlightMode, idx);
before = getTrimValue(phase, idx);
thro = (idx==THR_STICK && g_model.thrTrim);
thro = (idx == (g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM) && g_model.thrTrim);
}
#else
phase = getTrimFlightMode(mixerCurrentFlightMode, idx);
@ -1824,24 +1824,27 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
pauseMixerCalculations();
evalFlightModeMixes(e_perout_mode_noinput, 0); // do output loop - zero input sticks and trims
for (uint8_t i=0; i<MAX_OUTPUT_CHANNELS; i++) {
for (uint8_t i = 0; i < MAX_OUTPUT_CHANNELS; i++) {
zeros[i] = applyLimits(i, chans[i]);
}
evalFlightModeMixes(e_perout_mode_noinput-e_perout_mode_notrims, 0); // do output loop - only trims
for (uint8_t i=0; i<MAX_OUTPUT_CHANNELS; i++) {
int16_t output = applyLimits(i, chans[i]) - zeros[i];
for (uint8_t i = 0; i < MAX_OUTPUT_CHANNELS; i++) {
int16_t diff = applyLimits(i, chans[i]) - zeros[i];
int16_t v = g_model.limitData[i].offset;
if (g_model.limitData[i].revert)
output = -output;
v += (output * 125) / 128;
g_model.limitData[i].offset = limit((int16_t)-1000, (int16_t)v, (int16_t)1000); // make sure the offset doesn't go haywire
diff = -diff;
v += (diff * 125) / 128;
g_model.limitData[i].offset = limit((int16_t) -1000, (int16_t) v, (int16_t) 1000); // make sure the offset doesn't go haywire
}
// reset all trims, except throttle (if throttle trim)
for (uint8_t i=0; i<NUM_TRIMS; i++) {
if (i != THR_STICK || !g_model.thrTrim) {
auto thrStick = g_model.getThrottleStickTrimSource() - MIXSRC_FIRST_TRIM;
if (i != thrStick || !g_model.thrTrim) {
int16_t original_trim = getTrimValue(mixerCurrentFlightMode, i);
for (uint8_t fm=0; fm<MAX_FLIGHT_MODES; fm++) {
trim_t trim = getRawTrimValue(fm, i);

View file

@ -2,7 +2,7 @@ option(SHUTDOWN_CONFIRMATION "Shutdown confirmation" OFF)
option(LCD_DUAL_BUFFER "Dual LCD Buffer" OFF)
option(PXX1 "PXX1 protocol support" ON)
option(PXX2 "PXX2 protocol support" OFF)
option(AFHDS3 "AFHDS3 TX Module" OFF)
option(AFHDS3 "AFHDS3 TX Module" ON)
option(GHOST "Ghost TX Module" ON)
option(INTERNAL_MODULE_PPM "Support for PPM internal module" OFF)
option(AUTOUPDATE "Auto update internal chips from SD" OFF)
@ -53,6 +53,7 @@ elseif(PCB STREQUAL X9D+)
set(LCD_DRIVER lcd_driver_spi.cpp)
set(GVAR_SCREEN model_gvars.cpp)
set(PCBREV 2014 CACHE STRING "PCB Revision")
set(AFHDS3 NO)
add_definitions(-DPCBREV=${PCBREV})
add_definitions(-DMANUFACTURER_FRSKY)
if (${PCBREV} STREQUAL 2019)
@ -106,6 +107,7 @@ elseif(PCB STREQUAL X9D)
set(GVAR_SCREEN model_gvars.cpp)
set(STATUS_LEDS NO)
add_definitions(-DMANUFACTURER_FRSKY)
set(AFHDS3 NO)
elseif(PCB STREQUAL X7)
set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)")
set(HAPTIC YES)

View file

@ -339,6 +339,106 @@ TEST_F(TrimsTest, CopySticksToOffset)
EXPECT_EQ(g_model.limitData[1].offset, -97);
}
TEST_F(TrimsTest, MoveTrimsToOffsets)
{
// No trim idle only
g_model.thrTrim = 0;
anaInValues[THR_STICK] = 0;
setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, 100);
setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, -100);
evalMixes(1);
EXPECT_EQ(channelOutputs[2], 200); // THR output value is reflecting 100 trim
moveTrimsToOffsets();
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[2].offset, 195); // value transferred
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[1].offset, -195); // value transferred
evalMixes(1);
EXPECT_EQ(channelOutputs[2], 200); // THR output value is still reflecting 100 trim
}
TEST_F(TrimsTest, MoveTrimsToOffsetsWithTrimIdle)
{
// Trim idle only
g_model.thrTrim = 1;
anaInValues[THR_STICK] = -1024; // Min stick
g_model.limitData[2].offset = 0;
g_model.limitData[1].offset = 0;
setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, 100);
setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, -100);
evalMixes(1);
EXPECT_EQ(channelOutputs[2], -574); // THR output value is reflecting 100 trim idle
moveTrimsToOffsets();
// Trim affecting Throttle should not be affected
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 100); // unchanged
EXPECT_EQ(g_model.limitData[2].offset, 0); // unchanged
// Other trims should
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[1].offset, -195); // value transferred
evalMixes(1);
EXPECT_EQ(channelOutputs[2], -574); // THR output value is still reflecting 100 trim idle
}
TEST_F(TrimsTest, MoveTrimsToOffsetsWithCrossTrims)
{
// No trim idle only
// Cross trims
g_model.thrTrim = 0;
g_model.limitData[2].offset = 0;
g_model.limitData[1].offset = 0;
g_model.thrTrimSw = MIXSRC_TrimEle - MIXSRC_FIRST_TRIM;
ExpoData *expo = expoAddress(THR_STICK);
expo->carryTrim = TRIM_ELE;
expo = expoAddress(ELE_STICK);
expo->carryTrim = TRIM_THR;
anaInValues[THR_STICK] = 0;
setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, 100);
setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, -100);
evalMixes(1);
EXPECT_EQ(channelOutputs[2], 200); // THR output value is reflecting 100 Ele trim
moveTrimsToOffsets();
evalMixes(1);
EXPECT_EQ(channelOutputs[2], 200); // THR output value remains unchanged
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[2].offset, 195); // value transferred
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[1].offset, -195); // value transferred
}
TEST_F(TrimsTest, MoveTrimsToOffsetsWithCrosstrimsAndTrimIdle)
{
// Trim idle only
// Cross trims
g_model.limitData[2].offset = 0;
g_model.limitData[1].offset = 0;
g_model.thrTrim = 1;
g_model.thrTrimSw = MIXSRC_TrimEle - MIXSRC_FIRST_TRIM;
ExpoData *expo = expoAddress(THR_STICK);
expo->carryTrim = TRIM_ELE;
expo = expoAddress(ELE_STICK);
expo->carryTrim = TRIM_THR;
anaInValues[THR_STICK] = -1024; // Min stick
setTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM, 100);
setTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM, -100);
evalMixes(1);
EXPECT_EQ(channelOutputs[2], -574); // THR output value is reflecting 100 ele trim idle
moveTrimsToOffsets();
// Trim affecting Throttle (now Ele because of crosstrims) should not be affected
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimEle - MIXSRC_FIRST_TRIM), 100); // unchanged
EXPECT_EQ(g_model.limitData[2].offset, 0); // THR chan offset unchanged
// Other trims should
EXPECT_EQ(getTrimValue(0, MIXSRC_TrimThr - MIXSRC_FIRST_TRIM), 0); // back to neutral
EXPECT_EQ(g_model.limitData[1].offset, -195); // Ele chan offset transfered
evalMixes(1);
EXPECT_EQ(channelOutputs[2], -574); // THR output value is still reflecting 100 trim idle
}
TEST_F(TrimsTest, InstantTrim)
{
anaInValues[AIL_STICK] = 50;