-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RSDK-8714: add Servo wrappers #60
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
core/sdk/src/main/java/com/viam/sdk/core/component/servo/Servo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package com.viam.sdk.core.component.servo; | ||
|
||
import com.google.protobuf.Struct; | ||
import com.viam.common.v1.Common; | ||
import com.viam.sdk.core.component.Component; | ||
import com.viam.sdk.core.resource.Resource; | ||
import com.viam.sdk.core.resource.Subtype; | ||
import com.viam.sdk.core.robot.RobotClient; | ||
|
||
|
||
/** | ||
* Servo represents a physical servo | ||
*/ | ||
public abstract class Servo extends Component { | ||
public static final Subtype SUBTYPE = new Subtype( | ||
Subtype.NAMESPACE_RDK, | ||
Subtype.RESOURCE_TYPE_COMPONENT, | ||
"servo"); | ||
|
||
public Servo(final String name) { | ||
super(SUBTYPE, named(name)); | ||
} | ||
|
||
/** | ||
* Get the ResourceName of the component | ||
* | ||
* @param name the name of the component | ||
* @return the component's ResourceName | ||
*/ | ||
public static Common.ResourceName named(final String name) { | ||
return Resource.named(SUBTYPE, name); | ||
} | ||
|
||
|
||
/** | ||
* Get the component with the provided name from the provided robot. | ||
* @param robot the RobotClient | ||
* @param name the name of the component | ||
* @return the component | ||
*/ | ||
public static Servo fromRobot(final RobotClient robot, final String name) { | ||
return robot.getResource(Servo.class, named(name)); | ||
} | ||
|
||
/** | ||
* Move the servo to the provided angle. | ||
* @param angle the desired angle of the servo in degrees | ||
*/ | ||
public abstract void move(int angle, Struct extra); | ||
|
||
/** | ||
* Move the servo to the provided angle. | ||
* @param angle the desired angle of the servo in degrees | ||
*/ | ||
public void move(int angle){ | ||
move(angle, Struct.getDefaultInstance()); | ||
} | ||
|
||
/** | ||
* Get the current angle (degrees) of the servo. | ||
* @return the current angle of the servo in degrees | ||
*/ | ||
public abstract int getPosition(Struct extra); | ||
|
||
/** | ||
* Get the current angle (degrees) of the servo. | ||
* @return the current angle of the servo in degrees | ||
*/ | ||
public int getPosition(){ | ||
return getPosition(Struct.getDefaultInstance()); | ||
} | ||
|
||
/** | ||
* Stop the servo. It is assumed that the servo stops immediately. | ||
*/ | ||
public abstract void stop(Struct extra); | ||
|
||
/** | ||
* Stop the servo. It is assumed that the servo stops immediately. | ||
*/ | ||
public void stop(){ | ||
stop(Struct.getDefaultInstance()); | ||
} | ||
|
||
|
||
/** | ||
* Get if the servo is currently moving. | ||
* @return whether the servo is moving | ||
*/ | ||
public abstract boolean isMoving(); | ||
|
||
|
||
} | ||
|
68 changes: 68 additions & 0 deletions
68
core/sdk/src/main/java/com/viam/sdk/core/component/servo/ServoRPCClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package com.viam.sdk.core.component.servo; | ||
|
||
import com.google.protobuf.Struct; | ||
import com.google.protobuf.Value; | ||
import com.viam.common.v1.Common; | ||
import com.viam.component.servo.v1.ServoServiceGrpc; | ||
|
||
import com.viam.sdk.core.rpc.Channel; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
public class ServoRPCClient extends Servo{ | ||
private final ServoServiceGrpc.ServoServiceBlockingStub client; | ||
|
||
public ServoRPCClient(final String name, final Channel chan) { | ||
super(name); | ||
final ServoServiceGrpc.ServoServiceBlockingStub client = ServoServiceGrpc.newBlockingStub(chan); | ||
if (chan.getCallCredentials().isPresent()) { | ||
this.client = client.withCallCredentials(chan.getCallCredentials().get()); | ||
} else { | ||
this.client = client; | ||
} | ||
} | ||
|
||
@Override | ||
public Struct doCommand(final Map<String, Value> command) { | ||
return client.doCommand(Common.DoCommandRequest.newBuilder(). | ||
setName(getName().getName()). | ||
setCommand(Struct.newBuilder().putAllFields(command).build()). | ||
build()).getResult(); | ||
} | ||
|
||
@Override | ||
public void move(int angle, Struct extra) { | ||
com.viam.component.servo.v1.Servo.MoveRequest moveRequest = com.viam.component.servo.v1.Servo.MoveRequest.newBuilder().setName(this.getName().getName()).setAngleDeg(angle).setExtra(extra).build(); | ||
client.move(moveRequest); | ||
} | ||
|
||
@Override | ||
public int getPosition(Struct extra) { | ||
com.viam.component.servo.v1.Servo.GetPositionRequest getPositionRequest = com.viam.component.servo.v1.Servo.GetPositionRequest.newBuilder().setName(this.getName().getName()).setExtra(extra).build(); | ||
return client.getPosition(getPositionRequest).getPositionDeg(); | ||
} | ||
|
||
|
||
@Override | ||
public void stop(Struct extra) { | ||
com.viam.component.servo.v1.Servo.StopRequest stopRequest = com.viam.component.servo.v1.Servo.StopRequest.newBuilder().setName(this.getName().getName()).setExtra(extra).build(); | ||
client.stop(stopRequest); | ||
} | ||
|
||
@Override | ||
public boolean isMoving() { | ||
com.viam.component.servo.v1.Servo.IsMovingRequest isMovingRequest = com.viam.component.servo.v1.Servo.IsMovingRequest.newBuilder().setName(this.getName().getName()).build(); | ||
return client.isMoving(isMovingRequest).getIsMoving(); | ||
} | ||
|
||
@Override | ||
public List<Common.Geometry> getGeometries(Optional<Struct> extra){ | ||
Common.GetGeometriesRequest.Builder builder = Common.GetGeometriesRequest.newBuilder().setName(this.getName().getName()); | ||
extra.ifPresent(builder::setExtra); | ||
return client.getGeometries(builder.build()).getGeometriesList(); | ||
|
||
} | ||
} | ||
|
76 changes: 76 additions & 0 deletions
76
core/sdk/src/main/java/com/viam/sdk/core/component/servo/ServoRPCService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package com.viam.sdk.core.component.servo; | ||
import com.google.protobuf.Struct; | ||
import com.viam.common.v1.Common; | ||
import com.viam.component.servo.v1.ServoServiceGrpc; | ||
import com.viam.sdk.core.resource.ResourceRPCService; | ||
import com.viam.sdk.core.resource.ResourceManager; | ||
import io.grpc.stub.StreamObserver; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
|
||
public class ServoRPCService extends ServoServiceGrpc.ServoServiceImplBase implements ResourceRPCService<Servo> { | ||
|
||
private final ResourceManager manager; | ||
public ServoRPCService(ResourceManager manager) { this.manager = manager; } | ||
@Override | ||
public Class<Servo> getResourceClass() { | ||
return Servo.class; | ||
} | ||
|
||
@Override | ||
public ResourceManager getManager() { | ||
return manager; | ||
} | ||
|
||
@Override | ||
public void move(com.viam.component.servo.v1.Servo.MoveRequest request, StreamObserver<com.viam.component.servo.v1.Servo.MoveResponse> responseObserver) { | ||
Servo servo = getResource(Servo.named(request.getName())); | ||
servo.move(request.getAngleDeg(), request.getExtra()); | ||
responseObserver.onNext(com.viam.component.servo.v1.Servo.MoveResponse.newBuilder().build()); | ||
responseObserver.onCompleted(); | ||
} | ||
|
||
@Override | ||
public void stop(com.viam.component.servo.v1.Servo.StopRequest request, StreamObserver<com.viam.component.servo.v1.Servo.StopResponse> responseObserver) { | ||
Servo servo = getResource(Servo.named(request.getName())); | ||
servo.stop(); | ||
responseObserver.onNext(com.viam.component.servo.v1.Servo.StopResponse.newBuilder().build()); | ||
responseObserver.onCompleted(); | ||
} | ||
|
||
@Override | ||
public void getPosition(com.viam.component.servo.v1.Servo.GetPositionRequest request, StreamObserver<com.viam.component.servo.v1.Servo.GetPositionResponse> responseObserver) { | ||
Servo servo = getResource(Servo.named(request.getName())); | ||
int position = servo.getPosition(request.getExtra()); | ||
responseObserver.onNext(com.viam.component.servo.v1.Servo.GetPositionResponse.newBuilder().setPositionDeg(position).build()); | ||
responseObserver.onCompleted(); | ||
} | ||
|
||
@Override | ||
public void isMoving(com.viam.component.servo.v1.Servo.IsMovingRequest request, StreamObserver<com.viam.component.servo.v1.Servo.IsMovingResponse> responseObserver) { | ||
Servo servo = getResource(Servo.named(request.getName())); | ||
boolean isMoving = servo.isMoving(); | ||
responseObserver.onNext(com.viam.component.servo.v1.Servo.IsMovingResponse.newBuilder().setIsMoving(isMoving).build()); | ||
responseObserver.onCompleted(); | ||
} | ||
|
||
@Override | ||
public void getGeometries(com.viam.common.v1.Common.GetGeometriesRequest request, | ||
StreamObserver<com.viam.common.v1.Common.GetGeometriesResponse> responseObserver){ | ||
Servo servo = getResource(Servo.named(request.getName())); | ||
List<Common.Geometry> geometries = servo.getGeometries(Optional.ofNullable(request.getExtra())); | ||
responseObserver.onNext(Common.GetGeometriesResponse.newBuilder().addAllGeometries(geometries).build()); | ||
responseObserver.onCompleted(); | ||
} | ||
@Override | ||
public void doCommand(Common.DoCommandRequest request, | ||
StreamObserver<Common.DoCommandResponse> responseObserver) { | ||
|
||
Servo servo = getResource(Servo.named(request.getName())); | ||
Struct result = servo.doCommand(request.getCommand().getFieldsMap()); | ||
responseObserver.onNext(Common.DoCommandResponse.newBuilder().setResult(result).build()); | ||
responseObserver.onCompleted(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
core/sdk/src/test/kotlin/com/viam/sdk/core/component/servo/ServoRPCClientTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.viam.sdk.core.component.servo | ||
|
||
import com.google.protobuf.Struct | ||
import com.google.protobuf.Value | ||
import com.viam.common.v1.Common.Geometry | ||
import com.viam.sdk.core.resource.ResourceManager | ||
import com.viam.sdk.core.rpc.BasicManagedChannel | ||
import io.grpc.inprocess.InProcessChannelBuilder | ||
import io.grpc.inprocess.InProcessServerBuilder | ||
import io.grpc.testing.GrpcCleanupRule | ||
import org.junit.Rule | ||
import org.junit.jupiter.api.Assertions.assertEquals | ||
import org.junit.jupiter.api.Assertions.assertFalse | ||
import org.junit.jupiter.api.BeforeEach | ||
import org.junit.jupiter.api.Test | ||
import org.mockito.Mockito.* | ||
import java.util.* | ||
|
||
class ServoRPCClientTest { | ||
private lateinit var servo: Servo | ||
private lateinit var client: ServoRPCClient | ||
|
||
@JvmField | ||
@Rule | ||
val grpcCleanupRule: GrpcCleanupRule = GrpcCleanupRule() | ||
|
||
@BeforeEach | ||
fun setup() { | ||
servo = mock( | ||
Servo::class.java, withSettings().useConstructor("mock-servo").defaultAnswer( | ||
CALLS_REAL_METHODS | ||
) | ||
) | ||
val resourceManager = ResourceManager(listOf(servo)) | ||
val service = ServoRPCService(resourceManager) | ||
val serviceName = InProcessServerBuilder.generateName() | ||
grpcCleanupRule.register( | ||
InProcessServerBuilder.forName(serviceName).directExecutor().addService(service).build().start() | ||
) | ||
val channel = grpcCleanupRule.register(InProcessChannelBuilder.forName(serviceName).directExecutor().build()) | ||
client = ServoRPCClient("mock-servo", BasicManagedChannel(channel)) | ||
} | ||
|
||
@Test | ||
fun move(){ | ||
val extra = | ||
Struct.newBuilder().putAllFields(mapOf("foo" to Value.newBuilder().setStringValue("bar").build())).build() | ||
client.move(20, extra) | ||
verify(servo).move(20, extra) | ||
|
||
} | ||
|
||
@Test | ||
fun stop() { | ||
client.stop() | ||
verify(servo).stop(Struct.getDefaultInstance()) | ||
} | ||
|
||
@Test | ||
fun isMoving() { | ||
`when`(servo.isMoving()).thenReturn(false) | ||
val isMoving = client.isMoving() | ||
verify(servo).isMoving() | ||
assertFalse(isMoving) | ||
} | ||
|
||
@Test | ||
fun getGeometries() { | ||
doReturn(listOf<Geometry>()).`when`(servo).getGeometries(any()) | ||
client.getGeometries(Optional.empty()) | ||
verify(servo).getGeometries(any()) | ||
} | ||
|
||
@Test | ||
fun getPosition() { | ||
`when`(servo.getPosition(any(Struct::class.java) ?: Struct.getDefaultInstance())).thenReturn(80) | ||
val pos = client.getPosition() | ||
verify(servo).getPosition(Struct.getDefaultInstance()) | ||
assertEquals(80, pos) | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing the test for |
||
@Test | ||
fun doCommand() { | ||
val command = mapOf("foo" to Value.newBuilder().setStringValue("bar").build()) | ||
doReturn(Struct.newBuilder().putAllFields(command).build()).`when`(servo).doCommand(anyMap()) | ||
val response = client.doCommand(command) | ||
verify(servo).doCommand(command) | ||
assertEquals(command, response.fieldsMap) | ||
} | ||
|
||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is missing
doCommand