$search
00001 00062 //################## 00063 //#### includes #### 00064 00065 // standard includes 00066 //-- 00067 00068 00069 // ROS includes 00070 #include <ros/ros.h> 00071 #include <tf/transform_listener.h> 00072 #include <tf_conversions/tf_kdl.h> 00073 00074 // ROS message includes 00075 #include <sensor_msgs/CameraInfo.h> 00076 #include <cob_srvs/Trigger.h> 00077 00078 00079 #include <dynamic_reconfigure/server.h> 00080 #include <cob_3d_mapping_common/keyframe_detectorConfig.h> 00081 00082 00083 00084 using namespace tf; 00085 using namespace cob_3d_mapping_common; 00086 00087 //#################### 00088 //#### node class #### 00089 class KeyframeDetector //: protected Reconfigurable_Node<keyframe_detectorConfig> 00090 { 00091 00092 public: 00093 // Constructor 00094 KeyframeDetector() 00095 : first_(true), trigger_always_(false) 00096 { 00097 config_server_.setCallback(boost::bind(&KeyframeDetector::dynReconfCallback, this, _1, _2)); 00098 point_cloud_sub_ = n_.subscribe("camera_info", 1, &KeyframeDetector::pointCloudSubCallback, this); 00099 transform_sub_ = n_.subscribe("/tf", 1, &KeyframeDetector::transformSubCallback, this); 00100 keyframe_trigger_client_ = n_.serviceClient<cob_srvs::Trigger>("trigger_keyframe"); 00101 00102 /*n_.param("aggregate_point_map/r_limit",r_limit_,0.01); 00103 n_.param("aggregate_point_map/y_limit",y_limit_,0.01); 00104 n_.param("aggregate_point_map/p_limit",p_limit_,0.01); 00105 n_.param("aggregate_point_map/distance_limit",distance_limit_,0.03); 00106 n_.param("aggregate_point_map/trigger_always",trigger_always_,false);*/ 00107 00108 //setReconfigureCallback(boost::bind(&callback, this, _1, _2)); 00109 } 00110 00111 00112 // Destructor 00113 ~KeyframeDetector() 00114 { 00116 } 00117 00118 void dynReconfCallback(cob_3d_mapping_common::keyframe_detectorConfig &config, uint32_t level) 00119 { 00120 r_limit_ = config.r_limit; 00121 p_limit_ = config.p_limit; 00122 y_limit_ = config.y_limit; 00123 distance_limit_ = config.distance_limit; 00124 trigger_always_ = config.trigger_always; 00125 } 00126 00127 // callback for dynamic reconfigure 00128 /*static void callback(KeyframeDetector *inst, keyframe_detectorConfig &config, uint32_t level) 00129 { 00130 if(!inst) 00131 return; 00132 00133 boost::mutex::scoped_lock l2(inst->m_mutex_pointCloudSubCallback); 00134 00135 inst->r_limit_ = config.r_limit; 00136 inst->p_limit_ = config.p_limit; 00137 inst->y_limit_ = config.y_limit; 00138 inst->distance_limit_ = config.distance_limit; 00139 inst->trigger_always_ = config.trigger_always; 00140 00141 }*/ 00142 00143 void 00144 pointCloudSubCallback(sensor_msgs::CameraInfo::ConstPtr pc_in) 00145 { 00146 frame_id_ = pc_in->header.frame_id; 00147 //point_cloud_sub_.shutdown(); 00148 } 00149 00150 void 00151 transformSubCallback(const tf::tfMessageConstPtr& msg) 00152 { 00153 r_limit_=p_limit_=y_limit_=distance_limit_=0.01; 00154 boost::mutex::scoped_lock l(m_mutex_pointCloudSubCallback); 00155 00156 if(frame_id_.size()<1) { 00157 ROS_WARN("frame id is missing"); 00158 //frame_id_="head_cam3d_link"; 00159 return; 00160 } 00161 00162 //pcl::PointCloud<Point>::Ptr pc = pcl::PointCloud<Point>::Ptr(new pcl::PointCloud<Point>); 00163 00164 StampedTransform transform; 00165 /* 00166 std::string mapped_src = assert_resolved(tf_prefix_, source_frame); 00167 00168 if (mapped_tgt == mapped_src) { 00169 transform.setIdentity(); 00170 transform.child_frame_id_ = mapped_src; 00171 transform.frame_id_ = mapped_tgt; 00172 transform.stamp_ = now(); 00173 return; 00174 } 00175 */ 00176 try 00177 { 00178 //ROS_INFO("%s", frame_id_.c_str()); 00179 std::stringstream ss2; 00180 tf_listener_.waitForTransform("/map", frame_id_, ros::Time(0), ros::Duration(0.1)); 00181 tf_listener_.lookupTransform("/map", frame_id_, ros::Time(0), transform); 00182 KDL::Frame frame_KDL, frame_KDL_old; 00183 tf::TransformTFToKDL(transform, frame_KDL); 00184 tf::TransformTFToKDL(transform_old_, frame_KDL_old); 00185 double r,p,y; 00186 frame_KDL.M.GetRPY(r,p,y); 00187 double r_old,p_old,y_old; 00188 frame_KDL_old.M.GetRPY(r_old,p_old,y_old); 00189 00190 if(trigger_always_ || first_ || fabs(r-r_old) > r_limit_ || fabs(p-p_old) > p_limit_ || fabs(y-y_old) > y_limit_ || 00191 transform.getOrigin().distance(transform_old_.getOrigin()) > distance_limit_) 00192 { 00193 if(triggerKeyFrame()) { 00194 transform_old_ = transform; 00195 first_=false; 00196 } 00197 } 00198 } 00199 catch (tf::TransformException ex) 00200 { 00201 ROS_ERROR("[keyframe_detector] : %s",ex.what()); 00202 } 00203 } 00204 00205 ros::NodeHandle n_; 00206 ros::Time stamp_; 00207 00208 bool triggerKeyFrame() { 00209 cob_srvs::Trigger::Request req; 00210 cob_srvs::Trigger::Response res; 00211 if(keyframe_trigger_client_.call(req,res)) 00212 { 00213 ROS_DEBUG("KeyFrame service called [OK]."); 00214 } 00215 else 00216 { 00217 ROS_WARN("KeyFrame service called [FAILED].", res.success.data); 00218 return false; 00219 } 00220 00221 return res.success.data; 00222 } 00223 00224 00225 protected: 00226 ros::Subscriber point_cloud_sub_, transform_sub_; //subscriber for input pc 00227 TransformListener tf_listener_; 00228 ros::ServiceClient keyframe_trigger_client_; 00229 dynamic_reconfigure::Server<cob_3d_mapping_common::keyframe_detectorConfig> config_server_; 00230 00231 bool first_; 00232 bool trigger_always_; 00233 00234 StampedTransform transform_old_; 00235 00236 std::string frame_id_; 00237 00238 00239 double y_limit_; 00240 double distance_limit_; 00241 double r_limit_; 00242 double p_limit_; 00243 00244 boost::mutex m_mutex_pointCloudSubCallback; 00245 00246 }; 00247 00248 00249 int main (int argc, char** argv) 00250 { 00251 ros::init (argc, argv, "keyframe_detector"); 00252 00253 KeyframeDetector kd; 00254 00255 ros::Rate loop_rate(10); 00256 while (ros::ok()) 00257 { 00258 ros::spinOnce (); 00259 //fov.transformNormals(); 00260 loop_rate.sleep(); 00261 } 00262 }