@agenticros/core 0.5.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.
Files changed (151) hide show
  1. package/LICENSE +192 -0
  2. package/README.md +88 -0
  3. package/dist/banner.d.ts +7 -0
  4. package/dist/banner.d.ts.map +1 -0
  5. package/dist/banner.js +25 -0
  6. package/dist/banner.js.map +1 -0
  7. package/dist/capabilities.d.ts +101 -0
  8. package/dist/capabilities.d.ts.map +1 -0
  9. package/dist/capabilities.js +240 -0
  10. package/dist/capabilities.js.map +1 -0
  11. package/dist/cmd-vel-twist.d.ts +9 -0
  12. package/dist/cmd-vel-twist.d.ts.map +1 -0
  13. package/dist/cmd-vel-twist.js +32 -0
  14. package/dist/cmd-vel-twist.js.map +1 -0
  15. package/dist/config.d.ts +1195 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +427 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/discovery.d.ts +113 -0
  20. package/dist/discovery.d.ts.map +1 -0
  21. package/dist/discovery.js +141 -0
  22. package/dist/discovery.js.map +1 -0
  23. package/dist/find-robots-for.d.ts +85 -0
  24. package/dist/find-robots-for.d.ts.map +1 -0
  25. package/dist/find-robots-for.js +120 -0
  26. package/dist/find-robots-for.js.map +1 -0
  27. package/dist/index.d.ts +32 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +20 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/memory/factory.d.ts +18 -0
  32. package/dist/memory/factory.d.ts.map +1 -0
  33. package/dist/memory/factory.js +51 -0
  34. package/dist/memory/factory.js.map +1 -0
  35. package/dist/memory/index.d.ts +3 -0
  36. package/dist/memory/index.d.ts.map +1 -0
  37. package/dist/memory/index.js +2 -0
  38. package/dist/memory/index.js.map +1 -0
  39. package/dist/memory/local/provider.d.ts +29 -0
  40. package/dist/memory/local/provider.d.ts.map +1 -0
  41. package/dist/memory/local/provider.js +202 -0
  42. package/dist/memory/local/provider.js.map +1 -0
  43. package/dist/memory/mem0/provider.d.ts +66 -0
  44. package/dist/memory/mem0/provider.d.ts.map +1 -0
  45. package/dist/memory/mem0/provider.js +310 -0
  46. package/dist/memory/mem0/provider.js.map +1 -0
  47. package/dist/memory/types.d.ts +91 -0
  48. package/dist/memory/types.d.ts.map +1 -0
  49. package/dist/memory/types.js +10 -0
  50. package/dist/memory/types.js.map +1 -0
  51. package/dist/mission-registry.d.ts +94 -0
  52. package/dist/mission-registry.d.ts.map +1 -0
  53. package/dist/mission-registry.js +123 -0
  54. package/dist/mission-registry.js.map +1 -0
  55. package/dist/mission-transcript-sink.d.ts +33 -0
  56. package/dist/mission-transcript-sink.d.ts.map +1 -0
  57. package/dist/mission-transcript-sink.js +76 -0
  58. package/dist/mission-transcript-sink.js.map +1 -0
  59. package/dist/mission.d.ts +281 -0
  60. package/dist/mission.d.ts.map +1 -0
  61. package/dist/mission.js +331 -0
  62. package/dist/mission.js.map +1 -0
  63. package/dist/planner/index.d.ts +84 -0
  64. package/dist/planner/index.d.ts.map +1 -0
  65. package/dist/planner/index.js +486 -0
  66. package/dist/planner/index.js.map +1 -0
  67. package/dist/robots.d.ts +133 -0
  68. package/dist/robots.d.ts.map +1 -0
  69. package/dist/robots.js +220 -0
  70. package/dist/robots.js.map +1 -0
  71. package/dist/topic-utils.d.ts +47 -0
  72. package/dist/topic-utils.d.ts.map +1 -0
  73. package/dist/topic-utils.js +136 -0
  74. package/dist/topic-utils.js.map +1 -0
  75. package/dist/transport/factory.d.ts +10 -0
  76. package/dist/transport/factory.d.ts.map +1 -0
  77. package/dist/transport/factory.js +40 -0
  78. package/dist/transport/factory.js.map +1 -0
  79. package/dist/transport/local/conversion.d.ts +30 -0
  80. package/dist/transport/local/conversion.d.ts.map +1 -0
  81. package/dist/transport/local/conversion.js +340 -0
  82. package/dist/transport/local/conversion.js.map +1 -0
  83. package/dist/transport/local/entities.d.ts +34 -0
  84. package/dist/transport/local/entities.d.ts.map +1 -0
  85. package/dist/transport/local/entities.js +108 -0
  86. package/dist/transport/local/entities.js.map +1 -0
  87. package/dist/transport/local/transport.d.ts +53 -0
  88. package/dist/transport/local/transport.d.ts.map +1 -0
  89. package/dist/transport/local/transport.js +344 -0
  90. package/dist/transport/local/transport.js.map +1 -0
  91. package/dist/transport/rosbridge/actions.d.ts +30 -0
  92. package/dist/transport/rosbridge/actions.d.ts.map +1 -0
  93. package/dist/transport/rosbridge/actions.js +61 -0
  94. package/dist/transport/rosbridge/actions.js.map +1 -0
  95. package/dist/transport/rosbridge/adapter.d.ts +29 -0
  96. package/dist/transport/rosbridge/adapter.d.ts.map +1 -0
  97. package/dist/transport/rosbridge/adapter.js +108 -0
  98. package/dist/transport/rosbridge/adapter.js.map +1 -0
  99. package/dist/transport/rosbridge/client.d.ts +55 -0
  100. package/dist/transport/rosbridge/client.d.ts.map +1 -0
  101. package/dist/transport/rosbridge/client.js +375 -0
  102. package/dist/transport/rosbridge/client.js.map +1 -0
  103. package/dist/transport/rosbridge/services.d.ts +14 -0
  104. package/dist/transport/rosbridge/services.d.ts.map +1 -0
  105. package/dist/transport/rosbridge/services.js +25 -0
  106. package/dist/transport/rosbridge/services.js.map +1 -0
  107. package/dist/transport/rosbridge/topics.d.ts +28 -0
  108. package/dist/transport/rosbridge/topics.d.ts.map +1 -0
  109. package/dist/transport/rosbridge/topics.js +59 -0
  110. package/dist/transport/rosbridge/topics.js.map +1 -0
  111. package/dist/transport/rosbridge/types.d.ts +87 -0
  112. package/dist/transport/rosbridge/types.d.ts.map +1 -0
  113. package/dist/transport/rosbridge/types.js +6 -0
  114. package/dist/transport/rosbridge/types.js.map +1 -0
  115. package/dist/transport/transport.d.ts +39 -0
  116. package/dist/transport/transport.d.ts.map +1 -0
  117. package/dist/transport/transport.js +2 -0
  118. package/dist/transport/transport.js.map +1 -0
  119. package/dist/transport/types.d.ts +100 -0
  120. package/dist/transport/types.d.ts.map +1 -0
  121. package/dist/transport/types.js +5 -0
  122. package/dist/transport/types.js.map +1 -0
  123. package/dist/transport/webrtc/signaling-client.d.ts +38 -0
  124. package/dist/transport/webrtc/signaling-client.d.ts.map +1 -0
  125. package/dist/transport/webrtc/signaling-client.js +161 -0
  126. package/dist/transport/webrtc/signaling-client.js.map +1 -0
  127. package/dist/transport/webrtc/signaling-types.d.ts +112 -0
  128. package/dist/transport/webrtc/signaling-types.d.ts.map +1 -0
  129. package/dist/transport/webrtc/signaling-types.js +8 -0
  130. package/dist/transport/webrtc/signaling-types.js.map +1 -0
  131. package/dist/transport/webrtc/transport.d.ts +67 -0
  132. package/dist/transport/webrtc/transport.d.ts.map +1 -0
  133. package/dist/transport/webrtc/transport.js +406 -0
  134. package/dist/transport/webrtc/transport.js.map +1 -0
  135. package/dist/transport/zenoh/adapter.d.ts +47 -0
  136. package/dist/transport/zenoh/adapter.d.ts.map +1 -0
  137. package/dist/transport/zenoh/adapter.js +296 -0
  138. package/dist/transport/zenoh/adapter.js.map +1 -0
  139. package/dist/transport/zenoh/cdr.d.ts +17 -0
  140. package/dist/transport/zenoh/cdr.d.ts.map +1 -0
  141. package/dist/transport/zenoh/cdr.js +170 -0
  142. package/dist/transport/zenoh/cdr.js.map +1 -0
  143. package/dist/transport/zenoh/keys.d.ts +21 -0
  144. package/dist/transport/zenoh/keys.d.ts.map +1 -0
  145. package/dist/transport/zenoh/keys.js +44 -0
  146. package/dist/transport/zenoh/keys.js.map +1 -0
  147. package/dist/transport-pool.d.ts +74 -0
  148. package/dist/transport-pool.d.ts.map +1 -0
  149. package/dist/transport-pool.js +135 -0
  150. package/dist/transport-pool.js.map +1 -0
  151. package/package.json +80 -0
