Improve app reliability
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Signed-off-by: Severin Kaderli <severin@kaderli.dev>
This commit is contained in:
Severin Kaderli 2022-12-22 20:39:09 +01:00
parent 5fb08ef5b4
commit efd8e63e4e
Signed by: severinkaderli
GPG key ID: F419F8835B72F0C4
3 changed files with 82 additions and 33 deletions

View file

@ -5,7 +5,7 @@ class Constants {
* @type {Number}
*/
static get CLOCK_TIME() {
return 1000;
return 500;
}
/**

View file

@ -16,7 +16,7 @@ abstract class BaseSensorActivity : BaseActivity(), SensorEventListener {
super.onResume()
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME);
}
override fun onStop() {

View file

@ -25,6 +25,9 @@ class ReceiveActivity : BaseSensorActivity() {
*/
private var signal = ArrayList<Sample<Signal>>()
/**
* Flag that determines if the preamble was already received.
*/
private var preambleReceived = false
override fun onCreate(savedInstanceState: Bundle?) {
@ -50,19 +53,51 @@ class ReceiveActivity : BaseSensorActivity() {
return getMidRangeOfData() + 3
}
return getMidRangeOfData();
return getMidRangeOfData() + 2
}
private fun getThresholdForLowSignals(): Float {
if (getRangeOfData() < 3) {
return getMidRangeOfData() + 3
}
return getMidRangeOfData() - 2
}
private fun getMidRangeOfData(): Float {
val maxValue = samples.maxByOrNull { it.value } ?: Sample(0f)
val minValue = samples.minByOrNull { it.value } ?: Sample(0f)
return (maxValue.value + minValue.value) / 2;
return (maxValue.value + minValue.value) / 2
}
private fun isHigh(value: Float): Boolean {
return value > getThresholdForHighSignals()
}
private fun isLow(value: Float): Boolean {
return value < getThresholdForLowSignals()
}
/**
* Check if the given sample should count as a high or low signal. If the sample is inside
* the threshold area it is not counted.
*/
private fun getSignalForSample(sample: Sample<Float>): Sample<Signal>? {
if (isHigh(sample.value)) {
return Sample(Signal.High)
}
if (isLow(sample.value)) {
return Sample(Signal.Low)
}
return null
}
/**
* Attempts to detect the preamble in the already received signal. If it can find the preamble it returns true and
* false otherwise.
*/
private fun detectPreamble(): Boolean {
val cleanedSignal = cleanSignal(signal)
val compressedSignal = compressSignal(cleanedSignal)
@ -89,9 +124,11 @@ class ReceiveActivity : BaseSensorActivity() {
return false
}
/**
* This functions takes the signal and filters out samples that are only in a cluster of 3 or less of the same signal.
* This way we can remove single jumps that occur in the signal.
*/
private fun cleanSignal(signal: List<Sample<Signal>>): List<Sample<Signal>> {
// TODO: Improve this method
// Remove outliers from the signal (single signal spikes or drops)
val cleanSignal = signal.filterIndexed { index, sample ->
var elementCount = 1
@ -127,40 +164,51 @@ class ReceiveActivity : BaseSensorActivity() {
private fun analyzePacketSignal(): List<Int> {
val cleanedSignal = cleanSignal(signal)
val compressedSignal = compressSignal(cleanedSignal)
if (compressedSignal.size < 2) {
return listOf()
}
val timeDifferences = ArrayList<Long>()
compressedSignal.forEachIndexed { index, sample ->
if (index == 0) {
var maxSamplesInARow = 0
var count = 0
cleanedSignal.forEachIndexed { index, sample ->
if(index == 0) {
return@forEachIndexed
}
timeDifferences.add(sample.timestamp - compressedSignal[index - 1].timestamp)
if(sample.value == cleanedSignal[index - 1].value) {
count ++
if(count > maxSamplesInARow) {
maxSamplesInARow = count
}
} else {
count = 0
}
}
val clockTimeThreshold = 900//timeDifferences.max() * 0.75
val packetData = ArrayList<Int>()
compressedSignal.forEachIndexed { index, sample ->
if (index == 0) {
return@forEachIndexed
var lastSignal: Sample<Signal>? = null
var isFirstSignal = true
var samplesSinceLastSignal = 0
cleanedSignal.forEach { sample ->
if (lastSignal == null) {
lastSignal = sample
}
val timeDifference = sample.timestamp - compressedSignal[index - 1].timestamp
if (timeDifference > clockTimeThreshold && timeDifference < 2500) {
if (sample.value == Signal.High) {
packetData.add(0)
} else {
packetData.add(1)
if (sample.value != lastSignal!!.value) {
if(samplesSinceLastSignal > (maxSamplesInARow * 0.75) || isFirstSignal) {
//Log.i(TAG, "$samplesSinceLastSignal")
if (sample.value == Signal.High) {
packetData.add(0)
} else {
packetData.add(1)
}
isFirstSignal = false
samplesSinceLastSignal=0
}
lastSignal = sample
}
samplesSinceLastSignal++
}
Log.i(TAG, "$timeDifferences")
//Log.i(TAG, "$cleanSignal")
return packetData
@ -171,15 +219,12 @@ class ReceiveActivity : BaseSensorActivity() {
samples.add(Sample(magneticFieldStrength))
// Determine whether the sample is a high or low signal
val currentSignal: Sample<Signal> = if (isHigh(magneticFieldStrength)) {
Sample(Signal.High)
} else {
Sample(Signal.Low)
}
val currentSignal = getSignalForSample(samples.last()) ?: return
signal.add(currentSignal)
// Try to detect the preamble in the signal
if (!preambleReceived) {
// If we detect the preamble we change the status on the screen and clear the existing signal data.
if (detectPreamble()) {
preambleReceived = true
preambleStatus.setText(R.string.preamble_status_detected)
@ -189,9 +234,12 @@ class ReceiveActivity : BaseSensorActivity() {
}
}
// After the preamble is detected we attempt to decode the packet.
if (preambleReceived) {
val packet = analyzePacketSignal();
// Get the decoded packet data
val packet = analyzePacketSignal()
// Get the payload length of in the data
var payloadLength = 0
if (packet.size >= 4) {
payloadLength = listToInteger(packet.take(4))
@ -207,6 +255,7 @@ class ReceiveActivity : BaseSensorActivity() {
receiveValue.text = payload
// TODO: CRC show and calculate if it's correct
if (packet.size >= 4 + (8 * payloadLength) + 8) {
// CRC Check
val crc = listToInteger(packet.take(4 + (8 * payloadLength) + 8).takeLast(8))
@ -217,7 +266,7 @@ class ReceiveActivity : BaseSensorActivity() {
}
private fun listToInteger(values: List<Int>): Int {
var value: Int = 0
var value = 0
for (bit in values) {
value = (value shl 1) + bit