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 #include "ar_pose/ar_single.h"
00026
00027 int main (int argc, char **argv)
00028 {
00029 ros::init (argc, argv, "ar_single");
00030 ros::NodeHandle n;
00031 ar_pose::ARSinglePublisher arSingle(n);
00032 ros::spin();
00033 return 0;
00034 }
00035
00036 namespace ar_pose
00037 {
00038 ARSinglePublisher::ARSinglePublisher (ros::NodeHandle & n):n_ (n), it_ (n_)
00039 {
00040 std::string local_path;
00041 std::string package_path = ros::package::getPath (ROS_PACKAGE_NAME);
00042 std::string default_path = "data/patt.hiro";
00043 ros::NodeHandle n_param ("~");
00044 XmlRpc::XmlRpcValue xml_marker_center;
00045
00046 ROS_INFO("Starting ArSinglePublisher");
00047
00048
00049
00050 if (!n_param.getParam("publish_tf", publishTf_))
00051 publishTf_ = true;
00052 ROS_INFO ("\tPublish transforms: %d", publishTf_);
00053
00054 if (!n_param.getParam("publish_visual_markers", publishVisualMarkers_))
00055 publishVisualMarkers_ = true;
00056 ROS_INFO ("\tPublish visual markers: %d", publishVisualMarkers_);
00057
00058 if (!n_param.getParam("threshold", threshold_))
00059 threshold_ = 100;
00060 ROS_INFO ("\tThreshold: %d", threshold_);
00061
00062 if (!n_param.getParam("marker_width", markerWidth_))
00063 markerWidth_ = 80.0;
00064 ROS_INFO ("\tMarker Width: %.1f", markerWidth_);
00065
00066 if (!n_param.getParam("reverse_transform", reverse_transform_))
00067 reverse_transform_ = false;
00068 ROS_INFO("\tReverse Transform: %d", reverse_transform_);
00069
00070 if (!n_param.getParam("marker_frame", markerFrame_))
00071 markerFrame_ = "ar_marker";
00072 ROS_INFO ("\tMarker frame: %s", markerFrame_.c_str());
00073
00074
00075
00076
00077 if (!n_param.getParam("use_history", useHistory_))
00078 useHistory_ = true;
00079 ROS_INFO("\tUse history: %d", useHistory_);
00080
00081
00082
00083
00084
00085
00086 n_param.param ("marker_pattern", local_path, default_path);
00087 if (local_path.compare(0,5,"data/") == 0){
00088
00089 sprintf (pattern_filename_, "%s/%s", package_path.c_str (), local_path.c_str ());
00090 }
00091 else{
00092
00093 sprintf (pattern_filename_, "%s", local_path.c_str ());
00094 }
00095
00096 n_param.param ("marker_center_x", marker_center_[0], 0.0);
00097 n_param.param ("marker_center_y", marker_center_[1], 0.0);
00098 ROS_INFO ("\tMarker Center: (%.1f,%.1f)", marker_center_[0], marker_center_[1]);
00099
00100
00101
00102 ROS_INFO ("Subscribing to info topic");
00103 sub_ = n_.subscribe (cameraInfoTopic_, 1, &ARSinglePublisher::camInfoCallback, this);
00104 getCamInfo_ = false;
00105
00106
00107
00108 arMarkerPub_ = n_.advertise<ar_pose::ARMarker>("ar_pose_marker", 0);
00109 if(publishVisualMarkers_){
00110 rvizMarkerPub_ = n_.advertise<visualization_msgs::Marker>("visualization_marker", 0);
00111 }
00112 }
00113
00114 ARSinglePublisher::~ARSinglePublisher (void)
00115 {
00116
00117 arVideoCapStop ();
00118 arVideoClose ();
00119 }
00120
00121 void ARSinglePublisher::camInfoCallback (const sensor_msgs::CameraInfoConstPtr & cam_info)
00122 {
00123 if (!getCamInfo_)
00124 {
00125 cam_info_ = (*cam_info);
00126
00127 cam_param_.xsize = cam_info_.width;
00128 cam_param_.ysize = cam_info_.height;
00129
00130 cam_param_.mat[0][0] = cam_info_.P[0];
00131 cam_param_.mat[1][0] = cam_info_.P[4];
00132 cam_param_.mat[2][0] = cam_info_.P[8];
00133 cam_param_.mat[0][1] = cam_info_.P[1];
00134 cam_param_.mat[1][1] = cam_info_.P[5];
00135 cam_param_.mat[2][1] = cam_info_.P[9];
00136 cam_param_.mat[0][2] = cam_info_.P[2];
00137 cam_param_.mat[1][2] = cam_info_.P[6];
00138 cam_param_.mat[2][2] = cam_info_.P[10];
00139 cam_param_.mat[0][3] = cam_info_.P[3];
00140 cam_param_.mat[1][3] = cam_info_.P[7];
00141 cam_param_.mat[2][3] = cam_info_.P[11];
00142
00143 cam_param_.dist_factor[0] = cam_info_.K[2];
00144 cam_param_.dist_factor[1] = cam_info_.K[5];
00145 if ( cam_info_.distortion_model == "plumb_bob" && cam_info_.D.size() == 5)
00146 cam_param_.dist_factor[2] = -100*cam_info_.D[0];
00147 else
00148 cam_param_.dist_factor[2] = 0;
00149
00150 cam_param_.dist_factor[3] = 1.0;
00151
00152 arInit();
00153
00154 ROS_INFO ("Subscribing to image topic");
00155 cam_sub_ = it_.subscribe (cameraImageTopic_, 1, &ARSinglePublisher::getTransformationCallback, this);
00156 getCamInfo_ = true;
00157 }
00158 }
00159
00160 void ARSinglePublisher::arInit ()
00161 {
00162 arInitCparam (&cam_param_);
00163
00164 ROS_INFO ("*** Camera Parameter ***");
00165 arParamDisp (&cam_param_);
00166
00167
00168 ROS_INFO ("Loading pattern");
00169 patt_id_ = arLoadPatt (pattern_filename_);
00170 if (patt_id_ < 0)
00171 {
00172 ROS_ERROR ("Pattern file load error: %s", pattern_filename_);
00173 ROS_BREAK ();
00174 }
00175
00176 sz_ = cvSize (cam_param_.xsize, cam_param_.ysize);
00177 #if ROS_VERSION_MINIMUM(1, 9, 0)
00178
00179 cv_bridge::CvImagePtr capture_;
00180 #else
00181
00182 capture_ = cvCreateImage (sz_, IPL_DEPTH_8U, 4);
00183 #endif
00184
00185 }
00186
00187 void ARSinglePublisher::getTransformationCallback (const sensor_msgs::ImageConstPtr & image_msg)
00188 {
00189 ARUint8 *dataPtr;
00190 ARMarkerInfo *marker_info;
00191 int marker_num;
00192 int i, k;
00193
00194
00195
00196
00197
00198 #if ROS_VERSION_MINIMUM(1, 9, 0)
00199 try
00200 {
00201 capture_ = cv_bridge::toCvCopy (image_msg, sensor_msgs::image_encodings::BGR8);
00202 }
00203 catch (cv_bridge::Exception& e)
00204 {
00205 ROS_ERROR("cv_bridge exception: %s", e.what());
00206 }
00207 dataPtr = (ARUint8 *) ((IplImage) capture_->image).imageData;
00208 #else
00209 try
00210 {
00211 capture_ = bridge_.imgMsgToCv (image_msg, "bgr8");
00212 }
00213 catch (sensor_msgs::CvBridgeException & e)
00214 {
00215 ROS_ERROR("cv_bridge exception: %s", e.what());
00216 }
00217 dataPtr = (ARUint8 *) capture_->imageData;
00218 #endif
00219
00220
00221 if (arDetectMarker (dataPtr, threshold_, &marker_info, &marker_num) < 0)
00222 {
00223 ROS_FATAL ("arDetectMarker failed");
00224 ROS_BREAK ();
00225 }
00226
00227
00228 k = -1;
00229 for (i = 0; i < marker_num; i++)
00230 {
00231 if (marker_info[i].id == patt_id_)
00232 {
00233 ROS_DEBUG ("Found pattern: %d ", patt_id_);
00234
00235
00236 if (k == -1)
00237 k = i;
00238 else if (marker_info[k].cf < marker_info[i].cf)
00239 k = i;
00240 }
00241 }
00242
00243 if (k != -1)
00244 {
00245
00246 double arQuat[4], arPos[3];
00247
00248 if (!useHistory_ || contF == 0)
00249 arGetTransMat (&marker_info[k], marker_center_, markerWidth_, marker_trans_);
00250 else
00251 arGetTransMatCont (&marker_info[k], marker_trans_, marker_center_, markerWidth_, marker_trans_);
00252
00253 contF = 1;
00254
00255
00256 arUtilMat2QuatPos (marker_trans_, arQuat, arPos);
00257
00258
00259
00260 double quat[4], pos[3];
00261
00262 pos[0] = arPos[0] * AR_TO_ROS;
00263 pos[1] = arPos[1] * AR_TO_ROS;
00264 pos[2] = arPos[2] * AR_TO_ROS;
00265
00266 quat[0] = -arQuat[0];
00267 quat[1] = -arQuat[1];
00268 quat[2] = -arQuat[2];
00269 quat[3] = arQuat[3];
00270
00271 ROS_DEBUG (" QUAT: Pos x: %3.5f y: %3.5f z: %3.5f", pos[0], pos[1], pos[2]);
00272 ROS_DEBUG (" Quat qx: %3.5f qy: %3.5f qz: %3.5f qw: %3.5f", quat[0], quat[1], quat[2], quat[3]);
00273
00274
00275
00276 ar_pose_marker_.header.frame_id = image_msg->header.frame_id;
00277 ar_pose_marker_.header.stamp = image_msg->header.stamp;
00278 ar_pose_marker_.id = marker_info->id;
00279
00280 ar_pose_marker_.pose.pose.position.x = pos[0];
00281 ar_pose_marker_.pose.pose.position.y = pos[1];
00282 ar_pose_marker_.pose.pose.position.z = pos[2];
00283
00284 ar_pose_marker_.pose.pose.orientation.x = quat[0];
00285 ar_pose_marker_.pose.pose.orientation.y = quat[1];
00286 ar_pose_marker_.pose.pose.orientation.z = quat[2];
00287 ar_pose_marker_.pose.pose.orientation.w = quat[3];
00288
00289 ar_pose_marker_.confidence = marker_info->cf;
00290
00291 arMarkerPub_.publish(ar_pose_marker_);
00292 ROS_DEBUG ("Published ar_single marker");
00293
00294
00295
00296 #if ROS_VERSION_MINIMUM(1, 9, 0)
00297 tf::Quaternion rotation (quat[0], quat[1], quat[2], quat[3]);
00298 tf::Vector3 origin (pos[0], pos[1], pos[2]);
00299 tf::Transform t (rotation, origin);
00300 #else
00301
00302 btQuaternion rotation (quat[0], quat[1], quat[2], quat[3]);
00303 btVector3 origin (pos[0], pos[1], pos[2]);
00304 btTransform t (rotation, origin);
00305 #endif
00306
00307
00308 if(publishTf_)
00309 {
00310 if(reverse_transform_)
00311 {
00312 tf::StampedTransform markerToCam (t.inverse(), image_msg->header.stamp, markerFrame_.c_str(), image_msg->header.frame_id);
00313 broadcaster_.sendTransform(markerToCam);
00314 } else {
00315 tf::StampedTransform camToMarker (t, image_msg->header.stamp, image_msg->header.frame_id, markerFrame_.c_str());
00316 broadcaster_.sendTransform(camToMarker);
00317 }
00318 }
00319
00320
00321
00322 if(publishVisualMarkers_)
00323 {
00324 #if ROS_VERSION_MINIMUM(1, 9, 0)
00325 tf::Vector3 markerOrigin (0, 0, 0.25 * markerWidth_ * AR_TO_ROS);
00326 tf::Transform m (tf::Quaternion::getIdentity (), markerOrigin);
00327 tf::Transform markerPose = t * m;
00328 #else
00329
00330 btVector3 markerOrigin (0, 0, 0.25 * markerWidth_ * AR_TO_ROS);
00331 btTransform m (btQuaternion::getIdentity (), markerOrigin);
00332 btTransform markerPose = t * m;
00333 #endif
00334
00335
00336 tf::poseTFToMsg(markerPose, rvizMarker_.pose);
00337
00338 rvizMarker_.header.frame_id = image_msg->header.frame_id;
00339 rvizMarker_.header.stamp = image_msg->header.stamp;
00340 rvizMarker_.id = 1;
00341
00342 rvizMarker_.scale.x = 1.0 * markerWidth_ * AR_TO_ROS;
00343 rvizMarker_.scale.y = 1.0 * markerWidth_ * AR_TO_ROS;
00344 rvizMarker_.scale.z = 0.5 * markerWidth_ * AR_TO_ROS;
00345 rvizMarker_.ns = "basic_shapes";
00346 rvizMarker_.type = visualization_msgs::Marker::CUBE;
00347 rvizMarker_.action = visualization_msgs::Marker::ADD;
00348 rvizMarker_.color.r = 0.0f;
00349 rvizMarker_.color.g = 1.0f;
00350 rvizMarker_.color.b = 0.0f;
00351 rvizMarker_.color.a = 1.0;
00352 rvizMarker_.lifetime = ros::Duration(1.0);
00353
00354 rvizMarkerPub_.publish(rvizMarker_);
00355 ROS_DEBUG ("Published visual marker");
00356 }
00357 }
00358 else
00359 {
00360 contF = 0;
00361 ROS_DEBUG ("Failed to locate marker");
00362 }
00363 }
00364 }
00365