15 #include <visiontransfer/internal/datachannel-imu-bno080.h>
16 #include <visiontransfer/internal/protocol-sh2-imu-bno080.h>
18 namespace visiontransfer {
21 ClientSideDataChannelIMUBNO080::ClientSideDataChannelIMUBNO080()
23 infoString =
"Receiver for the BNO080 IMU sensor";
25 lastXYZ[0x01 - 1] = {0, 0, 0, 0, 0, 10};
26 lastXYZ[0x02 - 1] = {0, 0, 0, 0, 0, 0};
27 lastXYZ[0x03 - 1] = {0, 0, 0, 0, 0, 0};
28 lastXYZ[0x04 - 1] = {0, 0, 0, 0, 0, 0};
29 lastXYZ[0x05 - 1] = {0, 0, 0, 0, 0, 0};
30 lastXYZ[0x06 - 1] = {0, 0, 0, 0, 0, 10};
31 lastScalar[0x0a - 0x0a] = {0, 0, 0, 0};
32 lastScalar[0x0b - 0x0a] = {0, 0, 0, 0};
33 lastScalar[0x0d - 0x0a] = {0, 0, 0, 0};
34 lastScalar[0x0d - 0x0a] = {0, 0, 0, 0};
35 lastScalar[0x0e - 0x0a] = {0, 0, 0, 0};
36 lastRotationQuaternion = {0, 0, 0, 0.0, 0.0, 0.0, 1.0, 0};
39 int ClientSideDataChannelIMUBNO080::handleSensorInputRecord(
unsigned char* data,
int datalen, uint64_t baseTime) {
40 int sensorid = data[0];
41 int status = data[2] & 3;
42 int delay = ((data[2] & 0xfc) << 6) | data[3];
43 uint64_t myTime = baseTime + delay;
46 case SH2Constants::SENSOR_ACCELEROMETER:
47 case SH2Constants::SENSOR_GYROSCOPE:
48 case SH2Constants::SENSOR_MAGNETOMETER:
49 case SH2Constants::SENSOR_LINEAR_ACCELERATION:
50 case SH2Constants::SENSOR_GRAVITY:
53 auto q = sh2GetSensorQPoint(sensorid);
54 x = sh2ConvertFixedQ16(sh2GetU16(data+4), q);
55 y = sh2ConvertFixedQ16(sh2GetU16(data+6), q);
56 z = sh2ConvertFixedQ16(sh2GetU16(data+8), q);
58 lastXYZ[sensorid-1] =
TimestampedVector((
int) (myTime/1000000), (
int) (myTime%1000000), status, x, z, -y);
59 ringbufXYZ[sensorid-1].pushData(lastXYZ[sensorid-1]);
63 case SH2Constants::SENSOR_ROTATION_VECTOR:
64 case SH2Constants::SENSOR_GAME_ROTATION_VECTOR:
65 case SH2Constants::SENSOR_GEOMAGNETIC_ROTATION:
68 double accuracy = -1.0;
69 auto q = sh2GetSensorQPoint(sensorid);
70 x = sh2ConvertFixedQ16(sh2GetU16(data+4), q);
71 y = sh2ConvertFixedQ16(sh2GetU16(data+6), q);
72 z = sh2ConvertFixedQ16(sh2GetU16(data+8), q);
73 w = sh2ConvertFixedQ16(sh2GetU16(data+10), q);
74 if (sensorid!=SH2Constants::SENSOR_GAME_ROTATION_VECTOR) {
77 accuracy = (double) ((
signed short) sh2GetU16(data+12)) / (
double) (1 << 12);
79 lastRotationQuaternion =
TimestampedQuaternion((
int) (myTime/1000000), (
int) (myTime%1000000), status, x, z, -y, w, accuracy);
80 ringbufRotationQuaternion.pushData(lastRotationQuaternion);
84 case SH2Constants::SENSOR_PRESSURE:
85 case SH2Constants::SENSOR_AMBIENT_LIGHT:
87 signed short svalue = sh2GetU32(data+4);
88 double value = (double) svalue / (
double)(1 << sh2GetSensorQPoint(sensorid));
89 lastScalar[sensorid - 0x0a] =
TimestampedScalar((
int) (myTime/1000000), (
int) (myTime%1000000), status, value);
90 ringbufScalar[sensorid - 0x0a].pushData(lastScalar[sensorid - 0x0a]);
93 case SH2Constants::SENSOR_HUMIDITY:
94 case SH2Constants::SENSOR_PROXIMITY:
95 case SH2Constants::SENSOR_TEMPERATURE:
97 signed short svalue = sh2GetU16(data+4);
98 double value = (double) svalue / (
double)(1 << sh2GetSensorQPoint(sensorid));
99 lastScalar[sensorid - 0x0a] =
TimestampedScalar((
int) (myTime/1000000), (
int) (myTime%1000000), status, value);
100 ringbufScalar[sensorid - 0x0a].pushData(lastScalar[sensorid - 0x0a]);
106 int recordlen = sh2GetSensorReportLength(sensorid);
110 void ClientSideDataChannelIMUBNO080::handleChunk(
unsigned char* data,
int datalen) {
111 if (datalen < 5)
return;
112 auto cargobase =
reinterpret_cast<SH2CargoBase*
>(data);
113 static uint64_t interruptTime = 0;
114 switch (cargobase->getReportType()) {
116 auto report =
reinterpret_cast<SH2CargoBodyScenescanTimestamp*
>(data);
117 interruptTime = report->getUSecSinceEpoch();
121 auto report =
reinterpret_cast<SH2CargoBodyTimeBase*
>(data);
122 long basetimeOfs = report->getTimeBase();
123 uint64_t localBase = interruptTime - basetimeOfs;
124 data +=
sizeof(SH2CargoBodyTimeBase); datalen -=
sizeof(SH2CargoBodyTimeBase);
128 while (datalen > 0) {
129 recordlen = handleSensorInputRecord(data, datalen, localBase);
130 if (recordlen<1)
break;
131 data += recordlen; datalen -= recordlen;
146 unsigned char* data = message.payload;
147 int datalen = message.header.payloadSize;
148 while (datalen > 0) {
149 int elemlen = sh2GetU16(data) & 0x7fff;
150 handleChunk(data, elemlen);
151 data += elemlen; datalen -= elemlen;