Support relative changes and wrapping for generic protocol input.
This commit is contained in:
parent
93a5765d08
commit
4ec6810c29
2 changed files with 69 additions and 27 deletions
|
@ -41,8 +41,6 @@
|
||||||
#include <Main/util.hxx>
|
#include <Main/util.hxx>
|
||||||
#include "generic.hxx"
|
#include "generic.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FGGeneric::FGGeneric(vector<string> tokens) : exitOnError(false)
|
FGGeneric::FGGeneric(vector<string> tokens) : exitOnError(false)
|
||||||
{
|
{
|
||||||
size_t configToken;
|
size_t configToken;
|
||||||
|
@ -288,10 +286,7 @@ bool FGGeneric::parse_message_binary(int length) {
|
||||||
} else {
|
} else {
|
||||||
tmp32 = *(int32_t *)p1;
|
tmp32 = *(int32_t *)p1;
|
||||||
}
|
}
|
||||||
|
updateValue(_in_message[i], (int)tmp32);
|
||||||
val = _in_message[i].offset + (double)tmp32 * _in_message[i].factor;
|
|
||||||
|
|
||||||
_in_message[i].prop->setIntValue((int)val);
|
|
||||||
p1 += sizeof(int32_t);
|
p1 += sizeof(int32_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -306,11 +301,7 @@ bool FGGeneric::parse_message_binary(int length) {
|
||||||
} else {
|
} else {
|
||||||
tmp32 = *(int32_t *)p1;
|
tmp32 = *(int32_t *)p1;
|
||||||
}
|
}
|
||||||
|
updateValue(_in_message[i], (float)tmp32 / 65536.0f);
|
||||||
val = _in_message[i].offset +
|
|
||||||
((double)tmp32 / 65536.0f) * _in_message[i].factor;
|
|
||||||
|
|
||||||
_in_message[i].prop->setFloatValue(val);
|
|
||||||
p1 += sizeof(int32_t);
|
p1 += sizeof(int32_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -321,11 +312,7 @@ bool FGGeneric::parse_message_binary(int length) {
|
||||||
} else {
|
} else {
|
||||||
tmpun32.floatVal = *(float *)p1;
|
tmpun32.floatVal = *(float *)p1;
|
||||||
}
|
}
|
||||||
|
updateValue(_in_message[i], tmpun32.floatVal);
|
||||||
val = _in_message[i].offset +
|
|
||||||
tmpun32.floatVal * _in_message[i].factor;
|
|
||||||
|
|
||||||
_in_message[i].prop->setFloatValue(val);
|
|
||||||
p1 += sizeof(int32_t);
|
p1 += sizeof(int32_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -336,11 +323,7 @@ bool FGGeneric::parse_message_binary(int length) {
|
||||||
} else {
|
} else {
|
||||||
tmpun64.doubleVal = *(double *)p1;
|
tmpun64.doubleVal = *(double *)p1;
|
||||||
}
|
}
|
||||||
|
updateValue(_in_message[i], tmpun64.doubleVal);
|
||||||
val = _in_message[i].offset +
|
|
||||||
tmpun64.doubleVal * _in_message[i].factor;
|
|
||||||
|
|
||||||
_in_message[i].prop->setDoubleValue(val);
|
|
||||||
p1 += sizeof(int64_t);
|
p1 += sizeof(int64_t);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -378,8 +361,7 @@ bool FGGeneric::parse_message_ascii(int length) {
|
||||||
|
|
||||||
switch (_in_message[i].type) {
|
switch (_in_message[i].type) {
|
||||||
case FG_INT:
|
case FG_INT:
|
||||||
val = _in_message[i].offset + atoi(p1) * _in_message[i].factor;
|
updateValue(_in_message[i], atoi(p1));
|
||||||
_in_message[i].prop->setIntValue((int)val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FG_BOOL:
|
case FG_BOOL:
|
||||||
|
@ -388,13 +370,11 @@ bool FGGeneric::parse_message_ascii(int length) {
|
||||||
|
|
||||||
case FG_FIXED:
|
case FG_FIXED:
|
||||||
case FG_FLOAT:
|
case FG_FLOAT:
|
||||||
val = _in_message[i].offset + strtod(p1, 0) * _in_message[i].factor;
|
updateValue(_in_message[i], (float)strtod(p1, 0));
|
||||||
_in_message[i].prop->setFloatValue((float)val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FG_DOUBLE:
|
case FG_DOUBLE:
|
||||||
val = _in_message[i].offset + strtod(p1, 0) * _in_message[i].factor;
|
updateValue(_in_message[i], (double)strtod(p1, 0));
|
||||||
_in_message[i].prop->setDoubleValue(val);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // SG_STRING
|
default: // SG_STRING
|
||||||
|
@ -686,6 +666,10 @@ FGGeneric::read_config(SGPropertyNode *root, vector<_serial_prot> &msg)
|
||||||
chunk.format = fgUnescape(chunks[i]->getStringValue("format", "%d"));
|
chunk.format = fgUnescape(chunks[i]->getStringValue("format", "%d"));
|
||||||
chunk.offset = chunks[i]->getDoubleValue("offset");
|
chunk.offset = chunks[i]->getDoubleValue("offset");
|
||||||
chunk.factor = chunks[i]->getDoubleValue("factor", 1.0);
|
chunk.factor = chunks[i]->getDoubleValue("factor", 1.0);
|
||||||
|
chunk.min = chunks[i]->getDoubleValue("min");
|
||||||
|
chunk.max = chunks[i]->getDoubleValue("max");
|
||||||
|
chunk.wrap = chunks[i]->getBoolValue("wrap");
|
||||||
|
chunk.rel = chunks[i]->getBoolValue("relative");
|
||||||
|
|
||||||
string node = chunks[i]->getStringValue("node", "/null");
|
string node = chunks[i]->getStringValue("node", "/null");
|
||||||
chunk.prop = fgGetNode(node.c_str(), true);
|
chunk.prop = fgGetNode(node.c_str(), true);
|
||||||
|
@ -727,3 +711,24 @@ FGGeneric::read_config(SGPropertyNode *root, vector<_serial_prot> &msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
set/getValue: Implementations for supported datatypes
|
||||||
|
*/
|
||||||
|
#define DEF_DATA_ACCESS(type, method)\
|
||||||
|
template<>\
|
||||||
|
const type FGGeneric::getValue(SGPropertyNode_ptr& prop)\
|
||||||
|
{\
|
||||||
|
return prop->get##method##Value();\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
template<>\
|
||||||
|
void FGGeneric::setValue(SGPropertyNode_ptr& prop, const type& val)\
|
||||||
|
{\
|
||||||
|
prop->set##method##Value(val);\
|
||||||
|
}
|
||||||
|
|
||||||
|
DEF_DATA_ACCESS(int, Int)
|
||||||
|
DEF_DATA_ACCESS(float, Float)
|
||||||
|
DEF_DATA_ACCESS(double, Double)
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,9 @@ protected:
|
||||||
e_type type;
|
e_type type;
|
||||||
double offset;
|
double offset;
|
||||||
double factor;
|
double factor;
|
||||||
|
double min, max;
|
||||||
|
bool wrap;
|
||||||
|
bool rel;
|
||||||
SGPropertyNode_ptr prop;
|
SGPropertyNode_ptr prop;
|
||||||
} _serial_prot;
|
} _serial_prot;
|
||||||
|
|
||||||
|
@ -99,6 +102,40 @@ private:
|
||||||
bool parse_message_binary(int length);
|
bool parse_message_binary(int length);
|
||||||
void read_config(SGPropertyNode *root, vector<_serial_prot> &msg);
|
void read_config(SGPropertyNode *root, vector<_serial_prot> &msg);
|
||||||
bool exitOnError;
|
bool exitOnError;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static void updateValue(_serial_prot& prot, const T& val)
|
||||||
|
{
|
||||||
|
T new_val = (prot.rel ? getValue<T>(prot.prop) : 0)
|
||||||
|
+ prot.offset
|
||||||
|
+ prot.factor * val;
|
||||||
|
|
||||||
|
if( prot.max > prot.min )
|
||||||
|
{
|
||||||
|
if( prot.wrap )
|
||||||
|
{
|
||||||
|
T range = prot.max - prot.min + 1;
|
||||||
|
if( range > 0 )
|
||||||
|
{
|
||||||
|
while( new_val < prot.min )
|
||||||
|
new_val += range;
|
||||||
|
while( new_val > prot.max )
|
||||||
|
new_val -= range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
new_val = std::min<T>(prot.max, std::max<T>(prot.min, new_val));
|
||||||
|
}
|
||||||
|
|
||||||
|
setValue(prot.prop, new_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static const T getValue(SGPropertyNode_ptr& prop);
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static void setValue(SGPropertyNode_ptr& prop, const T& val);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue