ViconImuStateEstimator.cpp
Go to the documentation of this file.
00001 /*
00002  * ViconImuStateEstimator.cpp
00003  *
00004  *  Created on: Jul 11, 2012
00005  *      Author: mriedel & rspica
00006  */
00007 
00008 #include <StateEstimators/ViconImuStateEstimator.hpp>
00009 #include <tk_state/StateEstimatorController.hpp>
00010 
00011 #include <telekyb_base/ROS.hpp>
00012 
00013 #include <telekyb_msgs/TKState.h>
00014 
00015 
00016 PLUGINLIB_DECLARE_CLASS(tk_state, ViconImuStateEstimator, telekyb_state::ViconImuStateEstimator, TELEKYB_NAMESPACE::StateEstimator);
00017 
00018 namespace telekyb_state {
00019 
00020 ViconImuStateEstimatorOptions::ViconImuStateEstimatorOptions()
00021         : OptionContainer("ViconImuStateEstimator")
00022 {
00023         tViconSeTopicName = addOption<std::string>("tViconSeTopicName","TopicName of Vicon Sensor.","undef",true,true);
00024         tImuSeTopicName = addOption<std::string>("tImuSeTopicName","TopicName of Imu Sensor.","undef",true,true);
00025 
00026         Eigen::Matrix3d m = Eigen::Matrix3d::Zero();
00027         m.diagonal() << 1.0,-1.0,-1.0;
00028         tViconToNEDMatrix = addOption<Eigen::Matrix3d>("tViconToNEDMatrix","ConversionMatrix from Vicon to NED", m, false, true);
00029 
00030         tViconToNEDQuaternion = addOption<Eigen::Quaterniond>("tViconToNEDQuaternion","ConversionQuaternion from Vicon to NED", Eigen::Quaterniond(1.0,0.0,0.0,0.0), false, true);
00031 
00032         tViconVelFilterFreq = addOption<double>("tViconVelFilterFreq",
00033                         "Frequency of Velocity Filter (Initial)", 40.0, false, true);
00034         tViconSmoothVelFilterFreq = addOption<double>("tViconSmoothVelFilterFreq",
00035                         "Frequency of Smooth Velocity Filter (Initial)", 10.0, false, true);
00036         tViconAngFilterFreq = addOption<double>("tViconAngFilterFreq",
00037                         "Frequency of Angular Velocity Filter (Initial)", 30.0, false, true);
00038 
00039         tViconSampleTime = addOption<double>("tViconSampleTime",
00040                         "Sampling Time of Vicon System. Default is 120Hz", 0.008333333333, false, true);
00041 
00042         tViconPublishSmoothVel = addOption<bool>("tViconPublishSmoothVel",
00043                         "Publish TKState with smoothed Velocity", false, false, true);
00044 
00045         timeStep = addOption<double>("timeStep","Time step for state publishing",4e-3,false,true);
00046 
00047         tIntegrateLinVel = addOption<bool>("tIntegrateLinVel",
00048                                 "Integrate linear velocity when Vicon position is not available", false, false, false);
00049         tIntegrateAngVel = addOption<bool>("tIntegrateAngVel",
00050                                 "Integrate angular velocity when Vicon orientation is not available", false, false, false);
00051 
00052 }
00053 
00054 //void ViconImuStateEstimator::ssxCallback(const telekyb_msgs::TKState::ConstPtr& stateMsg)
00055 //{
00056 //      // StateEstimatorController neest a telekyb::TKState
00057 //      TKState tStateMsg(*stateMsg);
00058 //      stateEstimatorController.activeStateCallBack(tStateMsg);
00059 //}
00060 
00061 
00062 
00063 void ViconImuStateEstimator::initVelocityFilters()
00064 {
00065         IIRFiltDeriv isDerivative;
00066         for(int i=0;i<3;i++){
00067                 velFilter[i] = new IIRFilter(
00068                                 isDerivative,
00069                                 2.0*M_PI*options.tViconVelFilterFreq->getValue(),
00070                                 1.0,
00071                                 options.tViconSampleTime->getValue());
00072         }
00073 
00074         for(int i=0;i<3;i++){
00075                 smoothVelFilter[i] = new IIRFilter(
00076                                 isDerivative,
00077                                 2.0*M_PI*options.tViconSmoothVelFilterFreq->getValue(),
00078                                 1.0,
00079                                 options.tViconSampleTime->getValue());
00080         }
00081 }
00082 
00083 void ViconImuStateEstimator::initialize()
00084 {
00085 //      debugPub = nodeHandle.advertise<telekyb_msgs::TKState>("debugState",1);
00086         nodeHandle = ROSModule::Instance().getMainNodeHandle();
00087 
00088         initVelocityFilters();
00089 
00090         spinning = true;
00091         thread = boost::thread(&ViconImuStateEstimator::spin, this);
00092 }
00093 
00094 void ViconImuStateEstimator::spin()
00095 {
00096         while(spinning)
00097         {
00098                 rtTimer.reset();
00099                 publishState();
00100 
00101                 Time toSleep = Time(options.timeStep->getValue()) - rtTimer.getElapsed();
00102                 if (toSleep>0) {
00103                         toSleep.sleep();
00104                 } else {
00105                         ROS_WARN("State estimation was too slow!");
00106                 }
00107         }
00108 }
00109 
00110 void ViconImuStateEstimator::willBecomeActive()
00111 {
00112         viconSub = nodeHandle.subscribe<geometry_msgs::PoseWithCovarianceStamped>(
00113                         options.tViconSeTopicName->getValue(),1, &ViconImuStateEstimator::viconCallback, this);
00114 
00115         imuSub = nodeHandle.subscribe<sensor_msgs::Imu>(
00116                         options.tImuSeTopicName->getValue(),1, &ViconImuStateEstimator::imuCallback, this);
00117 
00118         if (options.tViconPublishSmoothVel->getValue()) {
00119                 smoothVelPub = nodeHandle.advertise<telekyb_msgs::TKState>("SmoothedVelocity",1);
00120         }
00121 
00122 //      debugPub = nodeHandle.advertise<telekyb_msgs::TKState>("debugState",1);
00123 //      ssxSub = nodeHandle.subscribe<telekyb_msgs::TKState>(
00124 //                      options.tSsxSeTopicName->getValue(),1, &ViconImuStateEstimator::ssxCallback, this);
00125 
00126 }
00127 
00128 void ViconImuStateEstimator::willBecomeInActive()
00129 {
00130         viconSub.shutdown();
00131         imuSub.shutdown();
00132         if (options.tViconPublishSmoothVel->getValue()) {
00133                 smoothVelPub.shutdown();
00134         }
00135 //      debugPub.shutdown();
00136 }
00137 
00138 void ViconImuStateEstimator::destroy()
00139 {
00140         for(int i=0;i<3;i++){
00141                 delete velFilter[i];
00142                 delete smoothVelFilter[i];
00143         }
00144 
00145         spinning = false;
00146         thread.join();
00147 }
00148 
00149 std::string ViconImuStateEstimator::getName() const
00150 {
00151         return options.tViconSeTopicName->getValue();
00152 }
00153 
00154 void ViconImuStateEstimator::viconCallback(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& msg)
00155 {
00156         Position3D posVicon(msg->pose.pose.position.x, msg->pose.pose.position.y, msg->pose.pose.position.z);
00157         Quaternion quatVicon(msg->pose.pose.orientation.w, msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z);
00158 
00159         /*velocity NED */
00160         double output[3],outputMore[3];
00161         std::vector<double> input(1);
00162         input[0]=posNED(0);
00163         velFilter[0]->step(input, output[0]);
00164         smoothVelFilter[0]->step(input, outputMore[0]);
00165         input[0] = posNED(1);
00166         velFilter[1]->step(input, output[1]);
00167         smoothVelFilter[1]->step(input, outputMore[1]);
00168         input[0] = posNED(2);
00169         velFilter[2]->step(input, output[2]);
00170         smoothVelFilter[2]->step(input, outputMore[2]);
00171 
00172         boost::mutex::scoped_lock scopedLock(viconMutex);
00173 
00174         posNED = options.tViconToNEDQuaternion->getValue()*posVicon;
00175         velNED << output[0], output[1], output[2];
00176         smoothVelNED << outputMore[0], outputMore[1], outputMore[2];
00177         quatNED = options.tViconToNEDQuaternion->getValue()*quatVicon;
00178         scopedLock.unlock();
00179 }
00180 
00181 void ViconImuStateEstimator::publishState()
00182 {
00183         TKState tStateMsg;
00184 
00185         // Integrate time
00186         boost::mutex::scoped_lock scopedLock(timeMutex);
00187         telekyb::Time elapsedTime = intTimer.getElapsed();
00188         intTimer.reset();
00189         intTime = intTime + elapsedTime;
00190         tStateMsg.time = intTime;
00191         scopedLock.unlock();
00192 
00193 
00194         boost::mutex::scoped_lock scopedViconLock(viconMutex);
00195         // empty msg
00196         if (options.tIntegrateLinVel->getValue()){
00197                 posNED = posNED + velNED*elapsedTime.toDSec();
00198         }
00199         tStateMsg.position = posNED;
00200         tStateMsg.linVelocity = velNED;
00201 
00202         boost::mutex::scoped_lock scopedImuLock(imuMutex);
00203 
00204         if (options.tIntegrateAngVel->getValue()){
00205                 double angVelSqNorm = angVelocityNED.squaredNorm();
00206                 Eigen::Quaterniond deltaQuat;
00207                 double deltaT = elapsedTime.toDSec();
00208                 deltaQuat.w() = 1.0 - deltaT*deltaT*angVelSqNorm/8.0;
00209                 deltaQuat.vec() = (.5*deltaT - deltaT*deltaT*deltaT*angVelSqNorm/24) * angVelocityNED;
00210                 quatNED = quatNED*deltaQuat;
00211         }
00212         tStateMsg.orientation = quatNED;
00213         tStateMsg.angVelocity = angVelocityNED;
00214 
00215         scopedImuLock.unlock();
00216 
00217         // Publish Smooth Velocity
00218         if (options.tViconPublishSmoothVel->getValue()) {
00219                 telekyb_msgs::TKState smoothVelMsg;
00220                 tStateMsg.toTKStateMsg(smoothVelMsg);
00221                 //smoothVelMsg.header.stamp = ros::Time::now();
00222                 smoothVelMsg.twist.linear.x = smoothVelNED(0);
00223                 smoothVelMsg.twist.linear.y = smoothVelNED(1);
00224                 smoothVelMsg.twist.linear.z = smoothVelNED(2);
00225                 smoothVelPub.publish(smoothVelMsg);
00226         }
00227 
00228         scopedViconLock.unlock();
00229 
00230         stateEstimatorController.activeStateCallBack(tStateMsg);
00231 //      telekyb_msgs::TKState msg;
00232 //      tStateMsg.toTKStateMsg(msg);
00233 //      debugPub.publish(msg);
00234 
00235 }
00236 
00237 void ViconImuStateEstimator::imuCallback(const sensor_msgs::Imu::ConstPtr& msg)
00238 {
00239         boost::mutex::scoped_lock scopedLock(imuMutex);
00240 
00241         angVelocityNED(0) = msg->angular_velocity.x;
00242         angVelocityNED(1) = msg->angular_velocity.y;
00243         angVelocityNED(2) = msg->angular_velocity.z;
00244         
00245         scopedLock.unlock();
00246         scopedLock = boost::mutex::scoped_lock(timeMutex);
00247         
00248         intTime = Time(msg->header.stamp);
00249         intTimer.reset();
00250 
00251         scopedLock.unlock();
00252         
00253 }
00254 
00255 
00256 } /* namespace telekyb_state */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends


tk_state
Author(s): Dr. Antonio Franchi and Martin Riedel
autogenerated on Mon Nov 11 2013 11:13:03