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

Where is the main function in Rosjava

asked 2014-03-20 16:36:49 -0600

Mehdi. gravatar image

updated 2016-10-24 09:03:24 -0600

ngrennan gravatar image

Hello,

rosjava is still very mysterious for me, maybe because I'm also not very familiar with java yet. I understand how the simple listener talker are working but the thing is that there is no main function like in C++ that will run the program and create all the instances. Now I have both classes talker.java and listener.java both have their onStart methods which implement a cancellable loop and keep sending/listening. Running them with rosrun is easy but My question is : who calls these functions onStart?? and what is this parameter : onStart(final ConnectedNode connectedNode) where does it come from. I'm asking this because I want to run such a code from eclipse but it keeps saying there is no main function defined.

This is the talker.java code:

package com.github.rosjava_catkin_package_a.my_pub_sub_tutorial;

import org.ros.concurrent.CancellableLoop;
import org.ros.namespace.GraphName;
import org.ros.node.AbstractNodeMain;
import org.ros.node.ConnectedNode;
import org.ros.node.NodeMain;
import org.ros.node.topic.Publisher;

/**
 * A simple {@link Publisher} {@link NodeMain}.
 */
public class Talker extends AbstractNodeMain {

  @Override
  public GraphName getDefaultNodeName() {
    return GraphName.of("rosjava/talker");
  }

  @Override
  public void onStart(final ConnectedNode connectedNode) {
    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() {
      private int sequenceNumber;

      @Override
      protected void setup() {
        sequenceNumber = 0;
      }

      @Override
      protected void loop() throws InterruptedException {
        std_msgs.String str = publisher.newMessage();
        str.setData("Hello world! " + sequenceNumber);
        publisher.publish(str);
        sequenceNumber++;
        Thread.sleep(1000);
      }
    });
  }
}

thanks

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2014-04-09 16:05:27 -0600

Daniel Stonier gravatar image

I did something similar - I was creating a library class, but wanted a static main so that I could test the script. Basically you can use RosRun which will run the onStart, but if you want to do more than just that, or run multiple onStart's, break that down as you need. I then used the gradle application plugin with the installApp target to create an easy to use script for me.

I didn't actually try to run from inside eclipse though, just from the command line.

The build.gradle:

dependencies {
  compile 'org.ros.rosjava_core:rosjava:[0.1,)'
  compile 'org.ros.rosjava_messages:rocon_std_msgs:[0.7,)'
  compile project(':rosjava_utils')
}

apply plugin:'application'
mainClassName = 'com.github.robotics_in_concert.rocon_rosjava_core.master_info.MasterInfo'

defaultTasks 'installApp', 'publishMavenJavaPublicationToMavenRepository'

The java class:

package com.github.robotics_in_concert.rocon_rosjava_core.master_info;

/*****************************************************************************
** Imports
*****************************************************************************/

import java.util.concurrent.TimeoutException;

import org.ros.namespace.GraphName;
import org.ros.node.AbstractNodeMain;
import org.ros.node.ConnectedNode;
import org.ros.node.DefaultNodeMainExecutor;
import org.ros.node.NodeConfiguration;
import org.ros.node.NodeMainExecutor;
import org.ros.exception.RosRuntimeException;
import org.ros.internal.loader.CommandLineLoader;

import com.github.robotics_in_concert.rocon_rosjava_core.rosjava_utils.ListenerException;
import com.github.robotics_in_concert.rocon_rosjava_core.rosjava_utils.ListenerNode;
import com.github.robotics_in_concert.rocon_rosjava_core.rosjava_utils.RosTopicInfo;
import com.google.common.collect.Lists;

/*****************************************************************************
** MasterInfo
*****************************************************************************/

public class MasterInfo extends AbstractNodeMain {

    private ListenerNode<rocon_std_msgs.MasterInfo> masterInfoListener;

    public MasterInfo() {
        this.masterInfoListener = new ListenerNode<rocon_std_msgs.MasterInfo>();
    }
    @Override
    public void onStart(final ConnectedNode connectedNode) {
        RosTopicInfo topicInformation = new RosTopicInfo(connectedNode);
        String topicName = topicInformation.findTopic("rocon_std_msgs/MasterInfo");
        this.masterInfoListener.connect(connectedNode, topicName, rocon_std_msgs.MasterInfo._TYPE);
    }

    /**
     * Wait for data to come in. This uses a default timeout
     * set by ListenerNode.
     * 
     * @see ListenerNode
     * @throws InteractionsException : if listener error, timeout or general runtime problem
     */
    public void waitForResponse() throws MasterInfoException {
        try {
            this.masterInfoListener.waitForResponse();
        } catch(ListenerException e) {
            throw new MasterInfoException(e.getMessage());
        } catch(TimeoutException e) {
            throw new MasterInfoException(e.getMessage());
        }
    }

