Closed andreamancuso closed 2 months ago
Meanwhile I sent hand-crafted VALSETs and managed to enable NAV-POSLLH and NAV-PVT on an M10 EVK. I can parse both without any issues!
The tutorial4 explains how to access the <variant>
's fields. To assign the cfgdata
field as needed should probably look like this:
OutCfgValset msg;
auto& cfgData = msg.field_cfgdata();
using KeyType = OutCfgValset::Field_cfgdata::Field_key::ValueType;
cfgData.field_key().setValue(KeyType::CFG_MSGOUT_UBX_NAV_POSLLH_UART1);
cfgData.field_val().initField_cfgValL().setValue(1); // select (initialize) proper variant member and then set the value
In the spirit of the commsdsl the definition of the CfgValset
message should have referenced CfgValPair
instead of CfgValPairSimple
. However, such definition was too heavy for some compilers to handle, especially with development computers with less than 16GB of memory. Another less boilerplate (not enforcing the length of the val
field) code, although much heavier on compiler and probably runtime could look like this (not really tested, might not even compile):
#include "comms/util/cast.h"
...
cc_ublox::field::CfgValPair<> pairField;
auto& posllhMem = pairField.initField_msgoutUbxNavPosllhUart1();
posllhMem.field_val().setValue(1);
OutCfgValset msg;
msg.field_cfgdata() = comms::field_cast<OutCfgValset::Field_cfgdata>(pairField);
The cast function is documented here and explained in the tutorial21.
To resolve a burden of using a very small subset of the protocol functionality, especially having a long list of <variant>
members, (somehow) allowing selection of the custom list of the variant members during the code generation is on my future TODO list. If I come around to implement it, then maybe the definition of the protocol may change to include CfgValPair
field instead of CfgValPairSimple
.
Thank you for your comprehensive answer. 👍
This is likely due to me being thick - here's how I got it working
void Session::sendValSetWithSingleKeyValuePair(CfgValKeyId valKeyId, long valValue) {
using CfgdataElement = cc_ublox::message::CfgValsetFields<>::CfgdataMembers::Element;
OutCfgValset msg;
auto& layers = msg.field_layers();
auto& cfgData = msg.field_cfgdata().value();
layers.setBitValue_ram(true);
CfgdataElement valsetElement;
valsetElement.field_key().setValue(valKeyId);
valsetElement.field_val().initField_l().setValue(valValue);
cfgData.push_back(valsetElement);
sendMessage(msg);
};
I am very happy with the outcome and am looking forward to start adding more functionality.
Looks good, however it is important to remember that "L" field is only 1 byte long. you should change the type of the "valValue" parameter to be something like std::uint8_t
or even bool
. In case you'll need longer values you'll have do overload the function where you'll initialize and use other variant members, like ....initField_u8()...
for example.
Hi @arobenko
Are there any examples on how to construct a VALSET programmatically?
This is what I came up with so far
The compiler doesn't quite like that.
Thank you in advance!