dora-piper 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.4
2
+ Name: dora-piper
3
+ Version: 0.4.1
4
+ Summary: Dora Node for using Agilex piper
5
+ Author-email: Haixuan Xavier Tao <tao.xavier@outlook.com>
6
+ License: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: dora-rs>=0.3.9
10
+ Requires-Dist: piper_sdk>=0.0.8
11
+ Requires-Dist: numpy<2.0.0
12
+
13
+ # Dora Node (Experimental) to communicate with Agilex Piper SDK
14
+
15
+ This node is used to communicate with piper.
16
+
17
+ Make sure to follow both the setup script and installation script from https://github.com/agilexrobotics/piper_sdk
18
+
19
+ # To setup the arm
20
+
21
+ Make sure that the can bus is activated for both arm and leader arms are not connected.
@@ -0,0 +1,9 @@
1
+ # Dora Node (Experimental) to communicate with Agilex Piper SDK
2
+
3
+ This node is used to communicate with piper.
4
+
5
+ Make sure to follow both the setup script and installation script from https://github.com/agilexrobotics/piper_sdk
6
+
7
+ # To setup the arm
8
+
9
+ Make sure that the can bus is activated for both arm and leader arms are not connected.
@@ -0,0 +1,13 @@
1
+ """TODO: Add docstring."""
2
+
3
+ import os
4
+
5
+ # Define the path to the README file relative to the package directory
6
+ readme_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "README.md")
7
+
8
+ # Read the content of the README file
9
+ try:
10
+ with open(readme_path, encoding="utf-8") as f:
11
+ __doc__ = f.read()
12
+ except FileNotFoundError:
13
+ __doc__ = "README file not found."
@@ -0,0 +1,159 @@
1
+ """TODO: Add docstring."""
2
+
3
+ import os
4
+ import time
5
+
6
+ import numpy as np
7
+ import pyarrow as pa
8
+ from dora import Node
9
+ from piper_sdk import C_PiperInterface
10
+
11
+ TEACH_MODE = os.getenv("TEACH_MODE", "False") in ["True", "true"]
12
+
13
+
14
+ def enable_fun(piper: C_PiperInterface):
15
+ """使能机械臂并检测使能状态,尝试5s,如果使能超时则退出程序."""
16
+ enable_flag = False
17
+ # 设置超时时间(秒)
18
+ timeout = 5
19
+ # 记录进入循环前的时间
20
+ start_time = time.time()
21
+ elapsed_time_flag = False
22
+ while not (enable_flag):
23
+ elapsed_time = time.time() - start_time
24
+ print("--------------------")
25
+ enable_flag = (
26
+ piper.GetArmLowSpdInfoMsgs().motor_1.foc_status.driver_enable_status
27
+ and piper.GetArmLowSpdInfoMsgs().motor_2.foc_status.driver_enable_status
28
+ and piper.GetArmLowSpdInfoMsgs().motor_3.foc_status.driver_enable_status
29
+ and piper.GetArmLowSpdInfoMsgs().motor_4.foc_status.driver_enable_status
30
+ and piper.GetArmLowSpdInfoMsgs().motor_5.foc_status.driver_enable_status
31
+ and piper.GetArmLowSpdInfoMsgs().motor_6.foc_status.driver_enable_status
32
+ )
33
+ print("使能状态:", enable_flag)
34
+ print("--------------------")
35
+ # 检查是否超过超时时间
36
+ if elapsed_time > timeout:
37
+ print("超时....")
38
+ elapsed_time_flag = True
39
+ enable_flag = True
40
+ break
41
+ time.sleep(1)
42
+ if elapsed_time_flag:
43
+ print("程序自动使能超时,退出程序")
44
+ raise ConnectionError("程序自动使能超时,退出程序")
45
+
46
+
47
+ def main():
48
+ """TODO: Add docstring."""
49
+ elapsed_time = time.time()
50
+ can_bus = os.getenv("CAN_BUS", "")
51
+ piper = C_PiperInterface(can_bus)
52
+ piper.ConnectPort()
53
+
54
+ if not TEACH_MODE:
55
+ # piper.MotionCtrl_3(0, 0, 0, 0x00)#位置速度模式
56
+ piper.EnableArm(7)
57
+ enable_fun(piper=piper)
58
+ piper.MotionCtrl_2(0x01, 0x01, 50, 0x00)
59
+ piper.JointCtrl(0, 0, 0, 0, 0, 0)
60
+ piper.GripperCtrl(abs(0), 1000, 0x01, 0)
61
+ piper.MotionCtrl_2(0x01, 0x01, 50, 0x00)
62
+ time.sleep(5)
63
+
64
+ factor = 57324.840764 # 1000*180/3.14
65
+ node = Node()
66
+
67
+ for event in node:
68
+ if event["type"] == "INPUT":
69
+ if event["id"] == "joint_action":
70
+ if TEACH_MODE:
71
+ continue
72
+ # Do not push to many commands to fast. Limiting it to 20Hz
73
+ if time.time() - elapsed_time > 0.05:
74
+ elapsed_time = time.time()
75
+ else:
76
+ continue
77
+
78
+ position = event["value"].to_numpy()
79
+ joint_0 = round(position[0] * factor)
80
+ joint_1 = round(position[1] * factor)
81
+ joint_2 = round(position[2] * factor)
82
+ joint_3 = round(position[3] * factor)
83
+ joint_4 = round(position[4] * factor)
84
+ joint_5 = round(position[5] * factor)
85
+ joint_6 = round(position[6] * 1000 * 100)
86
+
87
+ piper.MotionCtrl_2(0x01, 0x01, 50, 0x00)
88
+ piper.JointCtrl(joint_0, joint_1, joint_2, joint_3, joint_4, joint_5)
89
+ piper.GripperCtrl(abs(joint_6), 1000, 0x01, 0)
90
+ piper.MotionCtrl_2(0x01, 0x01, 50, 0x00)
91
+
92
+ elif event["id"] == "eef_action":
93
+ if TEACH_MODE:
94
+ continue
95
+ # Do not push to many commands to fast. Limiting it to 20Hz
96
+ if time.time() - elapsed_time > 0.05:
97
+ elapsed_time = time.time()
98
+ else:
99
+ continue
100
+
101
+ position = event["value"].to_numpy()
102
+ piper.MotionCtrl_2(0x01, 0x01, 50, 0x00)
103
+ piper.EndPoseCtrl(
104
+ position[0] * 1000 * 1000,
105
+ position[1] * 1000 * 1000,
106
+ position[2] * 1000 * 1000,
107
+ position[3] * 1000 / (2 * np.pi) * 360,
108
+ position[4] * 1000 / (2 * np.pi) * 360,
109
+ position[5] * 1000 / (2 * np.pi) * 360,
110
+ )
111
+ piper.GripperCtrl(abs(position[6] * 1000 * 100), 1000, 0x01, 0)
112
+ piper.MotionCtrl_2(0x01, 0x01, 50, 0x00)
113
+
114
+ else:
115
+ joint = piper.GetArmJointMsgs()
116
+
117
+ joint_value = []
118
+ joint_value += [joint.joint_state.joint_1.real / factor]
119
+ joint_value += [joint.joint_state.joint_2.real / factor]
120
+ joint_value += [joint.joint_state.joint_3.real / factor]
121
+ joint_value += [joint.joint_state.joint_4.real / factor]
122
+ joint_value += [joint.joint_state.joint_5.real / factor]
123
+ joint_value += [joint.joint_state.joint_6.real / factor]
124
+
125
+ gripper = piper.GetArmGripperMsgs()
126
+ joint_value += [gripper.gripper_state.grippers_angle / 1000 / 100]
127
+
128
+ node.send_output("jointstate", pa.array(joint_value, type=pa.float32()))
129
+
130
+ position = piper.GetArmEndPoseMsgs()
131
+ position_value = []
132
+ position_value += [position.end_pose.X_axis * 0.001 * 0.001]
133
+ position_value += [position.end_pose.Y_axis * 0.001 * 0.001]
134
+ position_value += [position.end_pose.Z_axis * 0.001 * 0.001]
135
+ position_value += [position.end_pose.RX_axis * 0.001 / 360 * 2 * np.pi]
136
+ position_value += [position.end_pose.RY_axis * 0.001 / 360 * 2 * np.pi]
137
+ position_value += [position.end_pose.RZ_axis * 0.001 / 360 * 2 * np.pi]
138
+
139
+ node.send_output("pose", pa.array(position_value, type=pa.float32()))
140
+ node.send_output(
141
+ "gripper",
142
+ pa.array(
143
+ [gripper.gripper_state.grippers_angle / 1000 / 100],
144
+ type=pa.float32(),
145
+ ),
146
+ )
147
+
148
+ elif event["type"] == "STOP":
149
+ if not TEACH_MODE:
150
+ piper.MotionCtrl_2(0x01, 0x01, 50, 0x00)
151
+ piper.JointCtrl(0, 0, 0, 0, 0, 0)
152
+ piper.GripperCtrl(abs(0), 1000, 0x01, 0)
153
+ piper.MotionCtrl_2(0x01, 0x01, 50, 0x00)
154
+ time.sleep(5)
155
+ break
156
+
157
+
158
+ if __name__ == "__main__":
159
+ main()
@@ -0,0 +1,21 @@
1
+ Metadata-Version: 2.4
2
+ Name: dora-piper
3
+ Version: 0.4.1
4
+ Summary: Dora Node for using Agilex piper
5
+ Author-email: Haixuan Xavier Tao <tao.xavier@outlook.com>
6
+ License: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: dora-rs>=0.3.9
10
+ Requires-Dist: piper_sdk>=0.0.8
11
+ Requires-Dist: numpy<2.0.0
12
+
13
+ # Dora Node (Experimental) to communicate with Agilex Piper SDK
14
+
15
+ This node is used to communicate with piper.
16
+
17
+ Make sure to follow both the setup script and installation script from https://github.com/agilexrobotics/piper_sdk
18
+
19
+ # To setup the arm
20
+
21
+ Make sure that the can bus is activated for both arm and leader arms are not connected.
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ dora_piper/__init__.py
4
+ dora_piper/main.py
5
+ dora_piper.egg-info/PKG-INFO
6
+ dora_piper.egg-info/SOURCES.txt
7
+ dora_piper.egg-info/dependency_links.txt
8
+ dora_piper.egg-info/entry_points.txt
9
+ dora_piper.egg-info/requires.txt
10
+ dora_piper.egg-info/top_level.txt
11
+ tests/test_piper.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dora-piper = dora_piper.main:main
@@ -0,0 +1,3 @@
1
+ dora-rs>=0.3.9
2
+ piper_sdk>=0.0.8
3
+ numpy<2.0.0
@@ -0,0 +1 @@
1
+ dora_piper
@@ -0,0 +1,28 @@
1
+ [project]
2
+ name = "dora-piper"
3
+ version = "0.4.1"
4
+ authors = [{ name = "Haixuan Xavier Tao", email = "tao.xavier@outlook.com" }]
5
+ description = "Dora Node for using Agilex piper"
6
+ license = { text = "MIT" }
7
+ readme = "README.md"
8
+ requires-python = ">=3.8"
9
+
10
+ dependencies = ["dora-rs >= 0.3.9", "piper_sdk >= 0.0.8", "numpy < 2.0.0"]
11
+
12
+ [dependency-groups]
13
+ dev = ["pytest >=8.1.1", "ruff >=0.9.1"]
14
+
15
+ [project.scripts]
16
+ dora-piper = "dora_piper.main:main"
17
+
18
+ [tool.ruff.lint]
19
+ extend-select = [
20
+ "D", # pydocstyle
21
+ "UP", # Ruff's UP rule
22
+ "PERF", # Ruff's PERF rule
23
+ "RET", # Ruff's RET rule
24
+ "RSE", # Ruff's RSE rule
25
+ "NPY", # Ruff's NPY rule
26
+ "N", # Ruff's N rule
27
+ "I", # Ruff's I rule
28
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,8 @@
1
+ """TODO: Add docstring."""
2
+
3
+ def test_import_main():
4
+ """TODO: Add docstring."""
5
+ from piper_sdk import C_PiperInterface
6
+
7
+ ## Test piper installation
8
+ assert C_PiperInterface