fix(imu):fix tbe imu bug of s1030

This commit is contained in:
kalman 2018-12-21 22:04:40 +08:00
parent 5b8301c601
commit 0d664b28ad
8 changed files with 147 additions and 52 deletions

View File

@ -515,8 +515,8 @@ struct MYNTEYE_API ImgData {
* IMU data. * IMU data.
*/ */
struct MYNTEYE_API ImuData { struct MYNTEYE_API ImuData {
/** Imu serial number */ /** Imu frame id */
std::uint32_t serial_number; std::uint32_t frame_id;
/** accel or gyro flag:1 for accel,2 for gyro,3 for both */ /** accel or gyro flag:1 for accel,2 for gyro,3 for both */
std::uint8_t flag; std::uint8_t flag;
/** IMU timestamp in 1us */ /** IMU timestamp in 1us */

View File

@ -333,7 +333,7 @@ void Channels::SetImuCallback(imu_callback_t callback) {
void Channels::DoImuTrack() { void Channels::DoImuTrack() {
static ImuReqPacket req_packet{0}; static ImuReqPacket req_packet{0};
static ImuResPacket res_packet; static ImuResPacket res_packet(model_);
req_packet.serial_number = imu_sn_; req_packet.serial_number = imu_sn_;
if (!XuImuWrite(req_packet)) { if (!XuImuWrite(req_packet)) {
@ -360,7 +360,7 @@ void Channels::DoImuTrack() {
return n; return n;
}(); }();
auto &&sn = res_packet.packets.back().segments.back().serial_number; auto &&sn = res_packet.packets.back().serial_number;
if (imu_sn_ == sn) { if (imu_sn_ == sn) {
VLOG(2) << "New imu not ready, dropped"; VLOG(2) << "New imu not ready, dropped";
return; return;

View File

@ -71,6 +71,8 @@ class MYNTEYE_API Channels {
using img_params_t = std::map<Resolution, device::img_params_t>; using img_params_t = std::map<Resolution, device::img_params_t>;
using imu_params_t = device::imu_params_t; using imu_params_t = device::imu_params_t;
std::uint8_t model_;
explicit Channels(std::shared_ptr<uvc::device> device); explicit Channels(std::shared_ptr<uvc::device> device);
~Channels(); ~Channels();

View File

@ -36,7 +36,7 @@ void Motions::SetMotionCallback(motion_callback_t callback) {
if (motion_callback_) { if (motion_callback_) {
accel_range = channels_->GetControlValue(Option::ACCELEROMETER_RANGE); accel_range = channels_->GetControlValue(Option::ACCELEROMETER_RANGE);
if (accel_range == -1) if (accel_range == -1)
accel_range = 12; accel_range = (channels_->model_) ? 8 : 12; // ugly
gyro_range = channels_->GetControlValue(Option::GYROSCOPE_RANGE); gyro_range = channels_->GetControlValue(Option::GYROSCOPE_RANGE);
if (gyro_range == -1) if (gyro_range == -1)
@ -53,28 +53,16 @@ void Motions::SetMotionCallback(motion_callback_t callback) {
// static_cast<uint32_t>(-seg.offset) > packet.timestamp) { // static_cast<uint32_t>(-seg.offset) > packet.timestamp) {
// LOG(WARNING) << "Imu timestamp offset is incorrect"; // LOG(WARNING) << "Imu timestamp offset is incorrect";
// } // }
imu->serial_number = seg.serial_number; imu->frame_id = seg.frame_id;
imu->timestamp = seg.timestamp; imu->timestamp = seg.timestamp;
imu->flag = seg.flag; imu->flag = seg.flag;
imu->temperature = seg.temperature / 326.8f + 25; imu->temperature = seg.temperature / 326.8f + 25;
imu->accel[0] = seg.accel[0] * 1.f * accel_range / 0x10000;
if (imu->flag == 1) { imu->accel[1] = seg.accel[1] * 1.f * accel_range / 0x10000;
imu->accel[0] = seg.accel_or_gyro[0] * 1.f * accel_range / 0x10000; imu->accel[2] = seg.accel[2] * 1.f * accel_range / 0x10000;
imu->accel[1] = seg.accel_or_gyro[1] * 1.f * accel_range / 0x10000; imu->gyro[0] = seg.gyro[0] * 1.f * gyro_range / 0x10000;
imu->accel[2] = seg.accel_or_gyro[2] * 1.f * accel_range / 0x10000; imu->gyro[1] = seg.gyro[1] * 1.f * gyro_range / 0x10000;
imu->gyro[0] = 0; imu->gyro[2] = seg.gyro[2] * 1.f * gyro_range / 0x10000;
imu->gyro[1] = 0;
imu->gyro[2] = 0;
} else if (imu->flag == 2) {
imu->accel[0] = 0;
imu->accel[1] = 0;
imu->accel[2] = 0;
imu->gyro[0] = seg.accel_or_gyro[0] * 1.f * gyro_range / 0x10000;
imu->gyro[1] = seg.accel_or_gyro[1] * 1.f * gyro_range / 0x10000;
imu->gyro[2] = seg.accel_or_gyro[2] * 1.f * gyro_range / 0x10000;
} else {
imu->Reset();
}
std::lock_guard<std::mutex> _(mtx_datas_); std::lock_guard<std::mutex> _(mtx_datas_);
motion_data_t data = {imu}; motion_data_t data = {imu};
@ -90,7 +78,8 @@ void Motions::SetMotionCallback(motion_callback_t callback) {
} }
} }
void Motions::DoMotionTrack() { void Motions::DoMotionTrack(std::uint8_t model) {
channels_->model_ = model;
channels_->DoImuTrack(); channels_->DoImuTrack();
} }

View File

@ -37,7 +37,7 @@ class Motions {
~Motions(); ~Motions();
void SetMotionCallback(motion_callback_t callback); void SetMotionCallback(motion_callback_t callback);
void DoMotionTrack(); void DoMotionTrack(std::uint8_t model);
void StartMotionTracking(); void StartMotionTracking();
void StopMotionTracking(); void StopMotionTracking();

View File

@ -44,7 +44,7 @@ void StandardDevice::StartVideoStreaming() {
void StandardDevice::OnStereoStreamUpdate() { void StandardDevice::OnStereoStreamUpdate() {
if (motion_tracking_) { if (motion_tracking_) {
auto &&motions = this->motions(); auto &&motions = this->motions();
motions->DoMotionTrack(); motions->DoMotionTrack(1);
} }
} }

View File

@ -39,7 +39,7 @@ std::shared_ptr<StreamsAdapter> Standard2Device::CreateStreamsAdapter() const {
void Standard2Device::OnStereoStreamUpdate() { void Standard2Device::OnStereoStreamUpdate() {
if (motion_tracking_) { if (motion_tracking_) {
auto &&motions = this->motions(); auto &&motions = this->motions();
motions->DoMotionTrack(); motions->DoMotionTrack(2);
} }
} }

View File

@ -140,7 +140,7 @@ struct MYNTEYE_API DeviceInfo {
/** /**
* @ingroup datatypes * @ingroup datatypes
* Image packet for standand 2. * Image packet for standard 2.
*/ */
#pragma pack(push, 1) #pragma pack(push, 1)
struct ImagePacketS2 { struct ImagePacketS2 {
@ -176,7 +176,7 @@ struct ImagePacketS2 {
/** /**
* @ingroup datatypes * @ingroup datatypes
* Image packet for standand 1. * Image packet for standard 1.
*/ */
#pragma pack(push, 1) #pragma pack(push, 1)
struct ImagePacketS1 { struct ImagePacketS1 {
@ -230,18 +230,49 @@ struct ImuReqPacket {
/** /**
* @ingroup datatypes * @ingroup datatypes
* Imu segment. * Imu group for standard 1.
*/ */
#pragma pack(push, 1) #pragma pack(push, 1)
struct ImuSegment { struct ImuGroupS1 {
std::uint32_t serial_number; std::int16_t offset;
std::uint16_t frame_id;
std::int16_t accel[3];
std::int16_t temperature;
std::int16_t gyro[3];
ImuGroupS1() = default;
explicit ImuGroupS1(std::uint8_t *data) {
from_data(data);
}
void from_data(std::uint8_t *data) {
offset = (*(data) << 8) | *(data + 1);
frame_id = (*(data + 2) << 8) | *(data + 3);
accel[0] = (*(data + 4) << 8) | *(data + 5);
accel[1] = (*(data + 6) << 8) | *(data + 7);
accel[2] = (*(data + 8) << 8) | *(data + 9);
temperature = (*(data + 10) << 8) | *(data + 11);
gyro[0] = (*(data + 12) << 8) | *(data + 13);
gyro[1] = (*(data + 14) << 8) | *(data + 15);
gyro[2] = (*(data + 16) << 8) | *(data + 17);
}
};
#pragma pack(pop)
/**
* @ingroup datatypes
* Imu group for standard 2.
*/
#pragma pack(push, 1)
struct ImuGroupS2 {
std::uint32_t frame_id;
std::uint64_t timestamp; std::uint64_t timestamp;
std::uint8_t flag; std::uint8_t flag;
std::int16_t temperature; std::int16_t temperature;
std::int16_t accel_or_gyro[3]; std::int16_t accel_or_gyro[3];
ImuSegment() = default; ImuGroupS2() = default;
explicit ImuSegment(std::uint8_t *data) { explicit ImuGroupS2(std::uint8_t *data) {
from_data(data); from_data(data);
} }
@ -249,7 +280,7 @@ struct ImuSegment {
std::uint32_t timestamp_l; std::uint32_t timestamp_l;
std::uint32_t timestamp_h; std::uint32_t timestamp_h;
serial_number = (*(data) << 24) | (*(data + 1) << 16) | (*(data + 2) << 8) | frame_id = (*(data) << 24) | (*(data + 1) << 16) | (*(data + 2) << 8) |
*(data + 3); *(data + 3);
timestamp_h = (*(data + 4) << 24) | (*(data + 5) << 16) | timestamp_h = (*(data + 4) << 24) | (*(data + 5) << 16) |
(*(data + 6) << 8) | *(data + 7); (*(data + 6) << 8) | *(data + 7);
@ -265,24 +296,86 @@ struct ImuSegment {
}; };
#pragma pack(pop) #pragma pack(pop)
/**
* @ingroup datatypes
* Imu segment.
*/
#pragma pack(push, 1)
struct ImuSegment {
std::uint32_t frame_id;
std::uint64_t timestamp;
std::uint8_t flag;
std::int16_t temperature;
std::int16_t accel[3];
std::int16_t gyro[3];
ImuSegment() = default;
explicit ImuSegment(ImuGroupS2 group)
: frame_id(group.frame_id), timestamp(group.timestamp),
flag(group.flag), temperature(group.temperature) {
accel[0] = (flag == 1)?group.accel_or_gyro[0]:0;
accel[1] = (flag == 1)?group.accel_or_gyro[1]:0;
accel[2] = (flag == 1)?group.accel_or_gyro[2]:0;
gyro[0] = (flag == 2)?group.accel_or_gyro[0]:0;
gyro[1] = (flag == 2)?group.accel_or_gyro[1]:0;
gyro[2] = (flag == 2)?group.accel_or_gyro[2]:0;
}
explicit ImuSegment(std::uint32_t timestamp, ImuGroupS1 group) {
frame_id = static_cast<uint32_t> (group.frame_id);
this->timestamp = static_cast<uint64_t> (timestamp + group.offset);
flag = 3;
temperature = group.temperature;
accel[0] = group.accel[0];
accel[1] = group.accel[1];
accel[2] = group.accel[2];
gyro[0] = group.gyro[0];
gyro[1] = group.gyro[1];
gyro[2] = group.gyro[2];
}
};
#pragma pack(pop)
/** /**
* @ingroup datatypes * @ingroup datatypes
* Imu packet. * Imu packet.
*/ */
#pragma pack(push, 1) #pragma pack(push, 1)
struct ImuPacket { struct ImuPacket {
std::uint8_t model;
std::uint8_t count; std::uint8_t count;
std::uint32_t serial_number;
std::vector<ImuSegment> segments; std::vector<ImuSegment> segments;
ImuPacket() = default; ImuPacket() = default;
explicit ImuPacket(std::uint8_t seg_count, std::uint8_t *data) { explicit ImuPacket(
count = seg_count; std::uint8_t model, std::uint8_t seg_count, std::uint8_t *data)
from_data(data); : model(model), count(seg_count) {
} from_data(data);
}
void from_data(std::uint8_t *data) { void from_data(std::uint8_t *data) {
std::size_t seg_n = sizeof(ImuSegment); // 21 if (model == 1) {
for (std::size_t i = 0; i < count; i++) { serial_number =
segments.push_back(ImuSegment(data + seg_n * i)); (*(data) << 24) | (*(data + 1) << 16) |
(*(data + 2) << 8) | *(data + 3);
int timestamp =
(*(data + 4) << 24) | (*(data + 5) << 16)|
(*(data + 6) << 8) | *(data + 7);
count = *(data + 8);
std::size_t seg_n = sizeof(ImuGroupS1); // 18
for (std::size_t i = 0; i < count; i++) {
ImuGroupS1 group(data + 9 + (seg_n * i));
segments.push_back(ImuSegment(timestamp, group));
}
} else if (model == 2) {
std::size_t seg_n = sizeof(ImuGroupS2); // 21
for (std::size_t i = 0; i < count; i++) {
ImuGroupS2 group(data + seg_n * i);
segments.push_back(ImuSegment(group));
}
serial_number = segments.back().frame_id;
} }
} }
}; };
@ -294,6 +387,7 @@ struct ImuPacket {
*/ */
#pragma pack(push, 1) #pragma pack(push, 1)
struct ImuResPacket { struct ImuResPacket {
std::uint8_t model;
std::uint8_t header; std::uint8_t header;
std::uint8_t state; std::uint8_t state;
std::uint16_t size; std::uint16_t size;
@ -301,21 +395,31 @@ struct ImuResPacket {
std::uint8_t checksum; std::uint8_t checksum;
ImuResPacket() = default; ImuResPacket() = default;
explicit ImuResPacket(std::uint8_t *data) { explicit ImuResPacket(std::uint8_t model) : model(model) {}
from_data(data);
}
void from_data(std::uint8_t *data) { void from_data(std::uint8_t *data) {
header = *data; header = *data;
state = *(data + 1); state = *(data + 1);
size = (*(data + 2) << 8) | *(data + 3); size = (*(data + 2) << 8) | *(data + 3);
std::size_t seg_n = sizeof(ImuSegment); // 21 if (model == 1) {
std::uint8_t seg_count = size / seg_n; std::size_t seg_n = sizeof(ImuGroupS1); // 18
ImuPacket packet(seg_count, data + 4); for (std::size_t i = 4; i < size;) {
packets.push_back(packet); ImuPacket packet(model, 0, data + i);
// packet(2); packets.push_back(packet);
checksum = *(data + 4 + size); i += 9 + (packet.count * seg_n);
}
checksum = *(data + 4 + size);
}
if (model == 2) {
std::size_t seg_n = sizeof(ImuGroupS2); // 21
std::uint8_t seg_count = size / seg_n;
ImuPacket packet(model, seg_count, data + 4);
packets.push_back(packet);
// packet(2);
checksum = *(data + 4 + size);
}
} }
}; };
#pragma pack(pop) #pragma pack(pop)