Skip to content
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 Base wrappers #67

Merged
merged 3 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.viam.common.v1.Common;
import com.viam.common.v1.Common.ResourceName;
import com.viam.component.base.v1.BaseServiceGrpc;
import com.viam.component.arm.v1.ArmServiceGrpc;
import com.viam.component.board.v1.BoardServiceGrpc;
import com.viam.component.camera.v1.CameraServiceGrpc;
Expand All @@ -13,6 +14,7 @@
import com.viam.component.movementsensor.v1.MovementSensorServiceGrpc;
import com.viam.component.powersensor.v1.PowerSensorServiceGrpc;
import com.viam.component.sensor.v1.SensorServiceGrpc;
import com.viam.sdk.core.component.base.*;
import com.viam.sdk.core.component.arm.*;
import com.viam.component.servo.v1.ServoServiceGrpc;
import com.viam.sdk.core.component.board.Board;
Expand Down Expand Up @@ -69,6 +71,18 @@ public class ResourceManager implements Closeable {
static {
// register well-known subtypes
// COMPONENTS
Registry.registerSubtype(new ResourceRegistration<>(
Arm.SUBTYPE,
ArmServiceGrpc.SERVICE_NAME,
ArmRPCService::new,
ArmRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Base.SUBTYPE,
BaseServiceGrpc.SERVICE_NAME,
BaseRPCService::new,
BaseRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Board.SUBTYPE,
BoardServiceGrpc.SERVICE_NAME,
Expand All @@ -81,6 +95,18 @@ public class ResourceManager implements Closeable {
CameraRPCService::new,
CameraRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Encoder.SUBTYPE,
EncoderServiceGrpc.SERVICE_NAME,
EncoderRPCService::new,
EncoderRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Gantry.SUBTYPE,
GantryServiceGrpc.SERVICE_NAME,
GantryRPCService::new,
GantryRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Generic.SUBTYPE,
GenericServiceGrpc.SERVICE_NAME,
Expand All @@ -105,29 +131,17 @@ public class ResourceManager implements Closeable {
MovementSensorRPCService::new,
MovementSensorRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Sensor.SUBTYPE,
SensorServiceGrpc.SERVICE_NAME,
SensorRPCService::new,
SensorRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Encoder.SUBTYPE,
EncoderServiceGrpc.SERVICE_NAME,
EncoderRPCService::new,
EncoderRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
PowerSensor.SUBTYPE,
PowerSensorServiceGrpc.SERVICE_NAME,
PowerSensorRPCService::new,
PowerSensorRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Arm.SUBTYPE,
ArmServiceGrpc.SERVICE_NAME,
ArmRPCService::new,
ArmRPCClient::new
Sensor.SUBTYPE,
SensorServiceGrpc.SERVICE_NAME,
SensorRPCService::new,
SensorRPCClient::new
));
Registry.registerSubtype(new ResourceRegistration<>(
Servo.SUBTYPE,
Expand All @@ -136,13 +150,6 @@ public class ResourceManager implements Closeable {
ServoRPCClient::new
));

Registry.registerSubtype(new ResourceRegistration<>(
Gantry.SUBTYPE,
GantryServiceGrpc.SERVICE_NAME,
GantryRPCService::new,
GantryRPCClient::new
));

// SERVICES
Registry.registerSubtype(new ResourceRegistration<>(
DataManager.SUBTYPE,
Expand Down
163 changes: 163 additions & 0 deletions core/sdk/src/main/kotlin/com/viam/sdk/core/component/base/Base.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package com.viam.sdk.core.component.base

import com.google.protobuf.Struct
import com.viam.common.v1.Common.ResourceName
import com.viam.common.v1.Common.Vector3
import com.viam.component.base.v1.Base.GetPropertiesResponse
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

typealias Properties = GetPropertiesResponse

/**
* Base represents a physical base of a robot.
*/
abstract class Base(name: String) : Component(SUBTYPE, named(name)) {


companion object {
@JvmField
val SUBTYPE = Subtype(Subtype.NAMESPACE_RDK, Subtype.RESOURCE_TYPE_COMPONENT, "base")

/**
* Get the ResourceName of the component
* @param name the name of the component
* @return the component's ResourceName
*/
@JvmStatic
fun named(name: String): ResourceName {
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
*/
@JvmStatic
fun fromRobot(robot: RobotClient, name: String): Base {
return robot.getResource(Base::class.java, named(name))
}
}
/**
* Move the base in a straight line the given ``distance``, expressed in millimeters,
* at the given ``velocity``, expressed in millimeters per second.
* When ``distance`` or ``velocity`` is 0, the base will stop.
* This method blocks until completed or cancelled.
* @param distance The distance (in millimeters) to move. Negative implies backwards.
* @param velocity The velocity (in millimeters per second) to move.
* Negative implies backwards.
*/
abstract fun moveStraight(distance: Long, velocity: Double, extra: Struct)


/**
* Move the base in a straight line the given ``distance``, expressed in millimeters,
* at the given ``velocity``, expressed in millimeters per second.
* When ``distance`` or ``velocity`` is 0, the base will stop.
* This method blocks until completed or cancelled.
* @param distance The distance (in millimeters) to move. Negative implies backwards.
* @param velocity The velocity (in millimeters per second) to move.
* Negative implies backwards.
*/
fun moveStraight(distance: Long, velocity: Double) {
moveStraight(distance, velocity, Struct.getDefaultInstance())
}


/**
* Spin the base in place ``angle`` degrees, at the given angular ``velocity``,
* expressed in degrees per second.
* When ``velocity`` is 0, the base will stop.
* This method blocks until completed or cancelled.
* @param angle The angle (in degrees) to spin.
* @param velocity The angular velocity (in degrees per second) to spin.
* Given a positive angle and a positive velocity, the base will turn to the left.
*/
abstract fun spin(angle: Double, velocity: Double, extra: Struct)

/**
* Spin the base in place ``angle`` degrees, at the given angular ``velocity``,
* expressed in degrees per second.
* When ``velocity`` is 0, the base will stop.
* This method blocks until completed or cancelled.
* @param angle The angle (in degrees) to spin.
* @param velocity The angular velocity (in degrees per second) to spin.
* Given a positive angle and a positive velocity, the base will turn to the left.
*/
fun spin(angle: Double, velocity: Double) {
spin(angle, velocity, Struct.getDefaultInstance())
}

/**
* Set the linear and angular velocity of the Base
* When ``linear`` is 0, the the base will spin.
* When ``angular`` is 0, the the base will move in a straight line.
* When both ``linear`` and ``angular`` are 0, the base will stop.
* When ``linear`` and ``angular`` are both nonzero, the base will move in an arc, with a tighter radius if angular
* power is greater than linear power.
* @param linear The linear component. Only the Y component is used for wheeled base. Positive implies forwards.
* @param angular The angular component. Only the Z component is used
* for wheeled base. Positive turns left; negative turns right.
*/
abstract fun setPower(linear: Vector3, angular: Vector3, extra: Struct)

/**
* Set the linear and angular velocity of the Base
* When ``linear`` is 0, the the base will spin.
* When ``angular`` is 0, the the base will move in a straight line.
* When both ``linear`` and ``angular`` are 0, the base will stop.
* When ``linear`` and ``angular`` are both nonzero, the base will move in an arc, with a tighter radius if angular
* power is greater than linear power.
* @param linear The linear component. Only the Y component is used for wheeled base. Positive implies forwards.
* @param angular The angular component. Only the Z component is used
* for wheeled base. Positive turns left; negative turns right.
*/
fun setPower(linear: Vector3, angular: Vector3) {
setPower(linear, angular, Struct.getDefaultInstance())
}

/**
* Set the linear and angular velocities of the base.
* @param linear The velocity in mm/sec
* @param angular The velocity in mm/sec
*/
abstract fun setVelocity(linear: Vector3, angular: Vector3, extra: Struct)

/**
* Set the linear and angular velocities of the base.
* @param linear The velocity in mm/sec
* @param angular The velocity in mm/sec
*/
fun setVelocity(linear: Vector3, angular: Vector3) {
setVelocity(linear, angular, Struct.getDefaultInstance())
}

/**
* Stops the base.
*/
abstract fun stop(extra: Struct)

/**
* Stops the base.
*/
fun stop(){
stop(Struct.getDefaultInstance())
}

/**
* Get if the base is currently moving.
* @return Whether the base is moving.
*/
abstract fun isMoving(): Boolean

/**
* Get the base width and turning radius
* @return the properties of the base
*/
abstract fun getProperties(): Properties

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.viam.sdk.core.component.base

import com.google.protobuf.Struct
import com.google.protobuf.Value
import com.viam.common.v1.Common
import com.viam.common.v1.Common.GetGeometriesRequest
import com.viam.component.base.v1.BaseServiceGrpc
import com.viam.component.base.v1.BaseServiceGrpc.BaseServiceBlockingStub
import com.viam.component.base.v1.Base.*
import com.viam.sdk.core.rpc.Channel
import java.util.*
import kotlin.jvm.optionals.getOrDefault

class BaseRPCClient(name: String, channel: Channel) : Base(name) {
private val client: BaseServiceBlockingStub

init {
val client = BaseServiceGrpc.newBlockingStub(channel)
if (channel.callCredentials.isPresent) {
this.client = client.withCallCredentials(channel.callCredentials.get())
} else {
this.client = client
}
}

override fun moveStraight(distance: Long, velocity: Double, extra: Struct) {
val request = MoveStraightRequest.newBuilder().setName(this.name.name).setExtra(extra).setDistanceMm(distance).setMmPerSec(velocity).build()
client.moveStraight(request)
}

override fun spin(angle: Double, velocity: Double, extra: Struct) {
val request = SpinRequest.newBuilder().setName(this.name.name).setAngleDeg(angle).setDegsPerSec(velocity).setExtra(extra).build()
client.spin(request)
}

override fun setPower(linear: Common.Vector3, angular: Common.Vector3, extra: Struct) {
val request = SetPowerRequest.newBuilder().setName(this.name.name).setLinear(linear).setAngular(angular).setExtra(extra).build()
client.setPower(request)
}

override fun setVelocity(linear: Common.Vector3, angular: Common.Vector3, extra: Struct) {
val request = SetVelocityRequest.newBuilder().setName(this.name.name).setLinear(linear).setAngular(angular).setExtra(extra).build()
client.setVelocity(request)
}

override fun stop(extra: Struct) {
val request = StopRequest.newBuilder().setName(this.name.name).setExtra(extra).build()
this.client.stop(request)
}
override fun isMoving(): Boolean {
val request = IsMovingRequest.newBuilder().setName(this.name.name).build()
val response = this.client.isMoving(request)
return response.isMoving
}

override fun getProperties(): Properties {
val request = GetPropertiesRequest.newBuilder().setName(this.name.name).build()
return client.getProperties(request)
}

override fun doCommand(command: Map<String, Value>?): Struct {
val request = Common.DoCommandRequest.newBuilder().setName(this.name.name)
.setCommand(Struct.newBuilder().putAllFields(command).build()).build()
val response = this.client.doCommand(request)
return response.result
}

override fun getGeometries(extra: Optional<Struct>): List<Common.Geometry> {
val request = GetGeometriesRequest.newBuilder().setName(this.name.name)
.setExtra(extra.getOrDefault(Struct.getDefaultInstance())).build()
val response = this.client.getGeometries(request)
return response.geometriesList
}
}
Loading