zr300.h
Go to the documentation of this file.
00001 // License: Apache 2.0. See LICENSE file in root directory.
00002 // Copyright(c) 2016 Intel Corporation. All Rights Reserved.
00003 
00004 #pragma once
00005 #ifndef LIBREALSENSE_ZR300_H
00006 #define LIBREALSENSE_ZR300_H
00007 
00008 #include "motion-module.h"
00009 #include "ds-device.h"
00010 #include "sync.h"
00011 
00012 #include <deque>
00013 #include <cmath>
00014 #include <math.h>
00015 
00016 namespace rsimpl
00017 {
00018   
00019     struct IMU_version
00020     {
00021         byte ver[4];
00022         byte size;
00023         byte CRC32[4];
00024     };
00025 #pragma pack(push, 1)
00026     struct serial_number
00027     {
00028         IMU_version ver;
00029         byte MM_s_n[6];
00030         byte DS4_s_n[6];
00031         byte reserved[235];
00032     };
00033 
00034     struct fisheye_intrinsic 
00035     {
00036         IMU_version ver;
00037         float kf[9];
00038         float distf[5];
00039         byte reserved[191];
00040         
00041         int get_data_size() const
00042         {
00043             return sizeof(kf) + sizeof(distf);
00044         };
00045 
00046         bool has_data() const
00047         {
00048             return check_not_all_zeros({(byte*)&kf, ((byte*)&kf) + get_data_size()});
00049         }
00050 
00051         operator rs_intrinsics () const
00052         {
00053             return{ 640, 480, kf[2], kf[5], kf[0], kf[4], RS_DISTORTION_FTHETA, { distf[0], 0, 0, 0, 0 } };
00054         }
00055     };
00056 
00057 
00058     struct mm_extrinsic
00059     {
00060         float rotation[9];
00061         float translation[3];
00062 
00063         operator rs_extrinsics () const {
00064             return{ {   rotation[0], rotation[1], rotation[2],
00065                         rotation[3], rotation[4], rotation[5],
00066                         rotation[6], rotation[7], rotation[8] },
00067                       { translation[0], translation[1], translation[2] } };
00068         }
00069 
00070         int get_data_size() const
00071         {
00072             return sizeof(rotation) + sizeof(translation);
00073         }
00074 
00075         bool has_data() const
00076         {
00077             return check_not_all_zeros({ (byte*)&rotation, ((byte*)&rotation) + get_data_size() });
00078         }
00079     };
00080     struct IMU_extrinsic
00081     {
00082         IMU_version ver;
00083         mm_extrinsic  fe_to_imu;
00084         mm_extrinsic  fe_to_depth;
00085         mm_extrinsic  rgb_to_imu;
00086         mm_extrinsic  depth_to_imu;
00087         byte reserved[55];
00088 
00089         int get_data_size() const
00090         {
00091             return sizeof(fe_to_imu) + sizeof(fe_to_depth) + sizeof(rgb_to_imu) + sizeof(depth_to_imu);
00092         };
00093     };
00094 
00095     struct MM_intrinsics
00096     {
00097         //  Scale X        cross axis        cross axis      Bias X
00098         //  cross axis     Scale Y           cross axis      Bias Y
00099         //  cross axis     cross axis        Scale Z         Bias Z
00100 
00101         float val[3][4];
00102     };
00103 
00104   
00105     struct IMU_intrinsic
00106     {
00107         IMU_version ver;
00108         MM_intrinsics acc_intrinsic;
00109         MM_intrinsics gyro_intrinsic;
00110         float acc_bias_variance[3];
00111         float acc_noise_variance[3];
00112         float gyro_bias_variance[3];
00113         float gyro_noise_variance[3];
00114         byte reserved[103];
00115 
00116         int get_data_size() const
00117         {
00118             return sizeof(acc_intrinsic) + sizeof(gyro_intrinsic) + 
00119                 sizeof(acc_bias_variance) + sizeof(acc_noise_variance) + sizeof(gyro_bias_variance) + sizeof(gyro_noise_variance);
00120         };
00121 
00122         bool has_data() const
00123         {
00124             return check_not_all_zeros({(byte*)&acc_intrinsic, ((byte*)&acc_intrinsic) + get_data_size()});
00125         }
00126        
00127         rs_motion_device_intrinsic convert(const MM_intrinsics& intrin, const float bias_variance[3], const float noises_variance[3]) const
00128         {
00129             rs_motion_device_intrinsic res;
00130 
00131             for (auto i = 0; i < 3; i++)
00132             {
00133                 for (auto j = 0; j < 4; j++)
00134                 {
00135                     res.data[i][j] = intrin.val[i][j];
00136                 }
00137             }
00138 
00139             for (auto i = 0; i < 3; i++)
00140             {
00141                 res.noise_variances[i] = noises_variance[i];
00142                 res.bias_variances[i] = bias_variance[i];
00143             }
00144             return res;
00145         }
00146         rs_motion_device_intrinsic get_acc_intrinsic() const
00147         {
00148             return convert(acc_intrinsic, acc_bias_variance, acc_noise_variance);
00149         }
00150 
00151         rs_motion_device_intrinsic get_gyro_intrinsic() const
00152         {
00153             return convert(gyro_intrinsic, gyro_bias_variance, gyro_noise_variance);
00154         }
00155        
00156         operator rs_motion_intrinsics() const{
00157 
00158             return{ get_acc_intrinsic(), get_gyro_intrinsic() };
00159         }
00160     };
00161 
00162     struct calibration
00163     {
00164         fisheye_intrinsic fe_intrinsic;
00165         IMU_extrinsic mm_extrinsic;
00166         IMU_intrinsic imu_intrinsic;
00167     };
00168     struct motion_module_calibration
00169     {
00170         serial_number sn;
00171         calibration calib;
00172     };
00173 #pragma pack(pop)
00174 
00175     
00176    
00177     enum class auto_exposure_modes {
00178         static_auto_exposure = 0,
00179         auto_exposure_anti_flicker,
00180         auto_exposure_hybrid
00181     };
00182 
00183     class fisheye_auto_exposure_state
00184     {
00185     public:
00186         fisheye_auto_exposure_state() :
00187             is_auto_exposure(true),
00188             mode(auto_exposure_modes::auto_exposure_hybrid),
00189             rate(60),
00190             sample_rate(1),
00191             skip_frames(2)
00192         {}
00193 
00194         unsigned get_auto_exposure_state(rs_option option) const;
00195         void set_auto_exposure_state(rs_option option, double value);
00196 
00197     private:
00198         bool                is_auto_exposure;
00199         auto_exposure_modes mode;
00200         unsigned            rate;
00201         unsigned            sample_rate;
00202         unsigned            skip_frames;
00203     };
00204 
00205     class zr300_camera;
00206     class auto_exposure_algorithm {
00207     public:
00208         void modify_exposure(float& exposure_value, bool& exp_modified, float& gain_value, bool& gain_modified); // exposure_value in milliseconds
00209         bool analyze_image(const rs_frame_ref* image);
00210         auto_exposure_algorithm(fisheye_auto_exposure_state auto_exposure_state);
00211         void update_options(const fisheye_auto_exposure_state& options);
00212 
00213     private:
00214         struct histogram_metric { int under_exposure_count; int over_exposure_count; int shadow_limit; int highlight_limit; int lower_q; int upper_q; float main_mean; float main_std; };
00215         enum class rounding_mode_type { round, ceil, floor };
00216 
00217         inline void im_hist(const uint8_t* data, const int width, const int height, const int rowStep, int h[]);
00218         void increase_exposure_target(float mult, float& target_exposure);
00219         void decrease_exposure_target(float mult, float& target_exposure);
00220         void increase_exposure_gain(const float& target_exposure, const float& target_exposure0, float& exposure, float& gain);
00221         void decrease_exposure_gain(const float& target_exposure, const float& target_exposure0, float& exposure, float& gain);
00222         void static_increase_exposure_gain(const float& target_exposure, const float& target_exposure0, float& exposure, float& gain);
00223         void static_decrease_exposure_gain(const float& target_exposure, const float& target_exposure0, float& exposure, float& gain);
00224         void anti_flicker_increase_exposure_gain(const float& target_exposure, const float& target_exposure0, float& exposure, float& gain);
00225         void anti_flicker_decrease_exposure_gain(const float& target_exposure, const float& target_exposure0, float& exposure, float& gain);
00226         void hybrid_increase_exposure_gain(const float& target_exposure, const float& target_exposure0, float& exposure, float& gain);
00227         void hybrid_decrease_exposure_gain(const float& target_exposure, const float& target_exposure0, float& exposure, float& gain);
00228 
00229 #if defined(_WINDOWS) || defined(WIN32) || defined(WIN64)
00230         inline float round(float x) { return std::round(x); }
00231 #else
00232         inline float round(float x) { return x < 0.0 ? std::ceil(x - 0.5f) : std::floor(x + 0.5f); }
00233 #endif
00234 
00235         float exposure_to_value(float exp_ms, rounding_mode_type rounding_mode);
00236         float gain_to_value(float gain, rounding_mode_type rounding_mode);
00237         template <typename T> inline T sqr(const T& x) { return (x*x); }
00238         void histogram_score(std::vector<int>& h, const int total_weight, histogram_metric& score);
00239 
00240 
00241         float minimal_exposure = 0.1f, maximal_exposure = 20.f, base_gain = 2.0f, gain_limit = 15.0f;
00242         float exposure = 10.0f, gain = 2.0f, target_exposure = 0.0f;
00243         uint8_t under_exposure_limit = 5, over_exposure_limit = 250; int under_exposure_noise_limit = 50, over_exposure_noise_limit = 50;
00244         int direction = 0, prev_direction = 0; float hysteresis = 0.075f;// 05;
00245         float eps = 0.01f, exposure_step = 0.1f, minimal_exposure_step = 0.01f;
00246         fisheye_auto_exposure_state state; float flicker_cycle; bool anti_flicker_mode = true;
00247         std::recursive_mutex state_mutex;
00248     };
00249 
00250     class auto_exposure_mechanism {
00251     public:
00252         auto_exposure_mechanism(zr300_camera* dev, fisheye_auto_exposure_state auto_exposure_state);
00253         ~auto_exposure_mechanism();
00254         void add_frame(rs_frame_ref* frame, std::shared_ptr<rsimpl::frame_archive> archive);
00255         void update_auto_exposure_state(fisheye_auto_exposure_state& auto_exposure_state);
00256         struct exposure_and_frame_counter {
00257             exposure_and_frame_counter() : exposure(0), frame_counter(0) {};
00258             exposure_and_frame_counter(double exposure, unsigned long long frame_counter) : exposure(exposure), frame_counter(frame_counter){}
00259             double exposure;
00260             unsigned long long frame_counter;
00261         };
00262 
00263     private:
00264         void push_back_data(rs_frame_ref* data);
00265         bool try_pop_front_data(rs_frame_ref** data);
00266         size_t get_queue_size();
00267         void clear_queue();
00268         unsigned get_skip_frames(const fisheye_auto_exposure_state& auto_exposure_state) { return auto_exposure_state.get_auto_exposure_state(RS_OPTION_FISHEYE_AUTO_EXPOSURE_SKIP_FRAMES); }
00269         void push_back_exp_and_cnt(exposure_and_frame_counter exp_and_cnt);
00270         bool try_get_exp_by_frame_cnt(double& exposure, const unsigned long long frame_counter);
00271 
00272         const std::size_t                      max_size_of_exp_and_cnt_queue = 10;
00273         zr300_camera*                          device;
00274         auto_exposure_algorithm                auto_exposure_algo;
00275         std::shared_ptr<rsimpl::frame_archive> sync_archive;
00276         std::shared_ptr<std::thread>           exposure_thread;
00277         std::condition_variable                cv;
00278         std::atomic<bool>                      keep_alive;
00279         std::deque<rs_frame_ref*>              data_queue;
00280         std::mutex                             queue_mtx;
00281         std::atomic<unsigned>                  frames_counter;
00282         std::atomic<unsigned>                  skip_frames;
00283         std::deque<exposure_and_frame_counter> exposure_and_frame_counter_queue;
00284         std::mutex                             exp_and_cnt_queue_mtx;
00285     };
00286 
00287     class zr300_camera final : public ds::ds_device
00288     {
00289         motion_module::motion_module_control     motion_module_ctrl;
00290         motion_module::mm_config                 motion_module_configuration;
00291         fisheye_auto_exposure_state              auto_exposure_state;
00292         std::shared_ptr<auto_exposure_mechanism> auto_exposure;
00293         std::atomic<bool>                        to_add_frames;
00294 
00295     protected:
00296         void toggle_motion_module_power(bool bOn);
00297         void toggle_motion_module_events(bool bOn);
00298         void on_before_callback(rs_stream , rs_frame_ref *, std::shared_ptr<rsimpl::frame_archive>) override;
00299 
00300         std::timed_mutex usbMutex;
00301 
00302     public:
00303         zr300_camera(std::shared_ptr<uvc::device> device, const static_device_info & info, motion_module_calibration fe_intrinsic, calibration_validator validator);
00304         ~zr300_camera();
00305 
00306         void get_option_range(rs_option option, double & min, double & max, double & step, double & def) override;
00307         void set_options(const rs_option options[], size_t count, const double values[]) override;
00308         void get_options(const rs_option options[], size_t count, double values[]) override;
00309         void send_blob_to_device(rs_blob_type type, void * data, int size) override;
00310         bool supports_option(rs_option option) const override;
00311 
00312         void start_motion_tracking() override;
00313         void stop_motion_tracking() override;
00314 
00315         void start(rs_source source) override;
00316         void stop(rs_source source) override;
00317 
00318         rs_stream select_key_stream(const std::vector<rsimpl::subdevice_mode_selection> & selected_modes) override;
00319 
00320         rs_motion_intrinsics get_motion_intrinsics() const override;
00321         rs_extrinsics get_motion_extrinsics_from(rs_stream from) const override;
00322         unsigned long long get_frame_counter_by_usb_cmd();
00323 
00324        
00325     private:
00326         unsigned get_auto_exposure_state(rs_option option);
00327         void set_auto_exposure_state(rs_option option, double value);
00328         void set_fw_logger_option(double value);
00329         unsigned get_fw_logger_option();
00330 
00331         bool validate_motion_extrinsics(rs_stream) const;
00332         bool validate_motion_intrinsics() const;
00333 
00334         motion_module_calibration fe_intrinsic;
00335     };
00336     motion_module_calibration read_fisheye_intrinsic(uvc::device & device);
00337     std::shared_ptr<rs_device> make_zr300_device(std::shared_ptr<uvc::device> device);
00338 }
00339 
00340 #endif


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Tue Jun 25 2019 19:54:40