⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpscx.c

📁 GPS调试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <iom128.h>
#include <stdlib.h>
#include <string.h>
#include "stdio.h"
#include "math.h"
#include <ctype.h>
#include "htcprocdef.h"
#include "htcprocrom.h"
#include "biaoding.h"
/*保留最近三个GPS点*/
double  SQRT(double  y)  
{  
#define  eps  1e-15  
           double  x1,x2;  
 
           if(y<eps)  return  0;  
 
           x2=  y>1.0?  y/2  :  y*2;  
 
           do{  
                       x1  =  x2;  
                       x2  =  (x1  +  y/x1)/2;  
           }while(fabs(x2-x1)  >  eps);  
             
           return  x2;  
#undef  eps    
}

float lcd_bit5dis(unsigned char lcd_ds,unsigned char lcd_dy,float fdata)
{   long j;
	unsigned int i;
	unsigned int p;
	static unsigned char buf_lcd[5];
	j=fdata;
	buf_lcd[0]=j/10000;
	i=j%10000;
	p=i%1000;
	buf_lcd[1]=i/1000;
	buf_lcd[2]=p/100;
	buf_lcd[3]=(p%100)/10;
	buf_lcd[4]=(p%100)%10;

	lcd_display(lcd_ds,lcd_dy,buf_lcd,5);
	return (fdata-j);
}




/*由kcl和kch插值计算*/
void compass_in(float com_tem)
{
 float c_newton;
  if (kch!=kchN)
  {
    c_newton=(com_bd[kcl][1]-com_bd[kch][1])/(com_bd[kcl][0]-com_bd[kch][0]);
    compass_m=com_bd[kcl][1]+c_newton*(com_tem-com_bd[kcl][0]);
  }
  else if (com_tem>com_bd[kch][0])/*com_bd[kcl0+1][0]+360后再插值计算*/
  {
    c_newton=(com_bd[kcl][1]-com_bd[kch][1])/(com_bd[kcl][0]-com_bd[kch][0]-360);
    compass_m=com_bd[kcl][1]+c_newton*(com_tem-com_bd[kcl][0]);
  }
  else/*com_tem加360,com_bd[kcl0+1][0]+360后再插值计算,将得到的结果-360后,得到compass_m*/
  {
    c_newton=(com_bd[kcl][1]-com_bd[kch][1])/(com_bd[kcl][0]-com_bd[kch][0]-360);
    compass_m=com_bd[kcl][1]+c_newton*(com_tem+360-com_bd[kcl][0]);
  }
    compass_m=ceil(compass_m*10);
	compass_m=compass_m/10;/*去除小数点后面第二位*/
	compass_m=compass_m-compen_th;
}

