pymycobot 3.5.0.dev4__tar.gz → 3.5.0.dev6__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.
Files changed (51) hide show
  1. {pymycobot-3.5.0.dev4/pymycobot.egg-info → pymycobot-3.5.0.dev6}/PKG-INFO +1 -1
  2. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/__init__.py +3 -3
  3. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/common.py +6 -0
  4. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/error.py +4 -4
  5. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mercury_api.py +71 -31
  6. pymycobot-3.5.0.dev6/pymycobot/mercurychassis.py +325 -0
  7. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6/pymycobot.egg-info}/PKG-INFO +1 -1
  8. pymycobot-3.5.0.dev4/pymycobot/mercurychassis.py +0 -170
  9. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/LICENSE +0 -0
  10. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/MANIFEST.in +0 -0
  11. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/README.md +0 -0
  12. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/Interface.py +0 -0
  13. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/bluet.py +0 -0
  14. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/elephantrobot.py +0 -0
  15. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/generate.py +0 -0
  16. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/genre.py +0 -0
  17. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/log.py +0 -0
  18. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mecharm.py +0 -0
  19. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mecharmsocket.py +0 -0
  20. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mercury.py +0 -0
  21. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mercurysocket.py +0 -0
  22. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/myagv.py +0 -0
  23. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/myarm.py +0 -0
  24. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/myarm_api.py +0 -0
  25. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/myarmc.py +0 -0
  26. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/myarmm.py +0 -0
  27. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/myarmsocket.py +0 -0
  28. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mybuddy.py +0 -0
  29. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mybuddybluetooth.py +0 -0
  30. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mybuddyemoticon.py +0 -0
  31. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mybuddysocket.py +0 -0
  32. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mycobot.py +0 -0
  33. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mycobotpro630.py +0 -0
  34. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mycobotsocket.py +0 -0
  35. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mypalletizer.py +0 -0
  36. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/mypalletizersocket.py +0 -0
  37. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/progripper.py +0 -0
  38. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/public.py +0 -0
  39. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/ultraArm.py +0 -0
  40. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot/utils.py +0 -0
  41. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot.egg-info/SOURCES.txt +0 -0
  42. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot.egg-info/dependency_links.txt +0 -0
  43. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot.egg-info/requires.txt +0 -0
  44. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/pymycobot.egg-info/top_level.txt +0 -0
  45. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/requirements.txt +0 -0
  46. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/setup.cfg +0 -0
  47. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/setup.py +0 -0
  48. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/tests/test_api.py +0 -0
  49. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/tests/test_generator.py +0 -0
  50. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/tests/test_socket.py +0 -0
  51. {pymycobot-3.5.0.dev4 → pymycobot-3.5.0.dev6}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pymycobot
3
- Version: 3.5.0.dev4
3
+ Version: 3.5.0.dev6
4
4
  Summary: Python API for serial communication of MyCobot.
5
5
  Home-page: https://github.com/elephantrobotics/pymycobot
6
6
  Author: Elephantrobotics
@@ -23,7 +23,7 @@ from pymycobot.elephantrobot import ElephantRobot
23
23
  from pymycobot.mercury import Mercury
24
24
  from pymycobot.myagv import MyAgv
25
25
  from pymycobot.mecharmsocket import MechArmSocket
26
- from pymycobot.mercurychassis import MercuryChassis
26
+ from pymycobot.mercurychassis import ChassisControl
27
27
  from pymycobot.mercurysocket import MercurySocket
28
28
  from pymycobot.mycobotpro630 import Phoenix
29
29
  from pymycobot.myarmm import MyArmM
