00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef SKELETON_STATE_H
00027 #define SKELETON_STATE_H
00028
00029
00030
00031
00032 #include "state.h"
00033 #include "bone_appearance.h"
00034 #include "options.h"
00035 #include "math_types.h"
00036 #include "calibration.h"
00037 #include "auxil.h"
00038 #include "ellipsoid.h"
00039
00040 #include <OpenTissue/kinematics/skeleton/io/skeleton_cal3d_xml_read.h>
00041 #include <OpenTissue/kinematics/skeleton/skeleton_types.h>
00042 #include <OpenTissue/kinematics/inverse/inverse.h>
00043 #include <OpenTissue/core/math/math_basic_types.h>
00044 #include <OpenTissue/core/containers/grid/grid.h>
00045 #include <OpenTissue/core/containers/mesh/mesh.h>
00046 #include <OpenTissue/core/containers/grid/util/grid_idx2coord.h>
00047
00048
00049
00050 typedef OpenTissue::kinematics::inverse::BoneTraits <bone_appearance> bone_traits;
00051 typedef OpenTissue::skeleton::Types <math_types, bone_traits> skeleton_types;
00052
00053 typedef skeleton_types::skeleton_type skeleton_type;
00054 typedef skeleton_types::bone_type bone_type;
00055 typedef OpenTissue::kinematics::inverse::NonlinearSolver <skeleton_type> solver_type;
00056
00057 typedef skeleton_type::bone_iterator bone_iter;
00058 typedef skeleton_type::const_bone_iterator const_bone_iter;
00059 typedef solver_type::chain_iterator chain_iter;
00060 typedef solver_type::chain_type chain_type;
00061 typedef solver_type::const_chain_iterator const_chain_iter;
00062 typedef solver_type::matrix_type matrix_type;
00063 typedef solver_type::vector_type vector_type;
00064
00065
00066
00067
00068
00069
00070
00071 typedef OpenTissue::grid::Grid<float ,math_types> grid_type;
00072 typedef OpenTissue::trimesh::TriMesh<> mesh_type;
00073
00078 template <class observation_type>
00079 class skeleton_state : public state<observation_type>
00080 {
00081 public:
00093 skeleton_state (const options &opts, const calibration &_calib, const bool _for_show = true)
00094 : calib (_calib),
00095 root (0, 0, 0),
00096 cam (calib.camera_centre ()),
00097 #ifdef WITH_LINE
00098 line_offset (1),
00099 #else
00100 line_offset (0),
00101 #endif
00102 for_show (_for_show)
00103 {
00104
00105 OpenTissue::skeleton::cal3d_xml_read (opts.skeleton_xsf (), skeleton);
00106
00107 OpenTissue::kinematics::inverse::set_default_joint_settings (skeleton);
00108 skeleton.set_bind_pose ();
00109
00110 #ifndef ONE_BONE
00111 set_joint_types ();
00112 #endif // ! ONE_BONE
00113
00114
00115 solver.init (skeleton);
00116 solver.chain_begin ()->only_position () = true;
00117
00118 OpenTissue::kinematics::inverse::get_joint_parameters (skeleton, theta);
00119 load (opts.initial_pose ());
00120
00121 try
00122 {
00123 limits_file = opts.joint_limits ();
00124 }
00125 catch (missing_option)
00126 {
00127 limits_file = "";
00128 }
00129 set_joint_limits ();
00130
00131
00132 std::ifstream file (opts.bone_appearance ().c_str ());
00133 if (!file.is_open ())
00134 {
00135 std::cerr << "skeleton_state::skeleton_state: could not open '"
00136 << opts.bone_appearance () << "' for reading." << std::endl;
00137 }
00138
00139 for (bone_iter iter = skeleton.begin (); iter != skeleton.end (); iter ++)
00140 {
00141 if (!iter->is_root ())
00142 {
00143 std::string name;
00144 file >> name;
00145 iter->set_name (name);
00146
00147 double width;
00148 file >> width;
00149
00150 const vector3 a = iter->absolute ().T ();
00151 const vector3 b = iter->parent ()->absolute ().T ();
00152 const double length = sqrt ((a-b)*(a-b));
00153
00154 iter->set_size (width, length);
00155 }
00156 }
00157 file.close ();
00158
00159
00160 OpenTissue::kinematics::inverse::get_joint_limits (skeleton, min_limits, max_limits);
00161
00162 if (for_show)
00163 prepare_mesh ();
00164 };
00165
00169 void prepare_mesh ()
00170 {
00171
00172
00173 vector3 bb_min = skeleton.begin ()->absolute ().T ();
00174 vector3 bb_max = bb_min;
00175 for (const_bone_iter iter = skeleton.begin (); iter != skeleton.end (); iter++)
00176 {
00177 const vector3 p = iter->absolute ().T ();
00178 for (size_t k = 0; k < 3; k++)
00179 {
00180 bb_min [k] = std::min (bb_min [k], p [k]-1);
00181 bb_max [k] = std::max (bb_max [k], p [k]+1);
00182 }
00183 }
00184
00185 const size_t grid_size = 32;
00186 grid.create (bb_min, bb_max, grid_size, grid_size, grid_size);
00187 for (size_t k = 0; k < grid_size ; k++)
00188 for (size_t j = 0; j < grid_size; j++)
00189 for (size_t i = 0; i < grid_size; i++)
00190 grid (i, j, k) = 0;
00191
00192 for (const_bone_iter iter = skeleton.begin (); iter != skeleton.end (); iter++)
00193 {
00194 if (!iter->is_root () && !iter->parent ()->is_root ())
00195 {
00196 ellipsoid E;
00197 if (bone_to_ellipsoid (iter, E))
00198 {
00199 for (size_t k = 0; k < grid_size ; k++)
00200 for (size_t j = 0; j < grid_size; j++)
00201 for (size_t i = 0; i < grid_size; i++)
00202 {
00203 vector3 coord, p;
00204 double N;
00205 OpenTissue::grid::idx2coord (grid, i, j, k, coord);
00206 E.project_point (coord, p, N);
00207
00208 const double dist2 = E.euc_mahalanobis2 (coord, p);
00209 const float radial = (N > 1.0) ? exp (-dist2*1) : 1.0;
00210 grid (i, j, k) += radial;
00211 }
00212
00213 }
00214 }
00215 }
00216 OpenTissue::mesh::smooth_isosurface (grid, 0.9, isosurface);
00217 }
00218
00231 bool bone_to_ellipsoid (const_bone_iter &bone, ellipsoid &E) const
00232 {
00233 const vector3 absolute = bone->absolute ().T () - root;
00234 const vector3 pabsolute = bone->parent ()->absolute ().T () - root;
00235 const vector3 C = 0.5 * (absolute + pabsolute);
00236
00237 const double rx = 0.8 * bone->get_width ();
00238
00239 const OpenTissue::math::CoordSys<double> coord_sys = bone->parent ()->absolute ();
00240 vector3 a0 = absolute - C;
00241 const double ry = norm (a0);
00242
00243 if (ry > 0.1)
00244 {
00245 const double rz = (bone->get_number () < 5) ? 0.5 * rx : rx;
00246
00247 vector3 x (1.0, 0.0, 0.0);
00248 vector3 y (0.0, 1.0, 0.0);
00249 vector3 z (0.0, 0.0, 1.0);
00250 coord_sys.xform_vector (x);
00251 coord_sys.xform_vector (y);
00252 coord_sys.xform_vector (z);
00253
00254 E.init (C, x, y, z, rx, ry, rz);
00255
00256 return true;
00257 }
00258 else
00259 {
00260 return false;
00261 }
00262 }
00263
00270 void show (const double gray_level = 0.25) const
00271 {
00272 glPushMatrix ();
00273 glTranslatef (root (0), root (1), root (2));
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 for (const_bone_iter iter = skeleton.begin (); iter != skeleton.end (); iter++)
00296 {
00297 if (!iter->is_root () && !iter->parent ()->is_root ())
00298 {
00299 OpenTissue::gl::DrawStickBone (*iter, gray_level, 0, 0);
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 }
00322 }
00323
00324 if (for_show)
00325 {
00326 OpenTissue::gl::ColorPicker (1.0, 0.3, 0.0);
00327
00328 OpenTissue::gl::DrawMesh (isosurface, GL_LINE_LOOP);
00329
00330 }
00331
00332 glPopMatrix ();
00333 }
00334
00339 void make_every_bone_an_end_effector ()
00340 {
00341 this->compute_pose ();
00342
00343
00344 for (bone_iter iter = this->bone_begin (); iter != this->bone_end (); iter++)
00345 {
00346 if (iter->is_root ())
00347 continue;
00348
00349 chain_type chain;
00350 chain.init (this->skeleton.root (), &(*iter));
00351 this->solver.add_chain (chain);
00352 }
00353 }
00354
00359 size_t count_num_end_effectors () const
00360 {
00361 size_t retval = 0;
00362 for (const_chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00363 retval++;
00364 return retval;
00365 }
00366
00373 void save (const std::string filename) const
00374 {
00375 std::ofstream file (filename.c_str ());
00376 if (!file.is_open ())
00377 std::cerr << "skeleton_state::save: could not save to " << filename
00378 << std::endl;
00379 else
00380 {
00381 save (file);
00382 file.close ();
00383 }
00384 };
00385
00392 void save (std::ofstream &file) const
00393 {
00394 for (size_t k = 0; k < 3; k++)
00395 file << root [k] << " ";
00396 for (size_t k = 0; k < theta.size (); k++)
00397 file << theta [k] << " ";
00398 file << std::endl;
00399 };
00400
00410 bool load (const std::string filename)
00411 {
00412 bool success = false;
00413 std::ifstream file (filename.c_str ());
00414 if (!file.is_open ())
00415 std::cerr << "skeleton_state::load: could not open " << filename << std::endl;
00416 else
00417 {
00418 success = load (file);
00419 file.close ();
00420 }
00421
00422 return success;
00423 };
00424
00434 bool load (std::ifstream &file)
00435 {
00436
00437 for (size_t k = 0; k < 3; k++)
00438 file >> root [k];
00439 for (size_t k = 0; k < theta.size (); k++)
00440 file >> theta [k];
00441
00442
00443 compute_pose ();
00444
00445 return true;
00446 };
00447
00451 inline
00452 void compute_pose ()
00453 {
00454
00455 OpenTissue::kinematics::inverse::set_joint_parameters (skeleton, theta);
00456 OpenTissue::kinematics::inverse::get_joint_parameters (skeleton, theta);
00457 skeleton.compute_pose ();
00458 };
00459
00463 skeleton_state& operator= (skeleton_state &new_state)
00464 {
00465 theta.resize (new_state.theta.size ());
00466 for (size_t k = 0; k < theta.size (); k++)
00467 theta [k] = new_state.theta [k];
00468
00469 root = new_state.root;
00470
00471 return *this;
00472 };
00473
00480 inline
00481 solver_type::vector_type& get_theta ()
00482 {
00483 return theta;
00484 };
00485
00492 inline
00493 const solver_type::vector_type& get_theta () const
00494 {
00495 return theta;
00496 };
00497
00507 inline
00508 double get_theta (const int idx) const
00509 {
00510 return theta [idx];
00511 };
00512
00519 inline
00520 void set_theta (const solver_type::vector_type &new_theta)
00521 {
00522 for (size_t k = 0; k < new_theta.size (); k++)
00523 theta [k] = new_theta [k];
00524 };
00525
00535 inline
00536 void set_theta (const int idx, const double val)
00537 {
00538 theta [idx] = val;
00539 };
00540
00545 inline
00546 int theta_size () const
00547 {
00548 return theta.size ();
00549 };
00550
00555 inline
00556 skeleton_type& get_skeleton ()
00557 {
00558 return skeleton;
00559 };
00560
00565 inline
00566 const skeleton_type& get_skeleton () const
00567 {
00568 return skeleton;
00569 };
00570
00580 inline
00581 double get_min_limit (unsigned int idx) const
00582 {
00583 return min_limits [idx];
00584 };
00585
00595 inline
00596 double get_max_limit (unsigned int idx) const
00597 {
00598 return max_limits [idx];
00599 };
00600
00604 inline
00605 void project_limits ()
00606 {
00607 OpenTissue::kinematics::inverse::compute_joint_limits_projection (skeleton, theta);
00608 };
00609
00614 inline
00615 const vector3& get_root () const
00616 {
00617 return root;
00618 };
00619
00626 inline
00627 void set_root (vector3 &new_root)
00628 {
00629 for (int k = 0; k < 3; k++)
00630 root (k) = new_root (k);
00631 };
00632
00637 inline
00638 bone_iter bone_begin ()
00639 {
00640 return skeleton.begin ();
00641 };
00642
00647 inline
00648 bone_iter bone_end ()
00649 {
00650 return skeleton.end ();
00651 };
00652
00657 inline
00658 const_bone_iter bone_begin () const
00659 {
00660 return skeleton.begin ();
00661 };
00662
00667 inline
00668 const_bone_iter bone_end () const
00669 {
00670 return skeleton.end ();
00671 };
00672
00677 inline
00678 solver_type& get_solver ()
00679 {
00680 return solver;
00681 }
00682
00687 inline
00688 const mesh_type& get_mesh () const
00689 {
00690 return isosurface;
00691 }
00692
00693 private:
00694 void set_joint_types ()
00695 {
00696
00697 skeleton.get_bone (9+line_offset)->type () = bone_type::bone_traits::hinge_type;
00698 skeleton.get_bone (13+line_offset)->type () = bone_type::bone_traits::hinge_type;
00699
00700
00701 if (skeleton.size () > 16)
00702 {
00703 skeleton.get_bone (17+line_offset)->type () = bone_type::bone_traits::hinge_type;
00704 skeleton.get_bone (18+line_offset)->type () = bone_type::bone_traits::hinge_type;
00705 skeleton.get_bone (22+line_offset)->type () = bone_type::bone_traits::hinge_type;
00706 skeleton.get_bone (23+line_offset)->type () = bone_type::bone_traits::hinge_type;
00707 }
00708 };
00709
00710 void set_joint_limits ()
00711 {
00712
00713 #define GENERAL_PURPOSE_LIMITS
00714
00715
00716
00717
00718 #ifdef PELVIS_LIMITS
00719 #ifdef STICKS
00720 const double default_delta = 0.3;
00721 #else
00722 const double default_delta = 0.2;
00723 #endif // STICKS
00724
00725
00726 size_t idx = line_offset;
00727 bone_iter iter = skeleton.begin ();
00728 for (size_t n = 0; n < line_offset; n++) iter++;
00729
00730 for ( ; iter != skeleton.end (); iter ++)
00731 {
00732
00733 for (size_t k = 0; k < iter->active_dofs (); k++)
00734 {
00735 if (idx == 4+line_offset)
00736 {
00737 iter->min_joint_limit (k) = -0.1;
00738 iter->max_joint_limit (k) = 0.7;
00739 }
00740 else if (idx == 13+line_offset)
00741 {
00742 iter->min_joint_limit (k) = 1.5;
00743 iter->max_joint_limit (k) = 2.5;
00744 }
00745 else if (idx <= 40+line_offset)
00746 {
00747 iter->min_joint_limit (k) = iter->theta (k) - default_delta;
00748 iter->max_joint_limit (k) = iter->theta (k) + default_delta;
00749 }
00750 else
00751 {
00752 iter->min_joint_limit (k) = iter->theta (k) - 4.0 * default_delta;
00753 iter->max_joint_limit (k) = iter->theta (k) + 4.0 * default_delta;
00754 }
00755 idx ++;
00756 }
00757 }
00758 #endif // PELVIS_LIMITS
00759
00760 #ifdef GENERAL_PURPOSE_LIMITS
00761 const double default_delta = 0.1;
00762
00763
00764
00765 bone_iter iter = skeleton.begin ();
00766 for (size_t n = 0; n < line_offset; n++)
00767 iter++;
00768
00769 size_t idx = line_offset;
00770 for ( ; iter != skeleton.end (); iter ++)
00771 {
00772
00773 for (unsigned int k = 0; k < iter->active_dofs (); k++)
00774 {
00775
00776
00777
00778
00779
00780
00781
00782 {
00783 iter->min_joint_limit (k) = iter->theta (k) - default_delta;
00784 iter->max_joint_limit (k) = iter->theta (k) + default_delta;
00785 }
00786 }
00787
00788 idx++;
00789 }
00790
00791
00792
00793 #ifdef FULL_BODY
00794 skeleton.get_bone (8+line_offset)->min_joint_limit (0) = -2.0;
00795 skeleton.get_bone (8+line_offset)->max_joint_limit (0) = 0.0;
00796 skeleton.get_bone (8+line_offset)->min_joint_limit (1) = -0.5;
00797 skeleton.get_bone (8+line_offset)->max_joint_limit (1) = 2.3;
00798 skeleton.get_bone (8+line_offset)->min_joint_limit (2) = -0.5;
00799 skeleton.get_bone (8+line_offset)->max_joint_limit (2) = 2.0;
00800
00801
00802 skeleton.get_bone (9+line_offset)->min_joint_limit (0) = -0.1;
00803 skeleton.get_bone (9+line_offset)->max_joint_limit (0) = 2.6;
00804
00805
00806 skeleton.get_bone (12+line_offset)->min_joint_limit (0) = -3.1;
00807 skeleton.get_bone (12+line_offset)->max_joint_limit (0) = -1.1;
00808 skeleton.get_bone (12+line_offset)->min_joint_limit (1) = -0.5;
00809 skeleton.get_bone (12+line_offset)->max_joint_limit (1) = 2.3;
00810 skeleton.get_bone (12+line_offset)->min_joint_limit (2) = 2.0;
00811 skeleton.get_bone (12+line_offset)->max_joint_limit (2) = 4.1;
00812
00813
00814 skeleton.get_bone (13+line_offset)->min_joint_limit (0) = -2.6;
00815 skeleton.get_bone (13+line_offset)->max_joint_limit (0) = 0.1;
00816 #endif // FULL_BODY
00817
00818
00819 #ifndef FULL_BODY
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 skeleton.get_bone (7+line_offset)->min_joint_limit (0) = -1.2;
00850 skeleton.get_bone (7+line_offset)->max_joint_limit (0) = -0.5;
00851 skeleton.get_bone (7+line_offset)->min_joint_limit (1) = 2.8;
00852 skeleton.get_bone (7+line_offset)->max_joint_limit (1) = 4.3;
00853 skeleton.get_bone (7+line_offset)->min_joint_limit (2) = 0.2;
00854 skeleton.get_bone (7+line_offset)->max_joint_limit (2) = 1.2;
00855
00856 skeleton.get_bone (8+line_offset)->min_joint_limit (0) = -0.4;
00857 skeleton.get_bone (8+line_offset)->max_joint_limit (0) = 1.7;
00858 skeleton.get_bone (8+line_offset)->min_joint_limit (1) = -3.0;
00859 skeleton.get_bone (8+line_offset)->max_joint_limit (1) = -0.8;
00860 skeleton.get_bone (8+line_offset)->min_joint_limit (2) = -0.5;
00861 skeleton.get_bone (8+line_offset)->max_joint_limit (2) = 1.2;
00862
00863
00864 skeleton.get_bone (9+line_offset)->min_joint_limit (0) = 0;
00865 skeleton.get_bone (9+line_offset)->max_joint_limit (0) = 2.7;
00866
00867
00868 skeleton.get_bone (11+line_offset)->min_joint_limit (0) = -1.8;
00869 skeleton.get_bone (11+line_offset)->max_joint_limit (0) = -1.0;
00870 skeleton.get_bone (11+line_offset)->min_joint_limit (1) = -1.1;
00871 skeleton.get_bone (11+line_offset)->max_joint_limit (1) = 1.1;
00872 skeleton.get_bone (11+line_offset)->min_joint_limit (2) = 2.0;
00873 skeleton.get_bone (11+line_offset)->max_joint_limit (2) = 3.5;
00874
00875 skeleton.get_bone (12+line_offset)->min_joint_limit (0) = -6.6;
00876 skeleton.get_bone (12+line_offset)->max_joint_limit (0) = -5.2;
00877
00878
00879 skeleton.get_bone (12+line_offset)->min_joint_limit (1) = -3.6;
00880 skeleton.get_bone (12+line_offset)->max_joint_limit (1) = -0.8;
00881 skeleton.get_bone (12+line_offset)->min_joint_limit (2) = -2.9;
00882 skeleton.get_bone (12+line_offset)->max_joint_limit (2) = 0.6;
00883
00884
00885 skeleton.get_bone (13+line_offset)->min_joint_limit (0) = -2.5;
00886 skeleton.get_bone (13+line_offset)->max_joint_limit (0) = 0.0;
00887
00888 #endif // !FULL_BODY
00889 #endif // GENERAL_PURPOSE_LIMITS
00890
00891 #ifdef FILE_BASED
00892 std::ifstream file (limits_file.c_str ());
00893 if (!file.is_open ())
00894 {
00895 std::cerr << "skeleton_state::set_joint_limits: could not open '"
00896 << limits_file << "' for reading." << std::endl;
00897
00898 for (bone_iter iter = skeleton.begin (); iter != skeleton.end (); iter ++)
00899 {
00900 for (size_t k = 0; k < iter->active_dofs (); k++)
00901 {
00902 iter->min_joint_limit (k) = iter->theta (k) - 100000.0;
00903 iter->max_joint_limit (k) = iter->theta (k) + 100000.0;
00904 }
00905 }
00906 }
00907 else
00908 {
00909 for (bone_iter iter = skeleton.begin (); iter != skeleton.end (); iter ++)
00910 {
00911 for (size_t k = 0; k < iter->active_dofs (); k++)
00912 {
00913 double min_limit, max_limit;
00914 file >> min_limit;
00915 file >> max_limit;
00916
00917 iter->min_joint_limit (k) = min_limit;
00918 iter->max_joint_limit (k) = max_limit;
00919 }
00920 }
00921 file.close ();
00922 }
00923 #endif // FILE_BASED
00924 }
00925
00926 void draw_cylinder (const vector3 &a, const vector3 &b, const double radius) const
00927 {
00928
00929
00930 const double delta_t = M_PI / 10.0;
00931 const vector3 v1 = a - b;
00932 const vector3 ab2 = b + v1 / 2.0 - cam;
00933 const vector3 v2 = unit (v1 % ab2);
00934
00935 glBegin (GL_QUADS);
00936 const matrix3 Rt = OpenTissue::math::Ru (delta_t, v1);
00937 vector3 Rv2 = radius * v2;
00938
00939 for (double t = 0; t <= M_PI; t += delta_t)
00940
00941 {
00942 glNormal3f (Rv2 (0), Rv2 (1), Rv2 (2));
00943
00944 const vector3 a1 = a + Rv2;
00945 const vector3 b1 = b + Rv2;
00946 glVertex3f (a1 (0), a1 (1), a1 (2));
00947 glVertex3f (b1 (0), b1 (1), b1 (2));
00948
00949 Rv2 = Rt * Rv2;
00950
00951 const vector3 b2 = b + Rv2;
00952 const vector3 a2 = a + Rv2;
00953 glVertex3f (b2 (0), b2 (1), b2 (2));
00954 glVertex3f (a2 (0), a2 (1), a2 (2));
00955
00956
00957
00958 }
00959 glEnd ();
00960 };
00961
00962 protected:
00963 const calibration calib;
00964 solver_type::vector_type theta, min_limits, max_limits;
00965 skeleton_type skeleton;
00966 vector3 root;
00967 solver_type solver;
00968 const vector3 cam;
00969 const size_t line_offset;
00970 mesh_type isosurface;
00971 grid_type grid;
00972 const bool for_show;
00973 std::string limits_file;
00974 };
00975
00976
00977 #endif // SKELETON_STATE_H