1 #====================================================================== |
1 #====================================================================== |
2 # R D I _ B B _ R E A D . P L |
2 # R D I _ P D 0 _ I O . P L |
3 # doc: Sat Jan 18 14:54:43 2003 |
3 # doc: Sat Jan 18 14:54:43 2003 |
4 # dlm: Tue Aug 8 16:19:45 2017 |
4 # dlm: Wed Nov 22 11:03:59 2017 |
5 # (c) 2003 A.M. Thurnherr |
5 # (c) 2003 A.M. Thurnherr |
6 # uE-Info: 562 21 NIL 0 0 72 0 2 4 NIL ofnI |
6 # uE-Info: 156 40 NIL 0 0 72 0 2 4 NIL ofnI |
7 #====================================================================== |
7 #====================================================================== |
8 |
8 |
9 # Read RDI PD0 binary data files (*.[0-9][0-9][0-9]) |
9 # Read RDI PD0 binary data files (*.[0-9][0-9][0-9]) |
10 |
10 |
11 # HISTORY: |
11 # HISTORY: |
89 # Aug 1, 2017: BUG: minor typo in ocean surveyor code (err check not done?) |
89 # Aug 1, 2017: BUG: minor typo in ocean surveyor code (err check not done?) |
90 # Aug 7, 2017: - added LAG_LENGTH |
90 # Aug 7, 2017: - added LAG_LENGTH |
91 # - added SPEED_OF_SOUND to header |
91 # - added SPEED_OF_SOUND to header |
92 # Aug 8, 2017: - replaced croak() by die() |
92 # Aug 8, 2017: - replaced croak() by die() |
93 # - added actual transducer frequencies |
93 # - added actual transducer frequencies |
|
94 # Nov 22, 2017: - BUG: dayNo() and monthLength() clashed with [libconv.pl] |
94 |
95 |
95 # FIRMWARE VERSIONS: |
96 # FIRMWARE VERSIONS: |
96 # It appears that different firmware versions generate different file |
97 # It appears that different firmware versions generate different file |
97 # structures. Currently (Sep 2005) these routines have been tested |
98 # structures. Currently (Sep 2005) these routines have been tested |
98 # with the following firmware versions (as reported by [listHdr]): |
99 # with the following firmware versions (as reported by [listHdr]): |
148 # 0x88000100 FSU instrument during A0304 (Firmware 16.12) |
149 # 0x88000100 FSU instrument during A0304 (Firmware 16.12) |
149 # 0x88008180 LDEO uplooker (slave) during NBP0402 (Firmware 16.21) |
150 # 0x88008180 LDEO uplooker (slave) during NBP0402 (Firmware 16.21) |
150 # 0x00008180 LDEO downlooker (master) during NBP0402 (Firmware 16.21) |
151 # 0x00008180 LDEO downlooker (master) during NBP0402 (Firmware 16.21) |
151 # According to the manual (January 2001 version) this would, for example, |
152 # According to the manual (January 2001 version) this would, for example, |
152 # indicate power failures on both FSU and LDEO slave instruments... |
153 # indicate power failures on both FSU and LDEO slave instruments... |
|
154 # - defining the variable "$RDI_PD0_IO::IGNORE_Y2K_CLOCK" before calling &readData() |
|
155 # makes the code ignore the Y2K clock and use the old clock instead; this |
|
156 # is used for Dan Torres' KVH system |
153 |
157 |
154 # &readData() returns perl obj (ref to anonymous hash) with the following |
158 # &readData() returns perl obj (ref to anonymous hash) with the following |
155 # structure: |
159 # structure: |
156 # |
160 # |
157 # DATA_SOURCE_ID scalar 0x7f (Workhorse, also DVL) |
161 # DATA_SOURCE_ID scalar 0x7f (Workhorse, also DVL) |
291 use strict; |
295 use strict; |
292 use Time::Local; # timegm() |
296 use Time::Local; # timegm() |
293 |
297 |
294 #---------------------------------------------------------------------- |
298 #---------------------------------------------------------------------- |
295 # Time Conversion Subroutines |
299 # Time Conversion Subroutines |
|
300 # - prepended with _ to avoid conflicts with [libconv.pl] |
296 #---------------------------------------------------------------------- |
301 #---------------------------------------------------------------------- |
297 |
302 |
298 sub monthLength($$) # of days in month |
303 sub _monthLength($$) # of days in month |
299 { |
304 { |
300 my($Y,$M) = @_; |
305 my($Y,$M) = @_; |
301 |
306 |
302 return 31 if ($M==1 || $M==3 || $M==5 || $M==7 || |
307 return 31 if ($M==1 || $M==3 || $M==5 || $M==7 || |
303 $M==8 || $M==10 || $M==12); |
308 $M==8 || $M==10 || $M==12); |
308 return 29; |
313 return 29; |
309 } |
314 } |
310 |
315 |
311 { my($epoch,$lM,$lD,$lY,$ldn); # static scope |
316 { my($epoch,$lM,$lD,$lY,$ldn); # static scope |
312 |
317 |
313 sub dayNo($$$$$$) |
318 sub _dayNo($$$$$$) |
314 { |
319 { |
315 my($Y,$M,$D,$h,$m,$s) = @_; |
320 my($Y,$M,$D,$h,$m,$s) = @_; |
316 my($dn); |
321 my($dn); |
317 |
322 |
318 if ($Y==$lY && $M==$lM && $D==$lD) { # same day as last samp |
323 if ($Y==$lY && $M==$lM && $D==$lD) { # same day as last samp |
320 } else { # new day |
325 } else { # new day |
321 $epoch = $Y unless defined($epoch); # 1st call |
326 $epoch = $Y unless defined($epoch); # 1st call |
322 $lY = $Y; $lM = $M; $lD = $D; # store |
327 $lY = $Y; $lM = $M; $lD = $D; # store |
323 |
328 |
324 for ($dn=0,my($cY)=$epoch; $cY<$Y; $cY++) { # multiple years |
329 for ($dn=0,my($cY)=$epoch; $cY<$Y; $cY++) { # multiple years |
325 $dn += 337 + &monthLength($Y,$M); |
330 $dn += 337 + &_monthLength($Y,$M); |
326 } |
331 } |
327 |
332 |
328 $dn += $D; # day in month |
333 $dn += $D; # day in month |
329 while (--$M > 0) { # preceding months |
334 while (--$M > 0) { # preceding months |
330 $dn += &monthLength($Y,$M); |
335 $dn += &_monthLength($Y,$M); |
331 } |
336 } |
332 |
337 |
333 $ldn = $dn; # store |
338 $ldn = $dn; # store |
334 } |
339 } |
335 return $dn + $h/24 + $m/24/60 + $s/24/3600; |
340 return $dn + $h/24 + $m/24/60 + $s/24/3600; |
772 } else { |
777 } else { |
773 $id == 0x0080 || |
778 $id == 0x0080 || |
774 die(sprintf($FmtErr,$WBRcfn,"Variable Leader",$id,$ensNo + ($lastEns - ($lastEns & 0xFFFF)))); |
779 die(sprintf($FmtErr,$WBRcfn,"Variable Leader",$id,$ensNo + ($lastEns - ($lastEns & 0xFFFF)))); |
775 } |
780 } |
776 |
781 |
777 if ($fixed_leader_bytes==42 || $fixed_leader_bytes==58) { # BB150 & Explorer DVL |
782 # if ($fixed_leader_bytes==42 || $fixed_leader_bytes==58) { # BB150 & Explorer DVL |
778 sysread(WBRF,$buf,7) == 7 || die("$WBRcfn: $!"); |
783 sysread(WBRF,$buf,7) == 7 || die("$WBRcfn: $!"); |
779 (${$E}[$ens]->{YEAR},${$E}[$ens]->{MONTH}, |
784 (${$E}[$ens]->{YEAR},${$E}[$ens]->{MONTH}, |
780 ${$E}[$ens]->{DAY},${$E}[$ens]->{HOUR},${$E}[$ens]->{MINUTE}, |
785 ${$E}[$ens]->{DAY},${$E}[$ens]->{HOUR},${$E}[$ens]->{MINUTE}, |
781 ${$E}[$ens]->{SECONDS},$B4) = unpack('CCCCCCC',$buf); |
786 ${$E}[$ens]->{SECONDS},$B4) = unpack('CCCCCCC',$buf); |
782 ${$E}[$ens]->{SECONDS} += $B4/100; |
787 ${$E}[$ens]->{SECONDS} += $B4/100; |
783 ${$E}[$ens]->{YEAR} += (${$E}[$ens]->{YEAR} > 80) ? 1900 : 2000; |
788 ${$E}[$ens]->{YEAR} += (${$E}[$ens]->{YEAR} > 80) ? 1900 : 2000; |
784 } else { |
789 # } else { |
785 sysseek(WBRF,7,1) || die("$WBRcfn: $!"); # use Y2K RTC instead |
790 # sysseek(WBRF,7,1) || die("$WBRcfn: $!"); # use Y2K RTC instead |
786 } |
791 # } |
787 |
792 |
788 sysread(WBRF,$buf,1) == 1 || die("$WBRcfn: $!"); |
793 sysread(WBRF,$buf,1) == 1 || die("$WBRcfn: $!"); |
789 $ensNo += unpack('C',$buf) << 16; |
794 $ensNo += unpack('C',$buf) << 16; |
790 ${$E}[$ens]->{NUMBER} = $ensNo; |
795 ${$E}[$ens]->{NUMBER} = $ensNo; |
791 |
796 |
827 ${$E}[$ens]->{MIN_PRE_PING_WAIT_TIME} *= 60; |
832 ${$E}[$ens]->{MIN_PRE_PING_WAIT_TIME} *= 60; |
828 ${$E}[$ens]->{MIN_PRE_PING_WAIT_TIME} += $B1 + $B2/100; |
833 ${$E}[$ens]->{MIN_PRE_PING_WAIT_TIME} += $B1 + $B2/100; |
829 ${$E}[$ens]->{PITCH_STDDEV} /= 10; |
834 ${$E}[$ens]->{PITCH_STDDEV} /= 10; |
830 ${$E}[$ens]->{ROLL_STDDEV} /= 10; |
835 ${$E}[$ens]->{ROLL_STDDEV} /= 10; |
831 |
836 |
832 if ($fixed_leader_bytes==53 || $fixed_leader_bytes==59) { # Workhorse instruments |
837 if (($fixed_leader_bytes==53 || $fixed_leader_bytes==59) && # Workhorse instruments |
|
838 !defined($RDI_PD0_IO::IGNORE_Y2K_CLOCK)) { |
833 sysread(WBRF,$buf,23) == 23 || die("$WBRcfn: $!"); |
839 sysread(WBRF,$buf,23) == 23 || die("$WBRcfn: $!"); |
834 (${$E}[$ens]->{ERROR_STATUS_WORD}, |
840 (${$E}[$ens]->{ERROR_STATUS_WORD}, |
835 $dummy,${$E}[$ens]->{PRESSURE},${$E}[$ens]->{PRESSURE_STDDEV}, |
841 $dummy,${$E}[$ens]->{PRESSURE},${$E}[$ens]->{PRESSURE_STDDEV}, |
836 $dummy,${$E}[$ens]->{YEAR},$B3,${$E}[$ens]->{MONTH}, |
842 $dummy,${$E}[$ens]->{YEAR},$B3,${$E}[$ens]->{MONTH}, |
837 ${$E}[$ens]->{DAY},${$E}[$ens]->{HOUR},${$E}[$ens]->{MINUTE}, |
843 ${$E}[$ens]->{DAY},${$E}[$ens]->{HOUR},${$E}[$ens]->{MINUTE}, |
864 ${$E}[$ens]->{TIME} |
870 ${$E}[$ens]->{TIME} |
865 = sprintf("%02d:%02d:%05.02f",${$E}[$ens]->{HOUR}, |
871 = sprintf("%02d:%02d:%05.02f",${$E}[$ens]->{HOUR}, |
866 ${$E}[$ens]->{MINUTE}, |
872 ${$E}[$ens]->{MINUTE}, |
867 ${$E}[$ens]->{SECONDS}); |
873 ${$E}[$ens]->{SECONDS}); |
868 ${$E}[$ens]->{DAYNO} |
874 ${$E}[$ens]->{DAYNO} |
869 = &dayNo(${$E}[$ens]->{YEAR},${$E}[$ens]->{MONTH},${$E}[$ens]->{DAY}, |
875 = &_dayNo(${$E}[$ens]->{YEAR},${$E}[$ens]->{MONTH},${$E}[$ens]->{DAY}, |
870 ${$E}[$ens]->{HOUR},${$E}[$ens]->{MINUTE},${$E}[$ens]->{SECONDS}); |
876 ${$E}[$ens]->{HOUR},${$E}[$ens]->{MINUTE},${$E}[$ens]->{SECONDS}); |
871 |
877 |
872 # when analyzing an STA file from an OS75 SADCP (Poseidion), |
878 # when analyzing an STA file from an OS75 SADCP (Poseidion), |
873 # I noticed that there is no time information. This causes |
879 # I noticed that there is no time information. This causes |
874 # timegm to bomb. |
880 # timegm to bomb. |
875 if (${$E}[$ens]->{MONTH} == 0) { # no time info |
881 if (${$E}[$ens]->{MONTH} == 0) { # no time info |