@@ -49,7 +49,7 @@ __all__ = [
49
49
  "MyAgv",
50
50
  "MechArmSocket",
51
51
  "MyArmSocket",
52
- "MercuryChassis",
52
+ "ChassisControl",
53
53
  "MercurySocket",
54
54
  "Phoenix",
55
55
  "MyArmM",
@@ -61,7 +61,7 @@ if sys.platform == "linux":
61
61
  from pymycobot.mybuddyemoticon import MyBuddyEmoticon
62
62
  __all__.append("MyBuddyEmoticon")
63
63
 
64
- __version__ = "3.5.0dev4"
64
+ __version__ = "3.5.0dev6"
65
65
  __author__ = "Elephantrobotics"
66
66
  __email__ = "weiquan.xu@elephantrobotics.com"
67
67
  __git_url__ = "https://github.com/elephantrobotics/pymycobot"
@@ -22,9 +22,15 @@ class ProtocolCode(object):
22
22
  CLEAR_ERROR_INFO = 0x08
23
23
  GET_ATOM_VERSION = 0x09
24
24
 
25
+ CLEAR_ZERO_POS = 0x0A
26
+ SET_SERVO_CW = 0x0B
27
+ GET_SERVO_CW = 0x0C
28
+ CLEAR_WAIST_QUEUE = 0x0D
29
+
25
30
  SetHTSGripperTorque = 0x35
26
31
  GetHTSGripperTorque = 0x36
27
32
  GetGripperProtectCurrent = 0x37
33
+ JOG_INCREMENT_BASE_COORD = 0x37
28
34
  InitGripper = 0x38
29
35
  SetGripperProtectCurrent = 0x39
30
36
 
@@ -238,15 +238,15 @@ def calibration_parameters(**kwargs):
238
238
  robot_limit = {
239
239
  "Mercury": {
240
240
  "id": [1, 2, 3, 4, 5, 6, 11, 12, 13],
241
- "angles_min": [-165, -55, -180, -165, -20, -180, -60, -140, -120],
242
- "angles_max": [165, 95, 5, 165, 273, 180, 0, 190, 120],
241
+ "angles_min": [-165, -55, -173, -165, -20, -180, -60, -138, -118],
242
+ "angles_max": [165, 95, 5, 165, 265, 180, 0, 188, 118],
243
243
  "coords_min": [-441.37, -441.37, -206.52, -180, -180, -180],
244
244
  "coords_max": [441.37, 441.37, 628.02, 180, 180, 180]
245
245
  },
246
246
  "MercurySocket": {
247
247
  "id": [1, 2, 3, 4, 5, 6, 11, 12, 13],
248
- "angles_min": [-165, -55, -180, -165, -20, -180, -60, -140, -120],
249
- "angles_max": [165, 95, 5, 165, 273, 180, 0, 190, 120],
248
+ "angles_min": [-165, -55, -173, -165, -20, -180, -60, -138, -118],
249
+ "angles_max": [165, 95, 5, 165, 265, 180, 0, 188, 118],
250
250
  "coords_min": [-441.37, -441.37, -206.52, -180, -180, -180],
251
251
  "coords_max": [441.37, 441.37, 628.02, 180, 180, 180]
252
252
  },
@@ -61,21 +61,21 @@ class MercuryCommandGenerator(CommandGenerator):
61
61
  elif genre in [ProtocolCode.POWER_OFF, ProtocolCode.RELEASE_ALL_SERVOS, ProtocolCode.FOCUS_ALL_SERVOS,
62
62
  ProtocolCode.RELEASE_SERVO, ProtocolCode.FOCUS_SERVO, ProtocolCode.STOP]:
63
63
  wait_time = 3
64
- elif genre in [
65
- ProtocolCode.SEND_ANGLE,
66
- ProtocolCode.SEND_ANGLES,
67
- ProtocolCode.SEND_COORD,
68
- ProtocolCode.SEND_COORDS,
69
- ProtocolCode.JOG_ANGLE,
70
- ProtocolCode.JOG_COORD,
71
- ProtocolCode.JOG_INCREMENT,
72
- ProtocolCode.JOG_INCREMENT_COORD,
73
- ProtocolCode.COBOTX_SET_SOLUTION_ANGLES,
74
- ProtocolCode.MERCURY_SET_BASE_COORDS,
75
- ProtocolCode.MERCURY_JOG_BASE_COORD,
76
- ProtocolCode.MERCURY_SET_BASE_COORD]:
77
- wait_time = 300
78
- is_in_position = True
64
+ # elif genre in [
65
+ # ProtocolCode.SEND_ANGLE,
66
+ # ProtocolCode.SEND_ANGLES,
67
+ # ProtocolCode.SEND_COORD,
68
+ # ProtocolCode.SEND_COORDS,
69
+ # ProtocolCode.JOG_ANGLE,
70
+ # ProtocolCode.JOG_COORD,
71
+ # ProtocolCode.JOG_INCREMENT,
72
+ # ProtocolCode.JOG_INCREMENT_COORD,
73
+ # ProtocolCode.COBOTX_SET_SOLUTION_ANGLES,
74
+ # ProtocolCode.MERCURY_SET_BASE_COORDS,
75
+ # ProtocolCode.MERCURY_JOG_BASE_COORD,
76
+ # ProtocolCode.MERCURY_SET_BASE_COORD]:
77
+ # wait_time = 300
78
+ # is_in_position = True
79
79
  need_break = False
80
80
  data = None
81
81
  while True and time.time() - t < wait_time:
@@ -181,18 +181,18 @@ class MercuryCommandGenerator(CommandGenerator):
181
181
  one = valid_data[i : i + 2]
182
182
  res.append(self._decode_int16(one))
183
183
  i+=2
184
- # elif data_len == 38:
185
- # # right arm get_robot_status
186
- # i = 0
187
- # res = []
188
- # while i < data_len:
189
- # if i < 10 or i >= 30:
190
- # res.append(valid_data[i])
191
- # i+=1
192
- # elif i < 38:
193
- # one = valid_data[i : i + 2]
194
- # res.append(self._decode_int16(one))
195
- # i+=2
184
+ elif data_len == 30:
185
+ # right arm get_robot_status
186
+ i = 0
187
+ res = []
188
+ while i < data_len:
189
+ if i < 8 or i >= 24:
190
+ res.append(valid_data[i])
191
+ i+=1
192
+ elif i < 23:
193
+ one = valid_data[i : i + 2]
194
+ res.append(self._decode_int16(one))
195
+ i+=2
196
196
  elif data_len == 48:
197
197
  # get_pos_over
198
198
  for i in range(0, data_len, 8):
@@ -297,7 +297,7 @@ class MercuryCommandGenerator(CommandGenerator):
297
297
  if res[i] == 1:
298
298
  r.append(i)
299
299
  return r
300
- elif genre in [ProtocolCode.COBOTX_GET_ANGLE, ProtocolCode.COBOTX_GET_SOLUTION_ANGLES, ProtocolCode.MERCURY_GET_POS_OVER_SHOOT]:
300
+ elif genre in [ProtocolCode.COBOTX_GET_ANGLE, ProtocolCode.COBOTX_GET_SOLUTION_ANGLES, ProtocolCode.MERCURY_GET_POS_OVER_SHOOT, ProtocolCode.GET_SERVO_CW]:
301
301
  return self._int2angle(res[0])
302
302
  elif genre == ProtocolCode.MERCURY_ROBOT_STATUS:
303
303
  if len(res) == 23:
@@ -437,8 +437,9 @@ class MercuryCommandGenerator(CommandGenerator):
437
437
  for d in datas:
438
438
  command_log += hex(d)[2:] + " "
439
439
  self.log.debug("_read : {}".format(command_log))
440
- with self.lock:
441
- self.read_command.append(res)
440
+ if res != []:
441
+ with self.lock:
442
+ self.read_command.append(res)
442
443
  # return datas
443
444
 
444
445
  def set_solution_angles(self, angle, speed):
@@ -1022,4 +1023,43 @@ class MercuryCommandGenerator(CommandGenerator):
1022
1023
  5 : Drag teaching sampling period
1023
1024
  value (int): Filter length, range is 1 ~ 100
1024
1025
  """
1025
- return self._mesg(ProtocolCode.SET_FILTER_LEN, rank, value)
1026
+ return self._mesg(ProtocolCode.SET_FILTER_LEN, rank, value)
1027
+
1028
+ def clear_zero_pos(self):
1029
+ return self._mesg(ProtocolCode.CLEAR_ZERO_POS)
1030
+
1031
+ def set_servo_cw(self, joint_id, err_angle):
1032
+ """Set the joint in-place feedback error angle
1033
+
1034
+ Args:
1035
+ joint_id (int): Joint ID, 11 or 12.
1036
+ err_angle (float): Error range is 0 ~ 5.
1037
+ """
1038
+ return self._mesg(ProtocolCode.SET_SERVO_CW, joint_id, [self._angle2int(err_angle)])
1039
+
1040
+ def get_servo_cw(self, joint_id):
1041
+ """Get the joint in-place feedback error angle
1042
+
1043
+ Args:
1044
+ joint_id (int): Joint ID, 11 or 12.
1045
+
1046
+ Returns:
1047
+ float: Error angle, range is 0 ~ 5.
1048
+ """
1049
+ return self._mesg(ProtocolCode.GET_SERVO_CW, joint_id, has_reply=True)
1050
+
1051
+ def clearWaistQueue(self):
1052
+ """Clear the cache points of the three motors in the torso
1053
+ """
1054
+ return self._mesg(ProtocolCode.CLEAR_WAIST_QUEUE)
1055
+
1056
+ def jog_increment_base_coord(self, axis, increment, speed):
1057
+ """Base coordinate stepping control
1058
+
1059
+ Args:
1060
+ axis (int): axis id, range 1 ~ 6 corresponds to [x,y,z,rx,ry,rz]
1061
+ increment (float): Incremental value
1062
+ speed (int): speed
1063
+ """
1064
+ return self._mesg(ProtocolCode.JOG_INCREMENT_BASE_COORD, axis, [self._angle2int(increment)], speed)
1065
+
@@ -0,0 +1,325 @@
1
+ #!/usr/bin/python
2
+ # -*- coding:utf-8 -*-
3
+ # @File : mercurychassis_api.py
4
+ # @Author : Wang Weijian
5
+ # @Time : 2024/05/31 15:19:47
6
+ # @function: the script is used to do something
7
+ # @version : V1
8
+ import traceback
9
+ from datetime import datetime
10
+ import time
11
+ import serial
12
+
13
+
14
+ class ProtocolCode(object):
15
+ # send data
16
+ header = 0x7B
17
+ footer = 0x7D
18
+ # Ultrasonic data
19
+ ultrasound_header = 0xFA
20
+ ultrasound_footer = 0xFC
21
+
22
+
23
+ class ChassisControl:
24
+
25
+ def __init__(self, port="/dev/wheeltec_controller", baudrate=115200, timeout=0.1, debug=False):
26
+ """
27
+ Args:
28
+ port : port string
29
+ baudrate : baud rate string, default '115200'
30
+ timeout : default 0.1
31
+ debug : whether show debug info, default: False
32
+ """
33
+
34
+ self._serial_port = serial.Serial()
35
+ self._serial_port.port = port
36
+ self._serial_port.baudrate = baudrate
37
+ self._serial_port.timeout = timeout
38
+ self._serial_port.rts = True
39
+ self._serial_port.dtr = True
40
+ self._serial_port.open()
41
+ self.debug = debug
42
+ self.Send_Data = [0] * 11
43
+ time.sleep(0.2)
44
+
45
+ def _write(self):
46
+ pass
47
+
48
+ def _read(self):
49
+ data = b""
50
+ t = time.time()
51
+ time.sleep(0.1)
52
+ if self._serial_port.inWaiting() > 0:
53
+ data = self._serial_port.read(self._serial_port.inWaiting())
54
+ return data
55
+
56
+ def _debug(self, data):
57
+ """whether show info."""
58
+ hex_data = " ".join(f"{value:02X}" for value in data)
59
+ current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
60
+ if self.debug:
61
+ print(f"\n***** Debug Info *****\n{current_time} send command: {hex_data}")
62
+
63
+ def close(self):
64
+ self._serial_port.close()
65
+
66
+ def open(self):
67
+ self._serial_port.open()
68
+
69
+ def _request(self, flag=""):
70
+ """
71
+ Read Data
72
+ :param flag: Data type parameter variable
73
+ :return:
74
+ """
75
+ receive_all_data = self._read()
76
+ receive_all_data = [byte for byte in receive_all_data]
77
+ return_data = ''
78
+ if flag == "voltage":
79
+ receive_data = self._extract_frame(receive_all_data, ProtocolCode.header, ProtocolCode.footer)
80
+ # print(receive_data, len(receive_data))
81
+ self._debug(receive_data)
82
+ transition_16 = 0
83
+ transition_16 |= receive_data[20] << 8
84
+ transition_16 |= receive_data[21]
85
+ return_data = round(transition_16 / 1000 + (transition_16 % 1000) * 0.001, 3)
86
+
87
+ return return_data
88
+
89
+ elif flag == "ultrasonic":
90
+ receive_data = self._extract_frame(receive_all_data, ProtocolCode.ultrasound_header,
91
+ ProtocolCode.ultrasound_footer)
92
+ # print(receive_data, len(receive_data))
93
+ self._debug(receive_data)
94
+ return_data = [receive_data[1] * 256 + receive_data[2], receive_data[3] * 256 + receive_data[4],
95
+ receive_data[5] * 256 + receive_data[6]]
96
+ return return_data
97
+ else:
98
+ print('no data', return_data)
99
+
100
+ def _extract_frame(self, data, frame_header, frame_tail):
101
+ """
102
+ Extract the corresponding data
103
+ :param data: Get all data
104
+ :param frame_header: Frame Header
105
+ :param frame_tail: Frame tail
106
+ :return: A list of integers
107
+ """
108
+ try:
109
+ # Find the location of the frame header
110
+ start_index = data.index(frame_header)
111
+ # Find the end of the frame, starting from the frame header
112
+ end_index = data.index(frame_tail, start_index)
113
+ # Extracting dataframe
114
+ frame = data[start_index:end_index + 1]
115
+ return frame
116
+ except ValueError:
117
+ # If the frame header or frame trailer is not found, an empty list is returned.
118
+ return []
119
+
120
+ def _check_sum(self, count_number, mode):
121
+ """
122
+ Calculate the check digit
123
+ :param count_number: The total number of bytes before the check digit
124
+ :param mode: Verify whether to send or receive data, 0-Receive data mode, 1-Send data mode
125
+ :return: A byte type
126
+ """
127
+ check_sum_result = 0
128
+ # 接收数据模式
129
+ if mode == 0:
130
+ for k in range(count_number):
131
+ check_sum_result ^= self.Send_Data[k]
132
+ # 发送数据模式
133
+ elif mode == 1:
134
+ for k in range(count_number):
135
+ check_sum_result ^= self.Send_Data[k]
136
+
137
+ return check_sum_result
138
+
139
+ def get_power_voltage(self):
140
+ """
141
+ Get battery voltage
142
+ :return:
143
+ """
144
+ return self._request("voltage")
145
+
146
+ def get_ultrasonic_value(self):
147
+ """
148
+ Get ultrasonic value
149
+ :return:
150
+ """
151
+ return self._request('ultrasonic')
152
+
153
+ def go_straight(self, speed=0.2):
154
+ """
155
+ Forward control
156
+ :param speed: speed (float, optional): Movement speed. Defaults to 0.2. range 0 ~ 1
157
+ :return:
158
+ """
159
+ if speed < 0 or speed > 1:
160
+ raise Exception("The movement speed range is 0~1, but the received value is {}".format(speed))
161
+ self.Send_Data[0] = ProtocolCode.header
162
+ self.Send_Data[1] = 0
163
+ self.Send_Data[2] = 0
164
+ # The target velocity of the X-axis of the robot
165
+ transition = int(speed * 1000)
166
+ self.Send_Data[4] = transition & 0xFF # Lower 8 bits
167
+ self.Send_Data[3] = (transition >> 8) & 0xFF # Higher 8 bits
168
+ # The target velocity of the Y-axis of the robot
169
+ self.Send_Data[6] = 0
170
+ self.Send_Data[5] = 0
171
+
172
+ self.Send_Data[8] = 0
173
+ self.Send_Data[7] = 0
174
+ # Check the bits for the Check_Sum function
175
+ self.Send_Data[9] = self._check_sum(9, 1)
176
+ self.Send_Data[10] = ProtocolCode.footer
177
+
178
+ try:
179
+ self._serial_port.write(bytes(self.Send_Data))
180
+ self._serial_port.flush()
181
+ self._debug(self.Send_Data)
182
+ except serial.SerialException as e:
183
+ e = traceback.format_exc()
184
+ print('Unable to send data through serial port: {}'.format(e))
185
+
186
+ def go_back(self, speed=-0.2):
187
+ """
188
+ Back control
189
+ :param speed: speed (float, optional): Movement speed. Defaults to 0.25. range -1 ~ 0
190
+ :return:
191
+ """
192
+ if not -1 <= speed <= 0:
193
+ raise Exception("The movement speed range is -1~0, but the received value is {}".format(speed))
194
+ self.Send_Data = [0] * 11
195
+ self.Send_Data[0] = ProtocolCode.header
196
+ self.Send_Data[1] = 0
197
+ self.Send_Data[2] = 0
198
+ # The target velocity of the X-axis of the robot
199
+ transition = int(speed * 1000)
200
+ if transition < 0:
201
+ transition = (1 << 16) + transition
202
+ self.Send_Data[4] = transition & 0xFF # Lower 8 bits
203
+ self.Send_Data[3] = (transition >> 8) & 0xFF # Higher 8 bits
204
+ # The target velocity of the Y-axis of the robot
205
+ self.Send_Data[6] = 0
206
+ self.Send_Data[5] = 0
207
+ # The target velocity of the Z-axis of the robot
208
+ self.Send_Data[8] = 0
209
+ self.Send_Data[7] = 0
210
+ # Check the bits for the Check_Sum function
211
+ self.Send_Data[9] = self._check_sum(9, 1)
212
+ self.Send_Data[10] = ProtocolCode.footer
213
+
214
+ try:
215
+ self._serial_port.write(bytes(self.Send_Data))
216
+ self._serial_port.flush()
217
+ self._debug(self.Send_Data)
218
+ except serial.SerialException as e:
219
+ e = traceback.format_exc()
220
+ print('Unable to send data through serial port: {}'.format(e))
221
+
222
+ def turn_left(self, speed=0.2):
223
+ """
224
+ Left turn control
225
+ :param speed: speed (float, optional): Movement speed. Defaults to 0.2. range 0 ~ 1
226
+ :return:
227
+ """
228
+
229
+ if speed < 0 or speed > 1:
230
+ raise Exception("The movement speed range is 0~1, but the received value is {}".format(speed))
231
+ self.Send_Data = [0] * 11
232
+ self.Send_Data[0] = ProtocolCode.header
233
+ self.Send_Data[1] = 0
234
+ self.Send_Data[2] = 0
235
+ # The target velocity of the X-axis of the robot
236
+ self.Send_Data[4] = 0
237
+ self.Send_Data[3] = 0
238
+ # The target velocity of the Y-axis of the robot
239
+ self.Send_Data[6] = 0
240
+ self.Send_Data[5] = 0
241
+ # The target velocity of the Z-axis of the robot
242
+ transition = int(speed * 1000)
243
+ self.Send_Data[8] = transition & 0xFF # Lower 8 bits
244
+ self.Send_Data[7] = (transition >> 8) & 0xFF # Higher 8 bits
245
+ # Check the bits for the Check_Sum function
246
+ self.Send_Data[9] = self._check_sum(9, 1)
247
+ self.Send_Data[10] = ProtocolCode.footer
248
+
249
+ try:
250
+ self._serial_port.write(bytes(self.Send_Data))
251
+ self._serial_port.flush()
252
+ self._debug(self.Send_Data)
253
+ except serial.SerialException as e:
254
+ e = traceback.format_exc()
255
+ print('Unable to send data through serial port: {}'.format(e))
256
+
257
+ def turn_right(self, speed=-0.2):
258
+ """
259
+ Right turn control
260
+ :param speed: speed (float, optional): Movement speed. Defaults to -0.2. range -1 ~ 0
261
+ :return:
262
+ """
263
+ if not -1 <= speed <= 0:
264
+ raise Exception("The movement speed range is -1~0, but the received value is {}".format(speed))
265
+ self.Send_Data = [0] * 11
266
+
267
+ self.Send_Data[0] = ProtocolCode.header
268
+ self.Send_Data[1] = 0
269
+ self.Send_Data[2] = 0
270
+ # The target velocity of the X-axis of the robot
271
+ self.Send_Data[4] = 0
272
+ self.Send_Data[3] = 0
273
+ # The target velocity of the Y-axis of the robot
274
+ self.Send_Data[6] = 0
275
+ self.Send_Data[5] = 0
276
+ # The target velocity of the Z-axis of the robot
277
+ transition = int(speed * 1000)
278
+ if transition < 0:
279
+ transition = (1 << 16) + transition
280
+ self.Send_Data[8] = transition & 0xFF # Lower 8 bits
281
+ self.Send_Data[7] = (transition >> 8) & 0xFF # Higher 8 bits
282
+ # Check the bits for the Check_Sum function
283
+ self.Send_Data[9] = self._check_sum(9, 1)
284
+ self.Send_Data[10] = ProtocolCode.footer
285
+
286
+ try:
287
+ self._serial_port.write(bytes(self.Send_Data))
288
+ self._serial_port.flush()
289
+ self._debug(self.Send_Data)
290
+ except serial.SerialException as e:
291
+ e = traceback.format_exc()
292
+ print('Unable to send data through serial port: {}'.format(e))
293
+
294
+ def stop(self):
295
+ """
296
+ stop motion
297
+ :return:
298
+ """
299
+ self.Send_Data = [0] * 11
300
+ self.Send_Data[0] = ProtocolCode.header
301
+ self.Send_Data[1] = 0
302
+ self.Send_Data[2] = 0
303
+ # The target velocity of the X-axis of the robot
304
+ self.Send_Data[4] = 0
305
+ self.Send_Data[3] = 0
306
+ # The target velocity of the Y-axis of the robot
307
+ self.Send_Data[6] = 0
308
+ self.Send_Data[5] = 0
309
+ # The target velocity of the Z-axis of the robot
310
+ self.Send_Data[8] = 0
311
+ self.Send_Data[7] = 0
312
+ # Check the bits for the Check_Sum function
313
+ self.Send_Data[9] = self._check_sum(9, 1)
314
+ self.Send_Data[10] = ProtocolCode.footer
315
+
316
+ try:
317
+ self._serial_port.write(bytes(self.Send_Data))
318
+ self._serial_port.flush()
319
+ self._debug(self.Send_Data)
320
+ except serial.SerialException as e:
321
+ e = traceback.format_exc()
322
+ print('Unable to send data through serial port: {}'.format(e))
323
+
324
+
325
+ # mc = ChassisControl('/dev/wheeltec_controller', debug=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pymycobot
3
- Version: 3.5.0.dev4
3
+ Version: 3.5.0.dev6
4
4
  Summary: Python API for serial communication of MyCobot.
5
5
  Home-page: https://github.com/elephantrobotics/pymycobot
6
6
  Author: Elephantrobotics
@@ -1,170 +0,0 @@
1
-
2
- import socket
3
- import json
4
- import threading
5
- import struct
6
-
7
- class MercuryChassisError(Exception):
8
- pass
9
-
10
- class MercuryChassis:
11
- """
12
- Mercury X1 mobile chassis car socket class
13
- """
14
- def __init__(self, ip=None):
15
- self.ifname = b"wlan0"
16
- self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
17
- if ip is not None:
18
- self.host = ip
19
- else:
20
- import fcntl
21
- try:
22
- self.host = socket.inet_ntoa(fcntl.ioctl(self.server_socket.fileno(), 0x8915, struct.pack('256s', self.ifname[:15]))[20:24]) #IP
23
- except:
24
- self.host = "127.0.0.1"
25
- self._sock.connect((self.host, 9999))
26
- self.recv = threading.Thread(target=self.check_move_end, daemon=True)
27
- self.recv.start()
28
- self.move_end = False
29
-
30
- def close(self):
31
- self._sock.close()
32
-
33
- def open(self):
34
- self._sock.connect((self.host, 9999))
35
-
36
- def check_move_end(self):
37
- while True:
38
- try:
39
- data = self._sock.recv(1024)
40
- data = json.loads(data)
41
- self.move_end = data
42
- except:
43
- pass
44
-
45
- # @property
46
- def is_move_end(self):
47
- """Is the movement over
48
-
49
- Returns:
50
- _type_: _description_
51
- """
52
- return self.move_end
53
-
54
- def go_straight(self, speed=0.25, exercise_duration=5):
55
- """Forward control
56
-
57
- Args:
58
- speed (float, optional): Movement speed. Defaults to 0.25. range 0 ~ 1
59
- exercise_duration (int, optional): Exercise duration. Defaults to 5s.
60
- """
61
- if speed < 0 or speed > 1:
62
- raise MercuryChassisError("The movement speed range is 0~1, but the received value is {}".format(speed))
63
- command = {"goStraight": {"time": exercise_duration, "speed": speed}}
64
- self._sock.sendall(json.dumps(command).encode())
65
-
66
- def go_back(self, speed=0.25, exercise_duration=5):
67
- """Back control
68
-
69
- Args:
70
- speed (float, optional): Movement speed. Defaults to 0.25. range 0 ~ 1
71
- exercise_duration (int, optional): Exercise duration. Defaults to 5s.
72
- """
73
- if speed < 0 or speed > 1:
74
- raise MercuryChassisError("The movement speed range is 0~1, but the received value is {}".format(speed))
75
- command = {"goBack": {"time": exercise_duration, "speed": speed}}
76
- self._sock.sendall(json.dumps(command).encode())
77
-
78
- def turn_left(self, speed=0.5, exercise_duration=5):
79
- """left turn control
80
-
81
- Args:
82
- speed (float, optional): Movement speed. Defaults to 0.25. range 0 ~ 1
83
- exercise_duration (int, optional): Exercise duration. Defaults to 5s.
84
- """
85
- if speed < 0 or speed > 1:
86
- raise MercuryChassisError("The movement speed range is 0~1, but the received value is {}".format(speed))
87
- command = {"turnLeft": {"time": exercise_duration, "speed": speed}}
88
- self._sock.sendall(json.dumps(command).encode())
89
-
90
- def turn_right(self, speed=0.5, exercise_duration=5):
91
- """_summary_
92
-
93
- Args:
94
- speed (float, optional): Movement speed. Defaults to 0.25. range 0 ~ 1
95
- exercise_duration (int, optional): Exercise duration. Defaults to 5s.
96
- """
97
- if speed < 0 or speed > 1:
98
- raise MercuryChassisError("The movement speed range is 0~1, but the received value is {}".format(speed))
99
- command = {"turnRight": {"time": exercise_duration, "speed": speed}}
100
- self._sock.sendall(json.dumps(command).encode())
101
-
102
- def stop(self):
103
- """stop motion"""
104
- command = {"stop": True}
105
- self._sock.sendall(json.dumps(command).encode())
106
-
107
- def init_position(self,position_x,position_y,orientation_z,orientation_w,covariance):
108
- """Set navigation starting position
109
-
110
- Args:
111
- position_x (_type_): _description_
112
- position_y (_type_): _description_
113
- orientation_z (_type_): _description_
114
- orientation_w (_type_): _description_
115
- covariance (_type_): _description_
116
- """
117
- command = {"initPosition": {"x": position_x, "y": position_y, "o_z": orientation_z, "o_w": orientation_w, "cov": covariance}}
118
- self._sock.sendall(json.dumps(command).encode())
119
-
120
- def goto_position(self,position_x,position_y,orientation_z,orientation_w):
121
- """Set navigation target location
122
-
123
- Args:
124
- position_x (_type_): _description_
125
- position_y (_type_): _description_
126
- orientation_z (_type_): _description_
127
- orientation_w (_type_): _description_
128
- """
129
- command = {"goToPosition": {"x": position_x, "y": position_y, "o_z": orientation_z, "o_w": orientation_w}}
130
- self._sock.sendall(json.dumps(command).encode())
131
-
132
- def cancel_navigation(self):
133
- """Cancel navigation
134
- """
135
- command = {"movebaseCancel": True}
136
- self._sock.sendall(json.dumps(command).encode())
137
-
138
- def get_software_version(self):
139
- """Get the base server version number"""
140
- command = {"getSoftWareVersion": True}
141
- self._sock.sendall(json.dumps(command).encode())
142
- while True:
143
- if self.move_end:
144
- data = self.move_end.get("getSoftWareVersion", None)
145
- if data:
146
- return self.move_end["getSoftWareVersion"]["return"]
147
-
148
- def get_base_ros_version(self):
149
- """Get the base ROS project version number"""
150
- command = {"getBaseROSVersion": True}
151
- self._sock.sendall(json.dumps(command).encode())
152
- while True:
153
- if self.move_end:
154
- data = self.move_end.get("getBaseROSVersion", None)
155
- if data:
156
- return self.move_end["getBaseROSVersion"]["return"]
157
-
158
- def get_battery_state(self):
159
- """Get battery level
160
- """
161
- command = {"batteryState": True}
162
- self._sock.sendall(json.dumps(command).encode())
163
- while True:
164
- if self.move_end:
165
- data = self.move_end.get("batteryState", None)
166
- if data:
167
- return self.move_end["batteryState"]["return"]
168
-
169
-
170
-
File without changes
File without changes
File without changes
File without changes