Skip to content

Commit f6e0069

Browse files
committed
refactor: pymycobot
* modularization * add Error class
1 parent 115238c commit f6e0069

File tree

9 files changed

+244
-193
lines changed

9 files changed

+244
-193
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pip install pymycobot --upgrade
1919

2020
**Notes:**
2121

22-
> Now only the version after `Atom2.4` is supported. If you use an earlier version, please install `pymycobot 1.0.7`.
22+
> Now only the version is `Atom2.4` or later is supported. If you use an earlier version, please install `pymycobot 1.0.7`.
2323
2424
```bash
2525
pip install pymycobot==1.0.7

pymycobot/README.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ We support Python2, Python3.5 or later.
2626

2727
# MyCobot
2828

29+
```python
30+
from pymycobot.mycobot import MyCobot
31+
```
32+
2933
## Overall status
3034

3135
### power_on()
@@ -88,7 +92,7 @@ We support Python2, Python3.5 or later.
8892

8993
```python
9094
from pymycobot.mycobot import MyCobot
91-
from pymycobot.common import Angle
95+
from pymycobot.genre import Angle
9296

9397

9498
mycobot = MyCobot('/dev/ttyUSB0')
@@ -111,7 +115,7 @@ We support Python2, Python3.5 or later.
111115

112116
```python
113117
from pymycobot.mycobot import MyCobot
114-
from pymycobot.common import Angle
118+
from pymycobot.genre import Angle
115119

116120

117121
mycobot = MyCobot('/dev/ttyUSB0')
@@ -144,7 +148,7 @@ We support Python2, Python3.5 or later.
144148

145149
```python
146150
from pymycobot.mycobot import MyCobot
147-
from pymycobot.common import Angle
151+
from pymycobot.genre import Angle
148152

149153

150154
mycobot = MyCobot('/dev/ttyUSB0')
@@ -179,7 +183,7 @@ We support Python2, Python3.5 or later.
179183

180184
```python
181185
from pymycobot.mycobot import MyCobot
182-
from pymycobot.common import Coord
186+
from pymycobot.genre import Coord
183187

184188

185189
mycobot = MyCobot('/dev/ttyUSB0')
@@ -202,7 +206,7 @@ We support Python2, Python3.5 or later.
202206

203207
```python
204208
from pymycobot.mycobot import MyCobot
205-
from pymycobot.common import Coord
209+
from pymycobot.genre import Coord
206210

207211

208212
mycobot = MyCobot('/dev/ttyUSB0')
@@ -401,12 +405,20 @@ We support Python2, Python3.5 or later.
401405

402406
# Angle
403407

408+
```python
409+
from pymycobot.genre import Angle
410+
```
411+
404412
**Description**
405413

406414
Instance class of joint. It's recommended to use this class to select joint.
407415

408416
# Coord
409417

418+
```python
419+
from pymycobot.genre import Coord
420+
```
421+
410422
**Description**
411423

412424
Instance class of coord. It's recommended to use this class to select coord.

pymycobot/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
from __future__ import absolute_import
2-
import platform
32

43

54
name = 'pymycobot'
65

7-
version = (platform.python_version())
8-
9-
__all__ = ['mycobot', 'common']
6+
__version__ = '2.1.2'
107

8+
__all__ = ['mycobot', 'genre']

pymycobot/common.py

Lines changed: 140 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,146 @@
1-
import enum
1+
import sys
2+
sys.path.append('.')
3+
import struct
24

35

4-
class Angle(enum.Enum):
6+
class Command():
7+
#BASIC
8+
HEADER = 0xfe
9+
FOOTER = 0xfa
510

