mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 09:28:40 +02:00
Add set value to live data
Print new commands and signals
This commit is contained in:
@@ -18,5 +18,59 @@ double liveDataValueToDouble(const LiveDataValue& val) {
|
||||
return val.value * liveDataFixedPointToDouble;
|
||||
}
|
||||
|
||||
int liveDataDoubleToValue(LiveDataValue& value, const double& dFloat) {
|
||||
union {
|
||||
struct
|
||||
{
|
||||
uint32_t ValueFractionPart;
|
||||
int32_t ValueInt32;
|
||||
} parts;
|
||||
int64_t ValueLarge;
|
||||
} CminiFixedPt;
|
||||
constexpr double CM_FIXED_POINT_TO_DOUBLEVALUE = (1.0 / (double)(1ULL << 32)); // 2^-32
|
||||
constexpr double CM_DOUBLEVALUE_TO_FIXED_POINT = ((double)(1ULL << 32)); // 2^32
|
||||
// Use const for limits (C++98 compatible)
|
||||
const double INT32_MAX_DOUBLE =
|
||||
static_cast<double>(std::numeric_limits<int32_t>::max()) + (1.0 - std::numeric_limits<double>::epsilon());
|
||||
const double INT32_MIN_DOUBLE = static_cast<double>(std::numeric_limits<int32_t>::min());
|
||||
const double MIN_FIXED_POINT_DOUBLE = (double)(1ull * CM_FIXED_POINT_TO_DOUBLEVALUE);
|
||||
|
||||
// This needs to be assigned separately, otherwise, for dFloat >= 2^31,
|
||||
// long double dBigFloat = dFloat * CM_DOUBLEVALUE_TO_FIXED_POINT overflows
|
||||
// long long (value is >= 2^63) and so the assignment ValueLarge = dBigFloat is undefined
|
||||
|
||||
int32_t intPart; //creating temp variable due to static analysis warning about writing and reading to different union members
|
||||
if (dFloat < 0.0)
|
||||
intPart = (int32_t)floor(dFloat);
|
||||
else
|
||||
intPart = (int32_t)dFloat;
|
||||
|
||||
//using temp varialbes to avoid static analysis warning about read/write to different union members
|
||||
double frac = dFloat - (double)(intPart);
|
||||
uint32_t fracPart = (uint32_t)floor((frac * CM_DOUBLEVALUE_TO_FIXED_POINT) + 0.5);
|
||||
|
||||
//write temp vars back into the union
|
||||
CminiFixedPt.parts.ValueInt32 = intPart;
|
||||
CminiFixedPt.parts.ValueFractionPart = fracPart;
|
||||
value.value = CminiFixedPt.ValueLarge;
|
||||
|
||||
if (dFloat == (double)0.0)
|
||||
return 0;
|
||||
|
||||
//check if double can be stored as 32.32
|
||||
// 0x1 0000 0000 0000 0000 * CM_FIXED_POINT_TO_DOUBLEVALUE = 0x1 0000 0000
|
||||
if (dFloat > INT32_MAX_DOUBLE)
|
||||
return 1;
|
||||
if (dFloat < INT32_MIN_DOUBLE)
|
||||
return -1;
|
||||
|
||||
// Use absolute value for minimum fixed point check
|
||||
double absFloat = (dFloat < 0.0) ? -dFloat : dFloat;
|
||||
if (absFloat < MIN_FIXED_POINT_DOUBLE)
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace LiveDataUtil
|
||||
} // namespace icsneo
|
||||
@@ -99,6 +99,33 @@ bool HardwareLiveDataPacket::EncodeFromMessage(LiveDataMessage& message, std::ve
|
||||
clearMsg->cmd = static_cast<uint32_t>(message.cmd);
|
||||
break;
|
||||
}
|
||||
case LiveDataCommand::SET_VALUE: {
|
||||
auto setValMsg = reinterpret_cast<LiveDataSetValueMessage*>(&message);
|
||||
const auto numArgs = setValMsg->args.size();
|
||||
if(numArgs) {
|
||||
payloadSize = static_cast<uint16_t>(sizeof(LiveDataSetValue) + (sizeof(LiveDataSetValueEntry) * (numArgs-1)));
|
||||
bytestream.resize((payloadSize + sizeof(ExtendedCommandHeader)),0);
|
||||
LiveDataSetValue* out = reinterpret_cast<LiveDataSetValue*>(bytestream.data() + sizeof(ExtendedCommandHeader));
|
||||
out->version = icsneo::LiveDataUtil::LiveDataVersion;
|
||||
out->cmd = static_cast<uint32_t>(setValMsg->cmd);
|
||||
if(!setValMsg->handle)
|
||||
setValMsg->handle = LiveDataUtil::getNewHandle();
|
||||
out->handle = setValMsg->handle;
|
||||
out->numArgs = static_cast<uint32_t>(setValMsg->args.size());
|
||||
for(size_t i = 0; i < numArgs; ++i) {
|
||||
out->values[i].arg.objectType = setValMsg->args[i]->objectType;
|
||||
out->values[i].arg.objectIndex = setValMsg->args[i]->objectIndex;
|
||||
out->values[i].arg.signalIndex = setValMsg->args[i]->signalIndex;
|
||||
out->values[i].arg.valueType = setValMsg->args[i]->valueType;
|
||||
out->values[i].value.value = setValMsg->values[i]->value;
|
||||
out->values[i].value.header.length = sizeof(int64_t);
|
||||
}
|
||||
} else {
|
||||
report(APIEvent::Type::LiveDataInvalidArgument, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
report(APIEvent::Type::LiveDataInvalidCommand, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user