diff --git a/lib/node.js b/lib/node.js index fdc7da43..f76bdb43 100644 --- a/lib/node.js +++ b/lib/node.js @@ -1273,6 +1273,26 @@ class Node extends rclnodejs.ShadowNode { return params; } + /** + * Get the types of given parameters. + * + * Return the types of given parameters. + * + * @param {string[]} [names] - The names of the declared parameters. + * @return {Uint8Array} - The types. + */ + getParameterTypes(names = []) { + let types = []; + + for (const name of names) { + const descriptor = this._parameterDescriptors.get(name); + if (descriptor) { + types.push(descriptor.type); + } + } + return types; + } + /** * Get the names of all declared parameters. * diff --git a/lib/parameter_service.js b/lib/parameter_service.js index adaf989f..752d4665 100644 --- a/lib/parameter_service.js +++ b/lib/parameter_service.js @@ -110,6 +110,16 @@ class ParameterService { } ); + // Create GetParameterTypes service. + const getParameterTypesServiceName = nodeName + '/get_parameter_types'; + this._node.createService( + 'rcl_interfaces/srv/GetParameterTypes', + getParameterTypesServiceName, + (request, response) => { + this._handleGetParameterTypes(request, response); + } + ); + // create SetParametersAtomically service const setParametersAtomicallyServiceName = nodeName + '/set_parameters_atomically'; @@ -266,6 +276,23 @@ class ParameterService { response.send(msg); } + /** + * Get a list of parameter types. + * + * request.names identifies the parameter types to get. + * + * @param {GetParameterTypes_Request} request - The client request. + * @param {GetParameterTypes_Response} response - The service response with + * Uint8Array. + * @return {undefined} - + */ + _handleGetParameterTypes(request, response) { + const types = this._node.getParameterTypes(request.names); + const msg = response.template; + msg.types = types; + response.send(msg); + } + /** * Update a list of parameters atomically. * diff --git a/test/test-extra-destroy-methods.js b/test/test-extra-destroy-methods.js index 9e3f5f91..d2ecdc9d 100644 --- a/test/test-extra-destroy-methods.js +++ b/test/test-extra-destroy-methods.js @@ -93,7 +93,7 @@ describe('Node extra destroy methods testing', function () { const AddTwoInts = 'example_interfaces/srv/AddTwoInts'; // const AddTwoInts = rclnodejs.require('example_interfaces/srv/AddTwoInts'); var service = node.createService(AddTwoInts, 'add_two_ints', () => {}); - assert.deepStrictEqual(node._services.length, 6); + assert.deepStrictEqual(node._services.length, 7); assertThrowsError( function () { @@ -105,7 +105,7 @@ describe('Node extra destroy methods testing', function () { ); node.destroyService(service); - assert.deepStrictEqual(node._services.length, 5); + assert.deepStrictEqual(node._services.length, 6); }); it('destroyTimer()', function () { diff --git a/test/test-parameter-service.js b/test/test-parameter-service.js index b90140c6..507b0a6e 100644 --- a/test/test-parameter-service.js +++ b/test/test-parameter-service.js @@ -367,4 +367,34 @@ describe('Parameter_server tests', function () { `Expected 3 parameter-events, received ${eventCount} events.` ); }); + + it('Get_parameter_types', async function () { + const client = clientNode.createClient( + 'rcl_interfaces/srv/GetParameterTypes', + 'test_node/get_parameter_types' + ); + await client.waitForService(); + + const ParamTypes = rclnodejs.require('rcl_interfaces/msg/ParameterType'); + const request = new (rclnodejs.require( + 'rcl_interfaces/srv/GetParameterTypes' + ).Request)(); + request.names = ['p1', 'p2', 'A.p3']; + let success = false; + + client.sendRequest(request, (response) => { + assert.deepEqual(response.types.length, 3); + assert.deepEqual( + response.types, + Uint8Array.from([ + ParamTypes.PARAMETER_STRING, + ParamTypes.PARAMETER_INTEGER, + ParamTypes.PARAMETER_BOOL, + ]) + ); + success = true; + }); + await assertUtils.createDelay(STD_WAIT); + assert.ok(success); + }); });