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

📄 singldif.pas

📁 The idea behind differential GPS is to remove as much errors as possible from the range measurements
💻 PAS
字号:
program singldif;type   mat96 = array[1..32,1..3] of real;   vecb32 = array[1..32] of boolean;   vec32 = array[1..32] of real;   vec16 = array[1..16] of real;   vec8 = array[1..8] of real;   vec3 = array[1..3] of real;   mat16 = array[1..4,1..4] of real;const   We = 7.292115E-5;            {WGS-84 earth rotation rate}   c = 299792458.0;             {WGS-84 speed of light}   pi = 3.1415926535898         {WGS 84 value of pi};   Wedot = 7.2921151467E-5;     {WGS 84 value of earth's rotation rate}   mu = 3.986005E+14;           {WGS 84 value of earth's univ. grav. par.}   F = -4.442807633E-10;        {relativistic correction term constant}   a = 6378137.0;               {WGS-84 earth's semi major axis}   b = 6356752.31;              {WGS-84 earth's semi minor axis}   e1sqr = (a*a - b*b) / (a*a); {first  numerical eccentricity}   e2sqr = (a*a - b*b) / (b*b); {second numerical eccentricity}var   inp, out: text;   Ttr, tau, Trc, Trel: real;   alpha, Rrs, Crm: real;   prn, i: integer;   eph: array[1..32,1..16] of real;   Prs, Pms, Pmsc: vec32;   Xs: mat96;   SV: vecb32;   Xr, Xm, Xlla, tmp3: vec3;   status: boolean;   tmp16: vec16;   tmp5: array[1..5] of real;{***************************************************************************}procedure LLA2XYZ(Xi : vec3;      {lat [rad], lon [rad] alt [m]}              var Xo : vec3);     {ECEF X [m], Y [m] , Z[m]}{this procedure converts WGS-84 Lat, Lon and Alt [above ellipsoid] to ECEF XYZ}var   N: real;beginN := a / sqrt(1.0 - e1sqr * sin(Xi[1]) * sin(Xi[1]));Xo[1] := (N                 + Xi[3]) * cos(Xi[1]) * cos(Xi[2]);Xo[2] := (N                 + Xi[3]) * cos(Xi[1]) * sin(Xi[2]);Xo[3] := (N * (1.0 - e1sqr) + Xi[3]) * sin(Xi[1]);end; {procedure LLA2XYZ}{***************************************************************************}procedure XYZ2LLA(Xi : vec3;      {ECEF X [m], Y [m] , Z[m]}              var Xo : vec3);     {lat [rad], lon [rad] alt [m]}{this procedure converts WGS-84 ECEF XYZ to Lat, Lon, Alt [above ellipsoid]}var   p, T, sT, cT, N, sig: real;beginp := sqrt(Xi[1] * Xi[1] + Xi[2] * Xi[2]);T := arctan((Xi[3] * a) / (p * b));sT := sin(T); cT := cos(T);Xo[1] := arctan((Xi[3] + e2sqr * b * sT * sT * sT)         / (p - e1sqr * a * cT * cT * cT));if Xi[2] <> 0.0 then sig := Xi[2] / abs(Xi[2]) else sig := 1.0;if Xi[1] = 0.0 then Xo[2] := sig * pi / 2.0 else   begin   Xo[2] := arctan(Xi[2]/Xi[1]);   if (Xi[1] < 0.0) and (Xi[2] >= 0.0) then Xo[2] := Xo[2] + pi;   if (Xi[1] < 0.0) and (Xi[2] < 0.0) then Xo[2] := Xo[2] - pi   end;N := a / sqrt(1.0 - e1sqr * sin(Xo[1]) * sin(Xo[1]));Xo[3] := p / cos(Xo[1]) - N;end; {procedure XYZ2LLA}{***************************************************************************}procedure satpos(eph : vec16;    {ephemeris}                 Ttr : real;     {satellite GPS time}             var Trel: real;     {relativistic correction term}             var X   : vec3);    {satellite position}var  M0, dn, ec, A, W0, i0, w, Wdot, Cuc, Cus, Crc, Crs, Cic, Cis, Toe, Idot: real;  T, n0, n, M, E, Eold, snu, cnu, nu, phi, du, dr, di, u, r, i, Xdash, Ydash, Wc: real;  k: integer;begin{for clarity of code, copy the ephemeris parameters and convert to radians}Crs := eph[1];dn  := eph[2] * pi;M0  := eph[3] * pi;Cuc := eph[4];ec  := eph[5];Cus := eph[6];A   := eph[7] * eph[7];Toe := eph[8];Cic := eph[9];W0  := eph[10] * pi;Cis := eph[11];i0  := eph[12] * pi;Crc := eph[13];w   := eph[14] * pi;Wdot:= eph[15] * pi;idot:= eph[16] * pi;T:= Ttr - Toe;if T >  302400 then T := T - 604800;if T < -302400 then T := T + 604800;n0 := sqrt(mu / (A*A*A));n := n0 + dn;M := M0 + n*T;E := M; {start value for E}repeat   Eold := E;   E := M + ec * sin(E);   until abs(E - Eold) < 1.0e-8;snu := sqrt(1 - ec*ec) * sin(E) / (1 - ec*cos(E));cnu := (cos(E) - ec) / (1 - ec*cos(E)); if cnu = 0 then nu := pi/2 * snu / abs(snu)else if (snu = 0) and (cnu > 0) then nu := 0else if (snu = 0) and (cnu < 0) then nu := pielse nu := arctan(snu/cnu)+ ord(cnu<0) * pi * snu / abs(snu);phi := nu + w;du := Cuc*cos(2*phi) + Cus*sin(2*phi);dr := Crc*cos(2*phi) + Crs*sin(2*phi); di := Cic*cos(2*phi) + Cis*sin(2*phi); u := phi + du;r := A*(1 - ec*cos(E)) + dr;i := i0 + idot*T +di;Xdash := r*cos(u);Ydash := r*sin(u);Wc:= W0 + (Wdot - Wedot)*T - Wedot*Toe;X[1] := Xdash*cos(Wc) - Ydash*cos(i)*sin(Wc);X[2] := Xdash*sin(Wc) + Ydash*cos(i)*cos(Wc);X[3] := Ydash*sin(i);Trel := F * ec * eph[7] * sin(E) {relativistic correction term}end; {procedure satpos}{***************************************************************************}{At many places in the following procedure solve the subdeterminant value of a 4 x 4 array is required. For convenience the function sub is defined below}function sub (A : mat16;      {input 4 x 4 array}              r,              {row number to be deleted}              c : integer     {column number to be deleted}              ) : double;     {value of 3 x 3 subdeterminant}var  B: array[1..3,1..3] of double;  i, i1, j, j1: integer;begini1 := 0;for i := 1 to 4 do if i <> r then   begin   i1 := i1 + 1;   j1 := 0;   for j := 1 to 4 do if j <> c then      begin      j1 := j1 + 1;      B[i1,j1] := A[i,j]      end   end;sub := + B[1,1]*(B[2,2]*B[3,3] - B[2,3]*B[3,2])       - B[2,1]*(B[1,2]*B[3,3] - B[3,2]*B[1,3])       + B[3,1]*(B[1,2]*B[2,3] - B[1,3]*B[2,2]);end; {function sub}{***************************************************************************}procedure solve(Xs    : mat96;    {array with 3 columns and 32 rows                                   for the coordinates of the sat's}                SV    : vecb32;   {valid prn's}                P     : vec32;    {pseudoranges}            var Xr    : vec3;     {input of initial guess, output of                                   final position}            var Cr    : real;     {receiver clock error}            var status: boolean); {true: calculation OK, false: no solution}{procedure solve requires the following types to be declared in the main body of the program: type    mat96 = array[1..32,1..3] of real;    vecb32 = array[1..32] of boolean;    vec32 = array[1..32] of real;    vec3 = array[1..3] of real;    mat16 = array[1..4,1..4] of real;}var   prn, it, i, j, k: integer;   R, L: array[1..32] of real;   A: array[1..32,1..4] of real;   AL: array[1..4] of real;   AA, AAi: mat16;   n: longint;   det: real;   D: array[1..4] of real;begin {procedure solve}it := 0; {iteration counter}repeat {iterations}   it :=it + 1; {increase iteration counter}   for prn := 1 to 32 do if SV[prn] then      begin      R[prn] :=  {range from receiver to satellite}         sqrt((Xr[1] - Xs[prn,1]) * (Xr[1] - Xs[prn,1])            + (Xr[2] - Xs[prn,2]) * (Xr[2] - Xs[prn,2])            + (Xr[3] - Xs[prn,3]) * (Xr[3] - Xs[prn,3]));      L[prn] := P[prn] - R[prn]; {range residual value}      for k := 1 to 3 do A[prn,k] := (Xr[k] - Xs[prn,k]) / R[prn];      A[prn,4] := -1.0 {A is the geometry matrix or model matrix}      end;   For k :=1 to 4 do {calculate A.L}      begin      AL[k] := 0.0;      for prn := 1 to 32 do if SV[prn] then         AL[k] := AL[k] + A[prn,k] * L[prn]      end;   for k := 1 to 4 do for i := 1 to 4 do {calculate A.A}      begin      AA[k,i] :=0.0;      for prn := 1 to 32 do if SV[prn] then         AA[k,i] := AA[k,i] + A[prn,k] * A[prn,i]      end;   {invert A.A}   det := + AA[1,1] * sub(AA,1,1) - AA[2,1] * sub(AA,2,1)          + AA[3,1] * sub(AA,3,1) - AA[4,1] * sub(AA,4,1);   if det = 0.0 then status := false else      begin      status := true;      for k := 1 to 4 do for i := 1 to 4 do         begin         n:= k + i; if odd(n) then j := -1 else j :=1;         AAi[k,i] := j * sub(AA,i,k) / det         end;      {calculate (invA.A).(A.L)}      for k := 1 to 4 do         begin         D[k] := 0.0;         for i := 1 to 4 do D[k] := D[k] + AAi[k,i] * AL[i]         end;      {update position}      for k := 1 to 3 do Xr[k] := Xr[k] + D[k];      end;   until (it = 6){there is something wrong if more than 6 iterations are required}      or ((abs(D[1]) + abs(D[2]) + abs(D[3])) < 1.0E-2) {iteration criterion}         or (not(status)); {calculation not succeeded}Cr := D[4]; {receiver clock error}if it = 6 then begin writeln('solve it : ',it); status := false end; {iteration not succeeded}end; {procedure solve}{***************************************************************************}begin {main}{the following data should be available: 1. Pseudoranges at ref rcvr with receiver time of reception for each SV 2. Ephemeris for each SV 3. Pseudoranges at mov rcvr}{open input datafile}assign(inp,'inpsd.txt'); reset(inp);{read GPS time of reception and ref rcvr coordinates}readln(inp); {skip comment line}readln(inp,Trc,Xr[1],Xr[2],Xr[3]);{read pseudoranges}readln(inp); {skip comment line}for prn := 1 to 32 do SV[prn] := false;repeat   read(inp,prn);   if prn <> 0 then      begin      readln(inp,Prs[prn],Pms[prn]);      SV[prn] := true      end   else readln(inp);   until prn = 0;readln(inp); {skip comment line}{read ephemeris data}repeat   readln(inp,prn);   for i := 1 to 16 do readln(inp,eph[prn,i]);   until eof(inp);close(inp);{open output data file}assign(out,'outsd.txt'); rewrite(out);for prn := 1 to 32 do if SV[prn] then begin {do for each SV}   {calculate transit time and time of transmission}   tau := Prs[prn] / c;   Ttr := Trc - tau;   {calculate SV position and correct for earth rotation}   for i := 1 to 16 do tmp16[i] := eph[prn,i];   satpos(tmp16,Ttr,Trel,tmp3);   alpha := tau * We;   Xs[prn,1] := + tmp3[1] * cos(alpha) + tmp3[2] * sin(alpha);   Xs[prn,2] := - tmp3[1] * sin(alpha) + tmp3[2] * cos(alpha);   Xs[prn,3] := + tmp3[3];   writeln(out,'SV     : ',prn:2,Xs[prn,1]:15:3,Xs[prn,2]:15:3,Xs[prn,3]:15:3);   {calculate differential corrected pseudorange}   Rrs := sqrt((Xr[1] - Xs[prn,1]) * (Xr[1] - Xs[prn,1])             + (Xr[2] - Xs[prn,2]) * (Xr[2] - Xs[prn,2])             + (Xr[3] - Xs[prn,3]) * (Xr[3] - Xs[prn,3]));   Pmsc[prn] := Pms[prn] - (Prs[prn] - Rrs);   end; {do for each SV}{calculate receiver position}for i := 1 to 3 do Xm[i] := Xr[i]; {initial guess for mov rcvr position}solve(Xs,SV,Pmsc,Xm,Crm,status);if not status then   begin writeln('Error in solve - check input data'); exit end;writeln(out,'Pos XYZ: ',Xm[1]:12:3,Xm[2]:12:3,Xm[3]:12:3,Crm:12:3);{convert back to Lat, Lon, Alt}XYZ2LLA(Xm,Xlla);writeln(out,'Pos LLA: ',Xlla[1]*180.0/pi:15:8,Xlla[2]*180.0/pi:15:8,Xlla[3]:12:3);close(out)end. {main}

⌨️ 快捷键说明

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