Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/ADSB.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ is an air traffic surveillance technology that enables aircraft to be accurately

OSD can be configured to shows the closest aircraft.

## OSD element
## OSD ADSB Info element
* "-" no ADSB device detected
* "H" IMU heading is not valid
* "G" no GPS fix or less than 4 stats
* "[Number]" count of ADSB aircrafts

## OSD ADSB Warning element
OSD can be configured to simple view (one line) or to extended view (two lines) by \
`set osd_adsb_warning_style=EXTENDED`

Expand Down
34 changes: 31 additions & 3 deletions src/main/io/adsb.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,26 @@ adsbVehicle_t *findVehicleClosest(void) {
* @return
*/
adsbVehicle_t *findVehicleClosestLimit(int32_t maxVerticalDistance) {

////////////////////////////////////////////////////////////
//debug vehicle
/*adsbVehicleValues_t* vehicle = getVehicleForFill();
if(vehicle != NULL){
char name[9] = "DUMMY ";
vehicle->icao = 666;
vehicle->gps.lat = 492383514;
vehicle->gps.lon = 165148681;
vehicle->alt = 100000;
vehicle->heading = 66;
vehicle->flags = ADSB_FLAGS_VALID_ALTITUDE | ADSB_FLAGS_VALID_COORDS;
vehicle->altitudeType = 0;
memcpy(&(vehicle->callsign), name, sizeof(vehicle->callsign));
vehicle->emitterType = 6;
vehicle->tslc = 0;
adsbNewVehicle(vehicle);
}*/
////////////////////////////////////////////////////////////

adsbVehicle_t *adsbLocal = NULL;
for (uint8_t i = 0; i < MAX_ADSB_VEHICLES; i++) {
if(adsbVehiclesList[i].ttl > 0 && adsbVehiclesList[i].calculatedVehicleValues.valid){
Expand Down Expand Up @@ -178,7 +198,7 @@ void adsbNewVehicle(adsbVehicleValues_t* vehicleValuesLocal) {
}

// non GPS mode, GPS is not fix, just find free space in list or by icao and save vehicle without calculated values
if (!enviromentOkForCalculatingDistaceBearing()) {
if (!isEnvironmentOkForCalculatingADSBDistanceBearing()) {
if(vehicle == NULL){
vehicle = findFreeSpaceInList();
}
Expand Down Expand Up @@ -264,8 +284,16 @@ void adsbTtlClean(timeUs_t currentTimeUs) {
}
};

bool enviromentOkForCalculatingDistaceBearing(void){
return (STATE(GPS_FIX) && gpsSol.numSat > 4);
bool isEnvironmentOkForCalculatingADSBDistanceBearing(void){
return
(gpsSol.numSat > 4 &&
(
STATE(GPS_FIX)
#ifdef USE_GPS_FIX_ESTIMATION
|| STATE(GPS_ESTIMATED_FIX)
#endif
)
);
}

#endif
Expand Down
2 changes: 1 addition & 1 deletion src/main/io/adsb.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,5 @@ uint8_t getActiveVehiclesCount(void);
void adsbTtlClean(timeUs_t currentTimeUs);
adsbVehicleStatus_t* getAdsbStatus(void);
adsbVehicleValues_t* getVehicleForFill(void);
bool enviromentOkForCalculatingDistaceBearing(void);
bool isEnvironmentOkForCalculatingADSBDistanceBearing(void);
void recalculateVehicle(adsbVehicle_t* vehicle);
62 changes: 35 additions & 27 deletions src/main/io/osd.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,14 @@ static void osdFormatDistanceSymbol(char *buff, int32_t dist, uint8_t decimals,
}
}

/**
* return flight direction on degrees
*/
static int16_t osdGetFlightDirection(void)
{
return STATE(AIRPLANE) ? CENTIDEGREES_TO_DEGREES(posControl.actualState.cog) : DECIDEGREES_TO_DEGREES(osdGetHeading());
}

/**
* Converts distance into a string based on the current unit system.
* @param dist Distance in centimeters
Expand Down Expand Up @@ -1979,8 +1987,7 @@ static bool osdDrawSingleElement(uint8_t item)
if (!(osdConfig()->pan_servo_pwm2centideg == 0)){
panHomeDirOffset = osdGetPanServoOffset();
}
int16_t flightDirection = STATE(AIRPLANE) ? CENTIDEGREES_TO_DEGREES(posControl.actualState.cog) : DECIDEGREES_TO_DEGREES(osdGetHeading());
int homeDirection = GPS_directionToHome - flightDirection + panHomeDirOffset;
int homeDirection = GPS_directionToHome - osdGetFlightDirection() + panHomeDirOffset;
osdDrawDirArrow(osdDisplayPort, osdGetDisplayPortCanvas(), OSD_DRAW_POINT_GRID(elemPosX, elemPosY), homeDirection);
}
} else {
Expand Down Expand Up @@ -2176,16 +2183,17 @@ static bool osdDrawSingleElement(uint8_t item)
uint8_t buffIndexFirstLine = 0;
uint8_t arrowIndexIndex = 0;
adsbVehicle_t *vehicle = findVehicleClosestLimit(METERS_TO_CENTIMETERS(osdConfig()->adsb_ignore_plane_above_me_limit));
if(vehicle != NULL)
{
if (vehicle != NULL) {
recalculateVehicle(vehicle);
}

if (
vehicle != NULL &&
(vehicle->calculatedVehicleValues.dist > 0 &&
vehicle->calculatedVehicleValues.dist < METERS_TO_CENTIMETERS(osdConfig()->adsb_distance_warning))
){
vehicle != NULL
&& (vehicle->calculatedVehicleValues.dist > 0
&& vehicle->calculatedVehicleValues.dist < METERS_TO_CENTIMETERS(osdConfig()->adsb_distance_warning))
&& isEnvironmentOkForCalculatingADSBDistanceBearing()

) {
adsbLengthForClearFirstLine = 11;

buff[buffIndexFirstLine++] = SYM_ADSB;
Expand Down Expand Up @@ -2219,21 +2227,20 @@ static bool osdDrawSingleElement(uint8_t item)
//////////////////////////////////////////////////////
// ALT diff to ADSB vehicle draw
int16_t panServoDirOffset = 0;
if (osdConfig()->pan_servo_pwm2centideg != 0){
if (osdConfig()->pan_servo_pwm2centideg != 0) {
panServoDirOffset = osdGetPanServoOffset();
}

if(arrowIndexIndex > 0)
{
if (arrowIndexIndex > 0 && isImuHeadingValid()) {
//[direction to vehicle]
int directionToPeerError = osdGetHeadingAngle(CENTIDEGREES_TO_DEGREES(vehicle->calculatedVehicleValues.dir)) + panServoDirOffset - (int)DECIDEGREES_TO_DEGREES(osdGetHeading());
int directionToPeerError = osdGetHeadingAngle(CENTIDEGREES_TO_DEGREES(vehicle->calculatedVehicleValues.dir)) + panServoDirOffset - osdGetFlightDirection();
osdDrawDirCardinal(osdDisplayPort, elemPosX + arrowIndexIndex, elemPosY, directionToPeerError, elemAttr);
}
//////////////////////////////////////////////////////

//////////////////////////////////////////////////////
// Second line, extra info
if(osdConfig()->adsb_warning_style == OSD_ADSB_WARNING_STYLE_EXTENDED){
if (osdConfig()->adsb_warning_style == OSD_ADSB_WARNING_STYLE_EXTENDED) {
// Vehicle type
tfp_sprintf(buff, "%s", getAdsbEmitterTypeString(vehicle->vehicleValues.emitterType));

Expand All @@ -2245,41 +2252,43 @@ static bool osdDrawSingleElement(uint8_t item)
displayWriteWithAttr(osdDisplayPort, elemPosX, elemPosY + 1, buff, elemAttr);

// Vehicle direction
int16_t flightDirection = STATE(AIRPLANE) ? CENTIDEGREES_TO_DEGREES(posControl.actualState.cog) : DECIDEGREES_TO_DEGREES(osdGetHeading());
osdDrawDirArrow(osdDisplayPort, osdGetDisplayPortCanvas(), OSD_DRAW_POINT_GRID(elemPosX + 6, elemPosY + 1), (float)(CENTIDEGREES_TO_DEGREES(vehicle->vehicleValues.heading) - flightDirection + panServoDirOffset));
if(isImuHeadingValid())
{
osdDrawDirArrow(osdDisplayPort, osdGetDisplayPortCanvas(), OSD_DRAW_POINT_GRID(elemPosX + 6, elemPosY + 1), (float)(CENTIDEGREES_TO_DEGREES(vehicle->vehicleValues.heading) - osdGetFlightDirection() + panServoDirOffset));
}

adsbLengthForClearSecondLine += 7;
}
///////////////////////////////////////////////////
}
else
{
} else {
//clear first line
if(adsbLengthForClearFirstLine > 0){
if(adsbLengthForClearFirstLine > 0) {
memset(buff, SYM_BLANK, constrain(adsbLengthForClearFirstLine, 0, 20));
displayWrite(osdDisplayPort, elemPosX, elemPosY, buff);
adsbLengthForClearFirstLine = 0;
}

//clear second line
if(adsbLengthForClearSecondLine > 0){
if(adsbLengthForClearSecondLine > 0) {
memset(buff, SYM_BLANK, constrain(adsbLengthForClearSecondLine, 0, 20));
displayWrite(osdDisplayPort, elemPosX, elemPosY + 1, buff);
adsbLengthForClearSecondLine = 0;
}
}

return true;
}
case OSD_ADSB_INFO:
{
buff[0] = SYM_ADSB;
if(getAdsbStatus()->vehiclesMessagesTotal > 0 || getAdsbStatus()->heartbeatMessagesTotal > 0){
tfp_sprintf(buff + 1, "%1d", getActiveVehiclesCount());
}else{
if (getAdsbStatus()->vehiclesMessagesTotal == 0 && getAdsbStatus()->heartbeatMessagesTotal == 0) {
buff[1] = '-';
} else if (!isEnvironmentOkForCalculatingADSBDistanceBearing()) {
buff[1] = 'G';
} else if (!isImuHeadingValid()) {
buff[1] = 'H';
} else {
tfp_sprintf(buff + 1, "%1d", getActiveVehiclesCount());
}

break;
}

Expand Down Expand Up @@ -3996,8 +4005,7 @@ static bool osdDrawSingleElement(uint8_t item)
if (!(osdConfig()->pan_servo_pwm2centideg == 0)){
panHomeDirOffset = osdGetPanServoOffset();
}
int16_t flightDirection = STATE(AIRPLANE) ? CENTIDEGREES_TO_DEGREES(posControl.actualState.cog) : DECIDEGREES_TO_DEGREES(osdGetHeading());
int direction = CENTIDEGREES_TO_DEGREES(geozone.directionToNearestZone) - flightDirection + panHomeDirOffset;
int direction = CENTIDEGREES_TO_DEGREES(geozone.directionToNearestZone) - osdGetFlightDirection() + panHomeDirOffset;
osdDrawDirArrow(osdDisplayPort, osdGetDisplayPortCanvas(), OSD_DRAW_POINT_GRID(elemPosX, elemPosY), direction);
} else {
if (isGeozoneActive()) {
Expand Down