155 $v1*$I2E[2][0]+$v2*$I2E[2][1]+$v3*$I2E[2][2], |
157 $v1*$I2E[2][0]+$v2*$I2E[2][1]+$v3*$I2E[2][2], |
156 $v4); |
158 $v4); |
157 } |
159 } |
158 } # STATIC SCOPE |
160 } # STATIC SCOPE |
159 |
161 |
|
162 |
|
163 sub velBeamToEarth(@) |
|
164 { |
|
165 my($dtaR,$e,@v) = @_; |
|
166 return velInstrumentToEarth($dtaR,$e,velBeamToInstrument($dtaR,@v)); |
|
167 } |
|
168 |
160 #---------------------------------------------------------------------- |
169 #---------------------------------------------------------------------- |
161 # velEarthToInstrument() transforms earth to instrument coordinates |
170 # velEarthToInstrument() transforms earth to instrument coordinates |
162 # - based on manually inverted rotation matrix M (Sec 5.6 in coord-trans manual) |
171 # - based on manually inverted rotation matrix M (Sec 5.6 in coord-trans manual) |
|
172 # - code was verified for both down- and uplookers |
163 # - missing heading data (IMP) causes undef beam velocities |
173 # - missing heading data (IMP) causes undef beam velocities |
164 #---------------------------------------------------------------------- |
174 #---------------------------------------------------------------------- |
165 |
175 |
166 { # STATIC SCOPE |
176 { # STATIC SCOPE |
167 my($hdg,$pitch,$roll,@E2I); |
177 my($hdg,$pitch,$roll,@E2I); |
168 |
178 |
169 sub velEarthToInstrument(@) |
179 sub velEarthToInstrument(@) |
170 { |
180 { |
171 my($dta,$ens,$u,$v,$w,$ev) = @_; |
181 my($dta,$ens,$u,$v,$w,$ev) = @_; |
172 |
182 |
173 unless (@E2I) { |
183 unless (@E2I && |
|
184 $pitch == $dta->{ENSEMBLE}[$ens]->{PITCH} && |
|
185 $roll == $dta->{ENSEMBLE}[$ens]->{ROLL}) { |
174 $hdg = $dta->{ENSEMBLE}[$ens]->{HEADING} - $dta->{HEADING_BIAS} |
186 $hdg = $dta->{ENSEMBLE}[$ens]->{HEADING} - $dta->{HEADING_BIAS} |
175 if defined($dta->{ENSEMBLE}[$ens]->{HEADING}); |
187 if defined($dta->{ENSEMBLE}[$ens]->{HEADING}); |
176 $pitch = $dta->{ENSEMBLE}[$ens]->{PITCH}; |
188 $pitch = $dta->{ENSEMBLE}[$ens]->{PITCH}; |
177 $roll = $dta->{ENSEMBLE}[$ens]->{ROLL}; |
189 $roll = $dta->{ENSEMBLE}[$ens]->{ROLL}; |
178 my($rad_gimbal_pitch) = atan(tan(rad($pitch)) * cos(rad($roll))); |
190 my($rad_gimbal_pitch) = atan(tan(rad($pitch)) * cos(rad($roll))); |
|
191 my($useRoll) = ($dta->{ENSEMBLE}[$ens]->{XDUCER_FACING_UP}) ? $roll+180 : $roll; |
179 my($sh,$ch) = (sin(rad($hdg)),cos(rad($hdg))) |
192 my($sh,$ch) = (sin(rad($hdg)),cos(rad($hdg))) |
180 if defined($hdg); |
193 if defined($hdg); |
181 my($sp,$cp) = (sin($rad_gimbal_pitch),cos($rad_gimbal_pitch)); |
194 my($sp,$cp) = (sin($rad_gimbal_pitch),cos($rad_gimbal_pitch)); |
182 my($sr,$cr) = (sin(rad($roll)), cos(rad($roll))); |
195 my($sr,$cr) = (sin(rad($useRoll)), cos(rad($useRoll))); |
183 @E2I = $dta->{ENSEMBLE}[$ens]->{XDUCER_FACING_UP} |
196 @E2I = ([$ch*$cr+$sh*$sp*$sr, $ch*$sp*$sr-$sh*$cr, -$cp*$sr], # M^-1 = R^-1 * P^-1 * R^-1 |
184 ? ( |
197 [$sh*$cp, $ch*$cp, $sp ], |
185 [$ch*-$cr+$sh*$sp*-$sr, $ch*$sp*-$sr-$sh*-$cr, $cp*-$sr], |
198 [$ch*$sr-$sh*$sp*$cr, -$sh*$sr-$ch*$sp*$cr, $cp*$cr]); |
186 [$sh*$cp, $ch*$cp, $sp ], |
|
187 [$ch*-$sr-$sh*$sp*-$cr, -$sh*-$sr-$ch*$sp*-$cr, $cp*-$cr] |
|
188 ) : ( |
|
189 [$ch*$cr+$sh*$sp*$sr, $ch*$sp*$sr-$sh*$cr, $cp*$sr ], |
|
190 [$sh*$cp, $ch*$cp, $sp ], |
|
191 [$ch*$sr-$sh*$sp*$cr, -$sh*$sr-$ch*$sp*$cr, $cp*$cr ] |
|
192 ); |
|
193 } |
199 } |
194 |
200 |
195 return defined($dta->{ENSEMBLE}[$ens]->{HEADING}) |
201 return defined($dta->{ENSEMBLE}[$ens]->{HEADING}) |
196 ? ($u*$E2I[0][0]+$v*$E2I[0][1]+$w*$E2I[0][2], |
202 ? ($u*$E2I[0][0]+$v*$E2I[0][1]+$w*$E2I[0][2], |
197 $u*$E2I[1][0]+$v*$E2I[1][1]+$w*$E2I[1][2], |
203 $u*$E2I[1][0]+$v*$E2I[1][1]+$w*$E2I[1][2], |