Exemple #1
0
/// Initialize the Create
void oi_init(oi_t *self)
{
	lcd_clear();
	lcd_puts("Starting OI...");

	// Setup USART1 to communicate to the iRobot Create using serial (baud = 57600)
	UBRR1L = 16; // UBRR = (FOSC/16/BAUD-1);
	UCSR1B = (1 << RXEN) | (1 << TXEN);
	UCSR1C = (3 << UCSZ10);

	// Starts the SCI. Must be sent first
	oi_byte_tx(OI_OPCODE_START);
	oi_byte_tx(OI_OPCODE_BAUD);

	oi_byte_tx(8); // baud code for 28800
	wait_ms(100);
	
	// Set the baud rate on the Cerebot II to match the Create's baud
	UBRR1L = 33; // UBRR = (FOSC/16/BAUD-1);

	// Use Full mode, unrestricted control
	oi_byte_tx(OI_OPCODE_FULL);
	oi_set_leds(1, 1, 7, 255);
	
	oi_update(self);
	oi_update(self); // call twice to clear distance/angle

	lcd_clear();
}
Exemple #2
0
void turn_counterclockwise(oi_t *sensor, int degrees)
{
	int sum = 0;
	oi_set_wheels(500, -500); // move forward; full speed
	while (sum < degrees) {
		oi_update(sensor_data);
		sum += sensor_data->angle;
	}
	oi_set_wheels(0, 0); // stop
}
Exemple #3
0
void move_backward(oi_t *sensor, int centimeters)
{
	int sum = 0;
	oi_set_wheels(-500, -500); // move forward; full speed
	while (sum < centimeters) {
		oi_update(sensor_data);
		sum -= sensor_data->distance;
	}
	oi_set_wheels(0, 0); // stop
}
Exemple #4
0
/**
 * Virtual wall sensor function to detect the edge and prints to the putty that the wall was detected.
 * @param sensor_status - the robot
 **/
int check_virtual_wall(oi_t *sensor_status)
{
	oi_update(sensor_status);
	int status = sensor_status->virtual_wall;
	if (status == 1 && old_wall == 0)
	{
		oi_set_wheels(0,0);
		send_string("Virtual Wall Detected!");
	}
	old_wall = status;
	
	return status;
}
Exemple #5
0
void rotate_hare(int angle, int scale) {
	OBJAFF *oa_curr= &oa_buffer[0];
	OBJAFF *oa_new=  &oa_buffer[2];
	
	oa_identity(oa_curr);
	oa_identity(oa_new);

	oa_scale(oa_curr, scale, scale);
	oa_rotate(oa_new, angle & SIN_MASK);
	oa_postmultiply(oa_curr, oa_new);

   	oi_update(0, 1);
   	oa_update(0, 3);
}
Exemple #6
0
/**
 * Checks each of the cliff sensors and returns 1 if the sensor is tripped and prints to putty which sensor was tripped.
 * @param sensor_status - the robot 
 **/
int check_cliff(oi_t *sensor_status)
{
	
	int stop = 0;
		
    oi_update(sensor_status);

	if(old_cl != sensor_status->cliff_left)
	{
		old_cl = sensor_status->cliff_left;
		if(old_cl == 1)
		{
			oi_set_wheels(0, 0);
			stop = 1;
			send_string("Cliff Left Detected!");
		}
	}
	else if(old_cfl != sensor_status->cliff_frontleft)
	{
		old_cfl = sensor_status->cliff_frontleft;
		if(old_cfl == 1)
		{
			oi_set_wheels(0, 0);
			stop = 1;
			send_string("Cliff Front Left Detected!");
		}
	}
	else if(old_cfr != sensor_status->cliff_frontright)
	{
		old_cfr = sensor_status->cliff_frontright;
		if(old_cfr == 1)
		{
			oi_set_wheels(0, 0);
			stop = 1;
			send_string("Cliff Front Right Detected!");
		}
	}
	else if(old_cr != sensor_status->cliff_right)
	{
		old_cr = sensor_status->cliff_right;
		if(old_cr == 1)
		{
			oi_set_wheels(0, 0);
			stop = 1;
			send_string("Cliff Right Detected!");
		}
	}
	return stop;
}
/*
 *@apram sensor_status (structor that holds off os the info about the robot)
 */
