00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef BROWNIAN_STATE_H
00017 #define BROWNIAN_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 <boost/numeric/ublas/banded.hpp>
00026 #include <boost/numeric/ublas/io.hpp>
00027 #include <iostream>
00028
00042 template <class observation_type>
00043 class brownian_state : public angle_state<observation_type>
00044 {
00045 public:
00046 typedef boost::numeric::ublas::diagonal_matrix<double> diagonal_matrix_type;
00047
00048 brownian_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 {
00052 this->compute_pose ();
00053
00054
00055 std::list<vector3> chain_list;
00056 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00057 chain_list.push_back (iter->get_end_effector ()->absolute ().T ());
00058
00059
00060 int i = 0;
00061 for (bone_iter iter = this->bone_begin (); iter != this->bone_end (); iter++, i++)
00062 {
00063 if (iter->is_root ())
00064 continue;
00065
00066 const vector3 absolute = iter->absolute ().T ();
00067 const vector3 pabsolute = iter->parent ()->absolute ().T ();
00068
00069
00070 bool accept = true;
00071 for (std::list<vector3>::const_iterator ci = chain_list.begin ();
00072 ci != chain_list.end (); ci ++)
00073 {
00074 if (*ci == absolute)
00075 {
00076 accept = false;
00077 break;
00078 }
00079 }
00080
00081 if (accept)
00082 {
00083 chain_type chain;
00084 chain.init (this->skeleton.root (), &(*iter));
00085 this->solver.add_chain (chain);
00086 }
00087 }
00088
00089
00090 dim = 0;
00091 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00092 dim += 3;
00093
00094 initial_pose.resize (dim);
00095 int k = 0;
00096 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00097 {
00098 const vector3 e = iter->get_end_effector ()->absolute ().T ();
00099 for (size_t n = 0; n < 3; n++)
00100 initial_pose (k++) = e (n);
00101 }
00102 }
00103
00104 private:
00105 void jacobian (matrix_type &J)
00106 {
00107 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00108 iter->p_global () = iter->get_end_effector ()->absolute ().T ();
00109
00110 compute_jacobian (this->solver.chain_begin (), this->solver.chain_end (),
00111 this->bone_begin (), this->bone_end (), J);
00112 }
00113
00114 void current_pos (vector_type &x)
00115 {
00116 int idx = 0;
00117 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00118 {
00119 vector3 local_x = iter->get_end_effector ()->absolute ().T ();
00120 for (int d = 0; d < 3; d++)
00121 x (idx++) = local_x (d) + this->root (d);
00122 }
00123 }
00124
00125 void project (vector_type &x)
00126 {
00127 int idx = 0;
00128 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00129 {
00130 vector3 local_x;
00131 for (int d = 0; d < 3; d++)
00132 local_x (d) = x (idx++);
00133
00134 iter->p_global () = local_x - this->root;
00135
00136
00137 }
00138
00139 solver_type::Output output;
00140 this->solver.solve (&solver_type::default_SD_settings (), &output);
00141 OpenTissue::kinematics::inverse::get_joint_parameters (*(this->solver.skeleton ()),
00142 this->theta);
00143
00144 }
00145
00146 public:
00147
00148 double predict (const observation_type &observation, const double variance_scale = 1.0)
00149 {
00150 const double std [] = {0.019905, 0.003157, 0.008050, 0.180706, 0.101031, 0.137931,
00151 0.275119, 0.182599, 0.286416, 0.275119, 0.182599, 0.286416,
00152 0.390496, 0.301062, 0.483356, 0.508283, 0.808703, 0.806479,
00153 0.275119, 0.182599, 0.286416, 0.381652, 0.255074, 0.218130,
00154 0.498532, 0.249264, 0.615678, 0.938598, 0.593349, 1.098928,
00155 0.275119, 0.182599, 0.286416, 0.509799, 0.464794, 0.370578,
00156 0.988121, 0.796506, 0.450776, 1.155469, 1.320700, 0.709060};
00157
00158 const int num_time_steps = 10;
00159 const double normalisation = sqrt ((double)num_time_steps);
00160
00161 matrix_type J;
00162 ublas::matrix<double> U, V, UUT;
00163 vector_type S, W1 (dim), W2 (dim), incr1 (dim), incr2 (dim), x (dim), x_tmp (dim);
00164 diagonal_matrix_type Sd;
00165
00166 gaussian1D g;
00167
00168
00169
00170 for (int time_step = 0; time_step < num_time_steps; time_step++)
00171 {
00172
00173 for (size_t k = 0; k < dim; )
00174 {
00175 for (size_t n = 0; n < 3; n++, k++)
00176 {
00177 const double s = std [k] / normalisation;
00178 W1 (k) = s * g.random ();
00179 W2 (k) = s * g.random ();
00180 }
00181 const double s = ((k >= 21) ? 3.0 * pred_noise : pred_noise) / normalisation;
00182 for (size_t n = 0; n < 3; n++, k++)
00183 {
00184 W1 (k) = s * g.random ();
00185 W2 (k) = s * g.random ();
00186 }
00187 }
00188
00189
00190 this->compute_pose ();
00191 current_pos (x);
00192
00193
00194 jacobian (J);
00195 OpenTissue::math::big::svd (J, U, S, V);
00196 if (Sd.size1 () == 0)
00197 Sd.resize (S.size (), S.size ());
00198 Sd.clear ();
00199 for (size_t i = 0; i < S.size (); i++)
00200 Sd (i, i) = (S (i) > 1e-9) ? 1.0 : 0.0;
00201 U = prod (U, Sd);
00202 UUT = prod (U, trans (U));
00203
00204
00205 incr1 = prod (UUT, W1);
00206
00207
00208 incr2 = prod (UUT, W2);
00209 x_tmp = x + incr2;
00210 project (x_tmp);
00211 jacobian (J);
00212 OpenTissue::math::big::svd (J, U, S, V);
00213
00214
00215 Sd.clear ();
00216 for (size_t i = 0; i < S.size (); i++)
00217 Sd (i, i) = (S (i) > 1e-9) ? 1.0 : 0.0;
00218
00219 U = prod (U, Sd);
00220 UUT = prod (U, trans (U));
00221 incr2 = prod (UUT, W1);
00222
00223
00224 x = x + 0.5 * (incr1 + incr2);
00225 project (x);
00226 }
00227
00228 return 0;
00229 }
00230
00231 brownian_state& operator= (brownian_state &new_state)
00232 {
00233 angle_state<observation_type>::operator= (new_state);
00234 dim = new_state.dim;
00235
00236 return *this;
00237 }
00238
00239 bool load (const std::string filename)
00240 {
00241 return angle_state<observation_type>::load (filename);
00242 }
00243
00244 bool load (std::ifstream &file)
00245 {
00246 return angle_state<observation_type>::load (file);
00247 }
00248
00249 private:
00250 const double pred_noise;
00251 size_t dim;
00252 vector_type initial_pose;
00253 };
00254
00255 #endif // BROWNIAN_STATE_H