@@ -218,7 +218,18 @@ impl<'a, S: MessageSender> MainTab<'a, S> {
218218#[ cfg( test) ]
219219mod tests {
220220 use super :: * ;
221- use std:: { sync:: mpsc, time:: Duration } ;
221+ use crate :: types:: { PosLLH , VelNED } ;
222+ use crate :: utils:: { mm_to_m, ms_to_sec} ;
223+ use glob:: glob;
224+ use sbp:: messages:: navigation:: { MsgPosLLH , MsgVelNED } ;
225+ use std:: {
226+ fs:: File ,
227+ io:: { BufRead , BufReader } ,
228+ sync:: mpsc,
229+ time:: Duration ,
230+ } ;
231+ use tempfile:: TempDir ;
232+
222233 struct GpsTimeTests {
223234 pub zero_week : i16 ,
224235 pub good_week : i16 ,
@@ -276,4 +287,268 @@ mod tests {
276287 main. realtime_delay ( Some ( later_gps_time_good) ) ;
277288 assert ! ( now. elapsed( ) < Duration :: from_millis( 5 ) ) ;
278289 }
290+
291+ #[ test]
292+ fn csv_logging_test ( ) {
293+ let tmp_dir = TempDir :: new ( ) . unwrap ( ) ;
294+ let tmp_dir = tmp_dir. path ( ) . to_path_buf ( ) ;
295+ let shared_state = SharedState :: new ( ) ;
296+ let client_send = TestSender { inner : Vec :: new ( ) } ;
297+ let mut main = MainTab :: new ( shared_state, client_send) ;
298+ assert_eq ! ( main. last_csv_logging, CsvLogging :: OFF ) ;
299+ main. shared_state . set_csv_logging ( CsvLogging :: ON ) ;
300+ main. shared_state . set_logging_directory ( tmp_dir. clone ( ) ) ;
301+
302+ let flags = 0x01 ;
303+ let lat = 45_f64 ;
304+ let lon = -45_f64 ;
305+ let height = 1337_f64 ;
306+ let n_sats = 13 ;
307+ let h_accuracy = 0 ;
308+ let v_accuracy = 0 ;
309+ let tow = 1337 ;
310+ let sender_id = Some ( 1337 ) ;
311+
312+ let msg = MsgPosLLH {
313+ sender_id,
314+ flags,
315+ lat,
316+ lon,
317+ height,
318+ n_sats,
319+ h_accuracy,
320+ v_accuracy,
321+ tow,
322+ } ;
323+
324+ let n = 1 ;
325+ let e = 2 ;
326+ let d = 3 ;
327+ let msg_two = MsgVelNED {
328+ sender_id,
329+ flags,
330+ n,
331+ e,
332+ d,
333+ n_sats,
334+ tow,
335+ h_accuracy : 0 ,
336+ v_accuracy : 0 ,
337+ } ;
338+
339+ {
340+ main. serialize_sbp ( & SBP :: MsgPosLLH ( msg. clone ( ) ) ) ;
341+ main. solution_tab . handle_pos_llh ( PosLLH :: MsgPosLLH ( msg) ) ;
342+ main. serialize_sbp ( & SBP :: MsgVelNED ( msg_two. clone ( ) ) ) ;
343+ main. solution_tab
344+ . handle_vel_ned ( VelNED :: MsgVelNED ( msg_two. clone ( ) ) ) ;
345+ assert_eq ! ( main. last_csv_logging, CsvLogging :: ON ) ;
346+ main. end_csv_logging ( ) . unwrap ( ) ;
347+ main. serialize_sbp ( & SBP :: MsgVelNED ( msg_two) ) ;
348+ assert_eq ! ( main. last_csv_logging, CsvLogging :: OFF ) ;
349+ }
350+
351+ let pattern = tmp_dir. join ( "position_log_*" ) ;
352+ let path = glob ( & pattern. to_string_lossy ( ) )
353+ . unwrap ( )
354+ . next ( )
355+ . unwrap ( )
356+ . unwrap ( ) ;
357+ let mut reader = csv:: Reader :: from_reader ( File :: open ( path) . unwrap ( ) ) ;
358+ let mut records = reader. records ( ) ;
359+ let record = records. next ( ) . unwrap ( ) . unwrap ( ) ;
360+ let tow_: & f64 = & record[ 2 ] . parse ( ) . unwrap ( ) ;
361+ assert ! ( tow_ - ms_to_sec( tow as f64 ) <= f64 :: EPSILON ) ;
362+ let lat_: & f64 = & record[ 3 ] . parse ( ) . unwrap ( ) ;
363+ assert ! ( lat_ - lat <= f64 :: EPSILON ) ;
364+ let lon_: & f64 = & record[ 4 ] . parse ( ) . unwrap ( ) ;
365+ assert ! ( lon_ - lon <= f64 :: EPSILON ) ;
366+
367+ let pattern = tmp_dir. join ( "velocity_log_*" ) ;
368+ let path = glob ( & pattern. to_string_lossy ( ) )
369+ . unwrap ( )
370+ . next ( )
371+ . unwrap ( )
372+ . unwrap ( ) ;
373+ let mut reader = csv:: Reader :: from_reader ( File :: open ( path) . unwrap ( ) ) ;
374+ let mut records = reader. records ( ) ;
375+ let record = records. next ( ) . unwrap ( ) . unwrap ( ) ;
376+ let tow_: & f64 = & record[ 2 ] . parse ( ) . unwrap ( ) ;
377+ assert ! ( tow_ - ms_to_sec( tow as f64 ) <= f64 :: EPSILON ) ;
378+ let n_: & f64 = & record[ 3 ] . parse ( ) . unwrap ( ) ;
379+ let e_: & f64 = & record[ 4 ] . parse ( ) . unwrap ( ) ;
380+ let d_: & f64 = & record[ 5 ] . parse ( ) . unwrap ( ) ;
381+ assert ! ( n_ - mm_to_m( n as f64 ) <= f64 :: EPSILON ) ;
382+ assert ! ( e_ - mm_to_m( e as f64 ) <= f64 :: EPSILON ) ;
383+ assert ! ( d_ - mm_to_m( d as f64 ) <= f64 :: EPSILON ) ;
384+ }
385+
386+ #[ test]
387+ fn sbp_logging_test ( ) {
388+ let tmp_dir = TempDir :: new ( ) . unwrap ( ) ;
389+ let tmp_dir = tmp_dir. path ( ) . to_path_buf ( ) ;
390+ let shared_state = SharedState :: new ( ) ;
391+ let client_send = TestSender { inner : Vec :: new ( ) } ;
392+ let mut main = MainTab :: new ( shared_state, client_send) ;
393+ assert_eq ! ( main. last_sbp_logging, SbpLogging :: OFF ) ;
394+ main. shared_state . set_sbp_logging ( SbpLogging :: SBP ) ;
395+ main. shared_state . set_logging_directory ( tmp_dir. clone ( ) ) ;
396+
397+ let flags = 0x01 ;
398+ let lat = 45_f64 ;
399+ let lon = -45_f64 ;
400+ let height = 1337_f64 ;
401+ let n_sats = 13 ;
402+ let h_accuracy = 0 ;
403+ let v_accuracy = 0 ;
404+ let tow = 1337 ;
405+ let sender_id = Some ( 1337 ) ;
406+
407+ let msg_one = MsgPosLLH {
408+ sender_id,
409+ flags,
410+ lat,
411+ lon,
412+ height,
413+ n_sats,
414+ h_accuracy,
415+ v_accuracy,
416+ tow,
417+ } ;
418+
419+ let n = 1 ;
420+ let e = 2 ;
421+ let d = 3 ;
422+ let msg_two = MsgVelNED {
423+ sender_id,
424+ flags,
425+ n,
426+ e,
427+ d,
428+ n_sats,
429+ tow,
430+ h_accuracy : 0 ,
431+ v_accuracy : 0 ,
432+ } ;
433+
434+ {
435+ main. serialize_sbp ( & SBP :: MsgPosLLH ( msg_one. clone ( ) ) ) ;
436+ main. serialize_sbp ( & SBP :: MsgVelNED ( msg_two. clone ( ) ) ) ;
437+ assert_eq ! ( main. last_sbp_logging, SbpLogging :: SBP ) ;
438+ main. close_sbp ( ) ;
439+ main. serialize_sbp ( & SBP :: MsgVelNED ( msg_two. clone ( ) ) ) ;
440+ assert_eq ! ( main. last_sbp_logging, SbpLogging :: OFF ) ;
441+ }
442+
443+ let pattern = tmp_dir. join ( "swift-gnss-*.sbp" ) ;
444+ let path = glob ( & pattern. to_string_lossy ( ) )
445+ . unwrap ( )
446+ . next ( )
447+ . unwrap ( )
448+ . unwrap ( ) ;
449+ let file_read = File :: open ( path) . unwrap ( ) ;
450+ let mut messages = sbp:: iter_messages ( file_read) ;
451+ let msg = messages. next ( ) . unwrap ( ) . unwrap ( ) ;
452+ match msg {
453+ SBP :: MsgPosLLH ( msg) => {
454+ assert_eq ! ( msg. sender_id, msg_one. sender_id) ;
455+ assert_eq ! ( msg. flags, msg_one. flags) ;
456+ assert_eq ! ( msg. tow, msg_one. tow) ;
457+ assert ! ( msg. lat - msg_one. lat <= f64 :: EPSILON ) ;
458+ assert ! ( msg. lon - msg_one. lon <= f64 :: EPSILON ) ;
459+ assert ! ( msg. height - msg_one. height <= f64 :: EPSILON ) ;
460+ }
461+ _ => panic ! ( "first message does not match" ) ,
462+ }
463+ let msg = messages. next ( ) . unwrap ( ) . unwrap ( ) ;
464+ match msg {
465+ SBP :: MsgVelNED ( msg) => {
466+ assert_eq ! ( msg. sender_id, msg_two. sender_id) ;
467+ assert_eq ! ( msg. flags, msg_two. flags) ;
468+ assert_eq ! ( msg. n, msg_two. n) ;
469+ assert_eq ! ( msg. e, msg_two. e) ;
470+ assert_eq ! ( msg. d, msg_two. d) ;
471+ }
472+ _ => panic ! ( "second message does not match" ) ,
473+ }
474+ }
475+
476+ #[ test]
477+ fn sbp_json_logging_test ( ) {
478+ let tmp_dir = TempDir :: new ( ) . unwrap ( ) ;
479+ let tmp_dir = tmp_dir. path ( ) . to_path_buf ( ) ;
480+ let shared_state = SharedState :: new ( ) ;
481+ let client_send = TestSender { inner : Vec :: new ( ) } ;
482+ let mut main = MainTab :: new ( shared_state, client_send) ;
483+ assert_eq ! ( main. last_sbp_logging, SbpLogging :: OFF ) ;
484+ main. shared_state . set_sbp_logging ( SbpLogging :: SBP_JSON ) ;
485+ main. shared_state . set_logging_directory ( tmp_dir. clone ( ) ) ;
486+
487+ let flags = 0x01 ;
488+ let lat = 45_f64 ;
489+ let lon = -45_f64 ;
490+ let height = 1337_f64 ;
491+ let n_sats = 13 ;
492+ let h_accuracy = 0 ;
493+ let v_accuracy = 0 ;
494+ let tow = 1337 ;
495+ let sender_id = Some ( 1337 ) ;
496+
497+ let msg_one = MsgPosLLH {
498+ sender_id,
499+ flags,
500+ lat,
501+ lon,
502+ height,
503+ n_sats,
504+ h_accuracy,
505+ v_accuracy,
506+ tow,
507+ } ;
508+
509+ let n = 1 ;
510+ let e = 2 ;
511+ let d = 3 ;
512+ let msg_two = MsgVelNED {
513+ sender_id,
514+ flags,
515+ n,
516+ e,
517+ d,
518+ n_sats,
519+ tow,
520+ h_accuracy : 0 ,
521+ v_accuracy : 0 ,
522+ } ;
523+
524+ {
525+ main. serialize_sbp ( & SBP :: MsgPosLLH ( msg_one) ) ;
526+ main. serialize_sbp ( & SBP :: MsgVelNED ( msg_two. clone ( ) ) ) ;
527+ assert_eq ! ( main. last_sbp_logging, SbpLogging :: SBP_JSON ) ;
528+ main. close_sbp ( ) ;
529+ main. serialize_sbp ( & SBP :: MsgVelNED ( msg_two) ) ;
530+ assert_eq ! ( main. last_sbp_logging, SbpLogging :: OFF ) ;
531+ }
532+
533+ let pattern = tmp_dir. join ( "swift-gnss-*.sbp.json" ) ;
534+ let path = glob ( & pattern. to_string_lossy ( ) )
535+ . unwrap ( )
536+ . next ( )
537+ . unwrap ( )
538+ . unwrap ( ) ;
539+ let file_read = File :: open ( path) . unwrap ( ) ;
540+ let output_file = BufReader :: new ( file_read) ;
541+ let mut lines = output_file. lines ( ) ;
542+ let line = lines. next ( ) . unwrap ( ) ;
543+ let value: serde_json:: Value = serde_json:: from_str ( & line. unwrap ( ) ) . unwrap ( ) ;
544+ let value = value. as_object ( ) . unwrap ( ) ;
545+ let lat_ = value. get ( "lat" ) . unwrap ( ) ;
546+ assert_eq ! ( * lat_, serde_json:: json!( lat) ) ;
547+
548+ let line = lines. next ( ) . unwrap ( ) ;
549+ let value: serde_json:: Value = serde_json:: from_str ( & line. unwrap ( ) ) . unwrap ( ) ;
550+ let value = value. as_object ( ) . unwrap ( ) ;
551+ let n_ = value. get ( "n" ) . unwrap ( ) ;
552+ assert_eq ! ( * n_, serde_json:: json!( n) ) ;
553+ }
279554}
0 commit comments