Display rotator on Star Tracker and Satellite Tracker polar charts for #1641.

This commit is contained in:
Jon Beniston 2023-04-03 16:53:51 +01:00
parent 4ac5e729ff
commit f7ed662238
15 changed files with 787 additions and 463 deletions

View File

@ -116,7 +116,10 @@ On the display tab, you can set:
* The default frequency in MHz that is used for calculating Doppler and free space path loss in the Satellite Data table.
* The units used to display azimuth and elevation to the target satellite. This can be in degrees, minutes and seconds or decimal degrees.
* The number of points used for ground tracks on the map. More points result in smoother tracks, but require more processing.
* Whether times are displayrf in the local time zone or UTC.
* Which rotators are displayed on the polar chart. This can be All, None or Matching target. When Matching target is selected, the rotator will
only be displayed if the source in the Rotator Controller is set to this Satellite Tracker and Track is enabled.
* The format used for displaying dates. E.g. yyyy/MM/dd
* Whether times are displayed in the local time zone or UTC.
* Whether to draw the satellites on the map.
<h3>9: Latitude</h3>

View File

@ -28,8 +28,10 @@
#include "device/deviceapi.h"
#include "device/deviceset.h"
#include "channel/channelwebapiutils.h"
#include "feature/featureset.h"
#include "feature/featureuiset.h"
#include "feature/featureutils.h"
#include "feature/featurewebapiutils.h"
#include "gui/basicfeaturesettingsdialog.h"
#include "gui/dialogpositioner.h"
@ -295,6 +297,8 @@ SatelliteTrackerGUI::SatelliteTrackerGUI(PluginAPI* pluginAPI, FeatureUISet *fea
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
m_statusTimer.start(1000);
connect(&m_redrawTimer, &QTimer::timeout, this, &SatelliteTrackerGUI::plotChart);
// Intialise charts
m_emptyChart.layout()->setContentsMargins(0, 0, 0, 0);
m_emptyChart.setMargins(QMargins(1, 1, 1, 1));
@ -534,6 +538,7 @@ void SatelliteTrackerGUI::on_displaySettings_clicked()
m_settingsKeys.append("defaultFrequency");
m_settingsKeys.append("azElUnits");
m_settingsKeys.append("groundTrackPoints");
m_settingsKeys.append("drawRotators");
m_settingsKeys.append("dateFormat");
m_settingsKeys.append("utc");
m_settingsKeys.append("tles");
@ -792,6 +797,26 @@ static double interpolate(double x0, double y0, double x1, double y1, double x)
return (y0*(x1-x) + y1*(x-x0)) / (x1-x0);
}
// Reduce az/el range from 450,180 to 360,90
void SatelliteTrackerGUI::limitAzElRange(double& azimuth, double& elevation) const
{
if (elevation > 90.0)
{
elevation = 180.0 - elevation;
if (azimuth < 180.0) {
azimuth += 180.0;
} else {
azimuth -= 180.0;
}
}
if (azimuth > 360.0) {
azimuth -= 360.0f;
}
if (azimuth == 0) {
azimuth = 360.0;
}
}
// Plot pass in polar coords
void SatelliteTrackerGUI::plotPolarChart()
{
@ -916,6 +941,86 @@ void SatelliteTrackerGUI::plotPolarChart()
series[i]->attachAxis(radialAxis);
}
int redrawTime = 0;
if (m_settings.m_drawRotators != SatelliteTrackerSettings::NO_ROTATORS)
{
// Plot rotator position
QString ourSourceName = QString("F0:%1 %2").arg(m_satelliteTracker->getIndexInFeatureSet()).arg(m_satelliteTracker->getIdentifier()); // Only one feature set in practice?
std::vector<FeatureSet*>& featureSets = MainCore::instance()->getFeatureeSets();
for (int featureSetIndex = 0; featureSetIndex < featureSets.size(); featureSetIndex++)
{
FeatureSet *featureSet = featureSets[featureSetIndex];
for (int featureIndex = 0; featureIndex < featureSet->getNumberOfFeatures(); featureIndex++)
{
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (FeatureUtils::compareFeatureURIs(feature->getURI(), "sdrangel.feature.gs232controller"))
{
QString source;
ChannelWebAPIUtils::getFeatureSetting(featureSetIndex, featureIndex, "source", source); // Will return false if source isn't set in Controller
int track = 0;
ChannelWebAPIUtils::getFeatureSetting(featureSetIndex, featureIndex, "track", track);
if ((m_settings.m_drawRotators == SatelliteTrackerSettings::ALL_ROTATORS) || ((source == ourSourceName) && track))
{
int onTarget = 0;
ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "onTarget", onTarget);
if (!onTarget)
{
// Target azimuth red dotted line
double targetAzimuth, targetElevation;
bool targetAzimuthOk = ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "targetAzimuth", targetAzimuth);
bool targetElevationOk = ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "targetElevation", targetElevation);
if (targetAzimuthOk && targetElevationOk)
{
limitAzElRange(targetAzimuth, targetElevation);
QScatterSeries *rotatorSeries = new QScatterSeries();
QColor color(255, 0, 0, 150);
QPen pen(color);
rotatorSeries->setPen(pen);
rotatorSeries->setColor(color.darker());
rotatorSeries->setMarkerSize(20);
rotatorSeries->append(targetAzimuth, 90-targetElevation);
m_polarChart->addSeries(rotatorSeries);
rotatorSeries->attachAxis(angularAxis);
rotatorSeries->attachAxis(radialAxis);
redrawTime = 333;
}
}
// Current azimuth line. Yellow while off target, green on target.
double currentAzimuth, currentElevation;
bool currentAzimuthOk = ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "currentAzimuth", currentAzimuth);
bool currentElevationOk = ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "currentElevation", currentElevation);
if (currentAzimuthOk && currentElevationOk)
{
limitAzElRange(currentAzimuth, currentElevation);
QScatterSeries *rotatorSeries = new QScatterSeries();
QColor color;
if (onTarget) {
color = QColor(0, 255, 0, 150);
} else {
color = QColor(255, 255, 0, 150);
}
rotatorSeries->setPen(QPen(color));
rotatorSeries->setColor(color.darker());
rotatorSeries->setMarkerSize(20);
rotatorSeries->append(currentAzimuth, 90-currentElevation);
m_polarChart->addSeries(rotatorSeries);
rotatorSeries->attachAxis(angularAxis);
rotatorSeries->attachAxis(radialAxis);
redrawTime = 333;
}
}
}
}
}
}
// Create series with single point, so we can plot time of AOS
QLineSeries *aosSeries = new QLineSeries();
aosSeries->append(polarSeries->at(0));
@ -967,7 +1072,8 @@ void SatelliteTrackerGUI::plotPolarChart()
if ((currentTime >= pass.m_aos) && (currentTime <= pass.m_los))
{
// Create series with single point, so we can plot current time
QLineSeries *nowSeries = new QLineSeries();
QScatterSeries *nowSeries = new QScatterSeries();
nowSeries->setMarkerSize(3);
// 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()));
@ -978,8 +1084,16 @@ void SatelliteTrackerGUI::plotPolarChart()
m_polarChart->addSeries(nowSeries);
nowSeries->attachAxis(angularAxis);
nowSeries->attachAxis(radialAxis);
// Redraw in 5 seconds (call plotChart, incase user selects a different chart)
QTimer::singleShot(5000, this, &SatelliteTrackerGUI::plotChart);
if (!redrawTime) {
redrawTime = 5000;
}
}
if (redrawTime > 0)
{
// Redraw to show updated satellite position or rotator position
m_redrawTimer.setSingleShot(true);
m_redrawTimer.start(redrawTime);
}
delete polarSeries;
@ -1567,3 +1681,4 @@ void SatelliteTrackerGUI::makeUIConnections()
QObject::connect(ui->satTable->horizontalHeader(), &QHeaderView::sortIndicatorChanged, this, &SatelliteTrackerGUI::on_satTableHeader_sortIndicatorChanged);
QObject::connect(ui->deviceFeatureSelect, qOverload<int>(&QComboBox::currentIndexChanged), this, &SatelliteTrackerGUI::on_deviceFeatureSelect_currentIndexChanged);
}

