Skip to content

Commit a3c883a

Browse files
committed
update api to use 6 joints instead of 7
1 parent d8da11b commit a3c883a

File tree

2 files changed

+29
-30
lines changed

2 files changed

+29
-30
lines changed

pylabrobot/arms/precise_flex/precise_flex_api.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ async def get_version(self) -> str:
397397
return await self.send_command("version")
398398

399399
#region LOCATION COMMANDS
400-
async def get_location(self, location_index: int) -> tuple[int, int, float, float, float, float, float, float, float]:
400+
async def get_location(self, location_index: int) -> tuple[int, int, float, float, float, float, float, float]:
401401
"""Get the location values for the specified station index.
402402
403403
Parameters:
@@ -406,7 +406,7 @@ async def get_location(self, location_index: int) -> tuple[int, int, float, floa
406406
Returns:
407407
tuple: A tuple containing (type_code, station_index, val1, val2, val3, val4, val5, val6)
408408
- For Cartesian type (type_code=0): (0, station_index, X, Y, Z, yaw, pitch, roll, unused = 0.0)
409-
- For angles type (type_code=1): (1, station_index, angle1, angle2, angle3, angle4, angle5, angle6, angle7) - any unused angles are set to 0.0
409+
- For angles type (type_code=1): (1, station_index, angle1, angle2, angle3, angle4, angle5, angle6) - any unused angles are set to 0.0
410410
"""
411411
data = await self.send_command(f"loc {location_index}")
412412
parts = data.split(" ")
@@ -417,16 +417,16 @@ async def get_location(self, location_index: int) -> tuple[int, int, float, floa
417417
# location stored as cartesian
418418
if type_code == 0:
419419
x, y, z, yaw, pitch, roll = self._parse_xyz_response(parts[2:8])
420-
return (type_code, station_index, x, y, z, yaw, pitch, roll, 0.0)
420+
return (type_code, station_index, x, y, z, yaw, pitch, roll)
421421

422422
# location stored as angles
423423
if type_code == 1:
424-
angle1, angle2, angle3, angle4, angle5, angle6, angle7 = self._parse_angles_response(parts[2:])
425-
return (type_code, station_index, angle1, angle2, angle3, angle4, angle5, angle6, angle7)
424+
angle1, angle2, angle3, angle4, angle5, angle6 = self._parse_angles_response(parts[2:])
425+
return (type_code, station_index, angle1, angle2, angle3, angle4, angle5, angle6)
426426

427427
raise PreciseFlexError(-1, "Unexpected response format from loc command.")
428428

429-
async def get_location_angles(self, location_index: int) -> tuple[int, int, float, float, float, float, float, float, float]:
429+
async def get_location_angles(self, location_index: int) -> tuple[int, int, float, float, float, float, float, float]:
430430
"""Get the angle values for the specified station index.
431431
432432
Parameters:
@@ -446,9 +446,9 @@ async def get_location_angles(self, location_index: int) -> tuple[int, int, floa
446446
raise PreciseFlexError(-1, "Location is not of angles type.")
447447

448448
station_index = int(parts[1])
449-
angle1, angle2, angle3, angle4, angle5, angle6, angle7 = self._parse_angles_response(parts[2:])
449+
angle1, angle2, angle3, angle4, angle5, angle6 = self._parse_angles_response(parts[2:])
450450

451-
return (type_code, station_index, angle1, angle2, angle3, angle4, angle5, angle6, angle7)
451+
return (type_code, station_index, angle1, angle2, angle3, angle4, angle5, angle6)
452452

453453

454454

@@ -654,7 +654,7 @@ async def dest_c(self, arg1: int = 0) -> tuple[float, float, float, float, float
654654

655655
return (x, y, z, yaw, pitch, roll, config)
656656

657-
async def dest_j(self, arg1: int = 0) -> tuple[float, float, float, float, float, float, float]:
657+
async def dest_j(self, arg1: int = 0) -> tuple[float, float, float, float, float, float]:
658658
"""Get the destination or current joint location of the robot.
659659
660660
Parameters:
@@ -676,10 +676,10 @@ async def dest_j(self, arg1: int = 0) -> tuple[float, float, float, float, float
676676
if not parts:
677677
raise PreciseFlexError(-1, "Unexpected response format from destJ command.")
678678

679-
# Ensure we have exactly 7 elements, padding with 0.0 if necessary
680-
angle1, angle2, angle3, angle4, angle5, angle6, angle7 = self._parse_angles_response(parts)
679+
# Ensure we have exactly 6 elements, padding with 0.0 if necessary
680+
angle1, angle2, angle3, angle4, angle5, angle6 = self._parse_angles_response(parts)
681681

682-
return (angle1, angle2, angle3, angle4, angle5, angle6, angle7)
682+
return (angle1, angle2, angle3, angle4, angle5, angle6)
683683

684684
async def here_j(self, location_index: int) -> None:
685685
"""Record the current position of the selected robot into the specified Location as angles.
@@ -706,7 +706,7 @@ async def where(self) -> tuple[float, float, float, float, float, float, tuple[f
706706
"""Return the current position of the selected robot in both Cartesian and joints format.
707707
708708
Returns:
709-
tuple: A tuple containing (X, Y, Z, yaw, pitch, roll, (axis1, axis2, axis3, axis4, axis5, axis6, axis7))
709+
tuple: A tuple containing (X, Y, Z, yaw, pitch, roll, (axis1, axis2, axis3, axis4, axis5, axis6))
710710
"""
711711
data = await self.send_command("where")
712712
parts = data.split()
@@ -733,24 +733,24 @@ async def where_c(self) -> tuple[float, float, float, float, float, float, int]:
733733
data = await self.send_command("wherec")
734734
parts = data.split()
735735

736-
if len(parts) != 7:
736+
if len(parts) != 6:
737737
# In case of incomplete response, wait for EOM and try to read again
738738
await self.wait_for_eom()
739739
data = await self.send_command("wherec")
740740
parts = data.split()
741-
if len(parts) != 7:
741+
if len(parts) != 6:
742742
raise PreciseFlexError(-1, "Unexpected response format from wherec command.")
743743

744744
x, y, z, yaw, pitch, roll = self._parse_xyz_response(parts[0:6])
745745
config = int(parts[6])
746746

747747
return (x, y, z, yaw, pitch, roll, config)
748748

749-
async def where_j(self) -> tuple[float, float, float, float, float, float, float]:
749+
async def where_j(self) -> tuple[float, float, float, float, float, float]:
750750
"""Return the current joint position for the selected robot.
751751
752752
Returns:
753-
tuple: A tuple containing (axis1, axis2, axis3, axis4, axis5, axis6, axis7)
753+
tuple: A tuple containing (axis1, axis2, axis3, axis4, axis5, axis6)
754754
"""
755755
data = await self.send_command("wherej")
756756
parts = data.split()
@@ -1902,20 +1902,19 @@ def _parse_xyz_response(self, parts: list[str]) -> tuple[float, float, float, fl
19021902

19031903
return (x, y, z, yaw, pitch, roll)
19041904

1905-
def _parse_angles_response(self, parts: list[str]) -> tuple[float, float, float, float, float, float, float]:
1905+
def _parse_angles_response(self, parts: list[str]) -> tuple[float, float, float, float, float, float]:
19061906
if len(parts) < 3:
19071907
raise PreciseFlexError(-1, "Unexpected response format for angles.")
19081908

1909-
# Ensure we have exactly 7 elements, padding with 0.0 if necessary
1909+
# Ensure we have exactly 6 elements, padding with 0.0 if necessary
19101910
angle1 = float(parts[0])
19111911
angle2 = float(parts[1])
19121912
angle3 = float(parts[2])
19131913
angle4 = float(parts[3]) if len(parts) > 3 else 0.0
19141914
angle5 = float(parts[4]) if len(parts) > 4 else 0.0
19151915
angle6 = float(parts[5]) if len(parts) > 5 else 0.0
1916-
angle7 = float(parts[6]) if len(parts) > 6 else 0.0
19171916

1918-
return (angle1, angle2, angle3, angle4, angle5, angle6, angle7)
1917+
return (angle1, angle2, angle3, angle4, angle5, angle6)
19191918

19201919
def _parse_reply_ensure_successful(self, reply: bytes) -> str:
19211920
"""Parse reply from Precise Flex.

pylabrobot/arms/precise_flex/precise_flex_api_tests.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -298,24 +298,24 @@ async def test_get_location(self) -> None:
298298
"""Test get_location()"""
299299
location_data = await self.robot.get_location(self.TEST_LOCATION_ID)
300300
self.assertIsInstance(location_data, tuple)
301-
self.assertEqual(len(location_data), 9)
302-
type_code, station_index, val1, val2, val3, val4, val5, val6, val7 = location_data
301+
self.assertEqual(len(location_data), 8)
302+
type_code, station_index, val1, val2, val3, val4, val5, val6 = location_data
303303
self.assertIsInstance(type_code, int)
304304
self.assertIn(type_code, [0, 1]) # 0 = Cartesian, 1 = angles
305305
self.assertEqual(station_index, self.TEST_LOCATION_ID)
306-
print(f"Location {self.TEST_LOCATION_ID}: type={type_code}, values=({val1}, {val2}, {val3}, {val4}, {val5}, {val6}, {val7})")
306+
print(f"Location {self.TEST_LOCATION_ID}: type={type_code}, values=({val1}, {val2}, {val3}, {val4}, {val5}, {val6})")
307307

308308
async def test_get_location_angles(self) -> None:
309309
"""Test get_location_angles()"""
310310
# This test assumes location is already angles type or will fail appropriately
311311
try:
312312
location_data = await self.robot.get_location_angles(self.TEST_LOCATION_ID)
313313
self.assertIsInstance(location_data, tuple)
314-
self.assertEqual(len(location_data), 9)
315-
type_code, station_index, angle1, angle2, angle3, angle4, angle5, angle6, angle7 = location_data
314+
self.assertEqual(len(location_data), 8)
315+
type_code, station_index, angle1, angle2, angle3, angle4, angle5, angle6 = location_data
316316
self.assertEqual(type_code, 1) # Should be angles type
317317
self.assertEqual(station_index, self.TEST_LOCATION_ID)
318-
print(f"Location angles {self.TEST_LOCATION_ID}: ({angle1}, {angle2}, {angle3}, {angle4}, {angle5}, {angle6}, {angle7})")
318+
print(f"Location angles {self.TEST_LOCATION_ID}: ({angle1}, {angle2}, {angle3}, {angle4}, {angle5}, {angle6})")
319319
except Exception as e:
320320
print(f"Location {self.TEST_LOCATION_ID} is not angles type or error occurred: {e}")
321321

@@ -331,7 +331,7 @@ async def test_set_location_angles(self) -> None:
331331

332332
# Verify the angles were set
333333
location_data = await self.robot.get_location_angles(self.TEST_LOCATION_ID)
334-
_, _, angle1, angle2, angle3, angle4, angle5, angle6, angle7 = location_data
334+
_, _, angle1, angle2, angle3, angle4, angle5, angle6 = location_data
335335

336336
# Check first 6 angles (angle7 is typically 0)
337337
retrieved_angles = (angle1, angle2, angle3, angle4, angle5, angle6)
@@ -535,14 +535,14 @@ async def test_dest_j(self) -> None:
535535
# Test with default argument (current joint positions)
536536
dest_data = await self.robot.dest_j()
537537
self.assertIsInstance(dest_data, tuple)
538-
self.assertEqual(len(dest_data), 7)
538+
self.assertEqual(len(dest_data), 6)
539539
self.assertTrue(all(isinstance(val, (int, float)) for val in dest_data))
540540
print(f"Current joint destination: {dest_data}")
541541

542542
# Test with arg1=1 (target joint positions)
543543
dest_data_target = await self.robot.dest_j(1)
544544
self.assertIsInstance(dest_data_target, tuple)
545-
self.assertEqual(len(dest_data_target), 7)
545+
self.assertEqual(len(dest_data_target), 6)
546546
print(f"Target joint destination: {dest_data_target}")
547547

548548
async def test_here_j(self) -> None:

0 commit comments

Comments
 (0)