From f3877f7b13c4f19ac101a0c6c7d4122a46db9a76 Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Mon, 26 Mar 2018 12:35:42 -0600 Subject: Initial pass --- src/survive_tb_disambiguator.c | 143 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 src/survive_tb_disambiguator.c (limited to 'src') diff --git a/src/survive_tb_disambiguator.c b/src/survive_tb_disambiguator.c new file mode 100644 index 0000000..5d79429 --- /dev/null +++ b/src/survive_tb_disambiguator.c @@ -0,0 +1,143 @@ +// +#include "survive_internal.h" +#include +#include /* for sqrt */ +#include +#include +#include + +#define NUM_HISTORY 3 + +enum LightcapClassification { LCC_UNKNOWN = 0, LCC_SYNC = 1, LCC_SWEEP = 2 }; + +typedef struct { + LightcapElement history[NUM_HISTORY]; + enum LightcapClassification classifications[NUM_HISTORY]; + int idx; +} SensorHistory_t; + +typedef struct { + LightcapElement last_sync; + SensorHistory_t histories[]; +} Disambiguator_data_t; + +Disambiguator_data_t *Disambiguator_data_t_ctor(SurviveObject *so) { + return calloc(sizeof(Disambiguator_data_t) + sizeof(SensorHistory_t) * so->sensor_ct, 1); +} + +static uint32_t timestamp_diff(uint32_t recent, uint32_t prior) { + if (recent > prior) + return recent - prior; + return (0xFFFFFFFF - prior) + recent; +} + +#define LOWER_SYNC_TIME 2250 +#define UPPER_SYNC_TIME 6750 + +static int circle_buffer_get(int idx, int offset) { return ((idx + offset) + NUM_HISTORY) % NUM_HISTORY; } + +static enum LightcapClassification classify(Disambiguator_data_t *d, SensorHistory_t *history, + const LightcapElement *le) { + bool clearlyNotSync = le->length < LOWER_SYNC_TIME || le->length > UPPER_SYNC_TIME; + + if (clearlyNotSync) { + return LCC_SWEEP; + } + + uint32_t time_diff_last_sync = timestamp_diff(le->timestamp, d->last_sync.timestamp); + uint32_t split_time = 399840; // 8.33ms in 48mhz + uint32_t jitter_allowance = 4000; + + // If we are ~8.33ms ahead of the last sync; we are a sync + if (d->last_sync.length > 0 && time_diff_last_sync < (split_time + jitter_allowance) && + time_diff_last_sync > (split_time - jitter_allowance)) { + return LCC_SYNC; + } + + if (d->last_sync.length > 0 && time_diff_last_sync < (split_time - jitter_allowance)) { + return LCC_SWEEP; + } + + int prevIdx = circle_buffer_get(history->idx, -1); + uint32_t time_diff = timestamp_diff(le->timestamp, history->history[prevIdx].timestamp); + + // We don't have recent data; unclear + if (time_diff > split_time - jitter_allowance) { + fprintf(stderr, "Time diff too high %d\n", time_diff); + return LCC_UNKNOWN; + } + + switch (history->classifications[prevIdx]) { + case LCC_SWEEP: + return LCC_SYNC; + } + fprintf(stderr, "last not sweep\n"); + return LCC_UNKNOWN; +} + +static enum LightcapClassification update_histories(Disambiguator_data_t *d, const LightcapElement *le) { + SensorHistory_t *history = &d->histories[le->sensor_id]; + + enum LightcapClassification classification = classify(d, history, le); + + history->classifications[history->idx] = classification; + history->history[history->idx] = *le; + history->idx = (history->idx + 1) % NUM_HISTORY; + + return classification; +} + +static int find_acode(uint32_t pulseLen) { + const static int offset = 50; + if (pulseLen < 2500 - offset) + return -1; + + if (pulseLen < 3000 + offset) + return 0; + if (pulseLen < 3500 + offset) + return 1; + if (pulseLen < 4000 + offset) + return 2; + if (pulseLen < 4500 + offset) + return 3; + if (pulseLen < 5000 + offset) + return 4; + if (pulseLen < 5500 + offset) + return 5; + if (pulseLen < 6000 + offset) + return 6; + if (pulseLen < 6500 + offset) + return 7; + + return -1; +} + +void DisambiguatorTimeBased(SurviveObject *so, const LightcapElement *le) { + SurviveContext *ctx = so->ctx; + if (so->disambiguator_data == NULL) { + SV_INFO("Initializing Disambiguator Data"); + so->disambiguator_data = Disambiguator_data_t_ctor(so); + } + + Disambiguator_data_t *d = so->disambiguator_data; + + SensorHistory_t *history = &d->histories[le->sensor_id]; + int prevIdx = circle_buffer_get(history->idx, -1); + uint32_t time_diff = timestamp_diff(le->timestamp, history->history[prevIdx].timestamp); + enum LightcapClassification classification = update_histories(d, le); + + SV_INFO("Classification %d\t%d\t%d\t%u\t%u(%.02fms)", classification, le->sensor_id, le->length, le->timestamp, + time_diff, (double)time_diff / 48000.0); + if (classification == LCC_SYNC) { + uint32_t time_diff_last_sync = timestamp_diff(le->timestamp, d->last_sync.timestamp); + if (time_diff_last_sync > (0xFFFFFFFF / 2)) + time_diff_last_sync = 0xFFFFFFFFF - time_diff_last_sync; + d->last_sync = *le; + int acode = find_acode(le->length); + SV_INFO("acode: %d 0x%x a:%d d:%d s:%d (%.02fms)", le->length, acode, acode & 1, (bool)(acode & 2), + (bool)(acode & 4), (double)time_diff_last_sync / 48000.); + assert(acode != -1); + } +} + +REGISTER_LINKTIME(DisambiguatorTimeBased); -- cgit v1.2.3