void turnLeft(int maxspd, int minspd, int degrees) 
{
	//causes robot to spin left to a certain angle.

	int left1, left2, right1, right2, drotated = 0;
	get_motor_encoders(&left1, &right1);
	int turnLength = RIGHT_ANGLE_TURN_ENC * degrees / 90;
	
	while(drotated < turnLength) 
	{
		get_motor_encoders(&left2, &right2);
		drotated = ((left1 - left2) + (right2 - right1)) / 2;

		if(drotated < (maxspd - minspd) * 2)
		{
			//accelerate phase
			set_motors(-(minspd + drotated / 2), minspd + drotated / 2);
		} 
		else if(drotated < turnLength - (maxspd - minspd) * 2) 
		{
			//max speed phase
			set_motors(-maxspd, maxspd);
		} 
		else
		{
			//decelerate phase
			set_motors(-(minspd + (turnLength - drotated) / 2), minspd + (turnLength - drotated) / 2);
		}
		positioncalc();
	}
	set_motors(0, 0);
}
void moveBackwards(int maxspd, int minspd, int dist) 
{
	//speeds up, moves the robot backwards a certain distance, and slows down.

	int left1, left2, right1, right2;
	get_motor_encoders(&left1, &right1);
	
	while(1)
	{
		get_motor_encoders(&left2, &right2);
		int dtravelled = ((left1 - left2) + (right1 - right2)) / 2;

		if(dtravelled < (maxspd - minspd) * 2)
		{
			//accelerate phase
			set_motors(-(minspd + dtravelled / 2), -(minspd + dtravelled / 2));
		} 
		else if(dtravelled < dist - (maxspd - minspd) * 2) 
		{
			//max speed phase
			set_motors(-maxspd, -maxspd);
		} 
		else if(dtravelled < dist)
		{
			//decelerate phase
			set_motors(-(minspd + (dist - dtravelled) / 2), -(minspd + (dist - dtravelled) / 2));
		}
		else
		{
			break;
		}
		positioncalc();
	}
	set_motors(0, 0);
}
Exemple #3
0
//Position tracking on servo encoder reading.
double position_tracker(double curr_coord[2]) {
    //  Function update global var face_angle.
    //  Function update current coordinates.
    //  Return the distance traveled.

    int currenc[2] = {0, 0};
    get_motor_encoders(&currenc[LEFT], &currenc[RIGHT]);
    double dl = enc_to_dist(currenc[LEFT] - prevenc[LEFT]);
    double dr = enc_to_dist(currenc[RIGHT] - prevenc[RIGHT]);
    double dx = 0, dy = 0;
    double dangle = ( dl - dr )/ width;

    if (dangle != 0) {
        double rl = dl / dangle;
        double rr = dr / dangle;
        double rm = ( rl + rr ) / 2;
        dx = rm * ( cos(face_angle) - cos(face_angle + dangle) ); 
        dy = rm * ( sin(face_angle + dangle) - sin(face_angle) );
        face_angle += dangle;
        face_angle += (face_angle > to_rad(180)) ? -to_rad(360) : (face_angle < -to_rad(180)) ? to_rad(360) : 0;
    }
    else {
        dy = dl * cos(face_angle);
        dx = dr * sin(face_angle);
    }
    // Encoders update
    prevenc[LEFT] = currenc[LEFT]; 
    prevenc[RIGHT] = currenc[RIGHT];
    // Coordinates update
    
    curr_coord[0] += dx;       
    curr_coord[1] += dy;

    return sqrt(dx*dx + dy*dy);
}
void moveForwards(int maxspd, int minspd, int dist) 
{
	//speeds up, moves the robot forwards a certain distance, and slows down.

	int left1, left2, right1, right2;
	get_motor_encoders(&left1, &right1);
	
	while(1)
	{
		get_motor_encoders(&left2, &right2);
		int dtravelled = ((left2 - left1) + (right2 - right1)) / 2;

		if(dtravelled < (maxspd - minspd) * 2)
		{
			//accelerate phase
			set_motors(minspd + dtravelled / 2, minspd + dtravelled / 2);
		} 
		else if(dtravelled < dist - (maxspd - minspd) * 2) 
		{
			//max speed phase
			set_motors(maxspd, maxspd);
		} 
		else if(dtravelled < dist)
		{
			//decelerate phase
			set_motors(minspd + (dist - dtravelled) / 2, minspd + (dist - dtravelled) / 2);
		}
		else
		{
			break;
		}
		positioncalc();

		int ultrasound = get_us_dist();
		if(ultrasound < FRONT_WALL_MIN_DIST) { break; }
	}
	set_motors(0, 0);
}
void setup()
{
	connect_to_robot();
	initialize_robot();

	set_ir_angle(LEFT, -45);
	set_ir_angle(RIGHT, 45);

	set_origin();
	set_point(0, 0);
	print_square_centres();

	get_motor_encoders(&leftprev, &rightprev);
	moveBackwards(PHASE1_SPEED, PHASE1_SLOW, START_OFFSET * CM_TO_ENCODER); //move robot to centre of first square.
}
void positioncalc()
{
	//calculates robot position in each step/call.

	int leftenc, rightenc;
	get_motor_encoders(&leftenc, &rightenc);

	//gets change in left encoder and right encoder readings, convert to cm, and calculate angle turned by robot
	double leftdiff = (leftenc - leftprev) / CM_TO_ENCODER;
	double rightdiff = (rightenc - rightprev) / CM_TO_ENCODER;
	double anglediff = (leftdiff - rightdiff) / WIDTH;

	//saves current encoder values to global variables for next function call.
	leftprev = leftenc;
	rightprev = rightenc;

	//calculate change in x- and y- position.
	double deltax = 0.0, deltay = 0.0;	
	if(anglediff != 0) 
	{
		double radiusl = leftdiff / anglediff;
		double radiusr = rightdiff / anglediff;
		double radius = (radiusl + radiusr) / 2;

		deltax = (radius * cos(bearing)) - (radius * cos(bearing + anglediff));
		deltay = (radius * sin(bearing + anglediff)) - (radius * sin(bearing));
	}
	else if(anglediff == 0)
	{
		double dist = (leftdiff + rightdiff) / 2;
		deltax = dist * sin(bearing);
		deltay = dist * cos(bearing);
	}

	//saves current position and bearing to global variables.
	bearing += anglediff;
	if(bearing < 0) { bearing += 2 * M_PI; }
	else if(bearing > 2 * M_PI) { bearing -= 2 * M_PI; }
	xpos += deltax;
	ypos += deltay;

	//checks accurancy of the robot's calculated current position vs its real position
	//log_trail();
	//set_point(xpos, ypos);
}
Exemple #7
0
void spin(double curr_coord[2], double angle){
    if (angle == 0) 
        return;
    printf("Start Spinning: from %f, with :%f\n",to_degree(face_angle), to_degree(angle));
    double initial_angle = face_angle;
    int speed = 15;
    int tempspeed = 0;
    double angle_turned = 0; 
    double abs_angle = fabs(angle);
    double side = angle/fabs(angle);
    int tempenc[2] = {0, 0};

    while (angle_turned < abs_angle){
        get_motor_encoders(&tempenc[0], &tempenc[1]);
        double dl = enc_to_dist(tempenc[0] - prevenc[0]);
        double dr = enc_to_dist(tempenc[1] - prevenc[1]);
        face_angle += ( dl - dr )/ width;

        if (abs_angle < to_rad(30)){
            tempspeed = side * 1;
            set_motors(tempspeed, -tempspeed);
        }
        else if(angle_turned >= fabs(0.92*angle)){
            tempspeed = (tempspeed < 2) ? side : side * speed * (1 - fabs(angle_turned/angle));
            set_motors(tempspeed, -tempspeed);
        }
        else {
            set_motors(side*speed, side*-speed);
        }
        angle_turned = fabs(face_angle - initial_angle);
        prevenc[0] = tempenc[0];
        prevenc[1] = tempenc[1];
       //printf("Monitoring: angle: %f  X: %f , Y: %f \n", to_degree(face_angle), curr_coord[0], curr_coord[1] );

    }
    position_tracker(curr_coord);
    set_motors(0, 0);
    printf("(Spinning done ! %f \n", to_degree(face_angle) );
    usleep(10000);
}
Exemple #8
0
void followPath(Location path[], int pathLength, Location* currentLocation) {
	// Draw the path formed from collected points
	drawPath(path, pathLength);
	
	// Initialise the target location
	Location targetLocation = path[40];
	Measurement measurement = {0, 0, 0, 0};
	
	// Reset the measurements
	reset_motor_encoders();
	usleep(20000);
	
	// Initialise some variables
	double targetBearing = 0;
	double bearingDifference = 0;
	double closestDistance = 0;
	int closestLocationIndex = 0;
	int speedAddition = 0;
	int speedReduction = 0;
	int changeX = 0;
	int changeY = 0;
	
	// 120 -> 50, 70
	// 90  -> 40, 70
	int speed = 120;
	int speedLeft = speed;
	int speedRight = speed;
	
	// Get the robot moving
	set_motors(speed, speed);
	
	// Main control loop
	while(1) {
		// Take the measurement
		measurement.startLeft = measurement.endLeft;
		measurement.startRight = measurement.endRight;
		get_motor_encoders(&measurement.endLeft, &measurement.endRight);
		
		// Update the robot's bearing and location
		updateBearingAndLocation(&measurement, currentLocation);
		
		// Draw out the path taken
		set_point(currentLocation->x, currentLocation->y - 17.0);
		log_trail();
		
		if (speed - speedAddition < 1) {
			speedReduction = speed - 1;
		} else {
			speedReduction = speedAddition;
		}
		
		if (speed + speedAddition > 127) {
			speedAddition = 127 - speed;
		}
		
		// Adjust the wheel speeds according to to how wrong the robot's current direction is
		if (bearingDifference < 0) {
			speedLeft = speed - speedReduction;
			speedRight = speed + speedAddition;
		} else {
			speedLeft = speed + speedAddition;
			speedRight = speed - speedReduction;
		}
		
		set_motors(speedLeft, speedRight);
		
		// If closer than X cm to the last point in the path, stop the robot
		if (distance(&path[closestLocationIndex], &path[pathLength - 1]) < 23.0 || atFinalSquare(currentLocation)) {
			set_motors(0, 0);
			break;
		}
		
		// Find the point on the path that is closest to the robot
		closestDistance = distance(currentLocation, &path[0]);
		closestLocationIndex = 0;
		int i;
		for (i = 1; i < pathLength; i++) {
			if (closestDistance > distance(currentLocation, &path[i])) {
				closestDistance = distance(currentLocation, &path[i]);
				closestLocationIndex = i;
			} 
		}
		
		// Find the point on the path that is about X cm away from the robot
		targetLocation = path[closestLocationIndex];
		i = 1;
		while (distance(currentLocation, &targetLocation) < 50.0) {
			if (closestLocationIndex + i >= pathLength) {
				break;
			}
		
			targetLocation = path[closestLocationIndex + i];
			i++;
		}
		
		// Calculate difference between the current and target
		// location in terms of the x and y components
		//set_point(targetLocation.x, targetLocation.y);
		changeX = targetLocation.x - currentLocation->x;
		changeY = targetLocation.y - currentLocation->y;
		
		// Determine the target bearing and deal with some edge cases
		double angle = atan2(changeX, changeY);
		
		if (fabs(angle - currentLocation->bearing) <= fabs((2*M_PI - currentLocation->bearing) + angle)) {
			angle = angle - currentLocation->bearing;
		} else {
			angle = (2*M_PI - currentLocation->bearing) + angle;
		}
	

		if (angle > M_PI) {
			angle = currentLocation->bearing - 2*M_PI;
		}
		
		targetBearing = angle;
		
		// Adjust speed according to how wrong the robots current direction is
		bearingDifference = targetBearing - currentLocation->bearing;
		bearingDifference = angle;
		speedAddition = abs((int) (bearingDifference * 75.0));
		
		/*
		printf("Following the map \n");
		printf("Closest x = %f; y = %f \n", path[closestLocationIndex].x, path[closestLocationIndex].y);
		printf("Setting motor speeds: left = %d; right = %d \n", speedLeft, speedRight);
		printf("Current x = %f; y = %f; bearing %f %f \n", currentLocation->x, currentLocation->y, currentLocation->bearing, currentLocation->bearing * (180/M_PI));
		printf("Target x = %f; y = %f; bearing to target %f %f \n", targetLocation.x, targetLocation.y, targetBearing, targetBearing * (180/M_PI));
		printf("bearingDifference = %f %f; \n", bearingDifference, bearingDifference * (180/M_PI));
		printf("\n");
		*/
	}
}