00001
00002
00003
00004
00005
00006
00007
00008 #ifndef OUTLIERREJECTION_HPP_
00009 #define OUTLIERREJECTION_HPP_
00010
00011 #include <Eigen/Dense>
00012 #include <ros/ros.h>
00013
00014 #include <std_msgs/Float32.h>
00015
00016 namespace labust
00017 {
00018 namespace tools
00019 {
00020 class OutlierRejection
00021 {
00022 public:
00023 OutlierRejection(int input_size, double lambda, double a_wk0 = 1.0, double b_wk0 = 1.0):
00024 input_size(input_size),
00025 lambda(lambda),
00026 a_wk0(a_wk0),
00027 b_wk0(b_wk0),
00028 variance_k(1.0),
00029 exp_wk(1.0),
00030 y_k(0.0),
00031 x_k(Eigen::VectorXd::Zero(input_size)),
00032 exp_beta_k(Eigen::VectorXd::Zero(input_size)),
00033 beta_0(Eigen::VectorXd::Zero(input_size)),
00034 N_k(0.0),
00035 sum_wyy(0.0),
00036 sum_wxx(Eigen::MatrixXd::Zero(input_size, input_size)),
00037 sigma_beta_k(1000*Eigen::MatrixXd::Identity(input_size, input_size)),
00038 sum_wyx(Eigen::VectorXd::Zero(input_size))
00039 {
00040
00041 sigma_beta_0_inv = sigma_beta_k.inverse();
00042
00043 ros::NodeHandle nh;
00044 pubWK = nh.advertise<std_msgs::Float32>("outlier_wk",1);
00045 pubSIGMA = nh.advertise<std_msgs::Float32>("outlier_sigma",1);
00046 pubY = nh.advertise<std_msgs::Float32>("outlier_y",1);
00047
00048
00049 }
00050
00051 ~OutlierRejection()
00052 {
00053
00054 }
00055
00056
00057
00058
00059
00060 void step(Eigen::VectorXd input, double output, double* y_filt, double* sigma, double* w){
00061
00062
00063
00064
00065
00066
00067
00068 x_k = input;
00069 y_k = output;
00070
00071
00072
00073
00074
00075
00076 N_k = 1 + lambda*N_k;
00077 sum_wxx = exp_wk*x_k*x_k.transpose()+lambda*sum_wxx;
00078 sum_wyx = exp_wk*y_k*x_k + lambda*sum_wyx;
00079 sum_wyy = exp_wk*y_k*y_k + lambda*sum_wyy;
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 sigma_beta_k = (sigma_beta_0_inv + 1/variance_k*sum_wxx);
00090 sigma_beta_k = sigma_beta_k.inverse();
00091 exp_beta_k = sigma_beta_k*(sigma_beta_0_inv*beta_0 + 1/variance_k*sum_wyx);
00092
00093
00094
00095
00096
00097
00098 exp_wk = (a_wk0+0.5)/(b_wk0+1/(2*variance_k)*(std::pow(y_k-exp_beta_k.transpose()*x_k,2)+x_k.transpose()*sigma_beta_k*x_k));
00099
00100
00101
00102 Eigen::VectorXd Iones(Eigen::VectorXd::Constant(input_size,1.0));
00103
00104 double p1 = (2*sum_wyx.transpose()*exp_beta_k)(0,0);
00105 double p2 = (exp_beta_k.transpose()*sum_wxx*exp_beta_k)(0,0);
00106 double p3 = (Iones.transpose()*(sum_wxx*sigma_beta_k).diagonal())(0,0);
00107
00108 variance_k = 1/N_k*(sum_wyy - p1 + p2 + p3);
00109
00110
00111
00112 *y_filt = exp_beta_k.transpose()*input;
00113 *sigma = variance_k;
00114 *w = exp_wk;
00115
00116 std_msgs::Float32 msg;
00117 msg.data = exp_wk;
00118 pubWK.publish(msg);
00119 msg.data = variance_k;
00120 pubSIGMA.publish(msg);
00121 msg.data = exp_beta_k.transpose()*input;
00122 pubY.publish(msg);
00123
00124 }
00125
00126 int input_size;
00127 double y_k,lambda, exp_wk, variance_k, a_wk0, b_wk0, sum_wyy;
00128 Eigen::VectorXd exp_beta_k, beta_0, x_k, sum_wyx;
00129 Eigen::MatrixXd sigma_beta_k, sigma_beta_0_inv, sum_wxx;
00130 double N_k;
00131
00132 ros::Publisher pubWK, pubSIGMA, pubY;
00133 };
00134 }
00135 }
00136
00137 #endif