Skip to content

Commit a65edc5

Browse files
ivanpaunojacobperron
authored andcommitted
Initialize parameter services based on node options (osrf#46)
Signed-off-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
1 parent d6523f3 commit a65edc5

File tree

8 files changed

+98
-38
lines changed

8 files changed

+98
-38
lines changed

rcljava/src/main/java/org/ros2/rcljava/RCLJava.java

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import org.ros2.rcljava.timer.Timer;
4444

4545
/**
46-
* Entry point for the ROS2 Java API, similar to the rclcpp API.
46+
* Entry point for the ROS 2 Java API, similar to the rclcpp API.
4747
*/
4848
public final class RCLJava {
4949
private static final Logger logger = LoggerFactory.getLogger(RCLJava.class);
@@ -132,7 +132,7 @@ public static boolean isInitialized() {
132132

133133
/**
134134
* Initialize the RCLJava API. If successful, a valid RMW implementation will
135-
* be loaded and accessible, enabling the creating of ROS2 entities
135+
* be loaded and accessible, enabling the creating of ROS 2 entities
136136
* (@{link Node}s, @{link Publisher}s and @{link Subscription}s.
137137
* This also initializes the default context.
138138
*/
@@ -163,18 +163,18 @@ public static synchronized void rclJavaInit(String args[]) {
163163
private static native long nativeCreateContextHandle();
164164

165165
/**
166-
* Create a ROS2 node (rcl_node_t) and return a pointer to it as an integer.
166+
* Create a ROS 2 node (rcl_node_t) and return a pointer to it as an integer.
167167
*
168-
* @param nodeName The name that will identify this node in a ROS2 graph.
168+
* @param nodeName The name that will identify this node in a ROS 2 graph.
169169
* @param namespace The namespace of the node.
170170
* @param contextHandle Pointer to a context (rcl_context_t) with which to associated the node.
171-
* @return A pointer to the underlying ROS2 node structure.
171+
* @return A pointer to the underlying ROS 2 node structure.
172172
*/
173173
private static native long nativeCreateNodeHandle(String nodeName, String namespace, long contextHandle, ArrayList<String> arguments, boolean useGlobalArguments, boolean enableRosout);
174174

175175
/**
176176
* @return The identifier of the currently active RMW implementation via the
177-
* native ROS2 API.
177+
* native ROS 2 API.
178178
*/
179179
private static native String nativeGetRMWIdentifier();
180180

@@ -186,7 +186,7 @@ public static String getRMWIdentifier() {
186186
}
187187

188188
/**
189-
* Call the underlying ROS2 rcl mechanism to check if ROS2 has been shut
189+
* Call the underlying ROS 2 rcl mechanism to check if ROS 2 has been shut
190190
* down.
191191
*
192192
* @return true if RCLJava hasn't been shut down, false otherwise.
@@ -222,29 +222,50 @@ public static Context createContext() {
222222
/**
223223
* Create a @{link Node}.
224224
*
225-
* @param nodeName The name that will identify this node in a ROS2 graph.
226-
* @return A @{link Node} that represents the underlying ROS2 node
227-
* structure.
225+
* @param nodeName The name that will identify this node in a ROS 2 graph.
226+
* @return A @{link Node} that represents the underlying ROS 2 node structure.
228227
*/
229228
public static Node createNode(final String nodeName) {
230-
return createNode(nodeName, "", RCLJava.getDefaultContext(), new NodeOptions());
229+
return createNode(nodeName, "", new NodeOptions());
231230
}
232231

233232
/**
234233
* Create a @{link Node}.
235234
*
236-
* @param nodeName The name that will identify this node in a ROS2 graph.
235+
* @param nodeName The name that will identify this node in a ROS 2 graph.
237236
* @param namespace The namespace of the node.
238-
* @return A @{link Node} that represents the underlying ROS2 node
239-
* structure.
237+
* @return A @{link Node} that represents the underlying ROS 2 node structure.
240238
*/
239+
public static Node createNode(final String nodeName, final String namespace) {
240+
return createNode(nodeName, namespace, new NodeOptions());
241+
}
242+
243+
/**
244+
* Create a @{link Node}.
245+
*
246+
* @deprecated Use `RCLJava.createNode(nodeName, namespace, new NodeOptions.setContext(context))` instead.
247+
* @param nodeName The name that will identify this node in a ROS 2 graph.
248+
* @param namespace The namespace of the node.
249+
* @param context Context used for creating the node, @link{RCLJava.getDefaultContext()} will be used if `null`.
250+
* @return A @{link Node} that represents the underlying ROS 2 node structure.
251+
*/
252+
@Deprecated
241253
public static Node createNode(final String nodeName, final String namespace, final Context context) {
242-
return createNode(nodeName, namespace, context, new NodeOptions());
254+
return createNode(nodeName, namespace, new NodeOptions().setContext(context));
243255
}
244256

245-
public static Node createNode(final String nodeName, final String namespace, final Context context, final NodeOptions options) {
257+
/**
258+
* Create a @{link Node}.
259+
*
260+
* @param nodeName The name that will identify this node in a ROS 2 graph.
261+
* @param namespace The namespace of the node.
262+
* @param options Additional options to customize the Node creation. See @link{org.ros2.rcljava.node.NodeOptions}.
263+
* @return A @{link Node} that represents the underlying ROS 2 node structure.
264+
*/
265+
public static Node createNode(final String nodeName, final String namespace, final NodeOptions options) {
266+
Context context = options.getContext() == null ? RCLJava.getDefaultContext() : options.getContext();
246267
long nodeHandle = nativeCreateNodeHandle(nodeName, namespace, context.getHandle(), options.getCliArgs(), options.getUseGlobalArguments(), options.getEnableRosout());
247-
Node node = new NodeImpl(nodeHandle, context, options.getAllowUndeclaredParameters());
268+
Node node = new NodeImpl(nodeHandle, options);
248269
nodes.add(node);
249270
return node;
250271
}

rcljava/src/main/java/org/ros2/rcljava/node/NodeImpl.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,16 @@
2929
import org.ros2.rcljava.interfaces.Disposable;
3030
import org.ros2.rcljava.interfaces.MessageDefinition;
3131
import org.ros2.rcljava.interfaces.ServiceDefinition;
32+
import org.ros2.rcljava.node.NodeOptions;
3233
import org.ros2.rcljava.parameters.InvalidParametersException;
3334
import org.ros2.rcljava.parameters.InvalidParameterValueException;
3435
import org.ros2.rcljava.parameters.ParameterAlreadyDeclaredException;
3536
import org.ros2.rcljava.parameters.ParameterCallback;
3637
import org.ros2.rcljava.parameters.ParameterNotDeclaredException;
3738
import org.ros2.rcljava.parameters.ParameterType;
3839
import org.ros2.rcljava.parameters.ParameterVariant;
40+
import org.ros2.rcljava.parameters.service.ParameterService;
41+
import org.ros2.rcljava.parameters.service.ParameterServiceImpl;
3942
import org.ros2.rcljava.publisher.Publisher;
4043
import org.ros2.rcljava.publisher.PublisherImpl;
4144
import org.ros2.rcljava.qos.QoSProfile;
@@ -145,29 +148,44 @@ class ParameterAndDescriptor {
145148
private Object parameterCallbacksMutex;
146149
private List<ParameterCallback> parameterCallbacks;
147150

151+
private final ParameterService parameterService;
152+
148153
/**
149154
* Constructor.
150155
*
151156
* @param handle A pointer to the underlying ROS2 node structure. Must not
152157
* be zero.
153158
*/
154-
public NodeImpl(final long handle, final Context context, final boolean allowUndeclaredParameters) {
159+
public NodeImpl(final long handle, final NodeOptions nodeOptions) {
155160
this.handle = handle;
156-
this.context = context;
161+
this.context = nodeOptions.getContext() == null ?
162+
RCLJava.getDefaultContext() : nodeOptions.getContext();
157163
this.publishers = new LinkedBlockingQueue<Publisher>();
158164
this.subscriptions = new LinkedBlockingQueue<Subscription>();
159165
this.services = new LinkedBlockingQueue<Service>();
160166
this.clients = new LinkedBlockingQueue<Client>();
161167
this.timers = new LinkedBlockingQueue<Timer>();
162168
this.parametersMutex = new Object();
163169
this.parameters = new ConcurrentHashMap<String, ParameterAndDescriptor>();
164-
this.allowUndeclaredParameters = allowUndeclaredParameters;
170+
this.allowUndeclaredParameters = nodeOptions.getAllowUndeclaredParameters();
165171
this.parameterCallbacksMutex = new Object();
166172
this.parameterCallbacks = new ArrayList<ParameterCallback>();
167173
this.clock = new Clock(ClockType.ROS_TIME);
168174
this.wall_clock = new Clock(ClockType.STEADY_TIME);
169175
this.timeSource = new TimeSource(this);
170176
this.timeSource.attachClock(this.clock);
177+
try {
178+
this.parameterService = nodeOptions.getStartParameterServices() ?
179+
new ParameterServiceImpl(this) : null;
180+
// TODO(ivanpauno): Modify createService, createClient so they don't declare
181+
// NoSuchFieldException and IllegalAccessException checked exceptions.
182+
// That only happens if the user passed the wrong Class object, and the exception should
183+
// be rethrown as an unchecked IllegalArgumentException.
184+
} catch (NoSuchFieldException ex) {
185+
throw new IllegalArgumentException(ex.getMessage());
186+
} catch (IllegalAccessException ex) {
187+
throw new IllegalArgumentException(ex.getMessage());
188+
}
171189
}
172190

173191
/**

rcljava/src/main/java/org/ros2/rcljava/node/NodeOptions.java

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,15 @@
1717

1818
import java.util.ArrayList;
1919

20+
import org.ros2.rcljava.contexts.Context;
21+
2022
public class NodeOptions {
21-
private boolean useGlobalArguments;
22-
private boolean enableRosout;
23-
private boolean allowUndeclaredParameters;
24-
private ArrayList<String> cliArgs;
25-
26-
public NodeOptions() {
27-
this.useGlobalArguments = true;
28-
this.enableRosout = true;
29-
this.allowUndeclaredParameters = false;
30-
this.cliArgs = new ArrayList<String>();
31-
}
23+
private boolean useGlobalArguments = true;
24+
private boolean enableRosout = true;
25+
private boolean allowUndeclaredParameters = false;
26+
private boolean startParameterServices = true;
27+
private Context context = null;
28+
private ArrayList<String> cliArgs = new ArrayList<String>();
3229

3330
public final boolean getUseGlobalArguments() {
3431
return this.useGlobalArguments;
@@ -57,6 +54,24 @@ public NodeOptions setAllowUndeclaredParameters(boolean allow) {
5754
return this;
5855
}
5956

57+
public final boolean getStartParameterServices() {
58+
return this.startParameterServices;
59+
}
60+
61+
public NodeOptions setStartParameterServices(boolean startParameterServices) {
62+
this.startParameterServices = startParameterServices;
63+
return this;
64+
}
65+
66+
public final Context getContext() {
67+
return this.context;
68+
}
69+
70+
public NodeOptions setContext(Context context) {
71+
this.context = context;
72+
return this;
73+
}
74+
6075
public final ArrayList<String> getCliArgs() {
6176
return this.cliArgs;
6277
}

rcljava/src/main/java/org/ros2/rcljava/parameters/service/ParameterService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@
1515

1616
package org.ros2.rcljava.parameters.service;
1717

18-
public interface ParameterService {}
18+
public interface ParameterService {}

rcljava/src/main/java/org/ros2/rcljava/parameters/service/ParameterServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,4 @@ public void accept(RMWRequestId rmwRequestId,
149149
public ParameterServiceImpl(final Node node) throws NoSuchFieldException, IllegalAccessException {
150150
this(node, QoSProfile.PARAMETERS);
151151
}
152-
}
152+
}

rcljava/src/test/java/org/ros2/rcljava/node/NodeOptionsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static void tearDownOnce() {
5858
public final void testCreateNodeWithArgs() {
5959
NodeOptions options = new NodeOptions();
6060
options.setCliArgs(new ArrayList<String>(Arrays.asList("--ros-args", "-r", "__ns:=/foo")));
61-
Node node = RCLJava.createNode("test_node", "", RCLJava.getDefaultContext(), options);
61+
Node node = RCLJava.createNode("test_node", "", options);
6262
assertEquals("test_node", node.getName());
6363
assertEquals("/foo", node.getNamespace());
6464

rcljava/src/test/java/org/ros2/rcljava/node/NodeTest.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.ros2.rcljava.graph.NameAndTypes;
5252
import org.ros2.rcljava.graph.NodeNameInfo;
5353
import org.ros2.rcljava.node.Node;
54+
import org.ros2.rcljava.node.NodeOptions;
5455
import org.ros2.rcljava.publisher.Publisher;
5556
import org.ros2.rcljava.qos.policies.Reliability;
5657
import org.ros2.rcljava.qos.QoSProfile;
@@ -136,7 +137,8 @@ public final void accept(final T msg) {
136137

137138
@Before
138139
public void setUp() {
139-
node = RCLJava.createNode("test_node");
140+
node = RCLJava.createNode(
141+
"test_node", "/", new NodeOptions().setStartParameterServices(false));
140142

141143
primitives1 = new rcljava.msg.Primitives();
142144
primitives2 = new rcljava.msg.Primitives();
@@ -1369,7 +1371,9 @@ public void accept(final Collection<NameAndTypes> local, Collection<NameAndTypes
13691371

13701372
@Test
13711373
public final void testGetServiceNamesAndTypesByNode() throws Exception {
1372-
final Node remoteNode = RCLJava.createNode("test_get_service_names_and_types_remote_node");
1374+
final Node remoteNode = RCLJava.createNode(
1375+
"test_get_service_names_and_types_remote_node", "/",
1376+
new NodeOptions().setStartParameterServices(false));
13731377
Service<rcljava.srv.AddTwoInts> service1 = node.<rcljava.srv.AddTwoInts>createService(
13741378
rcljava.srv.AddTwoInts.class, "test_get_service_names_and_types_one",
13751379
new TriConsumer<
@@ -1487,7 +1491,9 @@ public void accept(final Collection<NameAndTypes> local, Collection<NameAndTypes
14871491

14881492
@Test
14891493
public final void testGetClientNamesAndTypesByNode() throws Exception {
1490-
final Node remoteNode = RCLJava.createNode("test_get_client_names_and_types_remote_node");
1494+
final Node remoteNode = RCLJava.createNode(
1495+
"test_get_client_names_and_types_remote_node", "/",
1496+
new NodeOptions().setStartParameterServices(false));
14911497
Client<rcljava.srv.AddTwoInts> client1 = node.<rcljava.srv.AddTwoInts>createClient(
14921498
rcljava.srv.AddTwoInts.class, "test_get_client_names_and_types_one");
14931499
Client<rcljava.srv.AddTwoInts> client2 = node.<rcljava.srv.AddTwoInts>createClient(

rcljava/src/test/java/org/ros2/rcljava/node/NodeUndeclaredParametersTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static void tearDownOnce() {
6767
public void setUp() {
6868
NodeOptions options = new NodeOptions();
6969
options.setAllowUndeclaredParameters(true);
70-
node = RCLJava.createNode("test_node", "", RCLJava.getDefaultContext(), options);
70+
node = RCLJava.createNode("test_node", "", options);
7171
}
7272

7373
@After

0 commit comments

Comments
 (0)