Skip to content

Commit b732608

Browse files
viambotgithub-actions[bot]
authored andcommitted
[WORKFLOW] AI update based on proto changes from commit f0044e0
1 parent 8311005 commit b732608

File tree

11 files changed

+174
-175
lines changed

11 files changed

+174
-175
lines changed

src/viam/app/data_client.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
TabularDataSourceType,
6868
TagsByFilterRequest,
6969
TagsByFilterResponse,
70+
UpdateBoundingBoxRequest,
7071
)
7172
from viam.proto.app.datapipelines import (
7273
CreateDataPipelineRequest,
@@ -1131,6 +1132,7 @@ async def add_bounding_box_to_image_by_id(
11311132
y_min_normalized: float,
11321133
x_max_normalized: float,
11331134
y_max_normalized: float,
1135+
confidence: Optional[float] = None,
11341136
) -> str:
11351137
"""Add a bounding box to an image.
11361138
@@ -1156,6 +1158,7 @@ async def add_bounding_box_to_image_by_id(
11561158
y_min_normalized (float): Min Y value of the bounding box normalized from 0 to 1.
11571159
x_max_normalized (float): Max X value of the bounding box normalized from 0 to 1.
11581160
y_max_normalized (float): Max Y value of the bounding box normalized from 0 to 1.
1161+
confidence (Optional[float]): The confidence score for the bounding box.
11591162
11601163
Raises:
11611164
GRPCError: If the X or Y values are outside of the [0, 1] range.
@@ -1174,6 +1177,7 @@ async def add_bounding_box_to_image_by_id(
11741177
x_min_normalized=x_min_normalized,
11751178
y_max_normalized=y_max_normalized,
11761179
y_min_normalized=y_min_normalized,
1180+
confidence=confidence,
11771181
)
11781182
else:
11791183
request = AddBoundingBoxToImageByIDRequest(
@@ -1183,6 +1187,7 @@ async def add_bounding_box_to_image_by_id(
11831187
x_min_normalized=x_min_normalized,
11841188
y_max_normalized=y_max_normalized,
11851189
y_min_normalized=y_min_normalized,
1190+
confidence=confidence,
11861191
)
11871192
response: AddBoundingBoxToImageByIDResponse = await self._data_client.AddBoundingBoxToImageByID(request, metadata=self._metadata)
11881193
return response.bbox_id
@@ -1535,6 +1540,7 @@ async def binary_data_capture_upload(
15351540
tags: Optional[List[str]] = None,
15361541
dataset_ids: Optional[List[str]] = None,
15371542
data_request_times: Optional[Tuple[datetime, datetime]] = None,
1543+
mime_type: Optional[str] = None,
15381544
) -> str:
15391545
"""Upload binary sensor data.
15401546
@@ -1573,6 +1579,7 @@ async def binary_data_capture_upload(
15731579
dataset_ids (Optional[List[str]]): Optional list of datasets to add the data to.
15741580
data_request_times (Optional[Tuple[datetime.datetime, datetime.datetime]]): Optional tuple containing datetime objects
15751581
denoting the times this data was requested ``[0]`` by the robot and received ``[1]`` from the appropriate sensor.
1582+
mime_type (Optional[str]): The MIME type of the file.
15761583
15771584
Raises:
15781585
GRPCError: If an invalid part ID is passed.
@@ -1603,6 +1610,7 @@ async def binary_data_capture_upload(
16031610
method_parameters=method_parameters,
16041611
tags=tags,
16051612
dataset_ids=dataset_ids,
1613+
mime_type=mime_type if mime_type else "",
16061614
)
16071615
if file_extension:
16081616
metadata.file_extension = file_extension if file_extension[0] == "." else f".{file_extension}"
@@ -1619,6 +1627,7 @@ async def tabular_data_capture_upload(
16191627
data_request_times: List[Tuple[datetime, datetime]],
16201628
method_parameters: Optional[Mapping[str, Any]] = None,
16211629
tags: Optional[List[str]] = None,
1630+
mime_type: Optional[str] = None,
16221631
) -> str:
16231632
"""Upload tabular sensor data.
16241633
@@ -1658,6 +1667,7 @@ async def tabular_data_capture_upload(
16581667
Pass a list of tabular data and timestamps with length ``n > 1`` to upload ``n`` datapoints, all with the same metadata.
16591668
method_parameters (Optional[Mapping[str, Any]]): Optional dictionary of method parameters. No longer in active use.
16601669
tags (Optional[List[str]]): Optional list of tags to allow for tag-based data filtering when retrieving data.
1670+
mime_type (Optional[str]): The MIME type of the file.
16611671
16621672
Raises:
16631673
GRPCError: If an invalid part ID is passed.
@@ -1700,6 +1710,7 @@ async def tabular_data_capture_upload(
17001710
type=DataType.DATA_TYPE_TABULAR_SENSOR,
17011711
method_parameters=method_parameters,
17021712
tags=tags,
1713+
mime_type=mime_type if mime_type else "",
17031714
)
17041715
response = await self._data_capture_upload(metadata=metadata, sensor_contents=sensor_contents)
17051716
return response.file_id
@@ -1721,6 +1732,7 @@ async def streaming_data_capture_upload(
17211732
data_request_times: Optional[Tuple[datetime, datetime]] = None,
17221733
tags: Optional[List[str]] = None,
17231734
dataset_ids: Optional[List[str]] = None,
1735+
mime_type: Optional[str] = None,
17241736
) -> str:
17251737
"""Uploads the metadata and contents of streaming binary data.
17261738
@@ -1753,6 +1765,7 @@ async def streaming_data_capture_upload(
17531765
denoting the times this data was requested ``[0]`` by the robot and received ``[1]`` from the appropriate sensor.
17541766
tags (Optional[List[str]]): Optional list of tags to allow for tag-based filtering when retrieving data.
17551767
dataset_ids (Optional[List[str]]): Optional list of datasets to add the data to.
1768+
mime_type (Optional[str]): The MIME type of the file.
17561769
17571770
Raises:
17581771
GRPCError: If an invalid part ID is passed.
@@ -1773,6 +1786,7 @@ async def streaming_data_capture_upload(
17731786
file_extension=file_ext if file_ext[0] == "." else f".{file_ext}",
17741787
tags=tags,
17751788
dataset_ids=dataset_ids,
1789+
mime_type=mime_type if mime_type else "",
17761790
)
17771791
sensor_metadata = SensorMetadata(
17781792
time_requested=datetime_to_timestamp(data_request_times[0]) if data_request_times else None,
@@ -1802,6 +1816,7 @@ async def file_upload(
18021816
file_extension: Optional[str] = None,
18031817
tags: Optional[List[str]] = None,
18041818
dataset_ids: Optional[List[str]] = None,
1819+
mime_type: Optional[str] = None,
18051820
) -> str:
18061821
"""Upload arbitrary file data.
18071822
@@ -1832,6 +1847,7 @@ async def file_upload(
18321847
isn't provided. Files with a ``.jpeg``, ``.jpg``, or ``.png`` extension will be saved to the **Images** tab.
18331848
tags (Optional[List[str]]): Optional list of tags to allow for tag-based filtering when retrieving data.
18341849
dataset_ids (Optional[List[str]]): Optional list of datasets to add the data to.
1850+
mime_type (Optional[str]): The MIME type of the file.
18351851
18361852
Raises:
18371853
GRPCError: If an invalid part ID is passed.
@@ -1852,6 +1868,7 @@ async def file_upload(
18521868
file_extension=file_extension if file_extension else "",
18531869
tags=tags,
18541870
dataset_ids=dataset_ids,
1871+
mime_type=mime_type if mime_type else "",
18551872
)
18561873
response: FileUploadResponse = await self._file_upload(metadata=metadata, file_contents=FileData(data=data))
18571874
return response.binary_data_id
@@ -1866,6 +1883,7 @@ async def file_upload_from_path(
18661883
method_parameters: Optional[Mapping[str, Any]] = None,
18671884
tags: Optional[List[str]] = None,
18681885
dataset_ids: Optional[List[str]] = None,
1886+
mime_type: Optional[str] = None,
18691887
) -> str:
18701888
"""Upload arbitrary file data.
18711889
@@ -1890,6 +1908,7 @@ async def file_upload_from_path(
18901908
method_parameters (Optional[str]): Optional dictionary of the method parameters. No longer in active use.
18911909
tags (Optional[List[str]]): Optional list of tags to allow for tag-based filtering when retrieving data.
18921910
dataset_ids (Optional[List[str]]): Optional list of datasets to add the data to.
1911+
mime_type (Optional[str]): The MIME type of the file.
18931912
18941913
Raises:
18951914
GRPCError: If an invalid part ID is passed.
@@ -1917,6 +1936,7 @@ async def file_upload_from_path(
19171936
file_extension=file_extension if file_extension else "",
19181937
tags=tags,
19191938
dataset_ids=dataset_ids,
1939+
mime_type=mime_type if mime_type else "",
19201940
)
19211941
response: FileUploadResponse = await self._file_upload(metadata=metadata, file_contents=FileData(data=data if data else bytes()))
19221942
return response.binary_data_id
@@ -2229,3 +2249,67 @@ def create_filter(
22292249
bbox_labels,
22302250
dataset_id,
22312251
)
2252+
2253+
async def update_bounding_box(
2254+
self,
2255+
binary_id: Union[BinaryID, str],
2256+
bbox_id: str,
2257+
label: Optional[str] = None,
2258+
x_min_normalized: Optional[float] = None,
2259+
y_min_normalized: Optional[float] = None,
2260+
x_max_normalized: Optional[float] = None,
2261+
y_max_normalized: Optional[float] = None,
2262+
confidence: Optional[float] = None,
2263+
) -> None:
2264+
"""Updates a bounding box in an image.
2265+
2266+
::
2267+
2268+
await data_client.update_bounding_box(
2269+
binary_id="<YOUR-BINARY-DATA-ID>",
2270+
bbox_id="your-bounding-box-id-to-update",
2271+
label="new-label",
2272+
x_min_normalized=0.1,
2273+
y_min_normalized=0.1,
2274+
x_max_normalized=0.3,
2275+
y_max_normalized=0.3,
2276+
confidence=0.9
2277+
)
2278+
2279+
Args:
2280+
binary_id (Union[~viam.proto.app.data.BinaryID, str]): The binary data ID or :class:`BinaryID` of the image containing the bounding
2281+
box to update. *DEPRECATED:* :class:`BinaryID` *is deprecated and will be removed in a future release. Instead, pass binary data IDs as a
2282+
list of strings.*
2283+
bbox_id (str): The ID of the bounding box to update.
2284+
label (Optional[str]): The new label for the bounding box.
2285+
x_min_normalized (Optional[float]): New min X value of the bounding box normalized from 0 to 1.
2286+
y_min_normalized (Optional[float]): New min Y value of the bounding box normalized from 0 to 1.
2287+
x_max_normalized (Optional[float]): New max X value of the bounding box normalized from 0 to 1.
2288+
y_max_normalized (Optional[float]): New max Y value of the bounding box normalized from 0 to 1.
2289+
confidence (Optional[float]): The new confidence score for the bounding box.
2290+
2291+
Raises:
2292+
GRPCError: If the X or Y values are outside of the [0, 1] range.
2293+
2294+
For more information, see `Data Client API <https://docs.viam.com/dev/reference/apis/data-client/#updateboundingbox>`_.
2295+
"""
2296+
request = UpdateBoundingBoxRequest(bbox_id=bbox_id)
2297+
if isinstance(binary_id, str):
2298+
request.binary_data_id = binary_id
2299+
else:
2300+
request.binary_id = binary_id
2301+
2302+
if label is not None:
2303+
request.label = label
2304+
if x_min_normalized is not None:
2305+
request.x_min_normalized = x_min_normalized
2306+
if y_min_normalized is not None:
2307+
request.y_min_normalized = y_min_normalized
2308+
if x_max_normalized is not None:
2309+
request.x_max_normalized = x_max_normalized
2310+
if y_max_normalized is not None:
2311+
request.y_max_normalized = y_max_normalized
2312+
if confidence is not None:
2313+
request.confidence = confidence
2314+
2315+
await self._data_client.UpdateBoundingBox(request, metadata=self._metadata)

src/viam/components/arm/arm.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import abc
2-
from typing import Any, Dict, Final, Optional, Tuple
2+
from typing import Any, Dict, Final, Mapping, Optional, Tuple
33

44
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
55

66
from ..component_base import ComponentBase
77
from . import JointPositions, KinematicsFileFormat, Pose
8+
from .mesh import Mesh
89

910

1011
class Arm(ComponentBase):
@@ -195,7 +196,7 @@ async def is_moving(self) -> bool:
195196
@abc.abstractmethod
196197
async def get_kinematics(
197198
self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
198-
) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
199+
) -> Tuple[KinematicsFileFormat.ValueType, bytes, Mapping[str, Mesh]]:
199200
"""
200201
Get the kinematics information associated with the arm.
201202
@@ -212,11 +213,14 @@ async def get_kinematics(
212213
# Get the byte contents of the file.
213214
k_bytes = kinematics[1]
214215
216+
# Get the map of meshes by URDF filepath.
217+
meshes_by_urdf_filepath = kinematics[2]
218+
215219
Returns:
216-
Tuple[KinematicsFileFormat.ValueType, bytes]: A tuple containing two values; the first [0] value represents the format of the
220+
Tuple[KinematicsFileFormat.ValueType, bytes, Mapping[str, Mesh]]: A tuple containing three values; the first [0] value represents the format of the
217221
file, either in URDF format (``KinematicsFileFormat.KINEMATICS_FILE_FORMAT_URDF``) or
218222
Viam's kinematic parameter format (spatial vector algebra) (``KinematicsFileFormat.KINEMATICS_FILE_FORMAT_SVA``),
219-
and the second [1] value represents the byte contents of the file.
223+
the second [1] value represents the byte contents of the file, and the third [2] value is a map of meshes by URDF filepath.
220224
221225
For more information, see `Arm component <https://docs.viam.com/dev/reference/apis/components/arm/#getkinematics>`_.
222226
"""

src/viam/components/arm/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from grpclib.client import Channel
44

5-
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetKinematicsRequest, GetKinematicsResponse
5+
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry, GetKinematicsRequest, GetKinematicsResponse, Mesh
66
from viam.proto.component.arm import (
77
ArmServiceStub,
88
GetEndPositionRequest,
@@ -113,11 +113,11 @@ async def do_command(
113113

114114
async def get_kinematics(
115115
self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs
116-
) -> Tuple[KinematicsFileFormat.ValueType, bytes]:
116+
) -> Tuple[KinematicsFileFormat.ValueType, bytes, Mapping[str, Mesh]]:
117117
md = kwargs.get("metadata", self.Metadata()).proto
118118
request = GetKinematicsRequest(name=self.name, extra=dict_to_struct(extra))
119119
response: GetKinematicsResponse = await self.client.GetKinematics(request, timeout=timeout, metadata=md)
120-
return (response.format, response.kinematics_data)
120+
return (response.format, response.kinematics_data, response.meshes_by_urdf_filepath)
121121

122122
async def get_geometries(self, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Geometry]:
123123
md = kwargs.get("metadata", self.Metadata())

src/viam/components/arm/service.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
GetGeometriesResponse,
88
GetKinematicsRequest,
99
GetKinematicsResponse,
10+
Mesh,
1011
)
1112
from viam.proto.component.arm import (
1213
GetEndPositionRequest,
@@ -109,8 +110,8 @@ async def GetKinematics(self, stream: Stream[GetKinematicsRequest, GetKinematics
109110
assert request is not None
110111
arm = self.get_resource(request.name)
111112
timeout = stream.deadline.time_remaining() if stream.deadline else None
112-
format, kinematics_data = await arm.get_kinematics(extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
113-
response = GetKinematicsResponse(format=format, kinematics_data=kinematics_data)
113+
format, kinematics_data, meshes_by_urdf_filepath = await arm.get_kinematics(extra=struct_to_dict(request.extra), timeout=timeout, metadata=stream.metadata)
114+
response = GetKinematicsResponse(format=format, kinematics_data=kinematics_data, meshes_by_urdf_filepath=meshes_by_urdf_filepath)
114115
await stream.send_message(response)
115116

116117
async def GetGeometries(self, stream: Stream[GetGeometriesRequest, GetGeometriesResponse]) -> None:

src/viam/components/audio_in/audio_in.py

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
import sys
33
from typing import Final, Optional
44

5-
from viam.proto.common import GetPropertiesResponse
6-
from viam.proto.component.audioin import GetAudioResponse
5+
from viam.proto.common import AudioInfo, GetPropertiesResponse
76
from viam.resource.types import API, RESOURCE_NAMESPACE_RDK, RESOURCE_TYPE_COMPONENT
87
from viam.streams import Stream
98

@@ -28,35 +27,7 @@ class AudioIn(ComponentBase):
2827
)
2928

3029
Properties: "TypeAlias" = GetPropertiesResponse
31-
AudioResponse: "TypeAlias" = GetAudioResponse
32-
AudioStream = Stream[AudioResponse]
33-
34-
@abc.abstractmethod
35-
async def get_audio(
36-
self, codec: str, duration_seconds: float, previous_timestamp_ns: int, *, timeout: Optional[float] = None, **kwargs
37-
) -> AudioStream:
38-
"""
39-
Get a stream of audio from the device
40-
41-
::
42-
43-
my_audio_in = AudioIn.from_robot(robot=machine, name="my_audio_in")
44-
45-
stream = await my_audio_in.get_audio(
46-
codec=AudioCodec.PCM16,
47-
duration_seconds=10.0,
48-
previous_timestamp_ns=0
49-
)
50-
51-
Args:
52-
codec (str): The desired codec of the returned audio data
53-
duration_seconds (float): duration of the stream. 0 = indefinite stream
54-
previous_timestamp_ns (int): starting timestamp in nanoseconds for recording continuity.
55-
Set to 0 to begin recording from the current time.
56-
Returns:
57-
AudioStream: stream of audio chunks.
58-
...
59-
"""
30+
AudioInfo: "TypeAlias" = AudioInfo
6031

6132
@abc.abstractmethod
6233
async def get_properties(self, *, timeout: Optional[float] = None, **kwargs) -> Properties:

0 commit comments

Comments
 (0)