<commit_before>/**
* OpenCV (OCV) - Video capture on BBB
*
* GOAL:
* This program takes continuous images from the host camera and detect a circular
* object of specific color. The color and other configuration are provided as 
* input argument to the program.
*
* INPUT:
* The program takes two arguments: 
* - The video device node (0/1)
* - The object color (blue/red)
*
* OUTPUT:
* On each frame captured by the program, three files are exported into the 
* host filesystem (apache directory specifically):
* - A colored image with a green circular around the circular object
* - A binarized image of the colored image (previous bullet)
* - A text file containing information about the object captured
* In addition to storing images, at each frame iteration, the program executes a shell script
* to communicate information about the frame with the ATMEGA328.
*
* HOST REQUIREMENTS:
* The following packages are required to be installed on the host:
* - Apache2 server
* - OpenSSH server
**/

#include <fstream>
#include <iostream>
#include <cstring>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <cstdlib>
#include <sstream>
#include <stdio.h>
#include <ctime>
#include <unistd.h>

#define PI 3.14159265

using namespace cv;
using namespace std;

// Keep track of video camera frame number
long frameNumber = 0;

// Write to files every time the counter reaches zero
const int FRAME_EVERY = 3;
int currentFrame = FRAME_EVERY;

// Assign unique ID for each direction. 
// The ID must be in sync with the GUI direction values 
// (Please refer to the documentation for more information about the GUI code)

int direction = 0;
clock_t start_time;

const int FORWARD = 1;
const int REVERSE = 2;
const int RIGHT = 3;
const int LEFT = 4;
const int ROTATE = 5;
const int PAUSE = 6;
const int STOP = 7;

/**
* Get the distance between the object and the camera
* Please refer to the documentation report for more information 
* about the calculations
* @return Distance in cm
**/
double getDistance(double realDimention, double digitalDimention) {
	double FOCAL_LENGTH = 339.079; // in pixels
	int ERROR_MARGIN = 0; //pixels lost due to selection of circular shape
	return realDimention * FOCAL_LENGTH / (digitalDimention + ERROR_MARGIN);
}

