Skip to content

Commit a42af76

Browse files
authored
Merge pull request iNavFlight#9883 from error414/fixed-formationflight
Fixed position for formation flight / inav radar
2 parents e989f23 + c5d6a4f commit a42af76

File tree

6 files changed

+150
-5
lines changed

6 files changed

+150
-5
lines changed

docs/Settings.md

+10
Original file line numberDiff line numberDiff line change
@@ -4972,6 +4972,16 @@ Number of leading digits removed from plus code. Removing 2, 4 and 6 digits requ
49724972

49734973
---
49744974

4975+
### osd_radar_peers_display_time
4976+
4977+
Time in seconds to display next peer
4978+
4979+
| Default | Min | Max |
4980+
| --- | --- | --- |
4981+
| 3 | 1 | 10 |
4982+
4983+
---
4984+
49754985
### osd_right_sidebar_scroll
49764986

49774987
Scroll type for the right sidebar

src/main/common/maths.c

+9
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,15 @@ int32_t wrap_18000(int32_t angle)
123123
return angle;
124124
}
125125

126+
int16_t wrap_180(int16_t angle)
127+
{
128+
if (angle > 180)
129+
angle -= 360;
130+
if (angle < -180)
131+
angle += 360;
132+
return angle;
133+
}
134+
126135
int32_t wrap_36000(int32_t angle)
127136
{
128137
if (angle >= 36000)

src/main/common/maths.h

+1
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ int scaleRange(int x, int srcMin, int srcMax, int destMin, int destMax);
166166
float scaleRangef(float x, float srcMin, float srcMax, float destMin, float destMax);
167167

168168
int32_t wrap_18000(int32_t angle);
169+
int16_t wrap_180(int16_t angle);
169170
int32_t wrap_36000(int32_t angle);
170171

171172
int32_t quickMedianFilter3(int32_t * v);

src/main/fc/settings.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -3486,6 +3486,12 @@ groups:
34863486
min: 1
34873487
max: 10
34883488
default_value: 3
3489+
- name: osd_radar_peers_display_time
3490+
description: "Time in seconds to display next peer "
3491+
field: radar_peers_display_time
3492+
min: 1
3493+
max: 10
3494+
default_value: 3
34893495
- name: osd_hud_wp_disp
34903496
description: "How many navigation waypoints are displayed, set to 0 (zero) to disable. As sample, if set to 2, and you just passed the 3rd waypoint of the mission, you'll see markers for the 4th waypoint (marked 1) and the 5th waypoint (marked 2)"
34913497
default_value: 0

src/main/io/osd.c

+119-2
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ static bool osdDisplayHasCanvas;
224224

225225
#define AH_MAX_PITCH_DEFAULT 20 // Specify default maximum AHI pitch value displayed (degrees)
226226

227-
PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 11);
227+
PG_REGISTER_WITH_RESET_TEMPLATE(osdConfig_t, osdConfig, PG_OSD_CONFIG, 12);
228228
PG_REGISTER_WITH_RESET_FN(osdLayoutsConfig_t, osdLayoutsConfig, PG_OSD_LAYOUTS_CONFIG, 1);
229229

230230
void osdStartedSaveProcess(void) {
@@ -2513,6 +2513,121 @@ static bool osdDrawSingleElement(uint8_t item)
25132513
}
25142514
#endif
25152515

