diff --git a/app/Locabean/build.xml b/app/Locabean/build.xml
new file mode 100644
index 0000000..65e5edb
--- /dev/null
+++ b/app/Locabean/build.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/Locabean/res/layout/setup_dialog.xml b/app/Locabean/res/layout/setup_dialog.xml
deleted file mode 100644
index 664a4cf..0000000
--- a/app/Locabean/res/layout/setup_dialog.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/Locabean/src/com/locaudio/functional/Function.java b/app/Locabean/src/com/locaudio/functional/Function.java
index 9635c05..c81f5fd 100644
--- a/app/Locabean/src/com/locaudio/functional/Function.java
+++ b/app/Locabean/src/com/locaudio/functional/Function.java
@@ -11,22 +11,22 @@ public R call(T input) {
return body(input);
}
- public List map(
- Function f, IN_TYPE[] inArray) {
+ public List map(
+ Function f, A[] inArray) {
- List retList = new ArrayList();
- for (IN_TYPE inVal : inArray) {
+ List retList = new ArrayList();
+ for (A inVal : inArray) {
retList.add(f.call(inVal));
}
return retList;
}
- public List map(
- Function f, List inArray) {
+ public List map(
+ Function f, List inArray) {
- List retList = new ArrayList();
- for (IN_TYPE inVal : inArray) {
+ List retList = new ArrayList();
+ for (A inVal : inArray) {
retList.add(f.call(inVal));
}
diff --git a/app/Locabean/src/com/locaudio/locabean/NodeActivity.java b/app/Locabean/src/com/locaudio/locabean/NodeActivity.java
index 84089c8..44761b0 100644
--- a/app/Locabean/src/com/locaudio/locabean/NodeActivity.java
+++ b/app/Locabean/src/com/locaudio/locabean/NodeActivity.java
@@ -25,7 +25,7 @@ public class NodeActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_node);
-
+
setupTextViews();
setupLocaudio();
}
@@ -45,18 +45,21 @@ private void setupLocaudio() {
locaudio = new Locaudio(IP_ADDRESS, PORT);
acquisitionThread = locaudio.getAcquisitionThread(
- getApplicationContext(), new UIFunction(this) {
+ getApplicationContext(), acquisitionCallback);
+
+ acquisitionThread.start();
+ }
- @Override
- public Void body(NotifyResponse nr) {
- nameTextView.setText(nr.name);
- confidenceTextView.setText("" + nr.confidence);
+ private UIFunction acquisitionCallback = new UIFunction(
+ this) {
- return null;
- }
+ @Override
+ public Void body(NotifyResponse nr) {
+ nameTextView.setText(nr.name);
+ confidenceTextView.setText("" + nr.confidence);
- });
+ return null;
+ }
- acquisitionThread.start();
- }
+ };
}
diff --git a/locaudio/detectionserver.py b/locaudio/detectionserver.py
index 75e78c5..1d58e99 100644
--- a/locaudio/detectionserver.py
+++ b/locaudio/detectionserver.py
@@ -17,6 +17,7 @@
import json
import triangulation as tri
import fingerprint
+import plot
import db
import os
@@ -94,7 +95,7 @@ def get_sound_positions(sound_name):
radius, spl, _ = db.get_reference_data(sound_name)
- location_list = tri.determine_sound_positions(
+ location_list = tri.determine_sound_locations(
radius, spl,
config.detection_events[sound_name],
disp=0
@@ -121,7 +122,7 @@ def get_position_viewer(sound_name):
radius, spl, _ = db.get_reference_data(sound_name)
- location_list = tri.determine_sound_positions(
+ location_list = tri.determine_sound_locations(
radius, spl,
config.detection_events[sound_name],
disp=0
@@ -131,7 +132,7 @@ def get_position_viewer(sound_name):
img_web_path = "/" + img_path
if config.new_data[sound_name]:
- tri.plot_detection_events(
+ plot.plot_detection_events(
location_list,
radius, spl,
config.detection_events[sound_name],
diff --git a/locaudio/plot.py b/locaudio/plot.py
new file mode 100644
index 0000000..e376a50
--- /dev/null
+++ b/locaudio/plot.py
@@ -0,0 +1,116 @@
+
+import triangulation as tri
+import numpy as np
+import matplotlib.pyplot as plt
+from matplotlib import cm
+from mpl_toolkits.mplot3d import Axes3D
+
+
+def determine_limits(*args):
+
+ x_min = args[0][0].x
+ x_max = args[0][0].x
+
+ y_min = args[0][0].y
+ y_max = args[0][0].y
+
+ for coord_list in args:
+ for coord in coord_list:
+ if coord.x < x_min:
+ x_min = coord.x
+ elif coord.x > x_max:
+ x_max = coord.x
+
+ if coord.y < y_min:
+ y_min = coord.y
+ elif coord.y > y_max:
+ y_max = coord.y
+
+ if x_max - x_min > y_max - y_min:
+ y_max = (x_max - x_min) + y_min
+ else:
+ x_max = (y_max - y_min) + x_min
+
+ x_step = (x_max - x_min) / float(30)
+ y_step = (y_max - y_min) / float(30)
+
+ return (
+ x_min - 100 * x_step, x_max + 100 * x_step,
+ y_min - 100 * y_step, y_max + 100 * y_step,
+ x_step, y_step
+ )
+
+
+def plot_detection_events(locations, r_ref, l_ref, d_events, filename):
+ """
+
+ Plots the detection events and saves the figure in the given path.
+
+ @param res The list of locations. Locations are named tuples with fields
+ which are position which is a point and confidence which is a float
+
+ @param rRef The reference distance at which the reference sound
+ pressure level was recorded
+
+ @param lRef The reference sound pressure level used to determine the
+ distance from the newly measured sound pressure level
+
+ @param nodeEvents The list ofassociated data when a node detects with some
+ confidence that the sound has been identified
+
+ @return The plt object of the saved figure
+
+ """
+
+ fig = plt.figure("Locaudio")
+ ax = fig.add_subplot(111)
+ ax.set_xlabel("X Location")
+ ax.set_ylabel("Y Location")
+
+ # x_min = 56.3399
+ # x_max = 56.3400
+ # y_min = -2.80834
+ # y_max = -2.80824
+
+ (
+ x_min, x_max,
+ y_min, y_max,
+ x_step, y_step
+ ) = determine_limits(locations, d_events)
+
+ x = np.arange(x_min, x_max, x_step)
+ y = np.arange(y_min, y_max, y_step)
+ X, Y = np.meshgrid(x, y)
+
+ zs = np.array(
+ [
+ tri.position_probability(x, y, r_ref, l_ref, d_events)
+ for x, y in zip(np.ravel(X), np.ravel(Y))
+ ]
+ )
+
+ Z = zs.reshape(X.shape)
+ ax.pcolormesh(X, Y, Z, cmap=cm.jet)
+ ax.scatter(
+ [p.position.x for p in locations],
+ [p.position.y for p in locations],
+ marker="+",
+ linewidths=15,
+ c="white"
+ )
+ ax.scatter(
+ [d_event.x for d_event in d_events],
+ [d_event.y for d_event in d_events],
+ marker="o",
+ linewidths=5,
+ c="white",
+ s=300
+ )
+
+ ax.set_xlim(x_min, x_max)
+ ax.set_ylim(y_min, y_max)
+
+ plt.savefig(filename)
+ return plt
+
+
diff --git a/locaudio/point.py b/locaudio/point.py
index 95cafa1..8e4b091 100644
--- a/locaudio/point.py
+++ b/locaudio/point.py
@@ -1,6 +1,10 @@
import math
+
+EARTH_RADIUS = 1000 * 6371
+
+
class Point(object):
def __init__(self, x, y):
@@ -25,6 +29,7 @@ def set_y(self, y):
self.y = y
return self
+
def dist_to(self, other_point):
return math.sqrt(
pow(self.x - other_point.x, 2) +
@@ -32,6 +37,27 @@ def dist_to(self, other_point):
)
+ def dist_to_lat_long(self, other_point):
+ lat1 = math.radians(self.x)
+ lon1 = math.radians(self.y)
+ lat2 = math.radians(other_point.x)
+ lon2 = math.radians(other_point.y)
+
+ dlon = lon2 - lon1
+ dlat = lat2 - lat1
+
+ a = (
+ (math.sin(dlat / 2)) ** 2 +
+ math.cos(lat1) * math.cos(lat2) * (math.sin(dlon / 2)) ** 2
+ )
+
+ c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
+
+ distance = EARTH_RADIUS * c
+
+ return distance
+
+
def to_list(self):
return [self.x, self.y]
diff --git a/locaudio/triangulation.py b/locaudio/triangulation.py
index c9c4ec8..6675982 100644
--- a/locaudio/triangulation.py
+++ b/locaudio/triangulation.py
@@ -29,13 +29,9 @@
import sklearn.cluster as clustering # AffinityPropagation
import numpy as np
-import matplotlib.pyplot as plt
-from matplotlib import cm
-from mpl_toolkits.mplot3d import Axes3D
-
STD_SCALE = 1.4
-MIN_DIST = 1
+MIN_DIST = 0.0001
MAX_RADIUS_INC = 10
MIN_RADIUS_INC = -10
RADIUS_STEP = 1
@@ -306,7 +302,7 @@ def determine_peaks(opt_vals, label_list):
for max_point in max_point_list:
too_close = False
for ret_point in ret_list:
- if ret_point.dist_to(max_point) < MIN_DIST:
+ if ret_point.dist_to_lat_long(max_point) < MIN_DIST:
too_close = True
break
if not too_close:
@@ -315,7 +311,7 @@ def determine_peaks(opt_vals, label_list):
return ret_list
-def determine_sound_positions_instance(r_ref, l_ref, node_events, **kwargs):
+def determine_sound_locations_instance(r_ref, l_ref, node_events, **kwargs):
"""
Determines the position in the probability grid that has the highest
@@ -362,6 +358,7 @@ def determine_sound_positions_instance(r_ref, l_ref, node_events, **kwargs):
def evaluate_location_list(location_list):
+
if location_list == None:
return 0
@@ -372,10 +369,10 @@ def evaluate_location_list(location_list):
return locations_conf
-def determine_sound_positions(r_ref, l_ref, node_events, **kwargs):
+def determine_reference_data(r_ref, l_ref, node_events, **kwargs):
pos_func = lambda ref: -1 * evaluate_location_list(
- determine_sound_positions_instance(
+ determine_sound_locations_instance(
ref[0], ref[1],
node_events,
**kwargs
@@ -386,103 +383,21 @@ def determine_sound_positions(r_ref, l_ref, node_events, **kwargs):
r_opt, l_opt = opt_output[0]
- return determine_sound_positions_instance(
- r_opt, l_opt,
- node_events,
- **kwargs
- )
-
-
-def generate_sound_position_func(r_ref, l_ref):
- """
-
- This is a closure that provides a new function that makes it so the
- developer does not need to continue passing the rRef, lRef and initGuess
- variables when determining the sound position. This is most useful when
- tracking a sound throughout an enivronment because these parameters will
- stay constant.
-
- @param rRef The reference distance at which the reference sound
- pressure level was recorded
-
- @param lRef The reference sound pressure level used to determine the
- distance from the newly measured sound pressure level
-
- @return A function that will use rRef, lRef, and initGuess to determine
- the position of the input sound. The independent variable will become
- just the node detection events.
-
- """
-
- return partial(
- determine_sound_positions,
- r_ref, l_ref, disp=0
- )
-
-
-def plot_detection_events(res, r_ref, l_ref, d_events, filename):
- """
+ return r_opt, l_opt
- Plots the detection events and saves the figure in the given path.
- @param res The list of locations. Locations are named tuples with fields
- which are position which is a point and confidence which is a float
+def determine_sound_locations(r_ref, l_ref, node_events, **kwargs):
- @param rRef The reference distance at which the reference sound
- pressure level was recorded
-
- @param lRef The reference sound pressure level used to determine the
- distance from the newly measured sound pressure level
-
- @param nodeEvents The list ofassociated data when a node detects with some
- confidence that the sound has been identified
-
- @return The plt object of the saved figure
-
- """
-
- fig = plt.figure("Locaudio")
- ax = fig.add_subplot(111)
- ax.set_xlabel("X Location")
- ax.set_ylabel("Y Location")
- x_min = 56.3399
- x_max = 56.3400
- y_min = -2.80834
- y_max = -2.80824
- v_step = 0.000001
- x = np.arange(x_min, x_max, v_step)
- y = np.arange(y_min, y_max, v_step)
- X, Y = np.meshgrid(x, y)
-
- zs = np.array(
- [
- position_probability(x, y, r_ref, l_ref, d_events)
- for x, y in zip(np.ravel(X), np.ravel(Y))
- ]
+ r_opt, l_opt = determine_reference_data(
+ r_ref, l_ref,
+ node_events,
+ **kwargs
)
- Z = zs.reshape(X.shape)
- ax.pcolormesh(X, Y, Z, cmap=cm.jet)
- ax.scatter(
- [p.position.x for p in res],
- [p.position.y for p in res],
- marker="+",
- linewidths=15,
- c="white"
- )
- ax.scatter(
- [d_event.x for d_event in d_events],
- [d_event.y for d_event in d_events],
- marker="o",
- linewidths=5,
- c="white",
- s=300
+ return determine_sound_locations_instance(
+ r_opt, l_opt,
+ node_events,
+ **kwargs
)
- ax.set_xlim(x_min, x_max)
- ax.set_ylim(y_min, y_max)
-
- plt.savefig(filename)
- return plt
-
diff --git a/tests/test_server.py b/tests/test_server.py
index 55b3097..d111aa8 100644
--- a/tests/test_server.py
+++ b/tests/test_server.py
@@ -14,7 +14,7 @@
import socket
-server_addr = socket.gethostbyname(socket.getfqdn())
+server_addr = "localhost" #socket.gethostbyname(socket.getfqdn())
server_port = 8000
test_sound_name = "Cock"
diff --git a/tests/test_triangulation.py b/tests/test_triangulation.py
index 11b8db2..3ee69bf 100644
--- a/tests/test_triangulation.py
+++ b/tests/test_triangulation.py
@@ -66,7 +66,7 @@ def test_optimization(self):
l_ref = 100
r_ref = 1
- res = tri.determine_sound_positions(
+ res = tri.determine_sound_locations(
r_ref, l_ref,
self.d_events,
disp=0
@@ -75,24 +75,12 @@ def test_optimization(self):
print "\n=== Optimization === :: [ Xs, Ys ] <--> ", res, "\n"
- def test_closure(self):
-
- r_ref = 1
- l_ref = 100
-
- clos = tri.generate_sound_position_func(r_ref, l_ref)
-
- print "\n=== Closure === :: V_1 == {0}, V_2 == {1}\n".format(
- clos(self.d_events), clos(self.d_events)
- )
-
-
def test_together(self):
r_ref = 1
l_ref = 100
- res = tri.determine_sound_positions(
+ res = tri.determine_sound_locations(
r_ref, l_ref,
self.d_events,
disp=0