Aftter adding this line,
in 'head' of the blogger template editor in html mode, you can use MathJax expressions.
For a new line, use this block,
and, for an inline equation, use this line,
Monday, August 26, 2019
Friday, June 7, 2019
[LaTeX] Download from TeX Users Group
Download 'install-tl.zip' from Installing TeX Live over the Internet. After extracting all files, and run the install bat file as administrator. After finishing installation, run 'Texworks editor'.
Wednesday, September 19, 2012
Short memo for angle calculation using atan2
Angle and arc-tangent function (in C/C++)
θ = atan2(x,y)
θ' = -(360 - θ)
#1: Bearing and an arc-tangent function
b = atan2(E, N)
Angle between 'N' axis and a vector.
CW is positive.

#2: Rotation angle about an axis and an arc-tangent function
ω = -atan2(x, y)
Angle between 'Y' axis and a vector.
CCW is positive.
Monday, September 3, 2012
Visual Studio 2010 C++ tips: for loop initializer
In Visual Studio 2010, for a loop's initialization variable is not available out of for loop scope, unlike Visual C++ 6.0. Whenever we compile old codes (generated in VC++ 6.0) using newest version, it annoys us. Then, take easy, and change project option to release your blood pressure.
Go to "Project property pages - C/C++ - Language - Force Conformance in For Loop Scope", and select "No (/Zc:forScope-)".
For more information, "http://msdn.microsoft.com/en-us/library/84wcsx8x.aspx".
Go to "Project property pages - C/C++ - Language - Force Conformance in For Loop Scope", and select "No (/Zc:forScope-)".
For more information, "http://msdn.microsoft.com/en-us/library/84wcsx8x.aspx".
Visual Studio 2010 C++ tips: Deprecated functions
strcpy, sscanf, fscanf.... etc. There functions are not available anymore in recent Visual Studio .Net C++. Instead of these function, it is recommend to use new functions such as strcpy_s, sscanf_s, fscanf_s ... etc. If you are not pleased to change your old style functions with new ones, you can avoid this problem easily by using this define statement, "#define _CRT_SECURE_NO_DEPRECATE".
For more information about deprecated functions, refer to "http://msdn.microsoft.com/en-us/library/ms235384(v=vs.80).aspx"
For more information about deprecated functions, refer to "http://msdn.microsoft.com/en-us/library/ms235384(v=vs.80).aspx"
Monday, July 30, 2012
Visual Studio 2010 C++ tips: Instead of istream::eatwhite
istream::eatwhite is not supported anymore by recent visual studio C++.
So far, I've used an alternative function implemented by myself. I realized recently that there is a simpler and easier way to avoiding the effort.
In Visual Studio 2010 and 2008, the use of "ws" is the way to skips white space in the stream.
For example, in order to skip white spaces end of each line of a text file.
fstream imufile;
imufile.open(fname, ios::in);
imufile>>record0>>record1>>ws;
For more information,
http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=KO-KR&k=k(%22ISTREAM%2fSTD%3a%3aWS%22);k(%22STD%3a%3aWS%22);k(WS);k(DevLang-%22C%2B%2B%22);k(TargetOS-WINDOWS)&rd=true
Friday, May 18, 2012
Derivation of direct linear transformation for a line scanner
Friday, April 20, 2012
Simple test: Kalman filter and least square filter for a dynamic system
Kalman filter is one of most popular signal filter. As well known, the fundamental of Kalman Filter and Least Square Method is same. Here is a sample for a dynamic system, where filtering is conducted by KF and LS approaches.
double rand_num()
{
return 2*((rand()/(double)RAND_MAX) - 0.5);
}
int KF_LS_Test()
{
double pos[NUMDATA];
double pos_t[NUMDATA];
srand((unsigned int)time(NULL));
double noise = 0.09;
for(int t=0; t<NUMDATA; t++)
{
double p = (double)cosf(2.0f*(float)t/(float)NUMDATA*(float)acos(-1.0));
pos_t[t] = p;
pos[t] = p + rand_num()*noise;
}
//Initial values
CSMMatrix<double> x0(1,1,0.0);
CSMMatrix<double> P0(1,1,0.0);
CSMMatrix<double> xk0(1,1,0.0);
CSMMatrix<double> Pk0(1,1,0.0);
CSMMatrix<double> xk1_(1,1,0.0);
CSMMatrix<double> Pk1_(1,1,0.0);
CSMMatrix<double> xk1(1,1,0.0);
CSMMatrix<double> Pk1(1,1,0.0);
CSMMatrix<double> Qk(1,1);
Qk(0,0) = noise*noise*0.01;
CSMMatrix<double> Rk(1,1);
Rk(0,0) = noise*noise;
CSMMatrix<double> K(1,1,1.0);
CSMMatrix<double> I(1,1,1.0);
xk1(0,0) = pos_t[0] + rand_num()*noise;
Pk1(0,0) = 0.0;//1.0e99;
fstream outfile;
outfile.open(_T("C:\\Users\\kibang\\Desktop\\KFtestout.txt"), ios::out);
_tprintf(_T("R = %lf\n"),Rk(0,0));
_tprintf(_T("Q = %lf\n"),Qk(0,0));
_tprintf(_T("@time = %d\n"),0);
_tprintf(_T("x = %lf\n"),xk1(0,0));
_tprintf(_T("P = %lf\n"),Pk1(0,0));
int count = 0;
CSMMatrix<double> Var_x_hat(1,1);
double s_hat;
CSMMatrix<double> X, H(1,1,1.0), L(1,1), L2(1,1), W(1,1), N(1,1,0.0), C(1,1,0.0);
W(0,0) = 1.0/Rk(0,0);
//Var_x_hat(0,0) = Pk1(0,0);
Var_x_hat(0,0) = Qk(0,0);
double VTV = 0;
for(int t=0; t<NUMDATA; t++)
{
//
//LS approach
//
count ++;
L(0,0) = pos[t];
L2(0,0) = xk1(0,0);
Var_x_hat = Qk;
CSMMatrix<double> Ni = ( H.Transpose() % W % H + Var_x_hat.Inverse() );
//CSMMatrix<double> Ni = ( H.Transpose() % W % H);
CSMMatrix<double> Ci = (H.Transpose() % W % L + Var_x_hat.Inverse() % L2);
//N = N + Ni; C = C + Ci;
N = Ni; C = Ci;
X = N.Inverse() % C;
//VTV += (X(0,0) - pos[t])*(X(0,0) - pos[t])*W(0,0);
VTV = (X(0,0) - pos[t])*(X(0,0) - pos[t])*W(0,0);
s_hat = sqrt(VTV/count);
Var_x_hat = N.Inverse()*(s_hat*s_hat);
//
//KF approach
//
_tprintf(_T("@time = %d\n"),t+1);
_tprintf(_T("True x = %lf\n"),0.0);
xk0 = xk1;
Pk0 = Pk1;
//Predict
xk1_ = xk0;
Pk1_ = Pk0 + Qk;
_tprintf(_T("Predicted x = %lf\n"),xk1_(0,0));
_tprintf(_T("Predicted P = %lf\n"),Pk1_(0,0));
//Kalman gain
K = Pk1_ % (Pk1_ + Rk).Inverse();
_tprintf(_T("Measured x = %lf\n"),pos[t]);
//Update state using measurement
CSMMatrix<double> Pos(1,1,pos[t]);
xk1 = xk1_ + K % (Pos - xk1_);
//Update error covariance
Pk1 = (I - K)%Pk1_;
_tprintf(_T("Updated x = %lf\n"),xk1(0,0));
_tprintf(_T("Updated P = %lf\n"),Pk1(0,0));
_tprintf(_T("Adjusted(LS) P = %lf\n"),X(0,0));
outfile<<t+1<<"\t"<<pos_t[t]<<"\t"<<xk1_(0,0)<<"\t"<<xk1(0,0)<<"\t"<<X(0,0)<<"\t"<<pos[t]<<endl;
}
outfile.close();
return 0;
}
double rand_num()
{
return 2*((rand()/(double)RAND_MAX) - 0.5);
}
int KF_LS_Test()
{
double pos[NUMDATA];
double pos_t[NUMDATA];
srand((unsigned int)time(NULL));
double noise = 0.09;
for(int t=0; t<NUMDATA; t++)
{
double p = (double)cosf(2.0f*(float)t/(float)NUMDATA*(float)acos(-1.0));
pos_t[t] = p;
pos[t] = p + rand_num()*noise;
}
//Initial values
CSMMatrix<double> x0(1,1,0.0);
CSMMatrix<double> P0(1,1,0.0);
CSMMatrix<double> xk0(1,1,0.0);
CSMMatrix<double> Pk0(1,1,0.0);
CSMMatrix<double> xk1_(1,1,0.0);
CSMMatrix<double> Pk1_(1,1,0.0);
CSMMatrix<double> xk1(1,1,0.0);
CSMMatrix<double> Pk1(1,1,0.0);
CSMMatrix<double> Qk(1,1);
Qk(0,0) = noise*noise*0.01;
CSMMatrix<double> Rk(1,1);
Rk(0,0) = noise*noise;
CSMMatrix<double> K(1,1,1.0);
CSMMatrix<double> I(1,1,1.0);
xk1(0,0) = pos_t[0] + rand_num()*noise;
Pk1(0,0) = 0.0;//1.0e99;
fstream outfile;
outfile.open(_T("C:\\Users\\kibang\\Desktop\\KFtestout.txt"), ios::out);
_tprintf(_T("R = %lf\n"),Rk(0,0));
_tprintf(_T("Q = %lf\n"),Qk(0,0));
_tprintf(_T("@time = %d\n"),0);
_tprintf(_T("x = %lf\n"),xk1(0,0));
_tprintf(_T("P = %lf\n"),Pk1(0,0));
int count = 0;
CSMMatrix<double> Var_x_hat(1,1);
double s_hat;
CSMMatrix<double> X, H(1,1,1.0), L(1,1), L2(1,1), W(1,1), N(1,1,0.0), C(1,1,0.0);
W(0,0) = 1.0/Rk(0,0);
//Var_x_hat(0,0) = Pk1(0,0);
Var_x_hat(0,0) = Qk(0,0);
double VTV = 0;
for(int t=0; t<NUMDATA; t++)
{
//
//LS approach
//
count ++;
L(0,0) = pos[t];
L2(0,0) = xk1(0,0);
Var_x_hat = Qk;
CSMMatrix<double> Ni = ( H.Transpose() % W % H + Var_x_hat.Inverse() );
//CSMMatrix<double> Ni = ( H.Transpose() % W % H);
CSMMatrix<double> Ci = (H.Transpose() % W % L + Var_x_hat.Inverse() % L2);
//N = N + Ni; C = C + Ci;
N = Ni; C = Ci;
X = N.Inverse() % C;
//VTV += (X(0,0) - pos[t])*(X(0,0) - pos[t])*W(0,0);
VTV = (X(0,0) - pos[t])*(X(0,0) - pos[t])*W(0,0);
s_hat = sqrt(VTV/count);
Var_x_hat = N.Inverse()*(s_hat*s_hat);
//
//KF approach
//
_tprintf(_T("@time = %d\n"),t+1);
_tprintf(_T("True x = %lf\n"),0.0);
xk0 = xk1;
Pk0 = Pk1;
//Predict
xk1_ = xk0;
Pk1_ = Pk0 + Qk;
_tprintf(_T("Predicted x = %lf\n"),xk1_(0,0));
_tprintf(_T("Predicted P = %lf\n"),Pk1_(0,0));
//Kalman gain
K = Pk1_ % (Pk1_ + Rk).Inverse();
_tprintf(_T("Measured x = %lf\n"),pos[t]);
//Update state using measurement
CSMMatrix<double> Pos(1,1,pos[t]);
xk1 = xk1_ + K % (Pos - xk1_);
//Update error covariance
Pk1 = (I - K)%Pk1_;
_tprintf(_T("Updated x = %lf\n"),xk1(0,0));
_tprintf(_T("Updated P = %lf\n"),Pk1(0,0));
_tprintf(_T("Adjusted(LS) P = %lf\n"),X(0,0));
outfile<<t+1<<"\t"<<pos_t[t]<<"\t"<<xk1_(0,0)<<"\t"<<xk1(0,0)<<"\t"<<X(0,0)<<"\t"<<pos[t]<<endl;
}
outfile.close();
return 0;
}
Thursday, July 28, 2011
Visual Studio 2010 C++ tips: sscanf_s and fopen_s
-. sscanf vs. sscanf_s
구 버전과 비교하여 파일 및 스트링 관련 함수들에 "_s"가 붙은 함수들이 제공되고 있다. 그러한 함수들 중에는 buffer overflow를 방지하기위한 목적 buffer 사이즈를 명시하도록 규정하고 있다.예를들어strcpy와strcpy_s를 비교해보면, 새로제공되는 함수는 target과source사이에 buffer 사이즈를 입력해야 한다.
"_s"가 붙은 신규함수와 붙지않은 구함수 사이에 함수원형에 있어서 차이점이 없는 경우는, #define을 사용하여 손쉽게 구함수를 신함수로 전환할 수 있으나, 주의해야할 함수가 있다. sscanf_s는 원형이 구 함수인 sscanf와 동일한것 처럼 보이고, 단순히 함수이름만 변경하여도 컴파일 에러가 발생하지 않지만, 실행시 에러가 발생하는 경우가 있다. %c 또는 %s의 포맷으로 데이터를 입력받는 변수의 경우, sizeof()를 사용하여 buffer의 사이즈를 명시하지 않는 경우, 에러가 발생하게 됨으로 주의해야 한다.
-. fopen vs fopen_s 과 fsopen
fopen_s 또한 fopen을 대신하도록 권고되고 있는데, 두 함수사이에 차이점이 있다.
outfile = fopen(filename, "w");
fopen(outfile, filename, "w");
위와 같이 파일을 open하는 경우, fopen과 달리 fopen_s를 사용하는 경우, open된 파일을 sharing이 허용되지 않는다.
따라서, sharing이 허용되도록 하기 위해서는
outfile = fsopen(filename, "w", _SH_DENYNO);
와 같이 fsopen함수와 _SH_DENYNO 플래그를 사용하여 파일을 open해야 한다.
구 버전과 비교하여 파일 및 스트링 관련 함수들에 "_s"가 붙은 함수들이 제공되고 있다. 그러한 함수들 중에는 buffer overflow를 방지하기위한 목적 buffer 사이즈를 명시하도록 규정하고 있다.예를들어strcpy와strcpy_s를 비교해보면, 새로제공되는 함수는 target과source사이에 buffer 사이즈를 입력해야 한다.
"_s"가 붙은 신규함수와 붙지않은 구함수 사이에 함수원형에 있어서 차이점이 없는 경우는, #define을 사용하여 손쉽게 구함수를 신함수로 전환할 수 있으나, 주의해야할 함수가 있다. sscanf_s는 원형이 구 함수인 sscanf와 동일한것 처럼 보이고, 단순히 함수이름만 변경하여도 컴파일 에러가 발생하지 않지만, 실행시 에러가 발생하는 경우가 있다. %c 또는 %s의 포맷으로 데이터를 입력받는 변수의 경우, sizeof()를 사용하여 buffer의 사이즈를 명시하지 않는 경우, 에러가 발생하게 됨으로 주의해야 한다.
-. fopen vs fopen_s 과 fsopen
fopen_s 또한 fopen을 대신하도록 권고되고 있는데, 두 함수사이에 차이점이 있다.
outfile = fopen(filename, "w");
fopen(outfile, filename, "w");
위와 같이 파일을 open하는 경우, fopen과 달리 fopen_s를 사용하는 경우, open된 파일을 sharing이 허용되지 않는다.
따라서, sharing이 허용되도록 하기 위해서는
outfile = fsopen(filename, "w", _SH_DENYNO);
와 같이 fsopen함수와 _SH_DENYNO 플래그를 사용하여 파일을 open해야 한다.
Thursday, February 17, 2011
Plane fitting
Plane equation:
(1) lx + my + nz = d
where d is a distance from an origin to the plane,
{l,m,n} is direction consines, and
sqrt(l*l + m*m + n*n)=1.
(2) ax + by + cz = 1
where d presented in (1) can be calculated by 1/sqrt(a*a + b*b + c*c).
(3) Ax + By + Cz = d^2
where (A, B, C) denotes a vector from an origin to the plane, which can be obtained by A = l*d, B=m*d, and C=n*d.
For a point cloud, P0, P1, P2, ~ Pn,
Its centroid C, (cx, cy, cz), is on an expected least squre fitted plane.
Therefore, dot product of [l, m, n] and (Pi-C) is zero.
l*xi + m*yi + n*zi = 0
whrer (xi,yi,zi) = Pi
To avoid [l, m, n] are estimated as zero,
a constraint of direction consines is adopted,
l^2 + m^2 + n^2 = 1.0
Subscribe to:
Comments (Atom)
-
-. A-priori reference variable has no unit (unitless). It is typically 1.0 or can be a different value for scaling. -. Weight is determ...
-
Aftter adding this line, in 'head' of the blogger template editor in html mode, you can use MathJax expressions. For a new ...
-
Multi-byte Unicode char TCHAR strcat_s() _tcscaft_s() strcpy_s() _tcscpy_s() strncpy_s() _tcsncpy_s() strien() _tcsien() sprinif_s()...




