/** * @brief Test loading of gpx files using TrackManager (threaded) */ void TestTracks::testFileLoading() { QUrl testDataDir = QUrl::fromLocalFile(GetTestDataDirectory() + QLatin1Char('/') + QLatin1String("gpxfile-1.gpx")); QList<QUrl> fileList; fileList << testDataDir; TrackManager myParser; QSignalSpy spyTrackFiles(&myParser, SIGNAL(signalTracksChanged(const QList<TrackManager::TrackChanges>))); QSignalSpy spyAllDone(&myParser, SIGNAL(signalAllTrackFilesReady())); myParser.loadTrackFiles(fileList); // wait until the files are loaded: while (spyAllDone.isEmpty()) { QTest::qWait(100); } QCOMPARE(spyAllDone.count(), 1); QCOMPARE(spyTrackFiles.count(), 1); const TrackManager::Track& file1 = myParser.getTrack(0); QVERIFY(!file1.points.isEmpty()); }
//------------------------------------------------------------------------------ // requestNextToShoot() -- Requests a specific track to be the next-to-shoot; // Returns true if successful //------------------------------------------------------------------------------ bool OnboardComputer::requestNextToShoot(const Track* const nts) { bool ok = false; if (nts != 0) { // First, let's get the active track list const unsigned int MAX_TRKS = 20; SPtr<Track> trackList[MAX_TRKS]; int n = 0; TrackManager* tm = getTrackManagerByType(typeid(AirTrkMgr)); // fall back to whatever TM we have, if we don't have an AirTrkMgr if (tm == 0) tm = getTrackManagerByType(typeid(TrackManager)); if (tm != 0) n = tm->getTrackList(trackList,MAX_TRKS); if (n > 0) { // try to find the requested track and save its index int nNTS = -1; for (int i = 0; i < n && nNTS < 0; i++) { if (nts == trackList[i]) nNTS = i; } // update the shoot list index values in the tracks if (nNTS >= 0) { // Start at the next-to-shoot int idx = nNTS; for (int i = 0; i < n; i++) { trackList[idx++]->setShootListIndex(i+1); if (idx >= n) idx = 0; } ok = true; } // Update the next to shoot if (ok) setNextToShoot(trackList[nNTS]); } } return ok; }
//------------------------------------------------------------------------------ // Manage the weapon release event //------------------------------------------------------------------------------ bool SimpleStoresMgr::onWpnRelEvent(const base::Boolean* const sw) { // Weapon release follows the switch or by default is true bool wpnRel = true; if (sw != nullptr) wpnRel = sw->getBoolean(); if ( wpnRel && (isWeaponDeliveryMode(A2A) || isWeaponDeliveryMode(A2G)) ) { // A/A missiles and A/G bombs only ... Weapon* wpn = getCurrentWeapon(); if (wpn != nullptr) { // release the weapon --- // if successful, returns a pre-ref()'d pointer to the flyout weapon. Weapon* flyout = releaseWeapon(wpn); if (flyout != nullptr) { if (isWeaponDeliveryMode(A2A)) { // --- // Setup the guidance ... // --- Track* trk = getNextTarget(); if (trk != nullptr) { Player* tgt = trk->getTarget(); TrackManager* tm = nullptr; RfSensor* sm = flyout->getSensor(); if (sm != nullptr) tm = sm->getTrackManager(); if (tm != nullptr) { // Give a copy of the track to the weapon's track manager Track* newTrk = trk->clone(); tm->clearTracksAndQueues(); tm->addTrack(newTrk); flyout->setTargetTrack(newTrk,true); } else if (tgt != nullptr) { // No sensor -- fake it and just track the target flyout->setTargetPlayer(tgt,true); } else { // no target track } trk->setWeaponReleased(true); } } // Set the weapon release timer setWeaponReleaseTimer(1.0); } if (flyout != nullptr) flyout->unref(); // unref() the flyout wpn->unref(); wpn = nullptr; } } else { setWeaponReleaseTimer(0); } return true; }
//------------------------------------------------------------------------------ // updateShootList() -- Update the shoot list. When the step flag is true, // force step to the next target. //------------------------------------------------------------------------------ void OnboardComputer::updateShootList(const bool step) { // Temporary next to shoot indexes int cNTS = -1; // Current int nNTS = -1; // New // First, let's get the active track list const unsigned int MAX_TRKS = 20; SPtr<Track> trackList[MAX_TRKS]; int n = 0; TrackManager* tm = getTrackManagerByType(typeid(AirTrkMgr)); // fall back to whatever TM we have, if we don't have an AirTrkMgr if (tm == 0) tm = getTrackManagerByType(typeid(TrackManager)); if (tm != 0) n = tm->getTrackList(trackList,MAX_TRKS); if (n > 0) { // --- // Find the current next-to-shoot index // --- Track* nts = nextToShoot; if (nextToShoot != 0) { for (int i = 0; i < n && cNTS < 0; i++) { if (nts == trackList[i]) cNTS = i; } } // --- // Update the next to shoot? // --- if (cNTS < 0) { // 1) When we don't have or couldn't find our NTS, pick the closest track // that has a valid ground speed. int i = 0; do { if (trackList[i]->getGroundSpeed() >= 1.0f) { if (nNTS >= 0) { // is this one closer? if (trackList[i]->getRange() < trackList[nNTS]->getRange()) { nNTS = i; } } else { // only one so far nNTS = i; } } i = i + 1; if (i >= n) i = 0; } while (i != 0); } else if (step) { // 2) When a target step has been requested ... int i = cNTS + 1; if (i >= n) i = 0; do { if (trackList[i]->getGroundSpeed() >= 50.0f) { nNTS = i; } i = i + 1; if (i >= n) i = 0; } while (nNTS < 0 && i != cNTS); } else { // 3) Keep the same next-to-shoot track nNTS = cNTS; } // --- // update the shoot list index values in the tracks // --- if (nNTS >= 0) { // Start at the next-to-shoot int idx = nNTS; for (int i = 0; i < n; i++) { trackList[idx++]->setShootListIndex(i+1); if (idx >= n) idx = 0; } } else { // When there isn't a next to shoot, clear all for (int i = 0; i < n; i++) trackList[i]->setShootListIndex(0); } } // Update the next to shoot if (nNTS >= 0) setNextToShoot( trackList[nNTS] ); else setNextToShoot(0); }
//------------------------------------------------------------------------------ // process() -- process the TWS reports //------------------------------------------------------------------------------ void Radar::process(const LCreal dt) { BaseClass::process(dt); // Find the track manager TrackManager* tm = getTrackManager(); if (tm == nullptr) { // No track manager! Then just flush the input queue. lcLock(myLock); for (Emission* em = rptQueue.get(); em != nullptr; em = rptQueue.get()) { em->unref(); rptSnQueue.get(); } lcUnlock(myLock); } // --- // When end of scan, send all unsent reports to the track manager // --- if (endOfScanFlg) { endOfScanFlg = false; lcLock(myLock); for (unsigned int i = 0; i < numReports && i < MAX_REPORTS; i++) { if (tm != nullptr) { tm->newReport(reports[i], rptMaxSn[i]); } reports[i]->unref(); reports[i] = nullptr; rptMaxSn[i] = 0; } numReports = 0; lcUnlock(myLock); } // --- // Process our returned emissions into reports for the track manager // 1) Match each emission with existing reports // 2) On emission/report matches, if the S/N value of the new emission // is greater than the report, use the new emission // 3) Create new reports for unmatched emissions // --- lcLock(myLock); while (rptQueue.isNotEmpty()) { // Get the emission Emission* em = rptQueue.get(); LCreal snDbl = rptSnQueue.get(); if (em != nullptr) { // --- // 1) Match the emission with existing reports // --- int matched = -1; for (unsigned int i = 0; i < numReports && matched < 0; i++) { // Compare targets if ( em->getTarget() == reports[i]->getTarget() ) { // We have a match!!! matched = i; } } // --- // 2) On emission/report match // --- if (matched >= 0) { if (snDbl > rptMaxSn[matched]) { // When the S/N value of the new emission is greater than the report, // we use the new emission reports[matched]->unref(); em->ref(); reports[matched] = em; rptMaxSn[matched] = snDbl; } } // --- // 3) Create a new report entry for the unmatched emission // --- if (matched < 0 && numReports < MAX_REPORTS) { em->ref(); reports[numReports] = em; rptMaxSn[numReports] = snDbl; numReports++; } // finished em->unref(); } } lcUnlock(myLock); }
//------------------------------------------------------------------------------ // receive() -- process received emissions //------------------------------------------------------------------------------ void Rwr::receive(const LCreal dt) { BaseClass::receive(dt); // clear the back buffer clearRays(0); // Receiver losses #if 0 LCreal noise = getRfRecvNoise(); #else LCreal noise = getRfRecvNoise() * getRfReceiveLoss(); #endif // Process received emissions TrackManager* tm = getTrackManager(); Emission* em = 0; LCreal signal = 0; // Get an emission from the queue lcLock(packetLock); if (np > 0) { np--; // Decrement 'np', now the array index em = packets[np]; signal = signals[np]; } lcUnlock(packetLock); while (em != 0) { //std::cout << "Rwr::receive(" << em->getOwnship() << "): "; //std::cout << " pwr=" << em->getPower(); //std::cout << " gain=" << em->getGain(); //std::cout << " rl=" << rl; //std::cout << " pulses=" << pulses; //std::cout << " losses=" << losses; //std::cout << " signal=" << signal; //std::cout << " recvN=" << getRfRecvNoise(); //std::cout << " sn=" << sn; //std::cout << " snDbl=" << snDbl; //std::cout << " thrs=" << getRfThreshold(); //std::cout << std::endl; // CGB, if "signal <= 0.0", then "snDbl" is probably invalid if (signal > 0.0 && dt != 0.0) { // Signal over noise (equation 3-5) LCreal sn = signal / noise; LCreal snDbl = 10.0f * lcLog10(sn); // Is S/N above receiver threshold ## dpg -- for now, don't include ECM emissions if (snDbl > getRfThreshold() && !em->isECM() && rptQueue.isNotFull()) { // Send report to the track manager if (tm != 0) { tm->newReport(em, snDbl); } // Get Angle Of Arrival LCreal aoa= em->getAzimuthAoi(); // Store received power for real-beam display LCreal sigDbl = 10.0f * lcLog10(signal); LCreal signal10 = (sigDbl + 50.0f)/50.f; int idx = getRayIndex( static_cast<LCreal>(Basic::Angle::R2DCC * aoa) ); rays[0][idx] = lim01(rays[0][idx] + signal10); //if (idx == 0 && getOwnship()->getID() == 1011) { // std::cout << "sig = " << signal10 << std::endl; //} // Send to the track list processor em->ref(); // ref() for track list processing rptQueue.put(em); } } // finished em->unref(); // this unref() undoes the ref() done by RfSystem::rfReceivedEmission em = 0; // Get another emission from the queue lcLock(packetLock); if (np > 0) { np--; em = packets[np]; signal = signals[np]; } lcUnlock(packetLock); } // Transfer the rays xferRays(); }