Go to the documentation of this file.00001 #include "bvgl_articulated_poly.h"
00002
00003
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
00014 bvgl_articulated_poly::bvgl_articulated_poly(const unsigned n_joints)
00015 {
00016 joint_transforms_.resize(n_joints);
00017
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
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
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 : vsol_polyline_2d(poly)
00055 {
00056 unsigned n = poly.size();
00057 joint_transforms_.resize(n);
00058 for (unsigned i = 0; i<n; ++i)
00059 {
00060 this->add_vertex(poly.joint_position(i));
00061 joint_transforms_[i]=poly.joint_transform(i);
00062 }
00063 }
00064
00065
00066 vsol_point_2d_sptr
00067 bvgl_articulated_poly::joint_position(const unsigned joint) const
00068 {
00069 if (joint == 0)
00070 return new vsol_point_2d(0.0, 0.0);
00071
00072 vgl_h_matrix_2d<double> T = joint_transforms_[0];
00073 for (unsigned i=1; i<=joint; ++i)
00074 {
00075 vgl_h_matrix_2d<double> Tp = joint_transforms_[i];
00076 T = T*Tp;
00077 }
00078
00079 vgl_homg_point_2d<double> zero(0.0,0.0,1.0);
00080 vgl_homg_point_2d<double> homg_wp = T(zero);
00081 vgl_point_2d<double> wp(homg_wp);
00082 return new vsol_point_2d(wp.x(), wp.y());
00083 }
00084
00085 void bvgl_articulated_poly::update()
00086 {
00087 unsigned n = this->size();
00088 for (unsigned i = 0; i<n; ++i)
00089 {
00090 vsol_point_2d_sptr p = this->joint_position(i);
00091 (*storage_)[i]->set_x(p->x());
00092 (*storage_)[i]->set_y(p->y());
00093 }
00094 }
00095
00096 void bvgl_articulated_poly::
00097 transform(vcl_vector<double > const& delta_joint_angle)
00098 {
00099 unsigned n = delta_joint_angle.size();
00100 assert(n==joint_transforms_.size());
00101 for (unsigned i = 0; i<n; ++i)
00102 {
00103 vgl_h_matrix_2d<double> r;
00104 r.set_identity();
00105 r.set_rotation(delta_joint_angle[i]);
00106 joint_transforms_[i]=joint_transforms_[i]*r;
00107 }
00108 this->update();
00109 }
00110
00111 void bvgl_articulated_poly::
00112 sub_manifold_transform(const double t,
00113 vcl_vector<double > const& basis_angles)
00114 {
00115 vcl_vector<double > angles;
00116 for (vcl_vector<double >::const_iterator ait = basis_angles.begin();
00117 ait != basis_angles.end(); ++ait)
00118 angles.push_back(t*(*ait));
00119 this->transform(angles);
00120 this->update();
00121 }
00122
00123
00124 static double angle_from_rotation_matrix(vgl_h_matrix_2d<double> const& r)
00125 {
00126 double c = r.get(0,0);
00127 double s = r.get(1,0);
00128 double ang = vcl_atan2(s,c);
00129 if (ang>vnl_math::pi)
00130 ang = 2*vnl_math::pi - ang;
00131 return ang;
00132 }
00133
00134 double bvgl_articulated_poly::joint_angle(unsigned joint) const
00135 {
00136 return angle_from_rotation_matrix(this->joint_transform(joint));
00137 }
00138
00139 double bvgl_articulated_poly::link_length(unsigned joint) const
00140 {
00141 unsigned n = this->size();
00142 if (joint>=n-1)
00143 return 0;
00144 vgl_h_matrix_2d<double> T = this->joint_transform(joint+1);
00145 double tx = T.get(0,2), ty = T.get(1,2);
00146 return vcl_sqrt(tx*tx + ty*ty);
00147 }
00148
00149
00150
00151 double bvgl_articulated_poly::
00152 lie_distance(bvgl_articulated_poly const& apa,
00153 bvgl_articulated_poly const& apb)
00154 {
00155 assert(apa.size()==apb.size());
00156 unsigned na = apa.size();
00157 double d = 0;
00158
00159
00160 for (unsigned i =0; i+1<na; ++i)
00161 {
00162 vgl_h_matrix_2d<double> Ta = apa.joint_transform(i);
00163 vgl_h_matrix_2d<double> Tb = apb.joint_transform(i);
00164 double ra = angle_from_rotation_matrix(Ta);
00165 double rb = angle_from_rotation_matrix(Tb);
00166 d += (na-i-1)*(ra-rb)*(ra-rb);
00167 }
00168 return vcl_sqrt(d);
00169 }
00170
00171 void bvgl_articulated_poly::print()
00172 {
00173 for (unsigned i = 0; i<joint_transforms_.size(); ++i)
00174 {
00175 vsol_point_2d_sptr p = this->joint_position(i);
00176 vcl_cout << "Joint[" << i << "](" << p->x() << ' ' << p->y()
00177 << ")| " << this->joint_angle(i) << "|\n";
00178 }
00179 }
00180
00181
00182 void bvgl_articulated_poly::print_xforms()
00183 {
00184 for (unsigned i = 0; i<joint_transforms_.size(); ++i)
00185 vcl_cout << "T[" << i << "]=>\n" << joint_transforms_[i] << '\n';
00186 }
00187
00188 bvgl_articulated_poly_sptr bvgl_articulated_poly::
00189 projection(bvgl_articulated_poly_sptr const& target,
00190 vcl_vector<double > const& manifold_basis)
00191 {
00192
00193 unsigned n = target->size();
00194 vcl_vector<double> links(n-1);
00195 for (unsigned i = 0; i+1<n; ++i)
00196 links[i]=target->link_length(i);
00197
00198 bvgl_articulated_poly_sptr manifold = new bvgl_articulated_poly(n, links);
00199 double d = vnl_numeric_traits<double>::maxval, tmin=0;
00200 for (double t = - 3.0; t<=3.0; t+=0.05)
00201 {
00202 manifold->sub_manifold_transform(t, manifold_basis);
00203 double dt = bvgl_articulated_poly::lie_distance(*manifold, *target);
00204 if (dt<d)
00205 {
00206 d = dt;
00207 tmin = t;
00208 }
00209
00210 manifold->sub_manifold_transform(-t, manifold_basis);
00211 }
00212 manifold->sub_manifold_transform(tmin, manifold_basis);
00213 return manifold;
00214 }