Skip to content

Commit

Permalink
Merge pull request #1664 from srcejon/ais_slot
Browse files Browse the repository at this point in the history
AIS Demod: Calculate time slot used for messages.
  • Loading branch information
f4exb authored Apr 18, 2023
2 parents e687b3b + 7db8c35 commit c09f404
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 23 deletions.
5 changes: 3 additions & 2 deletions plugins/channelrx/demodais/aisdemod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ bool AISDemod::handleMessage(const Message& cmd)
<< QString("%1").arg(ais->m_mmsi, 9, 10, QChar('0')) << ","
<< ais->getType() << ","
<< "\"" << ais->toString() << "\"" << ","
<< "\"" << ais->toNMEA() << "\"" << "\n";
<< "\"" << ais->toNMEA() << "\"" << ","
<< report.getSlot() << "\n";

delete ais;
}
Expand Down Expand Up @@ -354,7 +355,7 @@ void AISDemod::applySettings(const AISDemodSettings& settings, bool force)
if (newFile)
{
// Write header
m_logStream << "Date,Time,Data,MMSI,Type,Message,NMEA\n";
m_logStream << "Date,Time,Data,MMSI,Type,Message,NMEA,Slot\n";
}
}
else
Expand Down
11 changes: 7 additions & 4 deletions plugins/channelrx/demodais/aisdemod.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,23 @@ class AISDemod : public BasebandSampleSink, public ChannelAPI {
public:
QByteArray getMessage() const { return m_message; }
QDateTime getDateTime() const { return m_dateTime; }
int getSlot() const { return m_slot; }

static MsgMessage* create(QByteArray message)
static MsgMessage* create(QByteArray message, QDateTime dateTime, int slot)
{
return new MsgMessage(message, QDateTime::currentDateTime());
return new MsgMessage(message, dateTime, slot);
}

private:
QByteArray m_message;
QDateTime m_dateTime;
int m_slot;

MsgMessage(QByteArray message, QDateTime dateTime) :
MsgMessage(QByteArray message, QDateTime dateTime, int slot) :
Message(),
m_message(message),
m_dateTime(dateTime)
m_dateTime(dateTime),
m_slot(slot)
{
}
};
Expand Down
16 changes: 11 additions & 5 deletions plugins/channelrx/demodais/aisdemodgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void AISDemodGUI::resizeTable()
ui->messages->setItem(row, MESSAGE_COL_DATA, new QTableWidgetItem("ABCEDGHIJKLMNOPQRSTUVWXYZ"));
ui->messages->setItem(row, MESSAGE_COL_NMEA, new QTableWidgetItem("!AIVDM,1,1,,A,AAAAAAAAAAAAAAAAAAAAAAAAAAAA,0*00"));
ui->messages->setItem(row, MESSAGE_COL_HEX, new QTableWidgetItem("04058804002000069a0760728d9e00000040000000"));
ui->messages->setItem(row, MESSAGE_COL_SLOT, new QTableWidgetItem("2450"));
ui->messages->resizeColumnsToContents();
ui->messages->removeRow(row);
}
Expand Down Expand Up @@ -154,7 +155,7 @@ bool AISDemodGUI::deserialize(const QByteArray& data)
}

