$search
00001 00055 #include <cob_3d_mapping_semantics/move_to_table_node.h> 00056 #include <cob_3d_mapping_common/polygon.h> 00057 #include <cob_3d_mapping_common/ros_msg_conversions.h> 00058 using namespace std ; 00059 00060 /* 00061 * MoveToTable constructor 00062 * */ 00063 MoveToTableNode::MoveToTableNode(){ 00064 move_to_table_server_ = n_.advertiseService ("move_to_table", &MoveToTableNode::moveToTableService, this); 00065 safe_dist_ = 0.7 ; // should be set to a predefined safe distance 00066 table_im_server_.reset (new interactive_markers::InteractiveMarkerServer ("geometry_map/map", "", false)); 00067 navigation_goal_pub_ = n_.advertise<geometry_msgs::PoseStamped> ("move_base_simple/goal", 1); 00068 } 00069 00070 Eigen::Quaternionf MoveToTableNode::faceTable(geometry_msgs::Pose finalPose){ 00071 00072 Eigen::Vector2f finalTarget ; 00073 finalTarget(0) = finalPose.position.x; 00074 finalTarget(1) = finalPose.position.y; 00075 00076 Eigen::Vector2f robotPose ; 00077 robotPose(0) = robotPose_.position.x; 00078 robotPose(1) = robotPose_.position.y; 00079 00080 00081 Eigen::Vector2f direction = finalTarget - robotPose ; 00082 direction.normalize() ; 00083 00084 float angle = atan2(direction(1), direction(0)); 00085 00086 Eigen::AngleAxis <float> ax1(angle, Eigen::Vector3f::UnitZ()); 00087 Eigen::Matrix3f rotMat = ax1.toRotationMatrix().block(0,0,2,2); 00088 00089 Eigen::Quaternionf quat(rotMat); 00090 return quat ; 00091 00092 } 00093 00094 geometry_msgs::Pose MoveToTableNode::transformToTableCoordinateSystem(cob_3d_mapping_msgs::Table &table,geometry_msgs::Pose &Pose) 00095 { 00096 Eigen::Matrix4f transformationMat ; 00097 Eigen::Quaternionf quat ; 00098 Eigen::Vector4f poseInTableCoordinateSys ; 00099 Eigen::Vector4f poseInOwnCoordinateSys ; 00100 Eigen::Affine3f poseInOwnCoordinateSysAffine ; 00101 00102 geometry_msgs::Pose translatedPose; 00103 00104 poseInOwnCoordinateSys << Pose.position.x, 00105 Pose.position.y, 00106 Pose.position.z, 00107 1; 00108 00109 quat.x() = table.pose.pose.orientation.x ; 00110 quat.y() = table.pose.pose.orientation.y ; 00111 quat.z() = table.pose.pose.orientation.z ; 00112 quat.w() = table.pose.pose.orientation.w ; 00113 00114 quat.normalize() ; 00115 00116 transformationMat.block(0,0,3,3) = quat.toRotationMatrix(); 00117 transformationMat.col(3).head(3) << table.pose.pose.position.x,table.pose.pose.position.y,table.pose.pose.position.z ; 00118 transformationMat.row(3) << 0,0,0,1 ; 00119 00120 transformToTableCoordinateSys_ = transformationMat ; 00121 00122 poseInTableCoordinateSys = transformationMat*poseInOwnCoordinateSys ; 00123 00124 translatedPose.position.x = poseInTableCoordinateSys(0) ; 00125 translatedPose.position.y = poseInTableCoordinateSys(1) ; 00126 translatedPose.position.z = poseInTableCoordinateSys(2) ; 00127 00128 return translatedPose ; 00129 00130 } 00131 00132 bool MoveToTableNode::doIntersect(float line){ 00133 00134 bool intersection(false) ; 00135 geometry_msgs::Pose point3,point4 ; 00136 00137 00138 if (line == table_.y_max) { 00139 point3.position.x = table_.x_max ; 00140 point3.position.y = table_.y_max ; 00141 00142 point4.position.x = table_.x_min ; 00143 point4.position.y = table_.y_max ; 00144 } 00145 00146 if (line == table_.x_max) { 00147 point3.position.x = table_.x_max ; 00148 point3.position.y = table_.y_max ; 00149 00150 point4.position.x = table_.x_max ; 00151 point4.position.y = table_.y_min ; 00152 } 00153 00154 if (line == table_.y_min) { 00155 point3.position.x = table_.x_min ; 00156 point3.position.y = table_.y_min ; 00157 00158 point4.position.x = table_.x_max ; 00159 point4.position.y = table_.y_min ; 00160 } 00161 00162 if (line == table_.x_min) { 00163 point3.position.x = table_.x_min ; 00164 point3.position.y = table_.y_min ; 00165 00166 point4.position.x = table_.x_min ; 00167 point4.position.y = table_.y_max ; 00168 } 00169 Eigen::Matrix3f mat1 ; 00170 mat1 << robotPoseInTableCoordinateSys_.position.x,robotPoseInTableCoordinateSys_.position.y,1, 00171 0,0,1, 00172 point3.position.x,point3.position.y,1 ; 00173 00174 Eigen::Matrix3f mat2 ; 00175 mat2 << robotPoseInTableCoordinateSys_.position.x,robotPoseInTableCoordinateSys_.position.y,1, 00176 0,0,1, 00177 point4.position.x,point4.position.y,1 ; 00178 00179 Eigen::Matrix3f mat3 ; 00180 mat3 << point3.position.x,point3.position.y,1, 00181 point4.position.x,point4.position.y,1, 00182 0,0,1; 00183 00184 Eigen::Matrix3f mat4 ; 00185 mat4 << point3.position.x,point3.position.y,1, 00186 point4.position.x,point4.position.y,1, 00187 robotPoseInTableCoordinateSys_.position.x,robotPoseInTableCoordinateSys_.position.y,1; 00188 00189 if (mat1.determinant()*mat2.determinant() <0 && 00190 mat3.determinant()*mat4.determinant() <0) { 00191 00192 intersection = true ; 00193 } 00194 return intersection ; 00195 } 00196 00197 geometry_msgs::Pose MoveToTableNode::findIntersectionPoint(){ 00198 00199 geometry_msgs::Pose IntersectionPoint ; 00200 00201 bool xMax = doIntersect(table_.x_max) ; // check if there is an intersection between the line passing through robot pose and table centroid and x=table.x_max 00202 bool yMax = doIntersect(table_.y_max) ; // doing the same for the line passing through robot pose and table centroid and y=table.y_max 00203 bool xMin = doIntersect(table_.x_min) ; // doing the same for the line passing through robot pose and table centroid and x=table.x_min 00204 bool yMin = doIntersect(table_.y_min) ; // doing the same for the line passing through robot pose and table centroid and x=table.x_max 00205 00206 if (xMax) { 00207 ROS_INFO("intersection with x = x_max ..."); 00208 IntersectionPoint.position.x = table_.x_max ; 00209 IntersectionPoint.position.y = (table_.x_max/robotPoseInTableCoordinateSys_.position.x)*robotPoseInTableCoordinateSys_.position.y ; 00210 } 00211 00212 else if (yMax) { 00213 ROS_INFO("intersection with y = y_max ..."); 00214 IntersectionPoint.position.y = table_.y_max ; 00215 IntersectionPoint.position.x = (table_.y_max/robotPoseInTableCoordinateSys_.position.y)*robotPoseInTableCoordinateSys_.position.x ; 00216 } 00217 00218 else if (xMin) { 00219 ROS_INFO("intersection with x = x_min ..."); 00220 IntersectionPoint.position.x = table_.x_min ; 00221 IntersectionPoint.position.y = (table_.x_min/robotPoseInTableCoordinateSys_.position.x)*robotPoseInTableCoordinateSys_.position.y ; 00222 } 00223 else if (yMin) { 00224 ROS_INFO("intersection with y = y_min ..."); 00225 IntersectionPoint.position.y = table_.y_min ; 00226 IntersectionPoint.position.x = (table_.y_min/robotPoseInTableCoordinateSys_.position.y)*robotPoseInTableCoordinateSys_.position.x ; 00227 } 00228 else { 00229 ROS_INFO("no intersection...") ; 00230 } 00231 00232 return IntersectionPoint ; 00233 00234 } 00235 00236 geometry_msgs::Pose MoveToTableNode::findSafeTargetPoint(){ 00237 00238 geometry_msgs::Pose intersectionPoint = findIntersectionPoint() ; 00239 geometry_msgs::Pose finalTarget ; 00240 00241 // solve the quadratic equation to find the point which its distance to the intersection point equals to safeDist_ 00242 00243 float a((robotPoseInTableCoordinateSys_.position.x*robotPoseInTableCoordinateSys_.position.x)+ 00244 (robotPoseInTableCoordinateSys_.position.y*robotPoseInTableCoordinateSys_.position.y)); 00245 00246 float b ((-2*(intersectionPoint.position.x *robotPoseInTableCoordinateSys_.position.x))- 00247 (2*(intersectionPoint.position.y *robotPoseInTableCoordinateSys_.position.y))); 00248 00249 float c((intersectionPoint.position.x*intersectionPoint.position.x)+(intersectionPoint.position.y*intersectionPoint.position.y) 00250 -(safe_dist_*safe_dist_)); 00251 00252 float discriminant((b*b)-4*a*c) ; 00253 float t1 = (-b + sqrt(discriminant))/(2*a) ; 00254 float t2 = (-b - sqrt(discriminant))/(2*a) ; 00255 float t ; 00256 if (t1>= 0 && t1 <=1) { 00257 t = t1 ; 00258 finalTarget.position.x = t * robotPoseInTableCoordinateSys_.position.x ; 00259 finalTarget.position.y = t * robotPoseInTableCoordinateSys_.position.y ; 00260 } 00261 else if (t2>= 0 && t2 <=1) { 00262 t = t2; 00263 finalTarget.position.x = t * robotPoseInTableCoordinateSys_.position.x ; 00264 finalTarget.position.y = t * robotPoseInTableCoordinateSys_.position.y ; 00265 } 00266 00267 return finalTarget ; 00268 00269 } 00270 00271 void MoveToTableNode::addMarkerForFinalPose(geometry_msgs::Pose finalPose) { 00272 00273 std::stringstream ss; 00274 visualization_msgs::InteractiveMarker imarker; 00275 ss.str(""); 00276 ss.clear(); 00277 ss << "target"; 00278 00279 imarker.name = ss.str(); 00280 // imarker.header = shape_.header; 00281 00282 imarker.header.frame_id = "/map" ; 00283 00284 visualization_msgs::Marker marker; 00285 // marker.header = shape_.header; 00286 marker.header.frame_id = "/map" ; 00287 00288 marker.type = visualization_msgs::Marker::LINE_STRIP; 00289 marker.action = visualization_msgs::Marker::ADD; 00290 marker.lifetime = ros::Duration (); 00291 00292 //set color 00293 marker.color.r = 0; 00294 marker.color.g = 1; 00295 marker.color.b = 0; 00296 marker.color.a = 1; 00297 00298 //set scale 00299 marker.scale.x = 0.1; 00300 marker.scale.y = 0.1; 00301 marker.scale.z = 0.1; 00302 00303 //set pose 00304 marker.points.resize (2); 00305 marker.points[0].x = robotPose_.position.x ; 00306 marker.points[0].y = robotPose_.position.y ; 00307 marker.points[0].z = robotPose_.position.z ; 00308 // 00309 marker.points[1].x = finalPose.position.x; 00310 marker.points[1].y = finalPose.position.y ; 00311 marker.points[1].z = finalPose.position.z; 00312 00313 visualization_msgs::InteractiveMarkerControl im_ctrl; 00314 00315 im_ctrl.always_visible = true; 00316 ss << "target_ctrl_" ; 00317 im_ctrl.name = ss.str (); 00318 im_ctrl.markers.push_back (marker); 00319 imarker.controls.push_back (im_ctrl); 00320 00321 table_im_server_->insert (imarker); 00322 table_im_server_->applyChanges() ; 00323 } 00324 00325 bool MoveToTableNode::moveToTableService (cob_3d_mapping_msgs::MoveToTable::Request &req, 00326 cob_3d_mapping_msgs::MoveToTable::Response &res) 00327 { 00328 ROS_INFO("calling move_to_table Service ...") ; 00329 Eigen::Vector4f vec,vecFinal; 00330 geometry_msgs::Pose finalTargetInMapCoordinateSys; 00331 00332 geometry_msgs::PoseStamped finalPose ; 00333 00334 00335 // get robot position 00336 tf::TransformListener listener; 00337 tf::StampedTransform transform ; 00338 00339 listener.waitForTransform("/map", "/base_link", ros::Time::now(), ros::Duration(3.0)); //The listener needs to get the information first before it can transform. 00340 listener.lookupTransform("/map","/base_link",ros::Time(0), transform); 00341 00342 robotPose_.position.x = transform.getOrigin().x() ; 00343 robotPose_.position.y = transform.getOrigin().y() ; 00344 robotPose_.position.z = transform.getOrigin().z() ; 00345 00346 robotPose_.orientation.x = transform.getRotation().x() ; 00347 robotPose_.orientation.y = transform.getRotation().y() ; 00348 robotPose_.orientation.z = transform.getRotation().z() ; 00349 robotPose_.orientation.w = transform.getRotation().w() ; 00350 00351 00352 // test 00353 // robotPose_.position.x = 1 ; 00354 // robotPose_.position.y = 1 ; 00355 // robotPose_.position.z = 0 ; 00356 00357 cob_3d_mapping::Polygon p; 00358 fromROSMsg(req.targetTable, p); 00359 Eigen::Affine3f pose; 00360 Eigen::Vector4f min_pt; 00361 Eigen::Vector4f max_pt; 00362 p.computePoseAndBoundingBox(pose,min_pt, max_pt); 00363 table_.pose.pose.position.x = pose.translation()(0); //poly_ptr->centroid[0]; 00364 table_.pose.pose.position.y = pose.translation()(1) ;//poly_ptr->centroid[1]; 00365 table_.pose.pose.position.z = pose.translation()(2) ;//poly_ptr->centroid[2]; 00366 Eigen::Quaternionf quaternion(pose.rotation()); 00367 00368 table_.pose.pose.orientation.x = quaternion.x(); 00369 table_.pose.pose.orientation.y = quaternion.y(); 00370 table_.pose.pose.orientation.z = quaternion.z(); 00371 table_.pose.pose.orientation.w = quaternion.w(); 00372 table_.x_min = min_pt(0); 00373 table_.x_max = max_pt(0); 00374 table_.y_min = min_pt(1); 00375 table_.y_max = max_pt(1); 00376 00377 robotPoseInTableCoordinateSys_ = transformToTableCoordinateSystem(table_,robotPose_) ; 00378 00379 ROS_WARN("robotPoseInTableCoordinateSys: x=%f , y= %f , z= %f",robotPoseInTableCoordinateSys_.position.x 00380 ,robotPoseInTableCoordinateSys_.position.y 00381 ,robotPoseInTableCoordinateSys_.position.z); 00382 00383 00384 00385 00386 geometry_msgs::Pose targetPointInTableCoordinateSys = findSafeTargetPoint() ; 00387 // targetPointInTableCoordinateSys.position.z = req.tableCentroid.position.z ; 00388 00389 vec << targetPointInTableCoordinateSys.position.x , 00390 targetPointInTableCoordinateSys.position.y , 00391 targetPointInTableCoordinateSys.position.z , 00392 1; 00393 vecFinal << transformToTableCoordinateSys_.inverse() * vec ; 00394 00395 finalTargetInMapCoordinateSys.position.x = vecFinal (0) ; 00396 finalTargetInMapCoordinateSys.position.y = vecFinal (1) ; 00397 // finalTargetInMapCoordinateSys.position.z = vecFinal (2) ; 00398 ROS_WARN("Final Target point: x=%f , y= %f , z= %f",finalTargetInMapCoordinateSys.position.x 00399 ,finalTargetInMapCoordinateSys.position.y 00400 ,finalTargetInMapCoordinateSys.position.z); 00401 00402 addMarkerForFinalPose (finalTargetInMapCoordinateSys) ; 00403 finalPose.header.frame_id = "/map" ; 00404 // res.goalPoint.header.frame_id = "/map" ; 00405 00406 // set position 00407 finalPose.pose.position.x = vecFinal (0) ; 00408 finalPose.pose.position.y = vecFinal (1) ; 00409 finalPose.pose.position.z = 0;//vecFinal (2) ; 00410 00411 // set orientation 00412 Eigen::Quaternionf quat = faceTable(finalTargetInMapCoordinateSys) ; 00413 00414 finalPose.pose.orientation.x = quat.x(); 00415 finalPose.pose.orientation.y = quat.y(); 00416 finalPose.pose.orientation.z = quat.z(); 00417 finalPose.pose.orientation.w = quat.w(); 00418 00419 addMarkerForFinalPose (finalTargetInMapCoordinateSys) ; 00420 00421 navigation_goal_pub_.publish(finalPose) ; 00422 return true; 00423 } 00424 00425 int 00426 main (int argc, char** argv) 00427 { 00428 ros::init (argc, argv, "move_to_table_node"); 00429 ROS_INFO("move_to_table node started...."); 00430 MoveToTableNode mtt; 00431 00432 00433 while (ros::ok()){ 00434 ros::spin(); 00435 } 00436 }