diff --git a/plugins/feature/startracker/readme.md b/plugins/feature/startracker/readme.md
index ca049cbd8..39ab6f720 100644
--- a/plugins/feature/startracker/readme.md
+++ b/plugins/feature/startracker/readme.md
@@ -99,6 +99,7 @@ To allow Stellarium to set the RA and Dec, select Custom RA/Dec, and ensure the
| S7 | HI | IAU secondary calibration region (l=132,b=-1) | Tb=100 peak |
| S8 | HI | IAU primary calibration region (l=207,b=-15) | Tb=72 peak |
| S9 | HI | IAU secondary calibration region (l=356,b=-4) | Tb=85 peak |
+| SatelliteTracker | | Gets target Az/El from Satellite Tracker | |
References:
@@ -173,6 +174,9 @@ In order to assist in determining whether and when observations of the target ob
This can be plotted on Cartesian or polar axis.
Some objects may not be visible from a particular latitude for the specified time, in which case, the graph title will indicate the object is not visible on that particular date.
+When the target is set to a Satellite Tracker, this chart is plotted based on the Satellite's current position only. It does not take in to consideration the satellite's movement. For that,
+use the chart in the Satellite Tracker.
+
Solar flux vs frequency

diff --git a/plugins/feature/startracker/startracker.cpp b/plugins/feature/startracker/startracker.cpp
index d0185d5df..cdc3a2781 100644
--- a/plugins/feature/startracker/startracker.cpp
+++ b/plugins/feature/startracker/startracker.cpp
@@ -29,6 +29,7 @@
#include "device/deviceset.h"
#include "dsp/dspengine.h"
+#include "feature/featureset.h"
#include "util/weather.h"
#include "util/units.h"
#include "settings/serializable.h"
@@ -41,6 +42,7 @@
MESSAGE_CLASS_DEFINITION(StarTracker::MsgConfigureStarTracker, Message)
MESSAGE_CLASS_DEFINITION(StarTracker::MsgStartStop, Message)
MESSAGE_CLASS_DEFINITION(StarTracker::MsgSetSolarFlux, Message)
+MESSAGE_CLASS_DEFINITION(StarTracker::MsgReportAvailableSatelliteTrackers, Message)
const char* const StarTracker::m_featureIdURI = "sdrangel.feature.startracker";
const char* const StarTracker::m_featureId = "StarTracker";
@@ -69,12 +71,25 @@ StarTracker::StarTracker(WebAPIAdapterInterface *webAPIAdapterInterface) :
m_temps.append(new FITS(":/startracker/startracker/1420mhz_ra_dec.fits"));
m_spectralIndex = new FITS(":/startracker/startracker/408mhz_ra_dec_spectral_index.fits");
scanAvailableChannels();
+ scanAvailableFeatures();
QObject::connect(
MainCore::instance(),
&MainCore::channelAdded,
this,
&StarTracker::handleChannelAdded
);
+ QObject::connect(
+ MainCore::instance(),
+ &MainCore::featureAdded,
+ this,
+ &StarTracker::handleFeatureAdded
+ );
+ QObject::connect(
+ MainCore::instance(),
+ &MainCore::featureRemoved,
+ this,
+ &StarTracker::handleFeatureRemoved
+ );
}
StarTracker::~StarTracker()
@@ -908,6 +923,52 @@ void StarTracker::handleMessagePipeToBeDeleted(int reason, QObject* object)
}
}
+void StarTracker::scanAvailableFeatures()
+{
+ qDebug("StarTracker::scanAvailableFeatures");
+ MainCore *mainCore = MainCore::instance();
+ MessagePipes& messagePipes = mainCore->getMessagePipes();
+ std::vector& featureSets = mainCore->getFeatureeSets();
+ m_satelliteTrackers.clear();
+
+ for (const auto& featureSet : featureSets)
+ {
+ for (int fei = 0; fei < featureSet->getNumberOfFeatures(); fei++)
+ {
+ Feature *feature = featureSet->getFeatureAt(fei);
+
+ if (feature->getURI() == "sdrangel.feature.satellitetracker")
+ {
+ StarTrackerSettings::AvailableFeature satelliteTracker =
+ StarTrackerSettings::AvailableFeature{featureSet->getIndex(), fei, feature->getIdentifier()};
+ m_satelliteTrackers[feature] = satelliteTracker;
+ }
+ }
+ }
+
+ notifyUpdateSatelliteTrackers();
+}
+
+void StarTracker::handleFeatureAdded(int featureSetIndex, Feature *feature)
+{
+ scanAvailableFeatures();
+}
+
+void StarTracker::handleFeatureRemoved(int featureSetIndex, Feature *feature)
+{
+ scanAvailableFeatures();
+}
+
+void StarTracker::notifyUpdateSatelliteTrackers()
+{
+ if (getMessageQueueToGUI())
+ {
+ MsgReportAvailableSatelliteTrackers *msg = MsgReportAvailableSatelliteTrackers::create();
+ msg->getFeatures() = m_satelliteTrackers.values();
+ getMessageQueueToGUI()->push(msg);
+ }
+}
+
void StarTracker::handleChannelMessageQueue(MessageQueue* messageQueue)
{
Message* message;
diff --git a/plugins/feature/startracker/startracker.h b/plugins/feature/startracker/startracker.h
index fafe1f884..09871c0bb 100644
--- a/plugins/feature/startracker/startracker.h
+++ b/plugins/feature/startracker/startracker.h
@@ -106,6 +106,24 @@ public:
{ }
};
+ class MsgReportAvailableSatelliteTrackers : public Message {
+ MESSAGE_CLASS_DECLARATION
+
+ public:
+ QList& getFeatures() { return m_availableFeatures; }
+
+ static MsgReportAvailableSatelliteTrackers* create() {
+ return new MsgReportAvailableSatelliteTrackers();
+ }
+
+ private:
+ QList m_availableFeatures;
+
+ MsgReportAvailableSatelliteTrackers() :
+ Message()
+ {}
+ };
+
StarTracker(WebAPIAdapterInterface *webAPIAdapterInterface);
virtual ~StarTracker();
virtual void destroy() { delete this; }
@@ -165,6 +183,7 @@ private:
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
QSet m_availableChannels;
+ QHash m_satelliteTrackers;
Weather *m_weather;
float m_solarFlux;
@@ -178,12 +197,16 @@ private:
void webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport& response);
double applyBeam(const FITS *fits, double beamwidth, double ra, double dec, int& imgX, int& imgY) const;
void scanAvailableChannels();
+ void scanAvailableFeatures();
+ void notifyUpdateSatelliteTrackers();
private slots:
void networkManagerFinished(QNetworkReply *reply);
void weatherUpdated(float temperature, float pressure, float humidity);
void handleChannelAdded(int deviceSetIndex, ChannelAPI *channel);
void handleMessagePipeToBeDeleted(int reason, QObject* object);
+ void handleFeatureAdded(int featureSetIndex, Feature *feature);
+ void handleFeatureRemoved(int featureSetIndex, Feature *feature);
void handleChannelMessageQueue(MessageQueue* messageQueue);
};
diff --git a/plugins/feature/startracker/startrackergui.cpp b/plugins/feature/startracker/startrackergui.cpp
index 39b09ce87..3d54ac354 100644
--- a/plugins/feature/startracker/startrackergui.cpp
+++ b/plugins/feature/startracker/startrackergui.cpp
@@ -214,10 +214,67 @@ bool StarTrackerGUI::handleMessage(const Message& message)
}
return true;
}
+ else if (StarTracker::MsgReportAvailableSatelliteTrackers::match(message))
+ {
+ StarTracker::MsgReportAvailableSatelliteTrackers& report = (StarTracker::MsgReportAvailableSatelliteTrackers&) message;
+ updateSatelliteTrackerList(report.getFeatures());
+ return true;
+ }
return false;
}
+void StarTrackerGUI::updateSatelliteTrackerList(const QList& satelliteTrackers)
+{
+ // Update list of satellite trackers
+ ui->target->blockSignals(true);
+
+ // Remove Satellite Trackers no longer available
+ for (int i = 0; i < ui->target->count(); )
+ {
+ QString text = ui->target->itemText(i);
+ bool found = false;
+ if (text.contains("SatelliteTracker"))
+ {
+ for (const auto& satelliteTracker : satelliteTrackers)
+ {
+ if (satelliteTracker.getName() == text)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ ui->target->removeItem(i);
+ } else {
+ i++;
+ }
+ }
+ else
+ {
+ i++;
+ }
+ }
+
+ // Add new Satellite Trackers
+ for (const auto& satelliteTracker : satelliteTrackers)
+ {
+ QString name = satelliteTracker.getName();
+ if (ui->target->findText(name) == -1) {
+ ui->target->addItem(name);
+ }
+ }
+
+ // Satellite Tracker feature can be created after this plugin, so select it
+ // if the chosen tracker appears
+ int index = ui->target->findText(m_settings.m_target);
+ if (index >= 0) {
+ ui->target->setCurrentIndex(index);
+ }
+
+ ui->target->blockSignals(false);
+}
+
void StarTrackerGUI::handleInputMessages()
{
Message* message;
@@ -568,7 +625,7 @@ void StarTrackerGUI::on_declination_editingFinished()
void StarTrackerGUI::on_azimuth_valueChanged(double value)
{
m_settings.m_az = value;
- m_settingsKeys.append("az");
+ m_settingsKeys.append("azimuth");
applySettings();
plotChart();
}
@@ -576,7 +633,7 @@ void StarTrackerGUI::on_azimuth_valueChanged(double value)
void StarTrackerGUI::on_elevation_valueChanged(double value)
{
m_settings.m_el = value;
- m_settingsKeys.append("el");
+ m_settingsKeys.append("elevation");
applySettings();
plotChart();
}
@@ -691,7 +748,14 @@ void StarTrackerGUI::updateForTarget()
on_rightAscension_editingFinished();
on_declination_editingFinished();
}
- if (m_settings.m_target != "Custom Az/El")
+ if (m_settings.m_target.contains("SatelliteTracker"))
+ {
+ ui->azimuth->setReadOnly(true);
+ ui->elevation->setReadOnly(true);
+ ui->rightAscension->setReadOnly(true);
+ ui->declination->setReadOnly(true);
+ }
+ else if (m_settings.m_target != "Custom Az/El")
{
ui->azimuth->setReadOnly(true);
ui->elevation->setReadOnly(true);
@@ -710,11 +774,14 @@ void StarTrackerGUI::updateForTarget()
void StarTrackerGUI::on_target_currentTextChanged(const QString &text)
{
- m_settings.m_target = text;
- m_settingsKeys.append("target");
- applySettings();
- updateForTarget();
- plotChart();
+ if (!text.isEmpty())
+ {
+ m_settings.m_target = text;
+ m_settingsKeys.append("target");
+ applySettings();
+ updateForTarget();
+ plotChart();
+ }
}
void StarTrackerGUI::updateLST()
@@ -1672,6 +1739,8 @@ void StarTrackerGUI::plotElevationLineChart()
if (maxElevation < 0) {
m_azElLineChart->setTitle("Not visible from this latitude");
+ } else if (m_settings.m_target.contains("SatelliteTracker")) {
+ m_azElLineChart->setTitle("See Satellite Tracker for chart that accounts for satellite's movement");
} else {
m_azElLineChart->setTitle("");
}
@@ -2027,6 +2096,8 @@ void StarTrackerGUI::plotElevationPolarChart()
if (maxElevation < 0) {
m_azElPolarChart->setTitle("Not visible from this latitude");
+ } else if (m_settings.m_target.contains("SatelliteTracker")) {
+ m_azElPolarChart->setTitle("See Satellite Tracker for chart that accounts for satellite's movement");
} else {
m_azElPolarChart->setTitle("");
}
diff --git a/plugins/feature/startracker/startrackergui.h b/plugins/feature/startracker/startrackergui.h
index 03d31762a..1186121b8 100644
--- a/plugins/feature/startracker/startrackergui.h
+++ b/plugins/feature/startracker/startrackergui.h
@@ -163,6 +163,7 @@ private:
void updateSolarFlux(bool all);
void makeUIConnections();
void limitAzElRange(double& azimuth, double& elevation) const;
+ void updateSatelliteTrackerList(const QList& satelliteTrackers);
private slots:
void onMenuDialogCalled(const QPoint &p);
diff --git a/plugins/feature/startracker/startrackergui.ui b/plugins/feature/startracker/startrackergui.ui
index 0ec35de63..f717bef08 100644
--- a/plugins/feature/startracker/startrackergui.ui
+++ b/plugins/feature/startracker/startrackergui.ui
@@ -101,7 +101,7 @@
Offset in degrees to add to calculated target elevation
- 1
+ 3
-180.000000000000000
@@ -167,7 +167,7 @@
- 110
+ 150
0
@@ -460,7 +460,7 @@ This can be specified as a decimal (E.g. 34.23) or in degrees, minutes and secon
Offset in degrees to added to calculated target azimuth
- 1
+ 3
-360.000000000000000
diff --git a/plugins/feature/startracker/startrackersettings.cpp b/plugins/feature/startracker/startrackersettings.cpp
index 9023ccb21..ac6e1296e 100644
--- a/plugins/feature/startracker/startrackersettings.cpp
+++ b/plugins/feature/startracker/startrackersettings.cpp
@@ -341,10 +341,10 @@ void StarTrackerSettings::applySettings(const QStringList& settingsKeys, const S
if (settingsKeys.contains("reverseAPIFeatureIndex")) {
m_reverseAPIFeatureIndex = settings.m_reverseAPIFeatureIndex;
}
- if (settingsKeys.contains("az")) {
+ if (settingsKeys.contains("azimuth")) {
m_az = settings.m_az;
}
- if (settingsKeys.contains("el")) {
+ if (settingsKeys.contains("elevation")) {
m_el = settings.m_el;
}
if (settingsKeys.contains("l")) {
@@ -482,10 +482,10 @@ QString StarTrackerSettings::getDebugString(const QStringList& settingsKeys, boo
if (settingsKeys.contains("reverseAPIFeatureIndex") || force) {
ostr << " m_reverseAPIFeatureIndex: " << m_reverseAPIFeatureIndex;
}
- if (settingsKeys.contains("az") || force) {
+ if (settingsKeys.contains("azimuth") || force) {
ostr << " m_az: " << m_az;
}
- if (settingsKeys.contains("el") || force) {
+ if (settingsKeys.contains("elevation") || force) {
ostr << " m_el: " << m_el;
}
if (settingsKeys.contains("l") || force) {
diff --git a/plugins/feature/startracker/startrackersettings.h b/plugins/feature/startracker/startrackersettings.h
index 8210bda8a..946e6ebda 100644
--- a/plugins/feature/startracker/startrackersettings.h
+++ b/plugins/feature/startracker/startrackersettings.h
@@ -28,6 +28,23 @@ class Serializable;
struct StarTrackerSettings
{
+ struct AvailableFeature
+ {
+ int m_featureSetIndex;
+ int m_featureIndex;
+ QString m_type;
+
+ AvailableFeature() = default;
+ AvailableFeature(const AvailableFeature&) = default;
+ AvailableFeature& operator=(const AvailableFeature&) = default;
+ bool operator==(const AvailableFeature& a) const {
+ return (m_featureSetIndex == a.m_featureSetIndex) && (m_featureIndex == a.m_featureIndex) && (m_type == a.m_type);
+ }
+ QString getName() const {
+ return QString("F%1:%2 %3").arg(m_featureSetIndex).arg(m_featureIndex).arg(m_type);
+ }
+ };
+
QString m_ra;
QString m_dec;
double m_latitude;
diff --git a/plugins/feature/startracker/startrackerworker.cpp b/plugins/feature/startracker/startrackerworker.cpp
index 14cbef293..200361ed1 100644
--- a/plugins/feature/startracker/startrackerworker.cpp
+++ b/plugins/feature/startracker/startrackerworker.cpp
@@ -32,6 +32,7 @@
#include "webapi/webapiadapterinterface.h"
#include "webapi/webapiutils.h"
+#include "channel/channelwebapiutils.h"
#include "util/units.h"
#include "maincore.h"
@@ -141,8 +142,8 @@ void StarTrackerWorker::applySettings(const StarTrackerSettings& settings, const
|| settingsKeys.contains("temperatureLapseRate")
|| settingsKeys.contains("frequency")
|| settingsKeys.contains("beamwidth")
- || settingsKeys.contains("az")
- || settingsKeys.contains("el")
+ || settingsKeys.contains("azimuth")
+ || settingsKeys.contains("elevation")
|| settingsKeys.contains("l")
|| settingsKeys.contains("b")
|| settingsKeys.contains("azimuthOffset")
@@ -382,7 +383,7 @@ void StarTrackerWorker::updateRaDec(RADec rd, QDateTime dt, bool lbTarget)
// Send to Stellarium
writeStellariumTarget(rdJ2000.ra, rdJ2000.dec);
// Send to GUI
- if (m_settings.m_target == "Sun" || m_settings.m_target == "Moon" || (m_settings.m_target == "Custom Az/El") || lbTarget)
+ if (m_settings.m_target == "Sun" || m_settings.m_target == "Moon" || (m_settings.m_target == "Custom Az/El") || lbTarget || m_settings.m_target.contains("SatelliteTracker"))
{
if (getMessageQueueToGUI())
{
@@ -495,6 +496,32 @@ void StarTrackerWorker::update()
getMessageQueueToGUI()->push(StarTrackerReport::MsgReportRADec::create(moonRD.ra, moonRD.dec, "moon"));
}
+ if (m_settings.m_target.contains("SatelliteTracker"))
+ {
+ // Get Az/El from Satellite Tracker
+ double azimuth, elevation;
+
+ const QRegExp re("F([0-9]+):([0-9]+)");
+ if (re.indexIn(m_settings.m_target) >= 0)
+ {
+ int satelliteTrackerFeatureSetIndex = re.capturedTexts()[1].toInt();
+ int satelliteTrackerFeatureIndex = re.capturedTexts()[2].toInt();
+
+ if (ChannelWebAPIUtils::getFeatureReportValue(satelliteTrackerFeatureSetIndex, satelliteTrackerFeatureIndex, "targetAzimuth", azimuth)
+ && ChannelWebAPIUtils::getFeatureReportValue(satelliteTrackerFeatureSetIndex, satelliteTrackerFeatureIndex, "targetElevation", elevation))
+ {
+ m_settings.m_el = elevation;
+ m_settings.m_az = azimuth;
+ }
+ else
+ qDebug() << "StarTrackerWorker::update - Failed to target from feature " << m_settings.m_target;
+ }
+ else
+ qDebug() << "StarTrackerWorker::update - Failed to parse feature name " << m_settings.m_target;
+ }
+ else
+ qDebug() << "TARGET IS NOT SAT TRACKER!! " << m_settings.m_target;
+
if (m_settings.m_target == "Sun")
{
rd = sunRD;
@@ -507,7 +534,7 @@ void StarTrackerWorker::update()
aa = moonAA;
Astronomy::equatorialToGalactic(rd.ra, rd.dec, l, b);
}
- else if (m_settings.m_target == "Custom Az/El")
+ else if ((m_settings.m_target == "Custom Az/El") || m_settings.m_target.contains("SatelliteTracker"))
{
// Convert Alt/Az to RA/Dec
aa.alt = m_settings.m_el;