Skip to content

Commit e6cd037

Browse files
committed
Further unifying the interfaces
Implemented uint64 and int64 support Now generating all messages and services on the fly on start (if requested) - message.getAll works and is very fast (takes less than a second) - Fixes #14. Corrected implemention for [U]Int64 in on-the-fly approach Using bignum for [u]int64 if available, otherwise usual javascript numbers are used but a warning is printed if numbers are sent or received that are outside of the precise range of JS for integers (>= 1e15).
1 parent 5b17210 commit e6cd037

File tree

6 files changed

+328
-156
lines changed

6 files changed

+328
-156
lines changed

example_turtle.js

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/**
22
An example of using rosnodejs with turtlesim, incl. services,
33
pub/sub, and actionlib. This example uses the on-demand generated
44
messages.
@@ -9,16 +9,7 @@
99
let rosnodejs = require('./index.js');
1010
const ActionClient = require('./lib/ActionClient.js');
1111

12-
rosnodejs.initNode('/my_node', {
13-
messages: [
14-
'turtlesim/Pose',
15-
'turtle_actionlib/ShapeActionGoal',
16-
'turtle_actionlib/ShapeActionFeedback',
17-
'turtle_actionlib/ShapeActionResult',
18-
'geometry_msgs/Twist',
19-
],
20-
services: ["turtlesim/TeleportRelative"]
21-
}).then((rosNode) => {
12+
rosnodejs.initNode('/my_node', {onTheFly: true}).then((rosNode) => {
2213

2314
// get list of existing publishers, subscribers, and services
2415
rosNode._node._masterApi.getSystemState("/my_node").then((data) => {
@@ -30,11 +21,11 @@ rosnodejs.initNode('/my_node', {
3021

3122
const TeleportRelative = rosnodejs.require('turtlesim').srv.TeleportRelative;
3223
const teleport_request = new TeleportRelative.Request({
33-
linear: -1,
24+
linear: -1,
3425
angular: 0.0
3526
});
3627

37-
let serviceClient = rosNode.serviceClient("/turtle1/teleport_relative",
28+
let serviceClient = rosNode.serviceClient("/turtle1/teleport_relative",
3829
"turtlesim/TeleportRelative");
3930

4031
rosNode.waitForService(serviceClient.getService(), 2000)
@@ -52,17 +43,17 @@ rosnodejs.initNode('/my_node', {
5243
// ---------------------------------------------------------
5344
// Subscribe
5445
rosNode.subscribe(
55-
'/turtle1/pose',
46+
'/turtle1/pose',
5647
'turtlesim/Pose',
5748
(data) => {
5849
console.log('pose', data);
5950
},
6051
{queueSize: 1,
61-
throttleMs: 1000});
52+
throttleMs: 1000});
6253

6354
// ---------------------------------------------------------
6455
// Publish
65-
// equivalent to:
56+
// equivalent to:
6657
// rostopic pub /turtle1/cmd_vel geometry_msgs/Twist '[1, 0, 0]' '[0, 0, 0]'
6758
let cmd_vel = rosNode.advertise('/turtle1/cmd_vel','geometry_msgs/Twist', {
6859
queueSize: 1,
@@ -85,17 +76,54 @@ rosnodejs.initNode('/my_node', {
8576

8677
// wait two seconds for previous example to complete
8778
setTimeout(function() {
88-
let shapeActionGoal = rosnodejs.require('turtle_actionlib').msg.ShapeActionGoal;
89-
let ac = new ActionClient({
90-
type: "turtle_actionlib/ShapeAction",
91-
actionServer: "/turtle_shape"
79+
let shapeActionGoal = rosnodejs.require('turtle_actionlib').msg.ShapeActionGoal;
80+
let ac = new ActionClient({
81+
type: "turtle_actionlib/ShapeAction",
82+
actionServer: "/turtle_shape"
83+
});
84+
ac.sendGoal(new shapeActionGoal({
85+
goal: {
86+
edges: 3,
87+
radius: 1
88+
}
89+
}));
90+
}, 2000);
91+
92+
// ---------------------------------------------------------
93+
// test int64 + uint64
94+
95+
rosNode.subscribe(
96+
'/int64',
97+
'std_msgs/Int64',
98+
(data) => {
99+
console.log('int64', data);
100+
},
101+
{queueSize: 1,
102+
throttleMs: 1000});
103+
104+
let int64pub = rosNode.advertise('/int64','std_msgs/Int64', {
105+
queueSize: 1,
106+
latching: true,
107+
throttleMs: 9
92108
});
93-
ac.sendGoal(new shapeActionGoal({
94-
goal: {
95-
edges: 3,
96-
radius: 1
97-
}
98-
}));
99-
}, 2000);
109+
const Int64 = rosnodejs.require('std_msgs').msg.Int64;
110+
int64pub.publish(new Int64({ data: "429496729456789012" }));
111+
112+
rosNode.subscribe(
113+
'/uint64',
114+
'std_msgs/UInt64',
115+
(data) => {
116+
console.log('uint64', data);
117+
},
118+
{queueSize: 1,
119+
throttleMs: 1000});
120+
121+
let uint64pub = rosNode.advertise('/uint64','std_msgs/UInt64', {
122+
queueSize: 1,
123+
latching: true,
124+
throttleMs: 9
125+
});
126+
const UInt64 = rosnodejs.require('std_msgs').msg.UInt64;
127+
uint64pub.publish(new UInt64({ data: "9223372036854775807" }));
100128

101129
});

index.js

Lines changed: 12 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,19 @@ let Rosnodejs = {
133133
rosNode = new RosNode(nodeName, rosMasterUri);
134134

135135
return new Promise((resolve, reject) => {
136-
this.use(options.messages, options.services).then(() => {
137-
138-
const connectedToMasterCallback = () => {
139-
Logging.initializeOptions(this, options.logging);
140-
resolve(this.getNodeHandle());
141-
};
142-
136+
const connectedToMasterCallback = () => {
137+
Logging.initializeOptions(this, options.logging);
138+
resolve(this.getNodeHandle());
139+
};
140+
141+
if (options.onTheFly) {
142+
// generate definitions for all messages and services
143+
messages.getAll(function() {
144+
_checkMasterHelper(connectedToMasterCallback, 0);
145+
});
146+
} else {
143147
_checkMasterHelper(connectedToMasterCallback, 0);
144-
});
148+
}
145149
})
146150
.catch((err) => {
147151
log.error('Error: ' + err);
@@ -188,68 +192,6 @@ let Rosnodejs = {
188192
return rtv;
189193
},
190194

191-
/** create message classes and services classes for all the given
192-
* types before calling callback */
193-
use(messages, services) {
194-
const self = this;
195-
return new Promise((resolve, reject) => {
196-
self._useMessages(messages)
197-
.then(() => { return self._useServices(services); })
198-
.then(() => { resolve(); });
199-
});
200-
},
201-
202-
/** create message classes for all the given types */
203-
_useMessages(types) {
204-
const self = this;
205-
206-
// make sure required types are available
207-
[
208-
// for action lib:
209-
'actionlib_msgs/GoalStatusArray',
210-
'actionlib_msgs/GoalID',
211-
// for logging:
212-
'rosgraph_msgs/Log',
213-
].forEach(function(type) {
214-
if (!self.checkMessage(type)) {
215-
// required message definition not available yet, load it
216-
// on-demand
217-
types.unshift(type);
218-
}
219-
});
220-
221-
if (!types || types.length == 0) {
222-
return Promise.resolve();
223-
}
224-
var count = types.length;
225-
return new Promise((resolve, reject) => {
226-
types.forEach(function(type) {
227-
messages.getMessage(type, function(error, Message) {
228-
if (--count == 0) {
229-
resolve();
230-
}
231-
});
232-
});
233-
});
234-
},
235-
236-
/** create service classes for all the given types */
237-
_useServices(types) {
238-
if (!types || types.length == 0) {
239-
return Promise.resolve();
240-
}
241-
var count = types.length;
242-
return new Promise((resolve, reject) => {
243-
types.forEach(function(type) {
244-
messages.getService(type, function() {
245-
if (--count == 0) {
246-
resolve();
247-
}
248-
});
249-
});
250-
});
251-
},
252-
253195
/**
254196
* @return {NodeHandle} for initialized node
255197
*/

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"xmlrpc": "chfritz/node-xmlrpc",
2828
"walker" : "1.0.7",
2929
"md5" : "2.1.0",
30-
"async" : "0.1.22",
30+
"async" : "2.0.1",
3131
"bunyan": "1.8.1"
3232
}
3333
}

0 commit comments

Comments
 (0)