aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJulian Picht <julian.picht@gmail.com>2016-12-26 23:47:12 +0100
committerJulian Picht <julian.picht@gmail.com>2016-12-27 01:11:10 +0100
commit8688f251051fd0e12453f513b248f1c3e4f4dc7b (patch)
treeae38935445469012d9d227518103cd91bd6d04cf /src
parentfc193f834b55a37357796446579068722354e071 (diff)
downloadlibsurvive-8688f251051fd0e12453f513b248f1c3e4f4dc7b.tar.gz
libsurvive-8688f251051fd0e12453f513b248f1c3e4f4dc7b.tar.bz2
try to document disambiguator
Diffstat (limited to 'src')
-rw-r--r--src/disambiguator.c94
-rw-r--r--src/disambiguator.h49
2 files changed, 120 insertions, 23 deletions
diff --git a/src/disambiguator.c b/src/disambiguator.c
index f641834..b93639f 100644
--- a/src/disambiguator.c
+++ b/src/disambiguator.c
@@ -1,10 +1,54 @@
// (C) 2016 Julian Picht, MIT/x11 License.
//
-//All MIT/x11 Licensed Code in this file may be relicensed freely under the GPL or LGPL licenses.
+// All MIT/x11 Licensed Code in this file may be relicensed freely under the GPL or LGPL licenses.
+
+//
+// The theory behind this disambiguator is, that if we just track all pulses and if one could be a sync pulse, we look back in time,
+// if we saw as sync pulse X samples ago than it is probably a sync pulse.
+//
+// If the skip flag is set, X is 20000 else X is 400000
+//
#include "disambiguator.h"
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+
+typedef uint8_t pulse_data;
+
+/**
+ * Translate pulse length to pulse SKIP, DATA, AXIS
+ * @param length Length of the pulse in (1/48000000) seconds
+ * @return pulse data
+ */
+pulse_data get_pulse_data(uint32_t length) {
+ uint16_t temp = length - 2880;
+
+#if BETTER_SAFE_THAN_FAST
+ if (temp < 0 || length > 6525) {
+ return -1;
+ }
+#endif
+
+ if ((temp % 500) < 150) {
+ return temp / 500;
+ }
+
+ return -1;
+}
+
+const uint32_t pulse_types[] = {
+ 0, 1, 0, 1,
+ 2, 3, 2, 3,
+};
+
+#define PULSE_BIT_AXIS 0x1
+#define PULSE_BIT_DATA 0x2
+#define PULSE_BIT_SKIP 0x4
+
+#define PULSE_DATA(D) ((D >> 1)&0x1)
+#define PULSE_AXIS(D) (D&0x01)
+#define PULSE_SKIP(D) ((D >> 2)&0x1)
void disambiguator_init( struct disambiguator * d ) {
memset(&(d->times), 0x0, sizeof(d->times));
@@ -14,9 +58,14 @@ void disambiguator_init( struct disambiguator * d ) {
d->max_confidence = 0;
}
-inline void disambiguator_discard( struct disambiguator * d, long age );
+inline void disambiguator_discard( struct disambiguator * d, uint32_t age );
-void disambiguator_discard( struct disambiguator * d, long age )
+/**
+ * Drop all data that is outdated
+ * @param d
+ * @param age Maximum age of data we care to keep
+ */
+void disambiguator_discard( struct disambiguator * d, uint32_t age )
{
int confidence = 0;
for (unsigned int i = 0; i < DIS_NUM_VALUES; ++i) {
@@ -32,9 +81,15 @@ void disambiguator_discard( struct disambiguator * d, long age )
d->max_confidence = confidence;
}
-inline int disambiguator_find_nearest( struct disambiguator * d, long time, int max_diff );
+/**
+ * Find the index that has the best likelyhood too match up with the timestamp given
+ * @param time Rising edge time, where we expect to find the last sync pulse
+ * @param max_diff Maximum difference we are prepared to accept
+ * @return index inside d->times, if we found something, -1 otherwise
+ */
+inline int disambiguator_find_nearest( struct disambiguator * d, uint32_t time, int max_diff );
-int disambiguator_find_nearest( struct disambiguator * d, long time, int max_diff )
+int disambiguator_find_nearest( struct disambiguator * d, uint32_t time, int max_diff )
{
int diff = max_diff; // max allowed diff for a match
int idx = -1;
@@ -42,31 +97,44 @@ int disambiguator_find_nearest( struct disambiguator * d, long time, int max_dif
if (d->times[i] == 0) continue;
int a = abs(d->times[i] - time);
+
+// printf("T %d %d %d\n", time, i, a);
if (a < diff) {
idx = i;
diff = a;
}
}
+ if (idx != -1) {
+// printf("R %d %d %d\n", time, idx, d->scores[idx]);
+ }
return idx;
}
-pulse_type disambiguator_step( struct disambiguator * d, long time, int length)
+pulse_type disambiguator_step( struct disambiguator * d, uint32_t time, int length)
{
+ // all smaller pulses are most probably sweeps
+ // TODO: check we are inside the time window of actual sweeps
if (length < 2750) {
return d->state == D_STATE_LOCKED ? P_SWEEP : P_UNKNOWN;
}
- //printf( "%d %d\n", time, length );
- //printf( "." );
- //time -= length/2;
- disambiguator_discard(d, time - 10000000);
- int idx = disambiguator_find_nearest(d, time - 400000, 100);
-
+ // where to expect the corresponding pulse
+ uint32_t expected_diff = 400000;
+
+ // we expected to see a sync pulse earlier ...
if (time - d->last > 401000) {
d->state = D_STATE_UNLOCKED;
}
+
+ // discard all data, that is so old, we don't care about it anymore
+ disambiguator_discard(d, time - 10000000);
+
+ // find the best match for our timestamp and presumed offset
+ int idx = disambiguator_find_nearest(d, time - expected_diff, 100);
+ // We did not find a matching pulse, so try find a place to record the current
+ // one's time of arrival.
if (idx == -1) {
for (int i = 0; i < DIS_NUM_VALUES; ++i) {
if (d->times[i] == 0) {
@@ -78,7 +146,7 @@ pulse_type disambiguator_step( struct disambiguator * d, long time, int length)
return d->state == D_STATE_LOCKED ? P_SWEEP : P_UNKNOWN;
} else {
d->scores[idx]++;
- if (d->scores[idx] >= 30) {
+ if (d->scores[idx] >= DIS_NUM_PULSES_BEFORE_LOCK) {
d->state = D_STATE_LOCKED;
}
diff --git a/src/disambiguator.h b/src/disambiguator.h
index 0db19de..dbd4921 100644
--- a/src/disambiguator.h
+++ b/src/disambiguator.h
@@ -4,35 +4,64 @@
#ifndef DISAMBIGUATOR_H
#define DISAMBIGUATOR_H
-#define DIS_NUM_VALUES 8
+// Determines the number of samples stored in the disambiguator struct.
+// Has to be higher than the maximum number of pulses expected between sync pulses.
+#define DIS_NUM_VALUES 48
+#define DIS_NUM_PULSES_BEFORE_LOCK 30
+#include <stdint.h>
+/**
+ * internal disambiguator state
+ */
typedef enum {
D_STATE_INVALID = 0,
D_STATE_LOCKED = 1,
D_STATE_UNLOCKED = -1,
} dis_state;
+/**
+ * classification result
+ */
typedef enum {
P_UNKNOWN = 0,
P_SYNC = 1,
P_SWEEP = 2,
} pulse_type;
+/**
+ * internal state of the disambiguator
+ */
struct disambiguator {
- long times[DIS_NUM_VALUES];
- int scores[DIS_NUM_VALUES];
+ // the timestamps of the recorded pulses
+ uint32_t times[DIS_NUM_VALUES];
+ // countes how many sync pulses we have seen, that match the time offset at the same offset
+ uint16_t scores[DIS_NUM_VALUES];
+ // current state
dis_state state;
- long last;
+ // last sync pulse time
+ uint32_t last;
+ // the absolute maximum counter value
int max_confidence;
+ // the last code type seen
char code;
};
-struct classified_pulse_ {
- pulse_type t;
- int length;
-};
+/**
+ * Initialize a new disambiguator. calloc or memset with 0x00 will work just as well.
+ *
+ * @param d Pointer to the struct
+ */
void disambiguator_init( struct disambiguator * d);
-pulse_type disambiguator_step( struct disambiguator * d, long time, int length);
-#endif /* DISAMBIGUATOR_H */
+/**
+ * Feed in one pulse to have if classified.
+ *
+ * @param d Pointer to disambiguator state
+ * @param time Rising edge of the pulse
+ * @param length Length of the pulse
+ * @return Classification result
+ */
+pulse_type disambiguator_step( struct disambiguator * d, uint32_t time, int length);
+
+#endif /* DISAMBIGUATOR_H */ \ No newline at end of file