UNPKG

roslib

Version:

The standard ROS Javascript Library

144 lines (125 loc) 4.14 kB
/** * @fileOverview * @author Russell Toris - rctoris@wpi.edu */ var Topic = require('../core/Topic'); var Message = require('../core/Message'); var EventEmitter2 = require('eventemitter2').EventEmitter2; /** * An actionlib action client. * * Emits the following events: * * 'timeout' - if a timeout occurred while sending a goal * * 'status' - the status messages received from the action server * * 'feedback' - the feedback messages received from the action server * * 'result' - the result returned from the action server * * @constructor * @param options - object with following keys: * * ros - the ROSLIB.Ros connection handle * * serverName - the action server name, like /fibonacci * * actionName - the action message name, like 'actionlib_tutorials/FibonacciAction' * * timeout - the timeout length when connecting to the action server */ function ActionClient(options) { var that = this; options = options || {}; this.ros = options.ros; this.serverName = options.serverName; this.actionName = options.actionName; this.timeout = options.timeout; this.omitFeedback = options.omitFeedback; this.omitStatus = options.omitStatus; this.omitResult = options.omitResult; this.goals = {}; // flag to check if a status has been received var receivedStatus = false; // create the topics associated with actionlib this.feedbackListener = new Topic({ ros : this.ros, name : this.serverName + '/feedback', messageType : this.actionName + 'Feedback' }); this.statusListener = new Topic({ ros : this.ros, name : this.serverName + '/status', messageType : 'actionlib_msgs/GoalStatusArray' }); this.resultListener = new Topic({ ros : this.ros, name : this.serverName + '/result', messageType : this.actionName + 'Result' }); this.goalTopic = new Topic({ ros : this.ros, name : this.serverName + '/goal', messageType : this.actionName + 'Goal' }); this.cancelTopic = new Topic({ ros : this.ros, name : this.serverName + '/cancel', messageType : 'actionlib_msgs/GoalID' }); // advertise the goal and cancel topics this.goalTopic.advertise(); this.cancelTopic.advertise(); // subscribe to the status topic if (!this.omitStatus) { this.statusListener.subscribe(function(statusMessage) { receivedStatus = true; statusMessage.status_list.forEach(function(status) { var goal = that.goals[status.goal_id.id]; if (goal) { goal.emit('status', status); } }); }); } // subscribe the the feedback topic if (!this.omitFeedback) { this.feedbackListener.subscribe(function(feedbackMessage) { var goal = that.goals[feedbackMessage.status.goal_id.id]; if (goal) { goal.emit('status', feedbackMessage.status); goal.emit('feedback', feedbackMessage.feedback); } }); } // subscribe to the result topic if (!this.omitResult) { this.resultListener.subscribe(function(resultMessage) { var goal = that.goals[resultMessage.status.goal_id.id]; if (goal) { goal.emit('status', resultMessage.status); goal.emit('result', resultMessage.result); } }); } // If timeout specified, emit a 'timeout' event if the action server does not respond if (this.timeout) { setTimeout(function() { if (!receivedStatus) { that.emit('timeout'); } }, this.timeout); } } ActionClient.prototype.__proto__ = EventEmitter2.prototype; /** * Cancel all goals associated with this ActionClient. */ ActionClient.prototype.cancel = function() { var cancelMessage = new Message(); this.cancelTopic.publish(cancelMessage); }; /** * Unsubscribe and unadvertise all topics associated with this ActionClient. */ ActionClient.prototype.dispose = function() { this.goalTopic.unadvertise(); this.cancelTopic.unadvertise(); if (!this.omitStatus) {this.statusListener.unsubscribe();} if (!this.omitFeedback) {this.feedbackListener.unsubscribe();} if (!this.omitResult) {this.resultListener.unsubscribe();} }; module.exports = ActionClient;