468 lines
14 KiB
Rust
468 lines
14 KiB
Rust
use super::spectralbase;
|
|
use super::spectralbase::*;
|
|
use super::super::mydefine::*;
|
|
use lazy_static::lazy_static;
|
|
use chrono::{self, Datelike, Timelike};
|
|
use std::thread;
|
|
use std::fs::File;
|
|
use std::mem;
|
|
use std::path::Path;
|
|
use std::io::Read;
|
|
#[derive(PartialEq)]
|
|
enum WorkStat {
|
|
IDLE,
|
|
WOKING,
|
|
STOP,
|
|
OPTING,
|
|
|
|
}
|
|
|
|
|
|
use std::vec;
|
|
use std::{
|
|
sync::{Arc, Mutex},
|
|
};
|
|
struct is11_dev_data {
|
|
sensor_info: super::spectralbase::STRSensorInfo,
|
|
shuttertime: i32,
|
|
stat: WorkStat,
|
|
percent: i32,
|
|
workname: String,
|
|
hasdark: bool,
|
|
hasflat: bool,
|
|
removedark: bool,
|
|
computeflat: bool,
|
|
average_number_data: u32,
|
|
average_number_dark: u32,
|
|
average_number_flat: u32,
|
|
has_CalidataUP: bool,
|
|
|
|
}
|
|
|
|
lazy_static! {
|
|
static ref DEV_STAT: Arc<Mutex<is11_dev_data>> = Arc::new(Mutex::new(is11_dev_data {
|
|
sensor_info: super::spectralbase::STRSensorInfo::default(),
|
|
shuttertime: 0,
|
|
stat: WorkStat::IDLE,
|
|
percent: 0,
|
|
workname: "noting".to_string(),
|
|
hasdark: false,
|
|
hasflat: false,
|
|
removedark: false,
|
|
computeflat: true,
|
|
average_number_data: 1,
|
|
average_number_dark: 10,
|
|
average_number_flat: 10,
|
|
has_CalidataUP: false,
|
|
|
|
}));
|
|
}
|
|
|
|
|
|
// lazy_static! {
|
|
// static ref DATA: Arc<Mutex<Vec<u16>>> = Arc::new(Mutex::new(Vec::new()));
|
|
// }
|
|
|
|
lazy_static! {
|
|
static ref DATA_IS11: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
|
static ref DARK_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
|
static ref FLAT_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
|
static ref CALIDATAUP: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
|
static ref CALIOFFSETUP: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
|
|
}
|
|
|
|
|
|
|
|
pub fn is11_get_sensor_info() -> STRSensorInfo {
|
|
return super::spectralbase::sensor_get_sensor_info();
|
|
}
|
|
pub fn is11_init(){
|
|
super::spectralbase::sensor_init();
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
let sensorinfo= is11_get_sensor_info();
|
|
dev_stat.sensor_info=sensorinfo;
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn get_shuttertime() -> i32 {
|
|
let dev_stat=DEV_STAT.lock().unwrap();
|
|
return dev_stat.shuttertime;
|
|
}
|
|
|
|
|
|
pub fn opt_sensor(percent: i32) -> i32 {
|
|
|
|
|
|
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
if dev_stat.stat != WorkStat::IDLE {
|
|
return -1;
|
|
}
|
|
|
|
dev_stat.stat=WorkStat::OPTING;
|
|
dev_stat.percent=0;
|
|
dev_stat.workname="opting".to_string();
|
|
drop(dev_stat); //释放锁
|
|
thread::spawn(move || {
|
|
|
|
let shuttertime= super::spectralbase::sensor_opt_sensor(90); //多线程设置曝光时间
|
|
let mut dev_statnow=DEV_STAT.lock().unwrap();
|
|
dev_statnow.stat=WorkStat::IDLE;
|
|
dev_statnow.shuttertime=shuttertime;
|
|
dev_statnow.workname="finish".to_string();
|
|
dev_statnow.percent=100;
|
|
dev_statnow.hasdark=false;
|
|
dev_statnow.hasflat=false;
|
|
}
|
|
);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
pub fn get_now_stat()->(String,String,i32){
|
|
|
|
|
|
let dev_stat=DEV_STAT.lock().unwrap();
|
|
match dev_stat.stat {
|
|
WorkStat::IDLE => {
|
|
return ("finish".to_string(),dev_stat.workname.clone(),100);
|
|
},
|
|
WorkStat::WOKING => {
|
|
return ("working".to_string(),dev_stat.workname.clone(),dev_stat.percent);
|
|
},
|
|
WorkStat::STOP => {
|
|
return ("finish".to_string(),dev_stat.workname.clone(),dev_stat.percent);
|
|
},
|
|
WorkStat::OPTING => {
|
|
return ("opting".to_string(),dev_stat.workname.clone(),dev_stat.percent);
|
|
},
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
pub fn collect(shuttertime:u32,removedark:bool,computeflat:bool){
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
if dev_stat.stat != WorkStat::IDLE {
|
|
return ;
|
|
}
|
|
|
|
let averagenumber=dev_stat.average_number_data;
|
|
dev_stat.stat=WorkStat::WOKING;
|
|
dev_stat.percent=0;
|
|
|
|
dev_stat.workname="采集中".to_string();
|
|
let bandsunm=dev_stat.sensor_info.BandNum as usize;
|
|
drop(dev_stat); //释放锁
|
|
thread::spawn(move || {
|
|
|
|
|
|
let mut datasum:Vec<u32>=vec![0;bandsunm];
|
|
for _i in 0..averagenumber {
|
|
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
|
|
for i in 0..bandsunm {
|
|
datasum[i]=datasum[i]+data[i] as u32;
|
|
}
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
let info=format!("采集中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
|
|
dev_stat.workname=info;
|
|
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
|
|
drop(dev_stat); //释放锁
|
|
|
|
|
|
}
|
|
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
let _lenth=data.len();
|
|
println!("data len={}",_lenth);
|
|
let mut tempis11data=IS11DataStruct::default();
|
|
for i in 0.._lenth {
|
|
tempis11data.data[i]=data[i] as f32;
|
|
}
|
|
// 获取当前时间
|
|
let now = chrono::Local::now();
|
|
tempis11data.year=(now.year()-2000) as u8;
|
|
tempis11data.month=now.month() as u8;
|
|
tempis11data.day=now.day() as u8;
|
|
tempis11data.hour=now.hour() as u8;
|
|
tempis11data.minute=now.minute() as u8;
|
|
tempis11data.second=now.second() as u8;
|
|
tempis11data.shutter_time=shuttertime;
|
|
tempis11data.index=0;
|
|
tempis11data.datatype=0;
|
|
|
|
let mut data1=DATA_IS11.lock().unwrap();
|
|
let darkdata=DARK_DATA.lock().unwrap();
|
|
*data1=tempis11data;
|
|
if removedark && dev_stat.hasdark {
|
|
|
|
for i in 0.._lenth {
|
|
data1.data[i]=data1.data[i]-darkdata.data[i];
|
|
|
|
}
|
|
}
|
|
|
|
if computeflat && dev_stat.hasflat {
|
|
let flatdata=FLAT_DATA.lock().unwrap();
|
|
for i in 0.._lenth {
|
|
|
|
let temp=flatdata.data[i]-darkdata.data[i];
|
|
if temp<=0.0 {
|
|
data1.data[i]=10000.0;
|
|
}else{
|
|
data1.data[i]=data1.data[i]/temp*10000.0;
|
|
}
|
|
if data1.data[i]<0.0 {
|
|
data1.data[i]=0.0;
|
|
|
|
}
|
|
if data1.data[i]>15000.0 {
|
|
data1.data[i]=15000.0;
|
|
}
|
|
|
|
// data1.data[i]=data1.data[i]/(flatdata.data[i]-darkdata.data[i])*10000.0;
|
|
}
|
|
}
|
|
|
|
|
|
dev_stat.stat=WorkStat::IDLE;
|
|
dev_stat.percent=100;
|
|
dev_stat.workname="finish".to_string();
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
pub fn collcect_dark(shuttertime:u32)
|
|
{
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
if dev_stat.stat != WorkStat::IDLE {
|
|
return ;
|
|
}
|
|
let averagenumber=dev_stat.average_number_dark;
|
|
dev_stat.stat=WorkStat::WOKING;
|
|
dev_stat.percent=0;
|
|
dev_stat.workname="采集Dark中".to_string();
|
|
let bandsunm=dev_stat.sensor_info.BandNum as usize;
|
|
drop(dev_stat); //释放锁
|
|
thread::spawn(move || {
|
|
let mut datasum:Vec<u32>=vec![0;bandsunm];
|
|
sensor_set_shutter_open(0);
|
|
for _i in 0..averagenumber {
|
|
|
|
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
|
|
for i in 0..bandsunm {
|
|
datasum[i]=datasum[i]+data[i] as u32;
|
|
}
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
let info=format!("采集Dark中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
|
|
dev_stat.workname=info;
|
|
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
|
|
drop(dev_stat); //释放锁
|
|
}
|
|
sensor_set_shutter_open(1);
|
|
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
|
|
|
|
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
let _lenth=data.len();
|
|
println!("data len={}",_lenth);
|
|
let mut tempis11data=IS11DataStruct::default();
|
|
for i in 0.._lenth {
|
|
tempis11data.data[i]=data[i] as f32;
|
|
}
|
|
//获取当前时间
|
|
let now = chrono::Local::now();
|
|
tempis11data.year=(now.year()-2000) as u8;
|
|
tempis11data.month=now.month() as u8;
|
|
tempis11data.day=now.day() as u8;
|
|
tempis11data.hour=now.hour() as u8;
|
|
tempis11data.minute=now.minute() as u8;
|
|
tempis11data.second=now.second() as u8;
|
|
tempis11data.shutter_time=shuttertime;
|
|
tempis11data.index=0;
|
|
tempis11data.datatype=0;
|
|
|
|
let mut data1=DARK_DATA.lock().unwrap();
|
|
*data1=tempis11data;
|
|
dev_stat.stat=WorkStat::IDLE;
|
|
dev_stat.percent=100;
|
|
dev_stat.workname="finish".to_string();
|
|
dev_stat.hasdark=true;
|
|
});
|
|
|
|
|
|
}
|
|
|
|
pub fn collcect_flat(shuttertime:u32)
|
|
{
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
if dev_stat.stat != WorkStat::IDLE {
|
|
return ;
|
|
}
|
|
let averagenumber=dev_stat.average_number_flat;
|
|
dev_stat.stat=WorkStat::WOKING;
|
|
dev_stat.percent=0;
|
|
dev_stat.workname="采集中".to_string();
|
|
let bandsunm=dev_stat.sensor_info.BandNum as usize;
|
|
drop(dev_stat); //释放锁
|
|
thread::spawn(move || {
|
|
let mut datasum:Vec<u32>=vec![0;bandsunm];
|
|
for _i in 0..averagenumber {
|
|
let data=super::spectralbase::sensor_get_data(shuttertime as i32);
|
|
for i in 0..bandsunm {
|
|
datasum[i]=datasum[i]+data[i] as u32;
|
|
}
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
let info=format!("采集白板中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
|
|
dev_stat.workname=info;
|
|
dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
|
|
drop(dev_stat); //释放锁
|
|
}
|
|
let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
|
|
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
let _lenth=data.len();
|
|
println!("data len={}",_lenth);
|
|
let mut tempis11data=IS11DataStruct::default();
|
|
for i in 0.._lenth {
|
|
tempis11data.data[i]=data[i] as f32;
|
|
}
|
|
//获取当前时间
|
|
let now = chrono::Local::now();
|
|
tempis11data.year=(now.year()-2000) as u8;
|
|
tempis11data.month=now.month() as u8;
|
|
tempis11data.day=now.day() as u8;
|
|
tempis11data.hour=now.hour() as u8;
|
|
tempis11data.minute=now.minute() as u8;
|
|
tempis11data.second=now.second() as u8;
|
|
tempis11data.shutter_time=shuttertime;
|
|
tempis11data.index=0;
|
|
tempis11data.datatype=0;
|
|
|
|
let mut data1=FLAT_DATA.lock().unwrap();
|
|
*data1=tempis11data;
|
|
dev_stat.stat=WorkStat::IDLE;
|
|
dev_stat.percent=100;
|
|
dev_stat.workname="finish".to_string();
|
|
dev_stat.hasflat=true;
|
|
});
|
|
}
|
|
|
|
|
|
pub fn get_data()->IS11DataStruct{
|
|
let data1=DATA_IS11.lock().unwrap();
|
|
return data1.clone();
|
|
}
|
|
pub fn get_data_flat()->IS11DataStruct{
|
|
let data1=FLAT_DATA.lock().unwrap();
|
|
return data1.clone();
|
|
}
|
|
pub fn get_data_dark()->IS11DataStruct{
|
|
let data1=DARK_DATA.lock().unwrap();
|
|
return data1.clone();
|
|
}
|
|
pub fn get_is_computeref()->bool{
|
|
let dev_stat=DEV_STAT.lock().unwrap();
|
|
return dev_stat.computeflat;
|
|
}
|
|
|
|
pub fn set_shutter_time(shuttertime:u32){
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
dev_stat.shuttertime=shuttertime as i32;
|
|
dev_stat.hasdark=false;
|
|
dev_stat.hasflat=false;
|
|
}
|
|
|
|
|
|
pub fn set_average_number(arverage_number_data:u32,arverage_number_dark:u32,arverage_number_flat:u32){
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
dev_stat.average_number_data=arverage_number_data;
|
|
dev_stat.average_number_dark=arverage_number_dark;
|
|
dev_stat.average_number_flat=arverage_number_flat;
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn calibrate_file(orgdata: &IS11DataStruct) -> IS11DataStruct {
|
|
let dev_stat=DEV_STAT.lock().unwrap();
|
|
if !dev_stat.has_CalidataUP {
|
|
return orgdata.clone();
|
|
}
|
|
drop(dev_stat);
|
|
;
|
|
let calidata=CALIDATAUP.lock().unwrap();
|
|
let offsetdata=CALIOFFSETUP.lock().unwrap();
|
|
|
|
let mut data = IS11DataStruct::default();
|
|
let collect_gaindb = orgdata.temprature[0];
|
|
let collect_shutter = orgdata.shutter_time;
|
|
let cali_gaindb = calidata.temprature[0];
|
|
let cali_shutter = calidata.shutter_time;
|
|
//db 转系数
|
|
let collect_gain = 10.0_f32.powf(collect_gaindb / 20.0);
|
|
let cali_gain = 10.0_f32.powf(cali_gaindb / 20.0);
|
|
//计算增益
|
|
let Scale_gain = cali_gain / collect_gain;
|
|
let Scale_shutter = cali_shutter as f32/ collect_shutter as f32;
|
|
let SCale = Scale_gain * Scale_shutter as f32;
|
|
let len = orgdata.data.len();
|
|
for i in 0..len {
|
|
data.data[i] = orgdata.data[i] * SCale * calidata.data[i]+offsetdata.data[i];
|
|
}
|
|
return data;
|
|
}
|
|
|
|
|
|
pub fn load_all_calibrate_file(filepath: String) -> String {
|
|
let file_path = Path::new(&filepath);
|
|
if file_path.exists() {
|
|
let mut up_gain_data=CALIDATAUP.lock().unwrap();
|
|
*up_gain_data=load_calibrate_file(file_path.to_str().unwrap().to_string()).unwrap();
|
|
let mut dev_stat=DEV_STAT.lock().unwrap();
|
|
dev_stat.has_CalidataUP=true;
|
|
return "ok".to_string();
|
|
} else {
|
|
println!("文件不存在: {:?}", file_path);
|
|
return "文件不存在".to_string();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn load_calibrate_file(filepath: String) -> Result<IS11DataStruct, String> {
|
|
let mut data = IS11DataStruct::default();
|
|
let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
|
|
let mut file = File::open(filepath).unwrap();
|
|
file.read_exact(&mut buffer).unwrap();
|
|
unsafe {
|
|
let ptr = &mut data as *mut IS11DataStruct as *mut u8;
|
|
std::ptr::copy_nonoverlapping(buffer.as_ptr(), ptr, mem::size_of::<IS11DataStruct>());
|
|
}
|
|
return Ok(data);
|
|
}
|
|
|
|
pub fn set_weave_coeff(specnumber: i32, a0: f64, a1: f64, a2: f64, a3: f64) -> String {
|
|
let vecdata=vec![a0,a1,a2,a3];
|
|
spectralbase::set_sensor_weave_length_coeff(vecdata);
|
|
"ok".to_string()
|
|
}
|
|
|