/*** Main Triangulation Function ***/
int main() 
{
  initialize_api(); // Initializes the robot API
  robot_connect("127.0.0.1"); // This always needs to be 127.0.0.1 to connect to the robot
  
  barcode_configure(2 /*number of digits*/, 10 /*barcodes per pass*/, 2 /*kept passes*/, 
                    2 /*skip pixel width*/, 2 /*min bar width*/, 100 /* Allowed skew */, -1 /*Otsu thresholding*/,
                    image_width /*image width*/, image_height /*image height*/);
  sleep(1);
  
  int** barcodes; // Pointer for a two-dimensional array, will hold returned barcodes
  int* xy; // Pointer to an array [x,y]
  camera_set(CAM_ANGLE); // Sets the tilt on the camera to the current defined camera angle
  
  // Create a thread to handle grabbing images for checking barcodes
  pthread_create(&vision_thread, NULL, barcode_start, NULL);
  
  // The final x and y coordinates of the three barcodes
  double x1,y1,x2,y2,x3,y3;
  x1 = y1 = x2 = y2 = x3 = y3 = 0.0;

  // Grab the current seen barcodes
  barcode_frame_wait(); // Waits for the next frame from the current counter
  barcodes = barcode_get_barcodes(); // Retrieves the barcodes in the 2D array
  
  int num_codes = (int)barcodes[0];  // Number of barcodes detected
  int num_digits = (int)barcodes[1]; // Number of digits per barcode (will be 2)
  printf("Detected %d barcodes %d digits long:\n", num_codes, num_digits);
  
  
  // Find three barcodes if we didn't see three at first 
  while (num_codes < 3) {
    // Code to shutdown when the high bump is pressed. Just in case we never find the cans...
    if (get_high_bump() == 1) {
      free(barcodes);
      robot_stop();
      
      /*** Teardown Code ***/
      vision_running = 0; // Tells the background thread to nicely finish
      pthread_join(vision_thread, NULL); // Waits nicely for the barcode module to shutdown
      shutdown_api(); // Shuts down the robot API
      return 0; // Returns 0
    }
    printf("Didn't see 3 barcodes. Moving to find them...\n\n");
    random_move((int)barcodes[0]);
    free(barcodes);
    sleep(3);
    barcode_frame_wait_start(); // Reset the frame wait counter to wait for next full frame
    barcode_frame_wait(); // Waits for the next frame from the current counter
    barcodes = barcode_get_barcodes(); // Retrieves the barcodes in the 2D array
    
    num_codes = (int)barcodes[0];  // Number of barcodes detected
    num_digits = (int)barcodes[1]; // Number of digits per barcode (will be 2)
    printf("Detected %d barcodes %d digits long:\n", num_codes, num_digits);
  }
    
  int i;
  /* Runs through the barcodes detected, which start at index [2] */
  for(i = 2; i < num_codes+2; i++)
    {
      /* This block converts the raw digits into actual numbers */
      int j;
      uint32_t sum = 0;
      for(j = 0; j < num_digits; j++)
	{
	  sum += barcodes[i][j] * pow(10,(num_digits-1)-j);
	}
      
      /* Get the X and Y positions of the cans relative to the robot */
      xy = barcode_get_cur_xy(sum);
      int bottom_y = convert_camera_y(barcodes[i][j+3]);
      double x_pos = can_xpos(bottom_y);
      double y_pos = can_ypos(x_pos,convert_camera_x(xy[0]));
      
      printf("Barcode: %d\tX_CAM: %d\tY_CAM: %d\n",sum,convert_camera_x(xy[0]),bottom_y);
      printf("X_POS: %f\n",x_pos);
      printf("Y_POS: %f\n",y_pos);
      
      // Save the (x,y) coordinates in the proper variables for use later
      switch(i - 1) {
      case 1:
	x1 = x_pos;
	y1 = y_pos;
	break;
      case 2:
	x2 = x_pos;
	y2 = y_pos;
	break;
      case 3:
	x3 = x_pos;
	y3 = y_pos;
	break;
      default:
	break;
      }    
      
      free(xy);
    }

  // We don't need the camera or barcodes any more, so free them up
  vision_running = 0; // Tells the background thread to nicely finish
  pthread_join(vision_thread, NULL); // Waits nicely for the barcode module to shutdown
  free(barcodes);

  /*** Calculate the centroid, and the distance and angle of rotation to it ***/
  double x_centroid = (x1 + x2 + x3) / 3.0;
  double y_centroid = (y1 + y2 + y3) / 3.0;
  double dist_centroid = sqrt((x_centroid * x_centroid) + (y_centroid * y_centroid));
  int16_t dist_cm = (int16_t) round(dist_centroid);
  double theta_centroid = atan((y_centroid / x_centroid));
  int16_t theta_deg = (int16_t) round(DEG_CONV * (theta_centroid * calculate_error_damp(dist_centroid)));
  printf("\n\nCentroid X: %f\nCentroid Y: %f\nDistance: %f\nAngle: %d\n\n",x_centroid,y_centroid,dist_centroid,theta_deg);

  // Use the distance and angle calculations to set the proper robot turn and move values
  int8_t speed;
  if(theta_deg >= 0){
    speed = ROBOT_SPEED;
  }
  else{ // If the angle is negative, turn clockwise (= negative speed)
    speed = ROBOT_SPEED * (-1);
    theta_deg = theta_deg*(-1); // Angle must be positive for turn_robot_wait()
  }
  printf("Turning by %d degrees\n", theta_deg);
  turn_robot_wait(speed,theta_deg);
  printf("Moving %d cm\n",dist_cm);
  move_distance_wait(ROBOT_SPEED,dist_cm);

  // Make sure the robot has stopped
  robot_stop();

  /*** Teardown Code ***/
  shutdown_api(); // Shuts down the robot API
  return 0; // Returns 0
 }
Ejemplo n.º 2
0
void gnc_full_stop(void)
{
    robot_stop();
    pid_set_target(0, 0);
    pid_set_target(1, 0);
}