Skip to content

Commit 0b92214

Browse files
authored
Merge pull request #11529 from breadoven/abo_magless_heading_zero
Allow yaw reset to north when disarmed - for multirotors with no compass
2 parents 451c95e + 9cf6945 commit 0b92214

6 files changed

Lines changed: 94 additions & 60 deletions

File tree

docs/Controls.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ The stick positions are combined to activate different functions:
3131
| Battery profile 3 | HIGH | LOW | CENTER | HIGH |
3232
| Calibrate Gyro | LOW | LOW | LOW | CENTER |
3333
| Calibrate Acc | HIGH | LOW | LOW | CENTER |
34-
| Calibrate Mag/Compass | HIGH | HIGH | LOW | CENTER |
34+
| Calibrate Compass/Zero Yaw | HIGH | HIGH | LOW | CENTER |
3535
| Trim Acc Left | HIGH | CENTER | CENTER | LOW |
3636
| Trim Acc Right | HIGH | CENTER | CENTER | HIGH |
3737
| Trim Acc Forwards | HIGH | CENTER | HIGH | CENTER |
@@ -52,6 +52,14 @@ The stick positions are combined to activate different functions:
5252
For graphical stick position in all transmitter modes, check out [this page](https://www.mrd-rc.com/tutorials-tools-and-testing/inav-flight/inav-stick-commands-for-all-transmitter-modes/).
5353
![Stick Positions](assets/images/StickPositions.png)
5454

55+
## Compass Calibration and Yaw Zero Reset
56+
57+
The stick function `Calibrate Compass/Zero Yaw` provides 2 functions depending on whether or not a compass is available.
58+
59+
If a compass is available the stick function initiates the compass calibration routine.
60+
61+
If no compass is available the stick function will reset the current yaw/heading estimate to zero (North) and also set the heading as trusted. This is useful on multirotors, allowing the craft yaw/heading to be correctly aligned to actual North simply by physically pointing the craft North then using the stick function to zero the yaw estimate. Since this also sets the heading as trusted Nav modes reliant on heading will be available immediately after arming without the need to fly fast enough to obtain a valid heading from GPS ground course.
62+
5563
## Yaw control
5664

5765
While arming/disarming with sticks, your yaw stick will be moving to extreme values. In order to prevent your craft from trying to yaw during arming/disarming while on the ground, your yaw input will not cause the craft to yaw when the throttle is LOW (i.e. below the `min_check` setting).

src/main/fc/multifunction.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ static void multiFunctionApply(multi_function_e selectedItem)
7070
if (!ARMING_FLAG(ARMED)) {
7171
emergencyArmingUpdate(true, true);
7272
}
73+
break;
74+
case MULTI_FUNC_6: // Calibrate compass/Zero yaw heading
75+
#if defined(USE_GPS) || defined(USE_MAG)
76+
ENABLE_STATE(CALIBRATE_MAG);
77+
#endif
78+
break;
7379
case MULTI_FUNC_END:
7480
break;
7581
}

src/main/fc/multifunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ typedef enum {
5454
MULTI_FUNC_3,
5555
MULTI_FUNC_4,
5656
MULTI_FUNC_5,
57+
MULTI_FUNC_6,
5758
MULTI_FUNC_END,
5859
} multi_function_e;
5960

src/main/flight/imu.c

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#endif
5757

5858
#include "io/gps.h"
59+
#include "io/beeper.h"
5960

6061
#include "sensors/acceleration.h"
6162
#include "sensors/barometer.h"
@@ -85,7 +86,7 @@
8586
FASTRAM fpVector3_t imuMeasuredAccelBF;
8687
FASTRAM fpVector3_t imuMeasuredRotationBF;
8788
//centrifugal force compensated using gps
88-
FASTRAM fpVector3_t compansatedGravityBF;// cm/s/s
89+
FASTRAM fpVector3_t compensatedGravityBF;// cm/s/s
8990

9091
STATIC_FASTRAM float smallAngleCosZ;
9192

