I think as @bar and others have suspected, the calculations for the triangular kinematics are much much faster. I decided to try and see how fast I could get the PID frequency before things went bad.
Turns out, very fast. 2.5ms! 4 times faster than our current rate.
I played with it for 10-15 minutes and it seems to work really well. The only downside being that the motors start to sound like car horns when settling on a point, not super loud, but the tone has changed significantly. It seems to work well, I think it makes things smoother. Although it hasn’t solved the one type of oscillations that I have struggled with.
I put in some code to warn if the movement loop was not completing before the ISR loop happened, however, it seems like the failure mode of too high a frequency is worse. It looks like the serial interrupt may be unable to run completely as I had USB/ disconnects occur when I went to 2ms, but no other warnings.
It may be safest to back off to like 3.5ms or something, but this would still be a big increase frequency. I will continue to play with it.
Very cool! I’ve been thinking about what the right way to adjust that is, because we still need to support both systems. Did you find that the PID tuning values had to change, or could the same values work for both?
I didn’t touch the PID values and it didn’t seem to be an issue, although it would be interesting to see if we could do better. That said, tuning at that frequency is going to be tricky as we can’t get data out of the Arduino that fast.
So I was able to distill all of the frequency related things into a single variable. We could make this user facing, or we could make it so that choosing the kinematics also chooses the frequency.
Yes, but I don’t know that we would want to fix it. I have been able to get the motors to be silent when stopping, but it has generally required the use of a lot of Ki which isn’t really desirable. The noise isn’t really louder than the machine currently is, it is just more vibrant and comical.
I discovered an error in my code which was designed to warn me if the movement loop failed to complete before the interrupt occurred.
Once I fixed this, I found that the safe operating range for the triangular kinematics was about 4000 microseconds. If you start to see any garbled serial communications from the arduino, it likely means your interrupts are happening too frequently.
I have been poking around trying to increase the speed and it seems pretty clear that the improvements need to happen inside the PID loop. The Movement loop, at least for triangular, has very little computation and what is left, I haven’t been able to compress or improve anymore.
But the PID calculation process may happen up to 6 times per loop (twice for each axis). So any improvements here will bring larger dividends.
I created an entirely integer based version of the PID library and I have been able to convert all of the velocity PID calculations to be handled in integer based math. This has resulted in a significant improvement, maybe about 150 microseconds per velocity PID loop, or about 450 microseconds total.
It is pretty clear that conversions from float to int and back again are very time consuming, so I have hopes that converting the position PID will bring even larger benefits.
My dream is to get to 1000 microsecond loops, or 1khz operations. I don’t know how realistic that is.
I’ve been adapting a version of the firmware to the Teensy 3.5/3.6. It all seem to work, except that the ‘car horn’ sound is back, and it can be very slow to decide that the destination point has been reached. I remember you mentioned a single variable to adjust, would that be LOOPINTERVAL?
Perhaps the destination point decision is too precise, either a floating point fuzz thing or more accurate than the encoder stepsize? Can you give it a configurable tolerance and experiment a bit?
Put me on the Teensy motor driver board purchase list, might have a usable shop rather than a concrete dust covered Maslow over a hole by the time that happens (although I heard my contractor is going to Seminary for the winter). If not, happy to help out with the volume discount…
The car horn sound is comical at first and then becomes very annoying. There is a compiler variable in the CNC_Functions file called LOOPINTERVAL at the top. Although, I would be surprised if this was the cause.
The taking time to settle is a better clue. The machine doesn’t keep running until it settles, instead it always runs the motors for 2 seconds after the last command and then turns them off. It seems like it settles earlier only because the PID controllers are tuned well enough to not have any oscillation. If you are seeing a problem settling, then I suspect something has changed with how the PID controller works.
How current is your teensy branch? Are you staying up-to-date with the weekly fixes?
I’m using the current version, 0.97. Using a LOOPINTERVAL of 10000, I see one motor or the other retaining a PWM between 2% and 16%, the values seem higher when the sled is higher up the Y axis, lower when lower. I haven’t had time to try other values. You talked about 2.5ms, that would be 2500, if I understand how it’s used. Would that be worth trying?