Wednesday, September 20, 2023

Story: A real time controller

 To compete in Pi Wars, we think it would be good to have a differential drive robot that could move around predictably, based on odometry. So, we have two motors to control and feedback from the motor encoders to process. 

The motor encoders quadrature output which are estimated to have an output frequency of 1.5 kHz at top speed. 1500 Hz, two edges per period, two encoders, two pins per encoder are 6000 edges to track every second.

We were not sure how to do this on Raspberry Pi. Can this even be done reliably and if so, how much time and effort do we need to spend on this? Time and effort that can’t be spent on Pi Wars challenges itself and on OpenCV – our tool of choice for our main sensor (the camera) which is also new to us.

So, we decided to have a separate controller to move the robot around. We’ve made robots with motors and encoders before, so we knew it can be done, what it takes and even have code available to give us a head start. As additional advantage, two controllers (the Raspberry PI – our main controller- and the Realtime controller) creates modularity and enables us to splits tasks between team members.

Downside of this the robot will be larger due to the second controller. And the functionality (code) will be split between two modules (which could be a blessing or a curse, depending on the issue at hand).

The modules are coupled by a serial link with, for now, text-based commands sent by the Raspberry Pi and framed responses (along with lots of unstructured logging) sent by the Realtime controller. 

Realtime computing

From Wikipedia:

Real-time computing (RTC) is the computer science term for hardware and software systems subject to a "real-time constraint", for example from event to system response. Real-time programs must guarantee response within specified time constraints, often referred to as "deadlines".[1]

For this, our Realtime controller has a main loop that runs every 20ms to read the encoders and update the robot position estimate of the robot. This updated estimate is reported to the Raspberry Pi and used by the active ‘driver’ as feedback, to calculate the proper steering (pwm) signal for each motor.

Other actions in the main loop include processing of commands from the Raspberry Pi. This could be forementioned driver-commands of update of the servo-outputs, which are generated in the background.

And if additional sensors are required, they will probably be connected to the Realtime controller and read in the main loop.

And all those encoder edges? They are decoded with no overhead by two hardware counters of the microcontroller. So reading the encoders is basically get the counters and calculate the difference since the previous time.


 Implementation

The Realtime controller is based on a PCB, created with KiCad and manufactured by one of the big Chinese PCB-manufacturers. On this PCB are modules available from the well-known Chinese resellers. 

We’ve considered the Raspberry pi Pico as the microcontroller for the Realtime controller but chose an STM32F411 we’ve used on a similar robot, since we expected less risk of errors on the design and less issues with the software. 

And with regard to that risk: it turned out we had two pins swapped on the PCB, which could be fixed with one wire as long as we don’t use IR remote control.

Although they worked on another robot, we had quite an issue both the encoders. Both timer2 and timer4 did not count the encoder pulses from the motors. It took three long nights to track down what caused this: IO configuration values of the were swapped, and the 0x22 marked red should have been 0x11, while in another register, 0x11 should have been 0x22. Small but hard-to-find errors…



The software is compiled with the Arduino IDE (v1.8.19) and the ‘STM32 MCU based boards’ from STMicroelectronics. This is easy to configure and use. Instead of the basic Arduino IDE editor, an external editor with more advanced features for search and project/file management is used to write the software.

The only other external library used is the PID library of Brett Beauregard [2].

The source code is in a private repository on GitHub. We intend to make it public later this year, once we’ve thoroughly tested it.

In a future blog, we’ll go into more detail of our driver software and some of the supporting modules we’ve created for the Realtime controller. For now, we conclude with the block diagram of the motor control software (including the PID controllers).


[1] https://en.wikipedia.org/wiki/Real-time_computing

[2] https://github.com/br3ttb/Arduino-PID-Library

No comments:

Post a Comment

The Finale - Sunday, 21st April 2024

 Wow What an event this Pi Wars is, being inspiring for all participants. On Saturday we saw many young people transforming from being anxi...