利用MATLAB编制的GPS单点定位程序
更新时间:2023-10-24 12:40:01 阅读量: 综合文库 文档下载
function t=TimetoJD(Y,M,D,h,f,s) if(Y>=80)
Y=Y+1900; else
Y=Y+2000; end if M<=2 Y=Y-1; M=M+12; end
JD=fix(365.25*Y)+fix(30.6001*(M+1))+D+h/24+f/1440+s/24/3600+1720981.5; t=JD-2444244.5;
function [head,obs]=ReadObsData
%读接收机观测数据文件
%HeadODat :a structure stores header information if o-file
% .ApproXYZ[3]; //approximate coordinate % .interval; //intervals of two adjacent epochs % .SiteName; //point name % .Ant_H; //antenna height
% .Ant_E; //east offset of the antenna center % .Ant_N; //north offset of then antenna center
% .TimeOB; //first epoch time in modifuied Julian time % .TimeOE; //last epoch time in modifuied Julian time % .SumOType; //number of types of observables
% .SumOO[SumOType]; //type of observables 0-L1,1-L2,2-C1,3-P1,4-P2,5-D1,6-D2,
%ObsODat :a structure stores observables by one and one epoch % .TimeOEpp[2]; //reciever time of epoch % .SatSum; //number of satellites % .SatCode[SatSum]; //satellites' PRN % .Obs_FreL1[SatSum]; % .Obs_FreL2[SatSum]; % .Obs_RangeC1[SatSum]; % .Obs_RangeP1[SatSum]; % .Obs_RangeP2[SatSum]; global HeadODat; global ObsODat;
[fname,fpath]=uigetfile('*.*','选择一个O文件'); O_filename=strcat(fpath,fname);
fid1=fopen(O_filename,'rt'); if (fid1==-1)
msgbox('file invalide','warning','warn'); return; end
%将文件头数据存入结构体HeadODat中 t=0;
while(t<100)
s=fgets(fid1); t=t+1; L=size(s,2); if L<81
s(L+1:81)=' '; end
instrS=s(61:81);
%测站点近似坐标
if strncmp(instrS,'APPROX POSITION XYZ',19) HeadODat.ApproXYZ=zeros(1,3);
HeadODat.ApproXYZ(1,1)=str2num(s(1:14)); HeadODat.ApproXYZ(1,2)=str2num(s(15:28)); HeadODat.ApproXYZ(1,3)=str2num(s(29:42));
%历元间隔;
elseif strncmp(instrS,'INTERVAL',8)
HeadODat.interval=str2num(s(5:11)); %测站点号
elseif strncmp(instrS,'MARKER NAME',11) HeadODat.SiteName=s(1:4) %天线中心改正
elseif strncmp(instrS,'ANTENNA: DELTA H/E/N',20) HeadODat.Ant_H=str2num(s(1:14)); HeadODat.Ant_E=str2num(s(15:28)); HeadODat.Ant_N=str2num(s(29:42)); %第一个历元时间
elseif strncmp(instrS,'TIME OF FIRST OBS',17) year=str2num(s(1:6)); month=str2num(s(7:12)); day=str2num(s(13:18)); hour=str2num(s(19:24)); minute=str2num(s(25:30)); second=str2num(s(31:42));
HeadODat.TimeOB=TimetoJD(year,month,day,hour,minute,second); %最后一个历元时间
elseif strncmp(instrS,'TIME OF LAST OBS',16) year=str2num(s(1:6)); month=str2num(s(7:12));
day=str2num(s(13:18)); hour=str2num(s(19:24)); minute=str2num(s(25:30)); second=str2num(s(31:42));
HeadODat.TimeOE=TimetoJD(year,month,day,hour,minute,second); %观测值类型
elseif strncmp(instrS,'# / TYPES OF OBSERV',19) HeadODat.SumOType=str2num(s(1:6));
HeadODat.SumOO=ones(1,HeadODat.SumOType)*-1; for k=1:HeadODat.SumOType f=s(k*6+5:k*6+6); if strcmp(f,'L1')
HeadODat.SumOO(1,k)=0; elseif strcmp(f,'L2')
HeadODat.SumOO(1,k)=1; elseif strcmp(f,'C1')
HeadODat.SumOO(1,k)=2; elseif strcmp(f,'P1')
HeadODat.SumOO(1,k)=3; elseif strcmp(f,'P2')
HeadODat.SumOO(1,k)=4; elseif strcmp(f,'D1')
HeadODat.SumOO(1,k)=5; elseif strcmp(f,'D2')
HeadODat.SumOO(1,k)=6; end end
%头文件结束
elseif strncmp(instrS,'END OF HEADER',13) break; else
continue; end end
%观测数据结构体%观测数据结构 t=0;
while ~feof(fid1)
%每个历元的第一行数据,时间和观测到的卫星号 s=fgets(fid1); t=t+1;
year=str2num(s(1:3)); month=str2num(s(4:6));
day=str2num(s(7:9)); hour=str2num(s(10:12)); minute=str2num(s(13:15)); second=str2num(s(16:26));
%历元时间
ObsODat(t).TimeOEp=[year,month,day,hour,minute,second]; ObsODat(t).TimeOEpp=TimetoJD(year,month,day,hour,minute,second); %该历元观测到的卫星数
ObsODat(t).SatSum=str2num(s(30:32));
%该历元观测到的卫星号
ObsODat(t).SatCode=zeros(1,ObsODat(t).SatSum); ObsODat(t).Obs_FreL1=zeros(1,ObsODat(t).SatSum); ObsODat(t).Obs_FreL2=zeros(1,ObsODat(t).SatSum); ObsODat(t).Obs_RangeC1=zeros(1,ObsODat(t).SatSum); ObsODat(t).Obs_RangeP1=zeros(1,ObsODat(t).SatSum); ObsODat(t).Obs_RangeP2=zeros(1,ObsODat(t).SatSum); for k=1:ObsODat(t).SatSum f=s(31+k*3:32+k*3);
ObsODat(t).SatCode(1,k)=str2num(f); end
%每个历元的观测数据,按卫星号先后顺序分行存 for k=1:ObsODat(t).SatSum s=fgets(fid1);
%判断一个卫星的观测数据是否分两行存储,如果为两行,则再读入一行 if HeadODat.SumOType>5 sg=fgets(fid1); s=strcat(s,sg); end
L=size(s,2);
%补充数据长度
if L s(L+1:HeadODat.SumOType*16)=' '; end %对观测数据判断其类型,并存储到相应的数组中 for j=1:HeadODat.SumOType stemp=s(j*16-15:j*16); stemp=deblank(stemp); if isempty(stemp) continue; end stempNum=str2num(stemp); stempLength=size(stempNum,2); if stempLength>1 stempNum=stempNum(1,1); end if HeadODat.SumOO(1,j)==0 ObsODat(t).Obs_FreL1(1,k)=stempNum; elseif HeadODat.SumOO(1,j)==1 ObsODat(t).Obs_FreL2(1,k)=stempNum; elseif HeadODat.SumOO(1,j)==2 ObsODat(t).Obs_RangeC1(1,k)=stempNum; elseif HeadODat.SumOO(1,j)==3 ObsODat(t).Obs_RangeP1(1,k)=stempNum; elseif HeadODat.SumOO(1,j)==4 ObsODat(t).Obs_RangeP2(1,k)=stempNum; else continue; end end %完成一个卫星的所有观测数据存储 end %完成一个历元的数据存储 end %完成所有历元的数据存储 head=HeadODat; obs=ObsODat; return function EphDat=ReadGpsData global EphDat EphDat=struct; [filename,pathname]=uigetfile('*.**N','读取GPS广播星历文件'); fid1=fopen(strcat(pathname,filename),'rt'); if(fid1==-1) msgbox('Input File or Path is not correct','warning ','warn'); return; end while(1) temp=fgetl(fid1); header=findstr(temp,'END OF HEADER'); if(~isempty(header)) break; end end i=1; while(1) temp=fgetl(fid1); if(temp==-1) break; end EphDat(i).PRN=str2double(temp(1:2)); year=str2double(temp(3:5)); EphDat(i).toc=TimetoJD(year,str2double(temp(6:8)),str2double(temp(9:11)),str2double(temp(12:14)),str2double(temp(15:17)),str2double(temp(18:22))); EphDat(i).a0=str2num(temp(23:41)); EphDat(i).a1=str2num(temp(42:60)); EphDat(i).a2=str2num(temp(61:79)); temp=fgetl(fid1); EphDat(i).idoe=str2num(temp(4:22)); EphDat(i).Crs=str2num(temp(23:41)); EphDat(i).dn=str2num(temp(42:60)); EphDat(i).M0=str2num(temp(61:79)); temp=fgetl(fid1); EphDat(i).Cuc=str2num(temp(4:22)); EphDat(i).e=str2num(temp(23:41)); EphDat(i).Cus=str2num(temp(42:60)); EphDat(i).sqa=str2num(temp(61:79)); temp=fgetl(fid1); EphDat(i).toe=str2num(temp(4:22)); EphDat(i).Cic=str2num(temp(23:41)); EphDat(i).omg0=str2num(temp(42:60)); EphDat(i).Cis=str2num(temp(61:79)); temp=fgetl(fid1); EphDat(i).i0=str2num(temp(4:22)); EphDat(i).Crc=str2num(temp(23:41)); EphDat(i).w=str2num(temp(42:60)); EphDat(i).omg=str2num(temp(61:79)); temp=fgetl(fid1); EphDat(i).iDot=str2num(temp(4:22)); EphDat(i).cflgl2=str2num(temp(23:41)); EphDat(i).weekno=str2num(temp(42:60)); EphDat(i).pflgl2=str2num(temp(61:79)); temp=fgetl(fid1); EphDat(i).svacc=str2num(temp(4:22)); EphDat(i).svhlth=str2num(temp(23:41)); EphDat(i).tgd=str2num(temp(42:60)); EphDat(i).aodc=str2num(temp(61:79)); temp=fgetl(fid1); EphDat(i).ttm=str2num(temp(4:22)); if(i~=1) %删除重复数据 for k= i-1:i if (EphDat(i-1).PRN~=EphDat(i).PRN) break; elseif abs(EphDat(i-1).toc-EphDat(i).toc)<0.001 i=i - 1; end end end i=i + 1; end function DDDW format long clear all tic global HeadODat; global ObsODat; global EphDat; %先读N文件,再读O文件 EphDat=ReadGpsData; [HeadODat,ObsODat]=ReadObsData; %多个历元加权平均求测站点坐标 N = size(EphDat,2); c=299792458; epochNUM=size(ObsODat,2); %观测数据的个数 Xk0=HeadODat.ApproXYZ(1,1); %测站点的近似坐标 Yk0=HeadODat.ApproXYZ(1,2); Zk0=HeadODat.ApproXYZ(1,3); for k=1:epochNUM tr=ObsODat(k).TimeOEp; %历元接收数据时间 Snum=ObsODat(1,k).SatSum; %该历元观测到的卫星数 if Snum<4 break; %去除无解的历元 end Code=ObsODat(k).SatCode; %该历元观测到的卫星号组 R=ObsODat(k).Obs_RangeC1 ; %取出C1观测值,列向量 %卫星发射时间的迭代计算 for j=1:Snum if R(j) == 0 continue; end t=TimetoJD(tr(1),tr(2),tr(3),tr(4),tr(5),tr(6)); t2 = mod(t,7)*24*3600;%gps second %卫星钟差 dd=-1; for i=1:N if(EphDat(i).PRN==Code(j)&abs(t-EphDat(i).toc)<0.0417*2)%读入时间相近的星历文件 a0= EphDat(i).a0; a1=EphDat(i).a1; a2= EphDat(i).a2; toe=EphDat(i).toe; dt=a0+(t2-toe)*a1+(t2-toe)^2*a2;%卫星钟差 dd=1; break; end end if dd==-1 msgbox('没有相关星历文件'); return; end tt = tr; ts = tr(6) - R(j)/c;%用秒进行迭代 sign = 1; while(sign>1E-8) tt(6) = ts; [Xs1,Ys1,Zs1]= CalPos(Code(j),tt); ss1 = sqrt((Xk0-Xs1)^2+(Yk0-Ys1)^2+(Zk0-Zs1)*(Zk0-Zs1)); %卫星位置加地球自转改正 qe=0.000072921151467; %地球自转角速度 delt=ss1/c; Rotation=[cos(qe*delt),sin(qe*delt),0;-sin(qe*delt),cos(qe*delt),0;0,0,1]; h=Rotation*[Xs1;Ys1;Zs1] ; Xs=h(1); Ys=h(2); Zs=h(3); ss = sqrt((Xk0-Xs)^2+(Yk0-Ys)^2+(Zk0-Zs)*(Zk0-Zs)); ts = tr(6)-ss/c; sign = norm(ts-tt(6)); end axk = (Xk0-Xs)/ss; ayk = (Yk0-Ys)/ss; azk = (Zk0-Zs)/ss; EAB=CAL2POL(Xk0,Yk0,Zk0,Xs,Ys,Zs); if j==1 A = [axk,ayk,azk,1]; L = R(j)-ss++c*dt-2.47/(sin(EAB)+0.0121); else A = [A;axk,ayk,azk,1]; %构造误差方程 L = [L;(R(j)-ss++c*dt)-2.47/(sin(EAB)+0.0121)];%常数项 end end if Snum==4 dx=inv(A)*L; aaaa(k).Q=inv(A'*A); Px(k) = 1/aaaa(k).Q(1,1); Py(k) = 1/aaaa(k).Q(2,2); Pz(k) = 1/aaaa(k).Q(3,3); xchange(k) = dx(1); ychange(k) = dx(2); zchange(k) = dx(3); elseif Snum > 4 dx = inv(A'*A)*A'*L; %构造法方程并求解 aaaa(k).Q=inv(A'*A); Px(k) = 1/aaaa(k).Q(1,1); Py(k) = 1/aaaa(k).Q(2,2); Pz(k) = 1/aaaa(k).Q(3,3); xchange(k) = dx(1); ychange(k) = dx(2); zchange(k) = dx(3); end end Xp=sum(Px.*(Xk0+xchange))/sum(Px) Yp=sum(Py.*(Yk0+ychange))/sum(Py) Zp=sum(Pz.*(Zk0+zchange))/sum(Pz) figure(1); subplot(3,1,1);plot(xchange,'black--'); subplot(3,1,2);plot(ychange,'black--'); subplot(3,1,3);plot(zchange,'black--'); toc function [x,y,z]= CalPos(PRN,time) global EphDat t1=TimetoJD(time(1),time(2),time(3),time(4),time(5),time(6)); t2=TimetoJD(time(1),time(2),time(3),0,0,0); if isempty(EphDat) EphDat=ReadGpsData; end sz=size(EphDat,2); gg=0; %判断最近的时间 for i=1:sz if(EphDat(i).PRN==PRN & abs(EphDat(i).toc-t1)<0.0417*2) G=EphDat(i); gg=1; break; end end t3=t2-G.weekno*7; % 减整周 数 t=t3*24*3600+time(4)*3600+time(5)*60+time(6); %化为GPS秒 u=3.986004418E+14; %地球引力常数 we=7.2921151467E-5; %地球自转速度 a=G.sqa^2; %地球长半轴 n0=sqrt(u/a^3); %计算的平运动 tk=t-G.toe; %从参考历元开始的时间 if tk>=302400 tk=tk-604800; elseif tk<-302400 tk=tk + 604800; end n=n0+G.dn; %改正后的运动 Mk=G.M0+n*tk; Ek=Mk; %偏近点角for i=1:4 Ek=Mk+G.e*sin(Ek); end fk=2*atan((sqrt((1+G.e)/(1-G.e))*tan(Ek/2))); %真近点角 if(fk<0) fk=fk+2*pi; end cosf=(cos(Ek)-G.e)/(1-G.e*cos(Ek)); sinf=(sqrt(1-G.e^2)*sin(Ek))/(1-G.e*cos(Ek)); 弧度 uk=fk+G.w; %升交角矩及轨道摄动改正项 iuk=G.Cuc*cos(2*uk)+G.Cus*sin(2*uk); irk=G.Crc*cos(2*uk)+G.Crs*sin(2*uk); iik=G.Cic*cos(2*uk)+G.Cis*sin(2*uk); uk=uk+iuk ; %改正后的升角距 r=a*(1-G.e*cos(Ek))+irk; %改正后的地心相径 i=G.i0+iik+G.iDot*tk; %改正后的倾角 xx=r*cos(uk); %在轨道面中的位置 yy=r*sin(uk); omg=G.omg0+(G.omg-we)*tk-we*G.toe; %改正后的升交点经度 x=xx*cos(omg)-yy*cos(i)*sin(omg); y=xx*sin(omg)+yy*cos(i)*cos(omg); z=yy*sin(i); CalPos=[x,y,z]; %打印结果 % x=num2str(x,'.6f'); % y=num2str(y,'.6f'); % z=num2str(z,'.6f'); % fprintf('卫星号PRN:%2.0f',PRN); fprintf('\\n'); % fprintf('时间time:%4.0f%4.0f%4.0f%4.0f%4.0f%4.1f',time); fprintf('\\n'); % fprintf('所求卫星在地心坐标系中的空间坐标为:\\n'); % fprintf('X = ');fprintf(x,'\\n');fprintf('m\\n'); % fprintf('Y = ');fprintf(y,'\\n');fprintf('m\\n'); % fprintf('Z = ');fprintf(z,'\\n');fprintf('m\\n'); % return function EAB=CAL2POL(X,Y,Z,XB,YB,ZB) format long L=atan(Y/X); R=sqrt(X*X+Y*Y+Z*Z); a=6378137; e=sqrt(0.0066943799013); seta=atan(Z/sqrt(X*X+Y*Y)); B=asin(sqrt((a*a-R*R*cos(seta)*cos(seta))/(a*a-R*R*cos(seta)*cos(seta)*e*e))) B1=atan(tan(seta)*(1+a*e*e*sin(B)/Z/sqrt(1-e*e*sin(B)*sin(B)))); while abs(B1-B)>0.01*pi/180/3600 B=B1; B1=atan(tan(seta)*(1+a*e*e*sin(B)/Z/sqrt(1-e*e*sin(B)^2))); end H=R*cos(seta)/cos(B)-(a/sqrt(1-e*e*sin(B)*sin(B))); L=L*180/pi; B=B*180/pi; DX=XB-X; DY=YB-Y; DZ=ZB-Z; NB=-sin(B)*cos(L)*DX-sin(B)*sin(L)*DY+cos(B)*DZ; EB=-sin(L)*DX+cos(L)*DY; UB=cos(B)*cos(L)*DX+cos(B)*sin(L)*DY+sin(B)*DZ; SAB=sqrt(NB*NB+UB*UB+EB*EB); EAB=asin(UB/SAB);
正在阅读:
利用MATLAB编制的GPS单点定位程序10-24
重庆市土地利用总体规划(2006~2020年) - 图文06-27
《长方体和正方体表面积计算》的教学设计、说课、反思05-31
马年春联:带马字春联集锦02-09
监督所制度 - 图文01-28
2009年射击项目全国最高级别比赛10-27
溃疡性结肠炎模型选择及评价指标11-11
建筑空间构成教学大纲08-14
供电流程09-24
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 单点
- 编制
- 定位
- 利用
- 程序
- MATLAB
- GPS
- 《昆虫记》阅读指导课、活动课教学设计
- 2018-2019四年级数学下册期中试卷
- 学校食品、米面油采购投标方案说明(投标文件) - 图文
- 基于ASPNET的网上订餐系统
- 大学生社会调研心得体会
- 上海大众核心配套供应商名单
- 微观经济学第五章题库
- 液氨储存风险防范及管理措施
- 九年级化学上册第四单元自然界的水课题2水的净化同步练习(新版)新人教版
- C++程序设计论文模板
- 农副产品冷链物流中心项目可行性报告
- 企财险理赔操作实务
- 2012年中考初中语文综合性学习训练题
- 仲溪隧道施工组织设计
- 两位大师的个性
- 软件测试简答题库
- 911电子线路(模拟电路+数字电路)初试试卷(B卷)
- 现在完成时态讲解和练习
- 2016习题19 功和能一
- 2011年河南省中考英语试题