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> = 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>> = Arc::new(Mutex::new(Vec::new())); // } lazy_static! { static ref DATA_IS11: Arc> = Arc::new(Mutex::new(IS11DataStruct::default())); static ref DARK_DATA: Arc> = Arc::new(Mutex::new(IS11DataStruct::default())); static ref FLAT_DATA: Arc> = Arc::new(Mutex::new(IS11DataStruct::default())); static ref CALIDATAUP: Arc> = Arc::new(Mutex::new(IS11DataStruct::default())); static ref CALIOFFSETUP: Arc> = 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=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::>(); 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=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::>(); 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=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::>(); 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 { let mut data = IS11DataStruct::default(); let mut buffer = vec![0u8; mem::size_of::()]; 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::()); } 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() }