Star Tracker. Add support for tracking satellites. Fix settings keys.

This commit is contained in:
Jon Beniston 2023-05-23 22:32:26 +01:00
parent aba0e30a4f
commit 302c040515
9 changed files with 223 additions and 19 deletions

View File

@ -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.
<h3>Solar flux vs frequency</h3>
![Star Tracker Solar Flux](../../../doc/img/StarTracker_solarflux.png)

View File

@ -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<FeatureSet*>& 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;

View File

@ -106,6 +106,24 @@ public:
{ }
};
class MsgReportAvailableSatelliteTrackers : public Message {
MESSAGE_CLASS_DECLARATION
public:
QList<StarTrackerSettings::AvailableFeature>& getFeatures() { return m_availableFeatures; }
static MsgReportAvailableSatelliteTrackers* create() {
return new MsgReportAvailableSatelliteTrackers();
}
private:
QList<StarTrackerSettings::AvailableFeature> 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<ChannelAPI*> m_availableChannels;
QHash<Feature*, StarTrackerSettings::AvailableFeature> 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);
};

View File

@ -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<StarTrackerSettings::AvailableFeature>& 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("");
}

View File

@ -163,6 +163,7 @@ private:
void updateSolarFlux(bool all);
void makeUIConnections();
void limitAzElRange(double& azimuth, double& elevation) const;
void updateSatelliteTrackerList(const QList<StarTrackerSettings::AvailableFeature>& satelliteTrackers);
private slots:
void onMenuDialogCalled(const QPoint &p);

View File

@ -101,7 +101,7 @@
<string>Offset in degrees to add to calculated target elevation</string>
</property>
<property name="decimals">
<number>1</number>
<number>3</number>
</property>
<property name="minimum">
<double>-180.000000000000000</double>
@ -167,7 +167,7 @@
<widget class="QComboBox" name="target">
<property name="minimumSize">
<size>
<width>110</width>
<width>150</width>
<height>0</height>
</size>
</property>
@ -460,7 +460,7 @@ This can be specified as a decimal (E.g. 34.23) or in degrees, minutes and secon
<string>Offset in degrees to added to calculated target azimuth</string>
</property>
<property name="decimals">
<number>1</number>
<number>3</number>
</property>
<property name="minimum">
<double>-360.000000000000000</double>

View File

@ -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) {

View File

@ -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;

View File

@ -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;