Skip to content

Commit d557b60

Browse files
committed
Initialize parameter services based on node options (#46)
Signed-off-by: Ivan Santiago Paunovic <[email protected]>
1 parent c7c3c2c commit d557b60

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
@@ -28,13 +28,16 @@
2828
import org.ros2.rcljava.graph.NameAndTypes;
2929
import org.ros2.rcljava.interfaces.MessageDefinition;
3030
import org.ros2.rcljava.interfaces.ServiceDefinition;
31+
import org.ros2.rcljava.node.NodeOptions;
3132
import org.ros2.rcljava.parameters.InvalidParametersException;
3233
import org.ros2.rcljava.parameters.InvalidParameterValueException;
3334
import org.ros2.rcljava.parameters.ParameterAlreadyDeclaredException;
3435
import org.ros2.rcljava.parameters.ParameterCallback;
3536
import org.ros2.rcljava.parameters.ParameterNotDeclaredException;
3637
import org.ros2.rcljava.parameters.ParameterType;
3738
import org.ros2.rcljava.parameters.ParameterVariant;
39+
import org.ros2.rcljava.parameters.service.ParameterService;
40+
import org.ros2.rcljava.parameters.service.ParameterServiceImpl;
3841
import org.ros2.rcljava.publisher.Publisher;
3942
import org.ros2.rcljava.publisher.PublisherImpl;
4043
import org.ros2.rcljava.qos.QoSProfile;
@@ -144,29 +147,44 @@ class ParameterAndDescriptor {
144147
private Object parameterCallbacksMutex;
145148
private List<ParameterCallback> parameterCallbacks;
146149

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

172190
/**

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
@@ -46,7 +46,7 @@ public static void tearDownOnce() {
4646
public final void testCreateNodeWithArgs() {
4747
NodeOptions options = new NodeOptions();
4848
options.setCliArgs(new ArrayList<String>(Arrays.asList("--ros-args", "-r", "__ns:=/foo")));
49-
Node node = RCLJava.createNode("test_node", "", RCLJava.getDefaultContext(), options);
49+
Node node = RCLJava.createNode("test_node", "", options);
5050
assertEquals("test_node", node.getName());
5151
assertEquals("/foo", node.getNamespace());
5252

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;
@@ -125,7 +126,8 @@ public final void accept(final T msg) {
125126

126127
@Before
127128
public void setUp() {
128-
node = RCLJava.createNode("test_node");
129+
node = RCLJava.createNode(
130+
"test_node", "/", new NodeOptions().setStartParameterServices(false));
129131

130132
primitives1 = new rcljava.msg.Primitives();
131133
primitives2 = new rcljava.msg.Primitives();
@@ -1358,7 +1360,9 @@ public void accept(final Collection<NameAndTypes> local, Collection<NameAndTypes
13581360

13591361
@Test
13601362
public final void testGetServiceNamesAndTypesByNode() throws Exception {
1361-
final Node remoteNode = RCLJava.createNode("test_get_service_names_and_types_remote_node");
1363+
final Node remoteNode = RCLJava.createNode(
1364+
"test_get_service_names_and_types_remote_node", "/",
1365+
new NodeOptions().setStartParameterServices(false));
13621366
Service<rcljava.srv.AddTwoInts> service1 = node.<rcljava.srv.AddTwoInts>createService(
13631367
rcljava.srv.AddTwoInts.class, "test_get_service_names_and_types_one",
13641368
new TriConsumer<
@@ -1476,7 +1480,9 @@ public void accept(final Collection<NameAndTypes> local, Collection<NameAndTypes
14761480

14771481
@Test
14781482
public final void testGetClientNamesAndTypesByNode() throws Exception {
1479-
final Node remoteNode = RCLJava.createNode("test_get_client_names_and_types_remote_node");
1483+
final Node remoteNode = RCLJava.createNode(
1484+
"test_get_client_names_and_types_remote_node", "/",
1485+
new NodeOptions().setStartParameterServices(false));
14801486
Client<rcljava.srv.AddTwoInts> client1 = node.<rcljava.srv.AddTwoInts>createClient(
14811487
rcljava.srv.AddTwoInts.class, "test_get_client_names_and_types_one");
14821488
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
@@ -55,7 +55,7 @@ public static void tearDownOnce() {
5555
public void setUp() {
5656
NodeOptions options = new NodeOptions();
5757
options.setAllowUndeclaredParameters(true);
58-
node = RCLJava.createNode("test_node", "", RCLJava.getDefaultContext(), options);
58+
node = RCLJava.createNode("test_node", "", options);
5959
}
6060

6161
@After

0 commit comments

Comments
 (0)