From 6f54646482e44051af1d3e2965012888b00e2038 Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Wed, 21 Mar 2018 14:41:16 -0600 Subject: Internalize data recorder details --- src/survive_playback.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++--- src/survive_process.c | 11 ++++ 2 files changed, 164 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/survive_playback.c b/src/survive_playback.c index 54b97f6..45eea85 100644 --- a/src/survive_playback.c +++ b/src/survive_playback.c @@ -12,6 +12,139 @@ #include "survive_default_devices.h" #include "os_generic.h" +#include "stdarg.h" + +typedef struct SurviveRecordingData { + bool alwaysWriteStdOut; + FILE *output_file; +} SurviveRecordingData; + +static double timestamp_in_us() { + static double start_time_us = 0; + if (start_time_us == 0.) + start_time_us = OGGetAbsoluteTime(); + return OGGetAbsoluteTime() - start_time_us; +} + +static void write_to_output(SurviveRecordingData *recordingData, const char *format, ...) { + double ts = timestamp_in_us(); + + if (recordingData->output_file) { + va_list args; + va_start(args, format); + fprintf(recordingData->output_file, "%0.6f ", ts); + vfprintf(recordingData->output_file, format, args); + va_end(args); + } + + if (recordingData->alwaysWriteStdOut) { + va_list args; + va_start(args, format); + fprintf(stdout, "%0.6f ", ts); + vfprintf(stdout, format, args); + va_end(args); + } +} +void survive_recording_config_process(SurviveObject *so, char *ct0conf, int len) { + SurviveRecordingData *recordingData = so->ctx->recptr; + if (recordingData == 0) + return; + + char *buffer = malloc(len); + memcpy(buffer, ct0conf, len); + for (int i = 0; i < len; i++) + if (buffer[i] == '\n') + buffer[i] = ' '; + + write_to_output(recordingData, "%s CONFIG %.*s\n", so->codename, len, buffer); +} + +void survive_recording_lighthouse_process(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lh_pose, + SurvivePose *obj) { + SurviveRecordingData *recordingData = ctx->recptr; + if (recordingData == 0) + return; + + write_to_output(recordingData, "%d LH_POSE %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f\n", lighthouse, + lh_pose->Pos[0], lh_pose->Pos[1], lh_pose->Pos[2], lh_pose->Rot[0], lh_pose->Rot[1], + lh_pose->Rot[2], lh_pose->Rot[3]); +} +void survive_recording_raw_pose_process(SurviveObject *so, uint8_t lighthouse, SurvivePose *pose) { + SurviveRecordingData *recordingData = so->ctx->recptr; + if (recordingData == 0) + return; + + write_to_output(recordingData, "%s POSE %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f\n", so->codename, pose->Pos[0], + pose->Pos[1], pose->Pos[2], pose->Rot[0], pose->Rot[1], pose->Rot[2], pose->Rot[3]); +} + +void survive_recording_info_process(SurviveContext *ctx, const char *fault) { + SurviveRecordingData *recordingData = ctx->recptr; + if (recordingData == 0) + return; + + write_to_output(recordingData, "INFO LOG %s\n", fault); +} + +void survive_recording_angle_process(struct SurviveObject *so, int sensor_id, int acode, uint32_t timecode, FLT length, + FLT angle, uint32_t lh) { + SurviveRecordingData *recordingData = so->ctx->recptr; + if (recordingData == 0) + return; + + write_to_output(recordingData, "%s A %d %d %u %0.6f %0.6f %u\n", so->codename, sensor_id, acode, timecode, length, + angle, lh); +} + +void survive_recording_light_process(struct SurviveObject *so, int sensor_id, int acode, int timeinsweep, + uint32_t timecode, uint32_t length, uint32_t lh) { + SurviveRecordingData *recordingData = so->ctx->recptr; + if (recordingData == 0) + return; + + if (acode == -1) { + write_to_output(recordingData, "%s S %d %d %d %u %u %u\n", so->codename, sensor_id, acode, timeinsweep, + timecode, length, lh); + return; + } + + const char *LH_ID = 0; + const char *LH_Axis = 0; + + switch (acode) { + case 0: + case 2: + LH_ID = "L"; + LH_Axis = "X"; + break; + case 1: + case 3: + LH_ID = "L"; + LH_Axis = "Y"; + break; + case 4: + case 6: + LH_ID = "R"; + LH_Axis = "X"; + break; + case 5: + case 7: + LH_ID = "R"; + LH_Axis = "Y"; + break; + } + write_to_output(recordingData, "%s %s %s %d %d %d %u %u %u\n", so->codename, LH_ID, LH_Axis, sensor_id, acode, + timeinsweep, timecode, length, lh); +} + +void survive_recording_imu_process(struct SurviveObject *so, int mask, FLT *accelgyro, uint32_t timecode, int id) { + SurviveRecordingData *recordingData = so->ctx->recptr; + if (recordingData == 0) + return; + + write_to_output(recordingData, "%s I %d %u %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %d\n", so->codename, mask, timecode, + accelgyro[0], accelgyro[1], accelgyro[2], accelgyro[3], accelgyro[4], accelgyro[5], id); +} struct SurvivePlaybackData { SurviveContext *ctx; @@ -24,13 +157,6 @@ struct SurvivePlaybackData { }; typedef struct SurvivePlaybackData SurvivePlaybackData; -double timestamp_in_us() { - static double start_time_us = 0; - if (start_time_us == 0.) - start_time_us = OGGetAbsoluteTime(); - return OGGetAbsoluteTime() - start_time_us; -} - static int parse_and_run_imu(const char *line, SurvivePlaybackData *driver) { char dev[10]; int timecode = 0; @@ -174,7 +300,27 @@ static int playback_close(struct SurviveContext *ctx, void *_driver) { return 0; } +void install_recording(SurviveContext *ctx) { + const char *dataout_file = survive_configs(ctx, "dataoutfile", SC_SETCONFIG, ""); + int record_to_stdout = survive_configi(ctx, "datastdout", SC_SETCONFIG, 0); + + if (strlen(dataout_file) > 0 || record_to_stdout) { + ctx->recptr = calloc(1, sizeof(struct SurviveRecordingData)); + + ctx->recptr->output_file = fopen(dataout_file, "w"); + if (ctx->recptr->output_file == 0 && !record_to_stdout) { + SV_INFO("Could not open %s for writing\n", dataout_file); + free(ctx->recptr); + ctx->recptr = 0; + return; + } + ctx->recptr->alwaysWriteStdOut = record_to_stdout; + } +} + int DriverRegPlayback(SurviveContext *ctx) { + install_recording(ctx); + const char *playback_file = survive_configs(ctx, "playbackfile", SC_SETCONFIG, ""); if (strlen(playback_file) == 0) { diff --git a/src/survive_process.c b/src/survive_process.c index 1402dab..6136148 100644 --- a/src/survive_process.c +++ b/src/survive_process.c @@ -4,6 +4,7 @@ #include "survive_cal.h" #include "survive_config.h" #include "survive_default_devices.h" +#include "survive_playback.h" //XXX TODO: Once data is avialble in the context, use the stuff here to handle converting from time codes to //proper angles, then from there perform the rest of the solution. @@ -18,6 +19,8 @@ void survive_default_light_process( SurviveObject * so, int sensor_id, int acode survive_cal_light( so, sensor_id, acode, timeinsweep, timecode, length, lh); } + survive_recording_light_process(so, sensor_id, acode, timeinsweep, timecode, length, lh); + //We don't use sync times, yet. if (sensor_id <= -1) { if (so->PoserFn) { @@ -79,6 +82,8 @@ void survive_default_angle_process( SurviveObject * so, int sensor_id, int acode SurviveSensorActivations_add(&so->activations, &l); + survive_recording_angle_process(so, sensor_id, acode, timecode, length, angle, lh); + if (ctx->calptr) { survive_cal_angle(so, sensor_id, acode, timecode, length, angle, lh); } @@ -130,6 +135,7 @@ void survive_default_raw_pose_process(SurviveObject *so, uint8_t lighthouse, Sur //printf("Pose: [%1.1x][%s][% 08.8f,% 08.8f,% 08.8f] [% 08.8f,% 08.8f,% 08.8f,% 08.8f]\n", lighthouse, so->codename, pos[0], pos[1], pos[2], quat[0], quat[1], quat[2], quat[3]); so->OutPose = *pose; so->FromLHPose[lighthouse] = *pose; + survive_recording_raw_pose_process(so, lighthouse, pose); } void survive_default_lighthouse_pose_process(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lighthouse_pose, @@ -143,9 +149,12 @@ void survive_default_lighthouse_pose_process(SurviveContext *ctx, uint8_t lighth config_set_lighthouse(ctx->lh_config, &ctx->bsd[lighthouse], lighthouse); config_save(ctx, "config.json"); + + survive_recording_lighthouse_process(ctx, lighthouse, lighthouse_pose, object_pose); } int survive_default_htc_config_process(SurviveObject *so, char *ct0conf, int len) { + survive_recording_config_process(so, ct0conf, len); return survive_load_htc_config_format(so, ct0conf, len); } void survive_default_imu_process( SurviveObject * so, int mask, FLT * accelgyromag, uint32_t timecode, int id ) @@ -167,5 +176,7 @@ void survive_default_imu_process( SurviveObject * so, int mask, FLT * accelgyrom if (so->PoserFn) { so->PoserFn( so, (PoserData *)&imu ); } + + survive_recording_imu_process(so, mask, accelgyromag, timecode, id); } -- cgit v1.2.3 From abb8176f4ef23047a66e416f3f3a6eee6fc7a0c4 Mon Sep 17 00:00:00 2001 From: Justin Berger Date: Thu, 22 Mar 2018 10:11:22 -0600 Subject: Fixed startup bug; changed config names to be consistent --- src/survive.c | 4 ++++ src/survive_playback.c | 18 ++++++++++-------- src/survive_playback.h | 17 +++++++++++++++++ src/survive_vive.c | 2 +- 4 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 src/survive_playback.h (limited to 'src') diff --git a/src/survive.c b/src/survive.c index 2f3034b..9209e7c 100644 --- a/src/survive.c +++ b/src/survive.c @@ -10,6 +10,7 @@ #include "os_generic.h" #include "survive_config.h" #include "survive_default_devices.h" +#include "survive_playback.h" #ifdef __APPLE__ #define z_const const @@ -239,6 +240,9 @@ int survive_startup(SurviveContext *ctx) { const char *DriverName; i = 0; + + survive_install_recording(ctx); + while ((DriverName = GetDriverNameMatching("DriverReg", i++))) { DeviceDriver dd = GetDriver(DriverName); SV_INFO("Loading driver %s (%p) (%d)", DriverName, dd, i); diff --git a/src/survive_playback.c b/src/survive_playback.c index 45eea85..9261bb5 100644 --- a/src/survive_playback.c +++ b/src/survive_playback.c @@ -300,9 +300,9 @@ static int playback_close(struct SurviveContext *ctx, void *_driver) { return 0; } -void install_recording(SurviveContext *ctx) { - const char *dataout_file = survive_configs(ctx, "dataoutfile", SC_SETCONFIG, ""); - int record_to_stdout = survive_configi(ctx, "datastdout", SC_SETCONFIG, 0); +void survive_install_recording(SurviveContext *ctx) { + const char *dataout_file = survive_configs(ctx, "record", SC_SETCONFIG, ""); + int record_to_stdout = survive_configi(ctx, "record-stdout", SC_SETCONFIG, 0); if (strlen(dataout_file) > 0 || record_to_stdout) { ctx->recptr = calloc(1, sizeof(struct SurviveRecordingData)); @@ -314,14 +314,16 @@ void install_recording(SurviveContext *ctx) { ctx->recptr = 0; return; } + SV_INFO("Recording to '%s'", dataout_file); ctx->recptr->alwaysWriteStdOut = record_to_stdout; + if (record_to_stdout) { + SV_INFO("Recording to stdout"); + } } } int DriverRegPlayback(SurviveContext *ctx) { - install_recording(ctx); - - const char *playback_file = survive_configs(ctx, "playbackfile", SC_SETCONFIG, ""); + const char *playback_file = survive_configs(ctx, "playback", SC_SETCONFIG, ""); if (strlen(playback_file) == 0) { return 0; @@ -330,7 +332,7 @@ int DriverRegPlayback(SurviveContext *ctx) { SurvivePlaybackData *sp = calloc(1, sizeof(SurvivePlaybackData)); sp->ctx = ctx; sp->playback_dir = playback_file; - sp->time_factor = survive_configf(ctx, "playbackfactor", SC_SETCONFIG, 1.f); + sp->time_factor = survive_configf(ctx, "playback-factor", SC_SETCONFIG, 1.f); printf("%s\n", playback_file); @@ -341,7 +343,7 @@ int DriverRegPlayback(SurviveContext *ctx) { return -1; } - SV_INFO("Using playback file '%s'", playback_file); + SV_INFO("Using playback file '%s' with timefactor of %f", playback_file, sp->time_factor); SurviveObject *hmd = survive_create_hmd(ctx, "Playback", sp); SurviveObject *wm0 = survive_create_wm0(ctx, "Playback", sp, 0); SurviveObject *wm1 = survive_create_wm1(ctx, "Playback", sp, 0); diff --git a/src/survive_playback.h b/src/survive_playback.h new file mode 100644 index 0000000..52638a9 --- /dev/null +++ b/src/survive_playback.h @@ -0,0 +1,17 @@ +#include + +void survive_install_recording(SurviveContext *ctx); +void survive_recording_config_process(SurviveObject *so, char *ct0conf, int len); + +void survive_recording_lighthouse_process(SurviveContext *ctx, uint8_t lighthouse, SurvivePose *lh_pose, + SurvivePose *obj); + +void survive_recording_raw_pose_process(SurviveObject *so, uint8_t lighthouse, SurvivePose *pose); +void survive_recording_info_process(SurviveContext *ctx, const char *fault); +void survive_recording_angle_process(struct SurviveObject *so, int sensor_id, int acode, uint32_t timecode, FLT length, + FLT angle, uint32_t lh); + +void survive_recording_light_process(struct SurviveObject *so, int sensor_id, int acode, int timeinsweep, + uint32_t timecode, uint32_t length, uint32_t lh); + +void survive_recording_imu_process(struct SurviveObject *so, int mask, FLT *accelgyro, uint32_t timecode, int id); diff --git a/src/survive_vive.c b/src/survive_vive.c index cf068a3..d431207 100755 --- a/src/survive_vive.c +++ b/src/survive_vive.c @@ -1720,7 +1720,7 @@ void init_SurviveObject(SurviveObject* so) { int DriverRegHTCVive( SurviveContext * ctx ) { - const char *playback_dir = survive_configs(ctx, "playbackfile", SC_SETCONFIG, ""); + const char *playback_dir = survive_configs(ctx, "playback", SC_SETCONFIG, ""); if(strlen(playback_dir) != 0) { SV_INFO("Playback is active; disabling USB driver"); return 0; -- cgit v1.2.3