Skip to content

Commit 6bac906

Browse files
RSDK-9621: Add Discover Service and GetModelsFromModules to Typescript (#436)
Co-authored-by: John <[email protected]>
1 parent 3a8f661 commit 6bac906

File tree

6 files changed

+159
-9
lines changed

6 files changed

+159
-9
lines changed

src/robot/client.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@ import { PowerSensorService } from '../gen/component/powersensor/v1/powersensor_
2424
import { ServoService } from '../gen/component/servo/v1/servo_connect';
2525
import { RobotService } from '../gen/robot/v1/robot_connect';
2626
import {
27+
// DiscoveryQuery deprecated, remove on march 10th
2728
DiscoveryQuery,
29+
GetModelsFromModulesRequest,
2830
RestartModuleRequest,
2931
TransformPCDRequest,
3032
TransformPoseRequest,
3133
} from '../gen/robot/v1/robot_pb';
34+
import { DiscoveryService } from '../gen/service/discovery/v1/discovery_connect';
3235
import { MotionService } from '../gen/service/motion/v1/motion_connect';
3336
import { NavigationService } from '../gen/service/navigation/v1/navigation_connect';
3437
import { SLAMService } from '../gen/service/slam/v1/slam_connect';
@@ -133,6 +136,10 @@ export class RobotClient extends EventDispatcher implements Robot {
133136
| PromiseClient<typeof NavigationService>
134137
| undefined;
135138

139+
private discoveryServiceClient:
140+
| PromiseClient<typeof DiscoveryService>
141+
| undefined;
142+
136143
private motionServiceClient: PromiseClient<typeof MotionService> | undefined;
137144

138145
private visionServiceClient: PromiseClient<typeof VisionService> | undefined;
@@ -345,6 +352,13 @@ export class RobotClient extends EventDispatcher implements Robot {
345352
return this.navigationServiceClient;
346353
}
347354

355+
get discoveryService() {
356+
if (!this.discoveryServiceClient) {
357+
throw new Error(RobotClient.notConnectedYetStr);
358+
}
359+
return this.discoveryServiceClient;
360+
}
361+
348362
get motionService() {
349363
if (!this.motionServiceClient) {
350364
throw new Error(RobotClient.notConnectedYetStr);
@@ -603,6 +617,10 @@ export class RobotClient extends EventDispatcher implements Robot {
603617
SLAMService,
604618
clientTransport
605619
);
620+
this.discoveryServiceClient = createPromiseClient(
621+
DiscoveryService,
622+
clientTransport
623+
);
606624

607625
this.emit(MachineConnectionEvent.CONNECTED, {});
608626
} catch (error) {
@@ -692,15 +710,26 @@ export class RobotClient extends EventDispatcher implements Robot {
692710
return resp.pointCloudPcd;
693711
}
694712

695-
// DISCOVERY
713+
// DISCOVERY - deprecated, remove on march 10th
696714

697715
async discoverComponents(queries: DiscoveryQuery[]) {
716+
console.warn(
717+
'RobotClient.discoverComponents is deprecated. It will be removed on March 10 2025. Use the DiscoveryService APIs instead.'
718+
);
698719
const resp = await this.robotService.discoverComponents({
699720
queries,
700721
});
701722
return resp.discovery;
702723
}
703724

725+
// GET MODELS FROM MODULES
726+
727+
async getModelsFromModules() {
728+
const request = new GetModelsFromModulesRequest({});
729+
const resp = await this.robotService.getModelsFromModules(request);
730+
return resp.models;
731+
}
732+
704733
// GET CLOUD METADATA
705734

706735
async getCloudMetadata() {

src/robot/robot.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { MachineConnectionEvent } from '../events';
33
import type { PoseInFrame, Transform } from '../gen/common/v1/common_pb';
44
import type proto from '../gen/robot/v1/robot_pb';
55
import type { ResourceName } from '../types';
6+
import type { ModuleModel } from '../gen/robot/v1/robot_pb';
67

78
export type CloudMetadata = proto.GetCloudMetadataResponse;
89

@@ -103,6 +104,8 @@ export interface Robot {
103104
): Promise<Uint8Array>;
104105

105106
/**
107+
* Deprecated: v0.36.0, use the Discovery Service APIs instead.
108+
*
106109
* Get the list of discovered component configurations.
107110
*
108111
* @param queries - The list of component models to discovery.
@@ -113,6 +116,14 @@ export interface Robot {
113116
queries: proto.DiscoveryQuery[]
114117
): Promise<proto.Discovery[]>;
115118

119+
/**
120+
* Get the list of discovered component configurations.
121+
*
122+
* @group ComponentConfig
123+
* @alpha
124+
*/
125+
getModelsFromModules(): Promise<ModuleModel[]>;
126+
116127
/**
117128
* Get a list of all resources on the robot.
118129
*
@@ -173,12 +184,4 @@ export interface Robot {
173184
* @alpha
174185
*/
175186
restartModule(moduleId?: string, moduleName?: string): Promise<void>;
176-
177-
/**
178-
* Get version information about the robot, such as platform, version, and api
179-
* version.
180-
*
181-
* @alpha
182-
*/
183-
getVersion(): Promise<proto.GetVersionResponse>;
184187
}

src/services/discovery.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { DiscoveryClient } from './discovery/client';
2+
export type { Discovery } from './discovery/discovery';
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// @vitest-environment happy-dom
2+
3+
import {
4+
createPromiseClient,
5+
createRouterTransport,
6+
} from '@connectrpc/connect';
7+
import { beforeEach, describe, expect, it, vi } from 'vitest';
8+
import { DiscoveryService } from '../../gen/service/discovery/v1/discovery_connect';
9+
import { DiscoverResourcesResponse } from '../../gen/service/discovery/v1/discovery_pb';
10+
import { RobotClient } from '../../robot';
11+
import { DiscoveryClient } from './client';
12+
import { ComponentConfig } from '../../gen/app/v1/robot_pb';
13+
vi.mock('../../robot');
14+
vi.mock('../../gen/service/discovery/v1/discovery_pb_service');
15+
16+
const discoveryClientName = 'test-discovery';
17+
18+
let discovery: DiscoveryClient;
19+
20+
const discoveries: ComponentConfig = new ComponentConfig();
21+
22+
describe('DiscoveryClient Tests', () => {
23+
beforeEach(() => {
24+
const mockTransport = createRouterTransport(({ service }) => {
25+
service(DiscoveryService, {
26+
discoverResources: () =>
27+
new DiscoverResourcesResponse({ discoveries: [discoveries] }),
28+
});
29+
});
30+
31+
RobotClient.prototype.createServiceClient = vi
32+
.fn()
33+
.mockImplementation(() =>
34+
createPromiseClient(DiscoveryService, mockTransport)
35+
);
36+
discovery = new DiscoveryClient(
37+
new RobotClient('host'),
38+
discoveryClientName
39+
);
40+
});
41+
42+
describe('Discovery Resources Tests', () => {
43+
it('returns resources from a machine', async () => {
44+
const expected = [discoveries];
45+
46+
await expect(discovery.discoverResources()).resolves.toStrictEqual(
47+
expected
48+
);
49+
});
50+
});
51+
});

src/services/discovery/client.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { Struct, type JsonValue } from '@bufbuild/protobuf';
2+
import type { CallOptions, PromiseClient } from '@connectrpc/connect';
3+
import { DiscoveryService } from '../../gen/service/discovery/v1/discovery_connect';
4+
import { DiscoverResourcesRequest } from '../../gen/service/discovery/v1/discovery_pb';
5+
import type { RobotClient } from '../../robot';
6+
import { doCommandFromClient } from '../../utils';
7+
import type { Options } from '../../types';
8+
import type { Discovery } from './discovery';
9+
10+
/**
11+
* A gRPC-web client for a Vision service.
12+
*
13+
* @group Clients
14+
*/
15+
export class DiscoveryClient implements Discovery {
16+
private client: PromiseClient<typeof DiscoveryService>;
17+
private readonly name: string;
18+
private readonly options: Options;
19+
public callOptions: CallOptions = { headers: {} as Record<string, string> };
20+
21+
constructor(client: RobotClient, name: string, options: Options = {}) {
22+
this.client = client.createServiceClient(DiscoveryService);
23+
this.name = name;
24+
this.options = options;
25+
}
26+
27+
async discoverResources(extra = {}, callOptions = this.callOptions) {
28+
const request = new DiscoverResourcesRequest({
29+
name: this.name,
30+
extra: Struct.fromJson(extra),
31+
});
32+
33+
this.options.requestLogger?.(request);
34+
35+
const resp = await this.client.discoverResources(request, callOptions);
36+
return resp.discoveries;
37+
}
38+
39+
async doCommand(
40+
command: Struct,
41+
callOptions = this.callOptions
42+
): Promise<JsonValue> {
43+
return doCommandFromClient(
44+
this.client.doCommand,
45+
this.name,
46+
command,
47+
this.options,
48+
callOptions
49+
);
50+
}
51+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { Struct } from '@bufbuild/protobuf';
2+
import type { Resource } from '../../types';
3+
import type { ComponentConfig } from '../../gen/app/v1/robot_pb';
4+
5+
/** A service that enables various computer vision algorithms */
6+
export interface Discovery extends Resource {
7+
/**
8+
* Get a list of component configs of all discovered components.
9+
*
10+
* @param discoveryName - The name of the discovery service.
11+
* @returns - The list of ComponentConfigs.
12+
*/
13+
discoverResources: (extra?: Struct) => Promise<ComponentConfig[]>;
14+
}

0 commit comments

Comments
 (0)