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 #include <ros/ros.h>
00030 #include <tf/transform_listener.h>
00031 #include <tf/transform_broadcaster.h>
00032 #include <string>
00033 #include <iostream>
00034
00035 std::ostream& operator<<(std::ostream& os, const tf::Transform& transform)
00036 {
00037 using std::setw;
00038 tf::Vector3 origin = transform.getOrigin();
00039 tf::Quaternion quat = transform.getRotation();
00040 os << setw(10) << origin.x() << " " << setw(10) << origin.y() << " " << setw(10) << origin.z() << " ";
00041 os << setw(10) << quat.x() << " " << setw(10) << quat.y() << " " << setw(10) << quat.z() << " " << setw(10) << quat.w();
00042 return os;
00043 }
00044
00045 void printHeader(std::ostream& os, const std::string& frame_id)
00046 {
00047 os << frame_id << ".x " << frame_id << ".y " << frame_id << ".z "
00048 << frame_id << ".qx " << frame_id << ".qy " << frame_id << ".qz " << frame_id << ".qw ";
00049 }
00050
00051 int main(int argc, char** argv)
00052 {
00053 ros::init(argc, argv, "tf_filter");
00054
00055 ros::NodeHandle nh;
00056 ros::NodeHandle nhp("~");
00057
00058 std::string reference_frame_id;
00059 std::string child_frame_id;
00060 double frequency, ramp_wwf;
00061 int num_samples_wwf, wwf_index;
00062 bool full_arrays = false;
00063
00064 nhp.param("reference_frame_id", reference_frame_id, std::string("/base_link"));
00065 nhp.param("child_frame_id", child_frame_id, std::string("/camera"));
00066 nhp.param("frequency", frequency, 100.0);
00067
00068
00069 nhp.param("ramp_wwf", ramp_wwf, 0.5);
00070 nhp.param("num_samples_wwf", num_samples_wwf, 10);
00071
00072 ROS_INFO("TF Filter initiated.\n\tPARAMETERS: \
00073 \n\t * Reference frame ID: %s \
00074 \n\t * Child frame ID: %s \
00075 \n\t * Frequency: %f \
00076 \n\t * Ramp WWF: %f \
00077 \n\t * Num samples WWF: %d",
00078 reference_frame_id.c_str(),
00079 child_frame_id.c_str(),
00080 frequency,
00081 ramp_wwf,
00082 num_samples_wwf);
00083
00084 double * x_array, * y_array, * z_array;
00085 double * sR_array, * cR_array, * sP_array, * cP_array, * sY_array, * cY_array;
00086 double * t_array, * w_array;
00087
00088
00089 wwf_index = 0;
00090 x_array = new double[num_samples_wwf];
00091 y_array = new double[num_samples_wwf];
00092 z_array = new double[num_samples_wwf];
00093 sR_array = new double[num_samples_wwf];
00094 cR_array = new double[num_samples_wwf];
00095 sP_array = new double[num_samples_wwf];
00096 cP_array = new double[num_samples_wwf];
00097 sY_array = new double[num_samples_wwf];
00098 cY_array = new double[num_samples_wwf];
00099 t_array = new double[num_samples_wwf];
00100 w_array = new double[num_samples_wwf];
00101 for(int i = 0; i< num_samples_wwf; i++){
00102 x_array[i] = 0.0;
00103 y_array[i] = 0.0;
00104 z_array[i] = 0.0;
00105 sR_array[i] = 0.0;
00106 cR_array[i] = 0.0;
00107 sP_array[i] = 0.0;
00108 cP_array[i] = 0.0;
00109 sY_array[i] = 0.0;
00110 cY_array[i] = 0.0;
00111 t_array[i] = 0.0;
00112 w_array[i] = 0.0;
00113 }
00114
00115 tf::TransformListener listener;
00116 tf::TransformBroadcaster broadcaster;
00117
00118 ros::Rate rate(frequency);
00119 while (ros::ok())
00120 {
00121 rate.sleep();
00122
00123
00124 if (!ros::Time::isValid()) continue;
00125 ros::Time requested_time = ros::Time(0);
00126 tf::StampedTransform transform;
00127 try
00128 {
00129
00130 ros::Duration timeout(2 / frequency);
00131 ros::Duration polling_sleep_duration(0.5 / frequency);
00132 listener.waitForTransform(
00133 reference_frame_id,
00134 child_frame_id,
00135 requested_time,
00136 timeout,
00137 polling_sleep_duration);
00138 listener.lookupTransform(
00139 reference_frame_id,
00140 child_frame_id,
00141 requested_time,
00142 transform);
00143
00144 ROS_DEBUG_STREAM("Received transform: " << transform);
00145 ROS_DEBUG_STREAM("With frame_id: " << transform.frame_id_ << " and child_id " << transform.child_frame_id_);
00146
00147
00148 double roll, pitch, yaw;
00149 tf::Matrix3x3 rotm(transform.getRotation());
00150 rotm.getRPY(roll, pitch, yaw);
00151
00152 x_array[wwf_index] = transform.getOrigin().x();
00153 y_array[wwf_index] = transform.getOrigin().y();
00154 z_array[wwf_index] = transform.getOrigin().z();
00155 sR_array[wwf_index] = sin(roll);
00156 cR_array[wwf_index] = cos(roll);
00157 sP_array[wwf_index] = sin(pitch);
00158 cP_array[wwf_index] = cos(pitch);
00159 sY_array[wwf_index] = sin(yaw);
00160 cY_array[wwf_index] = cos(yaw);
00161
00162
00163 ros::Time now = transform.stamp_;
00164 t_array[wwf_index] = now.toSec();
00165
00166
00167
00168 int num_elem = num_samples_wwf;
00169 if(!full_arrays){
00170 num_elem = wwf_index + 1;
00171 }
00172 double w_total = 0.0;
00173 for(int i = 0; i < num_elem; i++){
00174 double t_aux = t_array[i] - t_array[wwf_index];
00175 w_array[i] = std::max(0.0,ramp_wwf*t_aux + 1);
00176 w_total += w_array[i];
00177 }
00178
00179
00180 double w_aux;
00181 double x, y, z, sinR, cosR, sinP, cosP, sinY, cosY;
00182 x = y = z = sinR = cosR = sinP = cosP = sinY = cosY = 0.0;
00183
00184
00185 for(int i = 0; i < num_elem; i++){
00186 w_aux = w_array[i]/w_total;
00187 x += w_aux * x_array[i];
00188 y += w_aux * y_array[i];
00189 z += w_aux * z_array[i];
00190 sinR += w_aux * sR_array[i];
00191 cosR += w_aux * cR_array[i];
00192 sinP += w_aux * sP_array[i];
00193 cosP += w_aux * cP_array[i];
00194 sinY += w_aux * sY_array[i];
00195 cosY += w_aux * cY_array[i];
00196 }
00197
00198 tf::Vector3 orig(x,y,z);
00199
00200 roll = atan2(sinR, cosR);
00201 pitch = atan2(sinP, cosP);
00202 yaw = atan2(sinY, cosY);
00203
00204 tf::Quaternion quat;
00205 quat.setRPY(roll, pitch, yaw);
00206
00207 transform.setOrigin(orig);
00208 transform.setRotation(quat);
00209
00210
00211 transform.child_frame_id_ = transform.child_frame_id_ + "_filtered";
00212 broadcaster.sendTransform(transform);
00213
00214
00215 wwf_index++;
00216 if (wwf_index==num_samples_wwf){
00217 full_arrays = true;
00218 wwf_index = 0;
00219 }
00220 }
00221 catch (const tf::TransformException& e)
00222 {
00223 std::cerr << "TransformException caught: " << e.what() << std::endl;
00224 }
00225 }
00226 return 0;
00227 }
00228