# 7. Robot

The purpose of this exercise is to write software that uses sensor data to maneuver the Pololu robot. You will gain experience with additional sensors.

## 7.1 Prelab

1. For this lab, we will be detecting and maneuvering around obstacles using the Pololu robot. What sensor(s) on the robot will be most useful for detecting obstacles?

2. For this lab, we will be using a gyroscope to sense turns made by the robot. The ST LMS6DSO inertial module, which you encountered in the Sensors lab, includes a gyroscope as well as the accelerometer you used in that lab. The gyroscope senses angular velocity and reports it in units of degrees per second (o/s).

There is a Lingua Franca reactor called `Gyro` available to you in `src/lib/IMU.lf` that outputs gyroscope measurements in units of degrees per second when triggered. Suppose that what you want is not angular velocity but rather a measurement of the current angle of the device relative to some starting angle. Explain how you can convert an angular velocity measurement into an angle measurement. Specifically, given the i th measurement vi of an angular velocity that is taken at time ti, how can you construct an estimate of the angle ai at time ti?

3. The speed of motors can be controlled using a technique called pulse width modulation (PWM). The RP2040 chip includes hardware for controlling up to 16 motors using PWM, as explained in Section 4.5 of the RP2040 datasheet. For this purpose, each PWM hardware block can be connected to a GPIO pin, and then you can use the GPIO pin to control the motors. Which GPIO pins are used to control the motors on the Pololu robot?

Hint: The Pololu 3pi+ 2040 Robot User's Guide might be helpful.

Note: The GPIO pins cannot drive a motor directly because they cannot source enough power without damaging the chip. The Pololu robot includes a Texas Instruments DRV8838 motor driver which takes as input the PWM signal and provides power to the motors.

4. Using the notation from the textbook for state machines, sketch a state machine for a robot controller that makes the robot move in a square. That is, when the program is run, the robot should move forward some distance D, turn 90 degrees, move forward a distance D again, and repeat these actions.

## 7.2 Motors

Your first task is to drive the motors on the Pololu robot. For your convenience, a library reactor called `Motors` is provided in `src/lib/Motors.lf`. You should start with the provided LF program `src/RobotTemplate.lf`. Start by verifying that this template works for you:

``````    lfc src/RobotTemplate.lf
``````

The robot should start by displaying `INIT`, then switch between `DRIVING` and `STOPPED`.

1. Examine the `Motors` reactor. How does it work? Find the `motors_set_power` function that it uses. (Hint: the search function in VS Code is very useful for this.) Explain how the implementation of this function conforms with the answer you gave in question (3) of the prelab.

2. Use the `Motors` reactor to make robot move forward while it is the `DRIVING` mode and stops while in the `STOPPED` mode. You can experiment with the power to provide, but a good starting point is 0.1f. Please put your solution in a file called `RobotDriveSolution.lf`.

Hint: The motors will not run if the only source of power to the robot is the USB cable. To get the motors to run, you must insert batteries and push the power button so that the blue power indicator LED is illuminated.

Checkoff: Show that you understand the implementation of the `motors_set_power` function and that your robot moves forward and stops.

## 7.3 Encoders

Encoders measure wheel rotation and can be used to estimate the distance traveled. A technique known as dead reckoning uses such measurements to help to know where the robot is located relative to some starting point. Our goal here is to create a reactor that takes as input an encoder reading and outputs an estimate of the distance traveled since the program has started for each wheel.

The output from the encoders is in degrees given as a 32-bit integer. Examine and run the `src/EncoderDisplay.lf` LF program. You will convert these numbers to distance.

1. The diameter of the wheels on the robot is approximately 3.175 cm. Find a formula that converts a change in angle in degrees to distance traveled in meters.

2. The encoder outputs increase as the wheels rotate forward. Given that the values are 32-bit signed integers, how far does a wheel need to travel before the numbers will overflow? Do you think you need to worry about overflow for these labs?

3. Write a reactor `AngleToDistance` to convert a change in encoder value to distance. Then create a variant of `src/EncoderDisplay.lf` that displays distance traveled for each wheel rather than angle in degrees. Please put your solution in a file called `RobotEncoderSolution.lf`.

Checkoff: Show that your distance measurement is reasonably accurate.

## 7.4 Navigation with a Gyroscope

As you (hopefully) determined in problem (2) of the prelab, the gyroscope output can be integrated to get a measure of the current angle of the robot relative to some starting point. You are provided with a reactor `GyroAngle` in `src/lib/IMU.lf` that uses the trapezoidal method to calculate the angle. Use this reactor to create modal Lingua Franca program `RobotSquareSolution.lf` that drives for approximately half a meter, turns 90 degrees, drives another half meter, and then repeats, so that the robot moves roughly in a square. What factors contribute to the imperfection of the square?

Checkoff: Show your robot moving in a square and show the diagram of the modal Lingua Franca program.

## 7.5 Obstacle Avoidance

Examine the src/BumpDisplay.lf example program provided by your template repository. How does it work? What does the Bump reactor class do?

Your task now is to use the Bump reactor class to modify your previous solution so that when the robot bumps into an obstacle as it navigates around the square, it backs off in such a way as to avoid the obstacle. Please put your solution in a file called `RobotAvoidSolution.lf`.