pose_and_orientation_to_imu_node.cpp
Go to the documentation of this file.
1 //=================================================================================================
2 // Copyright (c) 2012, Stefan Kohlbrecher, TU Darmstadt
3 // All rights reserved.
4 
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the Simulation, Systems Optimization and Robotics
13 // group, TU Darmstadt nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without
15 // specific prior written permission.
16 
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //=================================================================================================
28 
29 
30 #include "ros/ros.h"
32 #include <sensor_msgs/Imu.h>
33 #include <geometry_msgs/PoseStamped.h>
34 #include <nav_msgs/Odometry.h>
35 
36 std::string p_map_frame_;
39 std::string p_base_frame_;
42 
46 
49 
50 sensor_msgs::ImuConstPtr last_imu_msg_;
51 sensor_msgs::Imu fused_imu_msg_;
52 nav_msgs::Odometry odom_msg_;
53 geometry_msgs::PoseStampedConstPtr last_pose_msg_;
54 
57 
59 
60 #ifndef TF_MATRIX3x3_H
61 typedef btScalar tfScalar;
62 namespace tf { typedef btMatrix3x3 Matrix3x3; }
63 #endif
64 
65 void imuMsgCallback(const sensor_msgs::Imu::ConstPtr& imu_msg)
66 {
68 
69  tf::quaternionMsgToTF(imu_msg->orientation, tmp_);
70 
71  tfScalar imu_yaw, imu_pitch, imu_roll;
72  tf::Matrix3x3(tmp_).getRPY(imu_roll, imu_pitch, imu_yaw);
73 
74  tf::Transform transform;
75  transform.setIdentity();
76  tf::Quaternion quat;
77 
78  quat.setRPY(imu_roll, imu_pitch, 0.0);
79 
80  if (true){
81  transform.setRotation(quat);
82  tfB_->sendTransform(tf::StampedTransform(transform, imu_msg->header.stamp, p_base_stabilized_frame_, p_base_frame_));
83  }
84 
85  tfScalar pose_yaw, pose_pitch, pose_roll;
86 
87  if (last_pose_msg_ != 0){
88  tf::quaternionMsgToTF(last_pose_msg_->pose.orientation, tmp_);
89 
90  tf::Matrix3x3(tmp_).getRPY(pose_roll, pose_pitch, pose_yaw);
91  }else{
92  pose_yaw = 0.0;
93  }
94 
95  orientation_quaternion_.setRPY(imu_roll, imu_pitch, pose_yaw);
96 
97  fused_imu_msg_.header.stamp = imu_msg->header.stamp;
98 
99  fused_imu_msg_.orientation.x = orientation_quaternion_.getX();
100  fused_imu_msg_.orientation.y = orientation_quaternion_.getY();
101  fused_imu_msg_.orientation.z = orientation_quaternion_.getZ();
102  fused_imu_msg_.orientation.w = orientation_quaternion_.getW();
103 
104  fused_imu_publisher_.publish(fused_imu_msg_);
105 
106  //If no pose message received, yaw is set to 0.
107  //@TODO: Check for timestamp of pose and disable sending if too old
108  if (last_pose_msg_ != 0){
109  if ( (callback_count_ % 5) == 0){
110  odom_msg_.header.stamp = imu_msg->header.stamp;
111  odom_msg_.pose.pose.orientation = fused_imu_msg_.orientation;
112  odom_msg_.pose.pose.position = last_pose_msg_->pose.position;
113 
114  odometry_publisher_.publish(odom_msg_);
115  }
116  }
117 
118 }
119 
120 void poseMsgCallback(const geometry_msgs::PoseStamped::ConstPtr& pose_msg)
121 {
122 
123  std::vector<tf::StampedTransform> transforms;
124  transforms.resize(2);
125 
126  tf::quaternionMsgToTF(pose_msg->pose.orientation, robot_pose_quaternion_);
127  tf::pointMsgToTF(pose_msg->pose.position, robot_pose_position_);
128 
129  robot_pose_transform_.setRotation(robot_pose_quaternion_);
130  robot_pose_transform_.setOrigin(robot_pose_position_);
131 
132  tf::Transform height_transform;
133  height_transform.setIdentity();
134  height_transform.setOrigin(tf::Vector3(0.0, 0.0, 0.0));
135 
136  transforms[0] = tf::StampedTransform(robot_pose_transform_, pose_msg->header.stamp, p_map_frame_, p_base_footprint_frame_);
137  transforms[1] = tf::StampedTransform(height_transform, pose_msg->header.stamp, p_base_footprint_frame_, p_base_stabilized_frame_);
138 
139  tfB_->sendTransform(transforms);
140 
141  // Perform simple estimation of vehicle altitude based on orientation
142  if (last_pose_msg_){
143  tf::Vector3 plane_normal = tf::Matrix3x3(orientation_quaternion_) * tf::Vector3(0.0, 0.0, 1.0);
144 
145  tf::Vector3 last_position;
146  tf::pointMsgToTF(last_pose_msg_->pose.position, last_position);
147 
148  double height_difference =
149  (-plane_normal.getX() * (robot_pose_position_.getX() - last_position.getX())
150  -plane_normal.getY() * (robot_pose_position_.getY() - last_position.getY())
151  +plane_normal.getZ() * last_position.getZ()) / last_position.getZ();
152 
153  }
154 
155 
156 
157  last_pose_msg_ = pose_msg;
158 
159 }
160 
161 int main(int argc, char **argv) {
162  ros::init(argc, argv, ROS_PACKAGE_NAME);
163 
164  ros::NodeHandle n;
165  ros::NodeHandle pn("~");
166 
167  pn.param("map_frame", p_map_frame_, std::string("map"));
168  pn.param("base_footprint_frame", p_base_footprint_frame_, std::string("base_footprint"));
169  pn.param("base_stabilized_frame", p_base_stabilized_frame_, std::string("base_stabilized"));
170  pn.param("base_frame", p_base_frame_, std::string("base_link"));
171 
172  fused_imu_msg_.header.frame_id = p_base_stabilized_frame_;
173  odom_msg_.header.frame_id = "map";
174 
175  tfB_ = new tf::TransformBroadcaster();
176 
177  fused_imu_publisher_ = n.advertise<sensor_msgs::Imu>("/fused_imu",1,false);
178  odometry_publisher_ = n.advertise<nav_msgs::Odometry>("/state", 1, false);
179 
180  ros::Subscriber imu_subscriber = n.subscribe("/imu", 10, imuMsgCallback);
181  ros::Subscriber pose_subscriber = n.subscribe("/pose", 10, poseMsgCallback);
182 
183  callback_count_ = 0;
184 
185  ros::spin();
186 
187  delete tfB_;
188 
189  return 0;
190 }
TFSIMD_FORCE_INLINE void setRotation(const Quaternion &q)
static void pointMsgToTF(const geometry_msgs::Point &msg_v, Point &bt_v)
void publish(const boost::shared_ptr< M > &message) const
tf::Point robot_pose_position_
double tfScalar
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
tf::Transform robot_pose_transform_
tf::StampedTransform transform_
tf::TransformBroadcaster * tfB_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
TFSIMD_FORCE_INLINE const tfScalar & getY() const
geometry_msgs::PoseStampedConstPtr last_pose_msg_
ros::Publisher odometry_publisher_
TFSIMD_FORCE_INLINE const tfScalar & getW() const
TFSIMD_FORCE_INLINE const tfScalar & getZ() const
tf::Quaternion tmp_
std::string p_map_frame_
ROSCPP_DECL void spin(Spinner &spinner)
void setIdentity()
void setRPY(const tfScalar &roll, const tfScalar &pitch, const tfScalar &yaw)
static void quaternionMsgToTF(const geometry_msgs::Quaternion &msg, Quaternion &bt)
void poseMsgCallback(const geometry_msgs::PoseStamped::ConstPtr &pose_msg)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void sendTransform(const StampedTransform &transform)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
std::string p_base_stabilized_frame_
int main(int argc, char **argv)
void imuMsgCallback(const sensor_msgs::Imu::ConstPtr &imu_msg)
tf::Quaternion orientation_quaternion_
tf::Quaternion robot_pose_quaternion_
std::string p_base_footprint_frame_
sensor_msgs::Imu fused_imu_msg_
std::string p_base_frame_
TFSIMD_FORCE_INLINE const tfScalar & getX() const
nav_msgs::Odometry odom_msg_
sensor_msgs::ImuConstPtr last_imu_msg_
TFSIMD_FORCE_INLINE void setOrigin(const Vector3 &origin)
ros::Publisher fused_imu_publisher_


hector_imu_tools
Author(s): Stefan Kohlbrecher
autogenerated on Sun Nov 3 2019 03:18:30