# Presentation: 680557

## Robotics With the XBC ControllerSession 9

- 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 receive a comprehensive review of the the first 8 sessions of the course.
- The student will learn very basic odometry and implement this by writing a function that will cause his or her robot to travel a set distance in a straight line.

## Final Exam Review

- Session 1
- Know that all IC programs begin execution at the main() function.
- Most common error in C programming is forgetting the ; at the end of function calls.

## Final Exam Review Continued

- Session 2
- motor(<*motor_#*>, <*speed*>) function controls XBC motors in PWM mode.
- Know how to recognize and what to do if a motor wire is plugged in backwards.
- Know the basic Boolean operators and how they function.
- < less than
- <= less than or equal
- > greater than
- >= greater than or equal
- == equal
- != not equal
- && and
- || or
- ! not

## Final Exam Review Continued

- Session 2 continued
- Know the structure of an if-then statement
- if (<*expression*>)<*statement-1*>
- if (a > 10)
-   {
-     forward();
- }
- else
- {
-     backward();
- }

## Final Exam Review Continued

- Session 2 continued
- Know the structure of a while loop
- while (<*expression*>)<*statement*>
- while( a_button() == 0)
-   {
-     perform cool things
-   }

## Final Exam Review Continued

- Session 3
- Know the difference between an analog and a digital sensor.
- Analog sensors return a range of values.
- 8 bit resolution = 0 – 255
- 12 bit resolution = 0 – 4096
- Ports 0-7
- Digital sensors return either a 0 or a 1 (on or off)
- Ports 8-15

## Final Exam Review Continued

- Session 3.
- Know the 4 basic data types in IC.
**16-bit Integers**  .
- 16-bit integers are signified by the type indicator int. They are signed integers, and may be valued from -32,768 to +32,767 decimal.
**32-bit Integers.**
- 32-bit integers are signified by the type indicator long. They are signed integers, and may be valued from -2,147,483,648 to +2,147,483,647 decimal.
**32-bit Floating Point Numbers.**
- Floating point numbers are signified by the type indicator float. They have approximately seven decimal digits of precision and are valued from about 10^-38 to 10^38.
**8-bit Characters.**
- Characters are an 8-bit number signified by the type indicator char; characters can be used to refer to arbitrary 8-bit numbers.

## Final Exam Review Continued

- Session 3 Continued
- Know variable naming rules
- Names are case sensitive
- Underscore character allowed _
- Usually used to separate words
- range_to_object
- letters, numbers and the underscore may be used, but may not start with a number
- C keywords such as if, while, for etc... cannot be used as names

## Final Exam Review

- Session 3 Continued
- Know variable scoping rules
- If declared within a function or as an argument to a function it is local to that function and not available outside of it.
- If declared outside of a function then it is global and available to all functions.
- Local variables take precedence if a local and global variable have the same name.

## Final Exam Review Continued

- Session 3 Continued
- Know the syntax and use of a for-next loop
- for (<*expr-1*>;<*expr-2*>;<*expr-3*>)<*statement*>
- <*expr-1*> is an assignment
- <*expr-2*> is a relational expression
- <*expr-3*> is an increment or decrement of some manner
- <*statement*> is a group of C statements to be executed each time through the loop if <*expr-2*> evaluates to TRUE.
- for (count = 0; count < 100; count++)
- { do this stuff }

## Final Exam Review Continued

- Session 4
- Know what user defined functions are and how to implement them.
- A function is a separate block of code with a unique name that does a particular job.
- Functions let you chop up a long program into named sections.
- Functions can accept **parameters** and can **return** a result.
-  All code belonging to a function is contained in curly braces {}.
- int add_two_number(int num1, int num2)
- {
-     return num1+num2;
- }

## Final Exam Review Continued

- Know how to use the IC preprocessor.
- #use brings in the functions defined in another file.
- #use “xbccamlib.ic”
- #define sets a macro.
- A macro is local to the file in which it is defined.
- Essentially it sets one item equal to something.
- Unlike variables they CANNOT be changed later.
**Before** the program is compiled the preprocessor replaces every instance of a macro name with its value.

## Final Exam Review Continued

- Session 4 Continued
- Know the basic functions for reading XBC buttons
- Each function returns 0 if NOT pressed and 1 if pressed.
- int a_button()
- int b_button()
- int up_button()
- int down_button()
- int right_button()
- int left_button()
- int r_button() – The top right button
- int l_button() – The top left button
- int any_button()

## Final Exam Review Continued

- Session 5
- Know the difference between a servo motor and a normal DC motor.
- Servos have a “stop” and do not rotate 360 degrees.
- Servos are sent positions to move to.
- Activate all servos with the function enable_servos()
- Only do this once
- DO NOT USE IN A LOOP
- Deactivate servos with the disable_servos()
- Use the set_servo_position function to move a servo to a desired position.
- int set_servo_position(int srv, int pos)
- srv = Servo port number 0-3
- pos= position(10-245) **is ~0-180 degrees**

## Final Exam Review

- Session 5 Continued
- Know the difference between ‘bang-bang’ and proportional control.
- “Bang-bang” control uses on/off extremes.
- Proportional control adjusts the output or response of the robot as the sensor readings change.
- Example:
- 			speed= -(int)( (float)analog(0)/2.55) + 100;
-         	motor(0,speed);
-         	motor(2,speed);

## Final Exam Review

- Session 6
- Know what arrays are and how to declare them.
- 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.
- void main()
- {
-     int an_array[20];
-     int position = 4;
-     an_array[10] = 200;
-     an_array[position] = 18;
- }

## Final Exam Review Continued

- Session 6 continued.
- Know how many color blobs and how many channels the XBC can track.
- At LEAST 3 blobs on 3 separate channels.
- Know that you must #use “xbccamlib.ic” before using the camera.
- Know that you must call init_camera() before using the camera.
- Know that you must call track_update() to refresh the tracking data stored in the camera.

## Final Exam Review

- Know the basic blob tracking functions:
- 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.

## Final Exam Review Continued

- Session 7
- Know what BEMF is
- Know the basic BEMF motor control functions.
- long get_motor_position_counter(int motor)
- This function tells you the current position of the motor.
- void set_motor_position_counter(int motor, long value)
- This function sets the motor counter to the position you specified without moving the motor.  This is usually used to set the number of the position to zero or another number that is easy to work with.
- void clear_motor_position_counter(int motor)
- This function resets the motor counter to zero.

## Final Exam Review Continued

- Session 7 Continued
- void move_at_velocity(int motor, int velocity)
- This function will attempt to move the specified motor at the velocity between -1000 and 1000 pulses per second.  You can also use the shorthand -
- void mav(int motor, int velocity).
- void move_to_position(int motor, int **speed**, long goal_pos)
- This function will move the motor to the position goal specified at the speed chosen by the user.  **Note that we call it ‘speed’ because it is always positive; the polarity of the position goal determines direction.**  This also works with the shorthand -
- mtp(int motor, int speed, long goal_pos).

## Final Exam Review Continued

- Session 7
- void move_relative_position(int motor, int **speed**, long delta_pos)
- This function moves the motor delta_pos (change in position) units at the specified speed.  The shorthand for this function is -
- mrp(int motor, int speed, long delta_pos).
- int get_motor_done(int motor)
- This function will tell you if the motor is currently executing a command, returning a zero if it is and a one if it isn’t.
- void block_motor_done(int motor)
- This function will pause until the specified motor finishes its current command, so you can avoid sending commands to a motor before it finishes the last command.
- This function has a shorthand - bmd(int motor).

## Final Exam Review

- Session 7 Continued
- Know how to multi-task in IC
- int start_process(<*function_name*>(<*arg1*>, <*arg2*>, . . .));
- Used to get a process to start running in the back ground.
- Returns an int that is the process ID of the process.
- void kill_process(<*process_id*>);
- Stops the process indicated by process_id.

## Final Exam Review

- Session 8
- Know that the color temperature of each frame is set with the white balance option.
- int camera_get_wb_color_temp(int color[]);
- Returns a 2 element array corresponding to the red and blue levels.
- int camera_set_wb_color_temp(int color[]);
- color[] is a two element array which is the red and blue levels to use.
- color[0] = red.
- color[1] = blue.
- 8 bit numbers (0-255).
- Lower numbers filter out more of that color.

## Final Exam Review

- Whew – done with review.
- Lots of information covered during this course!
- 30 multiple choice questions.

## Odometry

- Measuring distance based upon wheel rotations.
- Concept first written about in 27 B.C by Vitruvius.
- Used a complex series of gears to measure distance of chariot wheels.
- Many wheeled and tracked robots use odometry to ***estimate*** their distance from a fixed object.
- Odometry is an EXTREMELY valuable tool in Botball.

## Parameters We Need to Know Before We Begin.

- The circumference of the robots wheels.
- Measure the diameter of your robots wheels in cm.
- C = pi * D
- Wheel base of the robot.
- Measure the distance from one wheel to the next in cm.
- Number of BEMF pulses per wheel rotation.
- See on screen demonstration

## Measuring Straight Line Distance.

- The robots straight line distance (d) is the number of wheel rotations * wheel circumference (C).
- Example:
- C = 10cm
- # rotations = 6.5
- d = 100mm * 6.5 rotations = 65cm
- #rotations = pulses traveled / pulses per rotation

## Example

- Wheel Diameter(D) = 3.18 cm
- C = pi*D
- Wheel C = 3.14159 *3.18cm = ~10cm
- Pulses per rotation = 1000
- Total pulses traveled = 3500
- How far has our robot traveled?
- #rotations = pulses traveled / pulses per rotation
- #rotations = 3500 / 1000 = 3.5 rotations
- d = number of wheel rotations * wheel circumference.
- d = 3.5 rotations * 10cm = 35cm

## Measuring Straight Line Distance (Other Things We Can Find Out)

- Wheel circumference / number of pulses per rotation = dist traveled per BEMF pulse.
- Example.
- C = 10cm.
- Pulses per rotation = 1000.
- d per pulse = 10cm/1000ppr = 0.01 cm per pulse.
- If we multiply dist per pulse by the total pulses traveled we have the total distance traveled.
- Example:
- Total BEMF pulses = 2000.
- 0.01 cm per pulse * 2000 = 20cm traveled.

## A Trick to Help Both Motors Travel Relatively the Same Velocity.

- The BEMF encoders are not perfect.
- All DC motors are slightly different.
- Different motors will return a different # of BEMF pulses.
- Two easy ways around this.
- Choose motors that return a similar # of BEMF pulses per motor rotation.
- Apply a delta_vel to the faster motor to slow it down – see next slide.

## Applying a delta_vel to the Faster Motor.

- Determine which motor is rotating faster.
- Set a variable called delta_vel that is negative.  Apply this variable to your BEMF motor functions for that motor.
- int delta_vel = -50
- mav(LEFT_MOTOR, vel);
- mav(RIGHT_MOTOR, vel + delta_vel);
- Requires experimentation to get it right.

## Implementing a Straight Line Function in IC.

- We should be able to pass the following parameters to our functions:
- int vel- The speed of the motor in clicks/sec
- float dist- The distance in CM to travel.
- The function should cause the wheels to rotate the set number of CM.

## #define Statements for Our Straight Line Function.

- #define LEFT_MOTOR 0
- #define RIGHT_MOTOR 2
- #define LEFT_CLICKS_PER_ROT 350 /*WHEEL ROTATIONS! NOT motor rotations!*/
- #define RIGHT_CLICKS_PER_ROT 350 /*WHEEL ROTATIONS! NOT motor rotations! */
- #define WHEEL_DIAMETER 1.5 /* in cm */
- #define PI 3.14159
- float wheel_circumference = WHEEL_DIAMETER*PI; //in cm
- These will need to be set to your robots parameters!

## An Algorithm for Implementing the Function.

- Calculate how many BEMF pulses to move the motor.
- float left_total_clicks_to_travel=(dist/wheel_circumference)*(float)LEFT_CLICKS_PER_ROT
- float right_total_clicks_to_travel=(dist/wheel_circumference)*(float)RIGHT_CLICKS_PER_ROT
- Use the mrp function to move the motors to the desired relative position.
- mrp(LEFT_MOTOR, vel, (long)left_total_clicks_to_travel).
- mrp(RIGHT_MOTOR, vel, (long)right_total_clicks_to_travel).
- Use a while loop to test if each motor has completed its move.

## Assignment...

- Write a function called travel_dist.
- travel_dist takes the following parameters:
- int vel- The speed of the motor in clicks/sec.
- float dist- The distance IN CM to travel.
- Will cause your robot to travel in a straight line for a set #of cm.
- Function definition looks like the following:
- void travel_dist(int vel, float dist).
- Use the function to make your robot travel the set number of cm.
- Write another function that when passed a number of BEMF pulses it will return the distance in cm that number of BEMF pulses corresponds to for either motor.

## /*
Function: travel_dist
Purpose: Will cause two wheels to travel a certain number of cm (it is possible to use more or less wheels)
Parameters:
    int vel- The speed to travel in clicks/sec
    float dist- The distance in cm to travel
*/
void travel_dist(int vel, float dist)
{
    //First calculate how far to travel in clicks
    float left_total_clicks_to_travel=(dist/wheel_circumference)*(float)LEFT_CLICKS_PER_ROT;
    float right_total_clicks_to_travel=(dist/wheel_circumference)*(float)LEFT_CLICKS_PER_ROT;
    mrp(LEFT_MOTOR, vel, (long)left_total_clicks_to_travel);
    mrp(RIGHT_MOTOR, vel, (long)right_total_clicks_to_travel);
    while( (get_motor_done(LEFT_MOTOR) == 0) || (get_motor_done(RIGHT_MOTOR) ==0) )
      {  };
	ao(); // turn off both motors when one is done to keep from turning
}

float return_dist(int bemf_pulses, int motor_num)
{
    if (motor_num == LEFT_MOTOR)
      {
        return (float) ( (float)(bemf_pulses/LEFT_CLICKS_PER_ROT) * wheel_circumference);
    }
    else if (motor_num == RIGHT_MOTOR)
        {
          return (float) ( (float)(bemf_pulses/RIGHT_CLICKS_PER_ROT) * wheel_circumference);
      }    
}

- Function: travel_dist
- Purpose: Will cause two wheels to travel a certain number of cm (it is possible to use more or less wheels)
- Parameters:
-     int vel- The speed to travel in clicks/sec
-     float dist- The distance in cm to travel
- */
- void travel_dist(int vel, float dist)
- {
-     //First calculate how far to travel in clicks
-     float left_total_clicks_to_travel=(dist/wheel_circumference)*(float)LEFT_CLICKS_PER_ROT;
-     float right_total_clicks_to_travel=(dist/wheel_circumference)*(float)LEFT_CLICKS_PER_ROT;
-     mrp(LEFT_MOTOR, vel, (long)left_total_clicks_to_travel);
-     mrp(RIGHT_MOTOR, vel, (long)right_total_clicks_to_travel);
-     while( (get_motor_done(LEFT_MOTOR) == 0) || (get_motor_done(RIGHT_MOTOR) ==0) )
-       {  };
- 	ao(); // turn off both motors when one is done to keep from turning
- }
- float return_dist(int bemf_pulses, int motor_num)
- {
-     if (motor_num == LEFT_MOTOR)
-       {
-         return (float) ( (float)(bemf_pulses/LEFT_CLICKS_PER_ROT) * wheel_circumference);
-     }
-     else if (motor_num == RIGHT_MOTOR)
-         {
-           return (float) ( (float)(bemf_pulses/RIGHT_CLICKS_PER_ROT) * wheel_circumference);
-       }
- }