void compassdata_cal(float com_tem)
{
 	 int kn,KCH=120;
	 float dc1,dc2;
	 kcl=0;kch=118;
	 kchN=kch+1;//int kcl,kchN,kcm,kch=116;插值时标定数据的序号*/
	 com_tem=ceil(com_tem*10);
	 com_tem=com_tem/10;/*去除小数点后面第二位*/
	 /*处理区间[10.9-357.5]*/
	 if (fabs(com_tem-com_bd[0][0])<0.08) /*判断是否相等*/
	 {
	 compass_m=com_bd[0][1];
	 compass_m=compass_m-compen_th;//double compen_th=0; 设置磁偏角
	 return;
	 }
	 if (fabs(com_tem-com_bd[kch][0])<0.08)/*判断是否相等*/
	 {
	   compass_m=com_bd[kcl-1][1];
	   compass_m=compass_m-compen_th;
	   return;
	 } 
	 if (com_tem>com_bd[0][0]&&com_tem<com_bd[kch][0])
	 {
	  while (kch-kcl!=1)
	  {
	   kcm=(kcl+kch)/2; 
	   dc1=com_tem-com_bd[kcl][0];
	   dc2=com_tem-com_bd[kcm][0];
	   if (fabs(dc2)<0.08)
	   {
	     compass_m=com_bd[kcm][1];
		 compass_m=compass_m-compen_th;
	     return;
	   }
	   if (dc1*dc2>0)
	   {
	     kcl=kcm;
	   }
	   else 
	   {
	     kch=kcm;
	   }
	 }
	 
	  /*调用插值公式,利用kcl和kch*/ 
	  compass_in(com_tem);	
	  return;
	} 
	 
     /*处理[kchN,KCH]区间上的读数*/
	 if (com_tem>com_bd[kchN][0]&&com_tem<com_bd[KCH][0])
	 {
	   for (kn=kchN+1;kn<=KCH;kn++)
	   {
		 if (fabs(com_tem-com_bd[kn][0])<0.08)/*判断是否相等*/
		 {
		  compass_m=com_bd[kn][1];
		  compass_m=compass_m-compen_th;
		  return;
		 }		 
		 if (com_tem<com_bd[kn][0])
	     {
	       kcl=kn-1;
	       kch=kn;
	       break;
	     }
	   }/*for*/
	   /*插值计算,得到compass_m*/
	   compass_in(com_tem);
	   return;
	 }
	  
	 /*处理区间[357.5-360]和[0-0.8]上的读数*/
	 if (fabs(com_tem-com_bd[kch][0])<0.08)/*判断是否相等*/
	 {
	   compass_m=com_bd[kch][1];
	   compass_m=compass_m-compen_th;
	   return;
	 }
	 if (fabs(com_tem-com_bd[kchN][0])<0.08)/*判断是否相等*/
	 {
	   compass_m=com_bd[kchN][1];
	   compass_m=compass_m-compen_th;
	   return;
	 }
	 if (com_tem>com_bd[kch][0]||com_tem<com_bd[kchN][0])
	 {
	   kcl=kch;
	   kch=kchN;
	   compass_in(com_tem);
	   return;	 
	 }
}


/*计算流速
**double move_velocity(int N_pulse,double time_velocity);
**输入:脉冲个数N_pulse,时间time_velocity,
**返回:该段时间内的流速,并置位is_vel_new*/
void move_velocity( void)
{
	if (move_time==0)
	move_vel=0;
	else
    move_vel=C_vel+K_vel*5*move_pulse/move_time;
	if (move_vel<5)
	   over_move_vel=move_vel;
	else
	   move_vel=over_move_vel;
}
/*海流速度的计算
**void wave_vel_cal(struct location *p_loc_data,double *p_wave_vel);
**输入:指向海流速度的指针double *p_wave_vel,指向结构体数组的指针struct location *p_loc_data
**返回:空*/
void wave_vel_cal(void)
{
    float a,b,c;
	a=b=c=0;
	
    a=location_data[2].GPS_x-location_data[1].GPS_x-location_data[2].Relative_x;
    b=location_data[2].GPS_time-location_data[1].GPS_time;
	b=b/10.0*10;
    wave_vel[0]=a/b;
    c=location_data[2].GPS_y-location_data[1].GPS_y-location_data[2].Relative_y;
    wave_vel[1]=c/b;
}

void wave_vel_cal1(void)
{
    float a,b,c;
	a=b=c=0;
	
    a=location_data[2].GPS_x-location_data[1].GPS_x-location_data[2].Relative_x;
    b=location_data[2].GPS_time-location_data[1].GPS_time;
	b=b/10.0*10;
    wave_vel[0]=a/b;
    c=location_data[2].GPS_y-location_data[1].GPS_y-location_data[2].Relative_y;
    wave_vel[1]=c/b;
}


/*计算两个GPS点在x轴和y轴方向的坐标差
**void dist_cal(struct location *p_loc_data,double *p_dist)
**输入:
**返回:*/
void dist_cal(void)
{
    int p_loc_tem;
	p_loc_tem=p_current_loc-1;
	dist[0]=dist[1];
	dist[2]=dist[3];
	dist[4]=dist[5];
	dist[6]=dist[7];

    dist[1]=location_data[p_loc_tem].GPS_x-location_data[p_loc_tem-1].GPS_x;
    dist[3]=location_data[p_loc_tem].GPS_y-location_data[p_loc_tem-1].GPS_y;
	dist[5]=location_data[p_loc_tem].GPS_time;
	dist[7]=SQRT(dist[1]*dist[1]+dist[3]*dist[3]);
}

