odometry.cpp
Go to the documentation of this file.
1 
10 /*****************************************************************************
11 ** Includes
12 *****************************************************************************/
13 
14 #include "../../include/xbot_node/odometry.hpp"
15 
16 /*****************************************************************************
17 ** Namespaces
18 *****************************************************************************/
19 
20 namespace xbot {
21 
22 /*****************************************************************************
23 ** Implementation
24 *****************************************************************************/
25 
27  : odom_frame("odom"),
28  base_frame("base_footprint"),
29  use_imu_heading(true),
30  publish_tf(true){};
31 
32 void Odometry::init(ros::NodeHandle &nh, const std::string &name) {
33  double timeout;
34  nh.param("cmd_vel_timeout", timeout, 0.6);
35  cmd_vel_timeout.fromSec(timeout);
36  ROS_INFO_STREAM("Xbot : Velocity commands timeout: "
37  << cmd_vel_timeout << " seconds [" << name << "].");
38 
39  if (!nh.getParam("odom_frame", odom_frame)) {
41  "Xbot : no param server setting for odom_frame, using default ["
42  << odom_frame << "][" << name << "].");
43  } else {
44  ROS_INFO_STREAM("Xbot : using odom_frame [" << odom_frame << "][" << name
45  << "].");
46  }
47 
48  if (!nh.getParam("base_frame", base_frame)) {
50  "Xbot : no param server setting for base_frame, using default ["
51  << base_frame << "][" << name << "].");
52  } else {
53  ROS_INFO_STREAM("Xbot : using base_frame [" << base_frame << "][" << name
54  << "].");
55  }
56 
57  if (!nh.getParam("publish_tf", publish_tf)) {
59  "Xbot : no param server setting for publish_tf, using default ["
60  << publish_tf << "][" << name << "].");
61  } else {
62  if (publish_tf) {
63  ROS_INFO_STREAM("Xbot : publishing transforms [" << name << "].");
64  } else {
65  ROS_INFO_STREAM("Xbot : not publishing transforms (see robot_pose_ekf) ["
66  << name << "].");
67  }
68  }
69 
70  if (!nh.getParam("use_imu_heading", use_imu_heading)) {
72  "Xbot : no param server setting for use_imu_heading, using default ["
73  << use_imu_heading << "][" << name << "].");
74  } else {
75  if (use_imu_heading) {
76  ROS_INFO_STREAM("Xbot : using imu data for heading [" << name << "].");
77  } else {
78  ROS_INFO_STREAM("Xbot : using encoders for heading (see robot_pose_ekf) ["
79  << name << "].");
80  }
81  }
82 
83  odom_trans.header.frame_id = odom_frame;
84  odom_trans.child_frame_id = base_frame;
85 
86  pose.setIdentity();
87 
88  odom_publisher = nh.advertise<nav_msgs::Odometry>(
89  "odom", 50); // topic name and queue size
90 }
91 
93  if ((!last_cmd_time.isZero()) &&
95  return true;
96  } else {
97  return false;
98  }
99 }
100 
101 void Odometry::update(const ecl::Pose2D<double> &pose_update,
102  ecl::linear_algebra::Vector3d &pose_update_rates,
103  double imu_heading, double imu_angular_velocity) {
104  pose *= pose_update;
105 
106  if (use_imu_heading == true) {
107  // Overwite with gyro heading data
108  pose.heading() = imu_heading;
109  pose_update_rates[2] = imu_angular_velocity;
110  }
111 
112  // since all ros tf odometry is 6DOF we'll need a quaternion created from yaw
113  geometry_msgs::Quaternion odom_quat =
115 
116  if (ros::ok()) {
117  publishTransform(odom_quat);
118  publishOdometry(odom_quat, pose_update_rates);
119  }
120 }
121 
122 /*****************************************************************************
123 ** Private Implementation
124 *****************************************************************************/
125 
126 void Odometry::publishTransform(const geometry_msgs::Quaternion &odom_quat) {
127  if (publish_tf == false) return;
128 
129  odom_trans.header.stamp = ros::Time::now();
130  odom_trans.transform.translation.x = pose.x();
131  odom_trans.transform.translation.y = pose.y();
132  odom_trans.transform.translation.z = 0;
133  odom_trans.transform.rotation = odom_quat;
135 }
136 
138  const geometry_msgs::Quaternion &odom_quat,
139  const ecl::linear_algebra::Vector3d &pose_update_rates) {
140  // Publish as shared pointer to leverage the nodelets' zero-copy pub/sub
141  // feature
142  nav_msgs::OdometryPtr odom(new nav_msgs::Odometry);
143 
144  // Header
145  odom->header.stamp = ros::Time::now();
146  odom->header.frame_id = odom_frame;
147  odom->child_frame_id = base_frame;
148 
149  // Position
150  odom->pose.pose.position.x = pose.x();
151  odom->pose.pose.position.y = pose.y();
152  odom->pose.pose.position.z = 0.0;
153  odom->pose.pose.orientation = odom_quat;
154 
155  // Velocity
156  odom->twist.twist.linear.x = pose_update_rates[0];
157  odom->twist.twist.linear.y = pose_update_rates[1];
158  odom->twist.twist.angular.z = pose_update_rates[2];
159 
160  // Pose covariance (required by robot_pose_ekf) TODO: publish realistic values
161  // Odometry yaw covariance must be much bigger than the covariance provided
162  // by the imu, as the later takes much better measures
163  odom->pose.covariance[0] = 0.1;
164  odom->pose.covariance[7] = 0.1;
165  odom->pose.covariance[35] = use_imu_heading ? 0.05 : 0.2;
166 
167  odom->pose.covariance[14] = DBL_MAX; // set a non-zero covariance on unused
168  odom->pose.covariance[21] = DBL_MAX; // dimensions (z, pitch and roll); this
169  odom->pose.covariance[28] = DBL_MAX; // is a requirement of robot_pose_ekf
170 
171  odom_publisher.publish(odom);
172 }
173 
174 } // namespace xbot
ros::Duration cmd_vel_timeout
Definition: odometry.hpp:55
tf::TransformBroadcaster odom_broadcaster
Definition: odometry.hpp:59
void publish(const boost::shared_ptr< M > &message) const
ros::Time last_cmd_time
Definition: odometry.hpp:56
ros::Publisher odom_publisher
Definition: odometry.hpp:60
const ros::Duration & timeout() const
Definition: odometry.hpp:47
bool use_imu_heading
Definition: odometry.hpp:58
void update(const ecl::Pose2D< double > &pose_update, ecl::linear_algebra::Vector3d &pose_update_rates, double imu_heading, double imu_angular_velocity)
Definition: odometry.cpp:101
bool commandTimeout() const
Definition: odometry.cpp:92
std::string base_frame
Definition: odometry.hpp:54
void publishTransform(const geometry_msgs::Quaternion &odom_quat)
Definition: odometry.cpp:126
Duration & fromSec(double t)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
geometry_msgs::TransformStamped odom_trans
Definition: odometry.hpp:51
ROSCPP_DECL bool ok()
void sendTransform(const StampedTransform &transform)
ecl::Pose2D< double > pose
Definition: odometry.hpp:52
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_WARN_STREAM(args)
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
std::string odom_frame
Definition: odometry.hpp:53
#define ROS_INFO_STREAM(args)
void publishOdometry(const geometry_msgs::Quaternion &odom_quat, const ecl::linear_algebra::Vector3d &pose_update_rates)
Definition: odometry.cpp:137
bool getParam(const std::string &key, std::string &s) const
static Time now()
void init(ros::NodeHandle &nh, const std::string &name)
Definition: odometry.cpp:32


xbot_node
Author(s): Roc, wangpeng@droid.ac.cn
autogenerated on Sat Oct 10 2020 03:28:13