# Presentation: 685010

## Robotics With the XBC ControllerSession 6

- Instructor: David Culp
- Email: _[culpd](mailto:culpd@cfbisd.edu)__[@](mailto:culpd@cfbisd.edu)__[cfbisd](mailto:culpd@cfbisd.edu)__[.](mailto:culpd@cfbisd.edu)__[edu](mailto:culpd@cfbisd.edu)_

## Learning Goals

- The student will learn to use arrays in IC and download arrays from the XBC, in addition the student will learn the basics of the XBC camera and program a robot to follow a colored object.

## Arrays

- Arrays store a list of data.
- All data in the array MUST be of the same type.
- Every array has a length or the number of elements it can hold.
- Arrays in C are 0 based – the first array element is the 0’th element.
- The data stored in the elements of an array can be set and retrieved in the same manner as for other variables.

## Declaring Arrays

- Done like any other variable except [] enclose the number of array elements.
- void main()
- {
-     int an_array[20];
- }

## Accessing arrays

- Once again, done like any other variable except the element number is contained in [] behind the variable name.
- void main()
- {
-     int an_array[20];
-     int position = 4;
-     an_array[10] = 200;
-     an_array[position] = 18;
- }

## A short assignment

- Write a short program that does the following:
- Declares an int array of 30 elements that will hold the return value of an IR sensor.
- The program loops once a second (hint – use a for loop) 30 times storing the value of the IR sensor into the array.
- The program prints all 30 values to the GBA screen.

## Solution

- int ir_array[20];  // our array will hold 20 values – global to allow uploads
- void main()
- {
- int position;  //  keeps track of our position in the array
-     sleep(2.0);
-     beep();  //beep to let us know we have begun
-     for(position = 0; position < 20; position ++)
-       {  // begin counting to 20
-         ir_array[position] = analog(1);  /* assign the current array position the value of   	the analog function */
-         sleep(1.0);  // Remember we only take one reading a second!
-     }
-     beep();
-     for(position = 0; position < 20; position ++)
-       {
-         printf("Second %d: %d\n", position, ir_array[position]);
-     }
- }

## Slightly more advanced ways of declaring and initializing arrays.

- int foo[]= {0, 4, 5, -8, 17, 301};
- Creates an array of six integers, with **foo[0]** equaling **0**, **foo[1]** equaling **4**, etc.
- char string[]= "Hello there";
- int k[2][3];
- Two-dimensional array.

## Uploading Arrays (From the IC Manual)

- When an executing program is paused or has finished, IC can upload the values stored in any global array via the serial port.
- This permits collecting and recording data for purposes such as experimentation or calibration.
- Follow on screen demonstration.

## XBC Color Vision

