UNPKG

roslib

Version:

The standard ROS Javascript Library

124 lines (109 loc) 3.55 kB
/** * @fileoverview * @author Brandon Alexander - baalexander@gmail.com */ var ServiceResponse = require('./ServiceResponse'); var ServiceRequest = require('./ServiceRequest'); var EventEmitter2 = require('eventemitter2').EventEmitter2; /** * A ROS service client. * * @constructor * @params options - possible keys include: * * ros - the ROSLIB.Ros connection handle * * name - the service name, like /add_two_ints * * serviceType - the service type, like 'rospy_tutorials/AddTwoInts' */ function Service(options) { options = options || {}; this.ros = options.ros; this.name = options.name; this.serviceType = options.serviceType; this.isAdvertised = false; this._serviceCallback = null; } Service.prototype.__proto__ = EventEmitter2.prototype; /** * Calls the service. Returns the service response in the * callback. Does nothing if this service is currently advertised. * * @param request - the ROSLIB.ServiceRequest to send * @param callback - function with params: * * response - the response from the service request * @param failedCallback - the callback function when the service call failed (optional). Params: * * error - the error message reported by ROS */ Service.prototype.callService = function(request, callback, failedCallback) { if (this.isAdvertised) { return; } var serviceCallId = 'call_service:' + this.name + ':' + (++this.ros.idCounter); if (callback || failedCallback) { this.ros.once(serviceCallId, function(message) { if (message.result !== undefined && message.result === false) { if (typeof failedCallback === 'function') { failedCallback(message.values); } } else if (typeof callback === 'function') { callback(new ServiceResponse(message.values)); } }); } var call = { op : 'call_service', id : serviceCallId, service : this.name, type: this.serviceType, args : request }; this.ros.callOnConnection(call); }; /** * Advertise the service. This turns the Service object from a client * into a server. The callback will be called with every request * that's made on this service. * * @param callback - This works similarly to the callback for a C++ service and should take the following params: * * request - the service request * * response - an empty dictionary. Take care not to overwrite this. Instead, only modify the values within. * It should return true if the service has finished successfully, * i.e. without any fatal errors. */ Service.prototype.advertise = function(callback) { if (this.isAdvertised || typeof callback !== 'function') { return; } this._serviceCallback = callback; this.ros.on(this.name, this._serviceResponse.bind(this)); this.ros.callOnConnection({ op: 'advertise_service', type: this.serviceType, service: this.name }); this.isAdvertised = true; }; Service.prototype.unadvertise = function() { if (!this.isAdvertised) { return; } this.ros.callOnConnection({ op: 'unadvertise_service', service: this.name }); this.isAdvertised = false; }; Service.prototype._serviceResponse = function(rosbridgeRequest) { var response = {}; var success = this._serviceCallback(rosbridgeRequest.args, response); var call = { op: 'service_response', service: this.name, values: new ServiceResponse(response), result: success }; if (rosbridgeRequest.id) { call.id = rosbridgeRequest.id; } this.ros.callOnConnection(call); }; module.exports = Service;