Granted, it was a long time ago, but I remember trying to work with a CNC milling machine that generated all of the timing on a Windows computer. Everything worked fine unless you touched the mouse, which would cause motion to stutter. So, there can be a lot of gotchas that have to be accounted for when using a "big" computer for "little" things.
Yes. This is just a "keep motor A in sync with encoder B" problem. That should be on something at the Arduino level, although you might need a faster CPU version. Something with no caches, no superscalar, just dumb static memory and fixed-time instruction execution. Linux would just get in the way. The loop that keeps both sides in sync should probably be running around 1000Hz or so. In one of the OP's rather long and numerous videos, he mentions 10Hz not being enough. Right.
If it needs a user interface, that might be on a separate computer, with an interconnect to set the ratio in the motor controller over I2C or something equally dumb.
Also, you can get stepper motors with encoders, so you can tell if you missed a step and correct. You don't have to use a servomotor, which seems to have complicated this project. Shopbots and Tormach mills use stepper motors with encoders.
Many people have converted existing milling machines to CNC, and there are kits for that. This is a much simpler project.
The Arduino development environment is just an IDE and a library for board-level systems. It's C++ underneath, and all of the C++ language, although not the libraries, is available to you. You can do the same thing without the Arduino system, but setting up the build environment tends to be complicated.
If you need precision timing, you either need to program bare-metal, or use some hard real time OS like VXworks or QNX. Here, where it's all stepping and reading encoders, bare metal is the way to go. If you were coordinating a multi-axis machine, a real-time OS might be better.
Note it's a 4096 step encoder, mounted on a different shaft than the one he's driving, that can run upwards of 2500rpm. His motor control loop (not the complete end-to-end, but the bit that maintains output position to that desired) takes under a microsecond. His code works with either a Nema 24 stepper or Nema 23 servo, and he demonstrated both.
In the second video he maths out some projections for error/drift (factoring in floating point representation error) and its ultimate impact on thread accuracy (which provides some motivation for what you might initially consider "overkill" hardware).
10hz is just the refresh rate for the tachometer calculation.
Thinking about dealing with an encoder, let's say it has 8k counts per revolution, and the motor can do 10 revolutions per second, which is pretty fast for a stepping motor. Then the encoder steps are coming in at an 80 kHz rate, but an 180 MHz MCU can execute a couple thousand instructions in that time period, so it's not even breathing hard.
Windows used to (maybe still does, idk) use an interrupt for mouse movement. That was likely the cause of your issue.
Measuring time (down to nanoseconds) is easy. Hard realtime scheduling with microsecond precision... just forget about it, unless you're building a custom distro & custom kernel and have in-depth knowledge about all the drivers that are going to be running on the system (you almost definitely do not).
EDIT: I found a relatively recent socket benchmark with worst case scheduling latencies ranging from tens to hundreds of usec: https://www.codeblueprint.co.uk/2019/12/23/linux-preemption-...
This technique doesn't work when you need to respond to inputs rapidly, but is fine for driving steppers. I see he appears to have gone with servos and encoders, so that would be a bit of a problem since there are inputs to be read.
Obviously; without buffering, glitch-free audio playback would be impossible. I made the assumption that when we're talking about timing on Linux, it's not about throwing buffers at a hardware clocked device.
Does libgpio or some other interface on Linux give you access to clocked DMA out of the box? Do the drivers on RPi support it?
All the gpio drivers I've worked with are just directly writing state to registers.
Sure, time-honored technique for audio. Very on the mark.
But it doesn't really fix the "latency is forever" problem. Buffer too much and your control will lag. Too little and buffers can bottom-out. Best is to over-spec the metal and then be the only code on it so you don't need to buffer at all.
(Worst is, you didn't get to spec the metal, and there's a whole OS full of someone else's Bright Ideas between you and that 200us-or-the-reactor-goes-blooie control loop. Good luck, you're gonna need it).
He mentioned not only microsecond but nanosecond.
It reminds me of Linux routers. They worked great until the PPS rate suddenly got high, like in a network loop or DDoS situation. The kernel would dynamically switch between interrupts and interrupt mitigation/polling, I couldn't find any way to force it to always poll.
If the system was in interrupt mode, and the PPS rate suddenly went way up, the system was so busy handling the interrupts that it couldn't find the time to switch to interrupt mitigation and would livelock.
The solution was fairly easy: Just have more CPU cores than physical network interfaces. Disclaimer: This was ~10 years ago.
The first thing you have to add for anything serious is a real time clock that Raspi DOES NOT HAVE by default.
What he is saying is that Linux is not intended for that,not designed for that, because it it not a RTOS, and it is huge.
You can fill the void, but you will be reinventing the wheel. Low level hardware design is painful.
Linux is extremely complex, too complex for a person to understand. It will take man-years of work to handle all the details, that is, it cost hundreds of thousands of dollars just in salaries alone.
It is way easier to do what this man has done. And then if you want you add an additional raspi with linux as the controlling UI.
That isn't to say it can't be done. Audio is very time sensitive and Linux does it well with the right kernel options. (video is easier, though it uses far more cpu and data on the bus, it is less sensitive to delay).
Depending on how bad delay it might or might not work. As rule though most real time control is run by low speed 8 bit cpus that have exact timing. You have a high power cpu doing the calculations and then the microcontroller just runs the result of the calculations checking in for new orders as needed.
A few years ago I made a 3d printer that used an open-loop stepper system in userland on the original raspberry pi. I got stepper precision down to 2 microseconds [1] — which IIRC is better than the arduino-based systems out there were using. Latency was a different matter — the steppers would still overstep a few times after triggering the endstops.
It takes some hacking (I used DMA and the audio peripherals to offload timing-critical parts from the cpu), but open-loop control is totally doable at 2 microseconds if you’re dedicated to getting it working. Maybe you can get down to 1 us on the newer raspberry pi’s. If you repurpose the video core, maybe you can find a way to do real-time closed-loop control, but that sounds even more involved than what in the end is a relatively simple DMA hack.
[1] https://github.com/Wallacoloo/printipi/blob/master/README.md... Read the scheduler code or check the video linked from the readme if you want more detail.
My Siglent SDG-2042X signal generator uses the same SoC, would guess it's using the PRUs to drive its DACs.
A member of our local makerspace used a PRU to drive a big display made with shift-register RGB LEDs (something like a WS2812 - can't recall details).
I have made a proof-of-concept interface to a fairly high end ADC that did a little bit of filtering in the PRU before sending the results to the main CPU.
Raspberry Pi is much more popular and costs far less. The PRUs can be replaced by a couple of Arduino Nanos for a buck or two each. Won't run at 200MHZ, but there are very few control tasks that need to run that fast.
[0] http://www.righto.com/2018/01/xerox-altos-3-mbs-ethernet-bui...
Having a bunch of cores is advantageous though. There are a variety of options for dedicating one core to the special purpose while the rest serve the general-purpose wild west.
But I'd be surprised if you didn't have headaches just using some python code with cpu affinity on an otherwise unchanged raspbian install.
I would love to see a real RTOS on a RPi though. Something based on sel4 would be very nice to see for instance. You won't get nanosecond precision due to the cache/system effects like people are saying, but microsecond precision should be more than doable.
An example would be better. Say there is an external input to the system (a sensor that detects roller coaster position), you want a deterministic scheduling of the task without any concern about the rest of the state of the operating system. Doesn't matter what the OS is doing - when the roller coaster's position is sensed and there is an interrupt generated to call a subroutine (ISR), a RTOS will not block and it will guarantee execution. Meanwhile, Linux will schedule the task hoping it will get executed but there is no guarantee... I am sure you can hack into the kernel space and write a driver but it becomes a much more of a laborious task - it is just better to use the right OS from the get go.
Hope that makes sense.
A professional motion control system such as [1] comes with 2 components. RTOS element which is a proprietary controller and a GPOS component which is used to communicate, monitor, interface with the user (GUI) and do high-level functions. Usually this is a piece of software installed on a Windows OS, with dedicated PCI cards to communicate to the RTOS modules.
[1] https://www.aerotech.com/product-catalog.aspx
Related reading: https://stackoverflow.com/questions/38241352/rtos-example-wh...
https://stackoverflow.com/questions/536506/how-do-real-time-...
Also, checkout LynxOS...this is the top-end of all RTOSs which has some POSIX (UNIX) like features. It can also run on powerful processors such as Intel and AMD. This is used in airplanes (avionics), trains and public works, super critical operations: https://www.lynx.com/products/lynxos-178-do-178c-certified-p...