contrib/brl/bbas/bvgl/bvgl_articulated_poly.cxx

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

Generated on Wed Dec 3 05:19:20 2008 for contrib/brl/bbas/bvgl by  doxygen 1.5.1