I got the outdated
neato_robot ROS package mostly working just by adding a timeout to its serial communications. But this only masked the symptom of an unknown problem with no understanding of why it failed. To understand what happened, I removed the timeout and add the standard Python debugging library to see where it had hung.
import pdb; pdb.set_trace()
I found the hang was
neato_driver.py. It is waiting for my Neato to return all the motor parameters specified in the list
xv11_motor_info. This list appears to reflect data returned by author’s Neato robot vacuum, but my Neato returns a much shorter list with only a partial overlap. Hence
getMotors() waits forever for data that will never come. This is a downside of writing ROS code without full information from hardware maker: We could write code that works on our own Neato, but we would have no idea how responses differ across different robot vacuums, or how to write code to accommodate those variations.
Turning attention back to this code,
self.state is supposed to be filled with responses to the kind of data listed in
xv11_motor_info. Once I added a timeout, though,
getMotors() breaks out of its
for loop with incomplete data in
self.state. How would this missing information manifest? What behavior does it change for the robot?
Answer: it doesn’t affect behavior at all. At the end of
getMotors()we see that it only really cared about two parameters:
RightWheel_PositionInMM. Remainder parameters are actually ignored. Happily, the partial overlap between author’s Neato and my Neato does include these two critical parameters, and that’s why I was able to obtain
/odom data running on my Neato after adding a timeout. (Side note: I have only looked to see there is data – I have not yet checked to see if
/odom data reflects actual robot odometry.)
Next I need to see if there are other similar problems in this code. I changed
xv11_motor_info list of parameters to match those returned by my Neato. Now
getMotors() will work as originally intended and cycle through all the parameters returned by my Neato (even though it only needs two of them.) If this change to
neato_robot package still hangs without a timeout, I know there are similar problems hiding elsewhere in this package. If my modification allow it to run without a timeout, I’ll know there aren’t any others I need to go hunt for.
Experiment result: success! There are no other hangs requiring a timeout to break out of their loop. This was encouraging, so I removed
Unfortunately, that removal caused the code to hang again. Unlike the now-understood problem, adding a timeout does not restore functionality. Removal of debugger package isn’t supposed to affect behavior, but when it does, it usually implies a threading or related timing issue in the code. This one will be annoying as the hang only manifests without Python’s debugging library, which meant I’d have to track it down without debugger support.