[Simulator][TelemetrySimulator] Add persistent option to enable simulation when window is opened; Add option to pause simulation on window hide (was always true); Add option to set RSSI=0 on simulation pause to trigger “telemetry lost” alarm.

This commit is contained in:
Max Paperno
2018-07-06 14:03:41 -04:00
parent 5dd365238e
commit 23aaee9ecf
4 changed files with 431 additions and 367 deletions
+55 -28
View File
@@ -32,7 +32,6 @@ TelemetrySimulator::TelemetrySimulator(QWidget * parent, SimulatorInterface * si
ui(new Ui::TelemetrySimulator),
simulator(simulator),
m_simuStarted(false),
m_telemEnable(false),
m_logReplayEnable(false)
{
ui->setupUi(this);
@@ -48,6 +47,9 @@ TelemetrySimulator::TelemetrySimulator(QWidget * parent, SimulatorInterface * si
ui->A1_ratio->setEnabled(false);
ui->A2_ratio->setEnabled(false);
ui->Simulate->setChecked(g.currentProfile().telemSimEnabled());
ui->cbPauseOnHide->setChecked(g.currentProfile().telemSimPauseOnHide());
ui->cbResetRssiOnStop->setChecked(g.currentProfile().telemSimResetRssiOnStop());
timer.setInterval(10);
connect(&timer, &QTimer::timeout, this, &TelemetrySimulator::generateTelemetryFrame);
@@ -56,7 +58,12 @@ TelemetrySimulator::TelemetrySimulator(QWidget * parent, SimulatorInterface * si
logPlayback = new LogPlaybackController(ui);
connect(ui->Simulate, SIGNAL(toggled(bool)), this, SLOT(onSimulateToggled(bool)));
connect(ui->Simulate, &QCheckBox::toggled, &g.currentProfile(), [=](bool on) { g.currentProfile().telemSimEnabled(on); });
connect(ui->cbPauseOnHide, &QCheckBox::toggled, &g.currentProfile(), [=](bool on) { g.currentProfile().telemSimPauseOnHide(on); });
connect(ui->cbResetRssiOnStop, &QCheckBox::toggled, &g.currentProfile(), [=](bool on) { g.currentProfile().telemSimResetRssiOnStop(on); });
connect(&g.currentProfile(), &Profile::telemSimEnabledChanged, this, &TelemetrySimulator::onSimulateToggled);
connect(ui->loadLogFile, SIGNAL(released()), this, SLOT(onLoadLogFile()));
connect(ui->play, SIGNAL(released()), this, SLOT(onPlay()));
connect(ui->rewind, SIGNAL(clicked()), this, SLOT(onRewind()));
@@ -73,12 +80,50 @@ TelemetrySimulator::TelemetrySimulator(QWidget * parent, SimulatorInterface * si
TelemetrySimulator::~TelemetrySimulator()
{
timer.stop();
logTimer.stop();
stopTelemetry();
delete logPlayback;
delete ui;
}
void TelemetrySimulator::hideEvent(QHideEvent *event)
{
if (g.currentProfile().telemSimPauseOnHide())
stopTelemetry();
event->accept();
}
void TelemetrySimulator::showEvent(QShowEvent * event)
{
if (g.currentProfile().telemSimEnabled())
startTelemetry();
}
void TelemetrySimulator::startTelemetry()
{
timer.start();
if (m_logReplayEnable)
onPlay();
}
void TelemetrySimulator::stopTelemetry()
{
timer.stop();
m_logReplayEnable = logTimer.isActive();
onStop();
if (!(g.currentProfile().telemSimResetRssiOnStop() && ui && ui->rssi_inst))
return;
bool ok = false;
const int id = ui->rssi_inst->text().toInt(&ok, 0);
if (!ok)
return;
uint8_t buffer[FRSKY_SPORT_PACKET_SIZE] = {0};
generateSportPacket(buffer, id - 1, DATA_FRAME, RSSI_ID, 0);
emit telemetryDataChanged(QByteArray((char *)buffer, FRSKY_SPORT_PACKET_SIZE));
}
void TelemetrySimulator::onSimulatorStarted()
{
m_simuStarted = true;
@@ -92,12 +137,10 @@ void TelemetrySimulator::onSimulatorStopped()
void TelemetrySimulator::onSimulateToggled(bool isChecked)
{
if (isChecked) {
timer.start();
}
else {
timer.stop();
}
if (isChecked)
startTelemetry();
else
stopTelemetry();
}
void TelemetrySimulator::onLogTimerEvent()
@@ -113,6 +156,7 @@ void TelemetrySimulator::onLoadLogFile()
void TelemetrySimulator::onPlay()
{
ui->Simulate->setChecked(true);
if (logPlayback->isReady()) {
logTimer.start(logPlayback->logFrequency * 1000 / SPEEDS[ui->replayRate->value()]);
logPlayback->play();
@@ -166,23 +210,6 @@ void TelemetrySimulator::onReplayRateChanged(int value)
}
}
void TelemetrySimulator::hideEvent(QHideEvent *event)
{
m_telemEnable = ui->Simulate->isChecked();
m_logReplayEnable = logTimer.isActive();
ui->Simulate->setChecked(false);
ui->stop->click();
event->accept();
}
void TelemetrySimulator::showEvent(QShowEvent * event)
{
ui->Simulate->setChecked(m_telemEnable);
if (m_logReplayEnable)
ui->play->click();
}
#define SET_INSTANCE(control, id, def) ui->control->setText(QString::number(simulator->getSensorInstance(id, ((def) & 0x1F) + 1)))
void TelemetrySimulator::setupDataFields()
@@ -235,7 +262,7 @@ uint8_t getBit(uint8_t position, uint8_t value)
return (value & (uint8_t)(1 << position)) ? 1 : 0;
}
bool generateSportPacket(uint8_t * packet, uint8_t dataId, uint8_t prim, uint16_t appId, uint32_t data)
bool TelemetrySimulator::generateSportPacket(uint8_t * packet, uint8_t dataId, uint8_t prim, uint16_t appId, uint32_t data)
{
if (dataId > 0x1B ) return false;
+7 -5
View File
@@ -46,14 +46,18 @@ class TelemetrySimulator : public QWidget
explicit TelemetrySimulator(QWidget * parent, SimulatorInterface * simulator);
virtual ~TelemetrySimulator();
signals:
public slots:
bool generateSportPacket(uint8_t * packet, uint8_t dataId, uint8_t prim, uint16_t appId, uint32_t data);
signals:
void telemetryDataChanged(const QByteArray data);
protected slots:
virtual void hideEvent(QHideEvent *event);
virtual void showEvent(QShowEvent *event);
void hideEvent(QHideEvent *event) override;
void showEvent(QShowEvent *event) override;
void startTelemetry();
void stopTelemetry();
void onSimulatorStarted();
void onSimulatorStopped();
void setupDataFields();
@@ -77,7 +81,6 @@ class TelemetrySimulator : public QWidget
QTimer logTimer;
SimulatorInterface *simulator;
bool m_simuStarted;
bool m_telemEnable;
bool m_logReplayEnable;
// protected classes follow
@@ -204,7 +207,6 @@ class TelemetrySimulator : public QWidget
uint32_t encodeLatLon(double latLon, bool isLat);
uint32_t encodeDateTime(uint8_t yearOrHour, uint8_t monthOrMinute, uint8_t dayOrSecond, bool isDate);
}; // GPSEmulator
}; // TelemetrySimulator
#endif // _TELEMETRYSIMU_H_
+366 -334
View File
@@ -18,7 +18,7 @@
<property name="windowTitle">
<string>Telemetry Simulator</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<layout class="QGridLayout" name="gridLayout_6" rowstretch="0,0,0,1" columnstretch="0,1">
<property name="leftMargin">
<number>7</number>
</property>
@@ -37,7 +37,7 @@
<property name="verticalSpacing">
<number>7</number>
</property>
<item row="0" column="0" alignment="Qt::AlignTop">
<item row="0" column="0">
<widget class="QCheckBox" name="Simulate">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -58,334 +58,7 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="title">
<string>Replay SD Log File</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_30">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Replay rate</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="loadLogFile">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Load</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QSlider" name="replayRate">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>8</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>4</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="5" rowspan="2">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>4</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout_4">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item row="0" column="3">
<widget class="QPushButton" name="stepForward">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>|&gt;</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="stepBack">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>&lt;|</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="play">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>&gt;</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="rewind">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>&lt;-</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="stop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>X</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QScrollBar" name="positionIndicator">
<property name="enabled">
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="positionLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Row #
Timestamp</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_26">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>1/5x</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="label_27">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>5x</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="QLabel" name="logFileLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>No Log File Currently Loaded</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -434,8 +107,8 @@ Timestamp</string>
<rect>
<x>0</x>
<y>0</y>
<width>346</width>
<height>370</height>
<width>329</width>
<height>412</height>
</rect>
</property>
<property name="sizePolicy">
@@ -1729,8 +1402,8 @@ Timestamp</string>
<rect>
<x>0</x>
<y>0</y>
<width>339</width>
<height>370</height>
<width>330</width>
<height>384</height>
</rect>
</property>
<property name="sizePolicy">
@@ -2954,6 +2627,365 @@ hh:mm:ss</string>
</layout>
</widget>
</item>
<item row="0" column="1" rowspan="3">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="title">
<string>Replay SD Log File</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_30">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>Replay rate</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="loadLogFile">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Load</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QSlider" name="replayRate">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>8</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>4</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="5" rowspan="2">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>4</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout_4">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item row="0" column="3">
<widget class="QPushButton" name="stepForward">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>|&gt;</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="stepBack">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>&lt;|</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="play">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>&gt;</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="rewind">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>&lt;-</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="stop">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="text">
<string>X</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoExclusive">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QScrollBar" name="positionIndicator">
<property name="enabled">
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="positionLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Row #
Timestamp</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_26">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>1/5x</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="label_27">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>5x</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="QLabel" name="logFileLabel">
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="text">
<string>No Log File Currently Loaded</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="cbResetRssiOnStop">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Setting RSSI to zero simulates telemetry and radio link loss.</string>
</property>
<property name="text">
<string>Set RSSI to zero when paused.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="cbPauseOnHide">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Stop sending telemetry data when the Telemetry Simulator window is hidden.</string>
</property>
<property name="text">
<string>Pause simulation when hidden.</string>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
+3
View File
@@ -383,6 +383,9 @@ class Profile: public CompStoreObj
// Simulator variables
PROPERTY(SimulatorOptions, simulatorOptions, SimulatorOptions())
PROPERTY(bool, telemSimEnabled, false)
PROPERTY(bool, telemSimPauseOnHide, true)
PROPERTY(bool, telemSimResetRssiOnStop, false)
// Firmware Variables
PROPERTYSTR2(beeper, "Beeper")