@@ -381,8 +381,8 @@ mod parsing {
381381
382382#[ cfg( test) ]
383383mod tests {
384- use super :: Gps ;
385- use libsbf:: { reader:: SbfReader , Messages } ;
384+ use super :: { parsing , FixStatus , Gps } ;
385+ use libsbf:: { reader:: SbfReader , Messages , PVTGeodetic , PosCovGeodetic } ;
386386 use std:: fs:: File ;
387387
388388 fn data_file ( file_name : & str ) -> std:: path:: PathBuf {
@@ -424,4 +424,142 @@ mod tests {
424424 assert ! ( info. coord. lat. is_finite( ) ) ;
425425 assert ! ( info. coord. lon. is_finite( ) ) ;
426426 }
427+
428+ #[ test]
429+ fn minimal_sbf_regression_expected_values ( ) {
430+ let file = File :: open ( data_file ( "minimal_sbf.sbf" ) ) . expect ( "sample file should open" ) ;
431+ let reader = SbfReader :: new ( file) ;
432+
433+ let mut pvt_geodetic: Option < PVTGeodetic > = None ;
434+ let mut pos_cov_geodetic: Option < PosCovGeodetic > = None ;
435+
436+ for msg in reader {
437+ let msg = msg. expect ( "minimal_sbf SBF should decode" ) ;
438+ match msg {
439+ Messages :: PVTGeodetic ( pvt) if pvt_geodetic. is_none ( ) => pvt_geodetic = Some ( pvt) ,
440+ Messages :: PosCovGeodetic ( pos_cov) if pos_cov_geodetic. is_none ( ) => {
441+ pos_cov_geodetic = Some ( pos_cov)
442+ }
443+ _ => { }
444+ }
445+
446+ if pvt_geodetic. is_some ( ) && pos_cov_geodetic. is_some ( ) {
447+ break ;
448+ }
449+ }
450+
451+ let pvt_geodetic = pvt_geodetic. expect ( "minimal_sbf.sbf should contain PVTGeodetic" ) ;
452+ let pos_cov_geodetic =
453+ pos_cov_geodetic. expect ( "minimal_sbf.sbf should contain PosCovGeodetic" ) ;
454+
455+ assert_eq ! ( pvt_geodetic. tow, Some ( 162480000 ) ) ;
456+ assert_close (
457+ pvt_geodetic. latitude . expect ( "lat should exist" ) ,
458+ 0.6145361740716572 ,
459+ 1e-12 ,
460+ ) ;
461+ assert_close (
462+ pvt_geodetic. longitude . expect ( "lon should exist" ) ,
463+ -1.7006749045222338 ,
464+ 1e-12 ,
465+ ) ;
466+ assert_close (
467+ pvt_geodetic. height . expect ( "height should exist" ) ,
468+ 326.3521656619435 ,
469+ 1e-12 ,
470+ ) ;
471+
472+ assert_eq ! ( pos_cov_geodetic. tow, Some ( 162480000 ) ) ;
473+ assert_close (
474+ f64:: from (
475+ pos_cov_geodetic
476+ . cov_latlat
477+ . expect ( "cov_latlat should exist" ) ,
478+ ) ,
479+ 1.4662505 ,
480+ 5e-7 ,
481+ ) ;
482+ assert_close (
483+ f64:: from (
484+ pos_cov_geodetic
485+ . cov_lonlon
486+ . expect ( "cov_lonlon should exist" ) ,
487+ ) ,
488+ 6.332064 ,
489+ 5e-7 ,
490+ ) ;
491+ assert_close (
492+ f64:: from (
493+ pos_cov_geodetic
494+ . cov_hgthgt
495+ . expect ( "cov_hgthgt should exist" ) ,
496+ ) ,
497+ 7.9160724 ,
498+ 5e-7 ,
499+ ) ;
500+ assert_close (
501+ f64:: from (
502+ pos_cov_geodetic
503+ . cov_latlon
504+ . expect ( "cov_latlon should exist" ) ,
505+ ) ,
506+ -1.0395553 ,
507+ 5e-7 ,
508+ ) ;
509+ assert_close (
510+ f64:: from (
511+ pos_cov_geodetic
512+ . cov_lathgt
513+ . expect ( "cov_lathgt should exist" ) ,
514+ ) ,
515+ -1.793132 ,
516+ 5e-7 ,
517+ ) ;
518+ assert_close (
519+ f64:: from (
520+ pos_cov_geodetic
521+ . cov_lonhgt
522+ . expect ( "cov_lonhgt should exist" ) ,
523+ ) ,
524+ 4.2639227 ,
525+ 5e-7 ,
526+ ) ;
527+
528+ let expected_covariance = [
529+ 6.332064151763916 ,
530+ -1.039555311203003 ,
531+ 4.263922691345215 ,
532+ -1.039555311203003 ,
533+ 1.4662505388259888 ,
534+ -1.793131947517395 ,
535+ 4.263922691345215 ,
536+ -1.793131947517395 ,
537+ 7.916072368621826 ,
538+ ] ;
539+ let ( cov_tow, covariance) = parsing:: pos_cov_geodetic_covariance ( & pos_cov_geodetic)
540+ . expect ( "minimal_sbf.sbf covariance should be complete" ) ;
541+ assert_eq ! ( cov_tow, 162480000 ) ;
542+ for ( actual, expected) in covariance. iter ( ) . zip ( expected_covariance. iter ( ) ) {
543+ assert_close ( * actual, * expected, 1e-12 ) ;
544+ }
545+
546+ let info = parsing:: pvt_geodetic_to_info ( & pvt_geodetic, covariance)
547+ . expect ( "PVT should parse into GpsInfo" ) ;
548+ assert_close ( info. coord . lat , 35.21032913242285 , 1e-12 ) ;
549+ assert_close ( info. coord . lon , -97.44149435293824 , 1e-12 ) ;
550+ assert_close ( info. height . 0 , 326.3521656619435 , 1e-12 ) ;
551+ assert_eq ! ( info. tow. 0 , 162480000 ) ;
552+ assert_eq ! ( info. fix_status, FixStatus :: SinglePoint ) ;
553+ for ( actual, expected) in info. covariance . iter ( ) . zip ( expected_covariance. iter ( ) ) {
554+ assert_close ( * actual, * expected, 1e-12 ) ;
555+ }
556+ }
557+
558+ fn assert_close ( actual : f64 , expected : f64 , tolerance : f64 ) {
559+ let delta = ( actual - expected) . abs ( ) ;
560+ assert ! (
561+ delta <= tolerance,
562+ "expected {expected} +/- {tolerance}, got {actual} (delta={delta})"
563+ ) ;
564+ }
427565}
0 commit comments