/*更新海流的速度
wave_vel_adjust(p_current_loc,dist,wave_vel);
** 返回:空 */
void wave_vel_adjust()
{
   	double a,b;
	int p_loc_data;
	p_loc_data=p_current_loc-1;
	a=dist[0]+dist[1]-location_data[p_loc_data].Relative_x-location_data[p_loc_data-2].Relative_x;
	b=dist[4]+dist[5];
	b=b*10.0/10;
    wave_vel[0]=a/b;
	a=dist[2]+dist[3]-location_data[p_loc_data].Relative_y-location_data[p_loc_data-2].Relative_y;
    wave_vel[1]=a/b;
}

/*相对轨迹的计算
**void relative_dis()
//	  relative_dis(compass_data,&Done_i,&Current_I,Relative_tem);
//void relative_dis(double *p_compass,char *p_Done_i,char *p_Current_I,double *p_rela_dis)

*/
void relative_dis(void)
{   double dir;
    while (Done_i!=Current_i)
	{
	  compassdata_cal(compass_data[Done_i]);
	  dir=compass_m;
	  Relative_tem[0]=Relative_tem[0]+sin(dir/180*PI)/f_compass;/*x轴方向*/
      Relative_tem[1]=Relative_tem[1]+cos(dir/180*PI)/f_compass;
	  Done_i++;
	  N_compass++;
	  if (Done_i==50)
	  Done_i=0;
	}
}

/*航行方向
**void navigate_direction()
//    navigate_direction(wave_vel,move_vel,compass_data[49],&nav_dir);

*/
void navigate_direction(float comp_cur)
{
   float a,b,theta;
    a=move_vel*sin(comp_cur/180*PI)+wave_vel[0];/*x轴方向*/
    b=move_vel*cos(comp_cur/180*PI)+wave_vel[1];/*y轴方向*/
	theta=atan2(a,b)/PI*180;/*返回值在-180—180度之间*/
	if (theta<0)
	nav_dir=360+theta;
	else
	nav_dir=theta;
}

/*计算经度和纬度的正弦和余弦值*/
void sin_cos(double *p_LBH_ini,double *p_sin_cos_ini)
{
    *p_sin_cos_ini=sin((*p_LBH_ini)/180.0*PI);
	*(p_sin_cos_ini+1)=cos((*p_LBH_ini)/180.0*PI);
	*(p_sin_cos_ini+2)=sin((*(p_LBH_ini+1))/180.0*PI);
	*(p_sin_cos_ini+3)=cos((*(p_LBH_ini+1))/180.0*PI);
}

/*将大地坐标系(经度、纬度、高度)转化到直角坐标系(XYZ)
**void LBH2XYZ(double L,double B,double H,double *p_XYZ)
*/
void LBH2XYZ(double *p_LBH,double *p_XYZ)
{
    double N,e2=0.00669437999013,a=6378137;//a:长轴
	double sinL,cosL,sinB,cosB;
	sinL=sin((*p_LBH)/180.0*PI);
	cosL=cos((*p_LBH)/180.0*PI);
	sinB=sin((*(p_LBH+1))/180.0*PI);
	cosB=cos((*(p_LBH+1))/180.0*PI);
    N=a/SQRT(1-e2*sinB*sinB);
	
	*p_XYZ=(N+(*(p_LBH+2)))*cosB*cosL;//X
    *(p_XYZ+1)=(N+(*(p_LBH+2)))*cosB*sinL;//Y
    *(p_XYZ+2)=(N*(1-e2)+(*(p_LBH+2)))*sinB;
	
}

