Go to the documentation of this file.00001 #include <math.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <ros/ros.h>
00005
00006 #include <nav_msgs/Odometry.h>
00007
00008 #include <tf/transform_datatypes.h>
00009 #include <tf/transform_listener.h>
00010 #include <tf/transform_broadcaster.h>
00011
00012 const double PI = 3.1415926;
00013 const double rad2deg = 180 / PI;
00014 const double deg2rad = PI / 180;
00015
00016 double timeOdomBefBA;
00017 double timeOdomAftBA;
00018
00019 double rollRec, pitchRec, yawRec;
00020 double txRec, tyRec, tzRec;
00021
00022 float transformBefBA[6] = {0};
00023 float transformAftBA[6] = {0};
00024
00025 ros::Publisher *voData2PubPointer = NULL;
00026 tf::TransformBroadcaster *tfBroadcaster2Pointer = NULL;
00027 nav_msgs::Odometry voData2;
00028 tf::StampedTransform voDataTrans2;
00029
00030 void transformAssociateToBA()
00031 {
00032 float txDiff = txRec - transformBefBA[3];
00033 float tyDiff = tyRec - transformBefBA[4];
00034 float tzDiff = tzRec - transformBefBA[5];
00035
00036 float x1 = cos(yawRec) * txDiff + sin(yawRec) * tzDiff;
00037 float y1 = tyDiff;
00038 float z1 = -sin(yawRec) * txDiff + cos(yawRec) * tzDiff;
00039
00040 float x2 = x1;
00041 float y2 = cos(pitchRec) * y1 - sin(pitchRec) * z1;
00042 float z2 = sin(pitchRec) * y1 + cos(pitchRec) * z1;
00043
00044 txDiff = cos(rollRec) * x2 + sin(rollRec) * y2;
00045 tyDiff = -sin(rollRec) * x2 + cos(rollRec) * y2;
00046 tzDiff = z2;
00047
00048 pitchRec += transformAftBA[0] - transformBefBA[0];
00049 yawRec += transformAftBA[1] - transformBefBA[1];
00050 rollRec += transformAftBA[2] - transformBefBA[2];
00051
00052 x1 = cos(rollRec) * txDiff - sin(rollRec) * tyDiff;
00053 y1 = sin(rollRec) * txDiff + cos(rollRec) * tyDiff;
00054 z1 = tzDiff;
00055
00056 x2 = x1;
00057 y2 = cos(pitchRec) * y1 + sin(pitchRec) * z1;
00058 z2 = -sin(pitchRec) * y1 + cos(pitchRec) * z1;
00059
00060 txDiff = cos(yawRec) * x2 - sin(yawRec) * z2;
00061 tyDiff = y2;
00062 tzDiff = sin(yawRec) * x2 + cos(yawRec) * z2;
00063
00064 txRec = transformAftBA[3] + txDiff;
00065 tyRec = transformAftBA[4] + tyDiff;
00066 tzRec = transformAftBA[5] + tzDiff;
00067 }
00068
00069 void voDataHandler(const nav_msgs::Odometry::ConstPtr& voData)
00070 {
00071 if (fabs(timeOdomBefBA - timeOdomAftBA) < 0.005) {
00072
00073 geometry_msgs::Quaternion geoQuat = voData->pose.pose.orientation;
00074 tf::Matrix3x3(tf::Quaternion(geoQuat.z, -geoQuat.x, -geoQuat.y, geoQuat.w)).getRPY(rollRec, pitchRec, yawRec);
00075
00076 txRec = voData->pose.pose.position.x;
00077 tyRec = voData->pose.pose.position.y;
00078 tzRec = voData->pose.pose.position.z;
00079
00080 transformAssociateToBA();
00081
00082 geoQuat = tf::createQuaternionMsgFromRollPitchYaw(rollRec, pitchRec, yawRec);
00083
00084 voData2.header.stamp = voData->header.stamp;
00085 voData2.pose.pose.orientation.x = -geoQuat.y;
00086 voData2.pose.pose.orientation.y = -geoQuat.z;
00087 voData2.pose.pose.orientation.z = geoQuat.x;
00088 voData2.pose.pose.orientation.w = geoQuat.w;
00089 voData2.pose.pose.position.x = txRec;
00090 voData2.pose.pose.position.y = tyRec;
00091 voData2.pose.pose.position.z = tzRec;
00092 voData2PubPointer->publish(voData2);
00093
00094 voDataTrans2.stamp_ = voData->header.stamp;
00095 voDataTrans2.setRotation(tf::Quaternion(-geoQuat.y, -geoQuat.z, geoQuat.x, geoQuat.w));
00096 voDataTrans2.setOrigin(tf::Vector3(txRec, tyRec, tzRec));
00097 tfBroadcaster2Pointer->sendTransform(voDataTrans2);
00098 }
00099 }
00100
00101 void odomBefBAHandler(const nav_msgs::Odometry::ConstPtr& odomBefBA)
00102 {
00103 timeOdomBefBA = odomBefBA->header.stamp.toSec();
00104
00105 double roll, pitch, yaw;
00106 geometry_msgs::Quaternion geoQuat = odomBefBA->pose.pose.orientation;
00107 tf::Matrix3x3(tf::Quaternion(geoQuat.z, -geoQuat.x, -geoQuat.y, geoQuat.w)).getRPY(roll, pitch, yaw);
00108
00109 transformBefBA[0] = pitch;
00110 transformBefBA[1] = yaw;
00111 transformBefBA[2] = roll;
00112
00113 transformBefBA[3] = odomBefBA->pose.pose.position.x;
00114 transformBefBA[4] = odomBefBA->pose.pose.position.y;
00115 transformBefBA[5] = odomBefBA->pose.pose.position.z;
00116 }
00117
00118 void odomAftBAHandler(const nav_msgs::Odometry::ConstPtr& odomAftBA)
00119 {
00120 timeOdomAftBA = odomAftBA->header.stamp.toSec();
00121
00122 double roll, pitch, yaw;
00123 geometry_msgs::Quaternion geoQuat = odomAftBA->pose.pose.orientation;
00124 tf::Matrix3x3(tf::Quaternion(geoQuat.z, -geoQuat.x, -geoQuat.y, geoQuat.w)).getRPY(roll, pitch, yaw);
00125
00126 transformAftBA[0] = pitch;
00127 transformAftBA[1] = yaw;
00128 transformAftBA[2] = roll;
00129
00130 transformAftBA[3] = odomAftBA->pose.pose.position.x;
00131 transformAftBA[4] = odomAftBA->pose.pose.position.y;
00132 transformAftBA[5] = odomAftBA->pose.pose.position.z;
00133 }
00134
00135 int main(int argc, char** argv)
00136 {
00137 ros::init(argc, argv, "transformMaintenance");
00138 ros::NodeHandle nh;
00139
00140 ros::Subscriber voDataSub = nh.subscribe<nav_msgs::Odometry>
00141 ("/cam_to_init", 1, voDataHandler);
00142
00143 ros::Subscriber odomBefBASub = nh.subscribe<nav_msgs::Odometry>
00144 ("/bef_ba_to_init", 1, odomBefBAHandler);
00145
00146 ros::Subscriber odomAftBASub = nh.subscribe<nav_msgs::Odometry>
00147 ("/aft_ba_to_init", 1, odomAftBAHandler);
00148
00149 ros::Publisher voData2Pub = nh.advertise<nav_msgs::Odometry> ("/cam2_to_init", 1);
00150 voData2PubPointer = &voData2Pub;
00151 voData2.header.frame_id = "/camera_init";
00152 voData2.child_frame_id = "/camera2";
00153
00154 tf::TransformBroadcaster tfBroadcaster2;
00155 tfBroadcaster2Pointer = &tfBroadcaster2;
00156 voDataTrans2.frame_id_ = "/camera_init";
00157 voDataTrans2.child_frame_id_ = "/camera2";
00158
00159 ros::spin();
00160
00161 return 0;
00162 }