Major site overhaul: resources hub, content migration, new blog posts, forms

- Redesign /resources as sectioned hub with category pages
- Migrate 645 Squarespace CDN images to local /images/content/
- Create 9 new news/blog posts with event photos
- Fix blog post slugs (rename gibberish filenames)
- Rename Design Blog to Design Blogs across site
- Remove education page, replace with Platform in nav
- Redesign rover repair request form with dynamic rover entries
- Add school search combobox to contact, store, and repair forms
- Extract shared KNOWN_SCHOOLS data
- Make /rover-expansion-3d-printing dynamically pull from MDX
- Add related resources sections to product pages
- Fix homepage broken /quote links to /store
- Store page: sample kit cards, inline quote builder, mailing list opt-in
This commit is contained in:
Tim Hadwen
2026-03-01 17:14:05 +10:00
parent 707c49dd3f
commit ae3ae18585
1212 changed files with 2477 additions and 6948 deletions

View File

@@ -1,7 +1,7 @@
---
title: "Getting Started With Proportional Control On A Micromelon Rover"
date: "2022-11-16"
categories: ["All"]
categories: ["All", "Advanced Guides"]
tags: ["Guides"]
excerpt: "Learn about proportional control."
featuredImage: "/images/resources/getting-started-with-proportional-controls.png"
@@ -15,17 +15,17 @@ Proportional control means that you are controlling *something *in relation to *
Okay, so control systems sound pretty cool, how does something like that actually work?
Lets say we have our garden installed with a sprinkler system. The sprinkler system is our **output **and the thing we are controlling is the amount of water they put into our soil.
Lets say we have our garden installed with a sprinkler system. The sprinkler system is our **output** and the thing we are controlling is the amount of water they put into our soil.
We need something called an **input**. The most obvious here is likely a moisture sensor in the soil near the roots of our plant. Lets suppose this device tells us exactly how much water is in the soil as an input into our control system.
We also have something called a “**goal**” or a “**target**”. This is the outcome we are trying to achieve and the result we are constantly striving for. In this case thats how much water our plant needs.
We also have something called a “**goal **” or a “** target**”. This is the outcome we are trying to achieve and the result we are constantly striving for. In this case thats how much water our plant needs.
All a proportional controller does is increase or decrease our output (water coming out of our sprinklers) proportional to how far off of our goal we are.(how thirsty or drowned our plants are at any given time based on the moisture sensor reading)
You could in this example consider the difference in moisture from the ground to what the plant needs to be our “**error**”, and one more piece of our control system recipe is our **proportional gain**, commonly denoted as “Kp”. This is a simple multiplier that gets applied to our entire system, so that we can apply the same control system on a thirstier plant like cucumber with a Kp of something like 2 (meaning we double the water outputs) and reduce the water outputs with a kp of 0.5 if we are growing a cactus (meaning we halve the water outputs)
You could in this example consider the difference in moisture from the ground to what the plant needs to be our “**error **”, and one more piece of our control system recipe is our** proportional gain**, commonly denoted as “Kp”. This is a simple multiplier that gets applied to our entire system, so that we can apply the same control system on a thirstier plant like cucumber with a Kp of something like 2 (meaning we double the water outputs) and reduce the water outputs with a kp of 0.5 if we are growing a cactus (meaning we halve the water outputs)
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/0d6fe628-d6de-4fbe-830c-3765d268fdc8/image6.png)
![](/images/content/4856a4-image6.png)
Control systems are so popular because this will deal with changes in circumstances and automates a lot of the work that would go into managing this garden. Did it rain last night? Moisture sensor will give the input that we have a lot of water in the soil, and will appropriately limit or turn off the sprinkler system because it has recognised it already has plenty of water. Has it been a particularly hot day? Moisture sensor will let the system know the ground is drier than usual and the sprinklers can be programmed to stay on for longer, all of which can be scaled for different plants using our Kp values for different water requirements.
Less people would be required to manage a larger garden if a control system can ensure people dont have to spend time worrying about these things.
@@ -36,9 +36,9 @@ It is this incredible versatility of the control system setup that allows us to
**The goal** which is the target
**The Inputs **which is all the information the control loop is given. (e.g. soil moisture, car speed, plane altitude, etc.)
**The Inputs** which is all the information the control loop is given. (e.g. soil moisture, car speed, plane altitude, etc.)
**The output **which is the result of the changes your control system made, and the thing you are trying to get close to your goal, or increase towards your goal. (e.g. time on for sprinklers, more gas for car, turning up the plane throttle, etc.)
**The output** which is the result of the changes your control system made, and the thing you are trying to get close to your goal, or increase towards your goal. (e.g. time on for sprinklers, more gas for car, turning up the plane throttle, etc.)
**An error**, which is a measure of how far away your system currently is from your goal or desired behaviour.
@@ -48,7 +48,7 @@ It is this incredible versatility of the control system setup that allows us to
A classical example of a control system is the cruise control in a car. Lets dive into what some of the previous terminology would look like in the context of cruise control as another example:
**Goal: **
**Goal:**
In cruise control, your goal is for the car to remain at the speed you have specified. Lets make our goal a speed of 80km/h.
@@ -62,7 +62,7 @@ Lets say the car drops to a speed of 75km/h due to aforementioned effects. Th
This is where we can use our Kp value to define exactly how drastically our system should respond to this error. A Kp value that is too high will result in the cruise controller to add an unreasonable amount of gas usage, meaning we will almost certainly greatly overshoot our goal of 80km/h, at which point we suddenly need to use the brakes to get back to our goal, but with a Kp too high we will likely slow down too much because our responses are too drastic and it will take a while before we finally get to our goal. A Kp too small may not be suitable either. If the Kp increases the gas by too little, we may only be able to reach a speed of 77km/h because the system will not make a change that is great enough for us to reach 80km/h.
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/091cbd21-8642-4a55-82ec-ace94f86c06b/image10.png)
![](/images/content/5928ab-image10.png)
Figure 1: System response of a high Kp vs a low Kp
@@ -71,27 +71,27 @@ Figure 1: System response of a high Kp vs a low Kp
By now weve seen an application with cruise control, but you could control almost any action the robot does based on any of the available inputs. You could vary the speed of the rovers wheels based on its colour sensors, ultrasonic sensors, gyro sensor, etc. You could even combine multiple inputs and have them control one or multiple outputs.
Lets do a very simple example first of changing speed based on ultrasonic sensor distance.
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/85b26497-8a13-440c-8963-e2ec8ccd5d74/image1.png)
![](/images/content/68263b-image1.png)
Figure 2: Simple proportional control example
This very small snippet of code essentially behaves like a proportional controller, and is likely the most simple one you can make.
**Input and Output: **Your input is the ultrasonic sensor distance value that the rover currently sees. Our output is the rovers wheel speed.
**Input and Output:** Your input is the ultrasonic sensor distance value that the rover currently sees. Our output is the rovers wheel speed.
**Goal:** Match the rovers speed to the live ultrasonic sensor distance
**Error: **Our error is less obvious. If our rover is 10cm away from a wall, and we move straight towards it at 10cm/s, that means if we move forwards for 0.1 seconds our ultrasonic distance will read 9. Our error is that we used to be moving at 10cm/s, but our input tells us that now to achieve our goal of matching the speed and the distance, our error is 1cm/s (10cm/s - 9cm distance) and the system dynamically adjusts for this instantly by just setting the outputs (motor speed) to our ultrasonic distance achieving our goal very efficiently.
**Error:** Our error is less obvious. If our rover is 10cm away from a wall, and we move straight towards it at 10cm/s, that means if we move forwards for 0.1 seconds our ultrasonic distance will read 9. Our error is that we used to be moving at 10cm/s, but our input tells us that now to achieve our goal of matching the speed and the distance, our error is 1cm/s (10cm/s - 9cm distance) and the system dynamically adjusts for this instantly by just setting the outputs (motor speed) to our ultrasonic distance achieving our goal very efficiently.
**Kp: **This program does not have a Kp, so it can be thought of as 1 as we are not scaling our speed based on our distance in this example just yet. If we wanted to move at half the speed of our ultrasonic sensor, then instead of simply inserting the ultrasonic sensor distance, we could do 0.5 * ultrasonic distance, meaning our Kp is 0.5.
**Kp:** This program does not have a Kp, so it can be thought of as 1 as we are not scaling our speed based on our distance in this example just yet. If we wanted to move at half the speed of our ultrasonic sensor, then instead of simply inserting the ultrasonic sensor distance, we could do 0.5 * ultrasonic distance, meaning our Kp is 0.5.
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/a31d099a-14df-48cb-b0ea-3780e8bb46bf/image15.png)
![](/images/content/424fc2-image15.png)
Figure 3: Example showing implementation of Kp = 0.5
This is also largely because we have changed our goal along with our Kp value. The goal is to now move at half of our sensor distance.
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/a9851616-6064-4690-a08e-b53edff81f57/image7.png)
![](/images/content/85e6c6-image7.png)
Figure 4: Proportional control example
@@ -104,27 +104,27 @@ This example also shows a lot more intelligent defensive programming. This means
## **Lets Break It Down:**
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/e472ea8a-4ee5-440d-9ebf-9f96b638c7c2/image3.png)
![](/images/content/1dcadd-image3.png)
- For these first two blocks we can define how far away from objects wed like to stop, and what our Kp gain value is. Experiment with different Kp values and observe what happens! (e.g. 0.1 and 10)
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/0e751959-3f3b-447b-aa3a-ab01b708a50f/image5.png)
![](/images/content/9a2452-image5.png)
- We set up an infinite while true loop so that the code goes on forever until stopped by the user. (Note: It is technically not great practice to have an infinite while loop, but for the sake of this example it will do) The first thing we need to do at the start of our loop is receive the data from our sensors and define that as our distance reading called “dist”. Based on this distance, we can find out how large our error is by subtracting it off our current distance. (e.g. if our goal is 10 cm and our sensor says we are 23 cm away from the wall, our dist is 23 and error is 23-10=13)
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/a0a9a571-6eb8-48d0-a431-45c2668c1c8d/image13.png)
![](/images/content/8faee9-image13.png)
- This is some defensive programming. We want our difference values to fall between the numbers 0 and 30, whereas the Ultrasonic Sensor can produce values from 0 - 255. We just want to ensure that values dont spiral out of control and the robot tries to move at 100cm/s.
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/97e755f8-4d09-4eed-b882-7a721efaa718/image8.png)
![](/images/content/fcd5ce-image8.png)
- This is where we adjust our speed similar to our previous example. We set our motor speed to be our error between our goal and current sensor reading (the 13 value from before)
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/bcbecffd-f59c-414d-95d2-74b0876784aa/image11.png)
![](/images/content/cd7b65-image11.png)
- If a high Kp value shoots up our speed value far above 30 or -30 again, thats the top speed of our robot! That means we need to restrict the values. The program can do this automatically, but its better to have it in your code as defensive programming.
![](https://images.squarespace-cdn.com/content/v1/60a43bf842d7b601064a8828/9b0d134b-efd6-4fb8-afac-e0900a8365e5/image14.png)
![](/images/content/068d50-image14.png)
- Finally, we print the speed so that we can see it in our console, and we make the rover move at the speed we have calculated using our controller.