diff --git a/.gitignore b/.gitignore index 7100014b2..25d2f4baf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .project .settings .svn +node_modules +.vagrant diff --git a/.travis.yml b/.travis.yml index 0f4a0c8ab..184691201 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,12 @@ language: node_js node_js: - - 0.8 + - "0.10" before_script: - - npm install -g karma + - npm install -g karma grunt-cli + - cd utils + - npm install . script: - - karma start test/karma.conf.js + - grunt build diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index d4035dd5b..000000000 --- a/AUTHORS +++ /dev/null @@ -1,10 +0,0 @@ -Original Authors ----------------- -Russell Toris (rctoris@wpi.edu) -Jihoon Lee (jihoonlee.in@gmail.com) -Brandon Alexander (balexander@willowgarage.com) -David Gossow (dgossow@willowgarage.com) -Benjamin Pitzer (ben.pitzer@gmail.com) - -Contributors ------------- diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 000000000..ed0bf1b16 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1,12 @@ +Original Authors +---------------- + + * Russell Toris (rctoris@wpi.edu) + * Jihoon Lee (jihoonlee.in@gmail.com) + * Brandon Alexander (balexander@willowgarage.com) + * David Gossow (dgossow@willowgarage.com) + * Benjamin Pitzer (ben.pitzer@gmail.com) + +Contributors +------------ + diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 81d2908c5..000000000 --- a/CHANGELOG +++ /dev/null @@ -1,14 +0,0 @@ -DEVEL - **r5** - -2013-04-02 - **r4** -* Bug in UrdfVisual origin to Pose conversion fixed (rctoris) -* Unit test infrastructure started (baalexander) - -2013-03-28 - **r3** -* URDF XML parser added (rctoris) - -2013-03-14 - **r2** -* First stable release (rctoris, baalexander) - -2013-03-14 - **r1** -* Initial development of ROSLIB (rctoris) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..b5462218b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +DEVEL - **r5** + * Replaces build system with Grunt (baalexander) + +2013-04-02 - **r4** + * Bug in UrdfVisual origin to Pose conversion fixed (rctoris) + * Unit test infrastructure started (baalexander) + +2013-03-28 - **r3** + * URDF XML parser added (rctoris) + +2013-03-14 - **r2** + * First stable release (rctoris, baalexander) + +2013-03-14 - **r1** + * Initial development of ROSLIB (rctoris) + diff --git a/README.md b/README.md index 59c056cde..653abad0a 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,46 @@ roslibjs [![Build Status](https://api.travis-ci.org/RobotWebTools/roslibjs.png)](https://travis-ci.org/RobotWebTools/roslibjs) ======== -#### The Standard ROS JavaScript Library #### +#### The Standard ROS JavaScript Library -For full documentation, see [the ROS wiki](http://ros.org/wiki/roslibjs) or check out some [working demos](http://robotwebtools.org/). +For full documentation, see [the ROS wiki](http://ros.org/wiki/roslibjs) or +check out some [working demos](http://robotwebtools.org/). -[JSDoc](http://robotwebtools.org/jsdoc/roslibjs/current/) can be found on the Robot Web Tools website. +[JSDoc](http://robotwebtools.org/jsdoc/roslibjs/current/) can be found on the +Robot Web Tools website. -This project is released as part of the [Robot Web Tools](http://robotwebtools.org/) effort. +This project is released as part of the [Robot Web +Tools](http://robotwebtools.org/) effort. -### Usage ### -Pre-built files can be found in either [roslib.js](build/roslib.js) or [roslib.min.js](build/roslib.min.js). +### Usage -Alternatively, you can use the current release via the Robot Web Tools CDN ([full](http://cdn.robotwebtools.org/roslibjs/current/roslib.js)) | ([min](http://cdn.robotwebtools.org/roslibjs/current/roslib.min.js)) +Pre-built files can be found in either [roslib.js](build/roslib.js) or +[roslib.min.js](build/roslib.min.js). -### Dependencies ### -roslibjs depends on [EventEmitter2](https://github.com/hij1nx/EventEmitter2). The current supported version is 0.4.11. -The current supported version can be found [in this project](include/EventEmitter2/eventemitter2.js) or on the Robot Web Tools CDN ([full](http://cdn.robotwebtools.org/EventEmitter2/0.4.11/eventemitter2.js)) | ([min](http://cdn.robotwebtools.org/EventEmitter2/0.4.11/eventemitter2.min.js)) +Alternatively, you can use the current release via the Robot Web Tools CDN +([full](http://cdn.robotwebtools.org/roslibjs/current/roslib.js)) | +([min](http://cdn.robotwebtools.org/roslibjs/current/roslib.min.js)) -### Build ### -To build from source, use the provided [ANT script](utils/build.xml). +### Dependencies -The script requires ANT, YUI Compressor, and JSDoc. To install these on an Ubuntu machine, use the following: +Roslibjs depends on [EventEmitter2](https://github.com/hij1nx/EventEmitter2). +The current supported version is 0.4.11. - sudo apt-get install ant yui-compressor jsdoc-toolkit +The current supported version can be found [in this +project](include/EventEmitter2/eventemitter2.js) or on the Robot Web Tools CDN +([full](http://cdn.robotwebtools.org/EventEmitter2/0.4.11/eventemitter2.js)) | +([min](http://cdn.robotwebtools.org/EventEmitter2/0.4.11/eventemitter2.min.js)) -To run the build script, use the following: +### Build - cd utils/ - ant +Checkout [utils/README.md](utils/README.md) for details on building. -### License ### -roslibjs is released with a BSD license. For full terms and conditions, see the [LICENSE](LICENSE) file. +### License + +Roslibjs is released with a BSD license. For full terms and conditions, see the +[LICENSE](LICENSE) file. + +### Authors -### Authors ### See the [AUTHORS](AUTHORS) file for a full list of contributors. + diff --git a/build/roslib.js b/build/roslib.js index 4f93ceec1..84a0d4a97 100644 --- a/build/roslib.js +++ b/build/roslib.js @@ -11,6 +11,7 @@ ROSLIB.URDF_SPHERE = 0; ROSLIB.URDF_BOX = 1; ROSLIB.URDF_CYLINDER = 2; ROSLIB.URDF_MESH = 3; + /** * @author Russell Toris - rctoris@wpi.edu */ @@ -127,6 +128,7 @@ ROSLIB.ActionClient.prototype.cancel = function() { this.cancelTopic.publish(cancelMessage); }; + /** * @author Russell Toris - rctoris@wpi.edu */ @@ -135,7 +137,7 @@ ROSLIB.ActionClient.prototype.cancel = function() { * An actionlib goal goal is associated with an action server. * * Emits the following events: - * * 'timeout' - if a timeout occurred while sending a goal + * * 'timeout' - if a timeout occurred while sending a goal * * @constructor * @param object with following keys: @@ -209,6 +211,7 @@ ROSLIB.Goal.prototype.cancel = function() { }); this.actionClient.cancelTopic.publish(cancelMessage); }; + /** * @author Brandon Alexander - baalexander@gmail.com */ @@ -221,12 +224,13 @@ ROSLIB.Goal.prototype.cancel = function() { */ ROSLIB.Message = function(values) { var that = this; - var values = values || {}; + values = values || {}; Object.keys(values).forEach(function(name) { that[name] = values[name]; }); }; + /** * @author Brandon Alexander - baalexander@gmail.com */ @@ -289,6 +293,7 @@ ROSLIB.Param.prototype.set = function(value) { paramClient.callService(request, function() { }); }; + /** * @author Brandon Alexander - baalexander@gmail.com */ @@ -308,7 +313,7 @@ ROSLIB.Param.prototype.set = function(value) { * * url (optional) - the WebSocket URL for rosbridge (can be specified later with `connect`) */ ROSLIB.Ros = function(options) { - var options = options || {}; + options = options || {}; var url = options.url; this.socket = null; @@ -334,7 +339,7 @@ ROSLIB.Ros.prototype.connect = function(url) { */ function onOpen(event) { that.emit('connection', event); - }; + } /** * Emits a 'close' event on WebSocket disconnection. @@ -343,7 +348,7 @@ ROSLIB.Ros.prototype.connect = function(url) { */ function onClose(event) { that.emit('close', event); - }; + } /** * Emits an 'error' event whenever there was an error. @@ -352,7 +357,7 @@ ROSLIB.Ros.prototype.connect = function(url) { */ function onError(event) { that.emit('error', event); - }; + } /** * If a message was compressed as a PNG image (a compression hack since @@ -407,7 +412,7 @@ ROSLIB.Ros.prototype.connect = function(url) { } else if (message.op === 'service_response') { that.emit(message.id, message.values); } - }; + } var data = JSON.parse(message.data); if (data.op === 'png') { @@ -417,7 +422,7 @@ ROSLIB.Ros.prototype.connect = function(url) { } else { handleMessage(data); } - }; + } this.socket = new WebSocket(url); this.socket.onopen = onOpen; @@ -459,7 +464,7 @@ ROSLIB.Ros.prototype.authenticate = function(mac, client, dest, rand, t, level, end : end }; // send the request - callOnConnection(auth); + this.callOnConnection(auth); }; /** @@ -537,6 +542,7 @@ ROSLIB.Ros.prototype.getParams = function(callback) { callback(result.names); }); }; + /** * @author Brandon Alexander - baalexander@gmail.com */ @@ -566,7 +572,7 @@ ROSLIB.Service = function(options) { */ ROSLIB.Service.prototype.callService = function(request, callback) { this.ros.idCounter++; - serviceCallId = 'call_service:' + this.name + ':' + this.ros.idCounter; + var serviceCallId = 'call_service:' + this.name + ':' + this.ros.idCounter; this.ros.once(serviceCallId, function(data) { var response = new ROSLIB.ServiceResponse(data); @@ -586,6 +592,7 @@ ROSLIB.Service.prototype.callService = function(request, callback) { }; this.ros.callOnConnection(call); }; + /** * @author Brandon Alexander - balexander@willowgarage.com */ @@ -598,12 +605,13 @@ ROSLIB.Service.prototype.callService = function(request, callback) { */ ROSLIB.ServiceRequest = function(values) { var that = this; - var values = values || {}; + values = values || {}; Object.keys(values).forEach(function(name) { that[name] = values[name]; }); }; + /** * @author Brandon Alexander - balexander@willowgarage.com */ @@ -616,12 +624,13 @@ ROSLIB.ServiceRequest = function(values) { */ ROSLIB.ServiceResponse = function(values) { var that = this; - var values = values || {}; + values = values || {}; Object.keys(values).forEach(function(name) { that[name] = values[name]; }); }; + /** * @author Brandon Alexander - baalexander@gmail.com */ @@ -652,8 +661,8 @@ ROSLIB.Topic = function(options) { // Check for valid compression types if (this.compression && this.compression !== 'png' && this.compression !== 'none') { - this.emit('warning', this.compression - + ' compression is not supported. No comression will be used.'); + this.emit('warning', this.compression + + ' compression is not supported. No compression will be used.'); } // Check if throttle rate is negative @@ -764,6 +773,7 @@ ROSLIB.Topic.prototype.publish = function(message) { }; this.ros.callOnConnection(call); }; + /** * @author David Gossow - dgossow@willowgarage.com */ @@ -777,7 +787,7 @@ ROSLIB.Topic.prototype.publish = function(message) { * * orientation - the ROSLIB.Quaternion describing the orientation */ ROSLIB.Pose = function(options) { - var options = options || {}; + options = options || {}; // copy the values into this object if they exist this.position = new ROSLIB.Vector3(options.position); this.orientation = new ROSLIB.Quaternion(options.orientation); @@ -804,6 +814,7 @@ ROSLIB.Pose.prototype.applyTransform = function(tf) { ROSLIB.Pose.prototype.clone = function() { return new ROSLIB.Pose(this); }; + /** * @author David Gossow - dgossow@willowgarage.com */ @@ -813,13 +824,13 @@ ROSLIB.Pose.prototype.clone = function() { * * @constructor * @param options - object with following keys: - * * x - the x value - * * y - the y value - * * z - the z value - * * w - the w value + * * x - the x value + * * y - the y value + * * z - the z value + * * w - the w value */ ROSLIB.Quaternion = function(options) { - var options = options || {}; + options = options || {}; this.x = options.x || 0; this.y = options.y || 0; this.z = options.z || 0; @@ -886,6 +897,8 @@ ROSLIB.Quaternion.prototype.multiply = function(q) { ROSLIB.Quaternion.prototype.clone = function() { return new ROSLIB.Quaternion(this); }; + + /** * @author David Gossow - dgossow@willowgarage.com */ @@ -899,8 +912,8 @@ ROSLIB.Quaternion.prototype.clone = function() { * * rotation - the ROSLIB.Quaternion describing the rotation */ ROSLIB.Transform = function(options) { - var options = options || {}; - // copy the values into this object if they exist + options = options || {}; + // Copy the values into this object if they exist this.translation = new ROSLIB.Vector3(options.translation); this.rotation = new ROSLIB.Quaternion(options.rotation); }; @@ -913,6 +926,7 @@ ROSLIB.Transform = function(options) { ROSLIB.Transform.prototype.clone = function() { return new ROSLIB.Transform(this); }; + /** * @author David Gossow - dgossow@willowgarage.com */ @@ -922,12 +936,12 @@ ROSLIB.Transform.prototype.clone = function() { * * @constructor * @param options - object with following keys: - * * x - the x value - * * y - the y value - * * z - the z value + * * x - the x value + * * y - the y value + * * z - the z value */ ROSLIB.Vector3 = function(options) { - var options = options || {}; + options = options || {}; this.x = options.x || 0; this.y = options.y || 0; this.z = options.z || 0; @@ -978,6 +992,7 @@ ROSLIB.Vector3.prototype.multiplyQuaternion = function(q) { ROSLIB.Vector3.prototype.clone = function() { return new ROSLIB.Vector3(this); }; + /** * @author David Gossow - dgossow@willowgarage.com */ @@ -995,7 +1010,7 @@ ROSLIB.Vector3.prototype.clone = function() { * * goalUpdateDelay - the goal update delay for the TF republisher */ ROSLIB.TFClient = function(options) { - var options = options || {}; + options = options || {}; this.ros = options.ros; this.fixedFrame = options.fixedFrame || '/base_link'; this.angularThres = options.angularThres || 2.0; @@ -1026,7 +1041,7 @@ ROSLIB.TFClient.prototype.processFeedback = function(tf) { tf.transforms.forEach(function(transform) { var frameID = transform.child_frame_id; var info = that.frameInfos[frameID]; - if (info != undefined) { + if (info !== undefined) { info.transform = new ROSLIB.Transform({ translation : transform.transform.translation, rotation : transform.transform.rotation @@ -1056,7 +1071,7 @@ ROSLIB.TFClient.prototype.updateGoal = function() { rate : this.rate }; - for (frame in this.frameInfos) { + for (var frame in this.frameInfos) { goalMessage.source_frames.push(frame); } @@ -1082,7 +1097,7 @@ ROSLIB.TFClient.prototype.subscribe = function(frameID, callback) { frameID = frameID.substring(1); } // if there is no callback registered for the given frame, create emtpy callback list - if (this.frameInfos[frameID] == undefined) { + if (this.frameInfos[frameID] === undefined) { this.frameInfos[frameID] = { cbs : [] }; @@ -1092,7 +1107,7 @@ ROSLIB.TFClient.prototype.subscribe = function(frameID, callback) { } } else { // if we already have a transform, call back immediately - if (this.frameInfos[frameID].transform != undefined) { + if (this.frameInfos[frameID].transform !== undefined) { callback(this.frameInfos[frameID].transform); } } @@ -1107,17 +1122,19 @@ ROSLIB.TFClient.prototype.subscribe = function(frameID, callback) { */ ROSLIB.TFClient.prototype.unsubscribe = function(frameID, callback) { var info = this.frameInfos[frameID]; - if (info != undefined) { + if (info !== undefined) { var cbIndex = info.cbs.indexOf(callback); if (cbIndex >= 0) { info.cbs.splice(cbIndex, 1); - if (info.cbs.length == 0) { + if (info.cbs.length === 0) { delete this.frameInfos[frameID]; } this.needUpdate = true; } } }; + + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu @@ -1125,27 +1142,27 @@ ROSLIB.TFClient.prototype.unsubscribe = function(frameID, callback) { /** * A Box element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfBox = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.dimension = null; this.type = null; /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { this.type = ROSLIB.URDF_BOX; - // parse the string + // Parse the string var xyz = xml.getAttribute('size').split(' '); that.dimension = new ROSLIB.Vector3({ x : parseFloat(xyz[0]), @@ -1154,9 +1171,10 @@ ROSLIB.UrdfBox = function(options) { }); }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu @@ -1164,14 +1182,14 @@ ROSLIB.UrdfBox = function(options) { /** * A Color element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfColor = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.r = null; this.g = null; @@ -1180,11 +1198,11 @@ ROSLIB.UrdfColor = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { - // parse the string + // Parse the string var rgba = xml.getAttribute('rgba').split(' '); that.r = parseFloat(rgba[0]); that.g = parseFloat(rgba[1]); @@ -1193,9 +1211,10 @@ ROSLIB.UrdfColor = function(options) { return true; }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu @@ -1203,14 +1222,14 @@ ROSLIB.UrdfColor = function(options) { /** * A Cylinder element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfCylinder = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.type = null; this.length = null; @@ -1218,7 +1237,7 @@ ROSLIB.UrdfCylinder = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { @@ -1227,9 +1246,11 @@ ROSLIB.UrdfCylinder = function(options) { that.radius = parseFloat(xml.getAttribute('radius')); }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu @@ -1237,21 +1258,21 @@ ROSLIB.UrdfCylinder = function(options) { /** * A Link element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfLink = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.name = null; this.visual = null; /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { @@ -1264,9 +1285,11 @@ ROSLIB.UrdfLink = function(options) { } }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu @@ -1274,14 +1297,14 @@ ROSLIB.UrdfLink = function(options) { /** * A Material element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfMaterial = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.name = null; this.textureFilename = null; @@ -1289,31 +1312,32 @@ ROSLIB.UrdfMaterial = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { that.name = xml.getAttribute('name'); - // texture + // Texture var textures = xml.getElementsByTagName('texture'); if (textures.length > 0) { that.textureFilename = textures[0].getAttribute('filename'); } - // color + // Color var colors = xml.getElementsByTagName('color'); if (colors.length > 0) { - // parse the RBGA string + // Parse the RBGA string that.color = new ROSLIB.UrdfColor({ xml : colors[0] }); } }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu @@ -1321,14 +1345,14 @@ ROSLIB.UrdfMaterial = function(options) { /** * A Mesh element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfMesh = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.filename = null; this.scale = null; @@ -1336,17 +1360,17 @@ ROSLIB.UrdfMesh = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { that.type = ROSLIB.URDF_MESH; that.filename = xml.getAttribute('filename'); - // check for a scale + // Check for a scale var scale = xml.getAttribute('scale'); if (scale) { - // get the XYZ + // Get the XYZ var xyz = scale.split(' '); that.scale = new ROSLIB.Vector3({ x : parseFloat(xyz[0]), @@ -1356,52 +1380,52 @@ ROSLIB.UrdfMesh = function(options) { } }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu */ /** - * A URDF Model can be used to parse a given URDF into the appropriate elements. - * + * A URDF Model can be used to parse a given URDF into the appropriate elements. + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse * * string - the XML element to parse as a string */ ROSLIB.UrdfModel = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; var string = options.string; - - this.name; this.materials = []; this.links = []; /** * Initialize the model with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { - // get the robot tag + // Get the robot tag var robotXml = xml.evaluate('//robot', xml, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; - // get the robot name + // Get the robot name that.name = robotXml.getAttribute('name'); - // parse all the visual elements we need - for (n in robotXml.childNodes) { + // Parse all the visual elements we need + for (var n in robotXml.childNodes) { var node = robotXml.childNodes[n]; if (node.tagName === 'material') { var material = new ROSLIB.UrdfMaterial({ xml : node }); - // make sure this is unique + // Make sure this is unique if (that.materials[material.name]) { console.warn('Material ' + material.name + 'is not unique.'); } else { @@ -1411,11 +1435,11 @@ ROSLIB.UrdfModel = function(options) { var link = new ROSLIB.UrdfLink({ xml : node }); - // make sure this is unique + // Make sure this is unique if (that.links[link.name]) { console.warn('Link ' + link.name + ' is not unique.'); } else { - // check for a material + // Check for a material if (link.visual && link.visual.material) { if (that.materials[link.visual.material.name]) { link.visual.material = that.materials[link.visual.material.name]; @@ -1424,22 +1448,24 @@ ROSLIB.UrdfModel = function(options) { } } - // add the link + // Add the link that.links[link.name] = link; } } } }; - // check if we are using a string or an XML element + // Check if we are using a string or an XML element if (string) { - // parse the string + // Parse the string var parser = new DOMParser(); xml = parser.parseFromString(string, 'text/xml'); } - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu @@ -1447,21 +1473,21 @@ ROSLIB.UrdfModel = function(options) { /** * A Sphere element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfSphere = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.radius = null; this.type = null; /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { @@ -1472,6 +1498,8 @@ ROSLIB.UrdfSphere = function(options) { // pass it to the XML parser initXml(xml); }; + + /** * @author Benjamin Pitzer - ben.pitzer@gmail.com * @author Russell Toris - rctoris@wpi.edu @@ -1479,14 +1507,14 @@ ROSLIB.UrdfSphere = function(options) { /** * A Visual element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfVisual = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.origin = null; this.geometry = null; @@ -1494,38 +1522,34 @@ ROSLIB.UrdfVisual = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { - // origin + // Origin var origins = xml.getElementsByTagName('origin'); if (origins.length === 0) { // use the identity as the default that.origin = new ROSLIB.Pose(); } else { - // check the XYZ + // Check the XYZ var xyz = origins[0].getAttribute('xyz'); - if (!xyz) { - // use the default values - var position = new ROSLIB.Vector3(); - } else { - var xyz = xyz.split(' '); - var position = new ROSLIB.Vector3({ + var position = new ROSLIB.Vector3(); + if (xyz) { + xyz = xyz.split(' '); + position = new ROSLIB.Vector3({ x : parseFloat(xyz[0]), y : parseFloat(xyz[1]), z : parseFloat(xyz[2]) }); } - // check the RPY + // Check the RPY var rpy = origins[0].getAttribute('rpy'); - if (!rpy) { - // use the default values - var orientation = new ROSLIB.Quaternion(); - } else { - var rpy = rpy.split(' '); - // convert from RPY + var orientation = new ROSLIB.Quaternion(); + if (rpy) { + rpy = rpy.split(' '); + // Convert from RPY var roll = parseFloat(rpy[0]); var pitch = parseFloat(rpy[1]); var yaw = parseFloat(rpy[2]); @@ -1541,7 +1565,7 @@ ROSLIB.UrdfVisual = function(options) { var w = Math.cos(phi) * Math.cos(the) * Math.cos(psi) + Math.sin(phi) * Math.sin(the) * Math.sin(psi); - var orientation = new ROSLIB.Quaternion({ + orientation = new ROSLIB.Quaternion({ x : x, y : y, z : z, @@ -1555,19 +1579,19 @@ ROSLIB.UrdfVisual = function(options) { }); } - // geometry + // Geometry var geoms = xml.getElementsByTagName('geometry'); if (geoms.length > 0) { var shape = null; - // check for the shape - for (n in geoms[0].childNodes) { + // Check for the shape + for (var n in geoms[0].childNodes) { var node = geoms[0].childNodes[n]; if (node.nodeType === 1) { shape = node; break; } } - // check the type + // Check the type var type = shape.nodeName; if (type === 'sphere') { that.geometry = new ROSLIB.UrdfSphere({ @@ -1590,7 +1614,7 @@ ROSLIB.UrdfVisual = function(options) { } } - // material + // Material var materials = xml.getElementsByTagName('material'); if (materials.length > 0) { that.material = new ROSLIB.UrdfMaterial({ @@ -1599,6 +1623,7 @@ ROSLIB.UrdfVisual = function(options) { } }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + diff --git a/build/roslib.min.js b/build/roslib.min.js index c340c4b31..d315df441 100644 --- a/build/roslib.min.js +++ b/build/roslib.min.js @@ -1 +1 @@ -var ROSLIB=ROSLIB||{REVISION:"5-devel"};ROSLIB.URDF_SPHERE=0;ROSLIB.URDF_BOX=1;ROSLIB.URDF_CYLINDER=2;ROSLIB.URDF_MESH=3;ROSLIB.ActionClient=function(b){var c=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 d=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.goalTopic.advertise();this.cancelTopic.advertise();e.subscribe(function(g){a=true;g.status_list.forEach(function(h){var i=c.goals[h.goal_id.id];if(i){i.emit("status",h)}})});d.subscribe(function(h){var g=c.goals[h.status.goal_id.id];if(g){g.emit("status",h.status);g.emit("feedback",h.feedback)}});f.subscribe(function(h){var g=c.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){c.emit("timeout")}},this.timeout)}};ROSLIB.ActionClient.prototype.__proto__=EventEmitter2.prototype;ROSLIB.ActionClient.prototype.cancel=function(){var a=new ROSLIB.Message();this.cancelTopic.publish(a)};ROSLIB.Goal=function(b){var c=this;this.actionClient=b.actionClient;this.goalMessage=b.goalMessage;this.isFinished=false;var a=new Date();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){c.status=d});this.on("result",function(d){c.isFinished=true;c.result=d});this.on("feedback",function(d){c.feedback=d});this.actionClient.goals[this.goalID]=this};ROSLIB.Goal.prototype.__proto__=EventEmitter2.prototype;ROSLIB.Goal.prototype.send=function(b){var a=this;a.actionClient.goalTopic.publish(a.goalMessage);if(b){setTimeout(function(){if(!a.isFinished){a.emit("timeout")}},b)}};ROSLIB.Goal.prototype.cancel=function(){var a=new ROSLIB.Message({id:this.goalID});this.actionClient.cancelTopic.publish(a)};ROSLIB.Message=function(a){var b=this;var a=a||{};Object.keys(a).forEach(function(c){b[c]=a[c]})};ROSLIB.Param=function(a){a=a||{};this.ros=a.ros;this.name=a.name};ROSLIB.Param.prototype.get=function(c){var b=new ROSLIB.Service({ros:this.ros,name:"/rosapi/get_param",serviceType:"rosapi/GetParam"});var a=new ROSLIB.ServiceRequest({name:this.name,value:JSON.stringify("")});b.callService(a,function(d){var e=JSON.parse(d.value);c(e)})};ROSLIB.Param.prototype.set=function(c){var b=new ROSLIB.Service({ros:this.ros,name:"/rosapi/set_param",serviceType:"rosapi/SetParam"});var a=new ROSLIB.ServiceRequest({name:this.name,value:JSON.stringify(c)});b.callService(a,function(){})};ROSLIB.Ros=function(b){var b=b||{};var a=b.url;this.socket=null;if(a){this.connect(a)}};ROSLIB.Ros.prototype.__proto__=EventEmitter2.prototype;ROSLIB.Ros.prototype.connect=function(c){var e=this;function b(h){e.emit("connection",h)}function a(h){e.emit("close",h)}function d(h){e.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 q=m.getImageData(0,0,i.width,i.height).data;var o="";for(var l=0;l=0){c.cbs.splice(b,1);if(c.cbs.length==0){delete this.frameInfos[a]}this.needUpdate=true}}};ROSLIB.UrdfBox=function(b){var c=this;var b=b||{};var a=b.xml;this.dimension=null;this.type=null;var d=function(f){this.type=ROSLIB.URDF_BOX;var e=f.getAttribute("size").split(" ");c.dimension=new ROSLIB.Vector3({x:parseFloat(e[0]),y:parseFloat(e[1]),z:parseFloat(e[2])})};d(a)};ROSLIB.UrdfColor=function(b){var c=this;var b=b||{};var a=b.xml;this.r=null;this.g=null;this.b=null;this.a=null;var d=function(e){var f=e.getAttribute("rgba").split(" ");c.r=parseFloat(f[0]);c.g=parseFloat(f[1]);c.b=parseFloat(f[2]);c.a=parseFloat(f[3]);return true};d(a)};ROSLIB.UrdfCylinder=function(b){var c=this;var b=b||{};var a=b.xml;this.type=null;this.length=null;this.radius=null;var d=function(e){c.type=ROSLIB.URDF_CYLINDER;c.length=parseFloat(e.getAttribute("length"));c.radius=parseFloat(e.getAttribute("radius"))};d(a)};ROSLIB.UrdfLink=function(b){var c=this;var b=b||{};var a=b.xml;this.name=null;this.visual=null;var d=function(e){c.name=e.getAttribute("name");var f=e.getElementsByTagName("visual");if(f.length>0){c.visual=new ROSLIB.UrdfVisual({xml:f[0]})}};d(a)};ROSLIB.UrdfMaterial=function(b){var c=this;var b=b||{};var a=b.xml;this.name=null;this.textureFilename=null;this.color=null;var d=function(g){c.name=g.getAttribute("name");var e=g.getElementsByTagName("texture");if(e.length>0){c.textureFilename=e[0].getAttribute("filename")}var f=g.getElementsByTagName("color");if(f.length>0){c.color=new ROSLIB.UrdfColor({xml:f[0]})}};d(a)};ROSLIB.UrdfMesh=function(b){var c=this;var b=b||{};var a=b.xml;this.filename=null;this.scale=null;this.type=null;var d=function(f){c.type=ROSLIB.URDF_MESH;c.filename=f.getAttribute("filename");var g=f.getAttribute("scale");if(g){var e=g.split(" ");c.scale=new ROSLIB.Vector3({x:parseFloat(e[0]),y:parseFloat(e[1]),z:parseFloat(e[2])})}};d(a)};ROSLIB.UrdfModel=function(c){var d=this;var c=c||{};var b=c.xml;var a=c.string;this.name;this.materials=[];this.links=[];var e=function(g){var k=g.evaluate("//robot",g,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;d.name=k.getAttribute("name");for(n in k.childNodes){var j=k.childNodes[n];if(j.tagName==="material"){var h=new ROSLIB.UrdfMaterial({xml:j});if(d.materials[h.name]){console.warn("Material "+h.name+"is not unique.")}else{d.materials[h.name]=h}}else{if(j.tagName==="link"){var i=new ROSLIB.UrdfLink({xml:j});if(d.links[i.name]){console.warn("Link "+i.name+" is not unique.")}else{if(i.visual&&i.visual.material){if(d.materials[i.visual.material.name]){i.visual.material=d.materials[i.visual.material.name]}else{if(i.visual.material){d.materials[i.visual.material.name]=i.visual.material}}}d.links[i.name]=i}}}}};if(a){var f=new DOMParser();b=f.parseFromString(a,"text/xml")}e(b)};ROSLIB.UrdfSphere=function(b){var c=this;var b=b||{};var a=b.xml;this.radius=null;this.type=null;var d=function(e){c.type=ROSLIB.URDF_SPHERE;c.radius=parseFloat(e.getAttribute("radius"))};d(a)};ROSLIB.UrdfVisual=function(b){var c=this;var b=b||{};var a=b.xml;this.origin=null;this.geometry=null;this.material=null;var d=function(k){var e=k.getElementsByTagName("origin");if(e.length===0){c.origin=new ROSLIB.Pose()}else{var C=e[0].getAttribute("xyz");if(!C){var D=new ROSLIB.Vector3()}else{var C=C.split(" ");var D=new ROSLIB.Vector3({x:parseFloat(C[0]),y:parseFloat(C[1]),z:parseFloat(C[2])})}var t=e[0].getAttribute("rpy");if(!t){var i=new ROSLIB.Quaternion()}else{var t=t.split(" ");var A=parseFloat(t[0]);var m=parseFloat(t[1]);var q=parseFloat(t[2]);var g=A/2;var p=m/2;var B=q/2;var r=Math.sin(g)*Math.cos(p)*Math.cos(B)-Math.cos(g)*Math.sin(p)*Math.sin(B);var o=Math.cos(g)*Math.sin(p)*Math.cos(B)+Math.sin(g)*Math.cos(p)*Math.sin(B);var l=Math.cos(g)*Math.cos(p)*Math.sin(B)-Math.sin(g)*Math.sin(p)*Math.cos(B);var s=Math.cos(g)*Math.cos(p)*Math.cos(B)+Math.sin(g)*Math.sin(p)*Math.sin(B);var i=new ROSLIB.Quaternion({x:r,y:o,z:l,w:s});i.normalize()}c.origin=new ROSLIB.Pose({position:D,orientation:i})}var u=k.getElementsByTagName("geometry");if(u.length>0){var f=null;for(n in u[0].childNodes){var v=u[0].childNodes[n];if(v.nodeType===1){f=v;break}}var j=f.nodeName;if(j==="sphere"){c.geometry=new ROSLIB.UrdfSphere({xml:f})}else{if(j==="box"){c.geometry=new ROSLIB.UrdfBox({xml:f})}else{if(j==="cylinder"){c.geometry=new ROSLIB.UrdfCylinder({xml:f})}else{if(j==="mesh"){c.geometry=new ROSLIB.UrdfMesh({xml:f})}else{console.warn("Unknown geometry type "+j)}}}}}var h=k.getElementsByTagName("material");if(h.length>0){c.material=new ROSLIB.UrdfMaterial({xml:h[0]})}};d(a)}; \ No newline at end of file +var ROSLIB=ROSLIB||{REVISION:"5-devel"};ROSLIB.URDF_SPHERE=0,ROSLIB.URDF_BOX=1,ROSLIB.URDF_CYLINDER=2,ROSLIB.URDF_MESH=3,ROSLIB.ActionClient=function(t){var e=this;t=t||{},this.ros=t.ros,this.serverName=t.serverName,this.actionName=t.actionName,this.timeout=t.timeout,this.goals={};var i=!1,s=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/feedback",messageType:this.actionName+"Feedback"}),n=new ROSLIB.Topic({ros:this.ros,name:this.serverName+"/status",messageType:"actionlib_msgs/GoalStatusArray"}),o=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.goalTopic.advertise(),this.cancelTopic.advertise(),n.subscribe(function(t){i=!0,t.status_list.forEach(function(t){var i=e.goals[t.goal_id.id];i&&i.emit("status",t)})}),s.subscribe(function(t){var i=e.goals[t.status.goal_id.id];i&&(i.emit("status",t.status),i.emit("feedback",t.feedback))}),o.subscribe(function(t){var i=e.goals[t.status.goal_id.id];i&&(i.emit("status",t.status),i.emit("result",t.result))}),this.timeout&&setTimeout(function(){i||e.emit("timeout")},this.timeout)},ROSLIB.ActionClient.prototype.__proto__=EventEmitter2.prototype,ROSLIB.ActionClient.prototype.cancel=function(){var t=new ROSLIB.Message;this.cancelTopic.publish(t)},ROSLIB.Goal=function(t){var e=this;this.actionClient=t.actionClient,this.goalMessage=t.goalMessage,this.isFinished=!1;var i=new Date;this.goalID="goal_"+Math.random()+"_"+i.getTime(),this.goalMessage=new ROSLIB.Message({goal_id:{stamp:{secs:0,nsecs:0},id:this.goalID},goal:this.goalMessage}),this.on("status",function(t){e.status=t}),this.on("result",function(t){e.isFinished=!0,e.result=t}),this.on("feedback",function(t){e.feedback=t}),this.actionClient.goals[this.goalID]=this},ROSLIB.Goal.prototype.__proto__=EventEmitter2.prototype,ROSLIB.Goal.prototype.send=function(t){var e=this;e.actionClient.goalTopic.publish(e.goalMessage),t&&setTimeout(function(){e.isFinished||e.emit("timeout")},t)},ROSLIB.Goal.prototype.cancel=function(){var t=new ROSLIB.Message({id:this.goalID});this.actionClient.cancelTopic.publish(t)},ROSLIB.Message=function(t){var e=this;t=t||{},Object.keys(t).forEach(function(i){e[i]=t[i]})},ROSLIB.Param=function(t){t=t||{},this.ros=t.ros,this.name=t.name},ROSLIB.Param.prototype.get=function(t){var e=new ROSLIB.Service({ros:this.ros,name:"/rosapi/get_param",serviceType:"rosapi/GetParam"}),i=new ROSLIB.ServiceRequest({name:this.name,value:JSON.stringify("")});e.callService(i,function(e){var i=JSON.parse(e.value);t(i)})},ROSLIB.Param.prototype.set=function(t){var e=new ROSLIB.Service({ros:this.ros,name:"/rosapi/set_param",serviceType:"rosapi/SetParam"}),i=new ROSLIB.ServiceRequest({name:this.name,value:JSON.stringify(t)});e.callService(i,function(){})},ROSLIB.Ros=function(t){t=t||{};var e=t.url;this.socket=null,e&&this.connect(e)},ROSLIB.Ros.prototype.__proto__=EventEmitter2.prototype,ROSLIB.Ros.prototype.connect=function(t){function e(t){a.emit("connection",t)}function i(t){a.emit("close",t)}function s(t){a.emit("error",t)}function n(t,e){var i=new Image;i.onload=function(){var t=document.createElement("canvas"),s=t.getContext("2d");t.width=i.width,t.height=i.height,s.drawImage(i,0,0);for(var n=s.getImageData(0,0,i.width,i.height).data,o="",a=0;n.length>a;a+=4)o+=String.fromCharCode(n[a],n[a+1],n[a+2]);var r=JSON.parse(o);e(r)},i.src="data:image/png;base64,"+t.data}function o(t){function e(t){"publish"===t.op?a.emit(t.topic,t.msg):"service_response"===t.op&&a.emit(t.id,t.values)}var i=JSON.parse(t.data);"png"===i.op?n(i,function(t){e(t)}):e(i)}var a=this;this.socket=new WebSocket(t),this.socket.onopen=e,this.socket.onclose=i,this.socket.onerror=s,this.socket.onmessage=o},ROSLIB.Ros.prototype.close=function(){this.socket&&this.socket.close()},ROSLIB.Ros.prototype.authenticate=function(t,e,i,s,n,o,a){var r={op:"auth",mac:t,client:e,dest:i,rand:s,t:n,level:o,end:a};this.callOnConnection(r)},ROSLIB.Ros.prototype.callOnConnection=function(t){var e=this,i=JSON.stringify(t);this.socket&&this.socket.readyState===WebSocket.OPEN?e.socket.send(i):e.once("connection",function(){e.socket.send(i)})},ROSLIB.Ros.prototype.getTopics=function(t){var e=new ROSLIB.Service({ros:this,name:"/rosapi/topics",serviceType:"rosapi/Topics"}),i=new ROSLIB.ServiceRequest;e.callService(i,function(e){t(e.topics)})},ROSLIB.Ros.prototype.getServices=function(t){var e=new ROSLIB.Service({ros:this,name:"/rosapi/services",serviceType:"rosapi/Services"}),i=new ROSLIB.ServiceRequest;e.callService(i,function(e){t(e.services)})},ROSLIB.Ros.prototype.getParams=function(t){var e=new ROSLIB.Service({ros:this,name:"/rosapi/get_param_names",serviceType:"rosapi/GetParamNames"}),i=new ROSLIB.ServiceRequest;e.callService(i,function(e){t(e.names)})},ROSLIB.Service=function(t){t=t||{},this.ros=t.ros,this.name=t.name,this.serviceType=t.serviceType},ROSLIB.Service.prototype.callService=function(t,e){this.ros.idCounter++;var i="call_service:"+this.name+":"+this.ros.idCounter;this.ros.once(i,function(t){var i=new ROSLIB.ServiceResponse(t);e(i)});var s=[];Object.keys(t).forEach(function(e){s.push(t[e])});var n={op:"call_service",id:i,service:this.name,args:s};this.ros.callOnConnection(n)},ROSLIB.ServiceRequest=function(t){var e=this;t=t||{},Object.keys(t).forEach(function(i){e[i]=t[i]})},ROSLIB.ServiceResponse=function(t){var e=this;t=t||{},Object.keys(t).forEach(function(i){e[i]=t[i]})},ROSLIB.Topic=function(t){t=t||{},this.ros=t.ros,this.name=t.name,this.messageType=t.messageType,this.isAdvertised=!1,this.compression=t.compression||"none",this.throttle_rate=t.throttle_rate||0,this.compression&&"png"!==this.compression&&"none"!==this.compression&&this.emit("warning",this.compression+" compression is not supported. No compression will be used."),0>this.throttle_rate&&(this.emit("warning",this.throttle_rate+" is not allowed. Set to 0"),this.throttle_rate=0)},ROSLIB.Topic.prototype.__proto__=EventEmitter2.prototype,ROSLIB.Topic.prototype.subscribe=function(t){var e=this;this.on("message",function(e){t(e)}),this.ros.on(this.name,function(t){var i=new ROSLIB.Message(t);e.emit("message",i)}),this.ros.idCounter++;var i="subscribe:"+this.name+":"+this.ros.idCounter,s={op:"subscribe",id:i,type:this.messageType,topic:this.name,compression:this.compression,throttle_rate:this.throttle_rate};this.ros.callOnConnection(s)},ROSLIB.Topic.prototype.unsubscribe=function(){this.ros.removeAllListeners([this.name]),this.ros.idCounter++;var t="unsubscribe:"+this.name+":"+this.ros.idCounter,e={op:"unsubscribe",id:t,topic:this.name};this.ros.callOnConnection(e)},ROSLIB.Topic.prototype.advertise=function(){this.ros.idCounter++;var t="advertise:"+this.name+":"+this.ros.idCounter,e={op:"advertise",id:t,type:this.messageType,topic:this.name};this.ros.callOnConnection(e),this.isAdvertised=!0},ROSLIB.Topic.prototype.unadvertise=function(){this.ros.idCounter++;var t="unadvertise:"+this.name+":"+this.ros.idCounter,e={op:"unadvertise",id:t,topic:this.name};this.ros.callOnConnection(e),this.isAdvertised=!1},ROSLIB.Topic.prototype.publish=function(t){this.isAdvertised||this.advertise(),this.ros.idCounter++;var e="publish:"+this.name+":"+this.ros.idCounter,i={op:"publish",id:e,topic:this.name,msg:t};this.ros.callOnConnection(i)},ROSLIB.Pose=function(t){t=t||{},this.position=new ROSLIB.Vector3(t.position),this.orientation=new ROSLIB.Quaternion(t.orientation)},ROSLIB.Pose.prototype.applyTransform=function(t){this.position.multiplyQuaternion(t.rotation),this.position.add(t.translation);var e=t.rotation.clone();e.multiply(this.orientation),this.orientation=e},ROSLIB.Pose.prototype.clone=function(){return new ROSLIB.Pose(this)},ROSLIB.Quaternion=function(t){t=t||{},this.x=t.x||0,this.y=t.y||0,this.z=t.z||0,this.w=t.w||1},ROSLIB.Quaternion.prototype.conjugate=function(){this.x*=-1,this.y*=-1,this.z*=-1},ROSLIB.Quaternion.prototype.normalize=function(){var t=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);0===t?(this.x=0,this.y=0,this.z=0,this.w=1):(t=1/t,this.x=this.x*t,this.y=this.y*t,this.z=this.z*t,this.w=this.w*t)},ROSLIB.Quaternion.prototype.invert=function(){this.conjugate(),this.normalize()},ROSLIB.Quaternion.prototype.multiply=function(t){var e=this.x*t.w+this.y*t.z-this.z*t.y+this.w*t.x,i=-this.x*t.z+this.y*t.w+this.z*t.x+this.w*t.y,s=this.x*t.y-this.y*t.x+this.z*t.w+this.w*t.z,n=-this.x*t.x-this.y*t.y-this.z*t.z+this.w*t.w;this.x=e,this.y=i,this.z=s,this.w=n},ROSLIB.Quaternion.prototype.clone=function(){return new ROSLIB.Quaternion(this)},ROSLIB.Transform=function(t){t=t||{},this.translation=new ROSLIB.Vector3(t.translation),this.rotation=new ROSLIB.Quaternion(t.rotation)},ROSLIB.Transform.prototype.clone=function(){return new ROSLIB.Transform(this)},ROSLIB.Vector3=function(t){t=t||{},this.x=t.x||0,this.y=t.y||0,this.z=t.z||0},ROSLIB.Vector3.prototype.add=function(t){this.x+=t.x,this.y+=t.y,this.z+=t.z},ROSLIB.Vector3.prototype.subtract=function(t){this.x-=t.x,this.y-=t.y,this.z-=t.z},ROSLIB.Vector3.prototype.multiplyQuaternion=function(t){var e=t.w*this.x+t.y*this.z-t.z*this.y,i=t.w*this.y+t.z*this.x-t.x*this.z,s=t.w*this.z+t.x*this.y-t.y*this.x,n=-t.x*this.x-t.y*this.y-t.z*this.z;this.x=e*t.w+n*-t.x+i*-t.z-s*-t.y,this.y=i*t.w+n*-t.y+s*-t.x-e*-t.z,this.z=s*t.w+n*-t.z+e*-t.y-i*-t.x},ROSLIB.Vector3.prototype.clone=function(){return new ROSLIB.Vector3(this)},ROSLIB.TFClient=function(t){t=t||{},this.ros=t.ros,this.fixedFrame=t.fixedFrame||"/base_link",this.angularThres=t.angularThres||2,this.transThres=t.transThres||.01,this.rate=t.rate||10,this.goalUpdateDelay=t.goalUpdateDelay||50,this.currentGoal=!1,this.frameInfos={},this.goalUpdateRequested=!1,this.actionClient=new ROSLIB.ActionClient({ros:this.ros,serverName:"/tf2_web_republisher",actionName:"tf2_web_republisher/TFSubscriptionAction"})},ROSLIB.TFClient.prototype.processFeedback=function(t){var e=this;t.transforms.forEach(function(t){var i=t.child_frame_id,s=e.frameInfos[i];void 0!==s&&(s.transform=new ROSLIB.Transform({translation:t.transform.translation,rotation:t.transform.rotation}),s.cbs.forEach(function(t){t(s.transform)}))})},ROSLIB.TFClient.prototype.updateGoal=function(){this.currentGoal&&this.currentGoal.cancel();var t={source_frames:[],target_frame:this.fixedFrame,angular_thres:this.angularThres,trans_thres:this.transThres,rate:this.rate};for(var e in this.frameInfos)t.source_frames.push(e);this.currentGoal=new ROSLIB.Goal({actionClient:this.actionClient,goalMessage:t}),this.currentGoal.on("feedback",this.processFeedback.bind(this)),this.currentGoal.send(),this.goalUpdateRequested=!1},ROSLIB.TFClient.prototype.subscribe=function(t,e){"/"===t[0]&&(t=t.substring(1)),void 0===this.frameInfos[t]?(this.frameInfos[t]={cbs:[]},this.goalUpdateRequested||(setTimeout(this.updateGoal.bind(this),this.goalUpdateDelay),this.goalUpdateRequested=!0)):void 0!==this.frameInfos[t].transform&&e(this.frameInfos[t].transform),this.frameInfos[t].cbs.push(e)},ROSLIB.TFClient.prototype.unsubscribe=function(t,e){var i=this.frameInfos[t];if(void 0!==i){var s=i.cbs.indexOf(e);s>=0&&(i.cbs.splice(s,1),0===i.cbs.length&&delete this.frameInfos[t],this.needUpdate=!0)}},ROSLIB.UrdfBox=function(t){t=t||{};var e=this,i=t.xml;this.dimension=null,this.type=null;var s=function(t){this.type=ROSLIB.URDF_BOX;var i=t.getAttribute("size").split(" ");e.dimension=new ROSLIB.Vector3({x:parseFloat(i[0]),y:parseFloat(i[1]),z:parseFloat(i[2])})};s(i)},ROSLIB.UrdfColor=function(t){t=t||{};var e=this,i=t.xml;this.r=null,this.g=null,this.b=null,this.a=null;var s=function(t){var i=t.getAttribute("rgba").split(" ");return e.r=parseFloat(i[0]),e.g=parseFloat(i[1]),e.b=parseFloat(i[2]),e.a=parseFloat(i[3]),!0};s(i)},ROSLIB.UrdfCylinder=function(t){t=t||{};var e=this,i=t.xml;this.type=null,this.length=null,this.radius=null;var s=function(t){e.type=ROSLIB.URDF_CYLINDER,e.length=parseFloat(t.getAttribute("length")),e.radius=parseFloat(t.getAttribute("radius"))};s(i)},ROSLIB.UrdfLink=function(t){t=t||{};var e=this,i=t.xml;this.name=null,this.visual=null;var s=function(t){e.name=t.getAttribute("name");var i=t.getElementsByTagName("visual");i.length>0&&(e.visual=new ROSLIB.UrdfVisual({xml:i[0]}))};s(i)},ROSLIB.UrdfMaterial=function(t){t=t||{};var e=this,i=t.xml;this.name=null,this.textureFilename=null,this.color=null;var s=function(t){e.name=t.getAttribute("name");var i=t.getElementsByTagName("texture");i.length>0&&(e.textureFilename=i[0].getAttribute("filename"));var s=t.getElementsByTagName("color");s.length>0&&(e.color=new ROSLIB.UrdfColor({xml:s[0]}))};s(i)},ROSLIB.UrdfMesh=function(t){t=t||{};var e=this,i=t.xml;this.filename=null,this.scale=null,this.type=null;var s=function(t){e.type=ROSLIB.URDF_MESH,e.filename=t.getAttribute("filename");var i=t.getAttribute("scale");if(i){var s=i.split(" ");e.scale=new ROSLIB.Vector3({x:parseFloat(s[0]),y:parseFloat(s[1]),z:parseFloat(s[2])})}};s(i)},ROSLIB.UrdfModel=function(t){t=t||{};var e=this,i=t.xml,s=t.string;this.materials=[],this.links=[];var n=function(t){var i=t.evaluate("//robot",t,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;e.name=i.getAttribute("name");for(var s in i.childNodes){var n=i.childNodes[s];if("material"===n.tagName){var o=new ROSLIB.UrdfMaterial({xml:n});e.materials[o.name]?console.warn("Material "+o.name+"is not unique."):e.materials[o.name]=o}else if("link"===n.tagName){var a=new ROSLIB.UrdfLink({xml:n});e.links[a.name]?console.warn("Link "+a.name+" is not unique."):(a.visual&&a.visual.material&&(e.materials[a.visual.material.name]?a.visual.material=e.materials[a.visual.material.name]:a.visual.material&&(e.materials[a.visual.material.name]=a.visual.material)),e.links[a.name]=a)}}};if(s){var o=new DOMParser;i=o.parseFromString(s,"text/xml")}n(i)},ROSLIB.UrdfSphere=function(t){t=t||{};var e=this,i=t.xml;this.radius=null,this.type=null;var s=function(t){e.type=ROSLIB.URDF_SPHERE,e.radius=parseFloat(t.getAttribute("radius"))};s(i)},ROSLIB.UrdfVisual=function(t){t=t||{};var e=this,i=t.xml;this.origin=null,this.geometry=null,this.material=null;var s=function(t){var i=t.getElementsByTagName("origin");if(0===i.length)e.origin=new ROSLIB.Pose;else{var s=i[0].getAttribute("xyz"),n=new ROSLIB.Vector3;s&&(s=s.split(" "),n=new ROSLIB.Vector3({x:parseFloat(s[0]),y:parseFloat(s[1]),z:parseFloat(s[2])}));var o=i[0].getAttribute("rpy"),a=new ROSLIB.Quaternion;if(o){o=o.split(" ");var r=parseFloat(o[0]),h=parseFloat(o[1]),c=parseFloat(o[2]),l=r/2,u=h/2,p=c/2,m=Math.sin(l)*Math.cos(u)*Math.cos(p)-Math.cos(l)*Math.sin(u)*Math.sin(p),f=Math.cos(l)*Math.sin(u)*Math.cos(p)+Math.sin(l)*Math.cos(u)*Math.sin(p),v=Math.cos(l)*Math.cos(u)*Math.sin(p)-Math.sin(l)*Math.sin(u)*Math.cos(p),S=Math.cos(l)*Math.cos(u)*Math.cos(p)+Math.sin(l)*Math.sin(u)*Math.sin(p);a=new ROSLIB.Quaternion({x:m,y:f,z:v,w:S}),a.normalize()}e.origin=new ROSLIB.Pose({position:n,orientation:a})}var R=t.getElementsByTagName("geometry");if(R.length>0){var d=null;for(var g in R[0].childNodes){var O=R[0].childNodes[g];if(1===O.nodeType){d=O;break}}var y=d.nodeName;"sphere"===y?e.geometry=new ROSLIB.UrdfSphere({xml:d}):"box"===y?e.geometry=new ROSLIB.UrdfBox({xml:d}):"cylinder"===y?e.geometry=new ROSLIB.UrdfCylinder({xml:d}):"mesh"===y?e.geometry=new ROSLIB.UrdfMesh({xml:d}):console.warn("Unknown geometry type "+y)}var I=t.getElementsByTagName("material");I.length>0&&(e.material=new ROSLIB.UrdfMaterial({xml:I[0]}))};s(i)}; \ No newline at end of file diff --git a/src/actionlib/Goal.js b/src/actionlib/Goal.js index d5ba98997..e5f9d7156 100644 --- a/src/actionlib/Goal.js +++ b/src/actionlib/Goal.js @@ -6,7 +6,7 @@ * An actionlib goal goal is associated with an action server. * * Emits the following events: - * * 'timeout' - if a timeout occurred while sending a goal + * * 'timeout' - if a timeout occurred while sending a goal * * @constructor * @param object with following keys: diff --git a/src/core/Message.js b/src/core/Message.js index 8890b9769..2298bf089 100644 --- a/src/core/Message.js +++ b/src/core/Message.js @@ -10,7 +10,7 @@ */ ROSLIB.Message = function(values) { var that = this; - var values = values || {}; + values = values || {}; Object.keys(values).forEach(function(name) { that[name] = values[name]; diff --git a/src/core/Ros.js b/src/core/Ros.js index b271ae44c..342611ed0 100644 --- a/src/core/Ros.js +++ b/src/core/Ros.js @@ -17,7 +17,7 @@ * * url (optional) - the WebSocket URL for rosbridge (can be specified later with `connect`) */ ROSLIB.Ros = function(options) { - var options = options || {}; + options = options || {}; var url = options.url; this.socket = null; @@ -43,7 +43,7 @@ ROSLIB.Ros.prototype.connect = function(url) { */ function onOpen(event) { that.emit('connection', event); - }; + } /** * Emits a 'close' event on WebSocket disconnection. @@ -52,7 +52,7 @@ ROSLIB.Ros.prototype.connect = function(url) { */ function onClose(event) { that.emit('close', event); - }; + } /** * Emits an 'error' event whenever there was an error. @@ -61,7 +61,7 @@ ROSLIB.Ros.prototype.connect = function(url) { */ function onError(event) { that.emit('error', event); - }; + } /** * If a message was compressed as a PNG image (a compression hack since @@ -116,7 +116,7 @@ ROSLIB.Ros.prototype.connect = function(url) { } else if (message.op === 'service_response') { that.emit(message.id, message.values); } - }; + } var data = JSON.parse(message.data); if (data.op === 'png') { @@ -126,7 +126,7 @@ ROSLIB.Ros.prototype.connect = function(url) { } else { handleMessage(data); } - }; + } this.socket = new WebSocket(url); this.socket.onopen = onOpen; @@ -168,7 +168,7 @@ ROSLIB.Ros.prototype.authenticate = function(mac, client, dest, rand, t, level, end : end }; // send the request - callOnConnection(auth); + this.callOnConnection(auth); }; /** diff --git a/src/core/Service.js b/src/core/Service.js index 8c3a0a182..8dc90586a 100644 --- a/src/core/Service.js +++ b/src/core/Service.js @@ -27,7 +27,7 @@ ROSLIB.Service = function(options) { */ ROSLIB.Service.prototype.callService = function(request, callback) { this.ros.idCounter++; - serviceCallId = 'call_service:' + this.name + ':' + this.ros.idCounter; + var serviceCallId = 'call_service:' + this.name + ':' + this.ros.idCounter; this.ros.once(serviceCallId, function(data) { var response = new ROSLIB.ServiceResponse(data); diff --git a/src/core/ServiceRequest.js b/src/core/ServiceRequest.js index 5c2e67312..d5ff7c062 100644 --- a/src/core/ServiceRequest.js +++ b/src/core/ServiceRequest.js @@ -10,7 +10,7 @@ */ ROSLIB.ServiceRequest = function(values) { var that = this; - var values = values || {}; + values = values || {}; Object.keys(values).forEach(function(name) { that[name] = values[name]; diff --git a/src/core/ServiceResponse.js b/src/core/ServiceResponse.js index 8cb1f2672..825ef111a 100644 --- a/src/core/ServiceResponse.js +++ b/src/core/ServiceResponse.js @@ -10,7 +10,7 @@ */ ROSLIB.ServiceResponse = function(values) { var that = this; - var values = values || {}; + values = values || {}; Object.keys(values).forEach(function(name) { that[name] = values[name]; diff --git a/src/core/Topic.js b/src/core/Topic.js index 28f811dc5..21ba26367 100644 --- a/src/core/Topic.js +++ b/src/core/Topic.js @@ -28,8 +28,8 @@ ROSLIB.Topic = function(options) { // Check for valid compression types if (this.compression && this.compression !== 'png' && this.compression !== 'none') { - this.emit('warning', this.compression - + ' compression is not supported. No comression will be used.'); + this.emit('warning', this.compression + + ' compression is not supported. No compression will be used.'); } // Check if throttle rate is negative diff --git a/src/math/Pose.js b/src/math/Pose.js index 876c88534..5d5b11b3a 100644 --- a/src/math/Pose.js +++ b/src/math/Pose.js @@ -11,7 +11,7 @@ * * orientation - the ROSLIB.Quaternion describing the orientation */ ROSLIB.Pose = function(options) { - var options = options || {}; + options = options || {}; // copy the values into this object if they exist this.position = new ROSLIB.Vector3(options.position); this.orientation = new ROSLIB.Quaternion(options.orientation); diff --git a/src/math/Quaternion.js b/src/math/Quaternion.js index 7b13639ea..e12ae45b9 100644 --- a/src/math/Quaternion.js +++ b/src/math/Quaternion.js @@ -7,13 +7,13 @@ * * @constructor * @param options - object with following keys: - * * x - the x value - * * y - the y value - * * z - the z value - * * w - the w value + * * x - the x value + * * y - the y value + * * z - the z value + * * w - the w value */ ROSLIB.Quaternion = function(options) { - var options = options || {}; + options = options || {}; this.x = options.x || 0; this.y = options.y || 0; this.z = options.z || 0; @@ -80,3 +80,4 @@ ROSLIB.Quaternion.prototype.multiply = function(q) { ROSLIB.Quaternion.prototype.clone = function() { return new ROSLIB.Quaternion(this); }; + diff --git a/src/math/Transform.js b/src/math/Transform.js index 58b5c1311..663c6af44 100644 --- a/src/math/Transform.js +++ b/src/math/Transform.js @@ -11,8 +11,8 @@ * * rotation - the ROSLIB.Quaternion describing the rotation */ ROSLIB.Transform = function(options) { - var options = options || {}; - // copy the values into this object if they exist + options = options || {}; + // Copy the values into this object if they exist this.translation = new ROSLIB.Vector3(options.translation); this.rotation = new ROSLIB.Quaternion(options.rotation); }; diff --git a/src/math/Vector3.js b/src/math/Vector3.js index 85b2e1510..770f1cb32 100644 --- a/src/math/Vector3.js +++ b/src/math/Vector3.js @@ -7,12 +7,12 @@ * * @constructor * @param options - object with following keys: - * * x - the x value - * * y - the y value - * * z - the z value + * * x - the x value + * * y - the y value + * * z - the z value */ ROSLIB.Vector3 = function(options) { - var options = options || {}; + options = options || {}; this.x = options.x || 0; this.y = options.y || 0; this.z = options.z || 0; diff --git a/src/tf/TFClient.js b/src/tf/TFClient.js index bbfb08e72..987a74c9d 100644 --- a/src/tf/TFClient.js +++ b/src/tf/TFClient.js @@ -15,7 +15,7 @@ * * goalUpdateDelay - the goal update delay for the TF republisher */ ROSLIB.TFClient = function(options) { - var options = options || {}; + options = options || {}; this.ros = options.ros; this.fixedFrame = options.fixedFrame || '/base_link'; this.angularThres = options.angularThres || 2.0; @@ -46,7 +46,7 @@ ROSLIB.TFClient.prototype.processFeedback = function(tf) { tf.transforms.forEach(function(transform) { var frameID = transform.child_frame_id; var info = that.frameInfos[frameID]; - if (info != undefined) { + if (info !== undefined) { info.transform = new ROSLIB.Transform({ translation : transform.transform.translation, rotation : transform.transform.rotation @@ -76,7 +76,7 @@ ROSLIB.TFClient.prototype.updateGoal = function() { rate : this.rate }; - for (frame in this.frameInfos) { + for (var frame in this.frameInfos) { goalMessage.source_frames.push(frame); } @@ -102,7 +102,7 @@ ROSLIB.TFClient.prototype.subscribe = function(frameID, callback) { frameID = frameID.substring(1); } // if there is no callback registered for the given frame, create emtpy callback list - if (this.frameInfos[frameID] == undefined) { + if (this.frameInfos[frameID] === undefined) { this.frameInfos[frameID] = { cbs : [] }; @@ -112,7 +112,7 @@ ROSLIB.TFClient.prototype.subscribe = function(frameID, callback) { } } else { // if we already have a transform, call back immediately - if (this.frameInfos[frameID].transform != undefined) { + if (this.frameInfos[frameID].transform !== undefined) { callback(this.frameInfos[frameID].transform); } } @@ -127,14 +127,15 @@ ROSLIB.TFClient.prototype.subscribe = function(frameID, callback) { */ ROSLIB.TFClient.prototype.unsubscribe = function(frameID, callback) { var info = this.frameInfos[frameID]; - if (info != undefined) { + if (info !== undefined) { var cbIndex = info.cbs.indexOf(callback); if (cbIndex >= 0) { info.cbs.splice(cbIndex, 1); - if (info.cbs.length == 0) { + if (info.cbs.length === 0) { delete this.frameInfos[frameID]; } this.needUpdate = true; } } }; + diff --git a/src/urdf/UrdfBox.js b/src/urdf/UrdfBox.js index 6bb136cec..883220cca 100644 --- a/src/urdf/UrdfBox.js +++ b/src/urdf/UrdfBox.js @@ -5,27 +5,27 @@ /** * A Box element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfBox = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.dimension = null; this.type = null; /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { this.type = ROSLIB.URDF_BOX; - // parse the string + // Parse the string var xyz = xml.getAttribute('size').split(' '); that.dimension = new ROSLIB.Vector3({ x : parseFloat(xyz[0]), @@ -34,6 +34,6 @@ ROSLIB.UrdfBox = function(options) { }); }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; diff --git a/src/urdf/UrdfColor.js b/src/urdf/UrdfColor.js index 46033d0c3..d36c453ee 100644 --- a/src/urdf/UrdfColor.js +++ b/src/urdf/UrdfColor.js @@ -5,14 +5,14 @@ /** * A Color element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfColor = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.r = null; this.g = null; @@ -21,11 +21,11 @@ ROSLIB.UrdfColor = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { - // parse the string + // Parse the string var rgba = xml.getAttribute('rgba').split(' '); that.r = parseFloat(rgba[0]); that.g = parseFloat(rgba[1]); @@ -34,6 +34,6 @@ ROSLIB.UrdfColor = function(options) { return true; }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; diff --git a/src/urdf/UrdfCylinder.js b/src/urdf/UrdfCylinder.js index 3a8150ecf..bc3f738e2 100644 --- a/src/urdf/UrdfCylinder.js +++ b/src/urdf/UrdfCylinder.js @@ -5,14 +5,14 @@ /** * A Cylinder element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfCylinder = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.type = null; this.length = null; @@ -20,7 +20,7 @@ ROSLIB.UrdfCylinder = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { @@ -29,6 +29,7 @@ ROSLIB.UrdfCylinder = function(options) { that.radius = parseFloat(xml.getAttribute('radius')); }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + diff --git a/src/urdf/UrdfLink.js b/src/urdf/UrdfLink.js index fe5ec6ecb..80906e97d 100644 --- a/src/urdf/UrdfLink.js +++ b/src/urdf/UrdfLink.js @@ -5,21 +5,21 @@ /** * A Link element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfLink = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.name = null; this.visual = null; /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { @@ -32,6 +32,7 @@ ROSLIB.UrdfLink = function(options) { } }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + diff --git a/src/urdf/UrdfMaterial.js b/src/urdf/UrdfMaterial.js index 0eaee03a5..456eacce1 100644 --- a/src/urdf/UrdfMaterial.js +++ b/src/urdf/UrdfMaterial.js @@ -5,14 +5,14 @@ /** * A Material element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfMaterial = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.name = null; this.textureFilename = null; @@ -20,28 +20,28 @@ ROSLIB.UrdfMaterial = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { that.name = xml.getAttribute('name'); - // texture + // Texture var textures = xml.getElementsByTagName('texture'); if (textures.length > 0) { that.textureFilename = textures[0].getAttribute('filename'); } - // color + // Color var colors = xml.getElementsByTagName('color'); if (colors.length > 0) { - // parse the RBGA string + // Parse the RBGA string that.color = new ROSLIB.UrdfColor({ xml : colors[0] }); } }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; diff --git a/src/urdf/UrdfMesh.js b/src/urdf/UrdfMesh.js index 5f6f0e88d..cc51b61f4 100644 --- a/src/urdf/UrdfMesh.js +++ b/src/urdf/UrdfMesh.js @@ -5,14 +5,14 @@ /** * A Mesh element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfMesh = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.filename = null; this.scale = null; @@ -20,17 +20,17 @@ ROSLIB.UrdfMesh = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { that.type = ROSLIB.URDF_MESH; that.filename = xml.getAttribute('filename'); - // check for a scale + // Check for a scale var scale = xml.getAttribute('scale'); if (scale) { - // get the XYZ + // Get the XYZ var xyz = scale.split(' '); that.scale = new ROSLIB.Vector3({ x : parseFloat(xyz[0]), @@ -40,6 +40,7 @@ ROSLIB.UrdfMesh = function(options) { } }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + diff --git a/src/urdf/UrdfModel.js b/src/urdf/UrdfModel.js index 3a623932d..a83691dca 100644 --- a/src/urdf/UrdfModel.js +++ b/src/urdf/UrdfModel.js @@ -4,43 +4,41 @@ */ /** - * A URDF Model can be used to parse a given URDF into the appropriate elements. - * + * A URDF Model can be used to parse a given URDF into the appropriate elements. + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse * * string - the XML element to parse as a string */ ROSLIB.UrdfModel = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; var string = options.string; - - this.name; this.materials = []; this.links = []; /** * Initialize the model with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { - // get the robot tag + // Get the robot tag var robotXml = xml.evaluate('//robot', xml, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; - // get the robot name + // Get the robot name that.name = robotXml.getAttribute('name'); - // parse all the visual elements we need - for (n in robotXml.childNodes) { + // Parse all the visual elements we need + for (var n in robotXml.childNodes) { var node = robotXml.childNodes[n]; if (node.tagName === 'material') { var material = new ROSLIB.UrdfMaterial({ xml : node }); - // make sure this is unique + // Make sure this is unique if (that.materials[material.name]) { console.warn('Material ' + material.name + 'is not unique.'); } else { @@ -50,11 +48,11 @@ ROSLIB.UrdfModel = function(options) { var link = new ROSLIB.UrdfLink({ xml : node }); - // make sure this is unique + // Make sure this is unique if (that.links[link.name]) { console.warn('Link ' + link.name + ' is not unique.'); } else { - // check for a material + // Check for a material if (link.visual && link.visual.material) { if (that.materials[link.visual.material.name]) { link.visual.material = that.materials[link.visual.material.name]; @@ -63,19 +61,20 @@ ROSLIB.UrdfModel = function(options) { } } - // add the link + // Add the link that.links[link.name] = link; } } } }; - // check if we are using a string or an XML element + // Check if we are using a string or an XML element if (string) { - // parse the string + // Parse the string var parser = new DOMParser(); xml = parser.parseFromString(string, 'text/xml'); } - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + diff --git a/src/urdf/UrdfSphere.js b/src/urdf/UrdfSphere.js index e59ab72d2..4f170cba7 100644 --- a/src/urdf/UrdfSphere.js +++ b/src/urdf/UrdfSphere.js @@ -5,21 +5,21 @@ /** * A Sphere element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfSphere = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.radius = null; this.type = null; /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { @@ -30,3 +30,4 @@ ROSLIB.UrdfSphere = function(options) { // pass it to the XML parser initXml(xml); }; + diff --git a/src/urdf/UrdfVisual.js b/src/urdf/UrdfVisual.js index 862927a5e..6a75f73f5 100644 --- a/src/urdf/UrdfVisual.js +++ b/src/urdf/UrdfVisual.js @@ -5,14 +5,14 @@ /** * A Visual element in a URDF. - * + * * @constructor * @param options - object with following keys: * * xml - the XML element to parse */ ROSLIB.UrdfVisual = function(options) { + options = options || {}; var that = this; - var options = options || {}; var xml = options.xml; this.origin = null; this.geometry = null; @@ -20,38 +20,34 @@ ROSLIB.UrdfVisual = function(options) { /** * Initialize the element with the given XML node. - * + * * @param xml - the XML element to parse */ var initXml = function(xml) { - // origin + // Origin var origins = xml.getElementsByTagName('origin'); if (origins.length === 0) { // use the identity as the default that.origin = new ROSLIB.Pose(); } else { - // check the XYZ + // Check the XYZ var xyz = origins[0].getAttribute('xyz'); - if (!xyz) { - // use the default values - var position = new ROSLIB.Vector3(); - } else { - var xyz = xyz.split(' '); - var position = new ROSLIB.Vector3({ + var position = new ROSLIB.Vector3(); + if (xyz) { + xyz = xyz.split(' '); + position = new ROSLIB.Vector3({ x : parseFloat(xyz[0]), y : parseFloat(xyz[1]), z : parseFloat(xyz[2]) }); } - // check the RPY + // Check the RPY var rpy = origins[0].getAttribute('rpy'); - if (!rpy) { - // use the default values - var orientation = new ROSLIB.Quaternion(); - } else { - var rpy = rpy.split(' '); - // convert from RPY + var orientation = new ROSLIB.Quaternion(); + if (rpy) { + rpy = rpy.split(' '); + // Convert from RPY var roll = parseFloat(rpy[0]); var pitch = parseFloat(rpy[1]); var yaw = parseFloat(rpy[2]); @@ -67,7 +63,7 @@ ROSLIB.UrdfVisual = function(options) { var w = Math.cos(phi) * Math.cos(the) * Math.cos(psi) + Math.sin(phi) * Math.sin(the) * Math.sin(psi); - var orientation = new ROSLIB.Quaternion({ + orientation = new ROSLIB.Quaternion({ x : x, y : y, z : z, @@ -81,19 +77,19 @@ ROSLIB.UrdfVisual = function(options) { }); } - // geometry + // Geometry var geoms = xml.getElementsByTagName('geometry'); if (geoms.length > 0) { var shape = null; - // check for the shape - for (n in geoms[0].childNodes) { + // Check for the shape + for (var n in geoms[0].childNodes) { var node = geoms[0].childNodes[n]; if (node.nodeType === 1) { shape = node; break; } } - // check the type + // Check the type var type = shape.nodeName; if (type === 'sphere') { that.geometry = new ROSLIB.UrdfSphere({ @@ -116,7 +112,7 @@ ROSLIB.UrdfVisual = function(options) { } } - // material + // Material var materials = xml.getElementsByTagName('material'); if (materials.length > 0) { that.material = new ROSLIB.UrdfMaterial({ @@ -125,6 +121,7 @@ ROSLIB.UrdfVisual = function(options) { } }; - // pass it to the XML parser + // Pass it to the XML parser initXml(xml); }; + diff --git a/utils/.jshintrc b/utils/.jshintrc new file mode 100644 index 000000000..d28b5b997 --- /dev/null +++ b/utils/.jshintrc @@ -0,0 +1,25 @@ +{ + "globals": { + "module": true, + "EventEmitter2" : true + }, + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "sub": true, + "undef": true, + "boss": false, + "eqnull": false, + "browser": true, + "devel": true, + "es5": true, + "strict": false, + "trailing": true, + "quotmark": "single", + "proto": true, + "laxbreak": true +} + diff --git a/utils/Gruntfile.js b/utils/Gruntfile.js new file mode 100644 index 000000000..c05262147 --- /dev/null +++ b/utils/Gruntfile.js @@ -0,0 +1,84 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + concat: { + build: { + src : ['../src/RosLib.js', '../src/**/*.js'], + dest : '../build/roslib.js' + } + }, + jshint: { + options: { + jshintrc: '.jshintrc', + }, + files: [ + 'Gruntfile.js', + '../build/roslib.js' + ], + }, + karma: { + build: { + configFile: '../test/karma.conf.js', + singleRun: true + } + }, + uglify: { + options: { + report: 'min' + }, + build: { + src: '../build/roslib.js', + dest: '../build/roslib.min.js' + } + }, + watch: { + dev: { + options: { + interrupt: true + }, + files: [ + '../src/RosLib.js', + '../src/**/*.js' + ], + tasks: ['concat'] + }, + build_and_watch: { + options: { + interrupt: true + }, + files: [ + 'Gruntfile.js', + '.jshintrc', + '../src/RosLib.js', + '../src/**/*.js' + ], + tasks: ['build'] + } + }, + jsdoc : { + doc : { + src: [ + '../src/RosLib.js', + '../src/**/*.js' + ], + options: { + destination: '../doc' + } + } + } + }); + + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-jsdoc'); + grunt.loadNpmTasks('grunt-karma'); + + grunt.registerTask('dev', ['concat', 'watch']); + grunt.registerTask('build', ['concat', 'jshint', 'karma', 'uglify']); + grunt.registerTask('build_and_watch', ['watch']); + grunt.registerTask('doc', ['jsdoc']); +}; + diff --git a/utils/README.md b/utils/README.md new file mode 100644 index 000000000..5b4c495fe --- /dev/null +++ b/utils/README.md @@ -0,0 +1,52 @@ +roslibjs build setup +==================== + +[Grunt](http://gruntjs.com/) is used for building, including concatenating, +minimizing, documenting, linting, and testing. + +### Install Grunt and its dependencies + +#### Ubuntu + + 1. Install Node.js and its package manager, NPM + * `sudo apt-get install python-software-properties` + * `sudo add-apt-repository ppa:chris-lea/node.js` + * `sudo apt-get install nodejs` + 2. Install Grunt and the test runner [Karma](http://karma-runner.github.io/) + * `sudo npm install -g grunt-cli karma` + 3. Install the Grunt tasks specific to this project + * `cd /path/to/roslibjs/utils/` + * `npm install .` + 4. (Optional) To generate the documentation, you'll need Java and JSDoc. Documentation generation is not required for patches. + * `sudo apt-get install jsdoc-toolkit` + +#### OS X + + 1. Install Node.js and its package manager, NPM + * Go to [Node.js Downloads](http://nodejs.org/download/) + * Download and install the Universal pkg file. + 2. Install Grunt and the test runner [Karma](http://karma-runner.github.io/) + * `sudo npm install -g grunt-cli karma` + 3. Install the Grunt tasks specific to this project + * `cd /path/to/roslibjs/utils/` + * `npm install .` + +### Build with Grunt + +Before proceeding, please confirm you have installed the dependencies above. + +To run the build tasks: + + 1. `cd /path/to/roslibjs/utils/` + 2. `grunt build` + +`grunt build` will concatenate and minimize the files under src and replace +roslib.js and roslib.min.js in the build directory. It will also run the linter +and test cases. This is what [Travis +CI](https://travis-ci.org/RobotWebTools/roslibjs) runs when a Pull Request is +submitted. + +`grunt dev` will watch for any changes to any of the src/ files and +automatically concatenate and minimize the files. This is ideal for those +developing as you should only have to run `grunt dev` once. + diff --git a/utils/build.xml b/utils/build.xml deleted file mode 100644 index 2af15e011..000000000 --- a/utils/build.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - Main Build Script - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${js} created. - - - - - - - - - ${js.min}created. - - - - - - - - - JSDOC created. - - - - diff --git a/utils/package.json b/utils/package.json new file mode 100644 index 000000000..1fb039261 --- /dev/null +++ b/utils/package.json @@ -0,0 +1,12 @@ +{ + "name": "roslibjs", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-concat": "~0.1.3", + "grunt-contrib-jshint": "~0.1.1", + "grunt-karma": "~0.3.0", + "grunt-contrib-watch": "~0.3.1", + "grunt-contrib-uglify": "~0.2.0", + "grunt-jsdoc": "~0.3.0" + } +}