1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 17:58:43 -05:00

Merge pull request #1694 from srcejon/fix_1682

Reimplement Doppler correction in Sat Tracker
This commit is contained in:
Edouard Griffiths 2023-05-21 11:54:51 +02:00 committed by GitHub
commit 11bc050b67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 349 additions and 58 deletions

View File

@ -262,6 +262,7 @@ QColor AISDemodGUI::getColor(const QString& mmsi)
return QColor(m_categoryColors.value(category)); return QColor(m_categoryColors.value(category));
} }
qDebug() << "No color for " << category; qDebug() << "No color for " << category;
return Qt::white;
} }
else else
{ {

View File

@ -66,7 +66,7 @@ void AISDemodSink::sampleToScope(Complex sample, Real magsq, Real fmDemod, Real
if (m_scopeSink) if (m_scopeSink)
{ {
m_sampleBuffer[0][m_sampleBufferIndex] = sample; m_sampleBuffer[0][m_sampleBufferIndex] = sample;
m_sampleBuffer[1][m_sampleBufferIndex] = Complex(m_magsq, 0.0f); m_sampleBuffer[1][m_sampleBufferIndex] = Complex(magsq, 0.0f);
m_sampleBuffer[2][m_sampleBufferIndex] = Complex(fmDemod, 0.0f); m_sampleBuffer[2][m_sampleBufferIndex] = Complex(fmDemod, 0.0f);
m_sampleBuffer[3][m_sampleBufferIndex] = Complex(filt, 0.0f); m_sampleBuffer[3][m_sampleBufferIndex] = Complex(filt, 0.0f);
m_sampleBuffer[4][m_sampleBufferIndex] = Complex(rxBuf, 0.0f); m_sampleBuffer[4][m_sampleBufferIndex] = Complex(rxBuf, 0.0f);

View File

@ -509,6 +509,8 @@ void SatelliteTracker::webapiFormatFeatureSettings(
response.getSatelliteTrackerSettings()->setPassStartTime(new QString(settings.m_passStartTime.toString())); response.getSatelliteTrackerSettings()->setPassStartTime(new QString(settings.m_passStartTime.toString()));
response.getSatelliteTrackerSettings()->setPassFinishTime(new QString(settings.m_passFinishTime.toString())); response.getSatelliteTrackerSettings()->setPassFinishTime(new QString(settings.m_passFinishTime.toString()));
response.getSatelliteTrackerSettings()->setDeviceSettings(getSWGSatelliteDeviceSettingsList(settings)); response.getSatelliteTrackerSettings()->setDeviceSettings(getSWGSatelliteDeviceSettingsList(settings));
response.getSatelliteTrackerSettings()->setAzimuthOffset(settings.m_azimuthOffset);
response.getSatelliteTrackerSettings()->setElevationOffset(settings.m_elevationOffset);
if (response.getSatelliteTrackerSettings()->getTitle()) { if (response.getSatelliteTrackerSettings()->getTitle()) {
*response.getSatelliteTrackerSettings()->getTitle() = settings.m_title; *response.getSatelliteTrackerSettings()->getTitle() = settings.m_title;
@ -633,6 +635,12 @@ void SatelliteTracker::webapiUpdateFeatureSettings(
if (featureSettingsKeys.contains("deviceSettings")) { if (featureSettingsKeys.contains("deviceSettings")) {
settings.m_deviceSettings = getSatelliteDeviceSettings(response.getSatelliteTrackerSettings()->getDeviceSettings()); settings.m_deviceSettings = getSatelliteDeviceSettings(response.getSatelliteTrackerSettings()->getDeviceSettings());
} }
if (featureSettingsKeys.contains("azimuthOffset")) {
settings.m_azimuthOffset = response.getSatelliteTrackerSettings()->getAzimuthOffset();
}
if (featureSettingsKeys.contains("elevationOffset")) {
settings.m_elevationOffset = response.getSatelliteTrackerSettings()->getElevationOffset();
}
if (featureSettingsKeys.contains("title")) { if (featureSettingsKeys.contains("title")) {
settings.m_title = *response.getSatelliteTrackerSettings()->getTitle(); settings.m_title = *response.getSatelliteTrackerSettings()->getTitle();
} }
@ -745,6 +753,12 @@ void SatelliteTracker::webapiReverseSendSettings(const QList<QString>& featureSe
if (featureSettingsKeys.contains("deviceSettings") || force) { if (featureSettingsKeys.contains("deviceSettings") || force) {
swgSatelliteTrackerSettings->setDeviceSettings(getSWGSatelliteDeviceSettingsList(settings)); swgSatelliteTrackerSettings->setDeviceSettings(getSWGSatelliteDeviceSettingsList(settings));
} }
if (featureSettingsKeys.contains("azimuthOffset") || force) {
swgSatelliteTrackerSettings->setAzimuthOffset(settings.m_azimuthOffset);
}
if (featureSettingsKeys.contains("elevationOffset") || force) {
swgSatelliteTrackerSettings->setElevationOffset(settings.m_elevationOffset);
}
if (featureSettingsKeys.contains("title") || force) { if (featureSettingsKeys.contains("title") || force) {
swgSatelliteTrackerSettings->setTitle(new QString(settings.m_title)); swgSatelliteTrackerSettings->setTitle(new QString(settings.m_title));
} }
@ -804,6 +818,11 @@ void SatelliteTracker::webapiFormatFeatureReport(SWGSDRangel::SWGFeatureReport&
} }
swgSatState->setPasses(passesList); swgSatState->setPasses(passesList);
list->append(swgSatState); list->append(swgSatState);
if (satState->m_name == m_settings.m_target)
{
response.getSatelliteTrackerReport()->setTargetAzimuth(satState->m_azimuth);
response.getSatelliteTrackerReport()->setTargetElevation(satState->m_elevation);
}
} }
} }

View File

@ -948,7 +948,7 @@ void SatelliteTrackerGUI::plotPolarChart()
// Plot rotator position // Plot rotator position
QString ourSourceName = QString("F0:%1 %2").arg(m_satelliteTracker->getIndexInFeatureSet()).arg(m_satelliteTracker->getIdentifier()); // Only one feature set in practice? 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(); std::vector<FeatureSet*>& featureSets = MainCore::instance()->getFeatureeSets();
for (int featureSetIndex = 0; featureSetIndex < featureSets.size(); featureSetIndex++) for (int featureSetIndex = 0; featureSetIndex < (int)featureSets.size(); featureSetIndex++)
{ {
FeatureSet *featureSet = featureSets[featureSetIndex]; FeatureSet *featureSet = featureSets[featureSetIndex];
for (int featureIndex = 0; featureIndex < featureSet->getNumberOfFeatures(); featureIndex++) for (int featureIndex = 0; featureIndex < featureSet->getNumberOfFeatures(); featureIndex++)

View File

@ -26,7 +26,7 @@
#include "satellitetrackersettings.h" #include "satellitetrackersettings.h"
#define DEAFULT_TARGET "ISS" #define DEAFULT_TARGET "ISS"
#define DEFAULT_TLES {"https://db.satnogs.org/api/tle/", "https://www.amsat.org/tle/current/nasabare.txt", "https://www.celestrak.com/NORAD/elements/goes.txt"} #define DEFAULT_TLES {"https://db.satnogs.org/api/tle/", "https://www.amsat.org/tle/current/nasabare.txt", "https://www.celestrak.com/NORAD/elements/goes.txt", "https://celestrak.org/NORAD/elements/gp.php?GROUP=gps-ops&FORMAT=tle"}
#define DEFAULT_DATE_FORMAT "yyyy/MM/dd" #define DEFAULT_DATE_FORMAT "yyyy/MM/dd"
#define DEFAULT_AOS_SPEECH "${name} is visible for ${duration} minutes. Max elevation, ${elevation} degrees." #define DEFAULT_AOS_SPEECH "${name} is visible for ${duration} minutes. Max elevation, ${elevation} degrees."
#define DEFAULT_LOS_SPEECH "${name} is no longer visible." #define DEFAULT_LOS_SPEECH "${name} is no longer visible."
@ -80,6 +80,8 @@ void SatelliteTrackerSettings::resetToDefaults()
m_mapFeature = ""; m_mapFeature = "";
m_fileInputDevice = ""; m_fileInputDevice = "";
m_drawRotators = MATCHING_TARGET; m_drawRotators = MATCHING_TARGET;
m_azimuthOffset = 0.0;
m_elevationOffset = 0.0;
m_workspaceIndex = 0; m_workspaceIndex = 0;
m_columnSort = -1; m_columnSort = -1;
m_columnSortOrder = Qt::AscendingOrder; m_columnSortOrder = Qt::AscendingOrder;
@ -144,6 +146,8 @@ QByteArray SatelliteTrackerSettings::serialize() const
s.writeS32(47, m_columnSort); s.writeS32(47, m_columnSort);
s.writeS32(48, (int)m_columnSortOrder); s.writeS32(48, (int)m_columnSortOrder);
s.writeS32(49, (int)m_drawRotators); s.writeS32(49, (int)m_drawRotators);
s.writeDouble(50, m_azimuthOffset);
s.writeDouble(51, m_elevationOffset);
for (int i = 0; i < SAT_COL_COLUMNS; i++) { for (int i = 0; i < SAT_COL_COLUMNS; i++) {
s.writeS32(100 + i, m_columnIndexes[i]); s.writeS32(100 + i, m_columnIndexes[i]);
@ -240,6 +244,8 @@ bool SatelliteTrackerSettings::deserialize(const QByteArray& data)
d.readS32(47, &m_columnSort, -1); d.readS32(47, &m_columnSort, -1);
d.readS32(48, (int *)&m_columnSortOrder, (int)Qt::AscendingOrder); d.readS32(48, (int *)&m_columnSortOrder, (int)Qt::AscendingOrder);
d.readS32(49, (int*)&m_drawRotators, (int)MATCHING_TARGET); d.readS32(49, (int*)&m_drawRotators, (int)MATCHING_TARGET);
d.readDouble(50, &m_azimuthOffset, 0.0);
d.readDouble(51, &m_elevationOffset, 0.0);
for (int i = 0; i < SAT_COL_COLUMNS; i++) { for (int i = 0; i < SAT_COL_COLUMNS; i++) {
d.readS32(100 + i, &m_columnIndexes[i], i); d.readS32(100 + i, &m_columnIndexes[i], i);
@ -458,6 +464,12 @@ void SatelliteTrackerSettings::applySettings(const QStringList& settingsKeys, co
if (settingsKeys.contains("drawRotators")) { if (settingsKeys.contains("drawRotators")) {
m_drawRotators = settings.m_drawRotators; m_drawRotators = settings.m_drawRotators;
} }
if (settingsKeys.contains("azimuthOffset")) {
m_azimuthOffset = settings.m_azimuthOffset;
}
if (settingsKeys.contains("elevationOffset")) {
m_elevationOffset = settings.m_elevationOffset;
}
if (settingsKeys.contains("columnSort")) { if (settingsKeys.contains("columnSort")) {
m_columnSort = settings.m_columnSort; m_columnSort = settings.m_columnSort;
} }
@ -638,6 +650,12 @@ QString SatelliteTrackerSettings::getDebugString(const QStringList& settingsKeys
if (settingsKeys.contains("drawRotators") || force) { if (settingsKeys.contains("drawRotators") || force) {
ostr << " m_drawRotators: " << m_drawRotators; ostr << " m_drawRotators: " << m_drawRotators;
} }
if (settingsKeys.contains("azimuthOffset") || force) {
ostr << " m_azimuthOffset: " << m_azimuthOffset;
}
if (settingsKeys.contains("elevationOffset") || force) {
ostr << " m_elevationOffset: " << m_elevationOffset;
}
if (settingsKeys.contains("columnSort") || force) { if (settingsKeys.contains("columnSort") || force) {
ostr << " m_columnSort: " << m_columnSort; ostr << " m_columnSort: " << m_columnSort;
} }

View File

@ -85,6 +85,8 @@ struct SatelliteTrackerSettings
QString m_mapFeature; //!< Which feature when FROM_MAP QString m_mapFeature; //!< Which feature when FROM_MAP
QString m_fileInputDevice; //!< Which device when FROM_FILE 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 enum Rotators {ALL_ROTATORS, NO_ROTATORS, MATCHING_TARGET} m_drawRotators; //!< Which rotators to draw on polar chart
double m_azimuthOffset; //!< Offset to add to az/el sent to rotator
double m_elevationOffset;
int m_columnSort; //!< Which column is used for sorting (-1 for none) int m_columnSort; //!< Which column is used for sorting (-1 for none)
Qt::SortOrder m_columnSortOrder; Qt::SortOrder m_columnSortOrder;

View File

@ -35,6 +35,8 @@ SatelliteTrackerSettingsDialog::SatelliteTrackerSettingsDialog(SatelliteTrackerS
ui->losSpeech->setText(settings->m_losSpeech); ui->losSpeech->setText(settings->m_losSpeech);
ui->rotatorMaximumAzimuth->setValue(settings->m_rotatorMaxAzimuth); ui->rotatorMaximumAzimuth->setValue(settings->m_rotatorMaxAzimuth);
ui->rotatorMaximumElevation->setValue(settings->m_rotatorMaxElevation); ui->rotatorMaximumElevation->setValue(settings->m_rotatorMaxElevation);
ui->azimuthOffset->setValue(settings->m_azimuthOffset);
ui->elevationOffset->setValue(settings->m_elevationOffset);
ui->aosCommand->setText(settings->m_aosCommand); ui->aosCommand->setText(settings->m_aosCommand);
ui->losCommand->setText(settings->m_losCommand); ui->losCommand->setText(settings->m_losCommand);
ui->updatePeriod->setValue(settings->m_updatePeriod); ui->updatePeriod->setValue(settings->m_updatePeriod);
@ -86,6 +88,8 @@ void SatelliteTrackerSettingsDialog::accept()
m_settings->m_minPassElevation = ui->minimumPassElevation->value(); m_settings->m_minPassElevation = ui->minimumPassElevation->value();
m_settings->m_rotatorMaxAzimuth = ui->rotatorMaximumAzimuth->value(); m_settings->m_rotatorMaxAzimuth = ui->rotatorMaximumAzimuth->value();
m_settings->m_rotatorMaxElevation = ui->rotatorMaximumElevation->value(); m_settings->m_rotatorMaxElevation = ui->rotatorMaximumElevation->value();
m_settings->m_azimuthOffset = ui->azimuthOffset->value();
m_settings->m_elevationOffset = ui->elevationOffset->value();
m_settings->m_aosSpeech = ui->aosSpeech->text(); m_settings->m_aosSpeech = ui->aosSpeech->text();
m_settings->m_losSpeech = ui->losSpeech->text(); m_settings->m_losSpeech = ui->losSpeech->text();
m_settings->m_aosCommand = ui->aosCommand->text(); m_settings->m_aosCommand = ui->aosCommand->text();

View File

@ -179,70 +179,70 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0"> <item row="10" column="0">
<widget class="QLabel" name="aosSpeechLabel"> <widget class="QLabel" name="aosSpeechLabel">
<property name="text"> <property name="text">
<string>AOS speech warning</string> <string>AOS speech warning</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="10" column="1">
<widget class="QLineEdit" name="aosSpeech"> <widget class="QLineEdit" name="aosSpeech">
<property name="toolTip"> <property name="toolTip">
<string>Text to say when a satellite signal is acquired</string> <string>Text to say when a satellite signal is acquired</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="0"> <item row="11" column="0">
<widget class="QLabel" name="losSpeechLabel"> <widget class="QLabel" name="losSpeechLabel">
<property name="text"> <property name="text">
<string>LOS speech warning</string> <string>LOS speech warning</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="1"> <item row="11" column="1">
<widget class="QLineEdit" name="losSpeech"> <widget class="QLineEdit" name="losSpeech">
<property name="toolTip"> <property name="toolTip">
<string>Text to say when a satellite signal is lost</string> <string>Text to say when a satellite signal is lost</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="0"> <item row="12" column="0">
<widget class="QLabel" name="aosCommandLabel"> <widget class="QLabel" name="aosCommandLabel">
<property name="text"> <property name="text">
<string>AOS command</string> <string>AOS command</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="1"> <item row="12" column="1">
<widget class="QLineEdit" name="aosCommand"> <widget class="QLineEdit" name="aosCommand">
<property name="toolTip"> <property name="toolTip">
<string>Program / script to execute on AOS</string> <string>Program / script to execute on AOS</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="0"> <item row="13" column="0">
<widget class="QLabel" name="losCommandLabel"> <widget class="QLabel" name="losCommandLabel">
<property name="text"> <property name="text">
<string>LOS command</string> <string>LOS command</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="1"> <item row="13" column="1">
<widget class="QLineEdit" name="losCommand"> <widget class="QLineEdit" name="losCommand">
<property name="toolTip"> <property name="toolTip">
<string>Program / script to execute on LOS</string> <string>Program / script to execute on LOS</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="0"> <item row="14" column="0">
<widget class="QLabel" name="dopplerPeriodLabel"> <widget class="QLabel" name="dopplerPeriodLabel">
<property name="text"> <property name="text">
<string>Doppler period (s)</string> <string>Doppler period (s)</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="1"> <item row="14" column="1">
<widget class="QDoubleSpinBox" name="dopplerPeriod"> <widget class="QDoubleSpinBox" name="dopplerPeriod">
<property name="toolTip"> <property name="toolTip">
<string>Enter the time in seconds between each Doppler correction</string> <string>Enter the time in seconds between each Doppler correction</string>
@ -258,7 +258,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="0"> <item row="15" column="0">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
@ -278,6 +278,52 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1">
<widget class="QDoubleSpinBox" name="azimuthOffset">
<property name="toolTip">
<string>Azimuth offset to add to target azimuth sent to rotator controller in degrees</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QDoubleSpinBox" name="elevationOffset">
<property name="toolTip">
<string>Elevation offset added to target elevation send to rotator controller in degrees</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-180.000000000000000</double>
</property>
<property name="maximum">
<double>180.000000000000000</double>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="azimuthOffsetLabel">
<property name="text">
<string>Rotator azimuth offset (°)</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="elevationOffsetLabel">
<property name="text">
<string>Rotator elevation offset (°)</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tleTab"> <widget class="QWidget" name="tleTab">

View File

@ -35,6 +35,7 @@
#include "util/units.h" #include "util/units.h"
#include "device/deviceset.h" #include "device/deviceset.h"
#include "device/deviceapi.h" #include "device/deviceapi.h"
#include "channel/channelapi.h"
#include "channel/channelwebapiutils.h" #include "channel/channelwebapiutils.h"
#include "feature/featurewebapiutils.h" #include "feature/featurewebapiutils.h"
#include "maincore.h" #include "maincore.h"
@ -223,6 +224,22 @@ void SatelliteTrackerWorker::applySettings(const SatelliteTrackerSettings& setti
} }
} }
if (settingsKeys.contains("target") && (settings.m_target != m_settings.m_target))
{
if (m_workerState.contains(m_settings.m_target))
{
SatWorkerState *satWorkerState = m_workerState.value(m_settings.m_target);
disableDoppler(satWorkerState);
}
if (m_workerState.contains(settings.m_target))
{
SatWorkerState *satWorkerState = m_workerState.value(settings.m_target);
if (satWorkerState->hasAOS(m_satelliteTracker->currentDateTimeUtc())) {
enableDoppler(satWorkerState);
}
}
}
if (force) { if (force) {
m_settings = settings; m_settings = settings;
} else { } else {
@ -427,8 +444,8 @@ void SatelliteTrackerWorker::update()
// Send Az/El of target to Rotator Controllers, if elevation above horizon // Send Az/El of target to Rotator Controllers, if elevation above horizon
if ((name == m_settings.m_target) && (satWorkerState->m_satState.m_elevation >= 0)) if ((name == m_settings.m_target) && (satWorkerState->m_satState.m_elevation >= 0))
{ {
double azimuth = satWorkerState->m_satState.m_azimuth; double azimuth = satWorkerState->m_satState.m_azimuth + m_settings.m_azimuthOffset;
double elevation = satWorkerState->m_satState.m_elevation; double elevation = satWorkerState->m_satState.m_elevation + m_settings.m_elevationOffset;
if (m_extendedAzRotation) if (m_extendedAzRotation)
{ {
if (azimuth < 180.0) if (azimuth < 180.0)
@ -574,7 +591,7 @@ void SatelliteTrackerWorker::aos(SatWorkerState *satWorkerState)
{ {
// Stop doppler correction for current target // Stop doppler correction for current target
if (m_workerState.contains(m_settings.m_target)) if (m_workerState.contains(m_settings.m_target))
m_workerState.value(m_settings.m_target)->m_dopplerTimer.stop(); disableDoppler(m_workerState.value(m_settings.m_target));
qDebug() << "SatelliteTrackerWorker::aos - autoTarget setting " << satWorkerState->m_name; qDebug() << "SatelliteTrackerWorker::aos - autoTarget setting " << satWorkerState->m_name;
m_settings.m_target = satWorkerState->m_name; m_settings.m_target = satWorkerState->m_name;
@ -759,40 +776,7 @@ void SatelliteTrackerWorker::applyDeviceAOSSettings(const QString& name)
FeatureWebAPIUtils::satelliteAOS(name, satWorkerState->m_aos, satWorkerState->m_los); FeatureWebAPIUtils::satelliteAOS(name, satWorkerState->m_aos, satWorkerState->m_los);
// Start Doppler correction, if needed // Start Doppler correction, if needed
satWorkerState->m_initFrequencyOffset.clear(); enableDoppler(satWorkerState);
bool requiresDoppler = false;
for (int i = 0; i < m_deviceSettingsList->size(); i++)
{
SatelliteTrackerSettings::SatelliteDeviceSettings *devSettings = m_deviceSettingsList->at(i);
if (devSettings->m_doppler.size() > 0)
{
requiresDoppler = true;
for (int j = 0; j < devSettings->m_doppler.size(); j++)
{
int offset;
if (ChannelWebAPIUtils::getFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
{
satWorkerState->m_initFrequencyOffset.append(offset);
qDebug() << "SatelliteTrackerWorker::applyDeviceAOSSettings: Initial frequency offset: " << offset;
}
else
{
qDebug() << "SatelliteTrackerWorker::applyDeviceAOSSettings: Failed to get initial frequency offset";
satWorkerState->m_initFrequencyOffset.append(0);
}
}
}
}
if (requiresDoppler)
{
qDebug() << "SatelliteTrackerWorker::applyDeviceAOSSettings: requiresDoppler";
satWorkerState->m_dopplerTimer.setInterval(m_settings.m_dopplerPeriod * 1000);
satWorkerState->m_dopplerTimer.start();
connect(&satWorkerState->m_dopplerTimer, &QTimer::timeout, [this, satWorkerState]() {
doppler(satWorkerState);
});
}
// Start file sinks (need a little delay to ensure sample rate message has been handled in filerecord) // Start file sinks (need a little delay to ensure sample rate message has been handled in filerecord)
QTimer::singleShot(1000, [m_deviceSettingsList]() QTimer::singleShot(1000, [m_deviceSettingsList]()
@ -824,6 +808,67 @@ void SatelliteTrackerWorker::applyDeviceAOSSettings(const QString& name)
} }
void SatelliteTrackerWorker::enableDoppler(SatWorkerState *satWorkerState)
{
QList<SatelliteTrackerSettings::SatelliteDeviceSettings *> *m_deviceSettingsList = m_settings.m_deviceSettings.value(satWorkerState->m_name);
satWorkerState->m_doppler.clear();
bool requiresDoppler = false;
for (int i = 0; i < m_deviceSettingsList->size(); i++)
{
SatelliteTrackerSettings::SatelliteDeviceSettings *devSettings = m_deviceSettingsList->at(i);
if (devSettings->m_doppler.size() > 0)
{
requiresDoppler = true;
for (int j = 0; j < devSettings->m_doppler.size(); j++) {
satWorkerState->m_doppler.append(0);
}
}
}
if (requiresDoppler)
{
qDebug() << "SatelliteTrackerWorker::applyDeviceAOSSettings: Enabling doppler for " << satWorkerState->m_name;
satWorkerState->m_dopplerTimer.setInterval(m_settings.m_dopplerPeriod * 1000);
satWorkerState->m_dopplerTimer.start();
connect(&satWorkerState->m_dopplerTimer, &QTimer::timeout, [this, satWorkerState]() {
doppler(satWorkerState);
});
}
}
void SatelliteTrackerWorker::disableDoppler(SatWorkerState *satWorkerState)
{
// Stop Doppler timer, and set interval to 0, so we don't restart it in start()
satWorkerState->m_dopplerTimer.stop();
satWorkerState->m_dopplerTimer.setInterval(0);
// Remove doppler correction from any channel
QList<SatelliteTrackerSettings::SatelliteDeviceSettings *> *m_deviceSettingsList = m_settings.m_deviceSettings.value(satWorkerState->m_name);
if (m_deviceSettingsList)
{
for (int i = 0; i < m_deviceSettingsList->size(); i++)
{
SatelliteTrackerSettings::SatelliteDeviceSettings *devSettings = m_deviceSettingsList->at(i);
if (devSettings->m_doppler.size() > 0)
{
for (int j = 0; j < devSettings->m_doppler.size(); j++)
{
int offset;
if (ChannelWebAPIUtils::getFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
{
// Remove old doppler
offset += satWorkerState->m_doppler[i];
if (!ChannelWebAPIUtils::setFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
qDebug() << "SatelliteTrackerWorker::doppler: Failed to set frequency offset";
}
else
qDebug() << "SatelliteTrackerWorker::doppler: Failed to get frequency offset";
}
satWorkerState->m_doppler[i] = 0;
}
}
}
}
void SatelliteTrackerWorker::doppler(SatWorkerState *satWorkerState) void SatelliteTrackerWorker::doppler(SatWorkerState *satWorkerState)
{ {
qDebug() << "SatelliteTrackerWorker::doppler " << satWorkerState->m_name; qDebug() << "SatelliteTrackerWorker::doppler " << satWorkerState->m_name;
@ -844,15 +889,42 @@ void SatelliteTrackerWorker::doppler(SatWorkerState *satWorkerState)
// Calculate frequency delta due to Doppler // Calculate frequency delta due to Doppler
double c = 299792458.0; double c = 299792458.0;
double deltaF = centerFrequency * satWorkerState->m_satState.m_rangeRate * 1000.0 / c; double deltaF = centerFrequency * satWorkerState->m_satState.m_rangeRate * 1000.0 / c;
int doppler = (int)round(deltaF);
for (int j = 0; j < devSettings->m_doppler.size(); j++) for (int j = 0; j < devSettings->m_doppler.size(); j++)
{ {
// For receive, we subtract, transmit we add int offset;
int offset = satWorkerState->m_initFrequencyOffset[i] - (int)round(deltaF); if (ChannelWebAPIUtils::getFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
{
// Apply doppler - For receive, we subtract, transmit we add
std::vector<DeviceSet*>& deviceSets = MainCore::instance()->getDeviceSets();
ChannelAPI *channel = deviceSets[devSettings->m_deviceSetIndex]->getChannelAt(j);
int tx = false;
if (channel) {
tx = channel->getStreamType() == ChannelAPI::StreamSingleSource; // What if MIMO?
}
// Remove old doppler and apply new
int initOffset;
if (tx)
{
initOffset = offset - satWorkerState->m_doppler[i];
offset = initOffset + doppler;
}
else
{
initOffset = offset + satWorkerState->m_doppler[i];
offset = initOffset - doppler;
}
if (!ChannelWebAPIUtils::setFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset)) if (!ChannelWebAPIUtils::setFrequencyOffset(devSettings->m_deviceSetIndex, devSettings->m_doppler[j], offset))
qDebug() << "SatelliteTrackerWorker::doppler: Failed to set frequency offset"; qDebug() << "SatelliteTrackerWorker::doppler: Failed to set frequency offset";
} }
else
qDebug() << "SatelliteTrackerWorker::doppler: Failed to get frequency offset";
}
satWorkerState->m_doppler[i] = doppler;
} }
else else
qDebug() << "SatelliteTrackerWorker::doppler: couldn't get centre frequency for device at " << devSettings->m_deviceSetIndex; qDebug() << "SatelliteTrackerWorker::doppler: couldn't get centre frequency for device at " << devSettings->m_deviceSetIndex;
@ -872,9 +944,7 @@ void SatelliteTrackerWorker::los(SatWorkerState *satWorkerState)
getMessageQueueToGUI()->push(SatelliteTrackerReport::MsgReportLOS::create(satWorkerState->m_name, speech)); getMessageQueueToGUI()->push(SatelliteTrackerReport::MsgReportLOS::create(satWorkerState->m_name, speech));
} }
// Stop Doppler timer, and set interval to 0, so we don't restart it in start() disableDoppler(satWorkerState);
satWorkerState->m_dopplerTimer.stop();
satWorkerState->m_dopplerTimer.setInterval(0);
if (m_settings.m_target == satWorkerState->m_name) if (m_settings.m_target == satWorkerState->m_name)
{ {

View File

@ -60,6 +60,7 @@ protected:
QTimer m_losTimer; QTimer m_losTimer;
QTimer m_dopplerTimer; QTimer m_dopplerTimer;
QList<int> m_initFrequencyOffset; QList<int> m_initFrequencyOffset;
QList<int> m_doppler; // How much doppler we've applied to a channel
SatelliteState m_satState; SatelliteState m_satState;
bool m_hasSignalledAOS; // For pass specified by m_aos and m_los bool m_hasSignalledAOS; // For pass specified by m_aos and m_los
@ -145,6 +146,8 @@ private:
void calculateRotation(SatWorkerState *satWorkerState); void calculateRotation(SatWorkerState *satWorkerState);
QString substituteVariables(const QString &textIn, const QString &satelliteName); QString substituteVariables(const QString &textIn, const QString &satelliteName);
void executeCommand(const QString &command, const QString &satelliteName); void executeCommand(const QString &command, const QString &satelliteName);
void enableDoppler(SatWorkerState *satWorkerState);
void disableDoppler(SatWorkerState *satWorkerState);
private slots: private slots:
void stopWork(); void stopWork();

View File

@ -97,6 +97,12 @@ SatelliteTrackerSettings:
type: array type: array
items: items:
$ref: "http://swgserver:8081/api/swagger/include/SatelliteTracker.yaml#/SatelliteDeviceSettingsList" $ref: "http://swgserver:8081/api/swagger/include/SatelliteTracker.yaml#/SatelliteDeviceSettingsList"
azimuthOffset:
type: number
format: float
elevationOffset:
type: number
format: float
title: title:
type: string type: string
rgbColor: rgbColor:
@ -179,6 +185,12 @@ SatelliteTrackerReport:
* 1 - idle * 1 - idle
* 2 - running * 2 - running
* 3 - error * 3 - error
targetAzimuth:
type: number
format: float
targetElevation:
type: number
format: float
satelliteState: satelliteState:
type: array type: array
items: items:

View File

@ -30,6 +30,10 @@ SWGSatelliteTrackerReport::SWGSatelliteTrackerReport(QString* json) {
SWGSatelliteTrackerReport::SWGSatelliteTrackerReport() { SWGSatelliteTrackerReport::SWGSatelliteTrackerReport() {
running_state = 0; running_state = 0;
m_running_state_isSet = false; m_running_state_isSet = false;
target_azimuth = 0.0f;
m_target_azimuth_isSet = false;
target_elevation = 0.0f;
m_target_elevation_isSet = false;
satellite_state = nullptr; satellite_state = nullptr;
m_satellite_state_isSet = false; m_satellite_state_isSet = false;
} }
@ -42,6 +46,10 @@ void
SWGSatelliteTrackerReport::init() { SWGSatelliteTrackerReport::init() {
running_state = 0; running_state = 0;
m_running_state_isSet = false; m_running_state_isSet = false;
target_azimuth = 0.0f;
m_target_azimuth_isSet = false;
target_elevation = 0.0f;
m_target_elevation_isSet = false;
satellite_state = new QList<SWGSatelliteState*>(); satellite_state = new QList<SWGSatelliteState*>();
m_satellite_state_isSet = false; m_satellite_state_isSet = false;
} }
@ -49,6 +57,8 @@ SWGSatelliteTrackerReport::init() {
void void
SWGSatelliteTrackerReport::cleanup() { SWGSatelliteTrackerReport::cleanup() {
if(satellite_state != nullptr) { if(satellite_state != nullptr) {
auto arr = satellite_state; auto arr = satellite_state;
for(auto o: *arr) { for(auto o: *arr) {
@ -71,6 +81,10 @@ void
SWGSatelliteTrackerReport::fromJsonObject(QJsonObject &pJson) { SWGSatelliteTrackerReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&running_state, pJson["runningState"], "qint32", ""); ::SWGSDRangel::setValue(&running_state, pJson["runningState"], "qint32", "");
::SWGSDRangel::setValue(&target_azimuth, pJson["targetAzimuth"], "float", "");
::SWGSDRangel::setValue(&target_elevation, pJson["targetElevation"], "float", "");
::SWGSDRangel::setValue(&satellite_state, pJson["satelliteState"], "QList", "SWGSatelliteState"); ::SWGSDRangel::setValue(&satellite_state, pJson["satelliteState"], "QList", "SWGSatelliteState");
} }
@ -92,6 +106,12 @@ SWGSatelliteTrackerReport::asJsonObject() {
if(m_running_state_isSet){ if(m_running_state_isSet){
obj->insert("runningState", QJsonValue(running_state)); obj->insert("runningState", QJsonValue(running_state));
} }
if(m_target_azimuth_isSet){
obj->insert("targetAzimuth", QJsonValue(target_azimuth));
}
if(m_target_elevation_isSet){
obj->insert("targetElevation", QJsonValue(target_elevation));
}
if(satellite_state && satellite_state->size() > 0){ if(satellite_state && satellite_state->size() > 0){
toJsonArray((QList<void*>*)satellite_state, obj, "satelliteState", "SWGSatelliteState"); toJsonArray((QList<void*>*)satellite_state, obj, "satelliteState", "SWGSatelliteState");
} }
@ -109,6 +129,26 @@ SWGSatelliteTrackerReport::setRunningState(qint32 running_state) {
this->m_running_state_isSet = true; this->m_running_state_isSet = true;
} }
float
SWGSatelliteTrackerReport::getTargetAzimuth() {
return target_azimuth;
}
void
SWGSatelliteTrackerReport::setTargetAzimuth(float target_azimuth) {
this->target_azimuth = target_azimuth;
this->m_target_azimuth_isSet = true;
}
float
SWGSatelliteTrackerReport::getTargetElevation() {
return target_elevation;
}
void
SWGSatelliteTrackerReport::setTargetElevation(float target_elevation) {
this->target_elevation = target_elevation;
this->m_target_elevation_isSet = true;
}
QList<SWGSatelliteState*>* QList<SWGSatelliteState*>*
SWGSatelliteTrackerReport::getSatelliteState() { SWGSatelliteTrackerReport::getSatelliteState() {
return satellite_state; return satellite_state;
@ -127,6 +167,12 @@ SWGSatelliteTrackerReport::isSet(){
if(m_running_state_isSet){ if(m_running_state_isSet){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }
if(m_target_azimuth_isSet){
isObjectUpdated = true; break;
}
if(m_target_elevation_isSet){
isObjectUpdated = true; break;
}
if(satellite_state && (satellite_state->size() > 0)){ if(satellite_state && (satellite_state->size() > 0)){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }

View File

@ -46,6 +46,12 @@ public:
qint32 getRunningState(); qint32 getRunningState();
void setRunningState(qint32 running_state); void setRunningState(qint32 running_state);
float getTargetAzimuth();
void setTargetAzimuth(float target_azimuth);
float getTargetElevation();
void setTargetElevation(float target_elevation);
QList<SWGSatelliteState*>* getSatelliteState(); QList<SWGSatelliteState*>* getSatelliteState();
void setSatelliteState(QList<SWGSatelliteState*>* satellite_state); void setSatelliteState(QList<SWGSatelliteState*>* satellite_state);
@ -56,6 +62,12 @@ private:
qint32 running_state; qint32 running_state;
bool m_running_state_isSet; bool m_running_state_isSet;
float target_azimuth;
bool m_target_azimuth_isSet;
float target_elevation;
bool m_target_elevation_isSet;
QList<SWGSatelliteState*>* satellite_state; QList<SWGSatelliteState*>* satellite_state;
bool m_satellite_state_isSet; bool m_satellite_state_isSet;

View File

@ -84,6 +84,10 @@ SWGSatelliteTrackerSettings::SWGSatelliteTrackerSettings() {
m_los_command_isSet = false; m_los_command_isSet = false;
device_settings = nullptr; device_settings = nullptr;
m_device_settings_isSet = false; m_device_settings_isSet = false;
azimuth_offset = 0.0f;
m_azimuth_offset_isSet = false;
elevation_offset = 0.0f;
m_elevation_offset_isSet = false;
title = nullptr; title = nullptr;
m_title_isSet = false; m_title_isSet = false;
rgb_color = 0; rgb_color = 0;
@ -164,6 +168,10 @@ SWGSatelliteTrackerSettings::init() {
m_los_command_isSet = false; m_los_command_isSet = false;
device_settings = new QList<SWGSatelliteDeviceSettingsList*>(); device_settings = new QList<SWGSatelliteDeviceSettingsList*>();
m_device_settings_isSet = false; m_device_settings_isSet = false;
azimuth_offset = 0.0f;
m_azimuth_offset_isSet = false;
elevation_offset = 0.0f;
m_elevation_offset_isSet = false;
title = new QString(""); title = new QString("");
m_title_isSet = false; m_title_isSet = false;
rgb_color = 0; rgb_color = 0;
@ -248,6 +256,8 @@ SWGSatelliteTrackerSettings::cleanup() {
} }
delete device_settings; delete device_settings;
} }
if(title != nullptr) { if(title != nullptr) {
delete title; delete title;
} }
@ -331,6 +341,10 @@ SWGSatelliteTrackerSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&device_settings, pJson["deviceSettings"], "QList", "SWGSatelliteDeviceSettingsList"); ::SWGSDRangel::setValue(&device_settings, pJson["deviceSettings"], "QList", "SWGSatelliteDeviceSettingsList");
::SWGSDRangel::setValue(&azimuth_offset, pJson["azimuthOffset"], "float", "");
::SWGSDRangel::setValue(&elevation_offset, pJson["elevationOffset"], "float", "");
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString"); ::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", ""); ::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
@ -447,6 +461,12 @@ SWGSatelliteTrackerSettings::asJsonObject() {
if(device_settings && device_settings->size() > 0){ if(device_settings && device_settings->size() > 0){
toJsonArray((QList<void*>*)device_settings, obj, "deviceSettings", "SWGSatelliteDeviceSettingsList"); toJsonArray((QList<void*>*)device_settings, obj, "deviceSettings", "SWGSatelliteDeviceSettingsList");
} }
if(m_azimuth_offset_isSet){
obj->insert("azimuthOffset", QJsonValue(azimuth_offset));
}
if(m_elevation_offset_isSet){
obj->insert("elevationOffset", QJsonValue(elevation_offset));
}
if(title != nullptr && *title != QString("")){ if(title != nullptr && *title != QString("")){
toJsonValue(QString("title"), title, obj, QString("QString")); toJsonValue(QString("title"), title, obj, QString("QString"));
} }
@ -755,6 +775,26 @@ SWGSatelliteTrackerSettings::setDeviceSettings(QList<SWGSatelliteDeviceSettingsL
this->m_device_settings_isSet = true; this->m_device_settings_isSet = true;
} }
float
SWGSatelliteTrackerSettings::getAzimuthOffset() {
return azimuth_offset;
}
void
SWGSatelliteTrackerSettings::setAzimuthOffset(float azimuth_offset) {
this->azimuth_offset = azimuth_offset;
this->m_azimuth_offset_isSet = true;
}
float
SWGSatelliteTrackerSettings::getElevationOffset() {
return elevation_offset;
}
void
SWGSatelliteTrackerSettings::setElevationOffset(float elevation_offset) {
this->elevation_offset = elevation_offset;
this->m_elevation_offset_isSet = true;
}
QString* QString*
SWGSatelliteTrackerSettings::getTitle() { SWGSatelliteTrackerSettings::getTitle() {
return title; return title;
@ -924,6 +964,12 @@ SWGSatelliteTrackerSettings::isSet(){
if(device_settings && (device_settings->size() > 0)){ if(device_settings && (device_settings->size() > 0)){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }
if(m_azimuth_offset_isSet){
isObjectUpdated = true; break;
}
if(m_elevation_offset_isSet){
isObjectUpdated = true; break;
}
if(title && *title != QString("")){ if(title && *title != QString("")){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }

View File

@ -129,6 +129,12 @@ public:
QList<SWGSatelliteDeviceSettingsList*>* getDeviceSettings(); QList<SWGSatelliteDeviceSettingsList*>* getDeviceSettings();
void setDeviceSettings(QList<SWGSatelliteDeviceSettingsList*>* device_settings); void setDeviceSettings(QList<SWGSatelliteDeviceSettingsList*>* device_settings);
float getAzimuthOffset();
void setAzimuthOffset(float azimuth_offset);
float getElevationOffset();
void setElevationOffset(float elevation_offset);
QString* getTitle(); QString* getTitle();
void setTitle(QString* title); void setTitle(QString* title);
@ -241,6 +247,12 @@ private:
QList<SWGSatelliteDeviceSettingsList*>* device_settings; QList<SWGSatelliteDeviceSettingsList*>* device_settings;
bool m_device_settings_isSet; bool m_device_settings_isSet;
float azimuth_offset;
bool m_azimuth_offset_isSet;
float elevation_offset;
bool m_elevation_offset_isSet;
QString* title; QString* title;
bool m_title_isSet; bool m_title_isSet;