Skip to content

Commit a58b858

Browse files
authored
Formatting Refactor (#12)
- Updated CONTRIBUTING.md with setup and linting instructions - Standardized formatting and import order across all modules - Refactored robot classes (Jaka, ElephantRobotics, Dobot, Fanuc) for readability and consistency - Improved error handling and validation logic - Fixed trailing commas and cleaned up multi-line strings
1 parent 9fe2c73 commit a58b858

30 files changed

Lines changed: 1005 additions & 332 deletions

CONTRIBUTING.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,29 @@ Always test new motion commands on virtual or low-power modes first.
121121

122122
**Docs:**
123123
Update this guide or relevant docstrings if you change command interfaces. Additionally, when adding a new manufacturer integration, include links to relevant source documentation in in-line comments and/or the README inside the added manufacturer folder. This helps future contributors understand implementation details and reference official resources easily.
124+
125+
**Linting and Code Quality:**
126+
127+
Please ensure your code adheres to the project's formatting and quality standards before submitting a pull request.
128+
129+
**Setup:**
130+
131+
```bash
132+
python -m venv .venv
133+
source .venv/bin/activate
134+
pip install poetry
135+
poetry install --with dev
136+
```
137+
138+
**Formatting Code:**
139+
140+
To ensure consistency and code quality, run the following commands before submitting your changes:
141+
142+
```bash
143+
poetry run black . && \
144+
poetry run isort . && \
145+
poetry run ruff format . && \
146+
poetry run mypy armctl
147+
```
148+
149+
> All code must be properly formatted and pass type checks. Please resolve any issues reported by these tools prior to opening a pull request.

armctl/__init__.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,48 @@
1414

1515
# from .dobot import Dobot
1616
from .elephant_robotics import ElephantRobotics, Pro600
17-
from .universal_robotics import (UniversalRobotics,
18-
UR3, UR5, UR5e, UR10, UR16,
19-
OnRobot)
17+
from .jaka import Jaka
18+
from .universal_robotics import (
19+
UR3,
20+
UR5,
21+
UR10,
22+
UR16,
23+
OnRobot,
24+
UniversalRobotics,
25+
UR5e,
26+
)
27+
2028
# from .fanuc import Fanuc
2129
from .vention import Vention
22-
from .jaka import Jaka
2330

2431
__all__ = [
2532
"ElephantRobotics",
2633
"Pro600",
27-
2834
"UniversalRobotics",
2935
"UR5",
3036
"UR5e",
3137
"OnRobot",
32-
3338
"Vention",
3439
"Jaka",
35-
3640
"Logger",
3741
]
3842

43+
3944
class Logger:
4045
"""Global logger utility for armctl."""
46+
4147
@staticmethod
4248
def disable():
4349
"""Disables logging."""
4450
import logging
51+
4552
# Disable all logging at and below the CRITICAL level
4653
logging.disable(logging.CRITICAL)
47-
54+
4855
@staticmethod
4956
def enable():
5057
"""Enables logging."""
5158
import logging
59+
5260
# Re-enable logging to its previous state
53-
logging.disable(logging.NOTSET)
61+
logging.disable(logging.NOTSET)

armctl/angle_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import math
22

3+
34
class AngleUtils:
45
@staticmethod
56
def to_degrees_joint(joint_positions):
@@ -15,4 +16,4 @@ def to_degrees_cartesian(pose):
1516

1617
@staticmethod
1718
def to_radians_cartesian(pose):
18-
return pose[:3] + [math.radians(a) for a in pose[3:]]
19+
return pose[:3] + [math.radians(a) for a in pose[3:]]

armctl/dobot/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .dobot import Dobot
1+
from .dobot import Dobot

armctl/dobot/dobot.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
from armctl.templates import SerialController as SCT
22

3+
34
class Dobot(SCT):
45
def __init__(self, ip: str, port: int):
56
super().__init__(ip, port)
67
self.JOINT_RANGES = [
78
(-135.00, 135.00),
89
(-5.00, 80.00),
910
(-10.00, 85.00),
10-
(-145.00, 145.00)
11+
(-145.00, 145.00),
1112
]
1213
self.DOF = len(self.JOINT_RANGES)
13-
raise NotImplementedError(f"{self.__class__.__name__.upper()} is not yet supported.")
14+
raise NotImplementedError(
15+
f"{self.__class__.__name__.upper()} is not yet supported."
16+
)
1417

1518
def sleep(self, seconds):
1619
self.send_command(f"sleep({seconds})")
@@ -23,9 +26,11 @@ def move_joints(self, pos, *args, **kwargs) -> str:
2326

2427
for j, (lower, upper) in enumerate(self.JOINT_RANGES):
2528
if not (lower <= pos[j] <= upper):
26-
raise ValueError(f"Joint {j+1} angle out of range: {lower} ~ {upper}")
27-
28-
command = "MOVJ({})".format(','.join(map(str, pos)))
29+
raise ValueError(
30+
f"Joint {j + 1} angle out of range: {lower} ~ {upper}"
31+
)
32+
33+
command = "MOVJ({})".format(",".join(map(str, pos)))
2934
return self.send_command(command)
3035

3136
def move_cartesian(self, pose) -> str:
@@ -35,30 +40,36 @@ def move_cartesian(self, pose) -> str:
3540
pose.append(0)
3641

3742
# Now check again if the robot pose has 4 elements
38-
if len(pose) != 4:
39-
raise ValueError("Robot pose must have 3 ([x, y, z]) or 4 elements: [x, y, z, rz]")
43+
if len(pose) != 4:
44+
raise ValueError(
45+
"Robot pose must have 3 ([x, y, z]) or 4 elements: [x, y, z, rz]"
46+
)
4047

41-
command = "MOVEL({})".format(','.join(map(str, pose)))
48+
command = "MOVEL({})".format(",".join(map(str, pose)))
4249
return self.send_command(command)
4350

44-
def get_joint_positions(self): pass
51+
def get_joint_positions(self):
52+
pass
4553

46-
def get_cartesian_position(self): pass
54+
def get_cartesian_position(self):
55+
pass
4756

48-
def stop_motion(self): pass
57+
def stop_motion(self):
58+
pass
4959

50-
def get_robot_state(self): pass
60+
def get_robot_state(self):
61+
pass
5162

5263
def move_arc(self, command):
5364
"""The trajectory of ARC mode is an arc, which is determined by three points (the current point, any point and the end point on the arc)"""
5465
if len(command) != 3:
5566
raise ValueError("Invalid ARC command. Must have 3 points")
56-
67+
5768
self.send_command(f"ARC({','.join(map(str, command))})")
5869

5970
def move_jump(self, command):
6071
"""If the movement of two points is required to lift upwards by amount of height, such as sucking up, grabbing, you can choose JUMP"""
6172
if len(command) != 2:
6273
raise ValueError("Invalid JUMP command. Must have 2 points")
63-
74+
6475
self.send_command(f"JUMP({','.join(map(str, command))})")
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
from .elephant_robotics import ElephantRobotics
2-
from .mycobot import Pro600
2+
from .mycobot import Pro600

armctl/elephant_robotics/elephant_robotics.py

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
from armctl.templates import SocketController as SCT, Commands
21
import time
32

3+
from armctl.templates import Commands
4+
from armctl.templates import SocketController as SCT
5+
6+
47
class ElephantRobotics(SCT, Commands):
58
def __init__(self, ip: str, port: int):
69
super().__init__(ip, port)
@@ -10,15 +13,19 @@ def __init__(self, ip: str, port: int):
1013
(-150.00, 150.00),
1114
(-260.00, 80.00),
1215
(-168.00, 168.00),
13-
(-174.00, 174.00)
16+
(-174.00, 174.00),
1417
]
1518
self.DOF = len(self.JOINT_RANGES)
1619

