mirror of
https://github.com/iNavFlight/inav.git
synced 2025-07-23 00:05:28 +03:00
first cut
This commit is contained in:
parent
a695edb475
commit
8d26904048
11 changed files with 236 additions and 9 deletions
|
@ -281,6 +281,8 @@ main_sources(COMMON_SRC
|
|||
fc/firmware_update.h
|
||||
fc/firmware_update_common.c
|
||||
fc/firmware_update_common.h
|
||||
fc/multifunction.c
|
||||
fc/multifunction.h
|
||||
fc/rc_smoothing.c
|
||||
fc/rc_smoothing.h
|
||||
fc/rc_adjustments.c
|
||||
|
|
|
@ -174,6 +174,8 @@
|
|||
#define SYM_FLIGHT_MINS_REMAINING 0xDA // 218 Flight time (mins) remaining
|
||||
#define SYM_FLIGHT_HOURS_REMAINING 0xDB // 219 Flight time (hours) remaining
|
||||
#define SYM_GROUND_COURSE 0xDC // 220 Ground course
|
||||
#define SYM_ALERT 0xDD // 221 General alert symbol
|
||||
|
||||
#define SYM_CROSS_TRACK_ERROR 0xFC // 252 Cross track error
|
||||
|
||||
#define SYM_LOGO_START 0x101 // 257 to 297, INAV logo
|
||||
|
|
|
@ -365,7 +365,7 @@ static bool emergencyArmingCanOverrideArmingDisabled(void)
|
|||
|
||||
static bool emergencyArmingIsEnabled(void)
|
||||
{
|
||||
return emergencyArmingUpdate(IS_RC_MODE_ACTIVE(BOXARM)) && emergencyArmingCanOverrideArmingDisabled();
|
||||
return emergencyArmingUpdate(IS_RC_MODE_ACTIVE(BOXARM), false) && emergencyArmingCanOverrideArmingDisabled();
|
||||
}
|
||||
|
||||
static void processPilotAndFailSafeActions(float dT)
|
||||
|
@ -457,7 +457,7 @@ disarmReason_t getDisarmReason(void)
|
|||
return lastDisarmReason;
|
||||
}
|
||||
|
||||
bool emergencyArmingUpdate(bool armingSwitchIsOn)
|
||||
bool emergencyArmingUpdate(bool armingSwitchIsOn, bool forceArm)
|
||||
{
|
||||
if (ARMING_FLAG(ARMED)) {
|
||||
return false;
|
||||
|
@ -486,6 +486,10 @@ bool emergencyArmingUpdate(bool armingSwitchIsOn)
|
|||
toggle = true;
|
||||
}
|
||||
|
||||
if (forceArm) {
|
||||
counter = EMERGENCY_ARMING_MIN_ARM_COUNT + 1;
|
||||
}
|
||||
|
||||
return counter >= EMERGENCY_ARMING_MIN_ARM_COUNT;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ timeUs_t getLastDisarmTimeUs(void);
|
|||
void tryArm(void);
|
||||
disarmReason_t getDisarmReason(void);
|
||||
|
||||
bool emergencyArmingUpdate(bool armingSwitchIsOn);
|
||||
bool emergencyArmingUpdate(bool armingSwitchIsOn, bool forceArm);
|
||||
|
||||
bool areSensorsCalibrating(void);
|
||||
float getFlightTime(void);
|
||||
|
|
|
@ -97,6 +97,7 @@ static const box_t boxes[CHECKBOX_ITEM_COUNT + 1] = {
|
|||
{ .boxId = BOXPLANWPMISSION, .boxName = "WP PLANNER", .permanentId = 55 },
|
||||
{ .boxId = BOXSOARING, .boxName = "SOARING", .permanentId = 56 },
|
||||
{ .boxId = BOXCHANGEMISSION, .boxName = "MISSION CHANGE", .permanentId = 59 },
|
||||
{ .boxId = BOXMULTIFUNCTION, .boxName = "MULTI FUNCTION", .permanentId = 60 },
|
||||
{ .boxId = CHECKBOX_ITEM_COUNT, .boxName = NULL, .permanentId = 0xFF }
|
||||
};
|
||||
|
||||
|
@ -178,6 +179,7 @@ void initActiveBoxIds(void)
|
|||
RESET_BOX_ID_COUNT;
|
||||
ADD_ACTIVE_BOX(BOXARM);
|
||||
ADD_ACTIVE_BOX(BOXPREARM);
|
||||
ADD_ACTIVE_BOX(BOXMULTIFUNCTION);
|
||||
|
||||
if (sensors(SENSOR_ACC) && STATE(ALTITUDE_CONTROL)) {
|
||||
ADD_ACTIVE_BOX(BOXANGLE);
|
||||
|
@ -410,6 +412,7 @@ void packBoxModeFlags(boxBitmask_t * mspBoxModeFlags)
|
|||
#ifdef USE_MULTI_MISSION
|
||||
CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXCHANGEMISSION)), BOXCHANGEMISSION);
|
||||
#endif
|
||||
CHECK_ACTIVE_BOX(IS_ENABLED(IS_RC_MODE_ACTIVE(BOXMULTIFUNCTION)), BOXMULTIFUNCTION);
|
||||
|
||||
memset(mspBoxModeFlags, 0, sizeof(boxBitmask_t));
|
||||
for (uint32_t i = 0; i < activeBoxIdCount; i++) {
|
||||
|
|
87
src/main/fc/multifunction.c
Normal file
87
src/main/fc/multifunction.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* This file is part of INAV Project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms
|
||||
* of the GNU General Public License Version 3, as described below:
|
||||
*
|
||||
* This file is free software: you may copy, redistribute and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include "build/debug.h"
|
||||
#include "drivers/time.h"
|
||||
|
||||
#include "fc/fc_core.h"
|
||||
#include "fc/multifunction.h"
|
||||
#include "fc/rc_modes.h"
|
||||
|
||||
#include "io/osd.h"
|
||||
#include "navigation/navigation.h"
|
||||
|
||||
static void multiFunctionApply(multi_function_e selectedItem)
|
||||
{
|
||||
switch (selectedItem) {
|
||||
case MULTI_FUNC_NONE:
|
||||
return;
|
||||
case MULTI_FUNC_1:
|
||||
resetOsdWarningMask();
|
||||
break;
|
||||
case MULTI_FUNC_2:
|
||||
emergencyArmingUpdate(true, true);
|
||||
break;
|
||||
case MULTI_FUNC_COUNT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool multiFunctionSelection(multi_function_e * returnItem)
|
||||
{
|
||||
static timeMs_t startTimer;
|
||||
static timeMs_t selectTimer;
|
||||
static int8_t selectedItem = 0;
|
||||
static bool toggle = true;
|
||||
const timeMs_t currentTime = millis();
|
||||
|
||||
if (IS_RC_MODE_ACTIVE(BOXMULTIFUNCTION)) {
|
||||
if (selectTimer) {
|
||||
if (currentTime - selectTimer > 3000) {
|
||||
*returnItem = selectedItem;
|
||||
multiFunctionApply(selectedItem);
|
||||
selectTimer = 0;
|
||||
selectedItem = 0;
|
||||
return true;
|
||||
}
|
||||
} else if (toggle) {
|
||||
selectedItem++;
|
||||
selectedItem = selectedItem == MULTI_FUNC_COUNT ? 1 : selectedItem;
|
||||
selectTimer = currentTime;
|
||||
}
|
||||
startTimer = currentTime;
|
||||
toggle = false;
|
||||
} else if (startTimer) {
|
||||
selectTimer = 0;
|
||||
if (currentTime - startTimer > 2000) {
|
||||
startTimer = 0;
|
||||
selectedItem = 0;
|
||||
}
|
||||
toggle = true;
|
||||
}
|
||||
|
||||
*returnItem = selectedItem;
|
||||
return false;
|
||||
}
|
34
src/main/fc/multifunction.h
Normal file
34
src/main/fc/multifunction.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of INAV Project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms
|
||||
* of the GNU General Public License Version 3, as described below:
|
||||
*
|
||||
* This file is free software: you may copy, redistribute and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
MULTI_FUNC_NONE,
|
||||
MULTI_FUNC_1,
|
||||
MULTI_FUNC_2,
|
||||
MULTI_FUNC_COUNT,
|
||||
} multi_function_e;
|
||||
|
||||
bool multiFunctionSelection(multi_function_e * returnItem);
|
|
@ -223,7 +223,7 @@ void processRcStickPositions(bool isThrottleLow)
|
|||
rcDisarmTimeMs = currentTimeMs;
|
||||
tryArm();
|
||||
} else {
|
||||
emergencyArmingUpdate(armingSwitchIsActive);
|
||||
emergencyArmingUpdate(armingSwitchIsActive, false);
|
||||
// Disarming via ARM BOX
|
||||
// Don't disarm via switch if failsafe is active or receiver doesn't receive data - we can't trust receiver
|
||||
// and can't afford to risk disarming in the air
|
||||
|
|
|
@ -77,6 +77,7 @@ typedef enum {
|
|||
BOXUSER3 = 48,
|
||||
BOXUSER4 = 49,
|
||||
BOXCHANGEMISSION = 50,
|
||||
BOXMULTIFUNCTION = 51,
|
||||
CHECKBOX_ITEM_COUNT
|
||||
} boxId_e;
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ FILE_COMPILE_FOR_SPEED
|
|||
#include "fc/controlrate_profile.h"
|
||||
#include "fc/fc_core.h"
|
||||
#include "fc/fc_tasks.h"
|
||||
#include "fc/multifunction.h"
|
||||
#include "fc/rc_adjustments.h"
|
||||
#include "fc/rc_controls.h"
|
||||
#include "fc/rc_modes.h"
|
||||
|
@ -183,6 +184,9 @@ static bool fullRedraw = false;
|
|||
static uint8_t armState;
|
||||
static uint8_t statsPagesCheck = 0;
|
||||
|
||||
textAttributes_t osdGetMultiFunctionMessage(char *buff);
|
||||
static osd_warnings_status_flags_e osdWarningsMask = 0;
|
||||
|
||||
typedef struct osdMapData_s {
|
||||
uint32_t scale;
|
||||
char referenceSymbol;
|
||||
|
@ -1684,8 +1688,10 @@ static bool osdDrawSingleElement(uint8_t item)
|
|||
buff[1] = SYM_SAT_R;
|
||||
tfp_sprintf(buff + 2, "%2d", gpsSol.numSat);
|
||||
if (!STATE(GPS_FIX)) {
|
||||
if (getHwGPSStatus() == HW_SENSOR_UNAVAILABLE || getHwGPSStatus() == HW_SENSOR_UNHEALTHY) {
|
||||
strcpy(buff + 2, "X!");
|
||||
hardwareSensorStatus_e sensorStatus = getHwGPSStatus();
|
||||
if (sensorStatus == HW_SENSOR_UNAVAILABLE || sensorStatus == HW_SENSOR_UNHEALTHY) {
|
||||
buff[2] = SYM_ALERT;
|
||||
buff[3] = '\0';
|
||||
}
|
||||
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
|
||||
}
|
||||
|
@ -3267,6 +3273,12 @@ static bool osdDrawSingleElement(uint8_t item)
|
|||
}
|
||||
#endif // USE_ADC
|
||||
#endif // USE_POWER_LIMITS
|
||||
case OSD_MULTI_FUNCTION:
|
||||
{
|
||||
displayWrite(osdDisplayPort, elemPosX, elemPosY, " ");
|
||||
elemAttr = osdGetMultiFunctionMessage(buff);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
@ -4656,4 +4668,77 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter
|
|||
return elemAttr;
|
||||
}
|
||||
|
||||
void resetOsdWarningMask(void)
|
||||
{
|
||||
osdWarningsMask = 0;
|
||||
}
|
||||
|
||||
bool checkOsdWarning(bool condition, osd_warnings_status_flags_e warningType)
|
||||
{
|
||||
static timeMs_t newWarningStartTime = 0;
|
||||
const timeMs_t currentTimeMs = millis();
|
||||
|
||||
if (condition) {
|
||||
if (!(osdWarningsMask & warningType)) {
|
||||
newWarningStartTime = currentTimeMs;
|
||||
osdWarningsMask |= warningType;
|
||||
}
|
||||
if (currentTimeMs - newWarningStartTime < 10000) { // Display new warnings for 10s
|
||||
return true;
|
||||
}
|
||||
} else if (osdWarningsMask & warningType) {
|
||||
osdWarningsMask ^= warningType;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
textAttributes_t osdGetMultiFunctionMessage(char *buff)
|
||||
{
|
||||
textAttributes_t elemAttr = TEXT_ATTRIBUTES_NONE;
|
||||
uint8_t warningCount = BITCOUNT(osdWarningsMask);
|
||||
|
||||
multi_function_e multiFuncItem;
|
||||
multiFunctionSelection(&multiFuncItem);
|
||||
if (multiFuncItem) {
|
||||
switch (multiFuncItem) {
|
||||
case MULTI_FUNC_NONE:
|
||||
case MULTI_FUNC_1:
|
||||
strcpy(buff, warningCount ? "WARNINGS " : "0 WARNINGS");
|
||||
break;
|
||||
case MULTI_FUNC_2:
|
||||
strcpy(buff, "EMERG ARM ");
|
||||
break;
|
||||
case MULTI_FUNC_COUNT:
|
||||
break;
|
||||
}
|
||||
|
||||
return elemAttr;
|
||||
}
|
||||
|
||||
/* WARNINGS --------------------------------------------- */
|
||||
const char *messages[2];
|
||||
const char *message = NULL;
|
||||
uint8_t messageCount = 0;
|
||||
|
||||
if (checkOsdWarning(!STATE(GPS_FIX), OSD_WARN_1)) {
|
||||
hardwareSensorStatus_e sensorStatus = getHwGPSStatus();
|
||||
bool gpsFailed = sensorStatus == HW_SENSOR_UNAVAILABLE || sensorStatus == HW_SENSOR_UNHEALTHY;
|
||||
messages[messageCount++] = gpsFailed ? "GPS FAILED" : "NO GPS FIX";
|
||||
}
|
||||
|
||||
if (messageCount) {
|
||||
message = messages[OSD_ALTERNATING_CHOICES(2000, messageCount)]; // display each warning for 2s
|
||||
strcpy(buff, message);
|
||||
TEXT_ATTRIBUTES_ADD_BLINK(elemAttr);
|
||||
return elemAttr;
|
||||
} else if (warningCount) {
|
||||
buff[0] = SYM_ALERT;
|
||||
tfp_sprintf(buff + 1, "%u", warningCount);
|
||||
return elemAttr;
|
||||
}
|
||||
/* WARNINGS --------------------------------------------- */
|
||||
|
||||
return elemAttr;
|
||||
}
|
||||
#endif // OSD
|
||||
|
|
|
@ -270,6 +270,7 @@ typedef enum {
|
|||
OSD_NAV_WP_MULTI_MISSION_INDEX,
|
||||
OSD_GROUND_COURSE, // 140
|
||||
OSD_CROSS_TRACK_ERROR,
|
||||
OSD_MULTI_FUNCTION,
|
||||
OSD_ITEM_COUNT // MUST BE LAST
|
||||
} osd_items_e;
|
||||
|
||||
|
@ -328,6 +329,12 @@ typedef enum {
|
|||
OSD_CRSF_LQ_TYPE3
|
||||
} osd_crsf_lq_format_e;
|
||||
|
||||
typedef enum {
|
||||
OSD_WARN_NONE = 0,
|
||||
OSD_WARN_1 = 1 << 0,
|
||||
OSD_WARN_2 = 1 << 1,
|
||||
} osd_warnings_status_flags_e;
|
||||
|
||||
typedef struct osdLayoutsConfig_s {
|
||||
// Layouts
|
||||
uint16_t item_pos[OSD_LAYOUT_COUNT][OSD_ITEM_COUNT];
|
||||
|
@ -473,6 +480,8 @@ int32_t osdGetAltitude(void);
|
|||
void osdStartedSaveProcess(void);
|
||||
void osdShowEEPROMSavedNotification(void);
|
||||
|
||||
void resetOsdWarningMask(void);
|
||||
|
||||
void osdCrosshairPosition(uint8_t *x, uint8_t *y);
|
||||
bool osdFormatCentiNumber(char *buff, int32_t centivalue, uint32_t scale, int maxDecimals, int maxScaledDecimals, int length);
|
||||
void osdFormatAltitudeSymbol(char *buff, int32_t alt);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue