diff --git a/docs/Settings.md b/docs/Settings.md index e0a8c522421..c7916f206d2 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -390,6 +390,8 @@ | osd_link_quality_alarm | 70 | LQ % indicator blinks below this value. For Crossfire use 70%, for Tracer use 50% | | osd_main_voltage_decimals | 1 | Number of decimals for the battery voltages displayed in the OSD [1-2]. | | osd_neg_alt_alarm | 5 | Value below which (negative altitude) to make the OSD relative altitude indicator blink (meters) | +| osd_pan_servo_index | | Index of the pan servo to adjust osd home heading direction based on camera pan. Note that this feature does not work with continiously rotating servos. | +| osd_pan_servo_pwm2centideg | 0 | Centidegrees of pan servo rotation us PWM signal. A servo with 180 degrees of rotation from 1000 to 2000 us PWM typically needs `18` for this setting. Change sign to inverse direction. | | osd_plus_code_digits | 10 | Numer of plus code digits before shortening with `osd_plus_code_short`. Precision at the equator: 10=13.9x13.9m; 11=2.8x3.5m; 12=56x87cm; 13=11x22cm. | | osd_plus_code_short | 0 | Number of leading digits removed from plus code. Removing 2, 4 and 6 digits requires a reference location within, respectively, ~800km, ~40 km and ~2km to recover the original coordinates. | | osd_right_sidebar_scroll | | | diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index ec2b1a01ea9..70a9a19797e 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -3021,6 +3021,20 @@ groups: default_value: "ON" description: Should home position coordinates be displayed on the arming screen. + - name: osd_pan_servo_index + description: Index of the pan servo to adjust osd home heading direction based on camera pan. Note that this feature does not work with continiously rotating servos. + field: pan_servo_index + min: 0 + max: 10 + + - name: osd_pan_servo_pwm2centideg + description: Centidegrees of pan servo rotation us PWM signal. A servo with 180 degrees of rotation from 1000 to 2000 us PWM typically needs `18` for this setting. Change sign to inverse direction. + field: pan_servo_pwm2centideg + default_value: 0 + min: -36 + max: 36 + + - name: PG_SYSTEM_CONFIG type: systemConfig_t headers: ["fc/config.h"] diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 4055cf733a6..75503c0f9dc 100755 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -87,6 +87,7 @@ FILE_COMPILE_FOR_SPEED #include "flight/pid.h" #include "flight/rth_estimator.h" #include "flight/wind_estimator.h" +#include "flight/servos.h" #include "navigation/navigation.h" #include "navigation/navigation_private.h" @@ -185,7 +186,7 @@ static bool osdDisplayHasCanvas; #define AH_MAX_PITCH_DEFAULT 20 // Specify default maximum AHI pitch value displayed (degrees) -PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 14); +PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 15); PG_REGISTER_WITH_RESET_FN(osdLayoutsConfig_t, osdLayoutsConfig, PG_OSD_LAYOUTS_CONFIG, 0); static int digitCount(int32_t value) @@ -945,6 +946,14 @@ int16_t osdGetHeading(void) return attitude.values.yaw; } +int16_t osdPanServoHomeDirectionOffset(void) +{ + int8_t servoIndex = osdConfig()->pan_servo_index; + int16_t servoPosition = servo[servoIndex]; + int16_t servoMiddle = servoParams(servoIndex)->middle; + return (int16_t)CENTIDEGREES_TO_DEGREES((servoPosition - servoMiddle) * osdConfig()->pan_servo_pwm2centideg); +} + // Returns a heading angle in degrees normalized to [0, 360). int osdGetHeadingAngle(int angle) { @@ -1334,7 +1343,11 @@ static bool osdDrawSingleElement(uint8_t item) } else { - int homeDirection = GPS_directionToHome - DECIDEGREES_TO_DEGREES(osdGetHeading()); + int16_t panHomeDirOffset = 0; + if (!(osdConfig()->pan_servo_pwm2centideg == 0)){ + panHomeDirOffset = osdPanServoHomeDirectionOffset(); + } + int homeDirection = GPS_directionToHome - DECIDEGREES_TO_DEGREES(osdGetHeading()) + panHomeDirOffset; osdDrawDirArrow(osdDisplayPort, osdGetDisplayPortCanvas(), OSD_DRAW_POINT_GRID(elemPosX, elemPosY), homeDirection); } } else { @@ -2590,6 +2603,8 @@ PG_RESET_TEMPLATE(osdConfig_t, osdConfig, .right_sidebar_scroll = OSD_SIDEBAR_SCROLL_NONE, .sidebar_scroll_arrows = 0, .osd_home_position_arm_screen = true, + .pan_servo_index = 0, + .pan_servo_pwm2centideg = 0, .units = OSD_UNIT_METRIC, .main_voltage_decimals = 1, diff --git a/src/main/io/osd.h b/src/main/io/osd.h index cff09933587..e2421071f90 100755 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -348,7 +348,8 @@ typedef struct osdConfig_s { uint8_t left_sidebar_scroll_step; // How many units each sidebar step represents. 0 means the default value for the scroll type. uint8_t right_sidebar_scroll_step; // Same as left_sidebar_scroll_step, but for the right sidebar. bool osd_home_position_arm_screen; - + uint8_t pan_servo_index; // Index of the pan servo used for home direction offset + int8_t pan_servo_pwm2centideg; // Centidegrees of servo rotation per us pwm uint8_t crsf_lq_format; } osdConfig_t;