Skip to content

Commit

Permalink
RSDK-2812 - Use API over Subtype (#2265)
Browse files Browse the repository at this point in the history
  • Loading branch information
edaniels authored Apr 23, 2023
1 parent ac094ac commit 538506e
Show file tree
Hide file tree
Showing 354 changed files with 4,770 additions and 4,469 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Example with a dummy configuration: `go run web/cmd/server/main.go -config etc/c
### Examples
* [SimpleServer](https://pkg.go.dev/go.viam.com/rdk/examples/simpleserver) - example for creating a simple custom server.
* [MySensor](https://pkg.go.dev/go.viam.com/rdk/examples/mysensor) - example for creating a custom sensor.
* [MyComponent](https://pkg.go.dev/go.viam.com/rdk/examples/mycomponent) - example for creating a custom resource subtype.
* [MyComponent](https://pkg.go.dev/go.viam.com/rdk/examples/mycomponent) - example for creating a custom resource API.

### SDKs

Expand Down
2 changes: 1 addition & 1 deletion cli/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ func (c *AppClient) StartRobotPartShell(
// Returns the first shell service found in the robot resources
var found *resource.Name
for _, name := range robotClient.ResourceNames() {
if name.Subtype == shell.Subtype {
if name.API == shell.API {
nameCopy := name
found = &nameCopy
break
Expand Down
24 changes: 9 additions & 15 deletions components/arm/arm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
)

func init() {
resource.RegisterSubtype(Subtype, resource.SubtypeRegistration[Arm]{
resource.RegisterAPI(API, resource.APIRegistration[Arm]{
Status: resource.StatusFunc(CreateStatus),
RPCServiceServerConstructor: NewRPCServiceServer,
RPCServiceHandler: pb.RegisterArmServiceHandlerFromEndpoint,
Expand All @@ -29,19 +29,17 @@ func init() {
})

data.RegisterCollector(data.MethodMetadata{
Subtype: Subtype,
API: API,
MethodName: endPosition.String(),
}, newEndPositionCollector)
data.RegisterCollector(data.MethodMetadata{
Subtype: Subtype,
API: API,
MethodName: jointPositions.String(),
}, newJointPositionsCollector)
}

// SubtypeName is a constant that identifies the component resource subtype string "arm".
const (
SubtypeName = resource.SubtypeName("arm")
)
// SubtypeName is a constant that identifies the component resource API string "arm".
const SubtypeName = "arm"

// MTPoob is a string that all MoveToPosition errors should contain if the method is called
// and there are joints which are out of bounds.
Expand All @@ -54,16 +52,12 @@ var (
}
)

// Subtype is a constant that identifies the component resource subtype.
var Subtype = resource.NewSubtype(
resource.ResourceNamespaceRDK,
resource.ResourceTypeComponent,
SubtypeName,
)
// API is a variable that identifies the component resource API.
var API = resource.APINamespaceRDK.WithComponentType(SubtypeName)

// Named is a helper for getting the named Arm's typed resource name.
func Named(name string) resource.Name {
return resource.NameFromSubtype(Subtype, name)
return resource.NewName(API, name)
}

// An Arm represents a physical robotic arm that exists in three-dimensional space.
Expand Down Expand Up @@ -104,7 +98,7 @@ func FromRobot(r robot.Robot, name string) (Arm, error) {

// NamesFromRobot is a helper for getting all arm names from the given Robot.
func NamesFromRobot(r robot.Robot) []string {
return robot.NamesBySubtype(r, Subtype)
return robot.NamesByAPI(r, API)
}

// CreateStatus creates a status from the arm.
Expand Down
18 changes: 9 additions & 9 deletions components/arm/arm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestCreateStatus(t *testing.T) {
return true, nil
}
injectArm.ModelFrameFunc = func() referenceframe.Model {
model, _ := ur.Model("ur5e")
model, _ := ur.MakeModelFrame("ur5e")
return model
}

Expand All @@ -95,10 +95,10 @@ func TestCreateStatus(t *testing.T) {
pose2 := spatialmath.NewPoseFromProtobuf(status.EndPosition)
test.That(t, spatialmath.PoseAlmostEqualEps(pose1, pose2, 0.01), test.ShouldBeTrue)

resourceSubtype, ok, err := resource.LookupSubtypeRegistration[arm.Arm](arm.Subtype)
resourceAPI, ok, err := resource.LookupAPIRegistration[arm.Arm](arm.API)
test.That(t, err, test.ShouldBeNil)
test.That(t, ok, test.ShouldBeTrue)
status2, err := resourceSubtype.Status(context.Background(), injectArm)
status2, err := resourceAPI.Status(context.Background(), injectArm)
test.That(t, err, test.ShouldBeNil)

statusMap, err := protoutils.InterfaceToMap(status2)
Expand Down Expand Up @@ -158,8 +158,8 @@ func TestCreateStatus(t *testing.T) {
func TestOOBArm(t *testing.T) {
logger := golog.NewTestLogger(t)
cfg := resource.Config{
Name: arm.Subtype.String(),
Model: resource.NewDefaultModel("ur5e"),
Name: arm.API.String(),
Model: resource.DefaultModelFamily.WithModel("ur5e"),
ConvertedAttributes: &fake.Config{
ArmModel: "ur5e",
},
Expand Down Expand Up @@ -258,8 +258,8 @@ func TestXArm6Locations(t *testing.T) {
// check the exact values/locations of arm geometries at a couple different poses
logger := golog.NewTestLogger(t)
cfg := resource.Config{
Name: arm.Subtype.String(),
Model: resource.NewDefaultModel("fake"),
Name: arm.API.String(),
Model: resource.DefaultModelFamily.WithModel("fake"),
ConvertedAttributes: &fake.Config{
ArmModel: "xArm6",
},
Expand Down Expand Up @@ -381,8 +381,8 @@ func TestUR5ELocations(t *testing.T) {
// check the exact values/locations of arm geometries at a couple different poses
logger := golog.NewTestLogger(t)
cfg := resource.Config{
Name: arm.Subtype.String(),
Model: resource.NewDefaultModel("fake"),
Name: arm.API.String(),
Model: resource.DefaultModelFamily.WithModel("fake"),
ConvertedAttributes: &fake.Config{
ArmModel: "ur5e",
},
Expand Down
14 changes: 10 additions & 4 deletions components/arm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,24 @@ type client struct {
}

// NewClientFromConn constructs a new Client from connection passed in.
func NewClientFromConn(ctx context.Context, conn rpc.ClientConn, name resource.Name, logger golog.Logger) (Arm, error) {
func NewClientFromConn(
ctx context.Context,
conn rpc.ClientConn,
remoteName string,
name resource.Name,
logger golog.Logger,
) (Arm, error) {
pbClient := pb.NewArmServiceClient(conn)
// TODO(DATA-853): requires that this support models being changed on the fly, not just at creation
// TODO(RSDK-882): will update this so that this is not necessary
r := robotpb.NewRobotServiceClient(conn)
model, modelErr := getModel(ctx, r, name.ShortNameForClient())
model, modelErr := getModel(ctx, r, name.ShortName())
if modelErr != nil {
logger.Errorw("error getting model for arm; will not allow certain methods")
}
c := &client{
Named: name.AsNamed(),
name: name.ShortNameForClient(),
Named: name.PrependRemote(remoteName).AsNamed(),
name: name.ShortName(),
client: pbClient,
logger: logger,
}
Expand Down
12 changes: 6 additions & 6 deletions components/arm/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,17 @@ func TestClient(t *testing.T) {
return nil
}

armSvc, err := resource.NewSubtypeCollection(
arm.Subtype, map[resource.Name]arm.Arm{
armSvc, err := resource.NewAPIResourceCollection(
arm.API, map[resource.Name]arm.Arm{
arm.Named(testArmName): injectArm,
arm.Named(testArmName2): injectArm2,
})
test.That(t, err, test.ShouldBeNil)
resourceSubtype, ok, err := resource.LookupSubtypeRegistration[arm.Arm](arm.Subtype)
resourceAPI, ok, err := resource.LookupAPIRegistration[arm.Arm](arm.API)
test.That(t, err, test.ShouldBeNil)
test.That(t, ok, test.ShouldBeTrue)

test.That(t, resourceSubtype.RegisterRPCService(context.Background(), rpcServer, armSvc), test.ShouldBeNil)
test.That(t, resourceAPI.RegisterRPCService(context.Background(), rpcServer, armSvc), test.ShouldBeNil)

injectRobot := &inject.Robot{}
injectRobot.FrameSystemConfigFunc = func(
Expand Down Expand Up @@ -128,7 +128,7 @@ func TestClient(t *testing.T) {
t.Run("arm client 1", func(t *testing.T) {
conn, err := viamgrpc.Dial(context.Background(), listener1.Addr().String(), logger)
test.That(t, err, test.ShouldBeNil)
arm1Client, err := arm.NewClientFromConn(context.Background(), conn, arm.Named(testArmName), logger)
arm1Client, err := arm.NewClientFromConn(context.Background(), conn, "", arm.Named(testArmName), logger)
test.That(t, err, test.ShouldBeNil)

// DoCommand
Expand Down Expand Up @@ -170,7 +170,7 @@ func TestClient(t *testing.T) {
t.Run("arm client 2", func(t *testing.T) {
conn, err := viamgrpc.Dial(context.Background(), listener1.Addr().String(), logger)
test.That(t, err, test.ShouldBeNil)
client2, err := resourceSubtype.RPCClient(context.Background(), conn, arm.Named(testArmName2), logger)
client2, err := resourceAPI.RPCClient(context.Background(), conn, "", arm.Named(testArmName2), logger)
test.That(t, err, test.ShouldBeNil)

pos, err := client2.EndPosition(context.Background(), nil)
Expand Down
2 changes: 1 addition & 1 deletion components/arm/collectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func newJointPositionsCollector(resource interface{}, params data.CollectorParam
func assertArm(resource interface{}) (Arm, error) {
arm, ok := resource.(Arm)
if !ok {
return nil, data.InvalidInterfaceErr(SubtypeName)
return nil, data.InvalidInterfaceErr(API)
}
return arm, nil
}
12 changes: 6 additions & 6 deletions components/arm/eva/eva.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ import (
"go.viam.com/rdk/spatialmath"
)

// ModelName is the name of the eva model of an arm component.
var ModelName = resource.NewDefaultModel("eva")
// Model is the name of the eva model of an arm component.
var Model = resource.DefaultModelFamily.WithModel("eva")

// Config is used for converting config attributes.
type Config struct {
Expand All @@ -44,7 +44,7 @@ type Config struct {
var evamodeljson []byte

func init() {
resource.RegisterComponent(arm.Subtype, ModelName, resource.Registration[arm.Arm, *Config]{
resource.RegisterComponent(arm.API, Model, resource.Registration[arm.Arm, *Config]{
Constructor: func(ctx context.Context, _ resource.Dependencies, conf resource.Config, logger golog.Logger) (arm.Arm, error) {
return NewEva(ctx, conf, logger)
},
Expand Down Expand Up @@ -96,7 +96,7 @@ type eva struct {

// NewEva TODO.
func NewEva(ctx context.Context, conf resource.Config, logger golog.Logger) (arm.Arm, error) {
model, err := Model(conf.Name)
model, err := MakeModelFrame(conf.Name)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -398,7 +398,7 @@ func (e *eva) Close(ctx context.Context) error {
return e.stop(ctx)
}

// Model returns the kinematics model of the eva arm, also has all Frame information.
func Model(name string) (referenceframe.Model, error) {
// MakeModelFrame returns the kinematics model of the eva arm, also has all Frame information.
func MakeModelFrame(name string) (referenceframe.Model, error) {
return referenceframe.UnmarshalModelJSON(evamodeljson, name)
}
22 changes: 11 additions & 11 deletions components/arm/fake/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import (
// errAttrCfgPopulation is the returned error if the Config's fields are fully populated.
var errAttrCfgPopulation = errors.New("can only populate either ArmModel or ModelPath - not both")

// ModelName is the string used to refer to the fake arm model.
var ModelName = resource.NewDefaultModel("fake")
// Model is the name used to refer to the fake arm model.
var Model = resource.DefaultModelFamily.WithModel("fake")

// Config is used for converting config attributes.
type Config struct {
Expand All @@ -33,15 +33,15 @@ type Config struct {
}

func modelFromName(model, name string) (referenceframe.Model, error) {
switch resource.ModelName(model) {
switch model {
case xarm.ModelName6DOF, xarm.ModelName7DOF, xarm.ModelNameLite:
return xarm.Model(name, model)
case ur.ModelName.Name:
return ur.Model(name)
case yahboom.ModelName.Name:
return yahboom.Model(name)
case eva.ModelName.Name:
return eva.Model(name)
return xarm.MakeModelFrame(name, model)
case ur.Model.Name:
return ur.MakeModelFrame(name)
case yahboom.Model.Name:
return yahboom.MakeModelFrame(name)
case eva.Model.Name:
return eva.MakeModelFrame(name)
default:
return nil, errors.Errorf("fake arm cannot be created, unsupported arm-model: %s", model)
}
Expand All @@ -62,7 +62,7 @@ func (conf *Config) Validate(path string) ([]string, error) {
}

func init() {
resource.RegisterComponent(arm.Subtype, ModelName, resource.Registration[arm.Arm, *Config]{
resource.RegisterComponent(arm.API, Model, resource.Registration[arm.Arm, *Config]{
Constructor: NewArm,
})
}
Expand Down
24 changes: 12 additions & 12 deletions components/arm/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ import (
"go.viam.com/rdk/spatialmath"
)

// subtypeServer implements the ArmService from arm.proto.
type subtypeServer struct {
// serviceServer implements the ArmService from arm.proto.
type serviceServer struct {
pb.UnimplementedArmServiceServer
coll resource.SubtypeCollection[Arm]
coll resource.APIResourceCollection[Arm]
}

// NewRPCServiceServer constructs an arm gRPC service server.
// It is intentionally untyped to prevent use outside of tests.
func NewRPCServiceServer(coll resource.SubtypeCollection[Arm]) interface{} {
return &subtypeServer{coll: coll}
func NewRPCServiceServer(coll resource.APIResourceCollection[Arm]) interface{} {
return &serviceServer{coll: coll}
}

// GetEndPosition returns the position of the arm specified.
func (s *subtypeServer) GetEndPosition(
func (s *serviceServer) GetEndPosition(
ctx context.Context,
req *pb.GetEndPositionRequest,
) (*pb.GetEndPositionResponse, error) {
Expand All @@ -42,7 +42,7 @@ func (s *subtypeServer) GetEndPosition(
}

// GetJointPositions gets the current joint position of an arm of the underlying robot.
func (s *subtypeServer) GetJointPositions(
func (s *serviceServer) GetJointPositions(
ctx context.Context,
req *pb.GetJointPositionsRequest,
) (*pb.GetJointPositionsResponse, error) {
Expand All @@ -59,7 +59,7 @@ func (s *subtypeServer) GetJointPositions(
}

// MoveToPosition returns the position of the arm specified.
func (s *subtypeServer) MoveToPosition(ctx context.Context, req *pb.MoveToPositionRequest) (*pb.MoveToPositionResponse, error) {
func (s *serviceServer) MoveToPosition(ctx context.Context, req *pb.MoveToPositionRequest) (*pb.MoveToPositionResponse, error) {
operation.CancelOtherWithLabel(ctx, req.Name)
arm, err := s.coll.Resource(req.Name)
if err != nil {
Expand All @@ -73,7 +73,7 @@ func (s *subtypeServer) MoveToPosition(ctx context.Context, req *pb.MoveToPositi
}

// MoveToJointPositions moves an arm of the underlying robot to the requested joint positions.
func (s *subtypeServer) MoveToJointPositions(
func (s *serviceServer) MoveToJointPositions(
ctx context.Context,
req *pb.MoveToJointPositionsRequest,
) (*pb.MoveToJointPositionsResponse, error) {
Expand All @@ -86,7 +86,7 @@ func (s *subtypeServer) MoveToJointPositions(
}

// Stop stops the arm specified.
func (s *subtypeServer) Stop(ctx context.Context, req *pb.StopRequest) (*pb.StopResponse, error) {
func (s *serviceServer) Stop(ctx context.Context, req *pb.StopRequest) (*pb.StopResponse, error) {
operation.CancelOtherWithLabel(ctx, req.Name)
arm, err := s.coll.Resource(req.Name)
if err != nil {
Expand All @@ -96,7 +96,7 @@ func (s *subtypeServer) Stop(ctx context.Context, req *pb.StopRequest) (*pb.Stop
}

// IsMoving queries of a component is in motion.
func (s *subtypeServer) IsMoving(ctx context.Context, req *pb.IsMovingRequest) (*pb.IsMovingResponse, error) {
func (s *serviceServer) IsMoving(ctx context.Context, req *pb.IsMovingRequest) (*pb.IsMovingResponse, error) {
arm, err := s.coll.Resource(req.GetName())
if err != nil {
return nil, err
Expand All @@ -109,7 +109,7 @@ func (s *subtypeServer) IsMoving(ctx context.Context, req *pb.IsMovingRequest) (
}

// DoCommand receives arbitrary commands.
func (s *subtypeServer) DoCommand(ctx context.Context,
func (s *serviceServer) DoCommand(ctx context.Context,
req *commonpb.DoCommandRequest,
) (*commonpb.DoCommandResponse, error) {
arm, err := s.coll.Resource(req.GetName())
Expand Down
2 changes: 1 addition & 1 deletion components/arm/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func newServer() (pb.ArmServiceServer, *inject.Arm, *inject.Arm, error) {
arm.Named(testArmName): injectArm,
arm.Named(failArmName): injectArm2,
}
armSvc, err := resource.NewSubtypeCollection(arm.Subtype, arms)
armSvc, err := resource.NewAPIResourceCollection(arm.API, arms)
if err != nil {
return nil, nil, nil, err
}
Expand Down
Loading

0 comments on commit 538506e

Please sign in to comment.