mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-04 05:30:32 -05:00 
			
		
		
		
	Merge pull request #1419 from srcejon/sat_tracker_threading_and_fix
Sat tracker and rotator controller threading updates for #1346
This commit is contained in:
		
						commit
						71ba8fd146
					
				@ -49,12 +49,12 @@ const char* const GS232Controller::m_featureIdURI = "sdrangel.feature.gs232contr
 | 
			
		||||
const char* const GS232Controller::m_featureId = "GS232Controller";
 | 
			
		||||
 | 
			
		||||
GS232Controller::GS232Controller(WebAPIAdapterInterface *webAPIAdapterInterface) :
 | 
			
		||||
    Feature(m_featureIdURI, webAPIAdapterInterface)
 | 
			
		||||
    Feature(m_featureIdURI, webAPIAdapterInterface),
 | 
			
		||||
    m_thread(nullptr),
 | 
			
		||||
    m_worker(nullptr)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("GS232Controller::GS232Controller: webAPIAdapterInterface: %p", webAPIAdapterInterface);
 | 
			
		||||
    setObjectName(m_featureId);
 | 
			
		||||
    m_worker = new GS232ControllerWorker();
 | 
			
		||||
    m_worker->moveToThread(&m_thread);
 | 
			
		||||
    m_state = StIdle;
 | 
			
		||||
    m_errorMessage = "GS232Controller error";
 | 
			
		||||
    m_selectedPipe = nullptr;
 | 
			
		||||
@ -124,22 +124,22 @@ GS232Controller::~GS232Controller()
 | 
			
		||||
        &GS232Controller::networkManagerFinished
 | 
			
		||||
    );
 | 
			
		||||
    delete m_networkManager;
 | 
			
		||||
    if (m_worker->isRunning()) {
 | 
			
		||||
        stop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    delete m_worker;
 | 
			
		||||
    stop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GS232Controller::start()
 | 
			
		||||
{
 | 
			
		||||
    qDebug("GS232Controller::start");
 | 
			
		||||
 | 
			
		||||
    m_worker->reset();
 | 
			
		||||
    m_thread = new QThread(this);
 | 
			
		||||
    m_worker = new GS232ControllerWorker();
 | 
			
		||||
    m_worker->moveToThread(m_thread);
 | 
			
		||||
    QObject::connect(m_thread, &QThread::started, m_worker, &GS232ControllerWorker::startWork);
 | 
			
		||||
    QObject::connect(m_thread, &QThread::finished, m_worker, &QObject::deleteLater);
 | 
			
		||||
    QObject::connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater);
 | 
			
		||||
    m_worker->setMessageQueueToFeature(getInputMessageQueue());
 | 
			
		||||
    bool ok = m_worker->startWork();
 | 
			
		||||
    m_state = ok ? StRunning : StError;
 | 
			
		||||
    m_thread.start();
 | 
			
		||||
    m_thread->start();
 | 
			
		||||
    m_state = StRunning;
 | 
			
		||||
 | 
			
		||||
    GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg = GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(m_settings, true);
 | 
			
		||||
    m_worker->getInputMessageQueue()->push(msg);
 | 
			
		||||
@ -150,10 +150,14 @@ void GS232Controller::start()
 | 
			
		||||
void GS232Controller::stop()
 | 
			
		||||
{
 | 
			
		||||
    qDebug("GS232Controller::stop");
 | 
			
		||||
    m_worker->stopWork();
 | 
			
		||||
    m_state = StIdle;
 | 
			
		||||
    m_thread.quit();
 | 
			
		||||
    m_thread.wait();
 | 
			
		||||
    if (m_thread)
 | 
			
		||||
    {
 | 
			
		||||
        m_thread->quit();
 | 
			
		||||
        m_thread->wait();
 | 
			
		||||
        m_thread = nullptr;
 | 
			
		||||
        m_worker = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GS232Controller::handleMessage(const Message& cmd)
 | 
			
		||||
@ -404,7 +408,9 @@ void GS232Controller::applySettings(const GS232ControllerSettings& settings, boo
 | 
			
		||||
    GS232ControllerWorker::MsgConfigureGS232ControllerWorker *msg = GS232ControllerWorker::MsgConfigureGS232ControllerWorker::create(
 | 
			
		||||
        settings, force
 | 
			
		||||
    );
 | 
			
		||||
    m_worker->getInputMessageQueue()->push(msg);
 | 
			
		||||
    if (m_worker) {
 | 
			
		||||
        m_worker->getInputMessageQueue()->push(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.m_useReverseAPI)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
@ -169,7 +169,7 @@ public:
 | 
			
		||||
    static const char* const m_featureId;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QThread m_thread;
 | 
			
		||||
    QThread *m_thread;
 | 
			
		||||
    GS232ControllerWorker *m_worker;
 | 
			
		||||
    GS232ControllerSettings m_settings;
 | 
			
		||||
    QHash<QObject*, GS232ControllerSettings::AvailableChannelOrFeature> m_availableChannelOrFeatures;
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,6 @@ MESSAGE_CLASS_DEFINITION(GS232ControllerReport::MsgReportAzAl, Message)
 | 
			
		||||
 | 
			
		||||
GS232ControllerWorker::GS232ControllerWorker() :
 | 
			
		||||
    m_msgQueueToFeature(nullptr),
 | 
			
		||||
    m_running(false),
 | 
			
		||||
    m_device(nullptr),
 | 
			
		||||
    m_serialPort(this),
 | 
			
		||||
    m_socket(this),
 | 
			
		||||
@ -48,33 +47,15 @@ GS232ControllerWorker::GS232ControllerWorker() :
 | 
			
		||||
 | 
			
		||||
GS232ControllerWorker::~GS232ControllerWorker()
 | 
			
		||||
{
 | 
			
		||||
    qDebug() << "GS232ControllerWorker::~GS232ControllerWorker";
 | 
			
		||||
    m_inputMessageQueue.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GS232ControllerWorker::reset()
 | 
			
		||||
void GS232ControllerWorker::startWork()
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
    m_inputMessageQueue.clear();
 | 
			
		||||
    m_lastAzimuth = -1.0f;
 | 
			
		||||
    m_lastElevation = -1.0f;
 | 
			
		||||
    m_spidSetOutstanding = false;
 | 
			
		||||
    m_spidSetSent = false;
 | 
			
		||||
    m_spidStatusSent = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GS232ControllerWorker::startWork()
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
    qDebug() << "GS232ControllerWorker::startWork";
 | 
			
		||||
    connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
 | 
			
		||||
    connect(thread(), SIGNAL(started()), this, SLOT(started()));
 | 
			
		||||
    connect(thread(), SIGNAL(finished()), this, SLOT(finished()));
 | 
			
		||||
    m_running = true;
 | 
			
		||||
    return m_running;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// startWork() is called from main thread. Serial ports on Linux need to be opened/closed on worker thread
 | 
			
		||||
void GS232ControllerWorker::started()
 | 
			
		||||
{
 | 
			
		||||
    connect(thread(), SIGNAL(finished()), this, SLOT(stopWork()));
 | 
			
		||||
    connect(&m_serialPort, &QSerialPort::readyRead, this, &GS232ControllerWorker::readData);
 | 
			
		||||
    connect(&m_socket, &QTcpSocket::readyRead, this, &GS232ControllerWorker::readData);
 | 
			
		||||
    if (m_settings.m_connection == GS232ControllerSettings::TCP) {
 | 
			
		||||
@ -84,18 +65,14 @@ void GS232ControllerWorker::started()
 | 
			
		||||
    }
 | 
			
		||||
    connect(&m_pollTimer, SIGNAL(timeout()), this, SLOT(update()));
 | 
			
		||||
    m_pollTimer.start(1000);
 | 
			
		||||
    disconnect(thread(), SIGNAL(started()), this, SLOT(started()));
 | 
			
		||||
    // Handle any messages already on the queue
 | 
			
		||||
    handleInputMessages();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GS232ControllerWorker::stopWork()
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
    qDebug() << "GS232ControllerWorker::stopWork";
 | 
			
		||||
    disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GS232ControllerWorker::finished()
 | 
			
		||||
{
 | 
			
		||||
    // Close serial port as USB/controller activity can create RFI
 | 
			
		||||
    if (m_device && m_device->isOpen()) {
 | 
			
		||||
        m_device->close();
 | 
			
		||||
    }
 | 
			
		||||
@ -103,8 +80,6 @@ void GS232ControllerWorker::finished()
 | 
			
		||||
    disconnect(&m_socket, &QTcpSocket::readyRead, this, &GS232ControllerWorker::readData);
 | 
			
		||||
    m_pollTimer.stop();
 | 
			
		||||
    disconnect(&m_pollTimer, SIGNAL(timeout()), this, SLOT(update()));
 | 
			
		||||
    m_running = false;
 | 
			
		||||
    disconnect(thread(), SIGNAL(finished()), this, SLOT(finished()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GS232ControllerWorker::handleInputMessages()
 | 
			
		||||
@ -123,7 +98,6 @@ bool GS232ControllerWorker::handleMessage(const Message& cmd)
 | 
			
		||||
{
 | 
			
		||||
    if (MsgConfigureGS232ControllerWorker::match(cmd))
 | 
			
		||||
    {
 | 
			
		||||
        QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
        MsgConfigureGS232ControllerWorker& cfg = (MsgConfigureGS232ControllerWorker&) cmd;
 | 
			
		||||
 | 
			
		||||
        applySettings(cfg.getSettings(), cfg.getForce());
 | 
			
		||||
 | 
			
		||||
@ -58,8 +58,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    GS232ControllerWorker();
 | 
			
		||||
    ~GS232ControllerWorker();
 | 
			
		||||
    void reset();
 | 
			
		||||
    bool startWork();
 | 
			
		||||
    void startWork();
 | 
			
		||||
    void stopWork();
 | 
			
		||||
    bool isRunning() const { return m_running; }
 | 
			
		||||
    MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
 | 
			
		||||
@ -71,7 +70,6 @@ private:
 | 
			
		||||
    MessageQueue *m_msgQueueToFeature; //!< Queue to report channel change to main feature object
 | 
			
		||||
    GS232ControllerSettings m_settings;
 | 
			
		||||
    bool m_running;
 | 
			
		||||
    QRecursiveMutex m_mutex;
 | 
			
		||||
    QIODevice *m_device;
 | 
			
		||||
    QSerialPort m_serialPort;
 | 
			
		||||
    QTcpSocket m_socket;
 | 
			
		||||
@ -95,8 +93,6 @@ private:
 | 
			
		||||
    void setAzimuthElevation(float azimuth, float elevation);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void started();
 | 
			
		||||
    void finished();
 | 
			
		||||
    void handleInputMessages();
 | 
			
		||||
    void readData();
 | 
			
		||||
    void update();
 | 
			
		||||
 | 
			
		||||
@ -48,14 +48,14 @@ const char* const SatelliteTracker::m_featureId = "SatelliteTracker";
 | 
			
		||||
 | 
			
		||||
SatelliteTracker::SatelliteTracker(WebAPIAdapterInterface *webAPIAdapterInterface) :
 | 
			
		||||
    Feature(m_featureIdURI, webAPIAdapterInterface),
 | 
			
		||||
    m_thread(nullptr),
 | 
			
		||||
    m_worker(nullptr),
 | 
			
		||||
    m_updatingSatData(false),
 | 
			
		||||
    m_tleIndex(0),
 | 
			
		||||
    m_firstUpdateSatData(true)
 | 
			
		||||
{
 | 
			
		||||
    qDebug("SatelliteTracker::SatelliteTracker: webAPIAdapterInterface: %p", webAPIAdapterInterface);
 | 
			
		||||
    setObjectName(m_featureId);
 | 
			
		||||
    m_worker = new SatelliteTrackerWorker(this, webAPIAdapterInterface);
 | 
			
		||||
    m_worker->moveToThread(&m_thread);
 | 
			
		||||
    m_state = StIdle;
 | 
			
		||||
    m_errorMessage = "SatelliteTracker error";
 | 
			
		||||
    m_networkManager = new QNetworkAccessManager();
 | 
			
		||||
@ -73,11 +73,7 @@ SatelliteTracker::SatelliteTracker(WebAPIAdapterInterface *webAPIAdapterInterfac
 | 
			
		||||
 | 
			
		||||
SatelliteTracker::~SatelliteTracker()
 | 
			
		||||
{
 | 
			
		||||
    if (m_worker->isRunning()) {
 | 
			
		||||
        stop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    delete m_worker;
 | 
			
		||||
    stop();
 | 
			
		||||
    qDeleteAll(m_satState);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -92,12 +88,18 @@ void SatelliteTracker::start()
 | 
			
		||||
        FeatureWebAPIUtils::mapSetDateTime(currentDateTime());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_worker->reset();
 | 
			
		||||
    m_thread = new QThread(this);
 | 
			
		||||
    m_worker = new SatelliteTrackerWorker(this, m_webAPIAdapterInterface);
 | 
			
		||||
    m_worker->moveToThread(m_thread);
 | 
			
		||||
 | 
			
		||||
    QObject::connect(m_thread, &QThread::started, m_worker, &SatelliteTrackerWorker::startWork);
 | 
			
		||||
    QObject::connect(m_thread, &QThread::finished, m_worker, &QObject::deleteLater);
 | 
			
		||||
    QObject::connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater);
 | 
			
		||||
 | 
			
		||||
    m_worker->setMessageQueueToFeature(getInputMessageQueue());
 | 
			
		||||
    m_worker->setMessageQueueToGUI(getMessageQueueToGUI());
 | 
			
		||||
    bool ok = m_worker->startWork();
 | 
			
		||||
    m_state = ok ? StRunning : StError;
 | 
			
		||||
    m_thread.start();
 | 
			
		||||
    m_thread->start();
 | 
			
		||||
    m_state = StRunning;
 | 
			
		||||
 | 
			
		||||
    m_worker->getInputMessageQueue()->push(SatelliteTrackerWorker::MsgConfigureSatelliteTrackerWorker::create(m_settings, true));
 | 
			
		||||
    m_worker->getInputMessageQueue()->push(MsgSatData::create(m_satellites));
 | 
			
		||||
@ -106,10 +108,14 @@ void SatelliteTracker::start()
 | 
			
		||||
void SatelliteTracker::stop()
 | 
			
		||||
{
 | 
			
		||||
    qDebug("SatelliteTracker::stop");
 | 
			
		||||
    m_worker->stopWork();
 | 
			
		||||
    m_state = StIdle;
 | 
			
		||||
    m_thread.quit();
 | 
			
		||||
    m_thread.wait();
 | 
			
		||||
    if (m_thread)
 | 
			
		||||
    {
 | 
			
		||||
        m_thread->quit();
 | 
			
		||||
        m_thread->wait();
 | 
			
		||||
        m_thread = nullptr;
 | 
			
		||||
        m_worker = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SatelliteTracker::handleMessage(const Message& cmd)
 | 
			
		||||
@ -323,7 +329,9 @@ void SatelliteTracker::applySettings(const SatelliteTrackerSettings& settings, b
 | 
			
		||||
    SatelliteTrackerWorker::MsgConfigureSatelliteTrackerWorker *msg = SatelliteTrackerWorker::MsgConfigureSatelliteTrackerWorker::create(
 | 
			
		||||
        settings, force
 | 
			
		||||
    );
 | 
			
		||||
    m_worker->getInputMessageQueue()->push(msg);
 | 
			
		||||
    if (m_worker) {
 | 
			
		||||
        m_worker->getInputMessageQueue()->push(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (settings.m_useReverseAPI)
 | 
			
		||||
    {
 | 
			
		||||
@ -896,12 +904,12 @@ void SatelliteTracker::webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport&
 | 
			
		||||
        swgSatState->setPeriod(satState->m_period);
 | 
			
		||||
        swgSatState->setElevation(satState->m_elevation);
 | 
			
		||||
        QList<SWGSDRangel::SWGSatellitePass *> *passesList = new QList<SWGSDRangel::SWGSatellitePass*>();
 | 
			
		||||
        for (auto pass : satState->m_passes)
 | 
			
		||||
        for (auto const &pass : satState->m_passes)
 | 
			
		||||
        {
 | 
			
		||||
            SWGSDRangel::SWGSatellitePass *swgPass = new SWGSDRangel::SWGSatellitePass();
 | 
			
		||||
            swgPass->setAos(new QString(pass->m_aos.toString(Qt::ISODateWithMs)));
 | 
			
		||||
            swgPass->setLos(new QString(pass->m_los.toString(Qt::ISODateWithMs)));
 | 
			
		||||
            swgPass->setMaxElevation(pass->m_maxElevation);
 | 
			
		||||
            swgPass->setAos(new QString(pass.m_aos.toString(Qt::ISODateWithMs)));
 | 
			
		||||
            swgPass->setLos(new QString(pass.m_los.toString(Qt::ISODateWithMs)));
 | 
			
		||||
            swgPass->setMaxElevation(pass.m_maxElevation);
 | 
			
		||||
            passesList->append(swgPass);
 | 
			
		||||
        }
 | 
			
		||||
        swgSatState->setPasses(passesList);
 | 
			
		||||
@ -1024,7 +1032,8 @@ bool SatelliteTracker::readSatData()
 | 
			
		||||
                    if (m_guiMessageQueue)
 | 
			
		||||
                        m_guiMessageQueue->push(MsgSatData::create(m_satellites));
 | 
			
		||||
                    // Send to worker
 | 
			
		||||
                    m_worker->getInputMessageQueue()->push(MsgSatData::create(m_satellites));
 | 
			
		||||
                    if (m_worker)
 | 
			
		||||
                        m_worker->getInputMessageQueue()->push(MsgSatData::create(m_satellites));
 | 
			
		||||
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -173,7 +173,7 @@ public:
 | 
			
		||||
    bool isUpdatingSatData() { return m_updatingSatData; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QThread m_thread;
 | 
			
		||||
    QThread *m_thread;
 | 
			
		||||
    SatelliteTrackerWorker *m_worker;
 | 
			
		||||
    SatelliteTrackerSettings m_settings;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -125,12 +125,12 @@ bool SatelliteTrackerGUI::handleMessage(const Message& message)
 | 
			
		||||
            ui->elevation->setText(convertDegreesToText(satState->m_elevation));
 | 
			
		||||
            if (satState->m_passes.size() > 0)
 | 
			
		||||
            {
 | 
			
		||||
                SatellitePass *pass = satState->m_passes[0];
 | 
			
		||||
                bool geostationary = !pass->m_aos.isValid() && !pass->m_los.isValid();
 | 
			
		||||
                if ((m_nextTargetAOS != pass->m_aos) || (m_nextTargetLOS != pass->m_los) || (geostationary != m_geostationarySatVisible))
 | 
			
		||||
                const SatellitePass &pass = satState->m_passes[0];
 | 
			
		||||
                bool geostationary = !pass.m_aos.isValid() && !pass.m_los.isValid();
 | 
			
		||||
                if ((m_nextTargetAOS != pass.m_aos) || (m_nextTargetLOS != pass.m_los) || (geostationary != m_geostationarySatVisible))
 | 
			
		||||
                {
 | 
			
		||||
                    m_nextTargetAOS = pass->m_aos;
 | 
			
		||||
                    m_nextTargetLOS = pass->m_los;
 | 
			
		||||
                    m_nextTargetAOS = pass.m_aos;
 | 
			
		||||
                    m_nextTargetLOS = pass.m_los;
 | 
			
		||||
                    m_geostationarySatVisible = geostationary;
 | 
			
		||||
                    plotChart();
 | 
			
		||||
                    updateTimeToAOS();
 | 
			
		||||
@ -724,7 +724,7 @@ void SatelliteTrackerGUI::plotPolarChart()
 | 
			
		||||
        m_plotPass = m_targetSatState->m_passes.size() - 1;
 | 
			
		||||
        ui->passLabel->setText(QString("%1").arg(m_plotPass));
 | 
			
		||||
    }
 | 
			
		||||
    SatellitePass *pass = m_targetSatState->m_passes[m_plotPass];
 | 
			
		||||
    const SatellitePass &pass = m_targetSatState->m_passes[m_plotPass];
 | 
			
		||||
 | 
			
		||||
    // Always create a new chart, otherwise sometimes they aren't drawn properly
 | 
			
		||||
    m_polarChart = new QPolarChart();
 | 
			
		||||
@ -753,13 +753,13 @@ void SatelliteTrackerGUI::plotPolarChart()
 | 
			
		||||
 | 
			
		||||
    SatNogsSatellite *sat = m_satellites.value(m_settings.m_target);
 | 
			
		||||
 | 
			
		||||
    if (pass->m_aos.isValid() && pass->m_los.isValid())
 | 
			
		||||
    if (pass.m_aos.isValid() && pass.m_los.isValid())
 | 
			
		||||
    {
 | 
			
		||||
        QString title;
 | 
			
		||||
        if (m_settings.m_utc)
 | 
			
		||||
            title = pass->m_aos.date().toString(m_settings.m_dateFormat);
 | 
			
		||||
            title = pass.m_aos.date().toString(m_settings.m_dateFormat);
 | 
			
		||||
        else
 | 
			
		||||
            title = pass->m_aos.toLocalTime().date().toString(m_settings.m_dateFormat);
 | 
			
		||||
            title = pass.m_aos.toLocalTime().date().toString(m_settings.m_dateFormat);
 | 
			
		||||
        m_polarChart->setTitle(QString("%1").arg(title));
 | 
			
		||||
 | 
			
		||||
        QLineSeries *polarSeries = new QLineSeries();
 | 
			
		||||
@ -767,7 +767,7 @@ void SatelliteTrackerGUI::plotPolarChart()
 | 
			
		||||
        getPassAzEl(nullptr, nullptr, polarSeries,
 | 
			
		||||
                    sat->m_tle->m_tle0, sat->m_tle->m_tle1, sat->m_tle->m_tle2,
 | 
			
		||||
                    m_settings.m_latitude, m_settings.m_longitude, m_settings.m_heightAboveSeaLevel/1000.0,
 | 
			
		||||
                    pass->m_aos, pass->m_los);
 | 
			
		||||
                    pass.m_aos, pass.m_los);
 | 
			
		||||
 | 
			
		||||
        // Polar charts can't handle points that are more than 180 degrees apart, so
 | 
			
		||||
        // we need to split passes that cross from 359 -> 0 degrees (or the reverse)
 | 
			
		||||
@ -821,9 +821,9 @@ void SatelliteTrackerGUI::plotPolarChart()
 | 
			
		||||
        aosSeries->append(polarSeries->at(0));
 | 
			
		||||
        QTime time;
 | 
			
		||||
        if (m_settings.m_utc)
 | 
			
		||||
            time = pass->m_aos.time();
 | 
			
		||||
            time = pass.m_aos.time();
 | 
			
		||||
        else
 | 
			
		||||
            time = pass->m_aos.toLocalTime().time();
 | 
			
		||||
            time = pass.m_aos.toLocalTime().time();
 | 
			
		||||
        if (m_settings.m_utc)
 | 
			
		||||
            aosSeries->setPointLabelsFormat(QString("AOS %1").arg(time.toString("hh:mm")));
 | 
			
		||||
        else
 | 
			
		||||
@ -837,9 +837,9 @@ void SatelliteTrackerGUI::plotPolarChart()
 | 
			
		||||
        QLineSeries *losSeries = new QLineSeries();
 | 
			
		||||
        losSeries->append(polarSeries->at(polarSeries->count()-1));
 | 
			
		||||
        if (m_settings.m_utc)
 | 
			
		||||
            time = pass->m_los.time();
 | 
			
		||||
            time = pass.m_los.time();
 | 
			
		||||
        else
 | 
			
		||||
            time = pass->m_los.toLocalTime().time();
 | 
			
		||||
            time = pass.m_los.toLocalTime().time();
 | 
			
		||||
        losSeries->setPointLabelsFormat(QString("LOS %1").arg(time.toString("hh:mm")));
 | 
			
		||||
        losSeries->setPointLabelsVisible(true);
 | 
			
		||||
        losSeries->setPointLabelsClipping(false);
 | 
			
		||||
@ -854,13 +854,13 @@ void SatelliteTrackerGUI::plotPolarChart()
 | 
			
		||||
            currentTime = QDateTime::fromString(m_settings.m_dateTime, Qt::ISODateWithMs);
 | 
			
		||||
        else
 | 
			
		||||
            currentTime = QDateTime::fromString(m_settings.m_dateTime, Qt::ISODateWithMs).toUTC();
 | 
			
		||||
        if ((currentTime >= pass->m_aos) && (currentTime <= pass->m_los))
 | 
			
		||||
        if ((currentTime >= pass.m_aos) && (currentTime <= pass.m_los))
 | 
			
		||||
        {
 | 
			
		||||
            // Create series with single point, so we can plot current time
 | 
			
		||||
            QLineSeries *nowSeries = new QLineSeries();
 | 
			
		||||
            // Find closest point to current time
 | 
			
		||||
            int idx = std::round(polarSeries->count() * (currentTime.toMSecsSinceEpoch() - pass->m_aos.toMSecsSinceEpoch())
 | 
			
		||||
                                                       / (pass->m_los.toMSecsSinceEpoch() - pass->m_aos.toMSecsSinceEpoch()));
 | 
			
		||||
            int idx = std::round(polarSeries->count() * (currentTime.toMSecsSinceEpoch() - pass.m_aos.toMSecsSinceEpoch())
 | 
			
		||||
                                                       / (pass.m_los.toMSecsSinceEpoch() - pass.m_aos.toMSecsSinceEpoch()));
 | 
			
		||||
            nowSeries->append(polarSeries->at(idx));
 | 
			
		||||
            nowSeries->setPointLabelsFormat(m_settings.m_target);
 | 
			
		||||
            nowSeries->setPointLabelsVisible(true);
 | 
			
		||||
@ -928,7 +928,7 @@ void SatelliteTrackerGUI::plotAzElChart()
 | 
			
		||||
        m_plotPass = m_targetSatState->m_passes.size() - 1;
 | 
			
		||||
        ui->passLabel->setText(QString("%1").arg(m_plotPass));
 | 
			
		||||
    }
 | 
			
		||||
    SatellitePass *pass = m_targetSatState->m_passes[m_plotPass];
 | 
			
		||||
    const SatellitePass &pass = m_targetSatState->m_passes[m_plotPass];
 | 
			
		||||
 | 
			
		||||
    // Always create a new chart, otherwise sometimes they aren't drawn properly
 | 
			
		||||
    m_lineChart = new QChart();
 | 
			
		||||
@ -939,9 +939,9 @@ void SatelliteTrackerGUI::plotAzElChart()
 | 
			
		||||
 | 
			
		||||
    QString title;
 | 
			
		||||
    if (m_settings.m_utc)
 | 
			
		||||
        title = pass->m_aos.date().toString(m_settings.m_dateFormat);
 | 
			
		||||
        title = pass.m_aos.date().toString(m_settings.m_dateFormat);
 | 
			
		||||
    else
 | 
			
		||||
        title = pass->m_aos.toLocalTime().date().toString(m_settings.m_dateFormat);
 | 
			
		||||
        title = pass.m_aos.toLocalTime().date().toString(m_settings.m_dateFormat);
 | 
			
		||||
    m_lineChart->setTitle(QString("%1").arg(title));
 | 
			
		||||
    m_lineChart->legend()->hide();
 | 
			
		||||
    m_lineChart->addAxis(xAxis, Qt::AlignBottom);
 | 
			
		||||
@ -958,7 +958,7 @@ void SatelliteTrackerGUI::plotAzElChart()
 | 
			
		||||
    getPassAzEl(azSeries, elSeries, nullptr,
 | 
			
		||||
                sat->m_tle->m_tle0, sat->m_tle->m_tle1, sat->m_tle->m_tle2,
 | 
			
		||||
                m_settings.m_latitude, m_settings.m_longitude, m_settings.m_heightAboveSeaLevel/1000.0,
 | 
			
		||||
                pass->m_aos, pass->m_los);
 | 
			
		||||
                pass.m_aos, pass.m_los);
 | 
			
		||||
 | 
			
		||||
    // Split crossing of 360/0 degrees in to multiple series in the same colour
 | 
			
		||||
    QList<QLineSeries *> azSeriesList;
 | 
			
		||||
@ -989,7 +989,7 @@ void SatelliteTrackerGUI::plotAzElChart()
 | 
			
		||||
        azSeriesList[i]->attachAxis(xAxis);
 | 
			
		||||
        azSeriesList[i]->attachAxis(yRightAxis);
 | 
			
		||||
    }
 | 
			
		||||
    xAxis->setRange(pass->m_aos, pass->m_los);
 | 
			
		||||
    xAxis->setRange(pass.m_aos, pass.m_los);
 | 
			
		||||
    xAxis->setFormat("hh:mm");
 | 
			
		||||
    yLeftAxis->setRange(0.0, 90.0);
 | 
			
		||||
    yLeftAxis->setTickCount(7);
 | 
			
		||||
@ -1163,19 +1163,19 @@ void SatelliteTrackerGUI::updateTable(SatelliteState *satState)
 | 
			
		||||
    {
 | 
			
		||||
        // Get number of days to AOS/LOS
 | 
			
		||||
        QDateTime currentDateTime = m_satelliteTracker->currentDateTime();
 | 
			
		||||
        int daysToAOS = currentDateTime.daysTo(satState->m_passes[0]->m_aos);
 | 
			
		||||
        int daysToLOS = currentDateTime.daysTo(satState->m_passes[0]->m_los);
 | 
			
		||||
        if( satState->m_passes[ 0 ]->m_aos > currentDateTime )
 | 
			
		||||
            items[SAT_COL_TNE]->setText(formatSecondsHHMM(currentDateTime.secsTo(satState->m_passes[0]->m_aos))+" AOS");
 | 
			
		||||
        int daysToAOS = currentDateTime.daysTo(satState->m_passes[0].m_aos);
 | 
			
		||||
        int daysToLOS = currentDateTime.daysTo(satState->m_passes[0].m_los);
 | 
			
		||||
        if (satState->m_passes[0].m_aos > currentDateTime)
 | 
			
		||||
            items[SAT_COL_TNE]->setText(formatSecondsHHMM(currentDateTime.secsTo(satState->m_passes[0].m_aos))+" AOS");
 | 
			
		||||
        else
 | 
			
		||||
            items[SAT_COL_TNE]->setText(formatSecondsHHMM(currentDateTime.secsTo(satState->m_passes[0]->m_los))+" LOS");
 | 
			
		||||
        items[SAT_COL_DUR]->setText(formatSecondsHHMM(satState->m_passes[0]->m_aos.secsTo(satState->m_passes[0]->m_los)));
 | 
			
		||||
        items[SAT_COL_AOS]->setText(formatDaysTime(daysToAOS, satState->m_passes[0]->m_aos));
 | 
			
		||||
        items[SAT_COL_AOS]->setData(Qt::UserRole, satState->m_passes[0]->m_aos);
 | 
			
		||||
        items[SAT_COL_LOS]->setText(formatDaysTime(daysToLOS, satState->m_passes[0]->m_los));
 | 
			
		||||
        items[SAT_COL_LOS]->setData(Qt::UserRole, satState->m_passes[0]->m_los);
 | 
			
		||||
        items[SAT_COL_MAX_EL]->setData(Qt::DisplayRole, (int)round(satState->m_passes[0]->m_maxElevation));
 | 
			
		||||
        if (satState->m_passes[0]->m_northToSouth)
 | 
			
		||||
            items[SAT_COL_TNE]->setText(formatSecondsHHMM(currentDateTime.secsTo(satState->m_passes[0].m_los))+" LOS");
 | 
			
		||||
        items[SAT_COL_DUR]->setText(formatSecondsHHMM(satState->m_passes[0].m_aos.secsTo(satState->m_passes[0].m_los)));
 | 
			
		||||
        items[SAT_COL_AOS]->setText(formatDaysTime(daysToAOS, satState->m_passes[0].m_aos));
 | 
			
		||||
        items[SAT_COL_AOS]->setData(Qt::UserRole, satState->m_passes[0].m_aos);
 | 
			
		||||
        items[SAT_COL_LOS]->setText(formatDaysTime(daysToLOS, satState->m_passes[0].m_los));
 | 
			
		||||
        items[SAT_COL_LOS]->setData(Qt::UserRole, satState->m_passes[0].m_los);
 | 
			
		||||
        items[SAT_COL_MAX_EL]->setData(Qt::DisplayRole, (int)round(satState->m_passes[0].m_maxElevation));
 | 
			
		||||
        if (satState->m_passes[0].m_northToSouth)
 | 
			
		||||
            items[SAT_COL_DIR]->setText(QString("%1").arg(QChar(0x2193))); // Down arrow
 | 
			
		||||
        else
 | 
			
		||||
            items[SAT_COL_DIR]->setText(QString("%1").arg(QChar(0x2191))); // Up arrow
 | 
			
		||||
 | 
			
		||||
@ -195,7 +195,7 @@ bool SatelliteTrackerSettings::deserialize(const QByteArray& data)
 | 
			
		||||
        d.readBool(22, &m_drawOnMap, true);
 | 
			
		||||
        d.readBool(23, &m_autoTarget, true);
 | 
			
		||||
        d.readString(24, &m_aosSpeech, DEFAULT_AOS_SPEECH);
 | 
			
		||||
        d.readString(25, &m_aosCommand, DEFAULT_LOS_SPEECH);
 | 
			
		||||
        d.readString(25, &m_losSpeech, DEFAULT_LOS_SPEECH);
 | 
			
		||||
        d.readString(26, &m_aosCommand, "");
 | 
			
		||||
        d.readString(27, &m_losCommand, "");
 | 
			
		||||
        d.readBlob(28, &blob);
 | 
			
		||||
 | 
			
		||||
@ -121,7 +121,7 @@ void getGroundTrack(QDateTime dateTime,
 | 
			
		||||
void getPassAzEl(QLineSeries* azimuth, QLineSeries* elevation, QLineSeries* polar,
 | 
			
		||||
                        const QString& tle0, const QString& tle1, const QString& tle2,
 | 
			
		||||
                        double latitude, double longitude, double altitude,
 | 
			
		||||
                        QDateTime& aos, QDateTime& los)
 | 
			
		||||
                        const QDateTime& aos, const QDateTime& los)
 | 
			
		||||
{
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
@ -366,12 +366,12 @@ bool inPassWindow(DateTime dateTime, QTime passStartTime, QTime passEndTime, boo
 | 
			
		||||
 | 
			
		||||
// Create a list of satellite passes, between the given start and end times, that exceed the specified minimum elevation
 | 
			
		||||
// We return an uninitalised QDateTime if AOS or LOS is outside of predictionPeriod
 | 
			
		||||
static QList<SatellitePass *> createPassList(Observer& obs, SGP4& sgp4, DateTime& startTime,
 | 
			
		||||
static QList<SatellitePass> createPassList(Observer& obs, SGP4& sgp4, DateTime& startTime,
 | 
			
		||||
                                            int predictionPeriod, double minAOSElevation, double minPassElevationDeg,
 | 
			
		||||
                                            QTime passStartTime, QTime passEndTime, bool utc,
 | 
			
		||||
                                            int noOfPasses)
 | 
			
		||||
{
 | 
			
		||||
    QList<SatellitePass *> passes;
 | 
			
		||||
    QList<SatellitePass> passes;
 | 
			
		||||
    bool aos = false;
 | 
			
		||||
    bool aosUnknown = true;
 | 
			
		||||
    double aosAz;
 | 
			
		||||
@ -418,13 +418,13 @@ static QList<SatellitePass *> createPassList(Observer& obs, SGP4& sgp4, DateTime
 | 
			
		||||
                && inPassWindow(aosTime, passStartTime, passEndTime, utc)
 | 
			
		||||
                && inPassWindow(losTime, passStartTime, passEndTime, utc))
 | 
			
		||||
            {
 | 
			
		||||
                SatellitePass *pass = new SatellitePass;
 | 
			
		||||
                pass->m_aos = aosUnknown ? QDateTime() : dateTimeToQDateTime(aosTime);
 | 
			
		||||
                pass->m_los = dateTimeToQDateTime(losTime);
 | 
			
		||||
                pass->m_maxElevation = maxElevationDeg;
 | 
			
		||||
                pass->m_aosAzimuth = aosAz;
 | 
			
		||||
                pass->m_losAzimuth = losAz;
 | 
			
		||||
                pass->m_northToSouth = std::min(360.0-aosAz, aosAz-0.0) < std::min(360.0-losAz, losAz-0.0);
 | 
			
		||||
                SatellitePass pass;
 | 
			
		||||
                pass.m_aos = aosUnknown ? QDateTime() : dateTimeToQDateTime(aosTime);
 | 
			
		||||
                pass.m_los = dateTimeToQDateTime(losTime);
 | 
			
		||||
                pass.m_maxElevation = maxElevationDeg;
 | 
			
		||||
                pass.m_aosAzimuth = aosAz;
 | 
			
		||||
                pass.m_losAzimuth = losAz;
 | 
			
		||||
                pass.m_northToSouth = std::min(360.0-aosAz, aosAz-0.0) < std::min(360.0-losAz, losAz-0.0);
 | 
			
		||||
                passes.append(pass);
 | 
			
		||||
                noOfPasses--;
 | 
			
		||||
                if (noOfPasses <= 0)
 | 
			
		||||
@ -450,13 +450,13 @@ static QList<SatellitePass *> createPassList(Observer& obs, SGP4& sgp4, DateTime
 | 
			
		||||
            && inPassWindow(aosTime, passStartTime, passEndTime, utc)
 | 
			
		||||
            && inPassWindow(losTime, passStartTime, passEndTime, utc))
 | 
			
		||||
        {
 | 
			
		||||
            SatellitePass *pass = new SatellitePass;
 | 
			
		||||
            pass->m_aos = aosUnknown ? QDateTime() : dateTimeToQDateTime(aosTime);
 | 
			
		||||
            pass->m_los = QDateTime();
 | 
			
		||||
            pass->m_aosAzimuth = aosAz;
 | 
			
		||||
            pass->m_losAzimuth = losAz;
 | 
			
		||||
            pass->m_maxElevation = maxElevationDeg;
 | 
			
		||||
            pass->m_northToSouth = std::min(360.0-aosAz, aosAz-0.0) < std::min(360.0-losAz, losAz-0.0);
 | 
			
		||||
            SatellitePass pass;
 | 
			
		||||
            pass.m_aos = aosUnknown ? QDateTime() : dateTimeToQDateTime(aosTime);
 | 
			
		||||
            pass.m_los = QDateTime();
 | 
			
		||||
            pass.m_aosAzimuth = aosAz;
 | 
			
		||||
            pass.m_losAzimuth = losAz;
 | 
			
		||||
            pass.m_maxElevation = maxElevationDeg;
 | 
			
		||||
            pass.m_northToSouth = std::min(360.0-aosAz, aosAz-0.0) < std::min(360.0-losAz, losAz-0.0);
 | 
			
		||||
            passes.append(pass);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -499,7 +499,7 @@ void getSatelliteState(QDateTime dateTime,
 | 
			
		||||
        satState->m_period = ele.Period();
 | 
			
		||||
        if (noOfPasses > 0)
 | 
			
		||||
        {
 | 
			
		||||
            qDeleteAll(satState->m_passes);
 | 
			
		||||
            satState->m_passes.clear();
 | 
			
		||||
            satState->m_passes = createPassList(obs, sgp4, dt, predictionPeriod,
 | 
			
		||||
                                                Units::degreesToRadians((double)minAOSElevationDeg),
 | 
			
		||||
                                                minPassElevationDeg,
 | 
			
		||||
 | 
			
		||||
@ -45,8 +45,8 @@ struct SatelliteState {
 | 
			
		||||
    double m_rangeRate;                 // km/s
 | 
			
		||||
    double m_speed;
 | 
			
		||||
    double m_period;
 | 
			
		||||
    QList<SatellitePass *> m_passes;
 | 
			
		||||
    QList<QGeoCoordinate *> m_groundTrack;
 | 
			
		||||
    QList<SatellitePass> m_passes;              // Used in worker and GUI threads
 | 
			
		||||
    QList<QGeoCoordinate *> m_groundTrack;      // These used only in worker thread
 | 
			
		||||
    QList<QDateTime *> m_groundTrackDateTime;
 | 
			
		||||
    QList<QGeoCoordinate *> m_predictedGroundTrack;
 | 
			
		||||
    QList<QDateTime *> m_predictedGroundTrackDateTime;
 | 
			
		||||
@ -66,7 +66,7 @@ void getSatelliteState(QDateTime dateTime,
 | 
			
		||||
void getPassAzEl(QLineSeries *azimuth, QLineSeries *elevation, QLineSeries *polar,
 | 
			
		||||
                        const QString& tle0, const QString& tle1, const QString& tle2,
 | 
			
		||||
                        double latitude, double longitude, double altitude,
 | 
			
		||||
                        QDateTime& aos, QDateTime& los);
 | 
			
		||||
                        const QDateTime& aos, const QDateTime& los);
 | 
			
		||||
 | 
			
		||||
bool getPassesThrough0Deg(const QString& tle0, const QString& tle1, const QString& tle2,
 | 
			
		||||
                          double latitude, double longitude, double altitude,
 | 
			
		||||
 | 
			
		||||
@ -55,7 +55,6 @@ SatelliteTrackerWorker::SatelliteTrackerWorker(SatelliteTracker* satelliteTracke
 | 
			
		||||
    m_webAPIAdapterInterface(webAPIAdapterInterface),
 | 
			
		||||
    m_msgQueueToFeature(nullptr),
 | 
			
		||||
    m_msgQueueToGUI(nullptr),
 | 
			
		||||
    m_running(false),
 | 
			
		||||
    m_pollTimer(this),
 | 
			
		||||
    m_recalculatePasses(true),
 | 
			
		||||
    m_flipRotation(false),
 | 
			
		||||
@ -66,30 +65,19 @@ SatelliteTrackerWorker::SatelliteTrackerWorker(SatelliteTracker* satelliteTracke
 | 
			
		||||
 | 
			
		||||
SatelliteTrackerWorker::~SatelliteTrackerWorker()
 | 
			
		||||
{
 | 
			
		||||
    qDebug() << "SatelliteTrackerWorker::~SatelliteTrackerWorker";
 | 
			
		||||
    m_inputMessageQueue.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SatelliteTrackerWorker::reset()
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
    m_inputMessageQueue.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SatelliteTrackerWorker::startWork()
 | 
			
		||||
void SatelliteTrackerWorker::startWork()
 | 
			
		||||
{
 | 
			
		||||
    qDebug() << "SatelliteTrackerWorker::startWork";
 | 
			
		||||
    QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
    connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
 | 
			
		||||
    connect(thread(), SIGNAL(started()), this, SLOT(started()));
 | 
			
		||||
    connect(thread(), SIGNAL(finished()), this, SLOT(finished()));
 | 
			
		||||
    connect(thread(), SIGNAL(finished()), this, SLOT(stopWork()));
 | 
			
		||||
    m_recalculatePasses = true;
 | 
			
		||||
    m_running = true;
 | 
			
		||||
    return m_running;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// startWork() is called from main thread. Timers need to be started on worker thread
 | 
			
		||||
void SatelliteTrackerWorker::started()
 | 
			
		||||
{
 | 
			
		||||
    m_pollTimer.start((int)round(m_settings.m_updatePeriod*1000.0));
 | 
			
		||||
     m_pollTimer.start((int)round(m_settings.m_updatePeriod*1000.0));
 | 
			
		||||
    // Resume doppler timers
 | 
			
		||||
    QHashIterator<QString, SatWorkerState *> itr(m_workerState);
 | 
			
		||||
    while (itr.hasNext())
 | 
			
		||||
@ -99,17 +87,16 @@ void SatelliteTrackerWorker::started()
 | 
			
		||||
        if (satWorkerState->m_dopplerTimer.interval() > 0)
 | 
			
		||||
            satWorkerState->m_dopplerTimer.start();
 | 
			
		||||
    }
 | 
			
		||||
    disconnect(thread(), SIGNAL(started()), this, SLOT(started()));
 | 
			
		||||
 | 
			
		||||
    // Handle any messages already on the queue
 | 
			
		||||
    handleInputMessages();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SatelliteTrackerWorker::stopWork()
 | 
			
		||||
{
 | 
			
		||||
    qDebug() << "SatelliteTrackerWorker::stopWork";
 | 
			
		||||
    QMutexLocker mutexLocker(&m_mutex);
 | 
			
		||||
    disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SatelliteTrackerWorker::finished()
 | 
			
		||||
{
 | 
			
		||||
    m_pollTimer.stop();
 | 
			
		||||
    // Stop doppler timers
 | 
			
		||||
    QHashIterator<QString, SatWorkerState *> itr(m_workerState);
 | 
			
		||||
@ -118,8 +105,6 @@ void SatelliteTrackerWorker::finished()
 | 
			
		||||
        itr.next();
 | 
			
		||||
        itr.value()->m_dopplerTimer.stop();
 | 
			
		||||
    }
 | 
			
		||||
    m_running = false;
 | 
			
		||||
    disconnect(thread(), SIGNAL(finished()), this, SLOT(finished()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SatelliteTrackerWorker::handleInputMessages()
 | 
			
		||||
@ -334,7 +319,7 @@ void SatelliteTrackerWorker::update()
 | 
			
		||||
            {
 | 
			
		||||
                // Calculate position, AOS/LOS and other details for satellite
 | 
			
		||||
                int noOfPasses;
 | 
			
		||||
                bool recalcAsPastLOS = (satWorkerState->m_satState.m_passes.size() > 0) && (satWorkerState->m_satState.m_passes[0]->m_los < qdt);
 | 
			
		||||
                bool recalcAsPastLOS = (satWorkerState->m_satState.m_passes.size() > 0) && (satWorkerState->m_satState.m_passes[0].m_los < qdt);
 | 
			
		||||
                if (m_recalculatePasses || recalcAsPastLOS)
 | 
			
		||||
                    noOfPasses = (name == m_settings.m_target) ? 99 : 1;
 | 
			
		||||
                else
 | 
			
		||||
@ -349,13 +334,13 @@ void SatelliteTrackerWorker::update()
 | 
			
		||||
                if ((m_settings.m_dateTime == "") && (satWorkerState->m_satState.m_passes.size() > 0))
 | 
			
		||||
                {
 | 
			
		||||
                    // Do we have a new AOS?
 | 
			
		||||
                    if ((satWorkerState->m_aos != satWorkerState->m_satState.m_passes[0]->m_aos) || (satWorkerState->m_los != satWorkerState->m_satState.m_passes[0]->m_los))
 | 
			
		||||
                    if ((satWorkerState->m_aos != satWorkerState->m_satState.m_passes[0].m_aos) || (satWorkerState->m_los != satWorkerState->m_satState.m_passes[0].m_los))
 | 
			
		||||
                    {
 | 
			
		||||
                        qDebug() << "SatelliteTrackerWorker: Current time: " << qdt.toString(Qt::ISODateWithMs);
 | 
			
		||||
                        qDebug() << "SatelliteTrackerWorker: New AOS: " << name << " new: " << satWorkerState->m_satState.m_passes[0]->m_aos << " old: " << satWorkerState->m_aos;
 | 
			
		||||
                        qDebug() << "SatelliteTrackerWorker: New LOS: " << name << " new: " << satWorkerState->m_satState.m_passes[0]->m_los << " old: " << satWorkerState->m_los;
 | 
			
		||||
                        satWorkerState->m_aos = satWorkerState->m_satState.m_passes[0]->m_aos;
 | 
			
		||||
                        satWorkerState->m_los = satWorkerState->m_satState.m_passes[0]->m_los;
 | 
			
		||||
                        qDebug() << "SatelliteTrackerWorker: New AOS: " << name << " new: " << satWorkerState->m_satState.m_passes[0].m_aos << " old: " << satWorkerState->m_aos;
 | 
			
		||||
                        qDebug() << "SatelliteTrackerWorker: New LOS: " << name << " new: " << satWorkerState->m_satState.m_passes[0].m_los << " old: " << satWorkerState->m_los;
 | 
			
		||||
                        satWorkerState->m_aos = satWorkerState->m_satState.m_passes[0].m_aos;
 | 
			
		||||
                        satWorkerState->m_los = satWorkerState->m_satState.m_passes[0].m_los;
 | 
			
		||||
                        if (satWorkerState->m_aos.isValid())
 | 
			
		||||
                        {
 | 
			
		||||
                            if (satWorkerState->m_aos > qdt)
 | 
			
		||||
@ -469,27 +454,27 @@ void SatelliteTrackerWorker::update()
 | 
			
		||||
                                               .arg((int)round(satWorkerState->m_satState.m_period));
 | 
			
		||||
                        if (satWorkerState->m_satState.m_passes.size() > 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            if ((qdt >= satWorkerState->m_satState.m_passes[0]->m_aos) && (qdt <= satWorkerState->m_satState.m_passes[0]->m_los))
 | 
			
		||||
                            if ((qdt >= satWorkerState->m_satState.m_passes[0].m_aos) && (qdt <= satWorkerState->m_satState.m_passes[0].m_los))
 | 
			
		||||
                                text = text.append("\nSatellite is visible");
 | 
			
		||||
                            else
 | 
			
		||||
                                text = text.append("\nAOS in: %1 mins").arg((int)round((satWorkerState->m_satState.m_passes[0]->m_aos.toSecsSinceEpoch() - qdt.toSecsSinceEpoch())/60.0));
 | 
			
		||||
                                text = text.append("\nAOS in: %1 mins").arg((int)round((satWorkerState->m_satState.m_passes[0].m_aos.toSecsSinceEpoch() - qdt.toSecsSinceEpoch())/60.0));
 | 
			
		||||
                            QString aosDateTime;
 | 
			
		||||
                            QString losDateTime;
 | 
			
		||||
                            if (m_settings.m_utc)
 | 
			
		||||
                            {
 | 
			
		||||
                                aosDateTime = satWorkerState->m_satState.m_passes[0]->m_aos.toString(m_settings.m_dateFormat + " hh:mm");
 | 
			
		||||
                                losDateTime = satWorkerState->m_satState.m_passes[0]->m_los.toString(m_settings.m_dateFormat + " hh:mm");
 | 
			
		||||
                                aosDateTime = satWorkerState->m_satState.m_passes[0].m_aos.toString(m_settings.m_dateFormat + " hh:mm");
 | 
			
		||||
                                losDateTime = satWorkerState->m_satState.m_passes[0].m_los.toString(m_settings.m_dateFormat + " hh:mm");
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                aosDateTime = satWorkerState->m_satState.m_passes[0]->m_aos.toLocalTime().toString(m_settings.m_dateFormat + " hh:mm");
 | 
			
		||||
                                losDateTime = satWorkerState->m_satState.m_passes[0]->m_los.toLocalTime().toString(m_settings.m_dateFormat + " hh:mm");
 | 
			
		||||
                                aosDateTime = satWorkerState->m_satState.m_passes[0].m_aos.toLocalTime().toString(m_settings.m_dateFormat + " hh:mm");
 | 
			
		||||
                                losDateTime = satWorkerState->m_satState.m_passes[0].m_los.toLocalTime().toString(m_settings.m_dateFormat + " hh:mm");
 | 
			
		||||
                            }
 | 
			
		||||
                            text = QString("%1\nAOS: %2\nLOS: %3\nMax El: %4%5")
 | 
			
		||||
                                            .arg(text)
 | 
			
		||||
                                            .arg(aosDateTime)
 | 
			
		||||
                                            .arg(losDateTime)
 | 
			
		||||
                                            .arg((int)round(satWorkerState->m_satState.m_passes[0]->m_maxElevation))
 | 
			
		||||
                                            .arg((int)round(satWorkerState->m_satState.m_passes[0].m_maxElevation))
 | 
			
		||||
                                            .arg(QChar(0xb0));
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -533,7 +518,7 @@ void SatelliteTrackerWorker::aos(SatWorkerState *satWorkerState)
 | 
			
		||||
        int durationMins = (int)round((satWorkerState->m_los.toSecsSinceEpoch() - satWorkerState->m_aos.toSecsSinceEpoch())/60.0);
 | 
			
		||||
        int maxElevation = 0;
 | 
			
		||||
        if (satWorkerState->m_satState.m_passes.size() > 0)
 | 
			
		||||
            maxElevation = satWorkerState->m_satState.m_passes[0]->m_maxElevation;
 | 
			
		||||
            maxElevation = satWorkerState->m_satState.m_passes[0].m_maxElevation;
 | 
			
		||||
        getMessageQueueToGUI()->push(SatelliteTrackerReport::MsgReportAOS::create(satWorkerState->m_name, durationMins, maxElevation));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -573,11 +558,11 @@ void SatelliteTrackerWorker::calculateRotation(SatWorkerState *satWorkerState)
 | 
			
		||||
        SatNogsSatellite *sat = m_satellites.value(satWorkerState->m_name);
 | 
			
		||||
        bool passes0 = getPassesThrough0Deg(sat->m_tle->m_tle0, sat->m_tle->m_tle1, sat->m_tle->m_tle2,
 | 
			
		||||
                                            m_settings.m_latitude, m_settings.m_longitude, m_settings.m_heightAboveSeaLevel/1000.0,
 | 
			
		||||
                                            satWorkerState->m_satState.m_passes[0]->m_aos, satWorkerState->m_satState.m_passes[0]->m_los);
 | 
			
		||||
                                            satWorkerState->m_satState.m_passes[0].m_aos, satWorkerState->m_satState.m_passes[0].m_los);
 | 
			
		||||
        if (passes0)
 | 
			
		||||
        {
 | 
			
		||||
            double aosAz = satWorkerState->m_satState.m_passes[0]->m_aosAzimuth;
 | 
			
		||||
            double losAz = satWorkerState->m_satState.m_passes[0]->m_losAzimuth;
 | 
			
		||||
            double aosAz = satWorkerState->m_satState.m_passes[0].m_aosAzimuth;
 | 
			
		||||
            double losAz = satWorkerState->m_satState.m_passes[0].m_losAzimuth;
 | 
			
		||||
            double minAz = std::min(aosAz, losAz);
 | 
			
		||||
            if ((m_settings.m_rotatorMaxAzimuth - 360.0) > minAz)
 | 
			
		||||
                m_extendedAzRotation = true;
 | 
			
		||||
@ -652,7 +637,7 @@ void SatelliteTrackerWorker::applyDeviceAOSSettings(const QString& name)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Wait a little bit for presets to load before performing other steps
 | 
			
		||||
        QTimer::singleShot(1000, [this, mainCore, name, m_deviceSettingsList]()
 | 
			
		||||
        QTimer::singleShot(1000, [this, name, m_deviceSettingsList]()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < m_deviceSettingsList->size(); i++)
 | 
			
		||||
@ -698,7 +683,7 @@ void SatelliteTrackerWorker::applyDeviceAOSSettings(const QString& name)
 | 
			
		||||
            SatNogsSatellite *sat = m_satellites.value(satWorkerState->m_name);
 | 
			
		||||
            // APT needs current time, for current position of satellite, not start of pass which may be in the past
 | 
			
		||||
            // if the satellite was already visible when Sat Tracker was started
 | 
			
		||||
            ChannelWebAPIUtils::satelliteAOS(name, satWorkerState->m_satState.m_passes[0]->m_northToSouth,
 | 
			
		||||
            ChannelWebAPIUtils::satelliteAOS(name, satWorkerState->m_satState.m_passes[0].m_northToSouth,
 | 
			
		||||
                                             sat->m_tle->toString(),
 | 
			
		||||
                                             m_satelliteTracker->currentDateTimeUtc());
 | 
			
		||||
            FeatureWebAPIUtils::satelliteAOS(name, satWorkerState->m_aos, satWorkerState->m_los);
 | 
			
		||||
@ -740,7 +725,7 @@ void SatelliteTrackerWorker::applyDeviceAOSSettings(const QString& name)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Start file sinks (need a little delay to ensure sample rate message has been handled in filerecord)
 | 
			
		||||
            QTimer::singleShot(1000, [this, m_deviceSettingsList]()
 | 
			
		||||
            QTimer::singleShot(1000, [m_deviceSettingsList]()
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < m_deviceSettingsList->size(); i++)
 | 
			
		||||
                {
 | 
			
		||||
@ -761,7 +746,7 @@ void SatelliteTrackerWorker::applyDeviceAOSSettings(const QString& name)
 | 
			
		||||
        // Send AOS message to channels/features
 | 
			
		||||
        SatWorkerState *satWorkerState = m_workerState.value(name);
 | 
			
		||||
        SatNogsSatellite *sat = m_satellites.value(satWorkerState->m_name);
 | 
			
		||||
        ChannelWebAPIUtils::satelliteAOS(name, satWorkerState->m_satState.m_passes[0]->m_northToSouth,
 | 
			
		||||
        ChannelWebAPIUtils::satelliteAOS(name, satWorkerState->m_satState.m_passes[0].m_northToSouth,
 | 
			
		||||
                                            sat->m_tle->toString(),
 | 
			
		||||
                                            m_satelliteTracker->currentDateTimeUtc());
 | 
			
		||||
        FeatureWebAPIUtils::satelliteAOS(name, satWorkerState->m_aos, satWorkerState->m_los);
 | 
			
		||||
 | 
			
		||||
@ -94,10 +94,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    SatelliteTrackerWorker(SatelliteTracker* satelliteTracker, WebAPIAdapterInterface *webAPIAdapterInterface);
 | 
			
		||||
    ~SatelliteTrackerWorker();
 | 
			
		||||
    void reset();
 | 
			
		||||
    bool startWork();
 | 
			
		||||
    void stopWork();
 | 
			
		||||
    bool isRunning() const { return m_running; }
 | 
			
		||||
    void startWork();
 | 
			
		||||
    MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
 | 
			
		||||
    void setMessageQueueToFeature(MessageQueue *messageQueue) { m_msgQueueToFeature = messageQueue; }
 | 
			
		||||
    void setMessageQueueToGUI(MessageQueue *messageQueue) { m_msgQueueToGUI = messageQueue; }
 | 
			
		||||
@ -110,7 +107,6 @@ private:
 | 
			
		||||
    MessageQueue *m_msgQueueToFeature; //!< Queue to report channel change to main feature object
 | 
			
		||||
    MessageQueue *m_msgQueueToGUI;
 | 
			
		||||
    SatelliteTrackerSettings m_settings;
 | 
			
		||||
    bool m_running;
 | 
			
		||||
    QRecursiveMutex m_mutex;
 | 
			
		||||
    QTimer m_pollTimer;
 | 
			
		||||
    QHash<QString, SatNogsSatellite *> m_satellites;
 | 
			
		||||
@ -144,8 +140,7 @@ private:
 | 
			
		||||
    void calculateRotation(SatWorkerState *satWorkerState);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void started();
 | 
			
		||||
    void finished();
 | 
			
		||||
    void stopWork();
 | 
			
		||||
    void handleInputMessages();
 | 
			
		||||
    void update();
 | 
			
		||||
    void aos(SatWorkerState *satWorkerState);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user