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.
@@ -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("连接断开",code, close_msg)
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
- setup.py
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.egg-info/zip-safe
11
+ scripts/carm
12
+ scripts/carm_ros2
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ carm = carm:main
3
+ carm_ros2 = carm:ros2_main
@@ -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
+
@@ -1,7 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: carm
3
- Version: 0.0.20250807
4
- Summary: Python interface for cvte arm.
5
- Author: Yong Zhao
6
- Author-email: zhaoyong11933@cvte.com
7
- Requires-Dist: websocket-client
@@ -1,7 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: carm
3
- Version: 0.0.20250807
4
- Summary: Python interface for cvte arm.
5
- Author: Yong Zhao
6
- Author-email: zhaoyong11933@cvte.com
7
- Requires-Dist: websocket-client
@@ -1 +0,0 @@
1
-
@@ -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