Rocket Simulator
- control theory
- PID controllers (what they are, how to implement them, how to tune them)
- linear algebra
- matrices/vectors
- passive transformations (i.e. mapping b/w spaces)
- active transformations (i.e. moving in current space)
- calculus
- integrals (area under curve, accumulated error)
- derivatives (instantaneous rate of change)
- statistics
- normally distributed random variables
Recently I was curious about how rockets steer themselves, so I decided to do a bit of research and see if I could build a simple rocket simulator.
Stochastic Systems and PID Controllers
The actuators and sensors of a rocket, like all devices, are not perfect. Thus when it wants to thrust at a certain angle, it won’t hit that angle exact. It will be a normally distributed random variable centered at that angle
It is not just the thrust that is subject to this inaccuracy. All actuators and sensors of the rocket are. Thus a rocket is a stochastic system, not a deterministic one.
Control theory is a field of engineering that deals with handling stochastic systems like this. More specifically it deals with guiding the actuators to constantly steer a sensor value to some target value, and then to keep it there (as best you can).
For example, you want the robot to be at position x
, so you use the actuators (motors) to move it to x
. But since this is a stochastic system, you may not have arrived exactly at x
. So you use the actuators to try to move him to x
again.
In a strictly mathematical sense, your variable always has a delta
from its target. In other words, the variables current value is different from the value you’d like it to be. This difference tells you in what direction the variable needs to move in.
But you can do one better. In addition to knowing the delta
between the target value and current value, you know the rate at which the variable is currently changing at, i.e. you know its derivative
. This info is useful, b/c for example, the higher the derivative
heading in the wrong direction, the stronger you’d want the correction signal to be.
Also, actuators often don’t take the variable exactly to the target value, there is usually a constant error remaining. By taking into account this constant error, i.e. by seeing how big the integral
of the error is, you can periodically give commands to steer the variable’s value closer to the target value.
A controller that takes into account the error, its derivative and its integral, and uses this information to proportionally control actuators, is called a PID controller.
A PID controller, given the error, derivative of the error, and integral of the error, will tell you the magnitude/direction of the commmand to apply to the actuator in order to reduce the error. The output scales linearly wrt all 3 of these variables (error, derivative of the error, and integral of the error). Very simple.
Basic PID Controller Implementation
Here is a basic implementation of a PID controller in python.
import math
class PIDController:
"""A basic PID controller. Naive implemenation of integral/derivative."""
def __init__(self, p_constant, i_constant, d_constant) -> None:
self.p_constant = p_constant
self.i_constant = i_constant
self.d_constant = d_constant
self._integral = 0
self._last_error = 0
def update(self, error, dt) -> float:
self._integral += error * dt
derivative = (error - self._last_error) / dt
self._last_error = error
value = self.p_constant * error + self.i_constant * self._integral + self.d_constant * derivative
return value
Here is example usage of it.
controller = PIDController(0.1,0.1,0.1)
plant = YourPlant() # w.e. your "plant" is (rocket, robot, etc)
while True:
# dt = delta time, time since plant/controller were last updated
error = plant.update(dt)
command = controller.update(error,dt)
plant.do_command(command)
Of course, the integral and derivative implementation in the above PID controller is minimal, use more complex implementations as needed, but always start with the simplest thing that works for what you are trying to achieve.
The Rocket
I built a basic virtual rocket to test/practice my control theory learnings. Here is what my virtual rocket models.
The rocket has a rectangular shape with a mass of 400 kg which is uniformly distributed. Gravity acts on the rocket’s center of mass downwards, thus the rocket can have both linear and angular acceleration due to gravity. The rocket can apply an impulse of up to 10,000 Newton-seconds anywhere in the range of +-10 degrees of the rocket’s “exhaust” direction. The rocket can apply this thrust within this range at any point in time. Air drag is not modeled. Neither are the mechanical aspects of the rocket (i.e. I don’t concern myself with how the rocket applies thrust, or how it moves its thrust vector, I just assume it can).
With no Controller
These videos show how the rocket behaves with no controller. It just spazzes lol.
Here is the no-controller rocket being launched vertically.
Here is the no-controller rocket being launched at an angle.
With Controller
These videos show how the rocket behaves with a (PID) controller.
Here is the controlled rocket being launched vertically.
Here is the controlled rocket being launched at an angle.
Steering During Flight
The controlled rocket has pretty good control, so I wondered if I could make it steer during flight.
So I decided to make it constantly head towards the position of the mouse.
Here is a video showing the result.