From 77877ae28e31a98be87678adf058df207979732a Mon Sep 17 00:00:00 2001 From: tangchao Date: Fri, 14 Jan 2022 14:26:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86calibration=20first?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + othersoft/calibration_console/CMakeLists.txt | 39 ++ .../Header_Files/ATPControl_Serial_QT.h | 87 +++ .../FiberSpectrometerOperationBase.h | 53 ++ .../Header_Files/IrisFiberSpectrometerBase.h | 42 ++ .../Header_Files/ZZ_Math.h | 121 ++++ .../Header_Files/ZZ_Types.h | 350 ++++++++++ .../Header_Files/atpFiberImager.h | 51 ++ .../Header_Files/calibration.h | 50 ++ .../Header_Files/library.h | 69 ++ .../Header_Files/oceanOpticsFiberImager.h | 50 ++ .../Source_Files/ATPControl_Serial_QT.cpp | 602 ++++++++++++++++++ .../Source_Files/ZZ_Math.cpp | 113 ++++ .../Source_Files/atpFiberImager.cpp | 186 ++++++ .../Source_Files/calibration.cpp | 232 +++++++ .../Source_Files/library.cpp | 564 ++++++++++++++++ .../calibration_console/Source_Files/main.cpp | 444 +++++++++++++ .../Source_Files/oceanOpticsFiberImager.cpp | 244 +++++++ 18 files changed, 3299 insertions(+) create mode 100644 othersoft/calibration_console/CMakeLists.txt create mode 100644 othersoft/calibration_console/Header_Files/ATPControl_Serial_QT.h create mode 100644 othersoft/calibration_console/Header_Files/FiberSpectrometerOperationBase.h create mode 100644 othersoft/calibration_console/Header_Files/IrisFiberSpectrometerBase.h create mode 100644 othersoft/calibration_console/Header_Files/ZZ_Math.h create mode 100644 othersoft/calibration_console/Header_Files/ZZ_Types.h create mode 100644 othersoft/calibration_console/Header_Files/atpFiberImager.h create mode 100644 othersoft/calibration_console/Header_Files/calibration.h create mode 100644 othersoft/calibration_console/Header_Files/library.h create mode 100644 othersoft/calibration_console/Header_Files/oceanOpticsFiberImager.h create mode 100644 othersoft/calibration_console/Source_Files/ATPControl_Serial_QT.cpp create mode 100644 othersoft/calibration_console/Source_Files/ZZ_Math.cpp create mode 100644 othersoft/calibration_console/Source_Files/atpFiberImager.cpp create mode 100644 othersoft/calibration_console/Source_Files/calibration.cpp create mode 100644 othersoft/calibration_console/Source_Files/library.cpp create mode 100644 othersoft/calibration_console/Source_Files/main.cpp create mode 100644 othersoft/calibration_console/Source_Files/oceanOpticsFiberImager.cpp diff --git a/.gitignore b/.gitignore index c303efb..41b2f3d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ /othersoft/shuttercali/project/LocationCali/build/ /Data/2022_01_11 /othersoft/movingliner/build +/othersoft/calibration_console/.idea/ +/othersoft/calibration_console/build/ diff --git a/othersoft/calibration_console/CMakeLists.txt b/othersoft/calibration_console/CMakeLists.txt new file mode 100644 index 0000000..51f1981 --- /dev/null +++ b/othersoft/calibration_console/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.5) +project(ocean_optics_calibration_console)#ocean_optics_calibration_console + +set(CMAKE_CXX_STANDARD 14) + +SET(CMAKE_INSTALL_PREFIX < /home/pi/bin >) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD 11) + +#set(CMAKE_PREFIX_PATH "/home/iris-xport/Qt5.9.0/5.9/gcc_64/")#tc_add: https://blog.csdn.net/aiyun5666/article/details/101915628 +set(QT Core Network SerialPort) +set(TEMPLATE app) +set(TARGET ximeaImageRecorder) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +find_package(Qt5 REQUIRED ${QT}) + +#include_directories(/home/iris-xport/projects/ocean/seabreeze-3.0.11/SeaBreeze/include/) +#LINK_DIRECTORIES(/home/iris-xport/projects/ocean/seabreeze-3.0.11/SeaBreeze/lib/) +include_directories(/home/pi/SeaBrease/include/) +LINK_DIRECTORIES(/home/pi/SeaBrease/lib/) + +include_directories(.)#包含头文件 +include_directories(/usr/include/eigen3)#包含头文件,安装eigen:sudo apt-get install libeigen3-dev + + +file(GLOB_RECURSE SRC_h ./Header_Files/*.h) +file(GLOB_RECURSE SRC_CPP ./Source_Files/*.cpp) + +add_executable(${CMAKE_PROJECT_NAME} ${SRC_h} ${SRC_CPP}) + + +qt5_use_modules(${CMAKE_PROJECT_NAME} ${QT}) + +TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} + seabreeze + usb + ) diff --git a/othersoft/calibration_console/Header_Files/ATPControl_Serial_QT.h b/othersoft/calibration_console/Header_Files/ATPControl_Serial_QT.h new file mode 100644 index 0000000..d01d8d1 --- /dev/null +++ b/othersoft/calibration_console/Header_Files/ATPControl_Serial_QT.h @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////// +//ATP??????????? +////////////////////////////////////////////////////////////////////////// +#pragma once +//#include "pch.h" +#include "ZZ_Types.h" +#include "ZZ_Math.h" +#include +#include "IrisFiberSpectrometerBase.h" + +using namespace ZZ_MISCDEF; +using namespace ZZ_MISCDEF::ATP; +using namespace ZZ_MISCDEF::IRIS::FS; + +class ZZ_ATPControl_Serial_Qt:public CIrisFSBase +{ + //Q_OBJECT +public: + ZZ_ATPControl_Serial_Qt(); + virtual ~ZZ_ATPControl_Serial_Qt(); + +public: + //???????? + //int SetBaudRate(int iBaud); + //???????? + int Initialize(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName); + int Initialize(bool bIsUSBMode,ZZ_U8 ucPortNumber,std::string strDeviceName); + //????? + void Close(); + + //???????????? ??????????????? + int SingleShot(int &iPixels); + + //???????????? + int SingleShot(DataFrame &dfData); + + //??????????? + //int SingleShotDark(ATPDataFrame &dfData); + + //int SingleShotDeducted(ATPDataFrame &dfData); + //?????????? + int SetExposureTime(int iExposureTimeInMS); + + //?????????????? + int GetExposureTime(int &iExposureTimeInMS); + + //int GetWaveLength(float *pfWaveLength); + + //?????????? + int GetDeviceInfo(DeviceInfo &Info); + + //????????????? + int GetDeviceAttribute(DeviceAttribute &Attr); + + //int GetDeviceListInfo(); //use type name to enum + + //??????? + int SetDeviceTemperature(float fTemperature); + + //???????? + int GetDeviceTemperature(float &fTemperature); + + //??????? + int PerformAutoExposure(float fMinScaleFactor, float fMaxScaleFactor, float &fPredictedExposureTime); + +#ifdef _DEBUG + public: +#else // +private: +#endif + //port + int m_iBaudRate; + QSerialPort *m_pSerialPort; + + //ATP + DeviceInfo m_diDeviceInfo; + DeviceAttribute m_daDeviceAttr; + + //////////////////////////////////////////////////////////////////////////shutter control stub code s + //int SetExtShutter(int iShutterUP0, int iShutterDOWN1,int iShutterDOWN2,int iShutterDOWN3); //0:close 1:open + //////////////////////////////////////////////////////////////////////////shutter control stub code e + int SendCommand(QByteArray qbCommand); + int RecvData(QByteArray &qbData); + int ParseData(QByteArray &qbData); +//private slots : + //void ReadMessage(); +}; \ No newline at end of file diff --git a/othersoft/calibration_console/Header_Files/FiberSpectrometerOperationBase.h b/othersoft/calibration_console/Header_Files/FiberSpectrometerOperationBase.h new file mode 100644 index 0000000..1ad2686 --- /dev/null +++ b/othersoft/calibration_console/Header_Files/FiberSpectrometerOperationBase.h @@ -0,0 +1,53 @@ +// +// Created by tangchao on 2022/1/11. +// + +#ifndef OCEAN_OPTICS_CALIBRATION_CONSOLE_FIBERSPECTROMETEROPERATIONBASE_H +#define OCEAN_OPTICS_CALIBRATION_CONSOLE_FIBERSPECTROMETEROPERATIONBASE_H + + +#include "ZZ_Types.h" + +using namespace ZZ_MISCDEF; +using namespace ZZ_MISCDEF::IRIS::FS; + +class FiberSpectrometerOperationBase +{ + +public: +// FiberSpectrometerOperationBase(); +// ~FiberSpectrometerOperationBase(); + + virtual void connectFiberSpectrometer(QString& sn, QString& pixelCount, QString& wavelengthInfo) = 0; + virtual void disconnectFiberSpectrometer() = 0; + virtual void getDeviceAttribute(DeviceAttribute& deviceAttribute) = 0; + virtual void getDeviceInfo(DeviceInfo& deviceInfo) = 0; + + virtual void setExposureTime(int iExposureTimeInMS) = 0; + + virtual void getExposureTime(int &iExposureTimeInMS) = 0; + virtual void getDeviceTemperature(float &fTemperature) = 0; + + virtual void singleShot(DataFrame &dfData) = 0; + +// ZZ_S32 GetMaxValue(ZZ_S32 * dark, int number) = 0; + + DataFrame m_IntegratingSphereData; + DataFrame m_DarkData; +protected: + ZZ_U32 m_MaxValueOfFiberSpectrometer; +private: + + + +public slots: + virtual void recordDark(QString path) = 0; + virtual void recordTarget(int recordTimes, QString path) = 0; + virtual void autoExpose() = 0; + + signals: + void sendExposureTimeSignal(int exposureTime); + +}; + +#endif //OCEAN_OPTICS_CALIBRATION_CONSOLE_FIBERSPECTROMETEROPERATIONBASE_H diff --git a/othersoft/calibration_console/Header_Files/IrisFiberSpectrometerBase.h b/othersoft/calibration_console/Header_Files/IrisFiberSpectrometerBase.h new file mode 100644 index 0000000..2709c47 --- /dev/null +++ b/othersoft/calibration_console/Header_Files/IrisFiberSpectrometerBase.h @@ -0,0 +1,42 @@ +#include +#include "ZZ_Types.h" +#pragma once +using namespace ZZ_MISCDEF; +using namespace ZZ_MISCDEF::IRIS::FS; + +class CIrisFSBase +{ +public: + //CIrisFSBase(); + //virtual ~CIrisFSBase()= 0; +public: + //ʼ豸 + //˴stringΪָĸoceanǵIJиΪc/c++׼ + //0Ϊ޴󣬲ͬ뷵زֵͬ + virtual int Initialize(bool bIsUSBMode,std::string ucPortNumber,std::string strDeviceName) = 0; + + //ر豸 + virtual void Close() = 0; + + //ݲɼ + virtual int SingleShot(DataFrame &dfData) = 0; + + //عʱ + virtual int SetExposureTime(int iExposureTimeInMS) = 0; + + //ȡعʱ + virtual int GetExposureTime(int &iExposureTimeInMS) = 0; + + //Ŀ¶ + virtual int SetDeviceTemperature(float fTemperature) = 0; + + //ȡ¶ + virtual int GetDeviceTemperature(float &fTemperature) = 0; + + //ȡ豸Ϣ + virtual int GetDeviceInfo(DeviceInfo &Info) = 0; + + //ȡ豸 + virtual int GetDeviceAttribute(DeviceAttribute &Attr) = 0; + +}; diff --git a/othersoft/calibration_console/Header_Files/ZZ_Math.h b/othersoft/calibration_console/Header_Files/ZZ_Math.h new file mode 100644 index 0000000..73e75e8 --- /dev/null +++ b/othersoft/calibration_console/Header_Files/ZZ_Math.h @@ -0,0 +1,121 @@ +#include +#include +#//#include "Dense" +#include "Eigen/Dense" +#include +#pragma once + +namespace ZZ_MATH +{ + template + void MinHeapify(T*arry, int size, int element) + { + int lchild = element * 2 + 1, rchild = lchild + 1; + while (rchild < size) + { + if (arry[element] <= arry[lchild] && arry[element] <= arry[rchild]) + { + return; + } + if (arry[lchild] <= arry[rchild]) + { + std::swap(arry[element], arry[lchild]); + element = lchild; + } + else + { + std::swap(arry[element], arry[rchild]); + element = rchild; + } + lchild = element * 2 + 1; + rchild = lchild + 1; + } + if (lchild < size&&arry[lchild] < arry[element]) + { + std::swap(arry[lchild], arry[element]); + } + return; + } + + template + void MaxHeapify(T*arry, int size, int element) + { + int lchild = element * 2 + 1, rchild = lchild + 1; + while (rchild < size) + { + if (arry[element] >= arry[lchild] && arry[element] >= arry[rchild]) + { + return; + } + if (arry[lchild] >= arry[rchild]) + { + std::swap(arry[element], arry[lchild]); + element = lchild; + } + else + { + std::swap(arry[element], arry[rchild]); + element = rchild; + } + lchild = element * 2 + 1; + rchild = lchild + 1; + } + if (lchildarry[element]) + { + std::swap(arry[lchild], arry[element]); + } + return; + } + + + template + void HeapSort(T*arry, int size) + { + int i; + for (i = size - 1; i >= 0; i--) + { + MinHeapify(arry, size, i); + } + while (size > 0) + { + std::swap(arry[size - 1], arry[0]); + + size--; + MinHeapify(arry, size, 0); + } + return; + } + + namespace PolyFit + { + void Eigen_Polyfit(const std::vector &xv, const std::vector &yv, std::vector &coeff, int order); + double Eigen_Polyeval(std::vector coeffs, double x); + }; + + namespace SplineFit + { + using namespace Eigen; + VectorXd Eigen_Normalize(const VectorXd &x); + void Test(std::vector const &x_vec, std::vector const &y_vec);// do not call + + + class SplineInterpolation + { + public: + SplineInterpolation(Eigen::VectorXd const &x_vec,Eigen::VectorXd const &y_vec); + double operator()(double x) const; + + private: + double x_min; + double x_max; + + double scaled_value(double x) const; + Eigen::RowVectorXd scaled_values(Eigen::VectorXd const &x_vec) const; + + Eigen::Spline spline_; + }; + }; +}; + + + diff --git a/othersoft/calibration_console/Header_Files/ZZ_Types.h b/othersoft/calibration_console/Header_Files/ZZ_Types.h new file mode 100644 index 0000000..779280d --- /dev/null +++ b/othersoft/calibration_console/Header_Files/ZZ_Types.h @@ -0,0 +1,350 @@ +////////////////////////////////////////////////////////////////////////// +//˵ļ +////////////////////////////////////////////////////////////////////////// +#pragma once +#include +#include + +#define MAX_DEVICENUMBER_FS 2 +#define MAX_LINEARSHUTTER_POSITION 12 +#define ZZ_Enum2String(x) #x + +namespace ZZ_MISCDEF +{ + typedef unsigned char ZZ_U8; + typedef unsigned short int ZZ_U16; + typedef unsigned long int ZZ_U32; + typedef long int ZZ_S32; + + + namespace IRIS + { + //Fiber Spectrometer + namespace FS + { + typedef struct tagDataFrame + { + ZZ_U32 usExposureTimeInMS; + ZZ_S32 lData[4096]; + float fTemperature = 0; + double dTimes = 0; + }DataFrame; + + + + typedef struct tagDeviceInfo + { + std::string strPN; + std::string strSN; + }DeviceInfo; + + typedef struct tagDeviceAttribute + { + int iPixels; + int iMaxIntegrationTimeInMS; + int iMinIntegrationTimeInMS; + float fWaveLengthInNM[4096]; + + }DeviceAttribute; + +// inline DataFrame GetIndex(DataFrame dfDark, DataFrame dfSignal) +// { +// +// } + } + + enum DeviceModel + { + OSIFAlpha=0, + OSIFBeta, + ISIF, + IS1, + IS2 + }; + + + + inline std::string GetDeviceModelName(int iModel) + { + switch (iModel) + { + case DeviceModel::OSIFAlpha: return "OSIFAlpha"; break; + case DeviceModel::OSIFBeta: return "OSIFBeta"; break; + case DeviceModel::ISIF: return "ISIF"; break; + case DeviceModel::IS1: return "IS1"; break; + case DeviceModel::IS2: return "IS2"; break; + default: return "error"; break; + } + } + + inline int GetIndex(std::string strDeviceModelName) + { + if (strDeviceModelName == "OSIFAlpha") + { + return DeviceModel::OSIFAlpha; + } + else if (strDeviceModelName == "OSIFBeta") + { + return DeviceModel::OSIFBeta; + } + else if (strDeviceModelName == "ISIF") + { + return DeviceModel::ISIF; + } + else if (strDeviceModelName == "IS1") + { + return DeviceModel::IS1; + } + else if (strDeviceModelName == "IS2") + { + return DeviceModel::IS2; + } + else + { + return -1; + } + } + + }; + + //ATP??????? + namespace ATP + { + const int MAX_SPECTRUM_SIZE = 4096; + + const int GET_MODULECIRCUIT_TEMP = 0x01; + const int GET_PN_NUMBER = 0x03; + const int GET_SN_NUMBER = 0x04; + const int GET_MANUFACTURE_DATA = 0x06; + const int GET_MANUFACTURE_INFO = 0x09; + const int GET_PIXEL_LENGTH = 0x0a; + const int GET_TEC_TEMP = 0x13; + const int SET_TEC_TEMP = 0x12; + const int GET_OPTICS_TEMP = 0x35; + const int GET_CIRCUITBOARD_TEMP = 0x36; + const int SET_INTEGRATION_TIME = 0x14; + const int GET_INTEGRATION_TIME = 0x41; + const int GET_MAX_INTEGRATION_TIME = 0x42; + const int GET_MIN_INTEGRATION_TIME = 0x43; + const int ASYNC_COLLECT_DARK = 0x23; + const int ASYNC_START_COLLECTION = 0x16; + const int ASYNC_READ_DATA = 0x17; + const int SET_AVERAGE_NUMBER = 0x28; + const int SYNC_GET_DATA = 0x1e; + const int SYNC_GET_DARK = 0x2f; + const int EXTERNAL_TRIGGER_ENABLE = 0x1f; + const int SET_XENON_LAMP_DELAY_TIME = 0x24; + const int GET_WAVELENGTH_CALIBRATION_COEF = 0x55; + const int GET_STAT_LAMPOUT = 0x60; + const int SET_GPIO = 0x61; + //const int SYNCHRONIZATION_GET_DARK = 0x23 + + //////////////////////////////////////////////////////////////////////////device + enum Model + { + ATP1010 = 0, + ATP6500 + }; + + //????????? + typedef struct tagATPDataFrame + { + unsigned short usExposureTime; + ZZ_U16 usData[4096]; + float fTemperature; + double dTimes = 0; + }ATPDataFrame; + + //????????? + typedef struct tagATPDeviceInfo + { + std::string strPN; + std::string strSN; + }ATPDeviceInfo; + + //???????? + typedef struct tagATPDeviceAttribute + { + int iPixels; + int iMaxIntegrationTime; + int iMinIntegrationTime; + float fWaveLength[4096]; + + }ATPDeviceAttribute; + //////////////////////////////////////////////////////////////////////////config file + + + + } + + //???????? + namespace ZZ_RUNPARAMS + { + typedef struct tagErrorInfo + { + int iDataTransferErr = -1000; + float fTecTempErr = -1000; + int iShutterErr = -1000; + float fChassisTempErr = -1000; + }ErrInfo; + + typedef struct tagFiberSpecContext + { + ZZ_U8 ucDeviceNumber; + ZZ_U8 ucDeviceModel[MAX_DEVICENUMBER_FS]; + std::string strInterface[MAX_DEVICENUMBER_FS]; + std::string strSN[MAX_DEVICENUMBER_FS]; + long lDepth[MAX_DEVICENUMBER_FS]; + float fMinFactor[MAX_DEVICENUMBER_FS]; + float fMaxFactor[MAX_DEVICENUMBER_FS]; + ZZ_U16 usPixels[MAX_DEVICENUMBER_FS]; + float fWavelength[MAX_DEVICENUMBER_FS][4096]; + }FSContext; + + typedef struct tagLinearShutterContext + { + std::string strInterface; + ZZ_U8 ucProtocolType; + ZZ_U8 ucCmdID; + }LSContext; + + typedef struct tagAcquisitionTimeSettings + { + QTime qtStartTime; + QTime qtStopTime; + QTime qtInterval; + }AcqTimeSettings; + + typedef struct tagAcquisitionPositionSettings + { + int iTotalPosition; + int iPosition[MAX_LINEARSHUTTER_POSITION]; + }AcqPosSettings; + + typedef struct tagRunTimeGrabberParams + { + LSContext lscParam; + FSContext fscParams; + AcqTimeSettings atsParams; + AcqPosSettings apsParams; + }RunTimeGrabberParams; + + typedef struct tagATPCalibrationSettings + { + //Up0 Down1,2,3 + QString qsISIF_CalibrationFilePath[4]; + QString qsIS1_CalibrationFilePath[4]; + }ATPCalibrationSettings; + } + + //??????????????? + namespace ZZ_DATAFILE + { + typedef struct tagEnvironmentalContext + { + QString qstrUTCDateTime; + QString qstrLocation; + QString qstrGPS_Longtitude; + QString qstrGPS_Latitude; + QString qstrGPS_Altitude; + QString qstrGPS_North; + QString qstrCaseTemperature; + QString qstrCaseHumidity; + QString qstrDEV_SN; + }EContext; + + typedef struct tagManmadeEnviromentalContext + { + QString qstrOriFileName; + QString qstrInstallationTime; + QString qstrISIFCalibrationTime; + QString qstrIS1CalibrationTime; + QString qstrNameOfMaintenanceStaff; + QString qstrPhoneNumberOfMaintenanceStaff; + QString qstrDownloadUserID; + QString qstrDownlaodAddress; + QString qstrHTTPServer; + }MEContext; + + + typedef struct tagIS1Information + { + QString qstrSN_ATP; + QString qstrSN_IRIS; + + QString qstrCalFile_U0; + QString qstrCalFile_D1; + QString qstrCalFile_D2; + QString qstrCalFile_D3; + + int iPixelCount; + + int iExposureTimeInMS_U0; + int iExposureTimeInMS_D1; + int iExposureTimeInMS_D2; + int iExposureTimeInMS_D3; + + float fTemperature_U0; + float fTemperature_D1; + float fTemperature_D2; + float fTemperature_D3; + }IS1Info; + + typedef struct tagISIFInformation + { + QString qstrSN_ATP; + QString qstrSN_IRIS; + + QString qstrCalFile_U0; + QString qstrCalFile_D1; + QString qstrCalFile_D2; + QString qstrCalFile_D3; + + int iPixelCount; + + int iExposureTimeInMS_U0; + int iExposureTimeInMS_D1; + int iExposureTimeInMS_D2; + int iExposureTimeInMS_D3; + + float fTemperature_U0; + float fTemperature_D1; + float fTemperature_D2; + float fTemperature_D3; + }ISIFInfo; + + typedef struct tagATPDataHeader + { + + + }ATPDataHeader; + + typedef struct tagCalibrationFrame + { + ZZ_U32 uiExposureTimeInMS; + float fTemperature; + int iPixels; + float fWaveLength[4096] = { 0 }; + double dCal_Gain[4096] = { 0 }; + double dCal_Offset[4096] = { 0 }; + }CalFrame; + + typedef struct tagCalDataFrame + { + ZZ_U32 usExposureTimeInMS; + float fTemperature = 0; + int iPixels; + float fData[4096]; + QString qstrGrabDate; + }CalDataFrame; + } + + //misc detector + namespace MISC_DETECTOR + { + typedef struct tagHumitureDeviceInfo + { + QString qstrInterfaceName; + }HumitureDeviceInfo; + } +}; \ No newline at end of file diff --git a/othersoft/calibration_console/Header_Files/atpFiberImager.h b/othersoft/calibration_console/Header_Files/atpFiberImager.h new file mode 100644 index 0000000..41ff34e --- /dev/null +++ b/othersoft/calibration_console/Header_Files/atpFiberImager.h @@ -0,0 +1,51 @@ +#pragma once +#include +//#include +#include + +#include +#include + +#include "ATPControl_Serial_QT.h" +#include "FiberSpectrometerOperationBase.h" + +class ATPFiberImager :public QObject,public FiberSpectrometerOperationBase +{ +Q_OBJECT + +public: + ATPFiberImager(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName); + ~ATPFiberImager(); + + ZZ_ATPControl_Serial_Qt * m_FiberSpectrometer; + + void connectFiberSpectrometer(QString& sn, QString& pixelCount, QString& wavelengthInfo); + void disconnectFiberSpectrometer(); + void getDeviceAttribute(DeviceAttribute& deviceAttribute); + void getDeviceInfo(DeviceInfo& deviceInfo); + + void setExposureTime(int iExposureTimeInMS); + + void getExposureTime(int &iExposureTimeInMS);//ok + void getDeviceTemperature(float &fTemperature);//ok + + void singleShot(DataFrame &dfData); + + ZZ_S32 GetMaxValue(ZZ_S32 * dark, int number); + +// DataFrame m_IntegratingSphereData; +// DataFrame m_DarkData; +protected: +private: + std::string mUcPortNumber; + +// ZZ_U32 m_MaxValueOfFiberSpectrometer; + +public slots: + void recordDark(QString path); + void recordTarget(int recordTimes, QString path); + void autoExpose(); + +signals: + void sendExposureTimeSignal(int exposureTime); +}; \ No newline at end of file diff --git a/othersoft/calibration_console/Header_Files/calibration.h b/othersoft/calibration_console/Header_Files/calibration.h new file mode 100644 index 0000000..15967d4 --- /dev/null +++ b/othersoft/calibration_console/Header_Files/calibration.h @@ -0,0 +1,50 @@ +#pragma once +#include +//#include +#include +#include +#include + +#include +#include + +#include "ZZ_Types.h" +#include "ZZ_Math.h" +//#include "Dense" +#include "Eigen/Dense" +#include "unsupported/Eigen/Splines" + +using namespace ZZ_MISCDEF::IRIS::FS; + +class CalibrationAlgorithm :public QObject +{ + Q_OBJECT + +public: + CalibrationAlgorithm(); + ~CalibrationAlgorithm(); + + void readFile(QString filePath, DeviceAttribute deviceAttribute, DeviceInfo deviceInfo); + + void produceCalfile(QString calFilePath, DeviceAttribute deviceAttribute, DataFrame integratingSphereData, DataFrame darkData); + + +protected: +private: + double m_dStandardLightDataBase;//��׼���ļ��Ļ�׼���� + double * m_dStandardLightWavelength; + double * m_dStandardLightData; + + double * m_dStandardLightWavelengthResampled; + double * m_dStandardLightDataResampled; + + double * m_gain; + double * m_offset; + +public slots: + + + +signals: + +}; \ No newline at end of file diff --git a/othersoft/calibration_console/Header_Files/library.h b/othersoft/calibration_console/Header_Files/library.h new file mode 100644 index 0000000..d9598ac --- /dev/null +++ b/othersoft/calibration_console/Header_Files/library.h @@ -0,0 +1,69 @@ +#ifndef OCEAN_LIB_LIBRARY_H +#define OCEAN_LIB_LIBRARY_H + +#include +#include +#include +//#include +#include + +#include "api/SeaBreezeWrapper.h" + +#include "IrisFiberSpectrometerBase.h" +#include "api/seabreezeapi/SeaBreezeAPI.h" + + +using namespace std; + +class OceanOptics_lib :public CIrisFSBase +{ +public: + OceanOptics_lib(); + virtual ~OceanOptics_lib(); +public: + //初始化设备 + //此处string为指明连接哪个ocean光谱仪的参数,可自行更换为其他c/c++标准类型 + //0为无错误,不同错误请返回不同值(不能确定:当不成功时SeaBreeze返回的错误代码error不为0 → 不敢将error直接返回) + int Initialize(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName);//ok + int Initialize();//ok + + //关闭设备 + void Close();//ok + + //单次数据采集 + int SingleShot(DataFrame &dfData); + + //设置曝光时间 + int SetExposureTime(int iExposureTimeInMS);//ok + + //获取曝光时间设置 + int GetExposureTime(int &iExposureTimeInMS);//ok + + //设置目标温度 + int SetDeviceTemperature(float fTemperature);//ok + + //获取温度设置 + int GetDeviceTemperature(float &fTemperature);//ok + + //获取设备信息 + int GetDeviceInfo(DeviceInfo &Info);//ok + + //获取设备特征数据 + int GetDeviceAttribute(DeviceAttribute &Attr);//ok + + //tc + static const char* get_error_string(int error); +private: + int m_iSpectralmeterHandle; + DeviceInfo m_deviceInfo; + int m_iExposureTime; + + bool isSuccess(char* resultStr); + + string GetDeviceType(int index); + string GetSerialNumber(int index); +}; + +#endif //OCEAN_LIB_LIBRARY_H + + diff --git a/othersoft/calibration_console/Header_Files/oceanOpticsFiberImager.h b/othersoft/calibration_console/Header_Files/oceanOpticsFiberImager.h new file mode 100644 index 0000000..ab5f1ff --- /dev/null +++ b/othersoft/calibration_console/Header_Files/oceanOpticsFiberImager.h @@ -0,0 +1,50 @@ +#pragma once +#include +//#include +#include + +#include +#include + +#include "library.h" +#include "FiberSpectrometerOperationBase.h" + +class OceanOpticsFiberImager :public QObject,public FiberSpectrometerOperationBase +{ + Q_OBJECT + +public: + OceanOpticsFiberImager(); + ~OceanOpticsFiberImager(); + + OceanOptics_lib * m_FiberSpectrometer; + + void connectFiberSpectrometer(QString& sn, QString& pixelCount, QString& wavelengthInfo); + void disconnectFiberSpectrometer(); + void getDeviceAttribute(DeviceAttribute& deviceAttribute); + void getDeviceInfo(DeviceInfo& deviceInfo); + + void setExposureTime(int iExposureTimeInMS); + + void getExposureTime(int &iExposureTimeInMS);//ok + void getDeviceTemperature(float &fTemperature);//ok + + void singleShot(DataFrame &dfData); + + ZZ_S32 GetMaxValue(ZZ_S32 * dark, int number); + +// DataFrame m_IntegratingSphereData; +// DataFrame m_DarkData; +protected: +private: + +// ZZ_U32 m_MaxValueOfFiberSpectrometer; + +public slots: + void recordDark(QString path); + void recordTarget(int recordTimes, QString path); + void autoExpose(); + +signals: + void sendExposureTimeSignal(int exposureTime); +}; \ No newline at end of file diff --git a/othersoft/calibration_console/Source_Files/ATPControl_Serial_QT.cpp b/othersoft/calibration_console/Source_Files/ATPControl_Serial_QT.cpp new file mode 100644 index 0000000..117087e --- /dev/null +++ b/othersoft/calibration_console/Source_Files/ATPControl_Serial_QT.cpp @@ -0,0 +1,602 @@ +//#include "pch.h" +#include "Header_Files/ATPControl_Serial_QT.h" +//#include "ZZ_Math_HDRONLY.h" +#include + + +ZZ_ATPControl_Serial_Qt::ZZ_ATPControl_Serial_Qt() +{ + m_pSerialPort = new QSerialPort; + //connect(m_pSerialPort, &QSerialPort::readyRead, this, &ZZ_ATPControl_Serial_Qt::ReadMessage); + m_iBaudRate = 115200; +} + +ZZ_ATPControl_Serial_Qt::~ZZ_ATPControl_Serial_Qt() +{ + if (m_pSerialPort != NULL) + { + delete m_pSerialPort; + } + +} + +// int ZZ_ATPControl_Serial_Qt::SetBaudRate(int iBaud) +// { +// m_iBaudRate = iBaud; +// return 0; +// } + + +int ZZ_ATPControl_Serial_Qt::Initialize(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName) +{ + QString qstrPortName = QString::fromStdString(ucPortNumber); + + m_pSerialPort->setPortName(qstrPortName); + m_pSerialPort->setReadBufferSize(512); + bool bRes = m_pSerialPort->setBaudRate(m_iBaudRate); + if (!bRes) + { + qDebug() << "Err:setBaudRate Failed.Exit Code:1"; + //std::cout << "Err.setBaudRate Failed" << std::endl; + return 1; + } + + bRes = m_pSerialPort->open(QIODevice::ReadWrite); + if (!bRes) + { + qDebug() << "Err:open Failed.Exit Code:2"; + //std::cout << "Err.open Failed" << std::endl; + return 2; + } + + return 0; +} + +void ZZ_ATPControl_Serial_Qt::Close() +{ + m_pSerialPort->close(); +} + +int ZZ_ATPControl_Serial_Qt::GetDeviceInfo(DeviceInfo &Info) +{ + QByteArray qbSend, qbRecv; + + qbSend.clear(); + qbRecv.clear(); + qbSend.append(GET_PN_NUMBER); + int iRes = SendCommand(qbSend); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceInfo Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = RecvData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceInfo Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = ParseData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceInfo Failed,Communication error.Exit Code:1"; + return 1; + } + m_diDeviceInfo.strPN = qbRecv.data(); + + qbSend.clear(); + qbRecv.clear(); + qbSend.append(GET_SN_NUMBER); + iRes = SendCommand(qbSend); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceInfo Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = RecvData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceInfo Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = ParseData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceInfo Failed,Communication error.Exit Code:1"; + return 1; + } + m_diDeviceInfo.strSN = qbRecv.data(); + + + Info = m_diDeviceInfo; + return 0; +} + +int ZZ_ATPControl_Serial_Qt::GetDeviceAttribute(DeviceAttribute &Attr) +{ + QByteArray qbSend, qbRecv; + + qbSend.clear(); + qbRecv.clear(); + qbSend.append(GET_MIN_INTEGRATION_TIME); + int iRes = SendCommand(qbSend); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = RecvData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = ParseData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + m_daDeviceAttr.iMinIntegrationTimeInMS = (ZZ_U8)qbRecv[1] + (ZZ_U8)qbRecv[0] * 256; + + qbSend.clear(); + qbRecv.clear(); + qbSend.append(GET_MAX_INTEGRATION_TIME); + iRes = SendCommand(qbSend); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = RecvData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = ParseData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + m_daDeviceAttr.iMaxIntegrationTimeInMS = (ZZ_U8)qbRecv[1] + (ZZ_U8)qbRecv[0] * 256; + + + iRes = SetExposureTime(m_daDeviceAttr.iMinIntegrationTimeInMS); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Call SetExposureTime error.Exit Code:2"; + return 2; + } + iRes = SingleShot(m_daDeviceAttr.iPixels); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Call SingleShot error.Exit Code:3"; + return 3; + } + + + qbSend.clear(); + qbRecv.clear(); + qbSend.append(GET_WAVELENGTH_CALIBRATION_COEF); + qbSend.resize(3); + qbSend[1] = 0x00; + qbSend[2] = 0x01; + iRes = SendCommand(qbSend); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = RecvData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + iRes = ParseData(qbRecv); + if (iRes != 0) + { + qDebug() << "Err:GetDeviceAttribute Failed,Communication error.Exit Code:1"; + return 1; + } + float fWaveLengthCoef[4]; + memcpy(fWaveLengthCoef, qbRecv.data()+16, 4 * sizeof(float)); + for (int i=0;i< m_daDeviceAttr.iPixels;i++) + { + m_daDeviceAttr.fWaveLengthInNM[i] = fWaveLengthCoef[0] * i*i*i + fWaveLengthCoef[1] * i*i + fWaveLengthCoef[2] * i + fWaveLengthCoef[3]; + } + + Attr = m_daDeviceAttr; + + return 0; +} + +int ZZ_ATPControl_Serial_Qt::SetDeviceTemperature(float fTemperature) +{ + return 0; +} + +int ZZ_ATPControl_Serial_Qt::SendCommand(QByteArray qbCommand) +{ + int iSize = qbCommand.size() + 3; + QByteArray qbSend; + qbSend.resize(4); + qbSend[0] = (ZZ_U8)0xAA; + qbSend[1] = 0x55; + qbSend[2] = iSize / 256; + qbSend[3] = iSize % 256; + qbSend.append(qbCommand); + + int iSum = 0; + for (int i = 0; i < iSize - 1; i++) + { + iSum = iSum + qbSend[i + 2]; + } + + qbSend.append(iSum % 256); + + qint64 qi64Write= m_pSerialPort->write(qbSend); + if (qi64Write != qbSend.size()) + { + qDebug() << "Err:write Failed.Exit Code:1"<< qi64Write; + return 1; + } + + return 0; +} + +int ZZ_ATPControl_Serial_Qt::RecvData(QByteArray &qbData) +{ + qbData.clear(); + qbData = m_pSerialPort->readAll(); + + int iCounter = 0; + while (qbData.size() < 4) + { + m_pSerialPort->waitForReadyRead(5000); + QByteArray qbTemp = m_pSerialPort->readAll(); + qbData.append(qbTemp); + + if (iCounter > 20) + { + qDebug() << "Err:RecvData Failed,Not Enough Data.Exit Code:1"<< qbData.size(); + return 1; + } + iCounter++; + } + +#include + if ((ZZ_U8)qbData[0] != (ZZ_U8)0xaa || (ZZ_U8)qbData[1] != (ZZ_U8)0x55) + { + qDebug() << "Err:RecvData Failed,Wrong Header.Exit Code:2" << qbData.size(); + return 2; + } + + iCounter = 0; + int iLength = qbData[2] * 256 + qbData[3] + 2; + while (qbData.size() < iLength) + { + m_pSerialPort->waitForReadyRead(50); + qbData.append(m_pSerialPort->readAll()); + + if (iCounter > 100) + { + qDebug() << "Err:RecvData Failed,Incomplete Data.Exit Code:3" << qbData.size(); + return 3; + } + iCounter++; + } + + if (qbData.size() > iLength) + { + qbData.remove(iLength - 1, qbData.size() - iLength); + } + int iCheckSumLength = iLength - 3; + ZZ_U16 usCheckSum = 0; + for (int i = 0; i < iCheckSumLength; i++) + { + usCheckSum += qbData[i+2]; + } + usCheckSum = usCheckSum % 256; + ZZ_U8 ucTemp = qbData[qbData.size() - 1]; + if ((ZZ_U8)usCheckSum != ucTemp) + { + qDebug() << "Err:RecvData Failed,Incorrect Check Sum.Exit Code:4" << qbData.size(); + qbData.clear(); + return 4; + } + + return 0; +} + +int ZZ_ATPControl_Serial_Qt::ParseData(QByteArray &qbData) +{ + if (qbData.size() < 6) + { + qDebug() << "Err:ParseData Failed,Not Enough Data.Exit Code:1" << qbData.size(); + return 1; + } + qbData.remove(0, 5); + qbData.remove(qbData.size() - 1, 1); + return 0; +} + +int ZZ_ATPControl_Serial_Qt::PerformAutoExposure(float fMinScaleFactor, float fMaxScaleFactor, float &fPredictedExposureTime) +{ + using namespace ZZ_MATH; + int iDeviceDepth = 65535; + + bool bFlagIsOverTrying = false; + bool bFlagIsLowerMinExposureTime = false; + bool bFlagIsOverMaxExposureTime = false; + bool bFlagIsAutoExposureOK = false; + bool bFlagIsAutoExposureFailed = false; + + bool bIsValueOverflow = false; + bool bIsLastValueOverflow = false; + + float fExposureTime = 0; + float fTempExposureTime = 0; + double fLastExposureTime = 0.1; + int iRepeatCount = 0; + + int iRes = SetExposureTime(2000);//need change to load from files + if (iRes != 0) + { + qDebug() << "Err:PerformAutoExposure Failed.Exit Code:1"; + return 1; + } + + while (!bFlagIsAutoExposureOK && !bFlagIsAutoExposureFailed) + { + DataFrame dfTemp; + + if (iRepeatCount++ > 30) + { + bFlagIsAutoExposureFailed = true; + bFlagIsOverTrying = true; + break; + } + + fExposureTime = (float)m_daDeviceAttr.iMinIntegrationTimeInMS; + fTempExposureTime = fExposureTime; + + iRes = SingleShot(dfTemp); + if (iRes != 0) + { + qDebug() << "Err:PerformAutoExposure Failed.Exit Code:2"; + return 2; + } + + HeapSort(dfTemp.lData, m_daDeviceAttr.iPixels); + + double dSum = 0; + int iCount = m_daDeviceAttr.iPixels / 100; + for (int i = 0; i < iCount; i++) + { + dSum += dfTemp.lData[i]; + } + double dTemp = dSum / iCount; + + if (dTemp >= iDeviceDepth * 0.99) + { + bIsValueOverflow = true; + if (!bIsLastValueOverflow) + { + fExposureTime = (float)(fLastExposureTime + fExposureTime) / 2; + } + else + { + fExposureTime = fExposureTime / 2; + } + } + + else if (iDeviceDepth * fMaxScaleFactor >= dTemp && dTemp >= iDeviceDepth * fMinScaleFactor) + { + bFlagIsAutoExposureOK = 1; + } + else if (dTemp > iDeviceDepth * fMaxScaleFactor) + { + bIsValueOverflow = true; + if (!bIsLastValueOverflow) + { + fExposureTime = (float)(fLastExposureTime + fExposureTime) / 2; + } + else + { + fExposureTime = fExposureTime * 3 / 4; + } + } + else if (dTemp < iDeviceDepth * fMinScaleFactor) + { + bIsValueOverflow = false; + if (bIsLastValueOverflow) + { + fExposureTime = (float)(fLastExposureTime + fExposureTime) / 2; + } + else + { + double dFactor; + dFactor = dTemp / (iDeviceDepth * fMaxScaleFactor); + fExposureTime = (float)(fExposureTime / dFactor); + } + if (/*fExposureTime > 100 || */fExposureTime < 10) + { + bFlagIsAutoExposureOK = false; + bFlagIsAutoExposureFailed = true; + bFlagIsLowerMinExposureTime = true; + } + } + bIsLastValueOverflow = bIsValueOverflow; + fLastExposureTime = fTempExposureTime; + + if (fExposureTime > 13000) + { + bFlagIsAutoExposureOK = false; + bFlagIsAutoExposureFailed = true; + fPredictedExposureTime = 13000; + iRes = SetExposureTime(13000); + if (iRes != 0) + { + qDebug() << "Err:PerformAutoExposure Failed.Exit Code:3"; + return 3; + } + bFlagIsOverMaxExposureTime = true; + break; + } + + iRes = SetExposureTime((int)fExposureTime); + if (iRes != 0) + { + qDebug() << "Err:PerformAutoExposure Failed.Exit Code:4"; + return 3; + } + } + fPredictedExposureTime = fExposureTime; + return 0; +} + + + +// int ZZ_ATPControl_Serial_Qt::SetExtShutter(int iShutterUP0, int iShutterDOWN1, int iShutterDOWN2, int iShutterDOWN3) +// { +// qDebug() << "stub code not implemented"; +// return -1; +// } + +int ZZ_ATPControl_Serial_Qt::SetExposureTime(int iExposureTimeInMS) +{ + QByteArray qbExposureTime,qbRecv; + qbExposureTime.append(SET_INTEGRATION_TIME); + qbExposureTime.resize(3); + qbExposureTime[1] = iExposureTimeInMS >> 8; + qbExposureTime[2] = iExposureTimeInMS & 0xFF; + + SendCommand(qbExposureTime); + RecvData(qbRecv); + ParseData(qbRecv); + + if ((ZZ_U8)qbRecv[0] != 0) + { + qDebug() << "Err:SetExposureTime Failed.Exit Code:1" ; + return 1; + } + + return 0; +} + +int ZZ_ATPControl_Serial_Qt::GetExposureTime(int &iExposureTimeInMS) +{ + QByteArray qbSend, qbRecv; + qbSend.clear(); + qbRecv.clear(); + qbSend.append(GET_INTEGRATION_TIME); + qbSend.resize(3); + qbSend[1] = 0x00; + qbSend[2] = 0x01; + SendCommand(qbSend); + RecvData(qbRecv); + ParseData(qbRecv); + return 0; +} + +int ZZ_ATPControl_Serial_Qt::SingleShot(DataFrame &dfData) +{ + + QByteArray qbSend, qbRecv; + qbSend.clear(); + qbRecv.clear(); + qbSend.append(SYNC_GET_DATA); + qbSend.resize(3); + qbSend[1] = 0x00; + qbSend[2] = 0x01; + SendCommand(qbSend); + RecvData(qbRecv); + ParseData(qbRecv); + + ZZ_U16 usData[4096] = {0}; + + if ((ZZ_U8)qbRecv[0] != 0) + { + qDebug() << "Err:SingleShot Failed.Exit Code:1"; + return 1; + } + else + { + //int aaa = qbRecv.size(); + int iDataSizeInPixel = (qbRecv.size() - 1) / 2; + memcpy(usData, qbRecv.data() + 1, iDataSizeInPixel * 2); + for (int i=0;i< iDataSizeInPixel;i++) + { + dfData.lData[i] = usData[i]; + } + } + + return 0; +} + +int ZZ_ATPControl_Serial_Qt::SingleShot(int &iPixels) +{ + QByteArray qbSend, qbRecv; + qbSend.clear(); + qbRecv.clear(); + qbSend.append(SYNC_GET_DATA); + qbSend.resize(3); + qbSend[1] = 0x00; + qbSend[2] = 0x01; + SendCommand(qbSend); + RecvData(qbRecv); + ParseData(qbRecv); + + if ((ZZ_U8)qbRecv[0] != 0) + { + qDebug() << "Err:SingleShot Failed.Exit Code:1"; + return 1; + } + else + { + iPixels = (qbRecv.size() - 1) / 2; + + } + return 0; +} + +// int ZZ_ATPControl_Serial_Qt::SingleShotDark(ATPDataFrame &dfData) +// { +// SetExtShutter(0,0,0,0); +// SingleShot(dfData); +// return 0; +// } + +int ZZ_ATPControl_Serial_Qt::GetDeviceTemperature(float &fTemperature) +{ + QByteArray qbSend, qbRecv; + qbSend.clear(); + qbRecv.clear(); + qbSend.append(GET_TEC_TEMP); + qbSend.resize(3); + qbSend[1] = 0x00; + qbSend[2] = 0x01; + SendCommand(qbSend); + RecvData(qbRecv); + ParseData(qbRecv); + return 0; +} + +//void ZZ_ATPControl_Serial_Qt::ReadMessage() +//{ +// QByteArray qbTemp, qbTemp1; +// qbTemp = m_pSerialPort->readAll(); +// while (qbTemp.size()<2) +// { +// m_pSerialPort->waitForReadyRead(50); +// qbTemp1 = m_pSerialPort->readAll(); +// qbTemp.append(qbTemp1); +// } + + + +//return; +// } diff --git a/othersoft/calibration_console/Source_Files/ZZ_Math.cpp b/othersoft/calibration_console/Source_Files/ZZ_Math.cpp new file mode 100644 index 0000000..6076476 --- /dev/null +++ b/othersoft/calibration_console/Source_Files/ZZ_Math.cpp @@ -0,0 +1,113 @@ +//#include "pch.h" +#include "Header_Files/ZZ_Math.h" + +void ZZ_MATH::PolyFit::Eigen_Polyfit(const std::vector &xv, const std::vector &yv, std::vector &coeff, int order) +{ + Eigen::MatrixXd A(xv.size(), order + 1); + Eigen::VectorXd yv_mapped = Eigen::VectorXd::Map(&yv.front(), yv.size()); + Eigen::VectorXd result; + + assert(xv.size() == yv.size()); + assert(xv.size() >= order + 1); + + + for (size_t i = 0; i < xv.size(); i++) + { + for (size_t j = 0; j < order + 1; j++) + { + A(i, j) = pow(xv.at(i), j); + } + } + + + result = A.householderQr().solve(yv_mapped); + + coeff.resize(order + 1); + for (size_t i = 0; i < order + 1; i++) + { + coeff[i] = result[i]; + } +} + +double ZZ_MATH::PolyFit::Eigen_Polyeval(std::vector coeffs, double x) +{ + double result = 0.0; + + for (int i = 0; i < coeffs.size(); i++) + { + result += coeffs[i] * pow(x, i); + } + + return result; +} + + +Eigen::VectorXd ZZ_MATH::SplineFit::Eigen_Normalize(const Eigen::VectorXd &x) +{ + using namespace Eigen; + VectorXd x_norm; + x_norm.resize(x.size()); + const double min = x.minCoeff(); + const double max = x.maxCoeff(); + + for (int k = 0; k < x.size(); k++) + { + x_norm(k) = (x(k) - min) / (max - min); + } + + return x_norm; + +} + +void ZZ_MATH::SplineFit::Test(std::vector const &x_vec, std::vector const &y_vec) +{ + typedef Spline Spline1D; + typedef SplineFitting Spline1DFitting; + + + //VectorXd vx,vy; + //vx.resize(x_vec.size()); + //vy.resize(y_vec.size()); + //vx.Map(&x_vec.front(), x_vec.size()); + //vy.Map(&y_vec.front(), y_vec.size()); + + Eigen::VectorXd vx = Eigen::VectorXd::Map(&x_vec.front(), 5/*x_vec.size()*/); + Eigen::VectorXd vy = Eigen::VectorXd::Map(&y_vec.front(), 5/*y_vec.size()*/); + + const double scale = 1 / (vx.maxCoeff() - vx.minCoeff()); + const double scale_sq = scale * scale; + + //VectorXd knots = Eigen_Normalize(vx); + //Spline1D spline = Spline1DFitting::Interpolate(vy.transpose(),3, knots); + //double a; + // a = spline.derivatives(0,1)(0); + //Eigen::VectorXd xvals(5); + //Eigen::VectorXd yvals(xvals.rows()); + //xvals << 0, 1, 2,3,4; + //yvals << 0, 1, 4,9,16; + + SplineInterpolation s(vx, vy); +} + +ZZ_MATH::SplineFit::SplineInterpolation::SplineInterpolation(Eigen::VectorXd const &x_vec, Eigen::VectorXd const &y_vec): + x_min(x_vec.minCoeff()), x_max(x_vec.maxCoeff()), + spline_(Eigen::SplineFitting>:: + Interpolate(y_vec.transpose(), 3, scaled_values(x_vec))) +{ + +} + +double ZZ_MATH::SplineFit::SplineInterpolation::operator()(double x) const +{ + return spline_(scaled_value(x))(0); +} + +double ZZ_MATH::SplineFit::SplineInterpolation::scaled_value(double x) const +{ + return (x - x_min) / (x_max - x_min); +} + +Eigen::RowVectorXd ZZ_MATH::SplineFit::SplineInterpolation::scaled_values(Eigen::VectorXd const &x_vec) const +{ + return x_vec.unaryExpr([this](double x) { return scaled_value(x); }).transpose(); +} diff --git a/othersoft/calibration_console/Source_Files/atpFiberImager.cpp b/othersoft/calibration_console/Source_Files/atpFiberImager.cpp new file mode 100644 index 0000000..876ebdf --- /dev/null +++ b/othersoft/calibration_console/Source_Files/atpFiberImager.cpp @@ -0,0 +1,186 @@ +#include "Header_Files/atpFiberImager.h" + +ATPFiberImager::ATPFiberImager(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName) +{ + m_FiberSpectrometer = NULL; + + mUcPortNumber=ucPortNumber; +} + +ATPFiberImager::~ATPFiberImager() +{ + +} + +void ATPFiberImager::connectFiberSpectrometer(QString& SN, QString& pixelCount, QString& wavelengthInfo) +{ + using namespace std; + + m_FiberSpectrometer = new ZZ_ATPControl_Serial_Qt(); + + m_FiberSpectrometer->Initialize(false, mUcPortNumber, "ocean_optics"); + + DeviceInfo deviceInfo;// + DeviceAttribute deviceAttribute; + + m_FiberSpectrometer->GetDeviceInfo(deviceInfo); + m_FiberSpectrometer->GetDeviceAttribute(deviceAttribute); + + SN = QString::fromStdString(deviceInfo.strSN); + pixelCount = QString::number(deviceAttribute.iPixels); + wavelengthInfo = QString::number(deviceAttribute.fWaveLengthInNM[0]) + "--" + QString::number(deviceAttribute.fWaveLengthInNM[deviceAttribute.iPixels - 1]); + + m_FiberSpectrometer->SetDeviceTemperature(-10); + + + //dnֵֵλأ + string qepro = "QEP";//????????????????????????????????????????????????????????????????????????????????????????? + string flame = "FLMS";//????????????????????????????????????????????????????????????????????????????????????????? + if (deviceInfo.strSN.find(qepro) != string::npos) + { + m_MaxValueOfFiberSpectrometer = 200000; + } + else if (deviceInfo.strSN.find(flame) != string::npos) + { + m_MaxValueOfFiberSpectrometer = 65535; + } + else//ûҵƥ dnֵֵ + { + + } + +} + +void ATPFiberImager::disconnectFiberSpectrometer() +{ + m_FiberSpectrometer->Close(); +} + +void ATPFiberImager::getDeviceAttribute(DeviceAttribute& deviceAttribute) +{ + m_FiberSpectrometer->GetDeviceAttribute(deviceAttribute); +} + +void ATPFiberImager::getDeviceInfo(DeviceInfo& deviceInfo) +{ + m_FiberSpectrometer->GetDeviceInfo(deviceInfo); +} + +void ATPFiberImager::setExposureTime(int iExposureTimeInMS) +{ + m_FiberSpectrometer->SetExposureTime(iExposureTimeInMS); +} + +void ATPFiberImager::getExposureTime(int &iExposureTimeInMS) +{ + m_FiberSpectrometer->GetExposureTime(iExposureTimeInMS); +} + +void ATPFiberImager::getDeviceTemperature(float &fTemperature) +{ + m_FiberSpectrometer->GetDeviceTemperature(fTemperature); +} + +void ATPFiberImager::singleShot(DataFrame &dfData) +{ + m_FiberSpectrometer->SingleShot(dfData); +} + +void ATPFiberImager::recordDark(QString path) +{ + //ȡ豸Ϣ + DeviceAttribute attribute; + DeviceInfo deviceInfo; + getDeviceAttribute(attribute); + getDeviceInfo(deviceInfo); + + //ɼ֡ + singleShot(m_DarkData); + + QDateTime curDateTime = QDateTime::currentDateTime(); + QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); + QString fileName = path + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_darkSpectral.csv"; + std::ofstream outfile(fileName.toStdString().c_str()); + + for (int i = 0; i < attribute.iPixels; i++) + { + if (i==0) + { + outfile << m_DarkData.usExposureTimeInMS << std::endl; + } + outfile << attribute.fWaveLengthInNM[i] << "," << m_DarkData.lData[i] << std::endl; + } + + outfile.close(); +} + +void ATPFiberImager::recordTarget(int recordTimes, QString path) +{ + //ȡ豸Ϣ + DeviceAttribute attribute; + DeviceInfo deviceInfo; + getDeviceAttribute(attribute); + getDeviceInfo(deviceInfo); + + + DataFrame integratingSphereData_tmp; + + for (int i = 0; i < recordTimes; i++) + { + singleShot(integratingSphereData_tmp); + + if (i == 0)//integratingSphereData_tmpеعʱ䡢¶ȵϢm_IntegratingSphereData + { + m_IntegratingSphereData = integratingSphereData_tmp; + } + else + { + for (int i = 0; i < attribute.iPixels; i++) + { + m_IntegratingSphereData.lData[i] += integratingSphereData_tmp.lData[i]; + } + } + + } + + for (int i = 0; i < attribute.iPixels; i++) + { + m_IntegratingSphereData.lData[i] = m_IntegratingSphereData.lData[i] / recordTimes; + } + + QDateTime curDateTime = QDateTime::currentDateTime(); + QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); + QString fileName = path + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_integratingSphereSpectral.csv"; + std::ofstream outfile(fileName.toStdString().c_str()); + + for (int i = 0; i < attribute.iPixels; i++) + { + if (i==0) + { + outfile << m_IntegratingSphereData.usExposureTimeInMS << std::endl; + } + outfile << attribute.fWaveLengthInNM[i] << "," << m_IntegratingSphereData.lData[i] << std::endl; + } + + outfile.close(); +} + +void ATPFiberImager::autoExpose() +{ + float fPredictedExposureTime; + m_FiberSpectrometer->PerformAutoExposure(0.7,0.8,fPredictedExposureTime); +} + +ZZ_S32 ATPFiberImager::GetMaxValue(ZZ_S32 * dark, int number) +{ + ZZ_S32 max = 0; + for (size_t i = 0; i < number; i++) + { + if (dark[i] > max) + { + max = dark[i]; + } + } + //std::cout << "ֵ֡Ϊ" << max << std::endl; + return max; +} \ No newline at end of file diff --git a/othersoft/calibration_console/Source_Files/calibration.cpp b/othersoft/calibration_console/Source_Files/calibration.cpp new file mode 100644 index 0000000..8ebeff7 --- /dev/null +++ b/othersoft/calibration_console/Source_Files/calibration.cpp @@ -0,0 +1,232 @@ +#include "Header_Files/calibration.h" + +CalibrationAlgorithm::CalibrationAlgorithm() +{ + +} + +CalibrationAlgorithm::~CalibrationAlgorithm() +{ + +} + +void CalibrationAlgorithm::readFile(QString filePath, DeviceAttribute deviceAttribute, DeviceInfo deviceInfo) +{ + + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + std::cout << "ļڣ" << std::endl; + + return; + } + + //ȡ׼ + int lineCount = 0; + while (!file.atEnd()) + { + QByteArray tmp = file.readLine(); + lineCount++; + } + double * StandardLightWavelength_tmp = new double[lineCount - 1]; + double * StandardLightData_tmp = new double[lineCount - 1]; + + + file.seek(0); + for (size_t i = 0; i < lineCount; i++) + { + QByteArray line = file.readLine(); + QString str(line); + //cout << str.section('\t', 1).trimmed().toStdString() << endl; + + if (i == 0) + { + QString first = str.section('\t', 0, 0); + m_dStandardLightDataBase = first.toDouble(); + } + else + { + QString first = str.section('\t', 0, 0); + QString second = str.section('\t', 1, 1); + StandardLightWavelength_tmp[i - 1] = first.toDouble(); + StandardLightData_tmp[i - 1] = second.toDouble(); + + //if (i== lineCount-1)//鿴һǷȷ + //{ + // double xx = first.toDouble(); + // double yy = second.toDouble(); + // std::cout << "xx" << xx < StandardLightWavelength_tmp[lineCount - 2])//׼ļΧδ󲨳 + { + endPos = lineCount - 2; + } + else + { + for (size_t i = 0; i < lineCount - 1; i++) + { + if (deviceAttribute.fWaveLengthInNM[deviceAttribute.iPixels - 1] < StandardLightWavelength_tmp[i]) + { + endPos = i + buffer;//?? + + break; + } + } + } + + m_dStandardLightWavelength = new double[endPos - startPos]; + m_dStandardLightData = new double[endPos - startPos]; + + for (size_t i = 0; i < endPos - startPos; i++) + { + m_dStandardLightWavelength[i] = StandardLightWavelength_tmp[i + startPos]; + m_dStandardLightData[i] = StandardLightData_tmp[i + startPos]; + } + + + + //ضϱ׼ + QFileInfo fileInfo(filePath); + QString standardLightFileFolder = fileInfo.path(); + QString standardLightFileName = fileInfo.fileName(); + + QDateTime curDateTime = QDateTime::currentDateTime(); + QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); + + QString tmp = standardLightFileFolder + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) +"_"+ standardLightFileName + "_truncation.csv"; + + std::ofstream outfile1(tmp.toStdString().c_str()); + + for (size_t i = 0; i < endPos - startPos; i++) + { + if (i == 0) + { + outfile1 << m_dStandardLightDataBase << std::endl; + } + + outfile1 << m_dStandardLightWavelength[i] << "," << m_dStandardLightData[i] << std::endl; + } + outfile1.close(); + + + + //ز׼ + Eigen::VectorXd vx = Eigen::VectorXd::Map(m_dStandardLightWavelength, endPos - startPos/*x_vec.size()*/); + Eigen::VectorXd vy = Eigen::VectorXd::Map(m_dStandardLightData, endPos - startPos/*y_vec.size()*/); + + using namespace ZZ_MATH::SplineFit; + SplineInterpolation m_sfLine(vx, vy); + + m_dStandardLightWavelengthResampled = new double[deviceAttribute.iPixels]; + m_dStandardLightDataResampled = new double[deviceAttribute.iPixels]; + + + QString outputName = standardLightFileFolder + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_" + standardLightFileName + "_resample.csv"; + std::ofstream outfile2(outputName.toStdString().c_str()); + + double dTemp; + for (size_t i = 0; i < deviceAttribute.iPixels; i++) + { + if (deviceAttribute.fWaveLengthInNM[i] < StandardLightWavelength_tmp[0])//˲ < ׼ļС + { + dTemp = m_sfLine(StandardLightWavelength_tmp[0]);//??????????????? + } + else if (deviceAttribute.fWaveLengthInNM[i] > StandardLightWavelength_tmp[lineCount - 2])//˲ > ׼ļ󲨳 + { + dTemp = m_sfLine(StandardLightWavelength_tmp[lineCount - 2]);//??????????????? + } + else + { + dTemp = m_sfLine(deviceAttribute.fWaveLengthInNM[i]);//????? + } + + //double dTemp2 = m_sfLine(deviceAttribute.fWaveLengthInNM[i]);//ûʹ + + m_dStandardLightWavelengthResampled[i] = deviceAttribute.fWaveLengthInNM[i]; + m_dStandardLightDataResampled[i] = dTemp; + + if (i == 0) + { + outfile2 << m_dStandardLightDataBase << std::endl; + } + + outfile2 << deviceAttribute.fWaveLengthInNM[i] << "," << dTemp << std::endl; + } + outfile2.close(); +} + +void CalibrationAlgorithm::produceCalfile(QString calFilePath, DeviceAttribute deviceAttribute, DataFrame integratingSphereData, DataFrame darkData) +{ + using namespace ZZ_MISCDEF;//ZZ_U32 + + int errorCode; + size_t writeCounter; + + double* m_gain = new double[deviceAttribute.iPixels];//double* + double* m_offset = new double[deviceAttribute.iPixels];//double* + + for (size_t i = 0; i < deviceAttribute.iPixels; i++) + { + if (integratingSphereData.lData[i] - darkData.lData[i] == 0)//ĸΪ + { + m_gain[i] = 0; + } + else + { + m_gain[i] = m_dStandardLightDataResampled[i] / (integratingSphereData.lData[i] - darkData.lData[i]); + } + + m_offset[i] = 0; + } + + //д뵽ļ + FILE *calFileHandle = fopen(calFilePath.toStdString().c_str(), "w+b"); + + writeCounter = fwrite(&integratingSphereData.usExposureTimeInMS, sizeof(ZZ_U32), 1, calFileHandle);//عʱ + writeCounter = fwrite(&integratingSphereData.fTemperature, sizeof(float), 1, calFileHandle);//¶ + writeCounter = fwrite(&deviceAttribute.iPixels, sizeof(int), 1, calFileHandle);// + writeCounter = fwrite(&deviceAttribute.fWaveLengthInNM, sizeof(float), deviceAttribute.iPixels, calFileHandle);// + writeCounter = fwrite(m_gain, sizeof(double), deviceAttribute.iPixels, calFileHandle);//gain + writeCounter = fwrite(m_offset, sizeof(double), deviceAttribute.iPixels, calFileHandle);//offset + + fclose(calFileHandle); + + //д뵽CSVļ + QString calFile_csv = calFilePath.split(".")[0] + ".csv"; + std::ofstream outfile(calFile_csv.toStdString().c_str()); + for (int i = 0; i < deviceAttribute.iPixels; i++) + { + outfile << deviceAttribute.fWaveLengthInNM[i] << "," << m_gain[i] << std::endl; + } + outfile.close(); + + delete[] m_gain; +} diff --git a/othersoft/calibration_console/Source_Files/library.cpp b/othersoft/calibration_console/Source_Files/library.cpp new file mode 100644 index 0000000..3386b35 --- /dev/null +++ b/othersoft/calibration_console/Source_Files/library.cpp @@ -0,0 +1,564 @@ +#include "Header_Files/library.h" + +#include +#include + +OceanOptics_lib::OceanOptics_lib() +{ + m_iSpectralmeterHandle = -100; +} + +OceanOptics_lib::~OceanOptics_lib() +{ + +} + +//ʹͷļ#include "api/SeaBreezeWrapper.h" +int OceanOptics_lib::Initialize(bool bIsUSBMode, std::string ucPortNumber, std::string strDeviceName) +{ + int flag; + int error; + char type[16]; + int device_count = 0; + int i; + + for (i = 0; i < SEABREEZE_MAX_DEVICES; i++) + { + // printf("\nOpening spectrometer %d.\n", i); + flag = seabreeze_open_spectrometer(i, &error); + // printf("Open spectrometer result is (%d) [%s]\n", flag, get_error_string(error)); + if (0 == flag) + { + device_count++; + } + else + { + continue; + } + string sn = GetSerialNumber(i); + + if (strcmp(sn.c_str(), strDeviceName.c_str()) == 0) + { + m_iSpectralmeterHandle = i; + // printf("\nfind!!!!!!!!!!!!\n"); + break; + } + else + { + // printf("\nClosing spectrometer %d.\n", i); + flag = seabreeze_close_spectrometer(i, &error); + // printf("Close spectrometer result is (%d) [%s]\n", flag, get_error_string(error)); + } + } + + if (m_iSpectralmeterHandle == -100) + { + // printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + seabreeze_set_trigger_mode(m_iSpectralmeterHandle, &error, 0); + + long test = seabreeze_get_buffer_capacity_minimum(m_iSpectralmeterHandle, &error); + seabreeze_set_buffer_capacity(m_iSpectralmeterHandle, &error, test); + + // printf("seabreeze_set_trigger_mode: Result is [%s]\n", get_error_string(error)); + + + + //óʼʱ + long minimum_time; + minimum_time = seabreeze_get_min_integration_time_microsec(m_iSpectralmeterHandle, &error); + //printf("...Minimum is %ld microseconds, result is [%s]\n", minimum_time, get_error_string(error)); + bool ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + // printf("\n-------------------ûɹ\n"); + return 1; + } + + if (minimum_time < 0) { + /* If there was an error, reset to a time that is supported widely. */ + minimum_time = 15000; + return 1; + } + + SetExposureTime(minimum_time / 1000); + + return 0; +} + +//ʹͷļ#include "api/SeaBreezeWrapper.h" +int OceanOptics_lib::Initialize() +{ + int flag; + int error; + char type[16]; + int device_count = 0; + int i; + + for (i = 0; i < SEABREEZE_MAX_DEVICES; i++) + { + printf("\nOpening spectrometer %d.\n", i); + flag = seabreeze_open_spectrometer(i, &error); + //printf("Open spectrometer result is (%d) [%s]\n", flag, get_error_string(error)); + if (0 == flag) + { + m_iSpectralmeterHandle = i; + break; + } + else + { + continue; + } + } + + if (m_iSpectralmeterHandle == -100) + { + printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + + seabreeze_set_trigger_mode(m_iSpectralmeterHandle, &error, 0); + seabreeze_set_trigger_mode(m_iSpectralmeterHandle, &error, 0); + seabreeze_set_trigger_mode(m_iSpectralmeterHandle, &error, 0); + + long test = seabreeze_get_buffer_capacity_minimum(m_iSpectralmeterHandle, &error); + printf("seabreeze_get_buffer_capacity_minimum: Result is [%s]\n", get_error_string(error)); + seabreeze_set_buffer_capacity(m_iSpectralmeterHandle, &error, test); + printf("seabreeze_set_buffer_capacity: Result is [%s]\n", get_error_string(error)); + + // printf("seabreeze_set_trigger_mode: Result is [%s]\n", get_error_string(error)); + + //óʼʱ + long minimum_time; + + minimum_time = seabreeze_get_min_integration_time_microsec(m_iSpectralmeterHandle, &error); + //printf("...Minimum is %ld microseconds, result is [%s]\n", minimum_time, get_error_string(error)); + bool ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + // printf("\n-------------------ûɹ\n"); + return 1; + } + + if (minimum_time < 0) { + /* If there was an error, reset to a time that is supported widely. */ + minimum_time = 15000; + return 1; + } + + SetExposureTime(minimum_time / 1000); + + return 0; +} + + +//ʹͷļ#include "api/seabreezeapi/SeaBreezeAPI.h" +//int OceanOptics_lib::Initialize(bool bIsUSBMode,ZZ_U8 ucPortNumber,std::string strDeviceName) +//{ +// int number_of_devices; +// long *device_ids; +// int i; +// int flag; +// int error = 0; +// char nameBuffer[80]; +// char *serialNumber; +// +// +//// /* Give the driver a chance to initialize itself */ +//// sbapi_initialize(); +// +// printf("Probing for devices...\n"); fflush(stdout); +// sbapi_probe_devices(); +// +// printf("Getting device count...\n"); fflush(stdout); +// number_of_devices = sbapi_get_number_of_device_ids(); +// std::cout<<"Device count is "<< number_of_devices < 0) { +// printf("\tDevice type: [%s]\n", nameBuffer); +// } +// +// serialNumber = GetSerialNumber(device_ids[i]); +// serialNumber = GetSerialNumber(device_ids[i]); +// +// printf("\tSerial number tc: [%s]\n", serialNumber); +// +//// /* Open the device */ +//// printf("\tAttempting to open:\n"); +//// flag = sbapi_open_device(device_ids[i], &error); +//// printf("\t\tResult is (%d) [%s]\n", flag, sbapi_get_error_string(error)); +//// +//// // jump to the next iteration if there was a problem +//// if(flag != 0) { +//// continue; +//// } +//// +//// // log deviations +//// unsupportedFeatureCount=0; +//// testFailureCount=0; +//// +//// /* Test the device */ +//// for(test_index = 0; test_index < __test_function_count; test_index++) { +//// /* Invoke each of the test functions against this device */ +//// __test_functions[test_index](device_ids[i], &unsupportedFeatureCount, &testFailureCount); +//// } +//// +//// /* Close the device */ +//// printf("\tAttempting to close:\n"); +//// sbapi_close_device(device_ids[i], &error); +//// printf("\t\tResult is (%d) [%s]\n", flag, sbapi_get_error_string(error)); +//// printf("%d: Device 0x%02lX: \n\tNumber of unsupported features = %d\n\tNumber of test failures = %d\n", i, device_ids[i], unsupportedFeatureCount, testFailureCount); +// } +// +// flag = sbapi_get_device_type(device_ids[i], &error, nameBuffer, 79); +// +// return 1; +//} + +//ر豸 +void OceanOptics_lib::Close() +{ + int flag; + int error; + + flag = seabreeze_close_spectrometer(m_iSpectralmeterHandle, &error); + // printf("Close spectrometer result is (%d) [%s]\n", flag, get_error_string(error)); +} + +//ݲɼ +int OceanOptics_lib::SingleShot(DataFrame &dfData) +{ + if (m_iSpectralmeterHandle == -100) + { + printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + + int error; + int flag; + int spec_length; + double *spectrum = 0; + bool ret; + + // printf("\n\nGetting formatted spectrum length.\n"); + spec_length = seabreeze_get_formatted_spectrum_length(m_iSpectralmeterHandle, &error); + //printf("Get formatted spectrum_length result is (%d) [%s]\n", spec_length, get_error_string(error)); + ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return 1; + } + + if (spec_length > 0) + { + spectrum = (double *)calloc((size_t)spec_length, sizeof(double)); + seabreeze_clear_buffer(m_iSpectralmeterHandle, &error); + + auto startTime = std::chrono::high_resolution_clock::now(); + + flag = seabreeze_get_formatted_spectrum(m_iSpectralmeterHandle, &error, spectrum, spec_length); + + auto endTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration fp_ms = endTime - startTime; + std::cout << "ɼʱΪ" << fp_ms.count() / 1000 << "s." << std::endl; + + // printf("Get formatted spectrum result is (%d) [%s]\n", flag, get_error_string(error)); + // printf("\tPixel value 20 is %1.2f\n", spectrum[20]); + ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return 1; + } + + for (int tmp = 0; tmp < spec_length; tmp++) + { + dfData.lData[tmp] = spectrum[tmp]; + } + + int exposureTimeInMS; + GetExposureTime(exposureTimeInMS); + dfData.usExposureTimeInMS = exposureTimeInMS; + + float temperature; + GetDeviceTemperature(temperature); + dfData.fTemperature = temperature; + + free(spectrum); + } + + return 0; +} + +//عʱ +int OceanOptics_lib::SetExposureTime(int iExposureTimeInMS) +{ + if (m_iSpectralmeterHandle == -100) + { + // printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + + int error; + + seabreeze_set_trigger_mode(m_iSpectralmeterHandle, &error, 0); // trigger to normal + seabreeze_set_integration_time_microsec(m_iSpectralmeterHandle, &error, iExposureTimeInMS * 1000); + printf("Set integration time result is [%s]\n", get_error_string(error)); + + bool ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return 1; + } + + m_iExposureTime = iExposureTimeInMS; + + + + // //---------------------------------------------------------------------------------------------------------------- + // int error; + // long *spectrometer_ids; + // int number_of_spectrometers; + // + // number_of_spectrometers = sbapi_get_number_of_spectrometer_features(m_iSpectralmeterHandle, &error); + // printf("\t\t\tResult is %d [%s]\n", number_of_spectrometers, sbapi_get_error_string(error)); + // spectrometer_ids = (long *)calloc(number_of_spectrometers, sizeof(long)); + // number_of_spectrometers = sbapi_get_spectrometer_features(m_iSpectralmeterHandle, &error, spectrometer_ids, number_of_spectrometers); + // printf("\t\t\tResult is %d [%s]\n", number_of_spectrometers, sbapi_get_error_string(error)); + // + // sbapi_spectrometer_set_integration_time_micros(m_iSpectralmeterHandle, spectrometer_ids[0], &error, iExposureTimeInMS*1000); + // printf("\t\t\t\tResult is [%s]\n", sbapi_get_error_string(error)); + + return 0; +} + +//ȡعʱ +int OceanOptics_lib::GetExposureTime(int &iExposureTimeInMS) +{ + if (m_iSpectralmeterHandle == -100) + { + printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + + iExposureTimeInMS = m_iExposureTime; + + return 0; +} + +//Ŀ¶ +int OceanOptics_lib::SetDeviceTemperature(float fTemperature) +{ + bool ret; + + if (m_iSpectralmeterHandle == -100) + { + printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + + int error; + + // printf("\nSetting TEC temperature to -5C\n"); + seabreeze_set_tec_temperature(m_iSpectralmeterHandle, &error, fTemperature); + // printf("Set tec temperature result is [%s]\n", get_error_string(error)); + ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return 1; + } + + + // printf("\nSetting TEC enable to true\n"); + seabreeze_set_tec_enable(m_iSpectralmeterHandle, &error, 1); + // printf("Set tec enable result is [%s]\n", get_error_string(error)); + ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return 1; + } + + return 0; +} + +//ȡ¶ +int OceanOptics_lib::GetDeviceTemperature(float &fTemperature) +{ + if (m_iSpectralmeterHandle == -100) + { + printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + + double temp; + int error; + + // usleep(1000000); + // printf("\nGetting TEC temperature\n"); + temp = seabreeze_read_tec_temperature(m_iSpectralmeterHandle, &error); + // printf("Read tec temperature result is %1.2f C [%s]\n", temp, get_error_string(error)); + bool ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return 1; + } + + fTemperature = temp; + + return 0; +} + +//ȡ豸Ϣ +int OceanOptics_lib::GetDeviceInfo(DeviceInfo &Info) +{ + if (m_iSpectralmeterHandle == -100) + { + printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + + string deviceType = GetDeviceType(m_iSpectralmeterHandle); + string SN = GetSerialNumber(m_iSpectralmeterHandle); + + Info.strPN = deviceType; + Info.strSN = SN; + + return 0; +} + +//ȡ豸 +int OceanOptics_lib::GetDeviceAttribute(DeviceAttribute &Attr) +{ + if (m_iSpectralmeterHandle == -100) + { + printf("\nNo!!!!!!!!!!!!\n"); + return 1; + } + + int error; + int flag; + int spec_length; + double *wls = 0; + + // printf("\n\nGetting formatted spectrum length.\n"); + spec_length = seabreeze_get_formatted_spectrum_length(m_iSpectralmeterHandle, &error); + // printf("Get formatted spectrum length result is (%d) [%s]\n", spec_length, get_error_string(error)); + bool ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return 1; + } + + Attr.iPixels = spec_length; + + long minimum_time; + minimum_time = seabreeze_get_min_integration_time_microsec(m_iSpectralmeterHandle, &error); + Attr.iMinIntegrationTimeInMS = minimum_time; + Attr.iMaxIntegrationTimeInMS = 60000; + + if (spec_length > 0) { + wls = (double *)calloc((size_t)spec_length, sizeof(double)); + + // printf("\nGetting wavelengths.\n"); + flag = seabreeze_get_wavelengths(m_iSpectralmeterHandle, &error, wls, spec_length); + // printf("Get wavelengths result is (%d) [%s]\n", flag, get_error_string(error)); + // printf("\tPixel 20 is wavelength %1.2f nm\n", wls[20]); + bool ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return 1; + } + + for (int tmp = 0; tmp < spec_length; tmp++) + { + Attr.fWaveLengthInNM[tmp] = wls[tmp]; + } + + free(wls); + } + + return 0; +} + +bool OceanOptics_lib::isSuccess(char* resultStr) +{ + if (strstr(resultStr, "Success") == NULL)//aвbڣ + { + //cout << "not found\n";// + return false; + } + else//ڡ + { + //cout <<"found\n"; // + return true; + } +} + +const char* OceanOptics_lib::get_error_string(int error) +{ + static char buffer[32]; + seabreeze_get_error_string(error, buffer, sizeof(buffer)); + return buffer; +} + +string OceanOptics_lib::GetDeviceType(int index) +{ + char type[16]; + int error; + + seabreeze_get_model(index, &error, type, sizeof(type)); + // printf("...Result is (%s) [%s]\n", type, get_error_string(error)); + bool ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return ""; + } + + type[15] = '\0'; + + string deviceType = type; + + return deviceType; +} + +string OceanOptics_lib::GetSerialNumber(int index) +{ + static char serial_number[32];//static˱ᶨstackغ󣬾 + int flag; + int error; + + // printf("\n\nGetting serial number.\n"); + flag = seabreeze_get_serial_number(index, &error, serial_number, 32); + // printf("Get serial number result is (%d) [%s]\n", flag, get_error_string(error)); + bool ret = isSuccess((char*)get_error_string(error)); + if (!ret) + { + return ""; + } + + serial_number[31] = '\0'; + if (flag > 0) { + printf("\tSerial number: [%s]\n", serial_number); + } + + string sn = serial_number; + + return sn; +} + + diff --git a/othersoft/calibration_console/Source_Files/main.cpp b/othersoft/calibration_console/Source_Files/main.cpp new file mode 100644 index 0000000..d1a433e --- /dev/null +++ b/othersoft/calibration_console/Source_Files/main.cpp @@ -0,0 +1,444 @@ +#include +#include +#include +#include + +#include + +#include "Header_Files/oceanOpticsFiberImager.h" +#include "Header_Files/atpFiberImager.h" +#include "Header_Files/calibration.h" + +enum CommandLineParseResult +{ + CommandLineOk, + CommandLineError, + CommandLineVersionRequested, + CommandLineHelpRequested +}; + +enum DeviceType +{ + OPTOSKY, + OceanOptics, + UnknownDevice +}; + +struct TcQuery +{ + DeviceType deviceType; + QString serialPort; + + int sleepTimeinSecond;//Ĭֵ + int averageTimes; + int position; + + QString calFileOutputDirectory;//Ĭֵ + QString calFileOutputName; + QString standardLightFilePath; + + bool justRecord; +}; + +CommandLineParseResult parseCommandLine2(QCommandLineParser &parser, TcQuery *query, QString *errorMessage); +bool copyFileToPath(QString sourceDir ,QString toDir, bool coverFileIfExist); +void logout(QString str); +void createDirectory(QString fullPath); +bool isFileExist(QString fullFileName); + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + QCoreApplication::setApplicationName("Ocean optics radiance calibration software"); + QCoreApplication::setApplicationVersion("1.0"); + + // в + QCommandLineParser parser; + parser.setApplicationDescription("This software is used for doing radiance calibration for ocean optics fiber imager."); + TcQuery query; + QString errorMessage; + + switch (parseCommandLine2(parser, &query, &errorMessage)) + { + case CommandLineOk: + break; + case CommandLineError: + fputs(qPrintable(errorMessage), stderr); + fputs("\n\n", stderr); + fputs(qPrintable(parser.helpText()), stderr); + return 1; + case CommandLineVersionRequested: + printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), + qPrintable(QCoreApplication::applicationVersion())); + return 0; + case CommandLineHelpRequested: + parser.showHelp(); + Q_UNREACHABLE(); + } + + + //Ƕ + FiberSpectrometerOperationBase * m_FiberSpectrometer; + switch (query.deviceType) + { + case OPTOSKY: + m_FiberSpectrometer = new ATPFiberImager(false,"ttyUSB0","ocean_optics"); + break; + case OceanOptics: + m_FiberSpectrometer = new OceanOpticsFiberImager(); + break; + case UnknownDevice: + parser.showHelp(); + Q_UNREACHABLE(); + } + + //ӹ + QString SN; + QString pixelCount; + QString wavelengthInfo; + logout("
Connectting the fiber spectrometer!"); + m_FiberSpectrometer->connectFiberSpectrometer(SN, pixelCount, wavelengthInfo); + + //Զع + logout("
AutoExpose!"); +// m_FiberSpectrometer->autoExpose(); + + + //sleepȴرտ + logout("
Wait for close the lamp!"); + QThread::sleep(query.sleepTimeinSecond); + + //ɼ֡ + logout("
Record dark frame!"); + m_FiberSpectrometer->recordDark(query.calFileOutputDirectory); + + + //sleepȴ򿪿 + logout("
Wait for open the lamp!"); + QThread::sleep(query.sleepTimeinSecond); + + //ɼ + logout("
Record integrating sphere frame!"); + m_FiberSpectrometer->recordTarget(query.averageTimes, query.calFileOutputDirectory); + + //׼ļ + DeviceAttribute deviceAttribute; + DeviceInfo deviceInfo; + m_FiberSpectrometer->getDeviceAttribute(deviceAttribute); + m_FiberSpectrometer->getDeviceInfo(deviceInfo); + + CalibrationAlgorithm * m_CalibrationAlgorithm = new CalibrationAlgorithm(); + m_CalibrationAlgorithm->readFile(query.standardLightFilePath, deviceAttribute, deviceInfo);// + + //ɷ䶨ļ + if (query.calFileOutputName.isEmpty())//query->calFileOutputName=="" + { + QDateTime curDateTime = QDateTime::currentDateTime(); + QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); + QString calFileName = QDir::cleanPath(query.calFileOutputDirectory + QDir::separator() + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + ".dat"); + + query.calFileOutputName=calFileName; + } + logout("
Produce calibration file!"); + m_CalibrationAlgorithm->produceCalfile(query.calFileOutputName, deviceAttribute, m_FiberSpectrometer->m_IntegratingSphereData, m_FiberSpectrometer->m_DarkData); + + //Ʒ䶨ļ + QDateTime curDateTime = QDateTime::currentDateTime(); + QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); + QString destName = QDir::cleanPath(query.calFileOutputDirectory + QDir::separator() + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_" +QString::number(query.position) + ".dat"); + copyFileToPath(query.calFileOutputName,destName,true); + + //Ͽ + m_FiberSpectrometer->disconnectFiberSpectrometer(); + //return a.exec(); +} + +CommandLineParseResult parseCommandLine2(QCommandLineParser &parser, TcQuery *query, QString *errorMessage) +{ + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + + QCommandLineOption deviceType("deviceType", "Device type. Options are OPTOSKY and OceanOptics", "deviceType"); + parser.addOption(deviceType); + + QCommandLineOption serialPort("serialPort", "Serial port.", "serialPort"); + parser.addOption(serialPort); + + QCommandLineOption sleepTimeinSecond("t", "The time app sleep.", "sleepTimeinSecond"); + sleepTimeinSecond.setDefaultValue("30");//Ĭϲ + parser.addOption(sleepTimeinSecond); + + QCommandLineOption averageTimes("a", "Average times.", "average_times"); + averageTimes.setDefaultValue("5");//Ĭϲ + parser.addOption(averageTimes); + + QCommandLineOption position("position", "Position.", "position"); + parser.addOption(position); + +// parser.addPositionalArgument("name", "The name to look up.");//???????????????????????????????????????????????????????????????????????????? + QCommandLineOption helpOption = parser.addHelpOption();//Adds the help option (-h, --help and -? on Windows) This option is handled automatically by QCommandLineParser. + QCommandLineOption versionOption = parser.addVersionOption();//This option is handled automatically by QCommandLineParser. + + + //// A boolean option with a single name (-p) + //QCommandLineOption showProgressOption("p", QCoreApplication::translate("main", "Show progress during copy")); + //parser.addOption(showProgressOption); + + // A boolean option with multiple names (-r, --record) + QCommandLineOption recordOption(QStringList() << "f" << "record", + QCoreApplication::translate("main", "Just record one spectral.")); + parser.addOption(recordOption); + + + //׼ļ + QCommandLineOption standardLightFilePath(QStringList() << "slfp" << "standard-light-file-path", + QCoreApplication::translate("main", "set standard light file."), + QCoreApplication::translate("main", "file")); + parser.addOption(standardLightFilePath); + + QCommandLineOption standardLightFileSelector(QStringList() << "slfs" << "standard-light-file-selector", + QCoreApplication::translate("main", "select standard light file."), + QCoreApplication::translate("main", "file")); + parser.addOption(standardLightFileSelector); + + + //ļ· + // An option with a value + QCommandLineOption calFileOutputDirectory(QStringList() << "cfod" << "calibration-file-output-directory", + QCoreApplication::translate("main", "Save cal file into ."), + QCoreApplication::translate("main", "directory")); +// QString tmpPath1 = QDir::cleanPath(QDir::rootPath() + QDir::separator()+"calFile"); + QString tmpPath1 = "/home/data/Cal/"; + calFileOutputDirectory.setDefaultValue(tmpPath1);//ĬϲQCoreApplication::applicationDirPath()standardLightFile + parser.addOption(calFileOutputDirectory); + + //ļļ + // An option with a value + QCommandLineOption calFileOutputName(QStringList() << "cfon" << "calibration-file-output-name", + QCoreApplication::translate("main", "Cal file name."), + QCoreApplication::translate("main", "fileName")); + parser.addOption(calFileOutputName); + + + + + + + + + + if (!parser.parse(QCoreApplication::arguments()))//Process the actual command line arguments given by the user + { + *errorMessage = parser.errorText(); + return CommandLineError; + } + + if (parser.isSet(versionOption)) + return CommandLineVersionRequested; + + if (parser.isSet(helpOption)) + return CommandLineHelpRequested; + + if (parser.isSet(deviceType)) + { + const QString deviceTypeTmp = parser.value(deviceType); + + if (deviceTypeTmp=="OPTOSKY") + { + query->deviceType = OPTOSKY; + } + else if(deviceTypeTmp=="OceanOptics") + { + query->deviceType = OceanOptics; + } + else + { + *errorMessage = "DeviceType set error."; + return CommandLineError; + } + + } + else//Ĭϲ + { + *errorMessage = "No deviceType set."; + return CommandLineError; + } + + if (parser.isSet(serialPort)) + { + const QString serialPortTmp = parser.value(serialPort); + query->serialPort = serialPortTmp; + } + else//Ĭϲ + { + if (query->deviceType == OceanOptics) + { + ; + } else if (query->deviceType == OPTOSKY) + { + *errorMessage = "No serialPort set."; + return CommandLineError; + } + } + + if (parser.isSet(sleepTimeinSecond)) + { + const QString timeTmp = parser.value(sleepTimeinSecond); + query->sleepTimeinSecond = timeTmp.toInt(); + } + else//Ĭϲ + { + QStringList tmp = sleepTimeinSecond.defaultValues(); + query->sleepTimeinSecond = tmp[0].toInt(); + } + + if (parser.isSet(averageTimes)) + { + const QString averageTimesTmp = parser.value(averageTimes); + + string tttt=averageTimesTmp.toStdString(); + + query->averageTimes = averageTimesTmp.toInt(); + } + else//Ĭϲ + { + QStringList tmp = averageTimes.defaultValues(); + query->averageTimes = tmp[0].toInt(); + } + + if (parser.isSet(position)) + { + const QString positionTmp = parser.value(position); + query->position = positionTmp.toInt(); + } + else + { + *errorMessage = "No position set."; + return CommandLineError; + } + + query->justRecord = parser.isSet(recordOption); + + + if (!parser.isSet(standardLightFilePath) && !parser.isSet(standardLightFileSelector))//ûö걣ļ· + { + *errorMessage = "No standard light file set."; + return CommandLineError; + } + + if (parser.isSet(standardLightFileSelector))// + { + QString selector = parser.value(standardLightFileSelector); +// QString standardLightFilePath_tmp = QDir::cleanPath(QDir::rootPath() + QDir::separator() + "standardLightFile" + QDir::separator() + selector); + + QString tmp = "/home/data/Setting/standardLightFile"; + QString standardLightFilePath_tmp = tmp + QDir::separator() + selector; + + //ж϶ļǷ + if (!isFileExist(standardLightFilePath_tmp)) + { + *errorMessage = "No standard light file set."; + return CommandLineError; + } + + query->standardLightFilePath = standardLightFilePath_tmp; + } + + if (parser.isSet(standardLightFilePath))// + { + query->standardLightFilePath = parser.value(standardLightFilePath); + } + + + if (parser.isSet(calFileOutputDirectory))//걣ļ· + { + query->calFileOutputDirectory = parser.value(calFileOutputDirectory); + createDirectory(query->calFileOutputDirectory);//ļв 򴴽 + } + else//Ĭϲ + { + QStringList tmp = calFileOutputDirectory.defaultValues(); + QString directory = tmp[0]; + + createDirectory(directory);//ļв 򴴽 + + query->calFileOutputDirectory = directory; + } + + if (parser.isSet(calFileOutputName))//------- + { + QString calFileOutputNameTmp = QDir::cleanPath(query->calFileOutputDirectory + QDir::separator() + parser.value(calFileOutputName)); + query->calFileOutputName = calFileOutputNameTmp; + } + else//Ĭϲ + { + query->calFileOutputName = ""; + } + +// const QStringList positionalArguments = parser.positionalArguments(); +// if (positionalArguments.isEmpty()) +// { +// *errorMessage = "Argument 'name' missing."; +// return CommandLineError; +// } +// if (positionalArguments.size() > 1) +// { +// *errorMessage = "Several 'name' arguments specified."; +// return CommandLineError; +// } + + return CommandLineOk; +} + +bool copyFileToPath(QString sourceDir ,QString toDir, bool coverFileIfExist) +{ + toDir.replace("\\","/"); + if (sourceDir == toDir){ + return true; + } + if (!QFile::exists(sourceDir)){ + return false; + } + QDir *createfile = new QDir; + bool exist = createfile->exists(toDir); + if (exist){ + if(coverFileIfExist){ + createfile->remove(toDir); + } + }//end if + + if(!QFile::copy(sourceDir, toDir)) + { + return false; + } + return true; +} + +void logout(QString str) +{ + std::cout << str.toStdString() << "
"; + std::fflush(stdout); +} + +void createDirectory(QString fullPath)// +{ + QDir dir(fullPath); + if (dir.exists()) + { + return; + } + else + { + bool ok = dir.mkdir(fullPath);//ֻһĿ¼뱣֤ϼĿ¼ + return; + } +} + +bool isFileExist(QString fullFileName) +{ + QFileInfo fileInfo(fullFileName); + if (fileInfo.isFile()) + { + return true; + } + return false; +} diff --git a/othersoft/calibration_console/Source_Files/oceanOpticsFiberImager.cpp b/othersoft/calibration_console/Source_Files/oceanOpticsFiberImager.cpp new file mode 100644 index 0000000..a473476 --- /dev/null +++ b/othersoft/calibration_console/Source_Files/oceanOpticsFiberImager.cpp @@ -0,0 +1,244 @@ +#include "Header_Files/oceanOpticsFiberImager.h" + +OceanOpticsFiberImager::OceanOpticsFiberImager() +{ + m_FiberSpectrometer = NULL; +} + +OceanOpticsFiberImager::~OceanOpticsFiberImager() +{ + +} + +void OceanOpticsFiberImager::connectFiberSpectrometer(QString& SN, QString& pixelCount, QString& wavelengthInfo) +{ + using namespace std; + + m_FiberSpectrometer = new OceanOptics_lib(); + + m_FiberSpectrometer->Initialize(); + + DeviceInfo deviceInfo; + DeviceAttribute deviceAttribute; + + m_FiberSpectrometer->GetDeviceInfo(deviceInfo); + m_FiberSpectrometer->GetDeviceAttribute(deviceAttribute); + + SN = QString::fromStdString(deviceInfo.strSN); + pixelCount = QString::number(deviceAttribute.iPixels); + wavelengthInfo = QString::number(deviceAttribute.fWaveLengthInNM[0]) + "--" + QString::number(deviceAttribute.fWaveLengthInNM[deviceAttribute.iPixels - 1]); + + m_FiberSpectrometer->SetDeviceTemperature(-10); + + + //dnֵֵλأ + string qepro = "QEP"; + string flame = "FLMS"; + if (deviceInfo.strSN.find(qepro) != string::npos) + { + m_MaxValueOfFiberSpectrometer = 200000; + } + else if (deviceInfo.strSN.find(flame) != string::npos) + { + m_MaxValueOfFiberSpectrometer = 65535; + } + else//ûҵƥ dnֵֵ + { + + } +} + +void OceanOpticsFiberImager::disconnectFiberSpectrometer() +{ + m_FiberSpectrometer->Close(); +} + +void OceanOpticsFiberImager::getDeviceAttribute(DeviceAttribute& deviceAttribute) +{ + m_FiberSpectrometer->GetDeviceAttribute(deviceAttribute); +} + +void OceanOpticsFiberImager::getDeviceInfo(DeviceInfo& deviceInfo) +{ + m_FiberSpectrometer->GetDeviceInfo(deviceInfo); +} + +void OceanOpticsFiberImager::setExposureTime(int iExposureTimeInMS) +{ + m_FiberSpectrometer->SetExposureTime(iExposureTimeInMS); +} + +void OceanOpticsFiberImager::getExposureTime(int &iExposureTimeInMS) +{ + m_FiberSpectrometer->GetExposureTime(iExposureTimeInMS); +} + +void OceanOpticsFiberImager::getDeviceTemperature(float &fTemperature) +{ + m_FiberSpectrometer->GetDeviceTemperature(fTemperature); +} + +void OceanOpticsFiberImager::singleShot(DataFrame &dfData) +{ + m_FiberSpectrometer->SingleShot(dfData); +} + +void OceanOpticsFiberImager::recordDark(QString path) +{ + //ȡ豸Ϣ + DeviceAttribute attribute; + DeviceInfo deviceInfo; + getDeviceAttribute(attribute); + getDeviceInfo(deviceInfo); + + //ɼ֡ + singleShot(m_DarkData); + + QDateTime curDateTime = QDateTime::currentDateTime(); + QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); + + QString fileName = path + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_darkSpectral.csv"; + std::ofstream outfile(fileName.toStdString().c_str()); + + for (int i = 0; i < attribute.iPixels; i++) + { + if (i==0) + { + outfile << m_DarkData.usExposureTimeInMS << std::endl; + } + outfile << attribute.fWaveLengthInNM[i] << "," << m_DarkData.lData[i] << std::endl; + } + + outfile.close(); +} + +void OceanOpticsFiberImager::recordTarget(int recordTimes, QString path) +{ + //ȡ豸Ϣ + DeviceAttribute attribute; + DeviceInfo deviceInfo; + getDeviceAttribute(attribute); + getDeviceInfo(deviceInfo); + + + DataFrame integratingSphereData_tmp; + + for (int i = 0; i < recordTimes; i++) + { + singleShot(integratingSphereData_tmp); + + if (i == 0)//integratingSphereData_tmpеعʱ䡢¶ȵϢm_IntegratingSphereData + { + m_IntegratingSphereData = integratingSphereData_tmp; + } + else + { + for (int i = 0; i < attribute.iPixels; i++) + { + m_IntegratingSphereData.lData[i] += integratingSphereData_tmp.lData[i]; + } + } + + } + + for (int i = 0; i < attribute.iPixels; i++) + { + m_IntegratingSphereData.lData[i] = m_IntegratingSphereData.lData[i] / recordTimes; + } + + QDateTime curDateTime = QDateTime::currentDateTime(); + QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss"); + + QString fileName = path + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_integratingSphereSpectral.csv"; + std::ofstream outfile(fileName.toStdString().c_str()); + + for (int i = 0; i < attribute.iPixels; i++) + { + if (i==0) + { + outfile << m_IntegratingSphereData.usExposureTimeInMS << std::endl; + } + outfile << attribute.fWaveLengthInNM[i] << "," << m_IntegratingSphereData.lData[i] << std::endl; + } + + outfile.close(); +} + +void OceanOpticsFiberImager::autoExpose() +{ + DeviceAttribute attribute; + getDeviceAttribute(attribute); + + int iterations = 0;//¼ԶعѾĴ + int maxIterations = 10;//ĵ + + ZZ_U32 thresholdValue = m_MaxValueOfFiberSpectrometer * 0.8;//Ϊ80% + ZZ_U16 range = 10000; + + //óʼعʱ + int exposureTimeInMS = 200; + setExposureTime(exposureTimeInMS); + emit sendExposureTimeSignal(exposureTimeInMS); + + DataFrame integratingSphereData_tmp; + while (true) + { + if (iterations > maxIterations)//Ƿ񳬹 + { + break; + } + + singleShot(integratingSphereData_tmp); + ZZ_S32 maxValue = GetMaxValue(integratingSphereData_tmp.lData, attribute.iPixels); + + if (maxValue < thresholdValue && maxValue < (thresholdValue - range))//عʱС + { + double scale = 1 + ((double)(thresholdValue - maxValue) / (double)thresholdValue); + + int exposureTime; + m_FiberSpectrometer->GetExposureTime(exposureTime); + m_FiberSpectrometer->SetExposureTime(exposureTime * scale); + + emit sendExposureTimeSignal(exposureTime); + + ZZ_S32 m = GetMaxValue(integratingSphereData_tmp.lData, attribute.iPixels); + + std::cout << "Զع-----------" << "ֵΪ" << m << std::endl; + } + else if (maxValue > thresholdValue && maxValue > (thresholdValue + range))//عʱ + { + double scale = 1 - ((double)(maxValue - thresholdValue) / (double)thresholdValue); + + int exposureTime; + m_FiberSpectrometer->GetExposureTime(exposureTime); + m_FiberSpectrometer->SetExposureTime(exposureTime * scale); + + emit sendExposureTimeSignal(exposureTime); + + ZZ_S32 m = GetMaxValue(integratingSphereData_tmp.lData, attribute.iPixels); + + std::cout << "Զع-----------" << "ֵΪ" << m << std::endl; + } + else//ҵعʱ䣬whileѭ + { + break; + } + + iterations++; + } + +} + +ZZ_S32 OceanOpticsFiberImager::GetMaxValue(ZZ_S32 * dark, int number) +{ + ZZ_S32 max = 0; + for (size_t i = 0; i < number; i++) + { + if (dark[i] > max) + { + max = dark[i]; + } + } + //std::cout << "ֵ֡Ϊ" << max << std::endl; + return max; +} \ No newline at end of file