Robotics StackExchange | Archived questions

conver a python script in to a python class and make the callback function a class member

Hi all,

I'd love to use my callback function to process some data and then deliver some result that will be used by other functions in the same python script. And I learned that one common way to do this is to use define a class and make the callback function a class. I am going to show you both of the original script and the one I tried to rewrite in class form. Can you please tell me what i did wrong in my class? I know it is a big favor. Hope you can help. My class throws errors like

ted@vra1:~/dual_ws$ rosrun robotiq_s_model_control SModelSimpleController.py _topic:=/left_hand/command
  File "/home/ted/dual_ws/src/robotiq/robotiq_s_model_control/nodes/SModelSimpleController.py", line 81
    def genCommand(char, self.command):
                             ^
SyntaxError: invalid syntax
ted@vra1:~/dual_ws$ 

My original script which has no errors in shown below:

import roslib; roslib.load_manifest('robotiq_s_model_control')
import rospy
from robotiq_s_model_articulated_msgs.msg import SModelRobotOutput 
from time import sleep
from geometry_msgs.msg import Twist


def callback(data):

print("Message received")
print(data.linear.x) 

def genCommand(char, command):
    """Update the command according to the character entered by the user."""  



if char == 'a':
    command = SModelRobotOutput()
    command.rACT = 1
    command.rGTO = 1
    command.rSPA = 255
    command.rFRA = 150

if char == 'r':
    command = SModelRobotOutput()
    command.rACT = 0

if char == 'c':
    command.rPRA = 255

if char == 'o':
    command.rPRA = 0

if char == 'b':
    command.rMOD = 0

if char == 'p':
    command.rMOD = 1

if char == 'w':
    command.rMOD = 2

if char == 's':
    command.rMOD = 3

#If the command entered is a int, assign this value to rPRA
try: 
    command.rPRA = int(char)
    if command.rPRA > 255:
        command.rPRA = 255
    if command.rPRA < 0:
        command.rPRA = 0
except ValueError:
    pass                    

if char == 'f':
    command.rSPA += 25
    if command.rSPA > 255:
        command.rSPA = 255

if char == 'l':
    command.rSPA -= 25
    if command.rSPA < 0:
        command.rSPA = 0


if char == 'i':
    command.rFRA += 25
    if command.rFRA > 255:
        command.rFRA = 255

if char == 'd':
    command.rFRA -= 25
    if command.rFRA < 0:
        command.rFRA = 0

return command


def askForCommand(command):
    """Ask the user for a command to send to the gripper."""    

currentCommand  = 'Simple S-Model Controller\n-----\nCurrent command:'
currentCommand += ' rACT = '  + str(command.rACT)
currentCommand += ', rMOD = ' + str(command.rMOD)
currentCommand += ', rGTO = ' + str(command.rGTO)
currentCommand += ', rATR = ' + str(command.rATR)
currentCommand += ', rGLV = ' + str(command.rGLV)
currentCommand += ', rICF = ' + str(command.rICF)
currentCommand += ', rICS = ' + str(command.rICS)
currentCommand += ', rPRA = ' + str(command.rPRA)
currentCommand += ', rSPA = ' + str(command.rSPA)
currentCommand += ', rFRA = ' + str(command.rFRA)

#We only show the simple control mode
currentCommand += ', rPRB = ' + str(command.rPRB)
currentCommand += ', rSPB = ' + str(command.rSPB)
currentCommand += ', rFRB = ' + str(command.rFRB)
currentCommand += ', rPRC = ' + str(command.rPRC)
currentCommand += ', rSPC = ' + str(command.rSPC)
currentCommand += ', rFRC = ' + str(command.rFRC)
currentCommand += ', rPRS = ' + str(command.rPRS)
currentCommand += ', rSPS = ' + str(command.rSPS)
currentCommand += ', rFRS = ' + str(command.rFRS)
print currentCommand
strAskForCommand  = '-----\nAvailable commands\n\n'
strAskForCommand += 'r: Reset\n'
strAskForCommand += 'a: Activate\n'
strAskForCommand += 'c: Close\n'
strAskForCommand += 'o: Open\n'
strAskForCommand += 'b: Basic mode\n'
strAskForCommand += 'p: Pinch mode\n'
strAskForCommand += 'w: Wide mode\n'
strAskForCommand += 's: Scissor mode\n'
strAskForCommand += '(0-255): Go to that position\n'
strAskForCommand += 'f: Faster\n'
strAskForCommand += 'l: Slower\n'
strAskForCommand += 'i: Increase force\n'
strAskForCommand += 'd: Decrease force\n'

strAskForCommand += '-->'

return raw_input(strAskForCommand)

def publisher():
rospy.init_node('SModelSimpleController')
topic_name = rospy.get_param('~topic', 'SModelRobotOutput')
pub = rospy.Publisher(topic_name, SModelRobotOutput)

sub = rospy.Subscriber('unitygrabinput', Twist, callback)


command = SModelRobotOutput()

while not rospy.is_shutdown():

    command = genCommand(askForCommand(command), command)            

    pub.publish(command)

    rospy.sleep(0.1)                      

if __name__ == '__main__':
    publisher()

And the class form python script is shown below:

