Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions rcljava/src/main/java/org/ros2/rcljava/client/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
import org.ros2.rcljava.service.RMWRequestId;

public interface Client<T extends ServiceDefinition> extends Disposable {
<U extends MessageDefinition> Class<U> getRequestType();

<U extends MessageDefinition> Class<U> getResponseType();
ServiceDefinition getServiceDefinition();

<U extends MessageDefinition> void handleResponse(RMWRequestId header, U response);

Expand Down
29 changes: 13 additions & 16 deletions rcljava/src/main/java/org/ros2/rcljava/client/ClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,25 @@ public class ClientImpl<T extends ServiceDefinition> implements Client<T> {
private final String serviceName;
private Map<Long, Map.Entry<Consumer, RCLFuture>> pendingRequests;

private final Class<MessageDefinition> requestType;
private final Class<MessageDefinition> responseType;

public ClientImpl(final WeakReference<Node> nodeReference, final long handle,
final String serviceName, final Class<MessageDefinition> requestType,
final Class<MessageDefinition> responseType) {
private final ServiceDefinition serviceDefinition;

public ClientImpl(
final ServiceDefinition serviceDefinition,
final WeakReference<Node> nodeReference,
final long handle,
final String serviceName)
{
this.nodeReference = nodeReference;
this.handle = handle;
this.serviceName = serviceName;
this.requestType = requestType;
this.responseType = responseType;
this.serviceDefinition = serviceDefinition;
this.pendingRequests = new HashMap<Long, Map.Entry<Consumer, RCLFuture>>();
}

public ServiceDefinition getServiceDefinition() {
return this.serviceDefinition;
}

public final <U extends MessageDefinition, V extends MessageDefinition> Future<V>
asyncSendRequest(final U request) {
return asyncSendRequest(request, new Consumer<Future<V>>() {
Expand Down Expand Up @@ -112,14 +117,6 @@ private static native long nativeSendClientRequest(
long handle, long requestFromJavaConverterHandle, long requestDestructorHandle,
MessageDefinition requestMessage);

public final Class<MessageDefinition> getRequestType() {
return this.requestType;
}

public final Class<MessageDefinition> getResponseType() {
return this.responseType;
}

/**
* Destroy a ROS2 client (rcl_client_t).
*
Expand Down
36 changes: 10 additions & 26 deletions rcljava/src/main/java/org/ros2/rcljava/executors/BaseExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,9 @@ protected void executeAnyExecutable(AnyExecutable anyExecutable) {
}

if (anyExecutable.service != null) {
Class<? extends MessageDefinition> requestType = anyExecutable.service.getRequestType();
Class<? extends MessageDefinition> responseType = anyExecutable.service.getResponseType();

MessageDefinition requestMessage = null;
MessageDefinition responseMessage = null;

try {
requestMessage = requestType.getDeclaredConstructor().newInstance();
responseMessage = responseType.getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException e) {
throw new IllegalStateException("Failed to instantiate service request/response");
}
ServiceDefinition serviceDefinition = anyExecutable.service.getServiceDefinition();
MessageDefinition requestMessage = serviceDefinition.newRequestInstance();
MessageDefinition responseMessage = serviceDefinition.newResponseInstance();

if (requestMessage != null && responseMessage != null) {
long requestFromJavaConverterHandle = requestMessage.getFromJavaConverterInstance();
Expand All @@ -140,28 +131,21 @@ protected void executeAnyExecutable(AnyExecutable anyExecutable) {
long responseDestructorHandle = responseMessage.getDestructorInstance();

RMWRequestId rmwRequestId =
nativeTakeRequest(anyExecutable.service.getHandle(), requestFromJavaConverterHandle,
requestToJavaConverterHandle, requestDestructorHandle, requestMessage);
nativeTakeRequest(anyExecutable.service.getHandle(), requestFromJavaConverterHandle,
requestToJavaConverterHandle, requestDestructorHandle, requestMessage);
if (rmwRequestId != null) {
anyExecutable.service.executeCallback(rmwRequestId, requestMessage, responseMessage);
nativeSendServiceResponse(anyExecutable.service.getHandle(), rmwRequestId,
responseFromJavaConverterHandle, responseDestructorHandle, responseMessage);
nativeSendServiceResponse(
anyExecutable.service.getHandle(), rmwRequestId,
responseFromJavaConverterHandle, responseDestructorHandle, responseMessage);
}
}
serviceHandles.remove(anyExecutable.service.getHandle());
}

if (anyExecutable.client != null) {
Class<? extends MessageDefinition> requestType = anyExecutable.client.getRequestType();
Class<? extends MessageDefinition> responseType = anyExecutable.client.getResponseType();

MessageDefinition responseMessage = null;

try {
responseMessage = responseType.getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException ie) {
throw new IllegalStateException("Failed to instantiate service response");
}
ServiceDefinition serviceDefinition = anyExecutable.client.getServiceDefinition();
MessageDefinition responseMessage = serviceDefinition.newResponseInstance();

if (responseMessage != null) {
long responseFromJavaConverterHandle = responseMessage.getFromJavaConverterInstance();
Expand Down
29 changes: 21 additions & 8 deletions rcljava/src/main/java/org/ros2/rcljava/node/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import org.ros2.rcljava.parameters.ParameterCallback;
import org.ros2.rcljava.parameters.ParameterType;
import org.ros2.rcljava.parameters.ParameterVariant;
import org.ros2.rcljava.parameters.client.AsyncParametersClient;
import org.ros2.rcljava.parameters.client.SyncParametersClient;
import org.ros2.rcljava.publisher.Publisher;
import org.ros2.rcljava.qos.QoSProfile;
import org.ros2.rcljava.service.RMWRequestId;
Expand Down Expand Up @@ -126,23 +128,24 @@ <T extends MessageDefinition> Publisher<T> createPublisher(
<T extends MessageDefinition> Publisher<T> createPublisher(
final Class<T> messageType, final String topic);

<T extends ServiceDefinition> Service<T> createService(final Class<T> serviceType,
<T extends ServiceDefinition> Service<T> createService(
final Class<T> serviceType,
final String serviceName,
final TriConsumer<RMWRequestId, ? extends MessageDefinition, ? extends MessageDefinition>
callback,
final QoSProfile qosProfile) throws NoSuchFieldException, IllegalAccessException;
final QoSProfile qosProfile);

<T extends ServiceDefinition> Service<T> createService(final Class<T> serviceType,
<T extends ServiceDefinition> Service<T> createService(
final Class<T> serviceType,
final String serviceName,
final TriConsumer<RMWRequestId, ? extends MessageDefinition, ? extends MessageDefinition>
callback) throws NoSuchFieldException, IllegalAccessException;
callback);

<T extends ServiceDefinition> Client<T> createClient(
final Class<T> serviceType, final String serviceName, final QoSProfile qosProfile)
throws NoSuchFieldException, IllegalAccessException;
final Class<T> serviceType, final String serviceName, final QoSProfile qosProfile);

<T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
final String serviceName) throws NoSuchFieldException, IllegalAccessException;
<T extends ServiceDefinition> Client<T> createClient(
final Class<T> serviceType, final String serviceName);

/**
* Create an ActionServer&lt;T&gt;.
Expand Down Expand Up @@ -263,6 +266,16 @@ <T extends ActionDefinition> ActionServer<T> createActionServer(final Class<T> a
*/
String getNamespace();

/**
* Create an asynchronous parameter client.
*/
AsyncParametersClient createAsyncParametersClient(String nodeName);

/**
* Create an synchronous parameter client.
*/
SyncParametersClient createSyncParametersClient(String nodeName);

/**
* Declare and initialize a parameter, return the effective value.
*
Expand Down
82 changes: 48 additions & 34 deletions rcljava/src/main/java/org/ros2/rcljava/node/NodeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
import org.ros2.rcljava.parameters.ParameterNotDeclaredException;
import org.ros2.rcljava.parameters.ParameterType;
import org.ros2.rcljava.parameters.ParameterVariant;
import org.ros2.rcljava.parameters.client.AsyncParametersClient;
import org.ros2.rcljava.parameters.client.AsyncParametersClientImpl;
import org.ros2.rcljava.parameters.client.SyncParametersClient;
import org.ros2.rcljava.parameters.client.SyncParametersClientImpl;
import org.ros2.rcljava.parameters.service.ParameterService;
import org.ros2.rcljava.parameters.service.ParameterServiceImpl;
import org.ros2.rcljava.publisher.Publisher;
Expand Down Expand Up @@ -191,18 +195,8 @@ public NodeImpl(final long handle, final NodeOptions nodeOptions) {
this.wall_clock = new Clock(ClockType.STEADY_TIME);
this.timeSource = new TimeSource(this);
this.timeSource.attachClock(this.clock);
try {
this.parameterService = nodeOptions.getStartParameterServices() ?
new ParameterServiceImpl(this) : null;
// TODO(ivanpauno): Modify createService, createClient so they don't declare
// NoSuchFieldException and IllegalAccessException checked exceptions.
// That only happens if the user passed the wrong Class object, and the exception should
// be rethrown as an unchecked IllegalArgumentException.
} catch (NoSuchFieldException ex) {
throw new IllegalArgumentException(ex.getMessage());
} catch (IllegalAccessException ex) {
throw new IllegalArgumentException(ex.getMessage());
}
this.parameterService = nodeOptions.getStartParameterServices() ?
new ParameterServiceImpl(this) : null;
}

/**
Expand Down Expand Up @@ -340,30 +334,39 @@ private static native <T extends ServiceDefinition> long nativeCreateServiceHand
long handle, Class<T> cls, String serviceName, long qosProfileHandle);

public final <T extends ServiceDefinition> Service<T> createService(final Class<T> serviceType,
final String serviceName,
final TriConsumer<RMWRequestId, ? extends MessageDefinition, ? extends MessageDefinition>
callback,
final QoSProfile qosProfile) throws NoSuchFieldException, IllegalAccessException {
Class<MessageDefinition> requestType = (Class) serviceType.getField("RequestType").get(null);

Class<MessageDefinition> responseType = (Class) serviceType.getField("ResponseType").get(null);

final String serviceName,
final TriConsumer<RMWRequestId, ? extends MessageDefinition, ? extends MessageDefinition>
callback,
final QoSProfile qosProfile)
{
T serviceDefinition;
try {
serviceDefinition = serviceType.getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException e) {
throw new IllegalStateException("Failed to instantiate service definition");
}
long qosProfileHandle = RCLJava.convertQoSProfileToHandle(qosProfile);
long serviceHandle =
nativeCreateServiceHandle(this.handle, serviceType, serviceName, qosProfileHandle);
RCLJava.disposeQoSProfile(qosProfileHandle);

Service<T> service = new ServiceImpl<T>(new WeakReference<Node>(this), serviceHandle,
serviceName, callback, requestType, responseType);
Service<T> service = new ServiceImpl<T>(
serviceDefinition,
new WeakReference<Node>(this),
serviceHandle,
serviceName,
callback);
this.services.add(service);

return service;
}

public <T extends ServiceDefinition> Service<T> createService(final Class<T> serviceType,
final String serviceName,
final TriConsumer<RMWRequestId, ? extends MessageDefinition, ? extends MessageDefinition>
callback) throws NoSuchFieldException, IllegalAccessException {
public <T extends ServiceDefinition> Service<T> createService(
final Class<T> serviceType,
final String serviceName,
final TriConsumer<RMWRequestId, ? extends MessageDefinition, ? extends MessageDefinition>
callback)
{
return this.<T>createService(serviceType, serviceName, callback, QoSProfile.SERVICES_DEFAULT);
}

Expand All @@ -375,26 +378,29 @@ public final Collection<Service> getServices() {
}

public final <T extends ServiceDefinition> Client<T> createClient(
final Class<T> serviceType, final String serviceName, final QoSProfile qosProfile)
throws NoSuchFieldException, IllegalAccessException {
Class<MessageDefinition> requestType = (Class) serviceType.getField("RequestType").get(null);

Class<MessageDefinition> responseType = (Class) serviceType.getField("ResponseType").get(null);

final Class<T> serviceType, final String serviceName, final QoSProfile qosProfile)
{
long qosProfileHandle = RCLJava.convertQoSProfileToHandle(qosProfile);
long clientHandle =
nativeCreateClientHandle(this.handle, serviceType, serviceName, qosProfileHandle);
RCLJava.disposeQoSProfile(qosProfileHandle);

T serviceDefinition;
try {
serviceDefinition = serviceType.getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException e) {
throw new IllegalStateException("Failed to instantiate service definition");
}

Client<T> client = new ClientImpl<T>(
new WeakReference<Node>(this), clientHandle, serviceName, requestType, responseType);
serviceDefinition, new WeakReference<Node>(this), clientHandle, serviceName);
this.clients.add(client);

return client;
}

public <T extends ServiceDefinition> Client<T> createClient(final Class<T> serviceType,
final String serviceName) throws NoSuchFieldException, IllegalAccessException {
final String serviceName) {
return this.<T>createClient(serviceType, serviceName, QoSProfile.SERVICES_DEFAULT);
}

Expand Down Expand Up @@ -531,6 +537,14 @@ public final String getNamespace() {
return nativeGetNamespace(this.handle);
}

public AsyncParametersClient createAsyncParametersClient(String nodeName) {
return new AsyncParametersClientImpl(this, nodeName);
}

public SyncParametersClient createSyncParametersClient(String nodeName) {
return new SyncParametersClientImpl(this, nodeName);
}

public ParameterVariant declareParameter(ParameterVariant parameter) {
return declareParameter(parameter, new rcl_interfaces.msg.ParameterDescriptor().setName(parameter.getName()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class AsyncParametersClientImpl implements AsyncParametersClient {
private final Client<rcl_interfaces.srv.DescribeParameters> describeParametersClient;

public AsyncParametersClientImpl(final Node node, final String remoteName,
final QoSProfile qosProfile) throws NoSuchFieldException, IllegalAccessException {
final QoSProfile qosProfile) {
this.node = node;
if (remoteName != "") {
this.remoteName = remoteName;
Expand Down Expand Up @@ -84,17 +84,17 @@ public AsyncParametersClientImpl(final Node node, final String remoteName,
}

public AsyncParametersClientImpl(final Node node, final QoSProfile qosProfile)
throws NoSuchFieldException, IllegalAccessException {
{
this(node, "", qosProfile);
}

public AsyncParametersClientImpl(final Node node, final String remoteName)
throws NoSuchFieldException, IllegalAccessException {
{
this(node, remoteName, QoSProfile.PARAMETERS);
}

public AsyncParametersClientImpl(final Node node)
throws NoSuchFieldException, IllegalAccessException {
{
this(node, "", QoSProfile.PARAMETERS);
}

Expand Down
Loading