View File

@ -82,6 +82,7 @@ private:
QChart m_emptyChart;
QChart *m_lineChart;
QPolarChart *m_polarChart;
QTimer m_redrawTimer;
QDateTime m_nextTargetAOS;
QDateTime m_nextTargetLOS;
@ -138,6 +139,7 @@ private:
void updateFileInputList();
void updateMapList();
void makeUIConnections();
void limitAzElRange(double& azimuth, double& elevation) const;
private slots:
void onMenuDialogCalled(const QPoint &p);

View File

@ -79,6 +79,7 @@ void SatelliteTrackerSettings::resetToDefaults()
m_dateTimeSelect = NOW;
m_mapFeature = "";
m_fileInputDevice = "";
m_drawRotators = MATCHING_TARGET;
m_workspaceIndex = 0;
m_columnSort = -1;
m_columnSortOrder = Qt::AscendingOrder;
@ -142,6 +143,7 @@ QByteArray SatelliteTrackerSettings::serialize() const
s.writeBlob(46, m_geometryBytes);
s.writeS32(47, m_columnSort);
s.writeS32(48, (int)m_columnSortOrder);
s.writeS32(49, (int)m_drawRotators);
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
s.writeS32(100 + i, m_columnIndexes[i]);
@ -237,6 +239,7 @@ bool SatelliteTrackerSettings::deserialize(const QByteArray& data)
d.readBlob(46, &m_geometryBytes);
d.readS32(47, &m_columnSort, -1);
d.readS32(48, (int *)&m_columnSortOrder, (int)Qt::AscendingOrder);
d.readS32(49, (int*)&m_drawRotators, (int)MATCHING_TARGET);
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
d.readS32(100 + i, &m_columnIndexes[i], i);
@ -398,6 +401,15 @@ void SatelliteTrackerSettings::applySettings(const QStringList& settingsKeys, co
if (settingsKeys.contains("dopplerPeriod")) {
m_dopplerPeriod = settings.m_dopplerPeriod;
}
if (settingsKeys.contains("predictionPeriod")) {
m_predictionPeriod = settings.m_predictionPeriod;
}
if (settingsKeys.contains("passStartTime")) {
m_passStartTime = settings.m_passStartTime;
}
if (settingsKeys.contains("passFinishTime")) {
m_passFinishTime = settings.m_passFinishTime;
}
if (settingsKeys.contains("defaultFrequency")) {
m_defaultFrequency = settings.m_defaultFrequency;
}
@ -410,23 +422,59 @@ void SatelliteTrackerSettings::applySettings(const QStringList& settingsKeys, co
if (settingsKeys.contains("aosSpeech")) {
m_aosSpeech = settings.m_aosSpeech;
}
if (settingsKeys.contains("aosCommand")) {
m_aosCommand = settings.m_aosCommand;
}
if (settingsKeys.contains("losSpeech")) {
m_losSpeech = settings.m_losSpeech;
}
if (settingsKeys.contains("aosCommand")) {
m_aosCommand = settings.m_aosCommand;
}
if (settingsKeys.contains("losCommand")) {
m_losCommand = settings.m_losCommand;
}
if (settingsKeys.contains("predictionPeriod")) {
m_predictionPeriod = settings.m_predictionPeriod;
if (settingsKeys.contains("chartsDarkTheme")) {
m_chartsDarkTheme = settings.m_chartsDarkTheme;
}
if (settingsKeys.contains("passStartTime")) {
m_passStartTime = settings.m_passStartTime;
if (settingsKeys.contains("deviceSettings")) {
m_deviceSettings = settings.m_deviceSettings;
}
if (settingsKeys.contains("passFinishTime")) {
m_passFinishTime = settings.m_passFinishTime;
if (settingsKeys.contains("replayEnabled")) {
m_replayEnabled = settings.m_replayEnabled;
}
if (settingsKeys.contains("replayStartDateTime")) {
m_replayStartDateTime = settings.m_replayStartDateTime;
}
if (settingsKeys.contains("sendTimeToMap")) {
m_sendTimeToMap = settings.m_sendTimeToMap;
}
if (settingsKeys.contains("dateTimeSelect")) {
m_dateTimeSelect = settings.m_dateTimeSelect;
}
if (settingsKeys.contains("mapFeature")) {
m_mapFeature = settings.m_mapFeature;
}
if (settingsKeys.contains("fileInputDevice")) {
m_fileInputDevice = settings.m_fileInputDevice;
}
if (settingsKeys.contains("drawRotators")) {
m_drawRotators = settings.m_drawRotators;
}
if (settingsKeys.contains("columnSort")) {
m_columnSort = settings.m_columnSort;
}
if (settingsKeys.contains("columnSortOrder")) {
m_columnSortOrder = settings.m_columnSortOrder;
}
if (settingsKeys.contains("columnIndexes"))
{
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
m_columnIndexes[i] = settings.m_columnIndexes[i];
}
}
if (settingsKeys.contains("columnSizes"))
{
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
m_columnSizes[i] = settings.m_columnSizes[i];
}
}
if (settingsKeys.contains("title")) {
m_title = settings.m_title;
@ -449,44 +497,8 @@ void SatelliteTrackerSettings::applySettings(const QStringList& settingsKeys, co
if (settingsKeys.contains("reverseAPIFeatureIndex")) {
m_reverseAPIFeatureIndex = settings.m_reverseAPIFeatureIndex;
}
if (settingsKeys.contains("chartsDarkTheme")) {
m_chartsDarkTheme = settings.m_chartsDarkTheme;
}
if (settingsKeys.contains("replayEnabled")) {
m_replayEnabled = settings.m_replayEnabled;
}
if (settingsKeys.contains("replayStartDateTime")) {
m_replayStartDateTime = settings.m_replayStartDateTime;
}
if (settingsKeys.contains("sendTimeToMap")) {
m_sendTimeToMap = settings.m_sendTimeToMap;
}
if (settingsKeys.contains("dateTimeSelect")) {
m_dateTimeSelect = settings.m_dateTimeSelect;
}
if (settingsKeys.contains("columnSort")) {
m_columnSort = settings.m_columnSort;
}
if (settingsKeys.contains("columnSortOrder")) {
m_columnSortOrder = settings.m_columnSortOrder;
}
if (settingsKeys.contains("columnIndexes"))
{
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
m_columnIndexes[i] = settings.m_columnIndexes[i];
}
}
if (settingsKeys.contains("columnSizes"))
{
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
m_columnSizes[i] = settings.m_columnSizes[i];
}
}
if (settingsKeys.contains("deviceSettings")) {
m_deviceSettings = settings.m_deviceSettings;
if (settingsKeys.contains("workspaceIndex")) {
m_workspaceIndex = settings.m_workspaceIndex;
}
}
@ -503,7 +515,9 @@ QString SatelliteTrackerSettings::getDebugString(const QStringList& settingsKeys
if (settingsKeys.contains("heightAboveSeaLevel") || force) {
ostr << " m_heightAboveSeaLevel: " << m_heightAboveSeaLevel;
}
if (settingsKeys.contains("target") || force) {
ostr << " m_target: " << m_target.toStdString();
}
if (settingsKeys.contains("satellites") || force)
{
ostr << "m_satellites:";
@ -512,7 +526,6 @@ QString SatelliteTrackerSettings::getDebugString(const QStringList& settingsKeys
ostr << " " << satellite.toStdString();
}
}
if (settingsKeys.contains("tles") || force)
{
ostr << " m_tles:";
@ -521,7 +534,6 @@ QString SatelliteTrackerSettings::getDebugString(const QStringList& settingsKeys
ostr << " " << tle.toStdString();
}
}
if (settingsKeys.contains("dateTime") || force) {
ostr << " m_dateTime: " << m_dateTime.toStdString();
}
@ -555,6 +567,15 @@ QString SatelliteTrackerSettings::getDebugString(const QStringList& settingsKeys
if (settingsKeys.contains("dopplerPeriod") || force) {
ostr << " m_dopplerPeriod: " << m_dopplerPeriod;
}
if (settingsKeys.contains("predictionPeriod") || force) {
ostr << " m_predictionPeriod: " << m_predictionPeriod;
}
if (settingsKeys.contains("passStartTime") || force) {
ostr << " m_passStartTime: " << m_passStartTime.toString().toStdString();
}
if (settingsKeys.contains("passFinishTime") || force) {
ostr << " m_passFinishTime: " << m_passFinishTime.toString().toStdString();
}
if (settingsKeys.contains("defaultFrequency") || force) {
ostr << " m_defaultFrequency: " << m_defaultFrequency;
}
@ -576,14 +597,68 @@ QString SatelliteTrackerSettings::getDebugString(const QStringList& settingsKeys
if (settingsKeys.contains("losCommand") || force) {
ostr << " m_losCommand: " << m_losCommand.toStdString();
}
if (settingsKeys.contains("predictionPeriod") || force) {
ostr << " m_predictionPeriod: " << m_predictionPeriod;
if (settingsKeys.contains("chartsDarkTheme") || force) {
ostr << " m_chartsDarkTheme: " << m_chartsDarkTheme;
}
if (settingsKeys.contains("passStartTime") || force) {
ostr << " m_passStartTime: " << m_passStartTime.toString().toStdString();
if (settingsKeys.contains("deviceSettings"))
{
ostr << "m_deviceSettings: [";
for (auto deviceSettingList : m_deviceSettings)
{
ostr << "[";
for (auto deviceSettings : *deviceSettingList) {
deviceSettings->getDebugString(ostr);
}
ostr << "]";
}
ostr << "]";
}
if (settingsKeys.contains("passFinishTime") || force) {
ostr << " m_passFinishTime: " << m_passFinishTime.toString().toStdString();
if (settingsKeys.contains("replayEnabled") || force) {
ostr << " m_replayEnabled: " << m_replayEnabled;
}
if (settingsKeys.contains("replayStartDateTime") || force) {
ostr << " m_replayStartDateTime: " << m_replayStartDateTime.toString().toStdString();
}
if (settingsKeys.contains("sendTimeToMap") || force) {
ostr << " m_sendTimeToMap: " << m_sendTimeToMap;
}
if (settingsKeys.contains("dateTimeSelect") || force) {
ostr << " m_dateTimeSelect: " << m_dateTimeSelect;
}
if (settingsKeys.contains("mapFeature") || force) {
ostr << " m_mapFeature: " << m_mapFeature.toStdString();
}
if (settingsKeys.contains("fileInputDevice") || force) {
ostr << " m_fileInputDevice: " << m_fileInputDevice.toStdString();
}
if (settingsKeys.contains("drawRotators") || force) {
ostr << " m_drawRotators: " << m_drawRotators;
}
if (settingsKeys.contains("columnSort") || force) {
ostr << " m_columnSort: " << m_columnSort;
}
if (settingsKeys.contains("columnSortOrder") || force) {
ostr << " m_columnSortOrder: " << m_columnSortOrder;
}
if (settingsKeys.contains("columnIndexes"))
{
ostr << "m_columnIndexes:";
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
ostr << " " << m_columnIndexes[i];
}
}
if (settingsKeys.contains("columnSizes"))
{
ostr << "m_columnSizes:";
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
ostr << " " << m_columnSizes[i];
}
}
if (settingsKeys.contains("title") || force) {
ostr << " m_title: " << m_title.toStdString();
@ -606,72 +681,9 @@ QString SatelliteTrackerSettings::getDebugString(const QStringList& settingsKeys
if (settingsKeys.contains("reverseAPIFeatureIndex") || force) {
ostr << " m_reverseAPIFeatureIndex: " << m_reverseAPIFeatureIndex;
}
if (settingsKeys.contains("chartsDarkTheme") || force) {
ostr << " m_chartsDarkTheme: " << m_chartsDarkTheme;
}
if (settingsKeys.contains("replayEnabled") || force) {
ostr << " m_replayEnabled: " << m_replayEnabled;
}
if (settingsKeys.contains("replayStartDateTime") || force) {
ostr << " m_replayStartDateTime: " << m_replayStartDateTime.toString().toStdString();
}
if (settingsKeys.contains("sendTimeToMap") || force) {
ostr << " m_sendTimeToMap: " << m_sendTimeToMap;
}
if (settingsKeys.contains("dateTimeSelect") || force) {
ostr << " m_dateTimeSelect: " << m_dateTimeSelect;
}
if (settingsKeys.contains("mapFeature") || force) {
ostr << " m_mapFeature: " << m_mapFeature.toStdString();
}
if (settingsKeys.contains("fileInputDevice") || force) {
ostr << " m_fileInputDevice: " << m_fileInputDevice.toStdString();
}
if (settingsKeys.contains("workspaceIndex") || force) {
ostr << " m_workspaceIndex: " << m_workspaceIndex;
}
if (settingsKeys.contains("columnSort") || force) {
ostr << " m_columnSort: " << m_columnSort;
}
if (settingsKeys.contains("columnSortOrder") || force) {
ostr << " m_columnSortOrder: " << m_columnSortOrder;
}
if (settingsKeys.contains("columnIndexes"))
{
ostr << "m_columnIndexes:";
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
ostr << " " << m_columnIndexes[i];
}
}
if (settingsKeys.contains("columnSizes"))
{
ostr << "m_columnSizes:";
for (int i = 0; i < SAT_COL_COLUMNS; i++) {
ostr << " " << m_columnSizes[i];
}
}
if (settingsKeys.contains("deviceSettings"))
{
ostr << "m_deviceSettings: [";
for (auto deviceSettingList : m_deviceSettings)
{
ostr << "[";
for (auto deviceSettings : *deviceSettingList) {
deviceSettings->getDebugString(ostr);
}
ostr << "]";
}
ostr << "]";
}
return QString(ostr.str().c_str());
}
@ -696,3 +708,4 @@ void SatelliteTrackerSettings::SatelliteDeviceSettings::getDebugString(std::ostr
<< " m_aosCommand: " << m_aosCommand.toStdString()
<< " m_losCommand: " << m_losCommand.toStdString();
}

View File

@ -84,6 +84,7 @@ struct SatelliteTrackerSettings
enum DateTimeSelect {NOW, CUSTOM, FROM_MAP, FROM_FILE} m_dateTimeSelect;
QString m_mapFeature; //!< Which feature when FROM_MAP
QString m_fileInputDevice; //!< Which device when FROM_FILE
enum Rotators {ALL_ROTATORS, NO_ROTATORS, MATCHING_TARGET} m_drawRotators; //!< Which rotators to draw on polar chart
int m_columnSort; //!< Which column is used for sorting (-1 for none)
Qt::SortOrder m_columnSortOrder;

View File

@ -42,6 +42,7 @@ SatelliteTrackerSettingsDialog::SatelliteTrackerSettingsDialog(SatelliteTrackerS
ui->defaultFrequency->setValue(settings->m_defaultFrequency / 1000000.0);
ui->azElUnits->setCurrentIndex((int)settings->m_azElUnits);
ui->groundTrackPoints->setValue(settings->m_groundTrackPoints);
ui->drawRotators->setCurrentIndex((int)settings->m_drawRotators);
ui->dateFormat->setText(settings->m_dateFormat);
ui->utc->setChecked(settings->m_utc);
ui->drawOnMap->setChecked(settings->m_drawOnMap);
@ -94,6 +95,7 @@ void SatelliteTrackerSettingsDialog::accept()
m_settings->m_defaultFrequency = (float)(ui->defaultFrequency->value() * 1000000.0);
m_settings->m_azElUnits = (SatelliteTrackerSettings::AzElUnits)ui->azElUnits->currentIndex();
m_settings->m_groundTrackPoints = ui->groundTrackPoints->value();
m_settings->m_drawRotators = (SatelliteTrackerSettings::Rotators)ui->drawRotators->currentIndex();
m_settings->m_dateFormat = ui->dateFormat->text();
m_settings->m_utc = ui->utc->isChecked();
m_settings->m_drawOnMap = ui->drawOnMap->isChecked();

View File

@ -339,75 +339,20 @@
<string>Display</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="defaultFrequency">
<property name="toolTip">
<string>Frequency used for Doppler and free space path loss calculations in the satellite table</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>50000.000000000000000</double>
</property>
<property name="singleStep">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="dateFormat">
<property name="toolTip">
<string>Format for dates displayed in the GUI</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QCheckBox" name="drawOnMap">
<widget class="QCheckBox" name="utc">
<property name="toolTip">
<string>When checked satellite positions are sent to the map</string>
<string>When checked times are dispayed using UTC rather than the local time zone</string>
</property>
<property name="text">
<string>Draw satellites on map</string>
<string>Display times in UTC</string>
</property>
</widget>
</item>
<item row="12" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="updatePeriodLabel">
<item row="4" column="0">
<widget class="QLabel" name="groundTrackPointsLabel">
<property name="text">
<string>Update period (s)</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="updatePeriod">
<property name="toolTip">
<string>Enter the time in seconds between each calculation of the target's position</string>
</property>
<property name="maximum">
<double>3600.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
<string>Ground track points</string>
</property>
</widget>
</item>
@ -418,6 +363,20 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="dateFormatLabel">
<property name="text">
<string>Date format</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="dateFormat">
<property name="toolTip">
<string>Format for dates displayed in the GUI</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="azElUnits">
<property name="toolTip">
@ -448,6 +407,48 @@
</item>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="defaultFrequency">
<property name="toolTip">
<string>Frequency used for Doppler and free space path loss calculations in the satellite table</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>50000.000000000000000</double>
</property>
<property name="singleStep">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item row="13" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="updatePeriodLabel">
<property name="text">
<string>Update period (s)</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="azElUnitsLabel">
<property name="text">
@ -455,27 +456,16 @@
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QCheckBox" name="utc">
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="updatePeriod">
<property name="toolTip">
<string>When checked times are dispayed using UTC rather than the local time zone</string>
<string>Enter the time in seconds between each calculation of the target's position</string>
</property>
<property name="text">
<string>Display times in UTC</string>
<property name="maximum">
<double>3600.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="dateFormatLabel">
<property name="text">
<string>Date format</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="groundTrackPointsLabel">
<property name="text">
<string>Ground track points</string>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
@ -492,6 +482,45 @@
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QCheckBox" name="drawOnMap">
<property name="toolTip">
<string>When checked satellite positions are sent to the map</string>
</property>
<property name="text">
<string>Draw satellites on map</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="drawRotators">
<property name="toolTip">
<string>Select which rotators are displayed on the polar chart</string>
</property>
<item>
<property name="text">
<string>All</string>
</property>
</item>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Matching target</string>
</property>
</item>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="drawRotatorsLabel">
<property name="text">
<string>Rotators in polar chart</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="replayTab">
@ -614,8 +643,8 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
<x>257</x>
<y>533</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
@ -630,8 +659,8 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
<x>325</x>
<y>533</y>
</hint>
<hint type="destinationlabel">
<x>286</x>

View File

@ -134,7 +134,7 @@ void getPassAzEl(QLineSeries* azimuth, QLineSeries* elevation, QLineSeries* pola
DateTime aosTime = qDateTimeToDateTime(aos);
DateTime losTime = qDateTimeToDateTime(los);
DateTime currentTime(aosTime);
int steps = 20;
int steps = 150; // Needs to be high enough, so rotator intersect with satellite position
double timeStep = (losTime - aosTime).TotalSeconds() / steps;
if (timeStep <= 0.0)

View File

@ -49,6 +49,8 @@ Pressing this button displays a settings dialog, that allows you to set:
* The units to display the solar flux in, either Solar Flux Units, Jansky or Wm^-2Hz-1. 1 sfu equals 10,000 Jansky or 10^-22 Wm^-2Hz-1.
* The update period in seconds, which controls how frequently azimuth and elevation are re-calculated.
* The IP port number the Stellarium server listens on.
* Which rotators are displayed on the polar chart. This can be All, None or Matching target. When Matching target is selected, the rotator will
only be displayed if the source in the Rotator Controller is set to this Star Tracker and Track is enabled.
* Whether to start a Stellarium telescope server.
* Whether to draw the Sun in the map.
* Whether to draw the Moon on the map.

View File

@ -33,8 +33,11 @@
#include "SWGStarTrackerDisplaySettings.h"
#include "SWGStarTrackerDisplayLoSSettings.h"
#include "feature/featureset.h"
#include "feature/featureuiset.h"
#include "feature/featureutils.h"
#include "feature/featurewebapiutils.h"
#include "channel/channelwebapiutils.h"
#include "gui/basicfeaturesettingsdialog.h"
#include "gui/dmsspinbox.h"
#include "gui/graphicsviewzoom.h"
@ -285,6 +288,8 @@ StarTrackerGUI::StarTrackerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet,
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
m_statusTimer.start(1000);
connect(&m_redrawTimer, &QTimer::timeout, this, &StarTrackerGUI::plotChart);
connect(ui->azimuth, SIGNAL(valueChanged(double)), this, SLOT(on_azimuth_valueChanged(double)));
ui->azimuth->setRange(0, 360.0);
ui->elevation->setRange(-90.0, 90.0);
@ -812,7 +817,7 @@ void StarTrackerGUI::on_displaySettings_clicked()
ui->galacticLongitude->setUnits((DMSSpinBox::DisplayUnits)m_settings.m_azElUnits);
displaySolarFlux();
if (ui->chartSelect->currentIndex() == 1) {
if (ui->chartSelect->currentIndex() <= 1) {
plotChart();
}
}
@ -1651,6 +1656,26 @@ void StarTrackerGUI::plotElevationLineChart()
delete oldChart;
}
// Reduce az/el range from 450,180 to 360,90
void StarTrackerGUI::limitAzElRange(double& azimuth, double& elevation) const
{
if (elevation > 90.0)
{
elevation = 180.0 - elevation;
if (azimuth < 180.0) {
azimuth += 180.0;
} else {
azimuth -= 180.0;
}
}
if (azimuth > 360.0) {
azimuth -= 360.0f;
}
if (azimuth == 0) {
azimuth = 360.0;
}
}
// Plot target elevation angle over the day
void StarTrackerGUI::plotElevationPolarChart()
{
@ -1841,6 +1866,92 @@ void StarTrackerGUI::plotElevationPolarChart()
series[i]->attachAxis(radialAxis);
}
if (m_settings.m_drawRotators != StarTrackerSettings::NO_ROTATORS)
{
int redrawTime = 0;
// Plot rotator position
QString ourSourceName = QString("F0:%1 %2").arg(m_starTracker->getIndexInFeatureSet()).arg(m_starTracker->getIdentifier()); // Only one feature set in practice?
std::vector<FeatureSet*>& featureSets = MainCore::instance()->getFeatureeSets();
for (int featureSetIndex = 0; featureSetIndex < featureSets.size(); featureSetIndex++)
{
FeatureSet *featureSet = featureSets[featureSetIndex];
for (int featureIndex = 0; featureIndex < featureSet->getNumberOfFeatures(); featureIndex++)
{
Feature *feature = featureSet->getFeatureAt(featureIndex);
if (FeatureUtils::compareFeatureURIs(feature->getURI(), "sdrangel.feature.gs232controller"))
{
QString source;
ChannelWebAPIUtils::getFeatureSetting(featureSetIndex, featureIndex, "source", source); // Will return false if source isn't set in Controller
int track = 0;
ChannelWebAPIUtils::getFeatureSetting(featureSetIndex, featureIndex, "track", track);
if ((m_settings.m_drawRotators == StarTrackerSettings::ALL_ROTATORS) || ((source == ourSourceName) && track))
{
int onTarget = 0;
ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "onTarget", onTarget);
if (!onTarget)
{
// Target azimuth red dotted line
double targetAzimuth, targetElevation;
bool targetAzimuthOk = ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "targetAzimuth", targetAzimuth);
bool targetElevationOk = ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "targetElevation", targetElevation);
if (targetAzimuthOk && targetElevationOk)
{
limitAzElRange(targetAzimuth, targetElevation);
QScatterSeries *rotatorSeries = new QScatterSeries();
QColor color(255, 0, 0, 150);
QPen pen(color);
rotatorSeries->setPen(pen);
rotatorSeries->setColor(color.darker());
rotatorSeries->setMarkerSize(20);
rotatorSeries->append(targetAzimuth, 90-targetElevation);
m_azElPolarChart->addSeries(rotatorSeries);
rotatorSeries->attachAxis(angularAxis);
rotatorSeries->attachAxis(radialAxis);
redrawTime = 333;
}
}
// Current azimuth line. Yellow while off target, green on target.
double currentAzimuth, currentElevation;
bool currentAzimuthOk = ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "currentAzimuth", currentAzimuth);
bool currentElevationOk = ChannelWebAPIUtils::getFeatureReportValue(featureSetIndex, featureIndex, "currentElevation", currentElevation);
if (currentAzimuthOk && currentElevationOk)
{
limitAzElRange(currentAzimuth, currentElevation);
QScatterSeries *rotatorSeries = new QScatterSeries();
QColor color;
if (onTarget) {
color = QColor(0, 255, 0, 150);
} else {
color = QColor(255, 255, 0, 150);
}
rotatorSeries->setPen(QPen(color));
rotatorSeries->setColor(color.darker());
rotatorSeries->setMarkerSize(20);
rotatorSeries->append(currentAzimuth, 90-currentElevation);
m_azElPolarChart->addSeries(rotatorSeries);
rotatorSeries->attachAxis(angularAxis);
rotatorSeries->attachAxis(radialAxis);
redrawTime = 333;
}
}
}
}
}
if (redrawTime > 0)
{
// Redraw to show updated rotator position
// Update period may be long or custom time might be fixed
m_redrawTimer.setSingleShot(true);
m_redrawTimer.start(redrawTime);
}
}
// Create series with single point, so we can plot time of rising
if (riseTime.isValid())
{
@ -2242,3 +2353,4 @@ void StarTrackerGUI::makeUIConnections()
QObject::connect(ui->drawSun, &QToolButton::clicked, this, &StarTrackerGUI::on_drawSun_clicked);
QObject::connect(ui->drawMoon, &QToolButton::clicked, this, &StarTrackerGUI::on_drawMoon_clicked);
}

View File

@ -90,6 +90,7 @@ private:
QChart *m_azElLineChart;
QPolarChart *m_azElPolarChart;
QTimer m_redrawTimer;
QChart m_chart;
QDateTimeAxis m_chartXAxis;
@ -161,6 +162,7 @@ private:
void updateChartSubSelect();
void updateSolarFlux(bool all);
void makeUIConnections();
void limitAzElRange(double& azimuth, double& elevation) const;
private slots:
void onMenuDialogCalled(const QPoint &p);

View File

@ -83,6 +83,7 @@ void StarTrackerSettings::resetToDefaults()
m_drawSunOnSkyTempChart = true;
m_drawMoonOnSkyTempChart = true;
m_workspaceIndex = 0;
m_drawRotators = MATCHING_TARGET;
}
QByteArray StarTrackerSettings::serialize() const
@ -139,6 +140,7 @@ QByteArray StarTrackerSettings::serialize() const
s.writeS32(45, m_workspaceIndex);
s.writeBlob(46, m_geometryBytes);
s.writeS32(47, (int)m_drawRotators);
return s.final();
}
@ -227,6 +229,7 @@ bool StarTrackerSettings::deserialize(const QByteArray& data)
d.readS32(45, &m_workspaceIndex, 0);
d.readBlob(46, &m_geometryBytes);
d.readS32(47, (int *)&m_drawRotators, MATCHING_TARGET);
return true;
}
@ -374,6 +377,9 @@ void StarTrackerSettings::applySettings(const QStringList& settingsKeys, const S
if (settingsKeys.contains("workspaceIndex")) {
m_workspaceIndex = settings.m_workspaceIndex;
}
if (settingsKeys.contains("drawRotators")) {
m_drawRotators = settings.m_drawRotators;
}
}
QString StarTrackerSettings::getDebugString(const QStringList& settingsKeys, bool force) const
@ -512,6 +518,9 @@ QString StarTrackerSettings::getDebugString(const QStringList& settingsKeys, boo
if (settingsKeys.contains("workspaceIndex") || force) {
ostr << " m_workspaceIndex: " << m_workspaceIndex;
}
if (settingsKeys.contains("drawRotators") || force) {
ostr << " m_drawRotators: " << m_drawRotators;
}
return QString(ostr.str().c_str());
}

View File

@ -74,6 +74,7 @@ struct StarTrackerSettings
Serializable *m_rollupState;
int m_workspaceIndex;
QByteArray m_geometryBytes;
enum Rotators {ALL_ROTATORS, NO_ROTATORS, MATCHING_TARGET} m_drawRotators; //!< Which rotators to draw on polar chart
StarTrackerSettings();
void resetToDefaults();

View File

@ -44,8 +44,10 @@ StarTrackerSettingsDialog::StarTrackerSettingsDialog(
ui->temperatureLapseRate->setValue(settings->m_temperatureLapseRate);
ui->solarFluxData->setCurrentIndex((int)settings->m_solarFluxData);
ui->solarFluxUnits->setCurrentIndex((int)settings->m_solarFluxUnits);
ui->drawRotators->setCurrentIndex((int)settings->m_drawRotators);
ui->drawSunOnMap->setChecked(settings->m_drawSunOnMap);
ui->drawMoonOnMap->setChecked(settings->m_drawMoonOnMap);
ui->drawStarOnMap->setChecked(settings->m_drawStarOnMap);
}
StarTrackerSettingsDialog::~StarTrackerSettingsDialog()
@ -70,6 +72,7 @@ void StarTrackerSettingsDialog::accept()
m_settings->m_temperatureLapseRate = ui->temperatureLapseRate->value();
m_settings->m_solarFluxData = (StarTrackerSettings::SolarFluxData)ui->solarFluxData->currentIndex();
m_settings->m_solarFluxUnits = (StarTrackerSettings::SolarFluxUnits)ui->solarFluxUnits->currentIndex();
m_settings->m_drawRotators = (StarTrackerSettings::Rotators)ui->drawRotators->currentIndex();
m_settings->m_drawSunOnMap = ui->drawSunOnMap->isChecked();
m_settings->m_drawMoonOnMap = ui->drawMoonOnMap->isChecked();
m_settings->m_drawStarOnMap = ui->drawStarOnMap->isChecked();
@ -89,6 +92,7 @@ void StarTrackerSettingsDialog::accept()
m_settingsKeys.append("temperatureLapseRate");
m_settingsKeys.append("solarFluxData");
m_settingsKeys.append("solarFluxUnits");
m_settingsKeys.append("drawRotators");
m_settingsKeys.append("drawSunOnMap");
m_settingsKeys.append("drawMoonOnMap");
m_settingsKeys.append("drawStarOnMap");

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>569</width>
<height>535</height>
<height>556</height>
</rect>
</property>
<property name="font">
@ -23,24 +23,7 @@
<item>
<widget class="QGroupBox" name="groupBox">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QComboBox" name="epoch">
<property name="toolTip">
<string>Epoch for custom right ascension and declination</string>
</property>
<item>
<property name="text">
<string>J2000</string>
</property>
</item>
<item>
<property name="text">
<string>JNOW</string>
</property>
</item>
</widget>
</item>
<item row="15" column="0">
<item row="16" column="0">
<widget class="QCheckBox" name="enableServer">
<property name="toolTip">
<string>Enable Stellarium server which allows RA and Dec to be sent to and from Stellarium</string>
@ -50,74 +33,7 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="pressureLabel">
<property name="text">
<string>Air pressure (mb)</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QSpinBox" name="humidity">
<property name="toolTip">
<string>Relative humidity in %</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>80</number>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="temperatureLapseRateLabel">
<property name="toolTip">
<string>Temperature lapse rate (K/m)</string>
</property>
<property name="text">
<string>Temperature lapse rate (K/km)</string>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QCheckBox" name="drawMoonOnMap">
<property name="text">
<string>Draw Moon on map</string>
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QCheckBox" name="drawSunOnMap">
<property name="text">
<string>Draw Sun on map</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="temperatureLabel">
<property name="text">
<string>Air temperature (C)</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="pressure">
<property name="toolTip">
<string>Air pressure in millibars, for use in atmospheric refraction correction</string>
</property>
<property name="maximum">
<double>2000.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1010.000000000000000</double>
</property>
</widget>
</item>
<item row="20" column="1">
<item row="21" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -130,52 +46,13 @@
</property>
</spacer>
</item>
<item row="18" column="0">
<widget class="QCheckBox" name="drawStarOnMap">
<item row="17" column="0">
<widget class="QCheckBox" name="drawSunOnMap">
<property name="text">
<string>Draw target star on map</string>
<string>Draw Sun on map</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="weatherUpdatePeriodLabel">
<property name="text">
<string>Weather update period (min)</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="solarFluxDataLabel">
<property name="text">
<string>Solar flux density data</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="refraction">
<property name="toolTip">
<string>Atmospheric refraction correction</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Saemundsson</string>
</property>
</item>
<item>
<property name="text">
<string>Positional Astronomy Library</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="azElUnits">
<property name="toolTip">
@ -206,153 +83,58 @@
</item>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="temperature">
<property name="toolTip">
<string>Air temperature in degrees Celsius, for use in atmospheric refraction correction</string>
<item row="6" column="0">
<widget class="QLabel" name="temperatureLabel">
<property name="text">
<string>Air temperature (C)</string>
</property>
<property name="minimum">
<number>-100</number>
</widget>
</item>
<item row="7" column="1">
<widget class="QSpinBox" name="humidity">
<property name="toolTip">
<string>Relative humidity in %</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>10</number>
<number>80</number>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="solarFluxUnitsLabel">
<property name="text">
<string>Solar flux density units</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QDoubleSpinBox" name="temperatureLapseRate">
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>6.490000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="refractionLabel">
<property name="text">
<string>Refraction correction</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="solarFluxUnits">
<item row="2" column="1">
<widget class="QComboBox" name="refraction">
<property name="toolTip">
<string>Units to use for the display of the Solar flux density</string>
<string>Atmospheric refraction correction</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Solar flux units (sfu)</string>
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Jansky (Jy)</string>
<string>Saemundsson</string>
</property>
</item>
<item>
<property name="text">
<string>Watts per square metre per hertz (W m^-2 Hz-1)</string>
<string>Positional Astronomy Library</string>
</property>
</item>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="heightLabel">
<property name="text">
<string>Height above sea level (m)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="owmAPIKey">
<item row="9" column="0">
<widget class="QLabel" name="temperatureLapseRateLabel">
<property name="toolTip">
<string>API key from openweathermap.org to download real-time weather</string>
<string>Temperature lapse rate (K/m)</string>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="serverPortLabel">
<property name="text">
<string>Stellarium server port</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="epochLabel">
<property name="text">
<string>Epoch for RA &amp; Dec</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="azElUnitsLabel">
<property name="text">
<string>Azimuth and elevation units</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="owmAPIKeyLabel">
<property name="text">
<string>OpenWeatherMap API Key</string>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QSpinBox" name="serverPort">
<property name="toolTip">
<string>Stellarium telescope server IP port number</string>
</property>
<property name="minimum">
<number>1024</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>10001</number>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QDoubleSpinBox" name="updatePeriod">
<property name="toolTip">
<string>Enter the time in seconds between each calculation of the target's position</string>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="updatePeriodLabel">
<property name="text">
<string>Update period (s)</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="weatherUpdatePeriod">
<property name="toolTip">
<string>Enter the time in minutes between each weather update</string>
</property>
<property name="maximum">
<number>100000</number>
<string>Temperature lapse rate (K/km)</string>
</property>
</widget>
</item>
@ -363,16 +145,68 @@
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="height">
<property name="toolTip">
<string>Height of observation/antenna location above sea level in metres</string>
<item row="0" column="0">
<widget class="QLabel" name="epochLabel">
<property name="text">
<string>Epoch for RA &amp; Dec</string>
</property>
<property name="minimum">
<number>-1000</number>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="weatherUpdatePeriodLabel">
<property name="text">
<string>Weather update period (min)</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="pressureLabel">
<property name="text">
<string>Air pressure (mb)</string>
</property>
</widget>
</item>
<item row="19" column="0">
<widget class="QCheckBox" name="drawStarOnMap">
<property name="text">
<string>Draw target star on map</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="owmAPIKeyLabel">
<property name="text">
<string>OpenWeatherMap API Key</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="solarFluxUnitsLabel">
<property name="text">
<string>Solar flux density units</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="pressure">
<property name="toolTip">
<string>Air pressure in millibars, for use in atmospheric refraction correction</string>
</property>
<property name="maximum">
<number>20000</number>
<double>2000.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1010.000000000000000</double>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="heightLabel">
<property name="text">
<string>Height above sea level (m)</string>
</property>
</widget>
</item>
@ -433,6 +267,201 @@
</item>
</widget>
</item>
<item row="9" column="1">
<widget class="QDoubleSpinBox" name="temperatureLapseRate">
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>6.490000000000000</double>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="owmAPIKey">
<property name="toolTip">
<string>API key from openweathermap.org to download real-time weather</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="temperature">
<property name="toolTip">
<string>Air temperature in degrees Celsius, for use in atmospheric refraction correction</string>
</property>
<property name="minimum">
<number>-100</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="18" column="0">
<widget class="QCheckBox" name="drawMoonOnMap">
<property name="text">
<string>Draw Moon on map</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="updatePeriodLabel">
<property name="text">
<string>Update period (s)</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="epoch">
<property name="toolTip">
<string>Epoch for custom right ascension and declination</string>
</property>
<item>
<property name="text">
<string>J2000</string>
</property>
</item>
<item>
<property name="text">
<string>JNOW</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="refractionLabel">
<property name="text">
<string>Refraction correction</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="solarFluxDataLabel">
<property name="text">
<string>Solar flux density data</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QComboBox" name="solarFluxUnits">
<property name="toolTip">
<string>Units to use for the display of the Solar flux density</string>
</property>
<item>
<property name="text">
<string>Solar flux units (sfu)</string>
</property>
</item>
<item>
<property name="text">
<string>Jansky (Jy)</string>
</property>
</item>
<item>
<property name="text">
<string>Watts per square metre per hertz (W m^-2 Hz-1)</string>
</property>
</item>
</widget>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="height">
<property name="toolTip">
<string>Height of observation/antenna location above sea level in metres</string>
</property>
<property name="minimum">
<number>-1000</number>
</property>
<property name="maximum">
<number>20000</number>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QDoubleSpinBox" name="updatePeriod">
<property name="toolTip">
<string>Enter the time in seconds between each calculation of the target's position</string>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QSpinBox" name="serverPort">
<property name="toolTip">
<string>Stellarium telescope server IP port number</string>
</property>
<property name="minimum">
<number>1024</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>10001</number>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="serverPortLabel">
<property name="text">
<string>Stellarium server port</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="weatherUpdatePeriod">
<property name="toolTip">
<string>Enter the time in minutes between each weather update</string>
</property>
<property name="maximum">
<number>100000</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="azElUnitsLabel">
<property name="text">
<string>Azimuth and elevation units</string>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="drawRotatorsLabel">
<property name="text">
<string>Rotators in polar chart</string>
</property>
</widget>
</item>
<item row="15" column="1">
<widget class="QComboBox" name="drawRotators">
<property name="toolTip">
<string>Select which rotators are displayed on the polar chart</string>
</property>
<item>
<property name="text">
<string>All</string>
</property>
</item>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Matching target</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>