Skip to content

Commit 11dab7c

Browse files
gabegottlobviambot
andauthored
Added gripper GetKinematics (#928)
Co-authored-by: viambot <[email protected]>
1 parent 8d6b63a commit 11dab7c

File tree

22 files changed

+784
-561
lines changed

22 files changed

+784
-561
lines changed

examples/server/v1/components.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ class ExampleGripper(Gripper):
513513
def __init__(self, name: str):
514514
self.opened = False
515515
self.is_stopped = True
516+
self.kinematics = (KinematicsFileFormat.KINEMATICS_FILE_FORMAT_SVA, b"\x00\x01\x02")
516517
super().__init__(name)
517518

518519
async def open(self, extra: Optional[Dict[str, Any]] = None, **kwargs):
@@ -533,6 +534,9 @@ async def is_moving(self):
533534
async def get_geometries(self, extra: Optional[Dict[str, Any]] = None, **kwargs) -> List[Geometry]:
534535
return GEOMETRIES
535536

537+
async def get_kinematics(self, extra: Optional[Dict[str, Any]] = None, **kwargs) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
538+
return self.kinematics
539+
536540

537541
class ExampleMotor(Motor):
538542
def __init__(self, name: str):

src/viam/components/arm/arm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ async def is_moving(self) -> bool:
194194

195195
@abc.abstractmethod
196196
async def get_kinematics(
197-
self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None
197+
self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
198198
) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
199199
"""
200200
Get the kinematics information associated with the arm.

src/viam/components/gripper/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from viam.proto.common import KinematicsFileFormat
12
from viam.resource.registry import Registry, ResourceRegistration
23

34
from .client import GripperClient
@@ -6,6 +7,7 @@
67

78
__all__ = [
89
"Gripper",
10+
"KinematicsFileFormat",
911
]
1012

1113
Registry.register_api(ResourceRegistration(Gripper, GripperRPCService, lambda name, channel: GripperClient(name, channel)))

src/viam/components/gripper/client.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from typing import Any, Dict, List, Mapping, Optional
1+
from typing import Any, Dict, List, Mapping, Optional, Tuple
22

33
from grpclib.client import Channel
44

5-
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry
5+
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetKinematicsRequest, GetKinematicsResponse
66
from viam.proto.component.gripper import (
77
GrabRequest,
88
GrabResponse,
@@ -17,6 +17,7 @@
1717

1818
from .gripper import Gripper
1919

20+
from . import KinematicsFileFormat
2021

2122
class GripperClient(Gripper, ReconfigurableResourceRPCClientBase):
2223
"""
@@ -83,3 +84,15 @@ async def do_command(
8384
async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Geometry]:
8485
md = kwargs.get("metadata", self.Metadata())
8586
return await get_geometries(self.client, self.name, extra, timeout, md)
87+
88+
async def get_kinematics(
89+
self,
90+
*,
91+
extra: Optional[Dict[str, Any]] = None,
92+
timeout: Optional[float] = None,
93+
**kwargs,
94+
) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
95+
md = kwargs.get("metadata", self.Metadata()).proto
96+
request = GetKinematicsRequest(name=self.name, extra=dict_to_struct(extra))
97+
response: GetKinematicsResponse = await self.client.GetKinematics(request, timeout=timeout, metadata=md)
98+
return (response.format, response.kinematics_data)

src/viam/components/gripper/gripper.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import abc
2-
from typing import Any, Dict, Final, Optional
2+
from typing import Any, Dict, Final, Optional, Tuple
33

44
from viam.components.component_base import ComponentBase
55
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
66

7+
from . import KinematicsFileFormat
8+
79

810
class Gripper(ComponentBase):
911
"""
@@ -112,3 +114,37 @@ async def is_moving(self) -> bool:
112114
For more information, see `Gripper component <https://docs.viam.com/dev/reference/apis/components/gripper/#is_moving>`_.
113115
"""
114116
...
117+
118+
@abc.abstractmethod
119+
async def get_kinematics(
120+
self,
121+
*,
122+
extra: Optional[Dict[str, Any]] = None,
123+
timeout: Optional[float] = None,
124+
**kwargs,
125+
) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
126+
"""
127+
Get the kinematics information associated with the gripper.
128+
129+
::
130+
131+
my_gripper = Gripper.from_robot(robot=machine, name="my_gripper")
132+
133+
# Get the kinematics information associated with the gripper.
134+
kinematics = await my_gripper.get_kinematics()
135+
136+
# Get the format of the kinematics file.
137+
k_file = kinematics[0]
138+
139+
# Get the byte contents of the file.
140+
k_bytes = kinematics[1]
141+
142+
Returns:
143+
Tuple[KinematicsFileFormat.ValueType, bytes]: A tuple containing two values; the first [0] value represents the format of the
144+
file, either in URDF format (``KinematicsFileFormat.KINEMATICS_FILE_FORMAT_URDF``) or
145+
Viam's kinematic parameter format (spatial vector algebra) (``KinematicsFileFormat.KINEMATICS_FILE_FORMAT_SVA``),
146+
and the second [1] value represents the byte contents of the file.
147+
148+
For more information, see `Gripper component <https://docs.viam.com/dev/reference/apis/components/gripper/#getkinematics>`_.
149+
"""
150+
...

src/viam/components/gripper/service.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
from grpclib.server import Stream
22

3-
from viam.proto.common import DoCommandRequest, DoCommandResponse, GetGeometriesRequest, GetGeometriesResponse
3+
from viam.proto.common import (
4+
DoCommandRequest,
5+
DoCommandResponse,
6+
GetGeometriesRequest,
7+
GetGeometriesResponse,
8+
GetKinematicsRequest,
9+
GetKinematicsResponse
10+
)
411
from viam.proto.component.gripper import (
512
GrabRequest,
613
GrabResponse,
@@ -74,8 +81,17 @@ async def DoCommand(self, stream: Stream[DoCommandRequest, DoCommandResponse]) -
7481
async def GetGeometries(self, stream: Stream[GetGeometriesRequest, GetGeometriesResponse]) -> None:
7582
request = await stream.recv_message()
7683
assert request is not None
77-
arm = self.get_resource(request.name)
84+
gripper = self.get_resource(request.name)
7885
timeout = stream.deadline.time_remaining() if stream.deadline else None
79-
geometries = await arm.get_geometries(extra=struct_to_dict(request.extra), timeout=timeout)
86+
geometries = await gripper.get_geometries(extra=struct_to_dict(request.extra), timeout=timeout)
8087
response = GetGeometriesResponse(geometries=geometries)
8188
await stream.send_message(response)
89+
90+
async def GetKinematics(self, stream: Stream[GetKinematicsRequest, GetKinematicsResponse]) -> None:
91+
request = await stream.recv_message()
92+
assert request is not None
93+
gripper = self.get_resource(request.name)
94+
timeout = stream.deadline.time_remaining() if stream.deadline else None
95+
format, kinematics_data = await gripper.get_kinematics(extra=struct_to_dict(request.extra), timeout=timeout)
96+
response = GetKinematicsResponse(format=format, kinematics_data=kinematics_data)
97+
await stream.send_message(response)

0 commit comments

Comments
 (0)