/*将直角坐标(XYZ)转化到东北天坐标(xyz)
*/
//void LBH2xyz(double *p_XYZ_ini,double *p_sin_cos_ini,double *p_LBH,double *p_xyz)
//LBH2xyz(XYZ_ini,sin_cos_ini,LBH_Targ,xyz_Targ);
void LBH2xyz(double *p_LBH,double *p_xyz)
{
    double X1,Y1,Z1,XYZ[3];
	LBH2XYZ(p_LBH,XYZ);/*当前GPS点的XYZ*/
	//lcd_compass(-XYZ[0]-2613200);// 调试
	//lcd_pressure(XYZ[1]-4739600);//调试	
	X1=XYZ[0]-XYZ_ini[0];/*正确-X1-1380*/
    Y1=XYZ[1]-XYZ_ini[1];/*正确值应该是-760.5*/
    Z1=XYZ[2]-XYZ_ini[2];/*正确值应该是0*/
	*p_xyz=-sin_cos_ini[0]*X1+sin_cos_ini[1]*Y1;
    *(p_xyz+1)=-sin_cos_ini[1]*X1*sin_cos_ini[2]-sin_cos_ini[0]*Y1*sin_cos_ini[2]+sin_cos_ini[3]*Z1;
    *(p_xyz+2)=sin_cos_ini[1]*X1*sin_cos_ini[3]+sin_cos_ini[0]*Y1*sin_cos_ini[3]+sin_cos_ini[2]*Z1;
}

/*将东北天坐标xyz转化为直角坐标XYZ
void xyz2XYZ(double *p_xyz,double *p_sin_cos_ini,double *p_XYZ_ini,double *p_XYZ)
// xyz2XYZ(Relative_tem,sin_cos_ini,XYZ_ini,XYZ_cal);
*/

void xyz2XYZ(void)
{
  double dX,dY,dZ;
  dX=-sin_cos_ini[2]*Relative_tem[1]*sin_cos_ini[1]-sin_cos_ini[0]*Relative_tem[0]+sin_cos_ini[3]*Relative_tem[2]*sin_cos_ini[1];
  dY=-sin_cos_ini[2]*Relative_tem[1]*sin_cos_ini[0]+sin_cos_ini[1]*Relative_tem[0]+sin_cos_ini[3]*Relative_tem[2]*sin_cos_ini[0];
  dZ=sin_cos_ini[3]*Relative_tem[1]+sin_cos_ini[2]*Relative_tem[2];

  XYZ_cal[0]=XYZ_ini[0]+dX;
  XYZ_cal[1]=XYZ_ini[1]+dY;
  XYZ_cal[2]=XYZ_ini[2]+dZ;
}



/*将直角坐标(XYZ)转换到大地坐标(LBH)*/
//     XYZ2LBH(XYZ_cal,LBH_cal);
//void XYZ2LBH(double *p_XYZ,double *p_LBH_cal)

void XYZ2LBH(void)  
{
    
    double a=6378137,b=6356752.3142;
    double e1_2=0.00669437999013,e2_2=0.00673949674227;
    double B0,s_XY,u,sinu,cosu,N,T;/**/
    s_XY=SQRT(XYZ_cal[0]*XYZ_cal[0]+XYZ_cal[1]*XYZ_cal[1]);
	u=atan(a*XYZ_cal[2]/(s_XY*b));
	sinu=sin(u);cosu=cos(u);
	B0=atan((XYZ_cal[2]+b*e2_2*sinu*sinu*sinu)/(s_XY-a*e1_2*cosu*cosu*cosu));
	N=a/SQRT(1-e1_2*sin(B0)*sin(B0));

    LBH_cal[0]=atan(XYZ_cal[1]/XYZ_cal[0])+PI;
	T=XYZ_cal[2]+N*e1_2*sin(B0);
    LBH_cal[2]=SQRT(s_XY*s_XY+T*T)-N;
	LBH_cal[1]=atan(XYZ_cal[2]*(N+LBH_cal[2])/s_XY/(N*(1-e1_2)+LBH_cal[2]));

}


/*计算显示时需要转动的角度
*/
void display_rotate(double *p_Targ_xyz,float *p_disp_rot)
{
    float theta;
    theta=atan2(*p_Targ_xyz,*(p_Targ_xyz+1))/PI*180;/*返回值在-180—180度之间*/
	if (theta<0)
	*p_disp_rot=360+theta;
	else
	*p_disp_rot=theta;
}

