My son was into “Secret Coders“, a graphic novel series wherein a pair of kids discover and thwart a plot to take over the world by learning to program in the LOGO computer language. When I told him that these “turtle bots” were originally actually real physical things, he wanted one. So we built one out of some nice geared DC motors I had lying around.
A turtle bot has essentially three jobs: move forward in a straight line a controlled distance, turn a given number of degrees, and raise and lower a pen. If you’re already screaming “use stepper motors!” at your screen, well, you’re probably right. But I had these nice Faulhaber/Micromo geared motors with encoders that were just collecting dust in the closet, so I used ’em. And because of that, the robot stumbles on two of its three goals in life — the servo pen lifter works just fine.
Perfectly matched DC motors don’t exist. Of course I knew this, because I’ve built bots with DC motors before. But they’ve all had complex control mechanisms and/or feedback that made it moot. Not here. This bot needs to drive perfectly straight without any lines to guide it or more interesting navigation algorithms.
We spent a good half hour driving it around in not-quite-but-almost squares, tweaking each side’s PWMs, running the motors backwards for short bursts to brake the wheels, and generally trying to map degrees of rotation to milliseconds of motor drive. And you know what, my son enjoyed it. The concepts were simple enough for a second grader, and guessing the right PWM values was like a game. When we finally got it good enough, there was a small celebration.
Of course I know that what it really needs is encoder feedback. I installed those encoder gearmotors on purpose after all. But dealing with quadrature and probably a PID loop to control and sync the two sides is not for my son, at least not for another couple years. (They do learn closed-loop control theory in fourth grade these days, right?) I’ll have to do that all offline some night while he’s sleeping.
But I hope he’ll remember the lessons learned from stabbing at it the naive way. Abstractions are great, but no two motors are ever perfectly alike. You’d think you could just calibrate it out, but the motors differ in driven and coasting behavior, so you’ve got a lot more calibrating to do than you think at first. The real world is tough, and although it’s important to have theory and ideas and abstractions to guide you, you’re going to have to tweak to make it work when the wheels hit the floor. But also that it’s fun to do so, and super rewarding when it finally draws a wonky square.
17 thoughts on “The Real World Strikes Back”
Nice, looks great.
BTW, if anyone can help me with this, it would be much appreciated. I bought a couple of Valient Roamers (the plain grey ones rather than the translucent turtle versions) with the idea of linking them to an ESP and getting it to draw pictures for me, however I am really stumped at being able to talk to them. It looks like there was a box which went between the BBC micro and the roamer which translated the rs234 from the Miro to whatever the roamer speaks.
I have photos which I took of the circuits inside, but there’s basically nothing on the net about the roamer versions, and I have hit a dead end. I can look at wiring to the keypad input and emulating someone pressing the buttons on the top, but really I want to be able to pass it some code and have it follow that.
Does anyone have any experience with these things that can give me some advice on where to start, or to a group that is interested in this kind of thing? Happy to provide photos and pin tests but otherwise I have pretty much declared defeat at this point
archive.og / wayback machine has the websites backed up. Manual and other information is there.
I remember one robot like this which had an ingenious system to make it run straigth. Both wheels had shaft attached to them, and the other ends of the shafts were close together. At that end, there was magnets mounted such that when the wheels turned in the same direction, the magnets kept the rotation in sync. When turning in opposite directions, however, the force was low enough so that it did not affect that mode of operation. I think it is very clean way to achieve same speed in both wheels without any complex feedback, control loops and such.
Milton Bradley’s Big Trax.
We used to get the gearboxes from the local surplus joint for like $5
PI control is enough if you are not after the fastest possible response, and can be explained and implemented in simple terms. But don’t be lazy and go for I-only control, I’ve learned too many times that it will unconditionally oscillate :)
My kids loved that series too. I looked at the time to see if there was a microcontroller Logo, but couldn’t find anything. And existing open source logos looked like too much of a pain to port.
Micropython is great, but I really do love the way logo teaches functional style, and would pair so well with those books to make hands-on projects.
It should be “easy” to write a Logo interpreter in Python/Micropython? Do it on the ESP32 or similar, and you’ve got a web-based console to log into. That would be a great project!
I dunno if you can see the Bluetooth module in mine, but it connects to the microcontroller, which is running a Forth, which also has a console by default. The only trick is the reverse-polish to Logo conversion, and I figured out how to do all of that (mostly trivially) except for “for” loops. He’s been cool with the minor modification so far.
Yeah, I imagine you’d end up with a dialect of Logo with Analog and Digital I/O primitives, but turtle commands being implemented in userland. Never used Lego Logo (way out of our price range as a kid), but I’d imagine it would be similar.
You already learned that no two motors are the same. When you white software control loop with encoders, you will learn that no two wheels are the same, no two parts of the same surface are the same and so on… It will be better, but it won’t be perfect. Eventually you and your kids will learn that you need some sensors to feel the world around.
If your kids get really interested, find some local robotics club, this might be a good starting point: https://junior.robocup.org/
Keep up the good work!
And then you get to optical flow or mouse cameras looking at the floor for feedback😉
Actually you don’t need to do quadrature encoding as you already know the direction the motorsmotors are spinning in. So simple pulscounts are enough.
Yeah, good point. Quadrature is nice b/c you can tell if you’ve missed steps, but it’s also crappy b/c if you miss two steps, you think you’re going backwards.
I always just rip off / modify Peter Danegger’s code from here: https://www.mikrocontroller.net/articles/Drehgeber
I need to let the wheels run and figure out the pulse rate, but my guess is that it’s plenty slow: milliseconds rather than microseconds. And I think these things are internally debounced too, but again, the scope will show.
I once did something like that in Lego using a differential gear with one bigger motor driving the sum and a smaller motor driving the difference of the rotations. As long as the smaller motor was not turning, both wheels moved in unison by design.
Python also has a turtle module.
Have you tried going around by solving it mechanically instead? You could build a differential and map one motor for drive and one for steering:
I used a pair of cheap 28BYJ48 steppers and modified the Python Turtle Graphics module to drive them using MicroPython.
I worked on a version using gear motors and encoders but in the end, I decided the increased complexity and parts cost were not worth the trouble. Stepper motors are easier to explain than PID loops to non-technical people.
PID is great, n all, but I think it’s a bit overused (and overcomplicated) these days. Back when such systems were analog it made sense. Back when our processors were slow it made sense. Back when transistors were slow and largely worked in the analog range, it made sense.
As I see it, PID is largely best-suited for systems which have slow sensors, slow actuator-response, and slow processing ability… Basically all that math is to try to compensate for the effects of a slow sample/update-rate (which is often made slower *because* of that math!).
Imagine a sample/update rate of 15Hz, yet trying to move a motor smoothly at a speed of 30 encoder ticks per second. You *have to* have a dedicated encoder-counter chip to prevent missing steps. Similarly, imagine you have only off and on (and reverse and brake) to control the motor speed, at 15Hz that thing would be gnarly. So you *have to* have a dedicated PWM driver.
But, now, a lowly 8-bit microcontroller at 20MHz can run a simple loop fast enough to handle every quadrature step and recalculate motor power every step, which may be several times during a single PWM cycle. H-Bridges are fast enough to fully switch off/on/reverse/brake at those slow PWM speeds and faster… You can essentially “bit-bang” the power-modulation faster than PWM-cycle rates typically considered normal for motor-driving.
The limiting factors are no longer due to slow sample rates or slow update rates, but due to slow physical properties of the system (momentum, current overcoming inductance, etc.) … Many of which are *inherently* exactly the terms of a PID system. Inductance, Capacitance, Momentum, Current, integrals, differentials… Unless you’re trying to *simulate* a mass-spring system with the different physical one you already have, you can use the PID inherent in the system you have. Now your “error” can simply be “yes, error” or “no error” (or reverse-error/zero-error/forward-error). The “math” reduced dramatically.
Too far? Reverse. Too short? Go forward. Just right? Brake. “Right, but braking isn’t immediate.” “It’ll /oscillate!/” Right, but at an update rate of 50,000 times per second your oscillation turns into… PWM. And when that PWM is applied to an inductor? it becomes an analog voltage somewhere between full-forward and full-reverse, just exactly as would’ve happened if you’d chosen some arbitrary PWM frequency and could only update it once every ten cycles due to the amount of calculation required.
The problem, here, isn’t that it’s too complicated for a forth-grader, but that it has to be explained to 40th-graders who need an explanation in terms of what they’ve become accustomed.
In fact, I’m willing to bet your fourth-grader might’ve even come up with it on his own, only to be smacked-down by a “reality” which really only still exists because we’ve lived through it, or been taught of it, or are thinking of the future-endeavors wherein that same processor might be handling twenty other tasks. (consider a separate processor for that! KISS)
Doing this in Arduino-style of digital-writes and delay-ms is a no-go. But you can get that loop tight enough in C. I know for a fact it’s doable for step-rates of 0-~30,000/sec with four synchronized axes and a bit-banged UART for receiving commands.
Just… Keep in mind what’s happening, here… We’re not trying to match speeds, we’re trying to match [the changes in] *position*… over and over at a preferred (but maybe not exact) rate… 1 step, delay one microsecond, repeat. This’ll also inherently “ramp up” to the desired speed, as when it’s stopped it will take longer to overcome inertia… 1 step will take longer, but 1us delay before starting the next step is constant. And… during that 1us delay, keep that position-maintaining loop running.
But, as someone pointed-out, here, the fact is next you’ll discover that the wheel diameters are slightly different, or the carpet uneven…
Don’t go updating the code while he’s sleeping, learn together!
Please be kind and respectful to help make the comments section excellent. (Comment Policy)