void Foam::LocalInteraction<CloudType>::info(Ostream& os)
{
    // retrieve any stored data
    labelList npe0(patchData_.size(), 0);
    this->getModelProperty("nEscape", npe0);

    scalarList mpe0(patchData_.size(), 0.0);
    this->getModelProperty("massEscape", mpe0);

    labelList nps0(patchData_.size(), 0);
    this->getModelProperty("nStick", nps0);

    scalarList mps0(patchData_.size(), 0.0);
    this->getModelProperty("massStick", mps0);

    // accumulate current data
    labelList npe(nEscape_, 0);
    Pstream::listCombineGather(npe, plusEqOp<label>());
    npe = npe + npe0;

    scalarList mpe(massEscape_);
    Pstream::listCombineGather(mpe, plusEqOp<scalar>());
    mpe = mpe + mpe0;

    labelList nps(nStick_);
    Pstream::listCombineGather(nps, plusEqOp<label>());
    nps = nps + nps0;

    scalarList mps(massStick_);
    Pstream::listCombineGather(mps, plusEqOp<scalar>());
    mps = mps + mps0;


    forAll(patchData_, i)
    {
        os  << "    Parcel fate (number, mass)      : patch "
            <<  patchData_[i].patchName() << nl
            << "      - escape                      = " << npe[i]
            << ", " << mpe[i] << nl
            << "      - stick                       = " << nps[i]
            << ", " << mps[i] << nl;
    }

    if (this->outputTime())
    {
        this->setModelProperty("nEscape", npe);
        nEscape_ = 0;

        this->setModelProperty("massEscape", mpe);
        massEscape_ = 0.0;

        this->setModelProperty("nStick", nps);
        nStick_ = 0;

        this->setModelProperty("massStick", mps);
        massStick_ = 0.0;
    }
}
Example #2
0
File: main.c Project: romanz/thesis
int DLL_EXPORT extrapolate(real_t *vectors, uint_t dim, uint_t order, enum EXTR_METHOD method)
{
    real_t *const v0 = vectors;

    /* Compute differences */
    for (uint_t i = order - 1; i > 0; --i) {
        real_t *v = vectors + i * dim;
        real_t *u = v - dim;
        for (uint_t k = 0; k < dim; ++k)
            v[k] = v[k] - u[k];
    }
    vectors = vectors + dim;
    order = order - 1;

    /* QR decomposition */
    real_t R[order * order];
    mgs(vectors, R, dim, order);

    /* Compute coefficients */
    real_t gamma[order];
    switch (method) {
        case MPE:	mpe(R, gamma, order); break;
        case RRE:  	rre(R, gamma, order); break;
        default:    return -1;
    }

    /* xi = 1 - cumsum(gamma) */
    for (uint_t i = 1; i < order; ++i)
        gamma[i] = gamma[i] + gamma[i-1];
    real_t xi[order];
    for (uint_t i = 0; i < order; ++i)
        xi[i] = 1 - gamma[i];

    /* eta = R * xi */
    real_t eta[order];
    for (uint_t i = 0; i < order; ++i) {
        eta[i] = 0;
        for (uint_t k = 0; k < order; ++k)
            eta[i] = eta[i] + R[IDX(i, k, order)] * xi[k];
    }

    /* Compute the solution: v0 + Q * eta */
    for (uint_t i = 0; i < order; ++i) {
        real_t *q = vectors + i * dim;
        for (uint_t k = 0; k < dim; ++k)
            v0[k] = v0[k] + q[k] * eta[i];
    }
    return 0;
}
Example #3
0
TEST(suturo_perception_mbpe, empty_pointcloud)
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr input_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);

  std::string package_path = ros::package::getPath("suturo_perception_mbpe");
  std::string object_table_normal_path = "test_files/correctly_segmented_box.pcd_table_normal";
  Eigen::Vector4f table_normal = getTableNormalFromStringLine(object_table_normal_path,package_path);
  std::cout << "Using table normal: " << table_normal << std::endl;

  // Prepare the model that should be matched against the input cloud
  boost::shared_ptr<std::vector<suturo_msgs::Object> > objects(new std::vector<suturo_msgs::Object>);
  suturo_msgs::Object obj;
  obj.name="red_cube";
  obj.color="ff0000";
  obj.description="a red cube";
  obj.surface_material = suturo_msgs::Object::ALUMINIUM;

  shape_msgs::SolidPrimitive shape1;
	geometry_msgs::Pose pose1;
  shape1.type = shape1.BOX;
  // 0.05 x 0.05 x 0.05
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  pose1.position.x = 0;
  pose1.position.y = 0;
  pose1.position.z = 0;
  pose1.orientation.x = 0;
  pose1.orientation.y = 0;
  pose1.orientation.z = 0;
  pose1.orientation.w = 1;
  obj.primitives.push_back(shape1);
  obj.primitive_poses.push_back(pose1);
  objects->push_back(obj);

  suturo_perception::PipelineData::Ptr data_;
  suturo_perception::PipelineObject::Ptr object_;
  ModelPoseEstimation mpe(objects,data_,object_);
  mpe.setInputCloud(input_cloud);
  mpe.setSurfaceNormal(table_normal); // Test this
  // mpe.setRemoveNaNs(true);
  mpe.execute();

  // std::cout << "Fitness for nan matching: " << mpe.getFitnessScore() << std::endl;
  // The estimation should be succesful
	ASSERT_FALSE( mpe.poseEstimationSuccessful() );
  SUCCEED();
}
Example #4
0
// Use the fallback feature of MPE to detect the handlebar in the second iteration
TEST(suturo_perception_mbpe, pose_estimation_handlebar_task2_with_fallback)
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr input_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
  std::string package_path = ros::package::getPath("suturo_perception_mbpe");
  // std::string modelpath  = "test_files/005box_4000pts.pcd";
  std::string objectpath = "test_files/handlebar_task2.pcd";
  std::string object_table_normal_path = "test_files/handlebar_task2.pcd_table_normal";

  if (pcl::io::loadPCDFile<pcl::PointXYZRGB> (package_path + "/" + objectpath, *input_cloud) == -1)
  {
    PCL_ERROR ("Couldn't read input file\n");
    exit (-1);
  }

  Eigen::Vector4f table_normal = getTableNormalFromStringLine(object_table_normal_path,package_path);
  std::cout << "Using table normal: " << table_normal << std::endl;

  // Prepare the model that should be matched against the input cloud
  boost::shared_ptr<std::vector<suturo_msgs::Object> > objects(new std::vector<suturo_msgs::Object>);
  suturo_msgs::Object obj;
  obj.name="blue_handle";
  obj.color="0000ff";
  obj.description="a blue compound of a cylinder with two cubes";
  obj.surface_material = suturo_msgs::Object::ALUMINIUM;

  shape_msgs::SolidPrimitive shape1, shape2, shape3;
	geometry_msgs::Pose pose1, pose2, pose3;
  shape1.type = shape1.BOX;
  // 0.05 x 0.05 x 0.05
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  pose1.position.x = 0;
  pose1.position.y = 0;
  pose1.position.z = 0;
  pose1.orientation.x = 0;
  pose1.orientation.y = 0;
  pose1.orientation.z = 0;
  pose1.orientation.w = 1;

  // Define the extra parts on the handlebar
  shape2.type = shape1.BOX;
  // 0.05 x 0.05 x 0.05
  shape2.dimensions.push_back(0.05f);
  shape2.dimensions.push_back(0.05f);
  shape2.dimensions.push_back(0.05f);
  pose2.position.x = 0;
  pose2.position.y = 0;
  pose2.position.z = 0.35f;
  pose2.orientation.x = 0;
  pose2.orientation.y = 0;
  pose2.orientation.z = 0;
  pose2.orientation.w = 1;

  shape3.type = shape1.CYLINDER;
  shape3.dimensions.push_back(0.3f);
  shape3.dimensions.push_back(0.01f);
  pose3.position.x = 0;
  pose3.position.y = 0;
  pose3.position.z = 0.175f;
  pose3.orientation.x = 0;
  pose3.orientation.y = 0;
  pose3.orientation.z = 0;
  pose3.orientation.w = 1;


  obj.primitives.push_back(shape1);
  obj.primitives.push_back(shape2);
  obj.primitives.push_back(shape3);
  obj.primitive_poses.push_back(pose1);
  obj.primitive_poses.push_back(pose2);
  obj.primitive_poses.push_back(pose3);
  objects->push_back(obj);

  suturo_perception::PipelineData::Ptr data_;
  suturo_perception::PipelineObject::Ptr object_;
  ModelPoseEstimation mpe(objects,data_,object_);
  mpe.setInputCloud(input_cloud);
  mpe.setSurfaceNormal(table_normal);
  // mpe.setInitialAlignmentMethod(ICPFitter::IA_MINMAX);
  std::vector<int> modelsOfInterest;
  modelsOfInterest.push_back(0); // only match against the cylinder (and fail)
  mpe.setModelsOfInterest(modelsOfInterest);
  mpe.setVoxelSize(0.003f);
  mpe.setFallbackInitialAlignmentEnabled(true);
  mpe.setDumpICPFitterPointclouds(true); // Enable debugging. This will save pointclouds
  mpe.execute();

  std::cout << "Fitness for handlebar matching: " << mpe.getFitnessScore() << std::endl;
  // The estimation should be succesful
	ASSERT_TRUE( mpe.poseEstimationSuccessful() );
  // Check the pose (origin.x, origin.y, origin.z)
  // ASSERT_NEAR( mpe.getEstimatedPose()[0],  -0.320974, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[1],  -0.100329, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[2],    1.02429, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );

  // // Check the orientation (x,y,z,w from a Quaternionf)
  // ASSERT_NEAR( mpe.getEstimatedPose()[3],   0.876425, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[4], -0.0972819, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[5],    0.17143, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[6],  -0.439349, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );

  SUCCEED();
}
Example #5
0
TEST(suturo_perception_mbpe, pose_estimation_cylinder_minmax)
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr input_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
  std::string package_path = ros::package::getPath("suturo_perception_mbpe");
  // std::string modelpath  = "test_files/005box_4000pts.pcd";
  std::string objectpath = "test_files/correctly_segmented_cylinder.pcd";
  std::string object_table_normal_path = "test_files/correctly_segmented_cylinder.pcd_table_normal";

  if (pcl::io::loadPCDFile<pcl::PointXYZRGB> (package_path + "/" + objectpath, *input_cloud) == -1)
  {
    PCL_ERROR ("Couldn't read input file\n");
    exit (-1);
  }

  Eigen::Vector4f table_normal = getTableNormalFromStringLine(object_table_normal_path,package_path);
  std::cout << "Using table normal: " << table_normal << std::endl;

  // Prepare the model that should be matched against the input cloud
  boost::shared_ptr<std::vector<suturo_msgs::Object> > objects(new std::vector<suturo_msgs::Object>);
  suturo_msgs::Object obj;
  obj.name="green_cylinder";
  obj.color="00ff00";
  obj.description="a green cylinder";
  obj.surface_material = suturo_msgs::Object::ALUMINIUM;

  shape_msgs::SolidPrimitive shape1;
	geometry_msgs::Pose pose1;
  shape1.type = shape1.CYLINDER;
  // 0.1 x 0.02
  shape1.dimensions.push_back(0.1f);
  shape1.dimensions.push_back(0.02f);
  pose1.position.x = 0;
  pose1.position.y = 0;
  pose1.position.z = 0;
  pose1.orientation.x = 0;
  pose1.orientation.y = 0;
  pose1.orientation.z = 0;
  pose1.orientation.w = 1;
  obj.primitives.push_back(shape1);
  obj.primitive_poses.push_back(pose1);
  objects->push_back(obj);

  suturo_perception::PipelineData::Ptr data_;
  suturo_perception::PipelineObject::Ptr object_;
  ModelPoseEstimation mpe(objects,data_,object_);
  mpe.setInputCloud(input_cloud);
  mpe.setSurfaceNormal(table_normal);
  // mpe.setDumpICPFitterPointclouds(true);
  mpe.setInitialAlignmentMethod(ICPFitter::IA_MINMAX);
  mpe.setVoxelSize(0.003f);
  mpe.execute();

  std::cout << "Fitness for cylinder matching: " << mpe.getFitnessScore() << std::endl;
  // The estimation should be succesful
	ASSERT_TRUE( mpe.poseEstimationSuccessful() );
  // Check the pose (origin.x, origin.y, origin.z)
  // ASSERT_NEAR( mpe.getEstimatedPose()[0],  -0.110493, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[1],   0.163387, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[2],   0.566805, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );

  // // Check the orientation (x,y,z,w from a Quaternionf)
  // ASSERT_NEAR( mpe.getEstimatedPose()[3],  -0.270409, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[4], 0.00236567, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[5],  -0.227, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  // ASSERT_NEAR( mpe.getEstimatedPose()[6],   0.910853, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );

  SUCCEED();
}
Example #6
0
TEST(suturo_perception_mbpe, pose_estimation_cube)
{
  std::cout << "PE CUBE TEST" << std::endl;
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr input_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
  std::string package_path = ros::package::getPath("suturo_perception_mbpe");
  // std::string modelpath  = "test_files/005box_4000pts.pcd";
  std::string objectpath = "test_files/correctly_segmented_box.pcd";
  std::string object_table_normal_path = "test_files/correctly_segmented_box.pcd_table_normal";

  if (pcl::io::loadPCDFile<pcl::PointXYZRGB> (package_path + "/" + objectpath, *input_cloud) == -1)
  {
    PCL_ERROR ("Couldn't read input file\n");
    exit (-1);
  }

  Eigen::Vector4f table_normal = getTableNormalFromStringLine(object_table_normal_path,package_path);
  std::cout << "Using table normal: " << table_normal << std::endl;

  // Prepare the model that should be matched against the input cloud
  boost::shared_ptr<std::vector<suturo_msgs::Object> > objects(new std::vector<suturo_msgs::Object>);
  suturo_msgs::Object obj;
  obj.name="red_cube";
  obj.color="ff0000";
  obj.description="a red cube";
  obj.surface_material = suturo_msgs::Object::ALUMINIUM;

  shape_msgs::SolidPrimitive shape1;
	geometry_msgs::Pose pose1;
  shape1.type = shape1.BOX;
  // 0.05 x 0.05 x 0.05
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  pose1.position.x = 0;
  pose1.position.y = 0;
  pose1.position.z = 0;
  pose1.orientation.x = 0;
  pose1.orientation.y = 0;
  pose1.orientation.z = 0;
  pose1.orientation.w = 1;
  obj.primitives.push_back(shape1);
  obj.primitive_poses.push_back(pose1);
  objects->push_back(obj);

  suturo_perception::PipelineData::Ptr data_;
  suturo_perception::PipelineObject::Ptr object_;
  ModelPoseEstimation mpe(objects,data_,object_);
  mpe.setInputCloud(input_cloud);
  mpe.setSurfaceNormal(table_normal);
  mpe.setVoxelSize(0.003f);
  // mpe.setDumpICPFitterPointclouds(true);
  std::cout << "TEST: BEFORE MPE EXECUTE" << std::endl;
  mpe.execute();
  std::cout << "TEST: AFTER MPE EXECUTE" << std::endl;

  std::cout << "Fitness for cube matching: " << mpe.getFitnessScore() << std::endl;
  // The estimation should be succesful
	ASSERT_TRUE( mpe.poseEstimationSuccessful() );
  // Check the pose (origin.x, origin.y, origin.z)
  ASSERT_NEAR( mpe.getEstimatedPose()[0], -0.0634356, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );
  ASSERT_NEAR( mpe.getEstimatedPose()[1], -0.0439471, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );
  ASSERT_NEAR( mpe.getEstimatedPose()[2],    0.73877, CAD_RECOGNITION_TEST_ACCEPTABLE_POINT_ERROR );

  // Check the orientation (x,y,z,w from a Quaternionf)
  ASSERT_NEAR( mpe.getEstimatedPose()[3],  0.813566, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  ASSERT_NEAR( mpe.getEstimatedPose()[4], -0.164979, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  ASSERT_NEAR( mpe.getEstimatedPose()[5],  0.309649, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );
  ASSERT_NEAR( mpe.getEstimatedPose()[6], -0.463691, CAD_RECOGNITION_TEST_ACCEPTABLE_ORIENTATION_ERROR );

  SUCCEED();
}
Example #7
0
TEST(suturo_perception_mbpe, pose_estimation_box_against_multiple_models_but_ignore_the_best)
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr input_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
  std::string package_path = ros::package::getPath("suturo_perception_mbpe");
  // std::string modelpath  = "test_files/005box_4000pts.pcd";
  std::string objectpath = "test_files/correctly_segmented_box.pcd";
  std::string object_table_normal_path = "test_files/correctly_segmented_box.pcd_table_normal";

  if (pcl::io::loadPCDFile<pcl::PointXYZRGB> (package_path + "/" + objectpath, *input_cloud) == -1)
  {
    PCL_ERROR ("Couldn't read input file\n");
    exit (-1);
  }

  Eigen::Vector4f table_normal = getTableNormalFromStringLine(object_table_normal_path,package_path);
  std::cout << "Using table normal: " << table_normal << std::endl;

  // Prepare the model that should be matched against the input cloud
  boost::shared_ptr<std::vector<suturo_msgs::Object> > objects(new std::vector<suturo_msgs::Object>);
  suturo_msgs::Object obj;
  obj.name="red_cube";
  obj.color="ff0000";
  obj.description="a red cube";
  obj.surface_material = suturo_msgs::Object::ALUMINIUM;

  shape_msgs::SolidPrimitive shape1;
	geometry_msgs::Pose pose1;
  shape1.type = shape1.BOX;
  // 0.05 x 0.05 x 0.05
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  pose1.position.x = 0;
  pose1.position.y = 0;
  pose1.position.z = 0;
  pose1.orientation.x = 0;
  pose1.orientation.y = 0;
  pose1.orientation.z = 0;
  pose1.orientation.w = 1;
  obj.primitives.push_back(shape1);
  obj.primitive_poses.push_back(pose1);


  suturo_msgs::Object cobj;
  cobj.name="green_cylinder";
  cobj.color="00ff00";
  cobj.description="a green cylinder";
  cobj.surface_material = suturo_msgs::Object::ALUMINIUM;

  shape_msgs::SolidPrimitive shape2;
  geometry_msgs::Pose pose2;
  shape2.type = shape2.CYLINDER;
  // 0.1 x 0.02
  shape2.dimensions.push_back(0.1f);
  shape2.dimensions.push_back(0.02f);
  pose2.position.x = 0;
  pose2.position.y = 0;
  pose2.position.z = 0;
  pose2.orientation.x = 0;
  pose2.orientation.y = 0;
  pose2.orientation.z = 0;
  pose2.orientation.w = 1;
  cobj.primitives.push_back(shape2);
  cobj.primitive_poses.push_back(pose2);

  objects->push_back(obj);
  objects->push_back(cobj);

  suturo_perception::PipelineData::Ptr data_;
  suturo_perception::PipelineObject::Ptr object_;
  ModelPoseEstimation mpe(objects,data_,object_);
  mpe.setInputCloud(input_cloud);
  mpe.setSurfaceNormal(table_normal);
  mpe.setVoxelSize(0.003f);
  std::vector<int> modelsOfInterest;
  modelsOfInterest.push_back(1); // only match against the cylinder (and fail)
  mpe.setModelsOfInterest(modelsOfInterest);
  mpe.execute();

  // The estimation should be succesful
	ASSERT_FALSE( mpe.poseEstimationSuccessful() );

  SUCCEED();
}
Example #8
0
TEST(suturo_perception_mbpe, nan_handling)
{
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr input_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);

  // Fill in the cloud data
  input_cloud->width    = 5;
  input_cloud->height   = 1;
  input_cloud->is_dense = false;
  input_cloud->points.resize (input_cloud->width * input_cloud->height);

  for (size_t i = 0; i < input_cloud->points.size ()-1; ++i)
  {
    input_cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
    input_cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
    input_cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
  }
  // Produce NaN
  input_cloud->points[4].x = 0.0 / 0.0;
  input_cloud->points[4].y = 0.0 / 0.0;
  input_cloud->points[4].z = 0.0 / 0.0;

  // std::string package_path = ros::package::getPath("suturo_perception_mbpe");
  // // std::string modelpath  = "test_files/005box_4000pts.pcd";
  // std::string objectpath = "test_files/correctly_segmented_box.pcd";
  // std::string object_table_normal_path = "test_files/correctly_segmented_box.pcd_table_normal";

  // if (pcl::io::loadPCDFile<pcl::PointXYZRGB> (package_path + "/" + objectpath, *input_cloud) == -1)
  // {
  //   PCL_ERROR ("Couldn't read input file\n");
  //   exit (-1);
  // }

  std::string package_path = ros::package::getPath("suturo_perception_mbpe");
  std::string object_table_normal_path = "test_files/correctly_segmented_box.pcd_table_normal";
  Eigen::Vector4f table_normal = getTableNormalFromStringLine(object_table_normal_path,package_path);
  std::cout << "Using table normal: " << table_normal << std::endl;

  // Prepare the model that should be matched against the input cloud
  boost::shared_ptr<std::vector<suturo_msgs::Object> > objects(new std::vector<suturo_msgs::Object>);
  suturo_msgs::Object obj;
  obj.name="red_cube";
  obj.color="ff0000";
  obj.description="a red cube";
  obj.surface_material = suturo_msgs::Object::ALUMINIUM;

  shape_msgs::SolidPrimitive shape1;
	geometry_msgs::Pose pose1;
  shape1.type = shape1.BOX;
  // 0.05 x 0.05 x 0.05
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  shape1.dimensions.push_back(0.05f);
  pose1.position.x = 0;
  pose1.position.y = 0;
  pose1.position.z = 0;
  pose1.orientation.x = 0;
  pose1.orientation.y = 0;
  pose1.orientation.z = 0;
  pose1.orientation.w = 1;
  obj.primitives.push_back(shape1);
  obj.primitive_poses.push_back(pose1);
  objects->push_back(obj);

  suturo_perception::PipelineData::Ptr data_;
  suturo_perception::PipelineObject::Ptr object_;
  ModelPoseEstimation mpe(objects,data_,object_);
  mpe.setInputCloud(input_cloud);
  mpe.setSurfaceNormal(table_normal);
  mpe.setRemoveNaNs(true);
  mpe.execute();

  std::cout << "Fitness for nan matching: " << mpe.getFitnessScore() << std::endl;
  // The estimation should be succesful
	ASSERT_FALSE( mpe.poseEstimationSuccessful() );
  SUCCEED();
}