Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cpn): support more than just FrSky S.Port telemetry simulation #5410

Merged
merged 3 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading