From c6fd9db8270f9f9b586bb19b9a630ad88fed361e Mon Sep 17 00:00:00 2001 From: kalman Date: Wed, 2 Jan 2019 19:41:34 +0800 Subject: [PATCH] feat(root): add s210a --- CMakeLists.txt | 3 + include/mynteye/types.h | 6 +- samples/tutorials/control/auto_exposure.cc | 4 +- samples/tutorials/control/framerate.cc | 4 +- .../tutorials/control/imu_low_pass_filter.cc | 4 +- samples/tutorials/control/imu_range.cc | 6 +- samples/tutorials/control/infrared.cc | 5 +- samples/tutorials/control/manual_exposure.cc | 4 +- src/mynteye/device/config.cc | 25 ++- src/mynteye/device/device.cc | 18 +- .../standard2/channels_adapter_s210a.cc | 173 ++++++++++++++++ .../device/standard2/channels_adapter_s210a.h | 51 +++++ src/mynteye/device/standard2/device_s210a.cc | 45 +++++ src/mynteye/device/standard2/device_s210a.h | 37 ++++ .../device/standard2/streams_adapter_s2.cc | 30 +-- .../device/standard2/streams_adapter_s210a.cc | 186 ++++++++++++++++++ .../device/standard2/streams_adapter_s210a.h | 42 ++++ src/mynteye/types.cc | 1 + .../launch/mynteye.launch | 78 ++++++-- .../src/wrapper_nodelet.cc | 52 +++-- 20 files changed, 699 insertions(+), 75 deletions(-) create mode 100644 src/mynteye/device/standard2/channels_adapter_s210a.cc create mode 100644 src/mynteye/device/standard2/channels_adapter_s210a.h create mode 100644 src/mynteye/device/standard2/device_s210a.cc create mode 100644 src/mynteye/device/standard2/device_s210a.h create mode 100644 src/mynteye/device/standard2/streams_adapter_s210a.cc create mode 100644 src/mynteye/device/standard2/streams_adapter_s210a.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 44447ec..1c3859c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,9 @@ set(MYNTEYE_SRCS src/mynteye/device/standard2/channels_adapter_s2.cc src/mynteye/device/standard2/device_s2.cc src/mynteye/device/standard2/streams_adapter_s2.cc + src/mynteye/device/standard2/channels_adapter_s210a.cc + src/mynteye/device/standard2/device_s210a.cc + src/mynteye/device/standard2/streams_adapter_s210a.cc src/mynteye/device/streams.cc src/mynteye/device/types.cc src/mynteye/device/utils.cc diff --git a/include/mynteye/types.h b/include/mynteye/types.h index 3c8b2f9..9ce8a44 100644 --- a/include/mynteye/types.h +++ b/include/mynteye/types.h @@ -37,8 +37,10 @@ MYNTEYE_BEGIN_NAMESPACE enum class Model : std::uint8_t { /** Standard */ STANDARD, - /** Standard 2 generation */ + /** Standard 2 */ STANDARD2, + /** Standard 210a */ + STANDARD210A, /** Last guard */ LAST }; @@ -313,6 +315,8 @@ enum class Format : std::uint32_t { YUYV = MYNTEYE_FOURCC('Y', 'U', 'Y', 'V'), /** BGR 8:8:8, 24 bits per pixel */ BGR888 = MYNTEYE_FOURCC('B', 'G', 'R', '3'), + /** RGB 8:8:8, 24 bits per pixel */ + RGB888 = MYNTEYE_FOURCC('R', 'G', 'B', '3'), /** Last guard */ LAST }; diff --git a/samples/tutorials/control/auto_exposure.cc b/samples/tutorials/control/auto_exposure.cc index ba5ae65..cabe6ad 100644 --- a/samples/tutorials/control/auto_exposure.cc +++ b/samples/tutorials/control/auto_exposure.cc @@ -58,8 +58,8 @@ int main(int argc, char *argv[]) { << api->GetOptionValue(Option::DESIRED_BRIGHTNESS); } - // Set auto exposure options fo s210a or s2000 - if (model == Model::STANDARD2) { + // Set auto exposure options fo S2000/S2100/S210A + if (model == Model::STANDARD2 || model == Model::STANDARD210A) { // auto-exposure: 0 api->SetOptionValue(Option::EXPOSURE_MODE, 0); diff --git a/samples/tutorials/control/framerate.cc b/samples/tutorials/control/framerate.cc index 425647b..d1226f5 100644 --- a/samples/tutorials/control/framerate.cc +++ b/samples/tutorials/control/framerate.cc @@ -49,8 +49,8 @@ int main(int argc, char *argv[]) { << api->GetOptionValue(Option::IMU_FREQUENCY); } - // You should set frame rate for S210A by 'SelectStreamRequest()' - if (model == Model::STANDARD2) { + // You should set frame rate for S2000/S2100/S210A by 'SelectStreamRequest()' + if (model == Model::STANDARD2 || model == Model::STANDARD210A) { LOG(INFO) << "Please set frame rate by 'SelectStreamRequest()'"; } diff --git a/samples/tutorials/control/imu_low_pass_filter.cc b/samples/tutorials/control/imu_low_pass_filter.cc index 001c91d..88e71b8 100644 --- a/samples/tutorials/control/imu_low_pass_filter.cc +++ b/samples/tutorials/control/imu_low_pass_filter.cc @@ -38,8 +38,8 @@ int main(int argc, char *argv[]) { return 0; } - // Set imu low pass filter for s210a - if (model == Model::STANDARD2) { + // Set imu low pass filter for S2000/S2100/S210A + if (model == Model::STANDARD2 || model == Model::STANDARD210A) { // ACCELEROMETER_RANGE values: 0, 1, 2 api->SetOptionValue(Option::ACCELEROMETER_LOW_PASS_FILTER, 2); // GYROSCOPE_RANGE values: 23, 64 diff --git a/samples/tutorials/control/imu_range.cc b/samples/tutorials/control/imu_range.cc index e23f364..1431b20 100644 --- a/samples/tutorials/control/imu_range.cc +++ b/samples/tutorials/control/imu_range.cc @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) { Model model = api->GetModel(); - // Set imu range for s1030 + // Set imu range for S1030 if (model == Model::STANDARD) { // ACCELEROMETER_RANGE values: 4, 8, 16, 32 api->SetOptionValue(Option::ACCELEROMETER_RANGE, 8); @@ -40,8 +40,8 @@ int main(int argc, char *argv[]) { api->SetOptionValue(Option::GYROSCOPE_RANGE, 1000); } - // Set imu range for s210a - if (model == Model::STANDARD2) { + // Set imu range for S2000/S2100/S210A + if (model == Model::STANDARD2 || model == Model::STANDARD210A) { // ACCELEROMETER_RANGE values: 6, 12, 24, 32 api->SetOptionValue(Option::ACCELEROMETER_RANGE, 6); // GYROSCOPE_RANGE values: 250, 500, 1000, 2000, 4000 diff --git a/samples/tutorials/control/infrared.cc b/samples/tutorials/control/infrared.cc index d04cadd..c261e7a 100644 --- a/samples/tutorials/control/infrared.cc +++ b/samples/tutorials/control/infrared.cc @@ -29,8 +29,7 @@ int main(int argc, char *argv[]) { Model model = api->GetModel(); - // Set ir low pass filter for s210a - if (model == Model::STANDARD) { + if (model == Model::STANDARD || model == Model::STANDARD2) { // ir control: range [0,160], default 0 api->SetOptionValue(Option::IR_CONTROL, 80); @@ -39,7 +38,7 @@ int main(int argc, char *argv[]) { } // MYNTEYE-S210A don't support this option - if (model == Model::STANDARD2) { + if (model == Model::STANDARD210A) { LOG(INFO) << "Sorry,MYNTEYE-S210A don't support ir control"; return 0; } diff --git a/samples/tutorials/control/manual_exposure.cc b/samples/tutorials/control/manual_exposure.cc index 51f1a44..2761f58 100644 --- a/samples/tutorials/control/manual_exposure.cc +++ b/samples/tutorials/control/manual_exposure.cc @@ -54,8 +54,8 @@ int main(int argc, char *argv[]) { LOG(INFO) << "Set CONTRAST to " << api->GetOptionValue(Option::CONTRAST); } - // Set manual exposure options fo s210a or s2000 - if (model == Model::STANDARD2) { + // Set manual exposure options fo S2000/S2100/S210A + if (model == Model::STANDARD2 || model == Model::STANDARD210A) { // manual-exposure: 1 api->SetOptionValue(Option::EXPOSURE_MODE, 1); diff --git a/src/mynteye/device/config.cc b/src/mynteye/device/config.cc index 39a587f..a9d89ba 100644 --- a/src/mynteye/device/config.cc +++ b/src/mynteye/device/config.cc @@ -17,12 +17,14 @@ MYNTEYE_BEGIN_NAMESPACE const std::map stream_supports_map = { {Model::STANDARD, {Stream::LEFT, Stream::RIGHT}}, - {Model::STANDARD2, {Stream::LEFT, Stream::RIGHT}} + {Model::STANDARD2, {Stream::LEFT, Stream::RIGHT}}, + {Model::STANDARD210A, {Stream::LEFT, Stream::RIGHT}} }; const std::map capabilities_supports_map = { {Model::STANDARD, {Capabilities::STEREO, Capabilities::IMU}}, - {Model::STANDARD2, {Capabilities::STEREO_COLOR, Capabilities::IMU}} + {Model::STANDARD2, {Capabilities::STEREO_COLOR, Capabilities::IMU}}, + {Model::STANDARD210A, {Capabilities::STEREO_COLOR, Capabilities::IMU}} }; const std::map option_supports_map = { @@ -38,6 +40,14 @@ const std::map option_supports_map = { Option::ERASE_CHIP} }, {Model::STANDARD2, { + Option::BRIGHTNESS, + Option::EXPOSURE_MODE, Option::MAX_GAIN, Option::MAX_EXPOSURE_TIME, + Option::IR_CONTROL, Option::MIN_EXPOSURE_TIME, + Option::DESIRED_BRIGHTNESS, Option::ACCELEROMETER_RANGE, + Option::GYROSCOPE_RANGE, Option::ACCELEROMETER_LOW_PASS_FILTER, + Option::GYROSCOPE_LOW_PASS_FILTER, Option::ERASE_CHIP} + }, + {Model::STANDARD210A, { Option::BRIGHTNESS, Option::EXPOSURE_MODE, Option::MAX_GAIN, Option::MAX_EXPOSURE_TIME, Option::MIN_EXPOSURE_TIME, Option::DESIRED_BRIGHTNESS, @@ -55,6 +65,17 @@ stream_requests_map = { }} }, {Model::STANDARD2, + {{Capabilities::STEREO_COLOR, { + {1280, 400, Format::YUYV, 10}, + {1280, 400, Format::YUYV, 20}, + {1280, 400, Format::YUYV, 30}, + {1280, 400, Format::YUYV, 60}, + {2560, 800, Format::YUYV, 10}, + {2560, 800, Format::YUYV, 20}, + {2560, 800, Format::YUYV, 30}} + }} + }, + {Model::STANDARD210A, {{Capabilities::STEREO_COLOR, { {1280, 400, Format::BGR888, 10}, {1280, 400, Format::BGR888, 20}, diff --git a/src/mynteye/device/device.cc b/src/mynteye/device/device.cc index 484a52f..e57dd48 100644 --- a/src/mynteye/device/device.cc +++ b/src/mynteye/device/device.cc @@ -26,6 +26,7 @@ #include "mynteye/device/motions.h" #include "mynteye/device/standard/device_s.h" #include "mynteye/device/standard2/device_s2.h" +#include "mynteye/device/standard2/device_s210a.h" #include "mynteye/device/streams.h" #include "mynteye/device/types.h" #include "mynteye/util/strings.h" @@ -108,13 +109,18 @@ std::shared_ptr Device::Create( VLOG(2) << "MYNE EYE Model: " << model_s; DeviceModel model(model_s); if (model.type == 'S') { - switch (model.generation) { - case '1': - return std::make_shared(device); - case '2': + if (model.generation == '1') { + return std::make_shared(device); + } else if (model.generation == '2') { + if (model.custom_code == '0') { return std::make_shared(device); - default: - LOG(FATAL) << "No such generation now"; + } else if (model.custom_code == 'A') { + return std::make_shared(device); + } else { + LOG(FATAL) << "No such custom code now"; + } + } else { + LOG(FATAL) << "No such generation now"; } } else { LOG(FATAL) << "MYNT EYE model is not supported now"; diff --git a/src/mynteye/device/standard2/channels_adapter_s210a.cc b/src/mynteye/device/standard2/channels_adapter_s210a.cc new file mode 100644 index 0000000..22f5a69 --- /dev/null +++ b/src/mynteye/device/standard2/channels_adapter_s210a.cc @@ -0,0 +1,173 @@ +// Copyright 2018 Slightech Co., Ltd. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "mynteye/device/standard2/channels_adapter_s210a.h" + +#include "mynteye/device/config.h" +#include "mynteye/logger.h" + +MYNTEYE_BEGIN_NAMESPACE + +namespace { + +#pragma pack(push, 1) +struct ImuData { + std::uint32_t frame_id; + std::uint64_t timestamp; + std::uint8_t flag; + std::int16_t temperature; + std::int16_t accel_or_gyro[3]; + + ImuData() = default; + explicit ImuData(const std::uint8_t *data) { + from_data(data); + } + + void from_data(const std::uint8_t *data) { + std::uint32_t timestamp_l; + std::uint32_t timestamp_h; + + frame_id = (*(data) << 24) | (*(data + 1) << 16) | (*(data + 2) << 8) | + *(data + 3); + timestamp_h = (*(data + 4) << 24) | (*(data + 5) << 16) | + (*(data + 6) << 8) | *(data + 7); + timestamp_l = (*(data + 8) << 24) | (*(data + 9) << 16) | + (*(data + 10) << 8) | *(data + 11); + timestamp = (static_cast(timestamp_h) << 32) | timestamp_l; + flag = *(data + 12); + temperature = (*(data + 13) << 8) | *(data + 14); + accel_or_gyro[0] = (*(data + 15) << 8) | *(data + 16); + accel_or_gyro[1] = (*(data + 17) << 8) | *(data + 18); + accel_or_gyro[2] = (*(data + 19) << 8) | *(data + 20); + } +}; +#pragma pack(pop) + +void unpack_imu_segment(const ImuData &imu, ImuSegment *seg) { + seg->frame_id = imu.frame_id; + seg->timestamp = imu.timestamp; + seg->flag = imu.flag; + seg->temperature = imu.temperature; + seg->accel[0] = (seg->flag == 1) ? imu.accel_or_gyro[0] : 0; + seg->accel[1] = (seg->flag == 1) ? imu.accel_or_gyro[1] : 0; + seg->accel[2] = (seg->flag == 1) ? imu.accel_or_gyro[2] : 0; + seg->gyro[0] = (seg->flag == 2) ? imu.accel_or_gyro[0] : 0; + seg->gyro[1] = (seg->flag == 2) ? imu.accel_or_gyro[1] : 0; + seg->gyro[2] = (seg->flag == 2) ? imu.accel_or_gyro[2] : 0; +} + +void unpack_imu_packet(const std::uint8_t *data, ImuPacket *pkg) { + std::size_t data_n = sizeof(ImuData); // 21 + for (std::size_t i = 0; i < pkg->count; i++) { + ImuSegment seg; + unpack_imu_segment(ImuData(data + data_n * i), &seg); + pkg->segments.push_back(seg); + } + pkg->serial_number = pkg->segments.back().frame_id; +} + +void unpack_imu_res_packet(const std::uint8_t *data, ImuResPacket *res) { + res->header = *data; + res->state = *(data + 1); + res->size = (*(data + 2) << 8) | *(data + 3); + + std::size_t data_n = sizeof(ImuData); // 21 + ImuPacket packet; + packet.count = res->size / data_n; + unpack_imu_packet(data + 4, &packet); + res->packets.push_back(packet); + res->checksum = *(data + 4 + res->size); +} + +} // namespace + +Standard210aChannelsAdapter::Standard210aChannelsAdapter() { +} + +Standard210aChannelsAdapter::~Standard210aChannelsAdapter() { +} + +std::set