eternal navigation using bumper sensor

asked 2018-11-08 04:27:24 -0600

alexantosh gravatar image

updated 2018-11-08 05:37:23 -0600

Hi all, today I wanted to make my turtle bot move about the room forever without stopping, when something touches, the front bumper sensor, it goes back a bit, turns and keeps moving forward, if hit from the left, turns right and keeps moving forward. If its hit from the right, turns left and keeps going forward ... I have successfully implemented the direction methods and each works fine independently in the call back, however, after a while I get

bad call back error.

Below is the call back function logic which listens to bumper events. How should i improve it to get the above described behavior? Thanks.

def on_bump_event(self, data):
      if data.state == BumperEvent.PRESSED:
          bumped = True
      else
          bumped = False
     if data.bumper == 1:
     # should go backwards, turn and then go forwards
          self.move(speed, distance, direction) # direction is either
 forwards or backwards - a boolean
          #it never turns/reaches this point
          self.rotate(angular_velocity, radians, direction) # direction is
 either clockwise or anticlockwise    #
 turn right x radians, and then keep on
 going forward till collides again   
 if data.bumper == 2: 
          for(i in range(0, 1):
              self.rotate(0.2, x, True) # after rotating i get a bad callback, shows that bumper still is 2 then
 rotates again
          self.bumpData = 5   
      if data.bumper == 0: 
          for(i in range(0, 1):
              self.rotate(0.2, x, True) # after rotating i get a bad callback, shows that bumper still is 0 then
 rotates again
          self.bumpData = 5 


   if self.bumpdata = 5
     self.move(speed, 100000, direction) # should just move forever
 till bumps again - but not happening

Then in the initialisation method:

def __init__(self):
    self.bumpData = 5
# initialise
    rospy.init('node', anonymous=True)
    rospy.on_shutdown(self.shutdown)

    #initialise publishers and subscribers
   ...
    r = rospy-Rate(20)
    r.Sleep()

    while not rospy.is_shutdown():
        # just wait for the bumper to be touched. do nothing


def shutdown(self):
  #do shutdown stuff here:

if __name__ == '__main__':
   try:
        node()
        rospy.spin()
    except # get interruption Error

UPDATE

Got rid of the while loop as suggested in the comment but the problem persists. Also, the turtlebot2 starts with the move forward action, but when interrupted, instead of smoothly moving backwards, it first gives a weird sound, and shakes about, as if trying to both move forward and backwards at the same time. To stop it is it not sufficient to simply set the linear velocity of the robot to zero and then publish the velocity message?

edit retag flag offensive close merge delete

Comments

Not sure this is the answer, but:

def __init__(self):
    [..]
    while not rospy.is_shutdown():
        [..]

don't run infinite while-loops in your constructor (never a good idea).

you don't even need to do that, as you have a blocking rospy.spin() in your __main__.

gvdhoorn gravatar imagegvdhoorn ( 2018-11-08 04:39:31 -0600 )edit

oh alright. I will get rid of the while loop then. I also dont think it will solve it too either. I suspect the problem might be a ros logic related one.

alexantosh gravatar imagealexantosh ( 2018-11-08 05:17:37 -0600 )edit

I'm not super familiar with Python, but is it possible the bumper switch bounces and you end up with multiple threads running different versions of the callback issuing conflicting commands?

billy gravatar imagebilly ( 2018-11-09 02:03:04 -0600 )edit

@billy it is very possible - infact i suspected that too. how can I test/avoid that?

alexantosh gravatar imagealexantosh ( 2018-11-09 03:05:10 -0600 )edit

I would test it with a print in the callback with a unique identifier (increment a global, print it, run callback, decrement the global) to see if multiple versions are running, but a smarter person than me would google it to see if python inherently prevents this or allows to control the behavior.

billy gravatar imagebilly ( 2018-11-09 13:41:35 -0600 )edit

I tested on a Rasp Pi Zero using a function generator to trigger a python callback and scope to monitor status of callback. Re-triggering event before callback returns doesn't cause re-entrant behavior. No sign of 2 different threads at same time. But it can cause callback to function to behave.....

billy gravatar imagebilly ( 2018-11-10 17:22:37 -0600 )edit

..... improperly. The callback I used always took > 5 mS (5 - 40ms) to complete when events came in slowly. But if event came in quicker than 40 mS, I could see callback ending in 2 mS on rare occasions. That means it wasn't running the full callback. In one case the program crashed....

billy gravatar imagebilly ( 2018-11-10 17:26:50 -0600 )edit

...so I say it's possible that bumper re-triggers could be causing issues, but it's not causing multiple threads to be running concurrently. Adding a debounce time to the trigger fixed it for me. Do you have a debounce time defined? As you back away from wall bumper will retrigger. Prepare for that.

billy gravatar imagebilly ( 2018-11-10 17:28:07 -0600 )edit