rclnodejs 1.8.3 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -37
- package/index.js +39 -0
- package/lib/action/client.js +61 -3
- package/lib/action/server_goal_handle.js +26 -1
- package/lib/message_info.js +94 -0
- package/lib/node.js +260 -13
- package/lib/parameter_event_handler.js +566 -0
- package/lib/parameter_watcher.js +12 -12
- package/lib/qos_overriding_options.js +358 -0
- package/lib/subscription.js +38 -5
- package/lib/timer.js +3 -2
- package/lib/wait_for_message.js +111 -0
- package/package.json +7 -4
- package/prebuilds/linux-arm64/humble-jammy-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-arm64/jazzy-noble-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-arm64/kilted-noble-arm64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/humble-jammy-x64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/jazzy-noble-x64-rclnodejs.node +0 -0
- package/prebuilds/linux-x64/kilted-noble-x64-rclnodejs.node +0 -0
- package/scripts/run_asan_test.sh +118 -0
- package/src/executor.cpp +36 -2
- package/src/executor.h +11 -0
- package/src/rcl_action_client_bindings.cpp +70 -1
- package/src/rcl_context_bindings.cpp +3 -3
- package/src/rcl_graph_bindings.cpp +2 -2
- package/src/rcl_subscription_bindings.cpp +70 -2
- package/src/rcl_timer_bindings.cpp +21 -2
- package/src/rcl_utilities.cpp +2 -2
- package/tools/jsdoc/Makefile +5 -0
- package/tools/jsdoc/README.md +96 -0
- package/tools/jsdoc/build-index.js +610 -0
- package/tools/jsdoc/publish.js +854 -0
- package/tools/jsdoc/regenerate-published-docs.js +605 -0
- package/tools/jsdoc/static/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Bold-webfont.svg +1830 -0
- package/tools/jsdoc/static/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
- package/tools/jsdoc/static/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Italic-webfont.svg +1830 -0
- package/tools/jsdoc/static/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Light-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Light-webfont.svg +1831 -0
- package/tools/jsdoc/static/fonts/OpenSans-Light-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
- package/tools/jsdoc/static/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/tools/jsdoc/static/fonts/OpenSans-Regular-webfont.svg +1831 -0
- package/tools/jsdoc/static/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/tools/jsdoc/static/scripts/linenumber.js +25 -0
- package/tools/jsdoc/static/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/tools/jsdoc/static/scripts/prettify/lang-css.js +36 -0
- package/tools/jsdoc/static/scripts/prettify/prettify.js +738 -0
- package/tools/jsdoc/static/styles/jsdoc-default.css +1012 -0
- package/tools/jsdoc/static/styles/prettify-jsdoc.css +111 -0
- package/tools/jsdoc/static/styles/prettify-tomorrow.css +132 -0
- package/tools/jsdoc/tmpl/augments.tmpl +10 -0
- package/tools/jsdoc/tmpl/container.tmpl +193 -0
- package/tools/jsdoc/tmpl/details.tmpl +143 -0
- package/tools/jsdoc/tmpl/example.tmpl +2 -0
- package/tools/jsdoc/tmpl/examples.tmpl +13 -0
- package/tools/jsdoc/tmpl/exceptions.tmpl +17 -0
- package/tools/jsdoc/tmpl/layout.tmpl +83 -0
- package/tools/jsdoc/tmpl/mainpage.tmpl +163 -0
- package/tools/jsdoc/tmpl/members.tmpl +43 -0
- package/tools/jsdoc/tmpl/method.tmpl +124 -0
- package/tools/jsdoc/tmpl/params.tmpl +133 -0
- package/tools/jsdoc/tmpl/properties.tmpl +110 -0
- package/tools/jsdoc/tmpl/returns.tmpl +12 -0
- package/tools/jsdoc/tmpl/source.tmpl +8 -0
- package/tools/jsdoc/tmpl/tutorial.tmpl +19 -0
- package/tools/jsdoc/tmpl/type.tmpl +7 -0
- package/types/action_client.d.ts +8 -0
- package/types/index.d.ts +34 -0
- package/types/message_info.d.ts +72 -0
- package/types/node.d.ts +90 -5
- package/types/parameter_event_handler.d.ts +150 -0
- package/types/qos.d.ts +55 -0
- package/types/subscription.d.ts +14 -2
- package/types/timer.d.ts +3 -2
- package/test_data_integrity.js +0 -108
- package/test_repro_exact.js +0 -57
- package/test_repro_hz.js +0 -86
- package/test_repro_pub.js +0 -36
- package/test_repro_stress.js +0 -83
- package/test_repro_sub.js +0 -64
- package/test_xproc_data.js +0 -64
- package/types/interfaces.d.ts +0 -8895
package/test_repro_exact.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// Thorough latency/throughput test matching the exact issue scenario
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const rclnodejs = require('./index.js');
|
|
5
|
-
|
|
6
|
-
async function main() {
|
|
7
|
-
await rclnodejs.init();
|
|
8
|
-
|
|
9
|
-
const node = new rclnodejs.Node('test_node');
|
|
10
|
-
|
|
11
|
-
let lastTs;
|
|
12
|
-
let msgCount = 0;
|
|
13
|
-
const hzSamples = [];
|
|
14
|
-
|
|
15
|
-
node.createSubscription(
|
|
16
|
-
'std_msgs/msg/Float64MultiArray',
|
|
17
|
-
'/map_to_base_link_pose2d',
|
|
18
|
-
(msg) => {
|
|
19
|
-
const now = Date.now();
|
|
20
|
-
msgCount++;
|
|
21
|
-
if (lastTs) {
|
|
22
|
-
const hz = 1000 / (now - lastTs);
|
|
23
|
-
hzSamples.push(hz);
|
|
24
|
-
console.log('Raw Hz:', hz.toFixed(2));
|
|
25
|
-
}
|
|
26
|
-
lastTs = now;
|
|
27
|
-
}
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
rclnodejs.spin(node);
|
|
31
|
-
|
|
32
|
-
console.log('Waiting for messages on /map_to_base_link_pose2d at ~10Hz...');
|
|
33
|
-
console.log('Run this in another terminal:');
|
|
34
|
-
console.log(
|
|
35
|
-
' ros2 topic pub -r 10 /map_to_base_link_pose2d std_msgs/msg/Float64MultiArray "{data: [1.0, 2.0, 3.0]}"'
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
setTimeout(() => {
|
|
39
|
-
if (hzSamples.length > 0) {
|
|
40
|
-
const avgHz = hzSamples.reduce((a, b) => a + b, 0) / hzSamples.length;
|
|
41
|
-
console.log(`\n--- Summary ---`);
|
|
42
|
-
console.log(`Messages: ${msgCount}, Avg Hz: ${avgHz.toFixed(2)}`);
|
|
43
|
-
if (avgHz < 5) {
|
|
44
|
-
console.log('*** REGRESSION DETECTED ***');
|
|
45
|
-
} else {
|
|
46
|
-
console.log('Performance OK');
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
console.log('No messages received');
|
|
50
|
-
}
|
|
51
|
-
node.stop();
|
|
52
|
-
rclnodejs.shutdown();
|
|
53
|
-
process.exit(0);
|
|
54
|
-
}, 15000);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
main().catch(console.error);
|
package/test_repro_hz.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
// Reprocer for https://github.com/RobotWebTools/rclnodejs/issues/1394
|
|
2
|
-
// Tests subscription throughput at ~10Hz publishing rate
|
|
3
|
-
'use strict';
|
|
4
|
-
|
|
5
|
-
const rclnodejs = require('./index.js');
|
|
6
|
-
|
|
7
|
-
const PUBLISH_HZ = 10;
|
|
8
|
-
const TEST_DURATION_SEC = 10;
|
|
9
|
-
|
|
10
|
-
async function main() {
|
|
11
|
-
await rclnodejs.init();
|
|
12
|
-
|
|
13
|
-
const pubNode = new rclnodejs.Node('test_pub_node');
|
|
14
|
-
const subNode = new rclnodejs.Node('test_sub_node');
|
|
15
|
-
|
|
16
|
-
const publisher = pubNode.createPublisher(
|
|
17
|
-
'std_msgs/msg/Float64MultiArray',
|
|
18
|
-
'/test_hz_topic'
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
let msgCount = 0;
|
|
22
|
-
let lastTs = null;
|
|
23
|
-
const hzSamples = [];
|
|
24
|
-
|
|
25
|
-
subNode.createSubscription(
|
|
26
|
-
'std_msgs/msg/Float64MultiArray',
|
|
27
|
-
'/test_hz_topic',
|
|
28
|
-
(msg) => {
|
|
29
|
-
const now = Date.now();
|
|
30
|
-
msgCount++;
|
|
31
|
-
if (lastTs) {
|
|
32
|
-
const hz = 1000 / (now - lastTs);
|
|
33
|
-
hzSamples.push(hz);
|
|
34
|
-
}
|
|
35
|
-
lastTs = now;
|
|
36
|
-
}
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
pubNode.spin();
|
|
40
|
-
subNode.spin();
|
|
41
|
-
|
|
42
|
-
// Publish at target Hz
|
|
43
|
-
let pubCount = 0;
|
|
44
|
-
const pubInterval = setInterval(() => {
|
|
45
|
-
publisher.publish({ data: [1.0, 2.0, 3.0] });
|
|
46
|
-
pubCount++;
|
|
47
|
-
}, 1000 / PUBLISH_HZ);
|
|
48
|
-
|
|
49
|
-
// Wait for test duration then report
|
|
50
|
-
setTimeout(() => {
|
|
51
|
-
clearInterval(pubInterval);
|
|
52
|
-
|
|
53
|
-
if (hzSamples.length > 0) {
|
|
54
|
-
const avgHz =
|
|
55
|
-
hzSamples.reduce((a, b) => a + b, 0) / hzSamples.length;
|
|
56
|
-
const minHz = Math.min(...hzSamples);
|
|
57
|
-
const maxHz = Math.max(...hzSamples);
|
|
58
|
-
|
|
59
|
-
console.log(`Published: ${pubCount} messages`);
|
|
60
|
-
console.log(`Received: ${msgCount} messages`);
|
|
61
|
-
console.log(`Avg Hz: ${avgHz.toFixed(2)}`);
|
|
62
|
-
console.log(`Min Hz: ${minHz.toFixed(2)}`);
|
|
63
|
-
console.log(`Max Hz: ${maxHz.toFixed(2)}`);
|
|
64
|
-
console.log(
|
|
65
|
-
`Expected: ~${PUBLISH_HZ} Hz`
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
if (avgHz < PUBLISH_HZ * 0.5) {
|
|
69
|
-
console.log(
|
|
70
|
-
`\n*** REGRESSION DETECTED: Average Hz (${avgHz.toFixed(2)}) is less than 50% of expected (${PUBLISH_HZ}) ***`
|
|
71
|
-
);
|
|
72
|
-
} else {
|
|
73
|
-
console.log('\nPerformance looks OK.');
|
|
74
|
-
}
|
|
75
|
-
} else {
|
|
76
|
-
console.log('No messages received!');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
pubNode.stop();
|
|
80
|
-
subNode.stop();
|
|
81
|
-
rclnodejs.shutdown();
|
|
82
|
-
process.exit(0);
|
|
83
|
-
}, TEST_DURATION_SEC * 1000);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
main().catch(console.error);
|
package/test_repro_pub.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// Publisher for repro test - runs in separate process
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const rclnodejs = require('./index.js');
|
|
5
|
-
|
|
6
|
-
const PUBLISH_HZ = parseInt(process.argv[2] || '100');
|
|
7
|
-
|
|
8
|
-
async function main() {
|
|
9
|
-
await rclnodejs.init();
|
|
10
|
-
|
|
11
|
-
const node = new rclnodejs.Node('test_publisher_node');
|
|
12
|
-
const publisher = node.createPublisher(
|
|
13
|
-
'std_msgs/msg/Float64MultiArray',
|
|
14
|
-
'/test_hz_topic'
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
node.spin();
|
|
18
|
-
|
|
19
|
-
let pubCount = 0;
|
|
20
|
-
console.log(`Publishing at ${PUBLISH_HZ} Hz...`);
|
|
21
|
-
|
|
22
|
-
const pubInterval = setInterval(() => {
|
|
23
|
-
publisher.publish({ data: [1.0, 2.0, 3.0] });
|
|
24
|
-
pubCount++;
|
|
25
|
-
}, 1000 / PUBLISH_HZ);
|
|
26
|
-
|
|
27
|
-
setTimeout(() => {
|
|
28
|
-
clearInterval(pubInterval);
|
|
29
|
-
console.log(`Published ${pubCount} messages total`);
|
|
30
|
-
node.stop();
|
|
31
|
-
rclnodejs.shutdown();
|
|
32
|
-
process.exit(0);
|
|
33
|
-
}, 15000);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
main().catch(console.error);
|
package/test_repro_stress.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
// Multi-frequency stress test for subscription performance
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const rclnodejs = require('./index.js');
|
|
5
|
-
|
|
6
|
-
const PUBLISH_HZ = parseInt(process.argv[2] || '100');
|
|
7
|
-
const TEST_DURATION_SEC = 10;
|
|
8
|
-
|
|
9
|
-
async function main() {
|
|
10
|
-
await rclnodejs.init();
|
|
11
|
-
|
|
12
|
-
const pubNode = new rclnodejs.Node('stress_pub_node');
|
|
13
|
-
const subNode = new rclnodejs.Node('stress_sub_node');
|
|
14
|
-
|
|
15
|
-
const publisher = pubNode.createPublisher(
|
|
16
|
-
'std_msgs/msg/Float64MultiArray',
|
|
17
|
-
'/stress_test_topic'
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
let msgCount = 0;
|
|
21
|
-
let lastTs = null;
|
|
22
|
-
const hzSamples = [];
|
|
23
|
-
|
|
24
|
-
subNode.createSubscription(
|
|
25
|
-
'std_msgs/msg/Float64MultiArray',
|
|
26
|
-
'/stress_test_topic',
|
|
27
|
-
(msg) => {
|
|
28
|
-
const now = Date.now();
|
|
29
|
-
msgCount++;
|
|
30
|
-
if (lastTs) {
|
|
31
|
-
const hz = 1000 / (now - lastTs);
|
|
32
|
-
hzSamples.push(hz);
|
|
33
|
-
}
|
|
34
|
-
lastTs = now;
|
|
35
|
-
}
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
pubNode.spin();
|
|
39
|
-
subNode.spin();
|
|
40
|
-
|
|
41
|
-
let pubCount = 0;
|
|
42
|
-
|
|
43
|
-
// Use high-resolution timer for more precise publishing
|
|
44
|
-
const intervalMs = 1000 / PUBLISH_HZ;
|
|
45
|
-
const pubInterval = setInterval(() => {
|
|
46
|
-
publisher.publish({ data: [1.0, 2.0, 3.0, 4.0, 5.0] });
|
|
47
|
-
pubCount++;
|
|
48
|
-
}, intervalMs);
|
|
49
|
-
|
|
50
|
-
setTimeout(() => {
|
|
51
|
-
clearInterval(pubInterval);
|
|
52
|
-
|
|
53
|
-
if (hzSamples.length > 0) {
|
|
54
|
-
const avgHz = hzSamples.reduce((a, b) => a + b, 0) / hzSamples.length;
|
|
55
|
-
const minHz = Math.min(...hzSamples);
|
|
56
|
-
const maxHz = Math.max(...hzSamples);
|
|
57
|
-
const dropRate = ((pubCount - msgCount) / pubCount * 100);
|
|
58
|
-
|
|
59
|
-
console.log(`Target: ${PUBLISH_HZ} Hz`);
|
|
60
|
-
console.log(`Published: ${pubCount}`);
|
|
61
|
-
console.log(`Received: ${msgCount}`);
|
|
62
|
-
console.log(`Avg Hz: ${avgHz.toFixed(2)}`);
|
|
63
|
-
console.log(`Min Hz: ${minHz.toFixed(2)}`);
|
|
64
|
-
console.log(`Max Hz: ${maxHz.toFixed(2)}`);
|
|
65
|
-
console.log(`Drop rate: ${dropRate.toFixed(1)}%`);
|
|
66
|
-
|
|
67
|
-
if (avgHz < PUBLISH_HZ * 0.5) {
|
|
68
|
-
console.log(`FAIL: Avg Hz significantly below target`);
|
|
69
|
-
} else {
|
|
70
|
-
console.log(`PASS`);
|
|
71
|
-
}
|
|
72
|
-
} else {
|
|
73
|
-
console.log('No messages received!');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
pubNode.stop();
|
|
77
|
-
subNode.stop();
|
|
78
|
-
rclnodejs.shutdown();
|
|
79
|
-
process.exit(0);
|
|
80
|
-
}, TEST_DURATION_SEC * 1000);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
main().catch(console.error);
|
package/test_repro_sub.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// Subscriber for repro test - runs in separate process
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const rclnodejs = require('./index.js');
|
|
5
|
-
|
|
6
|
-
async function main() {
|
|
7
|
-
await rclnodejs.init();
|
|
8
|
-
|
|
9
|
-
const node = new rclnodejs.Node('test_subscriber_node');
|
|
10
|
-
|
|
11
|
-
let msgCount = 0;
|
|
12
|
-
let lastTs = null;
|
|
13
|
-
const hzSamples = [];
|
|
14
|
-
let startTime = null;
|
|
15
|
-
|
|
16
|
-
node.createSubscription(
|
|
17
|
-
'std_msgs/msg/Float64MultiArray',
|
|
18
|
-
'/test_hz_topic',
|
|
19
|
-
(msg) => {
|
|
20
|
-
const now = Date.now();
|
|
21
|
-
msgCount++;
|
|
22
|
-
if (!startTime) startTime = now;
|
|
23
|
-
if (lastTs) {
|
|
24
|
-
const hz = 1000 / (now - lastTs);
|
|
25
|
-
hzSamples.push(hz);
|
|
26
|
-
if (msgCount % 50 === 0) {
|
|
27
|
-
const recentSamples = hzSamples.slice(-50);
|
|
28
|
-
const recentAvg =
|
|
29
|
-
recentSamples.reduce((a, b) => a + b, 0) / recentSamples.length;
|
|
30
|
-
console.log(
|
|
31
|
-
`msg#${msgCount} recent avg Hz: ${recentAvg.toFixed(2)}`
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
lastTs = now;
|
|
36
|
-
}
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
node.spin();
|
|
40
|
-
|
|
41
|
-
setTimeout(() => {
|
|
42
|
-
if (hzSamples.length > 0) {
|
|
43
|
-
const avgHz =
|
|
44
|
-
hzSamples.reduce((a, b) => a + b, 0) / hzSamples.length;
|
|
45
|
-
const minHz = Math.min(...hzSamples);
|
|
46
|
-
const maxHz = Math.max(...hzSamples);
|
|
47
|
-
const elapsed = (Date.now() - startTime) / 1000;
|
|
48
|
-
|
|
49
|
-
console.log(`\n--- Results ---`);
|
|
50
|
-
console.log(`Received: ${msgCount} messages in ${elapsed.toFixed(1)}s`);
|
|
51
|
-
console.log(`Avg Hz: ${avgHz.toFixed(2)}`);
|
|
52
|
-
console.log(`Min Hz: ${minHz.toFixed(2)}`);
|
|
53
|
-
console.log(`Max Hz: ${maxHz.toFixed(2)}`);
|
|
54
|
-
} else {
|
|
55
|
-
console.log('No messages received!');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
node.stop();
|
|
59
|
-
rclnodejs.shutdown();
|
|
60
|
-
process.exit(0);
|
|
61
|
-
}, 12000);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
main().catch(console.error);
|
package/test_xproc_data.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// Cross-process data integrity test: validates data from external ROS2 publisher
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const rclnodejs = require('./index.js');
|
|
5
|
-
|
|
6
|
-
const EXPECTED_DATA = [1.0, 2.0, 3.0];
|
|
7
|
-
|
|
8
|
-
async function main() {
|
|
9
|
-
await rclnodejs.init();
|
|
10
|
-
|
|
11
|
-
const node = new rclnodejs.Node('xproc_data_sub');
|
|
12
|
-
let msgCount = 0;
|
|
13
|
-
let errCount = 0;
|
|
14
|
-
const errors = [];
|
|
15
|
-
|
|
16
|
-
node.createSubscription(
|
|
17
|
-
'std_msgs/msg/Float64MultiArray',
|
|
18
|
-
'/xproc_data_topic',
|
|
19
|
-
(msg) => {
|
|
20
|
-
msgCount++;
|
|
21
|
-
|
|
22
|
-
if (!msg || !msg.data) {
|
|
23
|
-
errCount++;
|
|
24
|
-
errors.push(`msg#${msgCount}: missing data`);
|
|
25
|
-
} else {
|
|
26
|
-
const arr = Array.from(msg.data);
|
|
27
|
-
for (let i = 0; i < EXPECTED_DATA.length; i++) {
|
|
28
|
-
if (Math.abs(arr[i] - EXPECTED_DATA[i]) > 1e-9) {
|
|
29
|
-
errCount++;
|
|
30
|
-
errors.push(
|
|
31
|
-
`msg#${msgCount}: data[${i}] expected ${EXPECTED_DATA[i]}, got ${arr[i]}`
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (arr.length !== EXPECTED_DATA.length) {
|
|
36
|
-
errCount++;
|
|
37
|
-
errors.push(
|
|
38
|
-
`msg#${msgCount}: expected ${EXPECTED_DATA.length} elements, got ${arr.length}`
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
rclnodejs.spin(node);
|
|
46
|
-
|
|
47
|
-
console.log('Listening on /xproc_data_topic for 10s...');
|
|
48
|
-
|
|
49
|
-
setTimeout(() => {
|
|
50
|
-
console.log(`\n=== Cross-Process Data Integrity ===`);
|
|
51
|
-
console.log(`Received: ${msgCount} messages`);
|
|
52
|
-
console.log(`Data errors: ${errCount}`);
|
|
53
|
-
if (errors.length > 0) {
|
|
54
|
-
errors.slice(0, 10).forEach((e) => console.log(` ${e}`));
|
|
55
|
-
}
|
|
56
|
-
const pass = errCount === 0 && msgCount > 0;
|
|
57
|
-
console.log(`Result: ${pass ? 'PASS' : 'FAIL'}`);
|
|
58
|
-
node.stop();
|
|
59
|
-
rclnodejs.shutdown();
|
|
60
|
-
process.exit(0);
|
|
61
|
-
}, 10000);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
main().catch(console.error);
|