Background:
I have been working on creating a speed control algorithm for the Rover 5 (t2 motor, 2 encoder). I adopted a reasonbly simple Proportional model based on standard control approaches. I began testing/tuning. While doing so, I instrumented the controller so that it would save the encoder signal period; this data gets printed after motion completes.
Plotting in Excel in theory gives me a reasonable view of the motor/belt motion in terms of the period. I think I discovered that fresh batteries result in much less variation over a belt rotation, as one might expect.
When trying to test the control equation tuning factors (and different implementations using floating point or long math), I wanted to ensure that any motion test started with the belt at the same location so each test would experience nearly identical mechanically caused variation. To do so, I turned off power to the motors, but not the controller, and manually turned a front (non-powered) wheel to position the belt.
Before doing the manual tweaking of belt position, with fresh batteries and a constant PWM value to the motors, the period appeard to have a +- 1.5% variation around an expected average. After tweaking the wheel manually, I got a +-7.5% variation around an unexpected average. In some tests the majority of periods were close to the expected average, but significant slowdowns occurred that reduced the overall average. In some tests, the average was faster than expected. I am totally confused now.
Question:
Is it possible that manual turning of the Rover 5 wheels could cause damage in some way? Would it be permanant or fixable?
Thanks to the responders.To
Thanks to the responders.
To OddBot,
I am measuring speed using the encoders, which cause interrupts on the Arduino-based DFRobot Romeo controller. I have seen interesting and consistent variations in encoder pulse width/period due to the construction of the encoder, and I have accounted for “8 state change” pattern in my code. I don’t think I’ve had problems due to floating point math, but I switched to long (and sometimes binary, i.e., shifting) math to decrease time in the ISR. I don’t know for sure what a broken gear tooth would feel or sound like, but I don’t believe I ever put enough stress on the wheel to break a tooth. Would a broken tooth show up as an artifact in a plot of the encoder pulse period?
To Duane,
I did move things slowly, and I am hoping I did not really cause any breakage. As I responded to OddBot, however, I am not sure I would know it if I did. Fortunately, I have had no trouble with treads falling off, but I have seen very odd speed changes on a transition from a wood surface to a rug; what was a slight bias to the left on wood turned into a strong bias to the left on the rug. I am hoping that monitoring speed and adjusting PWM will help. However, as long time software engineer, and novice mechanical engineer, I am finding the real world of motors, wheels and treads to be much less willing to bend to my control than the virtual world of software.
Update…Again thanks to
Update…
Again thanks to the responders for the help. I have worked on and off at introducing speed control and I think I have actually got something working. In fact, it appears to work quite nicely. In many circumstances I can make the robot go more or less straight over reasonably long distances, e.g., 2+ meters. It is probably as good as I am going to get given the electrical and mechanical variances involved.
I created a much more complex (perhaps needlessly so) approach than OddBot’s. Due to other things going on in my Arduino main loop(), e.g., checking proximity sensors, I felt I could not reliably control speed in the main() loop. Thus the heavy lifting of control is done in my interrupt service routine (ISR) for each motor independently. I took advantage of observations from plotting the encoder period (one phase, rising edge to rising edge). I found a 4 pulse pattern that was consistently imposed on any longer term period variation. As a result, I do speed control calculations and PWM update only every 4th interrupt, based on the average period over 4 periods. The approach, to the best of my ability (or tolerance) to measure it, appears to add roughly 20 microseconds to the ISR time, thus averaging adding only 5 microseconds per interrupt. The interrupts occur at roughly periods around 13000 microseconds, so the extra time does not seem too burdensome.
I have two components of control. The first is “instantaneous” that is done in the ISR, and it adjusts PWM based on the difference between the desired and measured pulse period; there is a proportional constant used. The second is “long term” done in the main loop() and is based on the difference between average period and measured pulse period; there is another proportional constant used.
I have done a lot of tuning and testing, and what I’ve achieved is far from perfect. There is about as much variation between what should be identical tests as between tests with different constants. And I still have some behaviors I can’t explain; for example, tests today showed that on my wood floor, the robot will travel roughly straight going “north” or “south”; on my rug, however, it will travel roughly straight going “north”, but turns strongly to the right when going “south”. I suspect there may be something involved with the nap of the rug, as it is visually different when viewing from “north” or “south”.
TO ODDBOT:
I do have another question. You code seems to ramp up the PWM value somewhat slowly, initially 2 counts at a time and then one count at a time. Is that important for control? I currently set the intial PVM value to what I think it should be to achieve the desired steady state speed and adjust around that value appropriately (at least according to my algorithm).