Files
edgetx-gx12/companion/src/simulation/simulatorinterface.h
T

209 lines
7.0 KiB
C++

/*
* 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.
*/
#ifndef _SIMULATORINTERFACE_H_
#define _SIMULATORINTERFACE_H_
#include "firmwares/boards.h"
#include "constants.h"
#include <algorithm>
#include <inttypes.h>
#include <QObject>
#include <QString>
#include <QByteArray>
#include <QDir>
#include <QLibrary>
#include <QMap>
#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_FRSKY_HUB_OOB,
SIMU_TELEMETRY_PROTOCOL_COUNT
};
class SimulatorInterface : public QObject
{
Q_OBJECT
public:
enum InputSourceType {
INPUT_SRC_NONE = 0,
INPUT_SRC_ANALOG, // any analog source, index into g_anas[]
INPUT_SRC_STICK, // Board::StickAxes, g_anas[index]
INPUT_SRC_KNOB, // g_anas[index + StickAxes]
INPUT_SRC_SLIDER, // g_anas[index + StickAxes + num_pots]
INPUT_SRC_TXVIN, // g_anas[Analogs::TX_VOLTAGE]
INPUT_SRC_SWITCH, // Named 2/3-pos switches
INPUT_SRC_TRIM_SW, // Board::TrimSwitches
INPUT_SRC_TRIM, // Board::TrimAxes
INPUT_SRC_KEY, // UI key/pushbutton
INPUT_SRC_ROTENC, // Rotary encoder (TODO)
INPUT_SRC_TRAINER, // Virtual trainer input
INPUT_SRC_ENUM_COUNT
};
enum OutputSourceType {
OUTPUT_SRC_NONE = 0,
OUTPUT_SRC_CHAN_OUT,
OUTPUT_SRC_CHAN_MIX,
OUTPUT_SRC_TRIM_VALUE,
OUTPUT_SRC_TRIM_RANGE,
OUTPUT_SRC_VIRTUAL_SW,
OUTPUT_SRC_PHASE,
OUTPUT_SRC_GVAR,
OUTPUT_SRC_ENUM_COUNT
};
// only for data not available from Boards or Firmware, eg. compile-time options
enum Capability {
CAP_LUA, // LUA
CAP_ROTARY_ENC, // ROTARY_ENCODERS
CAP_ROTARY_ENC_NAV, // ROTARY_ENCODER_NAVIGATION
CAP_TELEM_FRSKY_SPORT, // TELEMETRY_FRSKY_SPORT
CAP_ENUM_COUNT
};
// This allows automatic en/decoding of flight mode + gvarIdx value to/from any int32
struct gVarMode_t {
int16_t value;
uint8_t mode;
uint8_t prec:2;
uint8_t unit:2;
gVarMode_t(int i = 0) {
set(i);
}
void set(int i) {
unit = (i >> 26) & 0x3;
prec = (i >> 24) & 0x3;
mode = (i >> 16) & 0xFF;
value = (i & 0xFFFF);
}
operator int() {
return (((unit & 0x3) << 26) | ((prec & 0x3) << 24) | ((mode & 0xFF) << 16) | (value & 0xFFFF));
}
gVarMode_t & operator =(const int i) {
set(i);
return *this;
}
};
struct TxOutputs {
TxOutputs() { clear(); }
void clear() { memset(this, 0, sizeof(TxOutputs)); }
int16_t chans[CPN_MAX_CHNOUT]; // final channel outputs
int16_t ex_chans[CPN_MAX_CHNOUT]; // raw mix outputs
qint32 gvars[CPN_MAX_FLIGHT_MODES][CPN_MAX_GVARS];
int trims[CPN_MAX_TRIMS]; // Board::TrimAxes enum
bool vsw[CPN_MAX_LOGICAL_SWITCHES]; // virtual/logic switches
int8_t phase;
qint16 trimRange; // TRIM_MAX or TRIM_EXTENDED_MAX
// bool beep;
};
virtual ~SimulatorInterface() {}
virtual QString name() = 0;
virtual bool isRunning() = 0;
virtual void readRadioData(QByteArray & dest) = 0;
virtual uint8_t * getLcd() = 0;
virtual uint8_t getSensorInstance(uint16_t id, uint8_t defaultValue = 0) = 0;
virtual uint16_t getSensorRatio(uint16_t id) = 0;
virtual const int getCapability(Capability cap) = 0;
public slots:
virtual void init() = 0;
virtual void start(const char * filename = NULL, bool tests = true) = 0;
virtual void stop() = 0;
virtual void setSdPath(const QString & sdPath = "", const QString & settingsPath = "") = 0;
virtual void setVolumeGain(const int value) = 0;
virtual void setRadioData(const QByteArray & data) = 0;
virtual void setAnalogValue(uint8_t index, int16_t value) = 0;
virtual void setKey(uint8_t key, bool state) = 0;
virtual void setSwitch(uint8_t swtch, int8_t state) = 0;
virtual void setTrim(unsigned int idx, int value) = 0;
virtual void setTrimSwitch(uint8_t trim, bool state) = 0;
virtual void setTrainerInput(unsigned int inputNumber, int16_t value) = 0;
virtual void setInputValue(int type, uint8_t index, int16_t value) = 0;
virtual void rotaryEncoderEvent(int steps) = 0;
virtual void touchEvent(int type, int x, int y) = 0;
virtual void lcdFlushed() = 0;
virtual void setTrainerTimeout(uint16_t ms) = 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;
signals:
void started();
void stopped();
void heartbeat(qint32 loops, qint64 timestamp);
void runtimeError(const QString & error);
void lcdChange(bool backlightEnable);
void phaseChanged(qint8 phase, const QString & name);
void channelOutValueChange(quint8 index, qint32 value, qint32 limit);
void channelMixValueChange(quint8 index, qint32 value, qint32 limit);
void virtualSwValueChange(quint8 index, qint32 value);
void trimValueChange(quint8 index, qint32 value);
void trimRangeChange(quint8 index, qint32 min, qint16 max);
void gVarValueChange(quint8 index, qint32 value);
void outputValueChange(int type, quint8 index, qint32 value);
};
class SimulatorFactory {
public:
virtual ~SimulatorFactory() { }
virtual QString name() = 0;
virtual Board::Type type() = 0;
virtual SimulatorInterface *create() = 0;
};
class SimulatorLoader
{
public:
static void registerSimulators();
static void unregisterSimulators();
static QStringList getAvailableSimulators();
static QString findSimulatorByName(const QString & name);
static SimulatorInterface * loadSimulator(const QString & name);
static bool unloadSimulator(const QString & name);
protected:
typedef SimulatorFactory * (*RegisterSimulator)();
static int registerSimulators(const QDir & dir);
static QMap<QString, QLibrary *> registeredSimulators;
};
#endif // _SIMULATORINTERFACE_H_