Skip to content

Commit

Permalink
Merge branch 'f4exb:master' into mac_ci
Browse files Browse the repository at this point in the history
  • Loading branch information
srcejon authored Jan 23, 2025
2 parents 6df8b94 + 19d8a1d commit d524bf2
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 13 deletions.
135 changes: 129 additions & 6 deletions plugins/feature/radiosonde/radiosondegui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ RadiosondeGUI::RadiosondeGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, F
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));

m_sondeHub = SondeHub::create();
if (m_sondeHub)
{
connect(m_sondeHub, &SondeHub::prediction, this, &RadiosondeGUI::handlePrediction);
connect(&m_predicitionTimer, &QTimer::timeout, this, &RadiosondeGUI::requestPredictions);
m_predicitionTimer.setInterval(60 * 1000);
m_predicitionTimer.setSingleShot(false);
}

// Initialise chart
ui->chart->setRenderHint(QPainter::Antialiasing);
Expand Down Expand Up @@ -257,12 +264,14 @@ void RadiosondeGUI::displaySettings()
ui->y2->setCurrentIndex((int)m_settings.m_y2);

ui->feed->setChecked(m_settings.m_feedEnabled);
ui->showPredictedPaths->setChecked(m_settings.m_showPredictedPaths);

getRollupContents()->restoreState(m_rollupState);
blockApplySettings(false);
getRollupContents()->arrangeRollups();

updatePosition();
applyShowPredictedPaths();
}

void RadiosondeGUI::onMenuDialogCalled(const QPoint &p)
Expand Down Expand Up @@ -673,6 +682,10 @@ void RadiosondeGUI::updateRadiosondes(RS41Frame *message, QDateTime dateTime)
MainCore::instance()->getSettings().getAltitude()
);
}

if (!found) {
requestPredictions();
}
}

void RadiosondeGUI::on_radiosondes_itemSelectionChanged()
Expand Down Expand Up @@ -908,16 +921,38 @@ void RadiosondeGUI::on_deleteAll_clicked()
{
QString serial = ui->radiosondes->item(row, RADIOSONDE_COL_SERIAL)->text();
// Remove from map
sendToMap(serial, "",
"", "",
"", 0.0f,
0.0f, 0.0f, 0.0f, QDateTime(),
0.0f);
clearFromMapFeature(serial, 0);
// Remove from table
ui->radiosondes->removeRow(row);
// Remove from hash and free memory
delete m_radiosondes.take(serial);
}
deletePredictedPaths();
}

void RadiosondeGUI::deletePredictedPaths()
{
for (const auto& prediction : m_predictions) {
clearFromMapFeature(prediction, 3);
}
m_predictions.clear();
}

void RadiosondeGUI::clearFromMapFeature(const QString& name, int type)
{
QList<ObjectPipe*> mapPipes;
MainCore::instance()->getMessagePipes().getMessagePipes(m_radiosonde, "mapitems", mapPipes);

for (const auto& pipe : mapPipes)
{
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
SWGSDRangel::SWGMapItem *swgMapItem = new SWGSDRangel::SWGMapItem();
swgMapItem->setName(new QString(name));
swgMapItem->setImage(new QString(""));
swgMapItem->setType(type);
MainCore::MsgMapItem *msg = MainCore::MsgMapItem::create(m_radiosonde, swgMapItem);
messageQueue->push(msg);
}
}

void RadiosondeGUI::makeUIConnections()
Expand All @@ -928,6 +963,7 @@ void RadiosondeGUI::makeUIConnections()
QObject::connect(ui->y2, qOverload<int>(&QComboBox::currentIndexChanged), this, &RadiosondeGUI::on_y2_currentIndexChanged);
QObject::connect(ui->deleteAll, &QPushButton::clicked, this, &RadiosondeGUI::on_deleteAll_clicked);
QObject::connect(ui->feed, &ButtonSwitch::clicked, this, &RadiosondeGUI::on_feed_clicked);
QObject::connect(ui->showPredictedPaths, &ButtonSwitch::clicked, this, &RadiosondeGUI::on_showPredictedPaths_clicked);
}

void RadiosondeGUI::on_feed_clicked(bool checked)
Expand Down Expand Up @@ -956,6 +992,28 @@ void RadiosondeGUI::feedSelect(const QPoint& p)
}
}

void RadiosondeGUI::on_showPredictedPaths_clicked(bool checked)
{
m_settings.m_showPredictedPaths = checked;
m_settingsKeys.append("showPredictedPaths");
applySettings();
applyShowPredictedPaths();
}

void RadiosondeGUI::applyShowPredictedPaths()
{
if (m_settings.m_showPredictedPaths)
{
requestPredictions();
m_predicitionTimer.start();
}
else
{
m_predicitionTimer.stop();
deletePredictedPaths();
}
}

// Get names of devices with radiosonde demods, for SondeHub Radio string
QStringList RadiosondeGUI::getRadios()
{
Expand All @@ -965,7 +1023,7 @@ QStringList RadiosondeGUI::getRadios()

for (const auto& channel : channels)
{
DeviceAPI *device = mainCore->getDevice(channel.m_index);
DeviceAPI *device = mainCore->getDevice(channel.m_superIndex);
if (device)
{
QString name = device->getHardwareId();
Expand Down Expand Up @@ -1019,6 +1077,71 @@ void RadiosondeGUI::updatePosition()
}
}

void RadiosondeGUI::requestPredictions()
{
if (m_sondeHub && m_settings.m_showPredictedPaths)
{
for (int row = 0; row < ui->radiosondes->rowCount(); row++)
{
QString serial = ui->radiosondes->item(row, RADIOSONDE_COL_SERIAL)->text();
m_sondeHub->getPrediction(serial);
}
}
}

void RadiosondeGUI::handlePrediction(const QString& serial, const QList<SondeHub::Position>& positions)
{
if (positions.size() < 2) {
return;
}

// Send to Map feature
QList<ObjectPipe*> mapPipes;
MainCore::instance()->getMessagePipes().getMessagePipes(m_radiosonde, "mapitems", mapPipes);

if (mapPipes.size() > 0)
{
QString name = QString("%1_prediction").arg(serial);

for (const auto& pipe : mapPipes)
{
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
SWGSDRangel::SWGMapItem *swgMapItem = new SWGSDRangel::SWGMapItem();

swgMapItem->setName(new QString(name));
swgMapItem->setLatitude(positions[0].m_latitude);
swgMapItem->setLongitude(positions[0].m_longitude);
swgMapItem->setAltitude(positions[0].m_altitude);
QString image = QString("none");
swgMapItem->setImage(new QString(image));
swgMapItem->setImageRotation(0);
swgMapItem->setFixedPosition(true);
swgMapItem->setLabel(new QString(serial));
swgMapItem->setAltitudeReference(0);
QList<SWGSDRangel::SWGMapCoordinate *> *coords = new QList<SWGSDRangel::SWGMapCoordinate *>();

for (const auto& position : positions)
{
SWGSDRangel::SWGMapCoordinate* c = new SWGSDRangel::SWGMapCoordinate();
c->setLatitude(position.m_latitude);
c->setLongitude(position.m_longitude);
c->setAltitude(position.m_altitude);
coords->append(c);
}

swgMapItem->setCoordinates(coords);
swgMapItem->setType(3);

MainCore::MsgMapItem *msg = MainCore::MsgMapItem::create(m_radiosonde, swgMapItem);
messageQueue->push(msg);

if (!m_predictions.contains(name)) {
m_predictions.append(name);
}
}
}
}

void RadiosondeGUI::preferenceChanged(int elementType)
{
Preferences::ElementType pref = (Preferences::ElementType)elementType;
Expand Down
9 changes: 9 additions & 0 deletions plugins/feature/radiosonde/radiosondegui.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ class RadiosondeGUI : public FeatureGUI {
static const int m_minMobilePositionUpdateTime = 30; // In seconds
static const int m_minFixedPositionUpdateTime = 5 * 60;

QTimer m_predicitionTimer;
QStringList m_predictions;

explicit RadiosondeGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
virtual ~RadiosondeGUI();

Expand All @@ -130,6 +133,9 @@ class RadiosondeGUI : public FeatureGUI {
float getData(RadiosondeSettings::ChartData dataType, RadiosondeData *radiosonde, RS41Frame *message);
void updatePosition();
QStringList getRadios();
void applyShowPredictedPaths();
void deletePredictedPaths();
void clearFromMapFeature(const QString& name, int type);

enum RadiosondeCol {
RADIOSONDE_COL_SERIAL,
Expand Down Expand Up @@ -168,6 +174,9 @@ private slots:
void on_deleteAll_clicked();
void on_feed_clicked(bool checked);
void feedSelect(const QPoint& p);
void on_showPredictedPaths_clicked(bool checked);
void requestPredictions();
void handlePrediction(const QString& serial, const QList<SondeHub::Position>& positions);
void preferenceChanged(int elementType);

};
Expand Down
27 changes: 22 additions & 5 deletions plugins/feature/radiosonde/radiosondegui.ui
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<string>Radiosonde</string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
<enum>Qt::LayoutDirection::LeftToRight</enum>
</property>
<widget class="QWidget" name="tableContainer" native="true">
<property name="geometry">
Expand Down Expand Up @@ -76,20 +76,20 @@
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<widget class="QTableWidget" name="radiosondes">
<property name="toolTip">
<string>Radiosondes</string>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
<enum>QAbstractItemView::SelectionMode::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
</property>
<column>
<property name="text">
Expand Down Expand Up @@ -416,6 +416,23 @@
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="showPredictedPaths">
<property name="toolTip">
<string>Show predicted paths on map</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/logarithmic.png</normaloff>:/logarithmic.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
Expand Down
9 changes: 9 additions & 0 deletions plugins/feature/radiosonde/radiosondesettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void RadiosondeSettings::resetToDefaults()
m_displayPosition = false;
m_mobile = false;
m_email = "";
m_showPredictedPaths = false;

for (int i = 0; i < RADIOSONDES_COLUMNS; i++)
{
Expand Down Expand Up @@ -95,6 +96,7 @@ QByteArray RadiosondeSettings::serialize() const
s.writeBool(17, m_displayPosition);
s.writeBool(18, m_mobile);
s.writeString(19, m_email);
s.writeBool(20, m_showPredictedPaths);


for (int i = 0; i < RADIOSONDES_COLUMNS; i++) {
Expand Down Expand Up @@ -159,6 +161,7 @@ bool RadiosondeSettings::deserialize(const QByteArray& data)
d.readBool(17, &m_displayPosition, false);
d.readBool(18, &m_mobile, false);
d.readString(19, &m_email, "");
d.readBool(20, &m_showPredictedPaths, false);

for (int i = 0; i < RADIOSONDES_COLUMNS; i++) {
d.readS32(300 + i, &m_radiosondesColumnIndexes[i], i);
Expand Down Expand Up @@ -224,6 +227,9 @@ void RadiosondeSettings::applySettings(const QStringList& settingsKeys, const Ra
if (settingsKeys.contains("email")) {
m_email = settings.m_email;
}
if (settingsKeys.contains("showPredictedPaths")) {
m_showPredictedPaths = settings.m_showPredictedPaths;
}
if (settingsKeys.contains("workspaceIndex")) {
m_workspaceIndex = settings.m_workspaceIndex;
}
Expand Down Expand Up @@ -292,6 +298,9 @@ QString RadiosondeSettings::getDebugString(const QStringList& settingsKeys, bool
if (settingsKeys.contains("email") || force) {
ostr << " m_email: " << m_email.toStdString();
}
if (settingsKeys.contains("showPredictedPaths") || force) {
ostr << " m_showPredictedPaths: " << m_showPredictedPaths;
}
if (settingsKeys.contains("workspaceIndex") || force) {
ostr << " m_workspaceIndex: " << m_workspaceIndex;
}
Expand Down
1 change: 1 addition & 0 deletions plugins/feature/radiosonde/radiosondesettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct RadiosondeSettings
bool m_displayPosition;
bool m_mobile;
QString m_email;
bool m_showPredictedPaths;

int m_radiosondesColumnIndexes[RADIOSONDES_COLUMNS];
int m_radiosondesColumnSizes[RADIOSONDES_COLUMNS];
Expand Down
3 changes: 2 additions & 1 deletion plugins/feature/radiosonde/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ based on data received via [Radiosonde Demodulators](../../channelrx/demodradios

The chart can plot two data series vs time for the radiosonde selected in the table.

The Radiosonde feature can draw balloons objects on the [Map](../../feature/map/readme.md) feature in 2D and 3D.
The Radiosonde feature can draw balloons objects and predicted paths on the [Map](../../feature/map/readme.md) feature in 2D and 3D.

Received data can be forwarded to [SondeHub](https://sondehub.org/). Your location can be displayed on the SondeHub map, as either a stationary receiver or chase car.

Expand Down Expand Up @@ -48,6 +48,7 @@ The Radiosonde feature can plot balloons (during ascent) and parachutes (during
To use, simply open a Map feature and the Radiosonde plugin will display objects based upon the data it receives from that point.
Selecting a radiosonde item on the map will display a text bubble containing information from the above table.
To centre the map on an item in the table, double click in the Lat or Lon columns.
Predicted paths can be displayed by checking the Show Predicted Paths button. The path is predicted by SondeHub.

![Radiosonde on map](../../../doc/img/Radiosonde_plugin_map.png)

Expand Down
Loading

0 comments on commit d524bf2

Please sign in to comment.