    /****************************************
    ** Getters
    ****************************************/

    @Override
    public GraphName getDefaultNodeName() {
        return GraphName.of("rocon_rosjava_master_info");
    }

    public String getName() throws MasterInfoException {
        try {
            if (this.masterInfoListener.getMessage() == null) {
                masterInfoListener.waitForResponse();
            }
        } catch(ListenerException e) {
            throw new MasterInfoException(e.getMessage());
        } catch(TimeoutException e) {
            throw new MasterInfoException(e.getMessage());
        }
        return this.masterInfoListener.getMessage().getName();
    }

    public String getDescription() throws MasterInfoException {
        try {
            if (this.masterInfoListener.getMessage() == null) {
                masterInfoListener.waitForResponse();
            }
        } catch(ListenerException e) {
            throw new MasterInfoException(e.getMessage());
        } catch(TimeoutException e) {
            throw new MasterInfoException(e.getMessage());
        }
        return this.masterInfoListener.getMessage().getDescription();
    }

    public String getIconResourceName() throws MasterInfoException {
        try {
            if (this.masterInfoListener.getMessage() == null) {
                masterInfoListener.waitForResponse();
            }
        } catch(ListenerException e) {
            throw new MasterInfoException(e.getMessage());
        } catch(TimeoutException e) {
            throw new MasterInfoException(e.getMessage());
        }
        return this.masterInfoListener.getMessage().getIcon().getResourceName();
    }

    public String getIconFormat() throws MasterInfoException {
        try {
            if (this.masterInfoListener.getMessage() == null) {
                masterInfoListener.waitForResponse();
            }
        } catch(ListenerException e) {
            throw new MasterInfoException(e.getMessage());
        } catch(TimeoutException e) {
            throw new MasterInfoException(e.getMessage());
        }
        return this.masterInfoListener.getMessage().getIcon().getFormat();
    }

    public rocon_std_msgs.Icon getIcon() throws MasterInfoException {
        try {
            if (this.masterInfoListener.getMessage() == null) {
                masterInfoListener.waitForResponse();
            }
        } catch(ListenerException e) {
            throw new MasterInfoException(e.getMessage());
        } catch(TimeoutException e) {
            throw new MasterInfoException(e.getMessage());
        }
        return this.masterInfoListener.getMessage().getIcon();
    }

    /****************************************
    ** Main
    ****************************************/