2516+
case OSD_FORMATION_FLIGHT:
2517+
{
2518+
static uint8_t currentPeerIndex = 0;
2519+
static timeMs_t lastPeerSwitch;
2520+
2521+
if ((STATE(GPS_FIX) && isImuHeadingValid())) {
2522+
if ((radar_pois[currentPeerIndex].gps.lat == 0 || radar_pois[currentPeerIndex].gps.lon == 0 || radar_pois[currentPeerIndex].state >= 2) || (millis() > (osdConfig()->radar_peers_display_time * 1000) + lastPeerSwitch)) {
2523+
lastPeerSwitch = millis();
2524+
2525+
for(uint8_t i = 1; i < RADAR_MAX_POIS - 1; i++) {
2526+
uint8_t nextPeerIndex = (currentPeerIndex + i) % (RADAR_MAX_POIS - 1);
2527+
if (radar_pois[nextPeerIndex].gps.lat != 0 && radar_pois[nextPeerIndex].gps.lon != 0 && radar_pois[nextPeerIndex].state < 2) {
2528+
currentPeerIndex = nextPeerIndex;
2529+
break;
2530+
}
2531+
}
2532+
}
2533+
2534+
radar_pois_t *currentPeer = &(radar_pois[currentPeerIndex]);
2535+
if (currentPeer->gps.lat != 0 && currentPeer->gps.lon != 0 && currentPeer->state < 2) {
2536+
fpVector3_t poi;
2537+
geoConvertGeodeticToLocal(&poi, &posControl.gpsOrigin, &currentPeer->gps, GEO_ALT_RELATIVE);
2538+
2539+
currentPeer->distance = calculateDistanceToDestination(&poi) / 100; // In m
2540+
currentPeer->altitude = (int16_t )((currentPeer->gps.alt - osdGetAltitudeMsl()) / 100);
2541+
currentPeer->direction = (int16_t )(calculateBearingToDestination(&poi) / 100); // In °
2542+
2543+
int16_t panServoDirOffset = 0;
2544+
if (osdConfig()->pan_servo_pwm2centideg != 0){
2545+
panServoDirOffset = osdGetPanServoOffset();
2546+
}
2547+
2548+
//line 1
2549+
//[peer heading][peer ID][LQ][direction to peer]
2550+
2551+
//[peer heading]
2552+
int relativePeerHeading = osdGetHeadingAngle(currentPeer->heading - (int)DECIDEGREES_TO_DEGREES(osdGetHeading()));
2553+
displayWriteChar(osdDisplayPort, elemPosX, elemPosY, SYM_DECORATION + ((relativePeerHeading + 22) / 45) % 8);
2554+
2555+
//[peer ID]
2556+
displayWriteChar(osdDisplayPort, elemPosX + 1, elemPosY, 65 + currentPeerIndex);
2557+
2558+
//[LQ]
2559+
displayWriteChar(osdDisplayPort, elemPosX + 2, elemPosY, SYM_HUD_SIGNAL_0 + currentPeer->lq);
2560+
2561+
//[direction to peer]
2562+
int directionToPeerError = wrap_180(osdGetHeadingAngle(currentPeer->direction) + panServoDirOffset - (int)DECIDEGREES_TO_DEGREES(osdGetHeading()));
2563+
uint16_t iconIndexOffset = constrain(((directionToPeerError + 180) / 30), 0, 12);
2564+
if (iconIndexOffset == 12) {
2565+
iconIndexOffset = 0; // Directly behind
2566+
}
2567+
displayWriteChar(osdDisplayPort, elemPosX + 3, elemPosY, SYM_HUD_CARDINAL + iconIndexOffset);
2568+
2569+
2570+
//line 2
2571+
switch ((osd_unit_e)osdConfig()->units) {
2572+
case OSD_UNIT_UK:
2573+
FALLTHROUGH;
2574+
case OSD_UNIT_IMPERIAL:
2575+
osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(currentPeer->distance * 100), FEET_PER_MILE, 0, 4, 4, false);
2576+
break;
2577+
case OSD_UNIT_GA:
2578+
osdFormatCentiNumber(buff, CENTIMETERS_TO_CENTIFEET(currentPeer->distance * 100), (uint32_t)FEET_PER_NAUTICALMILE, 0, 4, 4, false);
2579+
break;
2580+
default:
2581+
FALLTHROUGH;
2582+
case OSD_UNIT_METRIC_MPH:
2583+
FALLTHROUGH;
2584+
case OSD_UNIT_METRIC:
2585+
osdFormatCentiNumber(buff, currentPeer->distance * 100, METERS_PER_KILOMETER, 0, 4, 4, false);
2586+
break;
2587+
}
2588+
displayWrite(osdDisplayPort, elemPosX, elemPosY + 1, buff);
2589+
2590+
2591+
//line 3
2592+
displayWriteChar(osdDisplayPort, elemPosX, elemPosY + 2, (currentPeer->altitude >= 0) ? SYM_AH_DECORATION_UP : SYM_AH_DECORATION_DOWN);
2593+
2594+
int altc = currentPeer->altitude;
2595+
switch ((osd_unit_e)osdConfig()->units) {
2596+
case OSD_UNIT_UK:
2597+
FALLTHROUGH;
2598+
case OSD_UNIT_GA:
2599+
FALLTHROUGH;
2600+
case OSD_UNIT_IMPERIAL:
2601+
// Convert to feet
2602+
altc = CENTIMETERS_TO_FEET(altc * 100);
2603+
break;
2604+
default:
2605+
FALLTHROUGH;
2606+
case OSD_UNIT_METRIC_MPH:
2607+
FALLTHROUGH;
2608+
case OSD_UNIT_METRIC:
2609+
// Already in metres
2610+
break;
2611+
}
2612+
2613+
altc = ABS(constrain(altc, -999, 999));
2614+
tfp_sprintf(buff, "%3d", altc);
2615+
displayWrite(osdDisplayPort, elemPosX + 1, elemPosY + 2, buff);
2616+
2617+
return true;
2618+
}
2619+
}
2620+
2621+
//clear screen
2622+
for(uint8_t i = 0; i < 4; i++){
2623+
displayWriteChar(osdDisplayPort, elemPosX + i, elemPosY, SYM_BLANK);
2624+
displayWriteChar(osdDisplayPort, elemPosX + i, elemPosY + 1, SYM_BLANK);
2625+
displayWriteChar(osdDisplayPort, elemPosX + i, elemPosY + 2, SYM_BLANK);
2626+
}
2627+
2628+
return true;
2629+
}
2630+
25162631
case OSD_CROSSHAIRS: // Hud is a sub-element of the crosshair
25172632