- The next 5 slides were adapted from the XBC v2 Getting Started Guide located at _[http://www.](http://www.botball.org/educational-resources/ic_manuals.php)__[botball](http://www.botball.org/educational-resources/ic_manuals.php)__[.org/educational-resources/](http://www.botball.org/educational-resources/ic_manuals.php)__[ic](http://www.botball.org/educational-resources/ic_manuals.php)__[_manuals.](http://www.botball.org/educational-resources/ic_manuals.php)__[php](http://www.botball.org/educational-resources/ic_manuals.php)_.
- In color tracking, one selects a rectangular piece of color space and segments all of the pixels in the image that fall within that piece.
- Contiguous pixels are combined into blobs.
- Each blob has a size, position, number of pixels, major and minor axis, etc.
- These blobs correspond to objects seen in the image that are the desired color.
- Camera resolution is 356X292. 0,0 is the upper left; 356x292 is the lower right.

## Color Blobs

- The XBC can segment the image using three different pieces of color space (each is called a color model) simultaneously.
- It can track a number of blobs from each color model.
- It can display the video (raw, processed, alternating (flashes between raw & processed), and segmented into blobs) on the GBA display.

## More on Color Blobs

- A Color Model-HSV specifies a bounding box in the color selection plane.
- Moving either edge towards the center line constrains the range of accepted color values to only include more vivid colors (ie only accept things that are more like Astro Brights paper).
- If everything you want is being accepted but so is a lot of other junk you don't want, move the corners closer to the center.
- Moving either edge towards the edges loosens the model to include less vivid colors.
- Moving the left edge out accepts colors that are closer to pastel than what is currently accepted.
- Move the right edge out accepts darker colors that what is currently accepted.
- Moving the top and bottom edges up and down changes the range of hues accepted by the model.

## Trying Out Color Vision

- Turn on the XBC, select *Vision* with the A button.
- Select *Color Model *and then *Restore to Default.*
- Press B then select *Live Video *and see what the camera sees.
- Press B and then select *Processed video *to see the image segmented.
- Press B and then select *Blob tracking *to see how those segments are broken into blobs.

## Trying Out Color Vision

- Press the B button and select *Color Model *and then *Modify Model 0.*
- Follow the onscreen instructions to modify the color model:
- The start button chooses symmetrical **M**ove or **R**esize modes for the box.
- L & R buttons switch you to a corner move (upper left or lower right) mode.
- The D-pad is used to **M**ove the box, **R**esize, or move the corners.
- The A button cycles between live, processed, or combined video.
- Do training by.
- Opening up the S and V ranges by moving the side edges outwards.
- Opening up the top and bottom edges as far as they go (MAX_HRANGE), then moving the whole range up and down until it includes what you want to accept.
- Then close down the top and bottom edges until they're as close together as they go before cutting out part of what you want to keep.
- After you have the top and bottom set up well, start moving the side edges closer to the center until you have cut out everything you want to get rid of.

## XBC Camera

- Create a color model for channel 0 that sees something orange.
- Load **xbctest.ic **onto your XBC.
- Run the program.
- Select the vision test.
- Select the correct channel/model to see orange.
- Follow on screen directions to get data on the blobs.
- If you like your model, save it to flash.
- For more info, see XBC Camera in **IC **Help.

## Controlling the XBC Camera Programmatically. 

- To use the camera in IC you MUST #use “xbccamlib.ic” at the top of your program.
- You must call void init_camera(); before using the camera!

## Tracking Data

- Tracking data:
- track_update();
- Gets new tracking information from the camera.  MUST be called for tracking info to update.
- track_is_new_data_available();
- Returns 1 if new tracking data is available.
- track_get_frame();
- Returns the current frame number (long)
- track_count(int ch);
- Returns the number of blobs (int) on color channel ch the camera is currently tracking.

## Blob Properties...

- int track_size(int ch, int i);
- Returns the size, in pixels, of blob number i on channel ch.
- int track_x(int ch, int i);
- Returns the x coordinate of the center of blob number i on channel ch.
- int track_y(int ch, int i);
- Returns the y coordinate of the center of blob number i on channel ch.
- int track_confidence(int ch, int i);
- Returns the confidence value (0-100) that blob i on channel ch is the correct color.
- Higher numbers mean better confidence.

## Enabling and Disabling Color Channels.

- void track_set_ch_enable(int ch, int val);
- ch = color channel.
- If val = 1 then enable channel.
- If val =0 then disable channel.
- int track_get_ch_enable(int ch);
- Returns 0 if channel ch is disabled, otherwise a 1 in enabled.

## An Example

- //We must first bring in the camera library
- #use "xbccamlib.ic"
- void main()
- {
- 	init_camera();
-     while(!b_button()) // Go until we press the b button
-       {
-         if( track_is_new_data_available())
-           {  // is new data available from the camera?
-             track_update(); // If yes then update the internal data
-             display_clear();
-             //Print data for the blob #0 on color channel 0
-             printf("Size: %d\n", track_size(0,0));
-             printf("Confidence: %d\n", track_confidence(0,0));
-             printf("X: %d\n", track_x(0,0));
-             printf("Y: %d\n", track_y(0,0));
-             sleep(0.1);
-         }
-     }
- }

## Using That Data to Control a Robot. 

- First a new motor control function!
- void move_at_velocity(int m, int vel)
- a.k.a - void mav(int m, int vel)
- Moves motor m at velocity vel
- Similar to the void motor(int m, int p) function but uses the internal BEMF motor encoders to move the motors at a specified velocity.
- The velocity range is -1000 to 1000 ticks per second.

## Proportional Control Using the Camera. 

- The X resolution is 356 pixels.
- Center at 176.
- We need to scale the return from the track_x function to control our motors.
- Good approximation is.
- 400+5*(track_x(0,0)-176);
- Left motor velocity.
- 400+5*(176-track_x(0,0));
- Right motor velocity.
- Camera is far more powerful than what we have learned tonight.  More advanced camera functions coming!

## Tonight's Challenge

- Use what you have learned tonight to cause your robot to do the following:
- Track and follow a colored object on channel 0.
- Assume the largest object it sees is object 0.
- The robot should stop when the object is above a certain size.

## Getting Started...

- void main()
- {
-     init_camera();
-     while(1)
-       {
- 		Call your track_object function IF track_size is less than 	a certain size AND (&&) track_confidence is greater 	than a certain confidence level.
- 	}
- }
- void track_object()
- {
-     int left_vel;
-     int right_vel;
-    Compute and assign your velocities to the mav function
- }

## #use "xbccamlib.ic"

void main()
{
    init_camera();
    while(1)
      {
        track_update();
	   if ( (track_size(0,0) < 10000) && (track_confidence(0,0) > 25) )
            track_object();
         else ao(); 
	}
}

void track_object()
{
    int left_vel;
    int right_vel;

    left_vel = 400+5*(track_x(0,0)-176);
    right_vel = 400+5*(176-track_x(0,0));

    mav(2, left_vel);
    mav(0, right_vel);
}

- void main()
- {
-     init_camera();
-     while(1)
-       {
-         track_update();
- 	   if ( (track_size(0,0) < 10000) && (track_confidence(0,0) > 25) )
-             track_object();
-          else ao();
- 	}
- }
- void track_object()
- {
-     int left_vel;
-     int right_vel;
-     left_vel = 400+5*(track_x(0,0)-176);
-     right_vel = 400+5*(176-track_x(0,0));
-     mav(2, left_vel);
-     mav(0, right_vel);
- }