Program Listing for File ubx_esf_meas.hpp
↰ Return to documentation for file (/tmp/ws/src/ublox_dgnss/ublox_dgnss_node/include/ublox_dgnss_node/ubx/esf/ubx_esf_meas.hpp
)
// Copyright 2023 Australian Robotics Supplies & Technology
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef UBLOX_DGNSS_NODE__UBX__ESF__UBX_ESF_MEAS_HPP_
#define UBLOX_DGNSS_NODE__UBX__ESF__UBX_ESF_MEAS_HPP_
#include <unistd.h>
#include <memory>
#include <tuple>
#include <string>
#include <vector>
#include "ublox_dgnss_node/ubx/ubx.hpp"
#include "ublox_dgnss_node/ubx/utils.hpp"
#include "ublox_ubx_msgs/msg/ubx_esf_meas.hpp"
namespace ubx::esf::meas
{
struct flags_t
{
union {
x2_t all;
struct
{
u8_t timeMarkSent : 2;
bool timeMarkEdge : 1;
bool calibTtagValid : 1;
u8_t numMeas : 5;
} bits;
};
};
struct data_t
{
union {
x4_t all;
struct
{
u4_t dataField : 24;
u8_t dataType : 6;
} bits;
};
};
class ESFMeasPayload : UBXPayload
{
public:
static const msg_class_t MSG_CLASS = UBX_ESF;
static const msg_id_t MSG_ID = UBX_ESF_MEAS;
u4_t timeTag; // ms - GPS Time of week of the navigation epoch.
flags_t flags;
u2_t id;
std::vector<data_t> datum;
u4_t calibTtags; // number of sensors
public:
ESFMeasPayload()
: UBXPayload(MSG_CLASS, MSG_ID)
{
}
ESFMeasPayload(ch_t * payload_polled, u2_t size)
: UBXPayload(MSG_CLASS, MSG_ID)
{
payload_.clear();
payload_.reserve(size);
payload_.resize(size);
memcpy(payload_.data(), payload_polled, size);
timeTag = buf_offset<u4_t>(&payload_, 0);
flags = buf_offset<flags_t>(&payload_, 4);
id = buf_offset<u2_t>(&payload_, 6);
// data fields numMeas times
uint numMeas = static_cast<uint>(flags.bits.numMeas);
datum.clear();
for (uint i = 0; i < numMeas; i++) {
datum.push_back(buf_offset<data_t>(&payload_, 8 + (i * 4)));
}
// make sure the calibTTags are there
if (flags.bits.calibTtagValid) {
uint calibTtags_start = 8 + (numMeas * 4);
calibTtags = buf_offset<u4_t>(&payload_, calibTtags_start);
}
}
// this payload is used to poll for output from device
std::tuple<u1_t *, size_t> make_poll_payload()
{
payload_.clear();
return std::make_tuple(payload_.data(), payload_.size());
}
std::string to_string()
{
std::ostringstream oss;
oss << "timeTag: " << +timeTag;
oss << " timeMarkSent: " << +flags.bits.timeMarkSent;
oss << " timeMarkEdge: " << +flags.bits.timeMarkEdge;
oss << " calibTragValid: " << +flags.bits.calibTtagValid;
oss << " numMeas: " << +flags.bits.numMeas;
oss << " data: [";
uint numMeas = static_cast<uint>(flags.bits.numMeas);
for (uint i = 0; i < numMeas; i++) {
if (i > 0) {oss << " |";}
data_t & data = datum[i];
oss << " field: " << +data.bits.dataField;
oss << " type: " << +data.bits.dataType;
}
oss << " ]";
oss << +calibTtags;
if (flags.bits.calibTtagValid) {
oss << " " << +calibTtags;
}
return oss.str();
}
};
// this is the full payload - ubx_esf_meas has input & output
// it is an exception to UBX where other cfg items are set via val set
// it uses the local values to create the full payload
class ESFMeasFullPayload : UBXPayload
{
public:
static const msg_class_t MSG_CLASS = UBX_ESF;
static const msg_id_t MSG_ID = UBX_ESF_MEAS;
u4_t timeTag; // ms - GPS Time of week of the navigation epoch.
flags_t flags;
u2_t id;
std::vector<data_t> datum;
u4_t calibTtag; // number of sensors
public:
ESFMeasFullPayload()
: UBXPayload(MSG_CLASS, MSG_ID)
{
}
void load_from_msg(const ublox_ubx_msgs::msg::UBXEsfMeas & msg)
{
// assign number of measurements if 0 use data array size
u8_t num_meas = msg.num_meas;
if (num_meas == 0) {
num_meas = msg.data.size();
}
timeTag = msg.time_tag;
flags.bits.timeMarkSent = msg.time_mark_sent;
flags.bits.timeMarkEdge = msg.time_mark_edge;
flags.bits.calibTtagValid = msg.calib_ttag_valid;
flags.bits.numMeas = num_meas;
id = msg.id;
data_t data;
datum.clear();
for (uint i = 0; i < msg.data.size(); i++) {
data.bits.dataField = msg.data[i].data_field;
data.bits.dataType = msg.data[i].data_type;
datum.push_back(data);
}
if (msg.calib_ttag_valid) {
calibTtag = msg.calib_ttag;
} else {
calibTtag = 0;
}
}
// this payload is used as input to the device
std::tuple<u1_t *, size_t> make_poll_payload()
{
payload_.clear();
buf_append_u4(&payload_, timeTag);
buf_append_x2(&payload_, flags.all);
buf_append_u2(&payload_, id);
auto numMeas = flags.bits.numMeas;
for (uint i = 0; i < numMeas; i++) {
buf_append_x4(&payload_, datum[i].all);
}
if (flags.bits.calibTtagValid) {
buf_append_u4(&payload_, calibTtag);
}
return std::make_tuple(payload_.data(), payload_.size());
}
std::string to_string()
{
std::ostringstream oss;
oss << "timeTag: " << +timeTag;
oss << " timeMarkSent: " << +flags.bits.timeMarkSent;
oss << " timeMarkEdge: " << +flags.bits.timeMarkEdge;
oss << " calibTragValid: " << +flags.bits.calibTtagValid;
oss << " numMeas: " << +flags.bits.numMeas;
oss << " data: [";
uint numMeas = static_cast<uint>(flags.bits.numMeas);
for (uint i = 0; i < numMeas; i++) {
if (i > 0) {oss << " |";}
data_t & data = datum[i];
oss << " field: " << +data.bits.dataField;
oss << " type: " << +data.bits.dataType;
}
oss << " ]";
if (flags.bits.calibTtagValid) {
oss << " calibTtag: " << +calibTtag;
}
return oss.str();
}
};
} // namespace ubx::esf::meas
#endif // UBLOX_DGNSS_NODE__UBX__ESF__UBX_ESF_MEAS_HPP_