@@ -173,8 +174,7 @@ void imuConfigure(void)
173174
* 1000× per second; the kP gains only change when the user saves settings,
174175
* so computing it here (called once per save) avoids one add, one multiply,
175176
* and one divide on every PID cycle. */
176-
imuRuntimeConfig.dcm_i_limit = DEGREES_TO_RADIANS(2.0f)
177-
* (imuRuntimeConfig.dcm_kp_acc + imuRuntimeConfig.dcm_kp_mag) * 0.5f;
177+
imuRuntimeConfig.dcm_i_limit = DEGREES_TO_RADIANS(2.0f) * (imuRuntimeConfig.dcm_kp_acc + imuRuntimeConfig.dcm_kp_mag) * 0.5f;
178178
}
179179

180180
void imuInit(void)
@@ -192,7 +192,7 @@ void imuInit(void)
192192
// Create magnetic declination matrix
193193
#ifdef USE_MAG
194194
const int deg = compassConfig()->mag_declination / 100;
195-
const int min = compassConfig()->mag_declination % 100;
195+
const int min = compassConfig()->mag_declination % 100;
196196
#else
197197
const int deg = 0;
198198
const int min = 0;
@@ -362,7 +362,7 @@ static float imuCalculateMcCogAccWeight(void)
362362
{
363363
fpVector3_t accBFNorm;
364364
vectorScale(&accBFNorm, &imuMeasuredAccelBFFiltered, 1.0f / GRAVITY_CMSS);
365-
float wCoGAcc = constrainf((accBFNorm.z - 1.0f)* 2, 0.0f, 1.0f); //z direction is verified via SITL
365+
float wCoGAcc = constrainf((accBFNorm.z - 1.0f) * 2.0f, 0.0f, 1.0f); //z direction is verified via SITL
366366
wCoGAcc = wCoGAcc * imuCalculateAccelerometerWeightRateIgnore(4.0f); //reduce weight when fast angular rate, gps acc is considered lagging
367367
return wCoGAcc;
368368
}
@@ -437,7 +437,7 @@ static void imuMahonyAHRSupdate(float dt, const fpVector3_t * gyroBF, const fpVe
437437
//vForward as trust vector
438438
if (STATE(MULTIROTOR) && (!isMixerTransitionMixing)){
439439
vForward.z = 1.0f;
440-
}else{
440+
} else {
441441
vForward.x = 1.0f;
442442
}
443443
fpVector3_t vHeadingEF;
@@ -448,23 +448,22 @@ static void imuMahonyAHRSupdate(float dt, const fpVector3_t * gyroBF, const fpVe
448448
float airSpeed = gpsSol.groundSpeed;
449449
#if defined(USE_WIND_ESTIMATOR)
450450
// remove wind elements in vCoGlocal for better heading estimation
451-
if (isEstimatedWindSpeedValid() && imuConfig()->gps_yaw_windcomp)
452-
{
451+
if (isEstimatedWindSpeedValid() && imuConfig()->gps_yaw_windcomp) {
453452
vectorScale(&vCoGlocal, &vCoGlocal, gpsSol.groundSpeed);
454453
vCoGlocal.x += getEstimatedWindSpeed(X);
455454
vCoGlocal.y -= getEstimatedWindSpeed(Y);
456455
airSpeed = fast_fsqrtf(vectorNormSquared(&vCoGlocal));
457456
}
458457
#endif
459-
wCoG *= scaleRangef(constrainf((airSpeed+gpsSol.groundSpeed)/2, 400, 1000), 400, 1000, 0.0f, 1.0f);
458+
wCoG *= scaleRangef(constrainf((airSpeed+gpsSol.groundSpeed) / 2.0f, 400.0f, 1000.0f), 400.0f, 1000.0f, 0.0f, 1.0f);
460459
} else { //vCOG is not avaliable and vCOGAcc is avaliable, set the weight of vCOG to zero
461460
wCoG = 0.0f;
462461
}
463-
if (STATE(MULTIROTOR)){
462+
if (STATE(MULTIROTOR)) {
464463
//when multicopter`s orientation or speed is changing rapidly. less weight on gps heading
465464
wCoG *= imuCalculateMcCogWeight();
466465
//handle acc based vector
467-
if(vCOGAcc){
466+
if (vCOGAcc) {
468467
float wCoGAcc = imuCalculateMcCogAccWeight();//stronger weight on acc if body frame z axis greate than 1G
469468
if (wCoGAcc > wCoG){
470469
//when copter is accelerating use gps acc vector instead of gps speed vector
@@ -627,8 +626,7 @@ STATIC_UNIT_TESTED void imuUpdateEulerAngles(void)
627626
attitude.values.yaw = RADIANS_TO_DECIDEGREES(-atan2_approx(rMat[1][0], rMat[0][0]));
628627
}
629628

630-
if (attitude.values.yaw < 0)
631-
attitude.values.yaw += 3600;
629+
if (attitude.values.yaw < 0) attitude.values.yaw += 3600;
632630

633631
/* Update small angle state */
634632
if (calculateCosTiltAngle() > smallAngleCosZ) {
@@ -667,23 +665,17 @@ static float imuCalculateAccelerometerWeightRateIgnore(const float acc_ignore_sl
667665
// Default - don't apply rate/ignore scaling
668666
float accWeight_RateIgnore = 1.0f;
669667

670-
if (ARMING_FLAG(ARMED) && imuConfig()->acc_ignore_rate)
671-
{
668+
if (ARMING_FLAG(ARMED) && imuConfig()->acc_ignore_rate) {
672669
float rotRateMagnitude = fast_fsqrtf(vectorNormSquared(&imuMeasuredRotationBFFiltered));
673670
rotRateMagnitude = rotRateMagnitude / (acc_ignore_slope_multipiler + 0.001f);
674-
if (imuConfig()->acc_ignore_slope)
675-
{
671+
672+
if (imuConfig()->acc_ignore_slope) {
676673
const float rateSlopeMin = DEGREES_TO_RADIANS((imuConfig()->acc_ignore_rate - imuConfig()->acc_ignore_slope));
677674
const float rateSlopeMax = DEGREES_TO_RADIANS((imuConfig()->acc_ignore_rate + imuConfig()->acc_ignore_slope));
678675

679676
accWeight_RateIgnore = scaleRangef(constrainf(rotRateMagnitude, rateSlopeMin, rateSlopeMax), rateSlopeMin, rateSlopeMax, 1.0f, 0.0f);
680-
}
681-
else
682-
{
683-
if (rotRateMagnitude > DEGREES_TO_RADIANS(imuConfig()->acc_ignore_rate))
684-
{
685-
accWeight_RateIgnore = 0.0f;
686-
}
677+
} else if (rotRateMagnitude > DEGREES_TO_RADIANS(imuConfig()->acc_ignore_rate)) {
678+
accWeight_RateIgnore = 0.0f;
687679
}
688680
}
689681

@@ -696,7 +688,7 @@ static void imuCalculateFilters(float dT)
696688
imuMeasuredRotationBFFiltered.x = pt1FilterApply4(&rotRateFilterX, imuMeasuredRotationBF.x, IMU_ROTATION_LPF, dT);
697689
imuMeasuredRotationBFFiltered.y = pt1FilterApply4(&rotRateFilterY, imuMeasuredRotationBF.y, IMU_ROTATION_LPF, dT);
698690
imuMeasuredRotationBFFiltered.z = pt1FilterApply4(&rotRateFilterZ, imuMeasuredRotationBF.z, IMU_ROTATION_LPF, dT);
699-
691+
700692
imuMeasuredAccelBFFiltered.x = pt1FilterApply4(&accelFilterX, imuMeasuredAccelBF.x, IMU_ROTATION_LPF, dT);
701693
imuMeasuredAccelBFFiltered.y = pt1FilterApply4(&accelFilterY, imuMeasuredAccelBF.y, IMU_ROTATION_LPF, dT);
702694
imuMeasuredAccelBFFiltered.z = pt1FilterApply4(&accelFilterZ, imuMeasuredAccelBF.z, IMU_ROTATION_LPF, dT);
@@ -718,8 +710,7 @@ static void imuCalculateGPSacceleration(fpVector3_t *vEstAccelEF,fpVector3_t *vE
718710

719711
// on first gps data acquired, time_delta_ms will be large, vEstcentrifugalAccelBF will be minimal to disable the compensation
720712
rtcTime_t time_delta_ms = currenttime - lastGPSNewDataTime;
721-
if (lastGPSHeartbeat != gpsSol.flags.gpsHeartbeat && time_delta_ms > 0)
722-
{
713+
if (lastGPSHeartbeat != gpsSol.flags.gpsHeartbeat && time_delta_ms > 0) {
723714
// on new gps frame, update accEF and estimate centrifugal accleration
724715
vEstAccelEF->x = -(currentGPSvel.x - lastGPSvel.x) / (MS2S(time_delta_ms)); // the x axis of accerometer is pointing backward
725716
vEstAccelEF->y = (currentGPSvel.y - lastGPSvel.y) / (MS2S(time_delta_ms));
@@ -734,11 +725,11 @@ static void imuCalculateGPSacceleration(fpVector3_t *vEstAccelEF,fpVector3_t *vE
734725
}
735726

736727
static void imuCalculateTurnRateacceleration(fpVector3_t *vEstcentrifugalAccelBF, float dT, float *acc_ignore_slope_multipiler)
737-
{
728+
{
738729
//fixed wing only
739730
static float lastspeed = -1.0f;
740731
float currentspeed = 0;
741-
if (isGPSTrustworthy()){
732+
if (isGPSTrustworthy()) {
742733
//first speed choice is gps
743734
static bool lastGPSHeartbeat;
744735
static pt1Filter_t GPS3DspeedFilter;
@@ -752,8 +743,7 @@ static void imuCalculateTurnRateacceleration(fpVector3_t *vEstcentrifugalAccelBF
752743
*acc_ignore_slope_multipiler = 4.0f;
753744
}
754745
#ifdef USE_PITOT
755-
else if (sensors(SENSOR_PITOT) && pitotIsHealthy())
756-
{
746+
else if (sensors(SENSOR_PITOT) && pitotIsHealthy()) {
757747
// second choice is pitot
758748
currentspeed = getAirspeedEstimate();
759749
*acc_ignore_slope_multipiler = 2.0f;
@@ -776,7 +766,7 @@ fpQuaternion_t* getTailSitterQuaternion(bool normal2tail){
776766
static bool firstRun = true;
777767
static fpQuaternion_t qNormal2Tail;
778768
static fpQuaternion_t qTail2Normal;
779-
if(firstRun){
769+
if (firstRun) {
780770
fpAxisAngle_t axisAngle;
781771
axisAngle.axis.x = 0;
782772
axisAngle.axis.y = 1;
@@ -792,7 +782,7 @@ fpQuaternion_t* getTailSitterQuaternion(bool normal2tail){
792782
void imuUpdateTailSitter(void)
793783
{
794784
static bool lastTailSitter=false;
795-
if (((bool)STATE(TAILSITTER)) != lastTailSitter){
785+
if (((bool)STATE(TAILSITTER)) != lastTailSitter) {
796786
fpQuaternion_t* rotation_for_tailsitter= getTailSitterQuaternion(STATE(TAILSITTER));
797787
quaternionMultiply(&orientation, &orientation, rotation_for_tailsitter);
798788
}
@@ -842,65 +832,76 @@ static void imuCalculateEstimatedAttitude(float dT)
842832
resetHeadingHoldTarget(DECIDEGREES_TO_DEGREES(attitude.values.yaw));
843833
}
844834
} else if (!ARMING_FLAG(ARMED)) {
845-
gpsHeadingInitialized = false;
835+
if (STATE(AIRPLANE)) {
836+
gpsHeadingInitialized = false; // required for fixed wing flight detection to work correctly
837+
} else if (!sensors(SENSOR_MAG) && STATE(CALIBRATE_MAG)) {
838+
// When no compass available allow yaw to be set to 0 (North) as required using compass calibration stick command
839+
DISABLE_STATE(CALIBRATE_MAG);
840+
beeper(BEEPER_ACTION_SUCCESS);
841+
842+
// Re-initialize quaternion from known Roll, Pitch with yaw set to 0 (North)
843+
imuComputeQuaternionFromRPY(attitude.values.roll, attitude.values.pitch, 0);
844+
gpsHeadingInitialized = true;
845+
}
846846
}
847847

848848
imuCalculateFilters(dT);
849+
849850
// centrifugal force compensation
850851
static fpVector3_t vEstcentrifugalAccelBF_velned;
851852
static fpVector3_t vEstcentrifugalAccelBF_turnrate;
852853
float acc_ignore_slope_multipiler = 1.0f; // when using gps centrifugal_force_compensation, AccelerometerWeightRateIgnore slope will be multiplied by this value
853-
if (isGPSTrustworthy())
854-
{
854+
855+
if (isGPSTrustworthy()) {
855856
imuCalculateGPSacceleration(&vCOGAcc, &vEstcentrifugalAccelBF_velned, &acc_ignore_slope_multipiler);
856857
useCOGAcc = true; //currently only for multicopter
857858
}
858-
if (STATE(AIRPLANE))
859-
{
859+
860+
if (STATE(AIRPLANE)) {
860861
imuCalculateTurnRateacceleration(&vEstcentrifugalAccelBF_turnrate, dT, &acc_ignore_slope_multipiler);
861862
}
862-
if (imuConfig()->inertia_comp_method == COMPMETHOD_ADAPTIVE && isGPSTrustworthy() && STATE(AIRPLANE))
863-
{
863+
864+
if (imuConfig()->inertia_comp_method == COMPMETHOD_ADAPTIVE && isGPSTrustworthy() && STATE(AIRPLANE)) {
864865
//pick the best centrifugal acceleration between velned and turnrate
865-
fpVector3_t compansatedGravityBF_velned;
866-
vectorAdd(&compansatedGravityBF_velned, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_velned);
867-
float velned_error = fabsf(fast_fsqrtf(vectorNormSquared(&compansatedGravityBF_velned)) - GRAVITY_CMSS);
866+
fpVector3_t compensatedGravityBF_velned;
867+
vectorAdd(&compensatedGravityBF_velned, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_velned);
868+
float velned_error = fabsf(fast_fsqrtf(vectorNormSquared(&compensatedGravityBF_velned)) - GRAVITY_CMSS);
868869

869-
fpVector3_t compansatedGravityBF_turnrate;
870-
vectorAdd(&compansatedGravityBF_turnrate, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_turnrate);
871-
float turnrate_error = fabsf(fast_fsqrtf(vectorNormSquared(&compansatedGravityBF_turnrate)) - GRAVITY_CMSS);
870+
fpVector3_t compensatedGravityBF_turnrate;
871+
vectorAdd(&compensatedGravityBF_turnrate, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_turnrate);
872+
float turnrate_error = fabsf(fast_fsqrtf(vectorNormSquared(&compensatedGravityBF_turnrate)) - GRAVITY_CMSS);
872873

873-
compansatedGravityBF = velned_error > turnrate_error? compansatedGravityBF_turnrate:compansatedGravityBF_velned;
874+
compensatedGravityBF = velned_error > turnrate_error ? compensatedGravityBF_turnrate : compensatedGravityBF_velned;
874875
}
875876
else if (((imuConfig()->inertia_comp_method == COMPMETHOD_VELNED) || (imuConfig()->inertia_comp_method == COMPMETHOD_ADAPTIVE)) && isGPSTrustworthy())
876877
{
877878
//velned centrifugal force compensation, quad will use this method
878-
vectorAdd(&compansatedGravityBF, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_velned);
879+
vectorAdd(&compensatedGravityBF, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_velned);
879880
}
880881
else if (STATE(AIRPLANE))
881882
{
882883
//turnrate centrifugal force compensation
883-
vectorAdd(&compansatedGravityBF, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_turnrate);
884+
vectorAdd(&compensatedGravityBF, &imuMeasuredAccelBF, &vEstcentrifugalAccelBF_turnrate);
884885
}
885886
else
886887
{
887-
compansatedGravityBF = imuMeasuredAccelBF;
888+
compensatedGravityBF = imuMeasuredAccelBF;
888889
}
889890
#else
890891
// In absence of GPS MAG is the only option
891892
if (canUseMAG) {
892893
useMag = true;
893894
}
894-
compansatedGravityBF = imuMeasuredAccelBF
895+
compensatedGravityBF = imuMeasuredAccelBF;
895896
#endif
896-
float accWeight = imuGetPGainScaleFactor() * imuCalculateAccelerometerWeightNearness(&compansatedGravityBF);
897+
float accWeight = imuGetPGainScaleFactor() * imuCalculateAccelerometerWeightNearness(&compensatedGravityBF);
897898
accWeight = accWeight * imuCalculateAccelerometerWeightRateIgnore(acc_ignore_slope_multipiler);
898899
const bool useAcc = (accWeight > 0.001f);
899900

900901
const float magWeight = imuGetPGainScaleFactor() * 1.0f;
901902
fpVector3_t measuredMagBF = {.v = {mag.magADC[X], mag.magADC[Y], mag.magADC[Z]}};
902903
imuMahonyAHRSupdate(dT, &imuMeasuredRotationBF,
903-
useAcc ? &compansatedGravityBF : NULL,
904+
useAcc ? &compensatedGravityBF : NULL,
904905
useMag ? &measuredMagBF : NULL,
905906
useCOG ? &vCOG : NULL,
906907
useCOGAcc ? &vCOGAcc : NULL,
@@ -950,7 +951,6 @@ void imuUpdateAttitude(timeUs_t currentTimeUs)
950951
acc.accADCf[Z] = 0.0f;
951952
}
952953
}
953-
954954

955955
bool isImuReady(void)
956956
{
@@ -966,9 +966,13 @@ float calculateCosTiltAngle(void)
966966
{
967967
return 1.0f - 2.0f * sq(orientation.q1) - 2.0f * sq(orientation.q2);
968968
}
969-
969+
#if defined(USE_GPS)
970+
bool isYawZeroResetAllowed(void)
971+
{
972+
return !ARMING_FLAG(ARMED) && !STATE(AIRPLANE) && sensors(SENSOR_GPS) && !sensors(SENSOR_MAG);
973+
}
974+
#endif
970975
#if defined(SITL_BUILD) || defined (USE_SIMULATOR)
971-
972976
void imuSetAttitudeRPY(int16_t roll, int16_t pitch, int16_t yaw)
973977
{
974978
attitude.values.roll = roll;

src/main/flight/imu.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@
2525
#include "config/parameter_group.h"
2626

2727
extern fpVector3_t imuMeasuredAccelBF; // cm/s/s
28-
extern fpVector3_t imuMeasuredAccelBFFiltered; // cm/s/s
2928
extern fpVector3_t imuMeasuredRotationBF; // rad/s
30-
extern fpVector3_t imuMeasuredRotationBFFiltered; // rad/s
31-
extern fpVector3_t compansatedGravityBF; // cm/s/s
3229
extern fpVector3_t HeadVecEFFiltered;
3330

3431
typedef union {
@@ -88,6 +85,7 @@ void imuUpdateAccelerometer(void);
8885
float calculateCosTiltAngle(void);
8986
bool isImuReady(void);
9087
bool isImuHeadingValid(void);
88+
bool isYawZeroResetAllowed(void);
9189

9290
void imuTransformVectorBodyToEarth(fpVector3_t * v);
9391
void imuTransformVectorEarthToBody(fpVector3_t * v);

src/main/io/osd.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6475,6 +6475,23 @@ static textAttributes_t osdGetMultiFunctionMessage(char *buff)
64756475
break;
64766476
}
64776477
activeFunction++;
6478+
FALLTHROUGH;
6479+
case MULTI_FUNC_6:
6480+
if (!ARMING_FLAG(ARMED)) {
6481+
#if defined(USE_MAG)
6482+
if (sensors(SENSOR_MAG)) {
6483+
message = "CAL COMPAS";
6484+
break;
6485+
}
6486+
#endif
6487+
#if defined(USE_GPS)
6488+
if (isYawZeroResetAllowed()) {
6489+
message = "SET HEADIN";
6490+
break;
6491+
}
6492+
#endif
6493+
}
6494+
activeFunction++;
64786495
break;
64796496
case MULTI_FUNC_END:
64806497
message = "*FUNC SET*";

0 commit comments

Comments
 (0)