|
1 | 1 | Implementing a Proportional Controller |
2 | 2 | ====================================== |
3 | 3 |
|
4 | | -Now that you've learned about proportional controllers, let's implement one on the distance tracking activity |
| 4 | +Now that you've learned about how proportional controllers, let's implement one for our distance tracking activity, |
| 5 | +where we want to keep the robot some distance from the object in front of it using the rangefinder! |
5 | 6 |
|
6 | | -Steps |
7 | | ------ |
| 7 | +Defining Terminology |
| 8 | +-------------------- |
8 | 9 |
|
9 | | -The first step when creating a proportional controller is to define your target and error terms. |
| 10 | +Let's identify the terms we'll need to use in our code: |
10 | 11 |
|
11 | | -For our target, let's set it to 20 cm. |
| 12 | +**Set Point** or desired value: In this example, this is some set distance from the rangefinder we want the robot to be at. |
| 13 | +For this example, let's say 20cm. |
12 | 14 |
|
13 | | -In this case, the error is the difference between the target and the current distance from the object in front of the XRP. |
| 15 | +**Process Variable** or current value: We obtain our measured value from polling the rangerfinder. This is |
| 16 | +:code:`rangefinder.distance()`. |
14 | 17 |
|
15 | | -Now, we need to define our proportional gain. |
| 18 | +Our goal is for our process variable (the rangefinder distance) to approach the set point (20 cm). |
16 | 19 |
|
17 | | - The first step of this is understanding the range of values that the error can take. |
| 20 | +Thus, our **error** is calculated as :code:`error = rangefinder.distance() - 20`. Note that :code:`error = 20 - rangefinder.distance()` |
| 21 | +is also "correct". The distinction in sign is simply whichever makes more sense for your application. Here, if we had an error of 30cm, |
| 22 | +we would want to drive forward 10cm, so we would want a positive error to make our motors spin forward. |
18 | 23 |
|
19 | | - The error can be any value between -20 and 20, meaning we're really close or really far. |
| 24 | +**Control Output**: In this case, this is our motor effort. This is because we want to drive with a speed proportional |
| 25 | +to the distance error. As a reminder for P control, this will be calculated as :code:`motor_effort = Kp * error`. |
20 | 26 |
|
21 | | - Then, the error would need to be scaled for an appropriate control signal (something from -1 to 1) |
| 27 | +**Kp**: This is our proportional gain. Though we will need to tune this value, we can guess a somewhat reasonable value |
| 28 | +by considering the range of values our error can take, and the domain of our control output. In this case, if we're 30cm away |
| 29 | +from the object, our error will be 10. We can guess that at this sufficient distance we will want to drive forward at a maximum |
| 30 | +effort of 1, as effort is restricted to the domain :math:`[-1, 1]`. Thus, we can guess that :code:`Kp = 1/10 = 0.1`. Of course, |
| 31 | +this isn't likely the final value that works best for your robot, but it's a good starting point. |
22 | 32 |
|
23 | | - Therefore, a good starting kp value would be 0.05. |
| 33 | +Implementing the Controller |
| 34 | +--------------------------- |
24 | 35 |
|
| 36 | +Now that we've defined our terms, let's write the code! |
25 | 37 |
|
26 | | -Finally, we need to set the speed of the XRP to our error times kp. |
| 38 | +Let's start by defining our proportional gain and our set point: |
27 | 39 |
|
28 | | -This is an example program that implements a proportional controller. |
| 40 | +.. tab-set:: |
29 | 41 |
|
30 | | -.. error:: |
| 42 | + .. tab-item:: Python |
31 | 43 |
|
32 | | - TODO add code to complete this |
33 | | - |
34 | | -.. admonition:: Try it out |
35 | | - |
36 | | - Now that you've designed a successful proportional controller, let's try some other values for kp. |
| 44 | + .. code-block:: python |
37 | 45 |
|
38 | | - First, let's try making kp too small (0.01). What happens? |
| 46 | + Kp = 0.1 |
| 47 | + desiredDistance = 20 |
39 | 48 |
|
40 | | - When kp is too small, the XRP doesn't react fast enough to the error, and it takes a long time to get to the target. |
| 49 | + .. tab-item:: Blockly |
41 | 50 |
|
42 | | - Next, let's try making kp too big (1). What happens? |
43 | | - |
44 | | - The behavior you're seeing is called oscillation and happens when kp is too high. |
| 51 | + .. image:: media/variables.png |
| 52 | + :width: 300 |
45 | 53 |
|
| 54 | +Next, we want to enter some sort of loop to continuously poll our rangefinder and update our motor effort from our controller output. |
0 commit comments