Skip to content

Commit c5ee335

Browse files
committed
Merge pull request #12 from chfritz/Issue#6_generate_message_handlers_automatically
Issue#6 generate message handlers automatically
2 parents 4c604d3 + 390c0fd commit c5ee335

File tree

12 files changed

+1132
-37
lines changed

12 files changed

+1132
-37
lines changed

example2.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
'use strict';
2+
3+
let rosnodejs = require('./index.js');
4+
// const std_msgs = rosnodejs.require('std_msgs').msg;
5+
// const SetBool = rosnodejs.require('std_srvs').srv.SetBool;
6+
7+
rosnodejs.use(['std_msgs/String'],
8+
['std_srvs/SetBool'], function() {
9+
10+
const msg = new (rosnodejs.message('std_msgs/String'))(
11+
{ data: "howdy" });
12+
13+
rosnodejs.initNode('/my_node')
14+
.then((rosNode) => {
15+
16+
// EXP 1) Service Server
17+
let service = rosNode.advertiseService({
18+
service: '/set_bool',
19+
type: 'std_srvs/SetBool'
20+
}, (req, resp) => {
21+
console.log('Handling request! ' + JSON.stringify(req));
22+
resp.success = !req.data;
23+
resp.message = 'Inverted!';
24+
return true;
25+
});
26+
27+
// EXP 2) Service Client
28+
setTimeout(function() {
29+
let serviceClient = rosNode.serviceClient({
30+
service: '/set_bool',
31+
type: 'std_srvs/SetBool'
32+
});
33+
rosNode.waitForService(serviceClient.getService(), 2000)
34+
.then((available) => {
35+
if (available) {
36+
const request =
37+
new (rosnodejs.serviceRequest('std_srvs/SetBool'))({
38+
data: false });
39+
serviceClient.call(request, (resp) => {
40+
console.log('Service response ' + JSON.stringify(resp));
41+
});
42+
} else {
43+
console.log('Service not available');
44+
}
45+
});
46+
}, 1000); // wait a second before calling our service
47+
48+
// EXP 3) Params
49+
rosNode.setParam('~junk', {'hi': 2}).then(() => {
50+
rosNode.getParam('~junk').then((val) => {
51+
console.log('Got Param!!! ' + JSON.stringify(val));
52+
});
53+
});
54+
55+
// // EXP 4) Publisher
56+
let pub = rosNode.advertise({
57+
topic: '/my_topic',
58+
type: 'std_msgs/String',
59+
queueSize: 1,
60+
latching: true,
61+
throttleMs: 9
62+
});
63+
64+
let msgStart = 'my message ';
65+
let iter = 0;
66+
setInterval(() => {
67+
msg.data = msgStart + iter
68+
pub.publish(msg);
69+
++iter;
70+
if (iter > 200) {
71+
iter = 0;
72+
}
73+
}, 5);
74+
75+
// EXP 5) Subscriber
76+
let sub = rosNode.subscribe({
77+
topic: '/my_topic',
78+
type: 'std_msgs/String',
79+
queueSize: 1,
80+
throttleMs: 1000},
81+
(data) => {
82+
console.log('SUB DATA ', data, data.data);
83+
});
84+
});
85+
86+
});
87+

index.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
const netUtils = require('./utils/network_utils.js');
2323
const msgUtils = require('./utils/message_utils.js');
24+
const messages = require('./utils/messages.js');
2425
msgUtils.findMessageFiles();
2526

2627
// these will be modules, they depend on logger which isn't initialized yet
@@ -136,6 +137,58 @@ let Rosnodejs = {
136137
return pack;
137138
},
138139

140+
/** create message classes and services classes for all the given
141+
* types before calling callback */
142+
use(messages, services, callback) {
143+
const self = this;
144+
this._useMessages(messages, function() {
145+
self._useServices(services, callback);
146+
});
147+
},
148+
149+
/** create message classes for all the given types */
150+
_useMessages(types, callback) {
151+
var Messages = [];
152+
types.forEach(function(type) {
153+
messages.getMessage(type, function(error, Message) {
154+
Messages.push(Message);
155+
if (Messages.length === types.length) {
156+
callback();
157+
}
158+
});
159+
});
160+
},
161+
162+
/** create message classes for all the given types */
163+
_useServices(types, callback) {
164+
var count = types.length;
165+
types.forEach(function(type) {
166+
messages.getServiceRequest(type, function() {
167+
messages.getServiceResponse(type, function() {
168+
if (--count == 0) {
169+
callback();
170+
}
171+
});
172+
});
173+
});
174+
},
175+
176+
/** get message definition class from registry. Do not generate it
177+
* from .msg file if it doesn't already exist. This is mostly
178+
* because that would need to be async right now and we want a sync
179+
* method. */
180+
message(type) {
181+
return messages.getFromRegistry(type, "message");
182+
},
183+
184+
serviceRequest(type) {
185+
return messages.getFromRegistry(type, "request");
186+
},
187+
188+
serviceResponse(type) {
189+
return messages.getFromRegistry(type, "response");
190+
},
191+
139192
/**
140193
* @return {NodeHandle} for initialized node
141194
*/

