1pub use estimated_horizontal_error_ellipse::EstimatedHorizontalErrorEllipse;
40pub use msg_age_corrections::MsgAgeCorrections;
41pub use msg_baseline_ecef::MsgBaselineEcef;
42pub use msg_baseline_ecef_dep_a::MsgBaselineEcefDepA;
43pub use msg_baseline_heading_dep_a::MsgBaselineHeadingDepA;
44pub use msg_baseline_ned::MsgBaselineNed;
45pub use msg_baseline_ned_dep_a::MsgBaselineNedDepA;
46pub use msg_dops::MsgDops;
47pub use msg_dops_dep_a::MsgDopsDepA;
48pub use msg_gps_time::MsgGpsTime;
49pub use msg_gps_time_dep_a::MsgGpsTimeDepA;
50pub use msg_gps_time_gnss::MsgGpsTimeGnss;
51pub use msg_pos_ecef::MsgPosEcef;
52pub use msg_pos_ecef_cov::MsgPosEcefCov;
53pub use msg_pos_ecef_cov_gnss::MsgPosEcefCovGnss;
54pub use msg_pos_ecef_dep_a::MsgPosEcefDepA;
55pub use msg_pos_ecef_gnss::MsgPosEcefGnss;
56pub use msg_pos_llh::MsgPosLlh;
57pub use msg_pos_llh_acc::MsgPosLlhAcc;
58pub use msg_pos_llh_cov::MsgPosLlhCov;
59pub use msg_pos_llh_cov_gnss::MsgPosLlhCovGnss;
60pub use msg_pos_llh_dep_a::MsgPosLlhDepA;
61pub use msg_pos_llh_gnss::MsgPosLlhGnss;
62pub use msg_pose_relative::MsgPoseRelative;
63pub use msg_protection_level::MsgProtectionLevel;
64pub use msg_protection_level_dep_a::MsgProtectionLevelDepA;
65pub use msg_reference_frame_param::MsgReferenceFrameParam;
66pub use msg_utc_leap_second::MsgUtcLeapSecond;
67pub use msg_utc_time::MsgUtcTime;
68pub use msg_utc_time_gnss::MsgUtcTimeGnss;
69pub use msg_vel_body::MsgVelBody;
70pub use msg_vel_cog::MsgVelCog;
71pub use msg_vel_ecef::MsgVelEcef;
72pub use msg_vel_ecef_cov::MsgVelEcefCov;
73pub use msg_vel_ecef_cov_gnss::MsgVelEcefCovGnss;
74pub use msg_vel_ecef_dep_a::MsgVelEcefDepA;
75pub use msg_vel_ecef_gnss::MsgVelEcefGnss;
76pub use msg_vel_ned::MsgVelNed;
77pub use msg_vel_ned_cov::MsgVelNedCov;
78pub use msg_vel_ned_cov_gnss::MsgVelNedCovGnss;
79pub use msg_vel_ned_dep_a::MsgVelNedDepA;
80pub use msg_vel_ned_gnss::MsgVelNedGnss;
81
82pub mod estimated_horizontal_error_ellipse {
83 #![allow(unused_imports)]
84
85 use super::*;
86 use crate::messages::lib::*;
87 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
89 #[allow(clippy::derive_partial_eq_without_eq)]
90 #[derive(Debug, PartialEq, Clone)]
91 pub struct EstimatedHorizontalErrorEllipse {
92 #[cfg_attr(feature = "serde", serde(rename = "semi_major"))]
95 pub semi_major: f32,
96 #[cfg_attr(feature = "serde", serde(rename = "semi_minor"))]
99 pub semi_minor: f32,
100 #[cfg_attr(feature = "serde", serde(rename = "orientation"))]
103 pub orientation: f32,
104 }
105
106 impl WireFormat for EstimatedHorizontalErrorEllipse {
107 const MIN_LEN: usize = <f32 as WireFormat>::MIN_LEN
108 + <f32 as WireFormat>::MIN_LEN
109 + <f32 as WireFormat>::MIN_LEN;
110 fn len(&self) -> usize {
111 WireFormat::len(&self.semi_major)
112 + WireFormat::len(&self.semi_minor)
113 + WireFormat::len(&self.orientation)
114 }
115 fn write<B: BufMut>(&self, buf: &mut B) {
116 WireFormat::write(&self.semi_major, buf);
117 WireFormat::write(&self.semi_minor, buf);
118 WireFormat::write(&self.orientation, buf);
119 }
120 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
121 EstimatedHorizontalErrorEllipse {
122 semi_major: WireFormat::parse_unchecked(buf),
123 semi_minor: WireFormat::parse_unchecked(buf),
124 orientation: WireFormat::parse_unchecked(buf),
125 }
126 }
127 }
128}
129
130pub mod msg_age_corrections {
131 #![allow(unused_imports)]
132
133 use super::*;
134 use crate::messages::lib::*;
135
136 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
142 #[allow(clippy::derive_partial_eq_without_eq)]
143 #[derive(Debug, PartialEq, Clone)]
144 pub struct MsgAgeCorrections {
145 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
147 pub sender_id: Option<u16>,
148 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
150 pub tow: u32,
151 #[cfg_attr(feature = "serde", serde(rename = "age"))]
153 pub age: u16,
154 }
155
156 impl ConcreteMessage for MsgAgeCorrections {
157 const MESSAGE_TYPE: u16 = 528;
158 const MESSAGE_NAME: &'static str = "MSG_AGE_CORRECTIONS";
159 }
160
161 impl SbpMessage for MsgAgeCorrections {
162 fn message_name(&self) -> &'static str {
163 <Self as ConcreteMessage>::MESSAGE_NAME
164 }
165 fn message_type(&self) -> Option<u16> {
166 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
167 }
168 fn sender_id(&self) -> Option<u16> {
169 self.sender_id
170 }
171 fn set_sender_id(&mut self, new_id: u16) {
172 self.sender_id = Some(new_id);
173 }
174 fn encoded_len(&self) -> usize {
175 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
176 }
177 fn is_valid(&self) -> bool {
178 true
179 }
180 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
181 Ok(self)
182 }
183
184 #[cfg(feature = "swiftnav")]
185 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
186 let tow_s = (self.tow as f64) / 1000.0;
187 let gps_time = match time::GpsTime::new(0, tow_s) {
188 Ok(gps_time) => gps_time.tow(),
189 Err(e) => return Some(Err(e.into())),
190 };
191 Some(Ok(time::MessageTime::Rover(gps_time.into())))
192 }
193 }
194
195 impl FriendlyName for MsgAgeCorrections {
196 fn friendly_name() -> &'static str {
197 "AGE CORRECTIONS"
198 }
199 }
200
201 impl TryFrom<Sbp> for MsgAgeCorrections {
202 type Error = TryFromSbpError;
203 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
204 match msg {
205 Sbp::MsgAgeCorrections(m) => Ok(m),
206 _ => Err(TryFromSbpError(msg)),
207 }
208 }
209 }
210
211 impl WireFormat for MsgAgeCorrections {
212 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN + <u16 as WireFormat>::MIN_LEN;
213 fn len(&self) -> usize {
214 WireFormat::len(&self.tow) + WireFormat::len(&self.age)
215 }
216 fn write<B: BufMut>(&self, buf: &mut B) {
217 WireFormat::write(&self.tow, buf);
218 WireFormat::write(&self.age, buf);
219 }
220 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
221 MsgAgeCorrections {
222 sender_id: None,
223 tow: WireFormat::parse_unchecked(buf),
224 age: WireFormat::parse_unchecked(buf),
225 }
226 }
227 }
228}
229
230pub mod msg_baseline_ecef {
231 #![allow(unused_imports)]
232
233 use super::*;
234 use crate::messages::lib::*;
235
236 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
246 #[allow(clippy::derive_partial_eq_without_eq)]
247 #[derive(Debug, PartialEq, Clone)]
248 pub struct MsgBaselineEcef {
249 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
251 pub sender_id: Option<u16>,
252 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
254 pub tow: u32,
255 #[cfg_attr(feature = "serde", serde(rename = "x"))]
257 pub x: i32,
258 #[cfg_attr(feature = "serde", serde(rename = "y"))]
260 pub y: i32,
261 #[cfg_attr(feature = "serde", serde(rename = "z"))]
263 pub z: i32,
264 #[cfg_attr(feature = "serde", serde(rename = "accuracy"))]
266 pub accuracy: u16,
267 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
269 pub n_sats: u8,
270 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
272 pub flags: u8,
273 }
274
275 impl MsgBaselineEcef {
276 pub fn fix_mode(&self) -> Result<FixMode, u8> {
282 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
283 }
284
285 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
287 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
288 }
289 }
290
291 impl ConcreteMessage for MsgBaselineEcef {
292 const MESSAGE_TYPE: u16 = 523;
293 const MESSAGE_NAME: &'static str = "MSG_BASELINE_ECEF";
294 }
295
296 impl SbpMessage for MsgBaselineEcef {
297 fn message_name(&self) -> &'static str {
298 <Self as ConcreteMessage>::MESSAGE_NAME
299 }
300 fn message_type(&self) -> Option<u16> {
301 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
302 }
303 fn sender_id(&self) -> Option<u16> {
304 self.sender_id
305 }
306 fn set_sender_id(&mut self, new_id: u16) {
307 self.sender_id = Some(new_id);
308 }
309 fn encoded_len(&self) -> usize {
310 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
311 }
312 fn is_valid(&self) -> bool {
313 true
314 }
315 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
316 Ok(self)
317 }
318
319 #[cfg(feature = "swiftnav")]
320 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
321 let tow_s = (self.tow as f64) / 1000.0;
322 let gps_time = match time::GpsTime::new(0, tow_s) {
323 Ok(gps_time) => gps_time.tow(),
324 Err(e) => return Some(Err(e.into())),
325 };
326 Some(Ok(time::MessageTime::Rover(gps_time.into())))
327 }
328 }
329
330 impl FriendlyName for MsgBaselineEcef {
331 fn friendly_name() -> &'static str {
332 "BASELINE ECEF"
333 }
334 }
335
336 impl TryFrom<Sbp> for MsgBaselineEcef {
337 type Error = TryFromSbpError;
338 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
339 match msg {
340 Sbp::MsgBaselineEcef(m) => Ok(m),
341 _ => Err(TryFromSbpError(msg)),
342 }
343 }
344 }
345
346 impl WireFormat for MsgBaselineEcef {
347 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
348 + <i32 as WireFormat>::MIN_LEN
349 + <i32 as WireFormat>::MIN_LEN
350 + <i32 as WireFormat>::MIN_LEN
351 + <u16 as WireFormat>::MIN_LEN
352 + <u8 as WireFormat>::MIN_LEN
353 + <u8 as WireFormat>::MIN_LEN;
354 fn len(&self) -> usize {
355 WireFormat::len(&self.tow)
356 + WireFormat::len(&self.x)
357 + WireFormat::len(&self.y)
358 + WireFormat::len(&self.z)
359 + WireFormat::len(&self.accuracy)
360 + WireFormat::len(&self.n_sats)
361 + WireFormat::len(&self.flags)
362 }
363 fn write<B: BufMut>(&self, buf: &mut B) {
364 WireFormat::write(&self.tow, buf);
365 WireFormat::write(&self.x, buf);
366 WireFormat::write(&self.y, buf);
367 WireFormat::write(&self.z, buf);
368 WireFormat::write(&self.accuracy, buf);
369 WireFormat::write(&self.n_sats, buf);
370 WireFormat::write(&self.flags, buf);
371 }
372 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
373 MsgBaselineEcef {
374 sender_id: None,
375 tow: WireFormat::parse_unchecked(buf),
376 x: WireFormat::parse_unchecked(buf),
377 y: WireFormat::parse_unchecked(buf),
378 z: WireFormat::parse_unchecked(buf),
379 accuracy: WireFormat::parse_unchecked(buf),
380 n_sats: WireFormat::parse_unchecked(buf),
381 flags: WireFormat::parse_unchecked(buf),
382 }
383 }
384 }
385
386 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
388 pub enum FixMode {
389 Invalid = 0,
391
392 DifferentialGnss = 2,
394
395 FloatRtk = 3,
397
398 FixedRtk = 4,
400 }
401
402 impl std::fmt::Display for FixMode {
403 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
404 match self {
405 FixMode::Invalid => f.write_str("Invalid"),
406 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
407 FixMode::FloatRtk => f.write_str("Float RTK"),
408 FixMode::FixedRtk => f.write_str("Fixed RTK"),
409 }
410 }
411 }
412
413 impl TryFrom<u8> for FixMode {
414 type Error = u8;
415 fn try_from(i: u8) -> Result<Self, u8> {
416 match i {
417 0 => Ok(FixMode::Invalid),
418 2 => Ok(FixMode::DifferentialGnss),
419 3 => Ok(FixMode::FloatRtk),
420 4 => Ok(FixMode::FixedRtk),
421 i => Err(i),
422 }
423 }
424 }
425}
426
427pub mod msg_baseline_ecef_dep_a {
428 #![allow(unused_imports)]
429
430 use super::*;
431 use crate::messages::lib::*;
432
433 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
438 #[allow(clippy::derive_partial_eq_without_eq)]
439 #[derive(Debug, PartialEq, Clone)]
440 pub struct MsgBaselineEcefDepA {
441 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
443 pub sender_id: Option<u16>,
444 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
446 pub tow: u32,
447 #[cfg_attr(feature = "serde", serde(rename = "x"))]
449 pub x: i32,
450 #[cfg_attr(feature = "serde", serde(rename = "y"))]
452 pub y: i32,
453 #[cfg_attr(feature = "serde", serde(rename = "z"))]
455 pub z: i32,
456 #[cfg_attr(feature = "serde", serde(rename = "accuracy"))]
458 pub accuracy: u16,
459 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
461 pub n_sats: u8,
462 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
464 pub flags: u8,
465 }
466
467 impl MsgBaselineEcefDepA {
468 pub fn raim_repair_flag(&self) -> Result<RaimRepairFlag, u8> {
474 get_bit_range!(self.flags, u8, u8, 4, 4).try_into()
475 }
476
477 pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) {
479 set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 4, 4);
480 }
481
482 pub fn raim_availability_flag(&self) -> Result<RaimAvailabilityFlag, u8> {
488 get_bit_range!(self.flags, u8, u8, 3, 3).try_into()
489 }
490
491 pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) {
493 set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 3, 3);
494 }
495
496 pub fn fix_mode(&self) -> Result<FixMode, u8> {
502 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
503 }
504
505 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
507 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
508 }
509 }
510
511 impl ConcreteMessage for MsgBaselineEcefDepA {
512 const MESSAGE_TYPE: u16 = 514;
513 const MESSAGE_NAME: &'static str = "MSG_BASELINE_ECEF_DEP_A";
514 }
515
516 impl SbpMessage for MsgBaselineEcefDepA {
517 fn message_name(&self) -> &'static str {
518 <Self as ConcreteMessage>::MESSAGE_NAME
519 }
520 fn message_type(&self) -> Option<u16> {
521 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
522 }
523 fn sender_id(&self) -> Option<u16> {
524 self.sender_id
525 }
526 fn set_sender_id(&mut self, new_id: u16) {
527 self.sender_id = Some(new_id);
528 }
529 fn encoded_len(&self) -> usize {
530 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
531 }
532 fn is_valid(&self) -> bool {
533 true
534 }
535 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
536 Ok(self)
537 }
538
539 #[cfg(feature = "swiftnav")]
540 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
541 let tow_s = (self.tow as f64) / 1000.0;
542 let gps_time = match time::GpsTime::new(0, tow_s) {
543 Ok(gps_time) => gps_time.tow(),
544 Err(e) => return Some(Err(e.into())),
545 };
546 Some(Ok(time::MessageTime::Rover(gps_time.into())))
547 }
548 }
549
550 impl FriendlyName for MsgBaselineEcefDepA {
551 fn friendly_name() -> &'static str {
552 "BASELINE ECEF DEP A"
553 }
554 }
555
556 impl TryFrom<Sbp> for MsgBaselineEcefDepA {
557 type Error = TryFromSbpError;
558 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
559 match msg {
560 Sbp::MsgBaselineEcefDepA(m) => Ok(m),
561 _ => Err(TryFromSbpError(msg)),
562 }
563 }
564 }
565
566 impl WireFormat for MsgBaselineEcefDepA {
567 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
568 + <i32 as WireFormat>::MIN_LEN
569 + <i32 as WireFormat>::MIN_LEN
570 + <i32 as WireFormat>::MIN_LEN
571 + <u16 as WireFormat>::MIN_LEN
572 + <u8 as WireFormat>::MIN_LEN
573 + <u8 as WireFormat>::MIN_LEN;
574 fn len(&self) -> usize {
575 WireFormat::len(&self.tow)
576 + WireFormat::len(&self.x)
577 + WireFormat::len(&self.y)
578 + WireFormat::len(&self.z)
579 + WireFormat::len(&self.accuracy)
580 + WireFormat::len(&self.n_sats)
581 + WireFormat::len(&self.flags)
582 }
583 fn write<B: BufMut>(&self, buf: &mut B) {
584 WireFormat::write(&self.tow, buf);
585 WireFormat::write(&self.x, buf);
586 WireFormat::write(&self.y, buf);
587 WireFormat::write(&self.z, buf);
588 WireFormat::write(&self.accuracy, buf);
589 WireFormat::write(&self.n_sats, buf);
590 WireFormat::write(&self.flags, buf);
591 }
592 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
593 MsgBaselineEcefDepA {
594 sender_id: None,
595 tow: WireFormat::parse_unchecked(buf),
596 x: WireFormat::parse_unchecked(buf),
597 y: WireFormat::parse_unchecked(buf),
598 z: WireFormat::parse_unchecked(buf),
599 accuracy: WireFormat::parse_unchecked(buf),
600 n_sats: WireFormat::parse_unchecked(buf),
601 flags: WireFormat::parse_unchecked(buf),
602 }
603 }
604 }
605
606 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
608 pub enum RaimRepairFlag {
609 NoRepair = 0,
611
612 SolutionCameFromRaimRepair = 1,
614 }
615
616 impl std::fmt::Display for RaimRepairFlag {
617 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
618 match self {
619 RaimRepairFlag::NoRepair => f.write_str("No repair"),
620 RaimRepairFlag::SolutionCameFromRaimRepair => {
621 f.write_str("Solution came from RAIM repair")
622 }
623 }
624 }
625 }
626
627 impl TryFrom<u8> for RaimRepairFlag {
628 type Error = u8;
629 fn try_from(i: u8) -> Result<Self, u8> {
630 match i {
631 0 => Ok(RaimRepairFlag::NoRepair),
632 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair),
633 i => Err(i),
634 }
635 }
636 }
637
638 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
640 pub enum RaimAvailabilityFlag {
641 RaimCheckWasExplicitlyDisabledOrUnavailable = 0,
643
644 RaimCheckWasAvailable = 1,
646 }
647
648 impl std::fmt::Display for RaimAvailabilityFlag {
649 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
650 match self {
651 RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => {
652 f.write_str("RAIM check was explicitly disabled or unavailable")
653 }
654 RaimAvailabilityFlag::RaimCheckWasAvailable => {
655 f.write_str("RAIM check was available")
656 }
657 }
658 }
659 }
660
661 impl TryFrom<u8> for RaimAvailabilityFlag {
662 type Error = u8;
663 fn try_from(i: u8) -> Result<Self, u8> {
664 match i {
665 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable),
666 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable),
667 i => Err(i),
668 }
669 }
670 }
671
672 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
674 pub enum FixMode {
675 FloatRtk = 0,
677
678 FixedRtk = 1,
680 }
681
682 impl std::fmt::Display for FixMode {
683 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
684 match self {
685 FixMode::FloatRtk => f.write_str("Float RTK"),
686 FixMode::FixedRtk => f.write_str("Fixed RTK"),
687 }
688 }
689 }
690
691 impl TryFrom<u8> for FixMode {
692 type Error = u8;
693 fn try_from(i: u8) -> Result<Self, u8> {
694 match i {
695 0 => Ok(FixMode::FloatRtk),
696 1 => Ok(FixMode::FixedRtk),
697 i => Err(i),
698 }
699 }
700 }
701}
702
703pub mod msg_baseline_heading_dep_a {
704 #![allow(unused_imports)]
705
706 use super::*;
707 use crate::messages::lib::*;
708
709 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
714 #[allow(clippy::derive_partial_eq_without_eq)]
715 #[derive(Debug, PartialEq, Clone)]
716 pub struct MsgBaselineHeadingDepA {
717 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
719 pub sender_id: Option<u16>,
720 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
722 pub tow: u32,
723 #[cfg_attr(feature = "serde", serde(rename = "heading"))]
725 pub heading: u32,
726 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
728 pub n_sats: u8,
729 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
731 pub flags: u8,
732 }
733
734 impl MsgBaselineHeadingDepA {
735 pub fn raim_repair_flag(&self) -> Result<RaimRepairFlag, u8> {
741 get_bit_range!(self.flags, u8, u8, 4, 4).try_into()
742 }
743
744 pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) {
746 set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 4, 4);
747 }
748
749 pub fn raim_availability_flag(&self) -> Result<RaimAvailabilityFlag, u8> {
755 get_bit_range!(self.flags, u8, u8, 3, 3).try_into()
756 }
757
758 pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) {
760 set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 3, 3);
761 }
762
763 pub fn fix_mode(&self) -> Result<FixMode, u8> {
769 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
770 }
771
772 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
774 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
775 }
776 }
777
778 impl ConcreteMessage for MsgBaselineHeadingDepA {
779 const MESSAGE_TYPE: u16 = 519;
780 const MESSAGE_NAME: &'static str = "MSG_BASELINE_HEADING_DEP_A";
781 }
782
783 impl SbpMessage for MsgBaselineHeadingDepA {
784 fn message_name(&self) -> &'static str {
785 <Self as ConcreteMessage>::MESSAGE_NAME
786 }
787 fn message_type(&self) -> Option<u16> {
788 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
789 }
790 fn sender_id(&self) -> Option<u16> {
791 self.sender_id
792 }
793 fn set_sender_id(&mut self, new_id: u16) {
794 self.sender_id = Some(new_id);
795 }
796 fn encoded_len(&self) -> usize {
797 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
798 }
799 fn is_valid(&self) -> bool {
800 true
801 }
802 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
803 Ok(self)
804 }
805
806 #[cfg(feature = "swiftnav")]
807 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
808 let tow_s = (self.tow as f64) / 1000.0;
809 let gps_time = match time::GpsTime::new(0, tow_s) {
810 Ok(gps_time) => gps_time.tow(),
811 Err(e) => return Some(Err(e.into())),
812 };
813 Some(Ok(time::MessageTime::Rover(gps_time.into())))
814 }
815 }
816
817 impl FriendlyName for MsgBaselineHeadingDepA {
818 fn friendly_name() -> &'static str {
819 "BASELINE HEADING DEP A"
820 }
821 }
822
823 impl TryFrom<Sbp> for MsgBaselineHeadingDepA {
824 type Error = TryFromSbpError;
825 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
826 match msg {
827 Sbp::MsgBaselineHeadingDepA(m) => Ok(m),
828 _ => Err(TryFromSbpError(msg)),
829 }
830 }
831 }
832
833 impl WireFormat for MsgBaselineHeadingDepA {
834 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
835 + <u32 as WireFormat>::MIN_LEN
836 + <u8 as WireFormat>::MIN_LEN
837 + <u8 as WireFormat>::MIN_LEN;
838 fn len(&self) -> usize {
839 WireFormat::len(&self.tow)
840 + WireFormat::len(&self.heading)
841 + WireFormat::len(&self.n_sats)
842 + WireFormat::len(&self.flags)
843 }
844 fn write<B: BufMut>(&self, buf: &mut B) {
845 WireFormat::write(&self.tow, buf);
846 WireFormat::write(&self.heading, buf);
847 WireFormat::write(&self.n_sats, buf);
848 WireFormat::write(&self.flags, buf);
849 }
850 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
851 MsgBaselineHeadingDepA {
852 sender_id: None,
853 tow: WireFormat::parse_unchecked(buf),
854 heading: WireFormat::parse_unchecked(buf),
855 n_sats: WireFormat::parse_unchecked(buf),
856 flags: WireFormat::parse_unchecked(buf),
857 }
858 }
859 }
860
861 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
863 pub enum RaimRepairFlag {
864 NoRepair = 0,
866
867 SolutionCameFromRaimRepair = 1,
869 }
870
871 impl std::fmt::Display for RaimRepairFlag {
872 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
873 match self {
874 RaimRepairFlag::NoRepair => f.write_str("No repair"),
875 RaimRepairFlag::SolutionCameFromRaimRepair => {
876 f.write_str("Solution came from RAIM repair")
877 }
878 }
879 }
880 }
881
882 impl TryFrom<u8> for RaimRepairFlag {
883 type Error = u8;
884 fn try_from(i: u8) -> Result<Self, u8> {
885 match i {
886 0 => Ok(RaimRepairFlag::NoRepair),
887 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair),
888 i => Err(i),
889 }
890 }
891 }
892
893 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
895 pub enum RaimAvailabilityFlag {
896 RaimCheckWasExplicitlyDisabledOrUnavailable = 0,
898
899 RaimCheckWasAvailable = 1,
901 }
902
903 impl std::fmt::Display for RaimAvailabilityFlag {
904 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
905 match self {
906 RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => {
907 f.write_str("RAIM check was explicitly disabled or unavailable")
908 }
909 RaimAvailabilityFlag::RaimCheckWasAvailable => {
910 f.write_str("RAIM check was available")
911 }
912 }
913 }
914 }
915
916 impl TryFrom<u8> for RaimAvailabilityFlag {
917 type Error = u8;
918 fn try_from(i: u8) -> Result<Self, u8> {
919 match i {
920 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable),
921 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable),
922 i => Err(i),
923 }
924 }
925 }
926
927 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
929 pub enum FixMode {
930 FloatRtk = 0,
932
933 FixedRtk = 1,
935 }
936
937 impl std::fmt::Display for FixMode {
938 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
939 match self {
940 FixMode::FloatRtk => f.write_str("Float RTK"),
941 FixMode::FixedRtk => f.write_str("Fixed RTK"),
942 }
943 }
944 }
945
946 impl TryFrom<u8> for FixMode {
947 type Error = u8;
948 fn try_from(i: u8) -> Result<Self, u8> {
949 match i {
950 0 => Ok(FixMode::FloatRtk),
951 1 => Ok(FixMode::FixedRtk),
952 i => Err(i),
953 }
954 }
955 }
956}
957
958pub mod msg_baseline_ned {
959 #![allow(unused_imports)]
960
961 use super::*;
962 use crate::messages::lib::*;
963
964 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
976 #[allow(clippy::derive_partial_eq_without_eq)]
977 #[derive(Debug, PartialEq, Clone)]
978 pub struct MsgBaselineNed {
979 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
981 pub sender_id: Option<u16>,
982 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
984 pub tow: u32,
985 #[cfg_attr(feature = "serde", serde(rename = "n"))]
987 pub n: i32,
988 #[cfg_attr(feature = "serde", serde(rename = "e"))]
990 pub e: i32,
991 #[cfg_attr(feature = "serde", serde(rename = "d"))]
993 pub d: i32,
994 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
996 pub h_accuracy: u16,
997 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
999 pub v_accuracy: u16,
1000 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
1002 pub n_sats: u8,
1003 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
1005 pub flags: u8,
1006 }
1007
1008 impl MsgBaselineNed {
1009 pub fn fix_mode(&self) -> Result<FixMode, u8> {
1015 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
1016 }
1017
1018 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
1020 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
1021 }
1022 }
1023
1024 impl ConcreteMessage for MsgBaselineNed {
1025 const MESSAGE_TYPE: u16 = 524;
1026 const MESSAGE_NAME: &'static str = "MSG_BASELINE_NED";
1027 }
1028
1029 impl SbpMessage for MsgBaselineNed {
1030 fn message_name(&self) -> &'static str {
1031 <Self as ConcreteMessage>::MESSAGE_NAME
1032 }
1033 fn message_type(&self) -> Option<u16> {
1034 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
1035 }
1036 fn sender_id(&self) -> Option<u16> {
1037 self.sender_id
1038 }
1039 fn set_sender_id(&mut self, new_id: u16) {
1040 self.sender_id = Some(new_id);
1041 }
1042 fn encoded_len(&self) -> usize {
1043 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
1044 }
1045 fn is_valid(&self) -> bool {
1046 true
1047 }
1048 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
1049 Ok(self)
1050 }
1051
1052 #[cfg(feature = "swiftnav")]
1053 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
1054 let tow_s = (self.tow as f64) / 1000.0;
1055 let gps_time = match time::GpsTime::new(0, tow_s) {
1056 Ok(gps_time) => gps_time.tow(),
1057 Err(e) => return Some(Err(e.into())),
1058 };
1059 Some(Ok(time::MessageTime::Rover(gps_time.into())))
1060 }
1061 }
1062
1063 impl FriendlyName for MsgBaselineNed {
1064 fn friendly_name() -> &'static str {
1065 "BASELINE NED"
1066 }
1067 }
1068
1069 impl TryFrom<Sbp> for MsgBaselineNed {
1070 type Error = TryFromSbpError;
1071 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
1072 match msg {
1073 Sbp::MsgBaselineNed(m) => Ok(m),
1074 _ => Err(TryFromSbpError(msg)),
1075 }
1076 }
1077 }
1078
1079 impl WireFormat for MsgBaselineNed {
1080 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
1081 + <i32 as WireFormat>::MIN_LEN
1082 + <i32 as WireFormat>::MIN_LEN
1083 + <i32 as WireFormat>::MIN_LEN
1084 + <u16 as WireFormat>::MIN_LEN
1085 + <u16 as WireFormat>::MIN_LEN
1086 + <u8 as WireFormat>::MIN_LEN
1087 + <u8 as WireFormat>::MIN_LEN;
1088 fn len(&self) -> usize {
1089 WireFormat::len(&self.tow)
1090 + WireFormat::len(&self.n)
1091 + WireFormat::len(&self.e)
1092 + WireFormat::len(&self.d)
1093 + WireFormat::len(&self.h_accuracy)
1094 + WireFormat::len(&self.v_accuracy)
1095 + WireFormat::len(&self.n_sats)
1096 + WireFormat::len(&self.flags)
1097 }
1098 fn write<B: BufMut>(&self, buf: &mut B) {
1099 WireFormat::write(&self.tow, buf);
1100 WireFormat::write(&self.n, buf);
1101 WireFormat::write(&self.e, buf);
1102 WireFormat::write(&self.d, buf);
1103 WireFormat::write(&self.h_accuracy, buf);
1104 WireFormat::write(&self.v_accuracy, buf);
1105 WireFormat::write(&self.n_sats, buf);
1106 WireFormat::write(&self.flags, buf);
1107 }
1108 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
1109 MsgBaselineNed {
1110 sender_id: None,
1111 tow: WireFormat::parse_unchecked(buf),
1112 n: WireFormat::parse_unchecked(buf),
1113 e: WireFormat::parse_unchecked(buf),
1114 d: WireFormat::parse_unchecked(buf),
1115 h_accuracy: WireFormat::parse_unchecked(buf),
1116 v_accuracy: WireFormat::parse_unchecked(buf),
1117 n_sats: WireFormat::parse_unchecked(buf),
1118 flags: WireFormat::parse_unchecked(buf),
1119 }
1120 }
1121 }
1122
1123 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1125 pub enum FixMode {
1126 Invalid = 0,
1128
1129 DifferentialGnss = 2,
1131
1132 FloatRtk = 3,
1134
1135 FixedRtk = 4,
1137 }
1138
1139 impl std::fmt::Display for FixMode {
1140 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1141 match self {
1142 FixMode::Invalid => f.write_str("Invalid"),
1143 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
1144 FixMode::FloatRtk => f.write_str("Float RTK"),
1145 FixMode::FixedRtk => f.write_str("Fixed RTK"),
1146 }
1147 }
1148 }
1149
1150 impl TryFrom<u8> for FixMode {
1151 type Error = u8;
1152 fn try_from(i: u8) -> Result<Self, u8> {
1153 match i {
1154 0 => Ok(FixMode::Invalid),
1155 2 => Ok(FixMode::DifferentialGnss),
1156 3 => Ok(FixMode::FloatRtk),
1157 4 => Ok(FixMode::FixedRtk),
1158 i => Err(i),
1159 }
1160 }
1161 }
1162}
1163
1164pub mod msg_baseline_ned_dep_a {
1165 #![allow(unused_imports)]
1166
1167 use super::*;
1168 use crate::messages::lib::*;
1169
1170 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1175 #[allow(clippy::derive_partial_eq_without_eq)]
1176 #[derive(Debug, PartialEq, Clone)]
1177 pub struct MsgBaselineNedDepA {
1178 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
1180 pub sender_id: Option<u16>,
1181 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
1183 pub tow: u32,
1184 #[cfg_attr(feature = "serde", serde(rename = "n"))]
1186 pub n: i32,
1187 #[cfg_attr(feature = "serde", serde(rename = "e"))]
1189 pub e: i32,
1190 #[cfg_attr(feature = "serde", serde(rename = "d"))]
1192 pub d: i32,
1193 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
1195 pub h_accuracy: u16,
1196 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
1198 pub v_accuracy: u16,
1199 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
1201 pub n_sats: u8,
1202 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
1204 pub flags: u8,
1205 }
1206
1207 impl MsgBaselineNedDepA {
1208 pub fn raim_repair_flag(&self) -> Result<RaimRepairFlag, u8> {
1214 get_bit_range!(self.flags, u8, u8, 4, 4).try_into()
1215 }
1216
1217 pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) {
1219 set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 4, 4);
1220 }
1221
1222 pub fn raim_availability_flag(&self) -> Result<RaimAvailabilityFlag, u8> {
1228 get_bit_range!(self.flags, u8, u8, 3, 3).try_into()
1229 }
1230
1231 pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) {
1233 set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 3, 3);
1234 }
1235
1236 pub fn fix_mode(&self) -> Result<FixMode, u8> {
1242 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
1243 }
1244
1245 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
1247 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
1248 }
1249 }
1250
1251 impl ConcreteMessage for MsgBaselineNedDepA {
1252 const MESSAGE_TYPE: u16 = 515;
1253 const MESSAGE_NAME: &'static str = "MSG_BASELINE_NED_DEP_A";
1254 }
1255
1256 impl SbpMessage for MsgBaselineNedDepA {
1257 fn message_name(&self) -> &'static str {
1258 <Self as ConcreteMessage>::MESSAGE_NAME
1259 }
1260 fn message_type(&self) -> Option<u16> {
1261 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
1262 }
1263 fn sender_id(&self) -> Option<u16> {
1264 self.sender_id
1265 }
1266 fn set_sender_id(&mut self, new_id: u16) {
1267 self.sender_id = Some(new_id);
1268 }
1269 fn encoded_len(&self) -> usize {
1270 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
1271 }
1272 fn is_valid(&self) -> bool {
1273 true
1274 }
1275 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
1276 Ok(self)
1277 }
1278
1279 #[cfg(feature = "swiftnav")]
1280 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
1281 let tow_s = (self.tow as f64) / 1000.0;
1282 let gps_time = match time::GpsTime::new(0, tow_s) {
1283 Ok(gps_time) => gps_time.tow(),
1284 Err(e) => return Some(Err(e.into())),
1285 };
1286 Some(Ok(time::MessageTime::Rover(gps_time.into())))
1287 }
1288 }
1289
1290 impl FriendlyName for MsgBaselineNedDepA {
1291 fn friendly_name() -> &'static str {
1292 "BASELINE NED DEP A"
1293 }
1294 }
1295
1296 impl TryFrom<Sbp> for MsgBaselineNedDepA {
1297 type Error = TryFromSbpError;
1298 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
1299 match msg {
1300 Sbp::MsgBaselineNedDepA(m) => Ok(m),
1301 _ => Err(TryFromSbpError(msg)),
1302 }
1303 }
1304 }
1305
1306 impl WireFormat for MsgBaselineNedDepA {
1307 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
1308 + <i32 as WireFormat>::MIN_LEN
1309 + <i32 as WireFormat>::MIN_LEN
1310 + <i32 as WireFormat>::MIN_LEN
1311 + <u16 as WireFormat>::MIN_LEN
1312 + <u16 as WireFormat>::MIN_LEN
1313 + <u8 as WireFormat>::MIN_LEN
1314 + <u8 as WireFormat>::MIN_LEN;
1315 fn len(&self) -> usize {
1316 WireFormat::len(&self.tow)
1317 + WireFormat::len(&self.n)
1318 + WireFormat::len(&self.e)
1319 + WireFormat::len(&self.d)
1320 + WireFormat::len(&self.h_accuracy)
1321 + WireFormat::len(&self.v_accuracy)
1322 + WireFormat::len(&self.n_sats)
1323 + WireFormat::len(&self.flags)
1324 }
1325 fn write<B: BufMut>(&self, buf: &mut B) {
1326 WireFormat::write(&self.tow, buf);
1327 WireFormat::write(&self.n, buf);
1328 WireFormat::write(&self.e, buf);
1329 WireFormat::write(&self.d, buf);
1330 WireFormat::write(&self.h_accuracy, buf);
1331 WireFormat::write(&self.v_accuracy, buf);
1332 WireFormat::write(&self.n_sats, buf);
1333 WireFormat::write(&self.flags, buf);
1334 }
1335 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
1336 MsgBaselineNedDepA {
1337 sender_id: None,
1338 tow: WireFormat::parse_unchecked(buf),
1339 n: WireFormat::parse_unchecked(buf),
1340 e: WireFormat::parse_unchecked(buf),
1341 d: WireFormat::parse_unchecked(buf),
1342 h_accuracy: WireFormat::parse_unchecked(buf),
1343 v_accuracy: WireFormat::parse_unchecked(buf),
1344 n_sats: WireFormat::parse_unchecked(buf),
1345 flags: WireFormat::parse_unchecked(buf),
1346 }
1347 }
1348 }
1349
1350 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1352 pub enum RaimRepairFlag {
1353 NoRepair = 0,
1355
1356 SolutionCameFromRaimRepair = 1,
1358 }
1359
1360 impl std::fmt::Display for RaimRepairFlag {
1361 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1362 match self {
1363 RaimRepairFlag::NoRepair => f.write_str("No repair"),
1364 RaimRepairFlag::SolutionCameFromRaimRepair => {
1365 f.write_str("Solution came from RAIM repair")
1366 }
1367 }
1368 }
1369 }
1370
1371 impl TryFrom<u8> for RaimRepairFlag {
1372 type Error = u8;
1373 fn try_from(i: u8) -> Result<Self, u8> {
1374 match i {
1375 0 => Ok(RaimRepairFlag::NoRepair),
1376 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair),
1377 i => Err(i),
1378 }
1379 }
1380 }
1381
1382 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1384 pub enum RaimAvailabilityFlag {
1385 RaimCheckWasExplicitlyDisabledOrUnavailable = 0,
1387
1388 RaimCheckWasAvailable = 1,
1390 }
1391
1392 impl std::fmt::Display for RaimAvailabilityFlag {
1393 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1394 match self {
1395 RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => {
1396 f.write_str("RAIM check was explicitly disabled or unavailable")
1397 }
1398 RaimAvailabilityFlag::RaimCheckWasAvailable => {
1399 f.write_str("RAIM check was available")
1400 }
1401 }
1402 }
1403 }
1404
1405 impl TryFrom<u8> for RaimAvailabilityFlag {
1406 type Error = u8;
1407 fn try_from(i: u8) -> Result<Self, u8> {
1408 match i {
1409 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable),
1410 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable),
1411 i => Err(i),
1412 }
1413 }
1414 }
1415
1416 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1418 pub enum FixMode {
1419 FloatRtk = 0,
1421
1422 FixedRtk = 1,
1424 }
1425
1426 impl std::fmt::Display for FixMode {
1427 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1428 match self {
1429 FixMode::FloatRtk => f.write_str("Float RTK"),
1430 FixMode::FixedRtk => f.write_str("Fixed RTK"),
1431 }
1432 }
1433 }
1434
1435 impl TryFrom<u8> for FixMode {
1436 type Error = u8;
1437 fn try_from(i: u8) -> Result<Self, u8> {
1438 match i {
1439 0 => Ok(FixMode::FloatRtk),
1440 1 => Ok(FixMode::FixedRtk),
1441 i => Err(i),
1442 }
1443 }
1444 }
1445}
1446
1447pub mod msg_dops {
1448 #![allow(unused_imports)]
1449
1450 use super::*;
1451 use crate::messages::lib::*;
1452
1453 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1463 #[allow(clippy::derive_partial_eq_without_eq)]
1464 #[derive(Debug, PartialEq, Clone)]
1465 pub struct MsgDops {
1466 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
1468 pub sender_id: Option<u16>,
1469 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
1471 pub tow: u32,
1472 #[cfg_attr(feature = "serde", serde(rename = "gdop"))]
1474 pub gdop: u16,
1475 #[cfg_attr(feature = "serde", serde(rename = "pdop"))]
1477 pub pdop: u16,
1478 #[cfg_attr(feature = "serde", serde(rename = "tdop"))]
1480 pub tdop: u16,
1481 #[cfg_attr(feature = "serde", serde(rename = "hdop"))]
1483 pub hdop: u16,
1484 #[cfg_attr(feature = "serde", serde(rename = "vdop"))]
1486 pub vdop: u16,
1487 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
1489 pub flags: u8,
1490 }
1491
1492 impl MsgDops {
1493 #[allow(clippy::identity_op)]
1495 pub fn raim_repair_flag(&self) -> bool {
1496 ((self.flags >> 7) & 1) == 1
1497 }
1498
1499 pub fn set_raim_repair_flag(&mut self, raim_repair_flag: bool) {
1501 self.flags ^= (!(raim_repair_flag as u8)) & (1 << 7)
1502 }
1503
1504 pub fn fix_mode(&self) -> Result<FixMode, u8> {
1510 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
1511 }
1512
1513 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
1515 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
1516 }
1517 }
1518
1519 impl ConcreteMessage for MsgDops {
1520 const MESSAGE_TYPE: u16 = 520;
1521 const MESSAGE_NAME: &'static str = "MSG_DOPS";
1522 }
1523
1524 impl SbpMessage for MsgDops {
1525 fn message_name(&self) -> &'static str {
1526 <Self as ConcreteMessage>::MESSAGE_NAME
1527 }
1528 fn message_type(&self) -> Option<u16> {
1529 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
1530 }
1531 fn sender_id(&self) -> Option<u16> {
1532 self.sender_id
1533 }
1534 fn set_sender_id(&mut self, new_id: u16) {
1535 self.sender_id = Some(new_id);
1536 }
1537 fn encoded_len(&self) -> usize {
1538 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
1539 }
1540 fn is_valid(&self) -> bool {
1541 true
1542 }
1543 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
1544 Ok(self)
1545 }
1546
1547 #[cfg(feature = "swiftnav")]
1548 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
1549 let tow_s = (self.tow as f64) / 1000.0;
1550 let gps_time = match time::GpsTime::new(0, tow_s) {
1551 Ok(gps_time) => gps_time.tow(),
1552 Err(e) => return Some(Err(e.into())),
1553 };
1554 Some(Ok(time::MessageTime::Rover(gps_time.into())))
1555 }
1556 }
1557
1558 impl FriendlyName for MsgDops {
1559 fn friendly_name() -> &'static str {
1560 "DOPS"
1561 }
1562 }
1563
1564 impl TryFrom<Sbp> for MsgDops {
1565 type Error = TryFromSbpError;
1566 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
1567 match msg {
1568 Sbp::MsgDops(m) => Ok(m),
1569 _ => Err(TryFromSbpError(msg)),
1570 }
1571 }
1572 }
1573
1574 impl WireFormat for MsgDops {
1575 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
1576 + <u16 as WireFormat>::MIN_LEN
1577 + <u16 as WireFormat>::MIN_LEN
1578 + <u16 as WireFormat>::MIN_LEN
1579 + <u16 as WireFormat>::MIN_LEN
1580 + <u16 as WireFormat>::MIN_LEN
1581 + <u8 as WireFormat>::MIN_LEN;
1582 fn len(&self) -> usize {
1583 WireFormat::len(&self.tow)
1584 + WireFormat::len(&self.gdop)
1585 + WireFormat::len(&self.pdop)
1586 + WireFormat::len(&self.tdop)
1587 + WireFormat::len(&self.hdop)
1588 + WireFormat::len(&self.vdop)
1589 + WireFormat::len(&self.flags)
1590 }
1591 fn write<B: BufMut>(&self, buf: &mut B) {
1592 WireFormat::write(&self.tow, buf);
1593 WireFormat::write(&self.gdop, buf);
1594 WireFormat::write(&self.pdop, buf);
1595 WireFormat::write(&self.tdop, buf);
1596 WireFormat::write(&self.hdop, buf);
1597 WireFormat::write(&self.vdop, buf);
1598 WireFormat::write(&self.flags, buf);
1599 }
1600 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
1601 MsgDops {
1602 sender_id: None,
1603 tow: WireFormat::parse_unchecked(buf),
1604 gdop: WireFormat::parse_unchecked(buf),
1605 pdop: WireFormat::parse_unchecked(buf),
1606 tdop: WireFormat::parse_unchecked(buf),
1607 hdop: WireFormat::parse_unchecked(buf),
1608 vdop: WireFormat::parse_unchecked(buf),
1609 flags: WireFormat::parse_unchecked(buf),
1610 }
1611 }
1612 }
1613
1614 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1616 pub enum FixMode {
1617 Invalid = 0,
1619
1620 SinglePointPosition = 1,
1622
1623 DifferentialGnss = 2,
1625
1626 FloatRtk = 3,
1628
1629 FixedRtk = 4,
1631
1632 Undefined = 5,
1634
1635 SbasPosition = 6,
1637 }
1638
1639 impl std::fmt::Display for FixMode {
1640 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1641 match self {
1642 FixMode::Invalid => f.write_str("Invalid"),
1643 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
1644 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
1645 FixMode::FloatRtk => f.write_str("Float RTK"),
1646 FixMode::FixedRtk => f.write_str("Fixed RTK"),
1647 FixMode::Undefined => f.write_str("Undefined"),
1648 FixMode::SbasPosition => f.write_str("SBAS Position"),
1649 }
1650 }
1651 }
1652
1653 impl TryFrom<u8> for FixMode {
1654 type Error = u8;
1655 fn try_from(i: u8) -> Result<Self, u8> {
1656 match i {
1657 0 => Ok(FixMode::Invalid),
1658 1 => Ok(FixMode::SinglePointPosition),
1659 2 => Ok(FixMode::DifferentialGnss),
1660 3 => Ok(FixMode::FloatRtk),
1661 4 => Ok(FixMode::FixedRtk),
1662 5 => Ok(FixMode::Undefined),
1663 6 => Ok(FixMode::SbasPosition),
1664 i => Err(i),
1665 }
1666 }
1667 }
1668}
1669
1670pub mod msg_dops_dep_a {
1671 #![allow(unused_imports)]
1672
1673 use super::*;
1674 use crate::messages::lib::*;
1675
1676 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1681 #[allow(clippy::derive_partial_eq_without_eq)]
1682 #[derive(Debug, PartialEq, Clone)]
1683 pub struct MsgDopsDepA {
1684 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
1686 pub sender_id: Option<u16>,
1687 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
1689 pub tow: u32,
1690 #[cfg_attr(feature = "serde", serde(rename = "gdop"))]
1692 pub gdop: u16,
1693 #[cfg_attr(feature = "serde", serde(rename = "pdop"))]
1695 pub pdop: u16,
1696 #[cfg_attr(feature = "serde", serde(rename = "tdop"))]
1698 pub tdop: u16,
1699 #[cfg_attr(feature = "serde", serde(rename = "hdop"))]
1701 pub hdop: u16,
1702 #[cfg_attr(feature = "serde", serde(rename = "vdop"))]
1704 pub vdop: u16,
1705 }
1706
1707 impl ConcreteMessage for MsgDopsDepA {
1708 const MESSAGE_TYPE: u16 = 518;
1709 const MESSAGE_NAME: &'static str = "MSG_DOPS_DEP_A";
1710 }
1711
1712 impl SbpMessage for MsgDopsDepA {
1713 fn message_name(&self) -> &'static str {
1714 <Self as ConcreteMessage>::MESSAGE_NAME
1715 }
1716 fn message_type(&self) -> Option<u16> {
1717 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
1718 }
1719 fn sender_id(&self) -> Option<u16> {
1720 self.sender_id
1721 }
1722 fn set_sender_id(&mut self, new_id: u16) {
1723 self.sender_id = Some(new_id);
1724 }
1725 fn encoded_len(&self) -> usize {
1726 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
1727 }
1728 fn is_valid(&self) -> bool {
1729 true
1730 }
1731 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
1732 Ok(self)
1733 }
1734
1735 #[cfg(feature = "swiftnav")]
1736 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
1737 let tow_s = (self.tow as f64) / 1000.0;
1738 let gps_time = match time::GpsTime::new(0, tow_s) {
1739 Ok(gps_time) => gps_time.tow(),
1740 Err(e) => return Some(Err(e.into())),
1741 };
1742 Some(Ok(time::MessageTime::Rover(gps_time.into())))
1743 }
1744 }
1745
1746 impl FriendlyName for MsgDopsDepA {
1747 fn friendly_name() -> &'static str {
1748 "DOPS DEP A"
1749 }
1750 }
1751
1752 impl TryFrom<Sbp> for MsgDopsDepA {
1753 type Error = TryFromSbpError;
1754 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
1755 match msg {
1756 Sbp::MsgDopsDepA(m) => Ok(m),
1757 _ => Err(TryFromSbpError(msg)),
1758 }
1759 }
1760 }
1761
1762 impl WireFormat for MsgDopsDepA {
1763 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
1764 + <u16 as WireFormat>::MIN_LEN
1765 + <u16 as WireFormat>::MIN_LEN
1766 + <u16 as WireFormat>::MIN_LEN
1767 + <u16 as WireFormat>::MIN_LEN
1768 + <u16 as WireFormat>::MIN_LEN;
1769 fn len(&self) -> usize {
1770 WireFormat::len(&self.tow)
1771 + WireFormat::len(&self.gdop)
1772 + WireFormat::len(&self.pdop)
1773 + WireFormat::len(&self.tdop)
1774 + WireFormat::len(&self.hdop)
1775 + WireFormat::len(&self.vdop)
1776 }
1777 fn write<B: BufMut>(&self, buf: &mut B) {
1778 WireFormat::write(&self.tow, buf);
1779 WireFormat::write(&self.gdop, buf);
1780 WireFormat::write(&self.pdop, buf);
1781 WireFormat::write(&self.tdop, buf);
1782 WireFormat::write(&self.hdop, buf);
1783 WireFormat::write(&self.vdop, buf);
1784 }
1785 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
1786 MsgDopsDepA {
1787 sender_id: None,
1788 tow: WireFormat::parse_unchecked(buf),
1789 gdop: WireFormat::parse_unchecked(buf),
1790 pdop: WireFormat::parse_unchecked(buf),
1791 tdop: WireFormat::parse_unchecked(buf),
1792 hdop: WireFormat::parse_unchecked(buf),
1793 vdop: WireFormat::parse_unchecked(buf),
1794 }
1795 }
1796 }
1797}
1798
1799pub mod msg_gps_time {
1800 #![allow(unused_imports)]
1801
1802 use super::*;
1803 use crate::messages::lib::*;
1804
1805 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1824 #[allow(clippy::derive_partial_eq_without_eq)]
1825 #[derive(Debug, PartialEq, Clone)]
1826 pub struct MsgGpsTime {
1827 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
1829 pub sender_id: Option<u16>,
1830 #[cfg_attr(feature = "serde", serde(rename = "wn"))]
1832 pub wn: u16,
1833 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
1835 pub tow: u32,
1836 #[cfg_attr(feature = "serde", serde(rename = "ns_residual"))]
1839 pub ns_residual: i32,
1840 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
1842 pub flags: u8,
1843 }
1844
1845 impl MsgGpsTime {
1846 pub fn time_source(&self) -> Result<TimeSource, u8> {
1852 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
1853 }
1854
1855 pub fn set_time_source(&mut self, time_source: TimeSource) {
1857 set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0);
1858 }
1859 }
1860
1861 impl ConcreteMessage for MsgGpsTime {
1862 const MESSAGE_TYPE: u16 = 258;
1863 const MESSAGE_NAME: &'static str = "MSG_GPS_TIME";
1864 }
1865
1866 impl SbpMessage for MsgGpsTime {
1867 fn message_name(&self) -> &'static str {
1868 <Self as ConcreteMessage>::MESSAGE_NAME
1869 }
1870 fn message_type(&self) -> Option<u16> {
1871 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
1872 }
1873 fn sender_id(&self) -> Option<u16> {
1874 self.sender_id
1875 }
1876 fn set_sender_id(&mut self, new_id: u16) {
1877 self.sender_id = Some(new_id);
1878 }
1879 fn encoded_len(&self) -> usize {
1880 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
1881 }
1882 fn is_valid(&self) -> bool {
1883 true
1884 }
1885 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
1886 Ok(self)
1887 }
1888
1889 #[cfg(feature = "swiftnav")]
1890 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
1891 if self.time_source().ok()? == TimeSource::None {
1892 return None;
1893 }
1894 let tow_s = (self.tow as f64) / 1000.0;
1895 #[allow(clippy::useless_conversion)]
1896 let wn: i16 = match self.wn.try_into() {
1897 Ok(wn) => wn,
1898 Err(e) => return Some(Err(e.into())),
1899 };
1900 let gps_time = match time::GpsTime::new(wn, tow_s) {
1901 Ok(gps_time) => gps_time,
1902 Err(e) => return Some(Err(e.into())),
1903 };
1904 Some(Ok(time::MessageTime::Rover(gps_time.into())))
1905 }
1906 }
1907
1908 impl FriendlyName for MsgGpsTime {
1909 fn friendly_name() -> &'static str {
1910 "GPS TIME"
1911 }
1912 }
1913
1914 impl TryFrom<Sbp> for MsgGpsTime {
1915 type Error = TryFromSbpError;
1916 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
1917 match msg {
1918 Sbp::MsgGpsTime(m) => Ok(m),
1919 _ => Err(TryFromSbpError(msg)),
1920 }
1921 }
1922 }
1923
1924 impl WireFormat for MsgGpsTime {
1925 const MIN_LEN: usize = <u16 as WireFormat>::MIN_LEN
1926 + <u32 as WireFormat>::MIN_LEN
1927 + <i32 as WireFormat>::MIN_LEN
1928 + <u8 as WireFormat>::MIN_LEN;
1929 fn len(&self) -> usize {
1930 WireFormat::len(&self.wn)
1931 + WireFormat::len(&self.tow)
1932 + WireFormat::len(&self.ns_residual)
1933 + WireFormat::len(&self.flags)
1934 }
1935 fn write<B: BufMut>(&self, buf: &mut B) {
1936 WireFormat::write(&self.wn, buf);
1937 WireFormat::write(&self.tow, buf);
1938 WireFormat::write(&self.ns_residual, buf);
1939 WireFormat::write(&self.flags, buf);
1940 }
1941 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
1942 MsgGpsTime {
1943 sender_id: None,
1944 wn: WireFormat::parse_unchecked(buf),
1945 tow: WireFormat::parse_unchecked(buf),
1946 ns_residual: WireFormat::parse_unchecked(buf),
1947 flags: WireFormat::parse_unchecked(buf),
1948 }
1949 }
1950 }
1951
1952 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1954 pub enum TimeSource {
1955 None = 0,
1957
1958 GnssSolution = 1,
1960
1961 Propagated = 2,
1963 }
1964
1965 impl std::fmt::Display for TimeSource {
1966 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1967 match self {
1968 TimeSource::None => f.write_str("None (invalid)"),
1969 TimeSource::GnssSolution => f.write_str("GNSS Solution"),
1970 TimeSource::Propagated => f.write_str("Propagated"),
1971 }
1972 }
1973 }
1974
1975 impl TryFrom<u8> for TimeSource {
1976 type Error = u8;
1977 fn try_from(i: u8) -> Result<Self, u8> {
1978 match i {
1979 0 => Ok(TimeSource::None),
1980 1 => Ok(TimeSource::GnssSolution),
1981 2 => Ok(TimeSource::Propagated),
1982 i => Err(i),
1983 }
1984 }
1985 }
1986}
1987
1988pub mod msg_gps_time_dep_a {
1989 #![allow(unused_imports)]
1990
1991 use super::*;
1992 use crate::messages::lib::*;
1993
1994 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1999 #[allow(clippy::derive_partial_eq_without_eq)]
2000 #[derive(Debug, PartialEq, Clone)]
2001 pub struct MsgGpsTimeDepA {
2002 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
2004 pub sender_id: Option<u16>,
2005 #[cfg_attr(feature = "serde", serde(rename = "wn"))]
2007 pub wn: u16,
2008 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
2010 pub tow: u32,
2011 #[cfg_attr(feature = "serde", serde(rename = "ns_residual"))]
2014 pub ns_residual: i32,
2015 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
2017 pub flags: u8,
2018 }
2019
2020 impl ConcreteMessage for MsgGpsTimeDepA {
2021 const MESSAGE_TYPE: u16 = 256;
2022 const MESSAGE_NAME: &'static str = "MSG_GPS_TIME_DEP_A";
2023 }
2024
2025 impl SbpMessage for MsgGpsTimeDepA {
2026 fn message_name(&self) -> &'static str {
2027 <Self as ConcreteMessage>::MESSAGE_NAME
2028 }
2029 fn message_type(&self) -> Option<u16> {
2030 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
2031 }
2032 fn sender_id(&self) -> Option<u16> {
2033 self.sender_id
2034 }
2035 fn set_sender_id(&mut self, new_id: u16) {
2036 self.sender_id = Some(new_id);
2037 }
2038 fn encoded_len(&self) -> usize {
2039 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
2040 }
2041 fn is_valid(&self) -> bool {
2042 true
2043 }
2044 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
2045 Ok(self)
2046 }
2047
2048 #[cfg(feature = "swiftnav")]
2049 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
2050 let tow_s = (self.tow as f64) / 1000.0;
2051 #[allow(clippy::useless_conversion)]
2052 let wn: i16 = match self.wn.try_into() {
2053 Ok(wn) => wn,
2054 Err(e) => return Some(Err(e.into())),
2055 };
2056 let gps_time = match time::GpsTime::new(wn, tow_s) {
2057 Ok(gps_time) => gps_time,
2058 Err(e) => return Some(Err(e.into())),
2059 };
2060 Some(Ok(time::MessageTime::Rover(gps_time.into())))
2061 }
2062 }
2063
2064 impl FriendlyName for MsgGpsTimeDepA {
2065 fn friendly_name() -> &'static str {
2066 "GPS TIME DEP A"
2067 }
2068 }
2069
2070 impl TryFrom<Sbp> for MsgGpsTimeDepA {
2071 type Error = TryFromSbpError;
2072 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
2073 match msg {
2074 Sbp::MsgGpsTimeDepA(m) => Ok(m),
2075 _ => Err(TryFromSbpError(msg)),
2076 }
2077 }
2078 }
2079
2080 impl WireFormat for MsgGpsTimeDepA {
2081 const MIN_LEN: usize = <u16 as WireFormat>::MIN_LEN
2082 + <u32 as WireFormat>::MIN_LEN
2083 + <i32 as WireFormat>::MIN_LEN
2084 + <u8 as WireFormat>::MIN_LEN;
2085 fn len(&self) -> usize {
2086 WireFormat::len(&self.wn)
2087 + WireFormat::len(&self.tow)
2088 + WireFormat::len(&self.ns_residual)
2089 + WireFormat::len(&self.flags)
2090 }
2091 fn write<B: BufMut>(&self, buf: &mut B) {
2092 WireFormat::write(&self.wn, buf);
2093 WireFormat::write(&self.tow, buf);
2094 WireFormat::write(&self.ns_residual, buf);
2095 WireFormat::write(&self.flags, buf);
2096 }
2097 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2098 MsgGpsTimeDepA {
2099 sender_id: None,
2100 wn: WireFormat::parse_unchecked(buf),
2101 tow: WireFormat::parse_unchecked(buf),
2102 ns_residual: WireFormat::parse_unchecked(buf),
2103 flags: WireFormat::parse_unchecked(buf),
2104 }
2105 }
2106 }
2107}
2108
2109pub mod msg_gps_time_gnss {
2110 #![allow(unused_imports)]
2111
2112 use super::*;
2113 use crate::messages::lib::*;
2114
2115 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2133 #[allow(clippy::derive_partial_eq_without_eq)]
2134 #[derive(Debug, PartialEq, Clone)]
2135 pub struct MsgGpsTimeGnss {
2136 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
2138 pub sender_id: Option<u16>,
2139 #[cfg_attr(feature = "serde", serde(rename = "wn"))]
2141 pub wn: u16,
2142 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
2144 pub tow: u32,
2145 #[cfg_attr(feature = "serde", serde(rename = "ns_residual"))]
2148 pub ns_residual: i32,
2149 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
2151 pub flags: u8,
2152 }
2153
2154 impl MsgGpsTimeGnss {
2155 pub fn time_source(&self) -> Result<TimeSource, u8> {
2161 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
2162 }
2163
2164 pub fn set_time_source(&mut self, time_source: TimeSource) {
2166 set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0);
2167 }
2168 }
2169
2170 impl ConcreteMessage for MsgGpsTimeGnss {
2171 const MESSAGE_TYPE: u16 = 260;
2172 const MESSAGE_NAME: &'static str = "MSG_GPS_TIME_GNSS";
2173 }
2174
2175 impl SbpMessage for MsgGpsTimeGnss {
2176 fn message_name(&self) -> &'static str {
2177 <Self as ConcreteMessage>::MESSAGE_NAME
2178 }
2179 fn message_type(&self) -> Option<u16> {
2180 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
2181 }
2182 fn sender_id(&self) -> Option<u16> {
2183 self.sender_id
2184 }
2185 fn set_sender_id(&mut self, new_id: u16) {
2186 self.sender_id = Some(new_id);
2187 }
2188 fn encoded_len(&self) -> usize {
2189 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
2190 }
2191 fn is_valid(&self) -> bool {
2192 true
2193 }
2194 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
2195 Ok(self)
2196 }
2197
2198 #[cfg(feature = "swiftnav")]
2199 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
2200 if self.time_source().ok()? == TimeSource::None {
2201 return None;
2202 }
2203 let tow_s = (self.tow as f64) / 1000.0;
2204 #[allow(clippy::useless_conversion)]
2205 let wn: i16 = match self.wn.try_into() {
2206 Ok(wn) => wn,
2207 Err(e) => return Some(Err(e.into())),
2208 };
2209 let gps_time = match time::GpsTime::new(wn, tow_s) {
2210 Ok(gps_time) => gps_time,
2211 Err(e) => return Some(Err(e.into())),
2212 };
2213 Some(Ok(time::MessageTime::Rover(gps_time.into())))
2214 }
2215 }
2216
2217 impl FriendlyName for MsgGpsTimeGnss {
2218 fn friendly_name() -> &'static str {
2219 "GPS TIME GNSS-only"
2220 }
2221 }
2222
2223 impl TryFrom<Sbp> for MsgGpsTimeGnss {
2224 type Error = TryFromSbpError;
2225 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
2226 match msg {
2227 Sbp::MsgGpsTimeGnss(m) => Ok(m),
2228 _ => Err(TryFromSbpError(msg)),
2229 }
2230 }
2231 }
2232
2233 impl WireFormat for MsgGpsTimeGnss {
2234 const MIN_LEN: usize = <u16 as WireFormat>::MIN_LEN
2235 + <u32 as WireFormat>::MIN_LEN
2236 + <i32 as WireFormat>::MIN_LEN
2237 + <u8 as WireFormat>::MIN_LEN;
2238 fn len(&self) -> usize {
2239 WireFormat::len(&self.wn)
2240 + WireFormat::len(&self.tow)
2241 + WireFormat::len(&self.ns_residual)
2242 + WireFormat::len(&self.flags)
2243 }
2244 fn write<B: BufMut>(&self, buf: &mut B) {
2245 WireFormat::write(&self.wn, buf);
2246 WireFormat::write(&self.tow, buf);
2247 WireFormat::write(&self.ns_residual, buf);
2248 WireFormat::write(&self.flags, buf);
2249 }
2250 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2251 MsgGpsTimeGnss {
2252 sender_id: None,
2253 wn: WireFormat::parse_unchecked(buf),
2254 tow: WireFormat::parse_unchecked(buf),
2255 ns_residual: WireFormat::parse_unchecked(buf),
2256 flags: WireFormat::parse_unchecked(buf),
2257 }
2258 }
2259 }
2260
2261 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2263 pub enum TimeSource {
2264 None = 0,
2266
2267 GnssSolution = 1,
2269
2270 Propagated = 2,
2272 }
2273
2274 impl std::fmt::Display for TimeSource {
2275 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2276 match self {
2277 TimeSource::None => f.write_str("None (invalid)"),
2278 TimeSource::GnssSolution => f.write_str("GNSS Solution"),
2279 TimeSource::Propagated => f.write_str("Propagated"),
2280 }
2281 }
2282 }
2283
2284 impl TryFrom<u8> for TimeSource {
2285 type Error = u8;
2286 fn try_from(i: u8) -> Result<Self, u8> {
2287 match i {
2288 0 => Ok(TimeSource::None),
2289 1 => Ok(TimeSource::GnssSolution),
2290 2 => Ok(TimeSource::Propagated),
2291 i => Err(i),
2292 }
2293 }
2294 }
2295}
2296
2297pub mod msg_pose_relative {
2298 #![allow(unused_imports)]
2299
2300 use super::*;
2301 use crate::messages::lib::*;
2302
2303 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2314 #[allow(clippy::derive_partial_eq_without_eq)]
2315 #[derive(Debug, PartialEq, Clone)]
2316 pub struct MsgPoseRelative {
2317 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
2319 pub sender_id: Option<u16>,
2320 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
2322 pub tow: u32,
2323 #[cfg_attr(feature = "serde", serde(rename = "sensor_id"))]
2325 pub sensor_id: u8,
2326 #[cfg_attr(feature = "serde", serde(rename = "timestamp_1"))]
2328 pub timestamp_1: u32,
2329 #[cfg_attr(feature = "serde", serde(rename = "timestamp_2"))]
2331 pub timestamp_2: u32,
2332 #[cfg_attr(feature = "serde", serde(rename = "trans"))]
2334 pub trans: [i32; 3],
2335 #[cfg_attr(feature = "serde", serde(rename = "w"))]
2338 pub w: i32,
2339 #[cfg_attr(feature = "serde", serde(rename = "x"))]
2342 pub x: i32,
2343 #[cfg_attr(feature = "serde", serde(rename = "y"))]
2346 pub y: i32,
2347 #[cfg_attr(feature = "serde", serde(rename = "z"))]
2350 pub z: i32,
2351 #[cfg_attr(feature = "serde", serde(rename = "cov_r_x_x"))]
2353 pub cov_r_x_x: f32,
2354 #[cfg_attr(feature = "serde", serde(rename = "cov_r_x_y"))]
2356 pub cov_r_x_y: f32,
2357 #[cfg_attr(feature = "serde", serde(rename = "cov_r_x_z"))]
2359 pub cov_r_x_z: f32,
2360 #[cfg_attr(feature = "serde", serde(rename = "cov_r_y_y"))]
2362 pub cov_r_y_y: f32,
2363 #[cfg_attr(feature = "serde", serde(rename = "cov_r_y_z"))]
2365 pub cov_r_y_z: f32,
2366 #[cfg_attr(feature = "serde", serde(rename = "cov_r_z_z"))]
2368 pub cov_r_z_z: f32,
2369 #[cfg_attr(feature = "serde", serde(rename = "cov_c_x_x"))]
2371 pub cov_c_x_x: f32,
2372 #[cfg_attr(feature = "serde", serde(rename = "cov_c_x_y"))]
2374 pub cov_c_x_y: f32,
2375 #[cfg_attr(feature = "serde", serde(rename = "cov_c_x_z"))]
2377 pub cov_c_x_z: f32,
2378 #[cfg_attr(feature = "serde", serde(rename = "cov_c_y_y"))]
2380 pub cov_c_y_y: f32,
2381 #[cfg_attr(feature = "serde", serde(rename = "cov_c_y_z"))]
2383 pub cov_c_y_z: f32,
2384 #[cfg_attr(feature = "serde", serde(rename = "cov_c_z_z"))]
2386 pub cov_c_z_z: f32,
2387 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
2389 pub flags: u8,
2390 }
2391
2392 impl MsgPoseRelative {
2393 pub fn time_source(&self) -> Result<TimeSource, u8> {
2399 get_bit_range!(self.flags, u8, u8, 5, 4).try_into()
2400 }
2401
2402 pub fn set_time_source(&mut self, time_source: TimeSource) {
2404 set_bit_range!(&mut self.flags, time_source, u8, u8, 5, 4);
2405 }
2406
2407 pub fn relative_translation_status(&self) -> Result<RelativeTranslationStatus, u8> {
2413 get_bit_range!(self.flags, u8, u8, 3, 2).try_into()
2414 }
2415
2416 pub fn set_relative_translation_status(
2418 &mut self,
2419 relative_translation_status: RelativeTranslationStatus,
2420 ) {
2421 set_bit_range!(&mut self.flags, relative_translation_status, u8, u8, 3, 2);
2422 }
2423
2424 pub fn relative_rotation_status(&self) -> Result<RelativeRotationStatus, u8> {
2430 get_bit_range!(self.flags, u8, u8, 1, 0).try_into()
2431 }
2432
2433 pub fn set_relative_rotation_status(
2435 &mut self,
2436 relative_rotation_status: RelativeRotationStatus,
2437 ) {
2438 set_bit_range!(&mut self.flags, relative_rotation_status, u8, u8, 1, 0);
2439 }
2440 }
2441
2442 impl ConcreteMessage for MsgPoseRelative {
2443 const MESSAGE_TYPE: u16 = 581;
2444 const MESSAGE_NAME: &'static str = "MSG_POSE_RELATIVE";
2445 }
2446
2447 impl SbpMessage for MsgPoseRelative {
2448 fn message_name(&self) -> &'static str {
2449 <Self as ConcreteMessage>::MESSAGE_NAME
2450 }
2451 fn message_type(&self) -> Option<u16> {
2452 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
2453 }
2454 fn sender_id(&self) -> Option<u16> {
2455 self.sender_id
2456 }
2457 fn set_sender_id(&mut self, new_id: u16) {
2458 self.sender_id = Some(new_id);
2459 }
2460 fn encoded_len(&self) -> usize {
2461 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
2462 }
2463 fn is_valid(&self) -> bool {
2464 true
2465 }
2466 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
2467 Ok(self)
2468 }
2469
2470 #[cfg(feature = "swiftnav")]
2471 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
2472 if self.time_source().ok()? == TimeSource::None {
2473 return None;
2474 }
2475 let tow_s = (self.tow as f64) / 1000.0;
2476 let gps_time = match time::GpsTime::new(0, tow_s) {
2477 Ok(gps_time) => gps_time.tow(),
2478 Err(e) => return Some(Err(e.into())),
2479 };
2480 Some(Ok(time::MessageTime::Rover(gps_time.into())))
2481 }
2482 }
2483
2484 impl FriendlyName for MsgPoseRelative {
2485 fn friendly_name() -> &'static str {
2486 "POSE RELATIVE"
2487 }
2488 }
2489
2490 impl TryFrom<Sbp> for MsgPoseRelative {
2491 type Error = TryFromSbpError;
2492 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
2493 match msg {
2494 Sbp::MsgPoseRelative(m) => Ok(m),
2495 _ => Err(TryFromSbpError(msg)),
2496 }
2497 }
2498 }
2499
2500 impl WireFormat for MsgPoseRelative {
2501 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
2502 + <u8 as WireFormat>::MIN_LEN
2503 + <u32 as WireFormat>::MIN_LEN
2504 + <u32 as WireFormat>::MIN_LEN
2505 + <[i32; 3] as WireFormat>::MIN_LEN
2506 + <i32 as WireFormat>::MIN_LEN
2507 + <i32 as WireFormat>::MIN_LEN
2508 + <i32 as WireFormat>::MIN_LEN
2509 + <i32 as WireFormat>::MIN_LEN
2510 + <f32 as WireFormat>::MIN_LEN
2511 + <f32 as WireFormat>::MIN_LEN
2512 + <f32 as WireFormat>::MIN_LEN
2513 + <f32 as WireFormat>::MIN_LEN
2514 + <f32 as WireFormat>::MIN_LEN
2515 + <f32 as WireFormat>::MIN_LEN
2516 + <f32 as WireFormat>::MIN_LEN
2517 + <f32 as WireFormat>::MIN_LEN
2518 + <f32 as WireFormat>::MIN_LEN
2519 + <f32 as WireFormat>::MIN_LEN
2520 + <f32 as WireFormat>::MIN_LEN
2521 + <f32 as WireFormat>::MIN_LEN
2522 + <u8 as WireFormat>::MIN_LEN;
2523 fn len(&self) -> usize {
2524 WireFormat::len(&self.tow)
2525 + WireFormat::len(&self.sensor_id)
2526 + WireFormat::len(&self.timestamp_1)
2527 + WireFormat::len(&self.timestamp_2)
2528 + WireFormat::len(&self.trans)
2529 + WireFormat::len(&self.w)
2530 + WireFormat::len(&self.x)
2531 + WireFormat::len(&self.y)
2532 + WireFormat::len(&self.z)
2533 + WireFormat::len(&self.cov_r_x_x)
2534 + WireFormat::len(&self.cov_r_x_y)
2535 + WireFormat::len(&self.cov_r_x_z)
2536 + WireFormat::len(&self.cov_r_y_y)
2537 + WireFormat::len(&self.cov_r_y_z)
2538 + WireFormat::len(&self.cov_r_z_z)
2539 + WireFormat::len(&self.cov_c_x_x)
2540 + WireFormat::len(&self.cov_c_x_y)
2541 + WireFormat::len(&self.cov_c_x_z)
2542 + WireFormat::len(&self.cov_c_y_y)
2543 + WireFormat::len(&self.cov_c_y_z)
2544 + WireFormat::len(&self.cov_c_z_z)
2545 + WireFormat::len(&self.flags)
2546 }
2547 fn write<B: BufMut>(&self, buf: &mut B) {
2548 WireFormat::write(&self.tow, buf);
2549 WireFormat::write(&self.sensor_id, buf);
2550 WireFormat::write(&self.timestamp_1, buf);
2551 WireFormat::write(&self.timestamp_2, buf);
2552 WireFormat::write(&self.trans, buf);
2553 WireFormat::write(&self.w, buf);
2554 WireFormat::write(&self.x, buf);
2555 WireFormat::write(&self.y, buf);
2556 WireFormat::write(&self.z, buf);
2557 WireFormat::write(&self.cov_r_x_x, buf);
2558 WireFormat::write(&self.cov_r_x_y, buf);
2559 WireFormat::write(&self.cov_r_x_z, buf);
2560 WireFormat::write(&self.cov_r_y_y, buf);
2561 WireFormat::write(&self.cov_r_y_z, buf);
2562 WireFormat::write(&self.cov_r_z_z, buf);
2563 WireFormat::write(&self.cov_c_x_x, buf);
2564 WireFormat::write(&self.cov_c_x_y, buf);
2565 WireFormat::write(&self.cov_c_x_z, buf);
2566 WireFormat::write(&self.cov_c_y_y, buf);
2567 WireFormat::write(&self.cov_c_y_z, buf);
2568 WireFormat::write(&self.cov_c_z_z, buf);
2569 WireFormat::write(&self.flags, buf);
2570 }
2571 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2572 MsgPoseRelative {
2573 sender_id: None,
2574 tow: WireFormat::parse_unchecked(buf),
2575 sensor_id: WireFormat::parse_unchecked(buf),
2576 timestamp_1: WireFormat::parse_unchecked(buf),
2577 timestamp_2: WireFormat::parse_unchecked(buf),
2578 trans: WireFormat::parse_unchecked(buf),
2579 w: WireFormat::parse_unchecked(buf),
2580 x: WireFormat::parse_unchecked(buf),
2581 y: WireFormat::parse_unchecked(buf),
2582 z: WireFormat::parse_unchecked(buf),
2583 cov_r_x_x: WireFormat::parse_unchecked(buf),
2584 cov_r_x_y: WireFormat::parse_unchecked(buf),
2585 cov_r_x_z: WireFormat::parse_unchecked(buf),
2586 cov_r_y_y: WireFormat::parse_unchecked(buf),
2587 cov_r_y_z: WireFormat::parse_unchecked(buf),
2588 cov_r_z_z: WireFormat::parse_unchecked(buf),
2589 cov_c_x_x: WireFormat::parse_unchecked(buf),
2590 cov_c_x_y: WireFormat::parse_unchecked(buf),
2591 cov_c_x_z: WireFormat::parse_unchecked(buf),
2592 cov_c_y_y: WireFormat::parse_unchecked(buf),
2593 cov_c_y_z: WireFormat::parse_unchecked(buf),
2594 cov_c_z_z: WireFormat::parse_unchecked(buf),
2595 flags: WireFormat::parse_unchecked(buf),
2596 }
2597 }
2598 }
2599
2600 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2602 pub enum TimeSource {
2603 None = 0,
2605
2606 GnssSolution = 1,
2608
2609 LocalCpuTime = 2,
2611 }
2612
2613 impl std::fmt::Display for TimeSource {
2614 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2615 match self {
2616 TimeSource::None => f.write_str("None (invalid)"),
2617 TimeSource::GnssSolution => f.write_str("GNSS Solution (ms in week)"),
2618 TimeSource::LocalCpuTime => f.write_str("Local CPU Time (ms)"),
2619 }
2620 }
2621 }
2622
2623 impl TryFrom<u8> for TimeSource {
2624 type Error = u8;
2625 fn try_from(i: u8) -> Result<Self, u8> {
2626 match i {
2627 0 => Ok(TimeSource::None),
2628 1 => Ok(TimeSource::GnssSolution),
2629 2 => Ok(TimeSource::LocalCpuTime),
2630 i => Err(i),
2631 }
2632 }
2633 }
2634
2635 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2637 pub enum RelativeTranslationStatus {
2638 Invalid = 0,
2640
2641 Valid = 1,
2643 }
2644
2645 impl std::fmt::Display for RelativeTranslationStatus {
2646 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2647 match self {
2648 RelativeTranslationStatus::Invalid => f.write_str("Invalid"),
2649 RelativeTranslationStatus::Valid => f.write_str("Valid"),
2650 }
2651 }
2652 }
2653
2654 impl TryFrom<u8> for RelativeTranslationStatus {
2655 type Error = u8;
2656 fn try_from(i: u8) -> Result<Self, u8> {
2657 match i {
2658 0 => Ok(RelativeTranslationStatus::Invalid),
2659 1 => Ok(RelativeTranslationStatus::Valid),
2660 i => Err(i),
2661 }
2662 }
2663 }
2664
2665 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2667 pub enum RelativeRotationStatus {
2668 Invalid = 0,
2670
2671 Valid = 1,
2673 }
2674
2675 impl std::fmt::Display for RelativeRotationStatus {
2676 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2677 match self {
2678 RelativeRotationStatus::Invalid => f.write_str("Invalid"),
2679 RelativeRotationStatus::Valid => f.write_str("Valid"),
2680 }
2681 }
2682 }
2683
2684 impl TryFrom<u8> for RelativeRotationStatus {
2685 type Error = u8;
2686 fn try_from(i: u8) -> Result<Self, u8> {
2687 match i {
2688 0 => Ok(RelativeRotationStatus::Invalid),
2689 1 => Ok(RelativeRotationStatus::Valid),
2690 i => Err(i),
2691 }
2692 }
2693 }
2694}
2695
2696pub mod msg_pos_ecef {
2697 #![allow(unused_imports)]
2698
2699 use super::*;
2700 use crate::messages::lib::*;
2701
2702 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2717 #[allow(clippy::derive_partial_eq_without_eq)]
2718 #[derive(Debug, PartialEq, Clone)]
2719 pub struct MsgPosEcef {
2720 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
2722 pub sender_id: Option<u16>,
2723 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
2725 pub tow: u32,
2726 #[cfg_attr(feature = "serde", serde(rename = "x"))]
2728 pub x: f64,
2729 #[cfg_attr(feature = "serde", serde(rename = "y"))]
2731 pub y: f64,
2732 #[cfg_attr(feature = "serde", serde(rename = "z"))]
2734 pub z: f64,
2735 #[cfg_attr(feature = "serde", serde(rename = "accuracy"))]
2737 pub accuracy: u16,
2738 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
2740 pub n_sats: u8,
2741 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
2743 pub flags: u8,
2744 }
2745
2746 impl MsgPosEcef {
2747 pub fn tow_type(&self) -> Result<TowType, u8> {
2753 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
2754 }
2755
2756 pub fn set_tow_type(&mut self, tow_type: TowType) {
2758 set_bit_range!(&mut self.flags, tow_type, u8, u8, 5, 5);
2759 }
2760
2761 pub fn inertial_navigation_mode(&self) -> Result<InertialNavigationMode, u8> {
2767 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
2768 }
2769
2770 pub fn set_inertial_navigation_mode(
2772 &mut self,
2773 inertial_navigation_mode: InertialNavigationMode,
2774 ) {
2775 set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3);
2776 }
2777
2778 pub fn fix_mode(&self) -> Result<FixMode, u8> {
2784 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
2785 }
2786
2787 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
2789 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
2790 }
2791 }
2792
2793 impl ConcreteMessage for MsgPosEcef {
2794 const MESSAGE_TYPE: u16 = 521;
2795 const MESSAGE_NAME: &'static str = "MSG_POS_ECEF";
2796 }
2797
2798 impl SbpMessage for MsgPosEcef {
2799 fn message_name(&self) -> &'static str {
2800 <Self as ConcreteMessage>::MESSAGE_NAME
2801 }
2802 fn message_type(&self) -> Option<u16> {
2803 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
2804 }
2805 fn sender_id(&self) -> Option<u16> {
2806 self.sender_id
2807 }
2808 fn set_sender_id(&mut self, new_id: u16) {
2809 self.sender_id = Some(new_id);
2810 }
2811 fn encoded_len(&self) -> usize {
2812 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
2813 }
2814 fn is_valid(&self) -> bool {
2815 true
2816 }
2817 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
2818 Ok(self)
2819 }
2820
2821 #[cfg(feature = "swiftnav")]
2822 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
2823 let tow_s = (self.tow as f64) / 1000.0;
2824 let gps_time = match time::GpsTime::new(0, tow_s) {
2825 Ok(gps_time) => gps_time.tow(),
2826 Err(e) => return Some(Err(e.into())),
2827 };
2828 Some(Ok(time::MessageTime::Rover(gps_time.into())))
2829 }
2830 }
2831
2832 impl FriendlyName for MsgPosEcef {
2833 fn friendly_name() -> &'static str {
2834 "POS ECEF"
2835 }
2836 }
2837
2838 impl TryFrom<Sbp> for MsgPosEcef {
2839 type Error = TryFromSbpError;
2840 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
2841 match msg {
2842 Sbp::MsgPosEcef(m) => Ok(m),
2843 _ => Err(TryFromSbpError(msg)),
2844 }
2845 }
2846 }
2847
2848 impl WireFormat for MsgPosEcef {
2849 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
2850 + <f64 as WireFormat>::MIN_LEN
2851 + <f64 as WireFormat>::MIN_LEN
2852 + <f64 as WireFormat>::MIN_LEN
2853 + <u16 as WireFormat>::MIN_LEN
2854 + <u8 as WireFormat>::MIN_LEN
2855 + <u8 as WireFormat>::MIN_LEN;
2856 fn len(&self) -> usize {
2857 WireFormat::len(&self.tow)
2858 + WireFormat::len(&self.x)
2859 + WireFormat::len(&self.y)
2860 + WireFormat::len(&self.z)
2861 + WireFormat::len(&self.accuracy)
2862 + WireFormat::len(&self.n_sats)
2863 + WireFormat::len(&self.flags)
2864 }
2865 fn write<B: BufMut>(&self, buf: &mut B) {
2866 WireFormat::write(&self.tow, buf);
2867 WireFormat::write(&self.x, buf);
2868 WireFormat::write(&self.y, buf);
2869 WireFormat::write(&self.z, buf);
2870 WireFormat::write(&self.accuracy, buf);
2871 WireFormat::write(&self.n_sats, buf);
2872 WireFormat::write(&self.flags, buf);
2873 }
2874 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
2875 MsgPosEcef {
2876 sender_id: None,
2877 tow: WireFormat::parse_unchecked(buf),
2878 x: WireFormat::parse_unchecked(buf),
2879 y: WireFormat::parse_unchecked(buf),
2880 z: WireFormat::parse_unchecked(buf),
2881 accuracy: WireFormat::parse_unchecked(buf),
2882 n_sats: WireFormat::parse_unchecked(buf),
2883 flags: WireFormat::parse_unchecked(buf),
2884 }
2885 }
2886 }
2887
2888 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2890 pub enum TowType {
2891 TimeOfMeasurement = 0,
2893
2894 Other = 1,
2896 }
2897
2898 impl std::fmt::Display for TowType {
2899 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2900 match self {
2901 TowType::TimeOfMeasurement => f.write_str("Time of Measurement"),
2902 TowType::Other => f.write_str("Other"),
2903 }
2904 }
2905 }
2906
2907 impl TryFrom<u8> for TowType {
2908 type Error = u8;
2909 fn try_from(i: u8) -> Result<Self, u8> {
2910 match i {
2911 0 => Ok(TowType::TimeOfMeasurement),
2912 1 => Ok(TowType::Other),
2913 i => Err(i),
2914 }
2915 }
2916 }
2917
2918 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2920 pub enum InertialNavigationMode {
2921 None = 0,
2923
2924 InsUsed = 1,
2926 }
2927
2928 impl std::fmt::Display for InertialNavigationMode {
2929 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2930 match self {
2931 InertialNavigationMode::None => f.write_str("None"),
2932 InertialNavigationMode::InsUsed => f.write_str("INS used"),
2933 }
2934 }
2935 }
2936
2937 impl TryFrom<u8> for InertialNavigationMode {
2938 type Error = u8;
2939 fn try_from(i: u8) -> Result<Self, u8> {
2940 match i {
2941 0 => Ok(InertialNavigationMode::None),
2942 1 => Ok(InertialNavigationMode::InsUsed),
2943 i => Err(i),
2944 }
2945 }
2946 }
2947
2948 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2950 pub enum FixMode {
2951 Invalid = 0,
2953
2954 SinglePointPosition = 1,
2956
2957 DifferentialGnss = 2,
2959
2960 FloatRtk = 3,
2962
2963 FixedRtk = 4,
2965
2966 DeadReckoning = 5,
2968
2969 SbasPosition = 6,
2971 }
2972
2973 impl std::fmt::Display for FixMode {
2974 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2975 match self {
2976 FixMode::Invalid => f.write_str("Invalid"),
2977 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
2978 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
2979 FixMode::FloatRtk => f.write_str("Float RTK"),
2980 FixMode::FixedRtk => f.write_str("Fixed RTK"),
2981 FixMode::DeadReckoning => f.write_str("Dead Reckoning"),
2982 FixMode::SbasPosition => f.write_str("SBAS Position"),
2983 }
2984 }
2985 }
2986
2987 impl TryFrom<u8> for FixMode {
2988 type Error = u8;
2989 fn try_from(i: u8) -> Result<Self, u8> {
2990 match i {
2991 0 => Ok(FixMode::Invalid),
2992 1 => Ok(FixMode::SinglePointPosition),
2993 2 => Ok(FixMode::DifferentialGnss),
2994 3 => Ok(FixMode::FloatRtk),
2995 4 => Ok(FixMode::FixedRtk),
2996 5 => Ok(FixMode::DeadReckoning),
2997 6 => Ok(FixMode::SbasPosition),
2998 i => Err(i),
2999 }
3000 }
3001 }
3002}
3003
3004pub mod msg_pos_ecef_cov {
3005 #![allow(unused_imports)]
3006
3007 use super::*;
3008 use crate::messages::lib::*;
3009
3010 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3026 #[allow(clippy::derive_partial_eq_without_eq)]
3027 #[derive(Debug, PartialEq, Clone)]
3028 pub struct MsgPosEcefCov {
3029 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
3031 pub sender_id: Option<u16>,
3032 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
3034 pub tow: u32,
3035 #[cfg_attr(feature = "serde", serde(rename = "x"))]
3037 pub x: f64,
3038 #[cfg_attr(feature = "serde", serde(rename = "y"))]
3040 pub y: f64,
3041 #[cfg_attr(feature = "serde", serde(rename = "z"))]
3043 pub z: f64,
3044 #[cfg_attr(feature = "serde", serde(rename = "cov_x_x"))]
3046 pub cov_x_x: f32,
3047 #[cfg_attr(feature = "serde", serde(rename = "cov_x_y"))]
3049 pub cov_x_y: f32,
3050 #[cfg_attr(feature = "serde", serde(rename = "cov_x_z"))]
3052 pub cov_x_z: f32,
3053 #[cfg_attr(feature = "serde", serde(rename = "cov_y_y"))]
3055 pub cov_y_y: f32,
3056 #[cfg_attr(feature = "serde", serde(rename = "cov_y_z"))]
3058 pub cov_y_z: f32,
3059 #[cfg_attr(feature = "serde", serde(rename = "cov_z_z"))]
3061 pub cov_z_z: f32,
3062 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
3064 pub n_sats: u8,
3065 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
3067 pub flags: u8,
3068 }
3069
3070 impl MsgPosEcefCov {
3071 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
3077 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
3078 }
3079
3080 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
3082 set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5);
3083 }
3084
3085 pub fn inertial_navigation_mode(&self) -> Result<InertialNavigationMode, u8> {
3091 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
3092 }
3093
3094 pub fn set_inertial_navigation_mode(
3096 &mut self,
3097 inertial_navigation_mode: InertialNavigationMode,
3098 ) {
3099 set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3);
3100 }
3101
3102 pub fn fix_mode(&self) -> Result<FixMode, u8> {
3108 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
3109 }
3110
3111 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
3113 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
3114 }
3115 }
3116
3117 impl ConcreteMessage for MsgPosEcefCov {
3118 const MESSAGE_TYPE: u16 = 532;
3119 const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_COV";
3120 }
3121
3122 impl SbpMessage for MsgPosEcefCov {
3123 fn message_name(&self) -> &'static str {
3124 <Self as ConcreteMessage>::MESSAGE_NAME
3125 }
3126 fn message_type(&self) -> Option<u16> {
3127 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
3128 }
3129 fn sender_id(&self) -> Option<u16> {
3130 self.sender_id
3131 }
3132 fn set_sender_id(&mut self, new_id: u16) {
3133 self.sender_id = Some(new_id);
3134 }
3135 fn encoded_len(&self) -> usize {
3136 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
3137 }
3138 fn is_valid(&self) -> bool {
3139 true
3140 }
3141 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
3142 Ok(self)
3143 }
3144
3145 #[cfg(feature = "swiftnav")]
3146 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
3147 let tow_s = (self.tow as f64) / 1000.0;
3148 let gps_time = match time::GpsTime::new(0, tow_s) {
3149 Ok(gps_time) => gps_time.tow(),
3150 Err(e) => return Some(Err(e.into())),
3151 };
3152 Some(Ok(time::MessageTime::Rover(gps_time.into())))
3153 }
3154 }
3155
3156 impl FriendlyName for MsgPosEcefCov {
3157 fn friendly_name() -> &'static str {
3158 "POS ECEF COV"
3159 }
3160 }
3161
3162 impl TryFrom<Sbp> for MsgPosEcefCov {
3163 type Error = TryFromSbpError;
3164 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
3165 match msg {
3166 Sbp::MsgPosEcefCov(m) => Ok(m),
3167 _ => Err(TryFromSbpError(msg)),
3168 }
3169 }
3170 }
3171
3172 impl WireFormat for MsgPosEcefCov {
3173 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
3174 + <f64 as WireFormat>::MIN_LEN
3175 + <f64 as WireFormat>::MIN_LEN
3176 + <f64 as WireFormat>::MIN_LEN
3177 + <f32 as WireFormat>::MIN_LEN
3178 + <f32 as WireFormat>::MIN_LEN
3179 + <f32 as WireFormat>::MIN_LEN
3180 + <f32 as WireFormat>::MIN_LEN
3181 + <f32 as WireFormat>::MIN_LEN
3182 + <f32 as WireFormat>::MIN_LEN
3183 + <u8 as WireFormat>::MIN_LEN
3184 + <u8 as WireFormat>::MIN_LEN;
3185 fn len(&self) -> usize {
3186 WireFormat::len(&self.tow)
3187 + WireFormat::len(&self.x)
3188 + WireFormat::len(&self.y)
3189 + WireFormat::len(&self.z)
3190 + WireFormat::len(&self.cov_x_x)
3191 + WireFormat::len(&self.cov_x_y)
3192 + WireFormat::len(&self.cov_x_z)
3193 + WireFormat::len(&self.cov_y_y)
3194 + WireFormat::len(&self.cov_y_z)
3195 + WireFormat::len(&self.cov_z_z)
3196 + WireFormat::len(&self.n_sats)
3197 + WireFormat::len(&self.flags)
3198 }
3199 fn write<B: BufMut>(&self, buf: &mut B) {
3200 WireFormat::write(&self.tow, buf);
3201 WireFormat::write(&self.x, buf);
3202 WireFormat::write(&self.y, buf);
3203 WireFormat::write(&self.z, buf);
3204 WireFormat::write(&self.cov_x_x, buf);
3205 WireFormat::write(&self.cov_x_y, buf);
3206 WireFormat::write(&self.cov_x_z, buf);
3207 WireFormat::write(&self.cov_y_y, buf);
3208 WireFormat::write(&self.cov_y_z, buf);
3209 WireFormat::write(&self.cov_z_z, buf);
3210 WireFormat::write(&self.n_sats, buf);
3211 WireFormat::write(&self.flags, buf);
3212 }
3213 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
3214 MsgPosEcefCov {
3215 sender_id: None,
3216 tow: WireFormat::parse_unchecked(buf),
3217 x: WireFormat::parse_unchecked(buf),
3218 y: WireFormat::parse_unchecked(buf),
3219 z: WireFormat::parse_unchecked(buf),
3220 cov_x_x: WireFormat::parse_unchecked(buf),
3221 cov_x_y: WireFormat::parse_unchecked(buf),
3222 cov_x_z: WireFormat::parse_unchecked(buf),
3223 cov_y_y: WireFormat::parse_unchecked(buf),
3224 cov_y_z: WireFormat::parse_unchecked(buf),
3225 cov_z_z: WireFormat::parse_unchecked(buf),
3226 n_sats: WireFormat::parse_unchecked(buf),
3227 flags: WireFormat::parse_unchecked(buf),
3228 }
3229 }
3230 }
3231
3232 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3234 pub enum TypeOfReportedTow {
3235 TimeOfMeasurement = 0,
3237
3238 Other = 1,
3240 }
3241
3242 impl std::fmt::Display for TypeOfReportedTow {
3243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3244 match self {
3245 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
3246 TypeOfReportedTow::Other => f.write_str("Other"),
3247 }
3248 }
3249 }
3250
3251 impl TryFrom<u8> for TypeOfReportedTow {
3252 type Error = u8;
3253 fn try_from(i: u8) -> Result<Self, u8> {
3254 match i {
3255 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
3256 1 => Ok(TypeOfReportedTow::Other),
3257 i => Err(i),
3258 }
3259 }
3260 }
3261
3262 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3264 pub enum InertialNavigationMode {
3265 None = 0,
3267
3268 InsUsed = 1,
3270 }
3271
3272 impl std::fmt::Display for InertialNavigationMode {
3273 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3274 match self {
3275 InertialNavigationMode::None => f.write_str("None"),
3276 InertialNavigationMode::InsUsed => f.write_str("INS used"),
3277 }
3278 }
3279 }
3280
3281 impl TryFrom<u8> for InertialNavigationMode {
3282 type Error = u8;
3283 fn try_from(i: u8) -> Result<Self, u8> {
3284 match i {
3285 0 => Ok(InertialNavigationMode::None),
3286 1 => Ok(InertialNavigationMode::InsUsed),
3287 i => Err(i),
3288 }
3289 }
3290 }
3291
3292 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3294 pub enum FixMode {
3295 Invalid = 0,
3297
3298 SinglePointPosition = 1,
3300
3301 DifferentialGnss = 2,
3303
3304 FloatRtk = 3,
3306
3307 FixedRtk = 4,
3309
3310 DeadReckoning = 5,
3312
3313 SbasPosition = 6,
3315 }
3316
3317 impl std::fmt::Display for FixMode {
3318 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3319 match self {
3320 FixMode::Invalid => f.write_str("Invalid"),
3321 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
3322 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
3323 FixMode::FloatRtk => f.write_str("Float RTK"),
3324 FixMode::FixedRtk => f.write_str("Fixed RTK"),
3325 FixMode::DeadReckoning => f.write_str("Dead Reckoning"),
3326 FixMode::SbasPosition => f.write_str("SBAS Position"),
3327 }
3328 }
3329 }
3330
3331 impl TryFrom<u8> for FixMode {
3332 type Error = u8;
3333 fn try_from(i: u8) -> Result<Self, u8> {
3334 match i {
3335 0 => Ok(FixMode::Invalid),
3336 1 => Ok(FixMode::SinglePointPosition),
3337 2 => Ok(FixMode::DifferentialGnss),
3338 3 => Ok(FixMode::FloatRtk),
3339 4 => Ok(FixMode::FixedRtk),
3340 5 => Ok(FixMode::DeadReckoning),
3341 6 => Ok(FixMode::SbasPosition),
3342 i => Err(i),
3343 }
3344 }
3345 }
3346}
3347
3348pub mod msg_pos_ecef_cov_gnss {
3349 #![allow(unused_imports)]
3350
3351 use super::*;
3352 use crate::messages::lib::*;
3353
3354 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3369 #[allow(clippy::derive_partial_eq_without_eq)]
3370 #[derive(Debug, PartialEq, Clone)]
3371 pub struct MsgPosEcefCovGnss {
3372 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
3374 pub sender_id: Option<u16>,
3375 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
3377 pub tow: u32,
3378 #[cfg_attr(feature = "serde", serde(rename = "x"))]
3380 pub x: f64,
3381 #[cfg_attr(feature = "serde", serde(rename = "y"))]
3383 pub y: f64,
3384 #[cfg_attr(feature = "serde", serde(rename = "z"))]
3386 pub z: f64,
3387 #[cfg_attr(feature = "serde", serde(rename = "cov_x_x"))]
3389 pub cov_x_x: f32,
3390 #[cfg_attr(feature = "serde", serde(rename = "cov_x_y"))]
3392 pub cov_x_y: f32,
3393 #[cfg_attr(feature = "serde", serde(rename = "cov_x_z"))]
3395 pub cov_x_z: f32,
3396 #[cfg_attr(feature = "serde", serde(rename = "cov_y_y"))]
3398 pub cov_y_y: f32,
3399 #[cfg_attr(feature = "serde", serde(rename = "cov_y_z"))]
3401 pub cov_y_z: f32,
3402 #[cfg_attr(feature = "serde", serde(rename = "cov_z_z"))]
3404 pub cov_z_z: f32,
3405 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
3407 pub n_sats: u8,
3408 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
3410 pub flags: u8,
3411 }
3412
3413 impl MsgPosEcefCovGnss {
3414 pub fn fix_mode(&self) -> Result<FixMode, u8> {
3420 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
3421 }
3422
3423 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
3425 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
3426 }
3427 }
3428
3429 impl ConcreteMessage for MsgPosEcefCovGnss {
3430 const MESSAGE_TYPE: u16 = 564;
3431 const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_COV_GNSS";
3432 }
3433
3434 impl SbpMessage for MsgPosEcefCovGnss {
3435 fn message_name(&self) -> &'static str {
3436 <Self as ConcreteMessage>::MESSAGE_NAME
3437 }
3438 fn message_type(&self) -> Option<u16> {
3439 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
3440 }
3441 fn sender_id(&self) -> Option<u16> {
3442 self.sender_id
3443 }
3444 fn set_sender_id(&mut self, new_id: u16) {
3445 self.sender_id = Some(new_id);
3446 }
3447 fn encoded_len(&self) -> usize {
3448 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
3449 }
3450 fn is_valid(&self) -> bool {
3451 true
3452 }
3453 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
3454 Ok(self)
3455 }
3456
3457 #[cfg(feature = "swiftnav")]
3458 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
3459 let tow_s = (self.tow as f64) / 1000.0;
3460 let gps_time = match time::GpsTime::new(0, tow_s) {
3461 Ok(gps_time) => gps_time.tow(),
3462 Err(e) => return Some(Err(e.into())),
3463 };
3464 Some(Ok(time::MessageTime::Rover(gps_time.into())))
3465 }
3466 }
3467
3468 impl FriendlyName for MsgPosEcefCovGnss {
3469 fn friendly_name() -> &'static str {
3470 "POS ECEF COV GNSS-only"
3471 }
3472 }
3473
3474 impl TryFrom<Sbp> for MsgPosEcefCovGnss {
3475 type Error = TryFromSbpError;
3476 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
3477 match msg {
3478 Sbp::MsgPosEcefCovGnss(m) => Ok(m),
3479 _ => Err(TryFromSbpError(msg)),
3480 }
3481 }
3482 }
3483
3484 impl WireFormat for MsgPosEcefCovGnss {
3485 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
3486 + <f64 as WireFormat>::MIN_LEN
3487 + <f64 as WireFormat>::MIN_LEN
3488 + <f64 as WireFormat>::MIN_LEN
3489 + <f32 as WireFormat>::MIN_LEN
3490 + <f32 as WireFormat>::MIN_LEN
3491 + <f32 as WireFormat>::MIN_LEN
3492 + <f32 as WireFormat>::MIN_LEN
3493 + <f32 as WireFormat>::MIN_LEN
3494 + <f32 as WireFormat>::MIN_LEN
3495 + <u8 as WireFormat>::MIN_LEN
3496 + <u8 as WireFormat>::MIN_LEN;
3497 fn len(&self) -> usize {
3498 WireFormat::len(&self.tow)
3499 + WireFormat::len(&self.x)
3500 + WireFormat::len(&self.y)
3501 + WireFormat::len(&self.z)
3502 + WireFormat::len(&self.cov_x_x)
3503 + WireFormat::len(&self.cov_x_y)
3504 + WireFormat::len(&self.cov_x_z)
3505 + WireFormat::len(&self.cov_y_y)
3506 + WireFormat::len(&self.cov_y_z)
3507 + WireFormat::len(&self.cov_z_z)
3508 + WireFormat::len(&self.n_sats)
3509 + WireFormat::len(&self.flags)
3510 }
3511 fn write<B: BufMut>(&self, buf: &mut B) {
3512 WireFormat::write(&self.tow, buf);
3513 WireFormat::write(&self.x, buf);
3514 WireFormat::write(&self.y, buf);
3515 WireFormat::write(&self.z, buf);
3516 WireFormat::write(&self.cov_x_x, buf);
3517 WireFormat::write(&self.cov_x_y, buf);
3518 WireFormat::write(&self.cov_x_z, buf);
3519 WireFormat::write(&self.cov_y_y, buf);
3520 WireFormat::write(&self.cov_y_z, buf);
3521 WireFormat::write(&self.cov_z_z, buf);
3522 WireFormat::write(&self.n_sats, buf);
3523 WireFormat::write(&self.flags, buf);
3524 }
3525 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
3526 MsgPosEcefCovGnss {
3527 sender_id: None,
3528 tow: WireFormat::parse_unchecked(buf),
3529 x: WireFormat::parse_unchecked(buf),
3530 y: WireFormat::parse_unchecked(buf),
3531 z: WireFormat::parse_unchecked(buf),
3532 cov_x_x: WireFormat::parse_unchecked(buf),
3533 cov_x_y: WireFormat::parse_unchecked(buf),
3534 cov_x_z: WireFormat::parse_unchecked(buf),
3535 cov_y_y: WireFormat::parse_unchecked(buf),
3536 cov_y_z: WireFormat::parse_unchecked(buf),
3537 cov_z_z: WireFormat::parse_unchecked(buf),
3538 n_sats: WireFormat::parse_unchecked(buf),
3539 flags: WireFormat::parse_unchecked(buf),
3540 }
3541 }
3542 }
3543
3544 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3546 pub enum FixMode {
3547 Invalid = 0,
3549
3550 SinglePointPosition = 1,
3552
3553 DifferentialGnss = 2,
3555
3556 FloatRtk = 3,
3558
3559 FixedRtk = 4,
3561
3562 SbasPosition = 6,
3564 }
3565
3566 impl std::fmt::Display for FixMode {
3567 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3568 match self {
3569 FixMode::Invalid => f.write_str("Invalid"),
3570 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
3571 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
3572 FixMode::FloatRtk => f.write_str("Float RTK"),
3573 FixMode::FixedRtk => f.write_str("Fixed RTK"),
3574 FixMode::SbasPosition => f.write_str("SBAS Position"),
3575 }
3576 }
3577 }
3578
3579 impl TryFrom<u8> for FixMode {
3580 type Error = u8;
3581 fn try_from(i: u8) -> Result<Self, u8> {
3582 match i {
3583 0 => Ok(FixMode::Invalid),
3584 1 => Ok(FixMode::SinglePointPosition),
3585 2 => Ok(FixMode::DifferentialGnss),
3586 3 => Ok(FixMode::FloatRtk),
3587 4 => Ok(FixMode::FixedRtk),
3588 6 => Ok(FixMode::SbasPosition),
3589 i => Err(i),
3590 }
3591 }
3592 }
3593}
3594
3595pub mod msg_pos_ecef_dep_a {
3596 #![allow(unused_imports)]
3597
3598 use super::*;
3599 use crate::messages::lib::*;
3600
3601 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3606 #[allow(clippy::derive_partial_eq_without_eq)]
3607 #[derive(Debug, PartialEq, Clone)]
3608 pub struct MsgPosEcefDepA {
3609 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
3611 pub sender_id: Option<u16>,
3612 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
3614 pub tow: u32,
3615 #[cfg_attr(feature = "serde", serde(rename = "x"))]
3617 pub x: f64,
3618 #[cfg_attr(feature = "serde", serde(rename = "y"))]
3620 pub y: f64,
3621 #[cfg_attr(feature = "serde", serde(rename = "z"))]
3623 pub z: f64,
3624 #[cfg_attr(feature = "serde", serde(rename = "accuracy"))]
3626 pub accuracy: u16,
3627 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
3629 pub n_sats: u8,
3630 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
3632 pub flags: u8,
3633 }
3634
3635 impl MsgPosEcefDepA {
3636 pub fn raim_repair_flag(&self) -> Result<RaimRepairFlag, u8> {
3642 get_bit_range!(self.flags, u8, u8, 4, 4).try_into()
3643 }
3644
3645 pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) {
3647 set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 4, 4);
3648 }
3649
3650 pub fn raim_availability_flag(&self) -> Result<RaimAvailabilityFlag, u8> {
3656 get_bit_range!(self.flags, u8, u8, 3, 3).try_into()
3657 }
3658
3659 pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) {
3661 set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 3, 3);
3662 }
3663
3664 pub fn fix_mode(&self) -> Result<FixMode, u8> {
3670 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
3671 }
3672
3673 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
3675 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
3676 }
3677 }
3678
3679 impl ConcreteMessage for MsgPosEcefDepA {
3680 const MESSAGE_TYPE: u16 = 512;
3681 const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_DEP_A";
3682 }
3683
3684 impl SbpMessage for MsgPosEcefDepA {
3685 fn message_name(&self) -> &'static str {
3686 <Self as ConcreteMessage>::MESSAGE_NAME
3687 }
3688 fn message_type(&self) -> Option<u16> {
3689 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
3690 }
3691 fn sender_id(&self) -> Option<u16> {
3692 self.sender_id
3693 }
3694 fn set_sender_id(&mut self, new_id: u16) {
3695 self.sender_id = Some(new_id);
3696 }
3697 fn encoded_len(&self) -> usize {
3698 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
3699 }
3700 fn is_valid(&self) -> bool {
3701 true
3702 }
3703 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
3704 Ok(self)
3705 }
3706
3707 #[cfg(feature = "swiftnav")]
3708 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
3709 let tow_s = (self.tow as f64) / 1000.0;
3710 let gps_time = match time::GpsTime::new(0, tow_s) {
3711 Ok(gps_time) => gps_time.tow(),
3712 Err(e) => return Some(Err(e.into())),
3713 };
3714 Some(Ok(time::MessageTime::Rover(gps_time.into())))
3715 }
3716 }
3717
3718 impl FriendlyName for MsgPosEcefDepA {
3719 fn friendly_name() -> &'static str {
3720 "POS ECEF DEP A"
3721 }
3722 }
3723
3724 impl TryFrom<Sbp> for MsgPosEcefDepA {
3725 type Error = TryFromSbpError;
3726 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
3727 match msg {
3728 Sbp::MsgPosEcefDepA(m) => Ok(m),
3729 _ => Err(TryFromSbpError(msg)),
3730 }
3731 }
3732 }
3733
3734 impl WireFormat for MsgPosEcefDepA {
3735 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
3736 + <f64 as WireFormat>::MIN_LEN
3737 + <f64 as WireFormat>::MIN_LEN
3738 + <f64 as WireFormat>::MIN_LEN
3739 + <u16 as WireFormat>::MIN_LEN
3740 + <u8 as WireFormat>::MIN_LEN
3741 + <u8 as WireFormat>::MIN_LEN;
3742 fn len(&self) -> usize {
3743 WireFormat::len(&self.tow)
3744 + WireFormat::len(&self.x)
3745 + WireFormat::len(&self.y)
3746 + WireFormat::len(&self.z)
3747 + WireFormat::len(&self.accuracy)
3748 + WireFormat::len(&self.n_sats)
3749 + WireFormat::len(&self.flags)
3750 }
3751 fn write<B: BufMut>(&self, buf: &mut B) {
3752 WireFormat::write(&self.tow, buf);
3753 WireFormat::write(&self.x, buf);
3754 WireFormat::write(&self.y, buf);
3755 WireFormat::write(&self.z, buf);
3756 WireFormat::write(&self.accuracy, buf);
3757 WireFormat::write(&self.n_sats, buf);
3758 WireFormat::write(&self.flags, buf);
3759 }
3760 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
3761 MsgPosEcefDepA {
3762 sender_id: None,
3763 tow: WireFormat::parse_unchecked(buf),
3764 x: WireFormat::parse_unchecked(buf),
3765 y: WireFormat::parse_unchecked(buf),
3766 z: WireFormat::parse_unchecked(buf),
3767 accuracy: WireFormat::parse_unchecked(buf),
3768 n_sats: WireFormat::parse_unchecked(buf),
3769 flags: WireFormat::parse_unchecked(buf),
3770 }
3771 }
3772 }
3773
3774 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3776 pub enum RaimRepairFlag {
3777 NoRepair = 0,
3779
3780 SolutionCameFromRaimRepair = 1,
3782 }
3783
3784 impl std::fmt::Display for RaimRepairFlag {
3785 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3786 match self {
3787 RaimRepairFlag::NoRepair => f.write_str("No repair"),
3788 RaimRepairFlag::SolutionCameFromRaimRepair => {
3789 f.write_str("Solution came from RAIM repair")
3790 }
3791 }
3792 }
3793 }
3794
3795 impl TryFrom<u8> for RaimRepairFlag {
3796 type Error = u8;
3797 fn try_from(i: u8) -> Result<Self, u8> {
3798 match i {
3799 0 => Ok(RaimRepairFlag::NoRepair),
3800 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair),
3801 i => Err(i),
3802 }
3803 }
3804 }
3805
3806 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3808 pub enum RaimAvailabilityFlag {
3809 RaimCheckWasExplicitlyDisabledOrUnavailable = 0,
3811
3812 RaimCheckWasAvailable = 1,
3814 }
3815
3816 impl std::fmt::Display for RaimAvailabilityFlag {
3817 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3818 match self {
3819 RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => {
3820 f.write_str("RAIM check was explicitly disabled or unavailable")
3821 }
3822 RaimAvailabilityFlag::RaimCheckWasAvailable => {
3823 f.write_str("RAIM check was available")
3824 }
3825 }
3826 }
3827 }
3828
3829 impl TryFrom<u8> for RaimAvailabilityFlag {
3830 type Error = u8;
3831 fn try_from(i: u8) -> Result<Self, u8> {
3832 match i {
3833 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable),
3834 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable),
3835 i => Err(i),
3836 }
3837 }
3838 }
3839
3840 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3842 pub enum FixMode {
3843 SinglePointPositioning = 0,
3845
3846 FixedRtk = 1,
3848
3849 FloatRtk = 2,
3851 }
3852
3853 impl std::fmt::Display for FixMode {
3854 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3855 match self {
3856 FixMode::SinglePointPositioning => f.write_str("Single Point Positioning (SPP)"),
3857 FixMode::FixedRtk => f.write_str("Fixed RTK"),
3858 FixMode::FloatRtk => f.write_str("Float RTK"),
3859 }
3860 }
3861 }
3862
3863 impl TryFrom<u8> for FixMode {
3864 type Error = u8;
3865 fn try_from(i: u8) -> Result<Self, u8> {
3866 match i {
3867 0 => Ok(FixMode::SinglePointPositioning),
3868 1 => Ok(FixMode::FixedRtk),
3869 2 => Ok(FixMode::FloatRtk),
3870 i => Err(i),
3871 }
3872 }
3873 }
3874}
3875
3876pub mod msg_pos_ecef_gnss {
3877 #![allow(unused_imports)]
3878
3879 use super::*;
3880 use crate::messages::lib::*;
3881
3882 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3896 #[allow(clippy::derive_partial_eq_without_eq)]
3897 #[derive(Debug, PartialEq, Clone)]
3898 pub struct MsgPosEcefGnss {
3899 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
3901 pub sender_id: Option<u16>,
3902 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
3904 pub tow: u32,
3905 #[cfg_attr(feature = "serde", serde(rename = "x"))]
3907 pub x: f64,
3908 #[cfg_attr(feature = "serde", serde(rename = "y"))]
3910 pub y: f64,
3911 #[cfg_attr(feature = "serde", serde(rename = "z"))]
3913 pub z: f64,
3914 #[cfg_attr(feature = "serde", serde(rename = "accuracy"))]
3916 pub accuracy: u16,
3917 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
3919 pub n_sats: u8,
3920 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
3922 pub flags: u8,
3923 }
3924
3925 impl MsgPosEcefGnss {
3926 pub fn fix_mode(&self) -> Result<FixMode, u8> {
3932 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
3933 }
3934
3935 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
3937 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
3938 }
3939 }
3940
3941 impl ConcreteMessage for MsgPosEcefGnss {
3942 const MESSAGE_TYPE: u16 = 553;
3943 const MESSAGE_NAME: &'static str = "MSG_POS_ECEF_GNSS";
3944 }
3945
3946 impl SbpMessage for MsgPosEcefGnss {
3947 fn message_name(&self) -> &'static str {
3948 <Self as ConcreteMessage>::MESSAGE_NAME
3949 }
3950 fn message_type(&self) -> Option<u16> {
3951 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
3952 }
3953 fn sender_id(&self) -> Option<u16> {
3954 self.sender_id
3955 }
3956 fn set_sender_id(&mut self, new_id: u16) {
3957 self.sender_id = Some(new_id);
3958 }
3959 fn encoded_len(&self) -> usize {
3960 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
3961 }
3962 fn is_valid(&self) -> bool {
3963 true
3964 }
3965 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
3966 Ok(self)
3967 }
3968
3969 #[cfg(feature = "swiftnav")]
3970 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
3971 let tow_s = (self.tow as f64) / 1000.0;
3972 let gps_time = match time::GpsTime::new(0, tow_s) {
3973 Ok(gps_time) => gps_time.tow(),
3974 Err(e) => return Some(Err(e.into())),
3975 };
3976 Some(Ok(time::MessageTime::Rover(gps_time.into())))
3977 }
3978 }
3979
3980 impl FriendlyName for MsgPosEcefGnss {
3981 fn friendly_name() -> &'static str {
3982 "POS ECEF GNSS-only"
3983 }
3984 }
3985
3986 impl TryFrom<Sbp> for MsgPosEcefGnss {
3987 type Error = TryFromSbpError;
3988 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
3989 match msg {
3990 Sbp::MsgPosEcefGnss(m) => Ok(m),
3991 _ => Err(TryFromSbpError(msg)),
3992 }
3993 }
3994 }
3995
3996 impl WireFormat for MsgPosEcefGnss {
3997 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
3998 + <f64 as WireFormat>::MIN_LEN
3999 + <f64 as WireFormat>::MIN_LEN
4000 + <f64 as WireFormat>::MIN_LEN
4001 + <u16 as WireFormat>::MIN_LEN
4002 + <u8 as WireFormat>::MIN_LEN
4003 + <u8 as WireFormat>::MIN_LEN;
4004 fn len(&self) -> usize {
4005 WireFormat::len(&self.tow)
4006 + WireFormat::len(&self.x)
4007 + WireFormat::len(&self.y)
4008 + WireFormat::len(&self.z)
4009 + WireFormat::len(&self.accuracy)
4010 + WireFormat::len(&self.n_sats)
4011 + WireFormat::len(&self.flags)
4012 }
4013 fn write<B: BufMut>(&self, buf: &mut B) {
4014 WireFormat::write(&self.tow, buf);
4015 WireFormat::write(&self.x, buf);
4016 WireFormat::write(&self.y, buf);
4017 WireFormat::write(&self.z, buf);
4018 WireFormat::write(&self.accuracy, buf);
4019 WireFormat::write(&self.n_sats, buf);
4020 WireFormat::write(&self.flags, buf);
4021 }
4022 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
4023 MsgPosEcefGnss {
4024 sender_id: None,
4025 tow: WireFormat::parse_unchecked(buf),
4026 x: WireFormat::parse_unchecked(buf),
4027 y: WireFormat::parse_unchecked(buf),
4028 z: WireFormat::parse_unchecked(buf),
4029 accuracy: WireFormat::parse_unchecked(buf),
4030 n_sats: WireFormat::parse_unchecked(buf),
4031 flags: WireFormat::parse_unchecked(buf),
4032 }
4033 }
4034 }
4035
4036 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4038 pub enum FixMode {
4039 Invalid = 0,
4041
4042 SinglePointPosition = 1,
4044
4045 DifferentialGnss = 2,
4047
4048 FloatRtk = 3,
4050
4051 FixedRtk = 4,
4053
4054 SbasPosition = 6,
4056 }
4057
4058 impl std::fmt::Display for FixMode {
4059 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4060 match self {
4061 FixMode::Invalid => f.write_str("Invalid"),
4062 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
4063 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
4064 FixMode::FloatRtk => f.write_str("Float RTK"),
4065 FixMode::FixedRtk => f.write_str("Fixed RTK"),
4066 FixMode::SbasPosition => f.write_str("SBAS Position"),
4067 }
4068 }
4069 }
4070
4071 impl TryFrom<u8> for FixMode {
4072 type Error = u8;
4073 fn try_from(i: u8) -> Result<Self, u8> {
4074 match i {
4075 0 => Ok(FixMode::Invalid),
4076 1 => Ok(FixMode::SinglePointPosition),
4077 2 => Ok(FixMode::DifferentialGnss),
4078 3 => Ok(FixMode::FloatRtk),
4079 4 => Ok(FixMode::FixedRtk),
4080 6 => Ok(FixMode::SbasPosition),
4081 i => Err(i),
4082 }
4083 }
4084 }
4085}
4086
4087pub mod msg_pos_llh {
4088 #![allow(unused_imports)]
4089
4090 use super::*;
4091 use crate::messages::lib::*;
4092
4093 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4108 #[allow(clippy::derive_partial_eq_without_eq)]
4109 #[derive(Debug, PartialEq, Clone)]
4110 pub struct MsgPosLlh {
4111 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
4113 pub sender_id: Option<u16>,
4114 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
4116 pub tow: u32,
4117 #[cfg_attr(feature = "serde", serde(rename = "lat"))]
4119 pub lat: f64,
4120 #[cfg_attr(feature = "serde", serde(rename = "lon"))]
4122 pub lon: f64,
4123 #[cfg_attr(feature = "serde", serde(rename = "height"))]
4125 pub height: f64,
4126 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
4128 pub h_accuracy: u16,
4129 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
4131 pub v_accuracy: u16,
4132 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
4134 pub n_sats: u8,
4135 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
4137 pub flags: u8,
4138 }
4139
4140 impl MsgPosLlh {
4141 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
4147 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
4148 }
4149
4150 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
4152 set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5);
4153 }
4154
4155 pub fn inertial_navigation_mode(&self) -> Result<InertialNavigationMode, u8> {
4161 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
4162 }
4163
4164 pub fn set_inertial_navigation_mode(
4166 &mut self,
4167 inertial_navigation_mode: InertialNavigationMode,
4168 ) {
4169 set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3);
4170 }
4171
4172 pub fn fix_mode(&self) -> Result<FixMode, u8> {
4178 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
4179 }
4180
4181 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
4183 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
4184 }
4185 }
4186
4187 impl ConcreteMessage for MsgPosLlh {
4188 const MESSAGE_TYPE: u16 = 522;
4189 const MESSAGE_NAME: &'static str = "MSG_POS_LLH";
4190 }
4191
4192 impl SbpMessage for MsgPosLlh {
4193 fn message_name(&self) -> &'static str {
4194 <Self as ConcreteMessage>::MESSAGE_NAME
4195 }
4196 fn message_type(&self) -> Option<u16> {
4197 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
4198 }
4199 fn sender_id(&self) -> Option<u16> {
4200 self.sender_id
4201 }
4202 fn set_sender_id(&mut self, new_id: u16) {
4203 self.sender_id = Some(new_id);
4204 }
4205 fn encoded_len(&self) -> usize {
4206 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
4207 }
4208 fn is_valid(&self) -> bool {
4209 true
4210 }
4211 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
4212 Ok(self)
4213 }
4214
4215 #[cfg(feature = "swiftnav")]
4216 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
4217 let tow_s = (self.tow as f64) / 1000.0;
4218 let gps_time = match time::GpsTime::new(0, tow_s) {
4219 Ok(gps_time) => gps_time.tow(),
4220 Err(e) => return Some(Err(e.into())),
4221 };
4222 Some(Ok(time::MessageTime::Rover(gps_time.into())))
4223 }
4224 }
4225
4226 impl FriendlyName for MsgPosLlh {
4227 fn friendly_name() -> &'static str {
4228 "POS LLH"
4229 }
4230 }
4231
4232 impl TryFrom<Sbp> for MsgPosLlh {
4233 type Error = TryFromSbpError;
4234 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
4235 match msg {
4236 Sbp::MsgPosLlh(m) => Ok(m),
4237 _ => Err(TryFromSbpError(msg)),
4238 }
4239 }
4240 }
4241
4242 impl WireFormat for MsgPosLlh {
4243 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
4244 + <f64 as WireFormat>::MIN_LEN
4245 + <f64 as WireFormat>::MIN_LEN
4246 + <f64 as WireFormat>::MIN_LEN
4247 + <u16 as WireFormat>::MIN_LEN
4248 + <u16 as WireFormat>::MIN_LEN
4249 + <u8 as WireFormat>::MIN_LEN
4250 + <u8 as WireFormat>::MIN_LEN;
4251 fn len(&self) -> usize {
4252 WireFormat::len(&self.tow)
4253 + WireFormat::len(&self.lat)
4254 + WireFormat::len(&self.lon)
4255 + WireFormat::len(&self.height)
4256 + WireFormat::len(&self.h_accuracy)
4257 + WireFormat::len(&self.v_accuracy)
4258 + WireFormat::len(&self.n_sats)
4259 + WireFormat::len(&self.flags)
4260 }
4261 fn write<B: BufMut>(&self, buf: &mut B) {
4262 WireFormat::write(&self.tow, buf);
4263 WireFormat::write(&self.lat, buf);
4264 WireFormat::write(&self.lon, buf);
4265 WireFormat::write(&self.height, buf);
4266 WireFormat::write(&self.h_accuracy, buf);
4267 WireFormat::write(&self.v_accuracy, buf);
4268 WireFormat::write(&self.n_sats, buf);
4269 WireFormat::write(&self.flags, buf);
4270 }
4271 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
4272 MsgPosLlh {
4273 sender_id: None,
4274 tow: WireFormat::parse_unchecked(buf),
4275 lat: WireFormat::parse_unchecked(buf),
4276 lon: WireFormat::parse_unchecked(buf),
4277 height: WireFormat::parse_unchecked(buf),
4278 h_accuracy: WireFormat::parse_unchecked(buf),
4279 v_accuracy: WireFormat::parse_unchecked(buf),
4280 n_sats: WireFormat::parse_unchecked(buf),
4281 flags: WireFormat::parse_unchecked(buf),
4282 }
4283 }
4284 }
4285
4286 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4288 pub enum TypeOfReportedTow {
4289 TimeOfMeasurement = 0,
4291
4292 Other = 1,
4294 }
4295
4296 impl std::fmt::Display for TypeOfReportedTow {
4297 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4298 match self {
4299 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
4300 TypeOfReportedTow::Other => f.write_str("Other"),
4301 }
4302 }
4303 }
4304
4305 impl TryFrom<u8> for TypeOfReportedTow {
4306 type Error = u8;
4307 fn try_from(i: u8) -> Result<Self, u8> {
4308 match i {
4309 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
4310 1 => Ok(TypeOfReportedTow::Other),
4311 i => Err(i),
4312 }
4313 }
4314 }
4315
4316 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4318 pub enum InertialNavigationMode {
4319 None = 0,
4321
4322 InsUsed = 1,
4324 }
4325
4326 impl std::fmt::Display for InertialNavigationMode {
4327 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4328 match self {
4329 InertialNavigationMode::None => f.write_str("None"),
4330 InertialNavigationMode::InsUsed => f.write_str("INS used"),
4331 }
4332 }
4333 }
4334
4335 impl TryFrom<u8> for InertialNavigationMode {
4336 type Error = u8;
4337 fn try_from(i: u8) -> Result<Self, u8> {
4338 match i {
4339 0 => Ok(InertialNavigationMode::None),
4340 1 => Ok(InertialNavigationMode::InsUsed),
4341 i => Err(i),
4342 }
4343 }
4344 }
4345
4346 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4348 pub enum FixMode {
4349 Invalid = 0,
4351
4352 SinglePointPosition = 1,
4354
4355 DifferentialGnss = 2,
4357
4358 FloatRtk = 3,
4360
4361 FixedRtk = 4,
4363
4364 DeadReckoning = 5,
4366
4367 SbasPosition = 6,
4369 }
4370
4371 impl std::fmt::Display for FixMode {
4372 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4373 match self {
4374 FixMode::Invalid => f.write_str("Invalid"),
4375 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
4376 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
4377 FixMode::FloatRtk => f.write_str("Float RTK"),
4378 FixMode::FixedRtk => f.write_str("Fixed RTK"),
4379 FixMode::DeadReckoning => f.write_str("Dead Reckoning"),
4380 FixMode::SbasPosition => f.write_str("SBAS Position"),
4381 }
4382 }
4383 }
4384
4385 impl TryFrom<u8> for FixMode {
4386 type Error = u8;
4387 fn try_from(i: u8) -> Result<Self, u8> {
4388 match i {
4389 0 => Ok(FixMode::Invalid),
4390 1 => Ok(FixMode::SinglePointPosition),
4391 2 => Ok(FixMode::DifferentialGnss),
4392 3 => Ok(FixMode::FloatRtk),
4393 4 => Ok(FixMode::FixedRtk),
4394 5 => Ok(FixMode::DeadReckoning),
4395 6 => Ok(FixMode::SbasPosition),
4396 i => Err(i),
4397 }
4398 }
4399 }
4400}
4401
4402pub mod msg_pos_llh_acc {
4403 #![allow(unused_imports)]
4404
4405 use super::*;
4406 use crate::messages::lib::*;
4407
4408 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4425 #[allow(clippy::derive_partial_eq_without_eq)]
4426 #[derive(Debug, PartialEq, Clone)]
4427 pub struct MsgPosLlhAcc {
4428 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
4430 pub sender_id: Option<u16>,
4431 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
4433 pub tow: u32,
4434 #[cfg_attr(feature = "serde", serde(rename = "lat"))]
4436 pub lat: f64,
4437 #[cfg_attr(feature = "serde", serde(rename = "lon"))]
4439 pub lon: f64,
4440 #[cfg_attr(feature = "serde", serde(rename = "height"))]
4442 pub height: f64,
4443 #[cfg_attr(feature = "serde", serde(rename = "orthometric_height"))]
4446 pub orthometric_height: f64,
4447 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
4450 pub h_accuracy: f32,
4451 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
4454 pub v_accuracy: f32,
4455 #[cfg_attr(feature = "serde", serde(rename = "ct_accuracy"))]
4458 pub ct_accuracy: f32,
4459 #[cfg_attr(feature = "serde", serde(rename = "at_accuracy"))]
4462 pub at_accuracy: f32,
4463 #[cfg_attr(feature = "serde", serde(rename = "h_ellipse"))]
4466 pub h_ellipse: EstimatedHorizontalErrorEllipse,
4467 #[cfg_attr(feature = "serde", serde(rename = "confidence_and_geoid"))]
4471 pub confidence_and_geoid: u8,
4472 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
4474 pub n_sats: u8,
4475 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
4477 pub flags: u8,
4478 }
4479
4480 impl MsgPosLlhAcc {
4481 pub fn geoid_model(&self) -> Result<GeoidModel, u8> {
4487 get_bit_range!(self.confidence_and_geoid, u8, u8, 6, 4).try_into()
4488 }
4489
4490 pub fn set_geoid_model(&mut self, geoid_model: GeoidModel) {
4492 set_bit_range!(&mut self.confidence_and_geoid, geoid_model, u8, u8, 6, 4);
4493 }
4494
4495 pub fn confidence_level(&self) -> Result<ConfidenceLevel, u8> {
4501 get_bit_range!(self.confidence_and_geoid, u8, u8, 3, 0).try_into()
4502 }
4503
4504 pub fn set_confidence_level(&mut self, confidence_level: ConfidenceLevel) {
4506 set_bit_range!(
4507 &mut self.confidence_and_geoid,
4508 confidence_level,
4509 u8,
4510 u8,
4511 3,
4512 0
4513 );
4514 }
4515
4516 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
4522 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
4523 }
4524
4525 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
4527 set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5);
4528 }
4529
4530 pub fn inertial_navigation_mode(&self) -> Result<InertialNavigationMode, u8> {
4536 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
4537 }
4538
4539 pub fn set_inertial_navigation_mode(
4541 &mut self,
4542 inertial_navigation_mode: InertialNavigationMode,
4543 ) {
4544 set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3);
4545 }
4546
4547 pub fn fix_mode(&self) -> Result<FixMode, u8> {
4553 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
4554 }
4555
4556 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
4558 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
4559 }
4560 }
4561
4562 impl ConcreteMessage for MsgPosLlhAcc {
4563 const MESSAGE_TYPE: u16 = 536;
4564 const MESSAGE_NAME: &'static str = "MSG_POS_LLH_ACC";
4565 }
4566
4567 impl SbpMessage for MsgPosLlhAcc {
4568 fn message_name(&self) -> &'static str {
4569 <Self as ConcreteMessage>::MESSAGE_NAME
4570 }
4571 fn message_type(&self) -> Option<u16> {
4572 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
4573 }
4574 fn sender_id(&self) -> Option<u16> {
4575 self.sender_id
4576 }
4577 fn set_sender_id(&mut self, new_id: u16) {
4578 self.sender_id = Some(new_id);
4579 }
4580 fn encoded_len(&self) -> usize {
4581 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
4582 }
4583 fn is_valid(&self) -> bool {
4584 true
4585 }
4586 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
4587 Ok(self)
4588 }
4589
4590 #[cfg(feature = "swiftnav")]
4591 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
4592 let tow_s = (self.tow as f64) / 1000.0;
4593 let gps_time = match time::GpsTime::new(0, tow_s) {
4594 Ok(gps_time) => gps_time.tow(),
4595 Err(e) => return Some(Err(e.into())),
4596 };
4597 Some(Ok(time::MessageTime::Rover(gps_time.into())))
4598 }
4599 }
4600
4601 impl FriendlyName for MsgPosLlhAcc {
4602 fn friendly_name() -> &'static str {
4603 "POS LLH ACC"
4604 }
4605 }
4606
4607 impl TryFrom<Sbp> for MsgPosLlhAcc {
4608 type Error = TryFromSbpError;
4609 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
4610 match msg {
4611 Sbp::MsgPosLlhAcc(m) => Ok(m),
4612 _ => Err(TryFromSbpError(msg)),
4613 }
4614 }
4615 }
4616
4617 impl WireFormat for MsgPosLlhAcc {
4618 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
4619 + <f64 as WireFormat>::MIN_LEN
4620 + <f64 as WireFormat>::MIN_LEN
4621 + <f64 as WireFormat>::MIN_LEN
4622 + <f64 as WireFormat>::MIN_LEN
4623 + <f32 as WireFormat>::MIN_LEN
4624 + <f32 as WireFormat>::MIN_LEN
4625 + <f32 as WireFormat>::MIN_LEN
4626 + <f32 as WireFormat>::MIN_LEN
4627 + <EstimatedHorizontalErrorEllipse as WireFormat>::MIN_LEN
4628 + <u8 as WireFormat>::MIN_LEN
4629 + <u8 as WireFormat>::MIN_LEN
4630 + <u8 as WireFormat>::MIN_LEN;
4631 fn len(&self) -> usize {
4632 WireFormat::len(&self.tow)
4633 + WireFormat::len(&self.lat)
4634 + WireFormat::len(&self.lon)
4635 + WireFormat::len(&self.height)
4636 + WireFormat::len(&self.orthometric_height)
4637 + WireFormat::len(&self.h_accuracy)
4638 + WireFormat::len(&self.v_accuracy)
4639 + WireFormat::len(&self.ct_accuracy)
4640 + WireFormat::len(&self.at_accuracy)
4641 + WireFormat::len(&self.h_ellipse)
4642 + WireFormat::len(&self.confidence_and_geoid)
4643 + WireFormat::len(&self.n_sats)
4644 + WireFormat::len(&self.flags)
4645 }
4646 fn write<B: BufMut>(&self, buf: &mut B) {
4647 WireFormat::write(&self.tow, buf);
4648 WireFormat::write(&self.lat, buf);
4649 WireFormat::write(&self.lon, buf);
4650 WireFormat::write(&self.height, buf);
4651 WireFormat::write(&self.orthometric_height, buf);
4652 WireFormat::write(&self.h_accuracy, buf);
4653 WireFormat::write(&self.v_accuracy, buf);
4654 WireFormat::write(&self.ct_accuracy, buf);
4655 WireFormat::write(&self.at_accuracy, buf);
4656 WireFormat::write(&self.h_ellipse, buf);
4657 WireFormat::write(&self.confidence_and_geoid, buf);
4658 WireFormat::write(&self.n_sats, buf);
4659 WireFormat::write(&self.flags, buf);
4660 }
4661 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
4662 MsgPosLlhAcc {
4663 sender_id: None,
4664 tow: WireFormat::parse_unchecked(buf),
4665 lat: WireFormat::parse_unchecked(buf),
4666 lon: WireFormat::parse_unchecked(buf),
4667 height: WireFormat::parse_unchecked(buf),
4668 orthometric_height: WireFormat::parse_unchecked(buf),
4669 h_accuracy: WireFormat::parse_unchecked(buf),
4670 v_accuracy: WireFormat::parse_unchecked(buf),
4671 ct_accuracy: WireFormat::parse_unchecked(buf),
4672 at_accuracy: WireFormat::parse_unchecked(buf),
4673 h_ellipse: WireFormat::parse_unchecked(buf),
4674 confidence_and_geoid: WireFormat::parse_unchecked(buf),
4675 n_sats: WireFormat::parse_unchecked(buf),
4676 flags: WireFormat::parse_unchecked(buf),
4677 }
4678 }
4679 }
4680
4681 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4683 pub enum GeoidModel {
4684 NoModel = 0,
4686
4687 EGM96 = 1,
4689
4690 EGM2008 = 2,
4692 }
4693
4694 impl std::fmt::Display for GeoidModel {
4695 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4696 match self {
4697 GeoidModel::NoModel => f.write_str("No model"),
4698 GeoidModel::EGM96 => f.write_str("EGM96"),
4699 GeoidModel::EGM2008 => f.write_str("EGM2008"),
4700 }
4701 }
4702 }
4703
4704 impl TryFrom<u8> for GeoidModel {
4705 type Error = u8;
4706 fn try_from(i: u8) -> Result<Self, u8> {
4707 match i {
4708 0 => Ok(GeoidModel::NoModel),
4709 1 => Ok(GeoidModel::EGM96),
4710 2 => Ok(GeoidModel::EGM2008),
4711 i => Err(i),
4712 }
4713 }
4714 }
4715
4716 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4718 pub enum ConfidenceLevel {
4719 _3935 = 1,
4721
4722 _6827 = 2,
4724
4725 _9545 = 3,
4727
4728 _9973 = 4,
4730 }
4731
4732 impl std::fmt::Display for ConfidenceLevel {
4733 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4734 match self {
4735 ConfidenceLevel::_3935 => f.write_str("39.35%"),
4736 ConfidenceLevel::_6827 => f.write_str("68.27%"),
4737 ConfidenceLevel::_9545 => f.write_str("95.45%"),
4738 ConfidenceLevel::_9973 => f.write_str("99.73%"),
4739 }
4740 }
4741 }
4742
4743 impl TryFrom<u8> for ConfidenceLevel {
4744 type Error = u8;
4745 fn try_from(i: u8) -> Result<Self, u8> {
4746 match i {
4747 1 => Ok(ConfidenceLevel::_3935),
4748 2 => Ok(ConfidenceLevel::_6827),
4749 3 => Ok(ConfidenceLevel::_9545),
4750 4 => Ok(ConfidenceLevel::_9973),
4751 i => Err(i),
4752 }
4753 }
4754 }
4755
4756 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4758 pub enum TypeOfReportedTow {
4759 TimeOfMeasurement = 0,
4761
4762 Other = 1,
4764 }
4765
4766 impl std::fmt::Display for TypeOfReportedTow {
4767 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4768 match self {
4769 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
4770 TypeOfReportedTow::Other => f.write_str("Other"),
4771 }
4772 }
4773 }
4774
4775 impl TryFrom<u8> for TypeOfReportedTow {
4776 type Error = u8;
4777 fn try_from(i: u8) -> Result<Self, u8> {
4778 match i {
4779 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
4780 1 => Ok(TypeOfReportedTow::Other),
4781 i => Err(i),
4782 }
4783 }
4784 }
4785
4786 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4788 pub enum InertialNavigationMode {
4789 None = 0,
4791
4792 InsUsed = 1,
4794 }
4795
4796 impl std::fmt::Display for InertialNavigationMode {
4797 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4798 match self {
4799 InertialNavigationMode::None => f.write_str("None"),
4800 InertialNavigationMode::InsUsed => f.write_str("INS used"),
4801 }
4802 }
4803 }
4804
4805 impl TryFrom<u8> for InertialNavigationMode {
4806 type Error = u8;
4807 fn try_from(i: u8) -> Result<Self, u8> {
4808 match i {
4809 0 => Ok(InertialNavigationMode::None),
4810 1 => Ok(InertialNavigationMode::InsUsed),
4811 i => Err(i),
4812 }
4813 }
4814 }
4815
4816 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4818 pub enum FixMode {
4819 Invalid = 0,
4821
4822 SinglePointPosition = 1,
4824
4825 DifferentialGnss = 2,
4827
4828 FloatRtk = 3,
4830
4831 FixedRtk = 4,
4833
4834 DeadReckoning = 5,
4836
4837 SbasPosition = 6,
4839 }
4840
4841 impl std::fmt::Display for FixMode {
4842 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4843 match self {
4844 FixMode::Invalid => f.write_str("Invalid"),
4845 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
4846 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
4847 FixMode::FloatRtk => f.write_str("Float RTK"),
4848 FixMode::FixedRtk => f.write_str("Fixed RTK"),
4849 FixMode::DeadReckoning => f.write_str("Dead Reckoning"),
4850 FixMode::SbasPosition => f.write_str("SBAS Position"),
4851 }
4852 }
4853 }
4854
4855 impl TryFrom<u8> for FixMode {
4856 type Error = u8;
4857 fn try_from(i: u8) -> Result<Self, u8> {
4858 match i {
4859 0 => Ok(FixMode::Invalid),
4860 1 => Ok(FixMode::SinglePointPosition),
4861 2 => Ok(FixMode::DifferentialGnss),
4862 3 => Ok(FixMode::FloatRtk),
4863 4 => Ok(FixMode::FixedRtk),
4864 5 => Ok(FixMode::DeadReckoning),
4865 6 => Ok(FixMode::SbasPosition),
4866 i => Err(i),
4867 }
4868 }
4869 }
4870}
4871
4872pub mod msg_pos_llh_cov {
4873 #![allow(unused_imports)]
4874
4875 use super::*;
4876 use crate::messages::lib::*;
4877
4878 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4894 #[allow(clippy::derive_partial_eq_without_eq)]
4895 #[derive(Debug, PartialEq, Clone)]
4896 pub struct MsgPosLlhCov {
4897 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
4899 pub sender_id: Option<u16>,
4900 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
4902 pub tow: u32,
4903 #[cfg_attr(feature = "serde", serde(rename = "lat"))]
4905 pub lat: f64,
4906 #[cfg_attr(feature = "serde", serde(rename = "lon"))]
4908 pub lon: f64,
4909 #[cfg_attr(feature = "serde", serde(rename = "height"))]
4911 pub height: f64,
4912 #[cfg_attr(feature = "serde", serde(rename = "cov_n_n"))]
4914 pub cov_n_n: f32,
4915 #[cfg_attr(feature = "serde", serde(rename = "cov_n_e"))]
4917 pub cov_n_e: f32,
4918 #[cfg_attr(feature = "serde", serde(rename = "cov_n_d"))]
4920 pub cov_n_d: f32,
4921 #[cfg_attr(feature = "serde", serde(rename = "cov_e_e"))]
4923 pub cov_e_e: f32,
4924 #[cfg_attr(feature = "serde", serde(rename = "cov_e_d"))]
4926 pub cov_e_d: f32,
4927 #[cfg_attr(feature = "serde", serde(rename = "cov_d_d"))]
4929 pub cov_d_d: f32,
4930 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
4932 pub n_sats: u8,
4933 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
4935 pub flags: u8,
4936 }
4937
4938 impl MsgPosLlhCov {
4939 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
4945 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
4946 }
4947
4948 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
4950 set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5);
4951 }
4952
4953 pub fn inertial_navigation_mode(&self) -> Result<InertialNavigationMode, u8> {
4959 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
4960 }
4961
4962 pub fn set_inertial_navigation_mode(
4964 &mut self,
4965 inertial_navigation_mode: InertialNavigationMode,
4966 ) {
4967 set_bit_range!(&mut self.flags, inertial_navigation_mode, u8, u8, 4, 3);
4968 }
4969
4970 pub fn fix_mode(&self) -> Result<FixMode, u8> {
4976 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
4977 }
4978
4979 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
4981 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
4982 }
4983 }
4984
4985 impl ConcreteMessage for MsgPosLlhCov {
4986 const MESSAGE_TYPE: u16 = 529;
4987 const MESSAGE_NAME: &'static str = "MSG_POS_LLH_COV";
4988 }
4989
4990 impl SbpMessage for MsgPosLlhCov {
4991 fn message_name(&self) -> &'static str {
4992 <Self as ConcreteMessage>::MESSAGE_NAME
4993 }
4994 fn message_type(&self) -> Option<u16> {
4995 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
4996 }
4997 fn sender_id(&self) -> Option<u16> {
4998 self.sender_id
4999 }
5000 fn set_sender_id(&mut self, new_id: u16) {
5001 self.sender_id = Some(new_id);
5002 }
5003 fn encoded_len(&self) -> usize {
5004 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
5005 }
5006 fn is_valid(&self) -> bool {
5007 true
5008 }
5009 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
5010 Ok(self)
5011 }
5012
5013 #[cfg(feature = "swiftnav")]
5014 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
5015 let tow_s = (self.tow as f64) / 1000.0;
5016 let gps_time = match time::GpsTime::new(0, tow_s) {
5017 Ok(gps_time) => gps_time.tow(),
5018 Err(e) => return Some(Err(e.into())),
5019 };
5020 Some(Ok(time::MessageTime::Rover(gps_time.into())))
5021 }
5022 }
5023
5024 impl FriendlyName for MsgPosLlhCov {
5025 fn friendly_name() -> &'static str {
5026 "POS LLH COV"
5027 }
5028 }
5029
5030 impl TryFrom<Sbp> for MsgPosLlhCov {
5031 type Error = TryFromSbpError;
5032 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
5033 match msg {
5034 Sbp::MsgPosLlhCov(m) => Ok(m),
5035 _ => Err(TryFromSbpError(msg)),
5036 }
5037 }
5038 }
5039
5040 impl WireFormat for MsgPosLlhCov {
5041 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
5042 + <f64 as WireFormat>::MIN_LEN
5043 + <f64 as WireFormat>::MIN_LEN
5044 + <f64 as WireFormat>::MIN_LEN
5045 + <f32 as WireFormat>::MIN_LEN
5046 + <f32 as WireFormat>::MIN_LEN
5047 + <f32 as WireFormat>::MIN_LEN
5048 + <f32 as WireFormat>::MIN_LEN
5049 + <f32 as WireFormat>::MIN_LEN
5050 + <f32 as WireFormat>::MIN_LEN
5051 + <u8 as WireFormat>::MIN_LEN
5052 + <u8 as WireFormat>::MIN_LEN;
5053 fn len(&self) -> usize {
5054 WireFormat::len(&self.tow)
5055 + WireFormat::len(&self.lat)
5056 + WireFormat::len(&self.lon)
5057 + WireFormat::len(&self.height)
5058 + WireFormat::len(&self.cov_n_n)
5059 + WireFormat::len(&self.cov_n_e)
5060 + WireFormat::len(&self.cov_n_d)
5061 + WireFormat::len(&self.cov_e_e)
5062 + WireFormat::len(&self.cov_e_d)
5063 + WireFormat::len(&self.cov_d_d)
5064 + WireFormat::len(&self.n_sats)
5065 + WireFormat::len(&self.flags)
5066 }
5067 fn write<B: BufMut>(&self, buf: &mut B) {
5068 WireFormat::write(&self.tow, buf);
5069 WireFormat::write(&self.lat, buf);
5070 WireFormat::write(&self.lon, buf);
5071 WireFormat::write(&self.height, buf);
5072 WireFormat::write(&self.cov_n_n, buf);
5073 WireFormat::write(&self.cov_n_e, buf);
5074 WireFormat::write(&self.cov_n_d, buf);
5075 WireFormat::write(&self.cov_e_e, buf);
5076 WireFormat::write(&self.cov_e_d, buf);
5077 WireFormat::write(&self.cov_d_d, buf);
5078 WireFormat::write(&self.n_sats, buf);
5079 WireFormat::write(&self.flags, buf);
5080 }
5081 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
5082 MsgPosLlhCov {
5083 sender_id: None,
5084 tow: WireFormat::parse_unchecked(buf),
5085 lat: WireFormat::parse_unchecked(buf),
5086 lon: WireFormat::parse_unchecked(buf),
5087 height: WireFormat::parse_unchecked(buf),
5088 cov_n_n: WireFormat::parse_unchecked(buf),
5089 cov_n_e: WireFormat::parse_unchecked(buf),
5090 cov_n_d: WireFormat::parse_unchecked(buf),
5091 cov_e_e: WireFormat::parse_unchecked(buf),
5092 cov_e_d: WireFormat::parse_unchecked(buf),
5093 cov_d_d: WireFormat::parse_unchecked(buf),
5094 n_sats: WireFormat::parse_unchecked(buf),
5095 flags: WireFormat::parse_unchecked(buf),
5096 }
5097 }
5098 }
5099
5100 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5102 pub enum TypeOfReportedTow {
5103 TimeOfMeasurement = 0,
5105
5106 Other = 1,
5108 }
5109
5110 impl std::fmt::Display for TypeOfReportedTow {
5111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5112 match self {
5113 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
5114 TypeOfReportedTow::Other => f.write_str("Other"),
5115 }
5116 }
5117 }
5118
5119 impl TryFrom<u8> for TypeOfReportedTow {
5120 type Error = u8;
5121 fn try_from(i: u8) -> Result<Self, u8> {
5122 match i {
5123 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
5124 1 => Ok(TypeOfReportedTow::Other),
5125 i => Err(i),
5126 }
5127 }
5128 }
5129
5130 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5132 pub enum InertialNavigationMode {
5133 None = 0,
5135
5136 InsUsed = 1,
5138 }
5139
5140 impl std::fmt::Display for InertialNavigationMode {
5141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5142 match self {
5143 InertialNavigationMode::None => f.write_str("None"),
5144 InertialNavigationMode::InsUsed => f.write_str("INS used"),
5145 }
5146 }
5147 }
5148
5149 impl TryFrom<u8> for InertialNavigationMode {
5150 type Error = u8;
5151 fn try_from(i: u8) -> Result<Self, u8> {
5152 match i {
5153 0 => Ok(InertialNavigationMode::None),
5154 1 => Ok(InertialNavigationMode::InsUsed),
5155 i => Err(i),
5156 }
5157 }
5158 }
5159
5160 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5162 pub enum FixMode {
5163 Invalid = 0,
5165
5166 SinglePointPosition = 1,
5168
5169 DifferentialGnss = 2,
5171
5172 FloatRtk = 3,
5174
5175 FixedRtk = 4,
5177
5178 DeadReckoning = 5,
5180
5181 SbasPosition = 6,
5183 }
5184
5185 impl std::fmt::Display for FixMode {
5186 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5187 match self {
5188 FixMode::Invalid => f.write_str("Invalid"),
5189 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
5190 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
5191 FixMode::FloatRtk => f.write_str("Float RTK"),
5192 FixMode::FixedRtk => f.write_str("Fixed RTK"),
5193 FixMode::DeadReckoning => f.write_str("Dead Reckoning"),
5194 FixMode::SbasPosition => f.write_str("SBAS Position"),
5195 }
5196 }
5197 }
5198
5199 impl TryFrom<u8> for FixMode {
5200 type Error = u8;
5201 fn try_from(i: u8) -> Result<Self, u8> {
5202 match i {
5203 0 => Ok(FixMode::Invalid),
5204 1 => Ok(FixMode::SinglePointPosition),
5205 2 => Ok(FixMode::DifferentialGnss),
5206 3 => Ok(FixMode::FloatRtk),
5207 4 => Ok(FixMode::FixedRtk),
5208 5 => Ok(FixMode::DeadReckoning),
5209 6 => Ok(FixMode::SbasPosition),
5210 i => Err(i),
5211 }
5212 }
5213 }
5214}
5215
5216pub mod msg_pos_llh_cov_gnss {
5217 #![allow(unused_imports)]
5218
5219 use super::*;
5220 use crate::messages::lib::*;
5221
5222 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5237 #[allow(clippy::derive_partial_eq_without_eq)]
5238 #[derive(Debug, PartialEq, Clone)]
5239 pub struct MsgPosLlhCovGnss {
5240 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
5242 pub sender_id: Option<u16>,
5243 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
5245 pub tow: u32,
5246 #[cfg_attr(feature = "serde", serde(rename = "lat"))]
5248 pub lat: f64,
5249 #[cfg_attr(feature = "serde", serde(rename = "lon"))]
5251 pub lon: f64,
5252 #[cfg_attr(feature = "serde", serde(rename = "height"))]
5254 pub height: f64,
5255 #[cfg_attr(feature = "serde", serde(rename = "cov_n_n"))]
5257 pub cov_n_n: f32,
5258 #[cfg_attr(feature = "serde", serde(rename = "cov_n_e"))]
5260 pub cov_n_e: f32,
5261 #[cfg_attr(feature = "serde", serde(rename = "cov_n_d"))]
5263 pub cov_n_d: f32,
5264 #[cfg_attr(feature = "serde", serde(rename = "cov_e_e"))]
5266 pub cov_e_e: f32,
5267 #[cfg_attr(feature = "serde", serde(rename = "cov_e_d"))]
5269 pub cov_e_d: f32,
5270 #[cfg_attr(feature = "serde", serde(rename = "cov_d_d"))]
5272 pub cov_d_d: f32,
5273 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
5275 pub n_sats: u8,
5276 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
5278 pub flags: u8,
5279 }
5280
5281 impl MsgPosLlhCovGnss {
5282 pub fn fix_mode(&self) -> Result<FixMode, u8> {
5288 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
5289 }
5290
5291 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
5293 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
5294 }
5295 }
5296
5297 impl ConcreteMessage for MsgPosLlhCovGnss {
5298 const MESSAGE_TYPE: u16 = 561;
5299 const MESSAGE_NAME: &'static str = "MSG_POS_LLH_COV_GNSS";
5300 }
5301
5302 impl SbpMessage for MsgPosLlhCovGnss {
5303 fn message_name(&self) -> &'static str {
5304 <Self as ConcreteMessage>::MESSAGE_NAME
5305 }
5306 fn message_type(&self) -> Option<u16> {
5307 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
5308 }
5309 fn sender_id(&self) -> Option<u16> {
5310 self.sender_id
5311 }
5312 fn set_sender_id(&mut self, new_id: u16) {
5313 self.sender_id = Some(new_id);
5314 }
5315 fn encoded_len(&self) -> usize {
5316 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
5317 }
5318 fn is_valid(&self) -> bool {
5319 true
5320 }
5321 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
5322 Ok(self)
5323 }
5324
5325 #[cfg(feature = "swiftnav")]
5326 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
5327 let tow_s = (self.tow as f64) / 1000.0;
5328 let gps_time = match time::GpsTime::new(0, tow_s) {
5329 Ok(gps_time) => gps_time.tow(),
5330 Err(e) => return Some(Err(e.into())),
5331 };
5332 Some(Ok(time::MessageTime::Rover(gps_time.into())))
5333 }
5334 }
5335
5336 impl FriendlyName for MsgPosLlhCovGnss {
5337 fn friendly_name() -> &'static str {
5338 "POS LLH COV GNSS-only"
5339 }
5340 }
5341
5342 impl TryFrom<Sbp> for MsgPosLlhCovGnss {
5343 type Error = TryFromSbpError;
5344 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
5345 match msg {
5346 Sbp::MsgPosLlhCovGnss(m) => Ok(m),
5347 _ => Err(TryFromSbpError(msg)),
5348 }
5349 }
5350 }
5351
5352 impl WireFormat for MsgPosLlhCovGnss {
5353 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
5354 + <f64 as WireFormat>::MIN_LEN
5355 + <f64 as WireFormat>::MIN_LEN
5356 + <f64 as WireFormat>::MIN_LEN
5357 + <f32 as WireFormat>::MIN_LEN
5358 + <f32 as WireFormat>::MIN_LEN
5359 + <f32 as WireFormat>::MIN_LEN
5360 + <f32 as WireFormat>::MIN_LEN
5361 + <f32 as WireFormat>::MIN_LEN
5362 + <f32 as WireFormat>::MIN_LEN
5363 + <u8 as WireFormat>::MIN_LEN
5364 + <u8 as WireFormat>::MIN_LEN;
5365 fn len(&self) -> usize {
5366 WireFormat::len(&self.tow)
5367 + WireFormat::len(&self.lat)
5368 + WireFormat::len(&self.lon)
5369 + WireFormat::len(&self.height)
5370 + WireFormat::len(&self.cov_n_n)
5371 + WireFormat::len(&self.cov_n_e)
5372 + WireFormat::len(&self.cov_n_d)
5373 + WireFormat::len(&self.cov_e_e)
5374 + WireFormat::len(&self.cov_e_d)
5375 + WireFormat::len(&self.cov_d_d)
5376 + WireFormat::len(&self.n_sats)
5377 + WireFormat::len(&self.flags)
5378 }
5379 fn write<B: BufMut>(&self, buf: &mut B) {
5380 WireFormat::write(&self.tow, buf);
5381 WireFormat::write(&self.lat, buf);
5382 WireFormat::write(&self.lon, buf);
5383 WireFormat::write(&self.height, buf);
5384 WireFormat::write(&self.cov_n_n, buf);
5385 WireFormat::write(&self.cov_n_e, buf);
5386 WireFormat::write(&self.cov_n_d, buf);
5387 WireFormat::write(&self.cov_e_e, buf);
5388 WireFormat::write(&self.cov_e_d, buf);
5389 WireFormat::write(&self.cov_d_d, buf);
5390 WireFormat::write(&self.n_sats, buf);
5391 WireFormat::write(&self.flags, buf);
5392 }
5393 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
5394 MsgPosLlhCovGnss {
5395 sender_id: None,
5396 tow: WireFormat::parse_unchecked(buf),
5397 lat: WireFormat::parse_unchecked(buf),
5398 lon: WireFormat::parse_unchecked(buf),
5399 height: WireFormat::parse_unchecked(buf),
5400 cov_n_n: WireFormat::parse_unchecked(buf),
5401 cov_n_e: WireFormat::parse_unchecked(buf),
5402 cov_n_d: WireFormat::parse_unchecked(buf),
5403 cov_e_e: WireFormat::parse_unchecked(buf),
5404 cov_e_d: WireFormat::parse_unchecked(buf),
5405 cov_d_d: WireFormat::parse_unchecked(buf),
5406 n_sats: WireFormat::parse_unchecked(buf),
5407 flags: WireFormat::parse_unchecked(buf),
5408 }
5409 }
5410 }
5411
5412 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5414 pub enum FixMode {
5415 Invalid = 0,
5417
5418 SinglePointPosition = 1,
5420
5421 DifferentialGnss = 2,
5423
5424 FloatRtk = 3,
5426
5427 FixedRtk = 4,
5429
5430 DeadReckoning = 5,
5432
5433 SbasPosition = 6,
5435 }
5436
5437 impl std::fmt::Display for FixMode {
5438 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5439 match self {
5440 FixMode::Invalid => f.write_str("Invalid"),
5441 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
5442 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
5443 FixMode::FloatRtk => f.write_str("Float RTK"),
5444 FixMode::FixedRtk => f.write_str("Fixed RTK"),
5445 FixMode::DeadReckoning => f.write_str("Dead Reckoning"),
5446 FixMode::SbasPosition => f.write_str("SBAS Position"),
5447 }
5448 }
5449 }
5450
5451 impl TryFrom<u8> for FixMode {
5452 type Error = u8;
5453 fn try_from(i: u8) -> Result<Self, u8> {
5454 match i {
5455 0 => Ok(FixMode::Invalid),
5456 1 => Ok(FixMode::SinglePointPosition),
5457 2 => Ok(FixMode::DifferentialGnss),
5458 3 => Ok(FixMode::FloatRtk),
5459 4 => Ok(FixMode::FixedRtk),
5460 5 => Ok(FixMode::DeadReckoning),
5461 6 => Ok(FixMode::SbasPosition),
5462 i => Err(i),
5463 }
5464 }
5465 }
5466}
5467
5468pub mod msg_pos_llh_dep_a {
5469 #![allow(unused_imports)]
5470
5471 use super::*;
5472 use crate::messages::lib::*;
5473
5474 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5479 #[allow(clippy::derive_partial_eq_without_eq)]
5480 #[derive(Debug, PartialEq, Clone)]
5481 pub struct MsgPosLlhDepA {
5482 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
5484 pub sender_id: Option<u16>,
5485 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
5487 pub tow: u32,
5488 #[cfg_attr(feature = "serde", serde(rename = "lat"))]
5490 pub lat: f64,
5491 #[cfg_attr(feature = "serde", serde(rename = "lon"))]
5493 pub lon: f64,
5494 #[cfg_attr(feature = "serde", serde(rename = "height"))]
5496 pub height: f64,
5497 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
5499 pub h_accuracy: u16,
5500 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
5502 pub v_accuracy: u16,
5503 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
5505 pub n_sats: u8,
5506 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
5508 pub flags: u8,
5509 }
5510
5511 impl MsgPosLlhDepA {
5512 pub fn raim_repair_flag(&self) -> Result<RaimRepairFlag, u8> {
5518 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
5519 }
5520
5521 pub fn set_raim_repair_flag(&mut self, raim_repair_flag: RaimRepairFlag) {
5523 set_bit_range!(&mut self.flags, raim_repair_flag, u8, u8, 5, 5);
5524 }
5525
5526 pub fn raim_availability_flag(&self) -> Result<RaimAvailabilityFlag, u8> {
5532 get_bit_range!(self.flags, u8, u8, 4, 4).try_into()
5533 }
5534
5535 pub fn set_raim_availability_flag(&mut self, raim_availability_flag: RaimAvailabilityFlag) {
5537 set_bit_range!(&mut self.flags, raim_availability_flag, u8, u8, 4, 4);
5538 }
5539
5540 pub fn height_mode(&self) -> Result<HeightMode, u8> {
5546 get_bit_range!(self.flags, u8, u8, 3, 3).try_into()
5547 }
5548
5549 pub fn set_height_mode(&mut self, height_mode: HeightMode) {
5551 set_bit_range!(&mut self.flags, height_mode, u8, u8, 3, 3);
5552 }
5553
5554 pub fn fix_mode(&self) -> Result<FixMode, u8> {
5560 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
5561 }
5562
5563 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
5565 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
5566 }
5567 }
5568
5569 impl ConcreteMessage for MsgPosLlhDepA {
5570 const MESSAGE_TYPE: u16 = 513;
5571 const MESSAGE_NAME: &'static str = "MSG_POS_LLH_DEP_A";
5572 }
5573
5574 impl SbpMessage for MsgPosLlhDepA {
5575 fn message_name(&self) -> &'static str {
5576 <Self as ConcreteMessage>::MESSAGE_NAME
5577 }
5578 fn message_type(&self) -> Option<u16> {
5579 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
5580 }
5581 fn sender_id(&self) -> Option<u16> {
5582 self.sender_id
5583 }
5584 fn set_sender_id(&mut self, new_id: u16) {
5585 self.sender_id = Some(new_id);
5586 }
5587 fn encoded_len(&self) -> usize {
5588 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
5589 }
5590 fn is_valid(&self) -> bool {
5591 true
5592 }
5593 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
5594 Ok(self)
5595 }
5596
5597 #[cfg(feature = "swiftnav")]
5598 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
5599 let tow_s = (self.tow as f64) / 1000.0;
5600 let gps_time = match time::GpsTime::new(0, tow_s) {
5601 Ok(gps_time) => gps_time.tow(),
5602 Err(e) => return Some(Err(e.into())),
5603 };
5604 Some(Ok(time::MessageTime::Rover(gps_time.into())))
5605 }
5606 }
5607
5608 impl FriendlyName for MsgPosLlhDepA {
5609 fn friendly_name() -> &'static str {
5610 "POS LLH DEP A"
5611 }
5612 }
5613
5614 impl TryFrom<Sbp> for MsgPosLlhDepA {
5615 type Error = TryFromSbpError;
5616 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
5617 match msg {
5618 Sbp::MsgPosLlhDepA(m) => Ok(m),
5619 _ => Err(TryFromSbpError(msg)),
5620 }
5621 }
5622 }
5623
5624 impl WireFormat for MsgPosLlhDepA {
5625 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
5626 + <f64 as WireFormat>::MIN_LEN
5627 + <f64 as WireFormat>::MIN_LEN
5628 + <f64 as WireFormat>::MIN_LEN
5629 + <u16 as WireFormat>::MIN_LEN
5630 + <u16 as WireFormat>::MIN_LEN
5631 + <u8 as WireFormat>::MIN_LEN
5632 + <u8 as WireFormat>::MIN_LEN;
5633 fn len(&self) -> usize {
5634 WireFormat::len(&self.tow)
5635 + WireFormat::len(&self.lat)
5636 + WireFormat::len(&self.lon)
5637 + WireFormat::len(&self.height)
5638 + WireFormat::len(&self.h_accuracy)
5639 + WireFormat::len(&self.v_accuracy)
5640 + WireFormat::len(&self.n_sats)
5641 + WireFormat::len(&self.flags)
5642 }
5643 fn write<B: BufMut>(&self, buf: &mut B) {
5644 WireFormat::write(&self.tow, buf);
5645 WireFormat::write(&self.lat, buf);
5646 WireFormat::write(&self.lon, buf);
5647 WireFormat::write(&self.height, buf);
5648 WireFormat::write(&self.h_accuracy, buf);
5649 WireFormat::write(&self.v_accuracy, buf);
5650 WireFormat::write(&self.n_sats, buf);
5651 WireFormat::write(&self.flags, buf);
5652 }
5653 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
5654 MsgPosLlhDepA {
5655 sender_id: None,
5656 tow: WireFormat::parse_unchecked(buf),
5657 lat: WireFormat::parse_unchecked(buf),
5658 lon: WireFormat::parse_unchecked(buf),
5659 height: WireFormat::parse_unchecked(buf),
5660 h_accuracy: WireFormat::parse_unchecked(buf),
5661 v_accuracy: WireFormat::parse_unchecked(buf),
5662 n_sats: WireFormat::parse_unchecked(buf),
5663 flags: WireFormat::parse_unchecked(buf),
5664 }
5665 }
5666 }
5667
5668 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5670 pub enum RaimRepairFlag {
5671 NoRepair = 0,
5673
5674 SolutionCameFromRaimRepair = 1,
5676 }
5677
5678 impl std::fmt::Display for RaimRepairFlag {
5679 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5680 match self {
5681 RaimRepairFlag::NoRepair => f.write_str("No repair"),
5682 RaimRepairFlag::SolutionCameFromRaimRepair => {
5683 f.write_str("Solution came from RAIM repair")
5684 }
5685 }
5686 }
5687 }
5688
5689 impl TryFrom<u8> for RaimRepairFlag {
5690 type Error = u8;
5691 fn try_from(i: u8) -> Result<Self, u8> {
5692 match i {
5693 0 => Ok(RaimRepairFlag::NoRepair),
5694 1 => Ok(RaimRepairFlag::SolutionCameFromRaimRepair),
5695 i => Err(i),
5696 }
5697 }
5698 }
5699
5700 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5702 pub enum RaimAvailabilityFlag {
5703 RaimCheckWasExplicitlyDisabledOrUnavailable = 0,
5705
5706 RaimCheckWasAvailable = 1,
5708 }
5709
5710 impl std::fmt::Display for RaimAvailabilityFlag {
5711 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5712 match self {
5713 RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable => {
5714 f.write_str("RAIM check was explicitly disabled or unavailable")
5715 }
5716 RaimAvailabilityFlag::RaimCheckWasAvailable => {
5717 f.write_str("RAIM check was available")
5718 }
5719 }
5720 }
5721 }
5722
5723 impl TryFrom<u8> for RaimAvailabilityFlag {
5724 type Error = u8;
5725 fn try_from(i: u8) -> Result<Self, u8> {
5726 match i {
5727 0 => Ok(RaimAvailabilityFlag::RaimCheckWasExplicitlyDisabledOrUnavailable),
5728 1 => Ok(RaimAvailabilityFlag::RaimCheckWasAvailable),
5729 i => Err(i),
5730 }
5731 }
5732 }
5733
5734 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5736 pub enum HeightMode {
5737 HeightAboveWgs84Ellipsoid = 0,
5739
5740 HeightAboveMeanSeaLevel = 1,
5742 }
5743
5744 impl std::fmt::Display for HeightMode {
5745 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5746 match self {
5747 HeightMode::HeightAboveWgs84Ellipsoid => {
5748 f.write_str("Height above WGS84 ellipsoid")
5749 }
5750 HeightMode::HeightAboveMeanSeaLevel => f.write_str("Height above mean sea level"),
5751 }
5752 }
5753 }
5754
5755 impl TryFrom<u8> for HeightMode {
5756 type Error = u8;
5757 fn try_from(i: u8) -> Result<Self, u8> {
5758 match i {
5759 0 => Ok(HeightMode::HeightAboveWgs84Ellipsoid),
5760 1 => Ok(HeightMode::HeightAboveMeanSeaLevel),
5761 i => Err(i),
5762 }
5763 }
5764 }
5765
5766 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5768 pub enum FixMode {
5769 SinglePointPositioning = 0,
5771
5772 FixedRtk = 1,
5774
5775 FloatRtk = 2,
5777 }
5778
5779 impl std::fmt::Display for FixMode {
5780 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5781 match self {
5782 FixMode::SinglePointPositioning => f.write_str("Single Point Positioning (SPP)"),
5783 FixMode::FixedRtk => f.write_str("Fixed RTK"),
5784 FixMode::FloatRtk => f.write_str("Float RTK"),
5785 }
5786 }
5787 }
5788
5789 impl TryFrom<u8> for FixMode {
5790 type Error = u8;
5791 fn try_from(i: u8) -> Result<Self, u8> {
5792 match i {
5793 0 => Ok(FixMode::SinglePointPositioning),
5794 1 => Ok(FixMode::FixedRtk),
5795 2 => Ok(FixMode::FloatRtk),
5796 i => Err(i),
5797 }
5798 }
5799 }
5800}
5801
5802pub mod msg_pos_llh_gnss {
5803 #![allow(unused_imports)]
5804
5805 use super::*;
5806 use crate::messages::lib::*;
5807
5808 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5822 #[allow(clippy::derive_partial_eq_without_eq)]
5823 #[derive(Debug, PartialEq, Clone)]
5824 pub struct MsgPosLlhGnss {
5825 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
5827 pub sender_id: Option<u16>,
5828 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
5830 pub tow: u32,
5831 #[cfg_attr(feature = "serde", serde(rename = "lat"))]
5833 pub lat: f64,
5834 #[cfg_attr(feature = "serde", serde(rename = "lon"))]
5836 pub lon: f64,
5837 #[cfg_attr(feature = "serde", serde(rename = "height"))]
5839 pub height: f64,
5840 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
5842 pub h_accuracy: u16,
5843 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
5845 pub v_accuracy: u16,
5846 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
5848 pub n_sats: u8,
5849 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
5851 pub flags: u8,
5852 }
5853
5854 impl MsgPosLlhGnss {
5855 pub fn fix_mode(&self) -> Result<FixMode, u8> {
5861 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
5862 }
5863
5864 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
5866 set_bit_range!(&mut self.flags, fix_mode, u8, u8, 2, 0);
5867 }
5868 }
5869
5870 impl ConcreteMessage for MsgPosLlhGnss {
5871 const MESSAGE_TYPE: u16 = 554;
5872 const MESSAGE_NAME: &'static str = "MSG_POS_LLH_GNSS";
5873 }
5874
5875 impl SbpMessage for MsgPosLlhGnss {
5876 fn message_name(&self) -> &'static str {
5877 <Self as ConcreteMessage>::MESSAGE_NAME
5878 }
5879 fn message_type(&self) -> Option<u16> {
5880 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
5881 }
5882 fn sender_id(&self) -> Option<u16> {
5883 self.sender_id
5884 }
5885 fn set_sender_id(&mut self, new_id: u16) {
5886 self.sender_id = Some(new_id);
5887 }
5888 fn encoded_len(&self) -> usize {
5889 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
5890 }
5891 fn is_valid(&self) -> bool {
5892 true
5893 }
5894 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
5895 Ok(self)
5896 }
5897
5898 #[cfg(feature = "swiftnav")]
5899 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
5900 let tow_s = (self.tow as f64) / 1000.0;
5901 let gps_time = match time::GpsTime::new(0, tow_s) {
5902 Ok(gps_time) => gps_time.tow(),
5903 Err(e) => return Some(Err(e.into())),
5904 };
5905 Some(Ok(time::MessageTime::Rover(gps_time.into())))
5906 }
5907 }
5908
5909 impl FriendlyName for MsgPosLlhGnss {
5910 fn friendly_name() -> &'static str {
5911 "POS LLH GNSS-only"
5912 }
5913 }
5914
5915 impl TryFrom<Sbp> for MsgPosLlhGnss {
5916 type Error = TryFromSbpError;
5917 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
5918 match msg {
5919 Sbp::MsgPosLlhGnss(m) => Ok(m),
5920 _ => Err(TryFromSbpError(msg)),
5921 }
5922 }
5923 }
5924
5925 impl WireFormat for MsgPosLlhGnss {
5926 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
5927 + <f64 as WireFormat>::MIN_LEN
5928 + <f64 as WireFormat>::MIN_LEN
5929 + <f64 as WireFormat>::MIN_LEN
5930 + <u16 as WireFormat>::MIN_LEN
5931 + <u16 as WireFormat>::MIN_LEN
5932 + <u8 as WireFormat>::MIN_LEN
5933 + <u8 as WireFormat>::MIN_LEN;
5934 fn len(&self) -> usize {
5935 WireFormat::len(&self.tow)
5936 + WireFormat::len(&self.lat)
5937 + WireFormat::len(&self.lon)
5938 + WireFormat::len(&self.height)
5939 + WireFormat::len(&self.h_accuracy)
5940 + WireFormat::len(&self.v_accuracy)
5941 + WireFormat::len(&self.n_sats)
5942 + WireFormat::len(&self.flags)
5943 }
5944 fn write<B: BufMut>(&self, buf: &mut B) {
5945 WireFormat::write(&self.tow, buf);
5946 WireFormat::write(&self.lat, buf);
5947 WireFormat::write(&self.lon, buf);
5948 WireFormat::write(&self.height, buf);
5949 WireFormat::write(&self.h_accuracy, buf);
5950 WireFormat::write(&self.v_accuracy, buf);
5951 WireFormat::write(&self.n_sats, buf);
5952 WireFormat::write(&self.flags, buf);
5953 }
5954 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
5955 MsgPosLlhGnss {
5956 sender_id: None,
5957 tow: WireFormat::parse_unchecked(buf),
5958 lat: WireFormat::parse_unchecked(buf),
5959 lon: WireFormat::parse_unchecked(buf),
5960 height: WireFormat::parse_unchecked(buf),
5961 h_accuracy: WireFormat::parse_unchecked(buf),
5962 v_accuracy: WireFormat::parse_unchecked(buf),
5963 n_sats: WireFormat::parse_unchecked(buf),
5964 flags: WireFormat::parse_unchecked(buf),
5965 }
5966 }
5967 }
5968
5969 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5971 pub enum FixMode {
5972 Invalid = 0,
5974
5975 SinglePointPosition = 1,
5977
5978 DifferentialGnss = 2,
5980
5981 FloatRtk = 3,
5983
5984 FixedRtk = 4,
5986
5987 SbasPosition = 6,
5989 }
5990
5991 impl std::fmt::Display for FixMode {
5992 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5993 match self {
5994 FixMode::Invalid => f.write_str("Invalid"),
5995 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
5996 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
5997 FixMode::FloatRtk => f.write_str("Float RTK"),
5998 FixMode::FixedRtk => f.write_str("Fixed RTK"),
5999 FixMode::SbasPosition => f.write_str("SBAS Position"),
6000 }
6001 }
6002 }
6003
6004 impl TryFrom<u8> for FixMode {
6005 type Error = u8;
6006 fn try_from(i: u8) -> Result<Self, u8> {
6007 match i {
6008 0 => Ok(FixMode::Invalid),
6009 1 => Ok(FixMode::SinglePointPosition),
6010 2 => Ok(FixMode::DifferentialGnss),
6011 3 => Ok(FixMode::FloatRtk),
6012 4 => Ok(FixMode::FixedRtk),
6013 6 => Ok(FixMode::SbasPosition),
6014 i => Err(i),
6015 }
6016 }
6017 }
6018}
6019
6020pub mod msg_protection_level {
6021 #![allow(unused_imports)]
6022
6023 use super::*;
6024 use crate::messages::lib::*;
6025
6026 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6033 #[allow(clippy::derive_partial_eq_without_eq)]
6034 #[derive(Debug, PartialEq, Clone)]
6035 pub struct MsgProtectionLevel {
6036 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
6038 pub sender_id: Option<u16>,
6039 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
6041 pub tow: u32,
6042 #[cfg_attr(feature = "serde", serde(rename = "wn"))]
6044 pub wn: i16,
6045 #[cfg_attr(feature = "serde", serde(rename = "hpl"))]
6047 pub hpl: u16,
6048 #[cfg_attr(feature = "serde", serde(rename = "vpl"))]
6050 pub vpl: u16,
6051 #[cfg_attr(feature = "serde", serde(rename = "atpl"))]
6053 pub atpl: u16,
6054 #[cfg_attr(feature = "serde", serde(rename = "ctpl"))]
6056 pub ctpl: u16,
6057 #[cfg_attr(feature = "serde", serde(rename = "hvpl"))]
6060 pub hvpl: u16,
6061 #[cfg_attr(feature = "serde", serde(rename = "vvpl"))]
6064 pub vvpl: u16,
6065 #[cfg_attr(feature = "serde", serde(rename = "hopl"))]
6067 pub hopl: u16,
6068 #[cfg_attr(feature = "serde", serde(rename = "popl"))]
6070 pub popl: u16,
6071 #[cfg_attr(feature = "serde", serde(rename = "ropl"))]
6073 pub ropl: u16,
6074 #[cfg_attr(feature = "serde", serde(rename = "lat"))]
6076 pub lat: f64,
6077 #[cfg_attr(feature = "serde", serde(rename = "lon"))]
6079 pub lon: f64,
6080 #[cfg_attr(feature = "serde", serde(rename = "height"))]
6082 pub height: f64,
6083 #[cfg_attr(feature = "serde", serde(rename = "v_x"))]
6085 pub v_x: i32,
6086 #[cfg_attr(feature = "serde", serde(rename = "v_y"))]
6088 pub v_y: i32,
6089 #[cfg_attr(feature = "serde", serde(rename = "v_z"))]
6091 pub v_z: i32,
6092 #[cfg_attr(feature = "serde", serde(rename = "roll"))]
6094 pub roll: i32,
6095 #[cfg_attr(feature = "serde", serde(rename = "pitch"))]
6097 pub pitch: i32,
6098 #[cfg_attr(feature = "serde", serde(rename = "heading"))]
6100 pub heading: i32,
6101 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
6103 pub flags: u32,
6104 }
6105
6106 impl MsgProtectionLevel {
6107 pub fn target_integrity_risk_tir_level(&self) -> u8 {
6109 get_bit_range!(self.flags, u32, u8, 2, 0)
6110 }
6111
6112 pub fn set_target_integrity_risk_tir_level(&mut self, target_integrity_risk_tir_level: u8) {
6114 set_bit_range!(
6115 &mut self.flags,
6116 target_integrity_risk_tir_level,
6117 u32,
6118 u8,
6119 2,
6120 0
6121 );
6122 }
6123
6124 pub fn fix_mode(&self) -> Result<FixMode, u8> {
6130 get_bit_range!(self.flags, u32, u8, 17, 15).try_into()
6131 }
6132
6133 pub fn set_fix_mode(&mut self, fix_mode: FixMode) {
6135 set_bit_range!(&mut self.flags, fix_mode, u32, u8, 17, 15);
6136 }
6137
6138 pub fn inertial_navigation_mode(&self) -> Result<InertialNavigationMode, u8> {
6144 get_bit_range!(self.flags, u32, u8, 19, 18).try_into()
6145 }
6146
6147 pub fn set_inertial_navigation_mode(
6149 &mut self,
6150 inertial_navigation_mode: InertialNavigationMode,
6151 ) {
6152 set_bit_range!(&mut self.flags, inertial_navigation_mode, u32, u8, 19, 18);
6153 }
6154
6155 pub fn time_status(&self) -> Result<TimeStatus, u8> {
6161 get_bit_range!(self.flags, u32, u8, 20, 20).try_into()
6162 }
6163
6164 pub fn set_time_status(&mut self, time_status: TimeStatus) {
6166 set_bit_range!(&mut self.flags, time_status, u32, u8, 20, 20);
6167 }
6168
6169 #[allow(clippy::identity_op)]
6171 pub fn velocity_valid(&self) -> bool {
6172 ((self.flags >> 21) & 1) == 1
6173 }
6174
6175 pub fn set_velocity_valid(&mut self, velocity_valid: bool) {
6177 self.flags ^= (!(velocity_valid as u32)) & (1 << 21)
6178 }
6179
6180 #[allow(clippy::identity_op)]
6182 pub fn attitude_valid(&self) -> bool {
6183 ((self.flags >> 22) & 1) == 1
6184 }
6185
6186 pub fn set_attitude_valid(&mut self, attitude_valid: bool) {
6188 self.flags ^= (!(attitude_valid as u32)) & (1 << 22)
6189 }
6190
6191 #[allow(clippy::identity_op)]
6193 pub fn safe_state_hpl(&self) -> bool {
6194 ((self.flags >> 23) & 1) == 1
6195 }
6196
6197 pub fn set_safe_state_hpl(&mut self, safe_state_hpl: bool) {
6199 self.flags ^= (!(safe_state_hpl as u32)) & (1 << 23)
6200 }
6201
6202 #[allow(clippy::identity_op)]
6204 pub fn safe_state_vpl(&self) -> bool {
6205 ((self.flags >> 24) & 1) == 1
6206 }
6207
6208 pub fn set_safe_state_vpl(&mut self, safe_state_vpl: bool) {
6210 self.flags ^= (!(safe_state_vpl as u32)) & (1 << 24)
6211 }
6212
6213 #[allow(clippy::identity_op)]
6215 pub fn safe_state_atpl(&self) -> bool {
6216 ((self.flags >> 25) & 1) == 1
6217 }
6218
6219 pub fn set_safe_state_atpl(&mut self, safe_state_atpl: bool) {
6221 self.flags ^= (!(safe_state_atpl as u32)) & (1 << 25)
6222 }
6223
6224 #[allow(clippy::identity_op)]
6226 pub fn safe_state_ctpl(&self) -> bool {
6227 ((self.flags >> 26) & 1) == 1
6228 }
6229
6230 pub fn set_safe_state_ctpl(&mut self, safe_state_ctpl: bool) {
6232 self.flags ^= (!(safe_state_ctpl as u32)) & (1 << 26)
6233 }
6234
6235 #[allow(clippy::identity_op)]
6237 pub fn safe_state_hvpl(&self) -> bool {
6238 ((self.flags >> 27) & 1) == 1
6239 }
6240
6241 pub fn set_safe_state_hvpl(&mut self, safe_state_hvpl: bool) {
6243 self.flags ^= (!(safe_state_hvpl as u32)) & (1 << 27)
6244 }
6245
6246 #[allow(clippy::identity_op)]
6248 pub fn safe_state_vvpl(&self) -> bool {
6249 ((self.flags >> 28) & 1) == 1
6250 }
6251
6252 pub fn set_safe_state_vvpl(&mut self, safe_state_vvpl: bool) {
6254 self.flags ^= (!(safe_state_vvpl as u32)) & (1 << 28)
6255 }
6256
6257 #[allow(clippy::identity_op)]
6259 pub fn safe_state_hopl(&self) -> bool {
6260 ((self.flags >> 29) & 1) == 1
6261 }
6262
6263 pub fn set_safe_state_hopl(&mut self, safe_state_hopl: bool) {
6265 self.flags ^= (!(safe_state_hopl as u32)) & (1 << 29)
6266 }
6267
6268 #[allow(clippy::identity_op)]
6270 pub fn safe_state_popl(&self) -> bool {
6271 ((self.flags >> 30) & 1) == 1
6272 }
6273
6274 pub fn set_safe_state_popl(&mut self, safe_state_popl: bool) {
6276 self.flags ^= (!(safe_state_popl as u32)) & (1 << 30)
6277 }
6278
6279 #[allow(clippy::identity_op)]
6281 pub fn safe_state_ropl(&self) -> bool {
6282 ((self.flags >> 31) & 1) == 1
6283 }
6284
6285 pub fn set_safe_state_ropl(&mut self, safe_state_ropl: bool) {
6287 self.flags ^= (!(safe_state_ropl as u32)) & (1 << 31)
6288 }
6289 }
6290
6291 impl ConcreteMessage for MsgProtectionLevel {
6292 const MESSAGE_TYPE: u16 = 535;
6293 const MESSAGE_NAME: &'static str = "MSG_PROTECTION_LEVEL";
6294 }
6295
6296 impl SbpMessage for MsgProtectionLevel {
6297 fn message_name(&self) -> &'static str {
6298 <Self as ConcreteMessage>::MESSAGE_NAME
6299 }
6300 fn message_type(&self) -> Option<u16> {
6301 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
6302 }
6303 fn sender_id(&self) -> Option<u16> {
6304 self.sender_id
6305 }
6306 fn set_sender_id(&mut self, new_id: u16) {
6307 self.sender_id = Some(new_id);
6308 }
6309 fn encoded_len(&self) -> usize {
6310 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
6311 }
6312 fn is_valid(&self) -> bool {
6313 true
6314 }
6315 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
6316 Ok(self)
6317 }
6318
6319 #[cfg(feature = "swiftnav")]
6320 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
6321 let tow_s = (self.tow as f64) / 1000.0;
6322 #[allow(clippy::useless_conversion)]
6323 let wn: i16 = match self.wn.try_into() {
6324 Ok(wn) => wn,
6325 Err(e) => return Some(Err(e.into())),
6326 };
6327 let gps_time = match time::GpsTime::new(wn, tow_s) {
6328 Ok(gps_time) => gps_time,
6329 Err(e) => return Some(Err(e.into())),
6330 };
6331 Some(Ok(time::MessageTime::Rover(gps_time.into())))
6332 }
6333 }
6334
6335 impl FriendlyName for MsgProtectionLevel {
6336 fn friendly_name() -> &'static str {
6337 "PROTECTION LEVEL"
6338 }
6339 }
6340
6341 impl TryFrom<Sbp> for MsgProtectionLevel {
6342 type Error = TryFromSbpError;
6343 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
6344 match msg {
6345 Sbp::MsgProtectionLevel(m) => Ok(m),
6346 _ => Err(TryFromSbpError(msg)),
6347 }
6348 }
6349 }
6350
6351 impl WireFormat for MsgProtectionLevel {
6352 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
6353 + <i16 as WireFormat>::MIN_LEN
6354 + <u16 as WireFormat>::MIN_LEN
6355 + <u16 as WireFormat>::MIN_LEN
6356 + <u16 as WireFormat>::MIN_LEN
6357 + <u16 as WireFormat>::MIN_LEN
6358 + <u16 as WireFormat>::MIN_LEN
6359 + <u16 as WireFormat>::MIN_LEN
6360 + <u16 as WireFormat>::MIN_LEN
6361 + <u16 as WireFormat>::MIN_LEN
6362 + <u16 as WireFormat>::MIN_LEN
6363 + <f64 as WireFormat>::MIN_LEN
6364 + <f64 as WireFormat>::MIN_LEN
6365 + <f64 as WireFormat>::MIN_LEN
6366 + <i32 as WireFormat>::MIN_LEN
6367 + <i32 as WireFormat>::MIN_LEN
6368 + <i32 as WireFormat>::MIN_LEN
6369 + <i32 as WireFormat>::MIN_LEN
6370 + <i32 as WireFormat>::MIN_LEN
6371 + <i32 as WireFormat>::MIN_LEN
6372 + <u32 as WireFormat>::MIN_LEN;
6373 fn len(&self) -> usize {
6374 WireFormat::len(&self.tow)
6375 + WireFormat::len(&self.wn)
6376 + WireFormat::len(&self.hpl)
6377 + WireFormat::len(&self.vpl)
6378 + WireFormat::len(&self.atpl)
6379 + WireFormat::len(&self.ctpl)
6380 + WireFormat::len(&self.hvpl)
6381 + WireFormat::len(&self.vvpl)
6382 + WireFormat::len(&self.hopl)
6383 + WireFormat::len(&self.popl)
6384 + WireFormat::len(&self.ropl)
6385 + WireFormat::len(&self.lat)
6386 + WireFormat::len(&self.lon)
6387 + WireFormat::len(&self.height)
6388 + WireFormat::len(&self.v_x)
6389 + WireFormat::len(&self.v_y)
6390 + WireFormat::len(&self.v_z)
6391 + WireFormat::len(&self.roll)
6392 + WireFormat::len(&self.pitch)
6393 + WireFormat::len(&self.heading)
6394 + WireFormat::len(&self.flags)
6395 }
6396 fn write<B: BufMut>(&self, buf: &mut B) {
6397 WireFormat::write(&self.tow, buf);
6398 WireFormat::write(&self.wn, buf);
6399 WireFormat::write(&self.hpl, buf);
6400 WireFormat::write(&self.vpl, buf);
6401 WireFormat::write(&self.atpl, buf);
6402 WireFormat::write(&self.ctpl, buf);
6403 WireFormat::write(&self.hvpl, buf);
6404 WireFormat::write(&self.vvpl, buf);
6405 WireFormat::write(&self.hopl, buf);
6406 WireFormat::write(&self.popl, buf);
6407 WireFormat::write(&self.ropl, buf);
6408 WireFormat::write(&self.lat, buf);
6409 WireFormat::write(&self.lon, buf);
6410 WireFormat::write(&self.height, buf);
6411 WireFormat::write(&self.v_x, buf);
6412 WireFormat::write(&self.v_y, buf);
6413 WireFormat::write(&self.v_z, buf);
6414 WireFormat::write(&self.roll, buf);
6415 WireFormat::write(&self.pitch, buf);
6416 WireFormat::write(&self.heading, buf);
6417 WireFormat::write(&self.flags, buf);
6418 }
6419 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
6420 MsgProtectionLevel {
6421 sender_id: None,
6422 tow: WireFormat::parse_unchecked(buf),
6423 wn: WireFormat::parse_unchecked(buf),
6424 hpl: WireFormat::parse_unchecked(buf),
6425 vpl: WireFormat::parse_unchecked(buf),
6426 atpl: WireFormat::parse_unchecked(buf),
6427 ctpl: WireFormat::parse_unchecked(buf),
6428 hvpl: WireFormat::parse_unchecked(buf),
6429 vvpl: WireFormat::parse_unchecked(buf),
6430 hopl: WireFormat::parse_unchecked(buf),
6431 popl: WireFormat::parse_unchecked(buf),
6432 ropl: WireFormat::parse_unchecked(buf),
6433 lat: WireFormat::parse_unchecked(buf),
6434 lon: WireFormat::parse_unchecked(buf),
6435 height: WireFormat::parse_unchecked(buf),
6436 v_x: WireFormat::parse_unchecked(buf),
6437 v_y: WireFormat::parse_unchecked(buf),
6438 v_z: WireFormat::parse_unchecked(buf),
6439 roll: WireFormat::parse_unchecked(buf),
6440 pitch: WireFormat::parse_unchecked(buf),
6441 heading: WireFormat::parse_unchecked(buf),
6442 flags: WireFormat::parse_unchecked(buf),
6443 }
6444 }
6445 }
6446
6447 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6449 pub enum FixMode {
6450 Invalid = 0,
6452
6453 SinglePointPosition = 1,
6455
6456 DifferentialGnss = 2,
6458
6459 FloatRtk = 3,
6461
6462 FixedRtk = 4,
6464
6465 DeadReckoning = 5,
6467
6468 SbasPosition = 6,
6470 }
6471
6472 impl std::fmt::Display for FixMode {
6473 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6474 match self {
6475 FixMode::Invalid => f.write_str("Invalid"),
6476 FixMode::SinglePointPosition => f.write_str("Single Point Position (SPP)"),
6477 FixMode::DifferentialGnss => f.write_str("Differential GNSS (DGNSS)"),
6478 FixMode::FloatRtk => f.write_str("Float RTK"),
6479 FixMode::FixedRtk => f.write_str("Fixed RTK"),
6480 FixMode::DeadReckoning => f.write_str("Dead Reckoning"),
6481 FixMode::SbasPosition => f.write_str("SBAS Position"),
6482 }
6483 }
6484 }
6485
6486 impl TryFrom<u8> for FixMode {
6487 type Error = u8;
6488 fn try_from(i: u8) -> Result<Self, u8> {
6489 match i {
6490 0 => Ok(FixMode::Invalid),
6491 1 => Ok(FixMode::SinglePointPosition),
6492 2 => Ok(FixMode::DifferentialGnss),
6493 3 => Ok(FixMode::FloatRtk),
6494 4 => Ok(FixMode::FixedRtk),
6495 5 => Ok(FixMode::DeadReckoning),
6496 6 => Ok(FixMode::SbasPosition),
6497 i => Err(i),
6498 }
6499 }
6500 }
6501
6502 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6504 pub enum InertialNavigationMode {
6505 None = 0,
6507
6508 InsUsed = 1,
6510 }
6511
6512 impl std::fmt::Display for InertialNavigationMode {
6513 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6514 match self {
6515 InertialNavigationMode::None => f.write_str("None"),
6516 InertialNavigationMode::InsUsed => f.write_str("INS used"),
6517 }
6518 }
6519 }
6520
6521 impl TryFrom<u8> for InertialNavigationMode {
6522 type Error = u8;
6523 fn try_from(i: u8) -> Result<Self, u8> {
6524 match i {
6525 0 => Ok(InertialNavigationMode::None),
6526 1 => Ok(InertialNavigationMode::InsUsed),
6527 i => Err(i),
6528 }
6529 }
6530 }
6531
6532 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6534 pub enum TimeStatus {
6535 GnssTimeOfValidity = 0,
6537
6538 Other = 1,
6540 }
6541
6542 impl std::fmt::Display for TimeStatus {
6543 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6544 match self {
6545 TimeStatus::GnssTimeOfValidity => f.write_str("GNSS time of validity"),
6546 TimeStatus::Other => f.write_str("Other"),
6547 }
6548 }
6549 }
6550
6551 impl TryFrom<u8> for TimeStatus {
6552 type Error = u8;
6553 fn try_from(i: u8) -> Result<Self, u8> {
6554 match i {
6555 0 => Ok(TimeStatus::GnssTimeOfValidity),
6556 1 => Ok(TimeStatus::Other),
6557 i => Err(i),
6558 }
6559 }
6560 }
6561}
6562
6563pub mod msg_protection_level_dep_a {
6564 #![allow(unused_imports)]
6565
6566 use super::*;
6567 use crate::messages::lib::*;
6568
6569 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6574 #[allow(clippy::derive_partial_eq_without_eq)]
6575 #[derive(Debug, PartialEq, Clone)]
6576 pub struct MsgProtectionLevelDepA {
6577 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
6579 pub sender_id: Option<u16>,
6580 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
6582 pub tow: u32,
6583 #[cfg_attr(feature = "serde", serde(rename = "vpl"))]
6585 pub vpl: u16,
6586 #[cfg_attr(feature = "serde", serde(rename = "hpl"))]
6588 pub hpl: u16,
6589 #[cfg_attr(feature = "serde", serde(rename = "lat"))]
6591 pub lat: f64,
6592 #[cfg_attr(feature = "serde", serde(rename = "lon"))]
6594 pub lon: f64,
6595 #[cfg_attr(feature = "serde", serde(rename = "height"))]
6597 pub height: f64,
6598 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
6600 pub flags: u8,
6601 }
6602
6603 impl MsgProtectionLevelDepA {
6604 pub fn target_integrity_risk_tir_level(&self) -> Result<TargetIntegrityRiskTirLevel, u8> {
6610 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
6611 }
6612
6613 pub fn set_target_integrity_risk_tir_level(
6615 &mut self,
6616 target_integrity_risk_tir_level: TargetIntegrityRiskTirLevel,
6617 ) {
6618 set_bit_range!(
6619 &mut self.flags,
6620 target_integrity_risk_tir_level,
6621 u8,
6622 u8,
6623 2,
6624 0
6625 );
6626 }
6627 }
6628
6629 impl ConcreteMessage for MsgProtectionLevelDepA {
6630 const MESSAGE_TYPE: u16 = 534;
6631 const MESSAGE_NAME: &'static str = "MSG_PROTECTION_LEVEL_DEP_A";
6632 }
6633
6634 impl SbpMessage for MsgProtectionLevelDepA {
6635 fn message_name(&self) -> &'static str {
6636 <Self as ConcreteMessage>::MESSAGE_NAME
6637 }
6638 fn message_type(&self) -> Option<u16> {
6639 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
6640 }
6641 fn sender_id(&self) -> Option<u16> {
6642 self.sender_id
6643 }
6644 fn set_sender_id(&mut self, new_id: u16) {
6645 self.sender_id = Some(new_id);
6646 }
6647 fn encoded_len(&self) -> usize {
6648 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
6649 }
6650 fn is_valid(&self) -> bool {
6651 true
6652 }
6653 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
6654 Ok(self)
6655 }
6656
6657 #[cfg(feature = "swiftnav")]
6658 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
6659 let tow_s = (self.tow as f64) / 1000.0;
6660 let gps_time = match time::GpsTime::new(0, tow_s) {
6661 Ok(gps_time) => gps_time.tow(),
6662 Err(e) => return Some(Err(e.into())),
6663 };
6664 Some(Ok(time::MessageTime::Rover(gps_time.into())))
6665 }
6666 }
6667
6668 impl FriendlyName for MsgProtectionLevelDepA {
6669 fn friendly_name() -> &'static str {
6670 "PROTECTION LEVEL DEP A"
6671 }
6672 }
6673
6674 impl TryFrom<Sbp> for MsgProtectionLevelDepA {
6675 type Error = TryFromSbpError;
6676 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
6677 match msg {
6678 Sbp::MsgProtectionLevelDepA(m) => Ok(m),
6679 _ => Err(TryFromSbpError(msg)),
6680 }
6681 }
6682 }
6683
6684 impl WireFormat for MsgProtectionLevelDepA {
6685 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
6686 + <u16 as WireFormat>::MIN_LEN
6687 + <u16 as WireFormat>::MIN_LEN
6688 + <f64 as WireFormat>::MIN_LEN
6689 + <f64 as WireFormat>::MIN_LEN
6690 + <f64 as WireFormat>::MIN_LEN
6691 + <u8 as WireFormat>::MIN_LEN;
6692 fn len(&self) -> usize {
6693 WireFormat::len(&self.tow)
6694 + WireFormat::len(&self.vpl)
6695 + WireFormat::len(&self.hpl)
6696 + WireFormat::len(&self.lat)
6697 + WireFormat::len(&self.lon)
6698 + WireFormat::len(&self.height)
6699 + WireFormat::len(&self.flags)
6700 }
6701 fn write<B: BufMut>(&self, buf: &mut B) {
6702 WireFormat::write(&self.tow, buf);
6703 WireFormat::write(&self.vpl, buf);
6704 WireFormat::write(&self.hpl, buf);
6705 WireFormat::write(&self.lat, buf);
6706 WireFormat::write(&self.lon, buf);
6707 WireFormat::write(&self.height, buf);
6708 WireFormat::write(&self.flags, buf);
6709 }
6710 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
6711 MsgProtectionLevelDepA {
6712 sender_id: None,
6713 tow: WireFormat::parse_unchecked(buf),
6714 vpl: WireFormat::parse_unchecked(buf),
6715 hpl: WireFormat::parse_unchecked(buf),
6716 lat: WireFormat::parse_unchecked(buf),
6717 lon: WireFormat::parse_unchecked(buf),
6718 height: WireFormat::parse_unchecked(buf),
6719 flags: WireFormat::parse_unchecked(buf),
6720 }
6721 }
6722 }
6723
6724 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6726 pub enum TargetIntegrityRiskTirLevel {
6727 SafeStateProtectionLevelShallNotBeUsedForSafetyCriticalApplication = 0,
6730
6731 TirLevel1 = 1,
6733
6734 TirLevel2 = 2,
6736
6737 TirLevel3 = 3,
6739 }
6740
6741 impl std::fmt::Display for TargetIntegrityRiskTirLevel {
6742 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6743 match self {
6744 TargetIntegrityRiskTirLevel::SafeStateProtectionLevelShallNotBeUsedForSafetyCriticalApplication => f.write_str("Safe state, protection level shall not be used for safety-critical application"),
6745 TargetIntegrityRiskTirLevel::TirLevel1 => f.write_str("TIR Level 1"),
6746 TargetIntegrityRiskTirLevel::TirLevel2 => f.write_str("TIR Level 2"),
6747 TargetIntegrityRiskTirLevel::TirLevel3 => f.write_str("TIR Level 3"),
6748 }
6749 }
6750 }
6751
6752 impl TryFrom<u8> for TargetIntegrityRiskTirLevel {
6753 type Error = u8;
6754 fn try_from(i: u8) -> Result<Self, u8> {
6755 match i {
6756 0 => Ok( TargetIntegrityRiskTirLevel :: SafeStateProtectionLevelShallNotBeUsedForSafetyCriticalApplication ),
6757 1 => Ok( TargetIntegrityRiskTirLevel :: TirLevel1 ),
6758 2 => Ok( TargetIntegrityRiskTirLevel :: TirLevel2 ),
6759 3 => Ok( TargetIntegrityRiskTirLevel :: TirLevel3 ),
6760 i => Err(i),
6761 }
6762 }
6763 }
6764}
6765
6766pub mod msg_reference_frame_param {
6767 #![allow(unused_imports)]
6768
6769 use super::*;
6770 use crate::messages::lib::*;
6771 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6773 #[allow(clippy::derive_partial_eq_without_eq)]
6774 #[derive(Debug, PartialEq, Clone)]
6775 pub struct MsgReferenceFrameParam {
6776 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
6778 pub sender_id: Option<u16>,
6779 #[cfg_attr(feature = "serde", serde(rename = "ssr_iod"))]
6781 pub ssr_iod: u8,
6782 #[cfg_attr(feature = "serde", serde(rename = "sn"))]
6784 pub sn: SbpString<[u8; 32], NullTerminated>,
6785 #[cfg_attr(feature = "serde", serde(rename = "tn"))]
6787 pub tn: SbpString<[u8; 32], NullTerminated>,
6788 #[cfg_attr(feature = "serde", serde(rename = "sin"))]
6790 pub sin: u8,
6791 #[cfg_attr(feature = "serde", serde(rename = "utn"))]
6793 pub utn: u16,
6794 #[cfg_attr(feature = "serde", serde(rename = "re_t0"))]
6797 pub re_t0: u16,
6798 #[cfg_attr(feature = "serde", serde(rename = "delta_X0"))]
6800 pub delta_x0: i32,
6801 #[cfg_attr(feature = "serde", serde(rename = "delta_Y0"))]
6803 pub delta_y0: i32,
6804 #[cfg_attr(feature = "serde", serde(rename = "delta_Z0"))]
6806 pub delta_z0: i32,
6807 #[cfg_attr(feature = "serde", serde(rename = "theta_01"))]
6809 pub theta_01: i32,
6810 #[cfg_attr(feature = "serde", serde(rename = "theta_02"))]
6812 pub theta_02: i32,
6813 #[cfg_attr(feature = "serde", serde(rename = "theta_03"))]
6815 pub theta_03: i32,
6816 #[cfg_attr(feature = "serde", serde(rename = "scale"))]
6818 pub scale: i32,
6819 #[cfg_attr(feature = "serde", serde(rename = "dot_delta_X0"))]
6821 pub dot_delta_x0: i32,
6822 #[cfg_attr(feature = "serde", serde(rename = "dot_delta_Y0"))]
6824 pub dot_delta_y0: i32,
6825 #[cfg_attr(feature = "serde", serde(rename = "dot_delta_Z0"))]
6827 pub dot_delta_z0: i32,
6828 #[cfg_attr(feature = "serde", serde(rename = "dot_theta_01"))]
6830 pub dot_theta_01: i32,
6831 #[cfg_attr(feature = "serde", serde(rename = "dot_theta_02"))]
6833 pub dot_theta_02: i32,
6834 #[cfg_attr(feature = "serde", serde(rename = "dot_theta_03"))]
6836 pub dot_theta_03: i32,
6837 #[cfg_attr(feature = "serde", serde(rename = "dot_scale"))]
6839 pub dot_scale: i16,
6840 }
6841
6842 impl ConcreteMessage for MsgReferenceFrameParam {
6843 const MESSAGE_TYPE: u16 = 580;
6844 const MESSAGE_NAME: &'static str = "MSG_REFERENCE_FRAME_PARAM";
6845 }
6846
6847 impl SbpMessage for MsgReferenceFrameParam {
6848 fn message_name(&self) -> &'static str {
6849 <Self as ConcreteMessage>::MESSAGE_NAME
6850 }
6851 fn message_type(&self) -> Option<u16> {
6852 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
6853 }
6854 fn sender_id(&self) -> Option<u16> {
6855 self.sender_id
6856 }
6857 fn set_sender_id(&mut self, new_id: u16) {
6858 self.sender_id = Some(new_id);
6859 }
6860 fn encoded_len(&self) -> usize {
6861 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
6862 }
6863 fn is_valid(&self) -> bool {
6864 true
6865 }
6866 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
6867 Ok(self)
6868 }
6869 }
6870
6871 impl FriendlyName for MsgReferenceFrameParam {
6872 fn friendly_name() -> &'static str {
6873 "REFERENCE FRAME PARAM"
6874 }
6875 }
6876
6877 impl TryFrom<Sbp> for MsgReferenceFrameParam {
6878 type Error = TryFromSbpError;
6879 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
6880 match msg {
6881 Sbp::MsgReferenceFrameParam(m) => Ok(m),
6882 _ => Err(TryFromSbpError(msg)),
6883 }
6884 }
6885 }
6886
6887 impl WireFormat for MsgReferenceFrameParam {
6888 const MIN_LEN: usize = <u8 as WireFormat>::MIN_LEN
6889 + <SbpString<[u8; 32], NullTerminated> as WireFormat>::MIN_LEN
6890 + <SbpString<[u8; 32], NullTerminated> as WireFormat>::MIN_LEN
6891 + <u8 as WireFormat>::MIN_LEN
6892 + <u16 as WireFormat>::MIN_LEN
6893 + <u16 as WireFormat>::MIN_LEN
6894 + <i32 as WireFormat>::MIN_LEN
6895 + <i32 as WireFormat>::MIN_LEN
6896 + <i32 as WireFormat>::MIN_LEN
6897 + <i32 as WireFormat>::MIN_LEN
6898 + <i32 as WireFormat>::MIN_LEN
6899 + <i32 as WireFormat>::MIN_LEN
6900 + <i32 as WireFormat>::MIN_LEN
6901 + <i32 as WireFormat>::MIN_LEN
6902 + <i32 as WireFormat>::MIN_LEN
6903 + <i32 as WireFormat>::MIN_LEN
6904 + <i32 as WireFormat>::MIN_LEN
6905 + <i32 as WireFormat>::MIN_LEN
6906 + <i32 as WireFormat>::MIN_LEN
6907 + <i16 as WireFormat>::MIN_LEN;
6908 fn len(&self) -> usize {
6909 WireFormat::len(&self.ssr_iod)
6910 + WireFormat::len(&self.sn)
6911 + WireFormat::len(&self.tn)
6912 + WireFormat::len(&self.sin)
6913 + WireFormat::len(&self.utn)
6914 + WireFormat::len(&self.re_t0)
6915 + WireFormat::len(&self.delta_x0)
6916 + WireFormat::len(&self.delta_y0)
6917 + WireFormat::len(&self.delta_z0)
6918 + WireFormat::len(&self.theta_01)
6919 + WireFormat::len(&self.theta_02)
6920 + WireFormat::len(&self.theta_03)
6921 + WireFormat::len(&self.scale)
6922 + WireFormat::len(&self.dot_delta_x0)
6923 + WireFormat::len(&self.dot_delta_y0)
6924 + WireFormat::len(&self.dot_delta_z0)
6925 + WireFormat::len(&self.dot_theta_01)
6926 + WireFormat::len(&self.dot_theta_02)
6927 + WireFormat::len(&self.dot_theta_03)
6928 + WireFormat::len(&self.dot_scale)
6929 }
6930 fn write<B: BufMut>(&self, buf: &mut B) {
6931 WireFormat::write(&self.ssr_iod, buf);
6932 WireFormat::write(&self.sn, buf);
6933 WireFormat::write(&self.tn, buf);
6934 WireFormat::write(&self.sin, buf);
6935 WireFormat::write(&self.utn, buf);
6936 WireFormat::write(&self.re_t0, buf);
6937 WireFormat::write(&self.delta_x0, buf);
6938 WireFormat::write(&self.delta_y0, buf);
6939 WireFormat::write(&self.delta_z0, buf);
6940 WireFormat::write(&self.theta_01, buf);
6941 WireFormat::write(&self.theta_02, buf);
6942 WireFormat::write(&self.theta_03, buf);
6943 WireFormat::write(&self.scale, buf);
6944 WireFormat::write(&self.dot_delta_x0, buf);
6945 WireFormat::write(&self.dot_delta_y0, buf);
6946 WireFormat::write(&self.dot_delta_z0, buf);
6947 WireFormat::write(&self.dot_theta_01, buf);
6948 WireFormat::write(&self.dot_theta_02, buf);
6949 WireFormat::write(&self.dot_theta_03, buf);
6950 WireFormat::write(&self.dot_scale, buf);
6951 }
6952 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
6953 MsgReferenceFrameParam {
6954 sender_id: None,
6955 ssr_iod: WireFormat::parse_unchecked(buf),
6956 sn: WireFormat::parse_unchecked(buf),
6957 tn: WireFormat::parse_unchecked(buf),
6958 sin: WireFormat::parse_unchecked(buf),
6959 utn: WireFormat::parse_unchecked(buf),
6960 re_t0: WireFormat::parse_unchecked(buf),
6961 delta_x0: WireFormat::parse_unchecked(buf),
6962 delta_y0: WireFormat::parse_unchecked(buf),
6963 delta_z0: WireFormat::parse_unchecked(buf),
6964 theta_01: WireFormat::parse_unchecked(buf),
6965 theta_02: WireFormat::parse_unchecked(buf),
6966 theta_03: WireFormat::parse_unchecked(buf),
6967 scale: WireFormat::parse_unchecked(buf),
6968 dot_delta_x0: WireFormat::parse_unchecked(buf),
6969 dot_delta_y0: WireFormat::parse_unchecked(buf),
6970 dot_delta_z0: WireFormat::parse_unchecked(buf),
6971 dot_theta_01: WireFormat::parse_unchecked(buf),
6972 dot_theta_02: WireFormat::parse_unchecked(buf),
6973 dot_theta_03: WireFormat::parse_unchecked(buf),
6974 dot_scale: WireFormat::parse_unchecked(buf),
6975 }
6976 }
6977 }
6978}
6979
6980pub mod msg_utc_leap_second {
6981 #![allow(unused_imports)]
6982
6983 use super::*;
6984 use crate::messages::lib::*;
6985
6986 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6992 #[allow(clippy::derive_partial_eq_without_eq)]
6993 #[derive(Debug, PartialEq, Clone)]
6994 pub struct MsgUtcLeapSecond {
6995 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
6997 pub sender_id: Option<u16>,
6998 #[cfg_attr(feature = "serde", serde(rename = "reserved_0"))]
7000 pub reserved_0: i16,
7001 #[cfg_attr(feature = "serde", serde(rename = "reserved_1"))]
7003 pub reserved_1: i16,
7004 #[cfg_attr(feature = "serde", serde(rename = "reserved_2"))]
7006 pub reserved_2: i8,
7007 #[cfg_attr(feature = "serde", serde(rename = "count_before"))]
7009 pub count_before: i8,
7010 #[cfg_attr(feature = "serde", serde(rename = "reserved_3"))]
7012 pub reserved_3: u16,
7013 #[cfg_attr(feature = "serde", serde(rename = "reserved_4"))]
7015 pub reserved_4: u16,
7016 #[cfg_attr(feature = "serde", serde(rename = "ref_wn"))]
7018 pub ref_wn: u16,
7019 #[cfg_attr(feature = "serde", serde(rename = "ref_dn"))]
7021 pub ref_dn: u8,
7022 #[cfg_attr(feature = "serde", serde(rename = "count_after"))]
7024 pub count_after: i8,
7025 }
7026
7027 impl ConcreteMessage for MsgUtcLeapSecond {
7028 const MESSAGE_TYPE: u16 = 570;
7029 const MESSAGE_NAME: &'static str = "MSG_UTC_LEAP_SECOND";
7030 }
7031
7032 impl SbpMessage for MsgUtcLeapSecond {
7033 fn message_name(&self) -> &'static str {
7034 <Self as ConcreteMessage>::MESSAGE_NAME
7035 }
7036 fn message_type(&self) -> Option<u16> {
7037 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
7038 }
7039 fn sender_id(&self) -> Option<u16> {
7040 self.sender_id
7041 }
7042 fn set_sender_id(&mut self, new_id: u16) {
7043 self.sender_id = Some(new_id);
7044 }
7045 fn encoded_len(&self) -> usize {
7046 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
7047 }
7048 fn is_valid(&self) -> bool {
7049 true
7050 }
7051 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
7052 Ok(self)
7053 }
7054 }
7055
7056 impl FriendlyName for MsgUtcLeapSecond {
7057 fn friendly_name() -> &'static str {
7058 "UTC LEAP SECOND"
7059 }
7060 }
7061
7062 impl TryFrom<Sbp> for MsgUtcLeapSecond {
7063 type Error = TryFromSbpError;
7064 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
7065 match msg {
7066 Sbp::MsgUtcLeapSecond(m) => Ok(m),
7067 _ => Err(TryFromSbpError(msg)),
7068 }
7069 }
7070 }
7071
7072 impl WireFormat for MsgUtcLeapSecond {
7073 const MIN_LEN: usize = <i16 as WireFormat>::MIN_LEN
7074 + <i16 as WireFormat>::MIN_LEN
7075 + <i8 as WireFormat>::MIN_LEN
7076 + <i8 as WireFormat>::MIN_LEN
7077 + <u16 as WireFormat>::MIN_LEN
7078 + <u16 as WireFormat>::MIN_LEN
7079 + <u16 as WireFormat>::MIN_LEN
7080 + <u8 as WireFormat>::MIN_LEN
7081 + <i8 as WireFormat>::MIN_LEN;
7082 fn len(&self) -> usize {
7083 WireFormat::len(&self.reserved_0)
7084 + WireFormat::len(&self.reserved_1)
7085 + WireFormat::len(&self.reserved_2)
7086 + WireFormat::len(&self.count_before)
7087 + WireFormat::len(&self.reserved_3)
7088 + WireFormat::len(&self.reserved_4)
7089 + WireFormat::len(&self.ref_wn)
7090 + WireFormat::len(&self.ref_dn)
7091 + WireFormat::len(&self.count_after)
7092 }
7093 fn write<B: BufMut>(&self, buf: &mut B) {
7094 WireFormat::write(&self.reserved_0, buf);
7095 WireFormat::write(&self.reserved_1, buf);
7096 WireFormat::write(&self.reserved_2, buf);
7097 WireFormat::write(&self.count_before, buf);
7098 WireFormat::write(&self.reserved_3, buf);
7099 WireFormat::write(&self.reserved_4, buf);
7100 WireFormat::write(&self.ref_wn, buf);
7101 WireFormat::write(&self.ref_dn, buf);
7102 WireFormat::write(&self.count_after, buf);
7103 }
7104 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
7105 MsgUtcLeapSecond {
7106 sender_id: None,
7107 reserved_0: WireFormat::parse_unchecked(buf),
7108 reserved_1: WireFormat::parse_unchecked(buf),
7109 reserved_2: WireFormat::parse_unchecked(buf),
7110 count_before: WireFormat::parse_unchecked(buf),
7111 reserved_3: WireFormat::parse_unchecked(buf),
7112 reserved_4: WireFormat::parse_unchecked(buf),
7113 ref_wn: WireFormat::parse_unchecked(buf),
7114 ref_dn: WireFormat::parse_unchecked(buf),
7115 count_after: WireFormat::parse_unchecked(buf),
7116 }
7117 }
7118 }
7119}
7120
7121pub mod msg_utc_time {
7122 #![allow(unused_imports)]
7123
7124 use super::*;
7125 use crate::messages::lib::*;
7126
7127 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7138 #[allow(clippy::derive_partial_eq_without_eq)]
7139 #[derive(Debug, PartialEq, Clone)]
7140 pub struct MsgUtcTime {
7141 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
7143 pub sender_id: Option<u16>,
7144 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
7146 pub flags: u8,
7147 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
7149 pub tow: u32,
7150 #[cfg_attr(feature = "serde", serde(rename = "year"))]
7152 pub year: u16,
7153 #[cfg_attr(feature = "serde", serde(rename = "month"))]
7155 pub month: u8,
7156 #[cfg_attr(feature = "serde", serde(rename = "day"))]
7158 pub day: u8,
7159 #[cfg_attr(feature = "serde", serde(rename = "hours"))]
7161 pub hours: u8,
7162 #[cfg_attr(feature = "serde", serde(rename = "minutes"))]
7164 pub minutes: u8,
7165 #[cfg_attr(feature = "serde", serde(rename = "seconds"))]
7167 pub seconds: u8,
7168 #[cfg_attr(feature = "serde", serde(rename = "ns"))]
7170 pub ns: u32,
7171 }
7172
7173 impl MsgUtcTime {
7174 pub fn utc_offset_source(&self) -> Result<UtcOffsetSource, u8> {
7180 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
7181 }
7182
7183 pub fn set_utc_offset_source(&mut self, utc_offset_source: UtcOffsetSource) {
7185 set_bit_range!(&mut self.flags, utc_offset_source, u8, u8, 4, 3);
7186 }
7187
7188 pub fn time_source(&self) -> Result<TimeSource, u8> {
7194 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
7195 }
7196
7197 pub fn set_time_source(&mut self, time_source: TimeSource) {
7199 set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0);
7200 }
7201 }
7202
7203 impl ConcreteMessage for MsgUtcTime {
7204 const MESSAGE_TYPE: u16 = 259;
7205 const MESSAGE_NAME: &'static str = "MSG_UTC_TIME";
7206 }
7207
7208 impl SbpMessage for MsgUtcTime {
7209 fn message_name(&self) -> &'static str {
7210 <Self as ConcreteMessage>::MESSAGE_NAME
7211 }
7212 fn message_type(&self) -> Option<u16> {
7213 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
7214 }
7215 fn sender_id(&self) -> Option<u16> {
7216 self.sender_id
7217 }
7218 fn set_sender_id(&mut self, new_id: u16) {
7219 self.sender_id = Some(new_id);
7220 }
7221 fn encoded_len(&self) -> usize {
7222 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
7223 }
7224 fn is_valid(&self) -> bool {
7225 true
7226 }
7227 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
7228 Ok(self)
7229 }
7230
7231 #[cfg(feature = "swiftnav")]
7232 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
7233 if self.time_source().ok()? == TimeSource::None {
7234 return None;
7235 }
7236 let tow_s = (self.tow as f64) / 1000.0;
7237 let gps_time = match time::GpsTime::new(0, tow_s) {
7238 Ok(gps_time) => gps_time.tow(),
7239 Err(e) => return Some(Err(e.into())),
7240 };
7241 Some(Ok(time::MessageTime::Rover(gps_time.into())))
7242 }
7243 }
7244
7245 impl FriendlyName for MsgUtcTime {
7246 fn friendly_name() -> &'static str {
7247 "UTC TIME"
7248 }
7249 }
7250
7251 impl TryFrom<Sbp> for MsgUtcTime {
7252 type Error = TryFromSbpError;
7253 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
7254 match msg {
7255 Sbp::MsgUtcTime(m) => Ok(m),
7256 _ => Err(TryFromSbpError(msg)),
7257 }
7258 }
7259 }
7260
7261 impl WireFormat for MsgUtcTime {
7262 const MIN_LEN: usize = <u8 as WireFormat>::MIN_LEN
7263 + <u32 as WireFormat>::MIN_LEN
7264 + <u16 as WireFormat>::MIN_LEN
7265 + <u8 as WireFormat>::MIN_LEN
7266 + <u8 as WireFormat>::MIN_LEN
7267 + <u8 as WireFormat>::MIN_LEN
7268 + <u8 as WireFormat>::MIN_LEN
7269 + <u8 as WireFormat>::MIN_LEN
7270 + <u32 as WireFormat>::MIN_LEN;
7271 fn len(&self) -> usize {
7272 WireFormat::len(&self.flags)
7273 + WireFormat::len(&self.tow)
7274 + WireFormat::len(&self.year)
7275 + WireFormat::len(&self.month)
7276 + WireFormat::len(&self.day)
7277 + WireFormat::len(&self.hours)
7278 + WireFormat::len(&self.minutes)
7279 + WireFormat::len(&self.seconds)
7280 + WireFormat::len(&self.ns)
7281 }
7282 fn write<B: BufMut>(&self, buf: &mut B) {
7283 WireFormat::write(&self.flags, buf);
7284 WireFormat::write(&self.tow, buf);
7285 WireFormat::write(&self.year, buf);
7286 WireFormat::write(&self.month, buf);
7287 WireFormat::write(&self.day, buf);
7288 WireFormat::write(&self.hours, buf);
7289 WireFormat::write(&self.minutes, buf);
7290 WireFormat::write(&self.seconds, buf);
7291 WireFormat::write(&self.ns, buf);
7292 }
7293 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
7294 MsgUtcTime {
7295 sender_id: None,
7296 flags: WireFormat::parse_unchecked(buf),
7297 tow: WireFormat::parse_unchecked(buf),
7298 year: WireFormat::parse_unchecked(buf),
7299 month: WireFormat::parse_unchecked(buf),
7300 day: WireFormat::parse_unchecked(buf),
7301 hours: WireFormat::parse_unchecked(buf),
7302 minutes: WireFormat::parse_unchecked(buf),
7303 seconds: WireFormat::parse_unchecked(buf),
7304 ns: WireFormat::parse_unchecked(buf),
7305 }
7306 }
7307 }
7308
7309 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7311 pub enum UtcOffsetSource {
7312 FactoryDefault = 0,
7314
7315 NonVolatileMemory = 1,
7317
7318 DecodedThisSession = 2,
7320 }
7321
7322 impl std::fmt::Display for UtcOffsetSource {
7323 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7324 match self {
7325 UtcOffsetSource::FactoryDefault => f.write_str("Factory Default"),
7326 UtcOffsetSource::NonVolatileMemory => f.write_str("Non Volatile Memory"),
7327 UtcOffsetSource::DecodedThisSession => f.write_str("Decoded this Session"),
7328 }
7329 }
7330 }
7331
7332 impl TryFrom<u8> for UtcOffsetSource {
7333 type Error = u8;
7334 fn try_from(i: u8) -> Result<Self, u8> {
7335 match i {
7336 0 => Ok(UtcOffsetSource::FactoryDefault),
7337 1 => Ok(UtcOffsetSource::NonVolatileMemory),
7338 2 => Ok(UtcOffsetSource::DecodedThisSession),
7339 i => Err(i),
7340 }
7341 }
7342 }
7343
7344 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7346 pub enum TimeSource {
7347 None = 0,
7349
7350 GnssSolution = 1,
7352
7353 Propagated = 2,
7355 }
7356
7357 impl std::fmt::Display for TimeSource {
7358 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7359 match self {
7360 TimeSource::None => f.write_str("None (invalid)"),
7361 TimeSource::GnssSolution => f.write_str("GNSS Solution"),
7362 TimeSource::Propagated => f.write_str("Propagated"),
7363 }
7364 }
7365 }
7366
7367 impl TryFrom<u8> for TimeSource {
7368 type Error = u8;
7369 fn try_from(i: u8) -> Result<Self, u8> {
7370 match i {
7371 0 => Ok(TimeSource::None),
7372 1 => Ok(TimeSource::GnssSolution),
7373 2 => Ok(TimeSource::Propagated),
7374 i => Err(i),
7375 }
7376 }
7377 }
7378}
7379
7380pub mod msg_utc_time_gnss {
7381 #![allow(unused_imports)]
7382
7383 use super::*;
7384 use crate::messages::lib::*;
7385
7386 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7396 #[allow(clippy::derive_partial_eq_without_eq)]
7397 #[derive(Debug, PartialEq, Clone)]
7398 pub struct MsgUtcTimeGnss {
7399 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
7401 pub sender_id: Option<u16>,
7402 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
7404 pub flags: u8,
7405 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
7407 pub tow: u32,
7408 #[cfg_attr(feature = "serde", serde(rename = "year"))]
7410 pub year: u16,
7411 #[cfg_attr(feature = "serde", serde(rename = "month"))]
7413 pub month: u8,
7414 #[cfg_attr(feature = "serde", serde(rename = "day"))]
7416 pub day: u8,
7417 #[cfg_attr(feature = "serde", serde(rename = "hours"))]
7419 pub hours: u8,
7420 #[cfg_attr(feature = "serde", serde(rename = "minutes"))]
7422 pub minutes: u8,
7423 #[cfg_attr(feature = "serde", serde(rename = "seconds"))]
7425 pub seconds: u8,
7426 #[cfg_attr(feature = "serde", serde(rename = "ns"))]
7428 pub ns: u32,
7429 }
7430
7431 impl MsgUtcTimeGnss {
7432 pub fn utc_offset_source(&self) -> Result<UtcOffsetSource, u8> {
7438 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
7439 }
7440
7441 pub fn set_utc_offset_source(&mut self, utc_offset_source: UtcOffsetSource) {
7443 set_bit_range!(&mut self.flags, utc_offset_source, u8, u8, 4, 3);
7444 }
7445
7446 pub fn time_source(&self) -> Result<TimeSource, u8> {
7452 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
7453 }
7454
7455 pub fn set_time_source(&mut self, time_source: TimeSource) {
7457 set_bit_range!(&mut self.flags, time_source, u8, u8, 2, 0);
7458 }
7459 }
7460
7461 impl ConcreteMessage for MsgUtcTimeGnss {
7462 const MESSAGE_TYPE: u16 = 261;
7463 const MESSAGE_NAME: &'static str = "MSG_UTC_TIME_GNSS";
7464 }
7465
7466 impl SbpMessage for MsgUtcTimeGnss {
7467 fn message_name(&self) -> &'static str {
7468 <Self as ConcreteMessage>::MESSAGE_NAME
7469 }
7470 fn message_type(&self) -> Option<u16> {
7471 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
7472 }
7473 fn sender_id(&self) -> Option<u16> {
7474 self.sender_id
7475 }
7476 fn set_sender_id(&mut self, new_id: u16) {
7477 self.sender_id = Some(new_id);
7478 }
7479 fn encoded_len(&self) -> usize {
7480 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
7481 }
7482 fn is_valid(&self) -> bool {
7483 true
7484 }
7485 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
7486 Ok(self)
7487 }
7488
7489 #[cfg(feature = "swiftnav")]
7490 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
7491 if self.time_source().ok()? == TimeSource::None {
7492 return None;
7493 }
7494 let tow_s = (self.tow as f64) / 1000.0;
7495 let gps_time = match time::GpsTime::new(0, tow_s) {
7496 Ok(gps_time) => gps_time.tow(),
7497 Err(e) => return Some(Err(e.into())),
7498 };
7499 Some(Ok(time::MessageTime::Rover(gps_time.into())))
7500 }
7501 }
7502
7503 impl FriendlyName for MsgUtcTimeGnss {
7504 fn friendly_name() -> &'static str {
7505 "UTC TIME GNSS-only"
7506 }
7507 }
7508
7509 impl TryFrom<Sbp> for MsgUtcTimeGnss {
7510 type Error = TryFromSbpError;
7511 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
7512 match msg {
7513 Sbp::MsgUtcTimeGnss(m) => Ok(m),
7514 _ => Err(TryFromSbpError(msg)),
7515 }
7516 }
7517 }
7518
7519 impl WireFormat for MsgUtcTimeGnss {
7520 const MIN_LEN: usize = <u8 as WireFormat>::MIN_LEN
7521 + <u32 as WireFormat>::MIN_LEN
7522 + <u16 as WireFormat>::MIN_LEN
7523 + <u8 as WireFormat>::MIN_LEN
7524 + <u8 as WireFormat>::MIN_LEN
7525 + <u8 as WireFormat>::MIN_LEN
7526 + <u8 as WireFormat>::MIN_LEN
7527 + <u8 as WireFormat>::MIN_LEN
7528 + <u32 as WireFormat>::MIN_LEN;
7529 fn len(&self) -> usize {
7530 WireFormat::len(&self.flags)
7531 + WireFormat::len(&self.tow)
7532 + WireFormat::len(&self.year)
7533 + WireFormat::len(&self.month)
7534 + WireFormat::len(&self.day)
7535 + WireFormat::len(&self.hours)
7536 + WireFormat::len(&self.minutes)
7537 + WireFormat::len(&self.seconds)
7538 + WireFormat::len(&self.ns)
7539 }
7540 fn write<B: BufMut>(&self, buf: &mut B) {
7541 WireFormat::write(&self.flags, buf);
7542 WireFormat::write(&self.tow, buf);
7543 WireFormat::write(&self.year, buf);
7544 WireFormat::write(&self.month, buf);
7545 WireFormat::write(&self.day, buf);
7546 WireFormat::write(&self.hours, buf);
7547 WireFormat::write(&self.minutes, buf);
7548 WireFormat::write(&self.seconds, buf);
7549 WireFormat::write(&self.ns, buf);
7550 }
7551 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
7552 MsgUtcTimeGnss {
7553 sender_id: None,
7554 flags: WireFormat::parse_unchecked(buf),
7555 tow: WireFormat::parse_unchecked(buf),
7556 year: WireFormat::parse_unchecked(buf),
7557 month: WireFormat::parse_unchecked(buf),
7558 day: WireFormat::parse_unchecked(buf),
7559 hours: WireFormat::parse_unchecked(buf),
7560 minutes: WireFormat::parse_unchecked(buf),
7561 seconds: WireFormat::parse_unchecked(buf),
7562 ns: WireFormat::parse_unchecked(buf),
7563 }
7564 }
7565 }
7566
7567 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7569 pub enum UtcOffsetSource {
7570 FactoryDefault = 0,
7572
7573 NonVolatileMemory = 1,
7575
7576 DecodedThisSession = 2,
7578 }
7579
7580 impl std::fmt::Display for UtcOffsetSource {
7581 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7582 match self {
7583 UtcOffsetSource::FactoryDefault => f.write_str("Factory Default"),
7584 UtcOffsetSource::NonVolatileMemory => f.write_str("Non Volatile Memory"),
7585 UtcOffsetSource::DecodedThisSession => f.write_str("Decoded this Session"),
7586 }
7587 }
7588 }
7589
7590 impl TryFrom<u8> for UtcOffsetSource {
7591 type Error = u8;
7592 fn try_from(i: u8) -> Result<Self, u8> {
7593 match i {
7594 0 => Ok(UtcOffsetSource::FactoryDefault),
7595 1 => Ok(UtcOffsetSource::NonVolatileMemory),
7596 2 => Ok(UtcOffsetSource::DecodedThisSession),
7597 i => Err(i),
7598 }
7599 }
7600 }
7601
7602 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7604 pub enum TimeSource {
7605 None = 0,
7607
7608 GnssSolution = 1,
7610
7611 Propagated = 2,
7613 }
7614
7615 impl std::fmt::Display for TimeSource {
7616 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7617 match self {
7618 TimeSource::None => f.write_str("None (invalid)"),
7619 TimeSource::GnssSolution => f.write_str("GNSS Solution"),
7620 TimeSource::Propagated => f.write_str("Propagated"),
7621 }
7622 }
7623 }
7624
7625 impl TryFrom<u8> for TimeSource {
7626 type Error = u8;
7627 fn try_from(i: u8) -> Result<Self, u8> {
7628 match i {
7629 0 => Ok(TimeSource::None),
7630 1 => Ok(TimeSource::GnssSolution),
7631 2 => Ok(TimeSource::Propagated),
7632 i => Err(i),
7633 }
7634 }
7635 }
7636}
7637
7638pub mod msg_vel_body {
7639 #![allow(unused_imports)]
7640
7641 use super::*;
7642 use crate::messages::lib::*;
7643
7644 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7660 #[allow(clippy::derive_partial_eq_without_eq)]
7661 #[derive(Debug, PartialEq, Clone)]
7662 pub struct MsgVelBody {
7663 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
7665 pub sender_id: Option<u16>,
7666 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
7668 pub tow: u32,
7669 #[cfg_attr(feature = "serde", serde(rename = "x"))]
7671 pub x: i32,
7672 #[cfg_attr(feature = "serde", serde(rename = "y"))]
7674 pub y: i32,
7675 #[cfg_attr(feature = "serde", serde(rename = "z"))]
7677 pub z: i32,
7678 #[cfg_attr(feature = "serde", serde(rename = "cov_x_x"))]
7680 pub cov_x_x: f32,
7681 #[cfg_attr(feature = "serde", serde(rename = "cov_x_y"))]
7683 pub cov_x_y: f32,
7684 #[cfg_attr(feature = "serde", serde(rename = "cov_x_z"))]
7686 pub cov_x_z: f32,
7687 #[cfg_attr(feature = "serde", serde(rename = "cov_y_y"))]
7689 pub cov_y_y: f32,
7690 #[cfg_attr(feature = "serde", serde(rename = "cov_y_z"))]
7692 pub cov_y_z: f32,
7693 #[cfg_attr(feature = "serde", serde(rename = "cov_z_z"))]
7695 pub cov_z_z: f32,
7696 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
7698 pub n_sats: u8,
7699 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
7701 pub flags: u8,
7702 }
7703
7704 impl MsgVelBody {
7705 pub fn ins_navigation_mode(&self) -> Result<InsNavigationMode, u8> {
7711 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
7712 }
7713
7714 pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) {
7716 set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3);
7717 }
7718
7719 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
7725 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
7726 }
7727
7728 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
7730 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
7731 }
7732 }
7733
7734 impl ConcreteMessage for MsgVelBody {
7735 const MESSAGE_TYPE: u16 = 531;
7736 const MESSAGE_NAME: &'static str = "MSG_VEL_BODY";
7737 }
7738
7739 impl SbpMessage for MsgVelBody {
7740 fn message_name(&self) -> &'static str {
7741 <Self as ConcreteMessage>::MESSAGE_NAME
7742 }
7743 fn message_type(&self) -> Option<u16> {
7744 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
7745 }
7746 fn sender_id(&self) -> Option<u16> {
7747 self.sender_id
7748 }
7749 fn set_sender_id(&mut self, new_id: u16) {
7750 self.sender_id = Some(new_id);
7751 }
7752 fn encoded_len(&self) -> usize {
7753 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
7754 }
7755 fn is_valid(&self) -> bool {
7756 true
7757 }
7758 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
7759 Ok(self)
7760 }
7761
7762 #[cfg(feature = "swiftnav")]
7763 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
7764 let tow_s = (self.tow as f64) / 1000.0;
7765 let gps_time = match time::GpsTime::new(0, tow_s) {
7766 Ok(gps_time) => gps_time.tow(),
7767 Err(e) => return Some(Err(e.into())),
7768 };
7769 Some(Ok(time::MessageTime::Rover(gps_time.into())))
7770 }
7771 }
7772
7773 impl FriendlyName for MsgVelBody {
7774 fn friendly_name() -> &'static str {
7775 "VEL BODY"
7776 }
7777 }
7778
7779 impl TryFrom<Sbp> for MsgVelBody {
7780 type Error = TryFromSbpError;
7781 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
7782 match msg {
7783 Sbp::MsgVelBody(m) => Ok(m),
7784 _ => Err(TryFromSbpError(msg)),
7785 }
7786 }
7787 }
7788
7789 impl WireFormat for MsgVelBody {
7790 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
7791 + <i32 as WireFormat>::MIN_LEN
7792 + <i32 as WireFormat>::MIN_LEN
7793 + <i32 as WireFormat>::MIN_LEN
7794 + <f32 as WireFormat>::MIN_LEN
7795 + <f32 as WireFormat>::MIN_LEN
7796 + <f32 as WireFormat>::MIN_LEN
7797 + <f32 as WireFormat>::MIN_LEN
7798 + <f32 as WireFormat>::MIN_LEN
7799 + <f32 as WireFormat>::MIN_LEN
7800 + <u8 as WireFormat>::MIN_LEN
7801 + <u8 as WireFormat>::MIN_LEN;
7802 fn len(&self) -> usize {
7803 WireFormat::len(&self.tow)
7804 + WireFormat::len(&self.x)
7805 + WireFormat::len(&self.y)
7806 + WireFormat::len(&self.z)
7807 + WireFormat::len(&self.cov_x_x)
7808 + WireFormat::len(&self.cov_x_y)
7809 + WireFormat::len(&self.cov_x_z)
7810 + WireFormat::len(&self.cov_y_y)
7811 + WireFormat::len(&self.cov_y_z)
7812 + WireFormat::len(&self.cov_z_z)
7813 + WireFormat::len(&self.n_sats)
7814 + WireFormat::len(&self.flags)
7815 }
7816 fn write<B: BufMut>(&self, buf: &mut B) {
7817 WireFormat::write(&self.tow, buf);
7818 WireFormat::write(&self.x, buf);
7819 WireFormat::write(&self.y, buf);
7820 WireFormat::write(&self.z, buf);
7821 WireFormat::write(&self.cov_x_x, buf);
7822 WireFormat::write(&self.cov_x_y, buf);
7823 WireFormat::write(&self.cov_x_z, buf);
7824 WireFormat::write(&self.cov_y_y, buf);
7825 WireFormat::write(&self.cov_y_z, buf);
7826 WireFormat::write(&self.cov_z_z, buf);
7827 WireFormat::write(&self.n_sats, buf);
7828 WireFormat::write(&self.flags, buf);
7829 }
7830 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
7831 MsgVelBody {
7832 sender_id: None,
7833 tow: WireFormat::parse_unchecked(buf),
7834 x: WireFormat::parse_unchecked(buf),
7835 y: WireFormat::parse_unchecked(buf),
7836 z: WireFormat::parse_unchecked(buf),
7837 cov_x_x: WireFormat::parse_unchecked(buf),
7838 cov_x_y: WireFormat::parse_unchecked(buf),
7839 cov_x_z: WireFormat::parse_unchecked(buf),
7840 cov_y_y: WireFormat::parse_unchecked(buf),
7841 cov_y_z: WireFormat::parse_unchecked(buf),
7842 cov_z_z: WireFormat::parse_unchecked(buf),
7843 n_sats: WireFormat::parse_unchecked(buf),
7844 flags: WireFormat::parse_unchecked(buf),
7845 }
7846 }
7847 }
7848
7849 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7851 pub enum InsNavigationMode {
7852 None = 0,
7854
7855 InsUsed = 1,
7857 }
7858
7859 impl std::fmt::Display for InsNavigationMode {
7860 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7861 match self {
7862 InsNavigationMode::None => f.write_str("None"),
7863 InsNavigationMode::InsUsed => f.write_str("INS used"),
7864 }
7865 }
7866 }
7867
7868 impl TryFrom<u8> for InsNavigationMode {
7869 type Error = u8;
7870 fn try_from(i: u8) -> Result<Self, u8> {
7871 match i {
7872 0 => Ok(InsNavigationMode::None),
7873 1 => Ok(InsNavigationMode::InsUsed),
7874 i => Err(i),
7875 }
7876 }
7877 }
7878
7879 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7881 pub enum VelocityMode {
7882 Invalid = 0,
7884
7885 MeasuredDopplerDerived = 1,
7887
7888 ComputedDopplerDerived = 2,
7890
7891 DeadReckoning = 3,
7893 }
7894
7895 impl std::fmt::Display for VelocityMode {
7896 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7897 match self {
7898 VelocityMode::Invalid => f.write_str("Invalid"),
7899 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
7900 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
7901 VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"),
7902 }
7903 }
7904 }
7905
7906 impl TryFrom<u8> for VelocityMode {
7907 type Error = u8;
7908 fn try_from(i: u8) -> Result<Self, u8> {
7909 match i {
7910 0 => Ok(VelocityMode::Invalid),
7911 1 => Ok(VelocityMode::MeasuredDopplerDerived),
7912 2 => Ok(VelocityMode::ComputedDopplerDerived),
7913 3 => Ok(VelocityMode::DeadReckoning),
7914 i => Err(i),
7915 }
7916 }
7917 }
7918}
7919
7920pub mod msg_vel_cog {
7921 #![allow(unused_imports)]
7922
7923 use super::*;
7924 use crate::messages::lib::*;
7925
7926 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7944 #[allow(clippy::derive_partial_eq_without_eq)]
7945 #[derive(Debug, PartialEq, Clone)]
7946 pub struct MsgVelCog {
7947 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
7949 pub sender_id: Option<u16>,
7950 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
7952 pub tow: u32,
7953 #[cfg_attr(feature = "serde", serde(rename = "cog"))]
7955 pub cog: u32,
7956 #[cfg_attr(feature = "serde", serde(rename = "sog"))]
7958 pub sog: u32,
7959 #[cfg_attr(feature = "serde", serde(rename = "v_up"))]
7961 pub v_up: i32,
7962 #[cfg_attr(feature = "serde", serde(rename = "cog_accuracy"))]
7964 pub cog_accuracy: u32,
7965 #[cfg_attr(feature = "serde", serde(rename = "sog_accuracy"))]
7967 pub sog_accuracy: u32,
7968 #[cfg_attr(feature = "serde", serde(rename = "v_up_accuracy"))]
7970 pub v_up_accuracy: u32,
7971 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
7973 pub flags: u16,
7974 }
7975
7976 impl MsgVelCog {
7977 pub fn cog_frozen(&self) -> Result<CogFrozen, u8> {
7983 get_bit_range!(self.flags, u16, u8, 9, 9).try_into()
7984 }
7985
7986 pub fn set_cog_frozen(&mut self, cog_frozen: CogFrozen) {
7988 set_bit_range!(&mut self.flags, cog_frozen, u16, u8, 9, 9);
7989 }
7990
7991 pub fn vertical_velocity_validity(&self) -> Result<VerticalVelocityValidity, u8> {
7997 get_bit_range!(self.flags, u16, u8, 8, 8).try_into()
7998 }
7999
8000 pub fn set_vertical_velocity_validity(
8002 &mut self,
8003 vertical_velocity_validity: VerticalVelocityValidity,
8004 ) {
8005 set_bit_range!(&mut self.flags, vertical_velocity_validity, u16, u8, 8, 8);
8006 }
8007
8008 pub fn sog_validity(&self) -> Result<SogValidity, u8> {
8014 get_bit_range!(self.flags, u16, u8, 7, 7).try_into()
8015 }
8016
8017 pub fn set_sog_validity(&mut self, sog_validity: SogValidity) {
8019 set_bit_range!(&mut self.flags, sog_validity, u16, u8, 7, 7);
8020 }
8021
8022 pub fn cog_validity(&self) -> Result<CogValidity, u8> {
8028 get_bit_range!(self.flags, u16, u8, 6, 6).try_into()
8029 }
8030
8031 pub fn set_cog_validity(&mut self, cog_validity: CogValidity) {
8033 set_bit_range!(&mut self.flags, cog_validity, u16, u8, 6, 6);
8034 }
8035
8036 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
8042 get_bit_range!(self.flags, u16, u8, 5, 5).try_into()
8043 }
8044
8045 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
8047 set_bit_range!(&mut self.flags, type_of_reported_tow, u16, u8, 5, 5);
8048 }
8049
8050 pub fn ins_navigation_mode(&self) -> Result<InsNavigationMode, u8> {
8056 get_bit_range!(self.flags, u16, u8, 4, 3).try_into()
8057 }
8058
8059 pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) {
8061 set_bit_range!(&mut self.flags, ins_navigation_mode, u16, u8, 4, 3);
8062 }
8063
8064 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
8070 get_bit_range!(self.flags, u16, u8, 2, 0).try_into()
8071 }
8072
8073 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
8075 set_bit_range!(&mut self.flags, velocity_mode, u16, u8, 2, 0);
8076 }
8077 }
8078
8079 impl ConcreteMessage for MsgVelCog {
8080 const MESSAGE_TYPE: u16 = 540;
8081 const MESSAGE_NAME: &'static str = "MSG_VEL_COG";
8082 }
8083
8084 impl SbpMessage for MsgVelCog {
8085 fn message_name(&self) -> &'static str {
8086 <Self as ConcreteMessage>::MESSAGE_NAME
8087 }
8088 fn message_type(&self) -> Option<u16> {
8089 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
8090 }
8091 fn sender_id(&self) -> Option<u16> {
8092 self.sender_id
8093 }
8094 fn set_sender_id(&mut self, new_id: u16) {
8095 self.sender_id = Some(new_id);
8096 }
8097 fn encoded_len(&self) -> usize {
8098 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
8099 }
8100 fn is_valid(&self) -> bool {
8101 true
8102 }
8103 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
8104 Ok(self)
8105 }
8106
8107 #[cfg(feature = "swiftnav")]
8108 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
8109 let tow_s = (self.tow as f64) / 1000.0;
8110 let gps_time = match time::GpsTime::new(0, tow_s) {
8111 Ok(gps_time) => gps_time.tow(),
8112 Err(e) => return Some(Err(e.into())),
8113 };
8114 Some(Ok(time::MessageTime::Rover(gps_time.into())))
8115 }
8116 }
8117
8118 impl FriendlyName for MsgVelCog {
8119 fn friendly_name() -> &'static str {
8120 "VEL COG"
8121 }
8122 }
8123
8124 impl TryFrom<Sbp> for MsgVelCog {
8125 type Error = TryFromSbpError;
8126 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
8127 match msg {
8128 Sbp::MsgVelCog(m) => Ok(m),
8129 _ => Err(TryFromSbpError(msg)),
8130 }
8131 }
8132 }
8133
8134 impl WireFormat for MsgVelCog {
8135 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
8136 + <u32 as WireFormat>::MIN_LEN
8137 + <u32 as WireFormat>::MIN_LEN
8138 + <i32 as WireFormat>::MIN_LEN
8139 + <u32 as WireFormat>::MIN_LEN
8140 + <u32 as WireFormat>::MIN_LEN
8141 + <u32 as WireFormat>::MIN_LEN
8142 + <u16 as WireFormat>::MIN_LEN;
8143 fn len(&self) -> usize {
8144 WireFormat::len(&self.tow)
8145 + WireFormat::len(&self.cog)
8146 + WireFormat::len(&self.sog)
8147 + WireFormat::len(&self.v_up)
8148 + WireFormat::len(&self.cog_accuracy)
8149 + WireFormat::len(&self.sog_accuracy)
8150 + WireFormat::len(&self.v_up_accuracy)
8151 + WireFormat::len(&self.flags)
8152 }
8153 fn write<B: BufMut>(&self, buf: &mut B) {
8154 WireFormat::write(&self.tow, buf);
8155 WireFormat::write(&self.cog, buf);
8156 WireFormat::write(&self.sog, buf);
8157 WireFormat::write(&self.v_up, buf);
8158 WireFormat::write(&self.cog_accuracy, buf);
8159 WireFormat::write(&self.sog_accuracy, buf);
8160 WireFormat::write(&self.v_up_accuracy, buf);
8161 WireFormat::write(&self.flags, buf);
8162 }
8163 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
8164 MsgVelCog {
8165 sender_id: None,
8166 tow: WireFormat::parse_unchecked(buf),
8167 cog: WireFormat::parse_unchecked(buf),
8168 sog: WireFormat::parse_unchecked(buf),
8169 v_up: WireFormat::parse_unchecked(buf),
8170 cog_accuracy: WireFormat::parse_unchecked(buf),
8171 sog_accuracy: WireFormat::parse_unchecked(buf),
8172 v_up_accuracy: WireFormat::parse_unchecked(buf),
8173 flags: WireFormat::parse_unchecked(buf),
8174 }
8175 }
8176 }
8177
8178 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8180 pub enum CogFrozen {
8181 NotFrozen = 0,
8183
8184 Frozen = 1,
8186 }
8187
8188 impl std::fmt::Display for CogFrozen {
8189 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8190 match self {
8191 CogFrozen::NotFrozen => f.write_str("Not frozen"),
8192 CogFrozen::Frozen => f.write_str("Frozen"),
8193 }
8194 }
8195 }
8196
8197 impl TryFrom<u8> for CogFrozen {
8198 type Error = u8;
8199 fn try_from(i: u8) -> Result<Self, u8> {
8200 match i {
8201 0 => Ok(CogFrozen::NotFrozen),
8202 1 => Ok(CogFrozen::Frozen),
8203 i => Err(i),
8204 }
8205 }
8206 }
8207
8208 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8210 pub enum VerticalVelocityValidity {
8211 Invalid = 0,
8213
8214 VerticalVelocityValid = 1,
8216 }
8217
8218 impl std::fmt::Display for VerticalVelocityValidity {
8219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8220 match self {
8221 VerticalVelocityValidity::Invalid => f.write_str("Invalid"),
8222 VerticalVelocityValidity::VerticalVelocityValid => {
8223 f.write_str("Vertical velocity valid")
8224 }
8225 }
8226 }
8227 }
8228
8229 impl TryFrom<u8> for VerticalVelocityValidity {
8230 type Error = u8;
8231 fn try_from(i: u8) -> Result<Self, u8> {
8232 match i {
8233 0 => Ok(VerticalVelocityValidity::Invalid),
8234 1 => Ok(VerticalVelocityValidity::VerticalVelocityValid),
8235 i => Err(i),
8236 }
8237 }
8238 }
8239
8240 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8242 pub enum SogValidity {
8243 Invalid = 0,
8245
8246 SogValid = 1,
8248 }
8249
8250 impl std::fmt::Display for SogValidity {
8251 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8252 match self {
8253 SogValidity::Invalid => f.write_str("Invalid"),
8254 SogValidity::SogValid => f.write_str("SOG valid"),
8255 }
8256 }
8257 }
8258
8259 impl TryFrom<u8> for SogValidity {
8260 type Error = u8;
8261 fn try_from(i: u8) -> Result<Self, u8> {
8262 match i {
8263 0 => Ok(SogValidity::Invalid),
8264 1 => Ok(SogValidity::SogValid),
8265 i => Err(i),
8266 }
8267 }
8268 }
8269
8270 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8272 pub enum CogValidity {
8273 Invalid = 0,
8275
8276 CogValid = 1,
8278 }
8279
8280 impl std::fmt::Display for CogValidity {
8281 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8282 match self {
8283 CogValidity::Invalid => f.write_str("Invalid"),
8284 CogValidity::CogValid => f.write_str("COG valid"),
8285 }
8286 }
8287 }
8288
8289 impl TryFrom<u8> for CogValidity {
8290 type Error = u8;
8291 fn try_from(i: u8) -> Result<Self, u8> {
8292 match i {
8293 0 => Ok(CogValidity::Invalid),
8294 1 => Ok(CogValidity::CogValid),
8295 i => Err(i),
8296 }
8297 }
8298 }
8299
8300 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8302 pub enum TypeOfReportedTow {
8303 TimeOfMeasurement = 0,
8305
8306 Other = 1,
8308 }
8309
8310 impl std::fmt::Display for TypeOfReportedTow {
8311 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8312 match self {
8313 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
8314 TypeOfReportedTow::Other => f.write_str("Other"),
8315 }
8316 }
8317 }
8318
8319 impl TryFrom<u8> for TypeOfReportedTow {
8320 type Error = u8;
8321 fn try_from(i: u8) -> Result<Self, u8> {
8322 match i {
8323 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
8324 1 => Ok(TypeOfReportedTow::Other),
8325 i => Err(i),
8326 }
8327 }
8328 }
8329
8330 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8332 pub enum InsNavigationMode {
8333 None = 0,
8335
8336 InsUsed = 1,
8338 }
8339
8340 impl std::fmt::Display for InsNavigationMode {
8341 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8342 match self {
8343 InsNavigationMode::None => f.write_str("None"),
8344 InsNavigationMode::InsUsed => f.write_str("INS used"),
8345 }
8346 }
8347 }
8348
8349 impl TryFrom<u8> for InsNavigationMode {
8350 type Error = u8;
8351 fn try_from(i: u8) -> Result<Self, u8> {
8352 match i {
8353 0 => Ok(InsNavigationMode::None),
8354 1 => Ok(InsNavigationMode::InsUsed),
8355 i => Err(i),
8356 }
8357 }
8358 }
8359
8360 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8362 pub enum VelocityMode {
8363 Invalid = 0,
8365
8366 MeasuredDopplerDerived = 1,
8368
8369 ComputedDopplerDerived = 2,
8371
8372 DeadReckoning = 3,
8374 }
8375
8376 impl std::fmt::Display for VelocityMode {
8377 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8378 match self {
8379 VelocityMode::Invalid => f.write_str("Invalid"),
8380 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
8381 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
8382 VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"),
8383 }
8384 }
8385 }
8386
8387 impl TryFrom<u8> for VelocityMode {
8388 type Error = u8;
8389 fn try_from(i: u8) -> Result<Self, u8> {
8390 match i {
8391 0 => Ok(VelocityMode::Invalid),
8392 1 => Ok(VelocityMode::MeasuredDopplerDerived),
8393 2 => Ok(VelocityMode::ComputedDopplerDerived),
8394 3 => Ok(VelocityMode::DeadReckoning),
8395 i => Err(i),
8396 }
8397 }
8398 }
8399}
8400
8401pub mod msg_vel_ecef {
8402 #![allow(unused_imports)]
8403
8404 use super::*;
8405 use crate::messages::lib::*;
8406
8407 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8418 #[allow(clippy::derive_partial_eq_without_eq)]
8419 #[derive(Debug, PartialEq, Clone)]
8420 pub struct MsgVelEcef {
8421 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
8423 pub sender_id: Option<u16>,
8424 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
8426 pub tow: u32,
8427 #[cfg_attr(feature = "serde", serde(rename = "x"))]
8429 pub x: i32,
8430 #[cfg_attr(feature = "serde", serde(rename = "y"))]
8432 pub y: i32,
8433 #[cfg_attr(feature = "serde", serde(rename = "z"))]
8435 pub z: i32,
8436 #[cfg_attr(feature = "serde", serde(rename = "accuracy"))]
8438 pub accuracy: u16,
8439 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
8441 pub n_sats: u8,
8442 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
8444 pub flags: u8,
8445 }
8446
8447 impl MsgVelEcef {
8448 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
8454 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
8455 }
8456
8457 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
8459 set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5);
8460 }
8461
8462 pub fn ins_navigation_mode(&self) -> Result<InsNavigationMode, u8> {
8468 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
8469 }
8470
8471 pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) {
8473 set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3);
8474 }
8475
8476 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
8482 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
8483 }
8484
8485 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
8487 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
8488 }
8489 }
8490
8491 impl ConcreteMessage for MsgVelEcef {
8492 const MESSAGE_TYPE: u16 = 525;
8493 const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF";
8494 }
8495
8496 impl SbpMessage for MsgVelEcef {
8497 fn message_name(&self) -> &'static str {
8498 <Self as ConcreteMessage>::MESSAGE_NAME
8499 }
8500 fn message_type(&self) -> Option<u16> {
8501 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
8502 }
8503 fn sender_id(&self) -> Option<u16> {
8504 self.sender_id
8505 }
8506 fn set_sender_id(&mut self, new_id: u16) {
8507 self.sender_id = Some(new_id);
8508 }
8509 fn encoded_len(&self) -> usize {
8510 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
8511 }
8512 fn is_valid(&self) -> bool {
8513 true
8514 }
8515 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
8516 Ok(self)
8517 }
8518
8519 #[cfg(feature = "swiftnav")]
8520 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
8521 let tow_s = (self.tow as f64) / 1000.0;
8522 let gps_time = match time::GpsTime::new(0, tow_s) {
8523 Ok(gps_time) => gps_time.tow(),
8524 Err(e) => return Some(Err(e.into())),
8525 };
8526 Some(Ok(time::MessageTime::Rover(gps_time.into())))
8527 }
8528 }
8529
8530 impl FriendlyName for MsgVelEcef {
8531 fn friendly_name() -> &'static str {
8532 "VEL ECEF"
8533 }
8534 }
8535
8536 impl TryFrom<Sbp> for MsgVelEcef {
8537 type Error = TryFromSbpError;
8538 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
8539 match msg {
8540 Sbp::MsgVelEcef(m) => Ok(m),
8541 _ => Err(TryFromSbpError(msg)),
8542 }
8543 }
8544 }
8545
8546 impl WireFormat for MsgVelEcef {
8547 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
8548 + <i32 as WireFormat>::MIN_LEN
8549 + <i32 as WireFormat>::MIN_LEN
8550 + <i32 as WireFormat>::MIN_LEN
8551 + <u16 as WireFormat>::MIN_LEN
8552 + <u8 as WireFormat>::MIN_LEN
8553 + <u8 as WireFormat>::MIN_LEN;
8554 fn len(&self) -> usize {
8555 WireFormat::len(&self.tow)
8556 + WireFormat::len(&self.x)
8557 + WireFormat::len(&self.y)
8558 + WireFormat::len(&self.z)
8559 + WireFormat::len(&self.accuracy)
8560 + WireFormat::len(&self.n_sats)
8561 + WireFormat::len(&self.flags)
8562 }
8563 fn write<B: BufMut>(&self, buf: &mut B) {
8564 WireFormat::write(&self.tow, buf);
8565 WireFormat::write(&self.x, buf);
8566 WireFormat::write(&self.y, buf);
8567 WireFormat::write(&self.z, buf);
8568 WireFormat::write(&self.accuracy, buf);
8569 WireFormat::write(&self.n_sats, buf);
8570 WireFormat::write(&self.flags, buf);
8571 }
8572 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
8573 MsgVelEcef {
8574 sender_id: None,
8575 tow: WireFormat::parse_unchecked(buf),
8576 x: WireFormat::parse_unchecked(buf),
8577 y: WireFormat::parse_unchecked(buf),
8578 z: WireFormat::parse_unchecked(buf),
8579 accuracy: WireFormat::parse_unchecked(buf),
8580 n_sats: WireFormat::parse_unchecked(buf),
8581 flags: WireFormat::parse_unchecked(buf),
8582 }
8583 }
8584 }
8585
8586 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8588 pub enum TypeOfReportedTow {
8589 TimeOfMeasurement = 0,
8591
8592 Other = 1,
8594 }
8595
8596 impl std::fmt::Display for TypeOfReportedTow {
8597 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8598 match self {
8599 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
8600 TypeOfReportedTow::Other => f.write_str("Other"),
8601 }
8602 }
8603 }
8604
8605 impl TryFrom<u8> for TypeOfReportedTow {
8606 type Error = u8;
8607 fn try_from(i: u8) -> Result<Self, u8> {
8608 match i {
8609 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
8610 1 => Ok(TypeOfReportedTow::Other),
8611 i => Err(i),
8612 }
8613 }
8614 }
8615
8616 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8618 pub enum InsNavigationMode {
8619 None = 0,
8621
8622 InsUsed = 1,
8624 }
8625
8626 impl std::fmt::Display for InsNavigationMode {
8627 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8628 match self {
8629 InsNavigationMode::None => f.write_str("None"),
8630 InsNavigationMode::InsUsed => f.write_str("INS used"),
8631 }
8632 }
8633 }
8634
8635 impl TryFrom<u8> for InsNavigationMode {
8636 type Error = u8;
8637 fn try_from(i: u8) -> Result<Self, u8> {
8638 match i {
8639 0 => Ok(InsNavigationMode::None),
8640 1 => Ok(InsNavigationMode::InsUsed),
8641 i => Err(i),
8642 }
8643 }
8644 }
8645
8646 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8648 pub enum VelocityMode {
8649 Invalid = 0,
8651
8652 MeasuredDopplerDerived = 1,
8654
8655 ComputedDopplerDerived = 2,
8657
8658 DeadReckoning = 3,
8660 }
8661
8662 impl std::fmt::Display for VelocityMode {
8663 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8664 match self {
8665 VelocityMode::Invalid => f.write_str("Invalid"),
8666 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
8667 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
8668 VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"),
8669 }
8670 }
8671 }
8672
8673 impl TryFrom<u8> for VelocityMode {
8674 type Error = u8;
8675 fn try_from(i: u8) -> Result<Self, u8> {
8676 match i {
8677 0 => Ok(VelocityMode::Invalid),
8678 1 => Ok(VelocityMode::MeasuredDopplerDerived),
8679 2 => Ok(VelocityMode::ComputedDopplerDerived),
8680 3 => Ok(VelocityMode::DeadReckoning),
8681 i => Err(i),
8682 }
8683 }
8684 }
8685}
8686
8687pub mod msg_vel_ecef_cov {
8688 #![allow(unused_imports)]
8689
8690 use super::*;
8691 use crate::messages::lib::*;
8692
8693 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8704 #[allow(clippy::derive_partial_eq_without_eq)]
8705 #[derive(Debug, PartialEq, Clone)]
8706 pub struct MsgVelEcefCov {
8707 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
8709 pub sender_id: Option<u16>,
8710 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
8712 pub tow: u32,
8713 #[cfg_attr(feature = "serde", serde(rename = "x"))]
8715 pub x: i32,
8716 #[cfg_attr(feature = "serde", serde(rename = "y"))]
8718 pub y: i32,
8719 #[cfg_attr(feature = "serde", serde(rename = "z"))]
8721 pub z: i32,
8722 #[cfg_attr(feature = "serde", serde(rename = "cov_x_x"))]
8724 pub cov_x_x: f32,
8725 #[cfg_attr(feature = "serde", serde(rename = "cov_x_y"))]
8727 pub cov_x_y: f32,
8728 #[cfg_attr(feature = "serde", serde(rename = "cov_x_z"))]
8730 pub cov_x_z: f32,
8731 #[cfg_attr(feature = "serde", serde(rename = "cov_y_y"))]
8733 pub cov_y_y: f32,
8734 #[cfg_attr(feature = "serde", serde(rename = "cov_y_z"))]
8736 pub cov_y_z: f32,
8737 #[cfg_attr(feature = "serde", serde(rename = "cov_z_z"))]
8739 pub cov_z_z: f32,
8740 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
8742 pub n_sats: u8,
8743 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
8745 pub flags: u8,
8746 }
8747
8748 impl MsgVelEcefCov {
8749 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
8755 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
8756 }
8757
8758 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
8760 set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5);
8761 }
8762
8763 pub fn ins_navigation_mode(&self) -> Result<InsNavigationMode, u8> {
8769 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
8770 }
8771
8772 pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) {
8774 set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3);
8775 }
8776
8777 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
8783 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
8784 }
8785
8786 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
8788 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
8789 }
8790 }
8791
8792 impl ConcreteMessage for MsgVelEcefCov {
8793 const MESSAGE_TYPE: u16 = 533;
8794 const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_COV";
8795 }
8796
8797 impl SbpMessage for MsgVelEcefCov {
8798 fn message_name(&self) -> &'static str {
8799 <Self as ConcreteMessage>::MESSAGE_NAME
8800 }
8801 fn message_type(&self) -> Option<u16> {
8802 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
8803 }
8804 fn sender_id(&self) -> Option<u16> {
8805 self.sender_id
8806 }
8807 fn set_sender_id(&mut self, new_id: u16) {
8808 self.sender_id = Some(new_id);
8809 }
8810 fn encoded_len(&self) -> usize {
8811 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
8812 }
8813 fn is_valid(&self) -> bool {
8814 true
8815 }
8816 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
8817 Ok(self)
8818 }
8819
8820 #[cfg(feature = "swiftnav")]
8821 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
8822 let tow_s = (self.tow as f64) / 1000.0;
8823 let gps_time = match time::GpsTime::new(0, tow_s) {
8824 Ok(gps_time) => gps_time.tow(),
8825 Err(e) => return Some(Err(e.into())),
8826 };
8827 Some(Ok(time::MessageTime::Rover(gps_time.into())))
8828 }
8829 }
8830
8831 impl FriendlyName for MsgVelEcefCov {
8832 fn friendly_name() -> &'static str {
8833 "VEL ECEF COV"
8834 }
8835 }
8836
8837 impl TryFrom<Sbp> for MsgVelEcefCov {
8838 type Error = TryFromSbpError;
8839 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
8840 match msg {
8841 Sbp::MsgVelEcefCov(m) => Ok(m),
8842 _ => Err(TryFromSbpError(msg)),
8843 }
8844 }
8845 }
8846
8847 impl WireFormat for MsgVelEcefCov {
8848 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
8849 + <i32 as WireFormat>::MIN_LEN
8850 + <i32 as WireFormat>::MIN_LEN
8851 + <i32 as WireFormat>::MIN_LEN
8852 + <f32 as WireFormat>::MIN_LEN
8853 + <f32 as WireFormat>::MIN_LEN
8854 + <f32 as WireFormat>::MIN_LEN
8855 + <f32 as WireFormat>::MIN_LEN
8856 + <f32 as WireFormat>::MIN_LEN
8857 + <f32 as WireFormat>::MIN_LEN
8858 + <u8 as WireFormat>::MIN_LEN
8859 + <u8 as WireFormat>::MIN_LEN;
8860 fn len(&self) -> usize {
8861 WireFormat::len(&self.tow)
8862 + WireFormat::len(&self.x)
8863 + WireFormat::len(&self.y)
8864 + WireFormat::len(&self.z)
8865 + WireFormat::len(&self.cov_x_x)
8866 + WireFormat::len(&self.cov_x_y)
8867 + WireFormat::len(&self.cov_x_z)
8868 + WireFormat::len(&self.cov_y_y)
8869 + WireFormat::len(&self.cov_y_z)
8870 + WireFormat::len(&self.cov_z_z)
8871 + WireFormat::len(&self.n_sats)
8872 + WireFormat::len(&self.flags)
8873 }
8874 fn write<B: BufMut>(&self, buf: &mut B) {
8875 WireFormat::write(&self.tow, buf);
8876 WireFormat::write(&self.x, buf);
8877 WireFormat::write(&self.y, buf);
8878 WireFormat::write(&self.z, buf);
8879 WireFormat::write(&self.cov_x_x, buf);
8880 WireFormat::write(&self.cov_x_y, buf);
8881 WireFormat::write(&self.cov_x_z, buf);
8882 WireFormat::write(&self.cov_y_y, buf);
8883 WireFormat::write(&self.cov_y_z, buf);
8884 WireFormat::write(&self.cov_z_z, buf);
8885 WireFormat::write(&self.n_sats, buf);
8886 WireFormat::write(&self.flags, buf);
8887 }
8888 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
8889 MsgVelEcefCov {
8890 sender_id: None,
8891 tow: WireFormat::parse_unchecked(buf),
8892 x: WireFormat::parse_unchecked(buf),
8893 y: WireFormat::parse_unchecked(buf),
8894 z: WireFormat::parse_unchecked(buf),
8895 cov_x_x: WireFormat::parse_unchecked(buf),
8896 cov_x_y: WireFormat::parse_unchecked(buf),
8897 cov_x_z: WireFormat::parse_unchecked(buf),
8898 cov_y_y: WireFormat::parse_unchecked(buf),
8899 cov_y_z: WireFormat::parse_unchecked(buf),
8900 cov_z_z: WireFormat::parse_unchecked(buf),
8901 n_sats: WireFormat::parse_unchecked(buf),
8902 flags: WireFormat::parse_unchecked(buf),
8903 }
8904 }
8905 }
8906
8907 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8909 pub enum TypeOfReportedTow {
8910 TimeOfMeasurement = 0,
8912
8913 Other = 1,
8915 }
8916
8917 impl std::fmt::Display for TypeOfReportedTow {
8918 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8919 match self {
8920 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
8921 TypeOfReportedTow::Other => f.write_str("Other"),
8922 }
8923 }
8924 }
8925
8926 impl TryFrom<u8> for TypeOfReportedTow {
8927 type Error = u8;
8928 fn try_from(i: u8) -> Result<Self, u8> {
8929 match i {
8930 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
8931 1 => Ok(TypeOfReportedTow::Other),
8932 i => Err(i),
8933 }
8934 }
8935 }
8936
8937 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8939 pub enum InsNavigationMode {
8940 None = 0,
8942
8943 InsUsed = 1,
8945 }
8946
8947 impl std::fmt::Display for InsNavigationMode {
8948 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8949 match self {
8950 InsNavigationMode::None => f.write_str("None"),
8951 InsNavigationMode::InsUsed => f.write_str("INS used"),
8952 }
8953 }
8954 }
8955
8956 impl TryFrom<u8> for InsNavigationMode {
8957 type Error = u8;
8958 fn try_from(i: u8) -> Result<Self, u8> {
8959 match i {
8960 0 => Ok(InsNavigationMode::None),
8961 1 => Ok(InsNavigationMode::InsUsed),
8962 i => Err(i),
8963 }
8964 }
8965 }
8966
8967 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8969 pub enum VelocityMode {
8970 Invalid = 0,
8972
8973 MeasuredDopplerDerived = 1,
8975
8976 ComputedDopplerDerived = 2,
8978
8979 DeadReckoning = 3,
8981 }
8982
8983 impl std::fmt::Display for VelocityMode {
8984 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8985 match self {
8986 VelocityMode::Invalid => f.write_str("Invalid"),
8987 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
8988 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
8989 VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"),
8990 }
8991 }
8992 }
8993
8994 impl TryFrom<u8> for VelocityMode {
8995 type Error = u8;
8996 fn try_from(i: u8) -> Result<Self, u8> {
8997 match i {
8998 0 => Ok(VelocityMode::Invalid),
8999 1 => Ok(VelocityMode::MeasuredDopplerDerived),
9000 2 => Ok(VelocityMode::ComputedDopplerDerived),
9001 3 => Ok(VelocityMode::DeadReckoning),
9002 i => Err(i),
9003 }
9004 }
9005 }
9006}
9007
9008pub mod msg_vel_ecef_cov_gnss {
9009 #![allow(unused_imports)]
9010
9011 use super::*;
9012 use crate::messages::lib::*;
9013
9014 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9024 #[allow(clippy::derive_partial_eq_without_eq)]
9025 #[derive(Debug, PartialEq, Clone)]
9026 pub struct MsgVelEcefCovGnss {
9027 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
9029 pub sender_id: Option<u16>,
9030 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
9032 pub tow: u32,
9033 #[cfg_attr(feature = "serde", serde(rename = "x"))]
9035 pub x: i32,
9036 #[cfg_attr(feature = "serde", serde(rename = "y"))]
9038 pub y: i32,
9039 #[cfg_attr(feature = "serde", serde(rename = "z"))]
9041 pub z: i32,
9042 #[cfg_attr(feature = "serde", serde(rename = "cov_x_x"))]
9044 pub cov_x_x: f32,
9045 #[cfg_attr(feature = "serde", serde(rename = "cov_x_y"))]
9047 pub cov_x_y: f32,
9048 #[cfg_attr(feature = "serde", serde(rename = "cov_x_z"))]
9050 pub cov_x_z: f32,
9051 #[cfg_attr(feature = "serde", serde(rename = "cov_y_y"))]
9053 pub cov_y_y: f32,
9054 #[cfg_attr(feature = "serde", serde(rename = "cov_y_z"))]
9056 pub cov_y_z: f32,
9057 #[cfg_attr(feature = "serde", serde(rename = "cov_z_z"))]
9059 pub cov_z_z: f32,
9060 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
9062 pub n_sats: u8,
9063 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
9065 pub flags: u8,
9066 }
9067
9068 impl MsgVelEcefCovGnss {
9069 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
9075 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
9076 }
9077
9078 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
9080 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
9081 }
9082 }
9083
9084 impl ConcreteMessage for MsgVelEcefCovGnss {
9085 const MESSAGE_TYPE: u16 = 565;
9086 const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_COV_GNSS";
9087 }
9088
9089 impl SbpMessage for MsgVelEcefCovGnss {
9090 fn message_name(&self) -> &'static str {
9091 <Self as ConcreteMessage>::MESSAGE_NAME
9092 }
9093 fn message_type(&self) -> Option<u16> {
9094 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
9095 }
9096 fn sender_id(&self) -> Option<u16> {
9097 self.sender_id
9098 }
9099 fn set_sender_id(&mut self, new_id: u16) {
9100 self.sender_id = Some(new_id);
9101 }
9102 fn encoded_len(&self) -> usize {
9103 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
9104 }
9105 fn is_valid(&self) -> bool {
9106 true
9107 }
9108 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
9109 Ok(self)
9110 }
9111
9112 #[cfg(feature = "swiftnav")]
9113 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
9114 let tow_s = (self.tow as f64) / 1000.0;
9115 let gps_time = match time::GpsTime::new(0, tow_s) {
9116 Ok(gps_time) => gps_time.tow(),
9117 Err(e) => return Some(Err(e.into())),
9118 };
9119 Some(Ok(time::MessageTime::Rover(gps_time.into())))
9120 }
9121 }
9122
9123 impl FriendlyName for MsgVelEcefCovGnss {
9124 fn friendly_name() -> &'static str {
9125 "VEL ECEF COV GNSS-only"
9126 }
9127 }
9128
9129 impl TryFrom<Sbp> for MsgVelEcefCovGnss {
9130 type Error = TryFromSbpError;
9131 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
9132 match msg {
9133 Sbp::MsgVelEcefCovGnss(m) => Ok(m),
9134 _ => Err(TryFromSbpError(msg)),
9135 }
9136 }
9137 }
9138
9139 impl WireFormat for MsgVelEcefCovGnss {
9140 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
9141 + <i32 as WireFormat>::MIN_LEN
9142 + <i32 as WireFormat>::MIN_LEN
9143 + <i32 as WireFormat>::MIN_LEN
9144 + <f32 as WireFormat>::MIN_LEN
9145 + <f32 as WireFormat>::MIN_LEN
9146 + <f32 as WireFormat>::MIN_LEN
9147 + <f32 as WireFormat>::MIN_LEN
9148 + <f32 as WireFormat>::MIN_LEN
9149 + <f32 as WireFormat>::MIN_LEN
9150 + <u8 as WireFormat>::MIN_LEN
9151 + <u8 as WireFormat>::MIN_LEN;
9152 fn len(&self) -> usize {
9153 WireFormat::len(&self.tow)
9154 + WireFormat::len(&self.x)
9155 + WireFormat::len(&self.y)
9156 + WireFormat::len(&self.z)
9157 + WireFormat::len(&self.cov_x_x)
9158 + WireFormat::len(&self.cov_x_y)
9159 + WireFormat::len(&self.cov_x_z)
9160 + WireFormat::len(&self.cov_y_y)
9161 + WireFormat::len(&self.cov_y_z)
9162 + WireFormat::len(&self.cov_z_z)
9163 + WireFormat::len(&self.n_sats)
9164 + WireFormat::len(&self.flags)
9165 }
9166 fn write<B: BufMut>(&self, buf: &mut B) {
9167 WireFormat::write(&self.tow, buf);
9168 WireFormat::write(&self.x, buf);
9169 WireFormat::write(&self.y, buf);
9170 WireFormat::write(&self.z, buf);
9171 WireFormat::write(&self.cov_x_x, buf);
9172 WireFormat::write(&self.cov_x_y, buf);
9173 WireFormat::write(&self.cov_x_z, buf);
9174 WireFormat::write(&self.cov_y_y, buf);
9175 WireFormat::write(&self.cov_y_z, buf);
9176 WireFormat::write(&self.cov_z_z, buf);
9177 WireFormat::write(&self.n_sats, buf);
9178 WireFormat::write(&self.flags, buf);
9179 }
9180 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
9181 MsgVelEcefCovGnss {
9182 sender_id: None,
9183 tow: WireFormat::parse_unchecked(buf),
9184 x: WireFormat::parse_unchecked(buf),
9185 y: WireFormat::parse_unchecked(buf),
9186 z: WireFormat::parse_unchecked(buf),
9187 cov_x_x: WireFormat::parse_unchecked(buf),
9188 cov_x_y: WireFormat::parse_unchecked(buf),
9189 cov_x_z: WireFormat::parse_unchecked(buf),
9190 cov_y_y: WireFormat::parse_unchecked(buf),
9191 cov_y_z: WireFormat::parse_unchecked(buf),
9192 cov_z_z: WireFormat::parse_unchecked(buf),
9193 n_sats: WireFormat::parse_unchecked(buf),
9194 flags: WireFormat::parse_unchecked(buf),
9195 }
9196 }
9197 }
9198
9199 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9201 pub enum VelocityMode {
9202 Invalid = 0,
9204
9205 MeasuredDopplerDerived = 1,
9207
9208 ComputedDopplerDerived = 2,
9210 }
9211
9212 impl std::fmt::Display for VelocityMode {
9213 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9214 match self {
9215 VelocityMode::Invalid => f.write_str("Invalid"),
9216 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
9217 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
9218 }
9219 }
9220 }
9221
9222 impl TryFrom<u8> for VelocityMode {
9223 type Error = u8;
9224 fn try_from(i: u8) -> Result<Self, u8> {
9225 match i {
9226 0 => Ok(VelocityMode::Invalid),
9227 1 => Ok(VelocityMode::MeasuredDopplerDerived),
9228 2 => Ok(VelocityMode::ComputedDopplerDerived),
9229 i => Err(i),
9230 }
9231 }
9232 }
9233}
9234
9235pub mod msg_vel_ecef_dep_a {
9236 #![allow(unused_imports)]
9237
9238 use super::*;
9239 use crate::messages::lib::*;
9240
9241 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9246 #[allow(clippy::derive_partial_eq_without_eq)]
9247 #[derive(Debug, PartialEq, Clone)]
9248 pub struct MsgVelEcefDepA {
9249 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
9251 pub sender_id: Option<u16>,
9252 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
9254 pub tow: u32,
9255 #[cfg_attr(feature = "serde", serde(rename = "x"))]
9257 pub x: i32,
9258 #[cfg_attr(feature = "serde", serde(rename = "y"))]
9260 pub y: i32,
9261 #[cfg_attr(feature = "serde", serde(rename = "z"))]
9263 pub z: i32,
9264 #[cfg_attr(feature = "serde", serde(rename = "accuracy"))]
9266 pub accuracy: u16,
9267 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
9269 pub n_sats: u8,
9270 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
9272 pub flags: u8,
9273 }
9274
9275 impl ConcreteMessage for MsgVelEcefDepA {
9276 const MESSAGE_TYPE: u16 = 516;
9277 const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_DEP_A";
9278 }
9279
9280 impl SbpMessage for MsgVelEcefDepA {
9281 fn message_name(&self) -> &'static str {
9282 <Self as ConcreteMessage>::MESSAGE_NAME
9283 }
9284 fn message_type(&self) -> Option<u16> {
9285 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
9286 }
9287 fn sender_id(&self) -> Option<u16> {
9288 self.sender_id
9289 }
9290 fn set_sender_id(&mut self, new_id: u16) {
9291 self.sender_id = Some(new_id);
9292 }
9293 fn encoded_len(&self) -> usize {
9294 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
9295 }
9296 fn is_valid(&self) -> bool {
9297 true
9298 }
9299 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
9300 Ok(self)
9301 }
9302
9303 #[cfg(feature = "swiftnav")]
9304 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
9305 let tow_s = (self.tow as f64) / 1000.0;
9306 let gps_time = match time::GpsTime::new(0, tow_s) {
9307 Ok(gps_time) => gps_time.tow(),
9308 Err(e) => return Some(Err(e.into())),
9309 };
9310 Some(Ok(time::MessageTime::Rover(gps_time.into())))
9311 }
9312 }
9313
9314 impl FriendlyName for MsgVelEcefDepA {
9315 fn friendly_name() -> &'static str {
9316 "VEL ECEF DEP A"
9317 }
9318 }
9319
9320 impl TryFrom<Sbp> for MsgVelEcefDepA {
9321 type Error = TryFromSbpError;
9322 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
9323 match msg {
9324 Sbp::MsgVelEcefDepA(m) => Ok(m),
9325 _ => Err(TryFromSbpError(msg)),
9326 }
9327 }
9328 }
9329
9330 impl WireFormat for MsgVelEcefDepA {
9331 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
9332 + <i32 as WireFormat>::MIN_LEN
9333 + <i32 as WireFormat>::MIN_LEN
9334 + <i32 as WireFormat>::MIN_LEN
9335 + <u16 as WireFormat>::MIN_LEN
9336 + <u8 as WireFormat>::MIN_LEN
9337 + <u8 as WireFormat>::MIN_LEN;
9338 fn len(&self) -> usize {
9339 WireFormat::len(&self.tow)
9340 + WireFormat::len(&self.x)
9341 + WireFormat::len(&self.y)
9342 + WireFormat::len(&self.z)
9343 + WireFormat::len(&self.accuracy)
9344 + WireFormat::len(&self.n_sats)
9345 + WireFormat::len(&self.flags)
9346 }
9347 fn write<B: BufMut>(&self, buf: &mut B) {
9348 WireFormat::write(&self.tow, buf);
9349 WireFormat::write(&self.x, buf);
9350 WireFormat::write(&self.y, buf);
9351 WireFormat::write(&self.z, buf);
9352 WireFormat::write(&self.accuracy, buf);
9353 WireFormat::write(&self.n_sats, buf);
9354 WireFormat::write(&self.flags, buf);
9355 }
9356 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
9357 MsgVelEcefDepA {
9358 sender_id: None,
9359 tow: WireFormat::parse_unchecked(buf),
9360 x: WireFormat::parse_unchecked(buf),
9361 y: WireFormat::parse_unchecked(buf),
9362 z: WireFormat::parse_unchecked(buf),
9363 accuracy: WireFormat::parse_unchecked(buf),
9364 n_sats: WireFormat::parse_unchecked(buf),
9365 flags: WireFormat::parse_unchecked(buf),
9366 }
9367 }
9368 }
9369}
9370
9371pub mod msg_vel_ecef_gnss {
9372 #![allow(unused_imports)]
9373
9374 use super::*;
9375 use crate::messages::lib::*;
9376
9377 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9387 #[allow(clippy::derive_partial_eq_without_eq)]
9388 #[derive(Debug, PartialEq, Clone)]
9389 pub struct MsgVelEcefGnss {
9390 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
9392 pub sender_id: Option<u16>,
9393 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
9395 pub tow: u32,
9396 #[cfg_attr(feature = "serde", serde(rename = "x"))]
9398 pub x: i32,
9399 #[cfg_attr(feature = "serde", serde(rename = "y"))]
9401 pub y: i32,
9402 #[cfg_attr(feature = "serde", serde(rename = "z"))]
9404 pub z: i32,
9405 #[cfg_attr(feature = "serde", serde(rename = "accuracy"))]
9407 pub accuracy: u16,
9408 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
9410 pub n_sats: u8,
9411 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
9413 pub flags: u8,
9414 }
9415
9416 impl MsgVelEcefGnss {
9417 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
9423 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
9424 }
9425
9426 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
9428 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
9429 }
9430 }
9431
9432 impl ConcreteMessage for MsgVelEcefGnss {
9433 const MESSAGE_TYPE: u16 = 557;
9434 const MESSAGE_NAME: &'static str = "MSG_VEL_ECEF_GNSS";
9435 }
9436
9437 impl SbpMessage for MsgVelEcefGnss {
9438 fn message_name(&self) -> &'static str {
9439 <Self as ConcreteMessage>::MESSAGE_NAME
9440 }
9441 fn message_type(&self) -> Option<u16> {
9442 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
9443 }
9444 fn sender_id(&self) -> Option<u16> {
9445 self.sender_id
9446 }
9447 fn set_sender_id(&mut self, new_id: u16) {
9448 self.sender_id = Some(new_id);
9449 }
9450 fn encoded_len(&self) -> usize {
9451 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
9452 }
9453 fn is_valid(&self) -> bool {
9454 true
9455 }
9456 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
9457 Ok(self)
9458 }
9459
9460 #[cfg(feature = "swiftnav")]
9461 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
9462 let tow_s = (self.tow as f64) / 1000.0;
9463 let gps_time = match time::GpsTime::new(0, tow_s) {
9464 Ok(gps_time) => gps_time.tow(),
9465 Err(e) => return Some(Err(e.into())),
9466 };
9467 Some(Ok(time::MessageTime::Rover(gps_time.into())))
9468 }
9469 }
9470
9471 impl FriendlyName for MsgVelEcefGnss {
9472 fn friendly_name() -> &'static str {
9473 "VEL ECEF GNSS-only"
9474 }
9475 }
9476
9477 impl TryFrom<Sbp> for MsgVelEcefGnss {
9478 type Error = TryFromSbpError;
9479 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
9480 match msg {
9481 Sbp::MsgVelEcefGnss(m) => Ok(m),
9482 _ => Err(TryFromSbpError(msg)),
9483 }
9484 }
9485 }
9486
9487 impl WireFormat for MsgVelEcefGnss {
9488 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
9489 + <i32 as WireFormat>::MIN_LEN
9490 + <i32 as WireFormat>::MIN_LEN
9491 + <i32 as WireFormat>::MIN_LEN
9492 + <u16 as WireFormat>::MIN_LEN
9493 + <u8 as WireFormat>::MIN_LEN
9494 + <u8 as WireFormat>::MIN_LEN;
9495 fn len(&self) -> usize {
9496 WireFormat::len(&self.tow)
9497 + WireFormat::len(&self.x)
9498 + WireFormat::len(&self.y)
9499 + WireFormat::len(&self.z)
9500 + WireFormat::len(&self.accuracy)
9501 + WireFormat::len(&self.n_sats)
9502 + WireFormat::len(&self.flags)
9503 }
9504 fn write<B: BufMut>(&self, buf: &mut B) {
9505 WireFormat::write(&self.tow, buf);
9506 WireFormat::write(&self.x, buf);
9507 WireFormat::write(&self.y, buf);
9508 WireFormat::write(&self.z, buf);
9509 WireFormat::write(&self.accuracy, buf);
9510 WireFormat::write(&self.n_sats, buf);
9511 WireFormat::write(&self.flags, buf);
9512 }
9513 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
9514 MsgVelEcefGnss {
9515 sender_id: None,
9516 tow: WireFormat::parse_unchecked(buf),
9517 x: WireFormat::parse_unchecked(buf),
9518 y: WireFormat::parse_unchecked(buf),
9519 z: WireFormat::parse_unchecked(buf),
9520 accuracy: WireFormat::parse_unchecked(buf),
9521 n_sats: WireFormat::parse_unchecked(buf),
9522 flags: WireFormat::parse_unchecked(buf),
9523 }
9524 }
9525 }
9526
9527 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9529 pub enum VelocityMode {
9530 Invalid = 0,
9532
9533 MeasuredDopplerDerived = 1,
9535
9536 ComputedDopplerDerived = 2,
9538 }
9539
9540 impl std::fmt::Display for VelocityMode {
9541 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9542 match self {
9543 VelocityMode::Invalid => f.write_str("Invalid"),
9544 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
9545 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
9546 }
9547 }
9548 }
9549
9550 impl TryFrom<u8> for VelocityMode {
9551 type Error = u8;
9552 fn try_from(i: u8) -> Result<Self, u8> {
9553 match i {
9554 0 => Ok(VelocityMode::Invalid),
9555 1 => Ok(VelocityMode::MeasuredDopplerDerived),
9556 2 => Ok(VelocityMode::ComputedDopplerDerived),
9557 i => Err(i),
9558 }
9559 }
9560 }
9561}
9562
9563pub mod msg_vel_ned {
9564 #![allow(unused_imports)]
9565
9566 use super::*;
9567 use crate::messages::lib::*;
9568
9569 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9581 #[allow(clippy::derive_partial_eq_without_eq)]
9582 #[derive(Debug, PartialEq, Clone)]
9583 pub struct MsgVelNed {
9584 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
9586 pub sender_id: Option<u16>,
9587 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
9589 pub tow: u32,
9590 #[cfg_attr(feature = "serde", serde(rename = "n"))]
9592 pub n: i32,
9593 #[cfg_attr(feature = "serde", serde(rename = "e"))]
9595 pub e: i32,
9596 #[cfg_attr(feature = "serde", serde(rename = "d"))]
9598 pub d: i32,
9599 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
9601 pub h_accuracy: u16,
9602 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
9604 pub v_accuracy: u16,
9605 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
9607 pub n_sats: u8,
9608 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
9610 pub flags: u8,
9611 }
9612
9613 impl MsgVelNed {
9614 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
9620 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
9621 }
9622
9623 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
9625 set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5);
9626 }
9627
9628 pub fn ins_navigation_mode(&self) -> Result<InsNavigationMode, u8> {
9634 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
9635 }
9636
9637 pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) {
9639 set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3);
9640 }
9641
9642 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
9648 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
9649 }
9650
9651 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
9653 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
9654 }
9655 }
9656
9657 impl ConcreteMessage for MsgVelNed {
9658 const MESSAGE_TYPE: u16 = 526;
9659 const MESSAGE_NAME: &'static str = "MSG_VEL_NED";
9660 }
9661
9662 impl SbpMessage for MsgVelNed {
9663 fn message_name(&self) -> &'static str {
9664 <Self as ConcreteMessage>::MESSAGE_NAME
9665 }
9666 fn message_type(&self) -> Option<u16> {
9667 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
9668 }
9669 fn sender_id(&self) -> Option<u16> {
9670 self.sender_id
9671 }
9672 fn set_sender_id(&mut self, new_id: u16) {
9673 self.sender_id = Some(new_id);
9674 }
9675 fn encoded_len(&self) -> usize {
9676 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
9677 }
9678 fn is_valid(&self) -> bool {
9679 true
9680 }
9681 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
9682 Ok(self)
9683 }
9684
9685 #[cfg(feature = "swiftnav")]
9686 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
9687 let tow_s = (self.tow as f64) / 1000.0;
9688 let gps_time = match time::GpsTime::new(0, tow_s) {
9689 Ok(gps_time) => gps_time.tow(),
9690 Err(e) => return Some(Err(e.into())),
9691 };
9692 Some(Ok(time::MessageTime::Rover(gps_time.into())))
9693 }
9694 }
9695
9696 impl FriendlyName for MsgVelNed {
9697 fn friendly_name() -> &'static str {
9698 "VEL NED"
9699 }
9700 }
9701
9702 impl TryFrom<Sbp> for MsgVelNed {
9703 type Error = TryFromSbpError;
9704 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
9705 match msg {
9706 Sbp::MsgVelNed(m) => Ok(m),
9707 _ => Err(TryFromSbpError(msg)),
9708 }
9709 }
9710 }
9711
9712 impl WireFormat for MsgVelNed {
9713 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
9714 + <i32 as WireFormat>::MIN_LEN
9715 + <i32 as WireFormat>::MIN_LEN
9716 + <i32 as WireFormat>::MIN_LEN
9717 + <u16 as WireFormat>::MIN_LEN
9718 + <u16 as WireFormat>::MIN_LEN
9719 + <u8 as WireFormat>::MIN_LEN
9720 + <u8 as WireFormat>::MIN_LEN;
9721 fn len(&self) -> usize {
9722 WireFormat::len(&self.tow)
9723 + WireFormat::len(&self.n)
9724 + WireFormat::len(&self.e)
9725 + WireFormat::len(&self.d)
9726 + WireFormat::len(&self.h_accuracy)
9727 + WireFormat::len(&self.v_accuracy)
9728 + WireFormat::len(&self.n_sats)
9729 + WireFormat::len(&self.flags)
9730 }
9731 fn write<B: BufMut>(&self, buf: &mut B) {
9732 WireFormat::write(&self.tow, buf);
9733 WireFormat::write(&self.n, buf);
9734 WireFormat::write(&self.e, buf);
9735 WireFormat::write(&self.d, buf);
9736 WireFormat::write(&self.h_accuracy, buf);
9737 WireFormat::write(&self.v_accuracy, buf);
9738 WireFormat::write(&self.n_sats, buf);
9739 WireFormat::write(&self.flags, buf);
9740 }
9741 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
9742 MsgVelNed {
9743 sender_id: None,
9744 tow: WireFormat::parse_unchecked(buf),
9745 n: WireFormat::parse_unchecked(buf),
9746 e: WireFormat::parse_unchecked(buf),
9747 d: WireFormat::parse_unchecked(buf),
9748 h_accuracy: WireFormat::parse_unchecked(buf),
9749 v_accuracy: WireFormat::parse_unchecked(buf),
9750 n_sats: WireFormat::parse_unchecked(buf),
9751 flags: WireFormat::parse_unchecked(buf),
9752 }
9753 }
9754 }
9755
9756 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9758 pub enum TypeOfReportedTow {
9759 TimeOfMeasurement = 0,
9761
9762 Other = 1,
9764 }
9765
9766 impl std::fmt::Display for TypeOfReportedTow {
9767 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9768 match self {
9769 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
9770 TypeOfReportedTow::Other => f.write_str("Other"),
9771 }
9772 }
9773 }
9774
9775 impl TryFrom<u8> for TypeOfReportedTow {
9776 type Error = u8;
9777 fn try_from(i: u8) -> Result<Self, u8> {
9778 match i {
9779 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
9780 1 => Ok(TypeOfReportedTow::Other),
9781 i => Err(i),
9782 }
9783 }
9784 }
9785
9786 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9788 pub enum InsNavigationMode {
9789 None = 0,
9791
9792 InsUsed = 1,
9794 }
9795
9796 impl std::fmt::Display for InsNavigationMode {
9797 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9798 match self {
9799 InsNavigationMode::None => f.write_str("None"),
9800 InsNavigationMode::InsUsed => f.write_str("INS used"),
9801 }
9802 }
9803 }
9804
9805 impl TryFrom<u8> for InsNavigationMode {
9806 type Error = u8;
9807 fn try_from(i: u8) -> Result<Self, u8> {
9808 match i {
9809 0 => Ok(InsNavigationMode::None),
9810 1 => Ok(InsNavigationMode::InsUsed),
9811 i => Err(i),
9812 }
9813 }
9814 }
9815
9816 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9818 pub enum VelocityMode {
9819 Invalid = 0,
9821
9822 MeasuredDopplerDerived = 1,
9824
9825 ComputedDopplerDerived = 2,
9827
9828 DeadReckoning = 3,
9830 }
9831
9832 impl std::fmt::Display for VelocityMode {
9833 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9834 match self {
9835 VelocityMode::Invalid => f.write_str("Invalid"),
9836 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
9837 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
9838 VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"),
9839 }
9840 }
9841 }
9842
9843 impl TryFrom<u8> for VelocityMode {
9844 type Error = u8;
9845 fn try_from(i: u8) -> Result<Self, u8> {
9846 match i {
9847 0 => Ok(VelocityMode::Invalid),
9848 1 => Ok(VelocityMode::MeasuredDopplerDerived),
9849 2 => Ok(VelocityMode::ComputedDopplerDerived),
9850 3 => Ok(VelocityMode::DeadReckoning),
9851 i => Err(i),
9852 }
9853 }
9854 }
9855}
9856
9857pub mod msg_vel_ned_cov {
9858 #![allow(unused_imports)]
9859
9860 use super::*;
9861 use crate::messages::lib::*;
9862
9863 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9877 #[allow(clippy::derive_partial_eq_without_eq)]
9878 #[derive(Debug, PartialEq, Clone)]
9879 pub struct MsgVelNedCov {
9880 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
9882 pub sender_id: Option<u16>,
9883 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
9885 pub tow: u32,
9886 #[cfg_attr(feature = "serde", serde(rename = "n"))]
9888 pub n: i32,
9889 #[cfg_attr(feature = "serde", serde(rename = "e"))]
9891 pub e: i32,
9892 #[cfg_attr(feature = "serde", serde(rename = "d"))]
9894 pub d: i32,
9895 #[cfg_attr(feature = "serde", serde(rename = "cov_n_n"))]
9897 pub cov_n_n: f32,
9898 #[cfg_attr(feature = "serde", serde(rename = "cov_n_e"))]
9900 pub cov_n_e: f32,
9901 #[cfg_attr(feature = "serde", serde(rename = "cov_n_d"))]
9903 pub cov_n_d: f32,
9904 #[cfg_attr(feature = "serde", serde(rename = "cov_e_e"))]
9906 pub cov_e_e: f32,
9907 #[cfg_attr(feature = "serde", serde(rename = "cov_e_d"))]
9909 pub cov_e_d: f32,
9910 #[cfg_attr(feature = "serde", serde(rename = "cov_d_d"))]
9912 pub cov_d_d: f32,
9913 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
9915 pub n_sats: u8,
9916 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
9918 pub flags: u8,
9919 }
9920
9921 impl MsgVelNedCov {
9922 pub fn type_of_reported_tow(&self) -> Result<TypeOfReportedTow, u8> {
9928 get_bit_range!(self.flags, u8, u8, 5, 5).try_into()
9929 }
9930
9931 pub fn set_type_of_reported_tow(&mut self, type_of_reported_tow: TypeOfReportedTow) {
9933 set_bit_range!(&mut self.flags, type_of_reported_tow, u8, u8, 5, 5);
9934 }
9935
9936 pub fn ins_navigation_mode(&self) -> Result<InsNavigationMode, u8> {
9942 get_bit_range!(self.flags, u8, u8, 4, 3).try_into()
9943 }
9944
9945 pub fn set_ins_navigation_mode(&mut self, ins_navigation_mode: InsNavigationMode) {
9947 set_bit_range!(&mut self.flags, ins_navigation_mode, u8, u8, 4, 3);
9948 }
9949
9950 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
9956 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
9957 }
9958
9959 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
9961 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
9962 }
9963 }
9964
9965 impl ConcreteMessage for MsgVelNedCov {
9966 const MESSAGE_TYPE: u16 = 530;
9967 const MESSAGE_NAME: &'static str = "MSG_VEL_NED_COV";
9968 }
9969
9970 impl SbpMessage for MsgVelNedCov {
9971 fn message_name(&self) -> &'static str {
9972 <Self as ConcreteMessage>::MESSAGE_NAME
9973 }
9974 fn message_type(&self) -> Option<u16> {
9975 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
9976 }
9977 fn sender_id(&self) -> Option<u16> {
9978 self.sender_id
9979 }
9980 fn set_sender_id(&mut self, new_id: u16) {
9981 self.sender_id = Some(new_id);
9982 }
9983 fn encoded_len(&self) -> usize {
9984 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
9985 }
9986 fn is_valid(&self) -> bool {
9987 true
9988 }
9989 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
9990 Ok(self)
9991 }
9992
9993 #[cfg(feature = "swiftnav")]
9994 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
9995 let tow_s = (self.tow as f64) / 1000.0;
9996 let gps_time = match time::GpsTime::new(0, tow_s) {
9997 Ok(gps_time) => gps_time.tow(),
9998 Err(e) => return Some(Err(e.into())),
9999 };
10000 Some(Ok(time::MessageTime::Rover(gps_time.into())))
10001 }
10002 }
10003
10004 impl FriendlyName for MsgVelNedCov {
10005 fn friendly_name() -> &'static str {
10006 "VEL NED COV"
10007 }
10008 }
10009
10010 impl TryFrom<Sbp> for MsgVelNedCov {
10011 type Error = TryFromSbpError;
10012 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
10013 match msg {
10014 Sbp::MsgVelNedCov(m) => Ok(m),
10015 _ => Err(TryFromSbpError(msg)),
10016 }
10017 }
10018 }
10019
10020 impl WireFormat for MsgVelNedCov {
10021 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
10022 + <i32 as WireFormat>::MIN_LEN
10023 + <i32 as WireFormat>::MIN_LEN
10024 + <i32 as WireFormat>::MIN_LEN
10025 + <f32 as WireFormat>::MIN_LEN
10026 + <f32 as WireFormat>::MIN_LEN
10027 + <f32 as WireFormat>::MIN_LEN
10028 + <f32 as WireFormat>::MIN_LEN
10029 + <f32 as WireFormat>::MIN_LEN
10030 + <f32 as WireFormat>::MIN_LEN
10031 + <u8 as WireFormat>::MIN_LEN
10032 + <u8 as WireFormat>::MIN_LEN;
10033 fn len(&self) -> usize {
10034 WireFormat::len(&self.tow)
10035 + WireFormat::len(&self.n)
10036 + WireFormat::len(&self.e)
10037 + WireFormat::len(&self.d)
10038 + WireFormat::len(&self.cov_n_n)
10039 + WireFormat::len(&self.cov_n_e)
10040 + WireFormat::len(&self.cov_n_d)
10041 + WireFormat::len(&self.cov_e_e)
10042 + WireFormat::len(&self.cov_e_d)
10043 + WireFormat::len(&self.cov_d_d)
10044 + WireFormat::len(&self.n_sats)
10045 + WireFormat::len(&self.flags)
10046 }
10047 fn write<B: BufMut>(&self, buf: &mut B) {
10048 WireFormat::write(&self.tow, buf);
10049 WireFormat::write(&self.n, buf);
10050 WireFormat::write(&self.e, buf);
10051 WireFormat::write(&self.d, buf);
10052 WireFormat::write(&self.cov_n_n, buf);
10053 WireFormat::write(&self.cov_n_e, buf);
10054 WireFormat::write(&self.cov_n_d, buf);
10055 WireFormat::write(&self.cov_e_e, buf);
10056 WireFormat::write(&self.cov_e_d, buf);
10057 WireFormat::write(&self.cov_d_d, buf);
10058 WireFormat::write(&self.n_sats, buf);
10059 WireFormat::write(&self.flags, buf);
10060 }
10061 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
10062 MsgVelNedCov {
10063 sender_id: None,
10064 tow: WireFormat::parse_unchecked(buf),
10065 n: WireFormat::parse_unchecked(buf),
10066 e: WireFormat::parse_unchecked(buf),
10067 d: WireFormat::parse_unchecked(buf),
10068 cov_n_n: WireFormat::parse_unchecked(buf),
10069 cov_n_e: WireFormat::parse_unchecked(buf),
10070 cov_n_d: WireFormat::parse_unchecked(buf),
10071 cov_e_e: WireFormat::parse_unchecked(buf),
10072 cov_e_d: WireFormat::parse_unchecked(buf),
10073 cov_d_d: WireFormat::parse_unchecked(buf),
10074 n_sats: WireFormat::parse_unchecked(buf),
10075 flags: WireFormat::parse_unchecked(buf),
10076 }
10077 }
10078 }
10079
10080 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10082 pub enum TypeOfReportedTow {
10083 TimeOfMeasurement = 0,
10085
10086 Other = 1,
10088 }
10089
10090 impl std::fmt::Display for TypeOfReportedTow {
10091 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10092 match self {
10093 TypeOfReportedTow::TimeOfMeasurement => f.write_str("Time of Measurement"),
10094 TypeOfReportedTow::Other => f.write_str("Other"),
10095 }
10096 }
10097 }
10098
10099 impl TryFrom<u8> for TypeOfReportedTow {
10100 type Error = u8;
10101 fn try_from(i: u8) -> Result<Self, u8> {
10102 match i {
10103 0 => Ok(TypeOfReportedTow::TimeOfMeasurement),
10104 1 => Ok(TypeOfReportedTow::Other),
10105 i => Err(i),
10106 }
10107 }
10108 }
10109
10110 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10112 pub enum InsNavigationMode {
10113 None = 0,
10115
10116 InsUsed = 1,
10118 }
10119
10120 impl std::fmt::Display for InsNavigationMode {
10121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10122 match self {
10123 InsNavigationMode::None => f.write_str("None"),
10124 InsNavigationMode::InsUsed => f.write_str("INS used"),
10125 }
10126 }
10127 }
10128
10129 impl TryFrom<u8> for InsNavigationMode {
10130 type Error = u8;
10131 fn try_from(i: u8) -> Result<Self, u8> {
10132 match i {
10133 0 => Ok(InsNavigationMode::None),
10134 1 => Ok(InsNavigationMode::InsUsed),
10135 i => Err(i),
10136 }
10137 }
10138 }
10139
10140 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10142 pub enum VelocityMode {
10143 Invalid = 0,
10145
10146 MeasuredDopplerDerived = 1,
10148
10149 ComputedDopplerDerived = 2,
10151
10152 DeadReckoning = 3,
10154 }
10155
10156 impl std::fmt::Display for VelocityMode {
10157 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10158 match self {
10159 VelocityMode::Invalid => f.write_str("Invalid"),
10160 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
10161 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
10162 VelocityMode::DeadReckoning => f.write_str("Dead Reckoning"),
10163 }
10164 }
10165 }
10166
10167 impl TryFrom<u8> for VelocityMode {
10168 type Error = u8;
10169 fn try_from(i: u8) -> Result<Self, u8> {
10170 match i {
10171 0 => Ok(VelocityMode::Invalid),
10172 1 => Ok(VelocityMode::MeasuredDopplerDerived),
10173 2 => Ok(VelocityMode::ComputedDopplerDerived),
10174 3 => Ok(VelocityMode::DeadReckoning),
10175 i => Err(i),
10176 }
10177 }
10178 }
10179}
10180
10181pub mod msg_vel_ned_cov_gnss {
10182 #![allow(unused_imports)]
10183
10184 use super::*;
10185 use crate::messages::lib::*;
10186
10187 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10200 #[allow(clippy::derive_partial_eq_without_eq)]
10201 #[derive(Debug, PartialEq, Clone)]
10202 pub struct MsgVelNedCovGnss {
10203 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
10205 pub sender_id: Option<u16>,
10206 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
10208 pub tow: u32,
10209 #[cfg_attr(feature = "serde", serde(rename = "n"))]
10211 pub n: i32,
10212 #[cfg_attr(feature = "serde", serde(rename = "e"))]
10214 pub e: i32,
10215 #[cfg_attr(feature = "serde", serde(rename = "d"))]
10217 pub d: i32,
10218 #[cfg_attr(feature = "serde", serde(rename = "cov_n_n"))]
10220 pub cov_n_n: f32,
10221 #[cfg_attr(feature = "serde", serde(rename = "cov_n_e"))]
10223 pub cov_n_e: f32,
10224 #[cfg_attr(feature = "serde", serde(rename = "cov_n_d"))]
10226 pub cov_n_d: f32,
10227 #[cfg_attr(feature = "serde", serde(rename = "cov_e_e"))]
10229 pub cov_e_e: f32,
10230 #[cfg_attr(feature = "serde", serde(rename = "cov_e_d"))]
10232 pub cov_e_d: f32,
10233 #[cfg_attr(feature = "serde", serde(rename = "cov_d_d"))]
10235 pub cov_d_d: f32,
10236 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
10238 pub n_sats: u8,
10239 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
10241 pub flags: u8,
10242 }
10243
10244 impl MsgVelNedCovGnss {
10245 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
10251 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
10252 }
10253
10254 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
10256 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
10257 }
10258 }
10259
10260 impl ConcreteMessage for MsgVelNedCovGnss {
10261 const MESSAGE_TYPE: u16 = 562;
10262 const MESSAGE_NAME: &'static str = "MSG_VEL_NED_COV_GNSS";
10263 }
10264
10265 impl SbpMessage for MsgVelNedCovGnss {
10266 fn message_name(&self) -> &'static str {
10267 <Self as ConcreteMessage>::MESSAGE_NAME
10268 }
10269 fn message_type(&self) -> Option<u16> {
10270 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
10271 }
10272 fn sender_id(&self) -> Option<u16> {
10273 self.sender_id
10274 }
10275 fn set_sender_id(&mut self, new_id: u16) {
10276 self.sender_id = Some(new_id);
10277 }
10278 fn encoded_len(&self) -> usize {
10279 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
10280 }
10281 fn is_valid(&self) -> bool {
10282 true
10283 }
10284 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
10285 Ok(self)
10286 }
10287
10288 #[cfg(feature = "swiftnav")]
10289 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
10290 let tow_s = (self.tow as f64) / 1000.0;
10291 let gps_time = match time::GpsTime::new(0, tow_s) {
10292 Ok(gps_time) => gps_time.tow(),
10293 Err(e) => return Some(Err(e.into())),
10294 };
10295 Some(Ok(time::MessageTime::Rover(gps_time.into())))
10296 }
10297 }
10298
10299 impl FriendlyName for MsgVelNedCovGnss {
10300 fn friendly_name() -> &'static str {
10301 "VEL NED COV GNSS-only"
10302 }
10303 }
10304
10305 impl TryFrom<Sbp> for MsgVelNedCovGnss {
10306 type Error = TryFromSbpError;
10307 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
10308 match msg {
10309 Sbp::MsgVelNedCovGnss(m) => Ok(m),
10310 _ => Err(TryFromSbpError(msg)),
10311 }
10312 }
10313 }
10314
10315 impl WireFormat for MsgVelNedCovGnss {
10316 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
10317 + <i32 as WireFormat>::MIN_LEN
10318 + <i32 as WireFormat>::MIN_LEN
10319 + <i32 as WireFormat>::MIN_LEN
10320 + <f32 as WireFormat>::MIN_LEN
10321 + <f32 as WireFormat>::MIN_LEN
10322 + <f32 as WireFormat>::MIN_LEN
10323 + <f32 as WireFormat>::MIN_LEN
10324 + <f32 as WireFormat>::MIN_LEN
10325 + <f32 as WireFormat>::MIN_LEN
10326 + <u8 as WireFormat>::MIN_LEN
10327 + <u8 as WireFormat>::MIN_LEN;
10328 fn len(&self) -> usize {
10329 WireFormat::len(&self.tow)
10330 + WireFormat::len(&self.n)
10331 + WireFormat::len(&self.e)
10332 + WireFormat::len(&self.d)
10333 + WireFormat::len(&self.cov_n_n)
10334 + WireFormat::len(&self.cov_n_e)
10335 + WireFormat::len(&self.cov_n_d)
10336 + WireFormat::len(&self.cov_e_e)
10337 + WireFormat::len(&self.cov_e_d)
10338 + WireFormat::len(&self.cov_d_d)
10339 + WireFormat::len(&self.n_sats)
10340 + WireFormat::len(&self.flags)
10341 }
10342 fn write<B: BufMut>(&self, buf: &mut B) {
10343 WireFormat::write(&self.tow, buf);
10344 WireFormat::write(&self.n, buf);
10345 WireFormat::write(&self.e, buf);
10346 WireFormat::write(&self.d, buf);
10347 WireFormat::write(&self.cov_n_n, buf);
10348 WireFormat::write(&self.cov_n_e, buf);
10349 WireFormat::write(&self.cov_n_d, buf);
10350 WireFormat::write(&self.cov_e_e, buf);
10351 WireFormat::write(&self.cov_e_d, buf);
10352 WireFormat::write(&self.cov_d_d, buf);
10353 WireFormat::write(&self.n_sats, buf);
10354 WireFormat::write(&self.flags, buf);
10355 }
10356 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
10357 MsgVelNedCovGnss {
10358 sender_id: None,
10359 tow: WireFormat::parse_unchecked(buf),
10360 n: WireFormat::parse_unchecked(buf),
10361 e: WireFormat::parse_unchecked(buf),
10362 d: WireFormat::parse_unchecked(buf),
10363 cov_n_n: WireFormat::parse_unchecked(buf),
10364 cov_n_e: WireFormat::parse_unchecked(buf),
10365 cov_n_d: WireFormat::parse_unchecked(buf),
10366 cov_e_e: WireFormat::parse_unchecked(buf),
10367 cov_e_d: WireFormat::parse_unchecked(buf),
10368 cov_d_d: WireFormat::parse_unchecked(buf),
10369 n_sats: WireFormat::parse_unchecked(buf),
10370 flags: WireFormat::parse_unchecked(buf),
10371 }
10372 }
10373 }
10374
10375 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10377 pub enum VelocityMode {
10378 Invalid = 0,
10380
10381 MeasuredDopplerDerived = 1,
10383
10384 ComputedDopplerDerived = 2,
10386 }
10387
10388 impl std::fmt::Display for VelocityMode {
10389 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10390 match self {
10391 VelocityMode::Invalid => f.write_str("Invalid"),
10392 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
10393 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
10394 }
10395 }
10396 }
10397
10398 impl TryFrom<u8> for VelocityMode {
10399 type Error = u8;
10400 fn try_from(i: u8) -> Result<Self, u8> {
10401 match i {
10402 0 => Ok(VelocityMode::Invalid),
10403 1 => Ok(VelocityMode::MeasuredDopplerDerived),
10404 2 => Ok(VelocityMode::ComputedDopplerDerived),
10405 i => Err(i),
10406 }
10407 }
10408 }
10409}
10410
10411pub mod msg_vel_ned_dep_a {
10412 #![allow(unused_imports)]
10413
10414 use super::*;
10415 use crate::messages::lib::*;
10416
10417 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10422 #[allow(clippy::derive_partial_eq_without_eq)]
10423 #[derive(Debug, PartialEq, Clone)]
10424 pub struct MsgVelNedDepA {
10425 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
10427 pub sender_id: Option<u16>,
10428 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
10430 pub tow: u32,
10431 #[cfg_attr(feature = "serde", serde(rename = "n"))]
10433 pub n: i32,
10434 #[cfg_attr(feature = "serde", serde(rename = "e"))]
10436 pub e: i32,
10437 #[cfg_attr(feature = "serde", serde(rename = "d"))]
10439 pub d: i32,
10440 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
10442 pub h_accuracy: u16,
10443 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
10445 pub v_accuracy: u16,
10446 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
10448 pub n_sats: u8,
10449 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
10451 pub flags: u8,
10452 }
10453
10454 impl ConcreteMessage for MsgVelNedDepA {
10455 const MESSAGE_TYPE: u16 = 517;
10456 const MESSAGE_NAME: &'static str = "MSG_VEL_NED_DEP_A";
10457 }
10458
10459 impl SbpMessage for MsgVelNedDepA {
10460 fn message_name(&self) -> &'static str {
10461 <Self as ConcreteMessage>::MESSAGE_NAME
10462 }
10463 fn message_type(&self) -> Option<u16> {
10464 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
10465 }
10466 fn sender_id(&self) -> Option<u16> {
10467 self.sender_id
10468 }
10469 fn set_sender_id(&mut self, new_id: u16) {
10470 self.sender_id = Some(new_id);
10471 }
10472 fn encoded_len(&self) -> usize {
10473 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
10474 }
10475 fn is_valid(&self) -> bool {
10476 true
10477 }
10478 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
10479 Ok(self)
10480 }
10481
10482 #[cfg(feature = "swiftnav")]
10483 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
10484 let tow_s = (self.tow as f64) / 1000.0;
10485 let gps_time = match time::GpsTime::new(0, tow_s) {
10486 Ok(gps_time) => gps_time.tow(),
10487 Err(e) => return Some(Err(e.into())),
10488 };
10489 Some(Ok(time::MessageTime::Rover(gps_time.into())))
10490 }
10491 }
10492
10493 impl FriendlyName for MsgVelNedDepA {
10494 fn friendly_name() -> &'static str {
10495 "VEL NED DEP A"
10496 }
10497 }
10498
10499 impl TryFrom<Sbp> for MsgVelNedDepA {
10500 type Error = TryFromSbpError;
10501 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
10502 match msg {
10503 Sbp::MsgVelNedDepA(m) => Ok(m),
10504 _ => Err(TryFromSbpError(msg)),
10505 }
10506 }
10507 }
10508
10509 impl WireFormat for MsgVelNedDepA {
10510 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
10511 + <i32 as WireFormat>::MIN_LEN
10512 + <i32 as WireFormat>::MIN_LEN
10513 + <i32 as WireFormat>::MIN_LEN
10514 + <u16 as WireFormat>::MIN_LEN
10515 + <u16 as WireFormat>::MIN_LEN
10516 + <u8 as WireFormat>::MIN_LEN
10517 + <u8 as WireFormat>::MIN_LEN;
10518 fn len(&self) -> usize {
10519 WireFormat::len(&self.tow)
10520 + WireFormat::len(&self.n)
10521 + WireFormat::len(&self.e)
10522 + WireFormat::len(&self.d)
10523 + WireFormat::len(&self.h_accuracy)
10524 + WireFormat::len(&self.v_accuracy)
10525 + WireFormat::len(&self.n_sats)
10526 + WireFormat::len(&self.flags)
10527 }
10528 fn write<B: BufMut>(&self, buf: &mut B) {
10529 WireFormat::write(&self.tow, buf);
10530 WireFormat::write(&self.n, buf);
10531 WireFormat::write(&self.e, buf);
10532 WireFormat::write(&self.d, buf);
10533 WireFormat::write(&self.h_accuracy, buf);
10534 WireFormat::write(&self.v_accuracy, buf);
10535 WireFormat::write(&self.n_sats, buf);
10536 WireFormat::write(&self.flags, buf);
10537 }
10538 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
10539 MsgVelNedDepA {
10540 sender_id: None,
10541 tow: WireFormat::parse_unchecked(buf),
10542 n: WireFormat::parse_unchecked(buf),
10543 e: WireFormat::parse_unchecked(buf),
10544 d: WireFormat::parse_unchecked(buf),
10545 h_accuracy: WireFormat::parse_unchecked(buf),
10546 v_accuracy: WireFormat::parse_unchecked(buf),
10547 n_sats: WireFormat::parse_unchecked(buf),
10548 flags: WireFormat::parse_unchecked(buf),
10549 }
10550 }
10551 }
10552}
10553
10554pub mod msg_vel_ned_gnss {
10555 #![allow(unused_imports)]
10556
10557 use super::*;
10558 use crate::messages::lib::*;
10559
10560 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10571 #[allow(clippy::derive_partial_eq_without_eq)]
10572 #[derive(Debug, PartialEq, Clone)]
10573 pub struct MsgVelNedGnss {
10574 #[cfg_attr(feature = "serde", serde(skip_serializing, alias = "sender"))]
10576 pub sender_id: Option<u16>,
10577 #[cfg_attr(feature = "serde", serde(rename = "tow"))]
10579 pub tow: u32,
10580 #[cfg_attr(feature = "serde", serde(rename = "n"))]
10582 pub n: i32,
10583 #[cfg_attr(feature = "serde", serde(rename = "e"))]
10585 pub e: i32,
10586 #[cfg_attr(feature = "serde", serde(rename = "d"))]
10588 pub d: i32,
10589 #[cfg_attr(feature = "serde", serde(rename = "h_accuracy"))]
10591 pub h_accuracy: u16,
10592 #[cfg_attr(feature = "serde", serde(rename = "v_accuracy"))]
10594 pub v_accuracy: u16,
10595 #[cfg_attr(feature = "serde", serde(rename = "n_sats"))]
10597 pub n_sats: u8,
10598 #[cfg_attr(feature = "serde", serde(rename = "flags"))]
10600 pub flags: u8,
10601 }
10602
10603 impl MsgVelNedGnss {
10604 pub fn velocity_mode(&self) -> Result<VelocityMode, u8> {
10610 get_bit_range!(self.flags, u8, u8, 2, 0).try_into()
10611 }
10612
10613 pub fn set_velocity_mode(&mut self, velocity_mode: VelocityMode) {
10615 set_bit_range!(&mut self.flags, velocity_mode, u8, u8, 2, 0);
10616 }
10617 }
10618
10619 impl ConcreteMessage for MsgVelNedGnss {
10620 const MESSAGE_TYPE: u16 = 558;
10621 const MESSAGE_NAME: &'static str = "MSG_VEL_NED_GNSS";
10622 }
10623
10624 impl SbpMessage for MsgVelNedGnss {
10625 fn message_name(&self) -> &'static str {
10626 <Self as ConcreteMessage>::MESSAGE_NAME
10627 }
10628 fn message_type(&self) -> Option<u16> {
10629 Some(<Self as ConcreteMessage>::MESSAGE_TYPE)
10630 }
10631 fn sender_id(&self) -> Option<u16> {
10632 self.sender_id
10633 }
10634 fn set_sender_id(&mut self, new_id: u16) {
10635 self.sender_id = Some(new_id);
10636 }
10637 fn encoded_len(&self) -> usize {
10638 WireFormat::len(self) + crate::HEADER_LEN + crate::CRC_LEN
10639 }
10640 fn is_valid(&self) -> bool {
10641 true
10642 }
10643 fn into_valid_msg(self) -> Result<Self, crate::messages::invalid::Invalid> {
10644 Ok(self)
10645 }
10646
10647 #[cfg(feature = "swiftnav")]
10648 fn gps_time(&self) -> Option<std::result::Result<time::MessageTime, time::GpsTimeError>> {
10649 let tow_s = (self.tow as f64) / 1000.0;
10650 let gps_time = match time::GpsTime::new(0, tow_s) {
10651 Ok(gps_time) => gps_time.tow(),
10652 Err(e) => return Some(Err(e.into())),
10653 };
10654 Some(Ok(time::MessageTime::Rover(gps_time.into())))
10655 }
10656 }
10657
10658 impl FriendlyName for MsgVelNedGnss {
10659 fn friendly_name() -> &'static str {
10660 "VEL NED GNSS-only"
10661 }
10662 }
10663
10664 impl TryFrom<Sbp> for MsgVelNedGnss {
10665 type Error = TryFromSbpError;
10666 fn try_from(msg: Sbp) -> Result<Self, Self::Error> {
10667 match msg {
10668 Sbp::MsgVelNedGnss(m) => Ok(m),
10669 _ => Err(TryFromSbpError(msg)),
10670 }
10671 }
10672 }
10673
10674 impl WireFormat for MsgVelNedGnss {
10675 const MIN_LEN: usize = <u32 as WireFormat>::MIN_LEN
10676 + <i32 as WireFormat>::MIN_LEN
10677 + <i32 as WireFormat>::MIN_LEN
10678 + <i32 as WireFormat>::MIN_LEN
10679 + <u16 as WireFormat>::MIN_LEN
10680 + <u16 as WireFormat>::MIN_LEN
10681 + <u8 as WireFormat>::MIN_LEN
10682 + <u8 as WireFormat>::MIN_LEN;
10683 fn len(&self) -> usize {
10684 WireFormat::len(&self.tow)
10685 + WireFormat::len(&self.n)
10686 + WireFormat::len(&self.e)
10687 + WireFormat::len(&self.d)
10688 + WireFormat::len(&self.h_accuracy)
10689 + WireFormat::len(&self.v_accuracy)
10690 + WireFormat::len(&self.n_sats)
10691 + WireFormat::len(&self.flags)
10692 }
10693 fn write<B: BufMut>(&self, buf: &mut B) {
10694 WireFormat::write(&self.tow, buf);
10695 WireFormat::write(&self.n, buf);
10696 WireFormat::write(&self.e, buf);
10697 WireFormat::write(&self.d, buf);
10698 WireFormat::write(&self.h_accuracy, buf);
10699 WireFormat::write(&self.v_accuracy, buf);
10700 WireFormat::write(&self.n_sats, buf);
10701 WireFormat::write(&self.flags, buf);
10702 }
10703 fn parse_unchecked<B: Buf>(buf: &mut B) -> Self {
10704 MsgVelNedGnss {
10705 sender_id: None,
10706 tow: WireFormat::parse_unchecked(buf),
10707 n: WireFormat::parse_unchecked(buf),
10708 e: WireFormat::parse_unchecked(buf),
10709 d: WireFormat::parse_unchecked(buf),
10710 h_accuracy: WireFormat::parse_unchecked(buf),
10711 v_accuracy: WireFormat::parse_unchecked(buf),
10712 n_sats: WireFormat::parse_unchecked(buf),
10713 flags: WireFormat::parse_unchecked(buf),
10714 }
10715 }
10716 }
10717
10718 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10720 pub enum VelocityMode {
10721 Invalid = 0,
10723
10724 MeasuredDopplerDerived = 1,
10726
10727 ComputedDopplerDerived = 2,
10729 }
10730
10731 impl std::fmt::Display for VelocityMode {
10732 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10733 match self {
10734 VelocityMode::Invalid => f.write_str("Invalid"),
10735 VelocityMode::MeasuredDopplerDerived => f.write_str("Measured Doppler derived"),
10736 VelocityMode::ComputedDopplerDerived => f.write_str("Computed Doppler derived"),
10737 }
10738 }
10739 }
10740
10741 impl TryFrom<u8> for VelocityMode {
10742 type Error = u8;
10743 fn try_from(i: u8) -> Result<Self, u8> {
10744 match i {
10745 0 => Ok(VelocityMode::Invalid),
10746 1 => Ok(VelocityMode::MeasuredDopplerDerived),
10747 2 => Ok(VelocityMode::ComputedDopplerDerived),
10748 i => Err(i),
10749 }
10750 }
10751 }
10752}