1720
def connect(self):
1821
super().connect() # Socket Connection
1922

20-
assert self.send_command("power_on()") == "power_on:[ok]" # Power on the robot
21-
assert self.send_command("state_on()") == "state_on:[ok]" # Enable the system
23+
assert (
24+
self.send_command("power_on()") == "power_on:[ok]"
25+
) # Power on the robot
26+
assert (
27+
self.send_command("state_on()") == "state_on:[ok]"
28+
) # Enable the system
2229

2330
def disconnect(self):
2431
self.stop_motion() # Stop any ongoing motion
@@ -28,19 +35,22 @@ def disconnect(self):
2835

2936
def _waitforfinish(self):
3037
while True:
31-
if self.send_command("wait_command_done()", timeout=60) == "wait_command_done:0":
38+
if (
39+
self.send_command("wait_command_done()", timeout=60)
40+
== "wait_command_done:0"
41+
):
3242
break
3343
time.sleep(0.25)
3444

3545
def sleep(self, seconds):
36-
assert isinstance(seconds, (int, float)), "Seconds must be a numeric value."
46+
assert isinstance(
47+
seconds, (int, float)
48+
), "Seconds must be a numeric value."
3749
assert seconds >= 0, "Seconds must be a non-negative value."
3850
self.send_command(f"wait({seconds})")
3951
time.sleep(seconds)
4052

