WiP: mix data
This commit is contained in:
@@ -37,6 +37,8 @@ set(firmwares_SRCS
|
||||
edgetx/yaml_switchconfig.cpp
|
||||
edgetx/yaml_modeldata.cpp
|
||||
edgetx/yaml_rawswitch.cpp
|
||||
edgetx/yaml_rawsource.cpp
|
||||
edgetx/yaml_mixdata.cpp
|
||||
datahelpers.cpp
|
||||
customisation_data.cpp
|
||||
)
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* 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 "yaml_mixdata.h"
|
||||
#include "yaml_rawswitch.h"
|
||||
#include "yaml_rawsource.h"
|
||||
#include "curvereference.h"
|
||||
|
||||
// static const YamlLookupTable timerModeLut = {
|
||||
// {TimerData::TIMERMODE_OFF, "OFF"},
|
||||
// {TimerData::TIMERMODE_ON, "ON"},
|
||||
// {TimerData::TIMERMODE_START, "START"},
|
||||
// {TimerData::TIMERMODE_THR, "THR"},
|
||||
// {TimerData::TIMERMODE_THR_REL, "THR_REL"},
|
||||
// {TimerData::TIMERMODE_THR_START, "THR_START"},
|
||||
// };
|
||||
|
||||
// static const YamlLookupTable trainerModeLut = {
|
||||
// { TRAINER_MODE_OFF, "OFF" },
|
||||
// { TRAINER_MODE_MASTER_JACK, "MASTER_TRAINER_JACK" },
|
||||
// { TRAINER_MODE_SLAVE_JACK, "SLAVE" },
|
||||
// { TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, "MASTER_SBUS_EXT" },
|
||||
// { TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, "MASTER_CPPM_EXT" },
|
||||
// { TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, "MASTER_BATT_COMP" },
|
||||
// { TRAINER_MODE_MASTER_BLUETOOTH, "MASTER_BT" },
|
||||
// { TRAINER_MODE_SLAVE_BLUETOOTH, "SLAVE_BT" },
|
||||
// { TRAINER_MODE_MULTI, "MASTER_MULTI" },
|
||||
// };
|
||||
|
||||
static const YamlLookupTable mixMultiplexLut = {
|
||||
{ MLTPX_ADD, "ADD" },
|
||||
{ MLTPX_MUL, "MUL" },
|
||||
{ MLTPX_REP, "REPL" },
|
||||
};
|
||||
|
||||
#define GVAR_SMALL 128
|
||||
#define CPN_GV1 1024
|
||||
|
||||
static int32_t readMixWeight(const std::string& val)
|
||||
{
|
||||
if ((val.size() >= 4)
|
||||
&& (val[0] == '-')
|
||||
&& (val[1] == 'G')
|
||||
&& (val[2] == 'V')
|
||||
&& (val[3] >= '1')
|
||||
&& (val[3] <= '9')) {
|
||||
|
||||
return -10000 - std::stoi(val.substr(3));
|
||||
}
|
||||
|
||||
if ((val.size() >= 3)
|
||||
&& (val[0] == 'G')
|
||||
&& (val[1] == 'V')
|
||||
&& (val[2] >= '1')
|
||||
&& (val[2] <= '9')) {
|
||||
|
||||
return 10000 + std::stoi(val.substr(2));
|
||||
}
|
||||
|
||||
return std::stoi(val);
|
||||
}
|
||||
|
||||
static std::string writeMixWeight(int32_t sval)
|
||||
{
|
||||
if (sval < -10000) {
|
||||
int n = -sval - 10000;
|
||||
return std::string("-GV") + std::to_string(n);
|
||||
} else if (sval > 10000) {
|
||||
int n = sval - 10000;
|
||||
return std::string("GV") + std::to_string(n);
|
||||
}
|
||||
|
||||
return std::to_string(sval);
|
||||
}
|
||||
|
||||
static const YamlLookupTable dummy = {};
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
ENUM_CONVERTER(MltpxValue, mixMultiplexLut);
|
||||
|
||||
template <>
|
||||
struct convert<CurveReference> {
|
||||
static Node encode(const CurveReference& rhs)
|
||||
{
|
||||
Node node;
|
||||
node["type"] = (int)rhs.type;
|
||||
node["value"] = rhs.value;
|
||||
return node;
|
||||
}
|
||||
|
||||
static bool decode(const Node& node, CurveReference& rhs)
|
||||
{
|
||||
// no symbolic value defined in radio
|
||||
int type = 0;
|
||||
node["type"] >> type;
|
||||
rhs.type = (CurveReference::CurveRefType)type;
|
||||
|
||||
node["value"] >> rhs.value;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Node convert<MixData>::encode(const MixData& rhs)
|
||||
{
|
||||
Node node;
|
||||
node["destCh"] = rhs.destCh - 1;
|
||||
|
||||
// node["srcRaw"] = rhs.srcRaw; // r_mixSrcRaw
|
||||
|
||||
node["weight"] = writeMixWeight(rhs.weight);
|
||||
node["swtch"] = rhs.swtch;
|
||||
node["curve"] = rhs.curve;
|
||||
node["delayUp"] = rhs.delayUp;
|
||||
node["delayDown"] = rhs.delayDown;
|
||||
node["speedUp"] = rhs.speedUp;
|
||||
node["speedDown"] = rhs.speedDown;
|
||||
node["carryTrim"] = rhs.carryTrim;
|
||||
node["mltpx"] = rhs.mltpx;
|
||||
node["mixWarn"] = rhs.mixWarn;
|
||||
|
||||
// TODO: constant for number of flight modes
|
||||
std::string fm_str;
|
||||
for (int i=0; i<9; i++) {
|
||||
uint32_t bit = (rhs.flightModes >> i) & 1;
|
||||
fm_str += bit ? "1" : "0";
|
||||
}
|
||||
node["flightModes"] = fm_str;
|
||||
|
||||
node["offset"] = rhs.sOffset; // TODO: use writeMixWeight()
|
||||
node["name"] = rhs.name;
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<MixData>::decode(const Node& node, MixData& rhs)
|
||||
{
|
||||
node["destCh"] >> ioffset_int((int&)rhs.destCh, -1);
|
||||
node["srcRaw"] >> rhs.srcRaw;
|
||||
|
||||
std::string weight_str;
|
||||
node["weight"] >> weight_str;
|
||||
if (!weight_str.empty()) {
|
||||
rhs.weight = readMixWeight(weight_str);
|
||||
}
|
||||
|
||||
node["swtch"] >> rhs.swtch;
|
||||
node["curve"] >> rhs.curve;
|
||||
node["delayUp"] >> rhs.delayUp;
|
||||
node["delayDown"] >> rhs.delayDown;
|
||||
node["speedUp"] >> rhs.speedUp;
|
||||
node["speedDown"] >> rhs.speedDown;
|
||||
node["carryTrim"] >> rhs.carryTrim;
|
||||
node["mltpx"] >> rhs.mltpx;
|
||||
node["mixWarn"] >> rhs.mixWarn;
|
||||
|
||||
if (node["flightModes"]) {
|
||||
std::string fm_str;
|
||||
node["flightModes"] >> fm_str;
|
||||
|
||||
uint32_t bits = 0;
|
||||
uint32_t mask = 1;
|
||||
|
||||
for (uint32_t i = 0; i < fm_str.size(); i++) {
|
||||
if (fm_str[i] == '1') bits |= mask;
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
rhs.flightModes = bits;
|
||||
}
|
||||
|
||||
node["offset"] >> rhs.sOffset; // TODO: use readMixWeight()
|
||||
node["name"] >> rhs.name;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* 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 "yaml_ops.h"
|
||||
#include "mixdata.h"
|
||||
|
||||
namespace YAML {
|
||||
|
||||
template <>
|
||||
struct convert<MixData> {
|
||||
static Node encode(const MixData& rhs);
|
||||
static bool decode(const Node& node, MixData& rhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
@@ -19,8 +19,12 @@
|
||||
*/
|
||||
|
||||
#include "yaml_modeldata.h"
|
||||
#include "yaml_rawswitch.h"
|
||||
#include "yaml_mixdata.h"
|
||||
#include "modeldata.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
static const YamlLookupTable timerModeLut = {
|
||||
{TimerData::TIMERMODE_OFF, "OFF"},
|
||||
{TimerData::TIMERMODE_ON, "ON"},
|
||||
@@ -97,7 +101,14 @@ Node convert<ModelData>::encode(const ModelData& rhs)
|
||||
node["throttleReversed"] = (int)rhs.throttleReversed;
|
||||
|
||||
// flightModeData[]
|
||||
// mixData[]
|
||||
for (int i=0; i<CPN_MAX_MIXERS; i++) {
|
||||
const MixData& mix = rhs.mixData[i];
|
||||
if (!mix.isEmpty()) {
|
||||
Node mixNode;
|
||||
mixNode = rhs.mixData[i];
|
||||
node["mixData"].push_back(mixNode);
|
||||
}
|
||||
}
|
||||
// limitData[]
|
||||
// inputNames[]
|
||||
// expoData[]
|
||||
@@ -169,6 +180,7 @@ bool convert<ModelData>::decode(const Node& node, ModelData& rhs)
|
||||
|
||||
// flightModeData[]
|
||||
// mixData[]
|
||||
node["mixData"] >> rhs.mixData;
|
||||
// limitData[]
|
||||
// inputNames[]
|
||||
// expoData[]
|
||||
|
||||
@@ -19,12 +19,8 @@
|
||||
*/
|
||||
|
||||
#include "yaml_ops.h"
|
||||
#include "yaml_rawswitch.h"
|
||||
|
||||
#include "modeldata.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace YAML {
|
||||
|
||||
template <>
|
||||
|
||||
@@ -95,20 +95,25 @@ void operator >> (const YAML::Node& node, char (&value)[N])
|
||||
template <typename T, size_t N>
|
||||
void operator>>(const YAML::Node& node, T (&value)[N])
|
||||
{
|
||||
if (!node.IsMap()) return;// false;
|
||||
if (node.IsMap()) {
|
||||
for (const auto& elmt : node) {
|
||||
try {
|
||||
int idx = std::stoi(elmt.first.Scalar());
|
||||
if (idx < 0 || idx >= N) return; // false;
|
||||
|
||||
for (const auto& elmt : node) {
|
||||
try {
|
||||
int idx = std::stoi(elmt.first.Scalar());
|
||||
if (idx < 0 || idx >= N) return;// false;
|
||||
|
||||
elmt.second >> value[idx];
|
||||
} catch (...) {
|
||||
//return false;
|
||||
return;
|
||||
elmt.second >> value[idx];
|
||||
} catch (...) {
|
||||
// return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (node.IsSequence()) {
|
||||
int idx = 0;
|
||||
for (const auto& elmt : node) {
|
||||
elmt >> value[idx];
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
//return true;
|
||||
}
|
||||
|
||||
namespace YAML {
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* 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 "yaml_rawsource.h"
|
||||
|
||||
// SOURCE_TYPE_STICK
|
||||
const YamlLookupTable analogSourceLut = {
|
||||
{ 0, "Rud" },
|
||||
{ 1, "Ele" },
|
||||
{ 2, "Thr" },
|
||||
{ 3, "Ail" },
|
||||
{ 4, "S1" },
|
||||
{ 5, "6POS" },
|
||||
{ 6, "S2" },
|
||||
{ 7, "EXT1" }, { 7, "S3" }, // rename to use only S3
|
||||
{ 8, "EXT2" }, { 8, "S4" }, // rename to use only S4
|
||||
// { 9, "EXT3" },
|
||||
// { 10, "EXT4" },
|
||||
{ 9, "LS" },
|
||||
{ 10, "RS" },
|
||||
{ 11, "MOUSE1" },
|
||||
{ 12, "MOUSE2" },
|
||||
};
|
||||
|
||||
// SOURCE_TYPE_TRIM
|
||||
const YamlLookupTable trimSourceLut = {
|
||||
{ 0, "TrimRud" },
|
||||
{ 1, "TrimEle" },
|
||||
{ 2, "TrimThr" },
|
||||
{ 3, "TrimAil" },
|
||||
{ 4, "TrimT5" },
|
||||
{ 5, "TrimT6" },
|
||||
};
|
||||
|
||||
// SOURCE_TYPE_CYC
|
||||
const YamlLookupTable cycSourceLut = {
|
||||
{ 0, "CYC1" },
|
||||
{ 1, "CYC2" },
|
||||
{ 2, "CYC3" },
|
||||
};
|
||||
|
||||
// SOURCE_TYPE_MAX
|
||||
// { MIXSRC_MAX, "MAX" },
|
||||
|
||||
const YamlLookupTable specialSourceLut = {
|
||||
{ 0, "TX_VOLTAGE" },
|
||||
{ 1, "TX_TIME" },
|
||||
{ 2, "ONE" },
|
||||
{ 3, "TIMER1" },
|
||||
{ 4, "TIMER2" },
|
||||
{ 5, "TIMER3" },
|
||||
// TODO: { ???, "TX_GPS" },
|
||||
};
|
||||
|
||||
namespace YAML {
|
||||
|
||||
//ENUM_CONVERTER(RawSourceType, sourceTypeLut);
|
||||
|
||||
Node convert<RawSource>::encode(const RawSource& rhs)
|
||||
{
|
||||
std::string src_str;
|
||||
return Node(src_str);
|
||||
}
|
||||
|
||||
bool convert<RawSource>::decode(const Node& node, RawSource& rhs)
|
||||
{
|
||||
std::string src_str = node.Scalar();
|
||||
const char* val = src_str.data();
|
||||
size_t val_len = src_str.size();
|
||||
|
||||
if (val_len > 0 && val[0] == 'I') {
|
||||
|
||||
rhs = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, std::stoi(src_str.substr(1)));
|
||||
|
||||
} else if (val_len > 4 &&
|
||||
val[0] == 'l' &&
|
||||
val[1] == 'u' &&
|
||||
val[2] == 'a' &&
|
||||
val[3] == '(') {
|
||||
|
||||
src_str = src_str.substr(4);
|
||||
|
||||
size_t next_pos = 0;
|
||||
int script = std::stoi(src_str, &next_pos);
|
||||
|
||||
if (next_pos >= src_str.size()) return false;
|
||||
src_str = src_str.substr(next_pos + 1);
|
||||
|
||||
int output = std::stoi(src_str);
|
||||
rhs = RawSource(SOURCE_TYPE_LUA_OUTPUT, script * 16 + output);
|
||||
|
||||
} else if (val_len > 3 &&
|
||||
val[0] == 'l' &&
|
||||
val[1] == 's' &&
|
||||
val[2] == '(') {
|
||||
|
||||
src_str = src_str.substr(3);
|
||||
int ls = std::stoi(src_str);
|
||||
rhs = RawSource(SOURCE_TYPE_CUSTOM_SWITCH, ls);
|
||||
|
||||
} else if (val_len > 3 &&
|
||||
val[0] == 't' &&
|
||||
val[1] == 'r' &&
|
||||
val[2] == '(') {
|
||||
|
||||
src_str = src_str.substr(3);
|
||||
int tr = std::stoi(src_str);
|
||||
rhs = RawSource(SOURCE_TYPE_PPM, tr);
|
||||
|
||||
} else if (val_len > 3 &&
|
||||
val[0] == 'c' &&
|
||||
val[1] == 'h' &&
|
||||
val[2] == '(') {
|
||||
|
||||
src_str = src_str.substr(3);
|
||||
int ch = std::stoi(src_str);
|
||||
rhs = RawSource(SOURCE_TYPE_CH, ch);
|
||||
|
||||
} else if (val_len > 3 &&
|
||||
val[0] == 'g' &&
|
||||
val[1] == 'v' &&
|
||||
val[2] == '(') {
|
||||
|
||||
src_str = src_str.substr(3);
|
||||
int gv = std::stoi(src_str);
|
||||
rhs = RawSource(SOURCE_TYPE_GVAR, gv);
|
||||
|
||||
} else if (val_len > 5 &&
|
||||
val[0] == 't' &&
|
||||
val[1] == 'e' &&
|
||||
val[2] == 'l' &&
|
||||
val[3] == 'e' &&
|
||||
val[4] == '(') {
|
||||
|
||||
src_str = src_str.substr(5);
|
||||
|
||||
// parse sign
|
||||
uint8_t sign = 0;
|
||||
if (src_str[0] == '-') {
|
||||
sign = 1;
|
||||
src_str = src_str.substr(1);
|
||||
} else if (src_str[0] == '+') {
|
||||
sign = 2;
|
||||
src_str = src_str.substr(1);
|
||||
}
|
||||
|
||||
int sensor = std::stoi(src_str);
|
||||
rhs = RawSource(SOURCE_TYPE_TELEMETRY, sensor * 3 + sign);
|
||||
|
||||
} else {
|
||||
|
||||
YAML::Node conv = node >> analogSourceLut;
|
||||
if (conv.IsScalar()) {
|
||||
rhs.type = SOURCE_TYPE_STICK;
|
||||
rhs.index = conv.as<int>();
|
||||
}
|
||||
|
||||
conv = node >> trimSourceLut;
|
||||
if (conv.IsScalar()) {
|
||||
rhs.type = SOURCE_TYPE_TRIM;
|
||||
rhs.index = conv.as<int>();
|
||||
}
|
||||
|
||||
conv = node >> cycSourceLut;
|
||||
if (conv.IsScalar()) {
|
||||
rhs.type = SOURCE_TYPE_CYC;
|
||||
rhs.index = conv.as<int>();
|
||||
}
|
||||
|
||||
conv = node >> specialSourceLut;
|
||||
if (conv.IsScalar()) {
|
||||
rhs.type = SOURCE_TYPE_SPECIAL;
|
||||
rhs.index = conv.as<int>();
|
||||
}
|
||||
}
|
||||
// TODO: raw analogs
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace YAML
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* 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 "yaml_ops.h"
|
||||
#include "rawsource.h"
|
||||
|
||||
namespace YAML {
|
||||
|
||||
template <>
|
||||
struct convert<RawSource> {
|
||||
static Node encode(const RawSource& rhs);
|
||||
static bool decode(const Node& node, RawSource& rhs);
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user