d/psmv: Refactor calibration and make room for ZCM2

This commit is contained in:
Jakob Bornecrantz 2019-09-15 12:11:17 +01:00
parent b5c7f080de
commit 932b8dfd70

View file

@ -196,7 +196,7 @@ struct psmv_vec3_i16_wire
* *
* @ingroup drv_psmv * @ingroup drv_psmv
*/ */
struct psmv_get_input struct psmv_input_zcm1
{ {
uint8_t header; uint8_t header;
uint8_t buttons[4]; uint8_t buttons[4];
@ -281,47 +281,8 @@ struct psmv_parsed_input
struct psmv_parsed_sample sample[2]; struct psmv_parsed_sample sample[2];
}; };
/*! struct psmv_parsed_calibration_zcm1
* A single PlayStation Move Controller.
*
* @ingroup drv_psmv
*/
struct psmv_device
{ {
struct xrt_device base;
struct os_hid_device *hid;
struct os_thread_helper oth;
struct
{
int64_t resend_time;
struct xrt_colour_rgb_u8 led;
uint8_t rumble;
} wants;
struct
{
struct xrt_colour_rgb_u8 led;
uint8_t rumble;
} state;
struct
{
//! Lock for last and fusion.
struct os_mutex lock;
//! Last sensor read.
struct psmv_parsed_input last;
struct
{
struct xrt_quat rot;
} fusion;
};
struct xrt_vec3_i32 accel_min_x; struct xrt_vec3_i32 accel_min_x;
struct xrt_vec3_i32 accel_max_x; struct xrt_vec3_i32 accel_max_x;
struct xrt_vec3_i32 accel_min_y; struct xrt_vec3_i32 accel_min_y;
@ -351,6 +312,73 @@ struct psmv_device
struct xrt_vec3 unknown_vec3; struct xrt_vec3 unknown_vec3;
float unknown_float_0, unknown_float_1; float unknown_float_0, unknown_float_1;
};
struct psmv_parsed_calibration
{
struct psmv_parsed_calibration_zcm1 zcm1;
};
/*!
* A single PlayStation Move Controller.
*
* @ingroup drv_psmv
*/
struct psmv_device
{
struct xrt_device base;
struct os_hid_device *hid;
struct os_thread_helper oth;
struct
{
int64_t resend_time;
struct xrt_colour_rgb_u8 led;
uint8_t rumble;
} wants;
struct
{
struct xrt_colour_rgb_u8 led;
uint8_t rumble;
} state;
struct
{
union {
struct psmv_parsed_calibration_zcm1 zcm1;
};
struct
{
struct xrt_vec3 factor;
struct xrt_vec3 bias;
} accel;
struct
{
struct xrt_vec3 factor;
struct xrt_vec3 bias;
} gyro;
} calibration;
struct
{
//! Lock for last and fusion.
struct os_mutex lock;
//! Last sensor read.
struct psmv_parsed_input last;
struct
{
struct xrt_quat rot;
} fusion;
};
struct struct
{ {
@ -495,39 +523,19 @@ update_fusion(struct psmv_device *psmv,
struct xrt_vec3_i32 *ra = &sample->accel; struct xrt_vec3_i32 *ra = &sample->accel;
struct xrt_vec3_i32 *rg = &sample->gyro; struct xrt_vec3_i32 *rg = &sample->gyro;
//! @todo Pre-calculate this. psmv->read.accel.x = (ra->x + psmv->calibration.accel.bias.x) *
double ax = (psmv->accel_max_x.x - psmv->accel_min_x.x) / 2.0; psmv->calibration.accel.factor.x;
double ay = (psmv->accel_max_y.y - psmv->accel_min_y.y) / 2.0; psmv->read.accel.y = (ra->y + psmv->calibration.accel.bias.y) *
double az = (psmv->accel_max_z.z - psmv->accel_min_z.z) / 2.0; psmv->calibration.accel.factor.y;
psmv->read.accel.z = (ra->z + psmv->calibration.accel.bias.z) *
psmv->calibration.accel.factor.z;
double bx = (psmv->accel_min_y.x + psmv->accel_max_y.x + psmv->read.gyro.x = (rg->x + psmv->calibration.gyro.bias.x) *
psmv->accel_min_z.x + psmv->accel_max_z.x) / psmv->calibration.gyro.factor.x;
-4.0; psmv->read.gyro.y = (rg->y + psmv->calibration.gyro.bias.y) *
double by = (psmv->accel_min_x.y + psmv->accel_max_x.y + psmv->calibration.gyro.factor.y;
psmv->accel_min_z.y + psmv->accel_max_z.y) / psmv->read.gyro.z = (rg->z + psmv->calibration.gyro.bias.z) *
-4.0; psmv->calibration.gyro.factor.z;
double bz = (psmv->accel_min_x.z + psmv->accel_max_x.z +
psmv->accel_min_y.z + psmv->accel_max_y.z) /
-4.0;
psmv->read.accel.x = (ra->x + bx) / ax;
psmv->read.accel.y = (ra->y + by) / ay;
psmv->read.accel.z = (ra->z + bz) / az;
double gx =
(psmv->gyro_rot_x.x - (psmv->gyro_bias_0.x * psmv->gyro_fact.x));
double gy =
(psmv->gyro_rot_y.y - (psmv->gyro_bias_0.y * psmv->gyro_fact.y));
double gz =
(psmv->gyro_rot_z.z - (psmv->gyro_bias_0.z * psmv->gyro_fact.z));
gx = (2.0 * M_PI * 80.0) / (60.0 * gx);
gy = (2.0 * M_PI * 80.0) / (60.0 * gy);
gz = (2.0 * M_PI * 80.0) / (60.0 * gz);
psmv->read.gyro.x = rg->x * gx;
psmv->read.gyro.y = rg->y * gy;
psmv->read.gyro.z = rg->z * gz;
// Super simple fusion. // Super simple fusion.
math_quat_integrate_velocity(&psmv->fusion.rot, &psmv->read.gyro, dt, math_quat_integrate_velocity(&psmv->fusion.rot, &psmv->read.gyro, dt,
@ -560,15 +568,21 @@ psmv_read_one_packet(struct psmv_device *psmv, uint8_t *buffer, size_t size)
return false; return false;
} }
static void * static void
psmv_run_thread(void *ptr) psmv_parse_input_zcm1(
struct psmv_device *psmv,
struct psmv_input_zcm1 *data,
struct psmv_parsed_input *input);
static void *psmv_run_thread(void *ptr)
{ {
struct psmv_device *psmv = (struct psmv_device *)ptr; struct psmv_device *psmv = (struct psmv_device *)ptr;
struct time_state *time = time_state_create(); struct time_state *time = time_state_create();
union { union {
uint8_t buffer[256]; uint8_t buffer[256];
struct psmv_get_input input; struct psmv_input_zcm1 input;
} data; } data;
struct psmv_parsed_input input = {0}; struct psmv_parsed_input input = {0};
@ -589,53 +603,7 @@ psmv_run_thread(void *ptr)
timepoint_ns now_ns = time_state_get_now(time); timepoint_ns now_ns = time_state_get_now(time);
input.battery = data.input.battery; psmv_parse_input_zcm1(psmv, &data.input, &input);
input.seq_no = data.input.buttons[3] & 0x0f;
input.buttons |= data.input.buttons[0] << 24;
input.buttons |= data.input.buttons[1] << 16;
input.buttons |= data.input.buttons[2] << 8;
input.buttons |= data.input.buttons[3] & 0xf0;
input.timestamp |= data.input.timestamp_low;
input.timestamp |= data.input.timestamp_high << 8;
input.sample[0].trigger = data.input.trigger_f1;
psmv_from_vec3_i16_zn_wire(&input.sample[0].accel,
&data.input.accel_f1);
psmv_from_vec3_i16_zn_wire(&input.sample[0].gyro,
&data.input.gyro_f1);
input.sample[1].trigger = data.input.trigger_f2;
psmv_from_vec3_i16_zn_wire(&input.sample[1].accel,
&data.input.accel_f2);
psmv_from_vec3_i16_zn_wire(&input.sample[1].gyro,
&data.input.gyro_f2);
uint32_t diff = psmv_calc_delta_and_handle_rollover(
input.timestamp, psmv->last.timestamp);
bool missed = input.seq_no != ((psmv->last.seq_no + 1) & 0x0f);
PSMV_SPEW(psmv,
"\n\t"
"missed: %s\n\t"
"buttons: %08x\n\t"
"battery: %x\n\t"
"sample[0].trigger: %02x\n\t"
"sample[0].accel_x: %i\n\t"
"sample[0].accel_y: %i\n\t"
"sample[0].accel_z: %i\n\t"
"sample[0].gyro_x: %i\n\t"
"sample[0].gyro_y: %i\n\t"
"sample[0].gyro_z: %i\n\t"
"sample[1].trigger: %02x\n\t"
"timestamp: %i\n\t"
"diff: %i\n\t"
"seq_no: %x\n",
missed ? "yes" : "no", input.buttons, input.battery,
input.sample[0].trigger, input.sample[0].accel.x,
input.sample[0].accel.y, input.sample[0].accel.z,
input.sample[0].gyro.x, input.sample[0].gyro.y,
input.sample[0].gyro.z, input.sample[1].trigger,
input.timestamp, diff, input.seq_no);
float dt = time_ns_to_s(now_ns - then_ns); float dt = time_ns_to_s(now_ns - then_ns);
then_ns = now_ns; then_ns = now_ns;
@ -719,99 +687,7 @@ psmv_led_and_trigger_update(struct psmv_device *psmv, int64_t time)
} }
static int static int
psmv_get_calibration(struct psmv_device *psmv) psmv_get_calibration_zcm1(struct psmv_device *psmv);
{
struct psmv_calibration_zcm1 data;
uint8_t *dst = (uint8_t *)&data;
int ret = 0;
size_t src_offset, dst_offset;
for (int i = 0; i < 3; i++) {
struct psmv_calibration_part part = {0};
uint8_t *src = (uint8_t *)&part;
part.id = 0x10;
ret = os_hid_get_feature(psmv->hid, 0x10, src, sizeof(part));
if (ret < 0) {
return ret;
}
if (ret != (int)sizeof(part)) {
return -1;
}
switch (part.which) {
case 0x00:
src_offset = 0;
dst_offset = 0;
break;
case 0x01:
src_offset = 2;
dst_offset = sizeof(part);
break;
case 0x82:
src_offset = 2;
dst_offset = sizeof(part) * 2 - 2;
break;
default: return -1;
}
memcpy(dst + dst_offset, src + src_offset,
sizeof(part) - src_offset);
}
psmv_from_vec3_i16_zn_wire(&psmv->accel_min_x, &data.accel_min_x);
psmv_from_vec3_i16_zn_wire(&psmv->accel_max_x, &data.accel_max_x);
psmv_from_vec3_i16_zn_wire(&psmv->accel_min_y, &data.accel_min_y);
psmv_from_vec3_i16_zn_wire(&psmv->accel_max_y, &data.accel_max_y);
psmv_from_vec3_i16_zn_wire(&psmv->accel_min_z, &data.accel_min_z);
psmv_from_vec3_i16_zn_wire(&psmv->accel_max_z, &data.accel_max_z);
psmv_from_vec3_i16_wire(&psmv->gyro_bias_0, &data.gyro_bias_0);
psmv_from_vec3_i16_wire(&psmv->gyro_bias_1, &data.gyro_bias_1);
psmv_from_vec3_i16_wire(&psmv->gyro_rot_x, &data.gyro_rot_x);
psmv_from_vec3_i16_wire(&psmv->gyro_rot_y, &data.gyro_rot_y);
psmv_from_vec3_i16_wire(&psmv->gyro_rot_z, &data.gyro_rot_z);
psmv_from_vec32_f32_wire(&psmv->gyro_fact, &data.gyro_fact);
psmv_from_vec3_f32_zn_wire(&psmv->unknown_vec3, &data.unknown_vec3);
psmv_f32_from_wire(&psmv->unknown_float_0, &data.unknown_float_0);
psmv_f32_from_wire(&psmv->unknown_float_1, &data.unknown_float_1);
PSMV_DEBUG(
psmv,
"Calibration:\n"
"\taccel_min_x: %i %i %i\n"
"\taccel_max_x: %i %i %i\n"
"\taccel_min_y: %i %i %i\n"
"\taccel_max_y: %i %i %i\n"
"\taccel_min_z: %i %i %i\n"
"\taccel_max_z: %i %i %i\n"
"\tgyro_bias_0: %i %i %i\n"
"\tgyro_bias_1: %i %i %i\n"
"\tgyro_fact: %f %f %f\n"
"\tgyro_rot_x: %i %i %i\n"
"\tgyro_rot_y: %i %i %i\n"
"\tgyro_rot_z: %i %i %i\n"
"\tunknown_vec3: %f %f %f\n"
"\tunknown_float_0 %f\n"
"\tunknown_float_1 %f\n",
psmv->accel_min_x.x, psmv->accel_min_x.y, psmv->accel_min_x.z,
psmv->accel_max_x.x, psmv->accel_max_x.y, psmv->accel_max_x.z,
psmv->accel_min_y.x, psmv->accel_min_y.y, psmv->accel_min_y.z,
psmv->accel_max_y.x, psmv->accel_max_y.y, psmv->accel_max_y.z,
psmv->accel_min_z.x, psmv->accel_min_z.y, psmv->accel_min_z.z,
psmv->accel_max_z.x, psmv->accel_max_z.y, psmv->accel_max_z.z,
psmv->gyro_bias_0.x, psmv->gyro_bias_0.y, psmv->gyro_bias_0.z,
psmv->gyro_bias_1.x, psmv->gyro_bias_1.y, psmv->gyro_bias_1.z,
psmv->gyro_fact.x, psmv->gyro_fact.y, psmv->gyro_fact.z,
psmv->gyro_rot_x.x, psmv->gyro_rot_x.y, psmv->gyro_rot_x.z,
psmv->gyro_rot_y.x, psmv->gyro_rot_y.y, psmv->gyro_rot_y.z,
psmv->gyro_rot_z.x, psmv->gyro_rot_z.y, psmv->gyro_rot_z.z,
psmv->unknown_vec3.x, psmv->unknown_vec3.y, psmv->unknown_vec3.z,
psmv->unknown_float_0, psmv->unknown_float_1);
return 0;
}
/* /*
@ -996,7 +872,7 @@ psmv_found(struct xrt_prober *xp,
} }
// Get calibration data. // Get calibration data.
ret = psmv_get_calibration(psmv); ret = psmv_get_calibration_zcm1(psmv);
if (ret != 0) { if (ret != 0) {
PSMV_ERROR(psmv, "Failed to get calibration data!"); PSMV_ERROR(psmv, "Failed to get calibration data!");
psmv_device_destroy(&psmv->base); psmv_device_destroy(&psmv->base);
@ -1017,18 +893,22 @@ psmv_found(struct xrt_prober *xp,
// clang-format off // clang-format off
u_var_add_root(psmv, "PSMV Controller", true); u_var_add_root(psmv, "PSMV Controller", true);
u_var_add_gui_header(psmv, &psmv->gui.calibration, "Calibration"); u_var_add_gui_header(psmv, &psmv->gui.calibration, "Calibration");
u_var_add_vec3_i32(psmv, &psmv->accel_min_x, "accel_min_x"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.accel_min_x, "zcm1.accel_min_x");
u_var_add_vec3_i32(psmv, &psmv->accel_max_x, "accel_max_x"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.accel_max_x, "zcm1.accel_max_x");
u_var_add_vec3_i32(psmv, &psmv->accel_min_y, "accel_min_y"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.accel_min_y, "zcm1.accel_min_y");
u_var_add_vec3_i32(psmv, &psmv->accel_max_y, "accel_max_y"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.accel_max_y, "zcm1.accel_max_y");
u_var_add_vec3_i32(psmv, &psmv->accel_min_z, "accel_min_z"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.accel_min_z, "zcm1.accel_min_z");
u_var_add_vec3_i32(psmv, &psmv->accel_max_z, "accel_max_z"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.accel_max_z, "zcm1.accel_max_z");
u_var_add_vec3_i32(psmv, &psmv->gyro_rot_x, "gyro_rot_x"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.gyro_rot_x, "zcm1.gyro_rot_x");
u_var_add_vec3_i32(psmv, &psmv->gyro_rot_y, "gyro_rot_y"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.gyro_rot_y, "zcm1.gyro_rot_y");
u_var_add_vec3_i32(psmv, &psmv->gyro_rot_z, "gyro_rot_z"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.gyro_rot_z, "zcm1.gyro_rot_z");
u_var_add_vec3_i32(psmv, &psmv->gyro_bias_0, "gyro_bias_0"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.gyro_bias_0, "zcm1.gyro_bias_0");
u_var_add_vec3_i32(psmv, &psmv->gyro_bias_1, "gyro_bias_1"); u_var_add_vec3_i32(psmv, &psmv->calibration.zcm1.gyro_bias_1, "zcm1.gyro_bias_1");
u_var_add_vec3_f32(psmv, &psmv->gyro_fact, "gyro_fact"); u_var_add_vec3_f32(psmv, &psmv->calibration.zcm1.gyro_fact, "zcm1.gyro_fact");
u_var_add_vec3_f32(psmv, &psmv->calibration.accel.factor, "accel.factor");
u_var_add_vec3_f32(psmv, &psmv->calibration.accel.bias, "accel.bias");
u_var_add_vec3_f32(psmv, &psmv->calibration.gyro.factor, "gyro.factor");
u_var_add_vec3_f32(psmv, &psmv->calibration.gyro.bias, "gyro.bias");
u_var_add_gui_header(psmv, &psmv->gui.last_frame, "Last data"); u_var_add_gui_header(psmv, &psmv->gui.last_frame, "Last data");
u_var_add_ro_vec3_i32(psmv, &psmv->last.sample[0].accel, "last.sample[0].accel"); u_var_add_ro_vec3_i32(psmv, &psmv->last.sample[0].accel, "last.sample[0].accel");
u_var_add_ro_vec3_i32(psmv, &psmv->last.sample[1].accel, "last.sample[1].accel"); u_var_add_ro_vec3_i32(psmv, &psmv->last.sample[1].accel, "last.sample[1].accel");
@ -1048,3 +928,223 @@ psmv_found(struct xrt_prober *xp,
return 1; return 1;
} }
/*
*
* Packet functions ZCM1
*
*/
static int
psmv_get_calibration_zcm1(struct psmv_device *psmv)
{
struct psmv_parsed_calibration_zcm1 *zcm1 = &psmv->calibration.zcm1;
struct psmv_calibration_zcm1 data;
uint8_t *dst = (uint8_t *)&data;
int ret = 0;
size_t src_offset, dst_offset;
for (int i = 0; i < 3; i++) {
struct psmv_calibration_part part = {0};
uint8_t *src = (uint8_t *)&part;
part.id = 0x10;
ret = os_hid_get_feature(psmv->hid, 0x10, src, sizeof(part));
if (ret < 0) {
return ret;
}
if (ret != (int)sizeof(part)) {
return -1;
}
switch (part.which) {
case 0x00:
src_offset = 0;
dst_offset = 0;
break;
case 0x01:
src_offset = 2;
dst_offset = sizeof(part);
break;
case 0x82:
src_offset = 2;
dst_offset = sizeof(part) * 2 - 2;
break;
default: return -1;
}
memcpy(dst + dst_offset, src + src_offset,
sizeof(part) - src_offset);
}
psmv_from_vec3_i16_zn_wire(&zcm1->accel_min_x, &data.accel_min_x);
psmv_from_vec3_i16_zn_wire(&zcm1->accel_max_x, &data.accel_max_x);
psmv_from_vec3_i16_zn_wire(&zcm1->accel_min_y, &data.accel_min_y);
psmv_from_vec3_i16_zn_wire(&zcm1->accel_max_y, &data.accel_max_y);
psmv_from_vec3_i16_zn_wire(&zcm1->accel_min_z, &data.accel_min_z);
psmv_from_vec3_i16_zn_wire(&zcm1->accel_max_z, &data.accel_max_z);
psmv_from_vec3_i16_wire(&zcm1->gyro_bias_0, &data.gyro_bias_0);
psmv_from_vec3_i16_wire(&zcm1->gyro_bias_1, &data.gyro_bias_1);
psmv_from_vec3_i16_wire(&zcm1->gyro_rot_x, &data.gyro_rot_x);
psmv_from_vec3_i16_wire(&zcm1->gyro_rot_y, &data.gyro_rot_y);
psmv_from_vec3_i16_wire(&zcm1->gyro_rot_z, &data.gyro_rot_z);
psmv_from_vec32_f32_wire(&zcm1->gyro_fact, &data.gyro_fact);
psmv_from_vec3_f32_zn_wire(&zcm1->unknown_vec3, &data.unknown_vec3);
psmv_f32_from_wire(&zcm1->unknown_float_0, &data.unknown_float_0);
psmv_f32_from_wire(&zcm1->unknown_float_1, &data.unknown_float_1);
/*
* Acceleration
*/
psmv->calibration.accel.factor.x =
1.0 / ((zcm1->accel_max_x.x - zcm1->accel_min_x.x) / 2.0);
psmv->calibration.accel.factor.y =
1.0 / ((zcm1->accel_max_y.y - zcm1->accel_min_y.y) / 2.0);
psmv->calibration.accel.factor.z =
1.0 / ((zcm1->accel_max_z.z - zcm1->accel_min_z.z) / 2.0);
psmv->calibration.accel.bias.x =
(zcm1->accel_min_y.x + zcm1->accel_max_y.x + zcm1->accel_min_z.x +
zcm1->accel_max_z.x) /
-4.0;
psmv->calibration.accel.bias.y =
(zcm1->accel_min_x.y + zcm1->accel_max_x.y + zcm1->accel_min_z.y +
zcm1->accel_max_z.y) /
-4.0;
psmv->calibration.accel.bias.z =
(zcm1->accel_min_x.z + zcm1->accel_max_x.z + zcm1->accel_min_y.z +
zcm1->accel_max_y.z) /
-4.0;
/*
* Gyro
*/
double gx =
(zcm1->gyro_rot_x.x - (zcm1->gyro_bias_0.x * zcm1->gyro_fact.x));
double gy =
(zcm1->gyro_rot_y.y - (zcm1->gyro_bias_0.y * zcm1->gyro_fact.y));
double gz =
(zcm1->gyro_rot_z.z - (zcm1->gyro_bias_0.z * zcm1->gyro_fact.z));
psmv->calibration.gyro.factor.x = (2.0 * M_PI * 80.0) / (60.0 * gx);
psmv->calibration.gyro.factor.y = (2.0 * M_PI * 80.0) / (60.0 * gy);
psmv->calibration.gyro.factor.z = (2.0 * M_PI * 80.0) / (60.0 * gz);
psmv->calibration.gyro.bias.x = 0.0;
psmv->calibration.gyro.bias.y = 0.0;
psmv->calibration.gyro.bias.z = 0.0;
/*
* Print
*/
PSMV_DEBUG(
psmv,
"Calibration:\n"
"\taccel_min_x: %i %i %i\n"
"\taccel_max_x: %i %i %i\n"
"\taccel_min_y: %i %i %i\n"
"\taccel_max_y: %i %i %i\n"
"\taccel_min_z: %i %i %i\n"
"\taccel_max_z: %i %i %i\n"
"\tgyro_bias_0: %i %i %i\n"
"\tgyro_bias_1: %i %i %i\n"
"\tgyro_fact: %f %f %f\n"
"\tgyro_rot_x: %i %i %i\n"
"\tgyro_rot_y: %i %i %i\n"
"\tgyro_rot_z: %i %i %i\n"
"\tunknown_vec3: %f %f %f\n"
"\tunknown_float_0 %f\n"
"\tunknown_float_1 %f\n"
"Calculated:\n"
"\taccel.factor: %f %f %f\n"
"\taccel.bias: %f %f %f\n"
"\tgyro.factor: %f %f %f\n"
"\tgyro.bias: %f %f %f\n",
zcm1->accel_min_x.x, zcm1->accel_min_x.y, zcm1->accel_min_x.z,
zcm1->accel_max_x.x, zcm1->accel_max_x.y, zcm1->accel_max_x.z,
zcm1->accel_min_y.x, zcm1->accel_min_y.y, zcm1->accel_min_y.z,
zcm1->accel_max_y.x, zcm1->accel_max_y.y, zcm1->accel_max_y.z,
zcm1->accel_min_z.x, zcm1->accel_min_z.y, zcm1->accel_min_z.z,
zcm1->accel_max_z.x, zcm1->accel_max_z.y, zcm1->accel_max_z.z,
zcm1->gyro_bias_0.x, zcm1->gyro_bias_0.y, zcm1->gyro_bias_0.z,
zcm1->gyro_bias_1.x, zcm1->gyro_bias_1.y, zcm1->gyro_bias_1.z,
zcm1->gyro_fact.x, zcm1->gyro_fact.y, zcm1->gyro_fact.z,
zcm1->gyro_rot_x.x, zcm1->gyro_rot_x.y, zcm1->gyro_rot_x.z,
zcm1->gyro_rot_y.x, zcm1->gyro_rot_y.y, zcm1->gyro_rot_y.z,
zcm1->gyro_rot_z.x, zcm1->gyro_rot_z.y, zcm1->gyro_rot_z.z,
zcm1->unknown_vec3.x, zcm1->unknown_vec3.y, zcm1->unknown_vec3.z,
zcm1->unknown_float_0, zcm1->unknown_float_1,
psmv->calibration.accel.factor.x, psmv->calibration.accel.factor.y,
psmv->calibration.accel.factor.z, psmv->calibration.accel.bias.x,
psmv->calibration.accel.bias.y, psmv->calibration.accel.bias.z,
psmv->calibration.gyro.factor.x, psmv->calibration.gyro.factor.y,
psmv->calibration.gyro.factor.z, psmv->calibration.gyro.bias.x,
psmv->calibration.gyro.bias.y, psmv->calibration.gyro.bias.z);
return 0;
}
static void
psmv_parse_input_zcm1(
struct psmv_device *psmv,
struct psmv_input_zcm1 *data,
struct psmv_parsed_input *input)
{
input->battery = data->battery;
input->seq_no = data->buttons[3] & 0x0f;
input->buttons |= data->buttons[0] << 24;
input->buttons |= data->buttons[1] << 16;
input->buttons |= data->buttons[2] << 8;
input->buttons |= data->buttons[3] & 0xf0;
input->timestamp |= data->timestamp_low;
input->timestamp |= data->timestamp_high << 8;
input->sample[0].trigger = data->trigger_f1;
psmv_from_vec3_i16_zn_wire(&input->sample[0].accel, &data->accel_f1);
psmv_from_vec3_i16_zn_wire(&input->sample[0].gyro, &data->gyro_f1);
input->sample[1].trigger = data->trigger_f2;
psmv_from_vec3_i16_zn_wire(&input->sample[1].accel, &data->accel_f2);
psmv_from_vec3_i16_zn_wire(&input->sample[1].gyro, &data->gyro_f2);
uint32_t diff = psmv_calc_delta_and_handle_rollover(
input->timestamp, psmv->last.timestamp);
bool missed = input->seq_no != ((psmv->last.seq_no + 1) & 0x0f);
/*
* Print
*/
PSMV_SPEW(psmv,
"\n\t"
"missed: %s\n\t"
"buttons: %08x\n\t"
"battery: %x\n\t"
"sample[0].trigger: %02x\n\t"
"sample[0].accel_x: %i\n\t"
"sample[0].accel_y: %i\n\t"
"sample[0].accel_z: %i\n\t"
"sample[0].gyro_x: %i\n\t"
"sample[0].gyro_y: %i\n\t"
"sample[0].gyro_z: %i\n\t"
"sample[1].trigger: %02x\n\t"
"timestamp: %i\n\t"
"diff: %i\n\t"
"seq_no: %x\n",
missed ? "yes" : "no", input->buttons, input->battery,
input->sample[0].trigger, input->sample[0].accel.x,
input->sample[0].accel.y, input->sample[0].accel.z,
input->sample[0].gyro.x, input->sample[0].gyro.y,
input->sample[0].gyro.z, input->sample[1].trigger,
input->timestamp, diff, input->seq_no);
}