41-
def move_joints(self,
42-
pos:list[float],
43-
speed:int=500) -> None:
53+
def move_joints(self, pos: list[float], speed: int = 500) -> None:
4454
"""
4555
Move the robot to the specified joint positions.
4656
@@ -59,21 +69,31 @@ def move_joints(self,
5969

6070
for i, (low, high) in enumerate(self.JOINT_RANGES):
6171
if not (low <= pos[i] <= high):
62-
raise ValueError(f"Joint {i+1} angle out of range: {low} ~ {high}")
72+
raise ValueError(
73+
f"Joint {i + 1} angle out of range: {low} ~ {high}"
74+
)
6375

6476
if not (0 <= speed <= 2000):
6577
raise ValueError("Speed out of range: 0 ~ 2000")
6678

6779
command = "set_angles"
68-
response = self.send_command(f"{command}({','.join(map(str, pos))},{speed})")
69-
assert response == f"{command}:[ok]", f"Failed to move joints: {response}"
70-
71-
while any(abs(a - b) > 3 for a, b in zip(self.get_joint_positions(), pos)):
80+
response = self.send_command(
81+
f"{command}({','.join(map(str, pos))},{speed})"
82+
)
83+
assert (
84+
response == f"{command}:[ok]"
85+
), f"Failed to move joints: {response}"
86+
87+
while any(
88+
abs(a - b) > 3 for a, b in zip(self.get_joint_positions(), pos)
89+
):
7290
time.sleep(1)
7391

74-
def move_cartesian(self,
75-
pose:tuple[float,float,float,float,float,float],
76-
speed:int=500) -> None:
92+
def move_cartesian(
93+
self,
94+
pose: tuple[float, float, float, float, float, float],
95+
speed: int = 500,
96+
) -> None:
7797
"""
7898
Move the robot to the specified Cartesian coordinates.
7999
@@ -88,27 +108,45 @@ def move_cartesian(self,
88108
if not (0 <= speed <= 2000):
89109
raise ValueError("Speed out of range: 0 ~ 2000")
90110
if len(pose) != 6:
91-
raise ValueError("Robot pose must have 6 elements: [x, y, z, rx, ry, rz]")
111+
raise ValueError(
112+
"Robot pose must have 6 elements: [x, y, z, rx, ry, rz]"
113+
)
92114

93115
command = f"set_coords({','.join(map(str, pose))},{speed})"
94116

95117
assert self.send_command(command) == "set_coords:[ok]"
96118

97-
while not all(abs(a - b) <= 1 for a, b in zip(self.get_cartesian_position(), pose)):
119+
while not all(
120+
abs(a - b) <= 1 for a, b in zip(self.get_cartesian_position(), pose)
121+
):
98122
time.sleep(1)
99123

100124
def get_joint_positions(self):
101125
response = self.send_command("get_angles()")
102126
if response == "[-1.0, -2.0, -3.0, -4.0, -1.0, -1.0]":
103127
raise ValueError("Invalid joint positions response from robot")
104-
joint_positions = list(map(float, response[response.index("[")+1:response.index("]")].split(","))) # From string list to float list
128+
joint_positions = list(
129+
map(
130+
float,
131+
response[response.index("[") + 1 : response.index("]")].split(
132+
","
133+
),
134+
)
135+
) # From string list to float list
105136
return [round(x, 2) for x in joint_positions]
106137

107138
def get_cartesian_position(self):
108139
response = self.send_command("get_coords()") # [x, y, z, rx, ry, rz]
109140
if response == "[-1.0, -2.0, -3.0, -4.0, -1.0, -1.0]":
110141
raise ValueError("Invalid cartesian position response from robot")
111-
cartesian_position = list(map(float, response[response.index("[")+1:response.index("]")].split(","))) # From string list to float list
142+
cartesian_position = list(
143+
map(
144+
float,
145+
response[response.index("[") + 1 : response.index("]")].split(
146+
","
147+
),
148+
)
149+
) # From string list to float list
112150
return [round(x, 2) for x in cartesian_position]
113151

114152
def stop_motion(self):
Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
from .elephant_robotics import ElephantRobotics
22

3+
34
class Pro600(ElephantRobotics):
4-
def __init__(self, ip:str = "192.168.1.159", port:int = 5001):
5-
"""Elephant Robotics myCobot Pro600"""
6-
super().__init__(ip, port)
7-
self.HOME_POSITION = [0,-90, 90,-90,-90,0]
8-
self.JOINT_RANGES = [
9-
(-180.00, 180.00),
10-
(-270.00, 90.00),
11-
(-150.00, 150.00),
12-
(-260.00, 80.00),
13-
(-168.00, 168.00),
14-
(-174.00, 174.00)
15-
]
16-
self.DOF = len(self.JOINT_RANGES)
5+
def __init__(self, ip: str = "192.168.1.159", port: int = 5001):
6+
"""Elephant Robotics myCobot Pro600"""
7+
super().__init__(ip, port)
8+
self.HOME_POSITION = [0, -90, 90, -90, -90, 0]
9+
self.JOINT_RANGES = [
10+
(-180.00, 180.00),
11+
(-270.00, 90.00),
12+
(-150.00, 150.00),
13+
(-260.00, 80.00),
14+
(-168.00, 168.00),
15+
(-174.00, 174.00),
16+
]
17+
self.DOF = len(self.JOINT_RANGES)
1718

18-
self.__class__.__name__ = f"{self.__class__.__bases__[0].__name__} {__name__.split('.')[-1]} {self.__class__.__name__}"
19+
self.__class__.__name__ = f"{self.__class__.__bases__[0].__name__} {__name__.split('.')[-1]} {self.__class__.__name__}"
1920

20-
def home(self):
21-
"""
22-
Move the robot to the home position: `[0, -90, 90, -90, -90, 0]`.
23-
"""
24-
self.move_joints(self.HOME_POSITION, speed=750)
21+
def home(self):
22+
"""
23+
Move the robot to the home position: `[0, -90, 90, -90, -90, 0]`.
24+
"""
25+
self.move_joints(self.HOME_POSITION, speed=750)

armctl/fanuc/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .fanuc import Fanuc
1+
from .fanuc import Fanuc

0 commit comments

Comments
 (0)