lib/Publisher.js

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
* You may obtain a copy of the License at
99
* http://www.apache.org/licenses/LICENSE-2.0
1010
*
11-
* Unless required by applicable law or agreed to in writing, software
12-
* distributed under the License is distributed on an "AS IS" BASIS,
13-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14-
* See the License for the specific language governing permissions and
15-
* limitations under the License.
11+
* Unless required by applicable law or agreed to in writing,
12+
* software distributed under the License is distributed on an "AS
13+
* IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14+
* express or implied. See the License for the specific language
15+
* governing permissions and limitations under the License.
1616
*/
1717

1818
"use strict";
@@ -48,9 +48,11 @@ class Publisher extends EventEmitter {
4848
}
4949

5050
/**
51-
* throttleMs interacts with queueSize to determine when to send messages.
51+
* throttleMs interacts with queueSize to determine when to send
52+
* messages.
5253
* < 0 : send immediately - no interaction with queue
53-
* >= 0 : place event at end of event queue to publish message after minimum delay (MS)
54+
* >= 0 : place event at end of event queue to publish message
55+
after minimum delay (MS)
5456
*/
5557
if (options.hasOwnProperty('throttleMs')) {
5658
this._throttleMs = options.throttleMs;
@@ -118,7 +120,8 @@ class Publisher extends EventEmitter {
118120
}
119121

120122
/**
121-
* Schedule the msg for publishing - or publish immediately if we're supposed to
123+
* Schedule the msg for publishing - or publish immediately if we're
124+
* supposed to
122125
* @param msg {object} object type matching this._type
123126
* @param [throttleMs] {number} optional override for publisher setting
124127
*/
@@ -149,7 +152,8 @@ class Publisher extends EventEmitter {
149152
if (this._pubTimeout === null) {
150153
let now = Date.now();
151154
if (this._pubTime !== null) {
152-
// check how long to throttle for based on the last time we published
155+
// check how long to throttle for based on the last time we
156+
// published
153157
if (now - this._pubTime > throttleMs) {
154158
throttleMs = 0;
155159
}
@@ -180,11 +184,16 @@ class Publisher extends EventEmitter {
180184
try {
181185
let bufferInfo = {buffer: [], length: 0};
182186
// serialize pushes buffers onto buffInfo.buffer in order
183-
// concat them, and preprend the byte length to the message before sending
187+
// concat them, and preprend the byte length to the message
188+
// before sending
189+
// console.log("_publish", this._messageHandler, msg);
184190
bufferInfo = this._messageHandler.serialize(msg, bufferInfo);
191+
// bufferInfo = msg.serialize();
192+
// console.log("_publish", bufferInfo);
185193

186194
// prepend byte length to message
187-
let serialized = Serialize(Buffer.concat(bufferInfo.buffer, bufferInfo.length));
195+
let serialized = Serialize(
196+
Buffer.concat(bufferInfo.buffer, bufferInfo.length));
188197
Object.keys(this._subClients).forEach((client) => {
189198
this._subClients[client].write(serialized);
190199
});
@@ -197,7 +206,7 @@ class Publisher extends EventEmitter {
197206
}
198207
}
199208
catch (err) {
200-
this._log.warn('Error when publishing message ' + err);
209+
this._log.warn('Error when publishing message ', err.stack);
201210
}
202211
});
203212

@@ -212,13 +221,16 @@ class Publisher extends EventEmitter {
212221
NetworkUtils.getFreePort()
213222
.then((port) => {
214223
let server = net.createServer((subscriber) => {
215-
let subName = subscriber.remoteAddress + ":" + subscriber.remotePort;
224+
let subName = subscriber.remoteAddress + ":"
225+
+ subscriber.remotePort;
216226
subscriber.name = subName;
217-
this._log.debug('Publisher ' + this.getTopic() + ' got connection from ' + subName);
227+
this._log.debug('Publisher ' + this.getTopic()
228+
+ ' got connection from ' + subName);
218229

219-
// subscriber will send us tcpros handshake before we can start publishing
220-
// to it.
221-
subscriber.$handshake = this._handleHandshake.bind(this, subscriber);
230+
// subscriber will send us tcpros handshake before we can
231+
// start publishing to it.
232+
subscriber.$handshake =
233+
this._handleHandshake.bind(this, subscriber);
222234

223235
// handshake will be TCPROS encoded, so use a DeserializeStream to
224236
// handle any chunking
@@ -233,7 +245,8 @@ class Publisher extends EventEmitter {
233245
}
234246

235247
subscriber.on('close', () => {
236-
this._log.info('Publisher ' + this.getTopic() + ' client ' + subscriber.name + ' disconnected!');
248+
this._log.info('Publisher ' + this.getTopic() + ' client '
249+
+ subscriber.name + ' disconnected!');
237250
delete this._subClients[subscriber.name];
238251
});
239252

@@ -271,15 +284,24 @@ class Publisher extends EventEmitter {
271284
_handleHandshake(subscriber, data) {
272285
if (!subscriber.$initialized) {
273286
let header = TcprosUtils.parseSubHeader(data);
274-
let valid = TcprosUtils.validateSubHeader(header, this.getTopic(), this.getType(), this._messageHandler.md5sum());
287+
let valid = TcprosUtils.validateSubHeader(
288+
header, this.getTopic(), this.getType(),
289+
this._messageHandler.md5sum());
275290
if (valid !== null) {
276-
this._log.error('Unable to validate connection header ' + JSON.stringify(header));
291+
this._log.error('Unable to validate connection header '
292+
+ JSON.stringify(header));
277293
subscriber.write(Serialize(valid));
278294
return;
279295
}
280-
this._log.debug('Pub ' + this.getTopic() + ' got connection header ' + JSON.stringify(header));
281-
282-
let respHeader = TcprosUtils.createPubHeader(this._nodeHandle.getNodeName(), this._messageHandler.md5sum(), this.getType(), this.getLatching());
296+
this._log.debug('Pub ' + this.getTopic()
297+
+ ' got connection header ' + JSON.stringify(header));
298+
299+
let respHeader =
300+
TcprosUtils.createPubHeader(
301+
this._nodeHandle.getNodeName(),
302+
this._messageHandler.md5sum(),
303+
this.getType(),
304+
this.getLatching());
283305
subscriber.write(respHeader);
284306

285307
if (this._lastSentMsg !== null) {
@@ -293,7 +315,8 @@ class Publisher extends EventEmitter {
293315
this.emit('connection', subscriber.name);
294316
}
295317
else {
296-
this._log.error('Got message from subscriber after handshake - what gives!!');
318+
this._log.error(
319+
'Got message from subscriber after handshake - what gives!!');
297320
}
298321
}
299322

@@ -310,7 +333,8 @@ class Publisher extends EventEmitter {
310333
}
311334
})
312335
.catch((err, resp) => {
313-
this._log.error('reg pub err ' + err + ' resp: ' + JSON.stringify(resp));
336+
this._log.error('reg pub err ' + err + ' resp: '
337+
+ JSON.stringify(resp));
314338
})
315339
}
316340

lib/ServiceClient.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ class ServiceClient extends EventEmitter {
7777
.then((resp) => {
7878
let serviceUri = resp[2];
7979
// connect to the service
80-
return this._connectToService(NetworkUtils.getAddressAndPortFromUri(serviceUri), request);
80+
return this._connectToService(
81+
NetworkUtils.getAddressAndPortFromUri(serviceUri),
82+
request
83+
);
8184
})
8285
.then((msg) => {
8386
responseCallback(msg);

lib/ServiceServer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ class ServiceServer extends EventEmitter {
3939

4040
this._nodeHandle = nodeHandle;
4141

42-
this._log = log.createLogger({name: 'srvServer' + this.getService()});
42+
this._log = log.createLogger({
43+
name: 'srvServer' + this.getService()
44+
});
4345

4446
this._requestCallback = callback;
4547

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
"dependencies": {
2222
"moment": "^2.12.0",
2323
"portscanner": "^1.0.0",
24-
"xmlrpc": "^1.3.1"
24+
"xmlrpc": "^1.3.1",
25+
"walker" : "1.0.7",
26+
"md5" : "2.1.0",
27+
"async" : "0.1.22"
2528
}
2629
}

0 commit comments

Comments
 (0)