Last active
February 17, 2016 15:50
-
-
Save kauevestena/71c47b0dadcb29f046cb to your computer and use it in GitHub Desktop.
programa, com a implementação das classes e funções para cálculo da leverArm e do boresight
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <armadillo> | |
#include <fstream> | |
#include <string> | |
#include <vector> | |
#include <math.h> | |
#include <iomanip> | |
using namespace std; | |
using namespace arma; | |
struct GMS | |
{ | |
int G,M,S; | |
GMS(int,int,int); | |
double gdec(); | |
double rad(); | |
}; | |
struct topoPoint | |
{ | |
double Hz,Ze,Di; | |
vec3 XYZ; | |
bool rad; | |
topoPoint(double,double,double,bool); | |
void cart(); | |
void translate(vec3 tvec); | |
void Rotate(mat R); | |
}; | |
GMS::GMS (int g,int m,int s) | |
{ | |
G=g;M=m;S=s; | |
} | |
double GMS::gdec () | |
{ | |
return double(G)+ (double(M)/60) + (double(S)/3600); | |
} | |
double GMS::rad() | |
{ | |
double radd = gdec() * (datum::pi/180); | |
return radd; | |
} | |
struct SMMTleverARM | |
{ | |
//to handle with the base from the file | |
vector<vector<string>> data; | |
vector<vector<GMS>> hor,zen; | |
vector<vector<double>> dists; | |
//the arbitrary-frame surveyed points | |
vector<vector<topoPoint>> points; | |
//the planes of the process (coefficients a,b,c,d) | |
vec4 Hplan,Vplan; | |
vec4 CEin,CEout,CDin,CDout; | |
//aux1 is parallel to Hplan | |
//matrices containing points | |
mat ptsH,ptsV; //at the sides of the IMU | |
mat ptsCEin,ptsCEout,ptsCDin,ptsCDout; //points on the parallel circular patterns, on the lens of the cameras | |
mat ptsOnCEin,ptsOnCEout,ptsOnCDin,ptsOnCDout; //adjusted points | |
//rotation matrices | |
mat Rot1 = eye<mat>(3,3); | |
//the principal vectors, to define the cannonical system | |
vec3 u,v,w; //u for x,v for y,w for z | |
//the axis direction of each camera system, in the same convention of the IMU | |
vec3 xE,yE,zE,xD,yD,zD; | |
//the axis of each camera system, with the z axis pointing backwards | |
vec3 Xe,Ye,Ze,Xd,Yd,Zd; | |
//the difference between the antena top and the center of phase | |
vec3 PhC = {0,0,-0.0071}; | |
//the lever-arm vectors | |
vec3 antLA,LcamLA,RcamLA; | |
//temporary, and auxiliar vectors | |
vec3 tempE,tempD,aux1e,aux1d,aux_E0,aux_D0; | |
//the boresight matrices | |
mat Rimu_LC = eye(3,3),Rimu_RC = eye(3,3),Rimu_LC2 = eye(3,3),Rimu_RC2 = eye(3,3); | |
//center of the IMU, the mark on the H plane, the mark on the v plane | |
vec3 imuC,Hm,Vm; | |
double planesAngle; | |
SMMTleverARM (string fileName); | |
vector<vector<string>> readLAFile(string filename); | |
//the member functions | |
void horiz(); | |
void zenit(); | |
void distanc(); | |
void avgOBS(); | |
void pointsPrint(string filename); | |
void translateAll(vec3 tvec); | |
void rotAll (mat R); | |
void report(); | |
}; | |
vec3 onPlanePoint(vec4 plCoef,double x,double y); | |
//all the function propotypes: | |
double pdpiH(double,double); | |
double pdpiV(double,double); | |
void TptMat (mat *M,vec Tvec); | |
void RptMat (mat *M,mat R); | |
vec4 plane3points(vec3 u,vec3 v,vec3 w); | |
mat topoPointsMat (vector<topoPoint> points,uword first,uword last); | |
vec4 parallelPlane(vec4 plane1,vec3 pointOnPlane); | |
vec3 ProjPtOrtPlane(vec3 pt2Proj,vec3 plNorm,vec3 ptOnPlane); | |
vec4 leasqPlane2(vector<topoPoint> pointList,mat *ptOnPlane,string repNam,uword ijpt=0) | |
{ | |
vec4 res,Xo; | |
mat data,P,Pinf,A,B,M,mvcXa,mvcLa,mvcV,mvcW; | |
vec Lb,W,X,Xa,K,V,La; | |
double vp; | |
if (pointList.size() >= 3) | |
{Xo = plane3points(pointList.at(0).XYZ,pointList.at(1).XYZ,pointList.at(2).XYZ);} | |
Pinf = eye(3,3)*10000; | |
if (pointList.size() < 3) | |
{ | |
res = {0,0,1,0}; | |
} | |
else if (pointList.size() == 3) | |
{ | |
res = Xo; | |
} | |
else | |
{ | |
ofstream out(repNam); | |
//vetor Lb | |
data = ones(pointList.size(),3); | |
for (uword i0 = 0; i0 < pointList.size();i0++) | |
{ | |
data.row(i0) = pointList.at(i0).XYZ.t(); | |
} | |
Lb = vectorise(data.t()); | |
//matriz dos pesos | |
P = eye(Lb.n_elem,Lb.n_elem); | |
if (ijpt != 0) | |
{ | |
//em caso de que haja um ponto a ser injuncionado | |
// P.submat(ijpt*3-2,ijpt*3-2,ijpt*3,ijpt*3) = Pinf; | |
P.submat(ijpt*3-3,ijpt*3-3,ijpt*3-1,ijpt*3-1) = Pinf; | |
} | |
//matriz jacobiana A (parametros) | |
A = ones<mat>(pointList.size(),4); | |
for (uword i = 0; i < pointList.size();i++) | |
{ | |
A(i,0)=data(i,0); | |
A(i,1)=data(i,1); | |
A(i,2)=data(i,2); | |
} | |
//matriz jacobiana B (observacoes) | |
B = zeros<mat>(pointList.size(),Lb.n_elem); | |
uword j = 0; | |
for (uword i2 = 0;i2 < pointList.size();i2++) | |
{ | |
B(i2,0+j)=Xo(0); | |
B(i2,1+j)=Xo(1); | |
B(i2,2+j)=Xo(2); | |
j += 3; | |
} | |
W = zeros<vec>(pointList.size()); | |
for (uword i3 = 0;i3 < pointList.size();i3++) | |
{ | |
W(i3) = dot(A.row(i3),Xo); | |
} | |
M = B * P.i() * B.t(); | |
X = - inv(A.t()*M.i()*A)*(A.t()*M.i()*W); | |
Xa = Xo + X; | |
K = -M.i()*(A*X+W); | |
V = P.i() * B.t() * K; | |
La = Lb+V; | |
*ptOnPlane = trans(reshape(La,3,pointList.size())); | |
vp = as_scalar( V.t() * P * V / (Lb.n_elem - Xo.n_elem) ); | |
mvcXa = vp * inv(A.t()*M.i()*A); | |
mvcLa = vp*(inv(P)+inv(P)*B.t()*inv(M)*A*inv(A.t()*inv(M)*A)*A.t()*inv(M)*B*inv(P)-inv(P)*B.t()*inv(M)*B*inv(P)); | |
mvcV = vp*P.i()-mvcLa; | |
mvcW = vp*M; | |
out.precision(30); | |
res = Xa; | |
// Xo.raw_print(out,"Xo"); | |
// X.raw_print(out,"X"); | |
// Xa.raw_print(out,"Xa:"); | |
// res.raw_print(out," b "); | |
// out <<"Xo+X: "<<endl<<std::setprecision(30)<< Xo+X<<endl; | |
//normalizing the plane equations | |
res.rows(0,2) = normalise(Xa.rows(0,2)); | |
res(3) = - dot(normalise(Xa.rows(0,2)),La.rows(0,2)); | |
// res.print(out," a "); | |
data.print(out,"dados de entrada: ");out<<endl; | |
res.print(out,"coeficientes do plano estimado: ");out<<endl; | |
V.print(out,"resíduos: ");out<<endl; | |
La.print(out,"La:");out<<endl; | |
out << "var. posteriori: " << vp << endl<<endl; | |
mvcXa.print(out,"MVC dos parametros ajustados");out<<endl; | |
mvcLa.print(out,"MVC das observações ajustadas");out<<endl; | |
} | |
//cout<< res<<endl; | |
return res; | |
} | |
void leasq2ParallelPlanes(vec4 *plane1,vec4 *plane2,mat points1,mat points2,mat *ptOnPlane1,mat *ptOnPlane2,string repNam,uword n=5,double e=.000001) | |
{ | |
vec5 Xo,X,Xa; | |
mat data,P,A,B,M,mvcXa,mvcLa,mvcV,mvcW,ptsOnPlanes; | |
vec Lb,W,K,V,La,temp5,temp6; | |
double vp; | |
vec4 temp1,temp2,temp3,temp4; | |
temp1.ones();temp2.zeros(); | |
uword iter; | |
ofstream out(repNam); | |
Xo.rows(0,3) = plane3points(trans(points1.row(0)),trans(points1.row(1)),trans(points1.row(2)) ); | |
Xo(4) = - dot(Xo.rows(0,2),points2.row(0)); | |
//vetor Lb | |
data = join_vert(points1,points2); | |
Lb = vectorise(data.t()); | |
//matriz dos pesos | |
P = eye(Lb.n_elem,Lb.n_elem); | |
//matriz jacobiana A (parametros) | |
A = zeros<mat>(data.n_rows,Xo.n_elem); | |
B = zeros<mat>(data.n_rows,Lb.n_elem); | |
W = zeros<vec>(data.n_rows); | |
A.submat(0,0,data.n_rows-1,data.n_cols-1) = data; | |
for (uword i = 0; i < data.n_rows;i++) | |
{ | |
if (i < points1.n_rows) | |
{ A(i,3) = 1; } | |
else | |
{ A(i,4) = 1; } | |
} | |
for(uword it = 0;it < n;it ++) | |
{ | |
uword j = 0; | |
for (uword i2 = 0;i2 < data.n_rows;i2++) | |
{ | |
B(i2,0+j)=Xo(0); | |
B(i2,1+j)=Xo(1); | |
B(i2,2+j)=Xo(2); | |
j += 3; | |
temp1.rows(0,2) = trans( data.row(i2) ); | |
temp2.rows(0,2) = Xo.rows(0,2); | |
if(i2 < points1.n_rows) | |
{temp2(3)=Xo(3);} | |
else | |
{temp2(3)=Xo(4);} | |
W(i2) = dot(temp1,temp2); | |
} | |
M = B * P.i() * B.t(); | |
X = - inv(A.t()*M.i()*A)*(A.t()*M.i()*W); | |
Xa = Xo + X; | |
Xo = Xa; | |
iter = it; | |
if (arma::max(arma::abs(X)) < e) | |
{ break; } | |
} | |
K = -M.i()*(A*X+W); | |
V = P.i() * B.t() * K; | |
La = Lb+V; | |
ptsOnPlanes = trans(reshape(La,data.n_cols,data.n_rows)); | |
*ptOnPlane1 = ptsOnPlanes.rows(0,points1.n_rows-1); | |
*ptOnPlane2 = ptsOnPlanes.rows(points1.n_rows,data.n_rows-1); | |
temp3.rows(0,2) = normalise(Xa.rows(0,2)); | |
temp3(3)= - dot(La.rows(0,2),normalise(Xa.rows(0,2))); | |
temp4 = temp3; | |
temp4(3)= - dot(La.rows(La.n_elem-3,La.n_elem-1),normalise(Xa.rows(0,2))); | |
*plane1 = temp3; | |
*plane2 = temp4; | |
vp = as_scalar( V.t() * P * V / (Lb.n_elem - Xo.n_elem) ); | |
mvcXa = vp * inv(A.t()*M.i()*A); | |
mvcLa = vp*(inv(P)+inv(P)*B.t()*inv(M)*A*inv(A.t()*inv(M)*A)*A.t()*inv(M)*B*inv(P)-inv(P)*B.t()*inv(M)*B*inv(P)); | |
mvcV = vp*P.i()-mvcLa; | |
mvcW = vp*M; | |
out.precision(20); | |
points1.raw_print(out,"dados de entrada (primeiro plano): ");out<<endl; | |
points2.raw_print(out,"dados de entrada (segundo plano): ");out<<endl; | |
out << iter <<" iterações necessárias" <<endl<<endl; | |
Xa.raw_print(out," vetor Xa (pré-normalização)");out<<endl; | |
temp3.raw_print(out,"coeficientes do primeiro plano estimado: ");out<<endl; | |
temp4.raw_print(out,"coeficientes do segundo plano estimado: ");out<<endl; | |
V.raw_print(out,"resíduos: ");out<<endl; | |
ptsOnPlanes.raw_print(out,"La:");out<<endl; | |
out << "var. posteriori: " << vp << endl<<endl; | |
mvcXa.raw_print(out,"MVC dos parametros ajustados");out<<endl; | |
mvcLa.raw_print(out,"MVC das observações ajustadas");out<<endl; | |
} | |
struct Sphere | |
{ | |
vec3 center; | |
double r; | |
mat onSpherePts; | |
Sphere(mat points,string repNam,uword n=20,double e=.000001); | |
}; | |
Sphere::Sphere(mat data,string repNam,uword n,double e) | |
{ | |
vec4 Xo,X,Xa; | |
mat P,A,B,M,mvcXa,mvcLa,mvcV,mvcW,ptsOnPlanes; | |
vec Lb,W,K,V,La,temp5,temp6,aux; | |
double vp; | |
vec4 temp1,temp2,temp3,temp4; | |
temp1.ones();temp2.zeros(); | |
uword iter; | |
ofstream out(repNam); | |
aux=zeros(data.n_rows); | |
for (uword i = 0;i < aux.n_rows;i++) | |
{ | |
aux(i) = norm(data.row(i) - mean(data)); | |
} | |
Xo.rows(1,3) = trans(mean(data)); | |
Xo(0) = mean(aux); | |
//vetor Lb | |
Lb = vectorise(data.t()); | |
//matriz dos pesos | |
P = eye(Lb.n_elem,Lb.n_elem); | |
//matriz jacobiana A (parametros) | |
A = zeros<mat>(data.n_rows,Xo.n_elem); | |
B = zeros<mat>(data.n_rows,Lb.n_elem); | |
W = zeros<vec>(data.n_rows); | |
for(uword it = 0;it < n;it ++) | |
{ | |
uword j = 0; | |
for (uword i2 = 0;i2 < data.n_rows;i2++) | |
{ | |
A(i2,0) = - 2 * Xo(0); | |
A(i2,1) = 2 * (Xo(1) - data(i2,0)); | |
A(i2,2) = 2 * (Xo(2) - data(i2,1)); | |
A(i2,3) = 2 * (Xo(3) - data(i2,2)); | |
B(i2,j) = - 2 * (Xo(1) - data(i2,0)); | |
B(i2,1+j)= - 2 * (Xo(2) - data(i2,1)); | |
B(i2,2+j)= - 2 * (Xo(3) - data(i2,2)); | |
j += 3; | |
W(i2) = std::pow((data(i2,0) - Xo(1)),2) + std::pow((data(i2,1) - Xo(2)),2) + | |
std::pow((data(i2,2) - Xo(3)),2) - std::pow(Xo(0),2); | |
} | |
M = B * P.i() * B.t(); | |
X = - inv(A.t()*M.i()*A)*(A.t()*M.i()*W); | |
Xa = Xo + X; | |
Xo = Xa; | |
iter = it; | |
if (arma::max(arma::abs(X)) < e) | |
{ break; } | |
} | |
K = -M.i()*(A*X+W); | |
V = P.i() * B.t() * K; | |
La = Lb+V; | |
onSpherePts = trans(reshape(La,data.n_cols,data.n_rows)); | |
vp = as_scalar( V.t() * P * V / (Lb.n_elem - Xo.n_elem) ); | |
mvcXa = vp * inv(A.t()*M.i()*A); | |
mvcLa = vp*(inv(P)+inv(P)*B.t()*inv(M)*A*inv(A.t()*inv(M)*A)*A.t()*inv(M)*B*inv(P)-inv(P)*B.t()*inv(M)*B*inv(P)); | |
mvcV = vp*P.i()-mvcLa; | |
mvcW = vp*M; | |
out.precision(20); | |
data.raw_print(out,"dados de entrada :");out<<endl; | |
out << iter <<" iterações necessárias" <<endl<<endl; | |
Xa.raw_print(out,"parametros ajustados (r,XC,YC,ZC)");out<<endl; | |
V.raw_print(out,"resíduos: ");out<<endl; | |
La.raw_print(out,"La:");out<<endl; | |
out << "var. posteriori: " << vp << endl<<endl; | |
mvcXa.raw_print(out,"MVC dos parametros ajustados");out<<endl; | |
mvcLa.raw_print(out,"MVC das observações ajustadas");out<<endl; | |
//assignment to the object variables | |
r = Xo(0); | |
center = Xo.rows(1,3); | |
} | |
int main() | |
{ | |
SMMTleverARM job("data.tcl"); | |
return 0; | |
} | |
vector<vector<string>> SMMTleverARM::readLAFile(string filename) | |
{ | |
//to read a file of the raw data of the Lever Arm surveying | |
ifstream in(filename); | |
vector<vector<string>> res; | |
vector<string> A,B,C,D,E; | |
//to control | |
int state = 0; | |
string line; | |
while (std::getline(in,line)) | |
{ | |
if (line.find("COD:[A") != -1) | |
{ | |
state = 1;continue; | |
} | |
if (line.find("COD:[B") != -1) | |
{ | |
state = 2;continue; | |
} | |
if (line.find("COD:[C") != -1) | |
{ | |
state =3 ;continue; | |
} | |
if (line.find("COD:[D") != -1) | |
{ | |
state =4 ;continue; | |
} | |
if (line.find("COD:[E") != -1) | |
{ | |
state =5 ;continue; | |
} | |
if (state == 1) | |
{ | |
A.push_back(line); | |
//cout << stoi(line.substr(23,3))<<endl; | |
} | |
if (state == 2) | |
{ | |
B.push_back(line); | |
} | |
if (state == 3) | |
{ | |
C.push_back(line); | |
} | |
if (state ==4 ) | |
{ | |
D.push_back(line); | |
} | |
if (state == 5) | |
{ | |
E.push_back(line); | |
} | |
} | |
res.push_back(A);res.push_back(B);res.push_back(C);res.push_back(D);res.push_back(E); | |
//cout<<A.size()<<" "<< B.size()<<" "<<C.size()<<" "<<D.size()<<" "<<E.size()<<endl; | |
//cout<<res.size(); | |
return res; | |
} | |
SMMTleverARM::SMMTleverARM (string fileName) | |
{ | |
// the constructor, all the modifying functions must have their calls here. | |
data = readLAFile(fileName); | |
horiz(); | |
zenit(); | |
distanc(); | |
avgOBS(); | |
//the two planes | |
Vplan = leasqPlane2(points.at(1),&ptsV,"plano_vert.txt",2); | |
Hplan = leasqPlane2(points.at(2),&ptsH,"plano_hor.txt",2); | |
//the angle between them | |
planesAngle = std::acos(dot(Vplan.rows(0,2),Hplan.rows(0,2))) * (180/datum::pi); | |
//the marks on the IMU surface | |
Hm = trans(ptsH.row(2)); | |
Vm = trans(ptsV.row(2)); | |
//the normal of the Hplan, is also the third direction (w), | |
//but at first, is needed some test | |
w = Hplan.rows(0,2); | |
if(w(2)<0) //the z component, needs to be positive, due to the z axis of the total station | |
{w *= -1;} | |
//the aux1 plane | |
//aux1.rows(0,2) = w; | |
//aux1(3) = - dot(w,Vm); | |
//IMU center with the intersection of the plane (aux1) and the line (point Hm and direction w) | |
//imuC = Hm + (dot(w,(Vm-Hm)))* w; //do not delete the old implementation | |
imuC = ProjPtOrtPlane(Hm,w,Vm); | |
//the first principal direction (u) | |
u = normalise(Vm - imuC); | |
//the second principal direction(v) | |
v = normalise(cross(w,u)); | |
//first, translating the origin to the calculated center of the IMU | |
TptMat(&ptsH,-imuC);TptMat(&ptsV,-imuC); | |
translateAll(-imuC); | |
pointsPrint("points1.txt"); | |
//composing the first rotation matrice | |
Rot1.col(0)=u; | |
Rot1.col(1)=v; | |
Rot1.col(2)=w; | |
Rot1 = Rot1.t(); | |
//rotating all to the imu BF | |
RptMat(&ptsH,Rot1);RptMat(&ptsV,Rot1); | |
rotAll(Rot1); | |
pointsPrint("points2.txt"); | |
//imuC += -imuC; | |
//creating matrices with the points, from topoPoints; | |
ptsCDin = topoPointsMat(points.at(3),0,4); | |
ptsCDout = topoPointsMat(points.at(3),5,9); | |
ptsCEin = topoPointsMat(points.at(4),0,4); | |
ptsCEout = topoPointsMat(points.at(4),5,9); | |
//the pair of parallel planes, one for each camera | |
leasq2ParallelPlanes(&CDin,&CDout,ptsCDin,ptsCDout,&ptsOnCDin,&ptsOnCDout,"RcamPlanes.txt"); | |
leasq2ParallelPlanes(&CEin,&CEout,ptsCEin,ptsCEout,&ptsOnCEin,&ptsOnCEout,"LcamPlanes.txt"); | |
//creating a sphere for each camera, to measure the center | |
Sphere Rsphere(join_vert(ptsOnCDin,ptsOnCDout),"Rsphere.txt"); | |
Sphere Lsphere(join_vert(ptsOnCEin,ptsOnCEout),"Lsphere.txt"); | |
//Y of each camera direction (with same convention) | |
//due to the IMU bf and the cameras position, the y component needs to be positive | |
// to point forward the camera axis | |
yE = normalise(CEin.rows(0,2)); | |
if (yE(1) < 0 ) { yE *= -1;} | |
yD = normalise(CDin.rows(0,2)); | |
if (yD(1) < 0 ) { yD *= -1;} | |
//yD.print();cout<<endl; | |
//yE.print();cout<<endl; | |
//we'll need points perfectly on the plane, and to have this guarantee: | |
//each one are obtained by the plane equation, with z=f(x,y) | |
aux1d = onPlanePoint(CDin,ptsOnCDin(ptsOnCDin.n_rows-1,0),ptsOnCDin(ptsOnCDin.n_rows-1,1)); | |
aux1e = onPlanePoint(CEin,ptsOnCEin(ptsOnCEin.n_rows-1,0),ptsOnCEin(ptsOnCEin.n_rows-1,1)); | |
aux_D0 = onPlanePoint(CDin,ptsOnCDin(0,0),ptsOnCDin(0,1)); | |
aux_E0 = onPlanePoint(CEin,ptsOnCEin(0,0),ptsOnCEin(0,1)); | |
//projecting the center of spheres on the inner plane of the rings on the camera lenses | |
tempD = ProjPtOrtPlane(Rsphere.center,yD,aux1d); | |
tempE = ProjPtOrtPlane(Lsphere.center,yE,aux1e); | |
//calculating the z direction, for each camera | |
zE = normalise(aux_E0 - tempE); | |
zD = normalise(aux_D0 - tempD); | |
//and, finally the x direction | |
xE = normalise(cross(yE,zE)); | |
xD = normalise(cross(yD,zD)); | |
//we can describe the axes in the camera conventional convention (z axis pointing from the CP to the focal plane) | |
Xe = xE;Ye = zE;Ze = -yE; | |
Xd = xD;Yd = zD;Zd = -yD; | |
//with the axis, we can have the boresight matrices: | |
//first with the same convention of the IMU: | |
Rimu_LC2.row(0) = trans(xE); | |
Rimu_LC2.row(1) = trans(yE); | |
Rimu_LC2.row(2) = trans(zE); | |
Rimu_RC2.row(0) = trans(xD); | |
Rimu_RC2.row(1) = trans(yD); | |
Rimu_RC2.row(2) = trans(zD); | |
//then with the camera usual convention | |
Rimu_LC.row(0) = trans(Xe); | |
Rimu_LC.row(1) = trans(Ye); | |
Rimu_LC.row(2) = trans(Ze); | |
Rimu_RC.row(0) = trans(Xd); | |
Rimu_RC.row(1) = trans(Yd); | |
Rimu_RC.row(2) = trans(Zd); | |
//now, the lever-arm | |
//antenna lever-arm: just the point at the antena top, and the offset from there to the PhC | |
antLA = (points.at(0).at(0).XYZ) + PhC; | |
//the lever-arm of the two cameras: | |
RcamLA = Rsphere.center; | |
LcamLA = Lsphere.center; | |
report(); | |
} | |
void SMMTleverARM::avgOBS() | |
{ | |
vector<topoPoint> temp; | |
double hA,zA,dA=0,hB,zB,dB,hC,zC,dC,hD,zD,dD,hE,zE,dE,hF,zF,dF,hG,zG,dG,hH,zH,dH,hI,zI,dI,hJ,zJ,dJ; | |
//std::setprecision(8); | |
for (unsigned int i = 0; i < hor.size();i++) | |
{ | |
if (i == 0) | |
{ | |
hA = (pdpiH(hor[i][0].gdec(),hor[i][1].gdec()) + | |
pdpiH(hor[i][2].gdec(),hor[i][3].gdec()) + | |
pdpiH(hor[i][4].gdec(),hor[i][5].gdec())) / 3; | |
zA = (pdpiV(zen[i][0].gdec(),zen[i][1].gdec()) + | |
pdpiV(zen[i][2].gdec(),zen[i][3].gdec()) + | |
pdpiV(zen[i][4].gdec(),zen[i][5].gdec())) / 3; | |
for (unsigned int j = 0;j < dists[i].size();j++) | |
{ | |
dA += dists[i][j]/6; | |
} | |
topoPoint ANT(hA,zA,dA,false); | |
temp.push_back(ANT); | |
//cout <<hA<<" "<<zA<<" "<<dA<<endl; | |
//cout <<hA<<" "<<zA<<" "<<dA<<endl; | |
} | |
if (i == 1) | |
{ | |
hA = (pdpiH(hor[i][0].gdec(),hor[i][5].gdec()) + | |
pdpiH(hor[i][10].gdec(),hor[i][15].gdec())) / 2; | |
hB = (pdpiH(hor[i][1].gdec(),hor[i][6].gdec()) + | |
pdpiH(hor[i][11].gdec(),hor[i][16].gdec())) / 2; | |
hC = (pdpiH(hor[i][2].gdec(),hor[i][7].gdec()) + | |
pdpiH(hor[i][12].gdec(),hor[i][17].gdec())) / 2; | |
hD = (pdpiH(hor[i][3].gdec(),hor[i][8].gdec()) + | |
pdpiH(hor[i][13].gdec(),hor[i][18].gdec())) / 2; | |
hE = (pdpiH(hor[i][4].gdec(),hor[i][9].gdec()) + | |
pdpiH(hor[i][14].gdec(),hor[i][19].gdec())) / 2; | |
zA = (pdpiV(zen[i][0].gdec(),zen[i][5].gdec()) + | |
pdpiV(zen[i][10].gdec(),zen[i][15].gdec())) / 2; | |
zB = (pdpiV(zen[i][1].gdec(),zen[i][6].gdec()) + | |
pdpiV(zen[i][11].gdec(),zen[i][16].gdec())) / 2; | |
zC = (pdpiV(zen[i][2].gdec(),zen[i][7].gdec()) + | |
pdpiV(zen[i][12].gdec(),zen[i][17].gdec())) / 2; | |
zD = (pdpiV(zen[i][3].gdec(),zen[i][8].gdec()) + | |
pdpiV(zen[i][13].gdec(),zen[i][18].gdec())) / 2; | |
zE = (pdpiV(zen[i][4].gdec(),zen[i][9].gdec()) + | |
pdpiV(zen[i][14].gdec(),zen[i][19].gdec())) / 2; | |
dA = (dists[i][0]+dists[i][5]+dists[i][10]+dists[i][15]) / 4; | |
dB = (dists[i][1]+dists[i][6]+dists[i][11]+dists[i][16]) / 4; | |
dC = (dists[i][2]+dists[i][7]+dists[i][12]+dists[i][17]) / 4; | |
dD = (dists[i][3]+dists[i][8]+dists[i][13]+dists[i][18]) / 4; | |
dE = (dists[i][4]+dists[i][9]+dists[i][14]+dists[i][19]) / 4; | |
topoPoint A(hA,zA,dA,false);temp.push_back(A); | |
topoPoint B(hB,zB,dB,false);temp.push_back(B); | |
topoPoint C(hC,zC,dC,false);temp.push_back(C); | |
topoPoint D(hD,zD,dD,false);temp.push_back(D); | |
topoPoint E(hE,zE,dE,false);temp.push_back(E); | |
// cout <<hA<<" "<<zA<<" "<<dA<<endl; | |
} | |
if (i == 2) | |
{ | |
hA = (pdpiH(hor[i][0].gdec(),hor[i][5].gdec()) + | |
pdpiH(hor[i][10].gdec(),hor[i][15].gdec())) / 2; | |
hB = (pdpiH(hor[i][1].gdec(),hor[i][6].gdec()) + | |
pdpiH(hor[i][11].gdec(),hor[i][16].gdec())) / 2; | |
hC = (pdpiH(hor[i][2].gdec(),hor[i][7].gdec()) + | |
pdpiH(hor[i][12].gdec(),hor[i][17].gdec())) / 2; | |
hD = (pdpiH(hor[i][3].gdec(),hor[i][8].gdec()) + | |
pdpiH(hor[i][13].gdec(),hor[i][18].gdec())) / 2; | |
hE = (pdpiH(hor[i][4].gdec(),hor[i][9].gdec()) + | |
pdpiH(hor[i][14].gdec(),hor[i][19].gdec())) / 2; | |
zA = (pdpiV(zen[i][0].gdec(),zen[i][5].gdec()) + | |
pdpiV(zen[i][10].gdec(),zen[i][15].gdec())) / 2; | |
zB = (pdpiV(zen[i][1].gdec(),zen[i][6].gdec()) + | |
pdpiV(zen[i][11].gdec(),zen[i][16].gdec())) / 2; | |
zC = (pdpiV(zen[i][2].gdec(),zen[i][7].gdec()) + | |
pdpiV(zen[i][12].gdec(),zen[i][17].gdec())) / 2; | |
zD = (pdpiV(zen[i][3].gdec(),zen[i][8].gdec()) + | |
pdpiV(zen[i][13].gdec(),zen[i][18].gdec())) / 2; | |
zE = (pdpiV(zen[i][4].gdec(),zen[i][9].gdec()) + | |
pdpiV(zen[i][14].gdec(),zen[i][19].gdec())) / 2; | |
dA = (dists[i][0]+dists[i][5]+dists[i][10]+dists[i][15]) / 4; | |
dB = (dists[i][1]+dists[i][6]+dists[i][11]+dists[i][16]) / 4; | |
dC = (dists[i][2]+dists[i][7]+dists[i][12]+dists[i][17]) / 4; | |
dD = (dists[i][3]+dists[i][8]+dists[i][13]+dists[i][18]) / 4; | |
dE = (dists[i][4]+dists[i][9]+dists[i][14]+dists[i][19]) / 4; | |
topoPoint A(hA,zA,dA,false);temp.push_back(A); | |
topoPoint B(hB,zB,dB,false);temp.push_back(B); | |
topoPoint C(hC,zC,dC,false);temp.push_back(C); | |
topoPoint D(hD,zD,dD,false);temp.push_back(D); | |
topoPoint E(hE,zE,dE,false);temp.push_back(E); | |
// cout <<hA<<" "<<zA<<" "<<dA<<endl; | |
} | |
if (i == 3) | |
{ | |
topoPoint EXTRA(hor[i][0].gdec(),zen[i][0].gdec(),dists[i][0],false); | |
hA = pdpiH(hor[i][1].gdec(),hor[i][11].gdec()); | |
hB = pdpiH(hor[i][2].gdec(),hor[i][12].gdec()); | |
hC = pdpiH(hor[i][3].gdec(),hor[i][13].gdec()); | |
hD = pdpiH(hor[i][4].gdec(),hor[i][14].gdec()); | |
hE = pdpiH(hor[i][5].gdec(),hor[i][15].gdec()); | |
hF = pdpiH(hor[i][6].gdec(),hor[i][16].gdec()); | |
hG = pdpiH(hor[i][7].gdec(),hor[i][17].gdec()); | |
hH = pdpiH(hor[i][8].gdec(),hor[i][18].gdec()); | |
hI = pdpiH(hor[i][9].gdec(),hor[i][19].gdec()); | |
hJ = pdpiH(hor[i][10].gdec(),hor[i][20].gdec()); | |
zA = pdpiV(zen[i][1].gdec(),zen[i][11].gdec()); | |
zB = pdpiV(zen[i][2].gdec(),zen[i][12].gdec()); | |
zC = pdpiV(zen[i][3].gdec(),zen[i][13].gdec()); | |
zD = pdpiV(zen[i][4].gdec(),zen[i][14].gdec()); | |
zE = pdpiV(zen[i][5].gdec(),zen[i][15].gdec()); | |
zF = pdpiV(zen[i][6].gdec(),zen[i][16].gdec()); | |
zG = pdpiV(zen[i][7].gdec(),zen[i][17].gdec()); | |
zH = pdpiV(zen[i][8].gdec(),zen[i][18].gdec()); | |
zI = pdpiV(zen[i][9].gdec(),zen[i][19].gdec()); | |
zJ = pdpiV(zen[i][10].gdec(),zen[i][20].gdec()); | |
dA = (dists[i][1]+dists[i][11]) / 2; | |
dB = (dists[i][2]+dists[i][12]) / 2; | |
dC = (dists[i][3]+dists[i][13]) / 2; | |
dD = (dists[i][4]+dists[i][14]) / 2; | |
dE = (dists[i][5]+dists[i][15]) / 2; | |
dF = (dists[i][6]+dists[i][16]) / 2; | |
dG = (dists[i][7]+dists[i][17]) / 2; | |
dH = (dists[i][8]+dists[i][18]) / 2; | |
dI = (dists[i][9]+dists[i][19]) / 2; | |
dJ = (dists[i][10]+dists[i][20]) / 2; | |
topoPoint A(hA,zA,dA,false);temp.push_back(A); | |
topoPoint B(hB,zB,dB,false);temp.push_back(B); | |
topoPoint C(hC,zC,dC,false);temp.push_back(C); | |
topoPoint D(hD,zD,dD,false);temp.push_back(D); | |
topoPoint E(hE,zE,dE,false);temp.push_back(E); | |
topoPoint F(hF,zF,dF,false);temp.push_back(F); | |
topoPoint G(hG,zG,dG,false);temp.push_back(G); | |
topoPoint H(hH,zH,dH,false);temp.push_back(H); | |
topoPoint I(hI,zI,dI,false);temp.push_back(I); | |
topoPoint J(hJ,zJ,dJ,false);temp.push_back(J); | |
temp.push_back(EXTRA); | |
// cout <<hA<<" "<<zA<<" "<<dA<<endl; | |
} | |
if (i == 4) | |
{ | |
topoPoint EXTRA(hor[i][0].gdec(),zen[i][0].gdec(),dists[i][0],false); | |
hA = pdpiH(hor[i][1].gdec(),hor[i][11].gdec()); | |
hB = pdpiH(hor[i][2].gdec(),hor[i][12].gdec()); | |
hC = pdpiH(hor[i][3].gdec(),hor[i][13].gdec()); | |
hD = pdpiH(hor[i][4].gdec(),hor[i][14].gdec()); | |
hE = pdpiH(hor[i][5].gdec(),hor[i][15].gdec()); | |
hF = pdpiH(hor[i][6].gdec(),hor[i][16].gdec()); | |
hG = pdpiH(hor[i][7].gdec(),hor[i][17].gdec()); | |
hH = pdpiH(hor[i][8].gdec(),hor[i][18].gdec()); | |
hI = pdpiH(hor[i][9].gdec(),hor[i][19].gdec()); | |
hJ = pdpiH(hor[i][10].gdec(),hor[i][20].gdec()); | |
zA = pdpiV(zen[i][1].gdec(),zen[i][11].gdec()); | |
zB = pdpiV(zen[i][2].gdec(),zen[i][12].gdec()); | |
zC = pdpiV(zen[i][3].gdec(),zen[i][13].gdec()); | |
zD = pdpiV(zen[i][4].gdec(),zen[i][14].gdec()); | |
zE = pdpiV(zen[i][5].gdec(),zen[i][15].gdec()); | |
zF = pdpiV(zen[i][6].gdec(),zen[i][16].gdec()); | |
zG = pdpiV(zen[i][7].gdec(),zen[i][17].gdec()); | |
zH = pdpiV(zen[i][8].gdec(),zen[i][18].gdec()); | |
zI = pdpiV(zen[i][9].gdec(),zen[i][19].gdec()); | |
zJ = pdpiV(zen[i][10].gdec(),zen[i][20].gdec()); | |
dA = (dists[i][1]+dists[i][11]) / 2; | |
dB = (dists[i][2]+dists[i][12]) / 2; | |
dC = (dists[i][3]+dists[i][13]) / 2; | |
dD = (dists[i][4]+dists[i][14]) / 2; | |
dE = (dists[i][5]+dists[i][15]) / 2; | |
dF = (dists[i][6]+dists[i][16]) / 2; | |
dG = (dists[i][7]+dists[i][17]) / 2; | |
dH = (dists[i][8]+dists[i][18]) / 2; | |
dI = (dists[i][9]+dists[i][19]) / 2; | |
dJ = (dists[i][10]+dists[i][20]) / 2; | |
topoPoint A(hA,zA,dA,false);temp.push_back(A); | |
topoPoint B(hB,zB,dB,false);temp.push_back(B); | |
topoPoint C(hC,zC,dC,false);temp.push_back(C); | |
topoPoint D(hD,zD,dD,false);temp.push_back(D); | |
topoPoint E(hE,zE,dE,false);temp.push_back(E); | |
topoPoint F(hF,zF,dF,false);temp.push_back(F); | |
topoPoint G(hG,zG,dG,false);temp.push_back(G); | |
topoPoint H(hH,zH,dH,false);temp.push_back(H); | |
topoPoint I(hI,zI,dI,false);temp.push_back(I); | |
topoPoint J(hJ,zJ,dJ,false);temp.push_back(J); | |
temp.push_back(EXTRA); | |
// cout <<hA<<" "<<zA<<" "<<dA<<endl; | |
} | |
points.push_back(temp); | |
temp.clear(); | |
} | |
pointsPrint("points0.txt"); | |
} | |
void SMMTleverARM::pointsPrint(string filename) | |
{ | |
ofstream outFile(filename); | |
for (unsigned ii = 0; ii < points.size();ii++) | |
{ | |
for (unsigned jj = 0;jj < points[ii].size();jj++) | |
{ | |
outFile << points[ii][jj].XYZ(0) <<" "; | |
outFile << points[ii][jj].XYZ(1) <<" "; | |
outFile << points[ii][jj].XYZ(2) << endl; | |
} | |
} | |
outFile.close(); | |
} | |
void SMMTleverARM::horiz() | |
{ | |
vector<GMS> temp; | |
int g,m,s; | |
for (unsigned int i = 0; i < data.size() ; i++) | |
{ | |
for (unsigned int j = 0;j < data[i].size();j++) | |
{ | |
g = stoi(data[i][j].substr(23,3)); m = stoi(data[i][j].substr(27,2)); s = stoi(data[i][j].substr(29,2)); | |
GMS temp2(g,m,s); | |
temp.push_back(temp2); | |
} | |
hor.push_back(temp); | |
temp.clear(); | |
} | |
} | |
void SMMTleverARM::zenit() | |
{ | |
vector<GMS> temp; | |
int g,m,s; | |
for (unsigned int i = 0; i < data.size() ; i++) | |
{ | |
for (unsigned int j = 0;j < data[i].size();j++) | |
{ | |
g = stoi(data[i][j].substr(35,3)); m = stoi(data[i][j].substr(39,2)); s = stoi(data[i][j].substr(41,2)); | |
GMS temp2(g,m,s); | |
// cout<<temp2.gdec()<<endl; | |
temp.push_back(temp2); | |
} | |
zen.push_back(temp); | |
temp.clear(); | |
} | |
} | |
void SMMTleverARM::distanc() | |
{ | |
vector<double> temp; | |
double temp2; | |
for (unsigned int i = 0; i < data.size() ; i++) | |
{ | |
for (unsigned int j = 0;j < data[i].size();j++) | |
{ | |
temp2 = stod(data[i][j].substr(47,10)); | |
// cout<<temp2<<endl; | |
temp.push_back(temp2); | |
} | |
dists.push_back(temp); | |
temp.clear(); | |
} | |
} | |
topoPoint::topoPoint(double h,double z,double di,bool isRad) | |
{ | |
Hz=h;Ze=z;Di=di; | |
rad = isRad; | |
cart(); | |
} | |
void topoPoint::cart() | |
{ | |
double X,Y,Z; | |
if (rad) | |
{ | |
X = std::sin(Ze) * std::sin(Hz) * Di; | |
Y = std::sin(Ze) * std::cos(Hz) * Di; | |
Z = std::cos(Ze) * Di; | |
} | |
else | |
{ | |
X = std::sin(Ze*(datum::pi/180)) * std::sin(Hz*(datum::pi/180)) * Di; | |
Y = std::sin(Ze*(datum::pi/180)) * std::cos(Hz*(datum::pi/180)) * Di; | |
Z = std::cos(Ze*(datum::pi/180)) * Di; | |
} | |
vec3 temp = {X,Y,Z}; | |
XYZ = temp; | |
} | |
double pdpiH(double h1,double h2) | |
{ | |
if (h1 > h2) | |
{ | |
return (h1+h2+180)/2; | |
} | |
else | |
{ | |
return (h1+h2-180)/2; | |
} | |
} | |
double pdpiV(double v1,double v2) | |
{ | |
if (v1 < v2) | |
{ | |
return (v1-v2+360)/2; | |
} | |
else | |
{ | |
return (v2-v1+360)/2; | |
} | |
} | |
vec4 plane3points(vec3 u,vec3 v,vec3 w) | |
{ | |
//the function returns a 4-vector with the plane equation coefficients | |
//assuming the form ax + by + cz + d = 0 | |
vec4 res; | |
vec3 p1,p2,n; | |
vec d; | |
p1 = normalise(v - u); | |
p2 = normalise(w - u); | |
n = normalise(cross(p1,p2)); | |
d = - dot(n,u); | |
res = join_vert(n,d); | |
//cout << res <<endl; | |
return res; | |
} | |
void topoPoint::translate(vec3 tvec) | |
{ | |
XYZ += tvec; | |
} | |
void topoPoint::Rotate(mat R) | |
{ | |
XYZ = R * XYZ; | |
} | |
void TptMat (mat *M,vec Tvec) | |
{ | |
mat temp = *M; | |
if(temp.n_cols == Tvec.n_elem) | |
{ | |
for (uword i = 0;i < temp.n_rows;i++) | |
{ | |
temp.row(i) = trans(trans(temp.row(i)) + Tvec ); | |
} | |
} | |
else | |
{ | |
cout << "nada realizado, tamanho de colunas da matriz diferente do numero de elementos do vetor dado"<<endl; | |
} | |
*M = temp; | |
} | |
void RptMat (mat *M,mat R) | |
{ | |
mat temp = *M; | |
if( (temp.n_cols == R.n_cols) & (R.n_cols == R.n_rows) ) | |
{ | |
for (uword i = 0;i < temp.n_rows;i++) | |
{ | |
temp.row(i) = trans(R*trans(temp.row(i))); | |
} | |
} | |
else | |
{ | |
cout << "nada realizado, tamanho de colunas da matriz diferente do numero de colunas da matriz dada"<<endl; | |
cout<<"ou a matriz fornecida não é quadrada"<<endl; | |
} | |
*M = temp; | |
} | |
void SMMTleverARM::translateAll(vec3 tvec) | |
{ | |
for (unsigned int i = 0;i < points.size();i++) | |
{ | |
for (unsigned int j = 0; j < points[i].size();j++) | |
{ | |
points[i][j].translate(tvec); | |
} | |
} | |
} | |
void SMMTleverARM::rotAll (mat R) | |
{ | |
for (unsigned int i = 0;i < points.size();i++) | |
{ | |
for (unsigned int j = 0; j < points[i].size();j++) | |
{ | |
points[i][j].Rotate(R); | |
} | |
} | |
} | |
mat topoPointsMat (vector<topoPoint> points,uword first,uword last) | |
{ | |
mat res; | |
uword nlin = last - first + 1; | |
res.zeros(nlin,3); | |
for (uword i = first; i < last+1;i++) | |
{ | |
res.row(i-first) = trans(points.at(i).XYZ); | |
// cout << i <<endl; | |
} | |
// cout<<res<<endl; | |
return res; | |
} | |
vec4 parallelPlane(vec4 plane1,vec3 pointOnPlane) | |
{ | |
vec4 res; | |
vec3 n = normalise(plane1.rows(0,2)); | |
res.rows(0,2) = n; | |
res(3) = - dot(n,pointOnPlane); | |
return res; | |
} | |
vec3 ProjPtOrtPlane(vec3 pt2Proj,vec3 plNorm,vec3 ptOnPlane) | |
{ | |
return pt2Proj + (dot(normalise(plNorm),ptOnPlane-pt2Proj)) * normalise(plNorm); | |
} | |
vec3 onPlanePoint(vec4 plCoef,double x,double y) | |
{ | |
vec3 res; | |
res(0) = x;res(1) = y; | |
res(2) = - (plCoef(0)*x+plCoef(1)*y+plCoef(3))/plCoef(2); | |
return res; | |
} | |
void SMMTleverARM::report() | |
{ | |
ofstream out("report.txt"); | |
out.precision(8); | |
out << "Relatório de Saída do Processamento da "; | |
out<< "determinação dos parâmetros de orientação relativa" <<endl; | |
out<<"do Sistema de Mapeamento Móvel Terrestre do LAPE"<<endl<<endl<<endl; | |
out << "Lever Arm (no body-frame da IMU) --------------------------------"<<endl<<endl; | |
out<< "IMU -> Antena"<<endl; | |
out << "X(m): " <<antLA(0)<< " | Y(m): " <<antLA(1)<< " | Z(m): " <<antLA(2)<<endl<<endl; | |
out<< "IMU -> Câmera Esquerda"<<endl; | |
out << "X(m): " <<LcamLA(0)<< " | Y(m): " <<LcamLA(1)<< " | Z(m): " <<LcamLA(2)<<endl<<endl; | |
out<< "IMU -> Câmera Direita"<<endl; | |
out << "X(m): " <<RcamLA(0)<< " | Y(m): " <<RcamLA(1)<< " | Z(m): " <<RcamLA(2)<<endl<<endl<<endl; | |
out<< "Matrizes do Boresight (cossenos diretores): "<<endl<<endl; | |
Rimu_LC.raw_print(out,"IMU (BF) -> Câmera Esquerda (BF)");out<<endl; | |
Rimu_RC.raw_print(out,"IMU (BF) -> Câmera Direita (BF)");out<<endl<<endl; | |
out<< "Matrizes do Boresight (cossenos diretores, mesma convenção da IMU): "<<endl<<endl; | |
Rimu_LC2.raw_print(out,"IMU (BF) -> Câmera Esquerda (BF)");out<<endl; | |
Rimu_RC2.raw_print(out,"IMU (BF) -> Câmera Direita (BF)");out<<endl<<endl; | |
out<<"no último caso, os angulos formados com os eixos do BF da IMU: "<<endl<<endl; | |
out<<"IMU (BF) -> Câmera Esquerda (BF)"<<endl<<arma::acos(Rimu_LC2)*(180/datum::pi)<<endl<<endl; | |
out<<"IMU (BF) -> Câmera Direita (BF)"<<endl<<arma::acos(Rimu_RC2)*(180/datum::pi)<<endl; | |
out<<endl<<"testes de consistência dos resultados"<<endl; | |
out<<"as matrizes de rotação deverão, ao ser multiplicadas por sua transposta, serem iguais a matriz identidade"<<endl<<endl; | |
out<<"Rtopo_imu * Rtopo_imu.t()"<<endl<<Rot1 * Rot1.t()<<endl; | |
out<<"Rimu_LC * Rimu_LC.t()"<<endl<<Rimu_LC * Rimu_LC.t()<<endl; | |
out<<"Rimu_RC * Rimu_RC.t()"<<endl<<Rimu_RC * Rimu_RC.t()<<endl; | |
out<<"Rimu_LC2 * Rimu_LC2.t()"<<endl<<Rimu_LC2 * Rimu_LC2.t()<<endl; | |
out<<"Rimu_RC2 * Rimu_RC2.t()"<<endl<<Rimu_RC2 * Rimu_RC2.t()<<endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment