#include "common.h" #include "ysp_debug.h" #include "msq.h" #include #include #include #include "thread.h" #include "analysis.h" #define DEBUG_ANALYSIS #define REDUCE_BIT 3 // #define SUM_NUM 8 //每点的宽度 #define MOVE_NUM 8 //计算向后移动的点数 #define JUDGE_NUM 8 //每次连续判断的点数 #define MAX_JUDGE_NUM 32 //最大的判断点数 #define MIN_JUDGE_NUM 7 //最小判断点数 #define MIN_AMP 4 //最小幅度 #define MIN_LEN 12 //最小时间宽度 #define BACK_SUM_NUM 20 /* 波峰顺序说明: 依次为H2,CO,CH4,C2H4,C2H6,C2H2 前三峰计算公式为: S=A*K=K*h*tr A=峰高计量值 h=峰高(高点值-基准值) tr=保留时间(秒) K=标定系数 后三峰计算公式为: S=A*K=K*1.064*h*(y/2)=1.064*K*h*h/4 A=1.064*h*(y/2)=1.064*h*h/4 y/2=半峰高 h=峰高=波峰最高点-左峰起点 y/2=h/2 高度修正公式 H'=Kx(H-最小高度)*tr+最低浓度值 H为算出来的高度 //面积修正公式: S'=Kx(S-最小面积)+最低浓度值 其中Kx为K1-K12中的一个系数,S为原始数据计算出的面积 Kx通过S从最大面积和最小面积中所处的位置查出Kx所处的级数 最小面积为kx_fac4,Kx为kx_fac1,低浓度值为kx_fac2 */ #define MIN_SLOPE 1 #define ANALYSIS_MESSAGE_SIZE 1024 #define ANALYSIS_MAX_MESSAGE 8 #define ANALYSIS_MQ_PRIO 30 #define ANALYSIS_MQ "/analysis_mq" #define MAX_DATA_LEN 5000 mqd_t analysis_mq;// char analysis_buf[ANALYSIS_MESSAGE_SIZE]; int slope_data[MAX_DATA_LEN]; int filter_data[MAX_DATA_LEN]; int raw_data_buf[MAX_DATA_LEN]; /* 1.区间斜率计算顶点和起点 2.第一步未找到,找区间最大值 3.前两步未找出,则用设定的参数计算 */ //计算整型的累加和 int cal_int_sum(int *buf,int len) { int sum=0; int i; if(buf==NULL) return 0; for(i=0;i>fac); } } //查找最大值,返回最大值的位置 int find_max_val(int *buf,int len,int *val) { int i; int max_val,max_pos; max_val=buf[0]; max_pos=0; for(i=0;imax_val) { max_val=buf[i]; max_pos=i; } } if(val!=NULL) *val=max_val; return max_pos; } //time():974943297 //time()->localtime()->mktime():974943297 int find_max_val_ex(int *buf,int len,int *val) { int i; int max_val,max_pos; max_val=buf[0]; max_pos=0; for(i=0;i=max_val) { max_val=buf[i]; max_pos=i; } } if(val!=NULL) *val=max_val; return max_pos; } //ref_val会返回最后一点的值 void process_data(int *raw_data,int len,int *ref_val) { static float proc_data[MAX_DATA_LEN]; float start_val,end_val,delt_y; float offs; int i; for(i=0;i0) //{ for(i=0;i=0;i-=(BACK_SUM_NUM/2)) { curr=cal_int_sum(&buf[i],BACK_SUM_NUM); if(curr<=(top_end_val+2)) { top_end_val=curr; top_end_pos=i+(BACK_SUM_NUM/2); } else { //printf("i=%d top_end_pos=%d\n",i,top_end_pos); break; } } max_pos=find_max_val(buf,top_end_pos,NULL); //printf("max_pos=%d\n",max_pos); return max_pos; }*/ //查找最大的累加和,返回位置,sum_num为累加的点数,从左往右找最大面积 int find_max_sum(int *buf,int len,int sum_num,int delt) { int i,result; int curr_sum,max_sum; max_sum=cal_int_sum(buf,sum_num); result=0; for(i=sum_num;imax_sum) { max_sum=curr_sum; result=i; } } result+=find_max_val(&buf[result],sum_num,NULL); return result; } /* //从右往左找最小面积 int find_min_sum(int *buf,int len,int sum_num,int delt) { int i,result; int curr_sum,min_sum; min_sum=cal_int_sum(&buf[len-1],sum_num); result=len-1; for(i=len-sum_num-1;i>0;i-=sum_num) { curr_sum=cal_int_sum(&buf[i-sum_num],sum_num); if(curr_sum(pre_sum+delt)) { //printf("arrived 1\n"); if((cal_int_sum(&buf[i+sum_num],sum_num)+delt)=contine_cnt) { *ret=(i+(forward_cnt/2)); return 0; } } return -2; } //查找左起点,第(i点到第i+per_width点平均值)和 //第(i+tot_width到第i+tot_width+per_width点平均值) //比较,连续比较3点,每比较一次向后移动mov_width点 int FindLeftPosEx(int *buf,int len,int tot_width,int per_width,int mov_width,int min_slope) { int i,n,result; int avr_val1[3],avr_val2[3]; result=-1; if(len<=(tot_width+4*mov_width+per_width)) return -1; for(n=0;n<(len-tot_width-4*mov_width-per_width);n++) { for(i=0;i<(sizeof(avr_val1)/sizeof(int));i++) { avr_val1[i]=cal_int_avr(&buf[n+i*mov_width],per_width); avr_val2[i]=cal_int_avr(&buf[n+i*mov_width+tot_width],per_width); } if(avr_val1[2]gas_cal_fac[i].position.start; //计算顶点结束位置 //end_pos=para_ptr->gas_cal_fac[i].position.peak+para_ptr->gas_cal_fac[i].position.width; end_pos=para_ptr->gas_cal_fac[i].position.end; //printf("start_pos=%d\n",start_pos); while(start_poscal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM)) { start_pos+=2; } else { break; } } if((start_pos+5+8)gas_cal_fac[i].gradient.lYmin; //查找起点,连续比5点,第1点和第8点比 if(FindLeftPos(data_stream,end_pos-start_pos,5,8,min_slope,&str_pos)==0) { FindMaxPos(data_stream+str_pos,end_pos-start_pos-str_pos,NULL,NULL,&peak_pos); left_pos=start_pos+str_pos; top_pos=left_pos+peak_pos; //if(top_pos>(left_pos+MIN_LEN)) //{ left_val=*(buf+left_pos); top_val=*(buf+top_pos); // if((left_val+MIN_AMP)(start_pos+MIN_LEN)) { if(cal_int_sum(&buf[end_pos-(SUM_NUM/2)],SUM_NUM)>cal_int_sum(&buf[end_pos-SUM_NUM],SUM_NUM)) { end_pos-=2; mov_tick++; } else { LOG_DEBUG(TRACE_DEBUG,"find pos%d in 2st\n",i); if(mov_tick>10) { left_pos=end_pos; ret|=(1<gas_cal_fac[i].position.start; top_pos=para_ptr->gas_cal_fac[i].position.peak; } else { left_pos=start_pos; top_pos=left_pos; } } if(pos_data!=NULL) { pos_data->position[i].start=left_pos; pos_data->position[i].peak=top_pos; } } return ret; } int find_key_pos2(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data) { int ret=0; int i; int *curr_ptr; int min_slope;//起点最小梯度 int start_pos,end_pos;//设定的起始位置和结束位置 int pos_start,pos_peak;//找到的起点和顶点位置 int start_val,peak_val;//找到的起点值和顶点值 for(i=INDEX_H2;i<=INDEX_C2H2;i++) { start_pos=para_ptr->gas_cal_fac[i].position.start; end_pos=para_ptr->gas_cal_fac[i].position.end; min_slope=(int)para_ptr->gas_cal_fac[i].gradient.lYmin; while(start_poscal_int_sum(&buf[start_pos+(SUM_NUM/2)],SUM_NUM)) { start_pos+=2; } else { break; } } if(start_pos0) { //找到了起点 //从起点找顶点 FindMaxPos(curr_ptr+pos_start,end_pos-start_pos-pos_start,¶_ptr->gas_cal_fac[i].gradient,NULL,&pos_peak); pos_start+=start_pos; pos_peak+=pos_start; if(pos_peak>(pos_start+MIN_LEN))//判断起点和顶点的宽度 { start_val=*(buf+pos_start); peak_val=*(buf+pos_peak); if((start_val+MIN_AMP)position[i].start=pos_start; pos_data->position[i].peak=pos_peak; } } return ret; } //从右往左找 int find_left_pos_ex(int *buf,int len,int sum_num,int delt) { int i,result; int start_sum,curr_sum; start_sum=cal_int_sum(&buf[len-sum_num-1],sum_num);//最右边的点 result=len-sum_num-1; for(i=len-sum_num-1;i>0;i-=sum_num) { curr_sum=cal_int_sum(&buf[i-sum_num],sum_num); //计算 if((curr_sum+delt)>start_sum) { if((cal_int_sum(&buf[i-2*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-sum_num],sum_num)) { if((cal_int_sum(&buf[i-3*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-2*sum_num],sum_num)) { if((cal_int_sum(&buf[i-4*sum_num],sum_num)+delt)>=cal_int_sum(&buf[i-3*sum_num],sum_num)) { //if((cal_int_sum(&buf[i-5*sum_num],sum_num)+delt)>cal_int_sum(&buf[i-4*sum_num],sum_num)) // { result=len-i; break; // } } } } } start_sum=curr_sum; } return result; } int find_key_pos(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data) { int i,n,*data_stream; int start_pos,end_pos; int left_pos,top_pos,right_pos; int ret=0; int top_val,left_val; int top_flg=0,left_flg=0; // #ifdef DEBUG_ANALYSIS int str_pos,peak_pos; //#endif for(i=INDEX_H2;i<=INDEX_C2H2;i++) { //1.查找顶点 //计算顶点起始位置 start_pos=para_ptr->gas_cal_fac[i].position.start; //计算顶点结束位置 //end_pos=para_ptr->gas_cal_fac[i].position.peak+para_ptr->gas_cal_fac[i].position.width; end_pos=para_ptr->gas_cal_fac[i].position.end; //printf("start_pos=%d\n",start_pos); while(start_poscal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM)) { start_pos+=2; } else { break; } } data_stream=buf+start_pos;// //获取顶点的数据位置 //if(i==INDEX_C2H4) if(find_top_pos(data_stream,end_pos-start_pos,&(para_ptr->gas_cal_fac[i].gradient),&str_pos,&peak_pos)>0) { //top_val=data_stream[peak_pos]; top_pos=peak_pos+start_pos;// top_val=top_pos-para_ptr->gas_cal_fac[i].position.width; data_stream=buf+top_val; top_pos=top_val+find_max_val(data_stream,para_ptr->gas_cal_fac[i].position.width+8,NULL); top_val=buf[top_pos]; top_flg|=(1<gas_cal_fac[i].position.peak-(para_ptr->gas_cal_fac[i].position.width/2); end_pos=start_pos+para_ptr->gas_cal_fac[i].position.width; data_stream=buf+start_pos;// top_pos=find_max_val(data_stream,end_pos-start_pos,NULL);//查找顶点 top_val=data_stream[top_pos]; if(top_pos!=0) { if((top_val-data_stream[0])>MIN_AMP)//此处需要再斟酌 { //找到了最大值 top_pos+=start_pos; top_flg|=(1<gas_cal_fac[i].position.start; //printf("top=%d sta=%d 2\n",top_val,data_stream[0]); } } else { //未确定是否找到了最大值,再深入分析,主要分析右侧是否有下降趋势 if(cal_int_avr(data_stream,4)>cal_int_avr(&data_stream[4],4)) { if(cal_int_avr(&data_stream[4],4)>cal_int_avr(&data_stream[8],4)) { if(cal_int_avr(&data_stream[8],4)>cal_int_avr(&data_stream[12],4)) { //找到了顶点 top_pos+=start_pos; top_flg|=(1<gas_cal_fac[i].position.start; } } else { //未找到顶点 top_pos=para_ptr->gas_cal_fac[i].position.start; } } else { //未找到顶点 top_pos=para_ptr->gas_cal_fac[i].position.start; } } } if(i==INDEX_CO||i==INDEX_CH4) { if((top_flg&(1<gas_cal_fac[i].position.peak; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"warning:can not find top pos,use default peak_pos=%d index=%d\n",top_pos,i); } } //2.查找左起点 if((top_flg&(1<gas_cal_fac[i].position.start;//获取数据起始下标 data_stream=buf+start_pos;//计算数据偏移地址 end_pos=top_pos;//结束位置为顶点 if(find_left_pos(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin,&left_pos)==0) { //找到了起点 left_val=data_stream[left_pos]; left_pos+=start_pos; left_flg|=(1<=top_pos)) { LOG_DEBUG(ANALYSIS_EEROR_DEBUG,"error:left_val=%d top_val=%d index=%d\n",left_val,top_val,i); ret&=(~(1<position[i].start=left_pos; pos_data->position[i].peak=top_pos; } return ret; } /* int find_left_start(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak) { int i,n; int area[JUDGE_NUM]; int k[JUDGE_NUM]; int avr[JUDGE_NUM]; int str_pos=0; int peak_pos=0; int tmp; int find_flg=0; for(n=0;n=k[n+1]) { break; } } //printf("\n"); //也可以是连续大于para_ptr->lYmin; if(n>=(JUDGE_NUM-2)) { if((k[0]>=0)&&k[1]>0&&k[2]>0&&k[3]>0&&k[4]>0) { //找到起点 if(find_flg==0) { str_pos=i-JUDGE_NUM*MOVE_NUM; //printf("str_pos=%d ",str_pos); find_flg=1; if(str!=NULL) *str=str_pos; } } } //找顶点 if(find_flg!=0) { for(n=(JUDGE_NUM-1);n>=0;n--) { if(k[n]>=0) { break; } } if(n<1) { //找到顶点 tmp=i-((JUDGE_NUM-n)*MOVE_NUM); if(peak_pos==0) { peak_pos=tmp; if(peak!=NULL) *peak=peak_pos; //printf("top_pos=%d\n",peak_pos); } } } //递推 for(n=0;n<(JUDGE_NUM-1);n++) { area[n]=area[n+1]; k[n]=k[n+1]; avr[n]=avr[n+1]; } area[n]=cal_int_sum(&buf[i],SUM_NUM);//面积往后移动一点 avr[n]=area[n]/SUM_NUM;//平均值往后移动一点 //k[n]=avr[n]-avr[n-1];//平均值的斜率往后移动一点 k[n]=area[n]-area[n-1];//平均值的斜率往后移动一点 } }*/ int find_top_pos(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak) { int i,n; int area[JUDGE_NUM]; int k[JUDGE_NUM]; int avr[JUDGE_NUM]; int find_pos[JUDGE_NUM]; //int find_val[JUDGE_NUM]; int str_pos=0; int peak_pos=0; int left_flg,right_flg; int tmp; int find_num=0; int pre_k=0,curr_k=0; //连续判断JUDGE_NUM个点,每个点为最近SUM_NUM个点的平均 for(n=0;n=(JUDGE_NUM/2)) { //右半边梯度全部小于零的情况下 //计算左半边梯度小于零的点数 left_flg=0; for(n=0;n<(JUDGE_NUM/2);n++) { if(k[n]>0) left_flg++; } if(left_flg>=(JUDGE_NUM/2))//左半边梯度全部大于零 { //找到顶点 find_pos[find_num]=i-((JUDGE_NUM+1)*MOVE_NUM/2); curr_k=0; for(tmp=0;tmp<(JUDGE_NUM/2);tmp++) { curr_k+=k[tmp];//计算累加k //printf("k%d=%d ",tmp,k[tmp]); } //printf("\n"); find_num++; if(curr_k>pre_k)//找到增长最猛的 { if(peak!=NULL) { *peak=i-((JUDGE_NUM+1)*MOVE_NUM/2); } pre_k=curr_k; } if(find_num>=JUDGE_NUM) break; } } } //递推 for(n=0;n<(JUDGE_NUM-1);n++) { area[n]=area[n+1]; k[n]=k[n+1]; avr[n]=avr[n+1]; } area[n]=cal_int_sum(&buf[i],SUM_NUM);//面积往后移动一点 avr[n]=area[n]/SUM_NUM;//平均值往后移动一点 k[n]=avr[n]-avr[n-1];//平均值的斜率往后移动一点 } return find_num; } int find_top_pos_ex(int *buf,int len,GRADIENT_TYPE_DEF *para_ptr,int *str,int *peak,int tot_width,int per_width,int mov_width) { int i,n; int area[MAX_JUDGE_NUM]; int k[MAX_JUDGE_NUM]; int avr[MAX_JUDGE_NUM]; int find_pos[MAX_JUDGE_NUM]; //int find_val[JUDGE_NUM]; int str_pos=0; int peak_pos=0; int left_flg,right_flg; int tmp; int find_num=0; int pre_k=0,curr_k=0; int tot_judge_num; tot_judge_num=(tot_width-((per_width+1)/2))/mov_width; if(tot_judge_numMAX_JUDGE_NUM) { tot_judge_num=MAX_JUDGE_NUM; } //连续判断JUDGE_NUM个点,每个点为最近SUM_NUM个点的平均 for(n=0;n=(tot_judge_num/2)) { //右半边梯度全部小于零的情况下 //计算左半边梯度小于零的点数 left_flg=0; for(n=0;n<(tot_judge_num/2);n++) { if(k[n]>0) left_flg++; } if(left_flg>=(tot_judge_num/2))//左半边梯度全部大于零 { //找到顶点 find_pos[find_num]=i-((tot_judge_num+1)*mov_width/2); curr_k=0; for(tmp=0;tmp<(tot_judge_num/2);tmp++) { curr_k+=k[tmp];//计算累加k //printf("k%d=%d ",tmp,k[tmp]); } //printf("\n"); find_num++; if(curr_k>pre_k)//找到增长最猛的 { if(peak!=NULL) { *peak=i-((tot_judge_num+1)*mov_width/2); } pre_k=curr_k; } if(find_num>=tot_judge_num) break; } } } //递推 for(n=0;n<(tot_judge_num-1);n++) { area[n]=area[n+1]; k[n]=k[n+1]; avr[n]=avr[n+1]; } area[n]=cal_int_sum(&buf[i],per_width);//面积往后移动一点 avr[n]=area[n]/per_width;//平均值往后移动一点 k[n]=avr[n]-avr[n-1];//平均值的斜率往后移动一点 } return find_num; } /* int find_key_pos_ex(int *buf,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data) { int i,n,*data_stream; int start_pos,end_pos; int left_pos,top_pos,right_pos; int ret=0; int top_val,left_val; for(i=INDEX_H2;i<=INDEX_C2H2;i++) { //1.查找顶点 //计算顶点起始位置 start_pos=para_ptr->gas_cal_fac[i].position.start; //计算顶点结束位置 end_pos=para_ptr->gas_cal_fac[i].position.end; while(start_poscal_int_sum(&buf[start_pos+SUM_NUM],SUM_NUM)) { start_pos+=4; } else { break; } } //获取顶点的数据位置 data_stream=buf+start_pos;// top_pos=find_max_val(data_stream,end_pos-start_pos,NULL);//查找顶点 top_val=data_stream[top_pos]; if(top_pos!=0) { //找到了最大值 top_pos+=start_pos; } else { //未确定是否找到了最大值,再深入分析,主要分析右侧是否有下降趋势 top_pos+=start_pos; } //2.查找左起点 start_pos=para_ptr->gas_cal_fac[i].position.start;//获取数据起始下标 data_stream=buf+start_pos;//计算数据偏移地址 end_pos=top_pos-(para_ptr->gas_cal_fac[i].position.width);//结束位置为顶点 left_pos=find_left_pos(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin); //left_pos=find_left_pos_ex(data_stream,end_pos-start_pos,SUM_NUM,(int)para_ptr->gas_cal_fac[i].gradient.lYmin); left_val=data_stream[left_pos]; left_pos+=start_pos; if(top_val<=left_val) { LOG_DEBUG(ANALYSIS_EEROR_DEBUG,"error:left_val=%d top_val=%d index=%d\n",left_val,top_val,i); } pos_data->position[i].start=left_pos; pos_data->position[i].peak=top_pos; ret|=(1<data[i-1]&&data[i]>data[i+1]) { data[i]=(data[i-1]+data[i+1])/2; } } } } void avr_filter(int *data,unsigned int len,unsigned int smooth_num,int *out) { unsigned int i,n; int num; num=smooth_num/2; for(i=0;i<(len-smooth_num);i++) { out[i+num]=cal_int_avr(&data[i],smooth_num); } for(n=0;ncorrect_fac.k[i].fac[3];//最小面积 max=gas_cal_fac->correct_fac.k[i].fac[4];//最大面积 if(((*raw_data)<=max)&&((*raw_data)>min)) { if(index_out!=NULL) { *index_out=i; } return &(gas_cal_fac->correct_fac.k[i]); } } return NULL; } //峰高 int cal_h(int *raw_data,int str_pos,int peak_pos,float *out_data,int *base_data) { int h,base_val; if(raw_data==NULL||out_data==NULL) return -1; if(base_data!=NULL) { base_val=(*base_data); } else { base_val=raw_data[str_pos-1]; } h=raw_data[peak_pos]-base_val; if(h<0) h=0; //printf("max=%d base=%d h=%d peak_pos=%d\n",raw_data[peak_pos],base_val,h,peak_pos); //out=h*tr //*out_data=((float)h*(peak_pos-str_pos+1)*(my_para_data.mach_run_para.sample_rate))/1000; *out_data=(float)h;//((float)h*(peak_pos)*(my_para_data.mach_run_para.sample_rate))/100000; return 0; } int correct_h(float *raw_h,float *out_h,GAS_CAL_PARA *gas_cal_fac) { float h=0; int k_index=0; FACTOR_TYPE *fac_ptr; if(gas_cal_fac==NULL||raw_h==NULL||out_h==NULL) return -1; //根据raw_h查找处于哪一级K值,然后使用该K值修正结果 if((fac_ptr=find_right_fac(raw_h,gas_cal_fac,&k_index))!=NULL) { //fac[0]=Kx //fac[1]=低浓度值 //fac[3]=最小面积 h=(fac_ptr->fac[0])*((*raw_h)-(fac_ptr->fac[3]))+(fac_ptr->fac[1]); if(out_h!=NULL) { *out_h=h; } return k_index; } return -2; } //计算面积 int cal_area(int *raw_data,int str_pos,int peak_pos,float *out_area) { float area=0; int tmp=0; int i; int base_data; if(raw_data==NULL||out_area==NULL) return -1; base_data=raw_data[str_pos];//计算基值 for(i=str_pos;ifac[0])*((*raw_area)-(fac_ptr->fac[3]))+(fac_ptr->fac[1]); if(out_area!=NULL) { *out_area=area; } return k_index; } return -2; } int save_dumy_file(const char *file,long offs,int *ptr,unsigned int len) { FILE *fp; unsigned int i; fp=fopen(file,"w"); if(fp==NULL) { LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when savefile\r\n",file); return -1; } if(offs!=0) { fseek(fp,offs,SEEK_SET); } for(i=0;iMAX_DATA_LEN) len=MAX_DATA_LEN; smooth_data(raw_data,len,1); //滤波去噪 /* avr_filter(raw_data,len,SUM_NUM,filter_data); ref_val=cal_int_avr(&filter_data[para_ptr->gas_cal_fac[INDEX_CH4].position.end],16); for(i=para_ptr->gas_cal_fac[INDEX_CH4].position.end;igas_cal_fac[INDEX_C2H4].position.start;i++) { filter_data[i]=ref_val; } for(i=INDEX_C2H4;i<=INDEX_C2H2;i++) { printf("ref_val=%d start=%d start1=%d\n",ref_val,filter_data[para_ptr->gas_cal_fac[i].position.start],filter_data[para_ptr->gas_cal_fac[i].position.start-1]); process_data(&filter_data[para_ptr->gas_cal_fac[i].position.start],(para_ptr->gas_cal_fac[i].position.end)-(para_ptr->gas_cal_fac[i].position.start)+1,&ref_val); if(i!=INDEX_C2H2) { for(n=para_ptr->gas_cal_fac[i].position.end;ngas_cal_fac[i+1].position.start;n++) { filter_data[n]=filter_data[n-1]; } } else { for(n=para_ptr->gas_cal_fac[i].position.end;ngas_cal_fac[i].position.end-1]; } */ //ref_val=cal_int_avr(&raw_data[para_ptr->gas_cal_fac[INDEX_CH4].position.end],16); //ref_val=&raw_data[para_ptr->gas_cal_fac[INDEX_C2H4].position.start]; //for(i=para_ptr->gas_cal_fac[INDEX_CH4].position.end;igas_cal_fac[INDEX_C2H4].position.start;i++) //{ // raw_data[i]=ref_val; // } ref_val=raw_data[para_ptr->gas_cal_fac[INDEX_C2H4].position.start]; for(i=INDEX_C2H4;i<=INDEX_C2H2;i++) { segment_len=(para_ptr->gas_cal_fac[i].position.end)-(para_ptr->gas_cal_fac[i].position.start)+1; //将数据拉平后再整体往下移动(起点值-ref_val) process_data(&raw_data[para_ptr->gas_cal_fac[i].position.start],segment_len,&ref_val); //ref_val存储区段最后一个点的值 if(i!=INDEX_C2H2) { for(n=para_ptr->gas_cal_fac[i].position.end;ngas_cal_fac[i+1].position.start;n++) { raw_data[n]=raw_data[n-1]; } } else {//拉平最后一段数据 for(n=para_ptr->gas_cal_fac[i].position.end;nfind_mask=find_mask; for(i=INDEX_H2;i<=INDEX_C2H2;i++) { str_pos[i]=pos_data->position[i].start; peak_pos[i]=pos_data->position[i].peak; ana_rlt->pos_info[i].start=str_pos[i]; ana_rlt->pos_info[i].peak=peak_pos[i]; } LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"find_mask=%d,now start cal ysp data\n",find_mask); //计算 if((find_mask&(1<area[INDEX_H2]=tmp; k_index=correct_h(&tmp,&ana_rlt->result.H2ppm,¶_ptr->gas_cal_fac[INDEX_H2]); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"H2_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.H2ppm,k_index,para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_H2].correct_fac.k[k_index].fac[1]); } else { //cal_h(raw_data,str_pos[INDEX_H2],peak_pos[INDEX_H2],&tmp,NULL); tmp=0; ana_rlt->area[INDEX_H2]=tmp; ana_rlt->result.H2ppm=0; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"H2_start=%d H2_peak=%d H2_amp=%f\n",str_pos[INDEX_H2],peak_pos[INDEX_H2],tmp); } //氢气和一氧化碳使用同一个基点 if((find_mask&(1<area[INDEX_CO]=tmp; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_start=%d CO_peak=%d CO_amp=%f\n",str_pos[INDEX_CO],peak_pos[INDEX_CO],tmp); k_index=correct_h(&tmp,&ana_rlt->result.COppm,¶_ptr->gas_cal_fac[INDEX_CO]); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.COppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]); } else { /* tmp=0; ana_rlt->area[INDEX_CO]=tmp; ana_rlt->result.COppm=0; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_start=%d CO_peak=%d CO_amp=%f\n",str_pos[INDEX_CO],peak_pos[INDEX_CO],tmp); */ base_val=raw_data[str_pos[INDEX_H2]-1]; cal_h(raw_data,para_ptr->gas_cal_fac[INDEX_CO].position.start,para_ptr->gas_cal_fac[INDEX_CO].position.peak,&tmp,&base_val); ana_rlt->area[INDEX_CO]=tmp; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"use dfault postion para:CO_start=%d CO_peak=%d CO_amp=%f\n",para_ptr->gas_cal_fac[INDEX_CO].position.start,para_ptr->gas_cal_fac[INDEX_CO].position.peak,tmp); k_index=correct_h(&tmp,&ana_rlt->result.COppm,¶_ptr->gas_cal_fac[INDEX_CO]); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CO_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.COppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]); } if((find_mask&(1<area[INDEX_CH4]=tmp; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_start=%d CH4_peak=%d CH4_amp=%f\n",str_pos[INDEX_CH4],peak_pos[INDEX_CH4],tmp); k_index=correct_h(&tmp,&ana_rlt->result.CH4ppm,¶_ptr->gas_cal_fac[INDEX_CH4]); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.CH4ppm,k_index,para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_CO].correct_fac.k[k_index].fac[1]); } else { tmp=0; ana_rlt->area[INDEX_CH4]=tmp; ana_rlt->result.CH4ppm=0; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"CH4_start=%d CH4_peak=%d CH4_amp=%f\n",str_pos[INDEX_CH4],peak_pos[INDEX_CH4],tmp); } if((find_mask&(1<area[INDEX_C2H4]=tmp; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_start=%d C2H4_peak=%d C2H4_amp=%f\n",str_pos[INDEX_C2H4],peak_pos[INDEX_C2H4],tmp); k_index=correct_area(&tmp,&ana_rlt->result.C2H4ppm,¶_ptr->gas_cal_fac[INDEX_C2H4]); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H4ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H4].correct_fac.k[k_index].fac[1]); } else { tmp=0; ana_rlt->area[INDEX_C2H4]=tmp; ana_rlt->result.C2H4ppm=0; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H4_start=%d C2H4_peak=%d C2H4_amp=%f\n",str_pos[INDEX_C2H4],peak_pos[INDEX_C2H4],tmp); } if((find_mask&(1<area[INDEX_C2H6]=tmp; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_start=%d C2H6_peak=%d C2H6_amp=%f\n",str_pos[INDEX_C2H6],peak_pos[INDEX_C2H6],tmp); k_index=correct_area(&tmp,&ana_rlt->result.C2H6ppm,¶_ptr->gas_cal_fac[INDEX_C2H6]); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H6ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H6].correct_fac.k[k_index].fac[1]); } else { tmp=0; ana_rlt->area[INDEX_C2H6]=tmp; ana_rlt->result.C2H6ppm=0; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H6_start=%d C2H6_peak=%d C2H6_amp=%f\n",str_pos[INDEX_C2H6],peak_pos[INDEX_C2H6],tmp); } //计算原始面积到tmp if((find_mask&(1<area[INDEX_C2H2]=tmp; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_start=%d C2H2_peak=%d C2H2_amp=%f\n",str_pos[INDEX_C2H2],peak_pos[INDEX_C2H2],tmp); //从tmp修正面积到&out_data->C2H2ppm k_index=correct_area(&tmp,&ana_rlt->result.C2H2ppm,¶_ptr->gas_cal_fac[INDEX_C2H2]); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_corect=%f k_index=%d kx=%f min_area=%f min_ppm=%f\n",ana_rlt->result.C2H2ppm,k_index,para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[0],para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[3],para_ptr->gas_cal_fac[INDEX_C2H2].correct_fac.k[k_index].fac[1]); } else { tmp=0; ana_rlt->area[INDEX_C2H2]=tmp; ana_rlt->result.C2H2ppm=0; LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"C2H2_start=%d C2H2_peak=%d C2H2_amp=%f\n",str_pos[INDEX_C2H2],peak_pos[INDEX_C2H2],tmp); } ana_rlt->result.TotHyd=(ana_rlt->result.CH4ppm)+(ana_rlt->result.C2H4ppm)+(ana_rlt->result.C2H6ppm)+(ana_rlt->result.C2H2ppm); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"h2=%fppm co=%fppm ch4=%fppm\n",ana_rlt->result.H2ppm,ana_rlt->result.COppm,ana_rlt->result.CH4ppm); LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"c2h4=%fppm c2h6=%fppm c2h2=%fppm\n",ana_rlt->result.C2H4ppm,ana_rlt->result.C2H6ppm,ana_rlt->result.C2H2ppm); //if(co2_is_ok) // { ana_rlt->result.CO2ppm=last_co2_ppm; // } // else // { // ana_rlt->result.CO2ppm=0; // } ret=0; return ret; } /* int analysis_co2(unsigned short *buf,unsigned int buf_len,float *result) { int i; int max_pos=0; int start_pos=0; unsigned short max=0; unsigned int sum=0; int find_flg=0; int large_cnt=0; int less_cnt=0; float ppm; //找起点 for(i=0;i<(buf_len-5);i++) { if(buf[i]max) { //找最高点 max=buf[i]; max_pos=i; large_cnt++; less_cnt=0; } if(buf[i]=4) { if(large_cnt>=4) { find_flg=2; break; } } } } if(find_flg==2) { sum=0; for(i=start_pos;i<=max_pos;i++) { sum+=(buf[i]-buf[start_pos]); } ppm=(float)2*sum; LOG_DEBUG(TRACE_DEBUG,"co2_start_pos=%d co2_peak_pos=%d co2_area=%f\n",start_pos,max_pos,ppm); if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0) { if(result!=NULL) *result=ppm; LOG_DEBUG(TRACE_DEBUG,"co2_ppm=%f\n",ppm); return 0; } else { LOG_DEBUG(ERROR_DEBUG,"can't find co2 cal fac\n"); if(result!=NULL) *result=0; return -3; } } else { LOG_DEBUG(ERROR_DEBUG,"can't find co2 peak pos\n"); if(result!=NULL) *result=0; return -1; } } else { LOG_DEBUG(ERROR_DEBUG,"can't find co2 start pos\n"); if(result!=NULL) *result=0; } return -2; }*/ int analysis_co2(unsigned short *buf,unsigned int buf_len,float *result) { int i; int max_pos=0; int start_pos=0; unsigned short max=0; unsigned int sum=0; int find_flg=0; int large_cnt=0; int less_cnt=0; float ppm; //找起点 for(i=0;i<(buf_len-5);i++) { if(buf[i](buf[i+2]-buf[i])) { start_pos=i; find_flg=1; break; } } } } } if(find_flg) { //找最高点 max=buf[start_pos]; large_cnt=0; for(i=(start_pos+1);imax) { //找最高点 max=buf[i]; max_pos=i; large_cnt++; less_cnt=0; } else if(buf[i]<=max) { less_cnt++; if(less_cnt>=2) { if(large_cnt>=2) { find_flg=2; break; } } } } if(find_flg==2) { sum=0; for(i=start_pos;i<=max_pos;i++) { sum+=(buf[i]-buf[start_pos]); } ppm=(float)2*sum; LOG_DEBUG(TRACE_DEBUG,"co2_start_pos=%d co2_peak_pos=%d co2_area=%f\n",start_pos,max_pos,ppm); if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0) { if(result!=NULL) *result=ppm; LOG_DEBUG(TRACE_DEBUG,"co2_ppm=%f\n",ppm); return 0; } else { LOG_DEBUG(ERROR_DEBUG,"can't find co2 cal fac\n"); if(result!=NULL) *result=0; return -3; } } else { LOG_DEBUG(ERROR_DEBUG,"can't find co2 peak pos\n"); if(result!=NULL) { ppm=(float)buf[buf_len/2]; if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0) { *result=ppm; } else { *result=0; } } return -1; } } else { LOG_DEBUG(ERROR_DEBUG,"can't find co2 start pos\n"); if(result!=NULL) { ppm=(float)buf[buf_len/2]; if(correct_area(&ppm,&ppm,&my_para_data.co2_cal_fac)==0) { *result=ppm; } else { *result=0; } } } return -2; } /* //从csv文件读取数据 int read_float_csv(const char *fname,float *buf,int len) { FILE *stream; int i; stream=fopen(fname,"r"); if(stream==NULL) return -1; for(i=0;i0) tmp_len=len; else tmp_len=para_ptr->mach_run_para.sample_len; if((act_len=read_int_raw(file_name,raw_data_buf,tmp_len))<=0)//读取待分析的数据 { LOG_DEBUG(ERROR_DEBUG,"read_int_raw failed\n"); return -1; } ana_rlt->result.SmpTm=time(NULL); //out_data->SmpTm=time(NULL); return analysis_data(raw_data_buf,act_len,para_ptr,ana_rlt);//分析数据 } /* //查找左波谷,正常左边k=0,右边连续k>0,两个波粘一起左边连续k<0,右边连续k>0 //综合起来就是左边连续k<=0,右边连续k>0,输入数据为斜率 int lfind_slope_trough(float *data,unsigned int len,unsigned int *pos,unsigned int pos_num) { unsigned int i; unsigned int find_pos; unsigned int find_index=0; for(i=0;i<(len-6);i++) { if(data[i]<=0&&data[i+1]<=0&&data[i+2]<=0) //左边连续<=0 { if(data[i+3]>0&&data[i+4]>0&&data[i+5]>=0)//右边连续大于0 { find_pos=i+2; pos[find_index++]=find_pos; if(find_index>=pos_num) break; } } } return find_index; } //查找波峰起点和顶点 int find_increase_start(float *data,int len,int judge_num,int *str_pos,int *endpos) { int i; int meet_lcnt=0,meet_rcnt=0; int start_pos=-1,end_pos=-1; for(i=0;iMIN_SLOPE)//数据连续上升 { meet_rcnt=0; meet_lcnt++; if(meet_lcnt>=judge_num) { if((-1)==start_pos) { start_pos=i-judge_num;//起点 *str_pos=start_pos; } } } else { meet_lcnt=0; if(data[i]<=0)// meet_rcnt++; if((-1)!=start_pos) { if(meet_rcnt>=judge_num) { if((-1)==end_pos) { end_pos=i-judge_num;//上升之后连续下降,判断为顶点 *endpos=end_pos; return 0; } } } } } return -1; } //查找波峰右谷点,从顶点开始查找 //正常情况下,k连续小于0,到连续趋近零;有粘连的时候k连续<0,又突然连续大于0 //左边k<-MIN_SLOPE,右边连续k>=0; int find_decrease_start(float *data,int len,int judge_num,int *str_pos,int *endpos) { int i; int meet_lcnt=0,meet_rcnt=0; int start_pos=-1,end_pos=-1; for(i=0;i=judge_num) { if((-1)==start_pos) { start_pos=i-judge_num;//起点 *str_pos=start_pos; } } } else { meet_lcnt=0; if(data[i]<=0) meet_rcnt++; if((-1)!=start_pos) { if(meet_rcnt>=judge_num) { if((-1)==end_pos) { end_pos=i-judge_num;//终点 *endpos=end_pos; return 0; } } } } } return -1; }*/ /* //判断波形是否正常,通过数波峰波谷是否粘连来判断,输入数据为斜率 int data_distinguish_type(float *data,unsigned int len,unsigned int judge_num) { int i; int last_slope=0,curr_slope=0; for(i=0;iMIN_SLOPE&&data[i+1]>MIN_SLOPE) { if(data[i+2]>MIN_SLOPE&&data[i+3]>MIN_SLOPE) { curr_slope=1; if(curr_slope!=last_slope) { //有跳变 } } } } } //查找波峰左边界 //左边>0,右边小于等于0,输入数据为斜率 int find_peak_lboundary(float *data,unsigned int len,unsigned int *pos) { unsigned int i; for(i=3;i<(len-1);i++) { if((data[i]<=0)&&data[i-1]>0&&data[i-2]>0&&data[i-3]>0) { if(data[i+1]<=0) { if(pos!=NULL) *pos=i; return i; } } } return -1; } //查找波峰右边界 //左边>=0,右边<0,输入数据为斜率 int find_peak_rboundary(float *data,unsigned int len,unsigned int *pos) { unsigned int i; for(i=3;i<(len-1);i++) { if((data[i]<0)&&data[i-1]>=0&&data[i-2]>=0&&data[i-3]>=0) { if(data[i+1]<0) { if(pos!=NULL) *pos=i; return i; } } } return -1; }*/ //查找右波谷,正常左边连续k<0,右边k=0,两个波粘一起左边连续k<0,右边连续k>0 //综合起来就是左边连续k<0,右边连续k>=0 int rfind_slope_trough(float *data,unsigned int len,unsigned int *pos,unsigned int pos_num,unsigned int *lpos) { unsigned int i; unsigned int find_pos; unsigned int find_index=0; for(i=0;i<(len-6);i++) { if(data[i]<0&&data[i+1]<0&&data[i+2]<0) //左边连续<=0 { if(data[i+3]>=0&&data[i+4]>=0&&data[i+5]>=0)//右边连续大于0 { find_pos=i+2; if(lpos!=NULL) { if(find_pos<=lpos[find_index]) continue; } pos[find_index++]=find_pos; if(find_index>=pos_num) break; } } } return find_index; } /* int find_key_points(float *raw_data,unsigned int len,void *key_points) { unsigned int lrough_pos[6]; //左波谷 unsigned int rrough_pos[6]; //右波谷 unsigned int peak_pos[6]; //波峰 smooth_data(raw_data,len,1); //滤波去噪 cal_slope(raw_data,slope_data,len);//计算斜率 //lfind_slope_trough(slope_data,len,lrough_pos,6);//查找左波谷 //rfind_slope_trough(slope_data,len,rrough_pos,6);//查找右波谷 //查找到的位置和设定的参数比较, //在查找到的位置中间查找波峰 return 0; }*/ int save_last_result(ANALY_RESULT *pri_data) { FILE *fp; if(pri_data==NULL) return -1; fp=fopen("last.dat","w"); if(fp==NULL) return -2; if(fwrite((const void *)pri_data,sizeof(ANALY_RESULT),1,fp)!=1) { fclose(fp); return -3; } fclose(fp); return 0; } int load_last_result(ANALY_RESULT *pri_data) { FILE *fp; if(pri_data==NULL) return -1; fp=fopen("last.dat","r"); if(fp==NULL) return -2; if(fread((void *)pri_data,sizeof(ANALY_RESULT),1,fp)!=1) { fclose(fp); return -3; } fclose(fp); return 0; } /*日期,参数,分析结果,数据*/ int save_analysis_file(char *file_name,int len,YSP_PARA *para_ptr,FIND_POS_DATA *pos_data,YSP_PRI_DATA *out_data) { FILE *fp; unsigned int i; char *p; char file[64]; if(file_name==NULL||para_ptr==NULL||pos_data==NULL||out_data==NULL) return -1; sprintf(file,"%s",file_name); i=strlen(file); if(i<3) return -2; //替换尾缀 sprintf(&file[i-3],"dat"); fp=fopen(file,"w"); if(fp==NULL) { LOG_DEBUG(ERROR_DEBUG,"Creat file %s failed when save_analysis_file\n",file); return -1; } if(fwrite((const void *)para_ptr->mach_run_para.version,16,1,fp)!=1) {//版本号 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save version failed when save_analysis_file %s\n",file); return -2; } if(fwrite((const void *)para_ptr->mach_run_para.station,64,1,fp)!=1) { //站名 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save station failed when save_analysis_file %s\n",file); return -3; } if(fwrite((const void *)para_ptr->mach_run_para.device,64,1,fp)!=1) { //设备名 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save device failed when save_analysis_file %s\n",file); return -4; } if(fwrite((const void *)&last_sample_time,4,1,fp)!=1) {//日期 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save sample date failed when save_analysis_file %s\n",file); return -5; } if(fwrite((const void *)¶_ptr->mach_run_para.sample_len,4,1,fp)!=1) {//采样长度 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save sample_len failed when save_analysis_file %s\n",file); return -6; } if(fwrite((const void *)¶_ptr->mach_run_para.sample_rate,4,1,fp)!=1) {//采样间隔 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save sample_rate failed when save_analysis_file %s\n",file); return -7; } for(i=0;i<6;i++) { if(fwrite((const void *)¶_ptr->gas_cal_fac[i],sizeof(GAS_CAL_PARA),1,fp)!=1) {//计数系数 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save cal fac failed when save_analysis_file %s\n",file); return (-8-i); } } if(fwrite((const void *)pos_data,sizeof(FIND_POS_DATA),1,fp)!=1) {//查找到的关键点 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save pos data failed when save_analysis_file %s\n",file); return -14; } if(fwrite((const void *)out_data,sizeof(YSP_PRI_DATA),1,fp)!=1) {//分析的结果 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save result data failed when save_analysis_file %s\n",file); return -14; } /* if(fwrite((const void *)out_data,sizeof(YSP_PRI_DATA),1,fp)!=1) {//分析的结果 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save result data failed when save_analysis_file %s\n",file); return -14; }*/ if(fseek(fp,RSV_SPACE_SIZE,SEEK_CUR)!=0) { //保留空间 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"fseek failed when save_analysis_file %s\n",file); return -15; } if(fwrite((const void *)raw_data_buf,(para_ptr->mach_run_para.sample_len)*4,1,fp)!=1) {//数据 fclose(fp); LOG_DEBUG(ERROR_DEBUG,"save sample data failed when save_analysis_file %s\n",file); return -16; } fclose(fp); return 0; } //分析线程,以及数据输出线程 void *analysis_routine(void *arg) { YSP_PRI_DATA ysp_pri_data; FIND_POS_DATA ysp_ana_pos; ANALY_RESULT latest_ana_rlt; float delt; int i; if((analysis_mq=create_mq(ANALYSIS_MQ,ANALYSIS_MAX_MESSAGE,ANALYSIS_MESSAGE_SIZE))<0) { LOG_DEBUG(ERROR_DEBUG,"create analysis message queue failed\n"); exit(1); } if(load_last_result(&ana_result)==0) { send_ysp_msg(&ana_result.result); } else { LOG_DEBUG(ERROR_DEBUG,"load last history data failed\n"); } while(1) { if(recv_mq_wait(analysis_mq,(void *)analysis_buf,sizeof(analysis_buf),60000000)>0) { if(analysis_file(analysis_buf,my_para_data.mach_run_para.sample_len,&my_para_data,&ana_result)==0) { LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"analysis %s sucessful\n",analysis_buf); if((my_para_data.mach_run_para.run_mode)==0) {//正常模式下才起作用,调试模式下不修正 if(read_his_entry(&latest_ana_rlt)==0) { //数据修正 if(ana_result.result.H2ppm0.2)//增长率大于-20% { LOG_DEBUG(TRACE_DEBUG,"lastH2=%f currH2=%f delt=%f correc to %f\n",latest_ana_rlt.result.H2ppm,ana_result.result.H2ppm,delt,latest_ana_rlt.result.H2ppm*0.9); ana_result.result.H2ppm=latest_ana_rlt.result.H2ppm*0.9; } } else if(latest_ana_rlt.result.H2ppm>=(1.0))//上次测量值大于1ppm { //本次比上次大 delt=(ana_result.result.H2ppm-latest_ana_rlt.result.H2ppm)/latest_ana_rlt.result.H2ppm; if(delt>0.4)//增长率大于40% { LOG_DEBUG(TRACE_DEBUG,"lastH2=%f currH2=%f delt=%f correc to %f\n",latest_ana_rlt.result.H2ppm,ana_result.result.H2ppm,delt,latest_ana_rlt.result.H2ppm*1.2); ana_result.result.H2ppm=latest_ana_rlt.result.H2ppm*1.2; } } if(ana_result.result.COppm0.2)//增长率大于-20% { LOG_DEBUG(TRACE_DEBUG,"lastCO=%f currCO=%f delt=%f correc to %f\n",latest_ana_rlt.result.COppm,ana_result.result.COppm,delt,latest_ana_rlt.result.COppm*0.9); ana_result.result.COppm=latest_ana_rlt.result.COppm*0.9; } } else if(latest_ana_rlt.result.COppm>=(1.0))//上次测量值大于1ppm { //本次比上次大 delt=(ana_result.result.COppm-latest_ana_rlt.result.COppm)/latest_ana_rlt.result.COppm; if(delt>0.4)//增长率大于40% { LOG_DEBUG(TRACE_DEBUG,"lastCO=%f currCO=%f delt=%f correc to %f\n",latest_ana_rlt.result.COppm,ana_result.result.COppm,delt,latest_ana_rlt.result.COppm*1.2); ana_result.result.COppm=latest_ana_rlt.result.COppm*1.2; } } if(ana_result.result.CH4ppm0.2)//增长率大于-20% { LOG_DEBUG(TRACE_DEBUG,"lastCH4=%f currCH4=%f delt=%f correc to %f\n",latest_ana_rlt.result.CH4ppm,ana_result.result.CH4ppm,delt,latest_ana_rlt.result.CH4ppm*0.9); ana_result.result.CH4ppm=latest_ana_rlt.result.CH4ppm*0.9; } } else if(latest_ana_rlt.result.CH4ppm>=(1.0))//上次测量值大于1ppm { //本次比上次大 delt=(ana_result.result.CH4ppm-latest_ana_rlt.result.CH4ppm)/latest_ana_rlt.result.CH4ppm; if(delt>0.4)//增长率大于40% { LOG_DEBUG(TRACE_DEBUG,"lastCH4=%f currCH4=%f delt=%f correc to %f\n",latest_ana_rlt.result.CH4ppm,ana_result.result.CH4ppm,delt,latest_ana_rlt.result.CH4ppm*1.2); ana_result.result.CH4ppm=latest_ana_rlt.result.CH4ppm*1.2; } } if(ana_result.result.C2H4ppm0.2)//增长率大于-20% { LOG_DEBUG(TRACE_DEBUG,"lastC2H4=%f currC2H4=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H4ppm,ana_result.result.C2H4ppm,delt,latest_ana_rlt.result.C2H4ppm*0.9); ana_result.result.C2H4ppm=latest_ana_rlt.result.C2H4ppm*0.9; } } else if(latest_ana_rlt.result.C2H4ppm>=(1.0))//上次测量值大于1ppm { //本次比上次大 delt=(ana_result.result.C2H4ppm-latest_ana_rlt.result.C2H4ppm)/latest_ana_rlt.result.C2H4ppm; if(delt>0.4)//增长率大于40% { LOG_DEBUG(TRACE_DEBUG,"lastC2H4=%f currC2H4=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H4ppm,ana_result.result.C2H4ppm,delt,latest_ana_rlt.result.C2H4ppm*1.2); ana_result.result.C2H4ppm=latest_ana_rlt.result.C2H4ppm*1.2; } } if(ana_result.result.C2H6ppm0.2)//增长率大于-20% { LOG_DEBUG(TRACE_DEBUG,"lastC2H6=%f currC2H6=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H6ppm,ana_result.result.C2H6ppm,delt,latest_ana_rlt.result.C2H6ppm*0.9); ana_result.result.C2H6ppm=latest_ana_rlt.result.C2H6ppm*0.9; } } else if(latest_ana_rlt.result.C2H6ppm>=(1.0))//上次测量值大于1ppm { //本次比上次大 delt=(ana_result.result.C2H6ppm-latest_ana_rlt.result.C2H6ppm)/latest_ana_rlt.result.C2H6ppm; if(delt>0.4)//增长率大于40% { LOG_DEBUG(TRACE_DEBUG,"lastC2H6=%f currC2H6=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H6ppm,ana_result.result.C2H6ppm,delt,latest_ana_rlt.result.C2H6ppm*1.2); ana_result.result.C2H6ppm=latest_ana_rlt.result.C2H6ppm*1.2; } } if(ana_result.result.C2H2ppm0.2)//增长率大于-20% { LOG_DEBUG(TRACE_DEBUG,"lastC2H2=%f currC2H2=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H2ppm,ana_result.result.C2H2ppm,delt,latest_ana_rlt.result.C2H2ppm*0.9); ana_result.result.C2H2ppm=latest_ana_rlt.result.C2H2ppm*0.9; } } else if(latest_ana_rlt.result.C2H2ppm>=(1.0))//上次测量值大于1ppm { //本次比上次大 delt=(ana_result.result.C2H2ppm-latest_ana_rlt.result.C2H2ppm)/latest_ana_rlt.result.C2H2ppm; if(delt>0.4)//增长率大于40% { LOG_DEBUG(TRACE_DEBUG,"lastC2H2=%f currC2H2=%f delt=%f correc to %f\n",latest_ana_rlt.result.C2H2ppm,ana_result.result.C2H2ppm,delt,latest_ana_rlt.result.C2H2ppm*1.2); ana_result.result.C2H2ppm=latest_ana_rlt.result.C2H2ppm*1.2; } } if(my_para_data.mach_run_para.co2_pos!=0) { if(ana_result.result.CO2ppm0.2)//增长率大于-20% { LOG_DEBUG(TRACE_DEBUG,"lastCO2=%f currCO2=%f delt=%f correc to %f\n",latest_ana_rlt.result.CO2ppm,ana_result.result.CO2ppm,delt,latest_ana_rlt.result.CO2ppm*0.9); ana_result.result.CO2ppm=latest_ana_rlt.result.CO2ppm*0.9; } } else if(latest_ana_rlt.result.CO2ppm>=(1.0))//上次测量值大于1ppm { //本次比上次大 delt=(ana_result.result.CO2ppm-latest_ana_rlt.result.CO2ppm)/latest_ana_rlt.result.CO2ppm; if(delt>0.4)//增长率大于40% { LOG_DEBUG(TRACE_DEBUG,"lastCO2=%f currCO2=%f delt=%f correc to %f\n",latest_ana_rlt.result.CO2ppm,ana_result.result.CO2ppm,delt,latest_ana_rlt.result.CO2ppm*1.2); ana_result.result.CO2ppm=latest_ana_rlt.result.CO2ppm*1.2; } } } else { ana_result.result.CO2ppm=0; } } } memcpy(&ysp_pri_data,&ana_result.result,sizeof(YSP_PRI_DATA)); ysp_pri_data.TotHyd=ysp_pri_data.CH4ppm+ysp_pri_data.C2H2ppm+ysp_pri_data.C2H4ppm+ysp_pri_data.C2H6ppm; ana_result.result.TotHyd=ysp_pri_data.TotHyd; add_his_entry(&ana_result);//添加进数据库 if(save_last_result(&ana_result)!=0) { LOG_DEBUG(ERROR_DEBUG,"save last data failed\n"); } send_ysp_msg(&ysp_pri_data); for(i=0;i<6;i++) { ysp_ana_pos.position[i].start=ana_result.pos_info[i].start; ysp_ana_pos.position[i].peak=ana_result.pos_info[i].peak; } if(save_analysis_file(analysis_buf,MAX_DATA_LEN,&my_para_data,&ysp_ana_pos,&ysp_pri_data)==0) { LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"save analysis file %s sucessful\n",analysis_buf); } else { LOG_DEBUG(ERROR_DEBUG,"save_analysis_file %s failed\n",analysis_buf); } } else { LOG_DEBUG(ERROR_DEBUG,"analysis %s failed\n",analysis_buf); } } else { //LOG_DEBUG(ANALYSIS_TRACE_DEBUG,"analysis is running\n"); } } return ((void *)0); } int analysis_init(void) { pthread_t analysis_thread; if((analysis_thread=task_create(analysis_routine,NULL,0,0))==-1) { LOG_DEBUG(ERROR_DEBUG,"create analysis_routine failed\n"); return 1; } return 0; }