Loading [MathJax]/extensions/tex2jax.js
Fixposition SDK 0.0.0-heads/main-0-g53fa5b5
Collection of c++ libraries and apps for use with Fixposition products on Linux
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Making a FP_B-MEASUREMENTS message
1/**
2 * \verbatim
3 * ___ ___
4 * \ \ / /
5 * \ \/ / Copyright (c) Fixposition AG (www.fixposition.com) and contributors
6 * / /\ \ License: see the LICENSE file
7 * /__/ \__\
8 * \endverbatim
9 *
10 * @file
11 * @brief Fixposition SDK examples: Making a FP_B-MEASUREMENTS message
12 *
13 * To build and run:
14 *
15 * make
16 * ./build/fpb_measurements
17 *
18 * This program shows how a FP_B-MEASUREMENTS message can be made.
19 *
20 * This file is both the source code of this example as well as the documentation on how it works.
21 */
22
23/* LIBC/STL */
24#include <cinttypes>
25#include <cmath>
26#include <cstdint>
27#include <cstdio>
28#include <cstdlib>
29#include <cstring>
30
31/* EXTERNAL */
32#include <unistd.h>
33
34/* Fixposition SDK */
35#include <fpsdk_common/app.hpp>
39
40/* PACKAGE */
41
42/* ****************************************************************************************************************** */
43
44using namespace fpsdk::common::time;
45using namespace fpsdk::common::app;
46using namespace fpsdk::common::parser::fpb;
47using namespace fpsdk::common::logging;
48using namespace fpsdk::common::types;
49
50// ---------------------------------------------------------------------------------------------------------------------
51
52int main(int /*argc*/, char** /*argv*/)
53{
54#ifndef NDEBUG
56#endif
57 LoggingSetParams({ LoggingLevel::TRACE });
58
59 // The speed measurement in XYZ in [m/s], two wheels
60 const double speed_FL[3] = { 5.422, -0.02, 0.4 };
61 const double speed_FR[3] = { 6.543, +0.03, 0.5 };
62
63 // The FP_B-MEASUREMENTS message payload consists of two parts:
64 // - 1. The header
66 head.num_meas = 2;
67 // - 2. The measurements. In this example we have two measurements:
68 FpbMeasurementsMeas meas[2];
69 // - FL wheel
70 meas[0].meas_x = std::floor(speed_FL[0] * 1e3); // [m/s] -> [mm/s]
71 meas[0].meas_y = std::floor(speed_FL[1] * 1e3); // [m/s] -> [mm/s]
72 meas[0].meas_z = std::floor(speed_FL[2] * 1e3); // [m/s] -> [mm/s]
73 meas[0].meas_x_valid = 1;
74 meas[0].meas_y_valid = 1;
75 meas[0].meas_z_valid = 1;
76 meas[0].meas_type = EnumToVal(FpbMeasurementsMeasType::VELOCITY);
77 meas[0].meas_loc = EnumToVal(FpbMeasurementsMeasLoc::FL);
78 meas[0].timestamp_type = EnumToVal(FpbMeasurementsTimestampType::TIMEOFARRIVAL);
79 // - FR wheel
80 meas[1].meas_x = std::floor(speed_FR[0] * 1e3); // [m/s] -> [mm/s]
81 meas[1].meas_y = std::floor(speed_FR[1] * 1e3); // [m/s] -> [mm/s]
82 meas[1].meas_z = std::floor(speed_FR[2] * 1e3); // [m/s] -> [mm/s]
83 meas[1].meas_x_valid = 1;
84 meas[1].meas_y_valid = 1;
85 meas[1].meas_z_valid = 1;
86 meas[1].meas_type = EnumToVal(FpbMeasurementsMeasType::VELOCITY);
87 meas[1].meas_loc = EnumToVal(FpbMeasurementsMeasLoc::FR);
88 meas[1].timestamp_type = EnumToVal(FpbMeasurementsTimestampType::TIMEOFARRIVAL);
89
90 // Create the raw payload by copying the structs above to the right place.
91 uint8_t payload[FP_B_MEASUREMENTS_HEAD_SIZE + (FP_B_MEASUREMENTS_MAX_NUM_MEAS * FP_B_MEASUREMENTS_MEAS_SIZE)];
92 std::size_t payload_size = 0;
93 // - The header
94 std::memcpy(&payload[payload_size], &head, sizeof(head));
95 payload_size += sizeof(head);
96 // - The data
97 for (std::size_t ix = 0; (ix < head.num_meas) && (ix < FP_B_MEASUREMENTS_MAX_NUM_MEAS); ix++) {
98 std::memcpy(&payload[payload_size], &meas[ix], sizeof(meas[ix]));
99 payload_size += sizeof(meas[ix]);
100 }
101
102 INFO("num_meas=%" PRIu8 " payload_size=%" PRIuMAX, head.num_meas, payload_size);
103 DEBUG_HEXDUMP(payload, payload_size, NULL, NULL);
104
105 // Create FP_B-MEASUREMENTS message
106 std::vector<uint8_t> message;
107 if (FpbMakeMessage(message, FP_B_MEASUREMENTS_MSGID, 0, payload, payload_size)) {
108 INFO("Message successfully made");
109 DEBUG_HEXDUMP(message.data(), message.size(), NULL, NULL);
110
111 // Print to stdio unless that's a terminal
112 if (isatty(fileno(stdout)) == 0) {
113 write(fileno(stdout), message.data(), message.size());
114 }
115 } else {
116 WARNING("Failed making FP_B-MEASUREMENTS message");
117 }
118
119 // clang-format off
120 // This should output:
121 //
122 // num_meas=2 payload_size=64
123 // 0x0000 00000 01 02 00 00 00 00 00 00 2e 15 00 00 ec ff ff ff |................|
124 // 0x0010 00016 90 01 00 00 01 01 01 01 03 00 00 00 00 01 00 00 |................|
125 // 0x0020 00032 00 00 00 00 8f 19 00 00 1e 00 00 00 f4 01 00 00 |................|
126 // 0x0030 00048 01 01 01 01 02 00 00 00 00 01 00 00 00 00 00 00 |................|
127 // Message successfully made
128 // 0x0000 00000 66 21 d1 07 40 00 00 00 01 02 00 00 00 00 00 00 |f!..@...........|
129 // 0x0010 00016 2e 15 00 00 ec ff ff ff 90 01 00 00 01 01 01 01 |................|
130 // 0x0020 00032 03 00 00 00 00 01 00 00 00 00 00 00 8f 19 00 00 |................|
131 // 0x0030 00048 1e 00 00 00 f4 01 00 00 01 01 01 01 02 00 00 00 |................|
132 // 0x0040 00064 00 01 00 00 00 00 00 00 22 59 21 e2
133 //
134 // The message can be stored to a file:
135 //
136 // ./build/fpb_measurements > fpbmeasurements.bin
137 //
138 // Which can be parsed by the parsertool from the Fixposition SDK:
139 //
140 // parsertool fpbmeasurements.bin
141 //
142 // Which prints something like this:
143 //
144 // ------- Seq# Offset Size Protocol Message Info
145 // Reading from fpbmeasurements.bin
146 // message 000001 0 76 FP_B FP_B-MEASUREMENTS 07d1@0 v1 [2] / 1 3 1 0 0 5422 -20 400 / 1 2 1 0 0 6543 30 500
147 // Stats: Messages Bytes
148 // Total 1 (100.0%) 76 (100.0%)
149 // FP_A 0 ( 0.0%) 0 ( 0.0%)
150 // FP_B 1 (100.0%) 76 (100.0%)
151 // NMEA 0 ( 0.0%) 0 ( 0.0%)
152 // UBX 0 ( 0.0%) 0 ( 0.0%)
153 // RTCM3 0 ( 0.0%) 0 ( 0.0%)
154 // NOV_B 0 ( 0.0%) 0 ( 0.0%)
155 // UNI_B 0 ( 0.0%) 0 ( 0.0%)
156 // SPARTN 0 ( 0.0%) 0 ( 0.0%)
157 // OTHER 0 ( 0.0%) 0 ( 0.0%)
158 // Done
159 // clang-format on
160
161 return EXIT_SUCCESS;
162}
163
164/* ****************************************************************************************************************** */
Fixposition SDK: Utilities for apps.
Helper to print a strack trace on SIGSEGV and SIGABRT.
Definition app.hpp:139
Fixposition SDK: Parser FP_B routines and types.
Fixposition SDK: Logging.
#define WARNING(...)
Print a warning message.
Definition logging.hpp:81
#define DEBUG_HEXDUMP(data, size, prefix,...)
Print a debug hexdump.
Definition logging.hpp:97
#define INFO(...)
Print a info message.
Definition logging.hpp:89
Utilities for apps.
Definition app.hpp:34
Parser FP_B routines and types.
Definition fpb.hpp:105
bool FpbMakeMessage(std::vector< uint8_t > &msg, const uint16_t msg_id, const uint16_t msg_time, const std::vector< uint8_t > &payload)
Make a FP_B message.
Time utilities.
Definition time.hpp:39
Common types.
Definition types.hpp:35
constexpr std::underlying_type< T >::type EnumToVal(T enum_val)
Convert enum class constant to the underlying integral type value.
Definition types.hpp:47
FP_B-MEASUREMENTS payload: head.
Definition fpb.hpp:328
uint8_t num_meas
Number of measurements in the body (1..FP_B_MEASUREMENTS_MAX_NUM_MEAS)
Definition fpb.hpp:331
FP_B-MEASUREMENTS payload: measurement.
Definition fpb.hpp:369
uint8_t timestamp_type
See FpbMeasurementsTimestampType.
Definition fpb.hpp:383
uint8_t meas_y_valid
Validity of measurement y (1 = meas_x contains valid data, 0 = data invalid or n/a)
Definition fpb.hpp:375
uint8_t meas_z_valid
Validity of measurement z (1 = meas_x contains valid data, 0 = data invalid or n/a)
Definition fpb.hpp:376
uint8_t meas_type
See FpbMeasurementsMeasType.
Definition fpb.hpp:378
uint8_t meas_x_valid
Validity of measurement x (1 = meas_x contains valid data, 0 = data invalid or n/a)
Definition fpb.hpp:374
uint8_t meas_loc
See FpbMeasurementsMeasLoc.
Definition fpb.hpp:380
Fixposition SDK: Common types and type helpers.