Home > Reflections | โฎ๏ธ โญ๏ธ
2024-05-19 | ๐น๏ธ PID ๐ซ Pod โ Plus ๐ชโจ๏ธ

๐๏ธ Pod Racing Continued
-
Yesterday (2024-05-18 | ๐น๏ธ PID ๐ซ Pod ๐ Racer) I tried several iterations on my intuitive algorithm.
-
๐ It seems that every added sophistication reduced overall performance.
-
๐ค This shouldnโt really be surprising.
-
๐ง Optimization is often unintuitive.
-
๐ก While I can intuit and implement a strategy, itโs hard to improve the overall performance without an explicit objective function.
-
โ Tractable optimization problems often take the form: minimize (or maximize) a single value under some constraints.
-
โ๏ธ Having a single optimization variable is important.
-
๐คฏ Attempting to optimize multiple values simultaneously is much more difficult.
-
๐ซ It may be fair to say that itโs often intractable or even impossible.
-
๐ฑ So when weโre tempted to optimize multiple values simultaneously, it can be fruitful to pick the objective we care most about and transform the others into constraints.
-
๐ฐ For example, if we want to simultaneously minimize the duration and cost of a project, we might instead minimize duration under the constraint that cost stays below some threshold.
-
๐ In this case, I think our optimization problem is something like: minimize time to complete the race under the constraint that we pass through every way point in the correct order.
-
โ This sounds nice. It seems like the most direction expression of our ultimate goal. But how do we solve it?
-
๐จ A brute force approach could be to
-
๐บ๏ธ generate all possible strategies to complete the race
-
๐๏ธ delete every strategy that doesnโt pass through all the checkpoints in the correct order
-
๐ฅ pick the remaining strategy with the best time
-
๐ซ This problem seems computationally intractable.
-
โ What even is a strategy to complete the race?
-
๐ฃ๏ธ Maybe a strategy is a path around the map.
-
๐ Not only are there a very large number of possible paths, but weโd need to add a constraint that our pod can actually follow the path given the gameโs physics engine.
-
๐ก One step we could take toward tractability could be to reduce the vast search space with some simplifying assumptions.
-
โจ Another approach could be to focus on solving a series of local optimization problems rather than a single global optimization problem.
-
๐ค The first intuitive algorithm I implemented is essentially a series of local optimization problems.
-
๐ฏ The implicit goals are to get to the next checkpoint as quickly as possible.
-
๐ฃ๏ธ I say thatโs the implied goal, rather than an explicit goal, because the explicit strategy is to
-
๐งญ always aim at the next checkpoint
-
๐ฏ maintain 100% throttle reduced proportionally to the difference between our podโs heading and the next checkpoint
-
โฑ๏ธ So itโs not even explicitly optimizing for time to each checkpoint.
-
๐ Expressed as an optimization problem, it would be more accurate to say weโre minimizing error in trajectory to the next checkpoint.
-
๐คท Honestly, I donโt think itโs technically even an optimization problem.
-
๐ We really just have a heuristic: reduce throttle by an arbitrarily chosen factor thatโs proportional to the error in trajectory to the next checkpoint.
-
๐ช Despite the lack of rigor, this heuristic performed quite well for a while.
-
๐ So letโs see if we can improve the performance with the use of PID controller.
๐จโ๐ป Letโs start by rewriting our sample Python code into TypeScript.
type PIDParams = {
kp: number
ki: number
kd: number
measurement: number
setpoint: number
time: number
}
type PIDState = {
control: number
error: number
integral: number
time: number
}
const pid = ({ kp, ki, kd, measurement, setpoint, time }: PIDParams, s: PIDState): PIDState => {
const error = setpoint - measurement
const de = error - s.error
const dt = time - s.time
const p = kp * error
const i = s.integral + ki * error * dt
const d = kd * de / dt
const control = p + i + d
return {
control,
error,
integral,
time
}
} - ๐ Now letโs apply this function in our ๐๏ธ pod racing game.
- ๐ Our measurement will be the ๐ angle between our podโs heading and the next ๐ checkpoint.
- ๐ฏ Our setpoint will be 0๏ธโฃ zero, implying that we want our ๐๏ธ pod pointed at the next ๐ checkpoint.
- ๐น๏ธ Our control variable will be the desired reduction in โฝ throttle.