blob: 74272b0d86dfb4ddf4a702886fd17565f9c0a98e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 InvenSense Corporation, All Rights Reserved.
******************************************************************************/
/*******************************************************************************
*
* $Id: main.c 6146 2011-10-04 18:33:51Z jcalizo $
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "invensense.h"
#include "invensense_adv.h"
#include "and_constructor.h"
#include "ml_math_func.h"
#include "datalogger_outputs.h"
#include "console_helper.h"
#include "mlos.h"
#include "mlsl.h"
#include "testsupport.h"
#include "log.h"
#undef MPL_LOG_TAG
#define MPL_LOG_TAG "MPL-playback"
/*
Defines & Macros
*/
#define UNPACK_3ELM_ARRAY(a) (a)[0], (a)[1], (a)[2]
#define UNPACK_4ELM_ARRAY(a) UNPACK_3ELM_ARRAY(a), (a)[3]
#define COMPONENT_NAME_MAX_LEN (30)
#define DEF_NAME(x) (#x)
#define PRINT_ON_CONSOLE(...) \
if (print_on_screen) \
printf(__VA_ARGS__)
#define PRINT_ON_FILE(...) \
if(stream_file) \
fprintf(stream_file, __VA_ARGS__)
#define PRINT(...) \
PRINT_ON_CONSOLE(__VA_ARGS__); \
PRINT_ON_FILE(__VA_ARGS__)
#define PRINT_FLOAT(width, prec, data) \
PRINT_ON_CONSOLE("%+*.*f", \
width, prec, data); \
PRINT_ON_FILE("%+f", data)
#define PRINT_INT(width, data) \
PRINT_ON_CONSOLE("%+*d", width, data); \
PRINT_ON_FILE("%+d", data);
#define PRINT_LONG(width, data) \
PRINT_ON_CONSOLE("%+*ld", width, data); \
PRINT_ON_FILE("%+ld", data);
#define PRINT_3ELM_ARRAY_FLOAT(w, p, data) \
PRINT_FLOAT(w, p, data[0]); \
PRINT(", "); \
PRINT_FLOAT(w, p, data[1]); \
PRINT(", "); \
PRINT_FLOAT(w, p, data[2]); \
PRINT(", ");
#define PRINT_4ELM_ARRAY_FLOAT(w, p, data) \
PRINT_3ELM_ARRAY_FLOAT(w, p, data); \
PRINT_FLOAT(w, p, data[3]); \
PRINT(", ");
#define PRINT_3ELM_ARRAY_LONG(w, data) \
PRINT_LONG(w, data[0]); \
PRINT(", "); \
PRINT_LONG(w, data[1]); \
PRINT(", "); \
PRINT_LONG(w, data[2]); \
PRINT(", ");
#define PRINT_4ELM_ARRAY_LONG(w, data) \
PRINT_3ELM_ARRAY_LONG(w, data); \
PRINT_LONG(w, data[3]); \
PRINT(", ");
#define PRINT_3ELM_ARRAY_INT(w, data) \
PRINT_INT(w, data[0]); \
PRINT(", "); \
PRINT_INT(w, data[1]); \
PRINT(", "); \
PRINT_INT(w, data[2]); \
PRINT(", ");
#define PRINT_4ELM_ARRAY_INT(w, data) \
PRINT_3ELM_ARRAY_LONG(w, data); \
PRINT_INT(w, data[3]); \
PRINT(", ");
#define CASE_NAME(CODE) \
case CODE: \
return #CODE
#define CALL_CHECK_N_PRINT(f) { \
MPL_LOGI("\n"); \
MPL_LOGI("################################################\n"); \
MPL_LOGI("# %s\n", #f); \
MPL_LOGI("################################################\n"); \
MPL_LOGI("\n"); \
CALL_N_CHECK(f); \
}
/*
Types
*/
/* A badly named enum type to track state of user input for tracker menu. */
typedef enum {
STATE_SELECT_A_TRACKER,
STATE_SET_TRACKER_STATE, /* I'm running out of ideas here. */
STATE_COUNT
} user_state_t;
/* bias trackers. */
typedef enum {
BIAS_FROM_NO_MOTION,
FAST_NO_MOTION,
BIAS_FROM_GRAVITY,
BIAS_FROM_TEMPERATURE,
BIAS_FROM_LPF,
DEAD_ZONE,
NUM_TRACKERS
} bias_t;
enum comp_ids {
TIME = 0,
CALIBRATED_GYROSCOPE,
CALIBRATED_ACCELEROMETER,
CALIBRATED_COMPASS,
RAW_GYROSCOPE,
RAW_GYROSCOPE_BODY,
RAW_ACCELEROMETER,
RAW_COMPASS,
QUATERNION_9_AXIS,
QUATERNION_6_AXIS,
GRAVITY,
HEADING,
COMPASS_BIAS_ERROR,
COMPASS_STATE,
TEMPERATURE,
TEMP_COMP_SLOPE,
LINEAR_ACCELERATION,
ROTATION_VECTOR,
MOTION_STATE,
NUM_OF_IDS
};
struct component_list {
char name[COMPONENT_NAME_MAX_LEN];
int order;
};
/*
Globals
*/
static int print_on_screen = true;
static int one_time_print = true;
static FILE *stream_file = NULL;
static unsigned long sample_count = 0;
static int enabled_9x = true;
signed char g_gyro_orientation[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
signed char g_accel_orientation[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
signed char g_compass_orientation[9] = {-1, 0, 0, 0, 1, 0, 0, 0, -1};
#ifdef WIN32
static double pc_freq;
static __int64 counter_start;
#else
static inv_time_t counter_start;
#endif
struct component_list components[NUM_OF_IDS];
/*
Prototypes
*/
void print_tracker_states(bias_t tracker);
/*
Callbacks
*/
/*--- motion / no motion callback function ---*/
void check_motion_event(void)
{
long msg = inv_get_message_level_0(1);
if (msg) {
if (msg & INV_MSG_MOTION_EVENT) {
MPL_LOGI("################################################\n");
MPL_LOGI("## Motion\n");
MPL_LOGI("################################################\n");
}
if (msg & INV_MSG_NO_MOTION_EVENT) {
MPL_LOGI("################################################\n");
MPL_LOGI("## No Motion\n");
MPL_LOGI("################################################\n");
}
}
}
/* number to string coversion */
char *compass_state_name(char* out, int state)
{
switch(state) {
CASE_NAME(SF_NORMAL);
CASE_NAME(SF_DISTURBANCE);
CASE_NAME(SF_FAST_SETTLE);
CASE_NAME(SF_SLOW_SETTLE);
CASE_NAME(SF_STARTUP_SETTLE);
CASE_NAME(SF_UNCALIBRATED);
}
#define UNKNOWN_ERROR_CODE 1234
return ERROR_NAME(UNKNOWN_ERROR_CODE);
}
/* component ID to name convertion */
char *component_name(char *out, int comp_id)
{
switch (comp_id) {
CASE_NAME(TIME);
CASE_NAME(CALIBRATED_GYROSCOPE);
CASE_NAME(CALIBRATED_ACCELEROMETER);
CASE_NAME(CALIBRATED_COMPASS);
CASE_NAME(RAW_GYROSCOPE);
CASE_NAME(RAW_GYROSCOPE_BODY);
CASE_NAME(RAW_ACCELEROMETER);
CASE_NAME(RAW_COMPASS);
CASE_NAME(QUATERNION_9_AXIS);
CASE_NAME(QUATERNION_6_AXIS);
CASE_NAME(GRAVITY);
CASE_NAME(HEADING);
CASE_NAME(COMPASS_BIAS_ERROR);
CASE_NAME(COMPASS_STATE);
CASE_NAME(TEMPERATURE);
CASE_NAME(TEMP_COMP_SLOPE);
CASE_NAME(LINEAR_ACCELERATION);
CASE_NAME(ROTATION_VECTOR);
CASE_NAME(MOTION_STATE);
}
return "UNKNOWN";
}
#ifdef WIN32
/*
Karthik Implementation.
http://stackoverflow.com/questions/1739259/how-to-use-queryperformancecounter
*/
double get_counter(__int64 *counter_start, double *pc_freq)
{
LARGE_INTEGER li;
double x;
QueryPerformanceCounter(&li);
x = (double) (li.QuadPart - (*counter_start));
x = x / (*pc_freq);
return(x);
}
void start_counter(double *pc_freq, __int64 *counter_start)
{
LARGE_INTEGER li;
double x;
if(!QueryPerformanceFrequency(&li))
printf("QueryPerformanceFrequency failed!\n");
x = (double)(li.QuadPart);
*pc_freq = x / 1000.0;
QueryPerformanceCounter(&li);
*counter_start = li.QuadPart;
}
#else
unsigned long get_counter(void)
{
return (inv_get_tick_count() - counter_start);
}
void start_counter(void)
{
counter_start = inv_get_tick_count();
}
#endif
/* processed data callback */
void fifo_callback(void)
{
int print_on_screen_saved = print_on_screen;
int i;
/* one_time_print causes the data labels to be printed on screen */
if (one_time_print) {
print_on_screen = true;
}
for (i = 0; i < NUM_OF_IDS; i++) {
if (components[TIME].order == i) {
if (one_time_print) {
PRINT("TIME,");
} else {
#ifdef WIN32
double time_ms;
static int first_value = 0;
if(first_value == 0){
first_value = 1;
start_counter(&pc_freq, &counter_start);
time_ms = 0;
} else {
time_ms = get_counter(&counter_start, &pc_freq);
}
PRINT("%6.0f, ", time_ms);
#else
unsigned long time_ms;
static int first_value = 0;
if(first_value == 0){
first_value = 1;
start_counter();
time_ms = 0;
} else {
time_ms = get_counter();
}
PRINT("%6ld, ", time_ms);
#endif
}
} else if (components[CALIBRATED_GYROSCOPE].order == i) {
if (one_time_print) {
PRINT("CALIBRATED_GYROSCOPE_X,"
"CALIBRATED_GYROSCOPE_Y,"
"CALIBRATED_GYROSCOPE_Z,");
/*
PRINT("CALIBRATED_GYROSCOPE_X_AVERAGE,"
"CALIBRATED_GYROSCOPE_Y_AVERAGE,"
"CALIBRATED_GYROSCOPE_Z_AVERAGE,");
*/
} else {
/*
#define window 20
static int cnt = 0;
static int valid = 0;
static float gyro_keep[window][3];
int kk, jj;
float avg[3];
*/
float gyro[3];
inv_get_gyro_float(gyro);
PRINT_3ELM_ARRAY_FLOAT(10, 5, gyro);
PRINT(" ");
/*
memcpy(gyro_keep[cnt], gyro, sizeof(float) * 3);
cnt= (cnt + 1) % window;
if (cnt == window - 1)
valid = 1;
if (valid) {
memset(avg, 0, sizeof(float) * 3);
jj = (cnt + 1) % window;
for (kk = 0; kk < window; kk++) {
avg[0] += gyro_keep[jj][0] / window;
avg[1] += gyro_keep[jj][1] / window;
avg[2] += gyro_keep[jj][2] / window;
jj = (jj + 1) % window;
}
PRINT("%+f, %+f, %+f, ",
UNPACK_3ELM_ARRAY(avg));
PRINT_3ELM_ARRAY_FLOAT(10, 5, avg);
PRINT(" ");
}
*/
}
} else if (components[CALIBRATED_ACCELEROMETER].order == i) {
if (one_time_print) {
PRINT("CALIBRATED_ACCELEROMETER_X,"
"CALIBRATED_ACCELEROMETER_Y,"
"CALIBRATED_ACCELEROMETER_Z,");
} else {
float accel[3];
inv_get_accel_float(accel);
PRINT_3ELM_ARRAY_FLOAT(10, 5, accel);
PRINT(" ");
}
} else if (components[CALIBRATED_COMPASS].order == i) {
if (one_time_print) {
PRINT("CALIBRATED_COMPASS_X,"
"CALIBRATED_COMPASS_Y,"
"CALIBRATED_COMPASS_Z,");
} else {
long lcompass[3];
float compass[3];
inv_get_compass_set(lcompass, 0, 0);
compass[0] = inv_q16_to_float(lcompass[0]);
compass[1] = inv_q16_to_float(lcompass[1]);
compass[2] = inv_q16_to_float(lcompass[2]);
PRINT_3ELM_ARRAY_FLOAT(10, 5, compass);
PRINT(" ");
}
} else if (components[RAW_GYROSCOPE].order == i) {
if (one_time_print) {
PRINT("RAW_GYROSCOPE_X,"
"RAW_GYROSCOPE_Y,"
"RAW_GYROSCOPE_Z,");
} else {
short raw[3];
inv_get_sensor_type_gyro_raw_short(raw, NULL);
PRINT_3ELM_ARRAY_INT(6, raw);
PRINT(" ");
}
} else if (components[RAW_GYROSCOPE_BODY].order == i) {
if (one_time_print) {
PRINT("RAW_GYROSCOPE_BODY_X,"
"RAW_GYROSCOPE_BODY_Y,"
"RAW_GYROSCOPE_BODY_Z,");
} else {
float raw_body[3];
inv_get_sensor_type_gyro_raw_body_float(raw_body, NULL);
PRINT_3ELM_ARRAY_FLOAT(10, 5, raw_body);
PRINT(" ");
}
} else if (components[RAW_ACCELEROMETER].order == i) {
if (one_time_print) {
PRINT("RAW_ACCELEROMETER_X,"
"RAW_ACCELEROMETER_Y,"
"RAW_ACCELEROMETER_Z,");
} else {
short raw[3];
inv_get_sensor_type_accel_raw_short(raw, NULL);
PRINT_3ELM_ARRAY_INT(6, raw);
PRINT(" ");
}
} else if (components[RAW_COMPASS].order == i) {
if (one_time_print) {
PRINT("RAW_COMPASS_X,"
"RAW_COMPASS_Y,"
"RAW_COMPASS_Z,");
} else {
short raw[3];
inv_get_sensor_type_compass_raw_short(raw, NULL);
PRINT_3ELM_ARRAY_INT(6, raw);
PRINT(" ");
}
} else if (components[QUATERNION_9_AXIS].order == i) {
if (one_time_print) {
PRINT("QUATERNION_9_AXIS_X,"
"QUATERNION_9_AXIS_Y,"
"QUATERNION_9_AXIS_Z,"
"QUATERNION_9_AXIS_w,");
} else {
float quat[4];
inv_get_quaternion_float(quat);
PRINT_4ELM_ARRAY_FLOAT(10, 5, quat);
PRINT(" ");
}
} else if (components[QUATERNION_6_AXIS].order == i) {
if (one_time_print) {
PRINT("QUATERNION_6_AXIS_X,"
"QUATERNION_6_AXIS_Y,"
"QUATERNION_6_AXIS_Z,"
"QUATERNION_6_AXIS_w,");
} else {
float quat[4];
long temp[4];
int j;
inv_get_6axis_quaternion(temp);
for (j = 0; j < 4; j++)
quat[j] = (float)temp[j] / (1 << 30);
PRINT_4ELM_ARRAY_FLOAT(10, 5, quat);
PRINT(" ");
}
} else if (components[HEADING].order == i) {
if (one_time_print) {
PRINT("HEADING,");
} else {
float heading[1];
inv_get_sensor_type_compass_float(heading, NULL, NULL,
NULL, NULL);
PRINT_FLOAT(10, 5, heading[0]);
PRINT(", ");
}
} else if (components[GRAVITY].order == i) {
if (one_time_print) {
PRINT("GRAVITY_X,"
"GRAVITY_Y,"
"GRAVITY_Z,");
} else {
float gravity[3];
inv_get_sensor_type_gravity_float(gravity, NULL, NULL);
PRINT_3ELM_ARRAY_FLOAT(10, 5, gravity);
PRINT(" ");
}
} else if (components[COMPASS_STATE].order == i) {
if (one_time_print) {
PRINT("COMPASS_STATE,"
"GOT_COARSE_HEADING,");
} else {
PRINT_INT(1, inv_get_compass_state());
PRINT(", ");
PRINT_INT(1, inv_got_compass_bias());
PRINT(", ");
}
} else if (components[COMPASS_BIAS_ERROR].order == i) {
if (one_time_print) {
PRINT("COMPASS_BIAS_ERROR_X,"
"COMPASS_BIAS_ERROR_Y,"
"COMPASS_BIAS_ERROR_Z,");
} else {
long mbe[3];
inv_get_compass_bias_error(mbe);
PRINT_3ELM_ARRAY_LONG(6, mbe);
}
} else if (components[TEMPERATURE].order == i) {
if (one_time_print) {
PRINT("TEMPERATURE,");
} else {
float temp;
inv_get_sensor_type_temperature_float(&temp, NULL);
PRINT_FLOAT(8, 4, temp);
PRINT(", ");
}
} else if (components[TEMP_COMP_SLOPE].order == i) {
if (one_time_print) {
PRINT("TEMP_COMP_SLOPE_X,"
"TEMP_COMP_SLOPE_Y,"
"TEMP_COMP_SLOPE_Z,");
} else {
long temp_slope[3];
float temp_slope_f[3];
(void)inv_get_gyro_ts(temp_slope);
temp_slope_f[0] = inv_q16_to_float(temp_slope[0]);
temp_slope_f[1] = inv_q16_to_float(temp_slope[1]);
temp_slope_f[2] = inv_q16_to_float(temp_slope[2]);
PRINT_3ELM_ARRAY_FLOAT(10, 5, temp_slope_f);
PRINT(" ");
}
} else if (components[LINEAR_ACCELERATION].order == i) {
if (one_time_print) {
PRINT("LINEAR_ACCELERATION_X,"
"LINEAR_ACCELERATION_Y,"
"LINEAR_ACCELERATION_Z,");
} else {
float lin_acc[3];
inv_get_linear_accel_float(lin_acc);
PRINT_3ELM_ARRAY_FLOAT(10, 5, lin_acc);
PRINT(" ");
}
} else if (components[ROTATION_VECTOR].order == i) {
if (one_time_print) {
PRINT("ROTATION_VECTOR_X,"
"ROTATION_VECTOR_Y,"
"ROTATION_VECTOR_Z,");
} else {
float rot_vec[3];
inv_get_sensor_type_rotation_vector_float(rot_vec, NULL, NULL);
PRINT_3ELM_ARRAY_FLOAT(10, 5, rot_vec);
PRINT(" ");
}
} else if (components[MOTION_STATE].order == i) {
if (one_time_print) {
PRINT("MOTION_STATE,");
} else {
unsigned int counter;
PRINT_INT(1, inv_get_motion_state(&counter));
PRINT(", ");
}
} else {
;
}
}
PRINT("\n");
if (one_time_print) {
one_time_print = false;
print_on_screen = print_on_screen_saved;
}
sample_count++;
}
void print_help(char *exename)
{
printf(
"\n"
"Usage:\n"
"\t%s [options]\n"
"\n"
"Options:\n"
" [-h|--help] = shows this help\n"
" [-o|--output PREFIX] = to dump data on csv file whose file\n"
" prefix is specified by the parameter,\n"
" e.g. '<PREFIX>-<timestamp>.csv'\n"
" [-i|--input NAME] = to read the provided playback.bin file\n"
" [-c|--comp C] = enable the following components in the\n"
" given order:\n"
" t = TIME\n"
" T = TEMPERATURE,\n"
" s = TEMP_COMP_SLOPE,\n"
" G = CALIBRATED_GYROSCOPE,\n"
" A = CALIBRATED_ACCELEROMETER,\n"
" C = CALIBRATED_COMPASS,\n"
" g = RAW_GYROSCOPE,\n"
" b = RAW_GYROSCOPE_BODY,\n"
" a = RAW_ACCELEROMETER,\n"
" c = RAW_COMPASS,\n"
" Q = QUATERNION_9_AXIS,\n"
" 6 = QUATERNION_6_AXIS,\n"
" V = GRAVITY,\n"
" L = LINEAR_ACCELERATION,\n"
" R = ROTATION_VECTOR,\n"
" H = HEADING,\n"
" E = COMPASS_BIAS_ERROR,\n"
" S = COMPASS_STATE,\n"
" M = MOTION_STATE.\n"
"\n"
"Note on compass state values:\n"
" SF_NORMAL = 0\n"
" SF_DISTURBANCE = 1\n"
" SF_FAST_SETTLE = 2\n"
" SF_SLOW_SETTLE = 3\n"
" SF_STARTUP_SETTLE = 4\n"
" SF_UNCALIBRATED = 5\n"
"\n",
exename);
}
char *output_filename_datetimestamp(char *out)
{
time_t t;
struct tm *now;
t = time(NULL);
now = localtime(&t);
sprintf(out,
"%02d%02d%02d_%02d%02d%02d.csv",
now->tm_year - 100, now->tm_mon + 1, now->tm_mday,
now->tm_hour, now->tm_min, now->tm_sec);
return out;
}
int components_parser(char pname[], char requested[], int length)
{
int j;
/* forcibly disable all */
for (j = 0; j < NUM_OF_IDS; j++)
components[j].order = -1;
/* parse each character one a time */
for (j = 0; j < length; j++) {
switch (requested[j]) {
case 'T':
components[TEMPERATURE].order = j;
break;
case 'G':
components[CALIBRATED_GYROSCOPE].order = j;
break;
case 'A':
components[CALIBRATED_ACCELEROMETER].order = j;
break;
case 'g':
components[RAW_GYROSCOPE].order = j;
break;
case 'b':
components[RAW_GYROSCOPE_BODY].order = j;
break;
case 'a':
components[RAW_ACCELEROMETER].order = j;
break;
case 'Q':
components[QUATERNION_9_AXIS].order = j;
break;
case '6':
components[QUATERNION_6_AXIS].order = j;
break;
case 'V':
components[GRAVITY].order = j;
break;
case 'L':
components[LINEAR_ACCELERATION].order = j;
break;
case 'R':
components[ROTATION_VECTOR].order = j;
break;
/* these components don't need to be enabled */
case 't':
components[TIME].order = j;
break;
case 'C':
components[CALIBRATED_COMPASS].order = j;
break;
case 'c':
components[RAW_COMPASS].order = j;
break;
case 'H':
components[HEADING].order = j;
break;
case 'E':
components[COMPASS_BIAS_ERROR].order = j;
break;
case 'S':
components[COMPASS_STATE].order = j;
break;
case 'M':
components[MOTION_STATE].order = j;
break;
default:
MPL_LOGI("Error : unrecognized component '%c'\n",
requested[j]);
print_help(pname);
return 1;
break;
}
}
return 0;
}
int main(int argc, char *argv[])
{
#ifndef INV_PLAYBACK_DBG
MPL_LOGI("Error : this application was not compiled with the "
"INV_PLAYBACK_DBG define and cannot work.\n");
MPL_LOGI(" Recompile the libmllite libraries with #define "
"INV_PLAYBACK_DBG uncommented\n");
MPL_LOGI(" in 'software/core/mllite/data_builder.h'.\n");
return INV_ERROR;
#endif
inv_time_t start_time;
double total_time;
char req_component_list[50] = "tQGACH";
char input_filename[101] = "/data/playback.bin";
int i = 0;
char *ver_str;
/* flags */
int use_nm_detection = true;
/* make sure there is no buffering of the print messages */
setvbuf(stdout, NULL, _IONBF, 0);
/* forcibly disable all and populate the names */
for (i = 0; i < NUM_OF_IDS; i++) {
char str_tmp[COMPONENT_NAME_MAX_LEN];
strcpy(components[i].name, component_name(str_tmp, i));
components[i].order = -1;
}
CALL_N_CHECK( inv_get_version(&ver_str) );
MPL_LOGI("\n");
MPL_LOGI("%s\n", ver_str);
MPL_LOGI("\n");
for (i = 1; i < argc; i++) {
if(strcmp(argv[i], "-h") == 0
|| strcmp(argv[i], "--help") == 0) {
print_help(argv[0]);
return INV_SUCCESS;
} else if(strcmp(argv[i], "-o") == 0
|| strcmp(argv[i], "--output") == 0) {
char output_filename[200];
char end[50] = "";
i++;
snprintf(output_filename, sizeof(output_filename), "%s-%s",
argv[i], output_filename_datetimestamp(end));
stream_file = fopen(output_filename, "w+");
if (!stream_file) {
printf("Unable to open file '%s'\n", output_filename);
return INV_ERROR;
}
MPL_LOGI("-- Output on file '%s'\n", output_filename);
} else if(strcmp(argv[i], "-i") == 0
|| strcmp(argv[i], "--input") == 0) {
i++;
strncpy(input_filename, argv[i], sizeof(input_filename));
MPL_LOGI("-- Playing back file '%s'\n", input_filename);
} else if(strcmp(argv[i], "-n") == 0
|| strcmp(argv[i], "--nm") == 0) {
i++;
if (!strcmp(argv[i], "none")) {
use_nm_detection = 0;
} else if (!strcmp(argv[i], "regular")) {
use_nm_detection = 1;
} else if (!strcmp(argv[i], "fast")) {
use_nm_detection = 2;
} else {
MPL_LOGI("Error : unrecognized no-motion type '%s'\n",
argv[i]);
return INV_ERROR_INVALID_PARAMETER;
}
MPL_LOGI("-- No motion algorithm : '%s', %d\n",
argv[i], use_nm_detection);
} else if(strcmp(argv[i], "-9") == 0
|| strcmp(argv[i], "--nine") == 0) {
MPL_LOGI("-- using 9 axis sensor fusion by default\n");
enabled_9x = true;
} else if(strcmp(argv[i], "-c") == 0
|| strcmp(argv[i], "--comp") == 0) {
i++;
strcpy(req_component_list, argv[i]);
} else {
MPL_LOGI("Unrecognized command-line parameter '%s'\n", argv[i]);
return INV_ERROR_INVALID_PARAMETER;
}
}
CALL_CHECK_N_RETURN_ERROR(
components_parser(
argv[0],
req_component_list, strlen(req_component_list)));
/* set up callbacks */
CALL_N_CHECK(inv_set_fifo_processed_callback(fifo_callback));
/* algorithm init */
CALL_N_CHECK(inv_enable_quaternion());
if (use_nm_detection == 1) {
CALL_N_CHECK(inv_enable_motion_no_motion());
} else if (use_nm_detection == 2) {
CALL_N_CHECK(inv_enable_fast_nomot());
}
CALL_N_CHECK(inv_enable_gyro_tc());
CALL_N_CHECK(inv_enable_in_use_auto_calibration());
CALL_N_CHECK(inv_enable_no_gyro_fusion());
CALL_N_CHECK(inv_enable_results_holder());
if (enabled_9x) {
CALL_N_CHECK(inv_enable_heading_from_gyro());
CALL_N_CHECK(inv_enable_compass_bias_w_gyro());
CALL_N_CHECK(inv_enable_vector_compass_cal());
CALL_N_CHECK(inv_enable_9x_sensor_fusion());
}
CALL_CHECK_N_RETURN_ERROR(inv_enable_datalogger_outputs());
CALL_CHECK_N_RETURN_ERROR(inv_constructor_start());
/* load persistent data */
{
FILE *fc = fopen("invcal.bin", "rb");
if (fc != NULL) {
size_t sz, rd;
inv_error_t result = 0;
// Read amount of memory we need to hold data
rd = fread(&sz, sizeof(size_t), 1, fc);
if (rd == sizeof(size_t)) {
unsigned char *cal_data = (unsigned char *)malloc(sizeof(sz));
unsigned char *cal_ptr;
cal_ptr = cal_data;
*(size_t *)cal_ptr = sz;
cal_ptr += sizeof(sz);
/* read rest of the file */
fread(cal_ptr, sz - sizeof(size_t), 1, fc);
//result = inv_load_mpl_states(cal_data, sz);
if (result) {
MPL_LOGE("Cal Load error\n");
}
MPL_LOGI("inv_load_mpl_states()\n");
free(cal_data);
} else {
MPL_LOGE("Cal Load error with size read\n");
}
fclose(fc);
}
}
sample_count = 0;
start_time = inv_get_tick_count();
/* playback data that was recorded */
inv_set_playback_filename(input_filename, strlen(input_filename) + 1);
inv_set_debug_mode(RD_PLAYBACK);
CALL_N_CHECK(inv_playback());
total_time = (1.0 * inv_get_tick_count() - start_time) / 1000;
if (total_time > 0) {
MPL_LOGI("\nPlayed back %ld samples in %.2f s (%.1f Hz)\n",
sample_count, total_time , 1.0 * sample_count / total_time);
}
if (stream_file)
fclose(stream_file);
return INV_SUCCESS;
}