aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorultramn <dchapm2@umbc.edu>2017-03-08 21:03:46 -0800
committerultramn <dchapm2@umbc.edu>2017-03-08 21:03:46 -0800
commit91598e1806efce519d76c667954fd4c8da74e82e (patch)
treecd68d7b3f20b3ca09881b418f92cc06e65d906c6
parent3fa72f4b765457ce369d1aa1495dc36c90a94ebf (diff)
parent5629fd458d1de11f604248422473291e434c289f (diff)
downloadlibsurvive-91598e1806efce519d76c667954fd4c8da74e82e.tar.gz
libsurvive-91598e1806efce519d76c667954fd4c8da74e82e.tar.bz2
Merge branch 'master' of https://github.com/cnlohr/libsurvive
-rw-r--r--Makefile17
-rw-r--r--README.md1
-rw-r--r--calibrate.c10
-rw-r--r--calibrate_client.c33
-rw-r--r--data_recorder.c6
-rw-r--r--include/libsurvive/poser.h56
-rw-r--r--include/libsurvive/survive.h171
-rw-r--r--include/libsurvive/survive_types.h44
-rw-r--r--include/survive.h102
-rw-r--r--redist/json_helpers.c124
-rw-r--r--redist/json_helpers.h6
-rw-r--r--redist/linmath.c7
-rw-r--r--src/poser_dummy.c52
-rw-r--r--src/survive.c77
-rw-r--r--src/survive_cal.c10
-rw-r--r--src/survive_cal.h16
-rw-r--r--src/survive_cal_lhfind.c14
-rw-r--r--src/survive_config.c243
-rw-r--r--src/survive_config.h23
-rw-r--r--src/survive_data.c13
-rw-r--r--src/survive_driverman.c2
-rw-r--r--src/survive_driverman.h38
-rw-r--r--src/survive_internal.h94
-rw-r--r--src/survive_process.c39
-rw-r--r--src/survive_vive.c98
-rw-r--r--useful_files/81-vive.rules (renamed from 81-vive.rules)0
-rw-r--r--useful_files/htc_vive_edid_on_display_port.datbin0 -> 256 bytes
27 files changed, 893 insertions, 403 deletions
diff --git a/Makefile b/Makefile
index 75b5606..1a1712d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,29 +1,34 @@
all : lib data_recorder test calibrate calibrate_client
-CFLAGS:=-Iinclude -I. -fPIC -g -O0 -Iredist -flto -DUSE_DOUBLE -std=gnu99
+CFLAGS:=-Iinclude/libsurvive -I. -fPIC -g -O0 -Iredist -flto -DUSE_DOUBLE -std=gnu99
LDFLAGS:=-lpthread -lusb-1.0 -lz -lX11 -lm -flto -g
-
CALS:=src/survive_cal_lhfind.o src/survive_cal.o
+POSERS:=src/poser_dummy.o
+REDISTS:=redist/json_helpers.o redist/linmath.o redist/jsmn.o
+LIBSURVIVE_CORE:=src/survive.o src/survive_usb.o src/survive_data.o src/survive_process.o src/ootx_decoder.o src/survive_driverman.o src/survive_vive.o src/survive_config.o
+LIBSURVIVE_O:=$(CALS) $(POSERS) $(REDISTS) $(LIBSURVIVE_CORE)
+
+GRAPHICS_LOFI:=redist/DrawFunctions.o redist/XDriver.o
# unused: redist/crc32.c
test : test.c lib/libsurvive.so redist/os_generic.o
gcc -o $@ $^ $(LDFLAGS) $(CFLAGS)
-data_recorder : data_recorder.c lib/libsurvive.so redist/os_generic.o redist/DrawFunctions.o redist/XDriver.o
+data_recorder : data_recorder.c lib/libsurvive.so redist/os_generic.c $(GRAPHICS_LOFI)
gcc -o $@ $^ $(LDFLAGS) $(CFLAGS)
-calibrate : calibrate.c lib/libsurvive.so redist/os_generic.c redist/DrawFunctions.c redist/XDriver.c
+calibrate : calibrate.c lib/libsurvive.so redist/os_generic.c $(GRAPHICS_LOFI)
gcc -o $@ $^ $(LDFLAGS) $(CFLAGS)
-calibrate_client : calibrate_client.c lib/libsurvive.so redist/os_generic.c redist/DrawFunctions.c redist/XDriver.c
+calibrate_client : calibrate_client.c lib/libsurvive.so redist/os_generic.c $(GRAPHICS_LOFI)
gcc -o $@ $^ $(LDFLAGS) $(CFLAGS)
lib:
mkdir lib
-lib/libsurvive.so : src/survive.o src/survive_usb.o src/survive_data.o src/survive_process.o redist/jsmn.o src/ootx_decoder.o redist/linmath.o src/survive_driverman.o src/survive_vive.o src/survive_config.o redist/json_helpers.o $(DEBUGSTUFF) $(CALS)
+lib/libsurvive.so : $(LIBSURVIVE_O)
gcc -o $@ $^ $(LDFLAGS) -shared
clean :
diff --git a/README.md b/README.md
index f90590f..9428f39 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ Discord: https://discordapp.com/invite/7QbCAGS
| Fourth livestream | https://www.youtube.com/watch?v=fces1O7kWGY | 4:50:33 |
| Fifth livestream | https://www.youtube.com/watch?v=hHt3twW5_fI | 3:13:38 |
| Sixth livestream | https://www.youtube.com/watch?v=JsfkNRFkFM4 | 3:44:49 |
+| Seventh livestream | https://www.youtube.com/watch?v=EKSHvO3QSWY | 1:17:21 |
Notes from second livestream trying to reverse engineer the watchman protocol: https://gist.github.com/cnlohr/581c433f36f4249f8bbc9c2b6450ef0e
diff --git a/calibrate.c b/calibrate.c
index a04c269..82da7a7 100644
--- a/calibrate.c
+++ b/calibrate.c
@@ -76,15 +76,14 @@ void my_light_process( struct SurviveObject * so, int sensor_id, int acode, int
}
}
-void my_imu_process( struct SurviveObject * so, int16_t * accelgyro, uint32_t timecode, int id )
+void my_imu_process( struct SurviveObject * so, int mask, FLT * accelgyro, uint32_t timecode, int id )
{
- survive_default_imu_process( so, accelgyro, timecode, id );
+ survive_default_imu_process( so, mask, accelgyro, timecode, id );
-return;
//if( so->codename[0] == 'H' )
- if( 1 )
+ if( 0 )
{
- printf( "I %s %d %d %d %d %d %d %d %d\n", so->codename, timecode, accelgyro[0], accelgyro[1], accelgyro[2], accelgyro[3], accelgyro[4], accelgyro[5], id );
+ printf( "I %s %d %f %f %f %f %f %f %d\n", so->codename, timecode, accelgyro[0], accelgyro[1], accelgyro[2], accelgyro[3], accelgyro[4], accelgyro[5], id );
}
}
@@ -148,7 +147,6 @@ void * GuiThread( void * v )
int main()
{
ctx = survive_init( 0 );
- config_init();
survive_install_light_fn( ctx, my_light_process );
survive_install_imu_fn( ctx, my_imu_process );
diff --git a/calibrate_client.c b/calibrate_client.c
index 08f0715..f28520b 100644
--- a/calibrate_client.c
+++ b/calibrate_client.c
@@ -75,15 +75,14 @@ void my_light_process( struct SurviveObject * so, int sensor_id, int acode, int
}
}
-void my_imu_process( struct SurviveObject * so, int16_t * accelgyro, uint32_t timecode, int id )
+void my_imu_process( struct SurviveObject * so, int mask, FLT * accelgyro, uint32_t timecode, int id )
{
- survive_default_imu_process( so, accelgyro, timecode, id );
+ survive_default_imu_process( so, mask, accelgyro, timecode, id );
-return;
//if( so->codename[0] == 'H' )
- if( 1 )
+ if( 0 )
{
- printf( "I %s %d %d %d %d %d %d %d %d\n", so->codename, timecode, accelgyro[0], accelgyro[1], accelgyro[2], accelgyro[3], accelgyro[4], accelgyro[5], id );
+ printf( "I %s %d %f %f %f %f %f %f %d\n", so->codename, timecode, accelgyro[0], accelgyro[1], accelgyro[2], accelgyro[3], accelgyro[4], accelgyro[5], id );
}
}
@@ -142,6 +141,23 @@ void * GuiThread( void * v )
int main()
{
+/*
+ config_init();
+ config_read("config.json");
+ config_set_str(&global_config_values, "Hello","World!");
+ const char *s = config_read_str(&global_config_values, "test123","default");
+ printf("%s\n", s);
+
+ FLT *f;
+
+ uint16_t fs = config_read_float_array(lh_config+1, "fcalgibpha", &f, NULL, 0);
+ printf("%d\n", fs);
+ printf("===> %f %f\n", f[0], f[1]);
+
+
+// config_save("config.json");
+*/
+
ctx = survive_init( 1 );
survive_install_light_fn( ctx, my_light_process );
@@ -159,13 +175,6 @@ int main()
CNFGSetup( "Survive GUI Debug", 640, 480 );
OGCreateThread( GuiThread, 0 );
- config_init();
- config_set_str(&global_config_values, "Hello","World!");
- const char *s = config_read_str(&global_config_values, "TestStr","This is a test.");
- printf("%s\n", s);
- config_save("config.json");
-
-
if( !ctx )
{
fprintf( stderr, "Fatal. Could not start\n" );
diff --git a/data_recorder.c b/data_recorder.c
index 951f234..5504d42 100644
--- a/data_recorder.c
+++ b/data_recorder.c
@@ -77,15 +77,15 @@ void my_light_process( struct SurviveObject * so, int sensor_id, int acode, int
}
-void my_imu_process( struct SurviveObject * so, int16_t * accelgyro, uint32_t timecode, int id )
+void my_imu_process( struct SurviveObject * so, int mask, FLT * accelgyro, uint32_t timecode, int id )
{
- survive_default_imu_process( so, accelgyro, timecode, id );
+ survive_default_imu_process( so, mask, accelgyro, timecode, id );
//return;
//if( so->codename[0] == 'H' )
if( 1 )
{
- printf( "I %s %d %d %d %d %d %d %d %d\n", so->codename, timecode, accelgyro[0], accelgyro[1], accelgyro[2], accelgyro[3], accelgyro[4], accelgyro[5], id );
+ printf( "I %s %d %f %f %f %f %f %f %d\n", so->codename, timecode, accelgyro[0], accelgyro[1], accelgyro[2], accelgyro[3], accelgyro[4], accelgyro[5], id );
}
}
diff --git a/include/libsurvive/poser.h b/include/libsurvive/poser.h
new file mode 100644
index 0000000..98c926e
--- /dev/null
+++ b/include/libsurvive/poser.h
@@ -0,0 +1,56 @@
+#ifndef _LSPOSER_H
+#define _LSPOSER_H
+
+#include "survive_types.h"
+
+typedef enum PoserType_t
+{
+ POSERDATA_NONE = 0,
+ POSERDATA_IMU,
+ POSERDATA_LIGHT, //Single lighting event.
+ POSERDATA_FULL_SCENE, //Full, statified X, Y sweep data for both lighthouses.
+ POSERDATA_DISASSOCIATE, //If you get this, it doesn't contain data. It just tells you to please disassociate from the current SurviveObject and delete your poserdata.
+} PoserType;
+
+typedef struct
+{
+ PoserType pt;
+ uint8_t data[0];
+} PoserData;
+
+typedef struct
+{
+ PoserType pt;
+ uint8_t datamask; //0 = accel present, 1 = gyro present, 2 = mag present.
+ FLT accel[3];
+ FLT gyro[3];
+ FLT mag[3];
+ uint32_t timecode; //In object-local ticks.
+} PoserDataIMU;
+
+typedef struct
+{
+ PoserType pt;
+ int sensor_id;
+ int acode; //OOTX Code associated with this sweep. base_station = acode >> 2; axis = acode & 1;
+ uint32_t timecode; //In object-local ticks.
+ FLT length; //In seconds
+ FLT angle; //In radians from center of lighthouse.
+} PoserDataLight;
+
+typedef struct
+{
+ PoserType pt;
+
+ //If "lengths[...]" < 0, means not a valid piece of sweep information.
+ FLT lengths[SENSORS_PER_OBJECT][NUM_LIGHTHOUSES][2];
+ FLT angles [SENSORS_PER_OBJECT][NUM_LIGHTHOUSES][2]; //2 Axes (Angles in LH space)
+
+ PoserDataIMU lastimu;
+} PoserDataFullScene;
+
+//When you write your posers, use the following definition, and register with REGISTER_LINKTIME.
+typedef int (*PoserCB)( SurviveObject * so, PoserData * pd );
+
+
+#endif
diff --git a/include/libsurvive/survive.h b/include/libsurvive/survive.h
new file mode 100644
index 0000000..03249e9
--- /dev/null
+++ b/include/libsurvive/survive.h
@@ -0,0 +1,171 @@
+#ifndef _SURVIVE_H
+#define _SURVIVE_H
+
+#include <stdint.h>
+#include "survive_types.h"
+#include "poser.h"
+
+//DANGER: This structure may be redefined. Note that it is logically split into 64-bit chunks
+//for optimization on 32- and 64-bit systems.
+
+struct SurviveObject
+{
+ SurviveContext * ctx;
+
+ char codename[4]; //3 letters, null-terminated. Currently HMD, WM0, WM1.
+ char drivername[4]; //3 letters for driver. Currently "HTC"
+ int16_t buttonmask;
+ int16_t axis1;
+
+ int16_t axis2;
+ int16_t axis3;
+ int8_t charge;
+ int8_t charging:1;
+ int8_t ison:1;
+ int8_t additional_flags:6;
+
+ //Pose Information, also "poser" field.
+ FLT PoseConfidence; //0..1
+ SurvivePose OutPose;
+ SurvivePose FromLHPose[NUM_LIGHTHOUSES]; //Optionally filled out by poser, contains computed position from each lighthouse.
+ void * PoserData; //Initialized to zero, configured by poser, can be anything the poser wants.
+ PoserCB PoserFn;
+
+ //Device-specific information about the location of the sensors. This data will be used by the poser.
+ int8_t nr_locations;
+ FLT * sensor_locations;
+ FLT * sensor_normals;
+
+ //Timing sensitive data (mostly for disambiguation)
+ int32_t timebase_hz; //48,000,000 for normal vive hardware. (checked)
+ int32_t timecenter_ticks; //200,000 for normal vive hardware. (checked)
+ int32_t pulsedist_max_ticks; //500,000 for normal vive hardware. (guessed)
+ int32_t pulselength_min_sync; //2,200 for normal vive hardware. (guessed)
+ int32_t pulse_in_clear_time; //35,000 for normal vive hardware. (guessed)
+ int32_t pulse_max_for_sweep; //1,800 for normal vive hardware. (guessed)
+ int32_t pulse_synctime_offset; //20,000 for normal vive hardware. (guessed)
+ int32_t pulse_synctime_slack; //5,000 for normal vive hardware. (guessed)
+
+ //Flood info, for calculating which laser is currently sweeping.
+ int8_t oldcode;
+ int8_t sync_set_number; //0 = master, 1 = slave, -1 = fault.
+ int8_t did_handle_ootx; //If unset, will send lightcap data for sync pulses next time a sensor is hit.
+ uint32_t last_time[NUM_LIGHTHOUSES];
+ uint32_t last_length[NUM_LIGHTHOUSES];
+ uint32_t recent_sync_time;
+
+ uint32_t last_lighttime; //May be a 24- or 32- bit number depending on what device.
+
+
+ //Debug
+ int tsl;
+};
+
+
+struct BaseStationData
+{
+ uint8_t PositionSet:1;
+
+ SurvivePose Pose;
+
+ uint8_t OOTXSet:1;
+ uint32_t BaseStationID;
+ FLT fcalphase[2];
+ FLT fcaltilt[2];
+ FLT fcalcurve[2];
+ FLT fcalgibpha[2];
+ FLT fcalgibmag[2];
+};
+
+struct config_group;
+
+struct SurviveContext
+{
+ text_feedback_func faultfunction;
+ text_feedback_func notefunction;
+ light_process_func lightproc;
+ imu_process_func imuproc;
+ angle_process_func angleproc;
+
+ struct config_group* global_config_values;
+ struct config_group* lh_config; //lighthouse configs
+
+ //Calibration data:
+ BaseStationData bsd[NUM_LIGHTHOUSES];
+
+ SurviveCalData * calptr; //If and only if the calibration subsystem is attached.
+
+ SurviveObject ** objs;
+ int objs_ct;
+
+ void ** drivers;
+ DeviceDriverCb * driverpolls;
+ DeviceDriverCb * drivercloses;
+ DeviceDriverMagicCb * drivermagics;
+ int driver_ct;
+};
+
+SurviveContext * survive_init( int headless );
+
+//For any of these, you may pass in 0 for the function pointer to use default behavior.
+//In general unless you are doing wacky things like recording or playing back data, you won't need to use this.
+void survive_install_info_fn( SurviveContext * ctx, text_feedback_func fbp );
+void survive_install_error_fn( SurviveContext * ctx, text_feedback_func fbp );
+void survive_install_light_fn( SurviveContext * ctx, light_process_func fbp );
+void survive_install_imu_fn( SurviveContext * ctx, imu_process_func fbp );
+void survive_install_angle_fn( SurviveContext * ctx, angle_process_func fbp );
+
+void survive_close( SurviveContext * ctx );
+int survive_poll();
+
+SurviveObject * survive_get_so_by_name( SurviveContext * ctx, const char * name );
+
+//Utilitiy functions.
+int survive_simple_inflate( SurviveContext * ctx, const char * input, int inlen, char * output, int outlen );
+
+int survive_send_magic( SurviveContext * ctx, int magic_code, void * data, int datalen );
+
+//Install the calibrator.
+void survive_cal_install( SurviveContext * ctx ); //XXX This will be removed if not already done so.
+
+//Call these from your callback if overridden.
+//Accept higher-level data.
+void survive_default_light_process( SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length );
+void survive_default_imu_process( SurviveObject * so, int mode, FLT * accelgyro, uint32_t timecode, int id );
+void survive_default_angle_process( SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle );
+
+
+////////////////////// Survive Drivers ////////////////////////////
+
+void RegisterDriver( const char * name, void * data );
+
+#define REGISTER_LINKTIME( func ) \
+ void __attribute__((constructor)) Register##func() { RegisterDriver( #func, &func ); }
+
+
+
+///////////////////////// General stuff for writing drivers ///////
+
+//For device drivers to call. This actually attaches them.
+int survive_add_object( SurviveContext * ctx, SurviveObject * obj );
+void survive_add_driver( SurviveContext * ctx, void * payload, DeviceDriverCb poll, DeviceDriverCb close, DeviceDriverMagicCb magic );
+
+//For lightcap, etc. Don't change this structure at all. Regular vive is dependent on it being exactly as-is.
+//When you write drivers, you can use this to send survive lightcap data.
+typedef struct
+{
+ uint8_t sensor_id;
+ uint8_t type; //Mostly unused. Set to 255 to ignore it.
+ uint16_t length;
+ uint32_t timestamp;
+} __attribute__((packed)) LightcapElement;
+
+//This is the disambiguator function, for taking light timing and figuring out place-in-sweep for a given photodiode.
+void handle_lightcap( SurviveObject * so, LightcapElement * le );
+
+#define SV_INFO( x... ) { char stbuff[1024]; sprintf( stbuff, x ); ctx->notefunction( ctx, stbuff ); }
+#define SV_ERROR( x... ) { char stbuff[1024]; sprintf( stbuff, x ); ctx->faultfunction( ctx, stbuff ); }
+#define SV_KILL() exit(0) //XXX This should likely be re-defined.
+
+#endif
+
diff --git a/include/libsurvive/survive_types.h b/include/libsurvive/survive_types.h
new file mode 100644
index 0000000..1600e11
--- /dev/null
+++ b/include/libsurvive/survive_types.h
@@ -0,0 +1,44 @@
+#ifndef _SURVIVE_TYPES_H
+#define _SURVIVE_TYPES_H
+
+#ifndef FLT
+#ifdef USE_DOUBLE
+#define FLT double
+#else
+#define FLT float
+#endif
+#endif
+
+typedef struct SurvivePose
+{
+ FLT Pos[3];
+ FLT Rot[4];
+} SurvivePose;
+
+//Careful with this, you can't just add another one right now, would take minor changes in survive_data.c and the cal tools.
+//It will also require a recompile. TODO: revisit this and correct the comment once fixed.
+#define NUM_LIGHTHOUSES 2
+
+#define INTBUFFSIZE 64
+#define SENSORS_PER_OBJECT 32
+
+typedef struct SurviveObject SurviveObject;
+typedef struct SurviveContext SurviveContext;
+typedef struct BaseStationData BaseStationData;
+typedef struct SurviveCalData SurviveCalData; //XXX Warning: This may be removed. Check at a later time for its defunctness.
+
+typedef void (*text_feedback_func)( SurviveContext * ctx, const char * fault );
+typedef void (*light_process_func)( SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length );
+typedef void (*imu_process_func)( SurviveObject * so, int mask, FLT * accelgyro, uint32_t timecode, int id );
+typedef void (*angle_process_func)( SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle );
+
+
+//Device drivers (prefix your drivers with "DriverReg") i.e.
+// REGISTER_LINKTIME( DriverRegHTCVive );
+typedef int (*DeviceDriver)( SurviveContext * ctx );
+typedef int (*DeviceDriverCb)( struct SurviveContext * ctx, void * driver );
+typedef int (*DeviceDriverMagicCb)( struct SurviveContext * ctx, void * driver, int magic_code, void * data, int datalen );
+
+
+#endif
+
diff --git a/include/survive.h b/include/survive.h
deleted file mode 100644
index 51910a6..0000000
--- a/include/survive.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef _SURVIVE_H
-#define _SURVIVE_H
-
-#include <stdint.h>
-
-#ifndef FLT
-#ifdef USE_DOUBLE
-#define FLT double
-#else
-#define FLT float
-#endif
-#endif
-
-struct SurviveContext;
-
-//DANGER: This structure may be redefined. Note that it is logically split into 64-bit chunks
-//for optimization on 32- and 64-bit systems.
-
-//Careful with this, you can't just add another one right now, would take minor changes in survive_data.c and the cal tools.
-//It will also require a recompile. TODO: revisit this and correct the comment once fixed.
-#define NUM_LIGHTHOUSES 2
-
-struct SurviveObject
-{
- struct SurviveContext * ctx;
-
- char codename[4]; //3 letters, null-terminated. Currently HMD, WM0, WM1.
- char drivername[4]; //3 letters for driver. Currently "HTC"
- int16_t buttonmask;
- int16_t axis1;
-
- int16_t axis2;
- int16_t axis3;
- int8_t charge;
- int8_t charging:1;
- int8_t ison:1;
- int8_t additional_flags:6;
-
- FLT * sensor_locations;
- FLT * sensor_normals;
- int8_t nr_locations;
-
- //Timing sensitive data (mostly for disambiguation)
- int32_t timebase_hz; //48,000,000 for normal vive hardware. (checked)
- int32_t timecenter_ticks; //200,000 for normal vive hardware. (checked)
- int32_t pulsedist_max_ticks; //500,000 for normal vive hardware. (guessed)
- int32_t pulselength_min_sync; //2,200 for normal vive hardware. (guessed)
- int32_t pulse_in_clear_time; //35,000 for normal vive hardware. (guessed)
- int32_t pulse_max_for_sweep; //1,800 for normal vive hardware. (guessed)
- int32_t pulse_synctime_offset; //20,000 for normal vive hardware. (guessed)
- int32_t pulse_synctime_slack; //5,000 for normal vive hardware. (guessed)
-
- //Flood info, for calculating which laser is currently sweeping.
- int8_t oldcode;
- int8_t sync_set_number; //0 = master, 1 = slave, -1 = fault.
- int8_t did_handle_ootx; //If unset, will send lightcap data for sync pulses next time a sensor is hit.
- uint32_t last_time[NUM_LIGHTHOUSES];
- uint32_t last_length[NUM_LIGHTHOUSES];
- uint32_t recent_sync_time;
-
- uint32_t last_lighttime; //May be a 24- or 32- bit number depending on what device.
-
- //Debug
- int tsl;
-};
-
-typedef void (*text_feedback_func)( struct SurviveContext * ctx, const char * fault );
-typedef void (*light_process_func)( struct SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length );
-typedef void (*imu_process_func)( struct SurviveObject * so, int16_t * accelgyro, uint32_t timecode, int id );
-typedef void (*angle_process_func)( struct SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle );
-
-struct SurviveContext * survive_init( int headless );
-
-//For any of these, you may pass in 0 for the function pointer to use default behavior.
-void survive_install_info_fn( struct SurviveContext * ctx, text_feedback_func fbp );
-void survive_install_error_fn( struct SurviveContext * ctx, text_feedback_func fbp );
-void survive_install_light_fn( struct SurviveContext * ctx, light_process_func fbp );
-void survive_install_imu_fn( struct SurviveContext * ctx, imu_process_func fbp );
-void survive_install_angle_fn( struct SurviveContext * ctx, angle_process_func fbp );
-
-void survive_close( struct SurviveContext * ctx );
-int survive_poll();
-
-struct SurviveObject * survive_get_so_by_name( struct SurviveContext * ctx, const char * name );
-
-//Utilitiy functions.
-int survive_simple_inflate( struct SurviveContext * ctx, const char * input, int inlen, char * output, int outlen );
-
-int survive_send_magic( struct SurviveContext * ctx, int magic_code, void * data, int datalen );
-
-//Install the calibrator.
-void survive_cal_install( struct SurviveContext * ctx );
-
-//Call these from your callback if overridden.
-//Accept higher-level data.
-void survive_default_light_process( struct SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length );
-void survive_default_imu_process( struct SurviveObject * so, int16_t * accelgyro, uint32_t timecode, int id );
-void survive_default_angle_process( struct SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle );
-
-
-#endif
-
diff --git a/redist/json_helpers.c b/redist/json_helpers.c
index 74028b2..4a3ba55 100644
--- a/redist/json_helpers.c
+++ b/redist/json_helpers.c
@@ -6,6 +6,8 @@
#include <stdlib.h>
#include <string.h>
#include "json_helpers.h"
+#include <jsmn.h>
+
void json_write_float_array(FILE* f, const char* tag, float* v, uint8_t count) {
uint8_t i = 0;
@@ -14,16 +16,16 @@ void json_write_float_array(FILE* f, const char* tag, float* v, uint8_t count) {
asprintf(&str1,"\"%s\":[", tag);
for (i=0;i<count;++i) {
- if (i<(count-1)) {
- asprintf(&str2, "%s\"%f\",", str1,v[i]);
- } else {
+ if ( (i+1) < count) {
asprintf(&str2, "%s\"%f\"", str1,v[i]);
+ } else {
+ asprintf(&str2, "%s\"%f\",", str1,v[i]);
}
free(str1);
str1=str2;
str2=NULL;
}
- asprintf(&str2, "%s]", str1,v[i]);
+ asprintf(&str2, "%s]", str1);
fputs(str2,f);
free(str1);
free(str2);
@@ -45,7 +47,7 @@ void json_write_double_array(FILE* f, const char* tag, double* v, uint8_t count)
str1=str2;
str2=NULL;
}
- asprintf(&str2, "%s]", str1,v[i]);
+ asprintf(&str2, "%s]", str1);
fputs(str2,f);
free(str1);
free(str2);
@@ -61,4 +63,114 @@ void json_write_float(FILE* f, const char* tag, float v) {
void json_write_str(FILE* f, const char* tag, const char* v) {
fprintf(f, "\"%s\":\"%s\"", tag, v);
-} \ No newline at end of file
+}
+
+
+
+
+void (*json_begin_object)(char* tag) = NULL;
+void (*json_end_object)() = NULL;
+void (*json_tag_value)(char* tag, char** values, uint16_t count) = NULL;
+
+uint32_t JSON_STRING_LEN;
+
+char* load_file_to_mem(const char* path) {
+ FILE * f = fopen( path, "r" );
+ if (f==NULL) return NULL;
+ fseek( f, 0, SEEK_END );
+ int len = ftell( f );
+ fseek( f, 0, SEEK_SET );
+ char * JSON_STRING = malloc( len );
+ fread( JSON_STRING, len, 1, f );
+ fclose( f );
+ return JSON_STRING;
+}
+
+static char* substr(const char* str, uint32_t start, uint32_t end, uint32_t npos) {
+ uint32_t l = end-start+1;
+
+ if (end<=start || end>=npos) return NULL;
+
+ char* x = malloc(l);
+ memcpy(x,str+start,l);
+ x[l-1] = '\0';
+ return x;
+}
+
+static uint16_t json_load_array(const char* JSON_STRING, jsmntok_t* tokens, uint16_t size, char* tag) {
+ jsmntok_t* t = tokens;
+ uint16_t i = 0;
+
+ char* values[size];
+
+ for (i=0;i<size;++i) {
+ t = tokens+i;
+ values[i] = substr(JSON_STRING, t->start, t->end, JSON_STRING_LEN);
+ }
+
+ if (json_tag_value != NULL) json_tag_value(tag, values, i);
+
+ for (i=0;i<size;++i) free(values[i]);
+
+ return size;
+}
+
+void json_load_file(const char* path) {
+ uint32_t i = 0;
+
+ char* JSON_STRING = load_file_to_mem(path);
+ if (JSON_STRING==NULL) return;
+
+ JSON_STRING_LEN = strlen(JSON_STRING);
+
+ jsmn_parser parser;
+ jsmn_init(&parser);
+
+ uint32_t items = jsmn_parse(&parser, JSON_STRING, JSON_STRING_LEN, NULL, 0);
+ jsmntok_t* tokens = malloc(items * sizeof(jsmntok_t));
+
+ jsmn_init(&parser);
+ items = jsmn_parse(&parser, JSON_STRING, JSON_STRING_LEN, tokens, items);
+
+ int16_t children = -1;
+
+ for (i=0; i<items; i+=2)
+ {
+ //increment i on each successful tag + values combination, not individual tokens
+ jsmntok_t* tag_t = tokens+i;
+ jsmntok_t* value_t = tokens+i+1;
+
+ char* tag = substr(JSON_STRING, tag_t->start, tag_t->end, JSON_STRING_LEN);
+ char* value = substr(JSON_STRING, value_t->start, value_t->end, JSON_STRING_LEN);
+
+ printf("%d %d c:%d %d %s \n", tag_t->start, tag_t->end, tag_t->size, tag_t->type, tag);
+
+
+ if (value_t->type == JSMN_ARRAY) {
+ i += json_load_array(JSON_STRING, tokens+i+2,value_t->size, tag); //look at array children
+ } else if (value_t->type == JSMN_OBJECT) {
+ printf("Begin Object\n");
+ if (json_begin_object != NULL) json_begin_object(tag);
+ children = value_t->size +1; //+1 to account for this loop where we are not yed parsing children
+// i += decode_jsmn_object(JSON_STRING, tokens+i+2,value_t->size);
+ }
+ else {
+ if (json_tag_value != NULL) json_tag_value(tag, &value, 1);
+ }
+
+ if (children>=0) children--;
+ if (children == 0) {
+ children = -1;
+ printf("End Object\n");
+ if (json_end_object!=NULL) json_end_object();
+ }
+
+// printf("%d %s \n", value_t->type, tag);
+
+ free(tag);
+ free(value);
+ }
+
+ free(JSON_STRING);
+}
+
diff --git a/redist/json_helpers.h b/redist/json_helpers.h
index 8d6eb64..1670058 100644
--- a/redist/json_helpers.h
+++ b/redist/json_helpers.h
@@ -11,4 +11,10 @@ void json_write_uint32(FILE* f, const char* tag, uint32_t v);
void json_write_float(FILE* f, const char* tag, float v);
void json_write_str(FILE* f, const char* tag, const char* v);
+void json_load_file(const char* path);
+extern void (*json_begin_object)(char* tag);
+extern void (*json_end_object)();
+extern void (*json_tag_value)(char* tag, char** values, uint16_t count);
+
+
#endif \ No newline at end of file
diff --git a/redist/linmath.c b/redist/linmath.c
index 157141f..1c5c25b 100644
--- a/redist/linmath.c
+++ b/redist/linmath.c
@@ -93,11 +93,6 @@ void quatsetnone(FLT * q)
q[0] = 1; q[1] = 0; q[2] = 0; q[3] = 0;
}
-void quatsetidentity(FLT * q)
-{
- q[0] = 1; q[1] = 0; q[2] = 0; q[3] = 1;
-}
-
void quatcopy(FLT * qout, const FLT * qin)
{
qout[0] = qin[0];
@@ -447,7 +442,7 @@ void quatfrom2vectors(FLT *q, const FLT *src, const FLT *dest)
// If dot == 1, vectors are the same
if (d >= 1.0f)
{
- quatsetidentity(q);
+ quatsetnone(q);
return;
}
if (d < (1e-6f - 1.0f))
diff --git a/src/poser_dummy.c b/src/poser_dummy.c
new file mode 100644
index 0000000..67f8edb
--- /dev/null
+++ b/src/poser_dummy.c
@@ -0,0 +1,52 @@
+#include <survive.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct
+{
+ int something;
+ //Stuff
+} DummyData;
+
+int PoserDummy( SurviveObject * so, PoserData * pd )
+{
+ PoserType pt = pd->pt;
+ SurviveContext * ctx = so->ctx;
+ DummyData * dd = so->PoserData;
+
+ if( !dd ) so->PoserData = dd = malloc( sizeof( DummyData ) );
+
+ switch( pt )
+ {
+ case POSERDATA_IMU:
+ {
+ PoserDataIMU * imu = (PoserDataIMU*)pd;
+ //printf( "IMU:%s (%f %f %f) (%f %f %f)\n", so->codename, imu->accel[0], imu->accel[1], imu->accel[2], imu->gyro[0], imu->gyro[1], imu->gyro[2] );
+ break;
+ }
+ case POSERDATA_LIGHT:
+ {
+ PoserDataLight * l = (PoserDataLight*)pd;
+ //printf( "LIG:%s %d @ %f rad, %f s (AC %d) (TC %d)\n", so->codename, l->sensor_id, l->angle, l->length, l->acode, l->timecode );
+ break;
+ }
+ case POSERDATA_FULL_SCENE:
+ {
+ PoserDataFullScene * fs = (PoserDataFullScene*)pd;
+ //printf( "Full scene data.\n" );
+ break;
+ }
+ case POSERDATA_DISASSOCIATE:
+ {
+ free( dd );
+ so->PoserData = 0;
+ //printf( "Need to disassociate.\n" );
+ break;
+ }
+ }
+
+}
+
+
+REGISTER_LINKTIME( PoserDummy );
+
diff --git a/src/survive.c b/src/survive.c
index 9bc1a2c..09eb432 100644
--- a/src/survive.c
+++ b/src/survive.c
@@ -3,12 +3,13 @@
#include <survive.h>
#include "survive_internal.h"
-#include "survive_driverman.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
+#include "survive_config.h"
+
static void survivefault( struct SurviveContext * ctx, const char * fault )
{
fprintf( stderr, "Error: %s\n", fault );
@@ -21,11 +22,19 @@ static void survivenote( struct SurviveContext * ctx, const char * fault )
}
-struct SurviveContext * survive_init( int headless )
+SurviveContext * survive_init( int headless )
{
int r = 0;
int i = 0;
- struct SurviveContext * ctx = calloc( 1, sizeof( struct SurviveContext ) );
+ SurviveContext * ctx = calloc( 1, sizeof( SurviveContext ) );
+
+ ctx->global_config_values = malloc( sizeof(config_group) );
+ ctx->lh_config = malloc( sizeof(config_group) * NUM_LIGHTHOUSES);
+
+ init_config_group(ctx->global_config_values,10);
+ init_config_group(ctx->lh_config,10);
+
+ config_read(ctx, "config.json");
ctx->faultfunction = survivefault;
ctx->notefunction = survivenote;
@@ -36,7 +45,6 @@ struct SurviveContext * survive_init( int headless )
const char * DriverName;
while( ( DriverName = GetDriverNameMatching( "DriverReg", i++ ) ) )
-
{
DeviceDriver dd = GetDriver( DriverName );
printf( "Loading driver %s (%p) (%d)\n", DriverName, dd, i );
@@ -44,10 +52,34 @@ struct SurviveContext * survive_init( int headless )
printf( "Driver %s reports status %d\n", DriverName, r );
}
+ i = 0;
+ const char * PreferredPoser = config_read_str( ctx->global_config_values, "DefualtPoser", "PoserDummy" );
+ PoserCB PreferredPoserCB = 0;
+ const char * FirstPoser = 0;
+ printf( "Available posers:\n" );
+ while( ( DriverName = GetDriverNameMatching( "Poser", i++ ) ) )
+ {
+ PoserCB p = GetDriver( DriverName );
+ if( !PreferredPoserCB ) PreferredPoserCB = p;
+ int ThisPoser = strcmp( DriverName, PreferredPoser ) == 0;
+ printf( "\t%c%s\n", ThisPoser?'*':' ', DriverName );
+ if( ThisPoser ) PreferredPoserCB = p;
+ }
+ printf( "Totals %d posers. Using selected poser (or first!).\n", i-1 );
+ if( !PreferredPoserCB )
+ {
+ SV_ERROR( "Error. Cannot find any valid poser." );
+ }
+
+ for( i = 0; i < ctx->objs_ct; i++ )
+ {
+ ctx->objs[i]->PoserFn = PreferredPoserCB;
+ }
+
return ctx;
}
-void survive_install_info_fn( struct SurviveContext * ctx, text_feedback_func fbp )
+void survive_install_info_fn( SurviveContext * ctx, text_feedback_func fbp )
{
if( fbp )
ctx->notefunction = fbp;
@@ -55,7 +87,7 @@ void survive_install_info_fn( struct SurviveContext * ctx, text_feedback_func f
ctx->notefunction = survivenote;
}
-void survive_install_error_fn( struct SurviveContext * ctx, text_feedback_func fbp )
+void survive_install_error_fn( SurviveContext * ctx, text_feedback_func fbp )
{
if( fbp )
ctx->faultfunction = fbp;
@@ -63,7 +95,7 @@ void survive_install_error_fn( struct SurviveContext * ctx, text_feedback_func
ctx->faultfunction = survivefault;
}
-void survive_install_light_fn( struct SurviveContext * ctx, light_process_func fbp )
+void survive_install_light_fn( SurviveContext * ctx, light_process_func fbp )
{
if( fbp )
ctx->lightproc = fbp;
@@ -71,7 +103,7 @@ void survive_install_light_fn( struct SurviveContext * ctx, light_process_func f
ctx->lightproc = survive_default_light_process;
}
-void survive_install_imu_fn( struct SurviveContext * ctx, imu_process_func fbp )
+void survive_install_imu_fn( SurviveContext * ctx, imu_process_func fbp )
{
if( fbp )
ctx->imuproc = fbp;
@@ -80,7 +112,7 @@ void survive_install_imu_fn( struct SurviveContext * ctx, imu_process_func fbp
}
-void survive_install_angle_fn( struct SurviveContext * ctx, angle_process_func fbp )
+void survive_install_angle_fn( SurviveContext * ctx, angle_process_func fbp )
{
if( fbp )
ctx->angleproc = fbp;
@@ -88,15 +120,15 @@ void survive_install_angle_fn( struct SurviveContext * ctx, angle_process_func
ctx->angleproc = survive_default_angle_process;
}
-int survive_add_object( struct SurviveContext * ctx, struct SurviveObject * obj )
+int survive_add_object( SurviveContext * ctx, SurviveObject * obj )
{
int oldct = ctx->objs_ct;
- ctx->objs = realloc( ctx->objs, sizeof( struct SurviveObject * ) * (oldct+1) );
+ ctx->objs = realloc( ctx->objs, sizeof( SurviveObject * ) * (oldct+1) );
ctx->objs[oldct] = obj;
ctx->objs_ct = oldct+1;
}
-void survive_add_driver( struct SurviveContext * ctx, void * payload, DeviceDriverCb poll, DeviceDriverCb close, DeviceDriverMagicCb magic )
+void survive_add_driver( SurviveContext * ctx, void * payload, DeviceDriverCb poll, DeviceDriverCb close, DeviceDriverMagicCb magic )
{
int oldct = ctx->driver_ct;
ctx->drivers = realloc( ctx->drivers, sizeof( void * ) * (oldct+1) );
@@ -110,7 +142,7 @@ void survive_add_driver( struct SurviveContext * ctx, void * payload, DeviceDriv
ctx->driver_ct = oldct+1;
}
-int survive_send_magic( struct SurviveContext * ctx, int magic_code, void * data, int datalen )
+int survive_send_magic( SurviveContext * ctx, int magic_code, void * data, int datalen )
{
int oldct = ctx->driver_ct;
int i;
@@ -120,7 +152,7 @@ int survive_send_magic( struct SurviveContext * ctx, int magic_code, void * data
}
}
-void survive_close( struct SurviveContext * ctx )
+void survive_close( SurviveContext * ctx )
{
const char * DriverName;
int r = 0;
@@ -134,16 +166,33 @@ void survive_close( struct SurviveContext * ctx )
int oldct = ctx->driver_ct;
int i;
+
+ for( i = 0; i < ctx->objs_ct; i++ )
+ {
+ PoserData pd;
+ pd.pt = POSERDATA_DISASSOCIATE;
+ if( ctx->objs[i]->PoserFn ) ctx->objs[i]->PoserFn( ctx->objs[i], &pd );
+ }
+
for( i = 0; i < oldct; i++ )
{
ctx->drivercloses[i]( ctx, ctx->drivers[i] );
}
+
+ config_save(ctx, "config.json");
+
+ destroy_config_group(ctx->global_config_values);
+ destroy_config_group(ctx->lh_config);
+
free( ctx->objs );
free( ctx->drivers );
free( ctx->driverpolls );
free( ctx->drivermagics );
free( ctx->drivercloses );
+ free( ctx->global_config_values );
+ free( ctx->lh_config );
+
free( ctx );
}
diff --git a/src/survive_cal.c b/src/survive_cal.c
index f372309..06914eb 100644
--- a/src/survive_cal.c
+++ b/src/survive_cal.c
@@ -27,8 +27,8 @@ static void reset_calibration( struct SurviveCalData * cd );
void ootx_packet_clbk_d(ootx_decoder_context *ct, ootx_packet* packet)
{
- struct SurviveContext * ctx = (struct SurviveContext*)(ct->user);
- struct SurviveCalData * cd = ctx->calptr;
+ SurviveContext * ctx = (SurviveContext*)(ct->user);
+ SurviveCalData * cd = ctx->calptr;
int id = ct->user1;
SV_INFO( "Got OOTX packet %d %p", id, cd );
@@ -36,7 +36,7 @@ void ootx_packet_clbk_d(ootx_decoder_context *ct, ootx_packet* packet)
lighthouse_info_v6 v6;
init_lighthouse_info_v6(&v6, packet->data);
- struct BaseStationData * b = &ctx->bsd[id];
+ BaseStationData * b = &ctx->bsd[id];
//print_lighthouse_info_v6(&v6);
b->BaseStationID = v6.id;
@@ -52,8 +52,8 @@ void ootx_packet_clbk_d(ootx_decoder_context *ct, ootx_packet* packet)
b->fcalgibmag[1] = v6.fcal_1_gibmag;
b->OOTXSet = 1;
- config_set_lighthouse(b,id);
- config_save("config.json");
+ config_set_lighthouse(ctx->lh_config,b,id);
+// config_save("config.json");
}
int survive_cal_get_status( struct SurviveContext * ctx, char * description, int description_length )
diff --git a/src/survive_cal.h b/src/survive_cal.h
index bb4eb32..dd2a1e2 100644
--- a/src/survive_cal.h
+++ b/src/survive_cal.h
@@ -2,6 +2,8 @@
// All OOTX code was written by J. Allen. Rest of the code is probably mostly CNLohr.
+//XXX XXX XXX Warning: This subsystem will likely be mostly re-written.
+
#ifndef _SURVIVE_CAL_H
#define _SURVIVE_CAL_H
@@ -21,21 +23,21 @@
#include "ootx_decoder.h"
#include "survive_internal.h"
-void survive_cal_install( struct SurviveContext * ctx );
-int survive_cal_get_status( struct SurviveContext * ctx, char * description, int description_length );
+void survive_cal_install( SurviveContext * ctx );
+int survive_cal_get_status( SurviveContext * ctx, char * description, int description_length );
//void survive_cal_teardown( struct SurviveContext * ctx );
//Called from survive_default_light_process
-void survive_cal_light( struct SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length );
-void survive_cal_angle( struct SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle );
+void survive_cal_light( SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length );
+void survive_cal_angle( SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle );
#define MAX_SENSORS_TO_CAL 96
#define DRPTS 1024
#define MAX_CAL_PT_DAT (MAX_SENSORS_TO_CAL*NUM_LIGHTHOUSES*2)
struct SurviveCalData
{
- struct SurviveContext * ctx;
+ SurviveContext * ctx;
//OOTX Data is sync'd off of the sync pulses coming from the lighthouses.
ootx_decoder_context ootx_decoders[NUM_LIGHTHOUSES];
@@ -57,7 +59,7 @@ struct SurviveCalData
int senid_of_checkpt; //This is a point on a watchman that can be used to check the lh solution.
- struct SurviveObject * hmd;
+ SurviveObject * hmd;
//Stage:
// 0: Idle
@@ -68,7 +70,7 @@ struct SurviveCalData
//The following function is not included in the core survive_cal and must be compiled from a camfind file.
//It should use data for stage 4 and report if it found the
-int survive_cal_lhfind( struct SurviveCalData * cd );
+int survive_cal_lhfind( SurviveCalData * cd );
#endif
diff --git a/src/survive_cal_lhfind.c b/src/survive_cal_lhfind.c
index 93d9dc0..a1bb2cc 100644
--- a/src/survive_cal_lhfind.c
+++ b/src/survive_cal_lhfind.c
@@ -7,13 +7,13 @@
#define MIN_HITS_FOR_VALID 10
-FLT static RunOpti( struct SurviveCalData * cd, int lh, int print, FLT * LighthousePos, FLT * LighthouseQuat );
+FLT static RunOpti( SurviveCalData * cd, int lh, int print, FLT * LighthousePos, FLT * LighthouseQuat );
//Values used for RunTest()
-int survive_cal_lhfind( struct SurviveCalData * cd )
+int survive_cal_lhfind( SurviveCalData * cd )
{
- struct SurviveContext * ctx = cd->ctx;
+ SurviveContext * ctx = cd->ctx;
int cycle, i;
int lh = 0;
FLT dx, dy, dz;
@@ -137,8 +137,8 @@ int survive_cal_lhfind( struct SurviveCalData * cd )
}
cd->ctx->bsd[lh].PositionSet = 1;
- copy3d( cd->ctx->bsd[lh].Position, LighthousePos );
- quatcopy( cd->ctx->bsd[lh].Quaternion, LighthouseQuat );
+ copy3d( cd->ctx->bsd[lh].Pose.Pos, LighthousePos );
+ quatcopy( cd->ctx->bsd[lh].Pose.Rot, LighthouseQuat );
}
return 0; //Return 0 if success.
@@ -149,14 +149,14 @@ int survive_cal_lhfind( struct SurviveCalData * cd )
-static FLT RunOpti( struct SurviveCalData * cd, int lh, int print, FLT * LighthousePos, FLT * LighthouseQuat )
+static FLT RunOpti( SurviveCalData * cd, int lh, int print, FLT * LighthousePos, FLT * LighthouseQuat )
{
int i, p;
FLT UsToTarget[3];
FLT LastUsToTarget[3];
FLT mux = .9;
quatsetnone( LighthouseQuat );
- struct SurviveObject * hmd = cd->hmd;
+ SurviveObject * hmd = cd->hmd;
FLT * hmd_points = hmd->sensor_locations;
FLT * hmd_normals = hmd->sensor_normals;
diff --git a/src/survive_config.c b/src/survive_config.c
index c46e300..3f0f199 100644
--- a/src/survive_config.c
+++ b/src/survive_config.c
@@ -4,55 +4,89 @@
#include "survive_config.h"
#include <json_helpers.h>
-#define MAX_CONFIG_ENTRIES 100
-#define MAX_LIGHTHOUSES 2
+#include <errno.h>
+//#define MAX_CONFIG_ENTRIES 100
+//#define MAX_LIGHTHOUSES 2
-
-config_group global_config_values;
-config_group lh_config[MAX_LIGHTHOUSES]; //lighthouse configs
+//config_group global_config_values;
+//config_group lh_config[MAX_LIGHTHOUSES]; //lighthouse configs
//static uint16_t used_entries = 0;
-static FILE *config_file = NULL;
+//static FILE *config_file = NULL;
const FLT* config_set_float_a(config_group *cg, const char *tag, const FLT* values, uint8_t count);
+void init_config_entry(config_entry* ce) {
+ ce->data = NULL;
+ ce->tag = NULL;
+ ce->type = CONFIG_UNKNOWN;
+ ce->elements = 0;
+}
+
+void destroy_config_entry(config_entry* ce) {
+ if (ce->tag!=NULL) { free(ce->tag); ce->tag=NULL; }
+ if (ce->data!=NULL) { free(ce->data); ce->data=NULL; }
+}
+
void init_config_group(config_group *cg, uint16_t count) {
uint16_t i = 0;
- cg->config_entries = malloc(count*sizeof(config_entry));
cg->used_entries = 0;
cg->max_entries = count;
+ cg->config_entries = NULL;
+
+ if (count==0) return;
+
+ cg->config_entries = malloc(count*sizeof(config_entry));
for (i=0;i<count;++i) {
- cg->config_entries[i].data = NULL;
- cg->config_entries[i].tag = NULL;
- cg->config_entries[i].type = CONFIG_UNKNOWN;
- cg->config_entries[i].elements = 0;
+ init_config_entry(cg->config_entries+i);
}
}
-void config_init() {
+void destroy_config_group(config_group* cg) {
uint16_t i = 0;
- init_config_group(&global_config_values, MAX_CONFIG_ENTRIES);
- for(i=0;i<MAX_LIGHTHOUSES;i++) {
- init_config_group(lh_config+i, 9);
+ if (cg->config_entries==NULL) return;
+
+ for (i=0;i<cg->max_entries;++i) {
+ destroy_config_entry(cg->config_entries+i);
}
+
+ free(cg->config_entries);
}
-void config_load(const char* path) {
- config_file = fopen(path, "r");
+void resize_config_group(config_group *cg, uint16_t count) {
+ uint16_t i = 0;
+
+ if (count > cg->max_entries) {
+ config_entry* ptr = realloc(cg->config_entries, sizeof(config_entry)*count);
+ assert(ptr!=NULL);
+
+ cg->config_entries = ptr;
+
+ for (i=cg->max_entries;i<count;++i) {
+ init_config_entry(cg->config_entries+i);
+ }
+
+ cg->max_entries = count;
+ }
}
-void config_close() {
- fclose(config_file);
+/*
+void config_init() {
+ uint16_t i = 0;
+ init_config_group(&global_config_values, MAX_CONFIG_ENTRIES);
+ for(i=0;i<MAX_LIGHTHOUSES;i++) {
+ init_config_group(lh_config+i, 9);
+ }
}
+*/
-void config_set_lighthouse(struct BaseStationData* bsd, uint8_t idx) {
+void config_set_lighthouse(config_group* lh_config, BaseStationData* bsd, uint8_t idx) {
config_group *cg = lh_config+idx;
config_set_uint32(cg,"index", idx);
config_set_uint32(cg,"id", bsd->BaseStationID);
- config_set_float_a(cg,"position", bsd->Position, 3);
- config_set_float_a(cg,"quaternion", bsd->Quaternion, 4);
+ config_set_float_a(cg,"pose", &bsd->Pose.Pos[0], 7);
config_set_float_a(cg,"fcalphase", bsd->fcalphase, 2);
config_set_float_a(cg,"fcaltilt", bsd->fcaltilt,2);
config_set_float_a(cg,"fcalcurve", bsd->fcalcurve,2);
@@ -64,11 +98,10 @@ void sstrcpy(char** dest, const char *src) {
uint32_t len = strlen(src)+1;
assert(dest!=NULL);
- if (*dest == NULL) {
- *dest = (char*)malloc(len);
- } else {
- *dest = (char*)realloc(*dest, len);
- }
+ char* ptr = (char*)realloc(*dest, len); //acts like malloc if dest==NULL
+ assert(ptr!=NULL);
+ *dest = ptr;
+
strcpy(*dest,src);
}
@@ -106,9 +139,29 @@ FLT config_read_float(config_group *cg, const char *tag, const FLT def) {
return config_set_float(cg, tag, def);
}
+uint16_t config_read_float_array(config_group *cg, const char *tag, const FLT** values, const FLT* def, uint16_t count) {
+ config_entry *cv = find_config_entry(cg, tag);
+
+ if (cv != NULL) {
+ *values = (FLT*)cv->data;
+ return cv->elements;
+ }
+
+ if (def == NULL) return 0;
+
+ config_set_float_a(cg, tag, def, count);
+ *values = def;
+ return count;
+}
+
config_entry* next_unused_entry(config_group *cg) {
- config_entry *cv = cg->config_entries + cg->used_entries;
- assert(cg->used_entries < cg->max_entries);
+ config_entry *cv = NULL;
+// assert(cg->used_entries < cg->max_entries);
+
+ if (cg->used_entries >= cg->max_entries) resize_config_group(cg, cg->max_entries + 10);
+
+ cv = cg->config_entries + cg->used_entries;
+
cg->used_entries++;
return cv;
}
@@ -152,12 +205,10 @@ const FLT* config_set_float_a(config_group *cg, const char *tag, const FLT* valu
sstrcpy(&(cv->tag), tag);
- if (cv->data == NULL) {
- cv->data = (char*)malloc(sizeof(FLT)*count);
- }
- else {
- cv->data = (char*)realloc(cv->data, sizeof(FLT)*count);
- }
+ char* ptr = (char*)realloc(cv->data, sizeof(FLT)*count);
+ assert(ptr!=NULL);
+ cv->data = ptr;
+
printf("float array\n");
memcpy(cv->data,values,sizeof(FLT)*count);
@@ -201,15 +252,129 @@ void write_config_group(FILE* f, config_group *cg, char *tag) {
}
}
-void config_save(const char* path) {
+//struct SurviveContext;
+SurviveContext* survive_context;
+
+void config_save(SurviveContext* sctx, const char* path) {
uint16_t i = 0;
FILE* f = fopen(path, "w");
- write_config_group(f,&global_config_values, NULL);
- write_config_group(f,lh_config, "lighthouse0");
- write_config_group(f,lh_config+1, "lighthouse1");
+ write_config_group(f,sctx->global_config_values, NULL);
+ write_config_group(f,sctx->lh_config, "lighthouse0");
+ write_config_group(f,sctx->lh_config+1, "lighthouse1");
fclose(f);
}
+void print_json_value(char* tag, char** values, uint16_t count) {
+ uint16_t i = 0;
+ for (i=0;i<count; ++i) {
+ printf("%s:%s \n", tag, values[i]);
+ }
+}
+
+config_group* cg_stack[10]; //handle 10 nested objects deep
+uint8_t cg_stack_head = 0;
+
+void handle_config_group(char* tag) {
+ cg_stack_head++;
+ if (strcmp("lighthouse0",tag) == 0) {
+ cg_stack[cg_stack_head] = survive_context->lh_config;
+ } else if (strcmp("lighthouse1",tag) == 0) {
+ cg_stack[cg_stack_head] = survive_context->lh_config+1;
+ } else {
+ cg_stack[cg_stack_head] = survive_context->global_config_values;
+ }
+}
+
+void pop_config_group() {
+ cg_stack_head--;
+}
+
+
+int parse_floats(char* tag, char** values, uint16_t count) {
+ uint16_t i = 0;
+ FLT f[count];
+ char* end = NULL;
+ config_group* cg = cg_stack[cg_stack_head];
+
+ for(i=0;i<count;++i) {
+
+ #ifdef USE_DOUBLE
+ f[i] = strtod(values[i], &end);
+ #else
+ f[i] = strtof(values[i], &end);
+ #endif
+
+// if (values[i] == end) return 0; //not a float
+ if (*end != '\0') return 0; //not an integer
+ }
+
+ if (count>1) {
+ config_set_float_a(cg, tag, f, count);
+ }
+ else {
+ config_set_float(cg, tag, f[0]);
+ }
+
+ return 1;
+}
+
+int parse_uint32(char* tag, char** values, uint16_t count) {
+ uint16_t i = 0;
+ uint32_t l[count];
+ char* end = NULL;
+ config_group* cg = cg_stack[cg_stack_head];
+
+/*
+ //look for non numeric values
+ for(end=values[0];*end!='\0';++end) {
+ if ((*end<48) || (*end>57)) return 0;
+ }
+
+ end=NULL;
+*/
+ for(i=0;i<count;++i) {
+ l[i] = strtol(values[i], &end, 10);
+// if (values[i] == end) return 0; //not an integer
+ if (*end != '\0') return 0; //not an integer
+ }
+
+// if (count>1)
+// config_set_uint32_array(cg, tag, f, count);
+// else
+ config_set_uint32(cg, tag, l[0]);
+
+ return 1;
+}
+
+void handle_tag_value(char* tag, char** values, uint16_t count) {
+ print_json_value(tag,values,count);
+ config_group* cg = cg_stack[cg_stack_head];
+
+ if (parse_uint32(tag,values,count) > 0) return; //parse integers first, stricter rules
+
+ if (parse_floats(tag,values,count) > 0) return;
+
+ //should probably also handle string arrays
+ config_set_str(cg,tag,values[0]);
+// else if (count>1) config_set_str
+}
+
+void config_read(SurviveContext* sctx, const char* path) {
+ survive_context = sctx;
+
+ json_begin_object = handle_config_group;
+ json_end_object = pop_config_group;
+ json_tag_value = handle_tag_value;
+
+ cg_stack[0] = sctx->global_config_values;
+
+ json_load_file(path);
+
+ json_begin_object = NULL;
+ json_end_object = NULL;
+ json_tag_value = NULL;
+}
+
diff --git a/src/survive_config.h b/src/survive_config.h
index 14e2fc6..c8c7762 100644
--- a/src/survive_config.h
+++ b/src/survive_config.h
@@ -26,29 +26,34 @@ typedef struct {
uint32_t elements;
} config_entry;
-typedef struct {
+typedef struct config_group {
config_entry *config_entries;
uint16_t used_entries;
uint16_t max_entries;
} config_group;
-extern config_group global_config_values;
-extern config_group lh_config[2]; //lighthouse configs
+//extern config_group global_config_values;
+//extern config_group lh_config[2]; //lighthouse configs
+
+void init_config_group(config_group *cg, uint16_t count);
+void destroy_config_group(config_group* cg);
+//void config_init();
+//void config_open(const char* path, const char* mode);
-void config_init();
-void config_open(const char* path, const char* mode);
-void config_close();
//void config_write_lighthouse(struct BaseStationData* bsd, uint8_t length);
-void config_set_lighthouse(struct BaseStationData* bsd, uint8_t idx);
+void config_set_lighthouse(config_group* lh_config, BaseStationData* bsd, uint8_t idx);
+
+void config_read(SurviveContext* sctx, const char* path);
+void config_save(SurviveContext* sctx, const char* path);
-void config_save(const char* path);
const FLT config_set_float(config_group *cg, const char *tag, const FLT value);
const uint32_t config_set_uint32(config_group *cg, const char *tag, const uint32_t value);
const char* config_set_str(config_group *cg, const char *tag, const char* value);
FLT config_read_float(config_group *cg, const char *tag, const FLT def);
+uint16_t config_read_float_array(config_group *cg, const char *tag, const FLT** values, const FLT* def, uint16_t count);
uint32_t config_read_uint32(config_group *cg, const char *tag, const uint32_t def);
const char* config_read_str(config_group *cg, const char *tag, const char *def);
-#endif \ No newline at end of file
+#endif
diff --git a/src/survive_data.c b/src/survive_data.c
index e55b640..63cc5c2 100644
--- a/src/survive_data.c
+++ b/src/survive_data.c
@@ -6,12 +6,19 @@
#include <string.h>
//This is the disambiguator function, for taking light timing and figuring out place-in-sweep for a given photodiode.
-void handle_lightcap( struct SurviveObject * so, struct LightcapElement * le )
+void handle_lightcap( SurviveObject * so, LightcapElement * le )
{
- struct SurviveContext * ctx = so->ctx;
+ SurviveContext * ctx = so->ctx;
//int32_t deltat = (uint32_t)le->timestamp - (uint32_t)so->last_master_time;
-// printf( "%s %d %d %d %d %d\n", so->codename, le->sensor_id, le->type, le->length, le->timestamp, le->timestamp-so->tsl );
+ //if( so->codename[0] != 'H' )
+ //printf( "*** %s %d %d %d %d %d\n", so->codename, le->sensor_id, le->type, le->length, le->timestamp, le->timestamp-so->tsl );
+
+ if( le->sensor_id > SENSORS_PER_OBJECT )
+ {
+ return;
+ }
+
so->tsl = le->timestamp;
if( le->length < 20 ) return; ///Assuming 20 is an okay value for here.
diff --git a/src/survive_driverman.c b/src/survive_driverman.c
index 8cdfb71..d694e64 100644
--- a/src/survive_driverman.c
+++ b/src/survive_driverman.c
@@ -3,7 +3,7 @@
// See notice in survive_driverman.h
//
-#include "survive_driverman.h"
+#include "survive_internal.h"
#include <string.h>
#include <stdio.h>
diff --git a/src/survive_driverman.h b/src/survive_driverman.h
deleted file mode 100644
index 5e13caf..0000000
--- a/src/survive_driverman.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// (C) 2017 <>< C. N. Lohr, Under MIT/x11 License.
-//
-// This file is intended to be used for self-registering functions. By using
-// this it means that you do not need to have complicated switch statements or
-// #defines for dfferent inclusion of drivers/other code. You can simply
-// register your function and it will be put into a list.
-//
-//
-
-#ifndef SURVIVE_DRIVERMAN_H
-#define SURVIVE_DRIVERMAN_H
-
-//Driver registration
-#define MAX_DRIVERS 32
-
-void RegisterDriver( const char * name, void * data );
-void * GetDriver( const char * name );
-const char * GetDriverNameMatching( const char * prefix, int place );
-void ListDrivers();
-
-#define REGISTER_LINKTIME( func ) \
- void __attribute__((constructor)) Register##func() { RegisterDriver( #func, &func ); }
-
-
-//
-// Specific types of drivers.
-//
-
-struct SurviveContext;
-
-//Device drivers (prefix your drivers with "DriverReg") i.e.
-// REGISTER_LINKTIME( DriverRegHTCVive );
-typedef int (*DeviceDriver)( struct SurviveContext * ctx );
-
-//more driver types here? i.e. posefinders, etc.
-
-#endif
-
diff --git a/src/survive_internal.h b/src/survive_internal.h
index 5962623..392104a 100644
--- a/src/survive_internal.h
+++ b/src/survive_internal.h
@@ -1,15 +1,5 @@
-//<>< (C) 2016 C. N. Lohr, MOSTLY Under MIT/x11 License.
+//<>< (C) 2016-2017 C. N. Lohr, MOSTLY Under MIT/x11 License.
//
-//Based off of https://github.com/collabora/OSVR-Vive-Libre
-// Originally Copyright 2016 Philipp Zabel
-// Originally Copyright 2016 Lubosz Sarnecki <lubosz.sarnecki@collabora.co.uk>
-// Originally Copyright (C) 2013 Fredrik Hultin
-// Originally Copyright (C) 2013 Jakob Bornecrantz
-//
-//But, re-written as best as I can to get it put under an open souce license instead of a forced-source license.
-//If there are portions of the code too similar to the original, I would like to know so they can be re-written.
-//All MIT/x11 Licensed Code in this file may be relicensed freely under the GPL or LGPL licenses.
-
#ifndef _SURVIVE_INTERNAL_H
#define _SURVIVE_INTERNAL_H
@@ -17,88 +7,16 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
-#include "survive_driverman.h"
#include <zlib.h>
#include <survive.h>
-#define SV_INFO( x... ) { char stbuff[1024]; sprintf( stbuff, x ); ctx->notefunction( ctx, stbuff ); }
-#define SV_ERROR( x... ) { char stbuff[1024]; sprintf( stbuff, x ); ctx->faultfunction( ctx, stbuff ); }
-
-//XXX TODO This one needs to be rewritten.
-#define SV_KILL() exit(0)
-
-#define INTBUFFSIZE 64
-#define SENSORS_PER_OBJECT 32
-
-struct SurviveContext;
-struct SurviveUSBInterface;
-
-typedef int (*DeviceDriverCb)( struct SurviveContext * ctx, void * driver );
-typedef int (*DeviceDriverMagicCb)( struct SurviveContext * ctx, void * driver, int magic_code, void * data, int datalen );
-
-
-//This is defined in survive.h
-struct SurviveObject;
-struct SurviveCalData;
-
-struct BaseStationData
-{
- uint8_t PositionSet:1;
- FLT Position[3];
- FLT Quaternion[4];
-
- uint8_t OOTXSet:1;
- uint32_t BaseStationID;
- FLT fcalphase[2];
- FLT fcaltilt[2];
- FLT fcalcurve[2];
- FLT fcalgibpha[2];
- FLT fcalgibmag[2];
-};
-
-struct SurviveContext
-{
- text_feedback_func faultfunction;
- text_feedback_func notefunction;
- light_process_func lightproc;
- imu_process_func imuproc;
- angle_process_func angleproc;
-
- //Calibration data:
- struct BaseStationData bsd[NUM_LIGHTHOUSES];
-
- struct SurviveCalData * calptr; //If and only if the calibration subsystem is attached.
-
- struct SurviveObject ** objs;
- int objs_ct;
-
- void ** drivers;
- DeviceDriverCb * driverpolls;
- DeviceDriverCb * drivercloses;
- DeviceDriverMagicCb * drivermagics;
- int driver_ct;
-};
-
-int survive_add_object( struct SurviveContext * ctx, struct SurviveObject * obj );
-
-void survive_add_driver( struct SurviveContext * ctx, void * payload, DeviceDriverCb poll, DeviceDriverCb close, DeviceDriverMagicCb magic );
-
-//For lightcap, etc. Don't change this structure at all. Regular vive is dependent on it being exactly as-is.
-struct LightcapElement
-{
- uint8_t sensor_id;
- uint8_t type;
- uint16_t length;
- uint32_t timestamp;
-} __attribute__((packed));
-
-//This is the disambiguator function, for taking light timing and figuring out place-in-sweep for a given photodiode.
-void handle_lightcap( struct SurviveObject * so, struct LightcapElement * le );
-
-//Accept Data from backend.
-void survive_data_cb( struct SurviveUSBInterface * si );
+//Driver registration
+#define MAX_DRIVERS 32
+void * GetDriver( const char * name );
+const char * GetDriverNameMatching( const char * prefix, int place );
+void ListDrivers();
#endif
diff --git a/src/survive_process.c b/src/survive_process.c
index 75453da..2fea99d 100644
--- a/src/survive_process.c
+++ b/src/survive_process.c
@@ -6,9 +6,9 @@
//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.
-void survive_default_light_process( struct SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length )
+void survive_default_light_process( SurviveObject * so, int sensor_id, int acode, int timeinsweep, uint32_t timecode, uint32_t length )
{
- struct SurviveContext * ctx = so->ctx;
+ SurviveContext * ctx = so->ctx;
int base_station = acode >> 2;
int axis = acode & 1;
@@ -25,7 +25,7 @@ void survive_default_light_process( struct SurviveObject * so, int sensor_id, in
//Need to now do angle correction.
#if 1
- struct BaseStationData * bsd = &ctx->bsd[base_station];
+ BaseStationData * bsd = &ctx->bsd[base_station];
//XXX TODO: This seriously needs to be worked on. See: https://github.com/cnlohr/libsurvive/issues/18
angle += bsd->fcalphase[axis];
@@ -39,20 +39,41 @@ void survive_default_light_process( struct SurviveObject * so, int sensor_id, in
}
-void survive_default_angle_process( struct SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle )
+void survive_default_angle_process( SurviveObject * so, int sensor_id, int acode, uint32_t timecode, FLT length, FLT angle )
{
- struct SurviveContext * ctx = so->ctx;
+ SurviveContext * ctx = so->ctx;
if( ctx->calptr )
{
survive_cal_angle( so, sensor_id, acode, timecode, length, angle );
}
-
- //TODO: Writeme!
+ if( so->PoserFn )
+ {
+ PoserDataLight l = {
+ .pt = POSERDATA_LIGHT,
+ .sensor_id = sensor_id,
+ .acode = acode,
+ .timecode = timecode,
+ .length = length,
+ .angle = angle,
+ };
+ so->PoserFn( so, (PoserData *)&l );
+ }
}
-void survive_default_imu_process( struct SurviveObject * so, int16_t * accelgyro, uint32_t timecode, int id )
+void survive_default_imu_process( SurviveObject * so, int mask, FLT * accelgyromag, uint32_t timecode, int id )
{
- //TODO: Writeme!
+ if( so->PoserFn )
+ {
+ PoserDataIMU imu = {
+ .pt = POSERDATA_IMU,
+ .datamask = mask,
+ .accel = { accelgyromag[0], accelgyromag[1], accelgyromag[2] },
+ .gyro = { accelgyromag[3], accelgyromag[4], accelgyromag[5] },
+ .mag = { accelgyromag[6], accelgyromag[7], accelgyromag[8] },
+ .timecode = timecode,
+ };
+ so->PoserFn( so, (PoserData *)&imu );
+ }
}
diff --git a/src/survive_vive.c b/src/survive_vive.c
index 47886c9..7da2897 100644
--- a/src/survive_vive.c
+++ b/src/survive_vive.c
@@ -10,27 +10,18 @@
//If there are portions of the code too similar to the original, I would like to know so they can be re-written.
//All MIT/x11 Licensed Code in this file may be relicensed freely under the GPL or LGPL licenses.
-#include "survive_internal.h"
-#include "survive_driverman.h"
+#include <survive.h>
#include <jsmn.h>
-
-#include "survive_internal.h"
#include <libusb-1.0/libusb.h>
#include <stdio.h>
-#include <unistd.h> //sleep if I ever use it.
+#include <stdlib.h>
+#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
struct SurviveViveData;
-//USB Subsystem
-void survive_usb_close( struct SurviveContext * t );
-int survive_usb_init( struct SurviveViveData * sv, struct SurviveObject * hmd, struct SurviveObject *wm0, struct SurviveObject * wm1 );
-int survive_usb_poll( struct SurviveContext * ctx );
-int survive_get_config( char ** config, struct SurviveViveData * ctx, int devno, int interface, int send_extra_magic );
-
-
const short vidpids[] = {
0x0bb4, 0x2c87, 0, //The main HTC HMD device
0x28de, 0x2000, 0, //Valve lighthouse
@@ -60,15 +51,18 @@ const char * devnames[] = {
#define USB_IF_LIGHTCAP 4
#define MAX_INTERFACES 5
-typedef void (*usb_callback)( struct SurviveUSBInterface * ti );
+typedef struct SurviveUSBInterface SurviveUSBInterface;
+typedef struct SurviveViveData SurviveViveData;
+
+typedef void (*usb_callback)( SurviveUSBInterface * ti );
struct SurviveUSBInterface
{
- struct SurviveViveData * sv;
- struct SurviveContext * ctx;
+ SurviveViveData * sv;
+ SurviveContext * ctx;
struct libusb_transfer * transfer;
- struct SurviveObject * assoc_obj;
+ SurviveObject * assoc_obj;
int actual_len;
uint8_t buffer[INTBUFFSIZE];
usb_callback cb;
@@ -78,16 +72,24 @@ struct SurviveUSBInterface
struct SurviveViveData
{
- struct SurviveContext * ctx;
+ SurviveContext * ctx;
//XXX TODO: UN-STATICIFY THIS.
- struct SurviveUSBInterface uiface[MAX_INTERFACES];
+ SurviveUSBInterface uiface[MAX_INTERFACES];
//USB Subsystem
struct libusb_context* usbctx;
struct libusb_device_handle * udev[MAX_USB_DEVS];
};
+void survive_data_cb( SurviveUSBInterface * si );
+
+//USB Subsystem
+void survive_usb_close( SurviveContext * t );
+int survive_usb_init( SurviveViveData * sv, SurviveObject * hmd, SurviveObject *wm0, SurviveObject * wm1 );
+int survive_usb_poll( SurviveContext * ctx );
+int survive_get_config( char ** config, SurviveViveData * ctx, int devno, int interface, int send_extra_magic );
+
@@ -115,10 +117,10 @@ static void handle_transfer(struct libusb_transfer* transfer)
-static int AttachInterface( struct SurviveViveData * sv, struct SurviveObject * assocobj, int which_interface_am_i, libusb_device_handle * devh, int endpoint, usb_callback cb, const char * hname )
+static int AttachInterface( SurviveViveData * sv, SurviveObject * assocobj, int which_interface_am_i, libusb_device_handle * devh, int endpoint, usb_callback cb, const char * hname )
{
- struct SurviveContext * ctx = sv->ctx;
- struct SurviveUSBInterface * iface = &sv->uiface[which_interface_am_i];
+ SurviveContext * ctx = sv->ctx;
+ SurviveUSBInterface * iface = &sv->uiface[which_interface_am_i];
iface->ctx = ctx;
iface->sv = sv;
iface->which_interface_am_i = which_interface_am_i;
@@ -593,7 +595,13 @@ static void handle_watchman( struct SurviveObject * w, uint8_t * readdata )
if( ( ( type & 0xe8 ) == 0xe8 ) || doimu ) //Hmm, this looks kind of yucky... we can get e8's that are accelgyro's but, cleared by first propset.
{
propset |= 2;
- w->ctx->imuproc( w, (int16_t *)&readdata[1], (time1<<24)|(time2<<16)|readdata[0], 0 );
+ //XXX XXX BIG TODO!!! Actually recal gyro data.
+ FLT agm[9] = { readdata[1], readdata[2], readdata[3],
+ readdata[4], readdata[5], readdata[6],
+ 0,0,0 };
+
+ w->ctx->imuproc( w, 3, agm, (time1<<24)|(time2<<16)|readdata[0], 0 );
+
int16_t * k = (int16_t *)readdata+1;
//printf( "Match8 %d %d %d %d %d %3d %3d\n", qty, k[0], k[1], k[2], k[3], k[4], k[5] );
readdata += 13; qty -= 13;
@@ -680,7 +688,7 @@ static void handle_watchman( struct SurviveObject * w, uint8_t * readdata )
}
- struct LightcapElement les[10];
+ LightcapElement les[10];
int lese = 0; //les's end
//Second, go through all LEDs and extract the lightevent from them.
@@ -711,7 +719,7 @@ static void handle_watchman( struct SurviveObject * w, uint8_t * readdata )
//reverse sorted, but that is to minimize operations. To read it
//in sorted order simply read it back backwards.
//Use insertion sort, since we should most of the time, be in order.
- struct LightcapElement * le = &les[lese++];
+ LightcapElement * le = &les[lese++];
le->sensor_id = led;
le->type = 0xfe;
@@ -725,7 +733,7 @@ static void handle_watchman( struct SurviveObject * w, uint8_t * readdata )
int swap = lese-2;
while( swap >= 0 && les[swap].timestamp < les[swap+1].timestamp )
{
- struct LightcapElement l;
+ LightcapElement l;
memcpy( &l, &les[swap], sizeof( l ) );
memcpy( &les[swap], &les[swap+1], sizeof( l ) );
memcpy( &les[swap+1], &l, sizeof( l ) );
@@ -744,17 +752,17 @@ static void handle_watchman( struct SurviveObject * w, uint8_t * readdata )
return;
end:
{
- struct SurviveContext * ctx = w->ctx;
+ SurviveContext * ctx = w->ctx;
SV_INFO( "Light decoding fault: %d\n", fault );
}
}
}
-void survive_data_cb( struct SurviveUSBInterface * si )
+void survive_data_cb( SurviveUSBInterface * si )
{
int size = si->actual_len;
- struct SurviveContext * ctx = si->ctx;
+ SurviveContext * ctx = si->ctx;
#if 0
int i;
printf( "%16s: %d: ", si->hname, len );
@@ -767,7 +775,7 @@ void survive_data_cb( struct SurviveUSBInterface * si )
#endif
int iface = si->which_interface_am_i;
- struct SurviveObject * obj = si->assoc_obj;
+ SurviveObject * obj = si->assoc_obj;
uint8_t * readdata = si->buffer;
int id = POP1;
@@ -808,7 +816,13 @@ void survive_data_cb( struct SurviveUSBInterface * si )
if( cd > 0 )
{
obj->oldcode = code;
- ctx->imuproc( obj, acceldata, timecode, code );
+
+ //XXX XXX BIG TODO!!! Actually recal gyro data.
+ FLT agm[9] = { acceldata[0], acceldata[1], acceldata[2],
+ acceldata[3], acceldata[4], acceldata[5],
+ 0,0,0 };
+
+ ctx->imuproc( obj, 3, agm, timecode, code );
}
}
@@ -818,7 +832,7 @@ void survive_data_cb( struct SurviveUSBInterface * si )
case USB_IF_WATCHMAN1:
case USB_IF_WATCHMAN2:
{
- struct SurviveObject * w = obj;
+ SurviveObject * w = obj;
if( id == 35 )
{
handle_watchman( w, readdata);
@@ -844,7 +858,7 @@ void survive_data_cb( struct SurviveUSBInterface * si )
int i;
for( i = 0; i < 7; i++ )
{
- handle_lightcap( obj, (struct LightcapElement*)&readdata[i*8] );
+ handle_lightcap( obj, (LightcapElement*)&readdata[i*8] );
}
break;
}
@@ -875,7 +889,7 @@ static int jsoneq(const char *json, jsmntok_t *tok, const char *s) {
}
-static int ParsePoints( struct SurviveContext * ctx, struct SurviveObject * so, char * ct0conf, FLT ** floats_out, jsmntok_t * t, int i )
+static int ParsePoints( SurviveContext * ctx, SurviveObject * so, char * ct0conf, FLT ** floats_out, jsmntok_t * t, int i )
{
int k;
int pts = t[i+1].size;
@@ -914,9 +928,9 @@ static int ParsePoints( struct SurviveContext * ctx, struct SurviveObject * so,
return 0;
}
-static int LoadConfig( struct SurviveViveData * sv, struct SurviveObject * so, int devno, int iface, int extra_magic )
+static int LoadConfig( SurviveViveData * sv, SurviveObject * so, int devno, int iface, int extra_magic )
{
- struct SurviveContext * ctx = sv->ctx;
+ SurviveContext * ctx = sv->ctx;
char * ct0conf = 0;
int len = survive_get_config( &ct0conf, sv, devno, iface, extra_magic );
@@ -1002,21 +1016,21 @@ static int LoadConfig( struct SurviveViveData * sv, struct SurviveObject * so, i
}
-int survive_vive_close( struct SurviveContext * ctx, void * driver )
+int survive_vive_close( SurviveContext * ctx, void * driver )
{
- struct SurviveViveData * sv = driver;
+ SurviveViveData * sv = driver;
survive_vive_usb_close( sv );
}
-int DriverRegHTCVive( struct SurviveContext * ctx )
+int DriverRegHTCVive( SurviveContext * ctx )
{
int i, r;
- struct SurviveObject * hmd = calloc( 1, sizeof( struct SurviveObject ) );
- struct SurviveObject * wm0 = calloc( 1, sizeof( struct SurviveObject ) );
- struct SurviveObject * wm1 = calloc( 1, sizeof( struct SurviveObject ) );
- struct SurviveViveData * sv = calloc( 1, sizeof( struct SurviveViveData ) );
+ SurviveObject * hmd = calloc( 1, sizeof( SurviveObject ) );
+ SurviveObject * wm0 = calloc( 1, sizeof( SurviveObject ) );
+ SurviveObject * wm1 = calloc( 1, sizeof( SurviveObject ) );
+ SurviveViveData * sv = calloc( 1, sizeof( SurviveViveData ) );
sv->ctx = ctx;
diff --git a/81-vive.rules b/useful_files/81-vive.rules
index ab38087..ab38087 100644
--- a/81-vive.rules
+++ b/useful_files/81-vive.rules
diff --git a/useful_files/htc_vive_edid_on_display_port.dat b/useful_files/htc_vive_edid_on_display_port.dat
new file mode 100644
index 0000000..c5fdce2
--- /dev/null
+++ b/useful_files/htc_vive_edid_on_display_port.dat
Binary files differ