dead_reckoning.cpp
Go to the documentation of this file.
00001 
00026 #include "ros/ros.h"
00027 #include "tf/transform_datatypes.h"
00028 #include "grizzly_motion/dead_reckoning.h"
00029 
00030 using Eigen::Vector2f;
00031 
00037 bool DeadReckoning::next(const grizzly_msgs::DriveConstPtr& encoders, nav_msgs::Odometry* odom)
00038 {
00039   bool success = false;
00040 
00041   // Angular velocity per-side in rad/s, velocity per-size in m/s
00042   Vector2f avg_rotations((encoders->front_left + encoders->rear_left) / 2,
00043                          (encoders->front_right + encoders->rear_right) / 2);
00044   Vector2f vels = avg_rotations * radius_;
00045 
00046   ros::Duration dt = encoders->header.stamp - last_time_;
00047   if (dt <= max_dt_) {
00048     // Integrate position based on previous yaw and speed
00049      position_.x += cos(yaw_) * twist_.linear.x * dt.toSec();
00050      position_.y += sin(yaw_) * twist_.linear.x * dt.toSec();
00051 
00052     // Update heading by integrating previous angular velocity.
00053      yaw_ += twist_.angular.z * dt.toSec();
00054 
00055     // Update linear and angular velocity
00056     twist_.linear.x = vels.mean();
00057     twist_.angular.z = (vels[1] - vels[0]) / width_;
00058     
00059     // Timestamp from encoder message, set frames correctly.
00060     odom->header = encoders->header;
00061     odom->header.frame_id = "odom";
00062     odom->child_frame_id = "base_footprint"; 
00063     odom->pose.pose.position = position_;
00064     odom->pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw(0, 0, yaw_);
00065     odom->twist.twist = twist_;
00066 
00067     Eigen::Map<Eigen::MatrixXd> poseCov(odom->pose.covariance.data(), 6, 6);
00068     Eigen::Map<Eigen::MatrixXd> twistCov(odom->twist.covariance.data(), 6, 6);
00069 
00070     if(twist_.linear.x <= 1e-3 && twist_.angular.z <= 1e-3) {
00071       poseCov = ODOM_POSE_COVAR_NOMOVE;
00072       twistCov = ODOM_TWIST_COVAR_NOMOVE;
00073     } else {
00074       poseCov = ODOM_POSE_COVAR_MOTION;
00075       twistCov = ODOM_TWIST_COVAR_MOTION;
00076     }
00077 
00078     success = true;
00079   } else {
00080     static bool first = true;
00081     ROS_WARN_COND(first, "Gap between encoders messages is too large, no odom generated.");
00082     first = false;
00083   }
00084 
00085   last_time_ = encoders->header.stamp;
00086   last_vels_ = vels;
00087   return success;
00088 }


grizzly_motion
Author(s):
autogenerated on Fri Aug 28 2015 10:55:30