summaryrefslogtreecommitdiff
path: root/altoslib
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-10-02 19:33:37 -0700
committerKeith Packard <keithp@keithp.com>2017-10-02 19:33:37 -0700
commit98dc29a7a964f8d653b73989c6751695d168844c (patch)
tree415e274078746fe853aad554aae1a2e5d1a57ca5 /altoslib
parentd75e8b9046295051c91696461e8d5f59c8260ccc (diff)
altoslib: Add user-selectable filter width for data smoothing
Also switch smoothing window to Kaiser and change default accel filter width to 1 second instead of 4 seconds. Now users can play with the filter and see what it does. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'altoslib')
-rw-r--r--altoslib/AltosFlightSeries.java90
-rw-r--r--altoslib/AltosTimeSeries.java42
-rw-r--r--altoslib/Makefile.am1
3 files changed, 105 insertions, 28 deletions
diff --git a/altoslib/AltosFlightSeries.java b/altoslib/AltosFlightSeries.java
index ab7943b3..02bf64ff 100644
--- a/altoslib/AltosFlightSeries.java
+++ b/altoslib/AltosFlightSeries.java
@@ -21,7 +21,7 @@ public class AltosFlightSeries extends AltosDataListener {
public ArrayList<AltosTimeSeries> series = new ArrayList<AltosTimeSeries>();
public double speed_filter_width = 4.0;
- public double accel_filter_width = 4.0;
+ public double accel_filter_width = 1.0;
public int[] indices() {
int[] indices = new int[series.size()];
@@ -160,6 +160,7 @@ public class AltosFlightSeries extends AltosDataListener {
}
public AltosTimeSeries accel_series;
+ public boolean accel_computed;
public static final String accel_name = "Accel";
@@ -174,17 +175,44 @@ public class AltosFlightSeries extends AltosDataListener {
accel_series = add_series(accel_name, AltosConvert.accel);
accel_series.add(time(), acceleration);
+ accel_computed = false;
}
- private void compute_accel() {
- if (accel_series != null)
- return;
+ private AltosTimeSeries compute_accel() {
+ AltosTimeSeries new_accel_series = null;
if (speed_series != null) {
- AltosTimeSeries temp_series = make_series(speed_name, AltosConvert.speed);
- speed_series.filter(temp_series, accel_filter_width);
- accel_series = add_series(accel_name, AltosConvert.accel);
- temp_series.differentiate(accel_series);
+ AltosTimeSeries temp_series;
+ if (accel_filter_width > 0) {
+ temp_series = make_series(speed_name, AltosConvert.speed);
+ speed_series.filter(temp_series, accel_filter_width);
+ } else
+ temp_series = speed_series;
+
+ new_accel_series = make_series(accel_name, AltosConvert.accel);
+ temp_series.differentiate(new_accel_series);
+ }
+ return new_accel_series;
+ }
+
+ public void set_filter(double speed_filter, double accel_filter) {
+ this.speed_filter_width = speed_filter;
+ this.accel_filter_width = accel_filter;
+
+ AltosTimeSeries new_speed_series = compute_speed();
+
+ if (new_speed_series != null) {
+ speed_series.erase_values();
+ for (AltosTimeValue tv : new_speed_series)
+ speed_series.add(tv);
+ }
+ if (accel_computed) {
+ AltosTimeSeries new_accel_series = compute_accel();
+ if (new_accel_series != null) {
+ accel_series.erase_values();
+ for (AltosTimeValue tv : new_accel_series)
+ accel_series.add(tv);
+ }
}
}
@@ -268,21 +296,24 @@ public class AltosFlightSeries extends AltosDataListener {
public static final String speed_name = "Speed";
- private void compute_speed() {
- if (speed_series != null)
- return;
-
+ private AltosTimeSeries compute_speed() {
+ AltosTimeSeries new_speed_series = null;
AltosTimeSeries alt_speed_series = null;
AltosTimeSeries accel_speed_series = null;
if (altitude_series != null) {
- AltosTimeSeries temp_series = make_series(altitude_name, AltosConvert.height);
- altitude_series.filter(temp_series, speed_filter_width);
+ AltosTimeSeries temp_series;
+
+ if (speed_filter_width > 0) {
+ temp_series = make_series(speed_name, AltosConvert.height);
+ altitude_series.filter(temp_series, speed_filter_width);
+ } else
+ temp_series = altitude_series;
alt_speed_series = make_series(speed_name, AltosConvert.speed);
temp_series.differentiate(alt_speed_series);
}
- if (accel_series != null) {
+ if (accel_series != null && !accel_computed) {
if (orient_series != null) {
vert_accel_series = add_series(vert_accel_name, AltosConvert.accel);
@@ -318,26 +349,25 @@ public class AltosFlightSeries extends AltosDataListener {
}
}
if (apogee_time == AltosLib.MISSING) {
- speed_series = alt_speed_series;
+ new_speed_series = alt_speed_series;
} else {
- speed_series = make_series(speed_name, AltosConvert.speed);
+ new_speed_series = make_series(speed_name, AltosConvert.speed);
for (AltosTimeValue d : accel_speed_series) {
if (d.time <= apogee_time)
- speed_series.add(d);
+ new_speed_series.add(d);
}
for (AltosTimeValue d : alt_speed_series) {
if (d.time > apogee_time)
- speed_series.add(d);
+ new_speed_series.add(d);
}
}
} else if (alt_speed_series != null) {
- speed_series = alt_speed_series;
+ new_speed_series = alt_speed_series;
} else if (accel_speed_series != null) {
- speed_series = accel_speed_series;
+ new_speed_series = accel_speed_series;
}
- if (speed_series != null)
- add_series(speed_series);
+ return new_speed_series;
}
public AltosTimeSeries orient_series;
@@ -690,8 +720,18 @@ public class AltosFlightSeries extends AltosDataListener {
public void finish() {
compute_orient();
- compute_speed();
- compute_accel();
+ if (speed_series == null) {
+ speed_series = compute_speed();
+ if (speed_series != null)
+ add_series(speed_series);
+ }
+ if (accel_series == null) {
+ accel_series = compute_accel();
+ if (accel_series != null) {
+ add_series(accel_series);
+ accel_computed = true;
+ }
+ }
compute_height();
}
diff --git a/altoslib/AltosTimeSeries.java b/altoslib/AltosTimeSeries.java
index 9f3b4d80..7208c176 100644
--- a/altoslib/AltosTimeSeries.java
+++ b/altoslib/AltosTimeSeries.java
@@ -20,15 +20,30 @@ public class AltosTimeSeries implements Iterable<AltosTimeValue>, Comparable<Alt
public String label;
public AltosUnits units;
ArrayList<AltosTimeValue> values;
+ boolean data_changed;
public int compareTo(AltosTimeSeries other) {
return label.compareTo(other.label);
}
public void add(AltosTimeValue tv) {
+ data_changed = true;
values.add(tv);
}
+ public void erase_values() {
+ data_changed = true;
+ this.values = new ArrayList<AltosTimeValue>();
+ }
+
+ public void clear_changed() {
+ data_changed = false;
+ }
+
+// public boolean changed() {
+// return data_changed;
+// }
+
public void add(double time, double value) {
add(new AltosTimeValue(time, value));
}
@@ -264,14 +279,35 @@ public class AltosTimeSeries implements Iterable<AltosTimeValue>, Comparable<Alt
}
- private double filter_coeff(double dist, double width) {
- double ratio = dist / (width / 2);
+ private static double i0(double x) {
+ double ds = 1, d = 0, s = 0;
- return Math.cos(ratio * Math.PI / 2);
+ do {
+ d += 2;
+ ds = ds * (x * x) / (d * d);
+ s += ds;
+ } while (ds - 0.2e-8 * s > 0);
+ return s;
+ }
+
+ private static double kaiser(double n, double m, double beta) {
+ double alpha = m / 2;
+ double t = (n - alpha) / alpha;
+
+ if (t > 1)
+ t = 1;
+ double k = i0 (beta * Math.sqrt (1 - t*t)) / i0(beta);
+ return k;
+ }
+
+ private double filter_coeff(double dist, double width) {
+ return kaiser(dist + width/2.0, width, 2 * Math.PI);
}
public AltosTimeSeries filter(AltosTimeSeries f, double width) {
+
double half_width = width/2;
+ int half_point = values.size() / 2;
for (int i = 0; i < values.size(); i++) {
double center_time = values.get(i).time;
double left_time = center_time - half_width;
diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am
index 08af9496..2a1cb8e4 100644
--- a/altoslib/Makefile.am
+++ b/altoslib/Makefile.am
@@ -55,6 +55,7 @@ altoslib_JAVA = \
AltosEepromList.java \
AltosEepromLog.java \
AltosFile.java \
+ AltosFilterListener.java \
AltosFlash.java \
AltosFlashListener.java \
AltosDataListener.java \