00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <ros/ros.h>
00035 #include <message_filters/subscriber.h>
00036 #include <tf/transform_broadcaster.h>
00037 #include <tf/transform_datatypes.h>
00038 #include <tf/transform_listener.h>
00039 #include <tf/message_filter.h>
00040 #include <sensor_msgs/JointState.h>
00041
00042 class BaseFootprint
00043 {
00044 public:
00045 BaseFootprint();
00046 ~BaseFootprint();
00047
00048
00049 private:
00050 void jsCallback(const sensor_msgs::JointState::ConstPtr & msg);
00051
00052 ros::NodeHandle m_nh;
00053 ros::NodeHandle m_privateNh;
00054
00055
00056 message_filters::Subscriber<sensor_msgs::JointState> * m_jsSub;
00057 tf::MessageFilter<sensor_msgs::JointState> * m_jsFilter;
00058 tf::TransformBroadcaster m_brBaseFootPrint;
00059 tf::TransformListener m_listener;
00060
00061 std::string m_odomFrameId;
00062 std::string m_baseFrameId;
00063 std::string m_lfootFrameId;
00064 std::string m_rfootFrameId;
00065 std::string m_baseFootPrintID;
00066
00067 };
00068
00069 BaseFootprint::BaseFootprint()
00070 : m_privateNh("~"), m_odomFrameId("odom"), m_baseFrameId("base_link"),
00071 m_lfootFrameId("l_sole"), m_rfootFrameId("r_sole"),
00072 m_baseFootPrintID("base_footprint")
00073 {
00074
00075 m_privateNh.param("odom_frame_id", m_odomFrameId, m_odomFrameId);
00076 m_privateNh.param("base_frame_id", m_baseFrameId, m_baseFrameId);
00077 m_privateNh.param("base_footprint_frame_id", m_baseFootPrintID, m_baseFootPrintID);
00078
00079
00080
00081
00082 m_odomFrameId = m_listener.resolve(m_odomFrameId);
00083 m_baseFrameId = m_listener.resolve(m_baseFrameId);
00084 m_baseFootPrintID = m_listener.resolve(m_baseFootPrintID);
00085 m_lfootFrameId = m_listener.resolve(m_lfootFrameId);
00086 m_rfootFrameId = m_listener.resolve(m_rfootFrameId);
00087
00088
00089
00090
00091 m_jsSub = new message_filters::Subscriber<sensor_msgs::JointState>(m_nh, "joint_states", 50);
00092 m_jsFilter = new tf::MessageFilter<sensor_msgs::JointState>(*m_jsSub, m_listener, m_rfootFrameId, 50);
00093 std::vector<std::string> frames;
00094 frames.push_back(m_rfootFrameId);
00095 frames.push_back(m_odomFrameId);
00096 m_jsFilter->setTargetFrames(frames);
00097 m_jsFilter->registerCallback(boost::bind(&BaseFootprint::jsCallback, this, _1));
00098 }
00099
00100 BaseFootprint::~BaseFootprint(){
00101 delete m_jsFilter;
00102 delete m_jsSub;
00103 }
00104
00105 void BaseFootprint::jsCallback(const sensor_msgs::JointState::ConstPtr & ptr)
00106 {
00107 ros::Time time = ptr->header.stamp;
00108 tf::StampedTransform tf_odom_to_base, tf_odom_to_left_foot, tf_odom_to_right_foot;
00109
00110 ROS_DEBUG("JointState callback function, computing frame %s", m_baseFootPrintID.c_str());
00111 try {
00112 m_listener.lookupTransform(m_odomFrameId, m_lfootFrameId, time, tf_odom_to_left_foot);
00113 m_listener.lookupTransform(m_odomFrameId, m_rfootFrameId, time, tf_odom_to_right_foot);
00114 m_listener.lookupTransform(m_odomFrameId, m_baseFrameId, time, tf_odom_to_base);
00115 } catch (const tf::TransformException& ex){
00116 ROS_ERROR("%s",ex.what());
00117 return ;
00118 }
00119
00120 tf::Vector3 new_origin = (tf_odom_to_right_foot.getOrigin() + tf_odom_to_left_foot.getOrigin())/2.0;
00121 double height = std::min(tf_odom_to_left_foot.getOrigin().getZ(), tf_odom_to_right_foot.getOrigin().getZ());
00122 new_origin.setZ(height);
00123
00124
00125 double roll, pitch, yaw;
00126 tf_odom_to_base.getBasis().getRPY(roll, pitch, yaw);
00127
00128 tf::Transform tf_odom_to_footprint(tf::createQuaternionFromYaw(yaw), new_origin);
00129 tf::Transform tf_base_to_footprint = tf_odom_to_base.inverse() * tf_odom_to_footprint;
00130
00131
00132
00133 m_brBaseFootPrint.sendTransform(tf::StampedTransform(tf_base_to_footprint, time, m_baseFrameId, m_baseFootPrintID));
00134 ROS_DEBUG("Published Transform %s --> %s", m_baseFrameId.c_str(), m_baseFootPrintID.c_str());
00135
00136 return;
00137
00138 }
00139
00140 int main(int argc, char** argv){
00141 ros::init(argc, argv, "base_footprint");
00142 BaseFootprint baseFootprint;
00143 ros::spin();
00144
00145 return 0;
00146 }
00147
00148