Signal localisation (Detailed)¶
Let’s begin with a simple example. Assuming signal detection has already been performed, here we’ll localise a single set of detections for one signal across all the channels.
from batracker import localiser
# mic_array_positions is the array geometry data
position = localiser(detections, mic_array_positions, v_sound=338)
print(position)
TDOA based methods¶
Time difference of arrival (TDOA) based methods rely on calculating source position from the range differences between microphone pairs. Some of these formulations include:
Spherical Intersection - SX method (Schau & Robinson 1987): formulated for 4 microphones only Status:
> Implemented, tests to be written
Spherical Interpolation - SI method (Smith & Abel 1987)
- Friedlander 1987: formulated for >= 4 microphones
- Statue:
> Not yet implemented
Non-TDOA based methods¶
There are whole bunch of methods which don’t necessarily use the time difference of arrival, but instead use the direction-of-arrival, or phase differences between sounds recorded across mics. These methods include (unsure of exact implementation details…):
MUSIC
Beamforming
signal localisation API¶
Localiser module
Deals with assigning signals across channels to the same sound, and localising the sound to its source
-
batracker.localisation.localiser.localise(multichannel_candidates, microphone_positions, **kwargs)¶ - Parameters
multichannel_candidates (list with sublists.) – Each sublist contains candidate regions where the signal of interest has been detected
microphone_positions (np.array) – Mmics x 3 np.array with the xyz positions of the mics. Each mic is in a new row
v_sound (float, optional) – Speed of sound in m/s. Defaults to 331 m/s.
formulation (str) – The mathematical formulation used to localise sounds Available options include #. Schau & Robinson 1987, IEEE Trans. Acoust. Speech & Sig. Proc.
- Returns
source_positions
- Return type
np.array
Notes
Error in the input data can contribute to errors in the actual source localisation.
Error in microphone position estimation can contribute to errors in source position estimation, especially when dealing with sources that are a bit further away [1]. At least in air, variation in the speed of sound is rather unlikely to contribute to big errors, and the error will also be homogenous in space (cause a uniform contraction or expansion of all position estimates).
References
- [1] Wahlberg, M., Møhl, B., & Teglberg Madsen, P. (2001).
Estimating source position accuracy of a large-aperture hydrophone array for bioacoustics. The Journal of the Acoustical Society of America, 109(1), 397-406.
See also
signal_detection.detection()
-
batracker.localisation.localiser.match_sounds_to_each_other(multichannel_candidates, microphone_positions, **kwargs)¶ Multiple sounds are detected within a channel and across channel. Each detecting in a channel needs to be grouped together with other detections across channels to proceed further with localisations.
-
batracker.localisation.localiser.localise_source(correspondence_map, multichannel_candidates, microphone_positions, **kwargs)¶
Localising sounds with the Schau & Robinson 1987 algorithm¶
The Schau & Robinson algorithm formulates the localisatin problem into finding a series of intersecting spheres, instead of hyperbolas. This also means that there are two possible solutions to the localisation. The user will need to choose the relevant option.
References
[1] Schau, H. C., & Robinson, A. Z. (1987). Passive source localization employing intersecting spherical surfaces from time-of-arrival differences. IEEE Transactions on Acoustics, Speech, and Signal Processing, 35(8), 1223-1225.
-
batracker.localisation.schau_robinson_1987.schau_robinson_solution(array_geometry, d)¶ - Parameters
array_geometry (np.array) – A 4x3 array with xyz coordinates of 4 mics. The last mic will be taken as the reference microphone.
d (np.array) – A 3x1 np.array with the range_differences to the source. All range_differences (\(d_{i4}\)), are calculated by taking \(D_{i}-D_{4}\), where \(D\) is the direct range from a mic to the source.
- Returns
x_real_world – A list with 2 3x1 np.arrays with the x,y,z positions of the source. The two xyz positions describe two possible solutions to the given array geometry and range differences.
- Return type
list
Attention
The Schau-Robinson algorithm does not work consistently for microphone arrays that have mics in the same plane (eg. ‘flat’ arrays with a common y coordinate)
For example, when using the Schau-Robinson on the flat tristar array [1]- all sources always have a faulty 0 ‘y’ coordinate.
References
Goerlitz, H.R. (2019, October 25). TOADSuite Manual. Zenodo. http://doi.org/10.5281/zenodo.3518761
-
batracker.localisation.schau_robinson_1987.parse_for_equation13(M, d, Delta)¶ Converts the simple M,d,Delta inputs into the quadratic type forms.
- Parameters
M (np.array) – A 3x3 array
d (np.array) – A 3x1 array
Delta – A 3x1 array
- Returns
a, b, c – 1x1 np.arrays with a single value
- Return type
np.array
-
batracker.localisation.schau_robinson_1987.equation_13(a, b, c)¶ Provides two solutions as it solves a quadratic solution to the range from source, \(R_{s} = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\). Being a quadratic equation, there will be two valid solutions, and the user will need to choose the range solution that is relevant (or not).
- Parameters
a (float) – Defined as \(4 - 4 d^T {M^{-1}}^{T} M^{-1} d\)
b (float) – Defined as \(2d^T {M^{-1}}^{T} M^{-1} \Delta + 2{\Delta}^{T}{M^{-1}}^{T}M^{-1} d\)
c (float) – Defined as \(-[{\Delta}^T {M^{-1}}^{T}M^{-1} \Delta]\)
- Returns
Rs – Tuple with both solutions of the quadratic equation.
- Return type
tuple
-
batracker.localisation.schau_robinson_1987.equation_10(M, Delta, Rs, d)¶ - Parameters
M (np.array) – 3 x 3 array with the xyz coordinates of the microphones. All positions are relative to mic 4, as the last mic is considered to be the origin (0,0,0)
Delta (np.array) – Matrix, \(\Delta\) in the paper, with \({R_{i}}^2 - {d_{i4}}^2\), where is is from 1-3, and refers to mic number. \(R_{i}\) is the distance from mic i to the origin. \(d_{i4}\) is the difference in source to mic travel distance between mic i and mic 4 (See Eqn 1&2).
Rs (tuple with 2 entries) – The two values of source range arising from the quadratic equation in Eq.13.
d (np.array) – The distances between each of the mics to the reference fourth mic. Each distance is notated as \(d_{i4}\) in the paper.
- Returns
X_1, X_2 – The x,y,z coordinates of the source, with the origin of the coordinate system set at mic 4.
- Return type
np.arrays
Notes
The \(R_{s}\) will have two range solutions, which also means that there will be two solutions of X. The user must make a prudent choice about which values are relevant for the situation.
-
exception
batracker.localisation.schau_robinson_1987.WrongShape¶
Implementing Friedlander 1987¶
Friedlander 1987 [1] formulates the localisation problem as the source being the intersection point of multiple major axis lines. Each set of three mics lies on an ellipsoid, where the major axis passes through the source. The final source position is calculated as the point where all the major axes of the ellipsoids intersect. See Figure 2. of the paper for a better idea.
References
- [1] Friedlander, B. (1987). A passive localization algorithm and its accuracy analysis.
IEEE Journal of Oceanic engineering, 12(1), 234-245.
-
batracker.localisation.friedlander_1987.solve_friedlander1987(array_geometry, d, **kwargs)¶ - Parameters
array_geometry (np.array) – A Nx3 array with xyz coordinates of N mics. The reference microphone channel number (j) used in the range difference estimation must be explicitly stated.
d (np.array) – A N-1x1 np.array with the range_differences to the source. All range_differences (\(r_{ij}\)), are calculated by taking \(R_{is}-R_{js}\), where \(R_{is}\) is the direct range from mic i to the source, and \(j\) is the reference microphone.
j (int >=0) – The channel number of the reference microphone. The first channel is the 0th.
use_analytical (bool, optional) – Whether to use the analytical solution to find the source position or not. Defaults to True. If False, a least squares routine is used to find the source position. The difference is likely to be negligible for most cases.
- Returns
x_real_world – If the array_geometry consists of >4 mics, then the output is a list with a 3x1 np.array with the x,y,z positions of the source. If the array_geometry consists of 4 mics, then the solution is a list with 2 candidate xyz source positions.
- Return type
list
-
batracker.localisation.friedlander_1987.friedlander1987(mic_posns, j, rij, use_analytical=True)¶
-
batracker.localisation.friedlander_1987.make_Sj(j, mic_posns)¶ - Parameters
j (int >=0) – The row number of the reference microphone
mic_posns (np.array) – A Nmicx3 np.array
- Returns
Sj – An Nchannels-1 x 3 array with \(\Delta\) x,y,z descirbing the variable \(S_{j}\) in equation 7b.
- Return type
np.array
-
batracker.localisation.friedlander_1987.make_muj(j, rij, mic_posns)¶ - Parameters
j (int >=0) – The row number of the reference microphone
rij (np.array) – Difference in range distances (\(R_{is}-R_{js}\))
mic_posns (np.array) – A Nmicx3 np.array
- Returns
mu_j – N-1 x 1 np.array with the \(mu_{j}\)
- Return type
np.array
Notes
I think there may be a typo in eq. 7c because the first row entry should bee \({R_{1o}}^2 - -{R_{jo}}^2 - {r_{1j}^2}\) rather than just \({R_{1o}} - -{R_{jo}}^2 - {r_{1j}^2}\). This is because \(\mu_{j}\) is obtained from eq. 6, where the term is \(({R_{io}^2}-{R_{jo}^2})-{R_{ij}^2}\) Here I”m going with my own interpretation of what is correct.
The positions given in mic_posns are assumed to be centred around the origin (0,0,0).
-
batracker.localisation.friedlander_1987.make_valid_i_array(j, num_channels)¶ - Parameters
j (0>int) – Index of reference sensor
num_channels (int) – Number of sensors
- Returns
valid_i_array – num_channels-1 array with all channel numbers apart from j.
- Return type
np.array