00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef TANGENT_STATE_H
00017 #define TANGENT_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_moore_penrose_pseudoinverse.h>
00025 #include <iostream>
00026
00044 template <class observation_type>
00045 class tangent_state : public angle_state<observation_type>
00046 {
00047 public:
00048 tangent_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 double predict (const observation_type &observation, const double variance_scale = 1.0)
00091 {
00092 const double std [] = {0.019905, 0.003157, 0.008050, 0.180706, 0.101031, 0.137931,
00093 0.275119, 0.182599, 0.286416, 0.275119, 0.182599, 0.286416,
00094 0.390496, 0.301062, 0.483356, 0.508283, 0.808703, 0.806479,
00095 0.275119, 0.182599, 0.286416, 0.381652, 0.255074, 0.218130,
00096 0.498532, 0.249264, 0.615678, 0.938598, 0.593349, 1.098928,
00097 0.275119, 0.182599, 0.286416, 0.509799, 0.464794, 0.370578,
00098 0.988121, 0.796506, 0.450776, 1.155469, 1.320700, 0.709060};
00099
00100 this->compute_pose ();
00101 for (chain_iter iter = this->solver.chain_begin (); iter != this->solver.chain_end (); iter++)
00102 iter->p_global () = iter->get_end_effector ()->absolute ().T ();
00103
00104 matrix_type J;
00105 compute_jacobian (this->solver.chain_begin (), this->solver.chain_end (),
00106 this->bone_begin (), this->bone_end (), J);
00107
00108 matrix_type Jpinv;
00109 OpenTissue::math::big::svd_moore_penrose_pseudoinverse (J, Jpinv);
00110
00111 gaussian1D g;
00112 matrix_type x (Jpinv.size2 (), 1);
00113
00114 for (size_t k = 0; k < J.size1 (); k++)
00115 x (k, 0) = 0.25 * std [k] * g.random ();
00116
00117 matrix_type T = prod (Jpinv, x);
00118 for (size_t k = 0; k < T.size1 (); k++)
00119 this->theta (k) += T (k, 0);
00120
00121 skeleton_state<observation_type>::project_limits ();
00122
00123 return 0;
00124 };
00125
00126 tangent_state& operator= (tangent_state &new_state)
00127 {
00128 angle_state<observation_type>::operator= (new_state);
00129
00130 return *this;
00131 };
00132
00133 bool load (const std::string filename)
00134 {
00135 return angle_state<observation_type>::load (filename);
00136 };
00137
00138 bool load (std::ifstream &file)
00139 {
00140 return angle_state<observation_type>::load (file);
00141 };
00142
00143 private:
00144 const double pred_noise;
00145 };
00146
00147 #endif // TANGENT_STATE_H