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

Revision history [back]

click to hide/show revision 1
initial version

After many hours of trying various things, I've finally managed to get something that works! The key was writing my own version of RosRun for my application, and then creating an instance of the custom RosRun in the java application that I want to use ROS from.

The code looks something like this:

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;

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

public class Run_PubSub {

  private Talker pubNodeMain;
  private Listener subNodeMain;

  public Run_PubSub() {
    // Set up the executor for both of the nodes
    NodeMainExecutor nodeMainExecutor = DefaultNodeMainExecutor.newDefault();

    // Load the publisher
    String[] pubArgv = { "Talker" };
    CommandLineLoader pubLoader = new CommandLineLoader(Lists.newArrayList(pubArgv));
    String nodeClassName = pubLoader.getNodeClassName();
    System.out.println("Loading node class: " + pubLoader.getNodeClassName());
    NodeConfiguration pubNodeConfiguration = pubLoader.build();

    try {
      pubNodeMain = (Talker)pubLoader.loadClass(nodeClassName);
    } catch (ClassNotFoundException e) {
      throw new RosRuntimeException("Unable to locate node: " + nodeClassName, e);
    } catch (InstantiationException e) {
      throw new RosRuntimeException("Unable to instantiate node: " + nodeClassName, e);
    } catch (IllegalAccessException e) {
      throw new RosRuntimeException("Unable to instantiate node: " + nodeClassName, e);
    }

    Preconditions.checkState(pubNodeMain != null);
    nodeMainExecutor.execute(pubNodeMain, pubNodeConfiguration);

    // Load the subscriber
    String[] subArgv = { "Listener" };
    CommandLineLoader subLoader = new CommandLineLoader(Lists.newArrayList(subArgv));
    nodeClassName = subLoader.getNodeClassName();
    System.out.println("Loading node class: " + subLoader.getNodeClassName());
    NodeConfiguration subNodeConfiguration = subLoader.build();

    try {
      subNodeMain = (Listener)subLoader.loadClass(nodeClassName);
    } catch (ClassNotFoundException e) {
      throw new RosRuntimeException("Unable to locate node: " + nodeClassName, e);
    } catch (InstantiationException e) {
      throw new RosRuntimeException("Unable to instantiate node: " + nodeClassName, e);
    } catch (IllegalAccessException e) {
      throw new RosRuntimeException("Unable to instantiate node: " + nodeClassName, e);
    }

    Preconditions.checkState(subNodeMain != null);
    nodeMainExecutor.execute(subNodeMain, subNodeConfiguration);
  }

  public void do_stuff() {
    subNodeMain.do_stuff();
    pubNodeMain.do_stuff();
  }
}

This can be compiled with javac, and you don't need to use gradle or catkin (as long as you set up your classpath properly). I found this super easy to integrate into my other projects, and hopefully it is helpful to others too. I based it off of this code