コード例 #1
0
/**
 * @brief estimated_pose Returns estimated object pose in cartesian frame
 */
geometry_msgs::Pose kalman_pose_estimation(geometry_msgs::Pose previous_pose_, geometry_msgs::Pose measured_pose_) {

	// TODO: create kalman filter for each estimated object separatelly.
	cv::KalmanFilter KF;         // instantiate Kalman Filter
	int nStates = 18;            // the number of states
	int nMeasurements = 6;       // the number of measured states
	int nInputs = 0;             // the number of action control
	double dt = 0.125;           // time between measurements (1/FPS)
	initKalmanFilter(KF, nStates, nMeasurements, nInputs, dt);    // init function
	cv::Mat measurements(nMeasurements, 1, CV_64F);
	measurements.setTo(cv::Scalar(0));

	// Get object pose in sensor frame.
	tf::Transform measured_tf;
	tf::poseMsgToTF (measured_pose_ , measured_tf);
//	tf::btMatrix3x3 measured_rot = measured_tf.getBasis();

	// Get the measured translation
	cv::Mat translation_measured(3, 1, CV_64F);
	// translation_measured = ... TODO!
	// Get the measured rotation
	cv::Mat rotation_measured(3, 3, CV_64F);
	//rotation_measured = ... TODO!
	// fill the measurements vector
	fillMeasurements(measurements, translation_measured, rotation_measured);

	// Instantiate estimated translation and rotation
	cv::Mat translation_estimated(3, 1, CV_64F);
	cv::Mat rotation_estimated(3, 3, CV_64F);
	// update the Kalman filter with good measurements
	updateKalmanFilter( KF, measurements, translation_estimated, rotation_estimated);

	geometry_msgs::Pose estimated_pose;
	return estimated_pose;
}
コード例 #2
0
void DoorHandleDetectionNode::mainComputation(const sensor_msgs::PointCloud2::ConstPtr &image)
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_bbox(new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_sandwich(new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_debug(new pcl::PointCloud<pcl::PointXYZ>);
  vpColVector direction_line(3);
  vpColVector normal(3);
  vpHomogeneousMatrix dMp;
  geometry_msgs::PoseStamped cMdh_msg;
  vpColVector coeffs;
  struct inliersAndCoefficients plane_variables;
  pcl::PointCloud<pcl::PointXYZ>::Ptr plane(new pcl::PointCloud<pcl::PointXYZ>);
  std_msgs::Int8 status_handle_msg;

  //Convert the sensor_msgs/PointCloud2 data to pcl/PointCloud
  pcl::fromROSMsg (*image, *cloud);

  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

  //Downsample the point cloud given by the camera
  pcl::VoxelGrid<pcl::PointXYZ> vg;
  vg.setInputCloud( cloud );
  vg.setLeafSize( 0.005f, 0.005f, 0.005f );
  vg.filter(*cloud_filtered);


  if(m_cam_is_initialized)
  {

    //Find the coefficients of the biggest plane of the point cloud
    plane_variables = DoorHandleDetectionNode::getPlaneInliersAndCoefficients(cloud_filtered);
    coeffs.stack(plane_variables.coefficients->values[0]);
    coeffs.stack(plane_variables.coefficients->values[1]);
    coeffs.stack(plane_variables.coefficients->values[2]);
    coeffs.stack(plane_variables.coefficients->values[3]);

    //Invert the normal in order to have the z axis toward the camera
    normal[0] = -coeffs[0];
    normal[1] = -coeffs[1];
    normal[2] = -coeffs[2];

    //Check if the size of the plane if big enough
    if (plane_variables.inliers->indices.size() < 100)
    {
      std::cout << "Could not find a plane in the scene." << std::endl;
      vpDisplay::displayText(m_img_, 60, 5, "No plane detected", vpColor::red);
      vpDisplay::flush(m_img_);
    }
    else
    {
      if (debug)
      {
        //Copy the inliers of the plane to a new cloud.
        plane = DoorHandleDetectionNode::createPlanePC(cloud, plane_variables.inliers, plane_variables.coefficients);

        //Create the center of the plane
        vpColVector centroidPlane(3);
        centroidPlane = DoorHandleDetectionNode::getCentroidPCL(plane);

        //Create a tf for the plane
        dMp = DoorHandleDetectionNode::createTFPlane(coeffs, centroidPlane[0], centroidPlane[1], centroidPlane[2]);
      }

      //Compute the Z of the corners of the smaller detection
      m_Z_topleft = -(coeffs[3] + m_height_dh)/(coeffs[0]*m_x_min + coeffs[1]*m_y_min + coeffs[2]) ;
      m_Z_topright = -(coeffs[3] + m_height_dh)/(coeffs[0]*m_x_max + coeffs[1]*m_y_min + coeffs[2]) ;
      m_Z_bottomright = -(coeffs[3] + m_height_dh)/(coeffs[0]*m_x_max + coeffs[1]*m_y_max + coeffs[2]) ;
      m_Z_bottomleft = -(coeffs[3] + m_height_dh)/(coeffs[0]*m_x_min + coeffs[1]*m_y_max + coeffs[2]) ;

      //Creating a cloud with all the points of the door handle
      if (m_tracking_works)
      {
        cloud_bbox = DoorHandleDetectionNode::getOnlyUsefulHandle(cloud);
        cloud_sandwich = DoorHandleDetectionNode::createPCLSandwich(cloud_bbox, coeffs);
      }
      else
        cloud_sandwich = DoorHandleDetectionNode::createPCLSandwich(cloud, coeffs);

      if (debug)
      {
        //Create a point cloud of only the top left and bottom right points used for the narrow detection
        cloud_debug->width = 2;
        cloud_debug->height = 1;
        cloud_debug->points.resize (cloud_debug->width * cloud_debug->height);
        cloud_debug->points[0].x = m_X_min;
        cloud_debug->points[0].y = m_Y_min;
        cloud_debug->points[0].z = m_Z_topleft;
        cloud_debug->points[1].x = m_X_max;
        cloud_debug->points[1].y = m_Y_max;
        cloud_debug->points[1].z = m_Z_bottomright;
        cloud_debug->header.frame_id = m_parent_depth_tf;
        debug_pcl_pub.publish(cloud_debug);

        //Publish the point cloud of the door handle with noise
        cloud_sandwich->header.frame_id = m_parent_depth_tf;
        pcl_dh_pub.publish(*cloud_sandwich);

        //Publish the point clouds of the plane
        plane->header.frame_id = m_parent_depth_tf;
        pcl_plane_pub.publish(*plane);

      }

      //Check if the size of the point cloud of the door handle if big enough to localize it or not and check if the detection should be done or not
      if (cloud_sandwich->size()<50 || m_stop_detection){
        m_is_door_handle_present = 0;
        ROS_INFO_STREAM("No door handle detected : " << cloud_sandwich->size());
        m_tracking_works = false;
        vpPixelMeterConversion::convertPoint(m_cam_depth, 0, 0, m_x_min, m_y_min);
        vpPixelMeterConversion::convertPoint(m_cam_depth, m_img_mono.getWidth() - 1, m_img_mono.getHeight() - 1, m_x_max, m_y_max);
      }
      else
      {
        m_is_door_handle_present = 1;

        //Get the axis from the cloud sandwich with the odr method
        direction_line = getCoeffLineWithODR(cloud_sandwich);

        //Set the axis of the door handle towards the right way
        if (m_dh_right)
        {
          if (direction_line[0]<0)
          {
            direction_line[0] = -direction_line[0];
            direction_line[1] = -direction_line[1];
            direction_line[2] = -direction_line[2];
          }
        }
        else
        {
          if (direction_line[0]>0)
          {
            direction_line[0] = -direction_line[0];
            direction_line[1] = -direction_line[1];
            direction_line[2] = -direction_line[2];
          }
        }

        //Create the black&white image used to reduce the detection
        DoorHandleDetectionNode::morphoSandwich(cloud_sandwich );

        //Get the centroid of the door handle
        vpColVector centroidDH = DoorHandleDetectionNode::getCentroidPCL(cloud_sandwich);

        //Compute the pose of the door handle with respect to the Depth camera and publish a tf of it
        m_dMh = DoorHandleDetectionNode::createTFLine(direction_line, normal, centroidDH[0], centroidDH[1], centroidDH[2]);
        vpHomogeneousMatrix cMd;
        for(unsigned int i=0; i<3; i++)
          cMd[i][3] = m_extrinsicParam[i];

        //Compute the pose of the door handle with respect to the RGB camera
        m_cMh = cMd * m_dMh;

        //Kalman Filter
        vpTranslationVector T_cMh = m_cMh.getTranslationVector();
        vpRotationMatrix R_cMh = m_cMh.getRotationMatrix();
        cv::Mat translation_measured(3, 1, CV_64F);
        cv::Mat rotation_measured(3, 3, CV_64F);
        for(int i = 0; i < 3; i++){
          for(int j = 0; j < 3; j++){
            rotation_measured.at<double>(i,j) = R_cMh[i][j];
          }
          translation_measured.at<double>(i) = T_cMh[i];
        }
        cv::Mat measurements(6, 1, CV_64F);
        // fill the measurements vector
        fillMeasurements(measurements, translation_measured, rotation_measured);

        // Instantiate estimated translation and rotation
        cv::Mat translation_estimated(3, 1, CV_64F);
        cv::Mat rotation_estimated(3, 3, CV_64F);
        // update the Kalman filter with good measurements
        updateKalmanFilter( m_KF, measurements, translation_estimated, rotation_estimated);
        for(int i = 0; i < 3; i++){
          for(int j = 0; j < 3; j++){
            m_cMh_filtered_kalman[i][j] = rotation_estimated.at<double>(i,j) ;
          }
          m_cMh_filtered_kalman[i][3] = translation_estimated.at<double>(i);
        }

        //Publish the pose of the handle with respect to the camera
        cMdh_msg.header.stamp = ros::Time::now();
        cMdh_msg.pose = visp_bridge::toGeometryMsgsPose(m_cMh_filtered_kalman);
        cMdh_msg.header.frame_id = m_parent_rgb_tf;
        pose_handle_pub.publish(cMdh_msg);

      }

    }

  }

  //Publish the status of the door handle : 0 if no door handle, 1 if a door handle is found
  status_handle_msg.data = m_is_door_handle_present;
  door_handle_status_pub.publish( status_handle_msg );

}