@@ -0,0 +1,344 @@
1
+ import { createRequire } from "node:module";
2
+ import { EntityCache } from "./entities.js";
3
+ import { toRosMessage, fromRosMessage, loadMessageClass, clearTypeCache } from "./conversion.js";
4
+ const require = createRequire(import.meta.url);
5
+ /** Internal ROS2 topics/services to filter from introspection results. */
6
+ const INTERNAL_TOPIC_PREFIXES = ["/rosout", "/parameter_events", "/agenticros/"];
7
+ const INTERNAL_SERVICE_SUFFIXES = [
8
+ "/describe_parameters",
9
+ "/get_parameter_types",
10
+ "/get_parameters",
11
+ "/list_parameters",
12
+ "/set_parameters",
13
+ "/set_parameters_atomically",
14
+ ];
15
+ /**
16
+ * Mode A transport: direct local DDS communication via rclnodejs.
17
+ *
18
+ * When OpenClaw runs on the robot itself, this transport talks to ROS2
19
+ * directly via the local DDS bus — no network intermediary needed.
20
+ */
21
+ export class LocalTransport {
22
+ domainId;
23
+ status = "disconnected";
24
+ connectionHandlers = new Set();
25
+ /** rclnodejs module — loaded dynamically at runtime (optional dep, no types). */
26
+ rclnodejs = null;
27
+ node = null;
28
+ entityCache = null;
29
+ activeGoals = new Map();
30
+ /** Singleton guard — rclnodejs.init() must only be called once per process. */
31
+ static rclInitialized = false;
32
+ constructor(options) {
33
+ this.domainId = options?.domainId ?? 0;
34
+ }
35
+ // --- Connection lifecycle ---
36
+ async connect() {
37
+ if (this.status === "connected")
38
+ return;
39
+ this.setStatus("connecting");
40
+ try {
41
+ this.rclnodejs = require("rclnodejs");
42
+ // Set domain ID before init if non-default
43
+ if (this.domainId !== 0) {
44
+ process.env.ROS_DOMAIN_ID = String(this.domainId);
45
+ }
46
+ // Global init — only once per process
47
+ if (!LocalTransport.rclInitialized) {
48
+ await this.rclnodejs.init();
49
+ LocalTransport.rclInitialized = true;
50
+ }
51
+ // Use a process-unique node name. If two AgenticROS adapters (e.g. the
52
+ // OpenClaw gateway plugin + the Claude Code MCP server) share the host,
53
+ // a fixed name collides on the DDS bus: rcl logs "Publisher already
54
+ // registered for provided node name" and DDS discovery on the duplicate
55
+ // becomes slow/lossy — listTopics() then returns 0 right after connect.
56
+ const nodeName = `agenticros_local_${process.pid}`;
57
+ this.node = this.rclnodejs.createNode(nodeName);
58
+ this.rclnodejs.spin(this.node);
59
+ this.entityCache = new EntityCache();
60
+ // Give DDS discovery a brief moment to receive announcements from peers
61
+ // before we report "connected". Without this the very first listTopics()
62
+ // can race the executor and return empty even though peers exist.
63
+ // 1500ms was chosen empirically on Jetson + Humble where /arm/*/cmd_pos
64
+ // topics from a sim_arm gz_bridge child take ~1.2s to propagate via
65
+ // multicast (vs ~400ms on x86); the prior 750ms cap caused first
66
+ // list_topics() calls to miss them.
67
+ await new Promise((resolve) => setTimeout(resolve, 1500));
68
+ this.setStatus("connected");
69
+ }
70
+ catch (err) {
71
+ this.setStatus("disconnected");
72
+ throw err;
73
+ }
74
+ }
75
+ async disconnect() {
76
+ if (this.status === "disconnected")
77
+ return;
78
+ // Cancel any active action goals
79
+ for (const [action] of this.activeGoals) {
80
+ try {
81
+ await this.cancelActionGoal(action);
82
+ }
83
+ catch {
84
+ // Best-effort
85
+ }
86
+ }
87
+ this.activeGoals.clear();
88
+ if (this.entityCache && this.node) {
89
+ this.entityCache.destroyAll(this.node);
90
+ this.entityCache = null;
91
+ }
92
+ if (this.node) {
93
+ this.node.destroy();
94
+ this.node = null;
95
+ }
96
+ if (this.rclnodejs && LocalTransport.rclInitialized) {
97
+ try {
98
+ this.rclnodejs.shutdown();
99
+ }
100
+ catch {
101
+ // May already be shut down
102
+ }
103
+ LocalTransport.rclInitialized = false;
104
+ }
105
+ clearTypeCache();
106
+ this.rclnodejs = null;
107
+ this.setStatus("disconnected");
108
+ }
109
+ getStatus() {
110
+ return this.status;
111
+ }
112
+ onConnection(handler) {
113
+ this.connectionHandlers.add(handler);
114
+ return () => {
115
+ this.connectionHandlers.delete(handler);
116
+ };
117
+ }
118
+ // --- Topics ---
119
+ publish(options) {
120
+ this.ensureConnected();
121
+ const publisher = this.entityCache.getPublisher(this.node, options.topic, options.type);
122
+ const rosMsg = toRosMessage(options.type, options.msg);
123
+ publisher.publish(rosMsg);
124
+ }
125
+ subscribe(options, handler) {
126
+ this.ensureConnected();
127
+ const type = options.type ?? this.resolveTopicType(options.topic);
128
+ if (!type) {
129
+ throw new Error(`Cannot subscribe to ${options.topic}: type is required when it cannot be inferred`);
130
+ }
131
+ return this.entityCache.addSubscription(this.node, options.topic, type, handler);
132
+ }
133
+ // --- Services ---
134
+ async callService(options) {
135
+ this.ensureConnected();
136
+ const type = options.type ?? this.resolveServiceType(options.service);
137
+ if (!type) {
138
+ throw new Error(`Cannot call service ${options.service}: type is required when it cannot be inferred`);
139
+ }
140
+ const client = this.entityCache.getServiceClient(this.node, options.service, type);
141
+ // Wait for service to become available (5s timeout)
142
+ const available = await client.waitForService(5000);
143
+ if (!available) {
144
+ throw new Error(`Service ${options.service} not available after 5 seconds`);
145
+ }
146
+ // Create request from args
147
+ const ServiceClass = loadMessageClass(type);
148
+ const request = new ServiceClass.Request();
149
+ if (options.args) {
150
+ for (const [key, value] of Object.entries(options.args)) {
151
+ request[key] = value;
152
+ }
153
+ }
154
+ // Send request with Promise wrapping + timeout
155
+ const response = await this.sendServiceRequest(client, request, 30_000);
156
+ return {
157
+ result: true,
158
+ values: fromRosMessage(response),
159
+ };
160
+ }
161
+ // --- Actions ---
162
+ async sendActionGoal(options) {
163
+ this.ensureConnected();
164
+ const ActionClass = loadMessageClass(options.actionType);
165
+ const actionClient = new this.rclnodejs.ActionClient(this.node, ActionClass, options.action);
166
+ // Wait for action server (5s)
167
+ const available = await actionClient.waitForServer(5000);
168
+ if (!available) {
169
+ actionClient.destroy();
170
+ throw new Error(`Action server ${options.action} not available after 5 seconds`);
171
+ }
172
+ // Build goal message
173
+ const goal = new ActionClass.Goal();
174
+ if (options.args) {
175
+ for (const [key, value] of Object.entries(options.args)) {
176
+ goal[key] = value;
177
+ }
178
+ }
179
+ try {
180
+ const result = await new Promise((resolve, reject) => {
181
+ const timer = setTimeout(() => {
182
+ this.activeGoals.delete(options.action);
183
+ reject(new Error(`Action ${options.action} timed out after 120 seconds`));
184
+ }, 120_000);
185
+ actionClient.sendGoal(goal, (goalHandle) => {
186
+ // Goal response callback — store for cancellation
187
+ this.activeGoals.set(options.action, goalHandle);
188
+ }, (feedback) => {
189
+ // Feedback callback
190
+ if (options.onFeedback) {
191
+ options.onFeedback(fromRosMessage(feedback));
192
+ }
193
+ }, (resultResponse) => {
194
+ // Result callback
195
+ clearTimeout(timer);
196
+ this.activeGoals.delete(options.action);
197
+ resolve(fromRosMessage(resultResponse));
198
+ });
199
+ });
200
+ return { result: true, values: result };
201
+ }
202
+ finally {
203
+ actionClient.destroy();
204
+ }
205
+ }
206
+ async cancelActionGoal(action) {
207
+ const goalHandle = this.activeGoals.get(action);
208
+ if (goalHandle && typeof goalHandle.cancelGoal === "function") {
209
+ await goalHandle.cancelGoal();
210
+ this.activeGoals.delete(action);
211
+ }
212
+ }
213
+ // --- Introspection ---
214
+ async listTopics() {
215
+ this.ensureConnected();
216
+ // DDS discovery is asynchronous AND stateful. On a freshly-connected
217
+ // node, getTopicNamesAndTypes() trickles in results as peers respond -
218
+ // the first call may return 0, the second 2, the third all of them.
219
+ //
220
+ // Two issues motivated the current tuning:
221
+ //
222
+ // 1. A short single-stable-hit policy (600ms) was returning truncated
223
+ // views to Claude: e.g. with the AMR sim alone it'd see /cmd_vel
224
+ // etc. on first call, then a second call 2s later would see all
225
+ // 29 topics including /arm/*/cmd_pos. Claude only calls
226
+ // list_topics once and was missing arm joint topics entirely.
227
+ //
228
+ // 2. DDS multicast announcements on Jetson take longer than on x86 -
229
+ // we routinely see /arm/* topics appear ~1.5s after first call.
230
+ //
231
+ // Fix: require 3 consecutive matching polls (2 stable hits at 300ms
232
+ // intervals = ~900ms of stability), with a 6 s deadline. Worst case
233
+ // ~900ms latency on a steady graph, ~5s+ if discovery is still
234
+ // streaming. The min-count guard (>=3) avoids exiting early when only
235
+ // /clock + /tf + /tf_static have come through.
236
+ const externalFilter = (t) => !INTERNAL_TOPIC_PREFIXES.some((prefix) => t.name.startsWith(prefix));
237
+ const deadline = Date.now() + 6000;
238
+ const MIN_STABLE_COUNT = 3;
239
+ const REQUIRED_STABLE_HITS = 2;
240
+ let raw = [];
241
+ let prevCount = -1;
242
+ let stableHits = 0;
243
+ while (Date.now() < deadline) {
244
+ raw = this.node.getTopicNamesAndTypes();
245
+ const externalCount = raw.filter(externalFilter).length;
246
+ if (externalCount === prevCount && externalCount >= MIN_STABLE_COUNT) {
247
+ stableHits++;
248
+ if (stableHits >= REQUIRED_STABLE_HITS)
249
+ break;
250
+ }
251
+ else {
252
+ stableHits = 0;
253
+ prevCount = externalCount;
254
+ }
255
+ await new Promise((resolve) => setTimeout(resolve, 300));
256
+ }
257
+ return raw.filter(externalFilter).map((t) => ({ name: t.name, type: t.types[0] ?? "" }));
258
+ }
259
+ async listServices() {
260
+ this.ensureConnected();
261
+ const namesAndTypes = this.node.getServiceNamesAndTypes();
262
+ return namesAndTypes
263
+ .filter((s) => !INTERNAL_SERVICE_SUFFIXES.some((suffix) => s.name.endsWith(suffix)))
264
+ .filter((s) => !INTERNAL_TOPIC_PREFIXES.some((prefix) => s.name.startsWith(prefix)))
265
+ .map((s) => ({ name: s.name, type: s.types[0] ?? "" }));
266
+ }
267
+ async listActions() {
268
+ // Same feedback-topic heuristic as rosbridge/adapter.ts
269
+ const topics = await this.listTopics();
270
+ const actions = [];
271
+ const feedbackSuffix = "/_action/feedback";
272
+ for (const topic of topics) {
273
+ if (topic.name.endsWith(feedbackSuffix)) {
274
+ const actionName = topic.name.slice(0, -feedbackSuffix.length);
275
+ let actionType = topic.type;
276
+ if (actionType.endsWith("_FeedbackMessage")) {
277
+ actionType = actionType.slice(0, -"_FeedbackMessage".length);
278
+ }
279
+ actions.push({ name: actionName, type: actionType });
280
+ }
281
+ }
282
+ return actions;
283
+ }
284
+ // --- Private helpers ---
285
+ setStatus(status) {
286
+ this.status = status;
287
+ for (const handler of this.connectionHandlers) {
288
+ handler(status);
289
+ }
290
+ }
291
+ ensureConnected() {
292
+ if (this.status !== "connected" || !this.node || !this.entityCache) {
293
+ throw new Error("LocalTransport is not connected");
294
+ }
295
+ }
296
+ /**
297
+ * Resolve a topic's type from the node's graph introspection.
298
+ * Returns undefined if the topic is not yet known.
299
+ */
300
+ resolveTopicType(topic) {
301
+ if (!this.node)
302
+ return undefined;
303
+ const namesAndTypes = this.node.getTopicNamesAndTypes();
304
+ const entry = namesAndTypes.find((t) => t.name === topic);
305
+ return entry?.types[0];
306
+ }
307
+ /**
308
+ * Resolve a service's type from the node's graph introspection.
309
+ * Returns undefined if the service is not yet known.
310
+ */
311
+ resolveServiceType(service) {
312
+ if (!this.node)
313
+ return undefined;
314
+ const namesAndTypes = this.node.getServiceNamesAndTypes();
315
+ const entry = namesAndTypes.find((s) => s.name === service);
316
+ return entry?.types[0];
317
+ }
318
+ /**
319
+ * Wrap rclnodejs callback-based sendRequest in a Promise with timeout.
320
+ */
321
+ sendServiceRequest(client, request, timeoutMs) {
322
+ return new Promise((resolve, reject) => {
323
+ const timer = setTimeout(() => {
324
+ reject(new Error(`Service call timed out after ${timeoutMs}ms`));
325
+ }, timeoutMs);
326
+ try {
327
+ client.sendRequest(request, (response) => {
328
+ clearTimeout(timer);
329
+ if (response) {
330
+ resolve(response);
331
+ }
332
+ else {
333
+ reject(new Error("Service returned no response"));
334
+ }
335
+ });
336
+ }
337
+ catch (err) {
338
+ clearTimeout(timer);
339
+ reject(err);
340
+ }
341
+ });
342
+ }
343
+ }
344
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/transport/local/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { RosbridgeClient } from "./client.js";
2
+ import type { ActionResultMessage, ActionFeedbackMessage } from "./types.js";
3
+ export interface ActionGoalOptions {
4
+ action: string;
5
+ actionType: string;
6
+ args?: Record<string, unknown>;
7
+ onFeedback?: (feedback: ActionFeedbackMessage) => void;
8
+ timeoutMs?: number;
9
+ }
10
+ /**
11
+ * Client for sending action goals and receiving feedback/results.
12
+ */
13
+ export declare class ActionClient {
14
+ private client;
15
+ constructor(client: RosbridgeClient);
16
+ /**
17
+ * Send an action goal and wait for the result.
18
+ *
19
+ * @param options - Action goal options including feedback handler
20
+ * @returns The action result
21
+ */
22
+ sendGoal(options: ActionGoalOptions): Promise<ActionResultMessage>;
23
+ /**
24
+ * Cancel an in-progress action goal.
25
+ *
26
+ * @param action - The action server name
27
+ */
28
+ cancelGoal(action: string): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/transport/rosbridge/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,eAAe;IAE3C;;;;;OAKG;IACG,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA0CxE;;;;OAIG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOhD"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Client for sending action goals and receiving feedback/results.
3
+ */
4
+ export class ActionClient {
5
+ client;
6
+ constructor(client) {
7
+ this.client = client;
8
+ }
9
+ /**
10
+ * Send an action goal and wait for the result.
11
+ *
12
+ * @param options - Action goal options including feedback handler
13
+ * @returns The action result
14
+ */
15
+ async sendGoal(options) {
16
+ const id = this.client.nextId("action");
17
+ const timeoutMs = options.timeoutMs ?? 120_000; // Actions can be long-running
18
+ // Register feedback handler if provided
19
+ let removeFeedbackHandler = null;
20
+ if (options.onFeedback) {
21
+ const feedbackKey = `__action_feedback__${id}`;
22
+ removeFeedbackHandler = this.client.onMessage(feedbackKey, (msg) => {
23
+ options.onFeedback(msg);
24
+ });
25
+ }
26
+ // Create promise that resolves on action_result
27
+ const resultPromise = new Promise((resolve, reject) => {
28
+ this.client.registerPending(id, (result) => resolve(result), reject, timeoutMs);
29
+ });
30
+ // Send the goal
31
+ this.client.send({
32
+ op: "send_action_goal",
33
+ id,
34
+ action: options.action,
35
+ action_type: options.actionType,
36
+ args: options.args,
37
+ });
38
+ try {
39
+ return await resultPromise;
40
+ }
41
+ finally {
42
+ // Clean up feedback handler regardless of outcome
43
+ if (removeFeedbackHandler) {
44
+ removeFeedbackHandler();
45
+ }
46
+ }
47
+ }
48
+ /**
49
+ * Cancel an in-progress action goal.
50
+ *
51
+ * @param action - The action server name
52
+ */
53
+ async cancelGoal(action) {
54
+ this.client.send({
55
+ op: "cancel_action_goal",
56
+ id: this.client.nextId("cancel"),
57
+ action,
58
+ });
59
+ }
60
+ }
61
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../../src/transport/rosbridge/actions.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,OAAO,YAAY;IACH;IAApB,YAAoB,MAAuB;QAAvB,WAAM,GAAN,MAAM,CAAiB;IAAG,CAAC;IAE/C;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,OAA0B;QACvC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,8BAA8B;QAE9E,wCAAwC;QACxC,IAAI,qBAAqB,GAAwB,IAAI,CAAC;QACtD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,sBAAsB,EAAE,EAAE,CAAC;YAC/C,qBAAqB,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE;gBACjE,OAAO,CAAC,UAAW,CAAC,GAAuC,CAAC,CAAC;YAC/D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,gDAAgD;QAChD,MAAM,aAAa,GAAG,IAAI,OAAO,CAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACzE,IAAI,CAAC,MAAM,CAAC,eAAe,CACzB,EAAE,EACF,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,MAA6B,CAAC,EAClD,MAAM,EACN,SAAS,CACV,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,gBAAgB;QAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,kBAAkB;YACtB,EAAE;YACF,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW,EAAE,OAAO,CAAC,UAAU;YAC/B,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,OAAO,MAAM,aAAa,CAAC;QAC7B,CAAC;gBAAS,CAAC;YACT,kDAAkD;YAClD,IAAI,qBAAqB,EAAE,CAAC;gBAC1B,qBAAqB,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,oBAAoB;YACxB,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;YAChC,MAAM;SACP,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { RosTransport } from "../transport.js";
2
+ import type { ConnectionStatus, ConnectionHandler, Subscription, PublishOptions, AdvertiseOptions, SubscribeOptions, ServiceCallOptions, ServiceCallResult, ActionGoalOptions, ActionResult, TopicInfo, ServiceInfo, ActionInfo, MessageHandler } from "../types.js";
3
+ import type { RosbridgeClientOptions } from "./types.js";
4
+ /**
5
+ * RosTransport adapter that wraps the existing RosbridgeClient.
6
+ *
7
+ * This is the Mode B (Local Network) transport. It connects to a
8
+ * rosbridge_server running on the robot via WebSocket and translates
9
+ * RosTransport method calls into rosbridge protocol messages.
10
+ */
11
+ export declare class RosbridgeTransport implements RosTransport {
12
+ private client;
13
+ private actionClient;
14
+ constructor(options: RosbridgeClientOptions);
15
+ connect(): Promise<void>;
16
+ disconnect(): Promise<void>;
17
+ getStatus(): ConnectionStatus;
18
+ onConnection(handler: ConnectionHandler): () => void;
19
+ advertise(options: AdvertiseOptions): void;
20
+ publish(options: PublishOptions): void;
21
+ subscribe(options: SubscribeOptions, handler: MessageHandler): Subscription;
22
+ callService(options: ServiceCallOptions): Promise<ServiceCallResult>;
23
+ sendActionGoal(options: ActionGoalOptions): Promise<ActionResult>;
24
+ cancelActionGoal(action: string): Promise<void>;
25
+ listTopics(): Promise<TopicInfo[]>;
26
+ listServices(): Promise<ServiceInfo[]>;
27
+ listActions(): Promise<ActionInfo[]>;
28
+ }
29
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/transport/rosbridge/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,cAAc,EACf,MAAM,aAAa,CAAC;AAKrB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;GAMG;AACH,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAAe;gBAEvB,OAAO,EAAE,sBAAsB;IAKrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,SAAS,IAAI,gBAAgB;IAI7B,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAIpD,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAQ1C,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAKtC,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,cAAc,GAAG,YAAY;IAUrE,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAapE,cAAc,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAejE,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAYlC,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAYtC,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;CAsB3C"}
@@ -0,0 +1,108 @@
1
+ import { RosbridgeClient } from "./client.js";
2
+ import { TopicPublisher, TopicSubscriber } from "./topics.js";
3
+ import { callService } from "./services.js";
4
+ import { ActionClient } from "./actions.js";
5
+ /**
6
+ * RosTransport adapter that wraps the existing RosbridgeClient.
7
+ *
8
+ * This is the Mode B (Local Network) transport. It connects to a
9
+ * rosbridge_server running on the robot via WebSocket and translates
10
+ * RosTransport method calls into rosbridge protocol messages.
11
+ */
12
+ export class RosbridgeTransport {
13
+ client;
14
+ actionClient;
15
+ constructor(options) {
16
+ this.client = new RosbridgeClient(options);
17
+ this.actionClient = new ActionClient(this.client);
18
+ }
19
+ async connect() {
20
+ await this.client.connect();
21
+ }
22
+ async disconnect() {
23
+ await this.client.disconnect();
24
+ }
25
+ getStatus() {
26
+ return this.client.getStatus();
27
+ }
28
+ onConnection(handler) {
29
+ return this.client.onConnection(handler);
30
+ }
31
+ advertise(options) {
32
+ this.client.send({
33
+ op: "advertise",
34
+ topic: options.topic,
35
+ type: options.type,
36
+ });
37
+ }
38
+ publish(options) {
39
+ const publisher = new TopicPublisher(this.client, options.topic, options.type);
40
+ publisher.publish(options.msg);
41
+ }
42
+ subscribe(options, handler) {
43
+ const subscriber = new TopicSubscriber(this.client, options.topic, options.type);
44
+ subscriber.subscribe(handler);
45
+ return {
46
+ unsubscribe() {
47
+ subscriber.unsubscribe();
48
+ },
49
+ };
50
+ }
51
+ async callService(options) {
52
+ const response = await callService(this.client, options.service, options.args, options.type);
53
+ return {
54
+ result: response.result,
55
+ values: response.values,
56
+ };
57
+ }
58
+ async sendActionGoal(options) {
59
+ const response = await this.actionClient.sendGoal({
60
+ action: options.action,
61
+ actionType: options.actionType,
62
+ args: options.args,
63
+ onFeedback: options.onFeedback
64
+ ? (feedback) => options.onFeedback(feedback.values)
65
+ : undefined,
66
+ });
67
+ return {
68
+ result: response.result,
69
+ values: response.values,
70
+ };
71
+ }
72
+ async cancelActionGoal(action) {
73
+ await this.actionClient.cancelGoal(action);
74
+ }
75
+ async listTopics() {
76
+ const response = await callService(this.client, "/rosapi/topics", {}, "rosapi/srv/Topics");
77
+ const topics = response.values?.["topics"] ?? [];
78
+ const types = response.values?.["types"] ?? [];
79
+ return topics.map((name, i) => ({ name, type: types[i] ?? "" }));
80
+ }
81
+ async listServices() {
82
+ const response = await callService(this.client, "/rosapi/services", {}, "rosapi/srv/Services");
83
+ const services = response.values?.["services"] ?? [];
84
+ const types = response.values?.["types"] ?? [];
85
+ return services.map((name, i) => ({ name, type: types[i] ?? "" }));
86
+ }
87
+ async listActions() {
88
+ // rosapi has no built-in action listing. Heuristic: action servers expose
89
+ // topics matching */_action/feedback. Extract action names from that pattern.
90
+ const topics = await this.listTopics();
91
+ const actions = [];
92
+ const feedbackSuffix = "/_action/feedback";
93
+ for (const topic of topics) {
94
+ if (topic.name.endsWith(feedbackSuffix)) {
95
+ const actionName = topic.name.slice(0, -feedbackSuffix.length);
96
+ // Feedback type is like "pkg/action/Name_FeedbackMessage"
97
+ // Extract base action type by stripping "_FeedbackMessage" suffix
98
+ let actionType = topic.type;
99
+ if (actionType.endsWith("_FeedbackMessage")) {
100
+ actionType = actionType.slice(0, -"_FeedbackMessage".length);
101
+ }
102
+ actions.push({ name: actionName, type: actionType });
103
+ }
104
+ }
105
+ return actions;
106
+ }
107
+ }
108
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/transport/rosbridge/adapter.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;;;;;GAMG;AACH,MAAM,OAAO,kBAAkB;IACrB,MAAM,CAAkB;IACxB,YAAY,CAAe;IAEnC,YAAY,OAA+B;QACzC,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IACjC,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;IACjC,CAAC;IAED,YAAY,CAAC,OAA0B;QACrC,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,SAAS,CAAC,OAAyB;QACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,WAAW;YACf,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,OAAuB;QAC7B,MAAM,SAAS,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/E,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,SAAS,CAAC,OAAyB,EAAE,OAAuB;QAC1D,MAAM,UAAU,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACjF,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO;YACL,WAAW;gBACT,UAAU,CAAC,WAAW,EAAE,CAAC;YAC3B,CAAC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAA2B;QAC3C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,IAAI,CAAC,MAAM,EACX,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,IAAI,CACb,CAAC;QACF,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAA0B;QAC7C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;YAChD,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC5B,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,UAAW,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACpD,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;SACxB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,MAAc;QACnC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,IAAI,CAAC,MAAM,EACX,gBAAgB,EAChB,EAAE,EACF,mBAAmB,CACpB,CAAC;QACF,MAAM,MAAM,GAAI,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAc,IAAI,EAAE,CAAC;QAC/D,MAAM,KAAK,GAAI,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,CAAc,IAAI,EAAE,CAAC;QAC7D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,IAAI,CAAC,MAAM,EACX,kBAAkB,EAClB,EAAE,EACF,qBAAqB,CACtB,CAAC;QACF,MAAM,QAAQ,GAAI,QAAQ,CAAC,MAAM,EAAE,CAAC,UAAU,CAAc,IAAI,EAAE,CAAC;QACnE,MAAM,KAAK,GAAI,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,CAAc,IAAI,EAAE,CAAC;QAC7D,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,WAAW;QACf,0EAA0E;QAC1E,8EAA8E;QAC9E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACvC,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,mBAAmB,CAAC;QAE3C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;gBACxC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;gBAC/D,0DAA0D;gBAC1D,kEAAkE;gBAClE,IAAI,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC;gBAC5B,IAAI,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;oBAC5C,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBAC/D,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}