6-
J1 = 1
7-
J2 = 2
8-
J3 = 3
9-
J4 = 4
10-
J5 = 5
11-
J6 = 6
11+
# Overall status
12+
POWER_ON = 0x10
13+
POWER_OFF = 0x11
14+
IS_POWER_ON = 0x12
15+
SET_FREE_MODE = 0x13
16+
17+
# MDI MODE AND OPERATION
18+
GET_ANGLES = 0x20
19+
SEND_ANGLE = 0x21
20+
SEND_ANGLES = 0x22
21+
GET_COORDS = 0x23
22+
SEND_COORD = 0x24
23+
SEND_COORDS = 0x25
24+
PAUSE = 0x26
25+
IS_PAUSED = 0x27
26+
RESUME = 0x28
27+
STOP = 0x29
28+
IS_IN_POSITION = 0x2a
29+
IS_MOVING = 0x2b
30+
31+
# JOG MODE AND OPERATION
32+
JOG_ANGLE = 0x30
33+
JOG_COORD = 0x32
34+
JOG_STOP = 0x34
35+
36+
# RUNNING STATUS AND SETTINGS
37+
GET_SPEED = 0x40
38+
SET_SPEED = 0x41
39+
GET_JOINT_MIN_ANGLE = 0x4a
40+
GET_JOINT_MAX_ANGLE = 0x4b
41+
42+
# SERVO CONTROL
43+
IS_SERVO_ENABLE = 0x50
44+
IS_ALL_SERVO_ENABLE = 0x51
45+
46+
# ATOM IO
47+
SET_COLOR = 0x6a
48+
SET_CLAW = 0x66
49+
50+
51+
class DataProcesser():
52+
# Functional approach
53+
def _encode_int8(self, data):
54+
return struct.pack('b', data)
55+
56+
def _encode_int16(self, data):
57+
return list(struct.pack('>h', data))
58+
59+
def _decode_int8(self, data):
60+
return struct.unpack('b', data)[0]
61+
62+
def _decode_int16(self, data):
63+
return struct.unpack('>h', data)[0]
64+
65+
def _angle_to_int(self, angle):
66+
return int(angle * 100)
67+
68+
def _coord_to_int(self, coord):
69+
return int(coord * 10)
70+
71+
def _int_to_angle(self, _int):
72+
return round(_int / 100.0, 3)
73+
74+
def _int_to_coord(self, _int):
75+
return round(_int / 10.0, 2)
76+
77+
def _flatten(self, _list):
78+
return sum(([x] if not isinstance(x, list) else self._flatten(x)
79+
for x in _list), [])
80+
81+
def _process_data_command(self, data, genre):
82+
if not data:
83+
return []
84+
85+
if genre in [
86+
Command.SEND_ANGLES, Command.SEND_COORDS,
87+
Command.IS_IN_POSITION
88+
]:
89+
_data_list = []
90+
for value in data[:6]:
91+
_data_list.extend(self._encode_int16((value)))
92+
for value in data[6:]:
93+
_data_list.append((value))
94+
return _data_list
95+
96+
elif genre in [Command.SEND_ANGLE, Command.SEND_COORD]:
97+
return self._flatten(
98+
[data[0],
99+
self._flatten(self._encode_int16(data[1])), data[2]])
100+
101+
elif genre in [
102+
Command.JOG_ANGLE, Command.JOG_COORD, Command.SET_COLOR
103+
]:
104+
return data
105+
106+
else:
107+
return [data[0]]
108+
109+
def _is_frame_header(self, data, pos):
110+
return data[pos] == Command.HEADER and data[pos + 1] == Command.HEADER
111+
112+
def _process_recived(self, data, genre):
113+
if not data:
114+
return []
115+
116+
data = bytearray(data)
117+
data_len = len(data)
118+
for idx in range(data_len - 1):
119+
if self._is_frame_header(data, idx):
120+
break
121+
else:
122+
return []
123+
124+
data_len = data[idx + 2] - 2
125+
cmd_id = data[idx + 3]
126+
if cmd_id != genre:
127+
return []
128+
data_pos = idx + 4
129+
avild_data = (data[data_pos:data_pos + data_len])
130+
131+
res = []
132+
if data_len == 12:
133+
for idx in range(0, len(avild_data), 2):
134+
a = avild_data[idx:idx + 2]
135+
res.append(self._decode_int16(a))
136+
elif data_len == 2:
137+
res.append(self._decode_int16(avild_data))
138+
else:
139+
res.append(self._decode_int8(avild_data))
140+
return res
141+
142+
def _process_bool(self, data):
143+
return data[0] if data else -1
12144

13145

14-
class Coord(enum.Enum):
15146

16-
X = 1
17-
Y = 2
18-
Z = 3
19-
Rx = 4
20-
Ry = 5
21-
Rz = 6

pymycobot/error.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import functools
2+
3+
4+
class MyCobotDataException(Exception):
5+
pass
6+
7+
def check_id(func):
8+
9+
@functools.wraps(func)
10+
def _wapper(*args, **kwargs):
11+
if not 0 <= args[1] <= 6:
12+
raise MyCobotDataException('id not right, should be 1 ~ 6')
13+
14+
return func(*args, **kwargs)
15+
16+
return _wapper
17+
18+

pymycobot/genre.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import sys
2+
sys.path.append('.')
3+
import enum
4+
5+
6+
class Angle(enum.Enum):
7+
8+
J1 = 1
9+
J2 = 2
10+
J3 = 3
11+
J4 = 4
12+
J5 = 5
13+
J6 = 6
14+
15+
16+
class Coord(enum.Enum):
17+
18+
X = 1
19+
Y = 2
20+
Z = 3
21+
Rx = 4
22+
Ry = 5
23+
Rz = 6

0 commit comments

Comments
 (0)