/*计算要在液晶屏上显示的航行方向
** p_disp_direction:要在液晶屏上显示的航行方向 
*/
/*void disp_direction(double *p_disp_rot,double *p_nav_dir,double *p_disp_direction)
{
    *p_disp_direction=*p_nav_dir-*p_disp_rot;
    if (*p_disp_direction<0)
    *p_disp_direction=360+*p_disp_direction;
}*/

/*当前方位的显示坐标
**void display_xy(double disp_rot,double *p_xyz,double *p_Disp_xy)
//display_xy(disp_rot,Relative_tem,Disp_xy);
*/
void display_xy(double *p_xyz)
{
    double a,b; 
	a=(*p_xyz)*cos(disp_rot/180.0*PI);
	b=(*(p_xyz+1))*sin(disp_rot/180.0*PI);
	Disp_xy[0]=a-b;
	//*p_Disp_xy=(*p_xyz)*cos(disp_rot/180*PI)-(*(p_xyz+1))*sin(disp_rot/180*PI);
	a=(*(p_xyz+1))*cos(disp_rot/180.0*PI);
	b=(*p_xyz)*sin(disp_rot/180.0*PI);
	Disp_xy[1]=a+b;
}

/*判断当前东北天坐标是否要显示
**char is_xy_display(double total_dist,double *p_Disp_xy,double *p_Disp_xy_int)
//is_display=is_xy_display(total_dist,Disp_xy,Disp_xy_int);
**返回:“0”表示无需在液晶屏上显示,“1”表示需要在液晶屏上显示。
*/
char is_xy_display(void)
{
    int x,y;
    x=ceil(Disp_xy[0]/total_dist*N_pixel);
    y=ceil(Disp_xy[1]/total_dist*N_pixel);
	is_exceed_bound=0;
	if (x>x_N_pixel)/*判断是否超出边界*/
	{ x=x_N_pixel;
	  is_exceed_bound=1;
	}
	if (x<-x_N_pixel)
	{ x=-x_N_pixel;
	  is_exceed_bound=1;
	}
	if (y<-15)/*也可以是0*/
	{ y=-15;
	  is_exceed_bound=1;
	}
	if (y>N_pixel+15)
	{ y=N_pixel+15;
	  is_exceed_bound=1;
	}
	
    if (Disp_xy_int[0]==x&&Disp_xy_int[1]==y)    /*判断是否要显示*/
      return (0);
    else 
    {
      Disp_xy_int[0]=x;
      Disp_xy_int[1]=y;
      return (1);
    }
}

/*计算方向箭头的点*/
//	 is_new_point=point_arrow(compass_data[Current_i-1],Disp_xy_int,arrow_point);

char point_arrow(float comp_cur)
{
  int x_arrow,y_arrow;
  char new_point=0;
  
    
      
  x_arrow=ceil(arrow_leng*sin((comp_cur-disp_rot)/180*PI))+ref_point[0] ;
  y_arrow=ceil(arrow_leng*cos((comp_cur-disp_rot)/180*PI))+ref_point[1];
  new_point=(x_arrow==arrow_point[0])&&(y_arrow==arrow_point[1]);
  if(new_point==0)  
  {
    past_arrow[0]=arrow_point[0];
	past_arrow[1]=arrow_point[1];
	past_arrow[2]=arrow_point[2];
	past_arrow[3]=arrow_point[3];
	past_arrow[4]=arrow_point[4];
	past_arrow[5]=arrow_point[5];
  
    arrow_point[0]=x_arrow;
    arrow_point[1]=y_arrow;
    arrow_point[2]=ceil(arrow_leng*0.6*sin((comp_cur-disp_rot)/180*PI+PI/6))+ref_point[0] ;
    arrow_point[3]=ceil(arrow_leng*0.6*cos((comp_cur-disp_rot)/180*PI+PI/6))+ref_point[1];
    arrow_point[4]=ceil(arrow_leng*0.6*sin((comp_cur-disp_rot)/180*PI-PI/6))+ref_point[0] ;
    arrow_point[5]=ceil(arrow_leng*0.6*cos((comp_cur-disp_rot)/180*PI-PI/6))+ref_point[1];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -