示例#1
0
int main(int argc, char** argv) {


  //##############################################################     

  string btFilename = "";
  unsigned char maxDepth = 16;


  // test timing:
  timeval start;
  timeval stop;
  const unsigned char tree_depth(16);
  const unsigned int tree_max_val(32768);
  double time_it, time_depr;

  if (argc <= 1|| argc >3 || strcmp(argv[1], "-h") == 0){
    printUsage(argv[0]);
  }

  btFilename = std::string(argv[1]);
  if (argc > 2){
    maxDepth = (unsigned char)atoi(argv[2]);
  }
  maxDepth = std::min((unsigned char)16,maxDepth);

  if (maxDepth== 0)
    maxDepth = tree_depth;

  // iterate over empty tree:
  OcTree emptyTree(0.2);
  EXPECT_EQ(emptyTree.size(), 0);
  EXPECT_EQ(emptyTree.calcNumNodes(), 0);

  size_t iteratedNodes = 0;
  OcTree::tree_iterator t_it = emptyTree.begin_tree(maxDepth);
  OcTree::tree_iterator t_end = emptyTree.end_tree();
  EXPECT_TRUE (t_it == t_end);
  for( ; t_it != t_end; ++t_it){
    iteratedNodes++;
  }
  EXPECT_EQ(iteratedNodes, 0);


  for(OcTree::leaf_iterator l_it = emptyTree.begin_leafs(maxDepth), l_end=emptyTree.end_leafs(); l_it!= l_end; ++l_it){
    iteratedNodes++;
  }
  EXPECT_EQ(iteratedNodes, 0);





  cout << "\nReading OcTree file\n===========================\n";
  OcTree* tree = new OcTree(btFilename);
  if (tree->size()<= 1){
    std::cout << "Error reading file, exiting!\n";
    return 1;
  }

  size_t count;
  std::list<OcTreeVolume> list_depr;
  std::list<OcTreeVolume> list_iterator;

  /**
   * get number of nodes:
   */
  gettimeofday(&start, NULL);  // start timer
  size_t num_leafs_recurs = tree->getNumLeafNodes();
  gettimeofday(&stop, NULL);  // stop timer
  time_depr = timediff(start, stop);

  gettimeofday(&start, NULL);  // start timer
  size_t num_leafs_it = 0;
  for(OcTree::leaf_iterator it = tree->begin(), end=tree->end(); it!= end; ++it) {
    num_leafs_it++;
  }
  gettimeofday(&stop, NULL);  // stop timer
  time_it = timediff(start, stop);
  std::cout << "Number of leafs: " << num_leafs_it << " / " << num_leafs_recurs << ", times: "
        <<time_it << " / " << time_depr << "\n========================\n\n";


  /**
   * get all occupied leafs
   */
  point3d tree_center;
  tree_center(0) = tree_center(1) = tree_center(2)
              = (float) (((double) tree_max_val) * tree->getResolution());

  gettimeofday(&start, NULL);  // start timer
  getLeafNodesRecurs(list_depr,maxDepth,tree->getRoot(), 0, tree_center, tree_center, tree, true);
  gettimeofday(&stop, NULL);  // stop timer
  time_depr = timediff(start, stop);

  gettimeofday(&start, NULL);  // start timer
  for(OcTree::iterator it = tree->begin(maxDepth), end=tree->end(); it!= end; ++it){
    if(tree->isNodeOccupied(*it))
    {
      //count ++;
     list_iterator.push_back(OcTreeVolume(it.getCoordinate(), it.getSize()));
    }

  }
  gettimeofday(&stop, NULL);  // stop timer
  time_it = timediff(start, stop);

  std::cout << "Occupied lists traversed, times: "
      <<time_it << " / " << time_depr << "\n";
  compareResults(list_iterator, list_depr);
  std::cout << "========================\n\n";


  /**
   * get all free leafs
   */
  list_iterator.clear();
  list_depr.clear();
  gettimeofday(&start, NULL);  // start timer
  for(OcTree::leaf_iterator it = tree->begin(maxDepth), end=tree->end(); it!= end; ++it) {
    if(!tree->isNodeOccupied(*it))
      list_iterator.push_back(OcTreeVolume(it.getCoordinate(), it.getSize()));
  }
  gettimeofday(&stop, NULL);  // stop timer
  time_it = timediff(start, stop);

  gettimeofday(&start, NULL);  // start timer
  getLeafNodesRecurs(list_depr,maxDepth,tree->getRoot(), 0, tree_center, tree_center, tree, false);
  gettimeofday(&stop, NULL);  // stop timer
  time_depr = timediff(start, stop);

  std::cout << "Free lists traversed, times: "
      <<time_it << " / " << time_depr << "\n";
  compareResults(list_iterator, list_depr);
    std::cout << "========================\n\n";



  /**
   * get all volumes
   */
  list_iterator.clear();
  list_depr.clear();

  gettimeofday(&start, NULL);  // start timer
  getVoxelsRecurs(list_depr,maxDepth,tree->getRoot(), 0, tree_center, tree_center, tree->getResolution());
  gettimeofday(&stop, NULL);  // stop timer
  time_depr = timediff(start, stop);

  gettimeofday(&start, NULL);  // start timers
  for(OcTree::tree_iterator it = tree->begin_tree(maxDepth), end=tree->end_tree();
      it!= end; ++it){
      //count ++;
      //std::cout << it.getDepth() << " " << " "<<it.getCoordinate()<< std::endl;
     list_iterator.push_back(OcTreeVolume(it.getCoordinate(), it.getSize()));
  }
  gettimeofday(&stop, NULL);  // stop timer
  time_it = timediff(start, stop);

  list_iterator.sort(OcTreeVolumeSortPredicate);
  list_depr.sort(OcTreeVolumeSortPredicate);

  std::cout << "All inner lists traversed, times: "
      <<time_it << " / " << time_depr << "\n";
  compareResults(list_iterator, list_depr);
    std::cout << "========================\n\n";



    // traverse all leaf nodes, timing:
    gettimeofday(&start, NULL);  // start timers
    count = 0;
    for(OcTree::iterator it = tree->begin(maxDepth), end=tree->end();
        it!= end; ++it){
      // do something:
      // std::cout << it.getDepth() << " " << " "<<it.getCoordinate()<< std::endl;
      count++;
    }

    gettimeofday(&stop, NULL);  // stop timer
    time_it = timediff(start, stop);

    std::cout << "Time to traverse all leafs at max depth " <<(unsigned int)maxDepth <<" ("<<count<<" nodes): "<< time_it << " s\n\n";




  /**
   * bounding box tests
   */
  //tree->expand();
  // test complete tree (should be equal to no bbx)
  OcTreeKey bbxMinKey, bbxMaxKey;
  double temp_x,temp_y,temp_z;
  tree->getMetricMin(temp_x,temp_y,temp_z);
  octomap::point3d bbxMin(temp_x,temp_y,temp_z);

  tree->getMetricMax(temp_x,temp_y,temp_z);
  octomap::point3d bbxMax(temp_x,temp_y,temp_z);

  EXPECT_TRUE(tree->coordToKeyChecked(bbxMin, bbxMinKey));
  EXPECT_TRUE(tree->coordToKeyChecked(bbxMax, bbxMaxKey));

  OcTree::leaf_bbx_iterator it_bbx = tree->begin_leafs_bbx(bbxMinKey,bbxMaxKey);
  EXPECT_TRUE(it_bbx == tree->begin_leafs_bbx(bbxMinKey,bbxMaxKey));
  OcTree::leaf_bbx_iterator end_bbx = tree->end_leafs_bbx();
  EXPECT_TRUE(end_bbx == tree->end_leafs_bbx());

  OcTree::leaf_iterator it = tree->begin_leafs();
  EXPECT_TRUE(it == tree->begin_leafs());
  OcTree::leaf_iterator end = tree->end_leafs();
  EXPECT_TRUE(end == tree->end_leafs());


  for( ; it!= end && it_bbx != end_bbx; ++it, ++it_bbx){
    EXPECT_TRUE(it == it_bbx);
  }
  EXPECT_TRUE(it == end && it_bbx == end_bbx);


  // now test an actual bounding box:
  tree->expand(); // (currently only works properly for expanded tree (no multires)
  bbxMin = point3d(-1, -1, - 1);
  bbxMax = point3d(3, 2, 1);
  EXPECT_TRUE(tree->coordToKeyChecked(bbxMin, bbxMinKey));
  EXPECT_TRUE(tree->coordToKeyChecked(bbxMax, bbxMaxKey));

  typedef unordered_ns::unordered_map<OcTreeKey, double, OcTreeKey::KeyHash> KeyVolumeMap;

  KeyVolumeMap bbxVoxels;

  count = 0;
  for(OcTree::leaf_bbx_iterator it = tree->begin_leafs_bbx(bbxMinKey,bbxMaxKey), end=tree->end_leafs_bbx();
      it!= end; ++it)
  {
    count++;
    OcTreeKey currentKey = it.getKey();
    // leaf is actually a leaf:
    EXPECT_FALSE(it->hasChildren());

    // leaf exists in tree:
    OcTreeNode* node = tree->search(currentKey);
    EXPECT_TRUE(node);
    EXPECT_EQ(node, &(*it));
    // all leafs are actually in the bbx:
    for (unsigned i = 0; i < 3; ++i){
//      if (!(currentKey[i] >= bbxMinKey[i] && currentKey[i] <= bbxMaxKey[i])){
//        std::cout << "Key failed: " << i << " " << currentKey[i] << " "<< bbxMinKey[i] << " "<< bbxMaxKey[i]
//             << "size: "<< it.getSize()<< std::endl;
//      }
      EXPECT_TRUE(currentKey[i] >= bbxMinKey[i] && currentKey[i] <= bbxMaxKey[i]);
    }

    bbxVoxels.insert(std::pair<OcTreeKey,double>(currentKey, it.getSize()));
  }
  EXPECT_EQ(bbxVoxels.size(), count);
  std::cout << "Bounding box traversed ("<< count << " leaf nodes)\n\n";


  // compare with manual BBX check on all leafs:
  for(OcTree::leaf_iterator it = tree->begin(), end=tree->end(); it!= end; ++it) {
    OcTreeKey key = it.getKey();
    if (    key[0] >= bbxMinKey[0] && key[0] <= bbxMaxKey[0]
         && key[1] >= bbxMinKey[1] && key[1] <= bbxMaxKey[1]
         && key[2] >= bbxMinKey[2] && key[2] <= bbxMaxKey[2])
    {
      KeyVolumeMap::iterator bbxIt = bbxVoxels.find(key);
      EXPECT_FALSE(bbxIt == bbxVoxels.end());
      EXPECT_TRUE(key == bbxIt->first);
      EXPECT_EQ(it.getSize(), bbxIt->second);
    }

  }

  // test tree with one node:
  OcTree simpleTree(0.01);
  simpleTree.updateNode(point3d(10, 10, 10), 5.0f);
  for(OcTree::leaf_iterator it = simpleTree.begin_leafs(maxDepth), end=simpleTree.end_leafs(); it!= end; ++it) {
    std::cout << it.getDepth() << " " << " "<<it.getCoordinate()<< std::endl;
  }


  std::cout << "Tests successful\n";


  return 0;
}
void compareCallbackUsingRegions(const ros::TimerEvent&)
{
// MODE 2: COMPARE OCTOMAP WITH REGIONS
// Compare a Octomap retrieved by a topic with Regions previously defined and check for inconsistencies.

    ros::Time t= ros::Time::now();

    ROS_INFO("Compare callback using regions triggered");

    // Checks if the OcTree Target was already received.
    if (octree_target == NULL)
    {
        ROS_INFO("OcTree Target Not Found");
        return;   
    }

    // Checks if the received target has changed, if not, exits the callback.
    if (flg_received_new_target==true)
    {
        flg_received_new_target = false;
    }
    else
    {
        return;
    }

    // Visualization Message Marker Array Initialization
    visualization_msgs::MarkerArray ma;
    visualization_msgs::MarkerArray ma_inconsistencies;
    visualization_msgs::MarkerArray ma_clusters;

    visualization_msgs::Marker marker_deleteall;
    marker_deleteall.header.stamp = ros::Time();
    marker_deleteall.header.frame_id = octree_frame_id ;
    marker_deleteall.ns = "target_inconsistent";
    marker_deleteall.action = 3;

    size_t id=0;
    size_t id_inconsistencies=0;
    size_t id_noneighbors=0;

    // Color initialization
    std_msgs::ColorRGBA color_occupied;
    color_occupied.r = 0; color_occupied.g = 0; color_occupied.b = 0.5; color_occupied.a = .8;

    std_msgs::ColorRGBA color_inconsistent;
    color_inconsistent.r = .5; color_inconsistent.g = 0; color_inconsistent.b = 0; color_inconsistent.a = .4;
    std_msgs::ColorRGBA color_inconsistent_missing;
    color_inconsistent_missing.r = .0; color_inconsistent_missing.g = 0.5; color_inconsistent_missing.b = 0; color_inconsistent_missing.a = .4;

    std_msgs::ColorRGBA color_target_volume;
    color_target_volume.r = .5; color_target_volume.g = 0.5; color_target_volume.b = 0; color_target_volume.a = 1;

    std_msgs::ColorRGBA color_noneighbors;
    color_noneighbors.r = .5; color_noneighbors.g = 0; color_noneighbors.b = 1; color_noneighbors.a = .8;


    // Vector of Inconsistencies Initialization
    std::vector<ClassBoundingBox> vi;
    std::vector<ClassBoundingBox> vi_missing;

    // Creates the target volume message array
    ma.markers.push_back(target_volume.getMarkerWithEdges("target_volume", octree_frame_id , color_target_volume, ++id));


    ROS_INFO_STREAM("Starting Iteration");

    // Iterates over each region
    for (size_t i=0; i < boxes.size(); ++i)
    {
        size_t num_occupied = 0;
        size_t num_neighbors = 0;

        // Iterates over target Octree
        for(OcTree::leaf_bbx_iterator it = octree_target->begin_leafs_bbx(boxes[i].getMinimumPoint(), boxes[i].getMaximumPoint(), depth), end=octree_target->end_leafs_bbx(); it!= end; ++it)
        {
            // Verifies if the node exists
            if (octree_target->search(it.getKey())) 
            {

                num_neighbors++;

                // Verifies if the node is free
                if (!octree_target->isNodeOccupied(*it)) 
                {
                    // Do nothing
                }
                
                else
                {
                    num_occupied++;
                }
            }
        }

            double occupation_ratio=0;
            
            // Occupation Ratio computation
            if (num_neighbors !=0)
            {
                occupation_ratio = (double)num_occupied/(double)num_neighbors;
            }

            // Checks for Inconsistencies of type EXCEEDING
            if (boxes[i].occupied == false && occupation_ratio >= exceeding_threshold_with_regions && num_neighbors !=0) 
            {
                // Add the inconsistency cell into a vector
                vi.push_back(boxes[i]);
            }

            // Checks for Inconsistencies of type MISSING
            if (boxes[i].occupied == true && occupation_ratio <= missing_threshold_with_regions && num_neighbors !=0) //If no occupied cell was found out of all iterated in the model's bbox, then an inconsistency is detected
                {
                    // Add the inconsistency cell into a vector
                    vi_missing.push_back(boxes[i]);
                }
    }


    //Cluster the EXCEEDING cells
    vector< vector<size_t> > cluster; 
    clusterBoundingBoxes(vi, cluster);
    ROS_INFO("There are %ld clusters", cluster.size());
    class_colormap cluster_colors("autumn", cluster.size(), 0.8);

    // Cluster the MISSING cells
    vector< vector<size_t> > cluster_missing; 
    clusterBoundingBoxes(vi_missing, cluster_missing);
    ROS_INFO("There are %ld clusters_missing", cluster_missing.size());
    class_colormap cluster_missing_colors("summer", cluster_missing.size(), 0.8);

    //Select only EXCEEDING clusters above a given volume threshold
    vector< vector<size_t> > selected_cluster; 
    filterClustersByVolume(vi, cluster, selected_cluster, volume_threshold);
    ROS_INFO("Selected %ld clusters using volume threshold", selected_cluster.size());

    //Select only MISSING clusters above a given volume threshold
    vector< vector<size_t> > selected_cluster_missing; 
    filterClustersByVolume(vi_missing, cluster_missing, selected_cluster_missing, volume_threshold);
    ROS_INFO("Selected %ld clusters_missing using volume threshold", selected_cluster_missing.size());

    //Draw filtered inconsistencies clusters in RVIZ
    class_colormap inconsistencies_colors(0.5,0,0,0.4);
    clustersToMarkerArray(vi, selected_cluster, ma_inconsistencies, id_inconsistencies, octree_frame_id, "inconsistencies", inconsistencies_colors);
    class_colormap inconsistencies_missing_colors(0,0.5,0,0.4);
    clustersToMarkerArray(vi_missing, selected_cluster_missing, ma_inconsistencies, id_inconsistencies, octree_frame_id, "inconsistencies", inconsistencies_missing_colors);

    // Draw all the clusters in RVIZ
    size_t id_clusters=0;
    clustersToMarkerArray(vi, selected_cluster, ma_clusters, id_clusters, octree_frame_id, "clusters", cluster_colors);
    clustersToMarkerArray(vi_missing, selected_cluster_missing, ma_clusters, id_clusters, octree_frame_id, "clusters", cluster_missing_colors);

    // Draw the Center of Mass Sphere and Volume Information
    visualization_msgs::MarkerArray ma_centerofmass;
    visualization_msgs::MarkerArray ma_volumeText;
    size_t id_ma_centerofmass = 0;
    centerOfMass(vi, selected_cluster, ma_centerofmass, ma_volumeText, id_ma_centerofmass, octree_frame_id);
    centerOfMass(vi_missing, selected_cluster_missing, ma_centerofmass, ma_volumeText, id_ma_centerofmass, octree_frame_id);

    // Publish the Marker Arrays
    marker_pub_inconsistencies->publish(ma_inconsistencies);
    marker_pub_clusters->publish(ma_clusters);
    marker_pub->publish(ma);
    marker_pub_center_of_mass->publish(ma_centerofmass);
    marker_pub_volume->publish(ma_volumeText);


    // Paint the Point Cloud (if available) with the Inconsistencies information.
    if (!flg_received_point_cloud)
    {
        ROS_ERROR_STREAM("No point_cloud2 has been received yet");
    }
    else
    {
        ROS_INFO("Processing point cloud ...");

        *pc = *pcin;
        
        pcl_ros::transformPointCloud(octree_frame_id, *pc, *pc, *listener);
        
        *pc2 = *pc;
        
        pc2->points.erase(pc2->points.begin(), pc2->points.end());

        for (size_t k = 0; k < selected_cluster.size(); ++k)
        {
            std::vector<size_t> lpoints;
            for (size_t l = 0; l < selected_cluster[k].size(); ++l)
            {
                size_t idx = selected_cluster[k][l];
                std::vector<size_t> ltmp;
                ltmp = vi[idx].pointsInPointCloud(pc);

                lpoints.insert(lpoints.end(), ltmp.begin(), ltmp.end());
            }

            // Change color of points to cluster color
            for (size_t i=0; i< lpoints.size(); ++i)
            {
                cv::Scalar c = cluster_colors.cv_color(k);
                int8_t r = c[2], g = c[1], b = c[0];
                uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
                pc->points[lpoints[i]].rgb = *reinterpret_cast<float*>(&rgb);;
                pc2->points.push_back(pc->points[lpoints[i]]);

            }
        }

        pc2->is_dense = false;
        pc2->width = pc2->points.size();
        pc2->height = 1;
        sensor_msgs::PointCloud2 pcmsgout;
        pcl::toROSMsg(*pc2, pcmsgout);
        pub_pointcloud->publish(pcmsgout);

    }

    ros::Duration d = (ros::Time::now() - t);
    ROS_INFO("Comparisson took %f secs", d.toSec());
}
示例#3
0
int main(int argc, char** argv)
{
  ros::init(argc, argv, "pose_3d");
  
  ros::NodeHandle node;
  
  ros::Rate rate(10.0);
  
  tf::TransformListener listener;
  static tf::TransformBroadcaster br;
  tf::Transform transform;
  tf::StampedTransform stransform;
  tf::Quaternion q;

  ros::Publisher path_pub = node.advertise<nav_msgs::Path>("/youbotPath", 15);
  ros::Publisher grid_pub = node.advertise<nav_msgs::OccupancyGrid>("/nav_map", 15);
  ros::Publisher mark_pub = node.advertise<visualization_msgs::MarkerArray>("/NBVs", 15);
  
  //sleep(5);
  
  ros::Subscriber sub = node.subscribe("/octomap_binary", 15, map_cb);
  ros::Subscriber flag_sub = node.subscribe("/nbv_iter", 15, flag_cb);
  ros::Subscriber grid_sub = node.subscribe("/projected_map", 15, grid_cb);
  
  point3d sensorOffset(0.1, 0.3, 0);
  point3d firstPos;
  
  /*//Create transform from sensor to robot base
  transform.setOrigin( tf::Vector3(sensorOffset.x(), sensorOffset.y(), 0.0) );
  q.setRPY(0, 0, 0);
  transform.setRotation(q);
  br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "base", "xtion"));
  br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "baseGoal", "sensorGoal"));
  //-----------------------*/
  
  const clock_t start = std::clock();
  
  point3d curPose(-1.1, -0.05, 0.0);
  vector<point3d> NBVList;
  vector<point3d> PoseList;
  visualization_msgs::MarkerArray views;
  
  transform.setOrigin( tf::Vector3(curPose.x(), curPose.y(), 0) );
  q.setRPY(0, 0, DEG2RAD(-90));
  transform.setRotation(q);
  ros::Time gTime = ros::Time::now();
  br.sendTransform(tf::StampedTransform(transform, gTime, "vicon", "sensorGoal"));
  
  //Create transform from sensor to robot base
  //transform.setOrigin( tf::Vector3(sensorOffset.x(), sensorOffset.y(), 0.0) );
  //q.setRPY(0, 0, 0);
  //transform.setRotation(q);
  //br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "xtion", "base"));
  //br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "sensorGoal", "baseGoal"));
  //-----------------------
  
  sleep(1);
  
  //int x;
  //cin >> x;
  
  //moveBase(origin, yaw, &listener);
  
  cout << range << endl;
  
  cout << sRes << endl;
  
  //Setup Stuff
  //OcTree tree(res);
  
  cout << "Loading Sensor Model from File" << endl;
    
  ifstream readEm("SensorModel.bin", ios::in | ios::binary);
  
  while (!readEm.eof())
  {
    int buffer;
    readEm.read((char*)&buffer, sizeof(int));
    if (buffer < 0) break;
    optiMap.push_back(buffer);
    vector<int> tempRay;
    while (!readEm.eof())
    {
      readEm.read((char*)&buffer, sizeof(int));
      if (buffer < 0) break;
      tempRay.push_back(buffer);
    }
    optiRays.push_back(tempRay);
  }
  
  readEm.close();
  
  cout << "Finished Loading Sensor Model" << endl;
  
  double tempRoll, tempPitch, tempYaw;
  try{
  gTime = ros::Time::now();
  listener.waitForTransform("vicon", "xtion", gTime, ros::Duration(15.0));
  listener.lookupTransform("vicon", "xtion", gTime, stransform);
  }
  catch (tf::TransformException &ex) {
    ROS_ERROR("%s",ex.what());
    ros::Duration(1.0).sleep();
  }
  point3d origin(stransform.getOrigin().x(), stransform.getOrigin().y(), stransform.getOrigin().z());
  tf::Matrix3x3 rot(stransform.getRotation());
  rot.getRPY(tempRoll, tempPitch, tempYaw);
  NBVList.push_back(origin);
  
  cout << "Starting Pose: " << tempYaw << " : " << tempPitch << endl;
  
  visualization_msgs::Marker mark;
  mark.header.frame_id = "vicon";
  mark.header.stamp = ros::Time::now();
  mark.ns = "basic_shapes";
  mark.id = 0;
  mark.type = visualization_msgs::Marker::ARROW;
  mark.action = visualization_msgs::Marker::ADD;
  
  mark.pose.position.x = origin.x();
  mark.pose.position.y = origin.y();
  mark.pose.position.z = origin.z();
  
  q.setRPY(0, tempPitch, tempYaw);

  mark.pose.orientation.x = q.getX();
  mark.pose.orientation.y = q.getY();
  mark.pose.orientation.z = q.getZ();
  mark.pose.orientation.w = q.getW();
  
  mark.scale.x = 0.2;
  mark.scale.y = 0.02;
  mark.scale.z = 0.02;
  
  mark.color.r = 1.0f;
  mark.color.g = 0.0f;
  mark.color.a = 1.0;
  mark.color.b = 0.0f;
  
  views.markers.push_back(mark);
  
  mark_pub.publish(views);
  
  int NBVcount = 0;
  while (ros::ok())
  {
    /*cout << "NBV " << NBVcount++ << endl; 
    mapReceived = false;
    startAlg = false;
    while ((!mapReceived || !startAlg) && ros::ok())
    {
      mark_pub.publish(views);
      ros::spinOnce();
      rate.sleep();
    }
    
    //AbstractOcTree
    
    OcTree* treeTemp = binaryMsgToMap(mapMsg);
    
    //OcTree treeTemp(0.01);
    
    treeTemp->writeBinary("firstMap.bt");
    
    cout << "Loaded the Map" << endl;
    
    sleep(2);
    
    try{
    gTime = ros::Time::now();
    listener.waitForTransform("vicon", "xtion", gTime, ros::Duration(15.0));
    listener.lookupTransform("vicon", "xtion", gTime, stransform);
    }
    catch (tf::TransformException &ex) {
      ROS_ERROR("%s",ex.what());
      ros::Duration(1.0).sleep();
    }
    point3d camPosition (stransform.getOrigin().x(), stransform.getOrigin().y(), 0);
    origin = NBVList.back();
    
    cout << "Map Loaded " << treeTemp->getResolution() << endl;*/
    
    point3d egoPose(0, 0, 0);
    point3d endPoint(-1.4, -1.5, 0);
    
    //pObj Tuning Coefficients
    double alpha = 0.5;
    double beta = 2.0;
    
    size_t pointCount = 0;
    
    //point3d origin = curPose;
    point3d camPosition(0,0,0);
    
    OcTree tree(res);
    
    tree.setClampingThresMax(0.999);
    tree.setClampingThresMin(0.001);
    tree.setProbMiss(0.1);
    tree.setProbHit(0.995);
    
    tree.readBinary("firstMap.bt");
    
    tree.expand();
    
    for (OcTree::leaf_iterator iter = tree.begin_leafs(); iter != tree.end_leafs(); iter++)
    {
      bool flag = false;
      for (vector<point3d>::iterator nbvIt = NBVList.begin(); nbvIt != NBVList.end(); nbvIt++)
      {
	if (iter.getCoordinate().distanceXY(*nbvIt) < 0.6)
	{
	  flag = true;
	}
      }
      if (tree.isNodeOccupied(*iter)) // && (iter.getZ() < 0.03 || iter.getX() < -2 || iter.getX() > 1 || iter.getY() < -1 || iter.getY() > 1) || flag)
      {
	tree.setNodeValue(iter.getKey(), -lEmpty);
	tree.updateNode(iter.getKey(), false);
	
	if (tree.isNodeOccupied(*iter))
	{
	  cout << "Errrnk" << endl;
	}
      }
    }
    
    cout << origin.x() << ", " << origin.y() << endl;
    
    origin = tree.keyToCoord(tree.coordToKey(origin));
    
    cout << "Origin: " << origin.x() << " : " << origin.y() << " : " << origin.z() << endl;
    
    if (NBVcount == 1)
    {
      firstPos = origin;
    }
    
    //Use Second Tree to store pObj entities for NBV prediction    
    OcTree tree2(tree);
    
    string fileName = "algMap" + to_string(NBVcount) + ".bt";
    
    tree.writeBinary(fileName);
    
    //-------------------
    //Cost Function Work - 2D Map Creation, Dijkstras Path
    //-------------------
    double robotRad = 0.52;
    
    double minX, minY, minZ, maxX, maxY, maxZ;
    tree.getMetricMin(minX, minY, minZ);
    tree.getMetricMax(maxX, maxY, maxZ);
    point3d minPoint(minX, minY, minZ);
    point3d maxPoint(maxX, maxY, maxZ);
    
    cout << minX << ", " << maxX << ", " << minY << ", " << maxY << endl;
    minPoint = tree.keyToCoord(tree.coordToKey(minPoint));
    minX = minPoint.x();
    minY = minPoint.y();
    minZ = minPoint.z();
    maxPoint = tree.keyToCoord(tree.coordToKey(maxPoint));
    maxX = maxPoint.x();
    maxY = maxPoint.y();
    maxZ = maxPoint.z();
    
    cout << minX << ", " << maxX << ", " << minY << ", " << maxY << endl;
    
    tree.expand();
    
    int rangeX = round((maxX - minX) * rFactor);
    int rangeY = round((maxY - minY) * rFactor);
    
    vector<GridNode> gridMap(rangeX * rangeY, GridNode());
    vector<int> freeMap(rangeX * rangeY, 0);
    
    for (int x = 0; x < rangeX; x++)
    {
      for (int y = 0; y < rangeY; y++)
      {
	//cout << "XY: " << x << ", " << y << endl;
	gridMap[rangeX * y + x].coords = point3d(double(x) * res + minX, double(y) * res + minY, 0);
	
	for (int i = -1; i <= 1; i += 1)
	{
	  for (int j = -1; j <= 1; j += 1)
	  {
	    if ((i != 0 || j != 0) && x + i >= 0 && x + i < rangeX && y + j >= 0 && y + j < rangeY)
	    {
	      gridMap[rangeX * y + x].neighbors.push_back(&gridMap[rangeX * (y + j) + x + i]);
	      gridMap[rangeX * y + x].edges.push_back(sqrt(pow(i, 2) + pow(j, 2)) * res);
	      
	      //cout << gridMap[rangeX*y + x].neighbors.size() << ", " << gridMap[rangeX*y + x].edges.size() << endl;
	    }
	  }
	}
      }
    }
    
    cout << "First" << endl;
    
    tree.expand();
    for (OcTree::leaf_iterator iter = tree.begin_leafs(); iter != tree.end_leafs(); iter++)
    {
      /*if (!tree.isNodeOccupied(*iter) && iter.getZ() > 0)
      {
	int index = int((iter.getCoordinate().y() - minY) / res) * rangeX + (iter.getCoordinate().x() - minX) / res;
	
	gridMap[index].object = true;
	gridMap[index].occupied = true;
	
	for (double offX = -robotRad; offX <= robotRad; offX += res)
	{
	  for (double offY = -robotRad; offY <= robotRad; offY += res)
	  {
	    if (sqrt(pow(offX, 2) + pow(offY, 2)) <= robotRad)
	    {
	      int xInd = (gridMap[index].coords.x() + offX - minX) * rFactor;
	      int yInd = (gridMap[index].coords.y() + offY - minY) * rFactor;
	      
	      if (xInd >= 0 && xInd < rangeX && yInd >= 0 && yInd < rangeY)
	      {
		int offIdx = yInd * rangeX + xInd;
		gridMap[offIdx].occupied = true;
	      }
	    }
	  }
	}
      }*/
      
      if (!tree.isNodeOccupied(*iter) && iter.getZ() > 0 && iter.getZ() <= 0.5)
      {
	int index = round((iter.getCoordinate().y() - minY) / res) * rangeX + round((iter.getCoordinate().x() - minX) / res);
	freeMap[index]++;
      }
    }
    
    for (int index = 0; index < rangeX * rangeY; index++)
    {
      if (freeMap[index] < 20 && gridMap[index].coords.distanceXY(firstPos) > 0.8 && gridMap[index].coords.distanceXY(camPosition) > 0.2)
      {
	gridMap[index].object = true;
	gridMap[index].occupied = true;
	
	for (double offX = -robotRad; offX <= robotRad; offX += res)
	{
	  for (double offY = -robotRad; offY <= robotRad; offY += res)
	  {
	    if (sqrt(pow(offX, 2) + pow(offY, 2)) <= robotRad)
	    {
	      int xInd = round((gridMap[index].coords.x() + offX - minX) * rFactor);
	      int yInd = round((gridMap[index].coords.y() + offY - minY) * rFactor);
	      
	      if (xInd >= 0 && xInd < rangeX && yInd >= 0 && yInd < rangeY)
	      {
		int offIdx = yInd * rangeX + xInd;
		if (gridMap[offIdx].coords.distanceXY(firstPos) > 0.4 && gridMap[offIdx].coords.distanceXY(camPosition) > 0.3)
		{
		  gridMap[offIdx].occupied = true;
		}
	      }
	    }
	  }
	}
      }
    }
    
    cout << "Second" << endl;
    
    cout << rangeX << ", " << rangeY << " : " << int((origin.x() - minX) * rFactor) << ", " << int((origin.y() - minY) * rFactor) << endl;
    
    int origIdx = rangeX * int((origin.y() - minY) / res) + int((origin.x() - minX) / res);
    
    //round(((origin.y() - minY) * rFactor) * rangeX + (origin.x() - minX) * rFactor);
    
    cout << origIdx << "     " << gridMap.size() << endl;
    
    GridNode* originNode = &gridMap[origIdx];
    originNode->cost = 0;
    
    cout << "Got Here" << endl;
    
    MinHeap heapy;
    
    heapy.Push(originNode);
    
    while (heapy.GetLength() > 0)
    {
      GridNode* minNode = heapy.Pop();
      
      vector<float>::iterator edgeIt = minNode->edges.begin();
      for (vector<GridNode*>::iterator iter = minNode->neighbors.begin(); iter != minNode->neighbors.end(); iter++, edgeIt++)
      {
	GridNode* nodePt = *iter;
	if ((*iter)->occupied == 0 && (*iter)->cost > (minNode->cost + *edgeIt))
	{
	  (*iter)->parent = minNode;
	  
	  if ((*iter)->state == 0)
	  {
	    (*iter)->cost = minNode->cost + *edgeIt;
	    heapy.Push((*iter));
	    (*iter)->state = 1;
	  }
	  else if ((*iter)->state == 1)
	  {
	    heapy.Update((*iter)->heapIdx, minNode->cost + *edgeIt);
	  }
	}
      }
    }
    
    cout << "Dijkstra Path Complete" << endl;
    
    nav_msgs::OccupancyGrid grid;
    grid.header.stamp = ros::Time::now();
    grid.header.frame_id = "vicon";
    
    nav_msgs::MapMetaData metas;
    metas.resolution = res;
    metas.origin.position.x = minX;
    metas.origin.position.y = minY;
    metas.origin.position.z = 0.07;
    metas.height = rangeY;
    metas.width = rangeX;
    
    grid.info = metas;
    
    cout << gridMap.size() << endl;
    
    for (vector<GridNode>::iterator iter = gridMap.begin(); iter != gridMap.end(); iter++)
    {
      if (iter->occupied)
      {
	grid.data.push_back(100);
      }
      else
      {
	grid.data.push_back(0);
      }
    }
    
    grid_pub.publish(grid);
    
    cout << "Map Published" << endl;
    
    pointCount = 0;
    
    int cubeCount = 0;
    int emptyCount = 0;
    /*tree.expand();
    for (OcTree::leaf_iterator iter = tree.begin_leafs(); iter != tree.end_leafs(); iter++)
    {
      if (tree.isNodeOccupied(*iter))
      {
	pointCount++;
      }
      else
      {
	emptyCount++;
      }
    }*/
    
    cout << cubeCount << " cubes" << endl;
    
    cout << "Empties: " << emptyCount << endl;
    
    //OcTreeCustom infoTree(res);
    
    //infoTree.readBinary("kinect.bt");
    
    //Copy all occupancy values from known nodes into pObj variables for those nodes
    
    //infoTree.expand();
    
    /*for (OcTreeCustom::iterator iter = infoTree.begin(); iter != infoTree.end(); iter++)
    *   { *
    *   iter->setpObj(float(iter->getOccupancy()));
  }*/
    
    int cellCount = 0;
    int unkCount = 0;
    
    //pointCount = 0;
    
    cout << "Beginning pObj Processing" << endl;
    
    for (OcTree::leaf_iterator iter = tree.begin_leafs(); iter != tree.end_leafs(); iter++)
    {
      OcTreeKey occKey = iter.getKey();
      OcTreeKey unKey;
      OcTreeKey freeKey;
      OcTreeNode *cellNode;
      OcTreeNode *unNode;
      
      if (tree.isNodeOccupied(*iter))
      {
	cellCount++;
	
	for (int i = -1; i <= 1; i++)
	{
	  for (int j = -1; j <= 1; j++)
	  {
	    for (int k = -1; k <= 1; k++)
	    {
	      if (i != 0 || j != 0 || k != 0)
	      {
		unKey = occKey;
		unKey[0] += i;
		unKey[1] += j;
		unKey[2] += k;
		
		unNode = tree.search(unKey);
		
		if (unNode == NULL)
		{
		  bool critical = false;
		  for (int u = -1; u <= 1; u++)
		  {
		    for (int v = -1; v <= 1; v++)
		    {
		      for (int w = -1; w <= 1; w++)
		      {
			if (abs(u) + abs(v) + abs(w) == 1)
			{
			  freeKey = unKey;
			  freeKey[0] += u;
			  freeKey[1] += v;
			  freeKey[2] += w;
			  
			  cellNode = tree.search(freeKey);
			  
			  if (cellNode != NULL && !tree.isNodeOccupied(cellNode) && tree.keyToCoord(freeKey).z() > 0.15)
			  {//unKey is a critical unknown cell, proceed to update pObj of unknown cells in vicinity
			    critical = true;
			  }
			}
		      }
		    }
		  }
		  
		  if (critical)
		  {
		    //cout << "Occ: " << tree.keyToCoord(occKey).x() << ", " << tree.keyToCoord(occKey).y() << ", " << tree.keyToCoord(occKey).z() << endl;
		    //cout << "Unk: " << tree.keyToCoord(unKey).x() << ", " << tree.keyToCoord(unKey).y() << ", " << tree.keyToCoord(unKey).z() << endl;
		    tree2.updateNode(tree2.coordToKey(tree.keyToCoord(unKey)), (float)log(alpha / (1 - alpha)));
		    
		    //New method using custom tree
		    //infoTree.updateNode(tree.keyToCoord(unKey), float(0));
		    //infoTree.search(tree.keyToCoord(unKey))->setpObj((float)log(alpha / (1 - alpha)));
		    
		    unkCount++;
		    
		    for (double boxX = -5 * res; boxX <= 5 * res; boxX += res)
		    {
		      for (double boxY = -5 * res; boxY <= 5 * res; boxY += res)
		      {
			for (double boxZ = -5 * res; boxZ <= 5 * res; boxZ += res)
			{
			  point3d objPoint = tree.keyToCoord(unKey) + point3d(boxX, boxY, boxZ);
			  if (objPoint.z() > 0.05)
			  {
			    double pObj = alpha*exp(-sqrt(pow(boxX, 2) + pow(boxY, 2) + pow(boxZ, 2)) * beta);
			    cellNode = tree.search(objPoint);
			    if (cellNode == NULL)
			    {
			      if (tree2.search(objPoint) == NULL)
			      {
				tree2.setNodeValue(objPoint, log(pObj / (1 - pObj)));
				
				pointCount++;
			      }
			      else
			      {
				if ((tree2.search(objPoint))->getLogOdds() < (float)log(pObj / (1 - pObj)))
				{
				  tree2.setNodeValue(objPoint, log(pObj / (1 - pObj)));
				}
				//tree2.updateNode(objPoint, max((tree2.search(objPoint))->getLogOdds(), (float)log2(pObj / (1 - pObj))));
			      }
			    }
			    /*else
			    *											{
			    *												tree2.setNodeValue(objPoint, cellNode->getLogOdds());
			    * 
			    *												infoTree.search(objPoint)->setpObj(cellNode->getOccupancy());
			  }*/
			  }
			}
		      }
		    }
		  }
		}
	      }
	    }
	  }
	}
      }
    }
    
    /*infoTree.expand();
    * 
    *   f *or (OcTreeCustom::leaf_iterator iter = infoTree.begin_leafs(searchDepth); iter != infoTree.end_leafs(); iter++)
    *   {
    *   iter->updateOccupancyChildren();
    *   if (iter->getLogOdds() != 0 && abs(iter->getOccupancy() - iter->getpObj()) > 0.01)
    *   {
    *   cout << iter->getLogOdds() << ", " << iter->getOccupancy() << ", " << iter->getpObj() << endl;
    *   addCube(iter.getCoordinate(), res, 0, 0, 1, 0.5);
  }
  if (iter->getLogOdds() == 0 && iter->getpObj() > 0.001)
  {
  addCube(iter.getCoordinate(), sRes, 0, 1, 0, 0.5);
  }
  }*/
    
    /*tree.expand();
    tree2.expand();
    for (OcTree::leaf_iterator iter = tree.begin_leafs(); iter != tree.end_leafs(); iter++)
    {
      if (tree2.search(iter.getCoordinate())->getOccupancy() != iter->getOccupancy())
      {
	cout << tree2.search(iter.getCoordinate())->getOccupancy() << ", " << iter->getOccupancy() << endl;
      }
    }*/
    
    cout << "Nothing Different" << endl;
    
    tree2.writeBinary("objMap.bt");
    
    pointCount = 0;
    
    tree2.expand();
    
    KeyRay cellList;
    point3d egoCOG(2.95, 1.95, 0);
    Quaternion egoTheta(point3d(0, 0, -M_PI / 2));
    endPoint = point3d(3.0, 0, 0);
    OcTreeKey myCell;
    OcTreeNode *cellNode;
    double cellLike;
    
    Pose6D trialPose(egoCOG, egoTheta);
    endPoint = trialPose.transform(endPoint);
    
    //Pre-Computing Table Stuff
    point3d rayOrigin(0.005, 0.005, 0.005);
    point3d rayInit(nRayLength * res, 0, 0);
    point3d rayEnd;
    
    /*vector<int> castMap;
    *   v *ector<int> logAdd;
    *   
    *   cellCount = 0;
    *   int traversed = 0;
    *   
    *   Pointcloud castCloud;
    *   
    *   for (double yaw = 0; yaw < 360; yaw++)
    *   {
    *   cout << yaw << endl;
    *   for (double pitch = -90; pitch <= 90; pitch++)
    *   {
    *   Quaternion rayTheta(point3d(0, DEG2RAD(pitch), DEG2RAD(yaw)));
    *   Pose6D rayPose(rayOrigin, rayTheta);
    *   rayEnd = rayPose.transform(rayInit);
    *   
    *   cellList.reset();
    *   tree.computeRayKeys(rayOrigin, rayEnd, cellList);
    *   //cout << "cellList Size: " << cellList.size() << endl;
    *   for (KeyRay::iterator iter = ++cellList.begin(); iter != cellList.end(); iter++)
    *   {
    *   traversed++;
    *   point3d rayCoord = tree.keyToCoord(*iter) - rayOrigin;
    *   
    *   if (rayCoord.norm() * sRes / res > 0.6)
    *   {
    *   int index = round(rayCoord.x() / res) + nRayLength + (2 * nRayLength + 1) * round(rayCoord.y() / res + nRayLength) + pow(2 * nRayLength + 1, 2) * round(rayCoord.z() / res + nRayLength);
    *   vector<int>::iterator findIt = find(castMap.begin(), castMap.end(), index);
    *   if (findIt == castMap.end())
    *   {
    *   castMap.push_back(index);
    *   castCloud.push_back(rayCoord + rayOrigin);
    *   logAdd.push_back(lFilled);
    *   cellCount++;
  }
  else
  {
  int foundIndex = distance(castMap.begin(), findIt);
  logAdd[foundIndex] += lFilled;
  }
  }
  }
  }
  }
  cout << "Cells in CastMap: " << cellCount << "out of " << traversed << "cells traversed" << endl;
  cout << "Min Index: " << *min_element(castMap.begin(), castMap.end()) << endl;
  cout << "Max Index: " << *max_element(castMap.begin(), castMap.end()) << endl;
  cout << "Max logAdd: " << *max_element(logAdd.begin(), logAdd.end()) << endl;
  cout << nRayLength << endl;
  cout << "Cloud Size: " << castCloud.size() << endl;
  cout << "Inserting Cloud..." << endl;

  tree.insertPointCloud(castCloud, rayOrigin);
  tree.writeBinary("castMap.bt");

  //Write pre-computed tables to files for quick retrieval
  ofstream outFile("mapCast.bin", ios::out | ios::binary);
  for (vector<int>::iterator iter = castMap.begin(); iter != castMap.end(); iter++)
  {
  outFile.write((char*)&(*iter), sizeof(int));
  }
  outFile.close();

  outFile = ofstream("logAdd.bin", ios::out | ios::binary);
  for (vector<int>::iterator iter = logAdd.begin(); iter != logAdd.end(); iter++)
  {
  outFile.write((char*)&(*iter), sizeof(int));
  }
  outFile.close();

  cout << "Done Writing" << endl;

  while (true)
  {

  }*/
    
    //--------------------
    //Create 3D Arrays of object information for quick retrieval in infoGain calcs
    //--------------------
    
    //First pass to find limits of info bounding box	
    double temp_x, temp_y, temp_z;
    tree2.getMetricMax(temp_x, temp_y, temp_z);
    //infoTree.getMetricMin(temp_x, temp_y, temp_z);
    ibxMin = point3d(temp_x, temp_y, temp_z);
    tree2.getMetricMin(temp_x, temp_y, temp_z);
    //infoTree.getMetricMax(temp_x, temp_y, temp_z);
    ibxMax = point3d(temp_x, temp_y, temp_z);
    
    for (OcTree::iterator iter = tree2.begin_leafs(searchDepth); iter != tree2.end_leafs(); iter++)
    {
      if (iter->getOccupancy() > 0.001)
      {
	//addCube(iter.getCoordinate(), sRes, 0, 0, 1, 0.5);
	ibxMin.x() = min(ibxMin.x(), iter.getCoordinate().x());
	ibxMin.y() = min(ibxMin.y(), iter.getCoordinate().y());
	ibxMin.z() = min(ibxMin.z(), iter.getCoordinate().z());
	
	ibxMax.x() = max(ibxMax.x(), iter.getCoordinate().x());
	ibxMax.y() = max(ibxMax.y(), iter.getCoordinate().y());
	ibxMax.z() = max(ibxMax.z(), iter.getCoordinate().z());
      }
    }
    
    /*for (OcTreeCustom::leaf_iterator iter = infoTree.begin_leafs(searchDepth); iter != infoTree.end_leafs(); iter++)
    *   { *
    *   iter->updateOccupancyChildren();
    *   if (iter->getpObj() > 0.001)
    *   {
    *   if (iter.getCoordinate().x() < ibxMin.x()) ibxMin.x() = iter.getCoordinate().x();
    *   if (iter.getCoordinate().y() < ibxMin.y()) ibxMin.y() = iter.getCoordinate().y();
    *   if (iter.getCoordinate().z() < ibxMin.z()) ibxMin.z() = iter.getCoordinate().z();
    *   
    *   if (iter.getCoordinate().x() > ibxMax.x()) ibxMax.x() = iter.getCoordinate().x();
    *   if (iter.getCoordinate().y() > ibxMax.y()) ibxMax.y() = iter.getCoordinate().y();
    *   if (iter.getCoordinate().z() > ibxMax.z()) ibxMax.z() = iter.getCoordinate().z();
  }
  }*/
    
    cout << "Min Corner: " << ibxMin.x() << ", " << ibxMin.y() << ", " << ibxMin.z() << endl;
    cout << "Max Corner: " << ibxMax.x() << ", " << ibxMax.y() << ", " << ibxMax.z() << endl;
    
    cout << "S: " << sFactor << endl;
    
    //Determine required size of infoChunk array and initialize accordingly
    boxX = round((ibxMax.x() - ibxMin.x()) / sRes + 1);
    boxY = round((ibxMax.y() - ibxMin.y()) / sRes + 1);
    boxZ = round((ibxMax.z() - ibxMin.z()) / sRes + 1);
    
    cout << boxX << ", " << boxY << ", " << boxZ << endl;
    
    infoChunk = vector<vector<float> >(boxX * boxY * boxZ, { 0 , 0 });
    
    //Second pass to populate 3D array with info values
    tree2.expand();
    for (OcTree::leaf_bbx_iterator iter = tree2.begin_leafs_bbx(ibxMin, ibxMax, searchDepth); iter != tree2.end_leafs_bbx(); iter++)
    {
      if (iter.getCoordinate().z() > 0.05 && iter->getOccupancy() > 0.001)
      {
	int xInd = round((iter.getCoordinate().x() - ibxMin.x()) * sFactor);
	int yInd = round((iter.getCoordinate().y() - ibxMin.y()) * sFactor);
	int zInd = round((iter.getCoordinate().z() - ibxMin.z()) * sFactor);
	
	if (xInd < 0 || xInd >= boxX || yInd < 0 || yInd >= boxY || zInd < 0 || zInd >= boxZ) continue;
	
	int index = xInd + yInd * boxX + zInd * boxX * boxY;
	
	//addCube(iter.getCoordinate(), sRes, 0, 0, 1, 0.5);
	infoChunk[index][1] = iter->getOccupancy();
	infoChunk[index][0] = iter->getOccupancy();
      }
    }
    
    tree.expand();
    for (OcTree::leaf_bbx_iterator iter = tree.begin_leafs_bbx(ibxMin, ibxMax, searchDepth); iter != tree.end_leafs_bbx(); iter++)
    {
      int xInd = round((iter.getCoordinate().x() - ibxMin.x()) * sFactor);
      int yInd = round((iter.getCoordinate().y() - ibxMin.y()) * sFactor);
      int zInd = round((iter.getCoordinate().z() - ibxMin.z()) * sFactor);
      
      if (xInd < 0 || xInd >= boxX || yInd < 0 || yInd >= boxY || zInd < 0 || zInd >= boxZ) continue;
      
      int index = xInd + yInd * boxX + zInd * boxX * boxY;
      
      if (iter.getCoordinate().z() > 0.05 && tree.isNodeOccupied(*iter))
      {
	double p = exp(iter->getLogOdds()) / (1 + exp(iter->getLogOdds()));
	infoChunk[index][0] = (-p * log2(p) - (1 - p) * log2(1 - p)) * infoChunk[index][1];
	//infoChunk[index][0] = iter->getLogOdds();
      }
      else
      {
	infoChunk[index][0] = 0;
      }
    }
    
    /*for (OcTreeCustom::leaf_bbx_iterator iter = infoTree.begin_leafs_bbx(ibxMin, ibxMax, searchDepth); iter != infoTree.end_leafs_bbx(); iter++)
    *   { *
    *   iter->updateOccupancyChildren();
    *   if (iter->getpObj() > 0.001)
    *   {
    *   int xInd = round((iter.getCoordinate().x() - ibxMin.x()) / sRes);
    *   int yInd = round((iter.getCoordinate().y() - ibxMin.y()) / sRes);
    *   int zInd = round((iter.getCoordinate().z() - ibxMin.z()) / sRes);
    *   
    *   cout << iter->getLogOdds() << endl;
    *   infoChunk[xInd + yInd * boxX + zInd * boxX * boxY][0] = iter->getLogOdds();
    *   infoChunk[xInd + yInd * boxX + zInd * boxX * boxY][1] = iter->getpObj();
  }
  }*/
    
    cout << "infoChunk populated, uploading sensor model" << endl;
    
    cout << "Begin Test" << endl;
    
    //Search Algorithm
    vector<InfoNode> gains;
    float maxHeight = 0.62;
    float minHeight = 0.28;
    
    pointCount = 0;
    
    double maxIG = 0;
    double maxCost = 0;
    double maxPitch = 0;
    double maxYaw = 0;
    point3d bestPos(0, 0, 0);
    int viewCount = 0;
    
    int searchCount = 0;
    
    point3d searchBoxMin = ibxMin - point3d(1.5, 1.5, 1.5);
    point3d searchBoxMax = ibxMax + point3d(1.5, 1.5, 1.5);
    
    searchBoxMin.z() = max(searchBoxMin.z(), minHeight);
    searchBoxMax.z() = min(searchBoxMax.z(), maxHeight);
    
    cout << "Search Space: " << searchBoxMin.x() << ", " << searchBoxMin.y() << ", " << searchBoxMin.z() << endl;
    cout << "To: " << searchBoxMax.x() << ", " << searchBoxMax.y() << ", " << searchBoxMax.z() << endl;
    
    //-------------
    //Heuristic Search Method
    //-------------
    /*const clock_t searchStart = clock();
    * 
    *   i *nt neighbDist = 2;
    *   double neighborStepSize = 0.02;
    *   vector<InfoNode> neighbors(6 * neighbDist, InfoNode());
    *   
    *   tree.expand();
    *   double xMax, yMax, zMax, xMin, yMin, zMin;
    *   tree.getMetricMax(xMax, yMax, zMax);
    *   tree.getMetricMin(xMin, yMin, zMin);
    *   for (OcTree::leaf_bbx_iterator iter = tree.begin_leafs_bbx(searchBoxMin, searchBoxMax, 10); iter != tree.end_leafs_bbx(); iter++)
    *   {
    *   if (iter.getCoordinate().z() < 0 || iter.getCoordinate().x() < xMin || iter.getCoordinate().x() > xMax || iter.getCoordinate().y() < yMin || iter.getCoordinate().y() > yMax || iter.getCoordinate().z() < zMin || iter.getCoordinate().z() > zMax || tree.search(iter.getCoordinate()) == NULL || tree.isNodeOccupied(tree.search(iter.getCoordinate()))) continue;
    *   
    *   searchCount++;
  }

  cout << searchCount << " positions to calculate" << endl;
  for (OcTree::leaf_iterator iter = tree.begin_leafs(11); iter != tree.end_leafs(); iter++)
  {
  if (iter.getCoordinate().z() < 0 || iter.getCoordinate().x() < xMin || iter.getCoordinate().x() > xMax || iter.getCoordinate().y() < yMin || iter.getCoordinate().y() > yMax || iter.getCoordinate().z() < zMin || iter.getCoordinate().z() > zMax || tree.search(iter.getCoordinate()) == NULL || tree.isNodeOccupied(tree.search(iter.getCoordinate()))) continue;

  if (viewCount % 100 == 0)
  {
  cout << viewCount << endl;
  }
  point3d nextPos = iter.getCoordinate();
  float pitch, yaw;
  double infoGain = getInfoGain(&tree, &tree2, nextPos, &yaw, &pitch);

  if (infoGain > 0)
  {
  gains.push_back(InfoNode(infoGain, 0, nextPos, yaw, pitch));

  if (infoGain > maxIG)
  {
  maxIG = infoGain;
  bestPos = nextPos;
  maxYaw = yaw;
  maxPitch = pitch;
  }

  //addCube(nextPos, 0.05, 1 - (infoGain / 40), infoGain / 40, 0, 0.9);
  }

  viewCount++;
  }

  cout << "First Pass: "******" views" << endl;

  sort(gains.begin(), gains.end());

  vector<InfoNode>::iterator testIt = gains.end()--;

  vector<InfoNode> searchTails;

  vector<InfoNode>::iterator iter = gains.end()--;
  for (int i = 0; i < 5; i++)
  {
  cout << i << endl;
  InfoNode curNode = *iter;

  while (true)
  {
  cout << ".";
  point3d curPoint = curNode.coords;
  double curGain = curNode.infoGain;
  vector<InfoNode>::iterator neighbIt = neighbors.begin();

  for (int offX = -neighbDist; offX <= neighbDist; offX++)
  {
  for (int offY = -neighbDist; offY <= neighbDist; offY++)
  {
  for (int offZ = -neighbDist; offZ <= neighbDist; offZ++)
  {
  if ((offX != 0) + (offY != 0) + (offZ != 0) != 1) continue;

  point3d neighbor = curPoint + point3d(offX, offY, offZ) * neighborStepSize;
  neighbIt->coords = neighbor;

  if (neighbor.z() < 0 || neighbor.x() < xMin || neighbor.x() > xMax || neighbor.y() < yMin || neighbor.y() > yMax || neighbor.z() < zMin || neighbor.z() > zMax || tree.search(neighbor) == NULL || tree.isNodeOccupied(tree.search(neighbor)))
  {
  neighbIt->infoGain = 0;
  }
  else
  {
  float pitch, yaw;
  neighbIt->infoGain = getInfoGain(&tree, &tree2, neighbor, &yaw, &pitch);
  viewCount++;
  neighbIt->pitch = pitch;
  neighbIt->yaw = yaw;
  }

  neighbIt++;
  }
  }
  }

  InfoNode maxNeighb = *max_element(neighbors.begin(), neighbors.end());

  if (maxNeighb.infoGain <= curGain)
  {
  break;
  }
  else
  {
  curNode = maxNeighb;
  }
  }

  searchTails.push_back(curNode);

  iter--;

  cout << endl;
  }

  InfoNode hNBV = *max_element(searchTails.begin(), searchTails.end());

  const clock_t searchEnd = clock();

  cout << "Heuristic NBV: " << hNBV.coords.x() << ", " << hNBV.coords.y() << ", " << hNBV.coords.z() << endl;
  cout << "With Info Gain = " << hNBV.infoGain << endl;
  cout << "In " << double(searchEnd - searchStart) / CLOCKS_PER_SEC << " seconds, for " << viewCount << "candidate viewpoints" << endl;*/
    
    //Original Grid Search
    time_t time1 = time(0);
    viewCount = 0;
    
    tree.expand();
    for (OcTree::leaf_bbx_iterator iter = tree.begin_leafs_bbx(searchBoxMin, searchBoxMax, 14); iter != tree.end_leafs_bbx(); iter++)
    {
      if (!tree.isNodeOccupied(*iter))
      {
	searchCount++;
      }
    }
    
    vector<double> infoMap(rangeX * rangeY, 0);
    
    cout << searchCount << " positions to calculate" << endl;
    for (OcTree::leaf_iterator iter = tree.begin_leafs(14); iter != tree.end_leafs(); iter++)
    {
      if (tree.search(iter.getCoordinate()) == NULL || tree.isNodeOccupied(tree.search(iter.getCoordinate())) || iter.getCoordinate().z() < minHeight || iter.getCoordinate().z() > maxHeight) continue;
      
      if (viewCount % 100 == 0)
      {
	cout << viewCount << endl;
      }
      point3d nextPos = iter.getCoordinate();
      float pitch, yaw;
      double infoGain = getInfoGain(&tree, &tree2, nextPos, &yaw, &pitch);
      
      if (infoGain > 0)
      {
	double moveCost = gridMap[rangeX * int((nextPos.y() - minY) / res) + int((nextPos.x() - minX) / res)].cost;
	
	if (infoGain > infoMap[rangeX * int((nextPos.y() - minY) / res) + int((nextPos.x() - minX) / res)])
	{
	  infoMap[rangeX * int((nextPos.y() - minY) / res) + int((nextPos.x() - minX) / res)] = infoGain;
	}
	
	gains.push_back(InfoNode(infoGain, moveCost, nextPos, yaw, pitch));
	
	if (infoGain > maxIG)
	{
	  maxIG = infoGain;
	  bestPos = nextPos;
	  maxYaw = yaw;
	  maxPitch = pitch;
	}
	
	if (moveCost > maxCost && moveCost < 600)
	{
	  maxCost = moveCost;
	}
	
	/*infoCloud->points[pointCount].x = nextPos.x();
	*	infoCloud->points[pointCount].y = nextPos.y();
	*	infoCloud->points[pointCount].z = nextPos.z();
	*	infoCloud->points[pointCount].intensity = infoGain;
	*	pointCount++;*/
	
	//addCube(nextPos, 0.05, 1 - (infoGain / 40), infoGain / 40, 0, 0.9);
      }
      
      viewCount++;
    }
    
    cout << "Time for " << viewCount << " views: " << (int)time(0) - time1 << endl;
    cout << "The NBV is at (" << bestPos.x() << ", " << bestPos.y() << ", " << bestPos.z() << ") with an expected info gain of " << maxIG << endl;
    
    cout << maxYaw << ", " << maxPitch << endl;
    
    cout << "Max Cost: " << maxCost << endl;
    
    double maxQual = 0;
    double correctIG = 0;
    point3d NBV = origin;
    
    for (vector<InfoNode>::iterator iter = gains.begin(); iter != gains.end(); iter++)
    {
      //iter->infoGain /= maxIG;
      //iter->cost /= maxCost;
      
      if (iter->cost < 600) iter->quality = iter->infoGain - 0 * iter->cost;
      else iter->quality = 0;
      
      if (iter->quality > maxQual)
      {
	maxQual = iter->quality;
	correctIG = iter->infoGain;
	NBV = iter->coords;
	maxYaw = iter->yaw;
	maxPitch = iter->pitch;
      }
    }
    
    cout << "Time for " << viewCount << " views: " << (int)time(0) - time1 << endl;
    cout << "The corrected NBV is at (" << NBV.x() << ", " << NBV.y() << ", " << NBV.z() << ") with a quality of " << maxQual << "and IG of " << correctIG << endl;
    cout << "Yaw: " << maxYaw << ", " << "Pitch: " << maxPitch << endl;
    
    point3d oldBest = bestPos;
    
    if (maxIG < 10)
    {
      cout << "Algorithm Complete" << endl;
      break;
    }
    
    NBVList.push_back(NBV);
    visualization_msgs::Marker mark;
    mark.header.frame_id = "vicon";
    mark.header.stamp = ros::Time::now();
    mark.ns = "basic_shapes";
    mark.id = NBVcount;
    mark.type = visualization_msgs::Marker::ARROW;
    mark.action = visualization_msgs::Marker::ADD;
    
    mark.pose.position.x = NBV.x();
    mark.pose.position.y = NBV.y();
    mark.pose.position.z = NBV.z();
    
    q.setRPY(0, DEG2RAD(-maxPitch), DEG2RAD(maxYaw));

    mark.pose.orientation.x = q.getX();
    mark.pose.orientation.y = q.getY();
    mark.pose.orientation.z = q.getZ();
    mark.pose.orientation.w = q.getW();
    
    mark.scale.x = 0.2;
    mark.scale.y = 0.02;
    mark.scale.z = 0.02;
    
    mark.color.r = 0.0f;
    mark.color.g = 1.0f;
    mark.color.a = 1.0;
    mark.color.b = 0.0f;
    
    views.markers.push_back(mark);
    
    mark_pub.publish(views);
    
    /*transform.setOrigin( tf::Vector3(NBV.x(), NBV.y(), 0) );
    q.setRPY(0, 0, DEG2RAD(maxYaw));
    transform.setRotation(q);
    gTime = ros::Time::now();
    br.sendTransform(tf::StampedTransform(transform, gTime, "vicon", "sensorGoal"));
    
    sleep(1);
    
    try{
      listener.lookupTransform("vicon", "baseGoal",
				gTime, stransform);
    }
    catch (tf::TransformException &ex) {
      ROS_ERROR("%s",ex.what());
      ros::Duration(1.0).sleep();
    }
    point3d baseGoal(stransform.getOrigin().x(), stransform.getOrigin().y(), 0);
    m = tf::Matrix3x3(stransform.getRotation());
    double bRoll, bPitch, bYaw;
    m.getRPY(bRoll, bPitch, bYaw);*/ 
    
    point3d baseGoal = NBV;
    
    GridNode* endNode = &gridMap[rangeX * int((baseGoal.y() - minY) / res) + int((baseGoal.x() - minX) / res)];
    
    vector<point3d> waypoints;
    
    while (endNode != NULL)
    {
      //cout << endNode->coords.x() << ", " << endNode->coords.y() << endl;
      //cout << "Cost: " << endNode->cost << endl;
      endNode->cost = 0;
      waypoints.push_back(endNode->coords);
      //cout << endNode->coords.x() << ", " << endNode->coords.y() << endl;
      endNode = endNode->parent;
    }
    
    reverse(waypoints.begin(), waypoints.end());
    
    nav_msgs::Path path;
    path.header.stamp = ros::Time::now();
    path.header.frame_id = "vicon";
    
     int state = 0;
    int oldState = -1;
    for (vector<point3d>::iterator iter = waypoints.begin(); iter != waypoints.end(); iter++)
    {
      geometry_msgs::PoseStamped pose;
      pose.header.stamp = path.header.stamp;
      pose.header.frame_id = path.header.frame_id;
      pose.pose.position.x = iter->x();
      pose.pose.position.y = iter->y();
      pose.pose.position.z = NBV.z();
      pose.pose.orientation.y = maxPitch;
      pose.pose.orientation.z = maxYaw;
      
      if (path.poses.size() > 0)
      {
	if (iter->x() == path.poses.back().pose.position.x)
	{
	  state = 0;
	}
	else if (iter->y() == path.poses.back().pose.position.y)
	{
	  state = 1;
	}
	else
	{
	  state = 2;
	}
      }
      
      //cout << "State, Old State, Size: " << state << " : " << oldState << " : " << path.poses.size() << endl;
      
      if (path.poses.size() > 1 && state == oldState)
      {
	path.poses.pop_back();
	//cout << pose.pose.position.x << ", " << pose.pose.position.y << endl;
      }
      
      path.poses.push_back(pose);
      
      oldState = state;
    }
    
    /*for (vector<point3d>::iterator iter = waypoints.begin(); iter != waypoints.end(); iter++)
    {
      geometry_msgs::PoseStamped pose;
      pose.header.stamp = path.header.stamp;
      pose.header.frame_id = path.header.frame_id;
      pose.pose.position.x = iter->x();
      pose.pose.position.y = iter->y();
      pose.pose.position.z = NBV.z();
      pose.pose.orientation.y = maxPitch;
      pose.pose.orientation.z = maxYaw;
      
      
      path.poses.push_back(pose);
      
      //cout << path.poses.back().position.x << ", " << path.poses.back().position.y << endl;
    }*/
    
    cout << "Path Message Generated" << endl;
    
    path_pub.publish<nav_msgs::Path>(path);
    ros::spinOnce();
    
    cout << "Path Message Published" << endl;
  }
  
  while (ros::ok())
  {
    mark_pub.publish(views);
    rate.sleep();
    ros::spinOnce();
  }
  
  return 0;
}
示例#4
0
void nav_callback(const projeto::QuadStatus status)
{

    struct timeval stop, start;
    gettimeofday(&start, NULL);
    //do stuff

    double timestamp = status.header.stamp.toSec();

    theta = Vector3d(status.theta.x, status.theta.y, status.theta.z);

    Vector3d x_new(status.position.x, status.position.y, status.position.z);

    Vector3d vel(status.vel.x, status.vel.y, status.vel.z);

	//theta(0) = degree_to_rad(msg_in.rotX);
	//theta(1) = degree_to_rad(msg_in.rotY);
	//theta(2) = degree_to_rad(msg_in.rotZ);

	//ROS_INFO("I heard ax: [%f]  ay: [%f] az: [%f]", vx_, vy_, vz_);

	//Vector3d velV (vx_, vy_, vz_);

	//Quaternion<double> rotQ = rotation(theta);

	//Matrix3d R = rotQ.matrix();

	//Vector3d vel = R * velV;

    //pthread_mutex_lock(&mutex_1);

    //float dt = timestamp - previous_tm; //geting dt in secs



    if (x_new(0) < -10 || x_new(0) > 10 || x_new(1) < -10 || x_new(1) > 10) {

        f_vector_print("theta", theta);
		f_vector_print("x", x);
		f_vector_print("x_new", x_new);
		return;
    }

    x = x_new;

    previous_tm = timestamp;

   // pthread_mutex_unlock(&mutex_1);

    Vector3d future_position;

    vector<Vector3d> trajectory = predict_trajectory2(vel, x, timestamp, timestamp + TIME_AHEAD, TRAJECTORY_DT, future_position);


    float short_dist = MAX_DIST;

    nav_msgs::GridCells gcells;
    vector<geometry_msgs::Point> obstaclerepo;

    if (!production_mode) {
        sensor_msgs::PointCloud pc;
        pc.header.frame_id = "/nav";
        pc.header.stamp = ros::Time();
        pc.channels.resize(1);
        pc.channels[0].name="trajectory";
        pc.channels[0].values.resize(trajectory.size());
        pc.points.resize(trajectory.size());

        int i = 0;
        for (vector<Vector3d>::iterator it=trajectory.begin(); it!=trajectory.end(); ++it) {

            Vector3d pos = *it;

            pc.channels[0].values[i] = 0;
            pc.points[i].x = pos(0);
            pc.points[i].y = pos(1);
            pc.points[i].z = pos(2);
            i++;
        }
        pub_pc2.publish(pc);

        gcells.header.frame_id = "/nav";
        gcells.header.stamp = ros::Time();
        gcells.cell_width = OCTREE_RESOLUTION;
        gcells.cell_height = OCTREE_RESOLUTION;


    }

    if (control_mode) {

//        cout << "TIMESTAMP " << timestamp << endl;
//        cout << "CONTADOR " << contador << endl;
//        cout << "LIMIT " << CONTROL_LIMIT << endl;
        if (timestamp < contador + CONTROL_LIMIT) {

            double u_x = pid_x.getCommand(pos_obj(0) - x(0), timestamp);
            double u_y = pid_y.getCommand(pos_obj(1) - x(1), timestamp);
            double u_z = pid_z.getCommand(pos_obj(2) - x(2), timestamp);
            double u_yaw = pid_yaw.getCommand(yaw_obj - theta(2), timestamp);



            double cx   = within(cos(theta(2)) * u_x + sin(theta(2)) * u_y, -1, 1);
            double cy   = within(-sin(theta(2)) * u_x + cos(theta(2)) * u_y, -1, 1);
            double cz   = within(u_z, -1, 1);
            double cyaw = within(u_yaw, -1, 1);

           // f_vector_print("objetivo", pos_obj);

           // f_vector_print("posicao", x);

	   cout << "SENDING AUTOMATIC CONTROLS" << endl;

            Command cmd(cx, cy, cz, cyaw);
            send_velocity_command(cmd);

        } else {

            control_mode = 0;
	    cout << "CONTROL MODE OFF" << endl;
            send_collision_mode_msg(false);
            pid_x.reset();
            pid_y.reset();
            pid_z.reset();
            pid_yaw.reset();
        }


    } else {

        OcTreeKey bbxMinKey, bbxMaxKey;

        //Vector3d lim1 = x + R * Vector3d(0, -DELTA_VOL/2, -1.0);
        //Vector3d lim2 = x + R * Vector3d(DELTA_VOL, DELTA_VOL/2, 1.0);

        point3d min_vol = point3d(x(0)-DELTA_VOL/2, x(1) -DELTA_VOL/2, x(2)-1.0);
        point3d max_vol = point3d(x(0)+DELTA_VOL/2, x(1) +DELTA_VOL/2, x(2)+1.0);


        tree.coordToKeyChecked(min_vol, bbxMinKey);
        tree.coordToKeyChecked(max_vol, bbxMaxKey);

        for(OcTree::leaf_bbx_iterator it = tree.begin_leafs_bbx(bbxMinKey, bbxMaxKey), end_bbx = tree.end_leafs_bbx(); it!= end_bbx; ++it){

            //cout << "passei" << endl;

            point3d coords = it.getCoordinate();

            Vector3d wrapped_coords = Vector3d(coords(0), coords(1), coords(2));


            //if (!in_perimeter(x, wrapped_coords, 0.5)) {
            if (!production_mode) {
                geometry_msgs::Point cell;
                cell.x = coords(0);
                cell.y = coords(1);
                cell.z = coords(2);
                obstaclerepo.push_back(cell);
            }


            if (it->getValue() > OCCUPIED_PROB) {


                for (vector<Vector3d>::iterator it=trajectory.begin(); it!=trajectory.end(); ++it) {

                    Vector3d pos = *it;

                    if (there_will_be_collision(pos, wrapped_coords)) {

                        float dist = (wrapped_coords - x).norm();

			cout << "DIST " << dist << endl;

                        if (dist < short_dist) {
                            short_dist = dist;
                        }
                        break;
                    }

                }

            }
              //manipulate node, e.g.:
              //cout << "Node center: " << it.getCoordinate() << endl;
              //cout << "Node size: " << it.getSize() << endl;
              //cout << "Node value: " << it->getValue() << endl;

            if (short_dist < MAX_DIST) {

                float ttc = short_dist/vel.norm();

                if (ttc < TTC_LIMIT) {

                    pos_obj = x;
                    yaw_obj = atan2(sin(theta(2)),cos(theta(2)));
                    send_collision_mode_msg(true);
                    control_mode = 1;
                    contador = timestamp;
	            cout << "CONTROL MODE ON" << endl;
                    pid_x.reset();
                    pid_y.reset();
                    pid_z.reset();
                    pid_yaw.reset();

                }

            }
        }
        //}

    }

    if (!production_mode) {
        int count_cells = 0;
        gcells.cells.resize(obstaclerepo.size());
        while (!obstaclerepo.empty()) {
            gcells.cells[count_cells++] = obstaclerepo.back();
            obstaclerepo.pop_back();
        }
        //pub_grid_cell.publish(gcells);
    }


    gettimeofday(&stop, NULL);



    previous_vel = vel;

    previous_theta = theta;

    //previous_omega = omega;

    gettimeofday(&stop, NULL);

    //cout << "time took: "<< stop.tv_sec - start.tv_sec << "." << (stop.tv_usec - start.tv_usec)/1000000 << "s" << endl;

}