Skip to content

Commit b56b66d

Browse files
feat(robots): Add UR config and example (#68)
* feat: add ur * feat: add ur example * chore: change home pose --------- Co-authored-by: Daniel San José Pro <42489409+danielsanjosepro@users.noreply.github.com>
1 parent 9353f1a commit b56b66d

3 files changed

Lines changed: 106 additions & 2 deletions

File tree

crisp_py/config/robots/ur.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
robot_type: "ur"

crisp_py/robot/robot_config.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,43 @@ class DynaArmConfig(RobotConfig):
291291
cartesian_impedance_controller_name: str = "crisp_cartesian_controller"
292292

293293

294+
@dataclass
295+
class URConfig(RobotConfig):
296+
"""Configuration specific to Universal Robots (UR) arms.
297+
298+
Provides default values for frame names, joint names, and home configuration
299+
specifically for UR robots.
300+
"""
301+
302+
joint_names: list = field(
303+
default_factory=lambda: [
304+
"shoulder_pan_joint",
305+
"shoulder_lift_joint",
306+
"elbow_joint",
307+
"wrist_1_joint",
308+
"wrist_2_joint",
309+
"wrist_3_joint",
310+
]
311+
)
312+
home_config: list = field(
313+
default_factory=lambda: [
314+
0,
315+
-np.pi / 2,
316+
np.pi / 2,
317+
-np.pi / 2,
318+
-np.pi / 2,
319+
0,
320+
],
321+
)
322+
base_frame: str = "base_link"
323+
target_frame: str = "tool0"
324+
325+
294326
def make_robot_config(robot_type: str, **kwargs) -> RobotConfig: # noqa: ANN003
295327
"""Factory function to create robot configuration objects.
296328
297329
Args:
298-
robot_type (str): Type of robot ('franka', 'kinova', 'iiwa', 'so101', 'dynaarm')
330+
robot_type (str): Type of robot ('franka', 'kinova', 'iiwa', 'so101', 'dynaarm', 'ur')
299331
**kwargs: Additional keyword arguments to override default configuration
300332
301333
Returns:
@@ -318,7 +350,9 @@ def make_robot_config(robot_type: str, **kwargs) -> RobotConfig: # noqa: ANN003
318350
return SO101Config(**kwargs)
319351
elif robot_type == "dynaarm":
320352
return DynaArmConfig(**kwargs)
353+
elif robot_type == "ur":
354+
return URConfig(**kwargs)
321355
else:
322356
raise ValueError(
323-
f"Unsupported robot type: {robot_type}. Supported types: franka, panda, kinova, iiwa, so101, dynaarm"
357+
f"Unsupported robot type: {robot_type}. Supported types: franka, panda, kinova, iiwa, so101, dynaarm, ur"
324358
)

examples/example_ur.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
"""Example script for using crisp_py with a UR robot. This example assumes you have the `ur_robot_driver` ROS package running and properly configured to control your UR robot."""
2+
import time
3+
import numpy as np
4+
5+
from crisp_py.robot import make_robot
6+
from crisp_py.utils.geometry import Pose
7+
8+
robot = make_robot("ur")
9+
robot.wait_until_ready()
10+
11+
#%%
12+
13+
print(f"Starting pose: {robot.end_effector_pose}")
14+
print(f"Starting joint values: {robot.joint_values}")
15+
16+
#%%
17+
18+
print("Going to home position...")
19+
robot.home() # This requires the joint_trajectory_controller to be active
20+
homing_pose = robot.end_effector_pose.copy()
21+
22+
print(f"Homing pose: {homing_pose}")
23+
24+
#%%
25+
26+
print("Switching to Cartesian Impedance Controller...")
27+
print("This will unload other controllers if necessary.")
28+
29+
# Change parameters now if needed
30+
# robot.cartesian_controller_parameters_client.set_parameters([
31+
# ("task.k_pos_x", 600.0),
32+
# ...
33+
# ])
34+
robot.controller_switcher_client.switch_controller("cartesian_impedance_controller")
35+
36+
#%%
37+
38+
# Figure eight
39+
input("Press Enter to start figure eight trajectory...")
40+
41+
duration = 6.0
42+
start_time = time.time()
43+
rate = 20.0
44+
45+
while time.time() - start_time < duration:
46+
t = time.time() - start_time
47+
48+
# Create figure eight trajectory in the XZ plane
49+
x = 0.1 * np.sin(2 * np.pi * t / duration)
50+
y = 0.0
51+
z = 0.1 * np.sin(4 * np.pi * t / duration)
52+
53+
target_pose = Pose(
54+
position=homing_pose.position + np.array([x, y, z]),
55+
orientation=homing_pose.orientation,
56+
)
57+
58+
robot.set_target(pose=target_pose)
59+
60+
time.sleep(1.0 / rate)
61+
62+
63+
# %%
64+
65+
print(f"Shutting down connection in 4 seconds... (robot will stay in place).")
66+
time.sleep(4.0)
67+
68+
robot.shutdown()
69+

0 commit comments

Comments
 (0)