50 out.resize(m.rows()+n.rows(), m.cols());
57 return Eigen::LLT<Eigen::MatrixXd>(matrix).matrixL();
61 std::vector<MatrixXd > out;
63 double gamma = std::sqrt((state.rows()+lambda));
64 MatrixXd sig_sqrt = gamma*
matrixSqrt(covariance);
70 for(
size_t i = 1; i <= state.rows(); i++){
71 out.push_back(state + sig_sqrt.col(i-1));
75 for(
size_t i = state.rows() + 1; i <= 2*state.rows(); i++){
76 out.push_back(state - sig_sqrt.col(i-(state.rows()+1)));
81 MatrixXd meanFromSigmaPoints(std::vector<MatrixXd >& sigma_points,
double n,
double lambda){
82 double weight_zero = lambda / (n + lambda);
83 MatrixXd out = weight_zero * sigma_points[0];
84 double weight_i = 1.0/(2*(n + lambda));
85 for(
size_t i = 1; i <= 2*n; i++){
86 out = out + weight_i * sigma_points[i];
92 MatrixXd
covarianceFromSigmaPoints(std::vector<MatrixXd >& sigma_points, MatrixXd& mean, MatrixXd process_noise,
double n,
double alpha,
double beta,
double lambda){
93 double cov_weight_zero = lambda / (n + lambda) + (1 - alpha*alpha + beta);
94 MatrixXd out = cov_weight_zero * (sigma_points[0] - mean) * (sigma_points[0] - mean).transpose();
95 double weight_i = 1.0/(2*(n + lambda));
96 for(
size_t i = 1; i <= 2*n; i++){
97 out = out + weight_i * (sigma_points[i] - mean) * (sigma_points[i] - mean).transpose();
99 return out+process_noise;
102 MatrixXd
crossCovariance(std::vector<MatrixXd >& sigma_points, MatrixXd& mean, std::vector<MatrixXd >& meas_sigma_points, MatrixXd& meas_mean,
double alpha,
double beta,
double lambda){
103 double n = sigma_points[0].rows();
104 double cov_weight_zero = lambda / (n + lambda) + (1 - alpha*alpha + beta);
105 MatrixXd out = cov_weight_zero * (sigma_points[0] - mean) * (meas_sigma_points[0] - meas_mean).transpose();
106 double weight_i = 1.0/(2*(n + lambda));
107 for(
size_t i = 1; i <= 2*n; i++){
108 out = out + weight_i * (sigma_points[i] - mean) * (meas_sigma_points[i] - meas_mean).transpose();
115 Matrix<double, SIZE, 1> out;
123 graft::GraftState::Ptr out(
new graft::GraftState());
124 out->twist.linear.x = state(0);
125 out->twist.linear.y = state(1);
126 out->twist.angular.z = state(2);
131 std::vector<MatrixXd > out;
132 for(
size_t i = 0; i < sigma_points.size(); i++){
133 out.push_back(
f(sigma_points[i], dt));
143 graft::GraftStatePtr msg(
new graft::GraftState());
144 msg->twist.linear.x = state(0);
145 msg->twist.linear.y = state(1);
146 msg->twist.angular.z = state(2);
148 for(
size_t i = 0; i <
SIZE*
SIZE; i++){
149 msg->covariance[i] = covariance(i);
155 VectorXd out(vec.size() + 1);
161 MatrixXd out(mat.rows() + 1, 1);
162 MatrixXd small(1, 1);
163 small(0,0) = element;
173 VectorXd actual_measurement;
174 output_measurement_sigmas.clear();
175 VectorXd innovation_covariance_diagonal;
176 innovation_covariance_diagonal.resize(0);
178 std::vector<graft::GraftState::ConstPtr> predicted_sigma_msgs;
179 for(
size_t i = 0; i < predicted_sigma_points.size(); i++){
181 output_measurement_sigmas.push_back(MatrixXd());
186 for(
size_t i = 0; i < topics.size(); i++){
188 graft::GraftSensorResidual::ConstPtr meas = topics[i]->z();
190 std::vector<graft::GraftSensorResidual::ConstPtr> residuals_msgs;
191 for(
size_t j = 0; j < predicted_sigma_msgs.size(); j++){
192 residuals_msgs.push_back(topics[i]->h(*predicted_sigma_msgs[j]));
199 if(meas->twist_covariance[0] > 1e-20){
201 innovation_covariance_diagonal =
addElementToVector(innovation_covariance_diagonal, meas->twist_covariance[0]);
202 for(
size_t j = 0; j < residuals_msgs.size(); j++){
203 output_measurement_sigmas[j] =
addElementToColumnMatrix(output_measurement_sigmas[j], residuals_msgs[j]->twist.linear.x);
207 if(meas->twist_covariance[7] > 1e-20){
209 innovation_covariance_diagonal =
addElementToVector(innovation_covariance_diagonal, meas->twist_covariance[7]);
210 for(
size_t j = 0; j < residuals_msgs.size(); j++){
211 output_measurement_sigmas[j] =
addElementToColumnMatrix(output_measurement_sigmas[j], residuals_msgs[j]->twist.linear.y);
215 if(meas->twist_covariance[35] > 1e-20){
217 innovation_covariance_diagonal =
addElementToVector(innovation_covariance_diagonal, meas->twist_covariance[35]);
218 for(
size_t j = 0; j < residuals_msgs.size(); j++){
219 output_measurement_sigmas[j] =
addElementToColumnMatrix(output_measurement_sigmas[j], residuals_msgs[j]->twist.angular.z);
225 output_innovation_covariance = innovation_covariance_diagonal.asDiagonal();
227 return actual_measurement;
231 for(
size_t i = 0; i < topics.size(); i++){
232 topics[i]->clearMessage();
252 std::vector<MatrixXd > predicted_sigma_points =
predict_sigma_points(previous_sigma_points, 0.0);
253 MatrixXd predicted_mean = meanFromSigmaPoints(predicted_sigma_points,
graft_state_.rows(), lambda);
257 std::vector<MatrixXd> observation_sigma_points =
generateSigmaPoints(predicted_mean, predicted_covariance, lambda);
258 std::vector<MatrixXd> predicted_observation_sigma_points;
259 MatrixXd measurement_noise;
260 MatrixXd z =
getMeasurements(
topics_, observation_sigma_points, predicted_observation_sigma_points, measurement_noise);
264 MatrixXd predicted_measurement = meanFromSigmaPoints(predicted_observation_sigma_points,
graft_state_.rows(), lambda);
266 MatrixXd cross_covariance =
crossCovariance(observation_sigma_points, predicted_mean, predicted_observation_sigma_points, predicted_measurement,
alpha_,
beta_, lambda);
267 MatrixXd K = cross_covariance * predicted_measurement_uncertainty.partialPivLu().inverse();
268 graft_state_ = predicted_mean + K*(z - predicted_measurement);
269 graft_covariance_ = predicted_covariance - K*predicted_measurement_uncertainty*K.transpose();
283 for(
size_t i = 0; i < P.size(); i++){
286 }
else if(P.size() == diagonal_size){
287 for(
size_t i = 0; i < P.size(); i++){
291 ROS_ERROR(
"initial_covariance is size %zu, expected %zu.\nUsing 0.1*Identity.\nThis probably won't work well.", P.size(),
graft_covariance_.size());
299 size_t diagonal_size = std::sqrt(
Q_.size());
300 if(Q.size() ==
Q_.size()){
301 for(
size_t i = 0; i < Q.size(); i++){
304 }
else if(Q.size() == diagonal_size){
305 for(
size_t i = 0; i < Q.size(); i++){
306 Q_(i*(diagonal_size+1)) = Q[i];
309 ROS_ERROR(
"process_noise parameter is size %zu, expected %zu.\nUsing 0.1*Identity.\nThis probably won't work well.", Q.size(),
Q_.size());