00001 #ifndef TAG_CONSTANTVELOCITY_H
00002 #define TAG_CONSTANTVELOCITY_H
00003
00004 #include <TooN/se3.h>
00005
00006 namespace tag {
00007
00008 namespace ConstantVelocity {
00009
00014
00018 class State {
00019 public:
00020 inline State(void){
00021 reset();
00022 }
00023
00024 inline void reset(void){
00025 pose = TooN::SE3();
00026 TooN::Zero(angularVelocity);
00027 TooN::Zero(velocity);
00028 TooN::Identity(covariance);
00029 }
00030
00031 inline void resetVelocity(void){
00032 TooN::Zero(angularVelocity);
00033 TooN::Zero(velocity);
00034 }
00035
00036 static const int STATE_DIMENSION = 12;
00037 TooN::SE3 pose;
00038 TooN::Vector<3> angularVelocity;
00039 TooN::Vector<3> velocity;
00040 TooN::Matrix<STATE_DIMENSION> covariance;
00041 };
00042
00045 template <class O>
00046 inline O & operator<< (O & os , const State & st){
00047 os << st.pose.ln() << st.velocity << st.angularVelocity << st.pose.inverse().get_translation();
00048 return os;
00049 }
00050
00054 class Model {
00055 public:
00056 TooN::Vector<State::STATE_DIMENSION> sigma;
00057 TooN::Matrix<State::STATE_DIMENSION> jacobian;
00058 TooN::Matrix<State::STATE_DIMENSION> noise;
00059
00060 double damp;
00061
00062 Model(void){
00063 TooN::Zero(sigma);
00064 damp = 1;
00065 TooN::Identity(jacobian);
00066 TooN::Zero(noise);
00067 }
00068
00069
00070 inline const TooN::Matrix<State::STATE_DIMENSION> & getJacobian(const State & state, const double dt) {
00071 jacobian(0,6) = dt;
00072 jacobian(1,7) = dt;
00073 jacobian(2,8) = dt;
00074 jacobian(3,9) = dt;
00075 jacobian(4,10) = dt;
00076 jacobian(5,11) = dt;
00077 return jacobian;
00078 }
00079
00080 inline void updateState( State & state, const double dt ){
00081
00082 TooN::Vector<6> vel;
00083 vel.slice<0,3>() = state.velocity;
00084 vel.slice<3,3>() = state.angularVelocity;
00085
00086
00087 state.pose = TooN::SE3::exp(vel * dt) * state.pose;
00088
00089 double attenuation = pow(damp, dt);
00090 state.velocity *= attenuation;
00091 state.angularVelocity *= attenuation;
00092 }
00093
00094 inline const TooN::Matrix<State::STATE_DIMENSION> & getNoiseCovariance( const double dt ){
00095 const double dt2 = dt * dt * 0.5;
00096 const double dt3 = dt * dt * dt * 0.3333333333333;
00097 for(unsigned int i = 0; i < 6; i++){
00098 noise(i,i) = dt * sigma[i] + dt3 * sigma[i+6];
00099 noise(i+6,i) = noise(i,i+6) = dt2 * sigma[i+6];
00100 noise(i+6, i+6) = dt * sigma[i+6];
00101 }
00102 return noise;
00103 }
00104
00105 inline void updateFromMeasurement( State & state, const TooN::Vector<State::STATE_DIMENSION> & innovation ){
00106 state.pose = TooN::SE3::exp(innovation.slice<0,6>()) * state.pose;
00107 state.velocity = state.velocity + innovation.slice<6,3>();
00108 state.angularVelocity = state.angularVelocity + innovation.slice<9,3>();
00109 }
00110 };
00111
00112 }
00113
00114 }
00115
00116 #endif