00001
00002
00003 #include <StateEstimators/ViconHandler.hpp>
00004 #include <EigenTools.hpp>
00005
00006
00007 namespace telekyb_state {
00008
00009 ViconHandlerOption::ViconHandlerOption()
00010 : OptionContainer("ViconHandler")
00011 {
00012
00013
00014 Eigen::Matrix<double,6,6> qt;
00015 qt.Zero();
00016 vicCov = addOption<Eigen::Matrix<double,6,6> >("vicCov", "Vicon noise covariance matrix", qt, false, true);
00017
00018 vicPosition = addOption<Eigen::Vector3d>("initState", "Initial estimate for Vicon position", Eigen::Vector3d(0.0,0.0,0.0), false, true);
00019 vicOrientation = addOption<Eigen::Quaterniond>("vicOrientation", "Initial estimate for Vicon orientation", Eigen::Quaterniond(1.0,0.0,0.0,0.0), false, true);
00020 }
00021
00022
00023 void ViconHandler::initialize()
00024 {
00025 sensorSub = nodeHandle.subscribe(options.vicTopic->getValue(),1, &ViconHandler::measureCallback, this);
00026 vicPosition = options.vicPosition->getValue();
00027 vicOrientation = options.vicOrientation->getValue()
00028 }
00029
00030 void ViconHandler::measureCallback(const geometry_msgs::TransformStamped::ConstPtr& msg)
00031 {
00032 lastMeasure.timeStamp = msg->header.stamp.sec;
00033 lastMeasure.measure = *msg;
00034
00035
00036 }
00037
00038
00039 void ViconHandler::update(StateBufferElement& state, const geometry_msgs::TransformStamped& z)
00040 {
00041
00042 EigenTools tools;
00043
00044
00045 const Eigen::Vector3d r(state.state.pose.position.x,state.state.pose.position.y,state.state.pose.position.z);
00046 const Eigen::Vector3d dr(state.state.twist.linear.x,state.state.twist.linear.y,state.state.twist.linear.z);
00047 const Eigen::Quaterniond q(state.state.pose.orientation.w,state.state.pose.orientation.x,state.state.pose.orientation.y,state.state.pose.orientation.z);
00048
00049
00050 const Eigen::Vector3d zr(state.state.pose.position.x,state.state.pose.position.y,state.state.pose.position.z);
00051 const Eigen::Quaterniond zq(state.state.pose.orientation.w,state.state.pose.orientation.x,state.state.pose.orientation.y,state.state.pose.orientation.z);
00052
00053 const Eigen::Matrix<double, 6, 6> Qt = options.vicCov->getValue();
00054
00055 const Eigen::Vector3d BrBM = vicPosition;
00056 const Eigen::Quaterniond BqM = vicOrientation;
00057 Eigen::Quaterniond WqM = q*BqM;
00058
00059 Eigen::Matrix<double, 6, 9> H;
00060 H << Eigen::Matrix3d::Identity(), Eigen::Matrix3d::Zero(), tools.gamma(q,BrBM)*tools.jacqp(q),
00061 Eigen::Matrix3d::Zero(), Eigen::Matrix3d::Zero(), Eigen::Matrix3d::Identity();
00062
00063 Eigen::Matrix<double, 6, 6> Hn;
00064 Hn.Identity();
00065
00066 Eigen::Matrix<double, 9, 6> K = state.covariance*H.transpose()*(H*state.covariance*H.transpose()+Hn*Qt*Hn.transpose());
00067
00068
00069 Eigen::Vector3d perr = tools.toRodrigues(zq*WqM.conjugate());
00070
00071 Eigen::Matrix<double, 6, 1> error;
00072 error << zr-(r+q*BrBM),
00073 perr;
00074 Eigen::Matrix<double, 9, 1> update = K*error;
00075
00076 r+=update.block<3,1>(0,0);
00077 dr+=update.block<3,1>(3,3);
00078 q = tools.toQuaternion((Eigen::Vector3d)update.block<3,1>(6,0))*q;
00079
00080 state.state.pose.position.x = r(0);
00081 state.state.pose.position.y = r(1);
00082 state.state.pose.position.z = r(2);
00083
00084 state.state.twist.linear.x = dr(0);
00085 state.state.twist.linear.y = dr(1);
00086 state.state.twist.linear.z = dr(2);
00087
00088 state.state.pose.orientation.w = q.w();
00089 state.state.pose.orientation.x = q.x();
00090 state.state.pose.orientation.y = q.y();
00091 state.state.pose.orientation.z = q.z();
00092
00093
00094 state.covariance = (Eigen::Matrix<double, 9, 9>::Identity()-K*H)*state.covariance*(Eigen::Matrix<double, 9, 9>::Identity()-K*H).transpose() + K*Qt*K.transpose();
00095 }
00096
00097
00098 }