Skip to content

Commit 916f86e

Browse files
RSDK-2480: Encoder API TypeScript SDK changes (#58)
1 parent 6d70b71 commit 916f86e

File tree

6 files changed

+139
-0
lines changed

6 files changed

+139
-0
lines changed

src/components/encoder.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export type { Encoder, EncoderProperties } from './encoder/Encoder';
2+
export { EncoderClient } from './encoder/Client';

src/components/encoder/Client.ts

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { Struct } from 'google-protobuf/google/protobuf/struct_pb';
2+
import type { RobotClient } from '../../robot';
3+
import type { Encoder } from './Encoder';
4+
import { EncoderServiceClient } from '../../gen/component/encoder/v1/encoder_pb_service';
5+
import { type Options, PositionType } from '../../types';
6+
import encoderApi from '../../gen/component/encoder/v1/encoder_pb';
7+
import { promisify } from '../../utils';
8+
9+
/**
10+
* A gRPC-web client for the Encoder component.
11+
*
12+
* @group Clients
13+
*/
14+
export class EncoderClient implements Encoder {
15+
private client: EncoderServiceClient;
16+
private readonly name: string;
17+
private readonly options: Options;
18+
19+
constructor(client: RobotClient, name: string, options: Options = {}) {
20+
this.client = client.createServiceClient(EncoderServiceClient);
21+
this.name = name;
22+
this.options = options;
23+
}
24+
25+
private get encoderService() {
26+
return this.client;
27+
}
28+
29+
async resetPosition(extra = {}) {
30+
const encoderService = this.encoderService;
31+
const request = new encoderApi.ResetPositionRequest();
32+
request.setName(this.name);
33+
request.setExtra(Struct.fromJavaScript(extra));
34+
35+
this.options.requestLogger?.(request);
36+
37+
await promisify<
38+
encoderApi.ResetPositionRequest,
39+
encoderApi.ResetPositionResponse
40+
>(encoderService.resetPosition.bind(encoderService), request);
41+
}
42+
43+
async getProperties(extra = {}) {
44+
const encoderService = this.encoderService;
45+
const request = new encoderApi.GetPropertiesRequest();
46+
request.setName(this.name);
47+
request.setExtra(Struct.fromJavaScript(extra));
48+
49+
this.options.requestLogger?.(request);
50+
51+
const response = await promisify<
52+
encoderApi.GetPropertiesRequest,
53+
encoderApi.GetPropertiesResponse
54+
>(encoderService.getProperties.bind(encoderService), request);
55+
return response.toObject();
56+
}
57+
58+
async getPosition(
59+
positionType: PositionType = PositionType.POSITION_TYPE_UNSPECIFIED,
60+
extra = {}
61+
) {
62+
const encoderService = this.encoderService;
63+
const request = new encoderApi.GetPositionRequest();
64+
request.setName(this.name);
65+
request.setPositionType(positionType);
66+
request.setExtra(Struct.fromJavaScript(extra));
67+
68+
this.options.requestLogger?.(request);
69+
70+
const response = await promisify<
71+
encoderApi.GetPositionRequest,
72+
encoderApi.GetPositionResponse
73+
>(encoderService.getPosition.bind(encoderService), request);
74+
return [response.getValue(), response.getPositionType()] as const;
75+
}
76+
}

src/components/encoder/Encoder.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { Extra, PositionType } from '../../types';
2+
import pb from '../../gen/component/encoder/v1/encoder_pb';
3+
4+
export type EncoderProperties = pb.GetPropertiesResponse.AsObject;
5+
6+
/** Represents a physical encoder. */
7+
export interface Encoder {
8+
/** Set the current position of the encoder as the new zero position. */
9+
resetPosition(extra?: Extra): Promise<void>;
10+
11+
/** Return the encoder's properties. */
12+
getProperties(extra?: Extra): Promise<EncoderProperties>;
13+
14+
/**
15+
* Return the current position either in relative units (ticks away from a
16+
* zero position) or absolute units (degrees along a circle).
17+
*
18+
* @param positionType - The type of position the encoder returns (ticks or
19+
* degrees)
20+
*/
21+
getPosition(
22+
positionType?: PositionType,
23+
extra?: Extra
24+
): Promise<readonly [number, PositionType]>;
25+
}

src/main.ts

+16
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ export { type Board, BoardClient } from './components/board';
7171
export { default as cameraApi } from './gen/component/camera/v1/camera_pb';
7272
export { type Camera, CameraClient } from './components/camera';
7373

74+
/**
75+
* Raw Protobuf interfaces for an Encoder component.
76+
*
77+
* Generated with https://github.com/improbable-eng/grpc-web
78+
*
79+
* @deprecated Use {@link EncoderClient} instead.
80+
* @alpha
81+
* @group Raw Protobufs
82+
*/
83+
export { default as encoderApi } from './gen/component/encoder/v1/encoder_pb';
84+
export {
85+
type Encoder,
86+
type EncoderProperties,
87+
EncoderClient,
88+
} from './components/encoder';
89+
7490
/**
7591
* Raw Protobuf interfaces for a Motor component.
7692
*

src/robot/Client.ts

+14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { dialDirect, dialWebRTC } from '@viamrobotics/rpc';
1313
import { ArmServiceClient } from '../gen/component/arm/v1/arm_pb_service';
1414
import { BaseServiceClient } from '../gen/component/base/v1/base_pb_service';
1515
import { BoardServiceClient } from '../gen/component/board/v1/board_pb_service';
16+
import { EncoderServiceClient } from '../gen/component/encoder/v1/encoder_pb_service';
1617
import { GantryServiceClient } from '../gen/component/gantry/v1/gantry_pb_service';
1718
import { GenericServiceClient } from '../gen/component/generic/v1/generic_pb_service';
1819
import { GripperServiceClient } from '../gen/component/gripper/v1/gripper_pb_service';
@@ -76,6 +77,8 @@ export class RobotClient implements Robot {
7677

7778
private boardServiceClient: BoardServiceClient | undefined;
7879

80+
private encoderServiceClient: EncoderServiceClient | undefined;
81+
7982
private gantryServiceClient: GantryServiceClient | undefined;
8083

8184
private genericServiceClient: GenericServiceClient | undefined;
@@ -155,6 +158,13 @@ export class RobotClient implements Robot {
155158
return this.boardServiceClient;
156159
}
157160

161+
get encoderService() {
162+
if (!this.encoderServiceClient) {
163+
throw new Error(RobotClient.notConnectedYetStr);
164+
}
165+
return this.encoderServiceClient;
166+
}
167+
158168
get gantryService() {
159169
if (!this.gantryServiceClient) {
160170
throw new Error(RobotClient.notConnectedYetStr);
@@ -373,6 +383,10 @@ export class RobotClient implements Robot {
373383
this.serviceHost,
374384
grpcOptions
375385
);
386+
this.encoderServiceClient = new EncoderServiceClient(
387+
this.serviceHost,
388+
grpcOptions
389+
);
376390
this.gantryServiceClient = new GantryServiceClient(
377391
this.serviceHost,
378392
grpcOptions

src/types.ts

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ export interface Options {
2424
requestLogger?: (req: unknown) => void;
2525
}
2626

27+
export enum PositionType {
28+
POSITION_TYPE_UNSPECIFIED = 0,
29+
POSITION_TYPE_TICKS_COUNT = 1,
30+
POSITION_TYPE_ANGLE_DEGREES = 2,
31+
}
32+
2733
// Common Protobuf Types
2834

2935
export type ResourceName = common.ResourceName.AsObject;

0 commit comments

Comments
 (0)