mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-10-31 23:57:10 -04:00
5d8f3a6395
Working frequencies can be for all regions or for individual IARU regions. This allows each mode band tuple to have one or more working frequencies which can include local ones only offered when the user configures their IARU region. Change working frequency default suggestions to better fit in FT8. General rule is FT8 is at JT65 -2kHz except where that is not possible e.g. where that would fall into a segment not allocated for narrow band data modes. For tight bands like top band sqeeze existing JT65 and JT allocations to allow space for FT8. NOTE: this change changes the WSPR frequency on 80m to allow access to JA stations that currently have no allocation where it was placed. ALSO NOTE: the JT65 and JT9 frequencies for 80m move down 6 kHz, again to accommodate region 3 users. Other appliactions not within our control should be asked to move in step when 1.8.0 is released. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7810 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
279 lines
9.2 KiB
C++
279 lines
9.2 KiB
C++
#include "astro.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <QApplication>
|
|
#include <QFile>
|
|
#include <QTextStream>
|
|
#include <QSettings>
|
|
#include <QDateTime>
|
|
#include <QDir>
|
|
#include <QDebug>
|
|
|
|
#include "commons.h"
|
|
#include "MessageBox.hpp"
|
|
#include "Configuration.hpp"
|
|
#include "SettingsGroup.hpp"
|
|
#include "qt_helpers.hpp"
|
|
|
|
#include "ui_astro.h"
|
|
#include "moc_astro.cpp"
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
Astro::Astro(QSettings * settings, Configuration const * configuration, QWidget * parent)
|
|
: QDialog {parent, Qt::WindowTitleHint}
|
|
, settings_ {settings}
|
|
, configuration_ {configuration}
|
|
, ui_ {new Ui::Astro}
|
|
, m_DopplerMethod {0}
|
|
{
|
|
ui_->setupUi (this);
|
|
setWindowTitle (QApplication::applicationName () + " - " + tr ("Astronomical Data"));
|
|
setStyleSheet ("QWidget {background: white;}");
|
|
connect (ui_->cbDopplerTracking, &QAbstractButton::toggled, ui_->doppler_widget, &QWidget::setVisible);
|
|
read_settings ();
|
|
ui_->text_label->clear ();
|
|
}
|
|
|
|
Astro::~Astro ()
|
|
{
|
|
ui_->cbDopplerTracking->setChecked (false);
|
|
Q_EMIT tracking_update ();
|
|
if (isVisible ()) write_settings ();
|
|
}
|
|
|
|
void Astro::closeEvent (QCloseEvent * e)
|
|
{
|
|
write_settings ();
|
|
QWidget::closeEvent (e);
|
|
}
|
|
|
|
void Astro::read_settings ()
|
|
{
|
|
SettingsGroup g (settings_, "Astro");
|
|
ui_->doppler_widget->setVisible (ui_->cbDopplerTracking->isChecked ());
|
|
m_DopplerMethod=settings_->value("DopplerMethod",0).toInt();
|
|
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;
|
|
}
|
|
move (settings_->value ("window/pos", pos ()).toPoint ());
|
|
}
|
|
|
|
void Astro::write_settings ()
|
|
{
|
|
SettingsGroup g (settings_, "Astro");
|
|
//settings_->setValue ("DopplerTracking", ui_->cbDopplerTracking->isChecked ());
|
|
settings_->setValue ("DopplerMethod",m_DopplerMethod);
|
|
settings_->setValue ("window/pos", pos ());
|
|
}
|
|
|
|
auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const& hisgrid, Frequency freq,
|
|
bool dx_is_self, bool bTx, bool no_tx_QSY, int TR_period) -> Correction
|
|
{
|
|
Frequency freq_moon {freq};
|
|
double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx;
|
|
double ramoon,decmoon,dgrd,poloffset,xnr,techo,width1,width2;
|
|
int ntsky;
|
|
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;
|
|
|
|
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());
|
|
|
|
if(hisgrid_padded==" ") {
|
|
azmoondx=0.0;
|
|
elmoondx=0.0;
|
|
ndop=0;
|
|
width2=0.0;
|
|
}
|
|
QString message;
|
|
{
|
|
QTextStream out {&message};
|
|
out << " " << date << "\n"
|
|
"UTC: " << utc << "\n"
|
|
<< fixed
|
|
<< qSetFieldWidth (6)
|
|
<< qSetRealNumberPrecision (1)
|
|
<< "Az: " << azmoon << "\n"
|
|
"El: " << elmoon << "\n"
|
|
"SelfDop:" << ndop00 << "\n"
|
|
"Width: " << int(width1) << "\n"
|
|
<< qSetRealNumberPrecision (2)
|
|
<< "Delay: " << techo << "\n"
|
|
<< qSetRealNumberPrecision (1)
|
|
<< "DxAz: " << azmoondx << "\n"
|
|
"DxEl: " << elmoondx << "\n"
|
|
"DxDop: " << ndop << "\n"
|
|
"DxWid: " << int(width2) << "\n"
|
|
"Dec: " << decmoon << "\n"
|
|
"SunAz: " << azsun << "\n"
|
|
"SunEl: " << elsun << "\n"
|
|
"Freq: " << nfreq << "\n";
|
|
if(nfreq>=50) { //Suppress data not relevant below VHF
|
|
out << "Tsky: " << ntsky << "\n"
|
|
"Dpol: " << poloffset << "\n"
|
|
"MNR: " << xnr << "\n"
|
|
"Dgrd: " << dgrd;
|
|
}
|
|
}
|
|
ui_->text_label->setText(message);
|
|
|
|
Correction correction;
|
|
if (ui_->cbDopplerTracking->isChecked ()) {
|
|
switch (m_DopplerMethod)
|
|
{
|
|
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;
|
|
break;
|
|
|
|
case 2:
|
|
// Doppler correction to constant frequency on Moon
|
|
correction.rx = ndop00 / 2;
|
|
break;
|
|
}
|
|
|
|
if (3 != m_DopplerMethod) correction.tx = -correction.rx;
|
|
if(dx_is_self && m_DopplerMethod == 1) correction.rx = 0;
|
|
|
|
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};
|
|
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,
|
|
"", 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;
|
|
|
|
case 2:
|
|
// Doppler correction to constant frequency on Moon
|
|
offset = ndop00 / 2;
|
|
break;
|
|
}
|
|
correction.tx = -offset;
|
|
}
|
|
}
|
|
return correction;
|
|
}
|
|
|
|
void Astro::check_split ()
|
|
{
|
|
if (doppler_tracking () && !configuration_->split_mode ())
|
|
{
|
|
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"));
|
|
ui_->rbNoDoppler->click ();
|
|
}
|
|
}
|
|
|
|
void Astro::on_rbFullTrack_clicked()
|
|
{
|
|
m_DopplerMethod = 1;
|
|
check_split ();
|
|
Q_EMIT tracking_update ();
|
|
}
|
|
|
|
void Astro::on_rbRxOnly_clicked()
|
|
{
|
|
m_DopplerMethod = 3;
|
|
check_split ();
|
|
Q_EMIT tracking_update ();
|
|
}
|
|
|
|
void Astro::on_rbConstFreqOnMoon_clicked()
|
|
{
|
|
m_DopplerMethod = 2;
|
|
check_split ();
|
|
Q_EMIT tracking_update ();
|
|
}
|
|
|
|
void Astro::on_rbNoDoppler_clicked()
|
|
{
|
|
m_DopplerMethod = 0;
|
|
Q_EMIT tracking_update ();
|
|
}
|
|
|
|
bool Astro::doppler_tracking () const
|
|
{
|
|
return ui_->cbDopplerTracking->isChecked () && m_DopplerMethod;
|
|
}
|
|
|
|
void Astro::on_cbDopplerTracking_toggled(bool)
|
|
{
|
|
check_split ();
|
|
Q_EMIT tracking_update ();
|
|
}
|
|
|
|
void Astro::nominal_frequency (Frequency rx, Frequency tx)
|
|
{
|
|
ui_->sked_frequency_label->setText (Radio::pretty_frequency_MHz_string (rx));
|
|
ui_->sked_tx_frequency_label->setText (Radio::pretty_frequency_MHz_string (tx));
|
|
}
|
|
|
|
void Astro::hideEvent (QHideEvent * e)
|
|
{
|
|
Q_EMIT tracking_update ();
|
|
QWidget::hideEvent (e);
|
|
}
|