00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef BROWNIAN_STICK_STATE_H
00017 #define BROWNIAN_STICK_STATE_H
00018
00019 #include "angle_state.h"
00020 #include "options.h"
00021 #include "simulator.h"
00022 #include "auxil.h"
00023
00024 #include <OpenTissue/core/math/big/big_svd.h>
00025 #include <OpenTissue/core/math/math_is_number.h>
00026 #include <boost/numeric/ublas/banded.hpp>
00027 #include <boost/numeric/ublas/io.hpp>
00028 #include <iostream>
00029 template <class observation_type>
00043 class brownian_stick_state : public angle_state<observation_type>
00044 {
00045 public:
00046 typedef boost::numeric::ublas::diagonal_matrix<double> diagonal_matrix_type;
00047
00048 brownian_stick_state (const options &opts, const calibration &_calib, const bool _for_show = true)
00049 : angle_state<observation_type> (opts, _calib, _for_show),
00050 pred_noise (opts.pred_noise ()),
00051 lambda (2)
00052 {
00053 for (unsigned int k = 0; k < lambda.size (); k++)
00054 lambda [k] = NaN;
00055
00056 this->compute_pose ();
00057
00058
00059 std::list<vector3> chain_list;
00060 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00061 chain_list.push_back (iter->get_end_effector ()->absolute ().T ());
00062
00063
00064 int i = 0;
00065 for (bone_iter iter = this->bone_begin (); iter != this->bone_end (); iter++, i++)
00066 {
00067 if (iter->is_root ())
00068 continue;
00069
00070 const vector3 absolute = iter->absolute ().T ();
00071 const vector3 pabsolute = iter->parent ()->absolute ().T ();
00072
00073
00074 bool accept = true;
00075 for (std::list<vector3>::const_iterator ci = chain_list.begin ();
00076 ci != chain_list.end (); ci ++)
00077 {
00078 if (*ci == absolute)
00079 {
00080 accept = false;
00081 break;
00082 }
00083 }
00084
00085 if (accept)
00086 {
00087 chain_type chain;
00088 chain.init (this->skeleton.root (), &(*iter));
00089 this->solver.add_chain (chain);
00090 }
00091 }
00092
00093
00094 dim = 0;
00095 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00096 dim += 3;
00097
00098 }
00099
00100 private:
00101 void jacobian (matrix_type &J)
00102 {
00103 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00104 iter->p_global () = iter->get_end_effector ()->absolute ().T ();
00105
00106 compute_jacobian (this->solver.chain_begin (), this->solver.chain_end (),
00107 this->bone_begin (), this->bone_end (), J);
00108 }
00109
00110 void current_pos (vector_type &x)
00111 {
00112 int idx = 0;
00113 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00114 {
00115 vector3 local_x = iter->get_end_effector ()->absolute ().T ();
00116 for (int d = 0; d < 3; d++)
00117 x (idx++) = local_x (d);
00118 }
00119 }
00120
00121 void project (const vector_type &x)
00122 {
00123 int idx = 0;
00124 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00125 {
00126 vector3 local_x;
00127 for (int d = 0; d < 3; d++)
00128 local_x (d) = x (idx++);
00129
00130 iter->p_global () = local_x;
00131 }
00132
00133 solver_type::Output output;
00134 this->solver.solve (&solver_type::default_SD_settings (), &output);
00135 OpenTissue::kinematics::inverse::get_joint_parameters (*(this->solver.skeleton ()),
00136 this->theta);
00137
00138 }
00139
00140 public:
00141
00142 double predict (const observation_type &observation, const double variance_scale = 1.0)
00143 {
00144 const int num_time_steps = 1;
00145 const double normalisation = sqrt ((double)num_time_steps);
00146
00147 const stick_type stick = observation.get_stick ();
00148
00149 const int num_indices = 2;
00150 const int indices [num_indices+1] = {9, 13, -1};
00151
00152 matrix_type J;
00153 ublas::matrix<double> U, V, UUT;
00154 vector_type S, W1 (dim), W2 (dim), incr1 (dim), incr2 (dim), x (dim), x_tmp (dim);
00155 diagonal_matrix_type Sd;
00156
00157 gaussian1D g;
00158
00159 for (unsigned int i = 0; i < lambda.size (); i++)
00160 {
00161 if (!is_number (lambda [i]))
00162 {
00163
00164 const_chain_iter iter = this->solver.chain_begin ();
00165 int k = 0;
00166 while (k++ != indices [i])
00167 iter ++;
00168 const vector3 hand = iter->get_end_effector ()->absolute ().T ();
00169
00170
00171 double alpha;
00172 const double hand_object_dist2 = dist2 (stick, hand, alpha);
00173 if (sqrt (hand_object_dist2) < T_E)
00174 lambda [i] = alpha;
00175 else
00176 lambda [i] = NaN;
00177 }
00178 else
00179 {
00180
00181
00182
00183
00184
00185
00186
00187
00188 {
00189 gaussian1D G (lambda [i], sigma);
00190 while (true)
00191 {
00192 const double l = G.random ();
00193 if (0.0 <= l && l <= 1.0)
00194 {
00195 lambda [i] = l;
00196 break;
00197 }
00198 }
00199 }
00200 }
00201 }
00202
00203 for (int time_step = 0; time_step < num_time_steps; time_step++)
00204 {
00205
00206 for (int k = 0; k < dim; )
00207 {
00208 const double s = ((k >= 21) ? 3.0 * pred_noise : pred_noise) / normalisation;
00209 for (size_t n = 0; n < 3; n++, k++)
00210 {
00211 W1 (k) = s * g.random ();
00212 W2 (k) = s * g.random ();
00213 }
00214 }
00215
00216
00217 this->compute_pose ();
00218 current_pos (x);
00219
00220
00221 jacobian (J);
00222 OpenTissue::math::big::svd (J, U, S, V);
00223 if (Sd.size1 () == 0)
00224 Sd.resize (S.size (), S.size ());
00225 Sd.clear ();
00226 for (size_t i = 0; i < S.size (); i++)
00227 Sd (i, i) = (S (i) > 1e-9) ? 1.0 : 0.0;
00228 U = prod (U, Sd);
00229 UUT = prod (U, trans (U));
00230
00231
00232 incr1 = prod (UUT, W1);
00233
00234
00235 incr2 = prod (UUT, W2);
00236 x_tmp = x + incr2;
00237 project (x_tmp);
00238 jacobian (J);
00239 OpenTissue::math::big::svd (J, U, S, V);
00240
00241
00242 Sd.clear ();
00243 for (size_t i = 0; i < S.size (); i++)
00244 Sd (i, i) = (S (i) > 1e-9) ? 1.0 : 0.0;
00245
00246 U = prod (U, Sd);
00247 UUT = prod (U, trans (U));
00248 incr2 = prod (UUT, W1);
00249
00250
00251 x = x + 0.5 * (incr1 + incr2);
00252
00253
00254 size_t i = 0;
00255 for (int k = 0; k < dim; k += 3)
00256 {
00257 if (k == 3*indices [i] && is_number (lambda [i]))
00258 {
00259 const vector3 nu = nearest_point_on_stick (stick, lambda [i]);
00260 i++;
00261 for (size_t n = 0; n < 3; n++)
00262 x (k+n) = nu (n);
00263 }
00264 }
00265
00266 project (x);
00267 }
00268
00269 return 0;
00270 }
00271
00272 brownian_stick_state& operator= (brownian_stick_state &new_state)
00273 {
00274 angle_state<observation_type>::operator= (new_state);
00275 dim = new_state.dim;
00276
00277 return *this;
00278 }
00279
00280 bool load (const std::string filename)
00281 {
00282 return angle_state<observation_type>::load (filename);
00283 }
00284
00285 bool load (std::ifstream &file)
00286 {
00287 return angle_state<observation_type>::load (file);
00288 }
00289
00290 private:
00291 const double pred_noise;
00292 int dim;
00293 std::vector<double> lambda;
00294 static const double p_letgo = 0.05, T_E = 1.0, sigma = 0.0001;
00295 };
00296
00297 #endif // BROWNIAN_STICK_STATE_H