Skip to content

Commit a260b86

Browse files
committed
CR141 + CR142
1 parent f12b2bf commit a260b86

File tree

7 files changed

+108
-45
lines changed

7 files changed

+108
-45
lines changed

docs/Settings.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4022,6 +4022,16 @@ P gain of altitude PID controller (Multirotor)
40224022

40234023
---
40244024

4025+
### nav_mc_toiletbowl_detection
4026+
4027+
Sets sensitivity of toilet bowling detection for multirotors. On detection a heading correction is applied which should stop the toilet bowling. A setting of 2 works well for 5 inch multirotors. Increasing the setting will reduce sensitivity and delay detection. Set to 0 to disable. (Toilet bowling occurs most obviously during position hold when an inaccurate compass heading causes a rapidly increasing fast sweeping bowl shaped flight path).
4028+
4029+
| Default | Min | Max |
4030+
| --- | --- | --- |
4031+
| 0 | 0 | 20 |
4032+
4033+
---
4034+
40254035
### nav_mc_vel_xy_d
40264036

40274037
D gain of Position-Rate (Velocity to Acceleration) PID controller. It can damp P and I. Increasing D might help when drone overshoots target.

src/main/io/osd.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5989,15 +5989,15 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter
59895989

59905990
/* WARNING: ensure number of messages returned does not exceed messages array size
59915991
* Messages array set 1 larger than maximum expected message count of 6 */
5992-
const char *messages[7];
5992+
const char *messages[8];
59935993
unsigned messageCount = 0;
59945994

59955995
const char *failsafeInfoMessage = NULL;
59965996
const char *invertedInfoMessage = NULL;
59975997

