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 #include <math.h>
00027 #include "ar_kinect/ar_kinect.h"
00028 #include "ar_kinect/object.h"
00029
00030 int main (int argc, char **argv)
00031 {
00032 ros::init (argc, argv, "ar_kinect");
00033 ros::NodeHandle n;
00034 ar_pose::ARPublisher ar_kinect (n);
00035 ros::spin ();
00036 return 0;
00037 }
00038
00039 namespace ar_pose
00040 {
00041 tf::Transform tfFromEigen(Eigen::Matrix4f trans)
00042 {
00043 tf::Matrix3x3 btm;
00044 btm.setValue(trans(0,0),trans(0,1),trans(0,2),
00045 trans(1,0),trans(1,1),trans(1,2),
00046 trans(2,0),trans(2,1),trans(2,2));
00047 tf::Transform ret;
00048 ret.setOrigin(tf::Vector3(trans(0,3),trans(1,3),trans(2,3)));
00049 ret.setBasis(btm);
00050 return ret;
00051 }
00052
00053 pcl::PointXYZRGB makeRGBPoint( float x, float y, float z )
00054 {
00055 pcl::PointXYZRGB p;
00056 p.x = x;
00057 p.y = y;
00058 p.z = z;
00059 return p;
00060 }
00061
00062 ARPublisher::ARPublisher (ros::NodeHandle & n):n_ (n), configured_(false)
00063 {
00064 std::string path;
00065 std::string package_path = ros::package::getPath (ROS_PACKAGE_NAME);
00066 ros::NodeHandle n_param ("~");
00067 XmlRpc::XmlRpcValue xml_marker_center;
00068
00069
00070
00071 if (!n_param.getParam ("publish_tf", publishTf_))
00072 publishTf_ = true;
00073 ROS_INFO ("\tPublish transforms: %d", publishTf_);
00074
00075 if (!n_param.getParam ("publish_visual_markers", publishVisualMarkers_))
00076 publishVisualMarkers_ = true;
00077 ROS_INFO ("\tPublish visual markers: %d", publishVisualMarkers_);
00078
00079 if (!n_param.getParam ("threshold", threshold_))
00080 threshold_ = 100;
00081 ROS_INFO ("\tThreshold: %d", threshold_);
00082
00083 if (!n_param.getParam ("marker_pattern_list", path)){
00084 sprintf(pattern_filename_, "%s/data/objects_kinect", package_path.c_str());
00085 }else{
00086 sprintf(pattern_filename_, "%s", path.c_str());
00087 }
00088 ROS_INFO ("Marker Pattern Filename: %s", pattern_filename_);
00089
00090 if (!n_param.getParam ("marker_data_directory", path)){
00091 sprintf(data_directory_, "%s", package_path.c_str());
00092 }else{
00093 sprintf(data_directory_, "%s", path.c_str());
00094 }
00095 ROS_INFO ("Marker Data Directory: %s", data_directory_);
00096
00097
00098
00099 configured_ = false;
00100 cloud_sub_ = n_.subscribe(cloudTopic_, 1, &ARPublisher::getTransformationCallback, this);
00101
00102
00103
00104 arMarkerPub_ = n_.advertise < ar_pose::ARMarkers > ("ar_pose_markers",0);
00105 if(publishVisualMarkers_)
00106 {
00107 rvizMarkerPub_ = n_.advertise < visualization_msgs::Marker > ("visualization_marker", 0);
00108 }
00109 }
00110
00111 ARPublisher::~ARPublisher (void)
00112 {
00113 arVideoCapStop ();
00114 arVideoClose ();
00115 }
00116
00117
00118
00119
00120 void ARPublisher::arInit ()
00121 {
00122 arInitCparam (&cam_param_);
00123 ROS_INFO ("*** Camera Parameter ***");
00124 arParamDisp (&cam_param_);
00125
00126
00127 if ((object = ar_object::read_ObjData (pattern_filename_, data_directory_, &objectnum)) == NULL)
00128 ROS_BREAK ();
00129 ROS_DEBUG ("Objectfile num = %d", objectnum);
00130
00131 sz_ = cvSize (cam_param_.xsize, cam_param_.ysize);
00132 capture_ = cvCreateImage (sz_, IPL_DEPTH_8U, 4);
00133 configured_ = true;
00134 }
00135
00136
00137
00138
00139 void ARPublisher::getTransformationCallback (const sensor_msgs::PointCloud2ConstPtr & msg)
00140 {
00141 sensor_msgs::ImagePtr image_msg(new sensor_msgs::Image);
00142 ARUint8 *dataPtr;
00143 ARMarkerInfo *marker_info;
00144 int marker_num;
00145 int i, k, j;
00146
00147
00148 if(!configured_)
00149 {
00150 if(msg->width == 0 || msg->height == 0)
00151 {
00152 ROS_ERROR ("Deformed cloud! Size = %d, %d.", msg->width, msg->height);
00153 return;
00154 }
00155
00156 cam_param_.xsize = msg->width;
00157 cam_param_.ysize = msg->height;
00158
00159 cam_param_.dist_factor[0] = msg->width/2;
00160 cam_param_.dist_factor[1] = msg->height/2;
00161 cam_param_.dist_factor[2] = 0;
00162 cam_param_.dist_factor[3] = 1.0;
00163
00164 arInit ();
00165 }
00166
00167
00168 PointCloud cloud;
00169 pcl::fromROSMsg(*msg, cloud);
00170
00171
00172 pcl::toROSMsg (cloud, *image_msg);
00173 try
00174 {
00175 capture_ = bridge_.imgMsgToCv (image_msg, "bgr8");
00176 }
00177 catch (sensor_msgs::CvBridgeException & e)
00178 {
00179 ROS_ERROR ("Could not convert from '%s' to 'bgr8'.", image_msg->encoding.c_str ());
00180 }
00181 dataPtr = (ARUint8 *) capture_->imageData;
00182
00183
00184 if (arDetectMarkerLite (dataPtr, threshold_, &marker_info, &marker_num) < 0)
00185 {
00186 argCleanup ();
00187 return;
00188 }
00189
00190 arPoseMarkers_.markers.clear ();
00191
00192 for (i = 0; i < objectnum; i++)
00193 {
00194 k = -1;
00195 for (j = 0; j < marker_num; j++)
00196 {
00197 if (object[i].id == marker_info[j].id)
00198 {
00199 if (k == -1)
00200 k = j;
00201 else
00202 if (marker_info[k].cf < marker_info[j].cf)
00203 k = j;
00204 }
00205 }
00206 if (k == -1)
00207 {
00208 object[i].visible = 0;
00209 continue;
00210 }
00211
00212
00213 int d = marker_info[k].dir;
00214 PointCloud marker;
00215 marker.push_back( cloud.at( (int)marker_info[k].vertex[(4-d)%4][0], (int)marker_info[k].vertex[(4-d)%4][1] ) );
00216 marker.push_back( cloud.at( (int)marker_info[k].vertex[(5-d)%4][0], (int)marker_info[k].vertex[(5-d)%4][1] ) );
00217 marker.push_back( cloud.at( (int)marker_info[k].vertex[(6-d)%4][0], (int)marker_info[k].vertex[(6-d)%4][1] ) );
00218 marker.push_back( cloud.at( (int)marker_info[k].vertex[(7-d)%4][0], (int)marker_info[k].vertex[(7-d)%4][1] ) );
00219
00220
00221 double w = object[i].marker_width;
00222 PointCloud ideal;
00223 ideal.push_back( makeRGBPoint(-w/2,w/2,0) );
00224 ideal.push_back( makeRGBPoint(w/2,w/2,0) );
00225 ideal.push_back( makeRGBPoint(w/2,-w/2,0) );
00226 ideal.push_back( makeRGBPoint(-w/2,-w/2,0) );
00227
00228
00229 Eigen::Matrix4f t;
00230 TransformationEstimationSVD obj;
00231 obj.estimateRigidTransformation( marker, ideal, t );
00232
00233
00234 tf::Transform transform = tfFromEigen(t.inverse());
00235
00236
00237 tf::Matrix3x3 m = transform.getBasis();
00238 tf::Vector3 p = transform.getOrigin();
00239 bool invalid = false;
00240 for(int i=0; i < 3; i++)
00241 for(int j=0; j < 3; j++)
00242 invalid = (invalid || isnan(m[i][j]) || fabs(m[i][j]) > 1.0);
00243
00244 for(int i=0; i < 3; i++)
00245 invalid = (invalid || isnan(p[i]));
00246
00247
00248 if(invalid)
00249 continue;
00250
00251
00252 ar_pose::ARMarker ar_pose_marker;
00253 ar_pose_marker.header.frame_id = msg->header.frame_id;
00254 ar_pose_marker.header.stamp = msg->header.stamp;
00255 ar_pose_marker.id = object[i].id;
00256
00257 ar_pose_marker.pose.pose.position.x = transform.getOrigin().getX();
00258 ar_pose_marker.pose.pose.position.y = transform.getOrigin().getY();
00259 ar_pose_marker.pose.pose.position.z = transform.getOrigin().getZ();
00260
00261 ar_pose_marker.pose.pose.orientation.x = transform.getRotation().getAxis().getX();
00262 ar_pose_marker.pose.pose.orientation.y = transform.getRotation().getAxis().getY();
00263 ar_pose_marker.pose.pose.orientation.z = transform.getRotation().getAxis().getZ();
00264 ar_pose_marker.pose.pose.orientation.w = transform.getRotation().getW();
00265
00266 ar_pose_marker.confidence = marker_info->cf;
00267 arPoseMarkers_.markers.push_back (ar_pose_marker);
00268
00269
00270 if (publishTf_)
00271 {
00272 broadcaster_.sendTransform(tf::StampedTransform(transform, msg->header.stamp, msg->header.frame_id, object[i].name));
00273 }
00274
00275
00276
00277 if (publishVisualMarkers_)
00278 {
00279 tf::Vector3 markerOrigin (0, 0, 0.25 * object[i].marker_width * AR_TO_ROS);
00280 tf::Transform m (tf::Quaternion::getIdentity (), markerOrigin);
00281 tf::Transform markerPose = transform * m;
00282
00283 tf::poseTFToMsg (markerPose, rvizMarker_.pose);
00284
00285 rvizMarker_.header.frame_id = msg->header.frame_id;
00286 rvizMarker_.header.stamp = msg->header.stamp;
00287 rvizMarker_.id = object[i].id;
00288
00289 rvizMarker_.scale.x = 1.0 * object[i].marker_width * AR_TO_ROS;
00290 rvizMarker_.scale.y = 1.0 * object[i].marker_width * AR_TO_ROS;
00291 rvizMarker_.scale.z = 0.5 * object[i].marker_width * AR_TO_ROS;
00292 rvizMarker_.ns = "basic_shapes";
00293 rvizMarker_.type = visualization_msgs::Marker::CUBE;
00294 rvizMarker_.action = visualization_msgs::Marker::ADD;
00295 switch (i)
00296 {
00297 case 0:
00298 rvizMarker_.color.r = 0.0f;
00299 rvizMarker_.color.g = 0.0f;
00300 rvizMarker_.color.b = 1.0f;
00301 rvizMarker_.color.a = 1.0;
00302 break;
00303 case 1:
00304 rvizMarker_.color.r = 1.0f;
00305 rvizMarker_.color.g = 0.0f;
00306 rvizMarker_.color.b = 0.0f;
00307 rvizMarker_.color.a = 1.0;
00308 break;
00309 default:
00310 rvizMarker_.color.r = 0.0f;
00311 rvizMarker_.color.g = 1.0f;
00312 rvizMarker_.color.b = 0.0f;
00313 rvizMarker_.color.a = 1.0;
00314 }
00315 rvizMarker_.lifetime = ros::Duration ();
00316
00317 rvizMarkerPub_.publish (rvizMarker_);
00318 ROS_DEBUG ("Published visual marker");
00319 }
00320 }
00321 arMarkerPub_.publish (arPoseMarkers_);
00322 ROS_DEBUG ("Published ar_multi markers");
00323 }
00324
00325 }