diff --git a/build/roslib.js b/build/roslib.js index bee4e293..3a62eaca 100644 --- a/build/roslib.js +++ b/build/roslib.js @@ -158,7 +158,7 @@ ROSLIB.Goal = function(options) { }; /** - * Cancel the current this. + * Cancel the current goal. */ this.cancel = function() { var cancelMessage = new ROSLIB.Message({ @@ -748,270 +748,428 @@ ROSLIB.Topic = function(options) { }; }; ROSLIB.Topic.prototype.__proto__ = EventEmitter2.prototype; -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define(['robotwebtools/eventemitter2','robotwebtools/actionclient'], factory); +/** + * @author David Gossow - dgossow@willowgarage.com + */ + +/** + * A Pose in 3D space. Values are copied into this object. + * + * @constructor + * @param position - the ROSLIB.Vector3 describing the position + * @param orientation - the ROSLIB.Quaternion describing the orientation + */ +ROSLIB.Pose = function(position, orientation) { + var pose = this; + // copy the values into this object if they exist + this.position = new ROSLIB.Vector3(); + this.orientation = new ROSLIB.Quaternion(); + if (position !== undefined) { + this.position.copy(position); } - else { - root.TfClient = factory(root.EventEmitter2,root.ActionClient); + if (orientation !== undefined) { + this.orientation.copy(orientation); } -}(this, function (EventEmitter2, ActionClient) { - - var TfClient = function(options) { - this.ros = options.ros; - this.fixedFrame = options.fixedFrame || 'base_link'; - this.angularThres = options.angularThres || 2.0; - this.transThres = options.transThres || 0.01; - this.rate = options.rate || 10.0; - this.goalUpdateDelay = options.goalUpdateDelay !== undefined ? options.goalUpdateDelay : 50; - - var options = { - ros: this.ros, - serverName: options.serverName || "/tf2_web_republisher", - actionName: "tf2_web_republisher/TFSubscriptionAction" - }; - this.actionClient = new ActionClient( options ); - this.currentGoal = false; - this.frame_infos = {}; - this.goalUpdateRequested = false; + /** + * Copy the values from the given pose into this pose. + * + * @param pose the pose to copy + * @returns a pointer to this pose + */ + this.copy = function(pose) { + pose.position.copy(pose.position); + pose.orientation.copy(pose.orientation); + return pose; + }; +}; +/** + * @author David Gossow - dgossow@willowgarage.com + */ + +/** + * A Quaternion. + * + * @constructor + * @param x - the x value + * @param y - the y value + * @param z - the z value + * @param w - the w value + */ +ROSLIB.Quaternion = function(x, y, z, w) { + var quaternion = this; + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w || 1; + + /** + * Copy the values from the given quaternion into this quaternion. + * + * @param q the quaternion to copy + * @returns a pointer to this quaternion + */ + this.copy = function(q) { + quaternion.x = q.x; + quaternion.y = q.y; + quaternion.z = q.z; + quaternion.w = q.w; + return quaternion; + }; + + /** + * Perform a conjugation on this quaternion. + * + * @returns a pointer to this quaternion + */ + this.conjugate = function() { + quaternion.x *= -1; + quaternion.y *= -1; + quaternion.z *= -1; + return quaternion; + }; + + /** + * Perform a normalization on this quaternion. + * + * @returns a pointer to this quaternion + */ + this.normalize = function() { + var l = Math.sqrt(quaternion.x * quaternion.x + quaternion.y * quaternion.y + quaternion.z + * quaternion.z + quaternion.w * quaternion.w); + if (l === 0) { + quaternion.x = 0; + quaternion.y = 0; + quaternion.z = 0; + quaternion.w = 1; + } else { + l = 1 / l; + quaternion.x = quaternion.x * l; + quaternion.y = quaternion.y * l; + quaternion.z = quaternion.z * l; + quaternion.w = quaternion.w * l; + } + return quaternion; + }; + + /** + * Convert this quaternion into its inverse. + * + * @returns a pointer to this quaternion + */ + this.inverse = function() { + this.conjugate().normalize(); + return quaternion; + }; + + /** + * Set the values of this quaternion to the product of quaternions a and b. + * + * @param a the first quaternion to multiply with + * @param b the second quaternion to multiply with + * @returns a pointer to this quaternion + */ + this.multiply = function(a, b) { + var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w, qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w; + this.x = qax * qbw + qay * qbz - qaz * qby + qaw * qbx; + this.y = -qax * qbz + qay * qbw + qaz * qbx + qaw * qby; + this.z = qax * qby - qay * qbx + qaz * qbw + qaw * qbz; + this.w = -qax * qbx - qay * qby - qaz * qbz + qaw * qbw; + return quaternion; + }; + + /** + * Multiply the given ROSLIB.Vector3 with this quaternion. + * + * @param vector the vector to multiply with + * @param dest (option) - where the computed values will go (defaults to 'vector'). + * @returns a pointer to dest + */ + this.multiplyVec3 = function(vector, dest) { + if (!dest) { + dest = vector; + } + var x = vector.x, y = vector.y, z = vector.z, qx = quaternion.x, qy = quaternion.y, qz = quaternion.z, qw = quaternion.w; + var ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx + * x - qy * y - qz * z; + dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return dest; + }; + + /** + * Clone a copy of this quaternion. + * + * @returns the cloned quaternion + */ + this.clone = function() { + return new ROSLIB.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w); + }; +}; +/** + * @author David Gossow - dgossow@willowgarage.com + */ + +/** + * A 3D vector. + * + * @constructor + * @param x - the x value + * @param y - the y value + * @param z - the z value + */ +ROSLIB.Vector3 = function(x, y, z) { + var vector3 = this; + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + + /** + * Copy the values from the given vector into this vector. + * + * @param v the vector to copy + * @returns a pointer to this vector + */ + this.copy = function(v) { + vector3.x = v.x; + vector3.y = v.y; + vector3.z = v.z; + return vector3; + }; + + /** + * Set the values of this vector to the sum of vectors a and b. + * + * @param a the first vector to add with + * @param b the second vector to add with + * @returns a pointer to this vector + */ + this.add = function(a, b) { + vector3.x = a.x + b.x; + vector3.y = a.y + b.y; + vector3.z = a.z + b.z; + return vector3; + }; + + /** + * Set the values of this vector to the difference of vectors a and b. + * + * @param a the first vector to add with + * @param b the second vector to add with + * @returns a pointer to this vector + */ + this.sub = function(a, b) { + vector3.x = a.x - b.x; + vector3.y = a.y - b.y; + vector3.z = a.z - b.z; + return vector3; + }; + + /** + * Clone a copy of this vector. + * + * @returns the cloned vector + */ + this.clone = function() { + return new ROSLIB.Vector3(vector3.x, vector3.y, vector3.z); }; +}; +/** + * @author David Gossow - dgossow@willowgarage.com + */ - TfClient.prototype.__proto__ = EventEmitter2.prototype; +/** + * A TF Client that listens to TFs from tf2_web_republisher. + * + * @constructor + * @param options - object with following keys: + * * ros - the ROSLIB.Ros connection handle + * * fixedFrame - the fixed frame, like /base_link + * * angularThres - the angular threshold for the TF republisher + * * transThres - the translation threshold for the TF republisher + * * rate - the rate for the TF republisher + * * goalUpdateDelay - the goal update delay for the TF republisher + */ +ROSLIB.TFClient = function(options) { + var tfClient = this; + var options = options || {}; + this.ros = options.ros; + this.fixedFrame = options.fixedFrame || '/base_link'; + this.angularThres = options.angularThres || 2.0; + this.transThres = options.transThres || 0.01; + this.rate = options.rate || 10.0; + this.goalUpdateDelay = options.goalUpdateDelay || 50; + + this.currentGoal = false; + this.frameInfos = {}; + this.goalUpdateRequested = false; + + // create an ActionClient + this.actionClient = new ROSLIB.ActionClient({ + ros : this.ros, + serverName : '/tf2_web_republisher', + actionName : 'tf2_web_republisher/TFSubscriptionAction' + }); - TfClient.prototype.processFeedback = function(tfMsg) { - var that = this; - tfMsg.transforms.forEach( function(transform) { - var frameId = transform.child_frame_id; - var info = that.frame_infos[frameId]; - if ( info != undefined ) { - info.transform = new Transform(transform.transform.translation,transform.transform.rotation); + /** + * Process the incoming TF message and send them out using the callback functions. + * + * @param tf - the TF message from the server + */ + this.processFeedback = function(tf) { + tf.transforms.forEach(function(transform) { + var frameID = transform.child_frame_id; + var info = tfClient.frameInfos[frameID]; + if (info != undefined) { + info.transform = new ROSLIB.Transform(transform.transform.translation, + transform.transform.rotation); info.cbs.forEach(function(cb) { cb(info.transform); }); } }); - } - - TfClient.prototype.requestGoalUpdate = function() { - if ( !this.goalUpdateRequested ) { - setTimeout(this.updateGoal.bind(this), this.goalUpdateDelay); - this.goalUpdateRequested = true; - return; - } - } + }; - TfClient.prototype.updateGoal = function() { - // Anytime the list of frames changes, - // we will need to send a new goal. - if ( this.currentGoal ) { - this.currentGoal.cancel(); + /** + * Create and send a new goal to the tf2_web_republisher based on the current list of TFs. + */ + this.updateGoal = function() { + // Anytime the list of frames changes, we will need to send a new goal. + if (tfClient.currentGoal) { + tfClient.currentGoal.cancel(); } - var goalMsg = { - source_frames: [], - target_frame: this.fixedFrame, - angular_thres: this.angularThres, - trans_thres: this.transThres, - rate: this.rate + var goalMessage = { + source_frames : [], + target_frame : tfClient.fixedFrame, + angular_thres : tfClient.angularThres, + trans_thres : tfClient.transThres, + rate : tfClient.rate }; - var source_frames = []; - for (frame in this.frame_infos ) { - goalMsg.source_frames.push(frame); - }; + for (frame in tfClient.frameInfos) { + goalMessage.source_frames.push(frame); + } - this.currentGoal = new this.actionClient.Goal(goalMsg); - this.currentGoal.on('feedback', this.processFeedback.bind(this)); - this.currentGoal.send(); - this.goalUpdateRequested = false; - } + tfClient.currentGoal = new ROSLIB.Goal({ + actionClient : tfClient.actionClient, + goalMessage : goalMessage + }); + tfClient.currentGoal.on('feedback', tfClient.processFeedback.bind(tfClient)); + tfClient.currentGoal.send(); + tfClient.goalUpdateRequested = false; + }; - TfClient.prototype.subscribe = function(frameId,callback) { + /** + * Subscribe to the given TF frame. + * + * @param frameID - the TF frame to subscribe to + * @param callback - function with params: + * * transform - the transform data + */ + this.subscribe = function(frameID, callback) { // make sure the frame id is relative - if ( frameId[0] === "/" ) { - frameId = frameId.substring(1); + if (frameID[0] === '/') { + frameID = frameID.substring(1); } - // if there is no callback registered for the given frame, - // create emtpy callback list - if ( this.frame_infos[frameId] == undefined ) { - this.frame_infos[frameId] = { - cbs: [] }; - this.requestGoalUpdate(); + // if there is no callback registered for the given frame, create emtpy callback list + if (tfClient.frameInfos[frameID] == undefined) { + tfClient.frameInfos[frameID] = { + cbs : [] + }; + if (!tfClient.goalUpdateRequested) { + setTimeout(tfClient.updateGoal.bind(tfClient), tfClient.goalUpdateDelay); + tfClient.goalUpdateRequested = true; + } } else { // if we already have a transform, call back immediately - if ( this.frame_infos[frameId].transform != undefined ) { - callback( this.frame_infos[frameId].transform ); + if (tfClient.frameInfos[frameID].transform != undefined) { + callback(tfClient.frameInfos[frameID].transform); } } - this.frame_infos[frameId].cbs.push( callback ); + tfClient.frameInfos[frameID].cbs.push(callback); }; - TfClient.prototype.unsubscribe = function(frameId,callback) { - var info = this.frame_infos[frameId]; - if ( info != undefined ) { - var cbIndex = info.cbs.indexOf( callback ); - if ( cbIndex >= 0 ) { + /** + * Unsubscribe from the given TF frame. + * + * @param frameID - the TF frame to unsubscribe from + * @param callback - the callback function to remove + */ + tfClient.unsubscribe = function(frameID, callback) { + var info = tfClient.frameInfos[frameID]; + if (info != undefined) { + var cbIndex = info.cbs.indexOf(callback); + if (cbIndex >= 0) { info.cbs.splice(cbIndex, 1); - if ( info.cbs.length == 0 ) { - delete this.frame_infos[frameId]; + if (info.cbs.length == 0) { + delete tfClient.frameInfos[frameID]; } - this.needUpdate = true; + tfClient.needUpdate = true; } } - } - - - var Pose = TfClient.Pose = function( position, orientation ) { - this.position = new Vector3; - this.orientation = new Quaternion; - if ( position !== undefined ) { - this.position.copy( position ); - } - if ( orientation !== undefined ) { - this.orientation.copy( orientation ); - } }; +}; +/** + * @author David Gossow - dgossow@willowgarage.com + */ - Pose.prototype = { - constructor: Pose, - copy: function( pose ) { - this.position.copy( pose.position ); - this.orientation.copy( pose.orientation ); - } +/** + * A Transform in 3-space. Values are copied into this object. + * + * @constructor + * @param translation - the ROSLIB.Vector3 describing the translation + * @param rotation - the ROSLIB.Quaternion describing the rotation + */ +ROSLIB.Transform = function(translation, rotation) { + var transform = this; + // copy the values into this object if they exist + this.translation = new ROSLIB.Vector3(); + this.rotation = new ROSLIB.Quaternion(); + if (translation !== undefined) { + this.translation.copy(translation); } - - var Transform = TfClient.Transform = function( translation, rotation ) { - this.translation = new Vector3; - this.rotation = new Quaternion; - if ( translation !== undefined ) { - this.translation.copy( translation ); - } - if ( rotation !== undefined ) { - this.rotation.copy( rotation ); - } - }; - - Transform.prototype = { - constructor: Transform, - apply: function( pose ) { - this.rotation.multiplyVec3(pose.position); - pose.position.add(pose.position,this.translation); - pose.orientation.multiply(this.rotation, pose.orientation); - return pose; - }, - applyInverse: function( pose ) { - var rotInv = this.rotation.clone().inverse(); - rotInv.multiplyVec3(pose.position); - pose.position.sub(pose.position,this.translation); - pose.orientation.multiply(rotInv, pose.orientation); - return pose; - }, - copy: function( transform ) { - this.translation.copy( transform.translation ); - this.rotation.copy( transform.rotation ); - } + if (rotation !== undefined) { + this.rotation.copy(rotation); } - var Quaternion = TfClient.Quaternion = function( x, y, z, w ) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = ( w !== undefined ) ? w : 1; - }; - - Quaternion.prototype = { - constructor: Quaternion, - copy: function ( q ) { - this.x = q.x; - this.y = q.y; - this.z = q.z; - this.w = q.w; - return this; - }, - inverse: function () { - this.conjugate().normalize(); - return this; - }, - conjugate: function () { - this.x *= -1; - this.y *= -1; - this.z *= -1; - return this; - }, - normalize: function () { - var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); - if ( l === 0 ) { - this.x = 0; - this.y = 0; - this.z = 0; - this.w = 1; - } else { - l = 1 / l; - this.x = this.x * l; - this.y = this.y * l; - this.z = this.z * l; - this.w = this.w * l; - } - return this; - }, - multiply: function ( a, b ) { - var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w, - qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w; - this.x = qax * qbw + qay * qbz - qaz * qby + qaw * qbx; - this.y = -qax * qbz + qay * qbw + qaz * qbx + qaw * qby; - this.z = qax * qby - qay * qbx + qaz * qbw + qaw * qbz; - this.w = -qax * qbx - qay * qby - qaz * qbz + qaw * qbw; - return this; - }, - multiplyVec3: function ( vector, dest ) { - if ( !dest ) { dest = vector; } - var x = vector.x, y = vector.y, z = vector.z, - qx = this.x, qy = this.y, qz = this.z, qw = this.w; - var ix = qw * x + qy * z - qz * y, - iy = qw * y + qz * x - qx * z, - iz = qw * z + qx * y - qy * x, - iw = -qx * x - qy * y - qz * z; - dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; - dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; - dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; - return dest; - }, - clone: function () { - return new Quaternion( this.x, this.y, this.z, this.w ); - } - } - - var Vector3 = TfClient.Vector3 = function ( x, y, z ) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; + /** + * Apply a transform against the given ROSLIB.Pose. + * + * @param pose the pose to transform with + * @returns a pointer to the pose + */ + this.apply = function(pose) { + transform.rotation.multiplyVec3(pose.position); + pose.position.add(pose.position, transform.translation); + pose.orientation.multiply(transform.rotation, pose.orientation); + return pose; }; - Vector3.prototype = { - constructor: Vector3, - copy: function ( v ) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - return this; - }, - add: function ( a, b ) { - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - return this; - }, - sub: function ( a, b ) { - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; - return this; - }, - clone: function () { - return new Vector3( this.x, this.y, this.z ); - } + /** + * Apply an inverse transform against the given ROSLIB.Pose. + * + * @param pose the pose to transform with + * @returns a pointer to the pose + */ + this.applyInverse = function(pose) { + var rotInv = transform.rotation.clone().inverse(); + rotInv.multiplyVec3(pose.position); + pose.position.sub(pose.position, transform.translation); + pose.orientation.multiply(rotInv, pose.orientation); + return pose; }; - return TfClient; -})); + /** + * Copy the values from the given transform into this transform. + * + * @param transform the transform to copy + * @returns a pointer to this transform + */ + this.copy = function(transform) { + transform.translation.copy(transform.translation); + transform.rotation.copy(transform.rotation); + return transform; + }; +}; diff --git a/build/roslib.min.js b/build/roslib.min.js index d7fbdc29..e1493b70 100644 --- a/build/roslib.min.js +++ b/build/roslib.min.js @@ -1 +1 @@ -var ROSLIB=ROSLIB||{REVISION:"1"};ROSLIB.ActionClient=function(b){var d=this;b=b||{};this.ros=b.ros;this.serverName=b.serverName;this.actionName=b.actionName;this.timeout=b.timeout;this.goals={};var a=false;var c=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/feedback",messageType:this.actionName+"Feedback"});var e=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/status",messageType:"actionlib_msgs/GoalStatusArray"});var f=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/result",messageType:this.actionName+"Result"});this.goalTopic=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/goal",messageType:this.actionName+"Goal"});this.cancelTopic=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/cancel",messageType:"actionlib_msgs/GoalID"});this.cancel=function(){var g=new ROSLIB.Message({});this.cancelTopic.publish(g)};this.goalTopic.advertise();this.cancelTopic.advertise();e.subscribe(function(g){a=true;g.status_list.forEach(function(h){var i=d.goals[h.goal_id.id];if(i){i.emit("status",h)}})});c.subscribe(function(h){var g=d.goals[h.status.goal_id.id];if(g){g.emit("status",h.status);g.emit("feedback",h.feedback)}});f.subscribe(function(h){var g=d.goals[h.status.goal_id.id];if(g){g.emit("status",h.status);g.emit("result",h.result)}});if(this.timeout){setTimeout(function(){if(!a){d.emit("timeout")}},this.timeout)}};ROSLIB.ActionClient.prototype.__proto__=EventEmitter2.prototype;ROSLIB.Goal=function(c){var b=this;this.actionClient=c.actionClient;this.goalMessage=c.goalMessage;this.isFinished=false;var a=new Date();this.send=function(d){b.actionClient.goalTopic.publish(b.goalMessage);if(d){setTimeout(function(){if(!b.isFinished){b.emit("timeout")}},d)}};this.cancel=function(){var d=new ROSLIB.Message({id:b.goalID});b.actionClient.cancelTopic.publish(d)};this.goalID="goal_"+Math.random()+"_"+a.getTime();this.goalMessage=new ROSLIB.Message({goal_id:{stamp:{secs:0,nsecs:0},id:this.goalID},goal:this.goalMessage});this.on("status",function(d){this.status=d});this.on("result",function(d){this.isFinished=true;this.result=d});this.on("feedback",function(d){this.feedback=d});this.actionClient.goals[this.goalID]=this};ROSLIB.Goal.prototype.__proto__=EventEmitter2.prototype;ROSLIB.Message=function(a){var b=this;if(a){Object.keys(a).forEach(function(c){b[c]=a[c]})}};ROSLIB.Param=function(a){var b=this;a=a||{};this.ros=a.ros;this.name=a.name;this.get=function(e){var d=new ROSLIB.Service({ros:ros,name:"/rosapi/get_param",serviceType:"rosapi/GetParam"});var c=new ROSLIB.ServiceRequest({name:b.name,value:JSON.stringify("")});d.callService(c,function(f){var g=JSON.parse(f.value);e(g)})};this.set=function(e){var d=new ROSLIB.Service({ros:ros,name:"/rosapi/set_param",serviceType:"rosapi/SetParam"});var c=new ROSLIB.ServiceRequest({name:b.name,value:JSON.stringify(e)});d.callService(c,function(){})}};ROSLIB.Ros=function(d){var c=this;this.socket=null;function b(h){c.emit("connection",h)}function a(h){c.emit("close",h)}function e(h){c.emit("error",h)}function g(h,j){var i=new Image();i.onload=function(){var k=document.createElement("canvas");var m=k.getContext("2d");k.width=i.width;k.height=i.height;m.drawImage(i,0,0);var p=m.getImageData(0,0,i.width,i.height).data;var n="";for(var l=0;l=0){j.cbs.splice(h,1);if(j.cbs.length==0){delete this.frame_infos[i]}this.needUpdate=true}}};var f=d.Pose=function(h,i){this.position=new a;this.orientation=new e;if(h!==undefined){this.position.copy(h)}if(i!==undefined){this.orientation.copy(i)}};f.prototype={constructor:f,copy:function(h){this.position.copy(h.position);this.orientation.copy(h.orientation)}};var c=d.Transform=function(i,h){this.translation=new a;this.rotation=new e;if(i!==undefined){this.translation.copy(i)}if(h!==undefined){this.rotation.copy(h)}};c.prototype={constructor:c,apply:function(h){this.rotation.multiplyVec3(h.position);h.position.add(h.position,this.translation);h.orientation.multiply(this.rotation,h.orientation);return h},applyInverse:function(i){var h=this.rotation.clone().inverse();h.multiplyVec3(i.position);i.position.sub(i.position,this.translation);i.orientation.multiply(h,i.orientation);return i},copy:function(h){this.translation.copy(h.translation);this.rotation.copy(h.rotation)}};var e=d.Quaternion=function(h,k,j,i){this.x=h||0;this.y=k||0;this.z=j||0;this.w=(i!==undefined)?i:1};e.prototype={constructor:e,copy:function(h){this.x=h.x;this.y=h.y;this.z=h.z;this.w=h.w;return this},inverse:function(){this.conjugate().normalize();return this},conjugate:function(){this.x*=-1;this.y*=-1;this.z*=-1;return this},normalize:function(){var h=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);if(h===0){this.x=0;this.y=0;this.z=0;this.w=1}else{h=1/h;this.x=this.x*h;this.y=this.y*h;this.z=this.z*h;this.w=this.w*h}return this},multiply:function(q,p){var n=q.x,m=q.y,l=q.z,o=q.w,j=p.x,i=p.y,h=p.z,k=p.w;this.x=n*k+m*h-l*i+o*j;this.y=-n*h+m*k+l*j+o*i;this.z=n*i-m*j+l*k+o*h;this.w=-n*j-m*i-l*h+o*k;return this},multiplyVec3:function(j,t){if(!t){t=j}var s=j.x,r=j.y,q=j.z,o=this.x,n=this.y,m=this.z,p=this.w;var k=p*s+n*q-m*r,i=p*r+m*s-o*q,h=p*q+o*r-n*s,l=-o*s-n*r-m*q;t.x=k*p+l*-o+i*-m-h*-n;t.y=i*p+l*-n+h*-o-k*-m;t.z=h*p+l*-m+k*-n-i*-o;return t},clone:function(){return new e(this.x,this.y,this.z,this.w)}};var a=d.Vector3=function(h,j,i){this.x=h||0;this.y=j||0;this.z=i||0};a.prototype={constructor:a,copy:function(h){this.x=h.x;this.y=h.y;this.z=h.z;return this},add:function(i,h){this.x=i.x+h.x;this.y=i.y+h.y;this.z=i.z+h.z;return this},sub:function(i,h){this.x=i.x-h.x;this.y=i.y-h.y;this.z=i.z-h.z;return this},clone:function(){return new a(this.x,this.y,this.z)}};return d})); \ No newline at end of file +var ROSLIB=ROSLIB||{REVISION:"1"};ROSLIB.ActionClient=function(b){var d=this;b=b||{};this.ros=b.ros;this.serverName=b.serverName;this.actionName=b.actionName;this.timeout=b.timeout;this.goals={};var a=false;var c=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/feedback",messageType:this.actionName+"Feedback"});var e=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/status",messageType:"actionlib_msgs/GoalStatusArray"});var f=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/result",messageType:this.actionName+"Result"});this.goalTopic=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/goal",messageType:this.actionName+"Goal"});this.cancelTopic=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/cancel",messageType:"actionlib_msgs/GoalID"});this.cancel=function(){var g=new ROSLIB.Message({});this.cancelTopic.publish(g)};this.goalTopic.advertise();this.cancelTopic.advertise();e.subscribe(function(g){a=true;g.status_list.forEach(function(h){var i=d.goals[h.goal_id.id];if(i){i.emit("status",h)}})});c.subscribe(function(h){var g=d.goals[h.status.goal_id.id];if(g){g.emit("status",h.status);g.emit("feedback",h.feedback)}});f.subscribe(function(h){var g=d.goals[h.status.goal_id.id];if(g){g.emit("status",h.status);g.emit("result",h.result)}});if(this.timeout){setTimeout(function(){if(!a){d.emit("timeout")}},this.timeout)}};ROSLIB.ActionClient.prototype.__proto__=EventEmitter2.prototype;ROSLIB.Goal=function(c){var b=this;this.actionClient=c.actionClient;this.goalMessage=c.goalMessage;this.isFinished=false;var a=new Date();this.send=function(d){b.actionClient.goalTopic.publish(b.goalMessage);if(d){setTimeout(function(){if(!b.isFinished){b.emit("timeout")}},d)}};this.cancel=function(){var d=new ROSLIB.Message({id:b.goalID});b.actionClient.cancelTopic.publish(d)};this.goalID="goal_"+Math.random()+"_"+a.getTime();this.goalMessage=new ROSLIB.Message({goal_id:{stamp:{secs:0,nsecs:0},id:this.goalID},goal:this.goalMessage});this.on("status",function(d){this.status=d});this.on("result",function(d){this.isFinished=true;this.result=d});this.on("feedback",function(d){this.feedback=d});this.actionClient.goals[this.goalID]=this};ROSLIB.Goal.prototype.__proto__=EventEmitter2.prototype;ROSLIB.Message=function(a){var b=this;if(a){Object.keys(a).forEach(function(c){b[c]=a[c]})}};ROSLIB.Param=function(a){var b=this;a=a||{};this.ros=a.ros;this.name=a.name;this.get=function(e){var d=new ROSLIB.Service({ros:ros,name:"/rosapi/get_param",serviceType:"rosapi/GetParam"});var c=new ROSLIB.ServiceRequest({name:b.name,value:JSON.stringify("")});d.callService(c,function(f){var g=JSON.parse(f.value);e(g)})};this.set=function(e){var d=new ROSLIB.Service({ros:ros,name:"/rosapi/set_param",serviceType:"rosapi/SetParam"});var c=new ROSLIB.ServiceRequest({name:b.name,value:JSON.stringify(e)});d.callService(c,function(){})}};ROSLIB.Ros=function(d){var c=this;this.socket=null;function b(h){c.emit("connection",h)}function a(h){c.emit("close",h)}function e(h){c.emit("error",h)}function g(h,j){var i=new Image();i.onload=function(){var k=document.createElement("canvas");var m=k.getContext("2d");k.width=i.width;k.height=i.height;m.drawImage(i,0,0);var p=m.getImageData(0,0,i.width,i.height).data;var n="";for(var l=0;l=0){e.cbs.splice(d,1);if(e.cbs.length==0){delete a.frameInfos[c]}a.needUpdate=true}}}};ROSLIB.Transform=function(c,b){var a=this;this.translation=new ROSLIB.Vector3();this.rotation=new ROSLIB.Quaternion();if(c!==undefined){this.translation.copy(c)}if(b!==undefined){this.rotation.copy(b)}this.apply=function(d){a.rotation.multiplyVec3(d.position);d.position.add(d.position,a.translation);d.orientation.multiply(a.rotation,d.orientation);return d};this.applyInverse=function(e){var d=a.rotation.clone().inverse();d.multiplyVec3(e.position);e.position.sub(e.position,a.translation);e.orientation.multiply(d,e.orientation);return e};this.copy=function(d){d.translation.copy(d.translation);d.rotation.copy(d.rotation);return d}}; \ No newline at end of file diff --git a/doc/files.html b/doc/files.html index dacb071d..c0488704 100644 --- a/doc/files.html +++ b/doc/files.html @@ -194,6 +194,10 @@

Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -202,8 +206,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -316,6 +326,42 @@

    /home/tor1pal/Documents/WPI/RAIL/ROS/groovy/src/roslibjs/src/math/Pose.js

    + +
    + + + + +
    + +
    + +
    +

    /home/tor1pal/Documents/WPI/RAIL/ROS/groovy/src/roslibjs/src/math/Quaternion.js

    + +
    + + + + +
    +
    +
    + +
    +

    /home/tor1pal/Documents/WPI/RAIL/ROS/groovy/src/roslibjs/src/math/Vector3.js

    + +
    + + + +

    @@ -333,7 +379,19 @@

    /home/tor1pal/Documents/WPI/RAIL/ROS/groovy/src/roslibjs/src/tf/TfClient.js

    +

    /home/tor1pal/Documents/WPI/RAIL/ROS/groovy/src/roslibjs/src/tf/TFClient.js

    + +
    + + + + +
    + +
    + +
    +

    /home/tor1pal/Documents/WPI/RAIL/ROS/groovy/src/roslibjs/src/tf/Transform.js

    @@ -348,7 +406,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)

    \ No newline at end of file diff --git a/doc/index.html b/doc/index.html index b3da1e78..9f5f14c9 100644 --- a/doc/index.html +++ b/doc/index.html @@ -194,6 +194,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -202,8 +206,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -242,6 +252,18 @@

    ROSLIB.Param


    +
    +

    ROSLIB.Pose

    + +
    +
    + +
    +

    ROSLIB.Quaternion

    + +
    +
    +

    ROSLIB.Ros

    @@ -266,17 +288,35 @@

    ROSLIB.ServiceResponse


    +
    +

    ROSLIB.TFClient

    + +
    +
    +

    ROSLIB.Topic


    +
    +

    ROSLIB.Transform

    + +
    +
    + +
    +

    ROSLIB.Vector3

    + +
    +
    +
    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    \ No newline at end of file diff --git a/doc/symbols/ROSLIB.ActionClient.html b/doc/symbols/ROSLIB.ActionClient.html index 11e00656..eafd7af8 100644 --- a/doc/symbols/ROSLIB.ActionClient.html +++ b/doc/symbols/ROSLIB.ActionClient.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -389,7 +399,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.Goal.html b/doc/symbols/ROSLIB.Goal.html index cf0cf156..793de68a 100644 --- a/doc/symbols/ROSLIB.Goal.html +++ b/doc/symbols/ROSLIB.Goal.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -279,7 +289,7 @@

    -
    Cancel the current this.
    +
    Cancel the current goal.
    @@ -364,7 +374,7 @@

    - Cancel the current this. + Cancel the current goal.
    @@ -429,7 +439,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.Message.html b/doc/symbols/ROSLIB.Message.html index e7cdaf07..652c3c6e 100644 --- a/doc/symbols/ROSLIB.Message.html +++ b/doc/symbols/ROSLIB.Message.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -322,7 +332,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.Param.html b/doc/symbols/ROSLIB.Param.html index 83fff972..6853539c 100644 --- a/doc/symbols/ROSLIB.Param.html +++ b/doc/symbols/ROSLIB.Param.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -438,7 +448,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.Pose.html b/doc/symbols/ROSLIB.Pose.html new file mode 100644 index 00000000..9a85063d --- /dev/null +++ b/doc/symbols/ROSLIB.Pose.html @@ -0,0 +1,419 @@ + + + + + + + JsDoc Reference - ROSLIB.Pose + + + + + + + + + + + + + +
    + +

    + + Class ROSLIB.Pose +

    + + +

    + + + + + + +
    Defined in: Pose.js. + +

    + + + + + + + + + + + + + + + + + +
    Class Summary
    Constructor AttributesConstructor Name and Description
      +
    + ROSLIB.Pose(position, orientation) +
    +
    A Pose in 3D space.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method Summary
    Method AttributesMethod Name and Description
      +
    copy(pose) +
    +
    Copy the values from the given pose into this pose.
    +
    + + + + + + + + + +
    +
    + Class Detail +
    + +
    + ROSLIB.Pose(position, orientation) +
    + +
    + A Pose in 3D space. Values are copied into this object. + +
    + + + + + +
    +
    Parameters:
    + +
    + position + +
    +
    - the ROSLIB.Vector3 describing the position
    + +
    + orientation + +
    +
    - the ROSLIB.Quaternion describing the orientation
    + +
    + + + + + + + + +
    + + + + + + + +
    + Method Detail +
    + + +
    + + + copy(pose) + +
    +
    + Copy the values from the given pose into this pose. + + +
    + + + + +
    +
    Parameters:
    + +
    + pose + +
    +
    the pose to copy
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to this pose
    + +
    + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT) +
    + + diff --git a/doc/symbols/ROSLIB.Quaternion.html b/doc/symbols/ROSLIB.Quaternion.html new file mode 100644 index 00000000..4634ef23 --- /dev/null +++ b/doc/symbols/ROSLIB.Quaternion.html @@ -0,0 +1,711 @@ + + + + + + + JsDoc Reference - ROSLIB.Quaternion + + + + + + + + + + + + + +
    + +

    + + Class ROSLIB.Quaternion +

    + + +

    + + + + + + +
    Defined in: Quaternion.js. + +

    + + + + + + + + + + + + + + + + + +
    Class Summary
    Constructor AttributesConstructor Name and Description
      +
    + ROSLIB.Quaternion(x, y, z, w) +
    +
    A Quaternion.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method Summary
    Method AttributesMethod Name and Description
      +
    clone() +
    +
    Clone a copy of this quaternion.
    +
      + +
    Perform a conjugation on this quaternion.
    +
      +
    copy(q) +
    +
    Copy the values from the given quaternion into this quaternion.
    +
      +
    inverse() +
    +
    Convert this quaternion into its inverse.
    +
      +
    multiply(a, b) +
    +
    Set the values of this quaternion to the product of quaternions a and b.
    +
      +
    multiplyVec3(vector, dest) +
    +
    Multiply the given ROSLIB.Vector3 with this quaternion.
    +
      + +
    Perform a normalization on this quaternion.
    +
    + + + + + + + + + +
    +
    + Class Detail +
    + +
    + ROSLIB.Quaternion(x, y, z, w) +
    + +
    + A Quaternion. + +
    + + + + + +
    +
    Parameters:
    + +
    + x + +
    +
    - the x value
    + +
    + y + +
    +
    - the y value
    + +
    + z + +
    +
    - the z value
    + +
    + w + +
    +
    - the w value
    + +
    + + + + + + + + +
    + + + + + + + +
    + Method Detail +
    + + +
    + + + clone() + +
    +
    + Clone a copy of this quaternion. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    the cloned quaternion
    + +
    + + + + +
    + + +
    + + + conjugate() + +
    +
    + Perform a conjugation on this quaternion. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    a pointer to this quaternion
    + +
    + + + + +
    + + +
    + + + copy(q) + +
    +
    + Copy the values from the given quaternion into this quaternion. + + +
    + + + + +
    +
    Parameters:
    + +
    + q + +
    +
    the quaternion to copy
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to this quaternion
    + +
    + + + + +
    + + +
    + + + inverse() + +
    +
    + Convert this quaternion into its inverse. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    a pointer to this quaternion
    + +
    + + + + +
    + + +
    + + + multiply(a, b) + +
    +
    + Set the values of this quaternion to the product of quaternions a and b. + + +
    + + + + +
    +
    Parameters:
    + +
    + a + +
    +
    the first quaternion to multiply with
    + +
    + b + +
    +
    the second quaternion to multiply with
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to this quaternion
    + +
    + + + + +
    + + +
    + + + multiplyVec3(vector, dest) + +
    +
    + Multiply the given ROSLIB.Vector3 with this quaternion. + + +
    + + + + +
    +
    Parameters:
    + +
    + vector + +
    +
    the vector to multiply with
    + +
    + dest + +
    +
    (option) - where the computed values will go (defaults to 'vector').
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to dest
    + +
    + + + + +
    + + +
    + + + normalize() + +
    +
    + Perform a normalization on this quaternion. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    a pointer to this quaternion
    + +
    + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT) +
    + + diff --git a/doc/symbols/ROSLIB.Ros.html b/doc/symbols/ROSLIB.Ros.html index e1199733..b629df1a 100644 --- a/doc/symbols/ROSLIB.Ros.html +++ b/doc/symbols/ROSLIB.Ros.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -931,7 +941,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.Service.html b/doc/symbols/ROSLIB.Service.html index 50e104af..744996d5 100644 --- a/doc/symbols/ROSLIB.Service.html +++ b/doc/symbols/ROSLIB.Service.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -397,7 +407,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.ServiceRequest.html b/doc/symbols/ROSLIB.ServiceRequest.html index bdca0f79..f9da5f07 100644 --- a/doc/symbols/ROSLIB.ServiceRequest.html +++ b/doc/symbols/ROSLIB.ServiceRequest.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -322,7 +332,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.ServiceResponse.html b/doc/symbols/ROSLIB.ServiceResponse.html index 36243f65..738574f0 100644 --- a/doc/symbols/ROSLIB.ServiceResponse.html +++ b/doc/symbols/ROSLIB.ServiceResponse.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -322,7 +332,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.TFClient.html b/doc/symbols/ROSLIB.TFClient.html new file mode 100644 index 00000000..1e9fb394 --- /dev/null +++ b/doc/symbols/ROSLIB.TFClient.html @@ -0,0 +1,498 @@ + + + + + + + JsDoc Reference - ROSLIB.TFClient + + + + + + + + + + + + + +
    + +

    + + Class ROSLIB.TFClient +

    + + +

    + + + + + + +
    Defined in: TFClient.js. + +

    + + + + + + + + + + + + + + + + + +
    Class Summary
    Constructor AttributesConstructor Name and Description
      +
    + ROSLIB.TFClient(options) +
    +
    A TF Client that listens to TFs from tf2_web_republisher.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method Summary
    Method AttributesMethod Name and Description
      + +
    Process the incoming TF message and send them out using the callback functions.
    +
      +
    subscribe(frameID, callback) +
    +
    Subscribe to the given TF frame.
    +
      + +
    Create and send a new goal to the tf2_web_republisher based on the current list of TFs.
    +
    + + + + + + + + + +
    +
    + Class Detail +
    + +
    + ROSLIB.TFClient(options) +
    + +
    + A TF Client that listens to TFs from tf2_web_republisher. + +
    + + + + + +
    +
    Parameters:
    + +
    + options + +
    +
    - object with following keys: + * ros - the ROSLIB.Ros connection handle + * fixedFrame - the fixed frame, like /base_link + * angularThres - the angular threshold for the TF republisher + * transThres - the translation threshold for the TF republisher + * rate - the rate for the TF republisher + * goalUpdateDelay - the goal update delay for the TF republisher
    + +
    + + + + + + + + +
    + + + + + + + +
    + Method Detail +
    + + +
    + + + processFeedback(tf) + +
    +
    + Process the incoming TF message and send them out using the callback functions. + + +
    + + + + +
    +
    Parameters:
    + +
    + tf + +
    +
    - the TF message from the server
    + +
    + + + + + + + + +
    + + +
    + + + subscribe(frameID, callback) + +
    +
    + Subscribe to the given TF frame. + + +
    + + + + +
    +
    Parameters:
    + +
    + frameID + +
    +
    - the TF frame to subscribe to
    + +
    + callback + +
    +
    - function with params: + * transform - the transform data
    + +
    + + + + + + + + +
    + + +
    + + + updateGoal() + +
    +
    + Create and send a new goal to the tf2_web_republisher based on the current list of TFs. + + +
    + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT) +
    + + diff --git a/doc/symbols/ROSLIB.Topic.html b/doc/symbols/ROSLIB.Topic.html index a321fb01..fd9b8a9f 100644 --- a/doc/symbols/ROSLIB.Topic.html +++ b/doc/symbols/ROSLIB.Topic.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -550,7 +560,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT)
    diff --git a/doc/symbols/ROSLIB.Transform.html b/doc/symbols/ROSLIB.Transform.html new file mode 100644 index 00000000..07029505 --- /dev/null +++ b/doc/symbols/ROSLIB.Transform.html @@ -0,0 +1,523 @@ + + + + + + + JsDoc Reference - ROSLIB.Transform + + + + + + + + + + + + + +
    + +

    + + Class ROSLIB.Transform +

    + + +

    + + + + + + +
    Defined in: Transform.js. + +

    + + + + + + + + + + + + + + + + + +
    Class Summary
    Constructor AttributesConstructor Name and Description
      +
    + ROSLIB.Transform(translation, rotation) +
    +
    A Transform in 3-space.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method Summary
    Method AttributesMethod Name and Description
      +
    apply(pose) +
    +
    Apply a transform against the given ROSLIB.Pose.
    +
      +
    applyInverse(pose) +
    +
    Apply an inverse transform against the given ROSLIB.Pose.
    +
      +
    copy(transform) +
    +
    Copy the values from the given transform into this transform.
    +
    + + + + + + + + + +
    +
    + Class Detail +
    + +
    + ROSLIB.Transform(translation, rotation) +
    + +
    + A Transform in 3-space. Values are copied into this object. + +
    + + + + + +
    +
    Parameters:
    + +
    + translation + +
    +
    - the ROSLIB.Vector3 describing the translation
    + +
    + rotation + +
    +
    - the ROSLIB.Quaternion describing the rotation
    + +
    + + + + + + + + +
    + + + + + + + +
    + Method Detail +
    + + +
    + + + apply(pose) + +
    +
    + Apply a transform against the given ROSLIB.Pose. + + +
    + + + + +
    +
    Parameters:
    + +
    + pose + +
    +
    the pose to transform with
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to the pose
    + +
    + + + + +
    + + +
    + + + applyInverse(pose) + +
    +
    + Apply an inverse transform against the given ROSLIB.Pose. + + +
    + + + + +
    +
    Parameters:
    + +
    + pose + +
    +
    the pose to transform with
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to the pose
    + +
    + + + + +
    + + +
    + + + copy(transform) + +
    +
    + Copy the values from the given transform into this transform. + + +
    + + + + +
    +
    Parameters:
    + +
    + transform + +
    +
    the transform to copy
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to this transform
    + +
    + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT) +
    + + diff --git a/doc/symbols/ROSLIB.Vector3.html b/doc/symbols/ROSLIB.Vector3.html new file mode 100644 index 00000000..ea9b2acf --- /dev/null +++ b/doc/symbols/ROSLIB.Vector3.html @@ -0,0 +1,582 @@ + + + + + + + JsDoc Reference - ROSLIB.Vector3 + + + + + + + + + + + + + +
    + +

    + + Class ROSLIB.Vector3 +

    + + +

    + + + + + + +
    Defined in: Vector3.js. + +

    + + + + + + + + + + + + + + + + + +
    Class Summary
    Constructor AttributesConstructor Name and Description
      +
    + ROSLIB.Vector3(x, y, z) +
    +
    A 3D vector.
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method Summary
    Method AttributesMethod Name and Description
      +
    add(a, b) +
    +
    Set the values of this vector to the sum of vectors a and b.
    +
      +
    clone() +
    +
    Clone a copy of this vector.
    +
      +
    copy(v) +
    +
    Copy the values from the given vector into this vector.
    +
      +
    sub(a, b) +
    +
    Set the values of this vector to the difference of vectors a and b.
    +
    + + + + + + + + + +
    +
    + Class Detail +
    + +
    + ROSLIB.Vector3(x, y, z) +
    + +
    + A 3D vector. + +
    + + + + + +
    +
    Parameters:
    + +
    + x + +
    +
    - the x value
    + +
    + y + +
    +
    - the y value
    + +
    + z + +
    +
    - the z value
    + +
    + + + + + + + + +
    + + + + + + + +
    + Method Detail +
    + + +
    + + + add(a, b) + +
    +
    + Set the values of this vector to the sum of vectors a and b. + + +
    + + + + +
    +
    Parameters:
    + +
    + a + +
    +
    the first vector to add with
    + +
    + b + +
    +
    the second vector to add with
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to this vector
    + +
    + + + + +
    + + +
    + + + clone() + +
    +
    + Clone a copy of this vector. + + +
    + + + + + + + + +
    +
    Returns:
    + +
    the cloned vector
    + +
    + + + + +
    + + +
    + + + copy(v) + +
    +
    + Copy the values from the given vector into this vector. + + +
    + + + + +
    +
    Parameters:
    + +
    + v + +
    +
    the vector to copy
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to this vector
    + +
    + + + + +
    + + +
    + + + sub(a, b) + +
    +
    + Set the values of this vector to the difference of vectors a and b. + + +
    + + + + +
    +
    Parameters:
    + +
    + a + +
    +
    the first vector to add with
    + +
    + b + +
    +
    the second vector to add with
    + +
    + + + + + +
    +
    Returns:
    + +
    a pointer to this vector
    + +
    + + + + + + + + + + + +
    +
    + + + +
    + + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:24 GMT-0700 (PDT) +
    + + diff --git a/doc/symbols/_global_.html b/doc/symbols/_global_.html index fdab0c9e..db554c22 100644 --- a/doc/symbols/_global_.html +++ b/doc/symbols/_global_.html @@ -199,6 +199,10 @@

    Classes

  • ROSLIB.Param
  • +
  • ROSLIB.Pose
  • + +
  • ROSLIB.Quaternion
  • +
  • ROSLIB.Ros
  • ROSLIB.Service
  • @@ -207,8 +211,14 @@

    Classes

  • ROSLIB.ServiceResponse
  • +
  • ROSLIB.TFClient
  • +
  • ROSLIB.Topic
  • +
  • ROSLIB.Transform
  • + +
  • ROSLIB.Vector3
  • +
    @@ -319,7 +329,7 @@

    - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 14:57:47 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 15 2013 16:59:23 GMT-0700 (PDT)
    diff --git a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_actionlib_Goal.js.html b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_actionlib_Goal.js.html index 663f9047..9e27a3c5 100644 --- a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_actionlib_Goal.js.html +++ b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_actionlib_Goal.js.html @@ -47,7 +47,7 @@ 40 }; 41 42 /** - 43 * Cancel the current this. + 43 * Cancel the current goal. 44 */ 45 this.cancel = function() { 46 var cancelMessage = new ROSLIB.Message({ diff --git a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Pose.js.html b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Pose.js.html new file mode 100644 index 00000000..ccb28663 --- /dev/null +++ b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Pose.js.html @@ -0,0 +1,43 @@ +
      1 /**
    +  2  * @author David Gossow - dgossow@willowgarage.com
    +  3  */
    +  4 
    +  5 /**
    +  6  * A Pose in 3D space. Values are copied into this object.
    +  7  *
    +  8  *  @constructor
    +  9  *  @param position - the ROSLIB.Vector3 describing the position
    + 10  *  @param orientation - the ROSLIB.Quaternion describing the orientation
    + 11  */
    + 12 ROSLIB.Pose = function(position, orientation) {
    + 13   var pose = this;
    + 14   // copy the values into this object if they exist
    + 15   this.position = new ROSLIB.Vector3();
    + 16   this.orientation = new ROSLIB.Quaternion();
    + 17   if (position !== undefined) {
    + 18     this.position.copy(position);
    + 19   }
    + 20   if (orientation !== undefined) {
    + 21     this.orientation.copy(orientation);
    + 22   }
    + 23 
    + 24   /**
    + 25    * Copy the values from the given pose into this pose.
    + 26    * 
    + 27    * @param pose the pose to copy
    + 28    * @returns a pointer to this pose
    + 29    */
    + 30   this.copy = function(pose) {
    + 31     pose.position.copy(pose.position);
    + 32     pose.orientation.copy(pose.orientation);
    + 33     return pose;
    + 34   };
    + 35 };
    + 36 
    \ No newline at end of file diff --git a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Quaternion.js.html b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Quaternion.js.html new file mode 100644 index 00000000..77a30405 --- /dev/null +++ b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Quaternion.js.html @@ -0,0 +1,132 @@ +
      1 /**
    +  2  * @author David Gossow - dgossow@willowgarage.com
    +  3  */
    +  4 
    +  5 /**
    +  6  * A Quaternion.
    +  7  *
    +  8  *  @constructor
    +  9  *  @param x - the x value 
    + 10  *  @param y - the y value
    + 11  *  @param z - the z value
    + 12  *  @param w - the w value
    + 13  */
    + 14 ROSLIB.Quaternion = function(x, y, z, w) {
    + 15   var quaternion = this;
    + 16   this.x = x || 0;
    + 17   this.y = y || 0;
    + 18   this.z = z || 0;
    + 19   this.w = w || 1;
    + 20 
    + 21   /**
    + 22    * Copy the values from the given quaternion into this quaternion.
    + 23    * 
    + 24    * @param q the quaternion to copy
    + 25    * @returns a pointer to this quaternion
    + 26    */
    + 27   this.copy = function(q) {
    + 28     quaternion.x = q.x;
    + 29     quaternion.y = q.y;
    + 30     quaternion.z = q.z;
    + 31     quaternion.w = q.w;
    + 32     return quaternion;
    + 33   };
    + 34 
    + 35   /**
    + 36    * Perform a conjugation on this quaternion.
    + 37    * 
    + 38    * @returns a pointer to this quaternion
    + 39    */
    + 40   this.conjugate = function() {
    + 41     quaternion.x *= -1;
    + 42     quaternion.y *= -1;
    + 43     quaternion.z *= -1;
    + 44     return quaternion;
    + 45   };
    + 46 
    + 47   /**
    + 48    * Perform a normalization on this quaternion.
    + 49    * 
    + 50    * @returns a pointer to this quaternion
    + 51    */
    + 52   this.normalize = function() {
    + 53     var l = Math.sqrt(quaternion.x * quaternion.x + quaternion.y * quaternion.y + quaternion.z
    + 54         * quaternion.z + quaternion.w * quaternion.w);
    + 55     if (l === 0) {
    + 56       quaternion.x = 0;
    + 57       quaternion.y = 0;
    + 58       quaternion.z = 0;
    + 59       quaternion.w = 1;
    + 60     } else {
    + 61       l = 1 / l;
    + 62       quaternion.x = quaternion.x * l;
    + 63       quaternion.y = quaternion.y * l;
    + 64       quaternion.z = quaternion.z * l;
    + 65       quaternion.w = quaternion.w * l;
    + 66     }
    + 67     return quaternion;
    + 68   };
    + 69 
    + 70   /**
    + 71    * Convert this quaternion into its inverse.
    + 72    * 
    + 73    * @returns a pointer to this quaternion
    + 74    */
    + 75   this.inverse = function() {
    + 76     this.conjugate().normalize();
    + 77     return quaternion;
    + 78   };
    + 79 
    + 80   /**
    + 81    * Set the values of this quaternion to the product of quaternions a and b.
    + 82    * 
    + 83    * @param a the first quaternion to multiply with
    + 84    * @param b the second quaternion to multiply with
    + 85    * @returns a pointer to this quaternion
    + 86    */
    + 87   this.multiply = function(a, b) {
    + 88     var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w, qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
    + 89     this.x = qax * qbw + qay * qbz - qaz * qby + qaw * qbx;
    + 90     this.y = -qax * qbz + qay * qbw + qaz * qbx + qaw * qby;
    + 91     this.z = qax * qby - qay * qbx + qaz * qbw + qaw * qbz;
    + 92     this.w = -qax * qbx - qay * qby - qaz * qbz + qaw * qbw;
    + 93     return quaternion;
    + 94   };
    + 95 
    + 96   /**
    + 97    * Multiply the given ROSLIB.Vector3 with this quaternion.
    + 98    * 
    + 99    * @param vector the vector to multiply with
    +100    * @param dest (option) - where the computed values will go (defaults to 'vector').
    +101    * @returns a pointer to dest
    +102    */
    +103   this.multiplyVec3 = function(vector, dest) {
    +104     if (!dest) {
    +105       dest = vector;
    +106     }
    +107     var x = vector.x, y = vector.y, z = vector.z, qx = quaternion.x, qy = quaternion.y, qz = quaternion.z, qw = quaternion.w;
    +108     var ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx
    +109         * x - qy * y - qz * z;
    +110     dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
    +111     dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
    +112     dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
    +113     return dest;
    +114   };
    +115 
    +116   /**
    +117    * Clone a copy of this quaternion.
    +118    * 
    +119    * @returns the cloned quaternion
    +120    */
    +121   this.clone = function() {
    +122     return new ROSLIB.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
    +123   };
    +124 };
    +125 
    \ No newline at end of file diff --git a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Vector3.js.html b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Vector3.js.html new file mode 100644 index 00000000..7d286250 --- /dev/null +++ b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_math_Vector3.js.html @@ -0,0 +1,76 @@ +
      1 /**
    +  2  * @author David Gossow - dgossow@willowgarage.com
    +  3  */
    +  4 
    +  5 /**
    +  6  * A 3D vector.
    +  7  *
    +  8  *  @constructor
    +  9  *  @param x - the x value 
    + 10  *  @param y - the y value
    + 11  *  @param z - the z value
    + 12  */
    + 13 ROSLIB.Vector3 = function(x, y, z) {
    + 14   var vector3 = this;
    + 15   this.x = x || 0;
    + 16   this.y = y || 0;
    + 17   this.z = z || 0;
    + 18 
    + 19   /**
    + 20    * Copy the values from the given vector into this vector.
    + 21    * 
    + 22    * @param v the vector to copy
    + 23    * @returns a pointer to this vector
    + 24    */
    + 25   this.copy = function(v) {
    + 26     vector3.x = v.x;
    + 27     vector3.y = v.y;
    + 28     vector3.z = v.z;
    + 29     return vector3;
    + 30   };
    + 31 
    + 32   /**
    + 33    * Set the values of this vector to the sum of vectors a and b.
    + 34    * 
    + 35    * @param a the first vector to add with
    + 36    * @param b the second vector to add with
    + 37    * @returns a pointer to this vector
    + 38    */
    + 39   this.add = function(a, b) {
    + 40     vector3.x = a.x + b.x;
    + 41     vector3.y = a.y + b.y;
    + 42     vector3.z = a.z + b.z;
    + 43     return vector3;
    + 44   };
    + 45 
    + 46   /**
    + 47    * Set the values of this vector to the difference of vectors a and b.
    + 48    * 
    + 49    * @param a the first vector to add with
    + 50    * @param b the second vector to add with
    + 51    * @returns a pointer to this vector
    + 52    */
    + 53   this.sub = function(a, b) {
    + 54     vector3.x = a.x - b.x;
    + 55     vector3.y = a.y - b.y;
    + 56     vector3.z = a.z - b.z;
    + 57     return vector3;
    + 58   };
    + 59 
    + 60   /**
    + 61    * Clone a copy of this vector.
    + 62    * 
    + 63    * @returns the cloned vector
    + 64    */
    + 65   this.clone = function() {
    + 66     return new ROSLIB.Vector3(vector3.x, vector3.y, vector3.z);
    + 67   };
    + 68 };
    + 69 
    \ No newline at end of file diff --git a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_TFClient.js.html b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_TFClient.js.html new file mode 100644 index 00000000..4bf1fcfa --- /dev/null +++ b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_TFClient.js.html @@ -0,0 +1,144 @@ +
      1 /**
    +  2  * @author David Gossow - dgossow@willowgarage.com
    +  3  */
    +  4 
    +  5 /**
    +  6  * A TF Client that listens to TFs from tf2_web_republisher.
    +  7  *
    +  8  *  @constructor
    +  9  *  @param options - object with following keys:
    + 10  *   * ros - the ROSLIB.Ros connection handle
    + 11  *   * fixedFrame - the fixed frame, like /base_link
    + 12  *   * angularThres - the angular threshold for the TF republisher
    + 13  *   * transThres - the translation threshold for the TF republisher
    + 14  *   * rate - the rate for the TF republisher
    + 15  *   * goalUpdateDelay - the goal update delay for the TF republisher
    + 16  */
    + 17 ROSLIB.TFClient = function(options) {
    + 18   var tfClient = this;
    + 19   var options = options || {};
    + 20   this.ros = options.ros;
    + 21   this.fixedFrame = options.fixedFrame || '/base_link';
    + 22   this.angularThres = options.angularThres || 2.0;
    + 23   this.transThres = options.transThres || 0.01;
    + 24   this.rate = options.rate || 10.0;
    + 25   this.goalUpdateDelay = options.goalUpdateDelay || 50;
    + 26 
    + 27   this.currentGoal = false;
    + 28   this.frameInfos = {};
    + 29   this.goalUpdateRequested = false;
    + 30 
    + 31   // create an ActionClient
    + 32   this.actionClient = new ROSLIB.ActionClient({
    + 33     ros : this.ros,
    + 34     serverName : '/tf2_web_republisher',
    + 35     actionName : 'tf2_web_republisher/TFSubscriptionAction'
    + 36   });
    + 37 
    + 38   /**
    + 39    * Process the incoming TF message and send them out using the callback functions.
    + 40    * 
    + 41    * @param tf - the TF message from the server
    + 42    */
    + 43   this.processFeedback = function(tf) {
    + 44     tf.transforms.forEach(function(transform) {
    + 45       var frameID = transform.child_frame_id;
    + 46       var info = tfClient.frameInfos[frameID];
    + 47       if (info != undefined) {
    + 48         info.transform = new ROSLIB.Transform(transform.transform.translation,
    + 49             transform.transform.rotation);
    + 50         info.cbs.forEach(function(cb) {
    + 51           cb(info.transform);
    + 52         });
    + 53       }
    + 54     });
    + 55   };
    + 56 
    + 57   /**
    + 58    * Create and send a new goal to the tf2_web_republisher based on the current list of TFs.
    + 59    */
    + 60   this.updateGoal = function() {
    + 61     // Anytime the list of frames changes, we will need to send a new goal.
    + 62     if (tfClient.currentGoal) {
    + 63       tfClient.currentGoal.cancel();
    + 64     }
    + 65 
    + 66     var goalMessage = {
    + 67       source_frames : [],
    + 68       target_frame : tfClient.fixedFrame,
    + 69       angular_thres : tfClient.angularThres,
    + 70       trans_thres : tfClient.transThres,
    + 71       rate : tfClient.rate
    + 72     };
    + 73 
    + 74     for (frame in tfClient.frameInfos) {
    + 75       goalMessage.source_frames.push(frame);
    + 76     }
    + 77 
    + 78     tfClient.currentGoal = new ROSLIB.Goal({
    + 79       actionClient : tfClient.actionClient,
    + 80       goalMessage : goalMessage
    + 81     });
    + 82     tfClient.currentGoal.on('feedback', tfClient.processFeedback.bind(tfClient));
    + 83     tfClient.currentGoal.send();
    + 84     tfClient.goalUpdateRequested = false;
    + 85   };
    + 86 
    + 87   /**
    + 88    * Subscribe to the given TF frame.
    + 89    * 
    + 90    * @param frameID - the TF frame to subscribe to
    + 91    * @param callback - function with params:
    + 92    *   * transform - the transform data
    + 93    */
    + 94   this.subscribe = function(frameID, callback) {
    + 95     // make sure the frame id is relative
    + 96     if (frameID[0] === '/') {
    + 97       frameID = frameID.substring(1);
    + 98     }
    + 99     // if there is no callback registered for the given frame, create emtpy callback list
    +100     if (tfClient.frameInfos[frameID] == undefined) {
    +101       tfClient.frameInfos[frameID] = {
    +102         cbs : []
    +103       };
    +104       if (!tfClient.goalUpdateRequested) {
    +105         setTimeout(tfClient.updateGoal.bind(tfClient), tfClient.goalUpdateDelay);
    +106         tfClient.goalUpdateRequested = true;
    +107       }
    +108     } else {
    +109       // if we already have a transform, call back immediately
    +110       if (tfClient.frameInfos[frameID].transform != undefined) {
    +111         callback(tfClient.frameInfos[frameID].transform);
    +112       }
    +113     }
    +114     tfClient.frameInfos[frameID].cbs.push(callback);
    +115   };
    +116 
    +117   /**
    +118    * Unsubscribe from the given TF frame.
    +119    * 
    +120    * @param frameID - the TF frame to unsubscribe from
    +121    * @param callback - the callback function to remove
    +122    */
    +123   tfClient.unsubscribe = function(frameID, callback) {
    +124     var info = tfClient.frameInfos[frameID];
    +125     if (info != undefined) {
    +126       var cbIndex = info.cbs.indexOf(callback);
    +127       if (cbIndex >= 0) {
    +128         info.cbs.splice(cbIndex, 1);
    +129         if (info.cbs.length == 0) {
    +130           delete tfClient.frameInfos[frameID];
    +131         }
    +132         tfClient.needUpdate = true;
    +133       }
    +134     }
    +135   };
    +136 };
    +137 
    \ No newline at end of file diff --git a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_TfClient.js.html b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_TfClient.js.html deleted file mode 100644 index 141109a5..00000000 --- a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_TfClient.js.html +++ /dev/null @@ -1,275 +0,0 @@ -
      1 (function (root, factory) {
    -  2   if (typeof define === 'function' && define.amd) {
    -  3     define(['robotwebtools/eventemitter2','robotwebtools/actionclient'], factory);
    -  4   }
    -  5   else {
    -  6     root.TfClient = factory(root.EventEmitter2,root.ActionClient);
    -  7   }
    -  8 }(this, function (EventEmitter2, ActionClient) {
    -  9 
    - 10   var TfClient = function(options) {
    - 11     this.ros = options.ros;
    - 12     this.fixedFrame = options.fixedFrame || 'base_link';
    - 13     this.angularThres = options.angularThres || 2.0;
    - 14     this.transThres = options.transThres || 0.01;
    - 15     this.rate = options.rate || 10.0;
    - 16     this.goalUpdateDelay = options.goalUpdateDelay !== undefined ? options.goalUpdateDelay : 50;
    - 17 
    - 18     var options = {
    - 19       ros: this.ros,
    - 20       serverName: options.serverName || "/tf2_web_republisher",
    - 21       actionName: "tf2_web_republisher/TFSubscriptionAction"
    - 22     };
    - 23 
    - 24     this.actionClient = new ActionClient( options );
    - 25     this.currentGoal = false;
    - 26     this.frame_infos = {};
    - 27     this.goalUpdateRequested = false;
    - 28   };
    - 29 
    - 30   TfClient.prototype.__proto__ = EventEmitter2.prototype;
    - 31 
    - 32   TfClient.prototype.processFeedback = function(tfMsg) {
    - 33     var that = this;
    - 34     tfMsg.transforms.forEach( function(transform) {
    - 35       var frameId = transform.child_frame_id;
    - 36       var info = that.frame_infos[frameId];
    - 37       if ( info != undefined ) {
    - 38         info.transform = new Transform(transform.transform.translation,transform.transform.rotation);
    - 39         info.cbs.forEach(function(cb) {
    - 40           cb(info.transform);
    - 41         });
    - 42       }
    - 43     });
    - 44   }
    - 45 
    - 46   TfClient.prototype.requestGoalUpdate = function() {
    - 47     if ( !this.goalUpdateRequested ) {
    - 48       setTimeout(this.updateGoal.bind(this), this.goalUpdateDelay);
    - 49       this.goalUpdateRequested = true;
    - 50       return;
    - 51     }
    - 52   }
    - 53 
    - 54   TfClient.prototype.updateGoal = function() {
    - 55     // Anytime the list of frames changes,
    - 56     // we will need to send a new goal.
    - 57     if ( this.currentGoal ) {
    - 58       this.currentGoal.cancel();
    - 59     }
    - 60 
    - 61     var goalMsg = {
    - 62       source_frames: [],
    - 63        target_frame: this.fixedFrame,
    - 64        angular_thres: this.angularThres,
    - 65        trans_thres: this.transThres,
    - 66        rate: this.rate
    - 67     };
    - 68 
    - 69     var source_frames = [];
    - 70     for (frame in this.frame_infos ) {
    - 71       goalMsg.source_frames.push(frame);
    - 72     };
    - 73 
    - 74     this.currentGoal = new this.actionClient.Goal(goalMsg);
    - 75     this.currentGoal.on('feedback', this.processFeedback.bind(this));
    - 76     this.currentGoal.send();
    - 77     this.goalUpdateRequested = false;
    - 78   }
    - 79 
    - 80   TfClient.prototype.subscribe = function(frameId,callback) {
    - 81     // make sure the frame id is relative
    - 82     if ( frameId[0] === "/" ) {
    - 83       frameId = frameId.substring(1);
    - 84     }
    - 85     // if there is no callback registered for the given frame,
    - 86     // create emtpy callback list
    - 87     if ( this.frame_infos[frameId] == undefined ) {
    - 88       this.frame_infos[frameId] = {
    - 89         cbs: [] };
    - 90       this.requestGoalUpdate();
    - 91     } else {
    - 92       // if we already have a transform, call back immediately
    - 93       if ( this.frame_infos[frameId].transform != undefined ) {
    - 94         callback( this.frame_infos[frameId].transform );
    - 95       }
    - 96     }
    - 97     this.frame_infos[frameId].cbs.push( callback );
    - 98   };
    - 99 
    -100   TfClient.prototype.unsubscribe = function(frameId,callback) {
    -101     var info = this.frame_infos[frameId];
    -102     if ( info != undefined ) {
    -103       var cbIndex = info.cbs.indexOf( callback );
    -104       if ( cbIndex >= 0 ) {
    -105         info.cbs.splice(cbIndex, 1);
    -106         if ( info.cbs.length == 0 ) {
    -107           delete this.frame_infos[frameId];
    -108         }
    -109       this.needUpdate = true;
    -110       }
    -111     }
    -112   }
    -113 
    -114 
    -115   var Pose = TfClient.Pose = function( position, orientation ) {
    -116     this.position = new Vector3;
    -117     this.orientation = new Quaternion;
    -118     if ( position !== undefined ) {
    -119       this.position.copy( position );
    -120     }
    -121     if ( orientation !== undefined ) {
    -122       this.orientation.copy( orientation );
    -123     }
    -124   };
    -125 
    -126   Pose.prototype = {
    -127     constructor: Pose,
    -128     copy: function( pose ) {
    -129       this.position.copy( pose.position );
    -130       this.orientation.copy( pose.orientation );
    -131     }
    -132   }
    -133 
    -134   var Transform = TfClient.Transform = function( translation, rotation ) {
    -135     this.translation = new Vector3;
    -136     this.rotation = new Quaternion;
    -137     if ( translation !== undefined ) {
    -138       this.translation.copy( translation );
    -139     }
    -140     if ( rotation !== undefined ) {
    -141       this.rotation.copy( rotation );
    -142     }
    -143   };
    -144 
    -145   Transform.prototype = {
    -146     constructor: Transform,
    -147     apply: function( pose ) {
    -148       this.rotation.multiplyVec3(pose.position);
    -149       pose.position.add(pose.position,this.translation);
    -150       pose.orientation.multiply(this.rotation, pose.orientation);
    -151       return pose;
    -152     },
    -153     applyInverse: function( pose ) {
    -154       var rotInv = this.rotation.clone().inverse();
    -155       rotInv.multiplyVec3(pose.position);
    -156       pose.position.sub(pose.position,this.translation);
    -157       pose.orientation.multiply(rotInv, pose.orientation);
    -158       return pose;
    -159     },
    -160     copy: function( transform ) {
    -161       this.translation.copy( transform.translation );
    -162       this.rotation.copy( transform.rotation );
    -163     }
    -164   }
    -165 
    -166   var Quaternion = TfClient.Quaternion = function( x, y, z, w ) {
    -167     this.x = x || 0;
    -168     this.y = y || 0;
    -169     this.z = z || 0;
    -170     this.w = ( w !== undefined ) ? w : 1;
    -171   };
    -172 
    -173   Quaternion.prototype = {
    -174     constructor: Quaternion,
    -175     copy: function ( q ) {
    -176       this.x = q.x;
    -177       this.y = q.y;
    -178       this.z = q.z;
    -179       this.w = q.w;
    -180       return this;
    -181     },
    -182     inverse: function () {
    -183       this.conjugate().normalize();
    -184       return this;
    -185     },
    -186     conjugate: function () {
    -187       this.x *= -1;
    -188       this.y *= -1;
    -189       this.z *= -1;
    -190       return this;
    -191     },
    -192     normalize: function () {
    -193       var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
    -194       if ( l === 0 ) {
    -195         this.x = 0;
    -196         this.y = 0;
    -197         this.z = 0;
    -198         this.w = 1;
    -199       } else {
    -200         l = 1 / l;
    -201         this.x = this.x * l;
    -202         this.y = this.y * l;
    -203         this.z = this.z * l;
    -204         this.w = this.w * l;
    -205       }
    -206       return this;
    -207     },
    -208     multiply: function ( a, b ) {
    -209       var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w,
    -210       qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
    -211       this.x =  qax * qbw + qay * qbz - qaz * qby + qaw * qbx;
    -212       this.y = -qax * qbz + qay * qbw + qaz * qbx + qaw * qby;
    -213       this.z =  qax * qby - qay * qbx + qaz * qbw + qaw * qbz;
    -214       this.w = -qax * qbx - qay * qby - qaz * qbz + qaw * qbw;
    -215       return this;
    -216     },
    -217     multiplyVec3: function ( vector, dest ) {
    -218       if ( !dest ) { dest = vector; }
    -219       var x    = vector.x,  y  = vector.y,  z  = vector.z,
    -220         qx   = this.x, qy = this.y, qz = this.z, qw = this.w;
    -221       var ix =  qw * x + qy * z - qz * y,
    -222         iy =  qw * y + qz * x - qx * z,
    -223         iz =  qw * z + qx * y - qy * x,
    -224         iw = -qx * x - qy * y - qz * z;
    -225       dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
    -226       dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
    -227       dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
    -228       return dest;
    -229     },
    -230     clone: function () {
    -231       return new Quaternion( this.x, this.y, this.z, this.w );
    -232     }
    -233   }
    -234 
    -235   var Vector3 = TfClient.Vector3 = function ( x, y, z ) {
    -236     this.x = x || 0;
    -237     this.y = y || 0;
    -238     this.z = z || 0;
    -239   };
    -240 
    -241   Vector3.prototype = {
    -242     constructor: Vector3,
    -243     copy: function ( v ) {
    -244       this.x = v.x;
    -245       this.y = v.y;
    -246       this.z = v.z;
    -247       return this;
    -248     },
    -249     add: function ( a, b ) {
    -250       this.x = a.x + b.x;
    -251       this.y = a.y + b.y;
    -252       this.z = a.z + b.z;
    -253       return this;
    -254     },
    -255     sub: function ( a, b ) {
    -256       this.x = a.x - b.x;
    -257       this.y = a.y - b.y;
    -258       this.z = a.z - b.z;
    -259       return this;
    -260     },
    -261     clone: function () {
    -262       return new Vector3( this.x, this.y, this.z );
    -263     }
    -264   };
    -265 
    -266   return TfClient;
    -267 }));
    -268 
    \ No newline at end of file diff --git a/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_Transform.js.html b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_Transform.js.html new file mode 100644 index 00000000..749358e7 --- /dev/null +++ b/doc/symbols/src/_home_tor1pal_Documents_WPI_RAIL_ROS_groovy_src_roslibjs_src_tf_Transform.js.html @@ -0,0 +1,70 @@ +
      1 /**
    +  2  * @author David Gossow - dgossow@willowgarage.com
    +  3  */
    +  4 
    +  5 /**
    +  6  * A Transform in 3-space. Values are copied into this object.
    +  7  *
    +  8  *  @constructor
    +  9  *  @param translation - the ROSLIB.Vector3 describing the translation
    + 10  *  @param rotation - the ROSLIB.Quaternion describing the rotation
    + 11  */
    + 12 ROSLIB.Transform = function(translation, rotation) {
    + 13   var transform = this;
    + 14   // copy the values into this object if they exist
    + 15   this.translation = new ROSLIB.Vector3();
    + 16   this.rotation = new ROSLIB.Quaternion();
    + 17   if (translation !== undefined) {
    + 18     this.translation.copy(translation);
    + 19   }
    + 20   if (rotation !== undefined) {
    + 21     this.rotation.copy(rotation);
    + 22   }
    + 23 
    + 24   /**
    + 25    * Apply a transform against the given ROSLIB.Pose.
    + 26    * 
    + 27    * @param pose the pose to transform with
    + 28    * @returns a pointer to the pose
    + 29    */
    + 30   this.apply = function(pose) {
    + 31     transform.rotation.multiplyVec3(pose.position);
    + 32     pose.position.add(pose.position, transform.translation);
    + 33     pose.orientation.multiply(transform.rotation, pose.orientation);
    + 34     return pose;
    + 35   };
    + 36 
    + 37   /**
    + 38    * Apply an inverse transform against the given ROSLIB.Pose.
    + 39    * 
    + 40    * @param pose the pose to transform with
    + 41    * @returns a pointer to the pose
    + 42    */
    + 43   this.applyInverse = function(pose) {
    + 44     var rotInv = transform.rotation.clone().inverse();
    + 45     rotInv.multiplyVec3(pose.position);
    + 46     pose.position.sub(pose.position, transform.translation);
    + 47     pose.orientation.multiply(rotInv, pose.orientation);
    + 48     return pose;
    + 49   };
    + 50 
    + 51   /**
    + 52    * Copy the values from the given transform into this transform.
    + 53    * 
    + 54    * @param transform the transform to copy
    + 55    * @returns a pointer to this transform
    + 56    */
    + 57   this.copy = function(transform) {
    + 58     transform.translation.copy(transform.translation);
    + 59     transform.rotation.copy(transform.rotation);
    + 60     return transform;
    + 61   };
    + 62 };
    + 63 
    \ No newline at end of file diff --git a/examples/math.html b/examples/math.html new file mode 100644 index 00000000..29e402be --- /dev/null +++ b/examples/math.html @@ -0,0 +1,35 @@ + + + + + + + + + + + +

    Simple Math Example

    +

    Check the JavaScript console for the output.

    + + \ No newline at end of file diff --git a/examples/tf.html b/examples/tf.html new file mode 100644 index 00000000..9eb460d4 --- /dev/null +++ b/examples/tf.html @@ -0,0 +1,54 @@ + + + + + + + + + + + +

    Simple TF Example

    +

    Run the following commands in the terminal then refresh this page. Check the JavaScript + console for the output.

    +
      +
    1. roslaunch turtle_tf turtle_tf_demo.launch
    2. +
    3. rosrun tf2_web_republisher tf2_web_republisher
    4. +
    5. roslaunch rosbridge_server rosbridge_websocket.launch
    6. +
    7. Use your arrow keys on your keyboard to move the turtle (must have + turtle_tf_demo.launch terminal focused).
    8. +
    + + \ No newline at end of file diff --git a/include/EventEmitter2/eventemitter2.js b/include/EventEmitter2/eventemitter2.js index ba83369e..0ba02143 100644 --- a/include/EventEmitter2/eventemitter2.js +++ b/include/EventEmitter2/eventemitter2.js @@ -451,7 +451,7 @@ } if(this.wildcard) { - leaf._listeners.splice(position, 1) + leaf._listeners.splice(position, 1); } else { this._events[type].splice(position, 1); diff --git a/src/actionlib/Goal.js b/src/actionlib/Goal.js index 0a0fb6a1..e5831068 100644 --- a/src/actionlib/Goal.js +++ b/src/actionlib/Goal.js @@ -40,7 +40,7 @@ ROSLIB.Goal = function(options) { }; /** - * Cancel the current this. + * Cancel the current goal. */ this.cancel = function() { var cancelMessage = new ROSLIB.Message({ diff --git a/src/math/Pose.js b/src/math/Pose.js new file mode 100644 index 00000000..30cfc743 --- /dev/null +++ b/src/math/Pose.js @@ -0,0 +1,35 @@ +/** + * @author David Gossow - dgossow@willowgarage.com + */ + +/** + * A Pose in 3D space. Values are copied into this object. + * + * @constructor + * @param position - the ROSLIB.Vector3 describing the position + * @param orientation - the ROSLIB.Quaternion describing the orientation + */ +ROSLIB.Pose = function(position, orientation) { + var pose = this; + // copy the values into this object if they exist + this.position = new ROSLIB.Vector3(); + this.orientation = new ROSLIB.Quaternion(); + if (position !== undefined) { + this.position.copy(position); + } + if (orientation !== undefined) { + this.orientation.copy(orientation); + } + + /** + * Copy the values from the given pose into this pose. + * + * @param pose the pose to copy + * @returns a pointer to this pose + */ + this.copy = function(pose) { + pose.position.copy(pose.position); + pose.orientation.copy(pose.orientation); + return pose; + }; +}; diff --git a/src/math/Quaternion.js b/src/math/Quaternion.js new file mode 100644 index 00000000..70a35bed --- /dev/null +++ b/src/math/Quaternion.js @@ -0,0 +1,124 @@ +/** + * @author David Gossow - dgossow@willowgarage.com + */ + +/** + * A Quaternion. + * + * @constructor + * @param x - the x value + * @param y - the y value + * @param z - the z value + * @param w - the w value + */ +ROSLIB.Quaternion = function(x, y, z, w) { + var quaternion = this; + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + this.w = w || 1; + + /** + * Copy the values from the given quaternion into this quaternion. + * + * @param q the quaternion to copy + * @returns a pointer to this quaternion + */ + this.copy = function(q) { + quaternion.x = q.x; + quaternion.y = q.y; + quaternion.z = q.z; + quaternion.w = q.w; + return quaternion; + }; + + /** + * Perform a conjugation on this quaternion. + * + * @returns a pointer to this quaternion + */ + this.conjugate = function() { + quaternion.x *= -1; + quaternion.y *= -1; + quaternion.z *= -1; + return quaternion; + }; + + /** + * Perform a normalization on this quaternion. + * + * @returns a pointer to this quaternion + */ + this.normalize = function() { + var l = Math.sqrt(quaternion.x * quaternion.x + quaternion.y * quaternion.y + quaternion.z + * quaternion.z + quaternion.w * quaternion.w); + if (l === 0) { + quaternion.x = 0; + quaternion.y = 0; + quaternion.z = 0; + quaternion.w = 1; + } else { + l = 1 / l; + quaternion.x = quaternion.x * l; + quaternion.y = quaternion.y * l; + quaternion.z = quaternion.z * l; + quaternion.w = quaternion.w * l; + } + return quaternion; + }; + + /** + * Convert this quaternion into its inverse. + * + * @returns a pointer to this quaternion + */ + this.inverse = function() { + this.conjugate().normalize(); + return quaternion; + }; + + /** + * Set the values of this quaternion to the product of quaternions a and b. + * + * @param a the first quaternion to multiply with + * @param b the second quaternion to multiply with + * @returns a pointer to this quaternion + */ + this.multiply = function(a, b) { + var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w, qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w; + this.x = qax * qbw + qay * qbz - qaz * qby + qaw * qbx; + this.y = -qax * qbz + qay * qbw + qaz * qbx + qaw * qby; + this.z = qax * qby - qay * qbx + qaz * qbw + qaw * qbz; + this.w = -qax * qbx - qay * qby - qaz * qbz + qaw * qbw; + return quaternion; + }; + + /** + * Multiply the given ROSLIB.Vector3 with this quaternion. + * + * @param vector the vector to multiply with + * @param dest (option) - where the computed values will go (defaults to 'vector'). + * @returns a pointer to dest + */ + this.multiplyVec3 = function(vector, dest) { + if (!dest) { + dest = vector; + } + var x = vector.x, y = vector.y, z = vector.z, qx = quaternion.x, qy = quaternion.y, qz = quaternion.z, qw = quaternion.w; + var ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx + * x - qy * y - qz * z; + dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + return dest; + }; + + /** + * Clone a copy of this quaternion. + * + * @returns the cloned quaternion + */ + this.clone = function() { + return new ROSLIB.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w); + }; +}; diff --git a/src/math/Vector3.js b/src/math/Vector3.js new file mode 100644 index 00000000..3d94fbd5 --- /dev/null +++ b/src/math/Vector3.js @@ -0,0 +1,68 @@ +/** + * @author David Gossow - dgossow@willowgarage.com + */ + +/** + * A 3D vector. + * + * @constructor + * @param x - the x value + * @param y - the y value + * @param z - the z value + */ +ROSLIB.Vector3 = function(x, y, z) { + var vector3 = this; + this.x = x || 0; + this.y = y || 0; + this.z = z || 0; + + /** + * Copy the values from the given vector into this vector. + * + * @param v the vector to copy + * @returns a pointer to this vector + */ + this.copy = function(v) { + vector3.x = v.x; + vector3.y = v.y; + vector3.z = v.z; + return vector3; + }; + + /** + * Set the values of this vector to the sum of vectors a and b. + * + * @param a the first vector to add with + * @param b the second vector to add with + * @returns a pointer to this vector + */ + this.add = function(a, b) { + vector3.x = a.x + b.x; + vector3.y = a.y + b.y; + vector3.z = a.z + b.z; + return vector3; + }; + + /** + * Set the values of this vector to the difference of vectors a and b. + * + * @param a the first vector to add with + * @param b the second vector to add with + * @returns a pointer to this vector + */ + this.sub = function(a, b) { + vector3.x = a.x - b.x; + vector3.y = a.y - b.y; + vector3.z = a.z - b.z; + return vector3; + }; + + /** + * Clone a copy of this vector. + * + * @returns the cloned vector + */ + this.clone = function() { + return new ROSLIB.Vector3(vector3.x, vector3.y, vector3.z); + }; +}; diff --git a/src/tf/TFClient.js b/src/tf/TFClient.js new file mode 100644 index 00000000..364329d2 --- /dev/null +++ b/src/tf/TFClient.js @@ -0,0 +1,136 @@ +/** + * @author David Gossow - dgossow@willowgarage.com + */ + +/** + * A TF Client that listens to TFs from tf2_web_republisher. + * + * @constructor + * @param options - object with following keys: + * * ros - the ROSLIB.Ros connection handle + * * fixedFrame - the fixed frame, like /base_link + * * angularThres - the angular threshold for the TF republisher + * * transThres - the translation threshold for the TF republisher + * * rate - the rate for the TF republisher + * * goalUpdateDelay - the goal update delay for the TF republisher + */ +ROSLIB.TFClient = function(options) { + var tfClient = this; + var options = options || {}; + this.ros = options.ros; + this.fixedFrame = options.fixedFrame || '/base_link'; + this.angularThres = options.angularThres || 2.0; + this.transThres = options.transThres || 0.01; + this.rate = options.rate || 10.0; + this.goalUpdateDelay = options.goalUpdateDelay || 50; + + this.currentGoal = false; + this.frameInfos = {}; + this.goalUpdateRequested = false; + + // create an ActionClient + this.actionClient = new ROSLIB.ActionClient({ + ros : this.ros, + serverName : '/tf2_web_republisher', + actionName : 'tf2_web_republisher/TFSubscriptionAction' + }); + + /** + * Process the incoming TF message and send them out using the callback functions. + * + * @param tf - the TF message from the server + */ + this.processFeedback = function(tf) { + tf.transforms.forEach(function(transform) { + var frameID = transform.child_frame_id; + var info = tfClient.frameInfos[frameID]; + if (info != undefined) { + info.transform = new ROSLIB.Transform(transform.transform.translation, + transform.transform.rotation); + info.cbs.forEach(function(cb) { + cb(info.transform); + }); + } + }); + }; + + /** + * Create and send a new goal to the tf2_web_republisher based on the current list of TFs. + */ + this.updateGoal = function() { + // Anytime the list of frames changes, we will need to send a new goal. + if (tfClient.currentGoal) { + tfClient.currentGoal.cancel(); + } + + var goalMessage = { + source_frames : [], + target_frame : tfClient.fixedFrame, + angular_thres : tfClient.angularThres, + trans_thres : tfClient.transThres, + rate : tfClient.rate + }; + + for (frame in tfClient.frameInfos) { + goalMessage.source_frames.push(frame); + } + + tfClient.currentGoal = new ROSLIB.Goal({ + actionClient : tfClient.actionClient, + goalMessage : goalMessage + }); + tfClient.currentGoal.on('feedback', tfClient.processFeedback.bind(tfClient)); + tfClient.currentGoal.send(); + tfClient.goalUpdateRequested = false; + }; + + /** + * Subscribe to the given TF frame. + * + * @param frameID - the TF frame to subscribe to + * @param callback - function with params: + * * transform - the transform data + */ + this.subscribe = function(frameID, callback) { + // make sure the frame id is relative + if (frameID[0] === '/') { + frameID = frameID.substring(1); + } + // if there is no callback registered for the given frame, create emtpy callback list + if (tfClient.frameInfos[frameID] == undefined) { + tfClient.frameInfos[frameID] = { + cbs : [] + }; + if (!tfClient.goalUpdateRequested) { + setTimeout(tfClient.updateGoal.bind(tfClient), tfClient.goalUpdateDelay); + tfClient.goalUpdateRequested = true; + } + } else { + // if we already have a transform, call back immediately + if (tfClient.frameInfos[frameID].transform != undefined) { + callback(tfClient.frameInfos[frameID].transform); + } + } + tfClient.frameInfos[frameID].cbs.push(callback); + }; + + /** + * Unsubscribe from the given TF frame. + * + * @param frameID - the TF frame to unsubscribe from + * @param callback - the callback function to remove + */ + tfClient.unsubscribe = function(frameID, callback) { + var info = tfClient.frameInfos[frameID]; + if (info != undefined) { + var cbIndex = info.cbs.indexOf(callback); + if (cbIndex >= 0) { + info.cbs.splice(cbIndex, 1); + if (info.cbs.length == 0) { + delete tfClient.frameInfos[frameID]; + } + tfClient.needUpdate = true; + } + } + }; +}; diff --git a/src/tf/TfClient.js b/src/tf/TfClient.js deleted file mode 100644 index f7a4b1f1..00000000 --- a/src/tf/TfClient.js +++ /dev/null @@ -1,267 +0,0 @@ -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - define(['robotwebtools/eventemitter2','robotwebtools/actionclient'], factory); - } - else { - root.TfClient = factory(root.EventEmitter2,root.ActionClient); - } -}(this, function (EventEmitter2, ActionClient) { - - var TfClient = function(options) { - this.ros = options.ros; - this.fixedFrame = options.fixedFrame || 'base_link'; - this.angularThres = options.angularThres || 2.0; - this.transThres = options.transThres || 0.01; - this.rate = options.rate || 10.0; - this.goalUpdateDelay = options.goalUpdateDelay !== undefined ? options.goalUpdateDelay : 50; - - var options = { - ros: this.ros, - serverName: options.serverName || "/tf2_web_republisher", - actionName: "tf2_web_republisher/TFSubscriptionAction" - }; - - this.actionClient = new ActionClient( options ); - this.currentGoal = false; - this.frame_infos = {}; - this.goalUpdateRequested = false; - }; - - TfClient.prototype.__proto__ = EventEmitter2.prototype; - - TfClient.prototype.processFeedback = function(tfMsg) { - var that = this; - tfMsg.transforms.forEach( function(transform) { - var frameId = transform.child_frame_id; - var info = that.frame_infos[frameId]; - if ( info != undefined ) { - info.transform = new Transform(transform.transform.translation,transform.transform.rotation); - info.cbs.forEach(function(cb) { - cb(info.transform); - }); - } - }); - } - - TfClient.prototype.requestGoalUpdate = function() { - if ( !this.goalUpdateRequested ) { - setTimeout(this.updateGoal.bind(this), this.goalUpdateDelay); - this.goalUpdateRequested = true; - return; - } - } - - TfClient.prototype.updateGoal = function() { - // Anytime the list of frames changes, - // we will need to send a new goal. - if ( this.currentGoal ) { - this.currentGoal.cancel(); - } - - var goalMsg = { - source_frames: [], - target_frame: this.fixedFrame, - angular_thres: this.angularThres, - trans_thres: this.transThres, - rate: this.rate - }; - - var source_frames = []; - for (frame in this.frame_infos ) { - goalMsg.source_frames.push(frame); - }; - - this.currentGoal = new this.actionClient.Goal(goalMsg); - this.currentGoal.on('feedback', this.processFeedback.bind(this)); - this.currentGoal.send(); - this.goalUpdateRequested = false; - } - - TfClient.prototype.subscribe = function(frameId,callback) { - // make sure the frame id is relative - if ( frameId[0] === "/" ) { - frameId = frameId.substring(1); - } - // if there is no callback registered for the given frame, - // create emtpy callback list - if ( this.frame_infos[frameId] == undefined ) { - this.frame_infos[frameId] = { - cbs: [] }; - this.requestGoalUpdate(); - } else { - // if we already have a transform, call back immediately - if ( this.frame_infos[frameId].transform != undefined ) { - callback( this.frame_infos[frameId].transform ); - } - } - this.frame_infos[frameId].cbs.push( callback ); - }; - - TfClient.prototype.unsubscribe = function(frameId,callback) { - var info = this.frame_infos[frameId]; - if ( info != undefined ) { - var cbIndex = info.cbs.indexOf( callback ); - if ( cbIndex >= 0 ) { - info.cbs.splice(cbIndex, 1); - if ( info.cbs.length == 0 ) { - delete this.frame_infos[frameId]; - } - this.needUpdate = true; - } - } - } - - - var Pose = TfClient.Pose = function( position, orientation ) { - this.position = new Vector3; - this.orientation = new Quaternion; - if ( position !== undefined ) { - this.position.copy( position ); - } - if ( orientation !== undefined ) { - this.orientation.copy( orientation ); - } - }; - - Pose.prototype = { - constructor: Pose, - copy: function( pose ) { - this.position.copy( pose.position ); - this.orientation.copy( pose.orientation ); - } - } - - var Transform = TfClient.Transform = function( translation, rotation ) { - this.translation = new Vector3; - this.rotation = new Quaternion; - if ( translation !== undefined ) { - this.translation.copy( translation ); - } - if ( rotation !== undefined ) { - this.rotation.copy( rotation ); - } - }; - - Transform.prototype = { - constructor: Transform, - apply: function( pose ) { - this.rotation.multiplyVec3(pose.position); - pose.position.add(pose.position,this.translation); - pose.orientation.multiply(this.rotation, pose.orientation); - return pose; - }, - applyInverse: function( pose ) { - var rotInv = this.rotation.clone().inverse(); - rotInv.multiplyVec3(pose.position); - pose.position.sub(pose.position,this.translation); - pose.orientation.multiply(rotInv, pose.orientation); - return pose; - }, - copy: function( transform ) { - this.translation.copy( transform.translation ); - this.rotation.copy( transform.rotation ); - } - } - - var Quaternion = TfClient.Quaternion = function( x, y, z, w ) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - this.w = ( w !== undefined ) ? w : 1; - }; - - Quaternion.prototype = { - constructor: Quaternion, - copy: function ( q ) { - this.x = q.x; - this.y = q.y; - this.z = q.z; - this.w = q.w; - return this; - }, - inverse: function () { - this.conjugate().normalize(); - return this; - }, - conjugate: function () { - this.x *= -1; - this.y *= -1; - this.z *= -1; - return this; - }, - normalize: function () { - var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); - if ( l === 0 ) { - this.x = 0; - this.y = 0; - this.z = 0; - this.w = 1; - } else { - l = 1 / l; - this.x = this.x * l; - this.y = this.y * l; - this.z = this.z * l; - this.w = this.w * l; - } - return this; - }, - multiply: function ( a, b ) { - var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w, - qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w; - this.x = qax * qbw + qay * qbz - qaz * qby + qaw * qbx; - this.y = -qax * qbz + qay * qbw + qaz * qbx + qaw * qby; - this.z = qax * qby - qay * qbx + qaz * qbw + qaw * qbz; - this.w = -qax * qbx - qay * qby - qaz * qbz + qaw * qbw; - return this; - }, - multiplyVec3: function ( vector, dest ) { - if ( !dest ) { dest = vector; } - var x = vector.x, y = vector.y, z = vector.z, - qx = this.x, qy = this.y, qz = this.z, qw = this.w; - var ix = qw * x + qy * z - qz * y, - iy = qw * y + qz * x - qx * z, - iz = qw * z + qx * y - qy * x, - iw = -qx * x - qy * y - qz * z; - dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; - dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; - dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; - return dest; - }, - clone: function () { - return new Quaternion( this.x, this.y, this.z, this.w ); - } - } - - var Vector3 = TfClient.Vector3 = function ( x, y, z ) { - this.x = x || 0; - this.y = y || 0; - this.z = z || 0; - }; - - Vector3.prototype = { - constructor: Vector3, - copy: function ( v ) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - return this; - }, - add: function ( a, b ) { - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - return this; - }, - sub: function ( a, b ) { - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; - return this; - }, - clone: function () { - return new Vector3( this.x, this.y, this.z ); - } - }; - - return TfClient; -})); diff --git a/src/tf/Transform.js b/src/tf/Transform.js new file mode 100644 index 00000000..7f3eeb4d --- /dev/null +++ b/src/tf/Transform.js @@ -0,0 +1,62 @@ +/** + * @author David Gossow - dgossow@willowgarage.com + */ + +/** + * A Transform in 3-space. Values are copied into this object. + * + * @constructor + * @param translation - the ROSLIB.Vector3 describing the translation + * @param rotation - the ROSLIB.Quaternion describing the rotation + */ +ROSLIB.Transform = function(translation, rotation) { + var transform = this; + // copy the values into this object if they exist + this.translation = new ROSLIB.Vector3(); + this.rotation = new ROSLIB.Quaternion(); + if (translation !== undefined) { + this.translation.copy(translation); + } + if (rotation !== undefined) { + this.rotation.copy(rotation); + } + + /** + * Apply a transform against the given ROSLIB.Pose. + * + * @param pose the pose to transform with + * @returns a pointer to the pose + */ + this.apply = function(pose) { + transform.rotation.multiplyVec3(pose.position); + pose.position.add(pose.position, transform.translation); + pose.orientation.multiply(transform.rotation, pose.orientation); + return pose; + }; + + /** + * Apply an inverse transform against the given ROSLIB.Pose. + * + * @param pose the pose to transform with + * @returns a pointer to the pose + */ + this.applyInverse = function(pose) { + var rotInv = transform.rotation.clone().inverse(); + rotInv.multiplyVec3(pose.position); + pose.position.sub(pose.position, transform.translation); + pose.orientation.multiply(rotInv, pose.orientation); + return pose; + }; + + /** + * Copy the values from the given transform into this transform. + * + * @param transform the transform to copy + * @returns a pointer to this transform + */ + this.copy = function(transform) { + transform.translation.copy(transform.translation); + transform.rotation.copy(transform.rotation); + return transform; + }; +};