@@ -36,81 +36,15 @@ const packages = require('./utils/messageGeneration/packages.js');
3636const ActionServer = require ( './actions/ActionServer.js' ) ;
3737
3838const MsgLoader = require ( './utils/messageGeneration/MessageLoader.js' ) ;
39+ const RemapUtils = require ( './utils/remapping_utils.js' ) ;
40+ const names = require ( './lib/Names.js' ) ;
3941
4042// will be initialized through call to initNode
4143let log = Logging . getLogger ( ) ;
4244let rosNode = null ;
4345let pingMasterTimeout = null ;
4446
4547//------------------------------------------------------------------
46- /**
47- * @private
48- * Helper function to see if the master is available and able to accept
49- * connections.
50- * @param {number } timeout time in ms between connection attempts
51- * @param {number } maxTimeout maximum time in ms to retry before timing out.
52- * A negative number will make it retry forever. 0 will only make one attempt
53- * before timing out.
54- */
55- function _checkMasterHelper ( timeout = 100 , maxTimeout = - 1 ) {
56- let startTime = Date . now ( ) ;
57- const localHelper = ( resolve , reject ) => {
58- pingMasterTimeout = setTimeout ( ( ) => {
59- // also check that the slave api server is set up
60- if ( ! rosNode . slaveApiSetupComplete ( ) ) {
61- if ( Date . now ( ) - startTime >= maxTimeout && ! ( maxTimeout < 0 ) ) {
62- log . error ( `Unable to register with master node [${ rosNode . getRosMasterUri ( ) } ]: unable to set up slave API Server. Stopping...` ) ;
63- reject ( Error ( 'Unable to setup slave API server.' ) ) ;
64- return ;
65- }
66- localHelper ( resolve , reject ) ;
67- return ;
68- }
69- rosNode . getMasterUri ( { maxAttempts : 1 } )
70- . then ( ( ) => {
71- log . infoOnce ( `Connected to master at ${ rosNode . getRosMasterUri ( ) } !` ) ;
72- pingMasterTimeout = null ;
73- resolve ( ) ;
74- } )
75- . catch ( ( err , resp ) => {
76- if ( Date . now ( ) - startTime >= maxTimeout && ! ( maxTimeout < 0 ) ) {
77- log . error ( `Timed out before registering with master node [${ rosNode . getRosMasterUri ( ) } ]: master may not be running yet.` ) ;
78- reject ( Error ( 'Registration with master timed out.' ) ) ;
79- return ;
80- } else {
81- log . warnThrottle ( 60000 , `Unable to register with master node [${ rosNode . getRosMasterUri ( ) } ]: master may not be running yet. Will keep trying.` ) ;
82- localHelper ( resolve , reject ) ;
83- }
84- } ) ;
85- } , timeout ) ;
86- } ;
87-
88- return new Promise ( ( resolve , reject ) => {
89- localHelper ( resolve , reject ) ;
90- } ) ;
91- }
92-
93- /**
94- * Very basic validation of node name - needs to start with a '/'
95- * TODO: more
96- * @return {string } name of node after validation
97- */
98- function _validateNodeName ( nodeName ) {
99- if ( ! nodeName . startsWith ( '/' ) ) {
100- nodeName = '/' + nodeName ;
101- }
102- return nodeName ;
103- }
104-
105- /**
106- * Appends a random string of numeric characters to the end
107- * of the node name. Follows rospy logic.
108- * @param nodeName {string} string to anonymize
109- * @return {string } anonymized nodeName
110- */
111- function _anonymizeNodeName ( nodeName ) {
112- return util . format ( '%s_%s_%s' , nodeName , process . pid , Date . now ( ) ) ;
113- }
11448
11549let Rosnodejs = {
11650 /**
@@ -131,12 +65,25 @@ let Rosnodejs = {
13165 * @return {Promise } resolved when connection to master is established
13266 */
13367 initNode ( nodeName , options ) {
134- options = options || { } ;
135- if ( options . anonymous ) {
136- nodeName = _anonymizeNodeName ( nodeName ) ;
68+ if ( typeof nodeName !== 'string' ) {
69+ throw new Error ( 'The node name must be a string' ) ;
13770 }
71+ else if ( nodeName . length === 0 ) {
72+ throw new Error ( 'The node name must not be empty!' ) ;
73+ }
74+
75+ options = options || { } ;
76+
77+ // process remappings from command line arguments.
78+ // First two are $ node <file> so we skip them
79+ const remappings = RemapUtils . processRemapping ( process . argv . slice ( 2 ) ) ;
13880
139- nodeName = _validateNodeName ( nodeName ) ;
81+ // initialize netUtils from possible command line remappings
82+ netUtils . init ( remappings ) ;
83+
84+ const [ resolvedName , namespace ] = _resolveNodeName ( nodeName , remappings , options ) ;
85+
86+ names . init ( remappings , namespace ) ;
14087
14188 if ( rosNode !== null ) {
14289 if ( nodeName === rosNode . getNodeName ( ) ) {
@@ -147,17 +94,14 @@ let Rosnodejs = {
14794 + rosNode . getNodeName ( ) + '] already exists' ) ) ;
14895 }
14996
150- let rosMasterUri = process . env . ROS_MASTER_URI ;
151- if ( options . rosMasterUri ) {
152- rosMasterUri = options . rosMasterUri ;
153- }
154-
155- Logging . initializeNodeLogger ( nodeName , options . logging ) ;
97+ Logging . initializeNodeLogger ( resolvedName , options . logging ) ;
15698
15799 // create the ros node. Return a promise that will
158100 // resolve when connection to master is established
159101 const nodeOpts = options . node || { } ;
160- rosNode = new RosNode ( nodeName , rosMasterUri , nodeOpts ) ;
102+ const rosMasterUri = options . rosMasterUri || remappings [ '__master' ] || process . env . ROS_MASTER_URI ; ;
103+
104+ rosNode = new RosNode ( resolvedName , rosMasterUri , nodeOpts ) ;
161105
162106 return new Promise ( ( resolve , reject ) => {
163107 this . _loadOnTheFlyMessages ( options )
@@ -338,3 +282,85 @@ let Rosnodejs = {
338282Rosnodejs . ActionServer = ActionServer ;
339283
340284module . exports = Rosnodejs ;
285+
286+ //------------------------------------------------------------------
287+ // Local Helper Functions
288+ //------------------------------------------------------------------
289+
290+ /**
291+ * @private
292+ * Helper function to see if the master is available and able to accept
293+ * connections.
294+ * @param {number } timeout time in ms between connection attempts
295+ * @param {number } maxTimeout maximum time in ms to retry before timing out.
296+ * A negative number will make it retry forever. 0 will only make one attempt
297+ * before timing out.
298+ */
299+ function _checkMasterHelper ( timeout = 100 , maxTimeout = - 1 ) {
300+ const startTime = Date . now ( ) ;
301+
302+ const localHelper = ( resolve , reject ) => {
303+ pingMasterTimeout = setTimeout ( ( ) => {
304+ // also check that the slave api server is set up
305+ if ( ! rosNode . slaveApiSetupComplete ( ) ) {
306+ if ( Date . now ( ) - startTime >= maxTimeout && maxTimeout >= 0 ) {
307+ log . error ( `Unable to register with master node [${ rosNode . getRosMasterUri ( ) } ]: unable to set up slave API Server. Stopping...` ) ;
308+ reject ( new Error ( 'Unable to setup slave API server.' ) ) ;
309+ return ;
310+ }
311+ localHelper ( resolve , reject ) ;
312+ return ;
313+ }
314+ rosNode . getMasterUri ( { maxAttempts : 1 } )
315+ . then ( ( ) => {
316+ log . infoOnce ( `Connected to master at ${ rosNode . getRosMasterUri ( ) } !` ) ;
317+ pingMasterTimeout = null ;
318+ resolve ( ) ;
319+ } )
320+ . catch ( ( err , resp ) => {
321+ if ( Date . now ( ) - startTime >= maxTimeout && ! ( maxTimeout < 0 ) ) {
322+ log . error ( `Timed out before registering with master node [${ rosNode . getRosMasterUri ( ) } ]: master may not be running yet.` ) ;
323+ reject ( new Error ( 'Registration with master timed out.' ) ) ;
324+ return ;
325+ } else {
326+ log . warnThrottle ( 60000 , `Unable to register with master node [${ rosNode . getRosMasterUri ( ) } ]: master may not be running yet. Will keep trying.` ) ;
327+ localHelper ( resolve , reject ) ;
328+ }
329+ } ) ;
330+ } , timeout ) ;
331+ } ;
332+
333+ return new Promise ( ( resolve , reject ) => {
334+ localHelper ( resolve , reject ) ;
335+ } ) ;
336+ }
337+
338+ function _resolveNodeName ( nodeName , remappings , options ) {
339+ let namespace = remappings [ '__ns' ] || process . env . ROS_NAMESPACE || '' ;
340+ namespace = names . clean ( namespace ) ;
341+ if ( namespace . length === 0 || ! namespace . startsWith ( '/' ) ) {
342+ namespace = `/${ namespace } ` ;
343+ }
344+
345+ names . validate ( namespace , true ) ;
346+
347+ nodeName = remappings [ '__name' ] || nodeName ;
348+ nodeName = names . resolve ( namespace , nodeName ) ;
349+
350+ // only anonymize node name if they didn't remap from the command line
351+ if ( options . anonymous && ! remappings [ '__name' ] ) {
352+ nodeName = _anonymizeNodeName ( nodeName ) ;
353+ }
354+
355+ return [ nodeName , namespace ]
356+ }
357+
358+ /**
359+ * Appends a random string of numeric characters to the end
360+ * of the node name. Follows rospy logic.
361+ * @param nodeName {string} string to anonymize
362+ * @return {string } anonymized nodeName
363+ */
364+ function _anonymizeNodeName ( nodeName ) {
365+ return util . format ( '%s_%s_%s' , nodeName , process . pid , Date . now ( ) ) ;
366+ }
0 commit comments