Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 void PolynomialSurface::init(const boost::array<float, 6> ¶ms, const float min_x, const float max_x, const float min_y, const float max_y, const float weight)
00010 {
00011 param_.col(0) = Eigen::Vector3f::Zero();
00012 param_.col(0)(2) = params[0];
00013
00014 param_.col(1)(0)=params[1];
00015 param_.col(1)(1)=params[3];
00016 param_.col(1)(2)=0;
00017
00018 param_.col(2)(0)=params[2];
00019 param_.col(2)(1)=params[4];
00020 param_.col(2)(2)=params[5];
00021
00022 Eigen::Vector3f x,y;
00023 x(0)=y(1)=1.f;
00024 x(1)=x(2)=y(0)=y(2)=0.f;
00025
00026 proj2plane_.col(0)=x;
00027 proj2plane_.col(1)=y;
00028 }
00029
00030 Eigen::Vector3f PolynomialSurface::project2world(const Eigen::Vector2f &pt) const {
00031 Eigen::Vector3f pt2;
00032 pt2(0)=pt(0)*pt(0);
00033 pt2(1)=pt(1)*pt(1);
00034 pt2(2)=pt(0)*pt(1);
00035
00036 return param_.col(0) + proj2plane_*pt + proj2plane_.col(0).cross(proj2plane_.col(1)) * (pt2.dot(param_.col(2)) + pt.dot(param_.col(1).head<2>()));
00037 }
00038
00039 Eigen::Vector3f PolynomialSurface::normalAt(const Eigen::Vector2f &v) const {
00040 Eigen::Vector3f r;
00041
00042 r(0) = -(param_.col(1)(0) + 2*v(0)*param_.col(2)(0)+v(1)*param_.col(2)(2));
00043 r(1) = -(param_.col(1)(1) + 2*v(1)*param_.col(2)(1)+v(0)*param_.col(2)(2));
00044 r(2) = 1;
00045
00046 r.normalize();
00047
00048 Eigen::Matrix3f M;
00049 M.col(0) = proj2plane_.col(0);
00050 M.col(1) = proj2plane_.col(1);
00051 M.col(2) = proj2plane_.col(0).cross(proj2plane_.col(1));
00052
00053 return M*r;
00054 }
00055
00056 Eigen::Vector3f PolynomialSurface::normalAt2(const Eigen::Vector2f &v) const {
00057 Eigen::Vector3f r;
00058
00059
00060
00061
00062
00063 r(0) = 0;
00064 r(1) = 0;
00065 r(2) = 1;
00066
00067
00068
00069 Eigen::Matrix3f M;
00070 M.col(0) = proj2plane_.col(0);
00071 M.col(1) = proj2plane_.col(1);
00072 M.col(2) = proj2plane_.col(0).cross(proj2plane_.col(1));
00073
00074 return M*r;
00075 }
00076
00077 void PolynomialSurface::transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr)
00078 {
00079 param_.col(0) = rot * param_.col(0)+tr;
00080
00081 proj2plane_.col(0) = rot * proj2plane_.col(0);
00082 proj2plane_.col(1) = rot * proj2plane_.col(1);
00083 }
00084
00085 bool PolynomialSurface::fitsCurvature(const Surface &o, const float thr) const
00086 {
00087 ROS_ASSERT(getSurfaceType()==getSurfaceType());
00088
00089 return param_.col(2).cross(((PolynomialSurface*)&o)->param_.col(2)).squaredNorm() < thr*thr;
00090 }
00091
00093 Eigen::Vector2f PolynomialSurface::_nextPoint(const Eigen::Vector3f &v, Eigen::Vector3f p, const int depth) const
00094 {
00095 Eigen::VectorXf r(2);
00096 r = v.head<2>();
00097
00098 MyFunctor functor={param_.col(2)(0),param_.col(2)(1),param_.col(2)(2),
00099 param_.col(1)(0),param_.col(1)(1),
00100 p(0),p(1),p(2)};
00101 Eigen::LevenbergMarquardt<MyFunctor, float> lm(functor);
00102 lm.parameters.maxfev = 50;
00103 lm.minimize(r);
00104
00105 return r;
00106 }
00107
00109 Eigen::Vector2f PolynomialSurface::nextPoint(const Eigen::Vector3f &v) const
00110 {
00111 Eigen::Vector3f p;
00112
00113 p(0) = (v-param_.col(0)).dot(proj2plane_.col(0))/proj2plane_.col(0).squaredNorm();
00114 p(1) = (v-param_.col(0)).dot(proj2plane_.col(1))/proj2plane_.col(1).squaredNorm();
00115 p(2) = (v-param_.col(0)).dot(proj2plane_.col(0).cross(proj2plane_.col(1)));
00116
00117 Eigen::Vector2f r = _nextPoint(p, p);
00118
00119 float e1 = (v-project2world(p.head<2>())).norm();
00120 float e2 = (v-project2world(r)).norm();
00121
00122 if(e1+0.001f<e2)
00123 {
00124 ROS_WARN("e1>=e2 %f %f",e1,e2);
00125 return p.head<2>();
00126 }
00127
00128 return r;
00129 }