# CS 153: Project 10

Fall 2018

### Project 10: Obstacle Avoidance

The purpose of this project is to continue to practice creating, editing, and using classes. The application for the project will be to get your robot moving, and to use a sensor within its control loop.

#### Setup

1. Copy over your LEDBank_p9.h and LEDBank_p9.cpp files. You can rename them just LEDBank.h, and LEDBank.cpp if you wish and put them in your library folder. You will also need your DualMotor.h and DualMotor.cpp files from project 9.

There are two main tasks. The first is to have the robot approach an obstacle and stop a certain distance away. If the obstacle moves further away, the robot should follow it. The second task is to make the robot wander around and not run into things, while reacting to bright lights.

• `int DualMotor::setMotorPower(int pleft, int pright)` - this function should first ensure that pleft and pright are in the range [0, 255]. Then it should use analogWrite to send pleft to the left motor pin and pright to the right motor pin.
• `int DualMotor::setSpeed(int speed)` - this function should set the speed of both motors to the given argument using the setMotorPower function. However, it should also first check if speed is < 0. If the speed is negative, then it should set the motor power to 0 for both motors.
• `int DualMotor::setRotation(int speed)` - this function should set the left motor to the magnitude of speed if speed is negative (right turn). It should set the right motor to the value of speed if the speed is positive (left turn). It should use the setMotorPower function to set the values, and it should limit the magnitude of the speed to 255.
• `int stop(void)` - this function should set the power of both motors to 0, immediately.

You may want to update the left, right, and forward member functions to make use of setMotorPower.

As an extension for this task, you can implement the concept of max acceleration, which means limiting the rate at which the motor power can change. In order to do this you need to add two fields, curSpeed and maxAccel, to the class. The curSpeed value should be updated every time the motor power is changed. If the setSpeed function is called and the change in power setting is greater than maxAccel, then the code should limit the change in speed to curSpeed +/- maxAccel depending on if the new speed is larger or smaller than the existing speed.

3. #### Part 1: Following

The purpose of this task is to have your robot go forward until it is a set distance from something in front of it, at which point it should stop. If the obstacle moves further away, the robot should follow it. Use proprtional control to have the robot follow smoothly.

4. Create a new sketch following.ino. Include DualMotor.h, LEDBank.h, and Sensor.h. Make sure these and their .cpp files are all in the same directory or else in your library folder. The template below provides an outline. You probably want to have print statements in strategic places as you are debugging.

```/*
*/

#include <Arduino.h>
#include "Sensor.h"
#include "LEDBank_p10.h"
#include "DualMotor.h"

int main() {
init();
const int desiredDistance = 6;

Serial.begin(9600);

// declare an LEDBank, IRSensor, and DualMotor
// declare other local variables.

for(;;) {
// update the IR sensor
// if the value is less than desiredDistance, turn on the LEDs
// else turn the LEDs off

// calculate the error as the current ir value - desiredDistance
// calculate the new speed as proportional to the error

// if the error is greater than zero, set the motor's speed to the new speed
// otherwise, set the speed to 0.
}

return(0);
}```

If you want to implement PI, PD, or PID control, you will need some additional variables and proportional constants.

5. Debug and test your code. The robot should go forward until it reaches an obstacle then stop. If the obstacle moves forward, the robot should follow it. Hand in a video of your rover following.
6. #### Part 2: Wandering

For this task, the robot should go forward until it senses an obstacle and reaches a minimum safe distance, at which point it should stop. Then the robot should pick a random direction and rotate in that direction until the distance sensor no longer sees an obstacle, at which point the robot should move forward again. If, at any time, the robot senses a bright light it should freeze in place.

7. A straightforward method of implementing the wandering rover is a state machine.
• In state 0, the robot should first check if threre is a bright light. If so, it should stop and move to state 2. Then robot should check if there is an obstacle in front of it. If so, then it should stop, randomly pick a direction (left or right), delay 500ms, and move to state 1. If there is no obstacle, it should go forward using the proportional control method from the prior task.
• In state 1, the robot has sensed an obstacle in front it and picked a rotate direction (negative or positive). If there is a bright light, it should stop and move to state 2. If the IR distance sensor reports a distance > 10, it should delay for 500ms and move to state 0. Otherwise, it should rotate (setRotation) at a fixed power in the chosen direction.
• In state 2, the robot has sense a bright light. It should do nothing until the light has gone away, at which point it should set its state to 0.

The main loop should have a delay of 100ms to keep it from querying the sensors too quickly.

8. Test your rover. Hand in a video of your rover wandering..

### Follow-up Questions

1. What is inheritance
2. How does inheritance make coding easier? Give an example from this project
3. What is proportional control?
4. How are P/PI/PD/PID control different?

### Extensions

• Add LEDs that reflect the robot's actions.
• Add other sensors to your robot and show it reacting to them.
• Paint your rover with flames so it will go faster.
• Add PI/PD/PID control to your robot for the following task. If you do this, try different combinations of proportional constants and record and discuss the differences in behavior.
• Just as we could record LED commands, record the robot commands for later replay.
• Set up some type of user input, such as a switch or a button.
• Set up a small maze and see if your robot can navigate it. Take a video of this.
• Make another constructor for the DualMotor class that takes in a string like "2 3 4 5 6" and uses the string to initialize the pins array and nPins fields. Look up the strsep function.

### Report

Each week you will write a brief report about your project. In general, your intended audience for your write-up is your peers not in the class. From week to week you can assume your audience has read your prior reports. Your wiki report should explain to friends what you accomplished in this project and to give them a sense of how you did it.

Your project report should contain the following elements.

1. Abstract: a brief summary (200 words or less) of the task, in your own words. give the reader context and identify the key purpose(s) of the project. You can assume the reader has read your prior assignments.

Writing an effective abstract is an important skill. Consider the following questions while writing it.

• Does it describe the CS concepts of the project (e.g. writing loops and conditionals)?
• Does it describe the specific project application (e.g. creating applications with the LCD)?
• Does it describe your the solution or how it was developed (e.g. what code did you write/circuits did you build)?
• Does it describe the results or outputs (e.g. did your code and circuit work as expected)?
• Is it concise?
• Are all of the terms well-defined?
• Does it read logically and in the proper order?

2. A description of your solution to the tasks. This should be a description of the form and functionality of your final code and the design of your breadboard circuits. Try to describe your algorithm or code without including actual code in your report. Using 1-2 lines as an example is acceptable. Using simple diagrams or pictures of your board may be helpful when describing your circuits. Note any unique computational solutions or hardware circuits you developed.
3. A description of any extensions you undertook, including images, videos, or diagrams demonstrating those extensions. If you added any functions, or other design components, note their structure and the algorithms you used.
4. The answers to any follow-up questions.
5. A brief description (1-3 sentences) of what you learned.
6. A list of people you worked with, including TAs, and professors. Include in that list anyone whose code you may have seen, such as those of friends who have taken the course in a previous semester.
7. Don't forget to label your writeup so that it is easy for others to find. For this lab, use cs153f18project10

### Handin

Mount the Courses volume. Navigate to the Private sub-directory. Create a new folder called project01. (It's best to avoid spces in the directory name.) Each week, the following items should be submitted here.

• Code that should graded and any required supporting materials. This week, submit your code from all of the project tasks. Code from lab exercises will generally not be graded unless it is used as part of the project tasks (e.g. the Sensor class).
• Videos of your work. You can also submit videos as part of your report on the wiki, but please put a copy of the video here.

Your report should be submitted as a wiki page with the appropriate label, as noted above.