int update_cliff(oi_t *sensor_status)
{
	
	int stop = 0;
		
    oi_update(sensor_status);

	if(old_cl != sensor_status->cliff_left)
	{
		old_cl = sensor_status->cliff_left;
		if(old_cl == 1)
		{
			stop = 1;
			oi_set_wheels(0, 0);
		}
	}
	else if(old_cfl != sensor_status->cliff_frontleft)
	{
		old_cfl = sensor_status->cliff_frontleft;
		if(old_cfl == 1)
		{
			stop = 1;
			oi_set_wheels(0, 0);
		}
	}
	else if(old_cfr != sensor_status->cliff_frontright)
	{
		old_cfr = sensor_status->cliff_frontright;
		if(old_cfr == 1)
		{
			stop = 1;
			oi_set_wheels(0, 0);
		}
	}
	else if(old_cr != sensor_status->cliff_right)
	{
		old_cr = sensor_status->cliff_right;
		if(old_cr == 1)
		{
			stop = 1;
			oi_set_wheels(0, 0);
		}
	}
	return stop;
}
Exemple #8
0
//Handler for OI, moved from control.
void oi_system()
{
	movement_data_t movement_data;
	rotation_data_t rotation_data;
	
	enum {
		oi_command_init = 0,
		oi_command_move = 1,
		oi_command_rotate = 2,
		oi_command_play_song = 3,
		oi_command_dump = 4,
		oi_command_end_sequence = 5
	} oi_command = usart_rx();

	txq_enqueue(oi_command);

	switch (oi_command) {

		case oi_command_init:
			oi_init(&(control.oi_state));
			break;

		case oi_command_move:
	
			if(rx_frame()) {
				r_error(error_frame,"Move should not have multiple frames.");
			}

			struct {
				uint16_t speed;
				uint16_t dist;
				bool stream;
			} *move_data = (void *) &control.data;
			
			struct {
				uint16_t dist;
				uint8_t flag;
			} *response_move = (void *) &control.data;

			#warning "Stream functionality to be implemented later."
			//Stream returns the distance traveled
			//lcd_puts  ("In OI subsystem"); //debug
			movement_data = move_dist(&(control.oi_state), move_data->dist, move_data->speed);
			
			response_move->dist = movement_data.travelled;
			response_move->flag = movement_data.flag;
			
			if (movement_data.flag != 0) {
				movement_data = move_dist(&(control.oi_state), -20, move_data->speed);
				response_move->dist += movement_data.travelled;
			}

			control.data_len = 3;
			tx_frame(false);
			break;

		case oi_command_rotate:

			if (rx_frame()) {
				r_error(error_bad_message, "Rotate should only have one data frame.");
			}

			int16_t *angle = &(control.data[0]); // TODO: test if this is the right number of bytes

			if (control.data_len != 2/*sizeof(*angle)*/) { // TODO: hardcoding to debug
				r_error(error_bad_message, "Received too much data with rotate "
																	   "message.");
			}

			struct {
				uint16_t rotation;
			} *response_rotation = (void *) &control.data;

			rotation_data = turn(&(control.oi_state), *angle);
			response_rotation->rotation = rotation_data.rotated;
			control.data_len = 2;
			tx_frame(false);
			break;
			
			//Sing me a song.
		case oi_command_play_song:
			
			#warning "oi_command_play_song is deprecated"
			
			;
			//assuming that we get two data frames, the first containing the notes and the second containing the durations.
			int j;
				struct {
					uint8_t n; //The number of notes present in the song
					//char data[n];
					uint8_t index;
				} *song_data = (void *) &control.data;
		
			//	int j;
		 
			while(rx_frame()) { //this should happen twice please
				char tmp_notes[song_data->n];
				char tmp_durs[song_data->n];
			
				for(j =0; j<song_data->n; j++) {
					//tmp_notes[n]; TODO: broken
					#warning "oi_command_play_song not implemented"
				}

			}
		
			break;

		case oi_command_dump:
			//copies all of the data from OI_UPDATE and transmits to Control.
			oi_update(&(control.oi_state));
			memcpy(control.data, &control.oi_state, sizeof(control.oi_state));
			control.data_len = sizeof(control.oi_state);
			tx_frame(false);
			break;
		
		case oi_command_end_sequence:
			#warning "oi_command_end_sequence not implemented"
			
			// Switch power LED off
			oi_set_leds(1, 1, 0, 0);
			
			wait_ms(50);
			
			// Switch power LED to orange
			oi_set_leds(1, 1, 170, 255);
			
			wait_ms(50);
			
			// Switch power LED off
			oi_set_leds(1, 1, 0, 0);
			
			wait_ms(50);
			
			// Switch power LED to yellow
			oi_set_leds(1, 1, 70, 255);
			
			wait_ms(50);
			
			// Switch power LED off
			oi_set_leds(1, 1, 0, 0);
			
			wait_ms(50);
			
			// Switch power LED back to default state (from oi_init())
			oi_set_leds(1, 1, 7, 255);
			
			// Play song
			songs_load(RICK_ROLL);
			
			break;
		
		default:
			r_error(error_bad_message, "Bad OI Command");
			break;
	}
}
Exemple #9
0
/**
* Runs the main part of the program.  Note it is an infinite loop.
* @author Group B1
* @date 12/4/2012
*/
void run_robot(oi_t *oi) 
{
	int x = STARTING_X_POS;
	int y = STARTING_Y_POS;
	int o = STARTING_ORENTATION;
	int msg = 0;
	while(1){

			char c = read_one_char(); 
			oi_update(oi);
			printf("11 %d\n", oi->virtual_wall);
			lprintf("\n      Group B1\n\n\n\n");
			lprintf("%d %d %d %d\n%d", oi->cliff_left_signal  , oi->cliff_frontleft_signal  , oi->cliff_frontright_signal  , oi->cliff_right_signal, oi->virtual_wall );
			if(	oi->cliff_left_signal > 1000 && oi->cliff_frontleft_signal > 1000 && oi->cliff_frontright_signal > 1000 && oi->cliff_right_signal > 1000 ){
				printf("10\n");
			}
			if(c == FORWARD)
			{	
				if(move_forward(oi, DEFAULT_DISTANCE) >= DEFAULT_DISTANCE){
					if(o == NORTH){
						y = y + 1 * STEP;
					}
					else if(o == EAST){
						x = x + 1 * STEP;
					}
					else if(o == SOUTH){
						y = y - 1 * STEP;
					}
					else if(o == WEST){
						x = x - 1 * STEP;
					}
					printf("2 %d %d %d %d\n", x,y,o,msg);
				}				
			}
			else if(c == RIGHT_TURN)
			{
				turn_clockwise();
				if(o == NORTH){
					o = WEST;
				}
				else if(o == EAST){
					o = NORTH;
				}
				else if(o == SOUTH){
					o = EAST;
				}
				else if(o == WEST){
					o = SOUTH;
				}
				printf("2 %d %d %d %d\n", x,y,o,msg);
			}
			else if(c == LEFT_TURN)
			{
				
				turn_counter_clockwise();
				if(o == NORTH){
					o = EAST;
				}
				else if(o == EAST){
					o = SOUTH;
				}
				else if(o == SOUTH){
					o = WEST;
				}
				else if(o == WEST){
					o = NORTH;
				}
				printf("2 %d %d %d %d\n", x,y,o,msg);

									
			}
			else if(c == RESET)
			{
				move_servo(0);
				x = STARTING_X_POS;
				y = STARTING_Y_POS;
				o = STARTING_ORENTATION;
				msg = 0;
				printf("2 %d %d %d %d\n", x,y,o,msg);
			}
			else if(c == MUSIC)
			{
				load_song();
				oi_play_song(JAWS);
			}
			else if(c == SCAN)
			{
				oi_update(oi);
				printf("1 %d %d %d %d %d ", oi->virtual_wall ,x,y,o,msg);
				for(int i = 0 ; i <= 1800 ;i = i + 1)
				{
					move_servo(i * 1);
					int x = ir_distance();
					printf("%d ", x);
				}
				printf("\n");
				move_servo(0);
			}				
	}
}
Exemple #10
0
/**
* The main loop which waits for commands via blue tooth and
* then acts based on commands received.
*
* @author Jacob Moyer,
*         Ed Droesch,
*         Aaron Pederson, &
*         Matthew Backes
*
* @date 12/13/2013
*/
void main()
{
    ///Initializes the open_interface struct to be used throughout the program.
    oi_t *sensor_data = oi_alloc();
    oi_init(sensor_data);
    initializer();
    char key =0;

    ///Waits for commands from the USART connection,
    ///Then performs the command and returns that the command was performed.
    while(1)
    {
        char message[32] = "";
        key = USART_Receive();

        ///Returns what the current tape sensor is reading.
        if (key == 'p')
        {
            oi_update(sensor_data);
            sprintf(message,"sensor->signal =%d\r\n",(int)sensor_data->cliff_frontleft_signal);
            string_tran(message);
        }

        ///Moves the servo motor to the 0 degree position.
        if(key == 'c')
        {
            calibrate_servo(0);
        }

        ///Scans 0 - 180 degrees in front of the robot and returns the readings,
        ///it also guesses where objects are and returns their angle and width.
        if(key == 'j')
        {
            fullScan();
            string_tran("Scan Complete.\r\n");
        }

        ///Moves FORWARD_DISTANCE centimeters forward.
        if(key =='w')
        {
            sprintf(message,"Moved %d\r\n",move(sensor_data, FORWARD_DISTANCE,&sensors));
            string_tran(message);
        }

        ///Moves BACKWARD_DISTANCE centimeters backwards.
        if(key=='s')
        {
            sprintf(message,"Moved %d\r\n",move(sensor_data, BACKWARD_DISTANCE,&sensors));
            string_tran(message);
        }

        ///Rotates ROTATE_DEGREES counterclockwise.
        if(key=='a')
        {
            turn_CCW(sensor_data,ROTATE_DEGREES);
            sprintf(message,"Rotated %d\r\n",ROTATE_DEGREES);
            string_tran(message);
        }

        ///Rotates ROTATE_DEGREES clockwise.
        if(key=='d')
        {
            turn_CCW(sensor_data,-ROTATE_DEGREES);
            sprintf(message,"Rotated %d\r\n",-ROTATE_DEGREES);
            string_tran(message);
        }

        ///Plays the Morrowind theme song.
        if(key=='r')
        {
            play_morrowind();
            string_tran("Playing song.");
        }
    }
}
/**
 *
 * Function that detects the error and updates the state of the iRobot
 * 
 * @param isRotating 0 if it's not rotating, 1 if it is
 * @return returns 1 if there's an error detected, 2 if it's only a light sensor, else 0
 */