import roslib; roslib.load_manifest('robotiq_s_model_control')
import rospy
from robotiq_s_model_articulated_msgs.msg import SModelRobotOutput 
from time import sleep

from geometry_msgs.msg import Twist

class UnityGrabInput(object):

def __init__(self):
    # Params
    self.sub = rospy.Subscriber('unitygrabinput', Twist, callback)

    self.topic_name = rospy.get_param('~topic', 'SModelRobotOutput')
    self.pub = rospy.Publisher(self.topic_name, SModelRobotOutput)
    self.command = SModelRobotOutput()

def callback(data):

        print("Message received")
    print(data.linear.x) 



def genCommand(char, self.command):    

    if char == 'a':
        self.command = SModelRobotOutput()
        self.command.rACT = 1
        self.command.rGTO = 1
        self.command.rSPA = 255
        self.command.rFRA = 150

    if char == 'r':
        self.command = SModelRobotOutput()
        self.command.rACT = 0

    if char == 'c':
        self.command.rPRA = 255

    if char == 'o':
        self.command.rPRA = 0

    if char == 'b':
        self.command.rMOD = 0

    if char == 'p':
        self.command.rMOD = 1

    if char == 'w':
        self.command.rMOD = 2

    if char == 's':
        self.command.rMOD = 3

    #If the command entered is a int, assign this value to rPRA
    try: 
        self.command.rPRA = int(char)
        if self.command.rPRA > 255:
            self.command.rPRA = 255
        if self.command.rPRA < 0:
            self.command.rPRA = 0
    except ValueError:
        pass                    

    if char == 'f':
        self.command.rSPA += 25
        if self.command.rSPA > 255:
            self.command.rSPA = 255

    if char == 'l':
        self.command.rSPA -= 25
        if self.command.rSPA < 0:
            self.command.rSPA = 0


    if char == 'i':
        self.command.rFRA += 25
        if self.command.rFRA > 255:
            self.command.rFRA = 255

    if char == 'd':
        self.command.rFRA -= 25
        if self.command.rFRA < 0:
            self.command.rFRA = 0

    return self.command


def askForCommand(self.command):

    currentCommand  = 'Simple S-Model Controller\n-----\nCurrent command:'
    currentCommand += ' rACT = '  + str(self.command.rACT)
    currentCommand += ', rMOD = ' + str(self.command.rMOD)
    currentCommand += ', rGTO = ' + str(self.command.rGTO)
    currentCommand += ', rATR = ' + str(self.command.rATR)
    currentCommand += ', rGLV = ' + str(self.command.rGLV)
    currentCommand += ', rICF = ' + str(self.command.rICF)
    currentCommand += ', rICS = ' + str(self.command.rICS)
    currentCommand += ', rPRA = ' + str(self.command.rPRA)
    currentCommand += ', rSPA = ' + str(self.command.rSPA)
    currentCommand += ', rFRA = ' + str(self.command.rFRA)

    #We only show the simple control mode
    currentCommand += ', rPRB = ' + str(self.command.rPRB)
    currentCommand += ', rSPB = ' + str(self.command.rSPB)
    currentCommand += ', rFRB = ' + str(self.command.rFRB)
    currentCommand += ', rPRC = ' + str(self.command.rPRC)
    currentCommand += ', rSPC = ' + str(self.command.rSPC)
    currentCommand += ', rFRC = ' + str(self.command.rFRC)
    currentCommand += ', rPRS = ' + str(self.command.rPRS)
    currentCommand += ', rSPS = ' + str(self.command.rSPS)
    currentCommand += ', rFRS = ' + str(self.command.rFRS)

    print currentCommand

    strAskForCommand  = '-----\nAvailable commands\n\n'
    strAskForCommand += 'r: Reset\n'
    strAskForCommand += 'a: Activate\n'
    strAskForCommand += 'c: Close\n'
    strAskForCommand += 'o: Open\n'
    strAskForCommand += 'b: Basic mode\n'
    strAskForCommand += 'p: Pinch mode\n'
    strAskForCommand += 'w: Wide mode\n'
    strAskForCommand += 's: Scissor mode\n'
    strAskForCommand += '(0-255): Go to that position\n'
    strAskForCommand += 'f: Faster\n'
    strAskForCommand += 'l: Slower\n'
    strAskForCommand += 'i: Increase force\n'
    strAskForCommand += 'd: Decrease force\n'

    strAskForCommand += '-->'

    return raw_input(strAskForCommand)


if __name__ == '__main__':

rospy.init_node('SModelSimpleController')
unity_grab_input_object = UnityGrabInput()

while not rospy.is_shutdown():

    self.command = genCommand(askForCommand(self.command), self.command)            

    pub.publish(self.command)

    rospy.sleep(0.1)

Asked by stevensu1838 on 2019-12-17 04:59:42 UTC

Comments

Answers

In the end, this is not a ROS but a python question.

You cannot have self.command as a parameter to a function.

You might want to read a bit up on what self means in python, there are a lot of pages out there about this. This seems to be the main reason for your issues...

some more hints:

  • it might make sense to have self as the first parameter of your class methods (i.e. def fct(self, var1, var2))
  • self.command below in the main doesn't make sense. You are not "inside" the class...

Asked by mgruhler on 2019-12-17 09:52:21 UTC

Comments