191 lines
5.2 KiB
Markdown
191 lines
5.2 KiB
Markdown
# Wall Follower
|
|
|
|
## Introduction @unplugged
|
|
|
|
This tutorial shows you how to use the ultrasonic sensor to
|
|
move a [EV3 Driving Base](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-driving-base-79bebfc16bd491186ea9c9069842155e.pdf)
|
|
along a wall.
|
|
|
|
Your ultrasonic sensor should be placed horizontally, near the driving wheel, facing the wall.
|
|
|
|
## Step 1 Measure distance
|
|
|
|
Declare a new variable ``distance`` and store the distance from
|
|
the ultrasonic sensor on port 4.
|
|
|
|
```blocks
|
|
let distance = 0
|
|
forever(function () {
|
|
distance = sensors.ultrasonic4.distance()
|
|
})
|
|
```
|
|
|
|
## Step 2 Show distance
|
|
|
|
Use a ``||brick:show value||`` block to display the distance value on the screen.
|
|
This is **very** helpful when you are debugging your code on the robot.
|
|
|
|
Once your code is ready, download it to your robot and check that the measured distance looks ok.
|
|
|
|
```blocks
|
|
let distance = 0
|
|
forever(function () {
|
|
distance = sensors.ultrasonic4.distance()
|
|
brick.showValue("distance", distance, 1)
|
|
})
|
|
```
|
|
|
|
## Step 3 Goal
|
|
|
|
Declare a new variable ``goal`` and assign it to ``10`` in ``on start``.
|
|
The value should be the distance in centimeters between your robot and the wall.
|
|
|
|
```blocks
|
|
let goal = 0
|
|
goal = 10
|
|
```
|
|
|
|
## Step 4 Compute Error
|
|
|
|
Declare a new variable ``error`` and assign a difference between ``distance`` and ``goal``.
|
|
We will use this value to determine how much the robot needs to correct its trajectory.
|
|
|
|
```blocks
|
|
let distance = 0
|
|
let goal = 0
|
|
let error = 0
|
|
goal = 10
|
|
forever(function () {
|
|
distance = sensors.ultrasonic4.distance()
|
|
brick.showValue("distance", distance, 1)
|
|
error = distance - goal
|
|
brick.showValue("error", error, 2)
|
|
})
|
|
```
|
|
|
|
## Step 5 Show Error
|
|
|
|
Just like ``distance``, use ``||brick:show value||`` to display the value of the error (line 2).
|
|
This will allow you to debug your code while it is running on the robot.
|
|
|
|
Download your program to the robot and check that the error goes to ``0`` when
|
|
the robot is around 10cm from the wall.
|
|
|
|
```blocks
|
|
let distance = 0
|
|
let goal = 0
|
|
let error = 0
|
|
goal = 10
|
|
forever(function () {
|
|
distance = sensors.ultrasonic4.distance()
|
|
brick.showValue("distance", distance, 1)
|
|
error = distance - goal
|
|
brick.showValue("error", error, 2)
|
|
})
|
|
```
|
|
|
|
## Step 6 Kp
|
|
|
|
Declare a new variable ``kp`` and assign it to ``1``.
|
|
This number determines how to convert the error into a ``turn ratio`` for the steer block.
|
|
For starter, set it to 1 and we will go through the steps to tune its value later on.
|
|
As usual, also use ``||brick:show value||`` to display the value of ``kp`` on the screen (line 3).
|
|
|
|
```blocks
|
|
let distance = 0
|
|
let goal = 0
|
|
let error = 0
|
|
let kp = 0
|
|
goal = 10
|
|
kp = 1
|
|
forever(function () {
|
|
distance = sensors.ultrasonic4.distance()
|
|
brick.showValue("distance", distance, 1)
|
|
error = distance - goal
|
|
brick.showValue("error", error, 2)
|
|
brick.showValue("kp", kp, 3)
|
|
})
|
|
```
|
|
|
|
## Step 7 Turn ratio
|
|
|
|
Declare a new variable ``turnratio`` and store the product of ``error`` and ``kp`` in it.
|
|
Also use ``||brick:show value||`` to display its value on screen.
|
|
|
|
Download the program on the robot and try moving the robot around the wall. You should see
|
|
the value of ``turnratio`` change similarly to ``error``.
|
|
|
|
```blocks
|
|
let distance = 0
|
|
let goal = 0
|
|
let error = 0
|
|
let kp = 0
|
|
let turnratio = 0
|
|
goal = 10
|
|
kp = 1
|
|
forever(function () {
|
|
distance = sensors.ultrasonic4.distance()
|
|
brick.showValue("distance", distance, 1)
|
|
error = distance - goal
|
|
brick.showValue("error", error, 2)
|
|
brick.showValue("kp", kp, 3)
|
|
turnratio = error * kp
|
|
brick.showValue("turn", turnratio, 4)
|
|
})
|
|
```
|
|
|
|
## Step 8 Steering
|
|
|
|
Add a ``||motors:steer motors||`` block for ``large B+C`` at 35% and place the ``turnratio``
|
|
variable for the turn value.
|
|
|
|
Download the code to your robot and try it out. Does it follow the wall?...
|
|
Not really, this is because we need to tune the ``kp`` variable.
|
|
|
|
```blocks
|
|
let distance = 0
|
|
let goal = 0
|
|
let error = 0
|
|
let kp = 0
|
|
let turnratio = 0
|
|
goal = 10
|
|
kp = 1
|
|
forever(function () {
|
|
distance = sensors.ultrasonic4.distance()
|
|
brick.showValue("distance", distance, 1)
|
|
error = distance - goal
|
|
brick.showValue("error", error, 2)
|
|
brick.showValue("kp", kp, 3)
|
|
turnratio = error * kp
|
|
brick.showValue("turn", turnratio, 4)
|
|
motors.largeBC.steer(turnratio, 35)
|
|
})
|
|
```
|
|
|
|
## Step 9 Tuning kp
|
|
|
|
As mentioned in a previous step, we need to find the right value for kp so that the robot
|
|
follows the wall properly. This tuning can be tedious so we are going to the brick buttons
|
|
to speed up the process.
|
|
|
|
Add ``||brick:on button||`` blocks to handle the left and right button pressed. When left is pressed, change ``kp`` by ``-1``. When right is pressed, change ``kp`` by 1.
|
|
|
|
Download your code to the robot and change the values of ``kp`` until the robot follows the wall. (Tip try something around -5 / -10).
|
|
|
|
```blocks
|
|
let kp = 0
|
|
brick.buttonLeft.onEvent(ButtonEvent.Pressed, function () {
|
|
kp += -1
|
|
})
|
|
brick.buttonRight.onEvent(ButtonEvent.Pressed, function () {
|
|
kp += 1
|
|
})
|
|
```
|
|
|
|
## Step 10 @unplugged
|
|
|
|
Well done! Your robot is using the ultrasonic distance
|
|
to correct is trajectory using a proportional controller!
|
|
|
|
The robot will be more precise if it goes slow... Try using a variable
|
|
and the brick up and down events to control the speed as well. |