int errorDetection(int isRotating)
{
	
	// update the sensors
	oi_update(sensor_data);
	
	// if there's an error, set to 1
	int detection = 0;
	
	/// light errors///
	/*
	// left sensor to detect white tape
	if(sensor_data->cliff_left_signal > WHITE_MIN)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 2;
		sensorArray[CLIFF_LEFT_SIGNAL] = 1;
	}
	// left sensor to detect black tape
	else if(sensor_data->cliff_left_signal < BLACK_MAX)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 2;
		sensorArray[CLIFF_LEFT_SIGNAL] = 2;
		
	}
	else
		sensorArray[CLIFF_LEFT_SIGNAL] = 0;
	
	// front left sensor to detect white tape
	if(sensor_data->cliff_frontleft_signal > WHITE_MIN)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 2;
		sensorArray[CLIFF_FRONT_LEFT_SIGNAL] = 1;
	}
	// front left sensor to detect black tape
	else if(sensor_data->cliff_frontleft_signal < BLACK_MAX)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 2;
		sensorArray[CLIFF_FRONT_LEFT_SIGNAL] = 2;
		
	}
	else
		sensorArray[CLIFF_FRONT_LEFT_SIGNAL] = 0;
	
	// front right sensor to detect white tape
	if(sensor_data->cliff_frontright_signal > WHITE_MIN)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 2;
		sensorArray[CLIFF_FRONT_RIGHT_SIGNAL] = 1;
	}
	// front right sensor to detect black tape
	else if(sensor_data->cliff_frontright_signal < BLACK_MAX)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 2;
		sensorArray[CLIFF_FRONT_RIGHT_SIGNAL] = 2;
		
	}
	else
		sensorArray[CLIFF_FRONT_RIGHT_SIGNAL] = 0;
	
	// right sensor to detect white tape
	if(sensor_data->cliff_right_signal > WHITE_MIN)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 2;
		sensorArray[CLIFF_RIGHT_SIGNAL] = 1;
	}
	// right sensor to detect black tape
	else if(sensor_data->cliff_right_signal < BLACK_MAX)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 2;
		sensorArray[CLIFF_RIGHT_SIGNAL] = 2;
		
	}
	else
		sensorArray[CLIFF_RIGHT_SIGNAL] = 0;
	*/
	
	/// bumper errors ///
	
	// left bumper
	if(sensor_data->bumper_left == 1)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 1;
		sensorArray[LEFT_BUMPER] = 1;
	}
	else
		sensorArray[LEFT_BUMPER] = 0;
	
	// right bumper
	if(sensor_data->bumper_right == 1)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 1;
		sensorArray[RIGHT_BUMPER] = 1;
	}
	else
		sensorArray[RIGHT_BUMPER] = 0;
	
	/// cliff errors ///
	
	// left cliff
	if(sensor_data->cliff_left == 1)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 1;
		sensorArray[CLIFF_LEFT] = 1;
	}
	else
		sensorArray[CLIFF_LEFT] = 0;
	
	// front left cliff
	if(sensor_data->cliff_frontleft == 1)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 1;
		sensorArray[CLIFF_FRONT_LEFT] = 1;
	}
	else
		sensorArray[CLIFF_FRONT_LEFT] = 0;
	
	// front right cliff
	if(sensor_data->cliff_frontright == 1)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 1;
		sensorArray[CLIFF_FRONT_RIGHT] = 1;
	}
	else
		sensorArray[CLIFF_FRONT_RIGHT] = 0;
	
	// right cliff
	if(sensor_data->cliff_right == 1)
	{
		// stop the iRobot
		oi_set_wheels(0, 0);
		// set detection to 1
		detection = 1;
		sensorArray[CLIFF_RIGHT] = 1;
	}
	else
		sensorArray[CLIFF_RIGHT] = 0;
	
		
	// if there's an error, print the status of the sensors
	if(detection != 0 && isRotating == 0);
		printSensorStatus(sensorArray);
	
	return detection;
}
/**
*	Used to control the robot.
*	Receive and transmit data, measure the distance from object and navigate to the retrieval zone.
**/
int main(void)
{
	lcd_init();
	timer3_init();
	timer_init();
	ADC_init();
	USART_Init();
	oi_t *sensor_data = oi_alloc();
	oi_init(sensor_data);//should turn the iRobot Create's power LED yellow
  
	lcd_init();
	serial_puts("Start");
	//USART_Transmit(13);
	//USART_Transmit(10);
	
	
    int TempAngle[4] = {0,0,0,0};
	int TempIR[4] = {0,0,0,0};
	int pos[4] = {0,0,0,0};
	int AddIR[4] = {0,0,0,0};
	int count[4] = {0,0,0,0};
	int found = 0;
	int x1 = 0;
	int x2 = 0;
	int x3 = 0;
	int x4 = 0;
	unsigned angle = 0;
	unsigned char IR = 0;
	volatile int i=0;
	volatile int x = 0;
	char command;
    char display[100];
	char display1[20];
	char display2[20];
	char display3[20];
	char display4[20];
	char display5[100];
	char display6[100];	
			
	while (1)
	{
		command = USART_Recieve();
		USART_Transmit(command);
		//USART_Transmit(13);
		//USART_Transmit(10);
		
		if (command == '1')
		{
			found = 0;
			angle = 0;
			int t;
			int TempAngle[6] = {0, 0,0,0,0,0};
			int TempIR[6] = {0, 0,0,0,0,0};
			int pos[6] = {0, 0,0,0,0,0};
			int AddIR[6] = {0, 0, 0,0,0,0};
			int count[6] = {0, 0, 0,0,0,0};
			for (angle = 0;angle < 181;angle++)
			{	
				move_servo(angle);
				wait_ms(20);				
				
				IR = 0;
				IR = 42800*pow(ADC_read(2),-1.23);
				
				sprintf(display6, "Angle: %5d		IR: %5d",angle,IR);
				serial_puts(display6);

				if (IR < 80)
				{
				   TempAngle[found]++;
				   count[found]++;
				   AddIR[found]+=IR;
				   TempIR[found]=AddIR[found]/count[found];
				}
				
				else
				{
					if(TempAngle[found] < 5)
					{
						TempAngle[found] = 0;
					}
					
					else
					{
						pos[found] = angle- TempAngle[found]/2;
						if (TempIR[found]*TempAngle[found]< 460)
						{
							USART_Transmit(13);
							USART_Transmit(10);
							for (int i = 0;i<strlen(s8);i++)
							{
								USART_Transmit(s8[i]);
							}
							
							sprintf(display5, "object position: %5d",pos[found]);
							serial_puts(display5);
						}
						sprintf(display, "object position: %5d		IR: %5d		object size: %5d",pos[found],TempIR[found],TempAngle[found]);
						serial_puts(display);
						USART_Transmit(13);
						USART_Transmit(10);
						found++;
					}	
			     }
			}
			OCR3B = 1000-1;				//return to 0 degree	
		}				

		 if (command == 'w')
		 {
			 move_forward(sensor_data,20);
		 }
		 if (command == 's')
		 {
			 move_backforward(sensor_data,20);
		 }
		 if (command == 'a')
		 {
			turn_clockwise(sensor_data,82);
		 }
		 if (command == 'd')
		 {
			turn_counterclockwise(sensor_data,82);
		 }
		 if (command == 'q')
		 {
			 turn_clockwise(sensor_data,38);
		 }
		 if (command == 'e')
		 {
			 turn_counterclockwise(sensor_data, 38);
		 }
		 if (command == '8')
		 {
			 move_forward(sensor_data,5);
		 }
		 if (command == '5')
		 {
			 move_backforward(sensor_data,5);
		 }
		 if (command == 'p')
		 {
			 oi_t* sensor = oi_alloc();
			 oi_init(sensor);
			 
			 load_songs();
			 oi_play_song(songings);
		 }
		 if(command == 'k')
		 {
			oi_update(sensor_data);
			x1 = sensor_data->cliff_left_signal;
			x2 = sensor_data->cliff_right_signal;
			x3 = sensor_data->cliff_frontleft_signal;
			x4 = sensor_data->cliff_frontright_signal; 
			sprintf (display1, "left        = %d",x1);
			sprintf (display2, "right       = %d",x2);
			sprintf (display3, "front left  = %d",x3);
			sprintf (display4, "front right = %d",x4);
			USART_Transmit(13);
			USART_Transmit(10);
	        serial_puts(display1);
	        serial_puts(display3);
	        serial_puts(display4);			
			serial_puts(display2);
			if (x1>500||x2>500||x3>500||x4>500)
			{
				USART_Transmit(13);
				USART_Transmit(10);
				for (int i=0;i<strlen(s6);i++)
				{
					USART_Transmit(s6[i]);
				}
			}						
		}
	}	
}