@@ -11,6 +11,11 @@ With 2x A4950s on the DAC, AS5047P on the encoder, etc.
- haven't tested with '+ve' signed calibrations, i.e. if motor += magnetic step does encoder += tick step.
## Likely Improvements
- encoder value filtering is a PITA, see note from 2021-02-17 about filtering and time constant. change loop structure so that we (1) sample the encoder as fast as possible, always, maybe 50kHz, and then (2) filter that with a heavier first exponential filter (keeping some small time constant as a target), and (3) run the actual control loop with this filtered value
- even better, run an [alpha beta filter](https://en.wikipedia.org/wiki/Alpha_beta_filter) underneath the control loop, as fast as possible, always.
## Evaluation
- static holding, watch encoder wobble when torque applied (can see ticks moving around even w/o motor torque being overcome), measure again with closed loop: can we hold *better* than static pointing?
...
...
@@ -1283,8 +1288,68 @@ It occurs to me also that this particular case (motor on desk, nothing else) is
Yeah, tuning will be hard, have the subsystems now though. I am suspicious of the heavy filtering - especially as I think it might be shifting the d-term signal phase to be 180' or so out of phase, making for oscillations. In any case, tomorrow, a serious tuning / pid-mastery-attempt session.
So, next would do:
- PID remote-set
- target-pos remote-set
- tuning attempts
- auto-tune ?
\ No newline at end of file
## 2021 02 17
So, got to design a little rotary drive last night, that should help establish a realistic baseline for 'the plant' so to speak.
Currently:

```
P -0.09
I 0
D -0.0003
A 0.2
A* 0.05
```
This feels... OK. I need an I term, and an I limit... which I figure should be (?) ~ 0.2, to start. I can end up adding oscillation and is a PITA to tune IIRC. In a lot of ways, it's another 'p' term.

I figured at the start that a relatively small iLimit would be the move, but a larger limit feels better to help small disturbances... i.e. it pins the torque to the max when there's a resting force on the rotor (as in machining / etc).
My current winners are:
```
P -0.09
I -0.002
Ilim 0.8
D -0.0003
A 0.2
A* 0.05
```
OK, I am satisfied with these for the time being, time now is to apply it to a real system. I have also a few things I want to know:
### Time Constant of the Exponential Filter?
I was suspecting earlier that my filters were too aggressive (alpha 0.01), causing effectively a signal phase delay that was driving oscillations. This was confirmed (psuedo-scientific / intuitive sense) when turning the filter values 'down' (to 0.2) caused oscillations to stop, and allowed me to tune my P values back up without bringing on more oscillation.
So, what's the real maths here? Shouldn't be that hard to find on the internet. Yeah, from [the wiki](https://en.wikipedia.org/wiki/Exponential_smoothing) it looks like (if the sampling interval `delT` is fast relative the time constant)
`tc = delT / alpha`
So for an alpha around 0.01, with our sampling rate of 10kHz or 0.0001 the time constant was ~ 0.1 seconds, or 100ms, which is a whole lot in these terms - and the oscillations I observed seemed around 10Hz (maybe faster) so, yes, ok, we cannot just filter this into oblivion.
However, we could sample the encoder more often (I think 50kHz was the hardware limit) and filter that, then run the PID loop on a pre-filtered value. I'm going to keep a list of 'likely improvements' here, that being one of them.
### The Alpha Beta Filter?
This also seems primo, the [alpha beta filter](https://en.wikipedia.org/wiki/Alpha_beta_filter) is basically a 2d kalman filter, IIRC from conversations with Sam. This is basically what we do when we know that i.e. our previous speed estimate is likely to give us a good expected value for our new position measurement.
Seems a bit tricky algorithmically because it is easy to become confused about time-steps / previous values / etc - and besides, we are using the position measurements to take derivatives that we then use to improve our position measurements, seems a bit cyclical.
In any case, I am not going to go down this rabbit hole now, but it's there for interest.
### Unrolling the Angles
So, then, next is having target set-points that are not directly related to the motor. I wonder if actually the way to do this is actually to add another layer that runs on top of the servo controller and, given a set-point with some 'RPU' (rotations per unit), calculates the rotations to get there, and keeps feeding a new target to the lower level hardware... nah, this won't work because eventually we will have some points that are at ~ 359.9 degs or so and it needs to intelligently servo from 0.1 degs to that, not around the other side.
So! There must be an established way to do this...