Skip to content

Commit

Permalink
RSDK-9621: Add Discover Service and GetModelsFromModules to Typescript (
Browse files Browse the repository at this point in the history
#436)

Co-authored-by: John <[email protected]>
  • Loading branch information
martha-johnston and JohnN193 authored Jan 27, 2025
1 parent 3a8f661 commit 6bac906
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 9 deletions.
31 changes: 30 additions & 1 deletion src/robot/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@ import { PowerSensorService } from '../gen/component/powersensor/v1/powersensor_
import { ServoService } from '../gen/component/servo/v1/servo_connect';
import { RobotService } from '../gen/robot/v1/robot_connect';
import {
// DiscoveryQuery deprecated, remove on march 10th
DiscoveryQuery,
GetModelsFromModulesRequest,
RestartModuleRequest,
TransformPCDRequest,
TransformPoseRequest,
} from '../gen/robot/v1/robot_pb';
import { DiscoveryService } from '../gen/service/discovery/v1/discovery_connect';
import { MotionService } from '../gen/service/motion/v1/motion_connect';
import { NavigationService } from '../gen/service/navigation/v1/navigation_connect';
import { SLAMService } from '../gen/service/slam/v1/slam_connect';
Expand Down Expand Up @@ -133,6 +136,10 @@ export class RobotClient extends EventDispatcher implements Robot {
| PromiseClient<typeof NavigationService>
| undefined;

private discoveryServiceClient:
| PromiseClient<typeof DiscoveryService>
| undefined;

private motionServiceClient: PromiseClient<typeof MotionService> | undefined;

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

get discoveryService() {
if (!this.discoveryServiceClient) {
throw new Error(RobotClient.notConnectedYetStr);
}
return this.discoveryServiceClient;
}

get motionService() {
if (!this.motionServiceClient) {
throw new Error(RobotClient.notConnectedYetStr);
Expand Down Expand Up @@ -603,6 +617,10 @@ export class RobotClient extends EventDispatcher implements Robot {
SLAMService,
clientTransport
);
this.discoveryServiceClient = createPromiseClient(
DiscoveryService,
clientTransport
);

this.emit(MachineConnectionEvent.CONNECTED, {});
} catch (error) {
Expand Down Expand Up @@ -692,15 +710,26 @@ export class RobotClient extends EventDispatcher implements Robot {
return resp.pointCloudPcd;
}

// DISCOVERY
// DISCOVERY - deprecated, remove on march 10th

async discoverComponents(queries: DiscoveryQuery[]) {
console.warn(
'RobotClient.discoverComponents is deprecated. It will be removed on March 10 2025. Use the DiscoveryService APIs instead.'
);
const resp = await this.robotService.discoverComponents({
queries,
});
return resp.discovery;
}

// GET MODELS FROM MODULES

async getModelsFromModules() {
const request = new GetModelsFromModulesRequest({});
const resp = await this.robotService.getModelsFromModules(request);
return resp.models;
}

// GET CLOUD METADATA

async getCloudMetadata() {
Expand Down
19 changes: 11 additions & 8 deletions src/robot/robot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MachineConnectionEvent } from '../events';
import type { PoseInFrame, Transform } from '../gen/common/v1/common_pb';
import type proto from '../gen/robot/v1/robot_pb';
import type { ResourceName } from '../types';
import type { ModuleModel } from '../gen/robot/v1/robot_pb';

export type CloudMetadata = proto.GetCloudMetadataResponse;

Expand Down Expand Up @@ -103,6 +104,8 @@ export interface Robot {
): Promise<Uint8Array>;

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

/**
* Get the list of discovered component configurations.
*
* @group ComponentConfig
* @alpha
*/
getModelsFromModules(): Promise<ModuleModel[]>;

/**
* Get a list of all resources on the robot.
*
Expand Down Expand Up @@ -173,12 +184,4 @@ export interface Robot {
* @alpha
*/
restartModule(moduleId?: string, moduleName?: string): Promise<void>;

/**
* Get version information about the robot, such as platform, version, and api
* version.
*
* @alpha
*/
getVersion(): Promise<proto.GetVersionResponse>;
}
2 changes: 2 additions & 0 deletions src/services/discovery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { DiscoveryClient } from './discovery/client';
export type { Discovery } from './discovery/discovery';
51 changes: 51 additions & 0 deletions src/services/discovery/client.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// @vitest-environment happy-dom

import {
createPromiseClient,
createRouterTransport,
} from '@connectrpc/connect';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DiscoveryService } from '../../gen/service/discovery/v1/discovery_connect';
import { DiscoverResourcesResponse } from '../../gen/service/discovery/v1/discovery_pb';
import { RobotClient } from '../../robot';
import { DiscoveryClient } from './client';
import { ComponentConfig } from '../../gen/app/v1/robot_pb';
vi.mock('../../robot');
vi.mock('../../gen/service/discovery/v1/discovery_pb_service');

const discoveryClientName = 'test-discovery';

let discovery: DiscoveryClient;

const discoveries: ComponentConfig = new ComponentConfig();

describe('DiscoveryClient Tests', () => {
beforeEach(() => {
const mockTransport = createRouterTransport(({ service }) => {
service(DiscoveryService, {
discoverResources: () =>
new DiscoverResourcesResponse({ discoveries: [discoveries] }),
});
});

RobotClient.prototype.createServiceClient = vi
.fn()
.mockImplementation(() =>
createPromiseClient(DiscoveryService, mockTransport)
);
discovery = new DiscoveryClient(
new RobotClient('host'),
discoveryClientName
);
});

describe('Discovery Resources Tests', () => {
it('returns resources from a machine', async () => {
const expected = [discoveries];

await expect(discovery.discoverResources()).resolves.toStrictEqual(
expected
);
});
});
});
51 changes: 51 additions & 0 deletions src/services/discovery/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Struct, type JsonValue } from '@bufbuild/protobuf';
import type { CallOptions, PromiseClient } from '@connectrpc/connect';
import { DiscoveryService } from '../../gen/service/discovery/v1/discovery_connect';
import { DiscoverResourcesRequest } from '../../gen/service/discovery/v1/discovery_pb';
import type { RobotClient } from '../../robot';
import { doCommandFromClient } from '../../utils';
import type { Options } from '../../types';
import type { Discovery } from './discovery';

/**
* A gRPC-web client for a Vision service.
*
* @group Clients
*/
export class DiscoveryClient implements Discovery {
private client: PromiseClient<typeof DiscoveryService>;
private readonly name: string;
private readonly options: Options;
public callOptions: CallOptions = { headers: {} as Record<string, string> };

constructor(client: RobotClient, name: string, options: Options = {}) {
this.client = client.createServiceClient(DiscoveryService);
this.name = name;
this.options = options;
}

async discoverResources(extra = {}, callOptions = this.callOptions) {
const request = new DiscoverResourcesRequest({
name: this.name,
extra: Struct.fromJson(extra),
});

this.options.requestLogger?.(request);

const resp = await this.client.discoverResources(request, callOptions);
return resp.discoveries;
}

async doCommand(
command: Struct,
callOptions = this.callOptions
): Promise<JsonValue> {
return doCommandFromClient(
this.client.doCommand,
this.name,
command,
this.options,
callOptions
);
}
}
14 changes: 14 additions & 0 deletions src/services/discovery/discovery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Struct } from '@bufbuild/protobuf';
import type { Resource } from '../../types';
import type { ComponentConfig } from '../../gen/app/v1/robot_pb';

/** A service that enables various computer vision algorithms */
export interface Discovery extends Resource {
/**
* Get a list of component configs of all discovered components.
*
* @param discoveryName - The name of the discovery service.
* @returns - The list of ComponentConfigs.
*/
discoverResources: (extra?: Struct) => Promise<ComponentConfig[]>;
}

0 comments on commit 6bac906

Please sign in to comment.