configuration.h
Go to the documentation of this file.
1 /**************************************************************************/ /**
2  * @brief Device configuration settings control messages.
3  * @file
4  ******************************************************************************/
5 
6 #pragma once
7 
11 
12 namespace point_one {
13 namespace fusion_engine {
14 namespace messages {
15 
16 // Enforce 4-byte alignment and packing of all data structures and values.
17 // Floating point values are aligned on platforms that require it. This is done
18 // with a combination of setting struct attributes, and manual alignment
19 // within the definitions. See the "Message Packing" section of the README.
20 #pragma pack(push, 1)
21 
22 /**************************************************************************/ /**
23  * @defgroup config_types Device Configuration Settings Control
24  * @brief Messages/types for configuring device parameters (lever arms,
25  * orientation, wheel speed settings, etc.).
26  * @ingroup config_and_ctrl_messages
27  *
28  * See also @ref import_export.
29  ******************************************************************************/
30 
31 /**
32  * @brief An identifier for the contents of a parameter configuration message.
33  * @ingroup config_types
34  *
35  * See also @ref SetConfigMessage.
36  */
37 enum class ConfigType : uint16_t {
38  INVALID = 0,
39 
40  /**
41  * The location of the device IMU with respect to the vehicle body frame,
42  * resolved in the vehicle body frame (in meters).
43  *
44  * Payload format: @ref Point3f
45  */
46  DEVICE_LEVER_ARM = 16,
47 
48  /**
49  * The orientation of the device IMU with respect to the vehicle body axes.
50  *
51  * Payload format: @ref CoarseOrientation
52  */
54 
55  /**
56  * The location of the primary GNSS antenna with respect to the vehicle body
57  * frame, resolved in the vehicle body frame (in meters).
58  *
59  * Payload format: @ref Point3f
60  */
61  GNSS_LEVER_ARM = 18,
62 
63  /**
64  * The offset of the desired output location with respect to the vehicle
65  * body frame, resolved in the vehicle body frame (in meters).
66  *
67  * Payload format: @ref Point3f
68  */
69  OUTPUT_LEVER_ARM = 19,
70 
71  /**
72  * Information about the vehicle including model and dimensions.
73  *
74  * Payload format: @ref VehicleDetails
75  */
76  VEHICLE_DETAILS = 20,
77 
78  /**
79  * Information pertaining to wheel speed/rotation measurements when wheel data
80  * is transmitted via software.
81  *
82  * @note
83  * For hardware wheel tick voltage capture, use @ref
84  * ConfigType::HARDWARE_TICK_CONFIG instead.
85  *
86  * Payload format: @ref WheelConfig
87  */
88  WHEEL_CONFIG = 21,
89 
90  /**
91  * Indicates the mode and direction used when capturing vehicle wheel tick
92  * data from a voltage pulse on an I/O pin.
93  *
94  * @note
95  * For software wheel tick capture (wheel ticks sent as FusionEngine messages
96  * or on a CAN bus), use @ref ConfigType::WHEEL_CONFIG instead.
97  *
98  * Payload format: @ref HardwareTickConfig
99  */
101 
102  /**
103  * Used to set horizontal (yaw) & vertical (pitch) biases (in degrees) on
104  * a dual-antenna heading platform configuration (deprecated).
105  *
106  * @deprecated
107  * Use @ref ConfigType::GNSS_AUX_LEVER_ARM instead.
108  */
110 
111  /**
112  * The location of the secondary GNSS antenna with respect to the vehicle body
113  * frame on a dual-antenna platform, resolved in the vehicle body frame (in
114  * meters).
115  *
116  * For dual-antenna systems, the secondary or auxiliary antenna is used to
117  * measure vehicle yaw and pitch.
118  *
119  * Payload format: @ref Point3f
120  */
121  GNSS_AUX_LEVER_ARM = 24,
122 
123  /**
124  * A bitmask indicating which GNSS constellations are enabled.
125  *
126  * Payload format: `uint32_t` (see @ref sat_type_masks)
127  */
129 
130  /**
131  * A bitmask indicating which GNSS frequency bands are enabled.
132  *
133  * Payload format: `uint32_t` (see @ref freq_band_masks)
134  */
136 
137  /**
138  * Specify a UTC leap second count override value to use for all UTC time
139  * conversions. Setting this value will disable all internal leap second
140  * sources, including data received from the GNSS almanac decoded from
141  * available signals.
142  *
143  * Set to -1 to disable leap second override and re-enable internal leap
144  * second handling.
145  *
146  * Payload format: `int32_t`
147  */
148  LEAP_SECOND = 52,
149 
150  /**
151  * Specify a GPS legacy week rollover count override to use when converting
152  * all legacy 10-bit GPS week numbers. Setting this value will disable all
153  * internal week rollover sources, including data received from modern GPS
154  * navigation messages (CNAV, CNAV2) or non-GPS constellations.
155  *
156  * Set to -1 to disable week rollover override and re-enable internal
157  * handling.
158  *
159  * Payload format: `int32_t`
160  */
161  GPS_WEEK_ROLLOVER = 53,
162 
163  /**
164  * Ionospheric delay model configuration.
165  *
166  * Payload format: @ref IonosphereConfig
167  */
168  IONOSPHERE_CONFIG = 54,
169 
170  /**
171  * Tropospheric delay model configuration.
172  *
173  * Payload format: @ref TroposphereConfig
174  */
175  TROPOSPHERE_CONFIG = 55,
176 
177  /**
178  * Change a configuration setting for a specified output interface.
179  *
180  * Payload format: `InterfaceConfigSubmessage`
181  */
182  INTERFACE_CONFIG = 200,
183 
184  /**
185  * Configure the UART1 serial baud rate (in bits/second).
186  *
187  * @deprecated
188  * The @ref ConfigType::INTERFACE_CONFIG type combined with @ref
189  * InterfaceConfigType::BAUD_RATE in the @ref InterfaceConfigSubmessage should
190  * be used to configure this value going forward.
191  *
192  * Payload format: `uint32_t`
193  */
194  UART1_BAUD = 256,
195 
196  /**
197  * Configure the UART2 serial baud rate (in bits/second).
198  *
199  * @deprecated
200  * The @ref ConfigType::INTERFACE_CONFIG type combined with @ref
201  * InterfaceConfigType::BAUD_RATE in the @ref InterfaceConfigSubmessage should
202  * be used to configure this value going forward.
203  *
204  * Payload format: `uint32_t`
205  */
206  UART2_BAUD = 257,
207 
208  /**
209  * Enable/disable output of diagnostic data on UART1.
210  *
211  * @deprecated
212  * The @ref ConfigType::INTERFACE_CONFIG type combined with @ref
213  * InterfaceConfigType::OUTPUT_DIAGNOSTICS_MESSAGES in the @ref
214  * InterfaceConfigSubmessage should be used to configure this value going
215  * forward.
216  *
217  * @note
218  * Enabling this setting will override the message rate/off settings for some
219  * FusionEngine messages.
220  *
221  * Payload format: `bool`
222  */
224 
225  /**
226  * Enable/disable output of diagnostic data on UART2.
227  *
228  * @deprecated
229  * The @ref ConfigType::INTERFACE_CONFIG type combined with @ref
230  * InterfaceConfigType::OUTPUT_DIAGNOSTICS_MESSAGES in the @ref
231  * InterfaceConfigSubmessage should be used to configure this value going
232  * forward.
233  *
234  * @note
235  * Enabling this setting will override the message rate/off settings for some
236  * FusionEngine messages.
237  *
238  * Payload format: `bool`
239  */
241 
242  /**
243  * Enable watchdog timer to restart device after fatal errors.
244  *
245  * Payload format: `bool`
246  */
247  ENABLE_WATCHDOG_TIMER = 300,
248 
249  /**
250  * A string for identifying a device.
251  *
252  * This is a string of ASCII characters padded to 32 bytes with `NULL`.
253  *
254  * Payload format: `char[32]`
255  */
256  USER_DEVICE_ID = 301,
257 
258  /**
259  * A bitmask indicating which profiling features are enabled.
260  *
261  * Payload format: `uint8_t` (`0` for disabled and `0xFF` for all features
262  * enabled. Individual bits are device specific.)
263  */
264  PROFILING_MASK = 310,
265 
266  /**
267  * Configuration of L-band Demodulator Parameters.
268  *
269  * @note
270  * This setting is only available on devices with an L-band receiver.
271  *
272  * Payload format: @ref LBandConfig
273  */
274  LBAND_PARAMETERS = 1024,
275 };
276 
277 /**
278  * @brief Get a human-friendly string name for the specified @ref ConfigType.
279  * @ingroup config_types
280  *
281  * @param type The desired configuration parameter type.
282  *
283  * @return The corresponding string name.
284  */
286  switch (type) {
287  case ConfigType::INVALID:
288  return "Invalid";
289 
291  return "Device Lever Arm";
292 
294  return "Device Coarse Orientation";
295 
297  return "GNSS Lever Arm";
298 
300  return "Output Lever Arm";
301 
303  return "Vehicle Details";
304 
306  return "Wheel Config";
307 
309  return "Hardware Tick Config";
310 
312  return "Heading Bias";
313 
315  return "GNSS Aux Lever Arm";
316 
318  return "Enabled GNSS Systems";
319 
321  return "Enabled GNSS Frequency Bands";
322 
324  return "Leap Second";
325 
327  return "GPS Week Rollover";
328 
330  return "Ionosphere Config";
331 
333  return "Troposphere Config";
334 
336  return "UART1 Baud Rate";
337 
339  return "UART2 Baud Rate";
340 
342  return "UART1 Diagnostic Messages Enabled";
343 
345  return "UART2 Diagnostic Messages Enabled";
346 
348  return "Watchdog Timer Enabled";
349 
351  return "User Device ID";
352 
354  return "Profiling Features Enabled";
355 
357  return "Interface Submessage";
358 
360  return "LBand Parameters";
361  }
362 
363  return "Unrecognized Configuration";
364 }
365 
366 /**
367  * @brief @ref ConfigType stream operator.
368  * @ingroup config_types
369  */
370 inline p1_ostream& operator<<(p1_ostream& stream, ConfigType type) {
371  stream << to_string(type) << " (" << (int)type << ")";
372  return stream;
373 }
374 
375 /**
376  * @brief The type of a device's configuration settings.
377  * @ingroup config_types
378  */
379 enum class ConfigurationSource : uint8_t {
380  ACTIVE = 0, ///< Active configuration currently in use by the device.
381  SAVED = 1, ///< Settings currently saved to persistent storage.
382  /**
383  * Read only device defaults. Attempting to write to this source will fail
384  * with a @ref Response::VALUE_ERROR.
385  */
386  DEFAULT = 2,
387 };
388 
389 /**
390  * @brief Get a human-friendly string name for the specified @ref
391  * ConfigurationSource.
392  * @ingroup config_types
393  *
394  * @param source The desired configuration source.
395  *
396  * @return The corresponding string name.
397  */
399  switch (source) {
401  return "Active";
402 
404  return "Saved";
405 
407  return "Default";
408 
409  default:
410  return "Unrecognized Source";
411  }
412 }
413 
414 /**
415  * @brief @ref ConfigurationSource stream operator.
416  * @ingroup config_types
417  */
419  stream << to_string(source) << " (" << (int)source << ")";
420  return stream;
421 }
422 
423 /**
424  * @brief The type configuration save operation to be performed.
425  * @ingroup config_types
426  */
427 enum class SaveAction : uint8_t {
428  /** Save all active parameters to persistent storage. */
429  SAVE = 0,
430  /** Revert the active configuration to previously saved values. */
431  REVERT_TO_SAVED = 1,
432  /** Reset the active _and_ saved configuration to default values. */
433  REVERT_TO_DEFAULT = 2,
434 };
435 
436 /**
437  * @brief Get a human-friendly string name for the specified @ref SaveAction.
438  * @ingroup config_types
439  *
440  * @param action The desired save operation.
441  *
442  * @return The corresponding string name.
443  */
445  switch (action) {
446  case SaveAction::SAVE:
447  return "Save";
448 
450  return "Revert To Saved";
451 
453  return "Revert To Default";
454 
455  default:
456  return "Unknown";
457  }
458 }
459 
460 /**
461  * @brief @ref SaveAction stream operator.
462  * @ingroup config_types
463  */
464 inline p1_ostream& operator<<(p1_ostream& stream, SaveAction action) {
465  stream << to_string(action) << " (" << (int)action << ")";
466  return stream;
467 }
468 
469 /**
470  * @brief Set a user configuration parameter (@ref MessageType::SET_CONFIG,
471  * version 1.0).
472  * @ingroup config_types
473  *
474  * This message must be followed by the parameter value to be used:
475  *
476  * ```
477  * {MessageHeader, SetConfigMessage, Parameter[data_length_bytes]}
478  * ```
479  *
480  * The format of the parameter value is defined by the the specified @ref
481  * config_type (@ref ConfigType). For example, an antenna lever arm definition
482  * may require three 32-bit `float` values, one for each axis, while a serial
483  * port baud rate may be specified as single 32-bit unsigned integer
484  * (`uint32_t`).
485  *
486  * Not all parameters defined in @ref ConfigType are supported on all devices.
487  *
488  * Parameter changes are applied to the device's active configuration
489  * immediately, but are not saved to persistent storage and will be restored to
490  * their previous values on reset. To save configuration settings to persistent
491  * storage, see @ref SaveConfigMessage.
492  *
493  * # Expected Response
494  * The device will respond with a @ref CommandResponseMessage indicating whether
495  * or not the request succeeded.
496  */
498  static constexpr MessageType MESSAGE_TYPE = MessageType::SET_CONFIG;
499  static constexpr uint8_t MESSAGE_VERSION = 0;
500 
501  /** Flag to immediately save the config after applying this setting. */
502  static constexpr uint8_t FLAG_APPLY_AND_SAVE = 0x01;
503  /**
504  * Flag to restore the config_type back to its default value.
505  *
506  * When set, the @ref config_length_bytes should be 0 and no data should be
507  * included unless the config_type is @ref ConfigType::INTERFACE_CONFIG. In
508  * that case the @ref config_length_bytes should be
509  * `sizeof(InterfaceConfigSubmessage)` with a an @ref
510  * InterfaceConfigSubmessage as the parameter value without any further
511  * payload.
512  */
513  static constexpr uint8_t FLAG_REVERT_TO_DEFAULT = 0x02;
514 
515  /** The type of parameter to be configured. */
517 
518  /** Bitmask of additional flags to modify the command. */
519  uint8_t flags = 0;
520 
521  uint8_t reserved[1] = {0};
522 
523  /** The size of the parameter value (in bytes). */
524  uint32_t config_length_bytes = 0;
525 };
526 
527 /**
528  * @brief Query the value of a user configuration parameter (@ref
529  * MessageType::GET_CONFIG, version 1.1).
530  * @ingroup config_types
531  *
532  * # Expected Response
533  * The device will respond with a @ref ConfigResponseMessage containing the
534  * requested parameter value or an error @ref Response value if the request did
535  * not succeed.
536  */
538  static constexpr MessageType MESSAGE_TYPE = MessageType::GET_CONFIG;
539  static constexpr uint8_t MESSAGE_VERSION = 1;
540 
541  /** The desired parameter. */
543 
544  /** The config source to request data from (active, saved, etc.). */
546 
547  uint8_t reserved[1] = {0};
548 
549  /**
550  * When @ref config_type is @ref ConfigType::INTERFACE_CONFIG, a @ref
551  * InterfaceConfigSubmessage must be added to the end of this message with
552  * empty @ref InterfaceConfigSubmessage::config_data.
553  */
554  //uint8_t optional_submessage_header[0];
555 };
556 
557 /**
558  * @brief Save or reload configuration settings (@ref MessageType::SAVE_CONFIG,
559  * version 1.0).
560  * @ingroup config_types
561  *
562  * # Expected Response
563  * The device will respond with a @ref CommandResponseMessage indicating whether
564  * or not the request succeeded.
565  */
567  static constexpr MessageType MESSAGE_TYPE = MessageType::SAVE_CONFIG;
568  static constexpr uint8_t MESSAGE_VERSION = 0;
569 
570  /** The action to performed. */
572 
573  uint8_t reserved[3] = {0};
574 };
575 
576 /**
577  * @brief Response to a @ref GetConfigMessage request (@ref
578  * MessageType::CONFIG_RESPONSE, version 1.0).
579  * @ingroup config_types
580  *
581  * This message is followed by `N` bytes, where `N` is equal to @ref
582  * config_length_bytes that make up the data associated with @ref config_type.
583  * For example if the @ref config_type is @ref ConfigType::UART1_BAUD, the
584  * payload will include a single 32-bit unsigned integer:
585  *
586  * ```
587  * {MessageHeader, ConfigResponseMessage, uint32_t}
588  * ```
589  *
590  * In response to a @ref GetConfigMessage with an invalid or unsupported @ref
591  * ConfigType, @ref config_type in the resulting @ref ConfigResponseMessage will
592  * be set to @ref ConfigType::INVALID, and @ref response will indicate the
593  * reason. Note that all @ref GetConfigMessage requests, including invalid and
594  * rejected requests, will receive a @ref ConfigResponseMessage, not a
595  * @ref CommandResponseMessage.
596  */
598  static constexpr MessageType MESSAGE_TYPE = MessageType::CONFIG_RESPONSE;
599  static constexpr uint8_t MESSAGE_VERSION = 0;
600 
601  /**
602  * Flag to indicate the active value for this configuration differs from the
603  * value saved to persistent memory.
604  */
605  static constexpr uint8_t FLAG_ACTIVE_DIFFERS_FROM_SAVED = 0x1;
606 
607  /** The source of the parameter value (active, saved, etc.). */
609 
610  /** Flags that describe the configuration parameter. */
611  uint8_t flags = 0;
612 
613  /** The type of configuration parameter contained in this message. */
615 
616  /** The response status (success, error, etc.). */
617  Response response = Response::OK;
618 
619  uint8_t reserved[3] = {0};
620 
621  /** The size of the parameter value (in bytes). */
622  uint32_t config_length_bytes = 0;
623 
624  /**
625  * A pointer to the beginning of the configuration parameter value.
626  *
627  * The size and format of the contents is specified by the @ref config_type.
628  * See @ref ConfigType.
629  */
630  //uint8_t config_change_data[0];
631 };
632 
633 /**
634  * @brief A 3-dimensional vector (used for lever arms, etc.).
635  * @ingroup config_types
636  */
637 struct P1_ALIGNAS(4) Point3f {
638  float x = NAN;
639  float y = NAN;
640  float z = NAN;
641 };
642 
643 /**
644  * @brief The orientation of a device with respect to the vehicle body axes.
645  * @ingroup config_types
646  *
647  * A device's orientation is defined by specifying how the +x and +z axes of its
648  * IMU are aligned with the vehicle body axes. For example, in a car:
649  * - `forward,up`: device +x = vehicle +x, device +z = vehicle +z (i.e.,
650  * IMU pointed towards the front of the vehicle).
651  * - `left,up`: device +x = vehicle +y, device +z = vehicle +z (i.e., IMU
652  * pointed towards the left side of the vehicle)
653  * - `up,backward`: device +x = vehicle +z, device +z = vehicle -x (i.e.,
654  * IMU pointed vertically upward, with the top of the IMU pointed towards the
655  * trunk)
656  */
658  enum class Direction : uint8_t {
659  FORWARD = 0, ///< Aligned with vehicle +x axis.
660  BACKWARD = 1, ///< Aligned with vehicle -x axis.
661  LEFT = 2, ///< Aligned with vehicle +y axis.
662  RIGHT = 3, ///< Aligned with vehicle -y axis.
663  UP = 4, ///< Aligned with vehicle +z axis.
664  DOWN = 5, ///< Aligned with vehicle -z axis.
665  INVALID = 255
666  };
667 
668  /** The direction of the device +x axis relative to the vehicle body axes. */
669  Direction x_direction = Direction::FORWARD;
670 
671  /** The direction of the device +z axis relative to the vehicle body axes. */
672  Direction z_direction = Direction::UP;
673 
674  uint8_t reserved[2] = {0};
675 };
676 
677 /**
678  * @brief The make and model of the vehicle.
679  * @ingroup config_types
680  */
681 enum class VehicleModel : uint16_t {
682  UNKNOWN_VEHICLE = 0,
683  DATASPEED_CD4 = 1,
684  // In general, all J1939 vehicles support a subset of the J1939 standard and
685  // may be set to vehicle model `J1939`. Their 29-bit CAN IDs may differ
686  // based on how the platform assigns message priorities and source
687  // addresses, but the underlying program group number (PGN) and message
688  // contents will be consistent.
689  //
690  // For most vehicles, it is not necessary to specify and particular make and
691  // model.
692  J1939 = 2,
693 
694  LEXUS_CT200H = 20,
695 
696  KIA_SORENTO = 40,
697  KIA_SPORTAGE = 41,
698 
699  AUDI_Q7 = 60,
700  AUDI_A8L = 61,
701 
702  TESLA_MODEL_X = 80,
703  TESLA_MODEL_3 = 81,
704 
705  HYUNDAI_ELANTRA = 100,
706 
707  PEUGEOT_206 = 120,
708 
709  MAN_TGX = 140,
710 
711  FACTION = 160,
712  FACTION_V2 = 161,
713 
714  LINCOLN_MKZ = 180,
715 
716  BMW_7 = 200,
717  BMW_MOTORRAD = 201,
718 
719  VW_4 = 220,
720 
721  RIVIAN = 240,
722 };
723 
724 /**
725  * @brief Get a human-friendly string name for the specified @ref VehicleModel.
726  * @ingroup config_types
727  *
728  * @param vehicle_model The desired vehicle model.
729  *
730  * @return The corresponding string name.
731  */
732 P1_CONSTEXPR_FUNC const char* to_string(VehicleModel vehicle_model) {
733  switch (vehicle_model) {
735  return "UNKNOWN";
737  return "DATASPEED_CD4";
738  case VehicleModel::J1939:
739  return "J1939";
741  return "LEXUS_CT200H";
743  return "KIA_SORENTO";
745  return "KIA_SPORTAGE";
747  return "AUDI_Q7";
749  return "AUDI_A8L";
751  return "TESLA_MODEL_X";
753  return "TESLA_MODEL_3";
755  return "HYUNDAI_ELANTRA";
757  return "PEUGEOT_206";
759  return "MAN_TGX";
761  return "FACTION";
763  return "FACTION_V2";
765  return "LINCOLN_MKZ";
766  case VehicleModel::BMW_7:
767  return "BMW_7";
769  return "BMW_MOTORRAD";
770  case VehicleModel::VW_4:
771  return "VW_4";
773  return "RIVIAN";
774  default:
775  return "UNRECOGNIZED";
776  }
777 }
778 
779 /**
780  * @brief @ref VehicleModel stream operator.
781  * @ingroup config_types
782  */
783 inline p1_ostream& operator<<(p1_ostream& stream, VehicleModel vehicle_model) {
784  stream << to_string(vehicle_model) << " (" << (int)vehicle_model << ")";
785  return stream;
786 }
787 
788 /**
789  * @brief Information about the vehicle including model and dimensions.
790  * @ingroup config_types
791  */
794  uint8_t reserved[10] = {0};
795 
796  /** The distance between the front axle and rear axle (in meters). */
797  float wheelbase_m = NAN;
798 
799  /** The distance between the two front wheels (in meters). */
800  float front_track_width_m = NAN;
801 
802  /** The distance between the two rear wheels (in meters). */
803  float rear_track_width_m = NAN;
804 };
805 
806 /**
807  * @brief The type of vehicle/wheel speed measurements produced by the vehicle.
808  * @ingroup config_types
809  */
810 enum class WheelSensorType : uint8_t {
811  /** Wheel/vehicle speed data not available. */
812  NONE = 0,
813  // RESERVED = 1,
814  /**
815  * Individual rotational angle measurements for multiple wheels, reported as
816  * accumulated encoder ticks. See @ref WheelTickInput.
817  * */
818  TICKS = 2,
819  /**
820  * Individual speed measurements for multiple wheels, reported in
821  * meters/second. See @ref WheelSpeedInput.
822  */
823  WHEEL_SPEED = 3,
824  /**
825  * A single value indicating the vehicle speed (in meters/second). See @ref
826  * VehicleSpeedInput.
827  */
828  VEHICLE_SPEED = 4,
829  /**
830  * A single wheel rotational angle, reported as accumulated encoder ticks. See
831  * @ref VehicleSpeedInput.
832  */
833  VEHICLE_TICKS = 5,
834 };
835 
836 /**
837  * @brief Get a human-friendly string name for the specified @ref
838  * WheelSensorType.
839  * @ingroup config_types
840  *
841  * @param wheel_sensor_type The desired wheel sensor type.
842  *
843  * @return The corresponding string name.
844  */
845 P1_CONSTEXPR_FUNC const char* to_string(WheelSensorType wheel_sensor_type) {
846  switch (wheel_sensor_type) {
847  case WheelSensorType::NONE: {
848  return "None";
849  }
850  case WheelSensorType::TICKS: {
851  return "Ticks";
852  }
854  return "Wheel Speed";
855  }
857  return "Vehicle Speed";
858  }
860  return "Vehicle Ticks";
861  }
862  default: {
863  return "None";
864  }
865  }
866 }
867 
868 /**
869  * @brief @ref WheelSensorType stream operator.
870  * @ingroup config_types
871  */
873  WheelSensorType wheel_sensor_type) {
874  stream << to_string(wheel_sensor_type) << " (" << (int)wheel_sensor_type
875  << ")";
876  return stream;
877 }
878 
879 /**
880  * @brief The type of vehicle/wheel speed measurements to be applied.
881  * @ingroup config_types
882  */
883 enum class AppliedSpeedType : uint8_t {
884  /** Speed data not applied to the system. */
885  NONE = 0,
886  /** Rear wheel speed data to be applied to the system (recommended). */
887  REAR_WHEELS = 1,
888  /** Front wheel speed data to be applied to the system. */
889  FRONT_WHEELS = 2,
890  /** Front and rear wheel speed data to be applied to the system. */
892  /** Individual vehicle speed to be applied to the system. */
893  VEHICLE_BODY = 4,
894 };
895 
896 /**
897  * @brief Get a human-friendly string name for the specified @ref
898  * AppliedSpeedType.
899  * @ingroup config_types
900  *
901  * @param applied_speed_type The desired applied speed type.
902  *
903  * @return The corresponding string name.
904  */
905 P1_CONSTEXPR_FUNC const char* to_string(AppliedSpeedType applied_speed_type) {
906  switch (applied_speed_type) {
907  case AppliedSpeedType::NONE: {
908  return "None";
909  }
911  return "Rear Wheels";
912  }
914  return "Front Wheels";
915  }
917  return "Front and Rear Wheels";
918  }
920  return "Vehicle Body";
921  }
922  default: {
923  return "Unrecognized";
924  }
925  }
926 }
927 
928 /**
929  * @brief @ref AppliedSpeedType stream operator.
930  * @ingroup config_types
931  */
933  AppliedSpeedType applied_speed_type) {
934  stream << to_string(applied_speed_type) << " (" << (int)applied_speed_type
935  << ")";
936  return stream;
937 }
938 
939 /**
940  * @brief Indication of which of the vehicle's wheels are steered.
941  * @ingroup config_types
942  */
943 enum class SteeringType : uint8_t {
944  /** Steered wheels unknown. */
945  UNKNOWN = 0,
946  /** Front wheels are steered. */
947  FRONT = 1,
948  /** Front and rear wheels are steered. */
949  FRONT_AND_REAR = 2,
950 };
951 
952 /**
953  * @brief Get a human-friendly string name for the specified @ref SteeringType.
954  * @ingroup config_types
955  *
956  * @param steering_type The desired steering type.
957  *
958  * @return The corresponding string name.
959  */
960 P1_CONSTEXPR_FUNC const char* to_string(SteeringType steering_type) {
961  switch (steering_type) {
962  case SteeringType::UNKNOWN: {
963  return "Unknown Steering";
964  }
965  case SteeringType::FRONT: {
966  return "Front Steering";
967  }
969  return "Front and Rear Steering";
970  }
971  default: {
972  return "Unrecognized";
973  }
974  }
975 }
976 
977 /**
978  * @brief @ref SteeringType stream operator.
979  * @ingroup config_types
980  */
981 inline p1_ostream& operator<<(p1_ostream& stream, SteeringType steering_type) {
982  stream << to_string(steering_type) << " (" << (int)steering_type << ")";
983  return stream;
984 }
985 
986 /**
987  * @brief Software vehicle/wheel speed measurement configuration settings.
988  * @ingroup config_types
989  *
990  * @warning
991  * The @ref WheelConfig payload is intended for use on vehicles where wheel
992  * speed or angle (tick) data is received via software, either using
993  * FusionEngine measurement messages, or from another software data source such
994  * as a vehicle CAN bus. For vehicles using a hardware wheel tick voltage
995  * signal, use @ref HardwareTickConfig instead.
996  *
997  * Wheel data may be differential (measurements from each individual wheel), or
998  * scalar (a single speed measurement for the vehicle body).
999  *
1000  * When using software wheel data, you must also specify @ref VehicleDetails,
1001  * which is used to describe the vehicle dimensions and make/model.
1002  *
1003  * See also:
1004  * - @ref WheelSpeedInput
1005  * - @ref VehicleSpeedInput
1006  * - @ref WheelTickInput
1007  * - @ref VehicleTickInput
1008  */
1010  /**
1011  * The type of vehicle/wheel speed measurements produced by the vehicle.
1012  */
1014 
1015  /**
1016  * The type of vehicle/wheel speed measurements to be applied to the
1017  * navigation solution.
1018  */
1020 
1021  /** Indication of which of the vehicle's wheels are steered. */
1023 
1024  uint8_t reserved1[1] = {0};
1025 
1026  /**
1027  * The rate at which wheel speed/tick measurements will be sent to the device
1028  * (in seconds).
1029  *
1030  * @note
1031  * This parameter is required when using software wheel measurements. It
1032  * may not be `NAN` if wheel measurements are enabled, and cannot be
1033  * determined automatically by the device.
1034  */
1035  float wheel_update_interval_sec = NAN;
1036 
1037  /**
1038  * Override the rate at which wheel tick measurements will be used by the
1039  * navigation engine (in seconds).
1040  *
1041  * If this parameter is `NAN` (default), the best rate will be selected
1042  * automatically by the device based on the input rate (@ref
1043  * wheel_update_interval_sec) and the wheel tick quantization (@ref
1044  * wheel_ticks_to_m).
1045  *
1046  * @warning
1047  * For most system configurations, we recommend setting this value to `NAN` to
1048  * let the device choose the appropriate setting. Use this setting with
1049  * caution.
1050  */
1051  float wheel_tick_output_interval_sec = NAN;
1052 
1053  /**
1054  * Ratio between angle of the steering wheel and the angle of the wheels on
1055  * the ground.
1056  *
1057  * Used when applying measurements from steered wheels only, ignored
1058  * otherwise.
1059  */
1060  float steering_ratio = NAN;
1061 
1062  /**
1063  * The scale factor to convert from wheel encoder ticks to distance (in
1064  * meters/tick).
1065  *
1066  * Used for @ref WheelSensorType::TICKS and @ref
1067  * WheelSensorType::VEHICLE_TICKS, ignored for wheel speed input.
1068  */
1069  float wheel_ticks_to_m = NAN;
1070 
1071  /**
1072  * The maximum value (inclusive) before the wheel tick measurement will roll
1073  * over.
1074  *
1075  * The rollover behavior depends on the value of @ref wheel_ticks_signed. For
1076  * example, a maximum value of 10 will work as follows:
1077  * - `wheel_ticks_signed == true`: [-11, 10]
1078  * - `wheel_ticks_signed == false`: [0, 10]
1079  *
1080  * Signed values are assumed to be asymmetric, consistent with a typical 2's
1081  * complement rollover.
1082  *
1083  * Used for @ref WheelSensorType::TICKS and @ref
1084  * WheelSensorType::VEHICLE_TICKS, ignored for wheel speed input.
1085  */
1086  uint32_t wheel_tick_max_value = 0;
1087 
1088  /**
1089  * `true` if the reported wheel tick measurements should be interpreted as
1090  * signed integers, or `false` if they should be interpreted as unsigned
1091  * integers.
1092  *
1093  * Used for @ref WheelSensorType::TICKS and @ref
1094  * WheelSensorType::VEHICLE_TICKS, ignored for wheel speed input. See
1095  * @ref wheel_tick_max_value for details.
1096  */
1097  bool wheel_ticks_signed = false;
1098 
1099  /**
1100  * `true` if the wheel tick measurements increase by a positive amount when
1101  * driving forward or backward. `false` if wheel tick measurements decrease
1102  * when driving backward.
1103  *
1104  * Used for @ref WheelSensorType::TICKS and @ref
1105  * WheelSensorType::VEHICLE_TICKS, ignored for wheel speed input.
1106  */
1107  bool wheel_ticks_always_increase = true;
1108 
1109  uint8_t reserved2[2] = {0};
1110 };
1111 
1112 /**
1113  * @brief The signal edge to use when capturing a wheel tick voltage signal.
1114  * @ingroup config_types
1115  */
1116 enum class TickMode : uint8_t {
1117  /** Wheel tick capture disabled. */
1118  OFF = 0,
1119  /** Capture a wheel tick on the rising edge of the incoming pulse. */
1120  RISING_EDGE = 1,
1121  /** Capture a wheel tick on the falling edge of the incoming pulse. */
1122  FALLING_EDGE = 2,
1123 };
1124 
1125 P1_CONSTEXPR_FUNC const char* to_string(TickMode tick_mode) {
1126  switch (tick_mode) {
1127  case TickMode::OFF:
1128  return "OFF";
1129  case TickMode::RISING_EDGE:
1130  return "RISING_EDGE";
1132  return "FALLING_EDGE";
1133  default:
1134  return "UNRECOGNIZED";
1135  }
1136 }
1137 
1138 /**
1139  * @brief @ref TickMode stream operator.
1140  * @ingroup config_types
1141  */
1142 inline p1_ostream& operator<<(p1_ostream& stream, TickMode tick_mode) {
1143  stream << to_string(tick_mode) << " (" << (int)tick_mode << ")";
1144  return stream;
1145 }
1146 
1147 /**
1148  * @brief The way to interpret an incoming voltage signal, used to indicate
1149  * direction of a hardware wheel tick pulse, if available.
1150  * @ingroup config_types
1151  */
1152 enum class TickDirection : uint8_t {
1153  /** Wheel tick direction not provided. */
1154  OFF = 0,
1155  /**
1156  * Assume vehicle is moving forward when direction signal voltage is high, and
1157  * backward when direction signal is low.
1158  */
1159  FORWARD_ACTIVE_HIGH = 1,
1160  /**
1161  * Assume vehicle is moving forward when direction signal voltage is low, and
1162  * backward when direction signal is high.
1163  */
1164  FORWARD_ACTIVE_LOW = 2,
1165 };
1166 
1167 P1_CONSTEXPR_FUNC const char* to_string(TickDirection tick_direction) {
1168  switch (tick_direction) {
1169  case TickDirection::OFF:
1170  return "OFF";
1172  return "FORWARD_ACTIVE_HIGH";
1174  return "FORWARD_ACTIVE_LOW";
1175  default:
1176  return "UNRECOGNIZED";
1177  }
1178 }
1179 
1180 /**
1181  * @brief @ref TickDirection stream operator.
1182  * @ingroup config_types
1183  */
1185  TickDirection tick_direction) {
1186  stream << to_string(tick_direction) << " (" << (int)tick_direction << ")";
1187  return stream;
1188 }
1189 
1190 /**
1191  * @brief Hardware wheel tick encoder configuration settings.
1192  * @ingroup config_types
1193  *
1194  * @warning
1195  * The @ref HardwareTickConfig payload is intended for use on vehicles with a
1196  * physical voltage signal, generated by a wheel encoder, that produces a series
1197  * of voltage pulses (encoder ticks) as the vehicle’s wheel rotates. These ticks
1198  * will be captured by the device on an input pin and used to indicate vehicle
1199  * speed. For vehicles using software wheel speed/tick information, including
1200  * data send using FusionEngine messages or a vehicle CAN bus, use @ref
1201  * WheelConfig instead.
1202  *
1203  * @note
1204  * In addition to the wheel tick signal, an optional voltage signal may be
1205  * provided to indicate vehicle direction. If this signal is not connected, the
1206  * @ref tick_direction setting MUST be set to `OFF` otherwise there will be
1207  * substantial errors in dead reckoning.
1208  *
1209  * See also @ref VehicleTickInput.
1210  */
1212  /**
1213  * If enabled -- tick mode is not @ref TickMode::OFF -- the device will
1214  * accumulate ticks received on the I/O pin, and use them as an indication of
1215  * vehicle speed. If enabled, you must also specify @ref wheel_ticks_to_m to
1216  * indicate the mapping of wheel tick encoder angle to tire circumference. All
1217  * other wheel tick-related parameters such as tick capture rate, rollover
1218  * value, etc. will be set internally.
1219  *
1220  * @warning
1221  * Do not enable this feature if a wheel tick voltage signal is not present.
1222  */
1224 
1225  /**
1226  * When direction is @ref TickDirection::OFF, the incoming ticks will be
1227  * treated as unsigned, meaning the tick count will continue to increase in
1228  * either direction of travel. If direction is not @ref TickDirection::OFF,
1229  * a second direction I/O pin will be used to indicate the direction of
1230  * travel and the accumulated tick count will increase/decrease accordingly.
1231  */
1233 
1234  uint8_t reserved1[2] = {0};
1235 
1236  /**
1237  * The scale factor to convert from wheel encoder ticks to distance (in
1238  * meters/tick). Used for @ref WheelSensorType::TICKS.
1239  */
1240  float wheel_ticks_to_m = NAN;
1241 };
1242 
1243 /**
1244  * @brief The ionospheric delay model to use.
1245  * @ingroup config_types
1246  */
1247 enum class IonoDelayModel : uint8_t {
1248  /** Select the best available ionospheric delay model. */
1249  AUTO = 0,
1250  /** Ionospheric delay model disabled. */
1251  OFF = 1,
1252  /** Use the Klobuchar ionospheric model. */
1253  KLOBUCHAR = 2,
1254  /** Use the SBAS ionospheric model. */
1255  SBAS = 3,
1256 };
1257 
1258 P1_CONSTEXPR_FUNC const char* to_string(IonoDelayModel iono_delay_model) {
1259  switch (iono_delay_model) {
1260  case IonoDelayModel::AUTO:
1261  return "AUTO";
1262  case IonoDelayModel::OFF:
1263  return "OFF";
1265  return "KLOBUCHAR";
1266  case IonoDelayModel::SBAS:
1267  return "SBAS";
1268  default:
1269  return "UNRECOGNIZED";
1270  }
1271 }
1272 
1273 /**
1274  * @brief @ref IonoDelayModel stream operator.
1275  * @ingroup config_types
1276  */
1278  IonoDelayModel iono_delay_model) {
1279  stream << to_string(iono_delay_model) << " (" << (int)iono_delay_model << ")";
1280  return stream;
1281 }
1282 
1283 /**
1284  * @brief Ionospheric delay model configuration.
1285  * @ingroup config_types
1286  */
1288  /** The ionospheric delay model to use. */
1290 
1291  uint8_t reserved[3] = {0};
1292 };
1293 
1294 /**
1295  * @brief The tropospheric delay model to use.
1296  * @ingroup config_types
1297  */
1298 enum class TropoDelayModel : uint8_t {
1299  /** Select the best available tropospheric delay model. */
1300  AUTO = 0,
1301  /** Tropospheric delay model disabled. */
1302  OFF = 1,
1303  /** Use the Saastamoinen tropospheric model. */
1304  SAASTAMOINEN = 2,
1305 };
1306 
1307 P1_CONSTEXPR_FUNC const char* to_string(TropoDelayModel tropo_delay_model) {
1308  switch (tropo_delay_model) {
1309  case TropoDelayModel::AUTO:
1310  return "AUTO";
1311  case TropoDelayModel::OFF:
1312  return "OFF";
1314  return "SAASTAMOINEN";
1315  default:
1316  return "UNRECOGNIZED";
1317  }
1318 }
1319 
1320 /**
1321  * @brief @ref TropoDelayModel stream operator.
1322  * @ingroup config_types
1323  */
1325  TropoDelayModel tropo_delay_model) {
1326  stream << to_string(tropo_delay_model) << " (" << (int)tropo_delay_model
1327  << ")";
1328  return stream;
1329 }
1330 
1331 /**
1332  * @brief Tropospheric delay model configuration.
1333  * @ingroup config_types
1334  */
1336  /** The tropospheric delay model to use. */
1338 
1339  uint8_t reserved[3] = {0};
1340 };
1341 
1342 /**************************************************************************/ /**
1343  * @defgroup import_export Device Configuration Import/Export
1344  * @brief Messages for importing/exporting device configuration.
1345  * @ingroup config_and_ctrl_messages
1346  *
1347  * See also @ref config_types.
1348  ******************************************************************************/
1349 
1350 /**
1351  * @brief Type of data stored on device.
1352  * @ingroup import_export
1353  */
1354 enum class DataType : uint8_t {
1355  CALIBRATION_STATE = 0,
1356  CRASH_LOG = 1,
1357  FILTER_STATE = 2,
1358  USER_CONFIG = 3,
1359  INVALID = 255
1360 };
1361 
1362 /**
1363  * @brief Get a string representation of a @ref DataType.
1364  * @ingroup import_export
1365  *
1366  * @param type The requested type.
1367  *
1368  * @return The corresponding string name.
1369  */
1371  switch (type) {
1373  return "CalibrationState";
1374  case DataType::CRASH_LOG:
1375  return "CrashLog";
1377  return "FilterState";
1378  case DataType::USER_CONFIG:
1379  return "UserConfig";
1380  default:
1381  return "Invalid";
1382  }
1383 }
1384 
1385 /**
1386  * @brief @ref DataType stream operator.
1387  * @ingroup import_export
1388  */
1389 inline p1_ostream& operator<<(p1_ostream& stream, DataType val) {
1390  stream << to_string(val) << " (" << (int)val << ")";
1391  return stream;
1392 }
1393 
1394 /**
1395  * @brief Import data from the host to the device (@ref
1396  * MessageType::IMPORT_DATA, version 1.0).
1397  * @ingroup import_export
1398  *
1399  * This message must be followed by @ref data_length_bytes bytes containing
1400  * the data to be imported:
1401  *
1402  * ```
1403  * {MessageHeader, ImportDataMessage, Payload[data_length_bytes]}
1404  * ```
1405  *
1406  * # Expected Response
1407  * The device will respond with a @ref CommandResponseMessage indicating whether
1408  * or not the request succeeded.
1409  */
1411  static constexpr MessageType MESSAGE_TYPE = MessageType::IMPORT_DATA;
1412  static constexpr uint8_t MESSAGE_VERSION = 0;
1413  /**
1414  * The type of data being imported.
1415  */
1417  /**
1418  * The location of the data to update (active, saved, etc.). For data that
1419  * doesn't have separate active and saved copies, this parameter is ignored.
1420  */
1422  uint8_t reserved1[2] = {0};
1423  /** @brief Version of data contents. */
1425  uint8_t reserved2[4] = {0};
1426  /** @brief Number of bytes to update. */
1427  uint32_t data_length_bytes = 0;
1428 };
1429 
1430 /**
1431  * @brief Export data from the device (@ref
1432  * MessageType::EXPORT_DATA, version 1.0).
1433  * @ingroup import_export
1434  *
1435  * # Expected Response
1436  * The device will respond with a @ref PlatformStorageDataMessage.
1437  */
1439  static constexpr MessageType MESSAGE_TYPE = MessageType::EXPORT_DATA;
1440  static constexpr uint8_t MESSAGE_VERSION = 0;
1441  /**
1442  * The type of data to be exported.
1443  */
1445  /**
1446  * The source to copy this data from. If the data_type doesn't separate active
1447  * and saved data, this will be ignored.
1448  */
1450  uint8_t reserved[2] = {0};
1451 };
1452 
1453 /**
1454  * @brief Message for reporting platform storage data (@ref
1455  * MessageType::PLATFORM_STORAGE_DATA, version 1.0).
1456  * @ingroup import_export
1457  *
1458  * This message will be followed by @ref data_length_bytes bytes containing
1459  * the data storage contents:
1460  *
1461  * ```
1462  * {MessageHeader, PlatformStorageDataMessage, Payload[data_length_bytes]}
1463  * ```
1464  *
1465  * See also @ref ExportDataMessage.
1466  *
1467  * Changes:
1468  * - Version 1: Added `data_validity` field.
1469  * - Version 2: Changed data_validity to a @ref Response enum and added
1470  * @ref source field.
1471  * - Version 3: Added @ref flags field.
1472  */
1474  static constexpr MessageType MESSAGE_TYPE =
1476  static constexpr uint8_t MESSAGE_VERSION = 3;
1477 
1478  /** @ref DataType::USER_CONFIG flag field is not set. */
1479  static constexpr uint8_t FLAG_USER_CONFIG_PLATFORM_NOT_SPECIFIED = 0;
1480  /** @ref DataType::USER_CONFIG flag for POSIX platforms. */
1481  static constexpr uint8_t FLAG_USER_CONFIG_PLATFORM_POSIX = 1;
1482  /** @ref DataType::USER_CONFIG flag for embedded platforms. */
1483  static constexpr uint8_t FLAG_USER_CONFIG_PLATFORM_EMBEDDED = 2;
1484  /** @ref DataType::USER_CONFIG flag for embedded SSR platforms. */
1485  static constexpr uint8_t FLAG_USER_CONFIG_PLATFORM_EMBEDDED_SSR = 3;
1486  /** @ref DataType::USER_CONFIG flag for the SSR client library. */
1487  static constexpr uint8_t FLAG_USER_CONFIG_SSR_CLIENT = 254;
1488 
1489  /**
1490  * The type of data contained in this message.
1491  */
1493  /**
1494  * The status of the specified data type on the device.
1495  */
1497  /**
1498  * The source this data was copied from. If the @ref data_type doesn't
1499  * separate active and saved data, this will be set to @ref
1500  * ConfigurationSource::ACTIVE.
1501  */
1503  /**
1504  * @ref DataType specific flags.
1505  *
1506  * Currently, only defined for @ref DataType::USER_CONFIG contents. This value
1507  * can optionally set to one of the `FLAG_USER_CONFIG_PLATFORM_*` values to
1508  * indicate which type of platform the UserConfig is valid for. This value
1509  * can be left at `0` for backwards compatibility or to indicate the platform
1510  * type is unknown.
1511  */
1512  uint8_t flags = 0;
1513  /** Version of data contents. */
1515  /** Number of bytes in data contents. */
1516  uint32_t data_length_bytes = 0;
1517 };
1518 
1519 /**************************************************************************/ /**
1520  * @defgroup io_interfaces Input/Output Interface And Message Rate Control
1521  * @brief Messages for controlling device output (e.g., define TCP server
1522  * parameters, configure message output rates).
1523  * @ingroup config_and_ctrl_messages
1524  ******************************************************************************/
1525 
1526 /**
1527  * @brief An identifier for the contents of a output interface configuration
1528  * submessage.
1529  * @ingroup io_interfaces
1530  *
1531  * See also @ref InterfaceConfigSubmessage.
1532  */
1533 enum class InterfaceConfigType : uint8_t {
1534  INVALID = 0,
1535 
1536  /**
1537  * Enable/disable output of diagnostic data on this interface.
1538  *
1539  * Valid for:
1540  * - All @ref TransportType
1541  *
1542  * @note
1543  * Enabling this setting will override the message rate/off settings for some
1544  * FusionEngine messages.
1545  *
1546  * Payload format: `bool`
1547  */
1549 
1550  /**
1551  * Configure the serial baud rate (in bits/second).
1552  *
1553  * Valid for:
1554  * - @ref TransportType::SERIAL
1555  *
1556  * Payload format: `uint32_t`
1557  */
1558  BAUD_RATE = 2,
1559 
1560  /**
1561  * Configure the network address for a client to connect to.
1562  *
1563  * For UNIX domain sockets, this string represents the path to the local
1564  * socket file.
1565  *
1566  * Valid for:
1567  * - @ref TransportType::TCP
1568  * - @ref TransportType::UDP
1569  * - @ref TransportType::UNIX
1570  *
1571  * Payload format: `char[64]` containing a NULL terminated string.
1572  */
1573  REMOTE_ADDRESS = 3,
1574 
1575  /**
1576  * Configure the network port.
1577  *
1578  * Valid for:
1579  * - @ref TransportType::TCP
1580  * - @ref TransportType::UDP
1581  * - @ref TransportType::WEBSOCKET
1582  *
1583  * Payload format: `uint16_t`
1584  */
1585  PORT = 4,
1586 
1587  /**
1588  * Enable/disable the interface.
1589  *
1590  * Valid for all @ref TransportType values.
1591  *
1592  * Payload format: `bool`
1593  */
1594  ENABLED = 5,
1595 
1596  /**
1597  * Set the interface direction (client/server).
1598  *
1599  * Valid for:
1600  * - @ref TransportType::TCP
1601  * - @ref TransportType::WEBSOCKET
1602  * - @ref TransportType::UNIX
1603  *
1604  * Payload format: @ref TransportDirection
1605  */
1606  DIRECTION = 6,
1607 
1608  /**
1609  * Set the UNIX domain socket type (streaming/datagram/sequenced).
1610  *
1611  * Valid for:
1612  * - @ref TransportType::UNIX
1613  *
1614  * Payload format: @ref SocketType
1615  */
1616  SOCKET_TYPE = 7,
1617 };
1618 
1619 /**
1620  * @brief Get a human-friendly string name for the specified @ref ConfigType.
1621  * @ingroup io_interfaces
1622  *
1623  * @param type The desired configuration parameter type.
1624  *
1625  * @return The corresponding string name.
1626  */
1628  switch (type) {
1630  return "Invalid";
1631 
1633  return "Diagnostic Messages Enabled";
1634 
1636  return "Serial Baud Rate";
1637 
1639  return "Remote Network Address";
1640 
1642  return "Network Port";
1643 
1645  return "Interface Enabled";
1646 
1648  return "Transport Direction";
1649 
1651  return "Socket Type";
1652 
1653  default:
1654  return "Unrecognized Configuration";
1655  }
1656 }
1657 
1658 /**
1659  * @brief @ref InterfaceConfigType stream operator.
1660  * @ingroup io_interfaces
1661  */
1663  stream << to_string(type) << " (" << (int)type << ")";
1664  return stream;
1665 }
1666 
1667 /**
1668  * @brief The framing protocol of a message.
1669  * @ingroup io_interfaces
1670  */
1671 enum class ProtocolType : uint8_t {
1672  INVALID = 0,
1673  FUSION_ENGINE = 1,
1674  NMEA = 2,
1675  RTCM = 3,
1676  /** This is used for requesting the configuration for all protocols. */
1677  ALL = 0xFF,
1678 };
1679 
1680 /** Setting message_id to this value acts as a wild card. */
1681 constexpr uint16_t ALL_MESSAGES_ID = 0xFFFF;
1682 
1683 /**
1684  * @brief Get a human-friendly string name for the specified @ref
1685  * ProtocolType.
1686  * @ingroup io_interfaces
1687  *
1688  * @param val The enum to get the string name for.
1689  *
1690  * @return The corresponding string name.
1691  */
1693  switch (val) {
1694  case ProtocolType::INVALID:
1695  return "Invalid";
1697  return "FusionEngine";
1698  case ProtocolType::NMEA:
1699  return "NMEA";
1700  case ProtocolType::RTCM:
1701  return "RTCM";
1702  case ProtocolType::ALL:
1703  return "ALL";
1704  default:
1705  return "Unrecognized";
1706  }
1707 }
1708 
1709 /**
1710  * @brief @ref ProtocolType stream operator.
1711  * @ingroup io_interfaces
1712  */
1714  stream << to_string(val) << " (" << (int)val << ")";
1715  return stream;
1716 }
1717 
1718 /**
1719  * @brief Type of I/O interface transport.
1720  * @ingroup io_interfaces
1721  */
1722 enum class TransportType : uint8_t {
1723  INVALID = 0,
1724  /** A serial data interface (e.g. an RS232 connection). */
1725  SERIAL = 1,
1726  /** A interface that writes to a file. */
1727  FILE = 2,
1728  // RESERVED = 3,
1729  /**
1730  * A TCP client or server.
1731  *
1732  * A TCP client will connect to a specified TCP server address and port. A TCP
1733  * server will listen for incoming client connections, and may communicate
1734  * with multiple clients at a time. Responses to commands will be sent only to
1735  * the the issuing client. All other configured output messages will be sent
1736  * to all clients.
1737  *
1738  * See also @ref TransportDirection.
1739  */
1740  TCP = 4,
1741  /**
1742  * A UDP client or server.
1743  *
1744  * UDP connections are stateless, unlike TCP. A UDP interface will listen for
1745  * incoming messages on a specified port. It may optionally be configured to
1746  * sent output to a specific hostname or IP address, including broadcast or
1747  * multicast addresses. If an address is not specified, the interface will not
1748  * send any output automatically, but it will respond to incoming commands,
1749  * sending responses back to the remote client's address and port.
1750  */
1751  UDP = 5,
1752  // RESERVED = 6,
1753  /**
1754  * A WebSocket client or server.
1755  *
1756  * WebSocket connections are similar to TCP connections, and use TCP as their
1757  * underlying transport, but use the WebSocket protocol to send and receive
1758  * data.
1759  *
1760  * See also @ref TransportDirection.
1761  */
1762  WEBSOCKET = 7,
1763  /**
1764  * A UNIX domain socket client or server.
1765  *
1766  * UNIX domain socket connections may be configured as either client that
1767  * connects to an existing server, or a server that listens for one or more
1768  * incoming client connections. UNIX domain sockets may operate in one of
1769  * three possible modes:
1770  * - A connection-oriented streaming mode where packet boundaries are not
1771  * preserved (similar to TCP)
1772  * - Datagram mode where packet boundaries are preserved but connections
1773  * between the client and server are not maintained, and the interface sends
1774  * output to an optional configured file (similar to UDP)
1775  * - Sequenced packet mode, which is connection-oriented (like TCP) but also
1776  * preserves message boundaries (like UDP) and guarantees in-order delivery
1777  *
1778  * For a UNIX domain socket, you must specify:
1779  * - The @ref TransportDirection (client or server)
1780  * - The @ref SocketType (streaming, datagram, or sequenced)
1781  * - The path to a socket file to connect to (client) or create (server)
1782  */
1783  UNIX = 8,
1784  /**
1785  * Set/get the configuration for the interface on which the command was
1786  * received.
1787  */
1788  CURRENT = 254,
1789  /** Set/get the configuration for the all I/O interfaces. */
1790  ALL = 255,
1791 };
1792 
1793 /**
1794  * @brief Get a human-friendly string name for the specified @ref
1795  * TransportType.
1796  * @ingroup io_interfaces
1797  *
1798  * @param val The enum to get the string name for.
1799  *
1800  * @return The corresponding string name.
1801  */
1803  switch (val) {
1805  return "Invalid";
1806  case TransportType::SERIAL:
1807  return "Serial";
1808  case TransportType::FILE:
1809  return "File";
1810  case TransportType::TCP:
1811  return "TCP";
1812  case TransportType::UDP:
1813  return "UDP";
1815  return "WebSocket";
1816  case TransportType::UNIX:
1817  return "UNIX";
1819  return "Current";
1820  case TransportType::ALL:
1821  return "All";
1822  }
1823  return "Unrecognized";
1824 }
1825 
1826 /**
1827  * @brief @ref TransportType stream operator.
1828  * @ingroup io_interfaces
1829  */
1831  stream << to_string(val) << " (" << (int)val << ")";
1832  return stream;
1833 }
1834 
1835 /**
1836  * @brief The direction (client/server) for an individual interface.
1837  * @ingroup io_interfaces
1838  */
1839 enum class TransportDirection : uint8_t {
1840  INVALID = 0,
1841  /** A server listening for one or more incoming remote connections. */
1842  SERVER = 1,
1843  /** A client connecting to a specified remote server. */
1844  CLIENT = 2,
1845 };
1846 
1847 /**
1848  * @brief Get a human-friendly string name for the specified @ref
1849  * TransportDirection.
1850  * @ingroup io_interfaces
1851  *
1852  * @param val The enum to get the string name for.
1853  *
1854  * @return The corresponding string name.
1855  */
1857  switch (val) {
1859  return "INVALID";
1861  return "SERVER";
1863  return "CLIENT";
1864  }
1865  return "Unrecognized";
1866 }
1867 
1868 /**
1869  * @brief @ref TransportDirection stream operator.
1870  * @ingroup io_interfaces
1871  */
1873  stream << to_string(val) << " (" << (int)val << ")";
1874  return stream;
1875 }
1876 
1877 /**
1878  * @brief The socket type specifying how data is transmitted for UNIX domain
1879  * sockets.
1880  * @ingroup io_interfaces
1881  */
1882 enum class SocketType : uint8_t {
1883  INVALID = 0,
1884  /**
1885  * Operate in connection-oriented streaming mode and do not preserve message
1886  * boundaries (similar to TCP).
1887  */
1888  STREAM = 1,
1889  /**
1890  * Operate in datagram mode, preserving message boundaries but not maintaining
1891  * client connections (similar to UDP).
1892  */
1893  DATAGRAM = 2,
1894  /**
1895  * Operate in sequenced packet mode, which is both connection-oriented and
1896  * preserves message boundaries.
1897  */
1898  SEQPACKET = 3,
1899 };
1900 
1901 /**
1902  * @brief Get a human-friendly string name for the specified @ref SocketType.
1903  * @ingroup io_interfaces
1904  *
1905  * @param val The enum to get the string name for.
1906  *
1907  * @return The corresponding string name.
1908  */
1910  switch (val) {
1911  case SocketType::INVALID:
1912  return "INVALID";
1913  case SocketType::STREAM:
1914  return "STREAM";
1915  case SocketType::DATAGRAM:
1916  return "DATAGRAM";
1917  case SocketType::SEQPACKET:
1918  return "SEQPACKET";
1919  }
1920  return "Unrecognized";
1921 }
1922 
1923 /**
1924  * @brief @ref SocketType stream operator.
1925  * @ingroup io_interfaces
1926  */
1928  stream << to_string(val) << " (" << (int)val << ")";
1929  return stream;
1930 }
1931 
1932 /**
1933  * @brief Identifier for an I/O interface.
1934  * @ingroup io_interfaces
1935  *
1936  * For example, serial port 1 or TCP server 2.
1937  *
1938  * @note
1939  * On most devices, serial ports (UARTs) use 1-based numbering: the first serial
1940  * port is typically index 1 (UART1).
1941  */
1943  /** The interface's transport type. **/
1945  /** An identifier for the instance of this transport. */
1946  uint8_t index = 0;
1947  uint8_t reserved[2] = {0};
1948 
1950 
1951  P1_CONSTEXPR_FUNC explicit InterfaceID(TransportType type, uint8_t index = 0)
1952  : type(type), index(index) {}
1953 
1954  P1_CONSTEXPR_FUNC bool operator==(const InterfaceID& other) const {
1955  return type == other.type && index == other.index;
1956  }
1957 
1958  P1_CONSTEXPR_FUNC bool operator!=(const InterfaceID& other) const {
1959  return !(*this == other);
1960  }
1961 
1962  P1_CONSTEXPR_FUNC bool operator<(const InterfaceID& other) const {
1963  if (type == other.type) {
1964  return index < other.index;
1965  } else {
1966  return type < other.type;
1967  }
1968  }
1969 
1970  P1_CONSTEXPR_FUNC bool operator>(const InterfaceID& other) const {
1971  return other < *this;
1972  }
1973 
1974  P1_CONSTEXPR_FUNC bool operator>=(const InterfaceID& other) const {
1975  return !(*this < other);
1976  }
1977 
1978  P1_CONSTEXPR_FUNC bool operator<=(const InterfaceID& other) const {
1979  return !(*this > other);
1980  }
1981 };
1982 
1983 /**
1984  * @brief @ref InterfaceID stream operator.
1985  * @ingroup io_interfaces
1986  */
1988  stream << "[type=" << val.type << ", index=" << (int)val.index << "]";
1989  return stream;
1990 }
1991 
1992 /**
1993  * @brief Integer ID for NMEA messages.
1994  * @ingroup io_interfaces
1995  */
1996 enum class NmeaMessageType : uint16_t {
1997  INVALID = 0,
1998 
1999  /**
2000  * @name Standard NMEA Messages
2001  * @{
2002  */
2003  GGA = 1,
2004  GLL = 2,
2005  GSA = 3,
2006  GSV = 4,
2007  RMC = 5,
2008  VTG = 6,
2009  ZDA = 7,
2010  /** @} */
2011 
2012  /**
2013  * @name Point One Proprietary Messages
2014  * @{
2015  */
2016  P1CALSTATUS = 1000,
2017  P1MSG = 1001,
2018  /** @} */
2019 
2020  /**
2021  * @name Quectel Proprietary Messages
2022  * @{
2023  */
2024  PQTMVERNO = 1200,
2025  PQTMVER = 1201,
2026  PQTMGNSS = 1202,
2027  PQTMVERNO_SUB = 1203,
2028  PQTMVER_SUB = 1204,
2029  PQTMTXT = 1205,
2030  /** @} */
2031 };
2032 
2033 /**
2034  * @brief Get a human-friendly string name for the specified @ref
2035  * NmeaMessageType.
2036  * @ingroup io_interfaces
2037  *
2038  * @param value The enum to get the string name for.
2039  *
2040  * @return The corresponding string name.
2041  */
2043  switch (value) {
2045  return "INVALID";
2046  case NmeaMessageType::GGA:
2047  return "GGA";
2048  case NmeaMessageType::GLL:
2049  return "GLL";
2050  case NmeaMessageType::GSA:
2051  return "GSA";
2052  case NmeaMessageType::GSV:
2053  return "GSV";
2054  case NmeaMessageType::RMC:
2055  return "RMC";
2056  case NmeaMessageType::VTG:
2057  return "VTG";
2058  case NmeaMessageType::ZDA:
2059  return "ZDA";
2061  return "P1CALSTATUS";
2063  return "P1MSG";
2065  return "PQTMVERNO";
2067  return "PQTMVER";
2069  return "PQTMGNSS";
2071  return "PQTMVERNO_SUB";
2073  return "PQTMVER_SUB";
2075  return "PQTMTXT";
2076  default:
2077  return "Unrecognized";
2078  }
2079 }
2080 
2081 /**
2082  * @brief @ref NmeaMessageType stream operator.
2083  * @ingroup io_interfaces
2084  */
2086  stream << to_string(val) << " (" << (int)val << ")";
2087  return stream;
2088 }
2089 
2090 /**
2091  * @brief The output rate for a message type on an interface.
2092  * @ingroup io_interfaces
2093  */
2094 enum class MessageRate : uint8_t {
2095  /**
2096  * Disable output of this message.
2097  */
2098  OFF = 0,
2099  /**
2100  * Output this message each time a new value is available.
2101  */
2102  ON_CHANGE = 1,
2103  /** Alias for @ref MessageRate::ON_CHANGE. */
2104  MAX_RATE = 1,
2105  /**
2106  * Output this message every 10 milliseconds. Not supported for all messages
2107  * or platforms.
2108  */
2109  INTERVAL_10_MS = 2,
2110  /**
2111  * Output this message every 20 milliseconds. Not supported for all messages
2112  * or platforms.
2113  */
2114  INTERVAL_20_MS = 3,
2115  /**
2116  * Output this message every 40 milliseconds. Not supported for all messages
2117  * or platforms.
2118  */
2119  INTERVAL_40_MS = 4,
2120  /**
2121  * Output this message every 50 milliseconds. Not supported for all messages
2122  * or platforms.
2123  */
2124  INTERVAL_50_MS = 5,
2125  /**
2126  * Output this message every 100 milliseconds. Not supported for all messages
2127  * or platforms.
2128  */
2129  INTERVAL_100_MS = 6,
2130  /**
2131  * Output this message every 200 milliseconds. Not supported for all messages
2132  * or platforms.
2133  */
2134  INTERVAL_200_MS = 7,
2135  /**
2136  * Output this message every 500 milliseconds. Not supported for all messages
2137  * or platforms.
2138  */
2139  INTERVAL_500_MS = 8,
2140  /**
2141  * Output this message every second. Not supported for all messages or
2142  * platforms.
2143  */
2144  INTERVAL_1_S = 9,
2145  /**
2146  * Output this message every 2 seconds. Not supported for all messages or
2147  * platforms.
2148  */
2149  INTERVAL_2_S = 10,
2150  /**
2151  * Output this message every 5 seconds. Not supported for all messages or
2152  * platforms.
2153  */
2154  INTERVAL_5_S = 11,
2155  /**
2156  * Output this message every 10 seconds. Not supported for all messages or
2157  * platforms.
2158  */
2159  INTERVAL_10_S = 12,
2160  /**
2161  * Output this message every 30 seconds. Not supported for all messages or
2162  * platforms.
2163  */
2164  INTERVAL_30_S = 13,
2165  /**
2166  * Output this message every 60 seconds. Not supported for all messages or
2167  * platforms.
2168  */
2169  INTERVAL_60_S = 14,
2170  /**
2171  * Restore this message's rate back to its default value.
2172  */
2173  DEFAULT = 255
2174 };
2175 
2176 /**
2177  * @brief Get a human-friendly string name for the specified @ref
2178  * MessageRate.
2179  * @ingroup io_interfaces
2180  *
2181  * @param value The enum to get the string name for.
2182  *
2183  * @return The corresponding string name.
2184  */
2186  switch (value) {
2187  case MessageRate::OFF:
2188  return "OFF";
2190  return "ON_CHANGE";
2192  return "INTERVAL_10_MS";
2194  return "INTERVAL_20_MS";
2196  return "INTERVAL_40_MS";
2198  return "INTERVAL_50_MS";
2200  return "INTERVAL_100_MS";
2202  return "INTERVAL_200_MS";
2204  return "INTERVAL_500_MS";
2206  return "INTERVAL_1_S";
2208  return "INTERVAL_2_S";
2210  return "INTERVAL_5_S";
2212  return "INTERVAL_10_S";
2214  return "INTERVAL_30_S";
2216  return "INTERVAL_60_S";
2217  case MessageRate::DEFAULT:
2218  return "DEFAULT";
2219  default:
2220  return "Unrecognized";
2221  }
2222 }
2223 
2224 /**
2225  * @brief @ref MessageRate stream operator.
2226  * @ingroup io_interfaces
2227  */
2229  stream << to_string(val) << " (" << (int)val << ")";
2230  return stream;
2231 }
2232 
2233 /**
2234  * @brief I/O interface parameter configuration submessage (used when sending
2235  * a @ref SetConfigMessage or @ref GetConfigMessage for @ref
2236  * ConfigType::INTERFACE_CONFIG).
2237  * @ingroup io_interfaces
2238  *
2239  * In @ref SetConfigMessage, @ref GetConfigMessage, and @ref
2240  * ConfigResponseMessage, this struct can be used to access settings
2241  * associated with a a particular I/O interface. For example, to set the
2242  * baudrate for serial port 1:
2243  *
2244  * ```
2245  * {
2246  * SetConfigMessage(
2247  * config_type=INTERFACE_CONFIG),
2248  * InterfaceConfigSubmessage(
2249  * interface=InterfaceID(TransportType::SERIAL, 1),
2250  * subtype=BAUD_RATE),
2251  * uint32_t 115200
2252  * }
2253  * ```
2254  *
2255  * This message must be followed by the parameter value to be used:
2256  *
2257  * ```
2258  * {MessageHeader, SetConfigMessage, InterfaceConfigSubmessage, Parameter}
2259  * ```
2260  *
2261  * See @ref InterfaceConfigType for a complete list of parameters and their
2262  * data formats.
2263  */
2265  /**
2266  * The ID of the interface to be configured or queried.
2267  *
2268  * @note
2269  * TransportType::ALL is not supported.
2270  */
2272 
2273  /**
2274  * The interface setting to get or set.
2275  */
2277 
2278  uint8_t reserved[3] = {0};
2279 };
2280 
2281 /**
2282  * @brief Set the output rate for the requested message types (@ref
2283  * MessageType::SET_MESSAGE_RATE, version 1.0).
2284  * @ingroup io_interfaces
2285  *
2286  * Multiple message rates can be configured with a single command if wild cards
2287  * are used for the interface, protocol, or message ID. When multiple messages
2288  * are specified, the following behaviors apply:
2289  * - Messages that are currently @ref MessageRate::OFF will not be changed
2290  * unless the @ref FLAG_INCLUDE_DISABLED_MESSAGES bit is set in the @ref flags
2291  * or the new rate is @ref MessageRate::DEFAULT.
2292  * - If the rate is an interval, it will only affect the messages that support
2293  * being rate controlled.
2294  *
2295  * Setting all the messages on an interface to @ref MessageRate::DEFAULT will
2296  * also restore the default `*_OUTPUT_DIAGNOSTICS_MESSAGES` configuration option
2297  * value for that interface. See @ref ConfigType.
2298  *
2299  * @note
2300  * When specifying @ref ProtocolType::ALL, message ID @ref ALL_MESSAGES_ID must
2301  * also be specified. Further, the rate must be set to either
2302  * @ref MessageRate::OFF or @ref MessageRate::DEFAULT.
2303  *
2304  * @section set_rate_examples Typical Use Cases
2305  *
2306  * @subsection set_rate_restore Restore Default Settings For All Messages
2307  *
2308  * To restore the default configuration on UART1 for all message types across all
2309  * supported protocols, specify the following:
2310  * - Interface transport type: @ref TransportType::SERIAL
2311  * - Interface index: 1
2312  * - Protocol: @ref ProtocolType::ALL
2313  * - Message ID: @ref ALL_MESSAGES_ID
2314  * - Rate: @ref MessageRate::DEFAULT
2315  *
2316  * @subsection set_rate_restore_nmea Restore Default Settings For All NMEA
2317  *
2318  * To restore the default configuration on UART1 for all NMEA message types,
2319  * specify the following:
2320  * - Interface transport type: @ref TransportType::SERIAL
2321  * - Interface index: 1
2322  * - Protocol: @ref ProtocolType::NMEA
2323  * - Message ID: @ref ALL_MESSAGES_ID
2324  * - Rate: @ref MessageRate::DEFAULT
2325  *
2326  * @subsection set_rate_change_nmea Change UART1 Output Rate To 1 Hz:
2327  *
2328  * To change the rate of all NMEA message types to 1 Hz on UART1, specify the
2329  * following:
2330  * - Interface transport type: @ref TransportType::SERIAL
2331  * - Interface index: 1
2332  * - Protocol: @ref ProtocolType::NMEA
2333  * - Message ID: @ref ALL_MESSAGES_ID
2334  * - Rate: @ref MessageRate::INTERVAL_1_S
2335  *
2336  * @note
2337  * Note that this will not affect any message types that are not rate controlled
2338  * (e.g., @ref MessageType::EVENT_NOTIFICATION).
2339  *
2340  * @subsection set_rate_off_all Change The Uart1 Output Rates For All Messages To Be Off:
2341  *
2342  * To change the rate of all messages to their max rate on UART1, specify the
2343  * following:
2344  * - Interface transport type: @ref TransportType::SERIAL
2345  * - Interface index: 1
2346  * - Protocol: @ref ProtocolType::ALL
2347  * - flags: @ref FLAG_INCLUDE_DISABLED_MESSAGES
2348  * - Message ID: @ref ALL_MESSAGES_ID
2349  * - Rate: @ref MessageRate::OFF
2350  *
2351  * @note
2352  * This will disable every message.
2353  *
2354  * @subsection set_and_save_rate_off_all Change And Save The UART1 Output Rates For All Messages To Be Off:
2355  *
2356  * To change the rate of all messages to their max rate on UART1, specify the
2357  * following:
2358  * - Interface transport type: @ref TransportType::SERIAL
2359  * - Interface index: 1
2360  * - Protocol: @ref ProtocolType::ALL
2361  * - flags: 0x03 (@ref FLAG_INCLUDE_DISABLED_MESSAGES | @ref FLAG_APPLY_AND_SAVE)
2362  * - Message ID: @ref ALL_MESSAGES_ID
2363  * - Rate: @ref MessageRate::OFF
2364  *
2365  * @note
2366  * Both of the bit flags are set for this message. This will cause the
2367  * configuration to be saved to non-volatile memory.
2368  *
2369  * # Expected Response
2370  * The device will respond with a @ref CommandResponseMessage indicating whether
2371  * or not the request succeeded.
2372  */
2374  static constexpr MessageType MESSAGE_TYPE = MessageType::SET_MESSAGE_RATE;
2375  static constexpr uint8_t MESSAGE_VERSION = 0;
2376 
2377  /** Flag to immediately save the config after applying this setting. */
2378  static constexpr uint8_t FLAG_APPLY_AND_SAVE = 0x01;
2379 
2380  /**
2381  * Flag to apply bulk interval changes to all messages instead of just
2382  * enabled messages.
2383  */
2384  static constexpr uint8_t FLAG_INCLUDE_DISABLED_MESSAGES = 0x02;
2385 
2386  /**
2387  * The output interface to configure. If @ref TransportType::ALL, set rates on
2388  * all supported interfaces.
2389  */
2391 
2392  /**
2393  * The message protocol being configured. If @ref ProtocolType::ALL, set rates
2394  * on all supported protocols.
2395  */
2397 
2398  /** Bitmask of additional flags to modify the command. */
2399  uint8_t flags = 0;
2400 
2401  /**
2402  * The ID of the desired message type (e.g., 10000 for FusionEngine
2403  * @ref MessageType::POSE messages). See @ref NmeaMessageType for NMEA-0183
2404  * messages. If @ref ALL_MESSAGES_ID, set the rate for all messages on the
2405  * selected interface and protocol.
2406  */
2407  uint16_t message_id = ALL_MESSAGES_ID;
2408 
2409  /** The desired message rate. */
2411 
2412  uint8_t reserved2[3] = {0};
2413 };
2414 
2415 /**
2416  * @brief Get the configured output rate for the he requested message type on
2417  * the specified interface (@ref MessageType::GET_MESSAGE_RATE,
2418  * version 1.0).
2419  * @ingroup io_interfaces
2420  *
2421  * Multiple message rates can be requested with a single command if wild cards
2422  * are used for the protocol, or message ID.
2423  *
2424  * # Expected Response
2425  * The device will respond with a @ref MessageRateResponse containing the
2426  * requested values or an error @ref Response value if the request did not
2427  * succeed.
2428  */
2430  static constexpr MessageType MESSAGE_TYPE = MessageType::GET_MESSAGE_RATE;
2431  static constexpr uint8_t MESSAGE_VERSION = 0;
2432 
2433  /**
2434  * The output interface to be queried.
2435  *
2436  * @ref TransportType::ALL is not supported. To query for multiple transports,
2437  * send separate requests.
2438  */
2440 
2441  /**
2442  * The desired message protocol. If @ref ProtocolType::ALL, return the current
2443  * settings for all supported protocols.
2444  */
2446 
2447  /** The source of the parameter value (active, saved, etc.). */
2449 
2450  /**
2451  * The ID of the desired message type (e.g., 10000 for FusionEngine
2452  * @ref MessageType::POSE messages). See @ref NmeaMessageType for NMEA-0183
2453  * messages. If @ref ALL_MESSAGES_ID, return the current settings for all
2454  * supported messages on the selected interface and protocol.
2455  */
2456  uint16_t message_id = ALL_MESSAGES_ID;
2457 };
2458 
2459 /**
2460  * @brief A list of transport interfaces supported by the device (@ref
2461  * MessageType::SUPPORTED_IO_INTERFACES, version 1.0).
2462  * @ingroup io_interfaces
2463  */
2465  static constexpr MessageType MESSAGE_TYPE =
2467  static constexpr uint8_t MESSAGE_VERSION = 0;
2468 
2469  /** The number of interfaces reported by this message. */
2470  uint8_t num_interfaces = 0;
2471 
2472  uint8_t reserved1[7] = {0};
2473 
2474  /** This is followed `num_interfaces` @ref InterfaceID elements. */
2475  // InterfaceID interfaces[num_interfaces]
2476 };
2477 
2478 /**
2479  * @brief An element of a @ref MessageRateResponse message.
2480  * @ingroup io_interfaces
2481  */
2483  /**
2484  * Flag to indicate the active value for this configuration differs from the
2485  * value saved to persistent memory.
2486  */
2487  static constexpr uint8_t FLAG_ACTIVE_DIFFERS_FROM_SAVED = 0x1;
2488 
2489  /** The protocol of the message being returned. */
2491 
2492  /** Flags that describe the entry. */
2493  uint8_t flags = 0;
2494 
2495  /**
2496  * The ID of the returned message type (e.g., 10000 for FusionEngine
2497  * @ref MessageType::POSE messages). See @ref NmeaMessageType for NMEA-0183
2498  * messages.
2499  */
2500  uint16_t message_id = 0;
2501 
2502  /** The current configuration for this message. */
2503  MessageRate configured_rate = MessageRate::OFF;
2504 
2505  /**
2506  * The currently active output rate for this message, factoring in effects of
2507  * additional configuration settings that may override the configured rate
2508  * such as enabling diagnostic output.
2509  */
2510  MessageRate effective_rate = MessageRate::OFF;
2511 
2512  uint8_t reserved1[2] = {0};
2513 };
2514 
2515 /**
2516  * @brief Response to a @ref GetMessageRate request (@ref
2517  * MessageType::MESSAGE_RATE_RESPONSE, version 1.1).
2518  * @ingroup io_interfaces
2519  *
2520  * This message will be followed by @ref num_rates @ref MessageRateResponseEntry
2521  * elements:
2522  *
2523  * ```
2524  * {MessageHeader, MessageRateResponse, MessageRateResponseEntry[num_rates]}
2525  * ```
2526  */
2528  static constexpr MessageType MESSAGE_TYPE =
2530  static constexpr uint8_t MESSAGE_VERSION = 1;
2531 
2532  /** The source of the parameter value (active, saved, etc.). */
2534 
2535  /** The response status (success, error, etc.). */
2537 
2538  /** The number of rates reported by this message. */
2539  uint16_t num_rates = 0;
2540 
2541  /** The output interface corresponding with this response. */
2542  InterfaceID output_interface = {};
2543 };
2544 
2545 /**************************************************************************/ /**
2546  * @defgroup gnss_corrections_control GNSS Corrections Control
2547  * @brief Messages for enabling/disabling GNSS corrections sources.
2548  * @ingroup config_and_ctrl_messages
2549  ******************************************************************************/
2550 
2551 /**
2552  * @brief L-band demodulator configuration parameters.
2553  * @ingroup gnss_corrections_control
2554  */
2556  /**
2557  * The center frequency of the L-band beam (Hz).
2558  */
2559  double center_frequency_hz = 1555492500.0;
2560 
2561  /**
2562  * The size of the signal acquisition search space (in Hz) around the center
2563  * frequency.
2564  *
2565  * For example, a value of 6000 will search +/- 3 kHz around the center
2566  * frequency.
2567  */
2568  float search_window_hz = 2000.0;
2569 
2570  /**
2571  * If `true`, only output data frames with the configured service ID.
2572  * Otherwise, output all decoded frames.
2573  */
2574  bool filter_data_by_service_id = true;
2575 
2576  /** Enable/disable the descrambler. */
2577  bool use_descrambler = true;
2578 
2579  /** Service ID of the provider. */
2580  uint16_t pmp_service_id = 0x5555;
2581 
2582  /** Unique word of the provider. */
2583  uint64_t pmp_unique_word = 0xE15AE893E15AE893ull;
2584 
2585  /** Data rate of the provider (bps). */
2586  uint16_t pmp_data_rate_bps = 4800;
2587 
2588  /** The initialization value for the descrambling vector. */
2589  uint16_t descrambler_init = 0x6969;
2590 };
2591 
2592 #pragma pack(pop)
2593 
2594 } // namespace messages
2595 } // namespace fusion_engine
2596 } // namespace point_one
@ INTERVAL_1_S
Output this message every second.
@ OFF
Tropospheric delay model disabled.
@ AUDI_Q7
@ INTERVAL_5_S
Output this message every 5 seconds.
P1_CONSTEXPR_FUNC InterfaceID()=default
@ IMPORT_DATA
ImportDataMessage
@ AUTO
Select the best available ionospheric delay model.
@ PQTMGNSS
@ ALL
Set/get the configuration for the all I/O interfaces.
@ WHEEL_SPEED
Individual speed measurements for multiple wheels, reported in meters/second.
@ FRONT_WHEELS
Front wheel speed data to be applied to the system.
ConfigurationSource
The type of a device's configuration settings.
@ INTERVAL_50_MS
Output this message every 50 milliseconds.
A 3-dimensional vector (used for lever arms, etc.).
P1_CONSTEXPR_FUNC InterfaceID(TransportType type, uint8_t index=0)
Identifier for an I/O interface.
@ FORWARD_ACTIVE_HIGH
Assume vehicle is moving forward when direction signal voltage is high, and backward when direction s...
TransportType type
The interface's transport type.
@ VEHICLE_DETAILS
Information about the vehicle including model and dimensions.
MessageType
Identifiers for the defined output message types.
Definition: defs.h:34
@ DEVICE_LEVER_ARM
The location of the device IMU with respect to the vehicle body frame, resolved in the vehicle body f...
@ NONE
Wheel/vehicle speed data not available.
Library portability helper definitions.
@ INTERVAL_100_MS
Output this message every 100 milliseconds.
@ INVALID
Response to a GetConfigMessage request (MessageType::CONFIG_RESPONSE, version 1.0).
@ ENABLED
Enable/disable the interface.
@ OK
@ RMC
@ USER_CONFIG
TropoDelayModel
The tropospheric delay model to use.
The orientation of a device with respect to the vehicle body axes.
@ BMW_MOTORRAD
@ UNIX
A UNIX domain socket client or server.
Hardware wheel tick encoder configuration settings.
P1_CONSTEXPR_FUNC const char * to_string(ConfigType type)
Get a human-friendly string name for the specified ConfigType.
Tropospheric delay model configuration.
VehicleModel
The make and model of the vehicle.
@ MAN_TGX
@ P1CALSTATUS
@ AUDI_A8L
@ GNSS_AUX_LEVER_ARM
The location of the secondary GNSS antenna with respect to the vehicle body frame on a dual-antenna p...
#define P1_ALIGNAS(N)
Definition: portability.h:57
@ HARDWARE_TICK_CONFIG
Indicates the mode and direction used when capturing vehicle wheel tick data from a voltage pulse on ...
@ OFF
Wheel tick capture disabled.
@ OFF
Disable output of this message.
@ REMOTE_ADDRESS
Configure the network address for a client to connect to.
@ SAASTAMOINEN
Use the Saastamoinen tropospheric model.
@ DATAGRAM
Operate in datagram mode, preserving message boundaries but not maintaining client connections (simil...
@ PEUGEOT_206
@ P1MSG
@ SUPPORTED_IO_INTERFACES
SupportedIOInterfacesMessage
@ REVERT_TO_SAVED
Revert the active configuration to previously saved values.
@ RIVIAN
Response to a GetMessageRate request (MessageType::MESSAGE_RATE_RESPONSE, version 1....
@ FRONT
Front wheels are steered.
@ FALLING_EDGE
Capture a wheel tick on the falling edge of the incoming pulse.
@ DATASPEED_CD4
MessageRate
The output rate for a message type on an interface.
@ INTERVAL_60_S
Output this message every 60 seconds.
@ PQTMTXT
@ FRONT_AND_REAR
Front and rear wheels are steered.
@ PQTMVERNO_SUB
Information about the vehicle including model and dimensions.
@ INVALID
@ GGA
@ REVERT_TO_DEFAULT
Reset the active and saved configuration to default values.
AppliedSpeedType
The type of vehicle/wheel speed measurements to be applied.
@ SAVED
Settings currently saved to persistent storage.
@ DIRECTION
Set the interface direction (client/server).
@ VTG
@ UNKNOWN
Steered wheels unknown.
Set the output rate for the requested message types (MessageType::SET_MESSAGE_RATE,...
@ KIA_SORENTO
I/O interface parameter configuration submessage (used when sending a SetConfigMessage or GetConfigMe...
@ SERIAL
A serial data interface (e.g.
@ SBAS
Use the SBAS ionospheric model.
Import data from the host to the device (MessageType::IMPORT_DATA, version 1.0).
@ MESSAGE_RATE_RESPONSE
MessageRateResponse
@ SAVE_CONFIG
SaveConfigMessage
@ STREAM
Operate in connection-oriented streaming mode and do not preserve message boundaries (similar to TCP)...
@ INVALID
@ FILE
A interface that writes to a file.
@ GLL
@ HYUNDAI_ELANTRA
P1_CONSTEXPR_FUNC bool operator<(const InterfaceID &other) const
P1_CONSTEXPR_FUNC bool operator!=(const InterfaceID &other) const
@ RISING_EDGE
Capture a wheel tick on the rising edge of the incoming pulse.
@ REAR_WHEELS
Rear wheel speed data to be applied to the system (recommended).
The base class for all message payloads.
Definition: defs.h:687
@ VEHICLE_TICKS
A single wheel rotational angle, reported as accumulated encoder ticks.
Query the value of a user configuration parameter (MessageType::GET_CONFIG, version 1....
@ J1939
@ DEFAULT
Restore this message's rate back to its default value.
@ IONOSPHERE_CONFIG
Ionospheric delay model configuration.
@ INTERVAL_20_MS
Output this message every 20 milliseconds.
TickMode
The signal edge to use when capturing a wheel tick voltage signal.
@ INTERFACE_CONFIG
Change a configuration setting for a specified output interface.
@ ENABLED_GNSS_FREQUENCY_BANDS
A bitmask indicating which GNSS frequency bands are enabled.
@ LBAND_PARAMETERS
Configuration of L-band Demodulator Parameters.
@ OFF
Wheel tick direction not provided.
@ FRONT_AND_REAR_WHEELS
Front and rear wheel speed data to be applied to the system.
@ UNKNOWN_VEHICLE
@ OUTPUT_LEVER_ARM
The offset of the desired output location with respect to the vehicle body frame, resolved in the veh...
GNSS signal and frequency type definitions.
Definition: logging.h:38
Get the configured output rate for the he requested message type on the specified interface (MessageT...
Export data from the device (MessageType::EXPORT_DATA, version 1.0).
@ UDP
A UDP client or server.
DataVersion data_version
Version of data contents.
@ DEVICE_COARSE_ORIENTATION
The orientation of the device IMU with respect to the vehicle body axes.
@ TCP
A TCP client or server.
@ TROPOSPHERE_CONFIG
Tropospheric delay model configuration.
uint8_t index
An identifier for the instance of this transport.
P1_CONSTEXPR_FUNC bool operator>(const InterfaceID &other) const
@ DEFAULT
Read only device defaults.
ConfigType
An identifier for the contents of a parameter configuration message.
Definition: configuration.h:37
@ GPS_WEEK_ROLLOVER
Specify a GPS legacy week rollover count override to use when converting all legacy 10-bit GPS week n...
@ WHEEL_CONFIG
Information pertaining to wheel speed/rotation measurements when wheel data is transmitted via softwa...
P1_CONSTEXPR_FUNC bool operator<=(const InterfaceID &other) const
@ PQTMVER
@ GNSS_LEVER_ARM
The location of the primary GNSS antenna with respect to the vehicle body frame, resolved in the vehi...
WheelSensorType
The type of vehicle/wheel speed measurements produced by the vehicle.
@ INVALID
@ UART2_BAUD
Configure the UART2 serial baud rate (in bits/second).
Direction
SaveAction
The type configuration save operation to be performed.
@ GET_MESSAGE_RATE
GetMessageRate
@ NONE
Speed data not applied to the system.
@ BAUD_RATE
Configure the serial baud rate (in bits/second).
@ INVALID
@ ENABLED_GNSS_SYSTEMS
A bitmask indicating which GNSS constellations are enabled.
std::ostream p1_ostream
Definition: portability.h:75
ConfigType config_type
The type of parameter to be configured.
Response
Command response status indicators.
Definition: defs.h:406
A list of transport interfaces supported by the device (MessageType::SUPPORTED_IO_INTERFACES,...
@ SOCKET_TYPE
Set the UNIX domain socket type (streaming/datagram/sequenced).
@ EXPORT_DATA
ExportDataMessage
@ GSA
@ PROFILING_MASK
A bitmask indicating which profiling features are enabled.
@ SAVE
Save all active parameters to persistent storage.
@ UART2_OUTPUT_DIAGNOSTICS_MESSAGES
Enable/disable output of diagnostic data on UART2.
@ MAX_RATE
Alias for MessageRate::ON_CHANGE.
p1_ostream & operator<<(p1_ostream &stream, ConfigType type)
ConfigType stream operator.
TickDirection
The way to interpret an incoming voltage signal, used to indicate direction of a hardware wheel tick ...
@ ENABLE_WATCHDOG_TIMER
Enable watchdog timer to restart device after fatal errors.
@ CALIBRATION_STATE
An element of a MessageRateResponse message.
NmeaMessageType
Integer ID for NMEA messages.
@ INTERVAL_500_MS
Output this message every 500 milliseconds.
DataType
Type of data stored on device.
@ SET_MESSAGE_RATE
SetMessageRate
@ FUSION_ENGINE
@ CURRENT
Set/get the configuration for the interface on which the command was received.
Save or reload configuration settings (MessageType::SAVE_CONFIG, version 1.0).
@ INTERVAL_10_S
Output this message every 10 seconds.
InterfaceConfigType
An identifier for the contents of a output interface configuration submessage.
@ RTCM
@ OFF
Ionospheric delay model disabled.
#define P1_CONSTEXPR_FUNC
Definition: portability.h:105
L-band demodulator configuration parameters.
Set a user configuration parameter (MessageType::SET_CONFIG, version 1.0).
ProtocolType
The framing protocol of a message.
Message for reporting platform storage data (MessageType::PLATFORM_STORAGE_DATA, version 1....
@ INVALID
@ CLIENT
A client connecting to a specified remote server.
@ INVALID
TransportType
Type of I/O interface transport.
@ WEBSOCKET
A WebSocket client or server.
@ FACTION
TransportDirection
The direction (client/server) for an individual interface.
@ INVALID
@ GET_CONFIG
GetConfigMessage
@ OUTPUT_DIAGNOSTICS_MESSAGES
Enable/disable output of diagnostic data on this interface.
@ ZDA
@ CRASH_LOG
@ PQTMVER_SUB
@ SERVER
A server listening for one or more incoming remote connections.
@ SET_CONFIG
SetConfigMessage
@ TICKS
Individual rotational angle measurements for multiple wheels, reported as accumulated encoder ticks.
@ ON_CHANGE
Output this message each time a new value is available.
@ VEHICLE_SPEED
A single value indicating the vehicle speed (in meters/second).
@ NMEA
@ KLOBUCHAR
Use the Klobuchar ionospheric model.
@ LEAP_SECOND
Specify a UTC leap second count override value to use for all UTC time conversions.
@ ACTIVE
Active configuration currently in use by the device.
P1_CONSTEXPR_FUNC bool operator==(const InterfaceID &other) const
@ FORWARD
The vehicle is in a forward gear.
SteeringType
Indication of which of the vehicle's wheels are steered.
Point One FusionEngine output message common definitions.
@ GSV
Software vehicle/wheel speed measurement configuration settings.
@ INTERVAL_2_S
Output this message every 2 seconds.
@ SEQPACKET
Operate in sequenced packet mode, which is both connection-oriented and preserves message boundaries.
Ionospheric delay model configuration.
@ LINCOLN_MKZ
@ PLATFORM_STORAGE_DATA
PlatformStorageDataMessage
IonoDelayModel
The ionospheric delay model to use.
@ FACTION_V2
@ BMW_7
@ ALL
This is used for requesting the configuration for all protocols.
@ PQTMVERNO
SocketType
The socket type specifying how data is transmitted for UNIX domain sockets.
DataVersion data_version
Version of data contents.
@ INTERVAL_30_S
Output this message every 30 seconds.
@ DEPRECATED_HEADING_BIAS
Used to set horizontal (yaw) & vertical (pitch) biases (in degrees) on a dual-antenna heading platfor...
@ AUTO
Select the best available tropospheric delay model.
@ UART1_OUTPUT_DIAGNOSTICS_MESSAGES
Enable/disable output of diagnostic data on UART1.
@ KIA_SPORTAGE
@ TESLA_MODEL_X
@ FORWARD_ACTIVE_LOW
Assume vehicle is moving forward when direction signal voltage is low, and backward when direction si...
@ LEXUS_CT200H
@ INTERVAL_40_MS
Output this message every 40 milliseconds.
@ FILTER_STATE
A struct representing the version of a data object.
Definition: data_version.h:24
@ INTERVAL_200_MS
Output this message every 200 milliseconds.
P1_CONSTEXPR_FUNC bool operator>=(const InterfaceID &other) const
@ PORT
Configure the network port.
@ TESLA_MODEL_3
constexpr uint16_t ALL_MESSAGES_ID
Setting message_id to this value acts as a wild card.
@ INTERVAL_10_MS
Output this message every 10 milliseconds.
@ VW_4
@ VEHICLE_BODY
Individual vehicle speed to be applied to the system.
@ UART1_BAUD
Configure the UART1 serial baud rate (in bits/second).
@ USER_DEVICE_ID
A string for identifying a device.
@ CONFIG_RESPONSE
ConfigResponseMessage