59985998
if (ARMING_FLAG(ARMED)) {
59995999
if (FLIGHT_MODE(FAILSAFE_MODE) || FLIGHT_MODE(NAV_RTH_MODE) || FLIGHT_MODE(NAV_WP_MODE) || navigationIsExecutingAnEmergencyLanding()) {
6000-
/* ADDS MAXIMUM OF 3 MESSAGES TO TOTAL NORMALLY, 5 MESSAGES DURING FAILSAFE */
6000+
/* ADDS MAXIMUM OF 4 MESSAGES TO TOTAL NORMALLY, 6 MESSAGES DURING FAILSAFE */
60016001
if (navGetCurrentStateFlags() & NAV_AUTO_WP_DONE) {
60026002
messages[messageCount++] = STATE(LANDING_DETECTED) ? OSD_MESSAGE_STR(OSD_MSG_WP_LANDED) : OSD_MESSAGE_STR(OSD_MSG_WP_FINISHED);
60036003
} else if (NAV_Status.state == MW_NAV_STATE_WP_ENROUTE) {
@@ -6063,7 +6063,7 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter
60636063
messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_LANDED);
60646064
} else {
60656065
/* Messages shown only when Failsafe, WP, RTH or Emergency Landing not active and landed state inactive */
6066-
/* ADDS MAXIMUM OF 4 MESSAGES TO TOTAL */
6066+
/* ADDS MAXIMUM OF 5 MESSAGES TO TOTAL */
60676067
#ifdef USE_GEOZONE
60686068
char buf[12], buf1[12];
60696069
switch (geozone.messageState) {
@@ -6181,8 +6181,13 @@ textAttributes_t osdGetSystemMessage(char *buff, size_t buff_size, bool isCenter
61816181
}
61826182
}
61836183
}
6184+
// CR142
6185+
if (posControl.flags.posEstimateDegraded) {
6186+
messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_POSEST_DEGRADED);
6187+
}
6188+
// CR142
61846189
// CR141
6185-
if (STATE(MULTIROTOR) && isNavHoldPositionActive() && toiletBowlingHeadingCorrection) {
6190+
if (STATE(MULTIROTOR) && mcToiletBowlingHeadingCorrection) {
61866191
messages[messageCount++] = OSD_MESSAGE_STR(OSD_MSG_TOILET_BOWL);
61876192
}
61886193
// CR141

src/main/io/osd.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@
123123
#define OSD_MSG_ANGLEHOLD_PITCH "(ANGLEHOLD PITCH)"
124124
#define OSD_MSG_ANGLEHOLD_LEVEL "(ANGLEHOLD LEVEL)"
125125
#define OSD_MSG_MOVE_STICKS "MOVE STICKS TO ABORT"
126-
#define OSD_MSG_TOILET_BOWL "TOILET BOWLING !" // CR141
126+
#define OSD_MSG_TOILET_BOWL "!TOILET BOWLING!" // CR141
127+
#define OSD_MSG_POSEST_DEGRADED "!POSITION ACCURACY POOR!" // CR142
128+
127129

128130
#ifdef USE_DEV_TOOLS
129131
#define OSD_MSG_GRD_TEST_MODE "GRD TEST > MOTORS DISABLED"

src/main/navigation/navigation.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ static navWapointHeading_t wpHeadingControl;
253253
navigationPosControl_t posControl;
254254
navSystemStatus_t NAV_Status;
255255
static bool landingDetectorIsActive = false;
256-
int16_t toiletBowlingHeadingCorrection; // Indicates toilet bowling detected multirotor // CR141
256+
int16_t mcToiletBowlingHeadingCorrection; // Indicates toilet bowling detected multirotor // CR141
257257

258258
EXTENDED_FASTRAM multicopterPosXyCoefficients_t multicopterPosXyCoefficients;
259259

@@ -1291,6 +1291,7 @@ static navigationFSMEvent_t navOnEnteringState_NAV_STATE_IDLE(navigationFSMState
12911291
resetAltitudeController(false);
12921292
resetHeadingController();
12931293
resetPositionController();
1294+
mcToiletBowlingHeadingCorrection = 0; // CR141
12941295
#ifdef USE_FW_AUTOLAND
12951296
resetFwAutoland();
12961297
#endif
@@ -2921,9 +2922,9 @@ void updateActualHeading(bool headingValid, int32_t newHeading, int32_t newGroun
29212922
if (STATE(MULTIROTOR) && IS_RC_MODE_ACTIVE(BOXBEEPERON)) {
29222923
newHeading = wrap_36000(newHeading + 9000);
29232924
} else {
2924-
toiletBowlingHeadingCorrection = 0;
2925+
mcToiletBowlingHeadingCorrection = 0;
29252926
}
2926-
// imuNavCompassSanity(toiletBowlingHeadingCorrection == 0);
2927+
// imuNavCompassSanity(mcToiletBowlingHeadingCorrection == 0);
29272928
// CR141
29282929
navigationEstimateStatus_e newEstHeading = headingValid ? EST_TRUSTED : EST_NONE;
29292930

src/main/navigation/navigation_multicopter.c

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -570,50 +570,54 @@ static float computeVelocityScale(
570570
// CR141
571571
static void checkForToiletBowling(void)
572572
{
573-
bool isHoldingPosition = ((FLIGHT_MODE(NAV_COURSE_HOLD_MODE) && posControl.cruise.multicopterSpeed < 50) || navGetCurrentStateFlags() & NAV_CTL_HOLD);
573+
// bool isHoldingPosition = ((FLIGHT_MODE(NAV_COURSE_HOLD_MODE) && posControl.cruise.multicopterSpeed < 50) || navGetCurrentStateFlags() & NAV_CTL_HOLD);
574+
bool isHoldingPosition = FLIGHT_MODE(NAV_COURSE_HOLD_MODE) || navGetCurrentStateFlags() & NAV_CTL_HOLD;
575+
uint16_t distanceToHoldPoint = calculateDistanceToDestination(&posControl.desiredState.pos);
574576

575-
if (navConfig()->mc.toiletbowl_detection == 0 || !isHoldingPosition || posControl.flags.isAdjustingPosition) {
576-
// toiletBowlingHeadingCorrection = 0;
577+
if (posControl.actualState.velXY < 100 || distanceToHoldPoint < 100 || !isHoldingPosition) { // || posControl.flags.isAdjustingPosition) {
577578
return;
578579
}
579580

580581
static timeMs_t startTime = 0;
581582

582-
uint16_t courseToHoldPoint = calculateBearingToDestination(&posControl.desiredState.pos);
583-
int16_t courseError = wrap_18000(courseToHoldPoint - 10 * gpsSol.groundCourse);
583+
int16_t courseError = wrap_18000(calculateBearingToDestination(&posControl.desiredState.pos) - 10 * gpsSol.groundCourse);
584584
bool courseErrorCheck = ABS(courseError) > 3000 && ABS(courseError) < 15500;
585585

586-
uint16_t distanceToHoldPoint = calculateDistanceToDestination(&posControl.desiredState.pos);
587586
bool distanceSpeedCheck = posControl.actualState.velXY * distanceToHoldPoint > (navConfig()->mc.toiletbowl_detection * 10000);
588587

589-
DEBUG_SET(DEBUG_ALWAYS, 0, courseError);
590-
DEBUG_SET(DEBUG_ALWAYS, 1, distanceToHoldPoint);
591-
DEBUG_SET(DEBUG_ALWAYS, 2, posControl.actualState.velXY * distanceToHoldPoint);
592-
DEBUG_SET(DEBUG_ALWAYS, 3, toiletBowlingHeadingCorrection);
593-
DEBUG_SET(DEBUG_ALWAYS, 5, posControl.actualState.velXY);
594-
DEBUG_SET(DEBUG_ALWAYS, 6, courseToHoldPoint);
595-
DEBUG_SET(DEBUG_ALWAYS, 7, posControl.actualState.yaw);
596-
597-
if (toiletBowlingHeadingCorrection) {
598-
uint16_t correctedHeading = wrap_36000(posControl.actualState.yaw - 0.67 * toiletBowlingHeadingCorrection);
599-
posControl.actualState.sinYaw = sin_approx(CENTIDEGREES_TO_RADIANS(correctedHeading));
600-
posControl.actualState.cosYaw = cos_approx(CENTIDEGREES_TO_RADIANS(correctedHeading));
601-
DEBUG_SET(DEBUG_ALWAYS, 4, correctedHeading);
602-
} else if (posControl.actualState.velXY > 100 && distanceToHoldPoint > 100 && courseErrorCheck && distanceSpeedCheck) {
588+
if (courseErrorCheck && distanceSpeedCheck) {
603589
if (startTime == 0) {
604590
startTime = millis();
605591
} else if (millis() - startTime > 1000) {
606-
// Try to correct heading error
607-
toiletBowlingHeadingCorrection = courseError;
592+
mcToiletBowlingHeadingCorrection = 0.67 * courseError; // Try to correct heading error
608593
}
609594
} else {
610595
startTime = 0;
611596
}
597+
598+
// DEBUG_SET(DEBUG_ALWAYS, 0, courseError);
599+
// DEBUG_SET(DEBUG_ALWAYS, 2, posControl.actualState.velXY * distanceToHoldPoint);
612600
}
613601
// CR141
614602
static void updatePositionAccelController_MC(timeDelta_t deltaMicros, float maxAccelLimit) // , const float maxSpeed) CR47
615603
{
616-
checkForToiletBowling(); // CR141
604+
// CR141
605+
// DEBUG_SET(DEBUG_ALWAYS, 1, calculateDistanceToDestination(&posControl.desiredState.pos));
606+
// DEBUG_SET(DEBUG_ALWAYS, 3, mcToiletBowlingHeadingCorrection);
607+
// DEBUG_SET(DEBUG_ALWAYS, 5, posControl.actualState.velXY);
608+
// DEBUG_SET(DEBUG_ALWAYS, 6, calculateBearingToDestination(&posControl.desiredState.pos));
609+
// DEBUG_SET(DEBUG_ALWAYS, 7, posControl.actualState.yaw);
610+
if (navConfig()->mc.toiletbowl_detection) {
611+
if (mcToiletBowlingHeadingCorrection) {
612+
uint16_t correctedHeading = wrap_36000(posControl.actualState.yaw - mcToiletBowlingHeadingCorrection);
613+
posControl.actualState.sinYaw = sin_approx(CENTIDEGREES_TO_RADIANS(correctedHeading));
614+
posControl.actualState.cosYaw = cos_approx(CENTIDEGREES_TO_RADIANS(correctedHeading));
615+
// DEBUG_SET(DEBUG_ALWAYS, 4, correctedHeading);
616+
} else {
617+
checkForToiletBowling();
618+
}
619+
}
620+
// CR141
617621

618622
const float measurementX = navGetCurrentActualPositionAndVelocity()->vel.x;
619623
const float measurementY = navGetCurrentActualPositionAndVelocity()->vel.y;
@@ -905,7 +909,11 @@ bool isMulticopterLandingDetected(void)
905909
bool startCondition = (navGetCurrentStateFlags() & (NAV_CTL_LAND | NAV_CTL_EMERG))
906910
|| (FLIGHT_MODE(FAILSAFE_MODE) && !FLIGHT_MODE(NAV_WP_MODE) && throttleIsBelowMidHover)
907911
|| (!navigationIsFlyingAutonomousMode() && throttleStickIsLow());
908-
912+
// CR137
913+
if (FLIGHT_MODE(NAV_RTH_MODE)) {
914+
startCondition = startCondition && posControl.actualState.abs.pos.z < 3000;
915+
}
916+
// CR137
909917
static timeMs_t landingDetectorStartedAt;
910918

911919
if (!startCondition || posControl.flags.resetLandingDetector) {

src/main/navigation/navigation_pos_estimator.c

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,11 @@ static void updateIMUTopic(timeUs_t currentTimeUs)
406406
posEstimator.imu.accelNEU.y = accelReading.y + posEstimator.imu.accelBias.y;
407407
posEstimator.imu.accelNEU.z = accelReading.z + posEstimator.imu.accelBias.z;
408408
// CR140
409+
// CR142
410+
if (IS_RC_MODE_ACTIVE(BOXBEEPERON)) {
411+
posEstimator.imu.accelNEU.z += -navConfig()->mc.max_auto_climb_rate;
412+
}
413+
// CR142
409414

410415
/* When unarmed, assume that accelerometer should measure 1G. Use that to correct accelerometer gain */
411416
if (gyroConfig()->init_gyro_cal_enabled) {
@@ -530,7 +535,7 @@ static void estimationPredict(estimationContext_t * ctx)
530535
// }
531536
// CR131
532537
// DEBUG_SET(DEBUG_ALWAYS, 7, posEstimator.est.vel.z);
533-
// DEBUG_SET(DEBUG_ALWAYS, 7, posEstimator.imu.accelNEU.z);
538+
DEBUG_SET(DEBUG_ALWAYS, 7, posEstimator.imu.accelNEU.z);
534539
}
535540

536541
/* Prediction step: XY-axis */
@@ -707,9 +712,8 @@ static bool estimationCalculateCorrection_XY_GPS(estimationContext_t * ctx)
707712
return false;
708713
}
709714

710-
static void estimationCalculateGroundCourse(timeUs_t currentTimeUs)
715+
static void estimationCalculateGroundCourse(void)
711716
{
712-
UNUSED(currentTimeUs);
713717
if ((STATE(GPS_FIX)
714718
#ifdef USE_GPS_FIX_ESTIMATION
715719
|| STATE(GPS_ESTIMATED_FIX)
@@ -719,7 +723,34 @@ static void estimationCalculateGroundCourse(timeUs_t currentTimeUs)
719723
posEstimator.est.cog = CENTIDEGREES_TO_DECIDEGREES(groundCourse);
720724
}
721725
}
726+
// CR142
727+
static void checkEstimateSanity(timeMs_t currentTimeMs)
728+
{
729+
static timeMs_t startTime[3];
730+
static bool useGpsRecovery = false;
731+
uint8_t axis;
732+
733+
for (axis = 0; axis < XYZ_AXIS_COUNT; axis++) {
734+
bool estimateSanityDegraded = ABS(posEstimator.est.vel.v[axis] - posEstimator.gps.vel.v[axis]) > 200 ||
735+
ABS(posEstimator.est.pos.v[axis] - posEstimator.gps.pos.v[axis]) > 1000;
736+
737+
if (estimateSanityDegraded || useGpsRecovery) {
738+
if (startTime[axis] == 0) {
739+
startTime[axis] = currentTimeMs;
740+
} else if (currentTimeMs - startTime[axis] > 3000) {
741+
posEstimator.imu.accelBias.v[axis] = 0;
742+
posEstimator.est.vel.v[axis] = posEstimator.gps.vel.v[axis];
743+
posEstimator.est.pos.v[axis] = posEstimator.gps.pos.v[axis];
744+
useGpsRecovery = currentTimeMs - startTime[axis] < 13000;
745+
}
746+
} else {
747+
startTime[axis] = 0;
748+
}
722749

750+
posControl.flags.posEstimateDegraded = useGpsRecovery;
751+
}
752+
}
753+
// CR142
723754
/**
724755
* Calculate next estimate using IMU and apply corrections from reference sensors (GPS, BARO etc)
725756
* Function is called at main loop rate
@@ -780,7 +811,11 @@ static void updateEstimatedTopic(timeUs_t currentTimeUs)
780811
// Apply corrections
781812
vectorAdd(&posEstimator.est.pos, &posEstimator.est.pos, &ctx.estPosCorr);
782813
vectorAdd(&posEstimator.est.vel, &posEstimator.est.vel, &ctx.estVelCorr);
783-
814+
// CR142
815+
if (ctx.newFlags & EST_XY_VALID && ctx.newFlags & EST_GPS_XY_VALID && ctx.newFlags & EST_Z_VALID && ctx.newFlags & EST_GPS_Z_VALID) {
816+
checkEstimateSanity(US2MS(currentTimeUs));
817+
}
818+
// CR142
784819
/* Correct accelerometer bias */
785820
const float w_acc_bias = positionEstimationConfig()->w_acc_bias;
786821
if (w_acc_bias > 0.0f) {
@@ -796,7 +831,7 @@ static void updateEstimatedTopic(timeUs_t currentTimeUs)
796831
}
797832
// CR140
798833
/* Update ground course */
799-
estimationCalculateGroundCourse(currentTimeUs);
834+
estimationCalculateGroundCourse();
800835

801836
/* Update uncertainty */
802837
posEstimator.est.eph = ctx.newEPH;
@@ -805,13 +840,13 @@ static void updateEstimatedTopic(timeUs_t currentTimeUs)
805840
// Keep flags for further usage
806841
posEstimator.flags = ctx.newFlags;
807842

808-
// DEBUG_SET(DEBUG_ALWAYS, 0, posEstimator.imu.accelBias.z * 1000);
809-
// DEBUG_SET(DEBUG_ALWAYS, 1, ctx.accBiasCorr.z);
810-
// DEBUG_SET(DEBUG_ALWAYS, 2, ctx.estPosCorr.z * 1000);
811-
// DEBUG_SET(DEBUG_ALWAYS, 3, ctx.estVelCorr.z * 1000);
812-
// DEBUG_SET(DEBUG_ALWAYS, 4, posEstimator.imu.accWeightFactor * 100);
813-
// DEBUG_SET(DEBUG_ALWAYS, 5, posEstimator.baro.baroAltRate);
814-
// DEBUG_SET(DEBUG_ALWAYS, 6, posEstimator.baro.alt);
843+
DEBUG_SET(DEBUG_ALWAYS, 0, posEstimator.imu.accelBias.z * 1000);
844+
DEBUG_SET(DEBUG_ALWAYS, 1, ctx.accBiasCorr.z);
845+
DEBUG_SET(DEBUG_ALWAYS, 2, ctx.estPosCorr.z * 1000);
846+
DEBUG_SET(DEBUG_ALWAYS, 3, ctx.estVelCorr.z * 1000);
847+
DEBUG_SET(DEBUG_ALWAYS, 4, posEstimator.imu.accWeightFactor * 100);
848+
DEBUG_SET(DEBUG_ALWAYS, 5, posEstimator.baro.baroAltRate);
849+
DEBUG_SET(DEBUG_ALWAYS, 6, posEstimator.baro.alt);
815850
}
816851

817852
/**

src/main/navigation/navigation_private.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ typedef struct navigationFlags_s {
9090
navigationEstimateStatus_e estAglStatus;
9191
navigationEstimateStatus_e estHeadingStatus; // Indicate valid heading - wither mag or GPS at certain speed on airplane
9292
bool gpsCfEstimatedAltitudeMismatch; // Indicates a mismatch between GPS altitude and estimated altitude
93+
94+
bool posEstimateDegraded; // CR142
9395

9496
climbRateToAltitudeControllerMode_e rocToAltMode;
9597

@@ -527,7 +529,7 @@ PG_DECLARE_ARRAY(navWaypoint_t, NAV_MAX_WAYPOINTS, nonVolatileWaypointList);
527529

528530
extern navigationPosControl_t posControl;
529531
extern multicopterPosXyCoefficients_t multicopterPosXyCoefficients;
530-
extern int16_t toiletBowlingHeadingCorrection; // Indicates toilet bowling detected multirotor // CR141
532+
extern int16_t mcToiletBowlingHeadingCorrection; // Indicates toilet bowling detected multirotor // CR141
531533

532534
/* Internally used functions */
533535
const navEstimatedPosVel_t * navGetCurrentActualPositionAndVelocity(void);

0 commit comments

Comments
 (0)