0
$\begingroup$

Rosanswers logo

Hey,

I want to implement button debouncing for my xbox controller and I couldn't find anything much helpful till now. All the info that is available on google is related to microcontrollers. Is there an option or a way button debouncing can be implemented in a ros python code?

Thanks in advance


Edit: C:\fakepath\Screenshot from 2018-05-27 19-00-33.png

@PeteBlackerThe3rd In the pic you can see that the joint changed once, when I gave the input through the controller, but instead of stopping at the first 'Plan complete', the loop ran for 7 more times, which causes a bit of delay in processing the second instruction given through the controller. Could you maybe point out my mistake or maybe guide me through the right process so that I can detect my mistake?

Edit-2 Code screenshot: I know it's not suggested to take a screen shot of the code and post it here, but I just wanted to make sure that the indentations I am having in my code are clear, since indentations are a not always correct here Code

Edit -2

This is my code

#!/usr/bin/env python

import sys
import copy
import rospy
import moveit_commander
from moveit_msgs.msg import *
from geometry_msgs.msg import *
from sensor_msgs.msg import *
import time

j1 = 0
a = 0
flag1 = 0
flag2 = 0


def callback(data, group1):
    global a, flag1, flag2, j1
    if ((data.buttons[0]==1) and (data.axes[6]==1)):
        if (flag1 == 0):
            a += 1
            flag1 = 1
            j1 = (int(a))*0.1
            print "Value of Joint 1 is: %s " %j1
            if (j1 >= 3.1): 
                group1_variable_values[0] = 3.1
                print "Limit reached joint 1"
            else:
                print "changing joint 1"
                print "Plan completed"
        group1_variable_values[0] = j1
        group1.set_joint_value_target(group1_variable_values)
        plan2 = group1.plan()
        execute2= group1.execute(plan2)
        rospy.sleep(1)
        print "plan complete"
    else:
        flag1 = 0
    
def move_group_python_interface():
    global group1_variable_values, robot
    moveit_commander.roscpp_initialize(sys.argv)
    rospy.init_node('move_group_python_interface', anonymous=True)
    robot = moveit_commander.RobotCommander()
    group1 = moveit_commander.MoveGroupCommander("igus_planning")
    group1_variable_values = group1.get_current_joint_values()
    display_trajectory_publisher = rospy.Publisher('/move_group/display_planned_path',
              moveit_msgs.msg.DisplayTrajectory,queue_size=50)
    rospy.Subscriber("joy", Joy, callback, callback_args=group1)
    rospy.spin()


if __name__=='__main__':
    try:
           move_group_python_interface()
    except rospy.ROSInterruptException:
        pass

Originally posted by Kashyap.m94 on ROS Answers with karma: 46 on 2018-05-27

Post score: 0


Original comments

Comment by PeteBlackerThe3rd on 2018-05-27:
The buttons on the Xbox controller are already de-bounced. This is a low level process performed by hardware not a function performed by software.

Comment by PeteBlackerThe3rd on 2018-05-27:
Can you show the source code of your node which is taking the controller input and interfacing with MoveIt, then we'll be able to see what's going on.

Comment by PeteBlackerThe3rd on 2018-05-27:
If you are responding to joy messages where the button is pressed, then it is expected for there to be many of these for a single key press. If there were hundreds of messages with the button going on and off, then this would be a de-bouncing problem.

Comment by PeteBlackerThe3rd on 2018-05-27:
You may be able to fix this by detecting the transition from off to on to trigger your plan, so called edge triggering, instead of just checking if the button is pressed (if that is what you're doing)

Comment by Kashyap.m94 on 2018-05-27:
I edited my previous comment with the code, and you actually did suggest me the edge triggering before and I did apply it. You can check in the code

Comment by gvdhoorn on 2018-05-27:
@Kashyap.m94: do not post extra information as an answer, unless you are answering your own question. I've merged your answer into your original question text, but please keep this in mind.

You've been asked this before, so it would be appreciated if you could follow forum etiquette.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

If you're indenting is corrent (It's tricky to paste it onto the forum correctly sometimes) then you need to indent the following code one more time so that it's all within the if (flag1 == 0): statement:

    print "Value of Joint 1 is: %s " %j1
        if (j1 >= 3.1): 
        group1_variable_values[0] = 3.1
        print "Limit reached joint 1"
    else:
        print "changing joint 1"
        print "Plan completed"
            group1_variable_values[0] = j1
    group1.set_joint_value_target(group1_variable_values)
    plan2 = group1.plan()
    execute2= group1.execute(plan2)

At the moment the only thing you're doing on the edge triggered event is updating the values of a and j1, everything else, the limit checking, planning and execution is still happening for every message with the button pressed.

Hope this helps.

Update: I've had a close look at your code screen shot and the terminal output you've shown, and they don't match. The terminal shows the string plan complete 8 times, but the print statement in code contains the string Plan completed. Extra d and a capital P. Also these two print statements are at shown within the same if:

print "changing joint 1"
print "Plan completed"

So it's not possible to have one without the other, but the terminal shows changing joint 1 once and 8 of the other.

Also even in your screen shot the plan and execute statements are outside of the flag if statement, which doesn't make any sense. You don't need to move the arm if the joint angles aren't changing.

Can you update your question with matching source code and screen shot then we'll be able to get to the bottom of this.

Update 2: I see where the problem is here, this code:

    group1_variable_values[0] = j1
    group1.set_joint_value_target(group1_variable_values)
    plan2 = group1.plan()
    execute2= group1.execute(plan2)
    rospy.sleep(1)
    print "plan complete"

is not within the if (flag1 == 0): statement so it is being executed for every joy message where the buttons are pressed. This is true both in your screen shot and the pasted code, these commands need indenting one more time. This explains the extra plan complete strings and delay. Your code would be cleaner and simpler if you just combined these two if statements into one.

The plan and execute commands will take a fair bit of time to execute so I see why this is casuing a delay. You should consider using asyncExecute instead, this command starts the robot moving but doesn't wait for it to finish moving before continuing on to the following code.

This should get the code doing what you want.


Originally posted by PeteBlackerThe3rd with karma: 9529 on 2018-05-27

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by Kashyap.m94 on 2018-05-27:
The indentation is there. Everything is with in the if (flag1 == 0): loop. I did correct the indentation below. Maybe you can check that

Comment by Kashyap.m94 on 2018-05-29:
@PeteBlackerThe3rd Hey, thanks for the observation. I have updated both the code and the sceen shot of the code above under the title Edit-2

Comment by Kashyap.m94 on 2018-05-29:
Oh damn. Yes, you're right. Thanks for the help.

I will apply asyncExecute too and try the same. Thanks again.

Comment by Kashyap.m94 on 2018-06-04:
@PeteBlackerThe3rd Hey, could you kindly check the Edit-3. I am trying something different and am facing a bit of a problem. Thanks

Comment by PeteBlackerThe3rd on 2018-06-04:
You'll need to ask a new question for this. We can't have multiple questions in a single thread. I'm happy to help you there, but the answer is not a straightforward one!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.