Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef KBK_STICK_STATE_H
00017 #define KBK_STICK_STATE_H
00018
00019 #include "angle_state.h"
00020 #include "options.h"
00021 #include "simulator.h"
00022 #include "cloud_and_stick.h"
00023
00024 #include <vector>
00025 #include <limits>
00026 #include <OpenTissue/core/math/math_is_number.h>
00027
00028 #define NaN std::numeric_limits<double>::quiet_NaN ()
00029
00041 template <class observation_type>
00042 class KBK_stick_state : public angle_state<observation_type>
00043 {
00044 public:
00045 KBK_stick_state (const options &opts, const calibration &_calib, const bool _for_show = true)
00046 : angle_state<observation_type> (opts, _calib, _for_show),
00047 lambda (2),
00048 p_letgo (0.01), T_E (1), sigma (0.05)
00049 {
00050 for (unsigned int k = 0; k < lambda.size (); k++)
00051 lambda [k] = NaN;
00052
00053
00054
00055 };
00056
00057 ~KBK_stick_state ()
00058 {
00059
00060
00061 };
00062
00063 double predict (const observation_type &observation, const double variance_scale = 1.0)
00064 {
00065 this->compute_pose ();
00066 const stick_type stick = observation.get_stick ();
00067
00068 const int num_indices = 2;
00069 const int indices [num_indices+1] = {10, 14, -1};
00070
00071
00072 for (unsigned int i = 0; i < lambda.size (); i++)
00073 {
00074 if (!is_number (lambda [i]))
00075 {
00076
00077 const_bone_iter iter = this->skeleton.begin ();
00078 int k = 0;
00079 while (k++ != indices [i])
00080 iter ++;
00081 const vector3 hand = iter->absolute ().T ();
00082
00083
00084 double alpha;
00085 const double hand_object_dist2 = dist2 (stick, hand, alpha);
00086 if (hand_object_dist2 < T_E)
00087 lambda [i] = alpha;
00088 else
00089 lambda [i] = NaN;
00090 }
00091 else
00092 {
00093
00094
00095
00096
00097
00098
00099
00100
00101 {
00102 gaussian1D G (lambda [i], sigma);
00103 while (true)
00104 {
00105 const double l = G.random ();
00106 if (0 <= l && l <= 1)
00107 {
00108 lambda [i] = l;
00109 break;
00110 }
00111 }
00112 }
00113 }
00114 }
00115
00116
00117 num_rejections = 0;
00118
00119
00120
00121
00122
00123 const vector_type init_theta (this->get_theta ());
00124 for (int iter = 0; iter < 5000; iter++)
00125 {
00126
00127 this->set_theta (init_theta);
00128 angle_state<observation_type>::predict (observation);
00129
00130
00131 this->compute_pose ();
00132 int k = 0, i = 0;
00133 bool accept = true;
00134 for (const_bone_iter iter = this->skeleton.begin ();
00135 iter != this->skeleton.end (); iter++, k++)
00136 {
00137 if (k == indices [i] && is_number (lambda [i]))
00138 {
00139 const vector3 attained = iter->absolute ().T ();
00140 const vector3 guess = nearest_point_on_stick (stick, lambda [i]);
00141 const vector3 delta = attained - guess;
00142 const double dist2 = delta * delta;
00143 if (dist2 > T_E)
00144 {
00145 accept = false;
00146 break;
00147 }
00148 i++;
00149 }
00150 }
00151
00152 if (accept)
00153 {
00154 break;
00155 }
00156
00157 num_rejections ++;
00158 }
00159
00160 return 0;
00161 };
00162
00163 KBK_stick_state& operator= (KBK_stick_state &new_state)
00164 {
00165 skeleton_state<observation_type>::operator= (new_state);
00166 this->lambda = new_state.lambda;
00167
00168 return *this;
00169 };
00170
00171 void write_to_log (std::ofstream &file) const
00172 {
00173 file << num_rejections << std::endl;
00174 }
00175
00176 protected:
00177 int num_rejections;
00178 std::vector<double> lambda;
00179 const double p_letgo, T_E, sigma;
00180 };
00181
00182 #endif // KBK_STICK_STATE_H