Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

bvgl_articulated_poly.cxx

Go to the documentation of this file.
00001 #include <vcl_iostream.h>
00002 #include <vcl_cassert.h>
00003 #include <vcl_vector.h>
00004 #include <vcl_cmath.h>
00005 #include <vnl/vnl_math.h>
00006 #include <vnl/vnl_numeric_traits.h>
00007 #include <vgl/vgl_homg_point_2d.h>
00008 #include <vgl/vgl_point_2d.h>
00009 #include <bvgl/bvgl_articulated_poly.h>
00010 
00011 //empty constructor
00012 bvgl_articulated_poly::bvgl_articulated_poly(const unsigned n_joints)
00013 {
00014   joint_transforms_.resize(n_joints);
00015   //make the transforms identity with unit length joints
00016   for (unsigned i = 0; i<n_joints; ++i)
00017   {
00018     joint_transforms_[i].set_identity();
00019     if (i>0)
00020       joint_transforms_[i].set_translation(1.0, 0.0);
00021   }
00022   for (unsigned i = 0; i<n_joints; ++i)
00023   {
00024     vsol_point_2d_sptr p = this->joint_position(i);
00025     this->add_vertex(p);
00026   }
00027 }
00028 
00029 //link lengths are specified. For n joints there are n-1 links
00030 bvgl_articulated_poly::
00031 bvgl_articulated_poly(const unsigned n_joints,
00032                       vcl_vector<double> const& link_lengths)
00033 {
00034   assert(n_joints==link_lengths.size()+1);
00035 
00036   joint_transforms_.resize(n_joints);
00037   //make the transforms identity with unit length joints
00038   for (unsigned i = 0; i<n_joints; ++i)
00039   {
00040     joint_transforms_[i].set_identity();
00041     if (i>0)
00042       joint_transforms_[i].set_translation(link_lengths[i-1], 0.0);
00043   }
00044   for (unsigned i = 0; i<n_joints; ++i)
00045   {
00046     vsol_point_2d_sptr p = this->joint_position(i);
00047     this->add_vertex(p);
00048   }
00049 }
00050 
00051 bvgl_articulated_poly::bvgl_articulated_poly(const bvgl_articulated_poly& poly)
00052 {
00053   unsigned n = poly.size();
00054   joint_transforms_.resize(n);
00055   for (unsigned i = 0; i<n; ++i)
00056   {
00057     this->add_vertex(poly.joint_position(i));
00058     joint_transforms_[i]=poly.joint_transform(i);
00059   }
00060 }
00061 
00062 //Transform the joint position to world coordinates
00063 vsol_point_2d_sptr
00064 bvgl_articulated_poly::joint_position(const unsigned joint) const
00065 {
00066   if (joint == 0)
00067     return new vsol_point_2d(0.0, 0.0);
00068 
00069   vgl_h_matrix_2d<double> T = joint_transforms_[0];
00070   for (unsigned i=1; i<=joint; ++i)
00071   {
00072     vgl_h_matrix_2d<double> Tp = joint_transforms_[i];
00073     T = T*Tp;
00074   }
00075   //The last joint has local coordinates (0,0) at the joint
00076   vgl_homg_point_2d<double> zero(0.0,0.0,1.0);
00077   vgl_homg_point_2d<double> homg_wp = T(zero);
00078   vgl_point_2d<double> wp(homg_wp);
00079   return new vsol_point_2d(wp.x(), wp.y());
00080 }
00081 
00082 void bvgl_articulated_poly::update()
00083 {
00084   unsigned n = this->size();
00085   for (unsigned i = 0; i<n; ++i)
00086   {
00087     vsol_point_2d_sptr p = this->joint_position(i);
00088     (*storage_)[i]->set_x(p->x());
00089     (*storage_)[i]->set_y(p->y());
00090   }
00091 }
00092 
00093 void bvgl_articulated_poly::
00094 transform(vcl_vector<double > const& delta_joint_angle)
00095 {
00096   unsigned n = delta_joint_angle.size();
00097   assert(n==joint_transforms_.size());
00098   for (unsigned i = 0; i<n; ++i)
00099   {
00100     vgl_h_matrix_2d<double> r;
00101     r.set_identity();
00102     r.set_rotation(delta_joint_angle[i]);
00103     joint_transforms_[i]=joint_transforms_[i]*r;
00104   }
00105   this->update();
00106 }
00107 
00108 void bvgl_articulated_poly::
00109 sub_manifold_transform(const double t,
00110                        vcl_vector<double > const& basis_angles)
00111 {
00112   vcl_vector<double > angles;
00113   for (vcl_vector<double >::const_iterator ait = basis_angles.begin();
00114        ait != basis_angles.end(); ++ait)
00115     angles.push_back(t*(*ait));
00116   this->transform(angles);
00117   this->update();
00118 }
00119 
00120 //only works up to equiform
00121 static double angle_from_rotation_matrix(vgl_h_matrix_2d<double> const& r)
00122 {
00123   double c = r.get(0,0);
00124   double s = r.get(1,0);
00125   double ang = vcl_atan2(s,c);
00126   if (ang>vnl_math::pi)
00127     ang = 2*vnl_math::pi - ang;
00128   return ang;
00129 }
00130 
00131 double bvgl_articulated_poly::joint_angle(unsigned joint) const
00132 {
00133   return angle_from_rotation_matrix(this->joint_transform(joint));
00134 }
00135 
00136 double bvgl_articulated_poly::link_length(unsigned joint) const
00137 {
00138   unsigned n = this->size();
00139   if (joint>=n-1)
00140     return 0;
00141   vgl_h_matrix_2d<double> T = this->joint_transform(joint+1);
00142   double tx = T.get(0,2), ty = T.get(1,2);
00143   return vcl_sqrt(tx*tx + ty*ty);
00144 }
00145 
00146 //The earlier joints in the chain are weighted more since they appear in more
00147 //backward chain matrices.
00148 double bvgl_articulated_poly::
00149 lie_distance(bvgl_articulated_poly const& apa,
00150              bvgl_articulated_poly const& apb)
00151 {
00152   unsigned na = apa.size();
00153   unsigned nb = apb.size();
00154   assert(na==nb);
00155   double d = 0;//distance
00156   //note that there is no effect of the angle of the last joint
00157   //The weight is N-(joint+1)
00158   for (unsigned i =0; i<na-1; ++i)
00159   {
00160     vgl_h_matrix_2d<double> Ta = apa.joint_transform(i);
00161     vgl_h_matrix_2d<double> Tb = apb.joint_transform(i);
00162     double ra = angle_from_rotation_matrix(Ta);
00163     double rb = angle_from_rotation_matrix(Tb);
00164     d += (na-i-1)*(ra-rb)*(ra-rb);
00165   }
00166   return vcl_sqrt(d);
00167 }
00168 
00169 void bvgl_articulated_poly::print()
00170 {
00171   for (unsigned i = 0; i<joint_transforms_.size(); ++i)
00172   {
00173     vsol_point_2d_sptr p = this->joint_position(i);
00174     vcl_cout << "Joint[" << i << "](" << p->x() << ' ' << p->y()
00175              << ")| " << this->joint_angle(i) << "|\n";
00176   }
00177 }
00178 
00179 
00180 void bvgl_articulated_poly::print_xforms()
00181 {
00182   for (unsigned i = 0; i<joint_transforms_.size(); ++i)
00183     vcl_cout << "T[" << i << "]=>\n" <<  joint_transforms_[i] << '\n';
00184 }
00185 
00186 bvgl_articulated_poly_sptr bvgl_articulated_poly::
00187 projection(bvgl_articulated_poly_sptr const& target,
00188            vcl_vector<double > const& manifold_basis)
00189 {
00190   //copy the target
00191   unsigned n = target->size();
00192   vcl_vector<double> links(n-1);
00193   for (unsigned i = 0; i<n-1; ++i)
00194     links[i]=target->link_length(i);
00195   //search for the projection.
00196   bvgl_articulated_poly_sptr manifold = new bvgl_articulated_poly(n, links);
00197   double d = vnl_numeric_traits<double>::maxval, tmin=0;
00198   for (double t = - 3.0; t<=3.0; t+=0.05)
00199   {
00200     manifold->sub_manifold_transform(t, manifold_basis);
00201     double dt = bvgl_articulated_poly::lie_distance(*manifold, *target);
00202     if (dt<d)
00203     {
00204       d = dt;
00205       tmin = t;
00206     }
00207     //undo the transform
00208     manifold->sub_manifold_transform(-t, manifold_basis);
00209   }
00210   manifold->sub_manifold_transform(tmin, manifold_basis);
00211   return manifold;
00212 }

Generated on Thu Jan 10 14:50:31 2008 for contrib/brl/bbas/bvgl by  doxygen 1.4.4