Skip to content

Commit 326dabc

Browse files
miikeeclaude
andcommitted
Fix move_to(list) to directly create PreciseFlexJointCoords
- move_to(list) now directly creates PreciseFlexJointCoords from canonical 6-element list - Previously called convert_to_joint_space() which was designed for wherej output parsing - Input list format: [rail, base, shoulder, elbow, wrist, gripper] - For has_rail=False robots, rail is expected to be 0.0 at position 0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 4175d76 commit 326dabc

File tree

3 files changed

+96
-51
lines changed

3 files changed

+96
-51
lines changed

pylabrobot/arms/precise_flex/pf_3400.py

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,52 @@ def __init__(self, host: str, port: int = 10100, timeout=20, has_rail: bool = Fa
1212
self._has_rail = has_rail
1313

1414
def convert_to_joint_space(self, position: List[float]) -> PreciseFlexJointCoords:
15-
"""Convert a list of joint angles to a PreciseFlexJointCoords object.
15+
"""Convert parsed joint values to PreciseFlexJointCoords.
1616
1717
Args:
18-
position: List of 6 joint angles in order: [rail, base, shoulder, elbow, wrist, gripper]
19-
This matches the output format of the wherej command.
18+
position: List of 6 floats from _parse_angles_response() (always padded to 6).
19+
For has_rail=True: [rail, base, shoulder, elbow, wrist, gripper]
20+
For has_rail=False: [base, shoulder, elbow, wrist, gripper, 0.0(padding)]
2021
2122
Returns:
22-
PreciseFlexJointCoords with all joint values mapped correctly.
23+
PreciseFlexJointCoords with joint values mapped based on robot configuration.
2324
"""
24-
if len(position) != 6:
25-
raise ValueError("Position must be a list of 6 joint angles.")
26-
return PreciseFlexJointCoords(
27-
rail=position[0],
28-
base=position[1],
29-
shoulder=position[2],
30-
elbow=position[3],
31-
wrist=position[4],
32-
gripper=position[5],
33-
)
25+
if len(position) < 5:
26+
raise ValueError("Position must have at least 5 joint angles.")
3427

35-
# def convert_to_joints_array(self, position: PreciseFlexJointCoords) -> List[float]:
36-
# """Convert a JointSpace object to a list of joint angles."""
37-
# return [
38-
# 0,
39-
# position.base,
40-
# position.shoulder,
41-
# position.elbow,
42-
# position.wrist,
43-
# position.gripper,
44-
# ] # PF400 has 5 joints, last is fixed
28+
if self._has_rail:
29+
if len(position) < 6:
30+
raise ValueError("Position must have 6 joint angles for robot with rail.")
31+
return PreciseFlexJointCoords(
32+
rail=position[0],
33+
base=position[1],
34+
shoulder=position[2],
35+
elbow=position[3],
36+
wrist=position[4],
37+
gripper=position[5],
38+
)
39+
else:
40+
# No rail: positions 0-4 are [base, shoulder, elbow, wrist, gripper]
41+
# position[5] is 0.0 padding from _parse_angles_response() - ignore it
42+
return PreciseFlexJointCoords(
43+
rail=0.0,
44+
base=position[0],
45+
shoulder=position[1],
46+
elbow=position[2],
47+
wrist=position[3],
48+
gripper=position[4],
49+
)
50+
51+
def convert_to_joints_array(self, position: PreciseFlexJointCoords) -> List[float]:
52+
"""Convert a JointSpace object to a list of joint angles."""
53+
return [
54+
position.rail,
55+
position.base,
56+
position.shoulder,
57+
position.elbow,
58+
position.wrist,
59+
position.gripper,
60+
]
4561

4662
async def move_j(self, profile_index: int, joint_coords: PreciseFlexJointCoords) -> None:
4763
"""Move the robot using joint coordinates, handling rail configuration."""

pylabrobot/arms/precise_flex/pf_400.py

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,52 @@ def __init__(self, host: str, port: int = 10100, timeout=20, has_rail: bool = Fa
1212
self._has_rail = has_rail
1313

1414
def convert_to_joint_space(self, position: List[float]) -> PreciseFlexJointCoords:
15-
"""Convert a list of joint angles to a PreciseFlexJointCoords object.
15+
"""Convert parsed joint values to PreciseFlexJointCoords.
1616
1717
Args:
18-
position: List of 6 joint angles in order: [rail, base, shoulder, elbow, wrist, gripper]
19-
This matches the output format of the wherej command.
18+
position: List of 6 floats from _parse_angles_response() (always padded to 6).
19+
For has_rail=True: [rail, base, shoulder, elbow, wrist, gripper]
20+
For has_rail=False: [base, shoulder, elbow, wrist, gripper, 0.0(padding)]
2021
2122
Returns:
22-
PreciseFlexJointCoords with all joint values mapped correctly.
23+
PreciseFlexJointCoords with joint values mapped based on robot configuration.
2324
"""
24-
if len(position) != 6:
25-
raise ValueError("Position must be a list of 6 joint angles.")
26-
return PreciseFlexJointCoords(
27-
rail=position[0],
28-
base=position[1],
29-
shoulder=position[2],
30-
elbow=position[3],
31-
wrist=position[4],
32-
gripper=position[5],
33-
)
25+
if len(position) < 5:
26+
raise ValueError("Position must have at least 5 joint angles.")
3427

35-
# def convert_to_joints_array(self, position: PreciseFlexJointCoords) -> List[float]:
36-
# """Convert a PreciseFlexJointCoords object to a list of joint angles."""
37-
# return [
38-
# 0,
39-
# position.base,
40-
# position.shoulder,
41-
# position.elbow,
42-
# position.wrist,
43-
# 0,
44-
# ] # PF400 has 4 joints, last two are fixed
28+
if self._has_rail:
29+
if len(position) < 6:
30+
raise ValueError("Position must have 6 joint angles for robot with rail.")
31+
return PreciseFlexJointCoords(
32+
rail=position[0],
33+
base=position[1],
34+
shoulder=position[2],
35+
elbow=position[3],
36+
wrist=position[4],
37+
gripper=position[5],
38+
)
39+
else:
40+
# No rail: positions 0-4 are [base, shoulder, elbow, wrist, gripper]
41+
# position[5] is 0.0 padding from _parse_angles_response() - ignore it
42+
return PreciseFlexJointCoords(
43+
rail=0.0,
44+
base=position[0],
45+
shoulder=position[1],
46+
elbow=position[2],
47+
wrist=position[3],
48+
gripper=position[4],
49+
)
50+
51+
def convert_to_joints_array(self, position: PreciseFlexJointCoords) -> List[float]:
52+
"""Convert a PreciseFlexJointCoords object to a list of joint angles."""
53+
return [
54+
position.rail,
55+
position.base,
56+
position.shoulder,
57+
position.elbow,
58+
position.wrist,
59+
position.gripper,
60+
]
4561

4662
async def move_j(self, profile_index: int, joint_coords: PreciseFlexJointCoords) -> None:
4763
"""Move the robot using joint coordinates, handling rail configuration."""

pylabrobot/arms/precise_flex/precise_flex_backend.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def __init__(self, host: str, port: int = 10100, timeout=20) -> None:
4949
@abstractmethod
5050
def convert_to_joint_space(self, position: List[float]) -> PreciseFlexJointCoords:
5151
"""Convert a tuple of joint angles to a PreciseFlexJointCoords object."""
52+
...
5253

5354
@abstractmethod
5455
def convert_to_joints_array(self, position: PreciseFlexJointCoords) -> List[float]:
@@ -313,10 +314,22 @@ async def place_plate(
313314
await self._place_plate_c(cartesian_position=position, access=access)
314315

315316
async def move_to(self, position: Union[PreciseFlexCartesianCoords, List[float]]):
316-
"""Move the arm to a specified position in 3D space."""
317+
"""Move the arm to a specified position in 3D space.
318+
319+
Args:
320+
position: Either CartesianCoords or a 6-element list [rail, base, shoulder, elbow, wrist, gripper]
321+
"""
317322
if isinstance(position, list):
318-
joint_coords = self.convert_to_joint_space(position)
319-
print(joint_coords)
323+
if len(position) < 6:
324+
raise ValueError("Joint list must have 6 elements: [rail, base, shoulder, elbow, wrist, gripper]")
325+
joint_coords = PreciseFlexJointCoords(
326+
rail=position[0],
327+
base=position[1],
328+
shoulder=position[2],
329+
elbow=position[3],
330+
wrist=position[4],
331+
gripper=position[5],
332+
)
320333
await self.move_j(profile_index=self.profile_index, joint_coords=joint_coords)
321334
elif isinstance(position, PreciseFlexCartesianCoords):
322335
await self.move_c(profile_index=self.profile_index, cartesian_coords=position)

0 commit comments

Comments
 (0)