/**
* Detect the edge point of the object. This information allows the 
* conclusion of the object digial radius
* @param imageDest Current video frame
* @param def Default point value in case no object was found
* @return arbitrary point on the object edge
**/
Point edgePoint(Mat imageDest, Point def) {
	int thresh = 100;

	// Canny Algorithm for object edge detection 
	Canny(imageDest, imageDest, thresh /*threshold1*/, thresh*2 /*threshold2*/, 3/*apertureSize*/);

	// Prepare data structure to store the edge points
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;

	// Perform the countour finder
	findContours(imageDest, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

	// If no object foud, return the provided default value
	if(contours.size() == 0) {
		return def;
	}
	
	// Return a point from the countour
	return contours[0][0];
}

/**
* Predefined set of colors that can be detected by the program
* The colors supported by the current program are blue and red 
* @param specs Data strucutre to hold the HSV channel color information
* based on the color specified
* @param color Color of the object (blue/red)
**/
void get_color_specs(vector<vector<int> > &specs, string color){

	if (!color.compare("blue")) {
		specs[0][0] = 100;
		specs[0][1] = 115;
		specs[0][2] = 50;
		specs[1][0] = 130;
		specs[1][1] = 255;
		specs[1][2] = 255;
	} else if (!color.compare("red")) {
		specs[0][0] = 0;
		specs[0][1] = 197;
		specs[0][2] = 109;
		specs[1][0] = 182;
		specs[1][1] = 255;
		specs[1][2] = 255;
	} else {
		specs[0][0] = 255;
		specs[0][1] = 255;
		specs[0][2] = 255;
		specs[1][0] = 255;
		specs[1][1] = 255;
		specs[1][2] = 255;
	}
}

void drive(int left, int right) {

	stringstream ss;
	ss << "/home/debian/mr_robot/tools/control/write " << left << "," << right << "#" << endl;
	cout << left << "," << right << "#" << endl;
	system(ss.str().c_str());
}

/**
* Drive the car based on the angle and distance
* Decisions are mainly taken based on experiments
* @param angle Car angel
* @param distance Distance of the car from the camera
* @param diameter Digital diameter of the circular object
* @param loop_count Necessary to keep from writing to Atmega328p faster than it can read messages
* @return Direction code
**/
void find_ball(double angle, double distance, double diameter, int &loop_count) {

	int full_speed = 255;
	int rotation_speed = 140;
	int turn_speed = 40;
	int pausing_distance = 45;
	int target_angle = 4;

	if (loop_count > 1) { 

		// If no object found: rotate
		if(diameter == 0 && direction != ROTATE) {
			cout << endl << "rotating ";
			drive(rotation_speed, -rotation_speed);
			direction = ROTATE;
			loop_count = 0;

			start_time = clock();

		// If object is within pausing_distance and visible: pause
		} else if(distance <= pausing_distance && diameter > 0 && direction != PAUSE) {<commit_msg>Added Matt changes<commit_after>/**
* OpenCV (OCV) - Video capture on BBB
*
* GOAL:
* This program takes continuous images from the host camera and detect a circular
* object of specific color. The color and other configuration are provided as 
* input argument to the program.
*
* INPUT:
* The program takes two arguments: 
* - The video device node (0/1)
* - The object color (blue/red)
*
* OUTPUT:
* On each frame captured by the program, three files are exported into the 
* host filesystem (apache directory specifically):
* - A colored image with a green circular around the circular object
* - A binarized image of the colored image (previous bullet)
* - A text file containing information about the object captured
* In addition to storing images, at each frame iteration, the program executes a shell script
* to communicate information about the frame with the ATMEGA328.
*
* HOST REQUIREMENTS:
* The following packages are required to be installed on the host:
* - Apache2 server
* - OpenSSH server
**/

#include <fstream>
#include <iostream>
#include <cstring>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <string>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <cstdlib>
#include <sstream>
#include <stdio.h>
#include <ctime>
#include <unistd.h>

#define PI 3.14159265

using namespace cv;
using namespace std;

// Keep track of video camera frame number
long frameNumber = 0;

// Write to files every time the counter reaches zero
const int FRAME_EVERY = 3;
int currentFrame = FRAME_EVERY;

// Assign unique ID for each direction. 
// The ID must be in sync with the GUI direction values 
// (Please refer to the documentation for more information about the GUI code)

int direction = 0;
clock_t start_time;

const int FORWARD = 1;
const int REVERSE = 2;
const int RIGHT = 3;
const int LEFT = 4;
const int ROTATE = 5;
const int PAUSE = 6;
const int STOP = 7;

/**
* Get the distance between the object and the camera
* Please refer to the documentation report for more information 
* about the calculations
* @return Distance in cm
**/
double getDistance(double realDimention, double digitalDimention) {
	double FOCAL_LENGTH = 339.079; // in pixels
	int ERROR_MARGIN = 0; //pixels lost due to selection of circular shape
	return realDimention * FOCAL_LENGTH / (digitalDimention + ERROR_MARGIN);
}

/**
* Detect the edge point of the object. This information allows the 
* conclusion of the object digial radius
* @param imageDest Current video frame
* @param def Default point value in case no object was found
* @return arbitrary point on the object edge
**/
Point edgePoint(Mat imageDest, Point def) {
	int thresh = 100;

	// Canny Algorithm for object edge detection 
	Canny(imageDest, imageDest, thresh /*threshold1*/, thresh*2 /*threshold2*/, 3/*apertureSize*/);

	// Prepare data structure to store the edge points
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;

	// Perform the countour finder
	findContours(imageDest, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

	// If no object foud, return the provided default value
	if(contours.size() == 0) {
		return def;
	}
	
	// Return a point from the countour
	return contours[0][0];
}

/**
* Predefined set of colors that can be detected by the program
* The colors supported by the current program are blue and red 
* @param specs Data strucutre to hold the HSV channel color information
* based on the color specified
* @param color Color of the object (blue/red)
**/
void get_color_specs(vector<vector<int> > &specs, string color){

	if (!color.compare("blue")) {
		specs[0][0] = 100;
		specs[0][1] = 115;
		specs[0][2] = 50;
		specs[1][0] = 130;
		specs[1][1] = 255;
		specs[1][2] = 255;
	} else if (!color.compare("red")) {
		specs[0][0] = 0;
		specs[0][1] = 197;
		specs[0][2] = 109;
		specs[1][0] = 182;
		specs[1][1] = 255;
		specs[1][2] = 255;
	} else {
		specs[0][0] = 255;
		specs[0][1] = 255;
		specs[0][2] = 255;
		specs[1][0] = 255;
		specs[1][1] = 255;
		specs[1][2] = 255;
	}
}

void drive(int left, int right) {

	stringstream ss;
	ss << "/home/debian/mr_robot/tools/control/write " << left << "," << right << "#" << endl;
	cout << left << "," << right << "#" << endl;
	system(ss.str().c_str());
}

/**
* Drive the car based on the angle and distance
* Decisions are mainly taken based on experiments
* @param angle <NAME>
* @param distance Distance of the car from the camera
* @param diameter Digital diameter of the circular object
* @param loop_count Necessary to keep from writing to Atmega328p faster than it can read messages
* @return Direction code
**/
void find_ball(double angle, double distance, double diameter, int &loop_count) {

	int full_speed = 200;
	int rotation_speed = 115;
	int turn_speed = 40;
	int pausing_distance = 75;
	int target_angle = 5;

	if (loop_count > 2) { 

		// If no object found: rotate
		if(diameter == 0 && direction != ROTATE) {
			cout << endl << "rotating ";
			drive(rotation_speed, -rotation_speed);
			direction = ROTATE;
			loop_count = 0;

			start_time = clock();

		// If object is within pausing_distance and visible: pause
		} else if(distance <= pausing_distance && diameter > 0 && direction != PAUSE) {
{'fraction_non_alphanumeric': 0.11056042699199391, 'fraction_numerical': 0.028974456728936334, 'mean_word_length': 4.088748787584869, 'pattern_counts': {'":': 0, '<': 96, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7437650', 'n_tokens_mistral': 3658, 'n_tokens_neox': 3309, 'n_words': 1299}