static void OnFlarmLockClicked(WindowControl * Sender) { (void)Sender; dlgTextEntryShowModal(XCSoarInterface::SetSettingsComputer().TeamFlarmCNTarget, 4); XCSoarInterface::SetSettingsComputer().TeammateCodeValid = false; int flarmId = LookupFLARMDetails(XCSoarInterface::SettingsComputer().TeamFlarmCNTarget); if (flarmId == 0) { MessageBoxX(gettext(TEXT("Unknown Competition Number")), gettext(TEXT("Not Found")), MB_OK|MB_ICONINFORMATION); XCSoarInterface::SetSettingsComputer().TeamFlarmTracking = false; XCSoarInterface::SetSettingsComputer().TeamFlarmIdTarget = 0; XCSoarInterface::SetSettingsComputer().TeamFlarmCNTarget[0] = 0; } else { XCSoarInterface::SetSettingsComputer().TeamFlarmIdTarget = flarmId; XCSoarInterface::SetSettingsComputer().TeamFlarmTracking = true; } }
static void OnDetailsListInfo(WindowControl * Sender, WndListFrame::ListInfo_t *ListInfo){ (void)Sender; if (ListInfo->DrawIndex == -1){ ListInfo->ItemCount = GetActiveFlarmTrafficCount(); } else { DrawListIndex = ListInfo->DrawIndex+ListInfo->ScrollIndex; if (DrawListIndex != -1) { if (XCSoarInterface::Basic().FLARM_Traffic[DrawListIndex].ID != 0) { if (LookupFLARMDetails(XCSoarInterface::Basic().FLARM_Traffic[DrawListIndex].ID) == NULL) { // not existing en primary or secondary flarm id list ((WndButton *)wf->FindByName(TEXT("cmdSetCN")))->SetCaption(TEXT("Set CN")); ((WndButton *)wf->FindByName(TEXT("cmdSetCN")))->SetVisible(true); } else { // the id was found - is it from secondary list ? int index = LookupSecondaryFLARMId(XCSoarInterface::Basic().FLARM_Traffic[DrawListIndex].ID); if (index != -1) { ((WndButton *)wf->FindByName(TEXT("cmdSetCN")))->SetCaption(TEXT("Edit CN")); ((WndButton *)wf->FindByName(TEXT("cmdSetCN")))->SetVisible(true); } else { ((WndButton *)wf->FindByName(TEXT("cmdSetCN")))->SetVisible(false); } } ((WndButton *)wf->FindByName(TEXT("cmdTrack")))->SetVisible(true); } else { ((WndButton *)wf->FindByName(TEXT("cmdTrack")))->SetVisible(false); ((WndButton *)wf->FindByName(TEXT("cmdSetCN")))->SetVisible(false); } } } }
// // The purpose of simulating flarm traffic is NOT to play a videogame against flarm objects: // we only need some traffic to display for testing on ground during simulations. // // >>>>> This is accessing directly the GPS_INFO main struct, writing inside it. <<<<< // Called by LKSimulator, already locking FlightData . No worry. // void SimFlarmTraffic(long ID, double offset) { int flarm_slot = 0; bool newtraffic=false; GPS_INFO.FLARM_Available=true; LastFlarmCommandTime=GPS_INFO.Time; // useless really, we dont call UpdateMonitor from SIM flarm_slot = FLARM_FindSlot(&GPS_INFO, ID); if (flarm_slot<0) return; if ( GPS_INFO.FLARM_Traffic[flarm_slot].Status == LKT_EMPTY) { newtraffic=true; } // before changing timefix, see if it was an old target back locked in! CheckBackTarget(&GPS_INFO, flarm_slot); // and then set time of fix to current time GPS_INFO.FLARM_Traffic[flarm_slot].Time_Fix = GPS_INFO.Time; /* TEXT("%hu,%lf,%lf,%lf,%hu,%lx,%lf,%lf,%lf,%lf,%hu"), &GPS_INFO.FLARM_Traffic[flarm_slot].AlarmLevel, // unsigned short 0 &GPS_INFO.FLARM_Traffic[flarm_slot].RelativeNorth, // 1 &GPS_INFO.FLARM_Traffic[flarm_slot].RelativeEast, // 2 &GPS_INFO.FLARM_Traffic[flarm_slot].RelativeAltitude, // 3 &GPS_INFO.FLARM_Traffic[flarm_slot].IDType, // unsigned short 4 &GPS_INFO.FLARM_Traffic[flarm_slot].ID, // 6 char hex &GPS_INFO.FLARM_Traffic[flarm_slot].TrackBearing, // double 6 &GPS_INFO.FLARM_Traffic[flarm_slot].TurnRate, // double 7 &GPS_INFO.FLARM_Traffic[flarm_slot].Speed, // double 8 m/s &GPS_INFO.FLARM_Traffic[flarm_slot].ClimbRate, // double 9 m/s &GPS_INFO.FLARM_Traffic[flarm_slot].Type); // unsigned short 10 */ // If first time seen this traffic, place it nearby if ( newtraffic ) { GPS_INFO.FLARM_Traffic[flarm_slot].RelativeNorth=2; GPS_INFO.FLARM_Traffic[flarm_slot].RelativeEast=2; GPS_INFO.FLARM_Traffic[flarm_slot].Latitude = SimNewCoordinate(GPS_INFO.Latitude, offset); GPS_INFO.FLARM_Traffic[flarm_slot].Longitude = SimNewCoordinate(GPS_INFO.Longitude,offset); GPS_INFO.FLARM_Traffic[flarm_slot].Altitude = SimNewAltitude(GPS_INFO.Altitude); GPS_INFO.FLARM_Traffic[flarm_slot].TrackBearing= (double) rand()/91.276; GPS_INFO.FLARM_Traffic[flarm_slot].AlarmLevel=0; GPS_INFO.FLARM_Traffic[flarm_slot].ID=ID; GPS_INFO.FLARM_Traffic[flarm_slot].TurnRate=0; GPS_INFO.FLARM_Traffic[flarm_slot].Speed= SimNewSpeed(GPS_INFO.Speed); GPS_INFO.FLARM_Traffic[flarm_slot].Status = LKT_REAL; } else { GPS_INFO.FLARM_Traffic[flarm_slot].Latitude += (double)(rand()/20000000.0)*(rand()>15000?1:-1); GPS_INFO.FLARM_Traffic[flarm_slot].Longitude += (double)(rand()/20000000.0)*(rand()>15000?1:-1); GPS_INFO.FLARM_Traffic[flarm_slot].Altitude += (double)(rand()/2200.0)*(rand()>15000?1:-1); } GPS_INFO.FLARM_Traffic[flarm_slot].RelativeAltitude = GPS_INFO.FLARM_Traffic[flarm_slot].Altitude - GPS_INFO.Altitude; // GPS_INFO.FLARM_Traffic[flarm_slot].Average30s = flarmCalculations.Average30s( GPS_INFO.FLARM_Traffic[flarm_slot].ID, GPS_INFO.Time, GPS_INFO.FLARM_Traffic[flarm_slot].Altitude); TCHAR *name = GPS_INFO.FLARM_Traffic[flarm_slot].Name; //TCHAR *cn = GPS_INFO.FLARM_Traffic[flarm_slot].Cn; // If there is no name yet, or if we have a pending update event.. if (!_tcslen(name) || GPS_INFO.FLARM_Traffic[flarm_slot].UpdateNameFlag ) { #ifdef DEBUG_SIMLKT if (GPS_INFO.FLARM_Traffic[flarm_slot].UpdateNameFlag ) { StartupStore(_T("... UpdateNameFlag for slot %d\n"),flarm_slot); } else { StartupStore(_T("... First lookup name for slot %d\n"),flarm_slot); } #endif GPS_INFO.FLARM_Traffic[flarm_slot].UpdateNameFlag=false; // clear flag first TCHAR *fname = LookupFLARMDetails(GPS_INFO.FLARM_Traffic[flarm_slot].ID); if (fname) { LK_tcsncpy(name,fname,MAXFLARMNAME); // Now we have the name, so lookup also for the Cn // This will return either real Cn or Name, again TCHAR *cname = LookupFLARMCn(GPS_INFO.FLARM_Traffic[flarm_slot].ID); if (cname) { int cnamelen=_tcslen(cname); if (cnamelen<=MAXFLARMCN) { _tcscpy( GPS_INFO.FLARM_Traffic[flarm_slot].Cn, cname); } else { // else probably it is the Name again, and we create a fake Cn GPS_INFO.FLARM_Traffic[flarm_slot].Cn[0]=cname[0]; GPS_INFO.FLARM_Traffic[flarm_slot].Cn[1]=cname[cnamelen-2]; GPS_INFO.FLARM_Traffic[flarm_slot].Cn[2]=cname[cnamelen-1]; GPS_INFO.FLARM_Traffic[flarm_slot].Cn[3]=_T('\0'); } } else { _tcscpy( GPS_INFO.FLARM_Traffic[flarm_slot].Cn, _T("Err")); } #ifdef DEBUG_SIMLKT StartupStore(_T("... PFLAA Name to FlarmSlot=%d ID=%lx Name=<%s> Cn=<%s>\n"), flarm_slot, GPS_INFO.FLARM_Traffic[flarm_slot].ID, GPS_INFO.FLARM_Traffic[flarm_slot].Name, GPS_INFO.FLARM_Traffic[flarm_slot].Cn); #endif } else { // Else we NEED to set a name, otherwise it will constantly search for it over and over.. name[0]=_T('?'); name[1]=_T('\0'); GPS_INFO.FLARM_Traffic[flarm_slot].Cn[0]=_T('?'); GPS_INFO.FLARM_Traffic[flarm_slot].Cn[1]=_T('\0'); #ifdef DEBUG_SIMLKT StartupStore(_T("... New FlarmSlot=%d ID=%lx with no name, assigned a \"?\"\n"), flarm_slot, GPS_INFO.FLARM_Traffic[flarm_slot].ID); #endif } } // update Virtual Waypoint for target FLARM if (flarm_slot == LKTargetIndex) { WayPointList[RESWP_FLARMTARGET].Latitude = GPS_INFO.FLARM_Traffic[LKTargetIndex].Latitude; WayPointList[RESWP_FLARMTARGET].Longitude = GPS_INFO.FLARM_Traffic[LKTargetIndex].Longitude; WayPointList[RESWP_FLARMTARGET].Altitude = GPS_INFO.FLARM_Traffic[LKTargetIndex].Altitude; } }
BOOL NMEAParser::PFLAA(TCHAR *String, TCHAR **params, size_t nparams, NMEA_INFO *pGPS) { int flarm_slot = 0; isFlarm = true; // 5 id, 6 digit hex long ID; swscanf(params[5],TEXT("%lx"), &ID); // unsigned long uID = ID; flarm_slot = FLARM_FindSlot(pGPS, ID); if (flarm_slot<0) { // no more slots available, #ifdef DEBUG_LKT StartupStore(_T("... NO SLOTS for Flarm traffic, too many ids!%s"),NEWLINE); #endif return FALSE; } // before changing timefix, see if it was an old target back locked in! CheckBackTarget(pGPS, flarm_slot); // and then set time of fix to current time pGPS->FLARM_Traffic[flarm_slot].Time_Fix = pGPS->Time; TCHAR nString[MAX_NMEA_LEN+1]; unsigned int i, j; for (i=0, j=0; i<_tcslen(String); i++) { // if not a comma, copy and proceed if (String[i] != _T(',')) { nString[j++]=String[i]; continue; } // there was a comma, but the next one is not a comma, so ok.. if (String[i+1] != _T(',') ) { nString[j++]=String[i]; continue; } // We have a bad ,, case that scanf cannot bear with, so we add a 0 nString[j++] = String[i]; nString[j++] = _T('0'); } nString[j]=_T('\0'); //#ifdef DEBUG_LKT //StartupStore(_T("PFLAA: %s%s"),nString,NEWLINE); //#endif _stscanf(nString, TEXT("%hu,%lf,%lf,%lf,%hu,%lx,%lf,%lf,%lf,%lf,%hu"), &pGPS->FLARM_Traffic[flarm_slot].AlarmLevel, // unsigned short 0 &pGPS->FLARM_Traffic[flarm_slot].RelativeNorth, // 1 &pGPS->FLARM_Traffic[flarm_slot].RelativeEast, // 2 &pGPS->FLARM_Traffic[flarm_slot].RelativeAltitude, // 3 &pGPS->FLARM_Traffic[flarm_slot].IDType, // unsigned short 4 &pGPS->FLARM_Traffic[flarm_slot].ID, // 6 char hex &pGPS->FLARM_Traffic[flarm_slot].TrackBearing, // double 6 &pGPS->FLARM_Traffic[flarm_slot].TurnRate, // double 7 &pGPS->FLARM_Traffic[flarm_slot].Speed, // double 8 m/s &pGPS->FLARM_Traffic[flarm_slot].ClimbRate, // double 9 m/s &pGPS->FLARM_Traffic[flarm_slot].Type); // unsigned short 10 // 1 relativenorth, meters pGPS->FLARM_Traffic[flarm_slot].Latitude = pGPS->FLARM_Traffic[flarm_slot].RelativeNorth *FLARM_NorthingToLatitude + pGPS->Latitude; // 2 relativeeast, meters pGPS->FLARM_Traffic[flarm_slot].Longitude = pGPS->FLARM_Traffic[flarm_slot].RelativeEast *FLARM_EastingToLongitude + pGPS->Longitude; // we need to compare with BARO altitude FLARM relative Alt difference! if (pGPS->BaroAltitude>0) // just to be sure pGPS->FLARM_Traffic[flarm_slot].Altitude = pGPS->FLARM_Traffic[flarm_slot].RelativeAltitude + pGPS->BaroAltitude; else pGPS->FLARM_Traffic[flarm_slot].Altitude = pGPS->FLARM_Traffic[flarm_slot].RelativeAltitude + pGPS->Altitude; pGPS->FLARM_Traffic[flarm_slot].Average30s = flarmCalculations.Average30s( pGPS->FLARM_Traffic[flarm_slot].ID, pGPS->Time, pGPS->FLARM_Traffic[flarm_slot].Altitude); TCHAR *name = pGPS->FLARM_Traffic[flarm_slot].Name; //TCHAR *cn = pGPS->FLARM_Traffic[flarm_slot].Cn; // If there is no name yet, or if we have a pending update event.. if (!_tcslen(name) || pGPS->FLARM_Traffic[flarm_slot].UpdateNameFlag ) { #ifdef DEBUG_LKT if (pGPS->FLARM_Traffic[flarm_slot].UpdateNameFlag ) { StartupStore(_T("... UpdateNameFlag for slot %d\n"),flarm_slot); } else { StartupStore(_T("... First lookup name for slot %d\n"),flarm_slot); } #endif pGPS->FLARM_Traffic[flarm_slot].UpdateNameFlag=false; // clear flag first TCHAR *fname = LookupFLARMDetails(pGPS->FLARM_Traffic[flarm_slot].ID); if (fname) { LK_tcsncpy(name,fname,MAXFLARMNAME); // Now we have the name, so lookup also for the Cn // This will return either real Cn or Name, again TCHAR *cname = LookupFLARMCn(pGPS->FLARM_Traffic[flarm_slot].ID); if (cname) { int cnamelen=_tcslen(cname); if (cnamelen<=MAXFLARMCN) { _tcscpy( pGPS->FLARM_Traffic[flarm_slot].Cn, cname); } else { // else probably it is the Name again, and we create a fake Cn pGPS->FLARM_Traffic[flarm_slot].Cn[0]=cname[0]; pGPS->FLARM_Traffic[flarm_slot].Cn[1]=cname[cnamelen-2]; pGPS->FLARM_Traffic[flarm_slot].Cn[2]=cname[cnamelen-1]; pGPS->FLARM_Traffic[flarm_slot].Cn[3]=_T('\0'); } } else { _tcscpy( pGPS->FLARM_Traffic[flarm_slot].Cn, _T("Err")); } #ifdef DEBUG_LKT StartupStore(_T("... PFLAA Name to FlarmSlot=%d ID=%lx Name=<%s> Cn=<%s>\n"), flarm_slot, pGPS->FLARM_Traffic[flarm_slot].ID, pGPS->FLARM_Traffic[flarm_slot].Name, pGPS->FLARM_Traffic[flarm_slot].Cn); #endif } else { // Else we NEED to set a name, otherwise it will constantly search for it over and over.. name[0]=_T('?'); name[1]=_T('\0'); pGPS->FLARM_Traffic[flarm_slot].Cn[0]=_T('?'); pGPS->FLARM_Traffic[flarm_slot].Cn[1]=_T('\0'); #ifdef DEBUG_LKT StartupStore(_T("... New FlarmSlot=%d ID=%lx with no name, assigned a \"?\"\n"), flarm_slot, pGPS->FLARM_Traffic[flarm_slot].ID); #endif } } #ifdef DEBUG_LKT StartupStore(_T("... PFLAA pGPS slot=%d ID=%lx name=<%s> cn=<%s> rAlt=%.0f Track=%.0f Speed=%.0f Climb=%.1f Baro=%f FlAlt=%f\n"), flarm_slot, pGPS->FLARM_Traffic[flarm_slot].ID, pGPS->FLARM_Traffic[flarm_slot].Name, pGPS->FLARM_Traffic[flarm_slot].Cn, pGPS->FLARM_Traffic[flarm_slot].RelativeAltitude, pGPS->FLARM_Traffic[flarm_slot].TrackBearing, pGPS->FLARM_Traffic[flarm_slot].Speed, pGPS->FLARM_Traffic[flarm_slot].ClimbRate, pGPS->BaroAltitude, pGPS->FLARM_Traffic[flarm_slot].Altitude); #endif // update Virtual Waypoint for target FLARM if (flarm_slot == LKTargetIndex) { WayPointList[RESWP_FLARMTARGET].Latitude = pGPS->FLARM_Traffic[LKTargetIndex].Latitude; WayPointList[RESWP_FLARMTARGET].Longitude = pGPS->FLARM_Traffic[LKTargetIndex].Longitude; WayPointList[RESWP_FLARMTARGET].Altitude = pGPS->FLARM_Traffic[LKTargetIndex].Altitude; } return FALSE; }