[ros-users] Subscribe messages from normal C++ code

Paul Fitzpatrick paulfitz at liralab.it
Sat Jun 19 03:20:25 UTC 2010


Hi Keisuke,

If you were willing to receive the "chatter" output of just the "talker" 
demo program, and don't require a real subscription, that's just about 
doable (although probably ill-advised).  Here's how:
  + Open a socket to the roscore server (usually at port 11311), and 
send an XML/RPC message asking for the address of the /talker node [1].
  + Open a socket to the address you are told, and send an XML/RPC 
message asking for the /chatter topic [2].
  + Open a socket to the address you are told, send a ROS message 
header, skip over the ROS message header that gets sent back, and from 
then on you'll be the happy recipient of a stream of chatter [3].

I've given examples below of messages that worked for me when I played 
with this a while back.  I'm not affiliated with Willow in any way, and 
this is just based on experimentation, so my suggestions could be broken 
in various ways (if not downright evil).  And if you want to go further, 
things get complicated.  If you'd asked how to *send* data rather than 
receive it, this would be a much longer email ;-).  Unless you have a 
really, really good reason, you don't want to reimplement this stuff.

Hope this helps,
Paul

===
[1] See http://www.ros.org/wiki/ROS/Master_API
Here's an example of asking roscore for the address of /talker:

POST /RPC2 HTTP/1.1
User-Agent: XMLRPC++ 0.7
Host: 192.168.1.2:11311
Content-Type: text/xml
Content-length: 179

<?xml version="1.0"?>
<methodCall><methodName>lookupNode</methodName>
<params><param><value>dummy_id</value></param><param><value>/talker</value></param></params></methodCall>

The response will look something like:

HTTP/1.0 200 OK
Server: BaseHTTP/0.3 Python/2.5.4
Date: Sat, 19 Jun 2010 02:02:50 GMT
Content-type: text/xml
Content-length: 261

<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><array><data>
<value><int>1</int></value>
<value><string>node api</string></value>
<value><string>http://contact:33561/</string></value>
</data></array></value>
</param>
</params>
</methodResponse>

Note the "http://contact:33561/" in there.

===

[2] See http://www.ros.org/wiki/ROS/Slave_API
Here's an example message asking /talker for the /chatter topic:

POST /RPC2 HTTP/1.1
User-Agent: XMLRPC++ 0.7
Host: 192.168.1.2:33561
Content-Type: text/xml
Content-length: 304

<?xml version="1.0"?>
<methodCall><methodName>requestTopic</methodName>
<params><param><value>dummy_id</value></param><param><value>/chatter</value></param><param><value><array><data><value><array><data><value>TCPROS</value></data></array></value></data></array></value></param></params></methodCall>

The response will look like:

HTTP/1.1 200 OK
Server: XMLRPC++ 0.7
Content-Type: text/xml
Content-length: 293

<?xml version="1.0"?>
<methodResponse><params><param>
<value><array><data><value><i4>1</i4></value><value></value><value><array><data><value>TCPROS</value><value>contact</value><value><i4>50365</i4></value></data></array></value></data></array></value>
</param></params></methodResponse>

Note the machine name (contact in my case) and port number in there.

===

[3] This is a little tricky.  Read the format of ROS headers here:
   http://www.ros.org/wiki/ROS/Connection%20Header
Here's the minimum I got away with sending:
   + A 4 byte integer in little-endian format, with the length of all 
the following:
     + A 4 byte integer in little-endian format, with the length of the 
following character sequence:
     + The character sequence (without quotes) "callerid=/fake/fake/fake"
     + A 4 byte integer in little-endian format, with the length of the 
following character sequence:
     + The character sequence (without quotes) "md5sum=*"
     + A 4 byte integer in little-endian format, with the length of the 
following character sequence:
     + The character sequence (without quotes) "topic=/chatter"
You should then get back a header in the same format, followed by a 
stream of data (4-byte length, payload, 4-byte length, payload, ...).  
For talker, the payload is a 4-byte length followed by a character 
sequence of that length.  See:
   http://www.ros.org/wiki/msg
You can find examples of code for reading/writing ROS headers either here:
   
https://code.ros.org/trac/ros/browser/stacks/ros/trunk/core/roscpp/src/libros/header.cpp?rev=9624
or here (completely unofficial):
   
http://yarp0.svn.sourceforge.net/viewvc/yarp0/trunk/yarp2/src/carriers/tcpros_carrier/RosHeader.cpp?view=markup


On 06/18/2010 06:20 PM, Josh Faust wrote:
> ROS is a protocol built on top of XMLRPC and transport layers which 
> currently use either TCP or UDP.  If you wanted to reimplement the 
> topic portion of roscpp you could, but it's a lot more than just 
> creating a socket connection.
>
> Josh
>
> 2010/6/17 <ros_user at yahoo.co.jp <mailto:ros_user at yahoo.co.jp>>
>
>     Hello all,
>
>     I am new comer in ROS.
>
>     I just finished the tutorial and made Publisher and Subscriber node.
>
>     Here is a question.
>
>     Can I subscribe messages from normal C++ code without ROS?
>     For instance, I want to subscribe "chatter" topic in the tutorial
>     with normal socket connection (without ROS subscribe method).
>
>     If possible, how can I do it?
>
>     Any information is welcome.
>
>     Thanks in advance.
>
>     Keisuke
>
>     ------------------------------------------------------------------------
>     2010 FIFA World Cup News [Yahoo!Sports/sportsnavi]
>     <http://pr.mail.yahoo.co.jp/southafrica2010/>
>
>     _______________________________________________
>     ros-users mailing list
>     ros-users at code.ros.org <mailto:ros-users at code.ros.org>
>     https://code.ros.org/mailman/listinfo/ros-users
>
>
>
> _______________________________________________
> ros-users mailing list
> ros-users at code.ros.org
> https://code.ros.org/mailman/listinfo/ros-users
>    




More information about the ros-users mailing list