Robotics StackExchange | Archived questions

Rosserial Service "Failed to parse subscriber"

I am attempting to create a simple service on an arduino. My arduino sketch compiles (verify), downloads, and runs on my arduino duemilanove. However, when I run rosserialpython serialnode, I get the following:

$ rosrun rosserial_python serial_node.py 
[INFO] [WallTime: 1353276138.035460] ROS Serial Python Node
[INFO] [WallTime: 1353276138.041617] Connected on /dev/ttyUSB0 at 57600 baud
[ERROR] [WallTime: 1353276140.194715] Failed to parse subscriber. 'module' object has no attribute 'gripper'

Any clue what's going on here? My arduino node does not include any subscribers (or publishers), just a service server for a service called gripper in a package called abbygripper. I have run rosmake abbygripper to create the message headers, and run rosserialclient makelibrary.py on abbygripper to put these in my arduino roslib, and the arduino sketch appears to be running.

Update 1:

Determined that the serial node thinks my service is a subscriber because it casts services to subcribers. Changing line 323 of node_handle.h (in the arduino roslib) as follows allows the serial node to properly identify the service as a service, but I still have a parsing issue. I think this is due to incorrectly identifying my service name in my arduino sketch.

node_handle.h, line 316-326:

    for(i = 0; i < MAX_SUBSCRIBERS; i++)
    {
      if(receivers[i] != 0) // non-empty slot
      {
        ti.topic_id = receivers[i]->id_;
        ti.topic_name = (char *) receivers[i]->topic_;
        ti.message_type = (char *) receivers[i]->getMsgType();
        no_.publish( receivers[i]->_getType(), &ti );
        //Above changed from no_.publish( TopicInfo::ID_SUBSCRIBER, &ti );
      }
    }
  }

Now when I run it, I get:

$ rosrun rosserial_python serial_node.py 
[INFO] [WallTime: 1353292452.468408] ROS Serial Python Node
[INFO] [WallTime: 1353292452.472808] Connected on /dev/ttyUSB0 at 57600 baud
[ERROR] [WallTime: 1353292454.598246] Failed to parse service server

Progress, I guess. I'll post if I make any more.

Update 2:

I am beginning to suspect that I am the first person to attempt to run a service server on a serial client.

I found that the loadpkgmodule method in SerialClient.py only works for messages, not services. I modified lines 52-69 as follows to allow it to be used for srvs as well as msgs:

def load_pkg_module(package, ext='msg'):
    #check if its in the python path
    in_path = False
    path = sys.path
    pkg_src = package+'/src' #check for the source directory which
                             # is added to path by roslib boostrapping
    for entry in sys.path:
        if pkg_src in entry:
            in_path = True
    if not in_path:
        roslib.load_manifest(package)
    try:
        m = __import__( package +'.'+ext)
    except:
        rospy.logerr( "Cannot import package : %s"% package )
        rospy.logerr( "sys.path was " + str(path) )
        return None
    return m

and call it from ServiceServer on line 127 like so:

    m = load_pkg_module(package, 'srv')

Now, when I run serial_node, I get the following output:

$ rosrun rosserial_python serial_node.py 
[INFO] [WallTime: 1353296694.048375] ROS Serial Python Node
[INFO] [WallTime: 1353296694.054464] Connected on /dev/ttyUSB0 at 57600 baud
[INFO] [WallTime: 1353296696.198338] Setup ServiceServer on abby_gripper/gripper [abby_gripper/gripper]

Success! Now I try to call my service using rosservice:

$ rosservice call /abby_gripper/gripper "command: 0"
ERROR: service [/abby_gripper/gripper] responded with an error: error processing request: global name 'data_buffer' is not defined

and from the rosserial_python node:

Traceback (most recent call last):
    File "/opt/ros/fuerte/lib/python2.7/dist-packages/rospy/impl/tcpros_service.py", line 615, in _handle_request
        response = convert_return_to_response(self.handler(request), self.response_class)
    File "/opt/ros/fuerte/stacks/rosserial/rosserial_python/src/rosserial_python/SerialClient.py", line 139, in callback
        msg.serialize(data_buffer)
NameError: global name 'data_buffer' is not defined
[ERROR] [WallTime: 1353296740.254393] Error processing request: global name 'data_buffer' is not defined
None

I'll keep plugging away on this.

Update 3:

After a bit of a rewrite to SerialClient.py, I now have a working service. It seems that services were added as an afterthought and never tested, because it looks like most/all of the service code was copied from the subscriber and publisher code, and there's no way it could have worked as-is. Worth noting as well, I was calling rosservice incorrectly above, but that was not the source of any of my problems. I'll be submitting my changes to the maintainer of rosserial, but in the mean time, post a comment if you want me to post my code here/elsewhere.

Update 4:

It appears that the latest code in the mercurial repo for rosserial has almost completely rewritten the python node. Presumably this is for groovy. I haven't tested it (and I'm sticking with fuerte on my platforms). It probably implements services properly. In the mean time, if anyone's running fuerte and wants to having working rosserial services, my fork is on my github at evenator/rosserial (I don't have enough karma to post links)

Asked by Ed Venator on 2012-11-18 11:18:58 UTC

Comments

Answers