Skip to content
Open
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
30 changes: 27 additions & 3 deletions parol6/client/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1003,18 +1003,42 @@ async def shapes(self) -> ShapeWorld | None:
return None
return ShapeWorld(
installation=tuple(
shape_from_wire(w.kind, w.params, w.pose, w.collision, w.margin, w.name)
shape_from_wire(
w.kind,
w.params,
w.pose,
w.collision,
w.margin,
w.name,
w.physics,
)
for w in resp.installation
),
program=tuple(
shape_from_wire(w.kind, w.params, w.pose, w.collision, w.margin, w.name)
shape_from_wire(
w.kind,
w.params,
w.pose,
w.collision,
w.margin,
w.name,
w.physics,
)
for w in resp.program
),
)

async def tcp_offset(self) -> list[float]:
"""Query current TCP offset in mm [x, y, z].

Raises ``ConnectionError`` when the controller does not answer.
``[0, 0, 0]`` is a legitimate offset -- a tool deliberately cleared
-- so returning it as a not-answered sentinel leaves the caller
unable to tell "the offset is zero" from "there is no controller",
and a host that adopts the readback quietly erases the offset the
user just set. ``_request`` already retries, so reaching the end
here means unreachable, not one lost datagram.

Category: Configuration

Example:
Expand All @@ -1023,7 +1047,7 @@ async def tcp_offset(self) -> list[float]:
resp = await self._request(TcpOffsetCmd())
if isinstance(resp, TcpOffsetResultStruct):
return [resp.x, resp.y, resp.z]
return [0.0, 0.0, 0.0]
raise ConnectionError("the controller did not answer tcp_offset()")

async def select_profile(self, profile: str) -> int:
"""Set the motion profile (e.g. ``"TOPPRA"``).
Expand Down
10 changes: 9 additions & 1 deletion parol6/protocol/wire.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,14 +638,22 @@ class SetTcpOffsetCmd(


class ShapeWire(msgspec.Struct, array_like=True, frozen=True, gc=False):
"""One workspace shape — mirrors waldoctl ``Shape.to_wire()``."""
"""One workspace shape — mirrors waldoctl ``Shape.to_wire()``.

``physics`` is seventh and defaulted, which is what keeps this readable
both ways across the waldoctl 0.13 boundary: a peer still sending the
six-element form decodes with ``physics`` absent, and one sending seven
decodes fully. Without the field at all, every ``set_shapes`` against
0.13 raised ``TypeError: Extra positional arguments provided``.
"""

kind: str
params: list[float]
pose: list[float]
collision: bool
margin: float | None
name: str
physics: list | None = None


class SetShapesCmd(
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ dependencies = [
"psutil>=5.9",
"msgspec>=0.18",
"ormsgpack>=1.4.0",
"waldoctl @ git+https://github.com/Jepson2k/waldoctl.git@v0.12.0",
"waldoctl @ git+https://github.com/Jepson2k/waldoctl.git@v0.13.1",
]

[tool.setuptools.packages.find]
Expand Down
Loading