-
Notifications
You must be signed in to change notification settings - Fork 0
/
state.hs
63 lines (48 loc) · 1.76 KB
/
state.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import Control.Monad.State.Lazy
import Data.Maybe
-- PID Gains
kp :: Double
kp = 0.0100
ki :: Double
ki = 0.0009
kd :: Double
kd = 0.0000
-- Flywheel Moment of Intertia
i :: Double
i = 1/2 * 0.1 * 0.05**2 -- for 100 g, 10 cm diameter flywheel
-- Drag coefficient
c :: Double
c = 0.001
-- timestep
dt :: Double
dt = 0.01 -- s
-- number of iterations
n :: Int
n = 1000
-- Controller setpoint
setpoint :: Double
setpoint = 100 -- rad/s
type SimulationState = (Double, Double)
sim_init :: SimulationState
sim_init = (0.0, 0.0)
type Gains = (Double, Double, Double)
type ControllerState = (Gains, Double, Double, Double)
controller_init :: Double -> ControllerState
controller_init s = ((kp, kd, ki), s, 0.0, 0.0)
s0 :: Double -> (ControllerState, SimulationState)
s0 set = (controller_init set, sim_init)
update :: State (ControllerState, SimulationState) Double
update = (get >>= \(((kp, kd, ki), s, d, i), (theta, omega)) -> let err = s - omega in put (((kp, kd, ki), s, err, i+err), (theta, omega)) >>= \() -> get >>= \(((kp, kd, ki), s, d, i), (_, omega)) -> let err = s - omega in return (kp * err + ki * (i+err) + kd * (d-err))) :: State (ControllerState, SimulationState) Double
simulate :: Double -> State (s, SimulationState) ()
simulate = (\tau -> get >>= \(cs, (theta, omega)) -> let alpha = 1.0/i * (tau - c * omega) in put (cs, (theta + omega * dt, omega + alpha * dt))) :: Double -> State (s, SimulationState) ()
:{
clip :: (Ord p, Fractional p) => p -> p
clip x | x > 1.0 = 1.0
| x < -1.0 = -1.0
| otherwise = x
:}
:{
run :: Int -> State (ControllerState, SimulationState) Double
run 0 = get >>= \(_, (_, omega)) -> return omega :: State (ControllerState, SimulationState) Double
run n = update >>= \tau -> return (clip tau) >>= simulate >>= \_ -> run (n-1)
:}