RDI_Coords.pl
changeset 58 78607e2e8add
parent 54 21cf468fa8e0
equal deleted inserted replaced
57:5a59411306ba 58:78607e2e8add
     1 #======================================================================
     1 #======================================================================
     2 #                    R D I _ C O O R D S . P L 
     2 #                    R D I _ C O O R D S . P L 
     3 #                    doc: Sun Jan 19 17:57:53 2003
     3 #                    doc: Sun Jan 19 17:57:53 2003
     4 #                    dlm: Mon Jun 29 10:59:01 2020
     4 #                    dlm: Wed Mar 17 23:20:13 2021
     5 #                    (c) 2003 A.M. Thurnherr
     5 #                    (c) 2003 A.M. Thurnherr
     6 #                    uE-Info: 61 83 NIL 0 0 72 10 2 4 NIL ofnI
     6 #                    uE-Info: 66 9 NIL 0 0 72 10 2 4 NIL ofnI
     7 #======================================================================
     7 #======================================================================
     8 
     8 
     9 # RDI Workhorse Coordinate Transformations
     9 # RDI Workhorse Coordinate Transformations
    10 
    10 
    11 # HISTORY:
    11 # HISTORY:
    57 #	Nov 26, 2017: - BUG: velBeamtoBPEarth() did not respect missing values
    57 #	Nov 26, 2017: - BUG: velBeamtoBPEarth() did not respect missing values
    58 #	Nov 27, 2017: - BUG: numbersp() from [antslib.pl] was used
    58 #	Nov 27, 2017: - BUG: numbersp() from [antslib.pl] was used
    59 #	Mar 28, 2018: - added &loadInstrumentTransformation()
    59 #	Mar 28, 2018: - added &loadInstrumentTransformation()
    60 #	Jun  5, 2020: - added sscorr_w & sscorr_w_mooring
    60 #	Jun  5, 2020: - added sscorr_w & sscorr_w_mooring
    61 #   Jun 29, 2020: - added comments for sscorr_w, which conflicts with LADCP_w_ocean
    61 #   Jun 29, 2020: - added comments for sscorr_w, which conflicts with LADCP_w_ocean
       
    62 #	Mar 17, 2021: - adapted velBeamToInstrument() to Nortek (checked w only)
       
    63 #				  - adapted velInstrumentToEarth() to Nortek, assuming Nortek pitch is gimbal pitch
       
    64 # HISTORY END
       
    65 
       
    66 # NORTEK TODO:
       
    67 #	- check u, v sign convention for Nortek
       
    68 #	- verify that gimbal pitch for Nortek gives better results
       
    69 #		for A20 test profile 900, the differences in w have a stddev of 1.3e-5 m/s
       
    70 #	- update gimbal pitch for Nortek in other routines
    62 
    71 
    63 use strict;
    72 use strict;
    64 use POSIX;
    73 use POSIX;
    65 
    74 
    66 my($PI) = 3.14159265358979;
    75 my($PI) = 3.14159265358979;
   133 		my($ADCP,$ens,$v1,$v2,$v3,$v4) = @_;
   142 		my($ADCP,$ens,$v1,$v2,$v3,$v4) = @_;
   134 		return undef unless (defined($v1) + defined($v2) +
   143 		return undef unless (defined($v1) + defined($v2) +
   135 					   		 defined($v3) + defined($v4)
   144 					   		 defined($v3) + defined($v4)
   136 								>= $RDI_Coords::minValidVels);
   145 								>= $RDI_Coords::minValidVels);
   137 
   146 
   138 		unless (@B2I) {
   147 		unless (@B2I) {															# nominal transformation matrix
   139 			my($a) = 1 / (2 * sin(rad($ADCP->{BEAM_ANGLE})));
   148 			my($a) = 1 / (2 * sin(rad($ADCP->{BEAM_ANGLE})));
   140 			my($b) = 1 / (4 * cos(rad($ADCP->{BEAM_ANGLE})));
   149 			my($b) = 1 / (4 * cos(rad($ADCP->{BEAM_ANGLE})));
   141 			my($c) = $ADCP->{CONVEX_BEAM_PATTERN} ? 1 : -1;
   150 			my($c) = $ADCP->{CONVEX_BEAM_PATTERN} ? 1 : -1;
   142 			my($d) = $a / sqrt(2);
   151 			my($d) = $a / sqrt(2);
   143 			@B2I = ([$c*$a,	-$c*$a,	0,		0	 ],
   152 			@B2I = ([$c*$a,	-$c*$a,	0,		0	 ],
   144 				    [0,		0,		-$c*$a,	$c*$a],
   153 				    [0,		0,		-$c*$a,	$c*$a],
   145 				    [$b,	$b,		$b,		$b	 ],
   154 				    [$b,	$b,		$b,		$b	 ],
   146 				    [$d,	$d,		-$d,	-$d	 ]);
   155 				    [$d,	$d,		-$d,	-$d	 ]);
   147 		}
   156 		}
   148 
   157 
   149 		if (!defined($v1)) {					# 3-beam solutions
   158 		if ($ADCP->{PRODUCER} =~ '^Nortek') {									# Nortek ADCPs use different coord system
       
   159 			$v1 *= -1 if defined($v1);
       
   160 			$v2 *= -1 if defined($v2);
       
   161 			$v3 *= -1 if defined($v3);
       
   162 			$v4 *= -1 if defined($v4);
       
   163 		}
       
   164 
       
   165 		if (!defined($v1)) {													# 3-beam solutions
   150 			$RDI_Coords::threeBeamFlag = 1;
   166 			$RDI_Coords::threeBeamFlag = 1;
   151 			$RDI_Coords::threeBeam_1++;
   167 			$RDI_Coords::threeBeam_1++;
   152 			$v1 = -($v2*$B2I[3][1]+$v3*$B2I[3][2]+$v4*$B2I[3][3])/$B2I[3][0];
   168 			$v1 = -($v2*$B2I[3][1]+$v3*$B2I[3][2]+$v4*$B2I[3][3])/$B2I[3][0];
   153 		} elsif (!defined($v2)) {
   169 		} elsif (!defined($v2)) {
   154 			$RDI_Coords::threeBeamFlag = 1;
   170 			$RDI_Coords::threeBeamFlag = 1;
   209 				if ($ADCP->{HEADING_ALIGNMENT});
   225 				if ($ADCP->{HEADING_ALIGNMENT});
   210 			$hdg   = $ADCP->{ENSEMBLE}[$ens]->{HEADING} - $ADCP->{HEADING_BIAS}
   226 			$hdg   = $ADCP->{ENSEMBLE}[$ens]->{HEADING} - $ADCP->{HEADING_BIAS}
   211 				if defined($ADCP->{ENSEMBLE}[$ens]->{HEADING});
   227 				if defined($ADCP->{ENSEMBLE}[$ens]->{HEADING});
   212 			$pitch = $ADCP->{ENSEMBLE}[$ens]->{PITCH};
   228 			$pitch = $ADCP->{ENSEMBLE}[$ens]->{PITCH};
   213 			$roll  = $ADCP->{ENSEMBLE}[$ens]->{ROLL};
   229 			$roll  = $ADCP->{ENSEMBLE}[$ens]->{ROLL};
   214 			my($rad_gimbal_pitch) = atan(tan(rad($pitch)) * cos(rad($roll)));
   230 			my($rad_gimbal_pitch);
       
   231 			if ($ADCP->{PRODUCER} =~ '^Nortek') {
       
   232 				$rad_gimbal_pitch = rad($pitch);									# I am assuming that this is correct
       
   233 			} else {
       
   234 				$rad_gimbal_pitch = atan(tan(rad($pitch)) * cos(rad($roll)));
       
   235 			}
       
   236 				
   215 			my($rad_calc_pitch) = ($RDI_Coords::beamTransformation eq 'RDI') ? $rad_gimbal_pitch : 
   237 			my($rad_calc_pitch) = ($RDI_Coords::beamTransformation eq 'RDI') ? $rad_gimbal_pitch : 
   216 								  asin(sin($rad_gimbal_pitch)*cos(rad($roll)) /
   238 								  asin(sin($rad_gimbal_pitch)*cos(rad($roll)) /
   217 									   sqrt(1-sin(rad($roll))**2*sin($rad_gimbal_pitch)**2));
   239 									   sqrt(1-sin(rad($roll))**2*sin($rad_gimbal_pitch)**2));
   218 			my($sh,$ch) = (sin(rad($hdg)),cos(rad($hdg)))
   240 			my($sh,$ch) = (sin(rad($hdg)),cos(rad($hdg)))
   219 				if defined($hdg);				
   241 				if defined($hdg);