carm 0.0.20250807__tar.gz → 0.0.20250815__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.
- carm-0.0.20250815/PKG-INFO +10 -0
- carm-0.0.20250815/README.md +31 -0
- {carm-0.0.20250807 → carm-0.0.20250815}/carm/carm.py +5 -5
- carm-0.0.20250815/carm.egg-info/PKG-INFO +10 -0
- {carm-0.0.20250807 → carm-0.0.20250815}/carm.egg-info/SOURCES.txt +5 -2
- carm-0.0.20250815/carm.egg-info/entry_points.txt +3 -0
- carm-0.0.20250815/pyproject.toml +31 -0
- carm-0.0.20250815/scripts/carm +106 -0
- carm-0.0.20250815/scripts/carm_ros2 +94 -0
- carm-0.0.20250807/PKG-INFO +0 -7
- carm-0.0.20250807/carm.egg-info/PKG-INFO +0 -7
- carm-0.0.20250807/carm.egg-info/zip-safe +0 -1
- carm-0.0.20250807/setup.py +0 -19
- {carm-0.0.20250807 → carm-0.0.20250815}/carm/__init__.py +0 -0
- {carm-0.0.20250807 → carm-0.0.20250815}/carm.egg-info/dependency_links.txt +0 -0
- {carm-0.0.20250807 → carm-0.0.20250815}/carm.egg-info/requires.txt +0 -0
- {carm-0.0.20250807 → carm-0.0.20250815}/carm.egg-info/top_level.txt +0 -0
- {carm-0.0.20250807 → carm-0.0.20250815}/setup.cfg +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: carm
|
|
3
|
+
Version: 0.0.20250815
|
|
4
|
+
Summary: Python interface for cvte arm.
|
|
5
|
+
Author-email: Yong Zhao <zhaoyong11933@cvte.com>
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
8
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
9
|
+
Requires-Python: >=3.6
|
|
10
|
+
Requires-Dist: websocket-client
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# pycarm
|
|
2
|
+
|
|
3
|
+
Python interface for cvte arm.
|
|
4
|
+
|
|
5
|
+
# Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
pip install carm
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
# Usage
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
import carm
|
|
15
|
+
|
|
16
|
+
arm = carm.Carm("ws://localhost:8090")
|
|
17
|
+
|
|
18
|
+
print("version:",carm.version)
|
|
19
|
+
print("limits:", carm.limit)
|
|
20
|
+
print("state:", carm.state)
|
|
21
|
+
|
|
22
|
+
carm.track_joint(carm.joint_pos)
|
|
23
|
+
|
|
24
|
+
carm.move_joint(carm.joint_pos)
|
|
25
|
+
|
|
26
|
+
carm.track_pose(carm.cart_pose)
|
|
27
|
+
|
|
28
|
+
carm.move_pose(carm.cart_pose)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
|
|
@@ -2,6 +2,7 @@ import websocket
|
|
|
2
2
|
import threading
|
|
3
3
|
import json
|
|
4
4
|
import uuid
|
|
5
|
+
import time
|
|
5
6
|
|
|
6
7
|
class Carm:
|
|
7
8
|
def __init__(self, addr = "ws://100.84.147.120:8090"):
|
|
@@ -42,6 +43,8 @@ class Carm:
|
|
|
42
43
|
"type":"version"})
|
|
43
44
|
|
|
44
45
|
def set_ready(self):
|
|
46
|
+
while self.state is None:
|
|
47
|
+
time.sleep(0.1)
|
|
45
48
|
arm = self.state["arm"][0]
|
|
46
49
|
if arm["fsm_state"] == "POSITION" or arm["fsm_state"] == "MIT":
|
|
47
50
|
return True
|
|
@@ -261,10 +264,10 @@ class Carm:
|
|
|
261
264
|
|
|
262
265
|
def on_open(self, ws):
|
|
263
266
|
self.open_ready.set()
|
|
264
|
-
print("
|
|
267
|
+
print("Connected successfully.")
|
|
265
268
|
|
|
266
269
|
def on_close(self, ws, code, close_msg):
|
|
267
|
-
print("
|
|
270
|
+
print("Disconnected, please check your --addr",code, close_msg)
|
|
268
271
|
|
|
269
272
|
def on_message(self, ws, message):
|
|
270
273
|
msg = json.loads(message)
|
|
@@ -289,9 +292,6 @@ class Carm:
|
|
|
289
292
|
|
|
290
293
|
if __name__ == "__main__":
|
|
291
294
|
carm = Carm()
|
|
292
|
-
print("version:",carm.version)
|
|
293
|
-
print("limits:", carm.limit)
|
|
294
|
-
print("state:", carm.state)
|
|
295
295
|
|
|
296
296
|
carm.track_joint(carm.joint_pos)
|
|
297
297
|
print(1)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: carm
|
|
3
|
+
Version: 0.0.20250815
|
|
4
|
+
Summary: Python interface for cvte arm.
|
|
5
|
+
Author-email: Yong Zhao <zhaoyong11933@cvte.com>
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
8
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
9
|
+
Requires-Python: >=3.6
|
|
10
|
+
Requires-Dist: websocket-client
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
2
3
|
carm/__init__.py
|
|
3
4
|
carm/carm.py
|
|
4
5
|
carm.egg-info/PKG-INFO
|
|
5
6
|
carm.egg-info/SOURCES.txt
|
|
6
7
|
carm.egg-info/dependency_links.txt
|
|
8
|
+
carm.egg-info/entry_points.txt
|
|
7
9
|
carm.egg-info/requires.txt
|
|
8
10
|
carm.egg-info/top_level.txt
|
|
9
|
-
carm
|
|
11
|
+
scripts/carm
|
|
12
|
+
scripts/carm_ros2
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=42"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "carm"
|
|
7
|
+
version = "0.0.20250815"
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "Yong Zhao", email = "zhaoyong11933@cvte.com"},
|
|
10
|
+
]
|
|
11
|
+
description = "Python interface for cvte arm."
|
|
12
|
+
requires-python = ">=3.6"
|
|
13
|
+
dependencies = ["websocket-client"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
17
|
+
"Programming Language :: Python :: Implementation :: PyPy",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
carm = "carm:main"
|
|
22
|
+
carm_ros2 = "carm:ros2_main"
|
|
23
|
+
|
|
24
|
+
[tool.setuptools]
|
|
25
|
+
packages = ["carm"]
|
|
26
|
+
|
|
27
|
+
[tool.setuptools.package-data]
|
|
28
|
+
carm = [
|
|
29
|
+
"__init__.py",
|
|
30
|
+
"carm.py",
|
|
31
|
+
]
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
import time
|
|
3
|
+
import os
|
|
4
|
+
import argparse
|
|
5
|
+
import svar
|
|
6
|
+
import numpy as np
|
|
7
|
+
import carm
|
|
8
|
+
|
|
9
|
+
messenger = svar.load("svar_messenger").messenger
|
|
10
|
+
|
|
11
|
+
class ArmDriver:
|
|
12
|
+
def __init__(self,args):
|
|
13
|
+
self.args = args
|
|
14
|
+
|
|
15
|
+
self.arm = carm.Carm(args.addr)
|
|
16
|
+
if args.mit:
|
|
17
|
+
self.arm.set_control_mode(3)
|
|
18
|
+
else:
|
|
19
|
+
self.arm.set_control_mode(1)
|
|
20
|
+
|
|
21
|
+
self.pub_joint = messenger.advertise(args.joint_topic, 0)
|
|
22
|
+
self.pub_end = messenger.advertise(args.end_topic, 0)
|
|
23
|
+
|
|
24
|
+
self.sub_joint = messenger.subscribe(args.joint_cmd_topic, 0, lambda msg:self.joint_callback(msg))
|
|
25
|
+
self.sub_end = messenger.subscribe(args.end_cmd_topic, 0, lambda msg:self.end_callback(msg))
|
|
26
|
+
|
|
27
|
+
def end_callback(self, msg):
|
|
28
|
+
position = np.frombuffer(msg["position"],dtype=np.float64).tolist()
|
|
29
|
+
self.arm.track_pose(position)
|
|
30
|
+
|
|
31
|
+
def joint_callback(self, msg):
|
|
32
|
+
position = np.frombuffer(msg["position"],dtype=np.float64).tolist()
|
|
33
|
+
self.arm.track_joint(position)
|
|
34
|
+
|
|
35
|
+
def loop(self):
|
|
36
|
+
while True:
|
|
37
|
+
stamp = time.time()
|
|
38
|
+
sec = int(stamp )
|
|
39
|
+
nanosec = int((stamp - sec) * 1e9)
|
|
40
|
+
header = {"stamp": {"sec": sec, "nanosec": nanosec},"frame_id": "base_link"}
|
|
41
|
+
|
|
42
|
+
end_msg = {"header": header, "position": self.arm.cart_pose + [self.arm.gripper_state["gripper_pos"],]}
|
|
43
|
+
joints_msg = {"header": header, "position": self.arm.joint_pos + [self.arm.gripper_state["gripper_pos"],]}
|
|
44
|
+
|
|
45
|
+
self.pub_joint.publish(joints_msg)
|
|
46
|
+
self.pub_end.publish(end_msg)
|
|
47
|
+
|
|
48
|
+
time.sleep(0.005)
|
|
49
|
+
|
|
50
|
+
def send_cmd(args):
|
|
51
|
+
arm = carm.Carm(args.addr,mit=args.mit)
|
|
52
|
+
|
|
53
|
+
cmd = args.cmd
|
|
54
|
+
|
|
55
|
+
if cmd == "disable":
|
|
56
|
+
arm.set_servo_enable(False)
|
|
57
|
+
if cmd == "remote":
|
|
58
|
+
arm.set_control_mode(3)
|
|
59
|
+
|
|
60
|
+
def driver_main(args):
|
|
61
|
+
print("Starting driver mode...")
|
|
62
|
+
|
|
63
|
+
driver = ArmDriver(args)
|
|
64
|
+
|
|
65
|
+
ros2 = svar.load(args.dds)
|
|
66
|
+
transfer = ros2.Transfer({"node": "carm_driver" + args.device,
|
|
67
|
+
"publishers":[[args.joint_topic, "sensor_msgs/msg/JointState",10],
|
|
68
|
+
[args.end_topic, "sensor_msgs/msg/JointState",10],
|
|
69
|
+
],
|
|
70
|
+
"subscriptions":[[args.joint_cmd_topic, "sensor_msgs/msg/JointState",10],
|
|
71
|
+
[args.end_cmd_topic, "sensor_msgs/msg/JointState",10]]})
|
|
72
|
+
|
|
73
|
+
driver.loop()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# 测试代码
|
|
78
|
+
if __name__ == "__main__":
|
|
79
|
+
parser = argparse.ArgumentParser()
|
|
80
|
+
parser.add_argument("--addr", type=str, default="ws://localhost:8090", help="Device address, including ip and port")
|
|
81
|
+
parser.add_argument("--cmd", type=str, default="", help="Send command instead of start driver, support enable,disable,remote")
|
|
82
|
+
parser.add_argument("--device", type=str, default="carm", help="device name, used as topic prefix")
|
|
83
|
+
parser.add_argument("--dds", type=str, default="svar_messenger_ros2", help="the dds plugin, default is ros2, options: svar_zbus, svar_lcm")
|
|
84
|
+
parser.add_argument("--mit", action="store_true", help="Enable mit mode")
|
|
85
|
+
parser.add_argument("--joint_topic", type=str, default="", help="the joints status topic")
|
|
86
|
+
parser.add_argument("--end_topic", type=str, default="", help="the joints status topic")
|
|
87
|
+
parser.add_argument("--joint_cmd_topic", type=str, default="", help="the joints cmd topic")
|
|
88
|
+
parser.add_argument("--end_cmd_topic", type=str, default="", help="the end cmd topic")
|
|
89
|
+
|
|
90
|
+
args = parser.parse_args()
|
|
91
|
+
|
|
92
|
+
if args.joint_topic == "":
|
|
93
|
+
args.joint_topic = "/"+args.device + "/joints"
|
|
94
|
+
if args.end_topic == "":
|
|
95
|
+
args.end_topic = "/"+args.device + "/end"
|
|
96
|
+
if args.joint_cmd_topic == "":
|
|
97
|
+
args.joint_cmd_topic = "/"+args.device + "/joints_cmd"
|
|
98
|
+
if args.end_cmd_topic == "":
|
|
99
|
+
args.end_cmd_topic = "/"+args.device + "/end_cmd"
|
|
100
|
+
|
|
101
|
+
if args.cmd == "":
|
|
102
|
+
driver_main(args)
|
|
103
|
+
else:
|
|
104
|
+
send_cmd(args)
|
|
105
|
+
|
|
106
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
import rclpy
|
|
3
|
+
from rclpy.node import Node
|
|
4
|
+
import time
|
|
5
|
+
import argparse
|
|
6
|
+
|
|
7
|
+
from std_msgs.msg import String, Bool, Int16MultiArray, MultiArrayLayout, MultiArrayDimension, Int8
|
|
8
|
+
from geometry_msgs.msg import Point, Pose, PoseArray
|
|
9
|
+
from sensor_msgs.msg import JointState
|
|
10
|
+
from example_interfaces.srv import AddTwoInts
|
|
11
|
+
import carm
|
|
12
|
+
import threading
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
class ArmDriver(Node):
|
|
16
|
+
def __init__(self,args):
|
|
17
|
+
super().__init__('carm_'+args.device)
|
|
18
|
+
self.args = args
|
|
19
|
+
|
|
20
|
+
self.arm = carm.Carm(args.addr)
|
|
21
|
+
if args.mit:
|
|
22
|
+
self.arm.set_control_mode(3)
|
|
23
|
+
else:
|
|
24
|
+
self.arm.set_control_mode(1)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
print("version:",self.arm.version)
|
|
28
|
+
print("limits:", self.arm.limit)
|
|
29
|
+
print("state:", self.arm.state)
|
|
30
|
+
|
|
31
|
+
self.pub_joint = self.create_publisher(JointState, args.joint_topic, 10)
|
|
32
|
+
self.pub_end = self.create_publisher(JointState, args.end_topic, 10)
|
|
33
|
+
|
|
34
|
+
self.sub_joint = self.create_subscription(JointState, args.joint_cmd_topic, self.joint_callback, 10)
|
|
35
|
+
self.sub_end = self.create_subscription(JointState, args.end_cmd_topic, self.end_callback, 10)
|
|
36
|
+
|
|
37
|
+
self.worker = threading.Thread(target=self.loop).start()
|
|
38
|
+
|
|
39
|
+
def end_callback(self, msg):
|
|
40
|
+
self.arm.track_pose(list(msg.position))
|
|
41
|
+
|
|
42
|
+
def joint_callback(self, msg):
|
|
43
|
+
self.arm.track_joint(list(msg.position))
|
|
44
|
+
|
|
45
|
+
def loop(self):
|
|
46
|
+
while True:
|
|
47
|
+
joint_msg = JointState() # list of string
|
|
48
|
+
joint_msg.header.stamp = self.get_clock().now().to_msg()
|
|
49
|
+
joint_msg.position = self.arm.joint_pos
|
|
50
|
+
joint_msg.velocity = self.arm.joint_vel
|
|
51
|
+
joint_msg.effort = self.arm.joint_tau
|
|
52
|
+
joint_msg.position.append(self.arm.gripper_state["gripper_pos"])
|
|
53
|
+
self.pub_joint.publish(joint_msg)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
end_msg = JointState() # list of string
|
|
57
|
+
end_msg.header.stamp = self.get_clock().now().to_msg()
|
|
58
|
+
end_msg.position = np.array(self.arm.cart_pose).tolist()
|
|
59
|
+
end_msg.position.append(self.arm.gripper_state["gripper_pos"])
|
|
60
|
+
self.pub_end.publish(end_msg)
|
|
61
|
+
|
|
62
|
+
time.sleep(0.005)
|
|
63
|
+
|
|
64
|
+
# 测试代码
|
|
65
|
+
if __name__ == "__main__":
|
|
66
|
+
parser = argparse.ArgumentParser()
|
|
67
|
+
parser.add_argument("--addr", type=str, default="ws://localhost:8090", help="Device address, including ip and port")
|
|
68
|
+
parser.add_argument("--device", type=str, default="carm", help="device name, used as topic prefix")
|
|
69
|
+
parser.add_argument("--dds", type=str, default="svar_messenger_ros2", help="the dds plugin, default is ros2, options: svar_zbus, svar_lcm")
|
|
70
|
+
parser.add_argument("--mit", action="store_true", help="Enable mit mode")
|
|
71
|
+
parser.add_argument("--joint_topic", type=str, default="", help="the joints status topic")
|
|
72
|
+
parser.add_argument("--end_topic", type=str, default="", help="the joints status topic")
|
|
73
|
+
parser.add_argument("--joint_cmd_topic", type=str, default="", help="the joints cmd topic")
|
|
74
|
+
parser.add_argument("--end_cmd_topic", type=str, default="", help="the end cmd topic")
|
|
75
|
+
|
|
76
|
+
args = parser.parse_args()
|
|
77
|
+
|
|
78
|
+
if args.joint_topic == "":
|
|
79
|
+
args.joint_topic = "/"+args.device + "/joints"
|
|
80
|
+
if args.end_topic == "":
|
|
81
|
+
args.end_topic = "/"+args.device + "/end"
|
|
82
|
+
if args.joint_cmd_topic == "":
|
|
83
|
+
args.joint_cmd_topic = "/"+args.device + "/joints_cmd"
|
|
84
|
+
if args.end_cmd_topic == "":
|
|
85
|
+
args.end_cmd_topic = "/"+args.device + "/end_cmd"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
rclpy.init(args=None)
|
|
89
|
+
node = ArmDriver(args)
|
|
90
|
+
rclpy.spin(node)
|
|
91
|
+
node.destroy_node()
|
|
92
|
+
rclpy.shutdown()
|
|
93
|
+
|
|
94
|
+
|
carm-0.0.20250807/PKG-INFO
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
carm-0.0.20250807/setup.py
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
from setuptools import setup, find_packages
|
|
2
|
-
|
|
3
|
-
setup(
|
|
4
|
-
name="carm",
|
|
5
|
-
version="0.0.20250807",
|
|
6
|
-
packages=find_packages(),
|
|
7
|
-
package_data={
|
|
8
|
-
"carm": [
|
|
9
|
-
"__init__.py",
|
|
10
|
-
"carm.py",
|
|
11
|
-
],
|
|
12
|
-
},
|
|
13
|
-
include_package_data=True,
|
|
14
|
-
install_requires=["websocket-client"],
|
|
15
|
-
zip_safe=True,
|
|
16
|
-
author='Yong Zhao',
|
|
17
|
-
author_email='zhaoyong11933@cvte.com',
|
|
18
|
-
description="Python interface for cvte arm.",
|
|
19
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|