00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <cstdlib>
00021 #include <iomanip>
00022
00023 #include <boost/numeric/ublas/io.hpp>
00024 #include <boost/numeric/ublas/vector.hpp>
00025 #include <boost/numeric/ublas/vector_proxy.hpp>
00026 #include <boost/numeric/ublas/matrix.hpp>
00027 #include <boost/numeric/ublas/matrix_proxy.hpp>
00028 #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
00029 #include <boost/numeric/bindings/traits/ublas_vector.hpp>
00030 #include <boost/numeric/bindings/lapack/lapack.hpp>
00031 #include <boost/numeric/ublas/symmetric.hpp>
00032
00033 #include "uvsim/sensing/Imu6DofSensor.h"
00034 #include "uvsim/utilities/utilities.h"
00035 #include "uvsim/visualization/PointCloud.h"
00036 #include "uvsim/visualization/SimpleViewer.h"
00037 #include "uvsim/visualization/Ellipsoid.h"
00038
00039 using namespace boost::numeric::ublas;
00040 using namespace uvsim;
00041 using namespace boost::numeric::bindings::lapack;
00042
00043 int main (int argc, char const* argv[])
00044 {
00045
00046 const static int freqImu = 520, freqMagCalib = 100;
00047 int maxN = 100000;
00048 int fps = 20;
00049 osg::Vec3d manipCenter(604,586,629);
00050 double manipDistance = 1000;
00051 float frameSize = 5;
00052
00053
00054 const static int freqRatio = freqImu/freqMagCalib;
00055 std::cout << "Frequency Ratio: " << freqRatio << std::endl;
00056 if (freqRatio <=0)
00057 {
00058 std::cout << "The frequency of the imu: " << freqImu
00059 << " must be faster than that of the calibration: " <<
00060 freqMagCalib << "." << std::endl;
00061 exit(-1);
00062 }
00063
00064
00065
00066 vector<double> freqCutMb(3), freqCutFb(3), freqCutWb(3);
00067
00068
00069 freqCutMb(0) = 3;
00070 freqCutMb(1) = 3;
00071 freqCutMb(2) = 3;
00072
00073
00074 freqCutFb(0) = 350;
00075 freqCutFb(1) = 350;
00076 freqCutFb(2) = 150;
00077
00078
00079 freqCutWb(0) = 120;
00080 freqCutWb(1) = 120;
00081 freqCutWb(2) = 120;
00082
00083
00084 Imu6DofSensor imu("/dev/rfcomm0", freqCutMb, freqCutFb, freqCutWb);
00085
00086
00087 vector<double> x(maxN), y(maxN), z(maxN), center(3), radii(3), bias(3), scaleFactor(3);
00088 matrix<double> temp(6,6);
00089
00090
00091 srand(time(0));
00092
00093
00094 osg::Vec3Array *points = new osg::Vec3Array;
00095 osg::Vec4Array *colors = new osg::Vec4Array;
00096 osg::Vec4 ini(1,1,0,1);
00097 osg::Vec4 fin(0,0,1,1);
00098 PointCloud *pointCloud = new PointCloud(5,points,colors);
00099 osg::Group *root = new osg::Group;
00100 root->addChild((pointCloud->root).get());
00101
00102
00103 int n = 0;
00104 imu.start(freqImu);
00105
00106
00107 double fogStart = 0, fogEnd = 1000;
00108 SimpleViewer simpleViewer(0,fps,root,manipDistance,manipCenter,frameSize,fogStart,fogEnd);
00109 simpleViewer.start();
00110
00111
00112 for (int j=0;!simpleViewer.viewer->done();j++)
00113 {
00114
00115 imu.update();
00116
00117
00118
00119 if ((j % freqRatio) == 0)
00120 {
00121
00122 clear();
00123 std::cout << (100.*(n+1))/maxN << "% Complete" << std::endl;
00124 std::cout << "data: " << imu.mb << std::endl;
00125
00126
00127 x(n) = imu.mb[0];
00128 y(n) = imu.mb[1];
00129 z(n) = imu.mb[2];
00130
00131
00132
00133
00134
00135
00136
00137 points->push_back(osg::Vec3(x(n),y(n),z(n)));
00138 colors->push_back(ini+(fin-ini)*(n*2/(float)maxN));
00139 pointCloud->updateSize();
00140
00141
00142 if (n++ == (maxN-1)) break;
00143 }
00144 }
00145
00146
00147 imu.stop();
00148
00149
00150 std::cout << "Creating design matrix." << std::endl;
00151
00152
00153
00154
00155 matrix<double> D(n,6);
00156 for (int i=0;i<n;i++)
00157 {
00158 D(i,0) = x(i)*x(i);
00159 D(i,1) = y(i)*y(i);
00160 D(i,2) = z(i)*z(i);
00161 D(i,3) = 2*x(i);
00162 D(i,4) = 2*y(i);
00163 D(i,5) = 2*z(i);
00164 }
00165
00166 std::cout << "Design matrix. " << std::endl;
00167 std::cout << "D: " << D << std::endl;
00168
00169
00170 if (n < 1000)
00171 {
00172 std::cout << "Solving for bias and scale factors. " << std::endl;
00173 matrix<double> v(6,1);
00174 matrix<double> K(3,3);
00175 K(0,0) = 1;
00176 K(1,2) = 3;
00177 K(2,0) =.3;
00178 K(1,1) =.4;
00179 std::cout << K << std::endl;
00180 std::cout << pinv(K) << std::endl;
00181
00182 double gam = 1 + ( v(3,0)*v(3,0) / v(0,0) + v(4,0)*v(4,0) / v(1,0) +
00183 v(5,0)*v(5,0) / v(2,0) );
00184 for (int i=0;i<3;i++)
00185 {
00186 center(i) = -v(i+3,0)/v(i,0);
00187 bias(i) = -center(i);
00188 radii(i) = sqrt(gam/v(i,0));
00189 scaleFactor(i) = 1/radii(i);
00190 }
00191
00192
00193 std::cout << std::setprecision(8);
00194 std::cout << "v: " << v << std::endl;
00195 std::cout << "center: " << center << std::endl;
00196 std::cout << "radii: " << radii << std::endl;
00197 std::cout << "bias: " << bias << std::endl;
00198 std::cout << "scale factor: " << scaleFactor << std::endl;
00199
00200 Ellipsoid ellipsoid(osg::Vec3d(radii(0),radii(1),radii(2)),osg::Vec3d(center(0),center(1),center(2)));
00201 root->addChild(ellipsoid.root.get());
00202 }
00203 else
00204 {
00205 std::cout << "N too large to compute svd" << std::endl;
00206 }
00207
00208 simpleViewer.stop();
00209 return 0;
00210 }
00211
00212