2014-12-02 19:06:54 -05:00
|
|
|
#include "astro.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QFile>
|
|
|
|
#include <QTextStream>
|
|
|
|
#include <QSettings>
|
|
|
|
#include <QDateTime>
|
|
|
|
#include <QStandardPaths>
|
|
|
|
#include <QDir>
|
2015-04-07 08:08:55 -04:00
|
|
|
#include <QDebug>
|
2014-12-02 19:06:54 -05:00
|
|
|
|
|
|
|
#include "commons.h"
|
2016-07-03 16:31:19 -04:00
|
|
|
#include "MessageBox.hpp"
|
2015-06-11 09:36:13 -04:00
|
|
|
#include "Configuration.hpp"
|
|
|
|
#include "SettingsGroup.hpp"
|
2015-04-07 08:08:55 -04:00
|
|
|
#include "qt_helpers.hpp"
|
2014-12-02 19:06:54 -05:00
|
|
|
|
|
|
|
#include "ui_astro.h"
|
|
|
|
#include "moc_astro.cpp"
|
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
void astrosub_(int* nyear, int* month, int* nday, double* uth, double* freqMoon,
|
|
|
|
const char* mygrid, const char* hisgrid, double* azsun,
|
|
|
|
double* elsun, double* azmoon, double* elmoon, double* azmoondx,
|
|
|
|
double* elmoondx, int* ntsky, int* ndop, int* ndop00,
|
|
|
|
double* ramoon, double* decmoon, double* dgrd, double* poloffset,
|
|
|
|
double* xnr, double* techo, double* width1, double* width2,
|
|
|
|
bool* bTx, const char* AzElFileName, const char* jpleph,
|
|
|
|
int len1, int len2, int len3, int len4);
|
|
|
|
}
|
|
|
|
|
2015-06-11 09:36:13 -04:00
|
|
|
Astro::Astro(QSettings * settings, Configuration const * configuration, QWidget * parent)
|
2016-04-06 13:11:58 -04:00
|
|
|
: QDialog {parent, Qt::WindowTitleHint}
|
2014-12-02 19:06:54 -05:00
|
|
|
, settings_ {settings}
|
2015-06-11 09:36:13 -04:00
|
|
|
, configuration_ {configuration}
|
2014-12-02 19:06:54 -05:00
|
|
|
, ui_ {new Ui::Astro}
|
2015-06-11 09:36:13 -04:00
|
|
|
, m_DopplerMethod {0}
|
2014-12-02 19:06:54 -05:00
|
|
|
{
|
2015-06-11 09:36:13 -04:00
|
|
|
ui_->setupUi (this);
|
|
|
|
setWindowTitle (QApplication::applicationName () + " - " + tr ("Astronomical Data"));
|
2015-04-22 13:48:03 -04:00
|
|
|
setStyleSheet ("QWidget {background: white;}");
|
2015-06-11 09:36:13 -04:00
|
|
|
connect (ui_->cbDopplerTracking, &QAbstractButton::toggled, ui_->doppler_widget, &QWidget::setVisible);
|
2014-12-02 19:06:54 -05:00
|
|
|
read_settings ();
|
2015-06-11 09:36:13 -04:00
|
|
|
ui_->text_label->clear ();
|
2014-12-02 19:06:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
Astro::~Astro ()
|
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
ui_->cbDopplerTracking->setChecked (false);
|
|
|
|
Q_EMIT tracking_update ();
|
2015-04-22 13:48:03 -04:00
|
|
|
if (isVisible ()) write_settings ();
|
2014-12-02 19:06:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void Astro::closeEvent (QCloseEvent * e)
|
|
|
|
{
|
|
|
|
write_settings ();
|
|
|
|
QWidget::closeEvent (e);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Astro::read_settings ()
|
|
|
|
{
|
2015-06-11 09:36:13 -04:00
|
|
|
SettingsGroup g (settings_, "Astro");
|
|
|
|
ui_->doppler_widget->setVisible (ui_->cbDopplerTracking->isChecked ());
|
2015-04-22 13:48:03 -04:00
|
|
|
m_DopplerMethod=settings_->value("DopplerMethod",0).toInt();
|
2016-04-06 13:11:58 -04:00
|
|
|
switch (m_DopplerMethod)
|
|
|
|
{
|
|
|
|
case 0: ui_->rbNoDoppler->setChecked (true); break;
|
|
|
|
case 1: ui_->rbFullTrack->setChecked (true); break;
|
|
|
|
case 2: ui_->rbConstFreqOnMoon->setChecked (true); break;
|
|
|
|
case 3: ui_->rbRxOnly->setChecked (true); break;
|
|
|
|
}
|
2014-12-02 19:06:54 -05:00
|
|
|
move (settings_->value ("window/pos", pos ()).toPoint ());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Astro::write_settings ()
|
|
|
|
{
|
2015-06-11 09:36:13 -04:00
|
|
|
SettingsGroup g (settings_, "Astro");
|
2016-04-06 13:11:58 -04:00
|
|
|
//settings_->setValue ("DopplerTracking", ui_->cbDopplerTracking->isChecked ());
|
2015-04-22 13:48:03 -04:00
|
|
|
settings_->setValue ("DopplerMethod",m_DopplerMethod);
|
2014-12-02 19:06:54 -05:00
|
|
|
settings_->setValue ("window/pos", pos ());
|
|
|
|
}
|
|
|
|
|
2015-06-11 09:36:13 -04:00
|
|
|
auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const& hisgrid, Frequency freq,
|
2016-04-06 13:11:58 -04:00
|
|
|
bool dx_is_self, bool bTx, bool no_tx_QSY, int TR_period) -> Correction
|
2014-12-02 19:06:54 -05:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
Frequency freq_moon {freq};
|
2014-12-02 19:06:54 -05:00
|
|
|
double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx;
|
2015-05-27 09:08:28 -04:00
|
|
|
double ramoon,decmoon,dgrd,poloffset,xnr,techo,width1,width2;
|
2015-04-22 13:48:03 -04:00
|
|
|
int ntsky;
|
2015-06-11 09:36:13 -04:00
|
|
|
QString date {t.date().toString("yyyy MMM dd").trimmed ()};
|
|
|
|
QString utc {t.time().toString().trimmed ()};
|
|
|
|
int nyear {t.date().year()};
|
|
|
|
int month {t.date().month()};
|
|
|
|
int nday {t.date().day()};
|
|
|
|
int nhr {t.time().hour()};
|
|
|
|
int nmin {t.time().minute()};
|
|
|
|
double sec {t.time().second() + 0.001*t.time().msec()};
|
|
|
|
double uth {nhr + nmin/60.0 + sec/3600.0};
|
|
|
|
if(freq_moon < 1) freq_moon = 144000000;
|
|
|
|
int nfreq {static_cast<int> (freq_moon / 1000000u)};
|
|
|
|
double freq8 {static_cast<double> (freq_moon)};
|
|
|
|
auto const& AzElFileName = QDir::toNativeSeparators (configuration_->azel_directory ().absoluteFilePath ("azel.dat"));
|
|
|
|
auto const& jpleph = configuration_->data_dir ().absoluteFilePath ("JPLEPH");
|
|
|
|
int ndop;
|
|
|
|
int ndop00;
|
2015-05-27 09:08:28 -04:00
|
|
|
|
2016-06-10 11:54:16 -04:00
|
|
|
QString mygrid_padded {(mygrid + " ").left (6)};
|
|
|
|
QString hisgrid_padded {(hisgrid + " ").left (6)};
|
|
|
|
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(),
|
|
|
|
hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon,
|
|
|
|
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00, &ramoon, &decmoon,
|
|
|
|
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
|
|
|
|
AzElFileName.toLatin1().constData(), jpleph.toLatin1().constData(), 6, 6,
|
|
|
|
AzElFileName.length(), jpleph.length());
|
2014-12-02 19:06:54 -05:00
|
|
|
|
|
|
|
QString message;
|
|
|
|
{
|
|
|
|
QTextStream out {&message};
|
2015-06-11 10:38:31 -04:00
|
|
|
out << " " << date << "\n"
|
2014-12-02 19:06:54 -05:00
|
|
|
"UTC: " << utc << "\n"
|
|
|
|
<< fixed
|
|
|
|
<< qSetFieldWidth (6)
|
|
|
|
<< qSetRealNumberPrecision (1)
|
2015-06-04 15:11:54 -04:00
|
|
|
<< "Az: " << azmoon << "\n"
|
|
|
|
"El: " << elmoon << "\n"
|
2015-06-11 09:36:13 -04:00
|
|
|
"SelfDop:" << ndop00 << "\n"
|
2015-06-04 15:11:54 -04:00
|
|
|
"Width: " << int(width1) << "\n"
|
2014-12-02 19:06:54 -05:00
|
|
|
<< qSetRealNumberPrecision (2)
|
2015-06-04 15:11:54 -04:00
|
|
|
<< "Delay: " << techo << "\n"
|
2014-12-02 19:06:54 -05:00
|
|
|
<< qSetRealNumberPrecision (1)
|
2015-06-04 15:11:54 -04:00
|
|
|
<< "DxAz: " << azmoondx << "\n"
|
|
|
|
"DxEl: " << elmoondx << "\n"
|
2015-06-11 09:36:13 -04:00
|
|
|
"DxDop: " << ndop << "\n"
|
2015-06-04 15:11:54 -04:00
|
|
|
"DxWid: " << int(width2) << "\n"
|
|
|
|
"Dec: " << decmoon << "\n"
|
|
|
|
"SunAz: " << azsun << "\n"
|
|
|
|
"SunEl: " << elsun << "\n"
|
2015-06-11 10:38:31 -04:00
|
|
|
"Freq: " << nfreq << "\n";
|
|
|
|
if(nfreq>=50) { //Suppress data not relevant below VHF
|
|
|
|
out << "Tsky: " << ntsky << "\n"
|
2016-07-04 14:25:10 -04:00
|
|
|
"Dpol: " << poloffset << "\n"
|
2015-06-11 10:38:31 -04:00
|
|
|
"MNR: " << xnr << "\n"
|
|
|
|
"Dgrd: " << dgrd;
|
|
|
|
}
|
2014-12-02 19:06:54 -05:00
|
|
|
}
|
|
|
|
ui_->text_label->setText(message);
|
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
Correction correction;
|
2015-06-11 20:26:36 -04:00
|
|
|
if (ui_->cbDopplerTracking->isChecked ()) {
|
|
|
|
switch (m_DopplerMethod)
|
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
case 1: // All Doppler correction done here; DX station stays at nominal dial frequency.
|
|
|
|
case 3: // Both stations do full correction on Rx and none on Tx
|
|
|
|
correction.rx = dx_is_self ? ndop00 : ndop;
|
2015-06-11 20:26:36 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
// Doppler correction to constant frequency on Moon
|
2016-04-06 13:11:58 -04:00
|
|
|
correction.rx = ndop00 / 2;
|
2015-06-11 20:26:36 -04:00
|
|
|
break;
|
|
|
|
}
|
2015-06-11 09:36:13 -04:00
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
if (3 != m_DopplerMethod) correction.tx = -correction.rx;
|
|
|
|
if(dx_is_self && m_DopplerMethod == 1) correction.rx = 0;
|
2015-04-22 13:48:03 -04:00
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
if (no_tx_QSY && 3 != m_DopplerMethod && 0 != m_DopplerMethod)
|
|
|
|
{
|
|
|
|
// calculate a single correction for transmit half way through
|
|
|
|
// the period as a compromise for rigs that can't CAT QSY
|
|
|
|
// while transmitting
|
|
|
|
//
|
|
|
|
// use a base time of (secs-since-epoch + 2) so as to be sure
|
|
|
|
// we do the next period if we calculate just before it starts
|
|
|
|
auto sec_since_epoch = t.toMSecsSinceEpoch () / 1000 + 2;
|
|
|
|
auto target_sec = sec_since_epoch - sec_since_epoch % TR_period + TR_period / 2;
|
|
|
|
auto target_date_time = QDateTime::fromMSecsSinceEpoch (target_sec * 1000);
|
|
|
|
QString date {target_date_time.date().toString("yyyy MMM dd").trimmed ()};
|
|
|
|
QString utc {target_date_time.time().toString().trimmed ()};
|
|
|
|
int nyear {target_date_time.date().year()};
|
|
|
|
int month {target_date_time.date().month()};
|
|
|
|
int nday {target_date_time.date().day()};
|
|
|
|
int nhr {target_date_time.time().hour()};
|
|
|
|
int nmin {target_date_time.time().minute()};
|
|
|
|
double sec {target_date_time.time().second() + 0.001*target_date_time.time().msec()};
|
|
|
|
double uth {nhr + nmin/60.0 + sec/3600.0};
|
2016-06-10 11:54:16 -04:00
|
|
|
astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(),
|
|
|
|
hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon,
|
2016-04-06 13:11:58 -04:00
|
|
|
&azmoondx, &elmoondx, &ntsky, &ndop, &ndop00, &ramoon, &decmoon,
|
|
|
|
&dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx,
|
|
|
|
"", jpleph.toLatin1().constData(), 6, 6,
|
|
|
|
0, jpleph.length());
|
|
|
|
FrequencyDelta offset {0};
|
|
|
|
switch (m_DopplerMethod)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
// All Doppler correction done here; DX station stays at nominal dial frequency.
|
|
|
|
offset = dx_is_self ? ndop00 : ndop;
|
|
|
|
break;
|
2015-04-22 13:48:03 -04:00
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
case 2:
|
|
|
|
// Doppler correction to constant frequency on Moon
|
|
|
|
offset = ndop00 / 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
correction.tx = -offset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return correction;
|
2015-04-22 13:48:03 -04:00
|
|
|
}
|
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
void Astro::check_split ()
|
2015-04-22 13:48:03 -04:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
if (doppler_tracking () && !configuration_->split_mode ())
|
|
|
|
{
|
2016-07-03 16:31:19 -04:00
|
|
|
MessageBox::warning_message (this, tr ("Doppler Tracking Error"),
|
|
|
|
tr ("Split operating is required for Doppler tracking"),
|
|
|
|
tr ("Go to \"Menu->File->Settings->Radio\" to enable split operation"));
|
2016-04-06 13:11:58 -04:00
|
|
|
ui_->rbNoDoppler->click ();
|
|
|
|
}
|
2015-04-22 13:48:03 -04:00
|
|
|
}
|
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
void Astro::on_rbFullTrack_clicked()
|
2015-04-22 13:48:03 -04:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
m_DopplerMethod = 1;
|
|
|
|
check_split ();
|
|
|
|
Q_EMIT tracking_update ();
|
2015-04-22 13:48:03 -04:00
|
|
|
}
|
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
void Astro::on_rbRxOnly_clicked()
|
2015-04-22 13:48:03 -04:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
m_DopplerMethod = 3;
|
|
|
|
check_split ();
|
|
|
|
Q_EMIT tracking_update ();
|
2015-04-22 13:48:03 -04:00
|
|
|
}
|
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
void Astro::on_rbConstFreqOnMoon_clicked()
|
2015-04-22 13:48:03 -04:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
m_DopplerMethod = 2;
|
|
|
|
check_split ();
|
|
|
|
Q_EMIT tracking_update ();
|
2015-04-22 13:48:03 -04:00
|
|
|
}
|
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
void Astro::on_rbNoDoppler_clicked()
|
2015-04-22 13:48:03 -04:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
m_DopplerMethod = 0;
|
|
|
|
Q_EMIT tracking_update ();
|
2015-04-22 13:48:03 -04:00
|
|
|
}
|
2015-05-27 09:08:28 -04:00
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
bool Astro::doppler_tracking () const
|
2015-05-27 09:08:28 -04:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
return ui_->cbDopplerTracking->isChecked () && m_DopplerMethod;
|
2015-05-27 09:08:28 -04:00
|
|
|
}
|
2015-06-11 20:26:44 -04:00
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
void Astro::on_cbDopplerTracking_toggled(bool)
|
2015-06-11 20:26:44 -04:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
check_split ();
|
|
|
|
Q_EMIT tracking_update ();
|
2015-06-11 20:26:44 -04:00
|
|
|
}
|
2015-11-17 20:28:12 -05:00
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
void Astro::nominal_frequency (Frequency rx, Frequency tx)
|
2015-11-17 20:28:12 -05:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
ui_->sked_frequency_label->setText (Radio::pretty_frequency_MHz_string (rx));
|
|
|
|
ui_->sked_tx_frequency_label->setText (Radio::pretty_frequency_MHz_string (tx));
|
2015-11-17 20:28:12 -05:00
|
|
|
}
|
|
|
|
|
2016-04-06 13:11:58 -04:00
|
|
|
void Astro::hideEvent (QHideEvent * e)
|
2015-11-17 20:28:12 -05:00
|
|
|
{
|
2016-04-06 13:11:58 -04:00
|
|
|
Q_EMIT tracking_update ();
|
|
|
|
QWidget::hideEvent (e);
|
2015-11-17 20:28:12 -05:00
|
|
|
}
|