ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

rosjava publishing to a topic based on user input (button)

asked 2017-10-13 08:41:48 -0600

agkhalil gravatar image

I have been playing around with rosjava now for a few days and it is great. I am able to connect my android phone to ros master over usb/wifi and have them publish/subscribe to one another.

What I am trying to do now is add a button on my android app, when the user hits it, the message being published changes. To clarify: I have a publisher node "talkernode" created that starts by publishing a String "Hello" message on a "/chatter" topic. When the user hits a button, I want the String message to change to something of my choice.

Below is the relevant portion of my code. The publishGo() method is my onClick callback function, where I am trying to add code to change the message being published. I have already tested that something happens when the button is hit and it works.

public class MainActivity extends RosActivity{
Button btn;

public MainActivity() {
    super("Example", "Example");

public void startMasterChooser() {
    URI uri;
    try {
        uri = new URI("");
    } catch (URISyntaxException e) {
        throw new RosRuntimeException(e);

    new AsyncTask<Void, Void, Void>() {
        protected Void doInBackground(Void... params) {
            return null;

protected void onCreate(Bundle savedInstanceState) {
    btn = (Button) findViewById(;

protected void init(NodeMainExecutor nodeMainExecutor) {
    Talker talkernode = new Talker(this);

    NodeConfiguration nodeConfiguration = NodeConfiguration.newPublic(

    nodeMainExecutor.execute(talkernode, nodeConfiguration);

protected void publishGo(View view) {
    // Code here

Below is the Talker class code. randomCommand is the string being published and the string I want to change when the button is clicked.

class Talker extends AbstractNodeMain {
private String randomCommand = "Hello";
Talker(MainActivity mainActivity) {


public GraphName getDefaultNodeName() {
    return GraphName.of("rosjava_tutorial_pubsub/talker");

public void onStart(final ConnectedNode connectedNode) {
    final Log log = connectedNode.getLog();
    final Publisher<std_msgs.String> publisher =
            connectedNode.newPublisher("chatter", std_msgs.String._TYPE);
    // This CancellableLoop will be canceled automatically when the node shuts
    // down.
    connectedNode.executeCancellableLoop(new CancellableLoop() {
        protected void setup() {

        protected void loop() throws InterruptedException {
            std_msgs.String str = publisher.newMessage();
  "I publish: \"" + randomCommand + "\"");


I apologize if this is an easy question or if it has been answered before, but any help would be immensely appreciated.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2017-10-13 15:05:48 -0600

jubeira gravatar image

updated 2017-10-13 15:06:36 -0600

@agkhalil what you need in this case is a publisher "on demand".

First of all, save the publisher object in a member variable in the node in the onStart method, so that you can use it later. You have to do this in onStart because the ConnectedNode provides you the publisher.

class Talker extends AbstractNodeMain {
Publisher<std_msgs.String> publisher;

public void onStart(final ConnectedNode connectedNode) {
    publisher = connectedNode.newPublisher("chatter", std_msgs.String._TYPE);

Second, add a publish method to your node that you can call whenever you want:

// Note that you shouldn't call this before onStart is called; 
// check that publisher is not null before using it!
public void publish(String message) {
    std_msgs.String toPublish = publisher.newMessage();

Then, just store your Talker node somewhere you can access from the callback button, and call publish from there. That should cover your use case. Remember that there is a period of time between the moment you create the node and the moment onStart is called; that's why you should be careful with the state of publisher member variable.

Bonus: Note that you can also make your publisher latched; if you do so, the publisher will publish the message to each new subscriber and you won't need to do anything else. To do so, after creating the publisher, do publisher.setLatchMode(true).

Hope it helps!

edit flag offensive delete link more


Thanks a bunch man! It works!

agkhalil gravatar image agkhalil  ( 2017-10-13 19:48:27 -0600 )edit

Question Tools



Asked: 2017-10-13 08:41:48 -0600

Seen: 1,054 times

Last updated: Oct 13 '17