Skip to content

Commit

Permalink
feat(cpn): support more than just FrSky S.Port telemetry simulation (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
nrw505 authored Aug 20, 2024
1 parent e61fc89 commit 005bd19
Show file tree
Hide file tree
Showing 17 changed files with 6,717 additions and 3,915 deletions.
3 changes: 3 additions & 0 deletions companion/src/simulation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ set(${PROJECT_NAME}_NAMES
simulatormainwindow
simulatorstartupdialog
simulatorwidget
simulatedgps
telemetrysimu
telemetryprovidercrossfire
telemetryproviderfrsky
trainersimu
widgets/lcdwidget
widgets/radiowidget
Expand Down
160 changes: 160 additions & 0 deletions companion/src/simulation/simulatedgps.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include "simulatedgps.h"
#include <QtMath>
#include <QDebug>

SimulatedGPS::SimulatedGPS()
{
lat = 0;
lon = 0;
courseDegrees = 0;
speedKMH = 0;
altitude = 0;
satellites = 0;
dt = QDateTime::currentDateTime();
running = false;
timer.setInterval(250);
connect(&timer, &QTimer::timeout, this, &SimulatedGPS::update);
}

SimulatedGPS::~SimulatedGPS()
{
}

void SimulatedGPS::setDateTime(QDateTime dateTime)
{
dt = dateTime;
}

void SimulatedGPS::setDateTime(QString dateTime)
{
if (dateTime.startsWith("*")) {
dt = QDateTime::currentDateTime();
} else {
dt = QDateTime::fromString(dateTime, Qt::ISODate);
}
}

void SimulatedGPS::setLatLon(QString latLon)
{
QStringList coords = latLon.split(",");
if (coords.length() < 2) {
coords = latLon.split(" ");
}
lat = 0.0;
lon = 0.0;
if (coords.length() > 1) {
lat = coords[0].simplified().toDouble();
lon = coords[1].simplified().toDouble();
} else {
stop();
}
}

void SimulatedGPS::setCourseDegrees(double course)
{
courseDegrees = course;
}

void SimulatedGPS::setSpeedKMH(double speed)
{
speedKMH = speed;
}

void SimulatedGPS::setAltitude(double altitude)
{
this->altitude = altitude;
}

void SimulatedGPS::setSatelliteCount(int sats)
{
satellites = sats;
}

void SimulatedGPS::start()
{
running = true;
timer.start();
}

void SimulatedGPS::stop()
{
running = false;
timer.stop();
}

void SimulatedGPS::update()
{
if (!running) {
return;
}

dt = QDateTime::currentDateTime().toTimeSpec(Qt::UTC);
emitDateTimeChange();

double b2 = lat;
double c2 = lon;
double d3 = speedKMH / 14400;
double f3 = courseDegrees;
double j2 = 6378.1;
double b3 = qRadiansToDegrees(qAsin( qSin(qDegreesToRadians(b2))*qCos(d3/j2) + qCos(qDegreesToRadians(b2))*qSin(d3/j2)*qCos(qDegreesToRadians(f3))));
double bb3 = b3;
if (bb3 < 0) {
bb3 = bb3 * -1;
}
if (bb3 > 89.99) {
f3 = f3 + 180;
if (f3 > 360) {
f3 = f3 - 360;
}
courseDegrees = f3;
emit courseDegreesChanged(courseDegrees);
}
double c3 = qRadiansToDegrees(qDegreesToRadians(c2) + qAtan2(qSin(qDegreesToRadians(f3))*qSin(d3/j2)*qCos(qDegreesToRadians(b2)),qCos(d3/j2)-qSin(qDegreesToRadians(b2))*qSin(qDegreesToRadians(b3))));
if (c3 > 180) {
c3 = c3 - 360;
}
if (c3 < -180) {
c3 = c3 + 360;
}
lat = b3;
lon = c3;

emitPositionChange();
}

void SimulatedGPS::emitPositionChange()
{
QString lats = QString::number(lat, 'f', 8);
QString lons = QString::number(lon, 'f', 8);
QString qs = lats + "," + lons;

emit positionChanged(qs);
}

void SimulatedGPS::emitDateTimeChange()
{
QString formatted = dt.toString(Qt::ISODate);
emit dateTimeChanged(formatted);
emit dateTimeChanged(dt);
}
68 changes: 68 additions & 0 deletions companion/src/simulation/simulatedgps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#pragma once

#include <QTimer>
#include <QDateTime>

class SimulatedGPS : public QObject
{
Q_OBJECT

public:
SimulatedGPS();
~SimulatedGPS();

QDateTime dt;
double lat;
double lon;
double courseDegrees;
double speedKMH;
double altitude; // in meters
uint8_t satellites;
bool running;

signals:
void positionChanged(const QString latLon);
void dateTimeChanged(const QString dateTime);
void dateTimeChanged(const QDateTime dateTime);
void courseDegreesChanged(double course);

public slots:
void setDateTime(QDateTime dateTime);
void setDateTime(QString dateTime);
void setLatLon(QString latLon);
void setCourseDegrees(double course);
void setSpeedKMH(double speed);
void setAltitude(double altitude);
void setSatelliteCount(int sats);
void start();
void stop();

protected slots:
void update();
void emitPositionChange();
void emitDateTimeChange();

private:
QTimer timer;
};
10 changes: 9 additions & 1 deletion companion/src/simulation/simulatorinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@

#define SIMULATOR_INTERFACE_HEARTBEAT_PERIOD 1000 // ms

enum SimulatorTelemetryProtocol {
SIMU_TELEMETRY_PROTOCOL_FRSKY_SPORT = 0,
SIMU_TELEMETRY_PROTOCOL_FRSKY_HUB,
SIMU_TELEMETRY_PROTOCOL_CROSSFIRE,
SIMU_TELEMETRY_PROTOCOL_COUNT
};

class SimulatorInterface : public QObject
{
Q_OBJECT
Expand Down Expand Up @@ -148,7 +155,8 @@ class SimulatorInterface : public QObject
virtual void touchEvent(int type, int x, int y) = 0;
virtual void lcdFlushed() = 0;
virtual void setTrainerTimeout(uint16_t ms) = 0;
virtual void sendTelemetry(const QByteArray data) = 0;
virtual void sendInternalModuleTelemetry(const quint8 protocol, const QByteArray data) = 0;
virtual void sendExternalModuleTelemetry(const quint8 protocol, const QByteArray data) = 0;
virtual void setLuaStateReloadPermanentScripts() = 0;
virtual void addTracebackDevice(QIODevice * device) = 0;
virtual void removeTracebackDevice(QIODevice * device) = 0;
Expand Down
50 changes: 50 additions & 0 deletions companion/src/simulation/telemetryprovider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#pragma once

#include "simulatorinterface.h"
#include <QHash>

class TelemetryProvider
{
public:
virtual ~TelemetryProvider() {}

virtual void resetRssi() = 0;

// Simulator has been updated externally, update the UI to match
virtual void loadUiFromSimulator(SimulatorInterface * simulator) = 0;

// Load a telemetry item from the log replay. value must be in the correct units,
// see supportLogItems
virtual void loadItemFromLog(QString itemName, QString value) = 0;

// Tell the log replayer what items we can accept and what units we need them in
// - returns e.g. { "Alt" => "m", "GSpd" => "kmh" }
virtual QHash<QString, QString> * getSupportedLogItems() = 0;

// In hopes of being able to load a file and select the appropriate provider in one step
virtual QString getLogfileIdentifier() = 0;

// do the work every however often
virtual void generateTelemetryFrame(SimulatorInterface * simulator) = 0;
};
Loading

0 comments on commit 005bd19

Please sign in to comment.