• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

/home/hauberg/Dokumenter/Capture/humim-tracker-0.1/src/angle_state.h

Go to the documentation of this file.
00001 // Copyright (C) 2011 Soren Hauberg
00002 //
00003 // This program is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU General Public License
00005 // as published by the Free Software Foundation; either version 3
00006 // of the License, or (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful, but
00009 // WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00015  
00016 #ifndef ANGLE_STATE_H
00017 #define ANGLE_STATE_H
00018 
00019 #include "skeleton_state.h"
00020 #include "options.h"
00021 #include "simulator.h"
00022 
00043 template <class observation_type>
00044 class angle_state : public skeleton_state<observation_type>
00045 {
00046 public:
00047   angle_state (const options &opts, const calibration &_calib, const bool _for_show = true)
00048     : skeleton_state<observation_type> (opts, _calib, _for_show),
00049       pred_noise (opts.pred_noise ()),
00050       noise (0, pred_noise),
00051       extrapolate (opts.extrapolate ())
00052     {
00053       OpenTissue::kinematics::inverse::get_joint_parameters (this->skeleton, prev_theta);
00054       for (size_t k = 0; k < this->theta.size (); k++)
00055         this->prev_theta [k] = this->theta [k];
00056     };
00057 
00058   double predict (const observation_type &observation, const double variance_scale = 1.0)
00059     {
00060       #define HANDS2_NORMAL
00061 
00062       const size_t theta_size = this->theta.size ();
00063 
00064       #ifdef HANDS2_NORMAL
00065       const double std [] = {0.118043, 0.106630, 0.187879, 0.110447, 0.115539, 0.154490,
00066                              0.207707, 0.247319, 0.131030, 0.162429, 0.278345, 0.232262,
00067                              0.129147, 0.201286, 0.169725, 0.257265, 0.350806, 0.163058,
00068                              0.204395, 0.222967, 0.194014, 0.121656, 0.155806, 0.199396,
00069                              0.537728, 0.354365, 0.560878, 0.381538, 0.234784, 0.239393,
00070                              0.179768, 0.161243, 0.181075, 0.184029, 0.904360, 0.797576,
00071                              0.525455, 0.590451, 0.201901, 0.143306, 0.169167};
00072 
00073       gaussian1D gauss;
00074       for (size_t idx = 0; idx < theta_size; idx++)
00075         {
00076           const double min_limit = this->get_min_limit (idx);
00077           const double max_limit = this->get_max_limit (idx);
00078  
00079           // Linear extrapolation
00080           double new_det_val;
00081           if (extrapolate)
00082             {
00083               new_det_val = 2.0 * this->theta [idx] - this->prev_theta [idx];
00084               new_det_val = force_in_range (new_det_val, min_limit, max_limit);
00085             }
00086           else
00087             {
00088               new_det_val = this->theta [idx];
00089             }
00090               
00091           // Rejection sampling from a Von Mises distribution constrained to the
00092           // joint limits
00093           double new_rand_val;
00094           const size_t max_iter = 20;
00095           size_t iter = 1;
00096           do
00097             {
00098               new_rand_val = new_det_val + 0.5 * std [idx] * gauss.random ();
00099               //std::cerr << idx << " " << std [idx] << " " << new_det_val << " " << new_rand_val << " " << max_limit << " " << min_limit << std::endl;
00100               
00101               if (iter++ >= max_iter)
00102                 {
00103                   new_rand_val = new_det_val;
00104                   break;
00105                 }
00106             }
00107           while (new_rand_val > max_limit || new_rand_val < min_limit);
00108     
00109           // Save stuff
00110           this->theta [idx] = new_rand_val;
00111         }
00112     
00113       #endif // HANDS2_NORMAL
00114       
00115       #ifndef HANDS2_NORMAL
00116       for (size_t idx = 0; idx < theta_size; idx++)
00117         {
00118           const double v = (idx == 27 || idx == 37)  ? 250 : 500;
00119           von_mises hack_noise (0, v);
00120     
00121           const double min_limit = this->get_min_limit (idx);
00122           const double max_limit = this->get_max_limit (idx);
00123               
00124           // Linear extrapolation
00125           double new_det_val;
00126           if (extrapolate)
00127             {
00128               new_det_val = 2.0 * this->theta [idx] - this->prev_theta [idx];
00129               new_det_val = force_in_range (new_det_val, min_limit, max_limit);
00130             }
00131           else
00132             {
00133               new_det_val = this->theta [idx];
00134             }
00135               
00136           // Rejection sampling from a Von Mises distribution constrained to the
00137           // joint limits (XXX: should we have a max-limit on the number of iterations?)
00138           double new_rand_val;
00139           do
00140             {
00141               new_rand_val = new_det_val + hack_noise.random ();
00142             }
00143           while (new_rand_val > max_limit || new_rand_val < min_limit);
00144     
00145           // Save stuff
00146           this->prev_theta [idx] = this->theta [idx];
00147           this->theta [idx] = new_rand_val;
00148         }
00149       #endif // !HANDS2_NORMAL
00150   
00151       // Predict root
00152       /*
00153       gaussian1D root_noise (0, 0.1);
00154       for (size_t idx = 0; idx < 3; idx++)
00155         root (idx) += root_noise.random ();
00156       */
00157       
00158       //skeleton_state<observation_type>::compute_pose (); // XXX: Do we need this?
00159 
00160       return 0;
00161     };
00162         
00163   angle_state& operator= (angle_state &new_state)
00164     {
00165       skeleton_state<observation_type>::operator= (new_state);
00166 
00167       for (size_t k = 0; k < this->prev_theta.size (); k++)
00168         this->prev_theta [k] = new_state.prev_theta [k];
00169 
00170       return *this;
00171     };
00172 
00173   bool load (const std::string filename)
00174     {
00175       const bool success = skeleton_state<observation_type>::load (filename);
00176   
00177       for (size_t k = 0; k < this->theta.size (); k++)
00178         this->prev_theta [k] = this->theta [k];
00179   
00180       return success;
00181     };
00182     
00183   bool load (std::ifstream &file)
00184     {
00185       const bool success = skeleton_state<observation_type>::load (file);
00186   
00187       for (size_t k = 0; k < this->theta.size (); k++)
00188         this->prev_theta [k] = this->theta [k];
00189   
00190       return success;
00191     };
00192 
00193 protected:
00194   solver_type::vector_type prev_theta;
00195   const double pred_noise;
00196   const von_mises noise;
00197   const bool extrapolate;
00198 };
00199 
00200 #endif // ANGLE_STATE_H

Generated on Thu Dec 1 2011 12:49:46 for HUMIM Tracker by  doxygen 1.7.1