Creating nodes: Messages | Publishers and subscribers | Services | Parameters | Logging | Exceptions | Running nodes | Building your package with Ant and rosmake | manifest.xml | ros.properties | Developing your project in Eclipse | Integrating test results from JUnit | rosjava-related packages

If you've read Creating nodes, then you know that Nodes start running as soon as they're created. That design is in part to discourage developers (like you) from creating bare Nodes everywhere. Instead, you should organize your system into units of NodeMains and run them using a NodeRunner.

NodeMain

Let's start with an example.

   1 public class Talker implements NodeMain {
   2 
   3   private Node node;
   4 
   5   @Override
   6   public void main(NodeConfiguration nodeConfiguration) {
   7     node = new DefaultNodeFactory().newNode(
   8         "talker", nodeConfiguration);
   9     Publisher<org.ros.message.std_msgs.String> publisher =
  10         node.newPublisher("chatter", "std_msgs/String");
  11     while (true) {
  12       org.ros.message.std_msgs.String str =
  13           new org.ros.message.std_msgs.String();
  14       str.data = "Hello world!";
  15       publisher.publish(str);
  16       Thread.sleep(1000);
  17     }
  18   }
  19 
  20   @Override
  21   public void shutdown() {
  22     node.shutdown();
  23     node = null;
  24   }
  25 }

There's a lot in there, but we'll take it step by step.

First, let's look at the interface.

   1 public class Talker implements NodeMain {
   2   @Override
   3   public void main(NodeConfiguration nodeConfiguration) {
   4     ...
   5   }
   6 
   7   @Override
   8   public void shutdown() {
   9     ...
  10   }
  11 }

NodeMains are relatively simple. They provide two methods that should be overridden. First, the main(NodeConfiguration) define the entry and exit points for your NodeMain.

Startup

Inside main is where you should configure and start a node and start performing your business logic. For example, in main you could create publishers, subscribers, etc. and begin continuously publishing or consuming messages.

   1 node = new DefaultNodeFactory().newNode(
   2     "talker", nodeConfiguration);
   3 Publisher<org.ros.message.std_msgs.String> publisher =
   4     node.newPublisher("chatter", "std_msgs/String");
   5 while (true) {
   6   org.ros.message.std_msgs.String str =
   7       new org.ros.message.std_msgs.String();
   8   str.data = "Hello world!";
   9   publisher.publish(str);
  10   Thread.sleep(1000);
  11 }

In this example, we created a Node, then a simple Publisher, and then we started continuously publishing "Hello world!" at 1 Hz.

Shutdown

In shutdown is where you should clean up any resources you've acquired and where you should shutdown any Nodes you've started.

   1 node.shutdown();
   2 node = null;

NodeRunner

Once you've created a NodeMain, you can execute it with a NodeRunner.

   1 public class MyRobot {
   2   public static void main(String[] args) {
   3     NodeMain nodeMain;
   4     NodeConfiguration nodeConfiguration;
   5 
   6     ...
   7 
   8     NodeRunner nodeRunner = DefaultNodeRunner.newDefault();
   9     nodeRunner.run(nodeMain, nodeConfiguration);
  10 
  11     ...
  12 
  13     nodeRunner.shutdown();
  14   }
  15 }

The DefaultNodeRunner runs your NodeMain in a thread pool. Calling shutdown on the NodeRunner will shutdown all NodeMains that were started using that NodeRunner.

Wiki: rosjava/Overview/NodeMains (last edited 2011-09-30 14:44:12 by DamonKohler)