26 bool enu2lla(
double lla[3], 
const double enu[3], 
const double ref_lla[3]){
 
   27 double ref_xyz[3],diff_xyz[3],xyz[3],R[3][3],Rt[3][3];
 
   30 if (!lla2xyz(ref_xyz,ref_lla))
 
   33        rot3d(R, ref_lla[0], ref_lla[1]);
 
   35        transposeMatrix(Rt,R);
 
   37        matrixMultiply(diff_xyz,Rt,enu);
 
   39        xyz[0] = diff_xyz[0] + ref_xyz[0];
 
   40        xyz[1] = diff_xyz[1] + ref_xyz[1];
 
   41        xyz[2] = diff_xyz[2] + ref_xyz[2];
 
   52 bool lla2enu(
double enu[3], 
const double lla[3], 
const double ref_lla[3]){
 
   59 if(!xyz2enu(enu,xyz,ref_lla))
 
   68 bool xyz2lla(
double lla[3], 
const double xyz[3]){
 
   73 double A_EARTH = 6378137.0;
 
   74 double flattening = 1.0 / 298.257223563;
 
   75 double NAV_E2 = (2.0 - flattening) * flattening; 
 
   76 double rad2deg = 180.0 / M_PI_R;
 
   78 if ((xyz[0] == 0.0) & (xyz[1] == 0.0)) {
 
   81            lla[1] = atan2(xyz[1], xyz[0]) * rad2deg;
 
   84 if ((xyz[0] == 0.0) & (xyz[1] == 0.0) & (xyz[2] == 0.0)) {
 
   85            std::cout << 
"WGS xyz at center of earth" << std::endl;
 
   89 double rhosqrd = xyz[0] * xyz[0] + xyz[1] * xyz[1];
 
   90 double rho = sqrt(rhosqrd);
 
   91 double templat = atan2(xyz[2], rho);
 
   92 double tempalt = sqrt(rhosqrd + xyz[2] * xyz[2]) - A_EARTH;
 
   93 double rhoerror = 1000.0;
 
   94 double zerror = 1000.0;
 
  103 while ((abs(rhoerror) > 1e-6) | (abs(zerror) > 1e-6)) {
 
  104 double slat = sin(templat);
 
  105 double clat = cos(templat);
 
  106 double q = 1.0 - NAV_E2 * slat*slat;
 
  107 double r_n = A_EARTH / sqrt(q);
 
  108 double drdl = r_n * NAV_E2 * slat * clat / q; 
 
  110                rhoerror = (r_n + tempalt) * clat - rho;
 
  111                zerror = (r_n * (1.0 - NAV_E2) + tempalt) * slat - xyz[2];
 
  119 double aa = drdl * clat - (r_n + tempalt) * slat;
 
  121 double cc = (1.0 - NAV_E2)*(drdl * slat + r_n * clat);
 
  126 double invdet = 1.0 / (aa * dd - bb * cc);
 
  127                templat = templat - invdet * (+dd * rhoerror - bb * zerror);
 
  128                tempalt = tempalt - invdet * (-cc * rhoerror + aa * zerror);
 
  133                    std::cout << 
"xyz2lla could not converge" << std::endl;
 
  138            lla[0] = templat*rad2deg;
 
  147 bool lla2xyz(
double xyz[3], 
const double lla[3]){
 
  149 if ((lla[0] < -90.0) | (lla[0] > +90.0) | (lla[1] < -180.0) | (lla[1] > +360.0)){
 
  150            std::cout << 
"WGS lat or WGS lon out of range" << std::endl;
 
  154 double A_EARTH = 6378137.0;
 
  155 double flattening = 1.0/298.257223563;
 
  156 double NAV_E2 = (2.0-flattening)*flattening; 
 
  157 double deg2rad = M_PI_R/180.0;
 
  159 double slat = sin(lla[0]*deg2rad);
 
  160 double clat = cos(lla[0]*deg2rad);
 
  161 double r_n = A_EARTH/sqrt(1.0 - NAV_E2*slat*slat);
 
  162        xyz[0] = (r_n + lla[2])*clat*cos(lla[1]*deg2rad);  
 
  163        xyz[1] = (r_n + lla[2])*clat*sin(lla[1]*deg2rad);  
 
  164        xyz[2] = (r_n*(1.0 - NAV_E2) + lla[2])*slat;
 
  172 bool enu2xyz(
double xyz[3], 
const double enu[3], 
const double ref_lla[3]){
 
  176 if(!enu2lla(lla,enu, ref_lla))
 
  180 if(!lla2xyz(xyz,lla))
 
  189 bool xyz2enu(
double enu[3], 
const double xyz[3], 
const double ref_lla[3]){
 
  191 double ref_xyz[3],diff_xyz[3],R[3][3];
 
  194 if (!lla2xyz(ref_xyz,ref_lla))
 
  198        diff_xyz[0] = xyz[0] - ref_xyz[0];
 
  199        diff_xyz[1] = xyz[1] - ref_xyz[1];
 
  200        diff_xyz[2] = xyz[2] - ref_xyz[2];
 
  202        rot3d(R, ref_lla[0], ref_lla[1]);
 
  204        matrixMultiply(enu,R,diff_xyz);
 
  212 void xyz2enu_vel(
double enu_vel[3], 
const double xyz_vel[3], 
const double ref_lla[3]){
 
  216        rot3d(R, ref_lla[0], ref_lla[1]);
 
  218        matrixMultiply(enu_vel,R,xyz_vel);
 
  225 void enu2xyz_vel(
double xyz_vel[3], 
const double enu_vel[3], 
const double ref_lla[3]){
 
  227 double R[3][3],Rt[3][3];
 
  229        rot3d(R, ref_lla[0], ref_lla[1]);
 
  231        transposeMatrix(Rt,R);
 
  233        matrixMultiply(xyz_vel,Rt,enu_vel);
 
  240 void xyz2enu_cov(
double enu_Cov[3][3], 
const double xyz_Cov[3][3], 
const double ref_lla[3]){
 
  242 double R[3][3],Rt[3][3],Tmp[3][3];
 
  244        rot3d(R, ref_lla[0], ref_lla[1]);
 
  246        transposeMatrix(Rt,R);
 
  248        matrixMultiply(Tmp,xyz_Cov,Rt); 
 
  250        matrixMultiply(enu_Cov,R,Tmp); 
 
  254 void xyz2enu_cov(
double enu_cov[9], 
const double xyz_cov[9], 
const double ref_lla[3]){
 
  256 double xyz_Cov[3][3],enu_Cov[3][3];
 
  260                xyz_Cov[i][j]=xyz_cov[3*i+j];
 
  262 double R[3][3],Rt[3][3],Tmp[3][3];
 
  264        rot3d(R, ref_lla[0], ref_lla[1]);
 
  266        transposeMatrix(Rt,R);
 
  268        matrixMultiply(Tmp,xyz_Cov,Rt);
 
  270        matrixMultiply(enu_Cov,R,Tmp);
 
  274                enu_cov[3*i+j] = enu_Cov[i][j];
 
  281 void enu2xyz_cov(
double xyz_Cov[3][3], 
const double enu_Cov[3][3], 
const double ref_lla[3]){
 
  283 double R[3][3],Rt[3][3],Tmp[3][3];
 
  285        rot3d(R, ref_lla[0], ref_lla[1]);
 
  287        transposeMatrix(Rt,R);
 
  289        matrixMultiply(Tmp,enu_Cov,R);
 
  291        matrixMultiply(xyz_Cov,Rt,Tmp);
 
  295 void enu2xyz_cov(
double xyz_cov[9], 
const double enu_cov[9], 
const double ref_lla[3]){
 
  297 double xyz_Cov[3][3],enu_Cov[3][3];
 
  301                enu_Cov[i][j]=enu_cov[3*i+j];
 
  303 double R[3][3],Rt[3][3],Tmp[3][3];
 
  305        rot3d(R, ref_lla[0], ref_lla[1]);
 
  307        transposeMatrix(Rt,R);
 
  309        matrixMultiply(Tmp,enu_Cov,R); 
 
  311        matrixMultiply(xyz_Cov,Rt,Tmp);
 
  315                xyz_cov[3*i+j] = xyz_Cov[i][j];
 
  323 void rot3d(
double R[3][3], 
const double reflat, 
const double reflon){
 
  325 double R1[3][3],R2[3][3];
 
  327        rot(R1, 90 + reflon, 3);
 
  328        rot(R2, 90 - reflat, 1);
 
  330        matrixMultiply(R, R2, R1);
 
  336 void matrixMultiply(
double C[3][3], 
const double A[3][3], 
const double B[3][3]){
 
  338        C[0][0] = A[0][0] * B[0][0] + A[0][1] * B[1][0] + A[0][2] * B[2][0];
 
  339        C[0][1] = A[0][0] * B[0][1] + A[0][1] * B[1][1] + A[0][2] * B[2][1];
 
  340        C[0][2] = A[0][0] * B[0][2] + A[0][1] * B[1][2] + A[0][2] * B[2][2];
 
  341        C[1][0] = A[1][0] * B[0][0] + A[1][1] * B[1][0] + A[1][2] * B[2][0];
 
  342        C[1][1] = A[1][0] * B[0][1] + A[1][1] * B[1][1] + A[1][2] * B[2][1];
 
  343        C[1][2] = A[1][0] * B[0][2] + A[1][1] * B[1][2] + A[1][2] * B[2][2];
 
  344        C[2][0] = A[2][0] * B[0][0] + A[2][1] * B[1][0] + A[2][2] * B[2][0];
 
  345        C[2][1] = A[2][0] * B[0][1] + A[2][1] * B[1][1] + A[2][2] * B[2][1];
 
  346        C[2][2] = A[2][0] * B[0][2] + A[2][1] * B[1][2] + A[2][2] * B[2][2];
 
  353 void matrixMultiply(
double c[3], 
const double A[3][3], 
const double b[3]){
 
  355        c[0] = A[0][0] * b[0] + A[0][1] * b[1] + A[0][2] * b[2];
 
  356        c[1] = A[1][0] * b[0] + A[1][1] * b[1] + A[1][2] * b[2];
 
  357        c[2] = A[2][0] * b[0] + A[2][1] * b[1] + A[2][2] * b[2];
 
  364 void transposeMatrix(
double At[3][3], 
const double A[3][3]){
 
  381 void rot(
double R[3][3], 
const double angle, 
const int axis) {
 
  383 double cang = cos(angle * M_PI_R / 180);
 
  384 double sang = sin(angle * M_PI_R / 180);
 
  396        } 
else if (axis == 2) {
 
  406        } 
else if (axis == 3) {