Ask Your Question
3

rosbridge JSON format for std_msgs/String error

asked 2012-02-15 01:00:51 -0600

Scott gravatar image

updated 2018-09-24 12:10:37 -0600

130s gravatar image

Hi, I am attempting to use rosbridge to publish a string message to a topic. My code is below, but this is the line that tries to do the publishing.

connection.publish('/recognizer/output', 'std_msgs/String', '{"Hello World"}');

I am able to make my connection to rosbridge and I can even listen to topics, it just appears my formatting for the String message publishing is not correct. This should be easy for anyone to reproduce, just start roscore, start rosbridge, copy my code into an html page (see code below) and open in google chrome.

The error I get is as follows. Any help would be greatly appreciated. It seems to argue that it needs a : delimiter, but I have tried putting one in and it is still not happy either. -Scott

The rosbridge/json format error
GET / HTTP/1.1
Host: 127.0.0.1:9090
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive, Upgrade
Sec-WebSocket-Version: 8
Sec-WebSocket-Origin: null
Sec-WebSocket-Extensions: deflate-stream
Sec-WebSocket-Key: UzHkStz0wbNSaL5vwnRaoQ==
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

------
draft-ietf-hybi-thewebsocketprotocol-06 (preliminary, _may_ be deprecated)
closed 9
Connection from 127.0.0.1:52592
2 concurrent connections.

------
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:9090
Origin: null
Sec-WebSocket-Key: PGcwCtYx88PudrPTfk4L3g==
Sec-WebSocket-Version: 13

------
draft-ietf-hybi-thewebsocketprotocol-06 (preliminary, _may_ be deprecated)
Problem Problem Problem Problem Problem Problem Problem Problem Problem Problem 
Traceback (most recent call last):
  File "/home/wilson/ros_packages/rosbridge/bin/rosbridge.py", line 39, in handleFrameHelper
    call = json.loads(frame)
  File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 360, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 376, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting : delimiter: line 1 column 53 (char 53)
Problem Problem Problem Problem Problem Problem Problem Problem Problem Problem

Here is my code

<html>
  <head>
    <script type="text/javascript" src="http://brown-ros-pkg.googlecode.com/svn/tags/brown-ros-pkg/rosbridge/ros.js"></script>
    <script type="text/javascript">
      function main() {

      var connection = new ros.Connection("ws://127.0.0.1:9090");
      connection.setOnClose(function (e) {
      document.write('connection closed<br/>');
      });
      connection.setOnError(function (e) {
      document.write('error!<br/>');
      });
      connection.setOnOpen(function (e) {
      document.write('connected to ROS<br/>');
      document.write('attempting to send message over socket connection.');
      connection.publish('/recognizer/output', 'std_msgs/String', '{"Hello World"}');
      });
      }
    </script>
  </head>
  <body onload="main()">
  </body>
</html>
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
2

answered 2012-02-15 07:37:18 -0600

Pi Robot gravatar image

Hi @Scott,

I think I found the problem. The ROS std_msgs/String message type requires a "data" keyword before the actual string. I just tried modifying your HTML code with the following form of the publish command and it worked for me under ROS Electric:

  connection.publish('/recognizer/output', 'std_msgs/String', '{"data":' + '"Hello World"' + '}');

--patrick

edit flag offensive delete link more

Comments

Thanks Patrick, that did the trick. In addition I have updated my code to include buttons that can also send messages over a published topic. Not sure it is optimal, as I had to create a second connection object. But it works pretty nicely. Below is the code as reference for others.

Scott gravatar imageScott ( 2012-02-15 12:06:09 -0600 )edit

-- '"{\"key\": true}"' also works.

Mr-Yellow gravatar imageMr-Yellow ( 2015-07-18 19:45:51 -0600 )edit
0

answered 2012-02-15 12:07:26 -0600

Scott gravatar image

updated 2018-09-24 12:11:33 -0600

130s gravatar image

<html> <head> <script type="text/javascript" src="http://brown-ros-pkg.googlecode.com/svn/tags/brown-ros-pkg/rosbridge/ros.js"></script> <script type="text/javascript"> function nop() {} /* console for logging */ var console = null;

function pub()
{
    var connection2 = new ros.Connection("ws://127.0.0.1:9090");
    connection2.setOnOpen(function (e) {
        log('connected to ros for 2nd time');
        log('attempting to send message over 2nd socket connection.');
    connection2.publish('/recognizer/output', 'std_msgs/String', '{"data":' + '"On Pub Button Click Message"' + '}');

    });
}

function displayDate()
{
    document.getElementById("demo").innerHTML=Date();
var connection3 = new ros.Connection("ws://127.0.0.1:9090");
connection3.setOnOpen(function (e) {
    log('connected to ros for 3rd time');
    log('attempting to send message over 3rd socket connection.');
connection3.publish('/recognizer/output', 'std_msgs/String', '{"data":' + '"On Display Date Button"' + '}');

});
}

function log(msg) {
    console.innerHTML = console.innerHTML + msg + "<br/>";
}
function init() {
    function waitForDOM() {
        var cnsl = document.getElementById('console');
        if (cnsl == null) {
            setTimeout(waitForDOM, 100);
        } else {
            console = cnsl;
            setTimeout(main, 0);
        }
    }
    setTimeout(waitForDOM, 100);
}

function main() {
    log('console initialized');
    var connectInfo = document.location.toString();

    log('creating ROSProxy connection object...');
    var connection = null;
    try {
        connection = new ros.Connection("ws://127.0.0.1:9090");
    } catch (err) {
        log('Problem creating proxy connection object!');
        return;
    }
    log('connection created');

    connection.setOnClose(function (e) {
        log('connection closed');
    });
    connection.setOnError(function (e) {
        log('network error!');
    });
    connection.setOnOpen(function (e) {
        log('connected');
        log('initializing ROSProxy...');
        try {
            connection.callService('/rosjs/topics', '[]', nop);
        } catch (error) {
            log('Problem initializing ROSProxy!');
            return;
        }
        log('initialized');       
        log('running');  
        log('trying to publish a message');
        connection.publish('/recognizer/output', 'std_msgs/String', '{"data":' + '"On Page Load Message"' + '}');
    });
}
    </script>
  </head>
<body onload="init()">
<div id="console"></div>
<h1>Rosbridge Test Page</h1>

    <p id="demo">This page shows how to publish messages with json over rosbridge on page load and on button click event</p>


<button type="button" onclick="displayDate()">Display Date</button>
<button type="button" onclick="pub()">Publish String Message</button> </body> </html>
edit flag offensive delete link more

Comments

Connection number is pretty much a stylistic issue (though there is overhead to connection creation). However, if you want an example of using a single connection, I've put a version of your test page that does so here: http://pastebin.com/ND1LRiqT (this version relies on the console div existing).

tjay gravatar imagetjay ( 2012-02-20 08:43:59 -0600 )edit

@tjay, works great for me! Thanks.

Pi Robot gravatar imagePi Robot ( 2012-02-23 02:54:39 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2012-02-15 01:00:51 -0600

Seen: 3,217 times

Last updated: Sep 24 '18