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
00012 bvgl_articulated_poly::bvgl_articulated_poly(const unsigned n_joints)
00013 {
00014 joint_transforms_.resize(n_joints);
00015
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
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
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
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
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
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
00147
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;
00156
00157
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
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
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
00208 manifold->sub_manifold_transform(-t, manifold_basis);
00209 }
00210 manifold->sub_manifold_transform(tmin, manifold_basis);
00211 return manifold;
00212 }