Skip to content

Commit 656d676

Browse files
committed
v3.0
* Refactor
1 parent e89ffa2 commit 656d676

32 files changed

+307
-1006
lines changed

build.gradle

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
2-
32
buildscript {
43
repositories {
5-
jcenter()
64
google()
5+
mavenCentral()
6+
maven { url 'https://jitpack.io' }
77
}
8+
9+
ext.kotlin_version = '1.9.22'
10+
811
dependencies {
9-
classpath 'com.android.tools.build:gradle:3.5.3'
10-
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
12+
classpath 'com.android.tools.build:gradle:8.1.4'
13+
14+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22"
1115
}
1216
}
1317

18+
plugins {}
19+
1420
allprojects {
1521
repositories {
16-
jcenter()
22+
maven { url "https://maven.google.com" }
23+
maven { url "https://jitpack.io" }
1724
google()
25+
mavenCentral();
1826
}
19-
}
20-
21-
task clean(type: Delete) {
22-
delete rootProject.buildDir
23-
}
27+
}

documentation/USAGE.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@ public void onSensorChanged(SensorEvent event) {
2929

3030
```
3131
// Stil a BaseFilter under the hood
32-
private AveragingFilter averagingFilter;
32+
private AveragingFilter sensorFilter;
3333
private LinearAcceleration linearAccelerationFilter;
3434
3535
private void init() {
36-
averagingFilter = new ... // LowPassFilter(), MeanFilter(), MedianFilter();
36+
sensorFilter = new ... // LowPassFilter(), MeanFilter(), MedianFilter();
3737
// Make the filter "stiff" with a large time constant since gravity is a constant (mostly)
38-
averagingFilter.setTimeConstant(5);
38+
sensorFilter.setTimeConstant(5);
3939
4040
// Initialize the linear acceleration filter with the averaging filter
41-
linearAccelerationFilter = new LinearAccelerationAveraging(averagingFilter);
41+
linearAccelerationFilter = new LinearAccelerationAveraging(sensorFilter);
4242
}
4343
4444
@Override
@@ -51,7 +51,7 @@ public void onSensorChanged(SensorEvent event) {
5151
// You need to drive *both* filters. The input and the outputs can be driven at different rates...
5252
// For instance, once your averaging filter has essentially converged on gravity, it doesn't
5353
// need anymore inputs...
54-
averagingFilter.filter(acceleration);
54+
sensorFilter.filter(acceleration);
5555
linearAccelerationFilter.filter(acceleration);
5656
}
5757
}

fsensor/build.gradle

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
apply plugin: 'com.android.library'
2-
apply plugin: 'com.github.dcendents.android-maven'
3-
4-
group='com.github.KalebKE'
52

63
android {
7-
compileSdkVersion 29
4+
compileSdkVersion 34
85
buildToolsVersion "29.0.3"
96

7+
namespace = "com.kircherelectronics.fsensor"
8+
109
lintOptions {
1110
abortOnError false
1211
}
1312

1413
defaultConfig {
1514
minSdkVersion 14
16-
targetSdkVersion 29
15+
targetSdkVersion 33
1716
versionCode 9
1817
versionName "2.2"
1918

@@ -37,5 +36,5 @@ dependencies {
3736
})
3837
testImplementation 'junit:junit:4.12'
3938

40-
api files('libs/commons-math3-3.6.1.jar')
39+
implementation 'org.apache.commons:commons-math3:3.6.1'
4140
}

fsensor/libs/commons-math3-3.6.1.jar

-2.11 MB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
package com.kircherelectronics.fsensor.filter.averaging;
1+
package com.kircherelectronics.fsensor.filter;
22

33
/*
4-
* Copyright 2018, Kircher Electronics, LLC
4+
* Copyright 2024, Tracqi Technology, LLC
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -25,75 +25,51 @@
2525
* dt) where the time constant is the length of signals the fusedOrientation should act on
2626
* and dt is the sample period (1/frequency) of the sensor.
2727
*
28-
* http://developer.android.com/reference/android/hardware/SensorEvent.html
29-
* @author Kaleb
28+
* @author Kaleb Kircher
3029
*/
31-
public class LowPassFilter extends AveragingFilter
32-
{
30+
public class LowPassFilter extends SensorFilter {
3331
private static final String tag = LowPassFilter.class.getSimpleName();
3432

35-
// Gravity and linear accelerations components for the
36-
// Wikipedia low-pass fusedOrientation
37-
private float[] output;
38-
39-
public LowPassFilter() {
40-
this(DEFAULT_TIME_CONSTANT);
41-
}
33+
public LowPassFilter() {}
4234

4335
public LowPassFilter(float timeConstant) {
4436
this.timeConstant = timeConstant;
45-
reset();
4637
}
4738

4839
/**
4940
* Add a sample.
5041
*
51-
* @param values
52-
* The acceleration data. A 1x3 matrix containing the data from the X, Y and Z axis of the sensor
53-
* noting that order is arbitrary.
42+
* @param values The acceleration data. A 1x3 matrix containing the data from the X, Y and Z axis of the sensor
43+
* noting that order is arbitrary.
5444
* @return Returns the output of the fusedOrientation.
5545
*/
56-
public float[] filter(float[] values)
57-
{
46+
public float[] filter(float[] values) {
5847
// Initialize the start time.
59-
if (startTime == 0)
60-
{
48+
if (startTime == 0) {
6149
startTime = System.nanoTime();
6250
}
6351

64-
timestamp = System.nanoTime();
65-
6652
// Find the sample period (between updates) and convert from
6753
// nanoseconds to seconds. Note that the sensor delivery rates can
6854
// individually vary by a relatively large time frame, so we use an
6955
// averaging technique with the number of sensor updates to
7056
// determine the delivery rate.
71-
float dt = 1 / (count++ / ((timestamp - startTime) / 1000000000.0f));
57+
float dt = 1 / (count++ / ((System.nanoTime() - startTime) / 1000000000.0f));
7258

7359
float alpha = timeConstant / (timeConstant + dt);
60+
float oneMinusAlpha = 1 - alpha;
7461

75-
output[0] = alpha * output[0] + (1 - alpha) * values[0];
76-
output[1] = alpha * output[1] + (1 - alpha) * values[1];
77-
output[2] = alpha * output[2] + (1 - alpha) * values[2];
62+
output[0] = alpha * output[0] + oneMinusAlpha * values[0];
63+
output[1] = alpha * output[1] + oneMinusAlpha * values[1];
64+
output[2] = alpha * output[2] + oneMinusAlpha * values[2];
7865

79-
return output;
80-
}
66+
if(filter != null) {
67+
float[] filteredOutput = filter.filter(output);
68+
output[0] = filteredOutput[0];
69+
output[1] = filteredOutput[1];
70+
output[2] = filteredOutput[2];
71+
}
8172

82-
@Override
83-
public float[] getOutput() {
8473
return output;
8574
}
86-
87-
public void setTimeConstant(float timeConstant)
88-
{
89-
this.timeConstant = timeConstant;
90-
}
91-
92-
public void reset()
93-
{
94-
super.reset();
95-
this.output = new float[]
96-
{ 0, 0, 0 };
97-
98-
}
9975
}

fsensor/src/main/java/com/kircherelectronics/fsensor/filter/averaging/MeanFilter.java fsensor/src/main/java/com/kircherelectronics/fsensor/filter/MeanFilter.java

+8-24
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
package com.kircherelectronics.fsensor.filter.averaging;
1+
package com.kircherelectronics.fsensor.filter;
22

33
import java.util.ArrayDeque;
44
import java.util.Arrays;
55

66
/*
7-
* Copyright 2018, Kircher Electronics, LLC
7+
* Copyright 2024, Tracqi Technology, LLC
88
*
99
* Licensed under the Apache License, Version 2.0 (the "License");
1010
* you may not use this file except in compliance with the License.
@@ -33,12 +33,11 @@
3333
*
3434
* @author Kaleb
3535
*/
36-
public class MeanFilter extends AveragingFilter {
36+
public class MeanFilter extends SensorFilter {
3737

3838
private static final String tag = MeanFilter.class.getSimpleName();
3939

40-
private final ArrayDeque<float[]> values;
41-
private float[] output;
40+
private final ArrayDeque<float[]> values = new ArrayDeque<>();
4241

4342
/**
4443
* Initialize a new MeanFilter object.
@@ -49,7 +48,6 @@ public MeanFilter() {
4948

5049
public MeanFilter(float timeConstant) {
5150
super(timeConstant);
52-
values = new ArrayDeque<>();
5351
}
5452

5553
/**
@@ -64,14 +62,12 @@ public float[] filter(float[] data) {
6462
startTime = System.nanoTime();
6563
}
6664

67-
timestamp = System.nanoTime();
68-
6965
// Find the sample period (between updates) and convert from
7066
// nanoseconds to seconds. Note that the sensor delivery rates can
7167
// individually vary by a relatively large time frame, so we use an
7268
// averaging technique with the number of sensor updates to
7369
// determine the delivery rate.
74-
float hz = (count++ / ((timestamp - startTime) / 1000000000.0f));
70+
float hz = (count++ / ((System.nanoTime() - startTime) / 1000000000.0f));
7571

7672
int filterWindow = (int) Math.ceil(hz * timeConstant);
7773

@@ -82,20 +78,15 @@ public float[] filter(float[] data) {
8278
}
8379

8480
if(!values.isEmpty()) {
85-
output = getMean(values);
81+
float[] mean = getMean(values);
82+
System.arraycopy(mean, 0, output, 0, output.length);
8683
} else {
87-
output = new float[data.length];
8884
System.arraycopy(data, 0, output, 0, data.length);
8985
}
9086

9187
return output;
9288
}
9389

94-
@Override
95-
public float[] getOutput() {
96-
return output;
97-
}
98-
9990
/**
10091
* Get the mean of the data set.
10192
*
@@ -118,15 +109,8 @@ private float[] getMean(ArrayDeque<float[]> data) {
118109
return mean;
119110
}
120111

121-
public void setTimeConstant(float timeConstant) {
122-
this.timeConstant = timeConstant;
123-
}
124-
125112
public void reset() {
126113
super.reset();
127-
128-
if(values != null) {
129-
this.values.clear();
130-
}
114+
this.values.clear();
131115
}
132116
}

fsensor/src/main/java/com/kircherelectronics/fsensor/filter/averaging/MedianFilter.java fsensor/src/main/java/com/kircherelectronics/fsensor/filter/MedianFilter.java

+14-23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
package com.kircherelectronics.fsensor.filter.averaging;
1+
package com.kircherelectronics.fsensor.filter;
22

33
import org.apache.commons.math3.stat.StatUtils;
44

55
import java.util.ArrayDeque;
66
import java.util.Arrays;
77

88
/*
9-
* Copyright 2018, Kircher Electronics, LLC
9+
* Copyright 2024, Tracqi Technology, LLC
1010
*
1111
* Licensed under the Apache License, Version 2.0 (the "License");
1212
* you may not use this file except in compliance with the License.
@@ -37,14 +37,12 @@
3737
* @author Kaleb
3838
* @version %I%, %G%
3939
*/
40-
public class MedianFilter extends AveragingFilter {
40+
public class MedianFilter extends SensorFilter {
4141

4242
private static final String tag = MedianFilter.class
4343
.getSimpleName();
4444

45-
private final ArrayDeque<float[]> values;
46-
private float[] output;
47-
45+
private final ArrayDeque<float[]> values = new ArrayDeque<>();;
4846

4947
/**
5048
* Initialize a new MeanFilter object.
@@ -55,9 +53,6 @@ public MedianFilter() {
5553

5654
public MedianFilter(float timeConstant) {
5755
this.timeConstant = timeConstant;
58-
this.values = new ArrayDeque<>();
59-
60-
reset();
6156
}
6257

6358
/**
@@ -72,14 +67,12 @@ public float[] filter(float[] data) {
7267
startTime = System.nanoTime();
7368
}
7469

75-
timestamp = System.nanoTime();
76-
7770
// Find the sample period (between updates) and convert from
7871
// nanoseconds to seconds. Note that the sensor delivery rates can
7972
// individually vary by a relatively large time frame, so we use an
8073
// averaging technique with the number of sensor updates to
8174
// determine the delivery rate.
82-
float hz = (count++ / ((timestamp - startTime) / 1000000000.0f));
75+
float hz = (count++ / ((System.nanoTime() - startTime) / 1000000000.0f));
8376

8477
int filterWindow = (int) Math.ceil(hz * timeConstant);
8578

@@ -90,17 +83,19 @@ public float[] filter(float[] data) {
9083
}
9184

9285
if(!values.isEmpty()) {
93-
output = getMean(values);
86+
float[] median = getMedian(values);
87+
System.arraycopy(median, 0, output, 0, output.length);
9488
} else {
95-
output = new float[data.length];
9689
System.arraycopy(data, 0, output, 0, data.length);
9790
}
9891

99-
return output;
100-
}
92+
if(filter != null) {
93+
float[] filteredOutput = filter.filter(output);
94+
output[0] = filteredOutput[0];
95+
output[1] = filteredOutput[1];
96+
output[2] = filteredOutput[2];
97+
}
10198

102-
@Override
103-
public float[] getOutput() {
10499
return output;
105100
}
106101

@@ -110,7 +105,7 @@ public float[] getOutput() {
110105
* @param data the data set.
111106
* @return the mean of the data set.
112107
*/
113-
private float[] getMean(ArrayDeque<float[]> data) {
108+
private float[] getMedian(ArrayDeque<float[]> data) {
114109
float[] mean = new float[data.getFirst().length];
115110

116111
double[][] values = new double[data.getFirst().length][data.size()];
@@ -130,10 +125,6 @@ private float[] getMean(ArrayDeque<float[]> data) {
130125
return mean;
131126
}
132127

133-
public void setTimeConstant(float timeConstant) {
134-
this.timeConstant = timeConstant;
135-
}
136-
137128
public void reset() {
138129
super.reset();
139130

0 commit comments

Comments
 (0)