25182633
osdCrosshairPosition(&elemPosX, &elemPosY);
@@ -3930,7 +4045,9 @@ PG_RESET_TEMPLATE(osdConfig_t, osdConfig,
39304045

39314046
.stats_energy_unit = SETTING_OSD_STATS_ENERGY_UNIT_DEFAULT,
39324047
.stats_page_auto_swap_time = SETTING_OSD_STATS_PAGE_AUTO_SWAP_TIME_DEFAULT,
3933-
.stats_show_metric_efficiency = SETTING_OSD_STATS_SHOW_METRIC_EFFICIENCY_DEFAULT
4048+
.stats_show_metric_efficiency = SETTING_OSD_STATS_SHOW_METRIC_EFFICIENCY_DEFAULT,
4049+
4050+
.radar_peers_display_time = SETTING_OSD_RADAR_PEERS_DISPLAY_TIME_DEFAULT
39344051
);
39354052

39364053
void pgResetFn_osdLayoutsConfig(osdLayoutsConfig_t *osdLayoutsConfig)

src/main/io/osd.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,10 @@ typedef enum {
283283
OSD_CUSTOM_ELEMENT_1,
284284
OSD_CUSTOM_ELEMENT_2,
285285
OSD_CUSTOM_ELEMENT_3,
286-
OSD_ADSB_WARNING,
286+
OSD_ADSB_WARNING, //150
287287
OSD_ADSB_INFO,
288288
OSD_BLACKBOX,
289+
OSD_FORMATION_FLIGHT, //153
289290
OSD_ITEM_COUNT // MUST BE LAST
290291
} osd_items_e;
291292

@@ -460,11 +461,12 @@ typedef struct osdConfig_s {
460461
#ifndef DISABLE_MSP_DJI_COMPAT
461462
bool highlight_djis_missing_characters; // If enabled, show question marks where there is no character in DJI's font to represent an OSD element symbol
462463
#endif
463-
#ifdef USE_ADSB
464+
#ifdef USE_ADSB
464465
uint16_t adsb_distance_warning; // in metres
465466
uint16_t adsb_distance_alert; // in metres
466467
uint16_t adsb_ignore_plane_above_me_limit; // in metres
467-
#endif
468+
#endif
469+
uint8_t radar_peers_display_time; // in seconds
468470
} osdConfig_t;
469471

470472
PG_DECLARE(osdConfig_t, osdConfig);

0 commit comments

Comments
 (0)