// Add row to table
void AISDemodGUI::messageReceived(const QByteArray& message, const QDateTime& dateTime)
void AISDemodGUI::messageReceived(const QByteArray& message, const QDateTime& dateTime, int slot)
{
AISMessage *ais;

Expand All @@ -177,20 +178,23 @@ void AISDemodGUI::messageReceived(const QByteArray& message, const QDateTime& da
QTableWidgetItem *dataItem = new QTableWidgetItem();
QTableWidgetItem *nmeaItem = new QTableWidgetItem();
QTableWidgetItem *hexItem = new QTableWidgetItem();
QTableWidgetItem *slotItem = new QTableWidgetItem();
ui->messages->setItem(row, MESSAGE_COL_DATE, dateItem);
ui->messages->setItem(row, MESSAGE_COL_TIME, timeItem);
ui->messages->setItem(row, MESSAGE_COL_MMSI, mmsiItem);
ui->messages->setItem(row, MESSAGE_COL_TYPE, typeItem);
ui->messages->setItem(row, MESSAGE_COL_DATA, dataItem);
ui->messages->setItem(row, MESSAGE_COL_NMEA, nmeaItem);
ui->messages->setItem(row, MESSAGE_COL_HEX, hexItem);
ui->messages->setItem(row, MESSAGE_COL_SLOT, slotItem);
dateItem->setText(dateTime.date().toString());
timeItem->setText(dateTime.time().toString());
mmsiItem->setText(QString("%1").arg(ais->m_mmsi, 9, 10, QChar('0')));
typeItem->setText(ais->getType());
dataItem->setText(ais->toString());
nmeaItem->setText(ais->toNMEA());
hexItem->setText(ais->toHex());
slotItem->setData(Qt::DisplayRole, slot);
ui->messages->setSortingEnabled(true);
if (scrollToBottom) {
ui->messages->scrollToBottom();
Expand All @@ -217,7 +221,7 @@ bool AISDemodGUI::handleMessage(const Message& message)
else if (AISDemod::MsgMessage::match(message))
{
AISDemod::MsgMessage& report = (AISDemod::MsgMessage&) message;
messageReceived(report.getMessage(), report.getDateTime());
messageReceived(report.getMessage(), report.getDateTime(), report.getSlot());
return true;
}
else if (DSPSignalNotification::match(message))
Expand Down Expand Up @@ -702,13 +706,14 @@ void AISDemodGUI::on_logOpen_clicked()
{
QTextStream in(&file);
QString error;
QHash<QString, int> colIndexes = CSV::readHeader(in, {"Date", "Time", "Data"}, error);
QHash<QString, int> colIndexes = CSV::readHeader(in, {"Date", "Time", "Data", "Slot"}, error);
if (error.isEmpty())
{
int dateCol = colIndexes.value("Date");
int timeCol = colIndexes.value("Time");
int dataCol = colIndexes.value("Data");
int maxCol = std::max({dateCol, timeCol, dataCol});
int slotCol = colIndexes.value("Slot");
int maxCol = std::max({dateCol, timeCol, dataCol, slotCol});

QMessageBox dialog(this);
dialog.setText("Reading messages");
Expand All @@ -730,9 +735,10 @@ void AISDemodGUI::on_logOpen_clicked()
QTime time = QTime::fromString(cols[timeCol]);
QDateTime dateTime(date, time);
QByteArray bytes = QByteArray::fromHex(cols[dataCol].toLatin1());
int slot = cols[slotCol].toInt();

// Add to table
messageReceived(bytes, dateTime);
messageReceived(bytes, dateTime, slot);

// Forward to AIS feature
for (const auto& pipe : aisPipes)
Expand Down
5 changes: 3 additions & 2 deletions plugins/channelrx/demodais/aisdemodgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public slots:
void blockApplySettings(bool block);
void applySettings(bool force = false);
void displaySettings();
void messageReceived(const QByteArray& message, const QDateTime& dateTime);
void messageReceived(const QByteArray& message, const QDateTime& dateTime, int slot);
bool handleMessage(const Message& message);
void makeUIConnections();
void updateAbsoluteCenterFrequency();
Expand All @@ -116,7 +116,8 @@ public slots:
MESSAGE_COL_TYPE,
MESSAGE_COL_DATA,
MESSAGE_COL_NMEA,
MESSAGE_COL_HEX
MESSAGE_COL_HEX,
MESSAGE_COL_SLOT
};

private slots:
Expand Down
24 changes: 16 additions & 8 deletions plugins/channelrx/demodais/aisdemodgui.ui
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,14 @@
<string>Packet data as hex</string>
</property>
</column>
<column>
<property name="text">
<string>Slot</string>
</property>
<property name="toolTip">
<string>Time slot</string>
</property>
</column>
</widget>
</item>
</layout>
Expand Down Expand Up @@ -917,21 +925,15 @@
</widget>
</widget>
<customwidgets>
<customwidget>
<class>RollupContents</class>
<extends>QWidget</extends>
<header>gui/rollupcontents.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
<customwidget>
<class>LevelMeterSignalDB</class>
<class>RollupContents</class>
<extends>QWidget</extends>
<header>gui/levelmeter.h</header>
<header>gui/rollupcontents.h</header>
<container>1</container>
</customwidget>
<customwidget>
Expand All @@ -940,6 +942,12 @@
<header>gui/valuedialz.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LevelMeterSignalDB</class>
<extends>QWidget</extends>
<header>gui/levelmeter.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GLScope</class>
<extends>QWidget</extends>
Expand Down
2 changes: 1 addition & 1 deletion plugins/channelrx/demodais/aisdemodsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
class Serializable;

// Number of columns in the tables
#define AISDEMOD_MESSAGE_COLUMNS 7
#define AISDEMOD_MESSAGE_COLUMNS 8

struct AISDemodSettings
{
Expand Down
12 changes: 11 additions & 1 deletion plugins/channelrx/demodais/aisdemodsink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ void AISDemodSink::processOneSample(Complex &ci)
int onesCount = 0;
int byteCount = 0;
int symbolPrev = 0;
int totalBitCount = 0; // Count of bits after start flag, before bit stuffing removal, including stop flag
for (int sampleIdx = 0; sampleIdx < m_rxBufLength; sampleIdx += m_samplesPerSymbol)
{
// Sum and slice
Expand Down Expand Up @@ -247,7 +248,14 @@ void AISDemodSink::processOneSample(Complex &ci)
//qDebug() << "RX: " << rxPacket.toHex();
if (getMessageQueueToChannel())
{
AISDemod::MsgMessage *msg = AISDemod::MsgMessage::create(rxPacket);
// Calculate slot number based on time of start of transmission
// This is unlikely to be accurate in absolute terms, given we don't know latency from SDR or buffering within SDRangel
// But can be used to get an idea of congestion
QDateTime currentTime = QDateTime::currentDateTime();
QDateTime startDateTime = currentTime.addMSecs(-(totalBitCount + 8 + 24 + 8) * (1000.0 / m_settings.m_baud)); // Add ramp up, preamble and start-flag
int ms = startDateTime.time().second() * 1000 + startDateTime.time().msec();
int slot = ms / 26.67; // 2250 slots per minute, 26ms per slot
AISDemod::MsgMessage *msg = AISDemod::MsgMessage::create(rxPacket, currentTime, slot);
getMessageQueueToChannel()->push(msg);
}

Expand All @@ -273,13 +281,15 @@ void AISDemodSink::processOneSample(Complex &ci)
bits = 0;
bitCount = 0;
byteCount = 0;
totalBitCount = 0;
}
}
onesCount = 0;
}

if (gotSOP)
{
totalBitCount++;
if (bitCount == 8)
{
// Could also check count according to message ID as that varies
Expand Down
1 change: 1 addition & 0 deletions plugins/channelrx/demodais/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,6 @@ The received messages table displays information about each AIS message received
* Data - A textual decode of the message displaying the most interesting fields.
* NMEA - The message in NMEA format.
* Hex - The message in hex format.
* Slot - Time slot (0-2249). Due to SDR to SDRangel latency being unknown, this is likely to have some offset.

Right clicking on the table header allows you to select which columns to show. The columns can be reorderd by left clicking and dragging the column header. Right clicking on an item in the table allows you to copy the value to the clipboard.

0 comments on commit c09f404

Please sign in to comment.