# Final Project Library Reference

We've combined your problem set code into a set of libraries for the final project. To develop in RAM, you must first load the libraries into Flash with the command:

robot.program('com?','math2.py','velocity.py','pose.py','motion.py','leds.py','neighbors.py','quidditch.py')

You can then connect to the robot and use the 'run' command to load and run your program from RAM. Note that you can unplug the USB cable from the robot after the program is in RAM. It will continue to run, but if you reset the robot, it will be cleared. You can load your program and the libraries into flash with the command:

robot.program('com?','your_program.py','math2.py','velocity.py','pose.py','motion.py','leds.py','neighbors.py','quidditch.py')

Your program must be the first file in the list.

You are not allowed to edit these libraries! However, you are encouraged to read them for reference. If you find problems, or can't do something that should be supported, let us know. We will upgrade the library files for you, and release them to the class.

## The math2 library

This library contains extra math functions.

• topolar(x, y): Converts the cartesian coordinates (x, y) into polar coordinates. Returns a tuple of the form (r, theta) where theta lies between -pi and pi.
• normalize_theta(theta): Returns the angle argument normalized to lie between 0 and 2pi.
• clamp(value, value_max): Bounds value to lie between -value_max and value_max.
• smallest_angle_diff(current_angle, goal_angle): Returns the smallest angle between the current_angle to the goal_angle. This is the smallest angle the robot needs to rotate to face the goal angle. The return value is normalized to lie between -pi and pi, and can be used directly for computation of rv for rotational control.

## The velocity library

This library contains functions to set and measure the velocity of the robot's motors. The update function runs the control loop, and must be called periodically to properly control the velocities.

• init(ki, kp): Initializes the velocity controller module.
• update(): Runs the velocity controllers for each wheel and updates the state of the velocity data structure. This function must be called repeatedly to control the motors. It maintains its own internal timer, and will only run an update if one is needed, so it it ok to call it asynchronously. (i.e. from a main while loop with uncontrolled execution time through the loop.)
• encoder_delta_ticks(new, old): Takes two encoder values, a new one and an old one, and returns the difference. Handles the wraparound of the encoders.
• def clamp(val, bound): Prevents val from going above bound or below negative bound.
• set_tvrv(tv, rv): Sets the velocity of both motors to produce a given translational velocity (tv) and rotational velocity(rv) Units are mm/s and miliradians/s

## The pose library

This library contains functions to estimate the pose (x, y, theta) of the center of the robot. The update function runs the estimator, and must be called periodically to accurately estimate the pose of the robot.

• init(): Initializes the pose estimator module. Returns a dictionary of state for the pose estimator. This state must be stored locally, and passed to the other functions.
• update(pose_state): Runs the pose estimator update. This function must be called repeatedly to maintain an accurate estimate. It maintains its own internal timer, and will only run an update if one is needed, so it it ok to call it asynchronously.
• get_pose(pose_state): Returns the current pose of the robot. Returns a tuple of the form: (x, y, theta) Units for x and y are mm, units for theta are radians, normalized to lie between 0 ad 2pi.
• set_pose(pose_state, x, y, theta): Sets the current pose of the robot. Units for x and y are mm, units for theta are radians.
• get_theta(pose_state): Returns the theta value of the pose. Units are radians, normalized to lie between 0 ad 2pi.
• get_odometer(pose_state): Returns the odometer. Units are mm.

## The leds library

This library contains functions to blink the LEDs with different patterns and animations. The update function runs the animations, and must be called periodically to produce smooth animations.

• init(): Initializes the led animation module. Returns a dictionary of state for the animator. This state must be stored locally, and passed to the other functions.
• set(leds_state, color, pattern, brightness): Sets the led animation parameters. Color can be 'r', 'g', 'b', or any combination. Pattern can be 'manual', 'group', 'ramp_slow', 'blink_slow', 'blink_fast', or 'circle'. The manual pattern disable the animator, and allows direct user control of the LEDs. The brightness can range between 0-127. Note that the lights are *very* bright, looking directly into bright lights is not recommended. This function must be called repeatedly to produce smooth animations. It maintains its own internal timer, and will only run an update if one is needed, so it it ok to call it asynchronously.

## The motion library

This library contains functions to move the robot to a goal position. The move_to_goal() function controls the motion, and must be called periodically. Usually, the function would be wrapped in a behavior, as it only needs to be called when the robot is driving towards a goal position.

• init(): Initializes the waypoint motion module. Returns a dictionary of state for the motion module. This state must be stored locally, and passed to the other functions.
• move_to_goal(motion_state, pose_state, tv_max): Computes the velocities required to move the robot towards the goal position. Returns a tuple of the form (tv, rv). This values can be passed to velocity.set_tvrv() directly, or encapsulated within a behavior or any other function.
• set_goal(motion_state, goal_pos): Sets the goal position for the waypoint. goal_pos is a tuple of the form (x, y).
• is_done(motion_state): Checks to see if the current motion is complete. Returns True if the robot is within range of the goal position, False otherwise.

## The neighbors library

This library contains functions to communicate with neighboring robots. The update function transmits and receives messages, and must be called periodically to accurately estimate the pose of the robot. The orientation system transmits an extra message for each neighbor, and should be enabled only if you need orientation information. You will not need orientation for robot rQuidditch.

The way to interact with the neighbor system is as follows: call neighbors.init() once, using the provided value for "nbr_period" and "False" for "orientation_enable". Get the full list of neighbors by using the get_neighbors(nbr_state) function. Then, you can access individual elements of each neighbor using the "get_nbr_?" getters.

• init(nbr_period, orientation_enable): Initializes the neighbor module. Returns a dictionary of state for the neighbors. This state must be stored locally, and passed to the other functions.
• update(nbr_state): Runs the neighbor system update. This function must be called repeatedly to maintain an accurate image of the current neighbors. It maintains its own internal timer, and will only run an update if one is needed, so it it ok to call it asynchronously.
• set_message(nbr_state, message): Sets the message to be broadcast each neighbor cycle. The message can only be three characters long.
• get_neighbors(nbr_state): Returns a list of the current neighbors of this robot. Each neighbor is a tuple, whose state can be queried via the functions below.

### The neighbors library: nbr getters

These functions are used to access the internal state of the nbr tuples returned by get_neighbors()

• get_nbr_id(nbr): Returns the id of the given neighbor.
• get_nbr_message(nbr): Returns the most recent message of the given neighbor.
• get_nbr_bearing(nbr): Returns the bearing of the given neighbor.
• get_nbr_close_range(nbr): Returns True is the given neighbor is close to the receiver robot.
• get_nbr_msg_time(nbr): Returns the time of the most recent message from this neighbor.

## The quidditch library

This library contains helper functions make it easier to send messages to your neighboring robots. These three functions let you broadcast your robot type, and let you read the type from your neighbors. See "test_quaffle.py" for usage examples.

• set_type(nbr_state, type): Sets the type of this robot. nbr_state is the variable returned by neighbor.init(). type is one of 'q', 'b', 's', 'n', 'e', see the next function for definitions. The type must be lowercase.
• get_nbr_type(nbr): Returns the type of the given neighbor:
'q' = Quaffle
'b' = Bludger
's' = Seeker
'n' = Snitch
'e' = End Zone