    public static void main(String argv[]) throws java.io.IOException {
        // Pulling the internals of rosrun ...
(more)
edit flag offensive delete link more
0

answered 2014-03-26 15:59:40 -0600

Mehdi. gravatar image

Well as nobody answered I'm going to post the solution I found. The main code "node" running all the "nodelets" (like listener or talker) is called RosRun You can find it in RosRun.java. Talker and listener classes are the same as the one I posted on my question. You can find them in rosjava tutorials. To be able to use RosRun.java separately in eclipse I had to do some modifications and I also renamed my class in this case to rosjavaPubSub:

package rosjavaPubSub;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.ros.exception.RosRuntimeException;
import org.ros.internal.loader.CommandLineLoader;
import org.ros.node.DefaultNodeMainExecutor;
import org.ros.node.NodeConfiguration;
import org.ros.node.NodeMain;
import org.ros.node.NodeMainExecutor;
import java.net.URI;

// This class will run a publisher and subscriber, and relay data between them.

public class rosjavaPubSub {
 //Create instances for Talker and Listener
  private Talker pubNodeMain = new Talker();
  private Listener subNodeMain = new Listener();

  //Here everything is done in constructor but doesn't have to be done like that, you could do it directly in a main function to be able to run the code directly
  public rosjavaPubSub() {
    // Set up the executor for both of the nodes
    NodeMainExecutor nodeMainExecutor = DefaultNodeMainExecutor.newDefault();
   //This is because I work on a remote machine masteruri has the roscore machine IP and host is the local IP
    URI masteruri = URI.create("http://192.168.10.2:11311");
    String host = "192.168.10.3";


    // Load the publisher(talker)
    NodeConfiguration pubNodeConfiguration = NodeConfiguration.newPublic(host, masteruri);
    //Check if Talker class correctly instantiated
    Preconditions.checkState(pubNodeMain != null);
    //execute the nodelet talker (this will run the method onStart of Talker.java)
    nodeMainExecutor.execute(pubNodeMain, pubNodeConfiguration);


    // Load the subscriber(listener) same as for publisher
    NodeConfiguration subNodeConfiguration = NodeConfiguration.newPublic(host, masteruri);    
    Preconditions.checkState(subNodeMain != null);
    nodeMainExecutor.execute(subNodeMain, subNodeConfiguration);
  }
}
edit flag offensive delete link more

Comments

0

answered 2014-04-13 05:59:26 -0600

pico gravatar image

updated 2014-04-13 11:28:04 -0600

Thanks for this example; i have tried to run your main but i have this error:

Apr 13, 2014 2:40:16 PM org.ros.internal.node.client.Registrar <init>
INFO: MasterXmlRpcEndpoint URI: http:/localhost:11311
Apr 13, 2014 2:40:16 PM org.ros.internal.node.client.Registrar onPublisherAdded
INFO: Registering publisher: Publisher<PublisherDefinition<PublisherIdentifier<NodeIdentifier</rosjava/talker, http:/localhost:42089/>, TopicIdentifier</rosout>>, Topic<TopicIdentifier</rosout>, TopicDescription<rosgraph_msgs/Log, acffd30cd6b6de30f120938c17c593fb>>>>
Apr 13, 2014 2:40:16 PM org.ros.internal.node.client.Registrar callMaster
INFO: Response<Success, Registered [/rosjava/talker] as publisher of [/rosout], [http://ubuntu:42979/]>
Apr 13, 2014 2:40:16 PM org.ros.internal.node.topic.DefaultPublisher$1 onMasterRegistrationSuccess
INFO: Publisher registered: Publisher<PublisherDefinition<PublisherIdentifier<NodeIdentifier</rosjava/talker, http:/localhost:42089/>, TopicIdentifier</rosout>>, Topic<TopicIdentifier</rosout>, TopicDescription<rosgraph_msgs/Log, acffd30cd6b6de30f120938c17c593fb>>>>    
Apr 13, 2014 2:40:16 PM org.ros.internal.node.client.Registrar onPublisherAdded
INFO: Registering publisher: Publisher<PublisherDefinition<PublisherIdentifier<NodeIdentifier</rosjava/talker, http:/localhost:42089/>, TopicIdentifier</chatter>>, Topic<TopicIdentifier</chatter>, TopicDescription<std_msgs/String, 992ce8a1687cec8c8bd883ec73ca41d1>>>>
Apr 13, 2014 2:40:16 PM org.ros.internal.node.client.Registrar callMaster
INFO: Response<Success, Registered [/rosjava/talker] as publisher of [/chatter], []>
Apr 13, 2014 2:40:16 PM org.ros.internal.node.topic.DefaultPublisher$1 onMasterRegistrationSuccess
INFO: Publisher registered: Publisher<PublisherDefinition<PublisherIdentifier<NodeIdentifier</rosjava/talker, http:/localhost:42089/>, TopicIdentifier</chatter>>, Topic<TopicIdentifier</chatter>, TopicDescription<std_msgs/String, 992ce8a1687cec8c8bd883ec73ca41d1>>>>
Apr 13, 2014 2:40:16 PM org.apache.xmlrpc.server.XmlRpcStreamServer execute
SEVERE: execute: Error while performing request
org.apache.xmlrpc.server.XmlRpcNoSuchHandlerException: No such handler: requestTopic
at org.apache.xmlrpc.server.AbstractReflectiveHandlerMapping.getHandler(AbstractReflectiveHandlerMapping.java:195)
at org.apache.xmlrpc.server.XmlRpcServerWorker.execute(XmlRpcServerWorker.java:42)
at org.apache.xmlrpc.server.XmlRpcServer.execute(XmlRpcServer.java:83)
at org.apache.xmlrpc.server.XmlRpcStreamServer.execute(XmlRpcStreamServer.java:182)
at org.apache.xmlrpc.webserver.Connection.run(Connection.java:175)
at org.apache.xmlrpc.util.ThreadPool$MyThread.runTask(ThreadPool.java:71)
at org.apache.xmlrpc.util.ThreadPool$MyThread.run(ThreadPool.java:87)

My roscore is start and if i write on a new shell "rostopic list" i see my topic (chatter); i have this error after few moments i run my main. The talker is created but it publish nothing. Do you have any idea whi I have this error?

Thanks

edit flag offensive delete link more

Comments

Can you please edit your answer and put the code into a code box? I can barely read it. Did you start Roscore?

Mehdi. gravatar image Mehdi.  ( 2014-04-13 06:19:20 -0600 )edit

done, thanks. if you see http:/ instead of http:// don't worry, i couldn't edit the post if i wrote http://

pico gravatar image pico  ( 2014-04-13 11:30:57 -0600 )edit

Question Tools

Stats

Asked: 2014-03-20 16:36:49 -0600

Seen: 1,841 times

Last updated: Apr 13 '14