aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCNLohr <charles@cnlohr.com>2016-12-26 22:24:10 -0500
committerGitHub <noreply@github.com>2016-12-26 22:24:10 -0500
commita4c008dd28d2dda226bf9f9eace1413519fd76c6 (patch)
tree8ae47cc208b2d89f6828ad5cf6fb03f0f975d4da
parentdfed49687c361ccaae75c7389cddcfd74fbdf82e (diff)
parent1f141a4cd74c1c9b2d13a204da05ad697fa1c4bf (diff)
downloadlibsurvive-a4c008dd28d2dda226bf9f9eace1413519fd76c6.tar.gz
libsurvive-a4c008dd28d2dda226bf9f9eace1413519fd76c6.tar.bz2
Merge pull request #13 from jpicht/disambiguate
disambiguator
-rw-r--r--include/survive.h1
-rw-r--r--src/disambiguator.c148
-rw-r--r--src/disambiguator.h52
-rw-r--r--src/survive_data.c6
-rw-r--r--tools/disambiguate/Makefile8
-rw-r--r--tools/disambiguate/disambiguate.c37
-rw-r--r--tools/disambiguate/disambiguate2.c238
7 files changed, 436 insertions, 54 deletions
diff --git a/include/survive.h b/include/survive.h
index cf2ab81..30ee310 100644
--- a/include/survive.h
+++ b/include/survive.h
@@ -35,6 +35,7 @@ struct SurviveObject
int32_t last_photo_time;
int32_t last_photo_length;
#else
+ int32_t last_photo_time;
struct disambiguator * d;
#endif
diff --git a/src/disambiguator.c b/src/disambiguator.c
index f641834..f1d310a 100644
--- a/src/disambiguator.c
+++ b/src/disambiguator.c
@@ -1,23 +1,80 @@
// (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.
+//
+// X can be 20000 or 400000, depending if it came from the master or the slave.
+//
#include "disambiguator.h"
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+#include <stdbool.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));
memset(&(d->scores), 0x0, sizeof(d->scores));
+
d->state = D_STATE_UNLOCKED;
d->last = 0;
d->max_confidence = 0;
}
-inline void disambiguator_discard( struct disambiguator * d, long age );
+inline void disambiguator_discard( struct disambiguator * d );
-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 )
{
+ long age;
+ if (d->state == D_STATE_LOCKED) {
+ age = d->last - 400000;
+ } else {
+ age = 1000000;
+ }
int confidence = 0;
for (unsigned int i = 0; i < DIS_NUM_VALUES; ++i) {
if (d->times[i] != 0 && d->times[i] < age) {
@@ -32,41 +89,73 @@ 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 t1 Rising edge time, where we expect to find the last sync pulse, if this is a master pulse
+ * @param t2 Rising edge time, where we expect to find the last sync pulse, if this is a slave 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 t1, uint32_t t2, int max_diff );
-int disambiguator_find_nearest( struct disambiguator * d, long time, int max_diff )
+int disambiguator_find_nearest( struct disambiguator * d, uint32_t t1, uint32_t t2, int max_diff )
{
int diff = max_diff; // max allowed diff for a match
int idx = -1;
for (unsigned int i = 0; i < DIS_NUM_VALUES; ++i) {
if (d->times[i] == 0) continue;
- int a = abs(d->times[i] - time);
- if (a < diff) {
+ int a_1 = abs(d->times[i] - t1);
+ int a_2 = abs(d->times[i] - t2);
+
+// printf("T %d %d %d\n", time, i, a);
+ if (a_1 < diff) {
+ idx = i;
+ diff = a_1;
+ } else if (a_2 < diff) {
idx = i;
- diff = a;
+ diff = a_2;
}
}
+// if (idx != -1) {
+// printf("R %d %d %d\n", idx, d->scores[idx], diff);
+// }
+
return idx;
}
-pulse_type disambiguator_step( struct disambiguator * d, long time, int length)
+pulse_type disambiguator_step_return_helper( struct disambiguator * d, bool sweep_possible ) {
+ if (d->state == D_STATE_LOCKED && sweep_possible) {
+ return P_SWEEP;
+ }
+ return P_UNKNOWN;
+}
+
+pulse_type disambiguator_step( struct disambiguator * d, uint32_t time, int length)
{
+ uint32_t diff = time - d->last;
+ bool sweep_possible = (diff > 70000 && diff < 350000);
+
+ // 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;
+ return disambiguator_step_return_helper(d, sweep_possible);
}
- //printf( "%d %d\n", time, length );
- //printf( "." );
- //time -= length/2;
- disambiguator_discard(d, time - 10000000);
- int idx = disambiguator_find_nearest(d, time - 400000, 100);
-
+ // 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);
+
+ // find the best match for our timestamp and presumed offset
+ int idx = disambiguator_find_nearest(d, time - 400000, time - 20000, 1000);
+
+ // 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) {
@@ -75,19 +164,34 @@ pulse_type disambiguator_step( struct disambiguator * d, long time, int length)
}
}
- return d->state == D_STATE_LOCKED ? P_SWEEP : P_UNKNOWN;
+ return d->state == D_STATE_LOCKED && sweep_possible ? P_SWEEP : P_UNKNOWN;
} else {
d->scores[idx]++;
- if (d->scores[idx] >= 30) {
+
+ // we need to be reasonably sure, that we have the right pulses
+ if (d->scores[idx] >= DIS_NUM_PULSES_BEFORE_LOCK) {
d->state = D_STATE_LOCKED;
}
+ // if the offset is about 20000 ticks, then this is a slave pulse
+ if (diff < 21000) {
+ if (d->state == D_STATE_LOCKED) {
+ return P_SLAVE;
+ }
+
+ return P_UNKNOWN;
+ }
+
d->times[idx] = time;
d->last = time;
- return d->state == D_STATE_LOCKED ? (
- d->scores[idx] >= d->max_confidence ? P_SYNC : P_SWEEP
- ) : P_UNKNOWN;
+
+ // TODO: why do we need to check the confidence level here?
+ if (d->state == D_STATE_LOCKED && d->scores[idx] >= d->max_confidence) {
+ return P_MASTER;
+ }
+
+ return P_UNKNOWN;
}
- return d->state == D_STATE_LOCKED ? P_SWEEP : P_UNKNOWN;
+ return disambiguator_step_return_helper(d, sweep_possible);
}
diff --git a/src/disambiguator.h b/src/disambiguator.h
index 0db19de..8258a18 100644
--- a/src/disambiguator.h
+++ b/src/disambiguator.h
@@ -4,35 +4,65 @@
#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_MASTER = 1,
P_SWEEP = 2,
+ P_SLAVE = 3,
} 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
diff --git a/src/survive_data.c b/src/survive_data.c
index 791bdf6..3e5f14e 100644
--- a/src/survive_data.c
+++ b/src/survive_data.c
@@ -43,9 +43,13 @@ static void handle_lightcap( struct SurviveObject * so, struct LightcapElement *
int32_t offset = le->timestamp - so->d->last;
switch( disambiguator_step( so->d, le->timestamp, le->length ) ) {
default:
+ case P_SLAVE:
+ // this is only interesting for the OOTX data
+ break;
case P_UNKNOWN:
// not currently locked
- case P_SYNC:
+ break;
+ case P_MASTER:
ct->lightproc( so, le->sensor_id, -1, 0, le->timestamp, offset );
so->d->code = ((le->length+125)/250) - 12;
break;
diff --git a/tools/disambiguate/Makefile b/tools/disambiguate/Makefile
index 8e8661c..ef4e84c 100644
--- a/tools/disambiguate/Makefile
+++ b/tools/disambiguate/Makefile
@@ -1,5 +1,11 @@
disambiguate: disambiguate.c ../../src/disambiguator.c
- gcc -Wall -Wextra -Werror -g -o $@ $^ -lm
+ gcc -I../../src -Wall -Wextra -Werror -g -o $@ $^ -lm
test: disambiguate
./disambiguate | head -n 100
+
+disambiguate2: disambiguate2.c
+ gcc -Wall -Wextra -Werror -g -o $@ $^
+
+test2: disambiguate2
+ ./disambiguate2 | head -n 100
diff --git a/tools/disambiguate/disambiguate.c b/tools/disambiguate/disambiguate.c
index 7e46625..6e468dd 100644
--- a/tools/disambiguate/disambiguate.c
+++ b/tools/disambiguate/disambiguate.c
@@ -6,54 +6,53 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
-#include "../../include/disambiguator.h"
+#include "disambiguator.h"
int main() {
- FILE * f = fopen( "raw_light_data_from_watchman.sorted.csv", "r" );
+ FILE * f = fopen( "new_lightcap_data.csv", "r" );
if (f == NULL) {
fprintf(stderr, "ERROR OPENING INPUT FILE\n");
return -1;
}
- long last = 0, lastl = 0;
+ uint32_t last = 0, lastl = 0;
- disambiguator d;
+ struct disambiguator d;
disambiguator_init(&d);
for (;;) {
char controller[10];
int sensor;
int unknown;
- int length;
- long time;
+ uint32_t length;
+ uint32_t time;
- if (fscanf(f, "%s %d %d %d %li", controller, &sensor, &unknown, &length, &time) != 5) {
+ if (fscanf(f, "%s %d %d %d %d", controller, &sensor, &unknown, &length, &time) != 5) {
break;
}
if (lastl > time) {
- printf("BACKWARDS: %li %li\n", lastl, time);
+ //printf("BACKWARDS: %li %li\n", lastl, time);
}
lastl = time;
+ if (strcmp(controller, "HMD") != 0) continue;
+ char cc = (length - 2750) / 500;
switch (disambiguator_step(&d, time, length)) {
default:
case P_UNKNOWN:
- //printf("UNKN %s %2d %li %d\n", controller, sensor, time - last, length);
+ //printf("UNKN %s %2d %d %d\n", controller, sensor, time - last, length);
continue;
- case P_SYNC:
- {
- double l = length;
- char cc = round(l / 500) - 6;
- int ll = (length+125)/250;
- printf("SYNC %s %2d %10li %5d %c%d %10li %d %d\n", controller, sensor, time, length, (cc & 0x1) ? 'k' : 'j', (cc >> 1) & 0x3, time-last, ll & 1, (ll >> 1) - 6);
- last = time;
- }
+ case P_MASTER:
+ printf("MASTR %s %2d %10d %5d %c%d %10d\n", controller, sensor, time, length, (cc & 0x1) ? 'k' : 'j', (cc >> 1) & 0x3, time-last);
+ last = time;
+ continue;
+ case P_SLAVE:
+ printf("SLAVE %s %2d %10d %5d %c%d %10d\n", controller, sensor, time, length, (cc & 0x1) ? 'k' : 'j', (cc >> 1) & 0x3, time-last);
continue;
case P_SWEEP:
- printf("SWEEP %s %2d %10li %5d\n", controller, sensor, time - last, length);
+ printf("SWEEP %s %2d %10d %5d\n", controller, sensor, time - last, length);
continue;
}
}
fclose(f);
}
-
diff --git a/tools/disambiguate/disambiguate2.c b/tools/disambiguate/disambiguate2.c
new file mode 100644
index 0000000..4154314
--- /dev/null
+++ b/tools/disambiguate/disambiguate2.c
@@ -0,0 +1,238 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef uint8_t pulse_data;
+
+#if 0
+struct sync_pulse_lengths {
+ uint32_t expected_offset;
+ uint16_t min;
+ uint16_t max;
+ pulse_data simple_data;
+ pulse_data data;
+};
+
+const struct sync_pulse_lengths sync_pulses[] = {
+ {400000, 2880, 3024, 0x0, 0x0}, // SKIP 0 DATA 0 AXIS 0
+ {400000, 3380, 3524, 0x1, 0x1}, // SKIP 0 DATA 0 AXIS 1
+ {400000, 3880, 4024, 0x0, 0x2}, // SKIP 0 DATA 1 AXIS 0
+ {400000, 4380, 4524, 0x1, 0x3}, // SKIP 0 DATA 1 AXIS 1
+ { 20000, 4880, 5024, 0x2, 0x4}, // SKIP 1 DATA 0 AXIS 0
+ { 20000, 5380, 5524, 0x3, 0x5}, // SKIP 1 DATA 0 AXIS 1
+ { 20000, 5880, 6024, 0x2, 0x6}, // SKIP 1 DATA 1 AXIS 0
+ { 20000, 6380, 6524, 0x3, 0x7}, // SKIP 1 DATA 1 AXIS 1
+};
+#endif
+
+const uint32_t pulse_types[] = {
+ 0, 1, 0, 1,
+ 2, 3, 2, 3,
+};
+
+typedef enum {
+ PT_UNKNOWN = 0,
+ PT_SWEEP = 1,
+ PT_SYNC = 2
+} pulse_type;
+
+typedef enum {
+ AX_J = 0,
+ AX_K = 1
+} scan_axis;
+typedef enum {
+ SK_ON = 0x4,
+ SK_OFF = 0
+} scan_skip;
+
+
+#define DEBUG(...) printf(__VA_ARGS__)
+
+#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) ((scan_axis)(D&0x01))
+#define PULSE_SKIP(D) ((D >> 2)&0x1)
+
+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;
+}
+
+struct disambiguator;
+typedef pulse_type (*pulse_fn)(struct disambiguator * d, uint32_t timestamp, uint32_t length);
+typedef void (*data_fn)(struct disambiguator * d, uint8_t bit);
+
+void null_data_fn(struct disambiguator * d __attribute__((unused)), uint8_t bit __attribute__((unused))) {
+ return;
+}
+
+struct disambiguator {
+ pulse_fn pulse_fn;
+ data_fn data_fn;
+ uint32_t last_master_sync;
+ bool locked;
+};
+
+void disambiguator_init(struct disambiguator * d);
+pulse_type disambiguator_sync_start(struct disambiguator * d, uint32_t timestamp, uint32_t length);
+pulse_type disambiguator_sync_A1(struct disambiguator * d, uint32_t timestamp, uint32_t length);
+pulse_type disambiguator_sync_B0(struct disambiguator * d, uint32_t timestamp, uint32_t length);
+pulse_type disambiguator_sync_B1(struct disambiguator * d, uint32_t timestamp, uint32_t length);
+
+pulse_type disambiguator_sync_DONE(struct disambiguator * d, uint32_t timestamp, uint32_t length);
+
+void disambiguator_init(struct disambiguator * d) {
+ d->data_fn = &null_data_fn;
+ d->pulse_fn = &disambiguator_sync_start;
+ d->locked = false;
+}
+
+pulse_type disambiguator_sync_start(struct disambiguator * d, uint32_t timestamp, uint32_t length) {
+ DEBUG("START %10d %6d %6d\n", timestamp, 0, length);
+ pulse_data dd = get_pulse_data(length);
+ if ((dd & (PULSE_BIT_AXIS | PULSE_BIT_SKIP)) == 0) {
+ d->pulse_fn = &disambiguator_sync_A1;
+ d->last_master_sync = timestamp;
+ }
+ return PT_UNKNOWN;
+}
+
+pulse_type disambiguator_sync_A1(struct disambiguator * d, uint32_t timestamp, uint32_t length) {
+ pulse_data dd = get_pulse_data(length);
+ uint32_t diff = timestamp - d->last_master_sync;
+ DEBUG("A1 %10d %6d %6d\n", timestamp, diff, length);
+ if (18720 > diff) {
+ return PT_UNKNOWN;
+ }
+ if (diff > 21600) {
+ d->pulse_fn = &disambiguator_sync_start;
+ return PT_UNKNOWN;
+ }
+
+ if ((dd & (PULSE_BIT_AXIS | PULSE_BIT_SKIP)) == PULSE_BIT_SKIP) {
+ d->pulse_fn = &disambiguator_sync_B0;
+ }
+ return PT_UNKNOWN;
+}
+
+pulse_type disambiguator_sync_B0(struct disambiguator * d, uint32_t timestamp, uint32_t length) {
+ pulse_data dd = get_pulse_data(length);
+ uint32_t diff = timestamp - d->last_master_sync;
+ DEBUG("B0 %10d %6d %6d\n", timestamp, diff, length);
+ if (398832 > diff) {
+ return PT_UNKNOWN;
+ }
+ if (diff > 401136) {
+ d->pulse_fn = &disambiguator_sync_start;
+ return PT_UNKNOWN;
+ }
+
+ if ((dd & (PULSE_BIT_AXIS | PULSE_BIT_SKIP)) == PULSE_BIT_AXIS) {
+ d->pulse_fn = &disambiguator_sync_B1;
+ d->last_master_sync = timestamp;
+ }
+ return PT_UNKNOWN;
+}
+
+pulse_type disambiguator_sync_B1(struct disambiguator * d, uint32_t timestamp, uint32_t length) {
+ pulse_data dd = get_pulse_data(length);
+ uint32_t diff = timestamp - d->last_master_sync;
+ DEBUG("B1 %10d %6d %6d\n", timestamp, diff, length);
+ if (18720 > diff) {
+ return PT_UNKNOWN;
+ }
+ if (diff > 21600) {
+ d->pulse_fn = &disambiguator_sync_start;
+ return PT_UNKNOWN;
+ }
+
+ if ((dd & (PULSE_BIT_AXIS | PULSE_BIT_SKIP)) == (PULSE_BIT_AXIS|PULSE_BIT_SKIP)) {
+ d->pulse_fn = &disambiguator_sync_DONE;
+ d->locked = true;
+ }
+ return PT_UNKNOWN;
+}
+
+pulse_type disambiguator_sync_DONE(struct disambiguator * d __attribute__((unused)), uint32_t timestamp, uint32_t length) {
+ DEBUG("DONE %10d %6d %6d\n", timestamp, 0, length);
+ return PT_UNKNOWN;
+}
+
+uint32_t fake_pulse_length(pulse_data d) {
+ return 3000 + (d*500);
+}
+
+
+int main() {
+#ifdef TEST
+ struct disambiguator d;
+ d.data_fn = &null_data_fn;
+ d.pulse_fn = &disambiguator_sync_start;
+ d.pulse_fn(&d, 0, 3000);
+ d.pulse_fn(&d, 20000, fake_pulse_length(PULSE_BIT_SKIP));
+ d.pulse_fn(&d, 20000, 3500);
+#else
+ FILE * f = fopen( "raw_light_data_from_watchman.sorted.csv", "r" );
+ if (f == NULL) {
+ fprintf(stderr, "ERROR OPENING INPUT FILE\n");
+ return -1;
+ }
+
+ //long last = 0, lastl = 0;
+ long lastl = 0;
+
+ struct disambiguator d;
+ disambiguator_init(&d);
+ for (;;) {
+ char controller[10];
+ int sensor;
+ int unknown;
+ int length;
+ long time;
+
+ if (fscanf(f, "%s %d %d %d %li", controller, &sensor, &unknown, &length, &time) != 5) {
+ break;
+ }
+ printf("%s: ", controller);
+ if (lastl > time) {
+ printf("BACKWARDS: %li %li\n", lastl, time);
+ }
+ lastl = time;
+
+ d.pulse_fn(&d, time, length);
+/* switch (d.step_fn(&d, time, length)) {
+ default:
+ case P_UNKNOWN:
+ //printf("UNKN %s %2d %li %d\n", controller, sensor, time - last, length);
+ continue;
+ case P_SYNC:
+ {
+ double l = length;
+ char cc = round(l / 500) - 6;
+ int ll = (length+125)/250;
+ printf("SYNC %s %2d %10li %5d %c%d %10li %d %d\n", controller, sensor, time, length, (cc & 0x1) ? 'k' : 'j', (cc >> 1) & 0x3, time-last, ll & 1, (ll >> 1) - 6);
+ last = time;
+ }
+ continue;
+ case P_SWEEP:
+ printf("SWEEP %s %2d %10li %5d\n", controller, sensor, time - last, length);
+ continue;
+ }*/
+ }
+ fclose(f);
+#endif
+} \ No newline at end of file