Skip to content

Commit 33b6cd8

Browse files
committed
fix bug: mybuddy data analysis
1 parent 24000a0 commit 33b6cd8

File tree

6 files changed

+320
-48
lines changed

6 files changed

+320
-48
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
import time
2+
import os
3+
import sys
4+
import termios
5+
import tty
6+
import threading
7+
import json
8+
import serial
9+
import serial.tools.list_ports
10+
11+
from pymycobot import MyBuddy
12+
13+
14+
port: str
15+
mc: MyBuddy
16+
sp: int = 80
17+
18+
19+
def setup():
20+
print("")
21+
global port, mc
22+
plist = list(serial.tools.list_ports.comports())
23+
idx = 1
24+
for port in plist:
25+
print("{} : {}".format(idx, port))
26+
idx += 1
27+
28+
_in = input("\nPlease input 1 - {} to choice:".format(idx - 1))
29+
port = str(plist[int(_in) - 1]).split(" - ")[0].strip()
30+
print(port)
31+
print("")
32+
33+
baud = 115200
34+
_baud = input("Please input baud(default:115200):")
35+
try:
36+
baud = int(_baud)
37+
except Exception:
38+
pass
39+
print(baud)
40+
print("")
41+
42+
DEBUG = False
43+
f = input("Wether DEBUG mode[Y/n]:")
44+
if f in ["y", "Y", "yes", "Yes"]:
45+
DEBUG = True
46+
# mc = MyCobot(port, debug=True)
47+
mc = MyBuddy(port, baud, debug=DEBUG)
48+
49+
50+
class Raw(object):
51+
"""Set raw input mode for device"""
52+
53+
def __init__(self, stream):
54+
self.stream = stream
55+
self.fd = self.stream.fileno()
56+
57+
def __enter__(self):
58+
self.original_stty = termios.tcgetattr(self.stream)
59+
tty.setcbreak(self.stream)
60+
61+
def __exit__(self, type, value, traceback):
62+
termios.tcsetattr(self.stream, termios.TCSANOW, self.original_stty)
63+
64+
65+
class Helper(object):
66+
def __init__(self) -> None:
67+
self.w, self.h = os.get_terminal_size()
68+
69+
def echo(self, msg):
70+
print("\r{}".format(" " * self.w), end="")
71+
print("\r{}".format(msg), end="")
72+
73+
74+
class TeachingTest(Helper):
75+
def __init__(self, mycobot) -> None:
76+
super().__init__()
77+
self.mc = mycobot
78+
self.recording = False
79+
self.playing = False
80+
self.record_list = []
81+
self.record_t = None
82+
self.play_t = None
83+
84+
def record(self):
85+
self.record_list = []
86+
self.recording = True
87+
88+
def _record():
89+
start_t = time.time()
90+
91+
while self.recording:
92+
angles_1 = self.mc.get_encoders(1)
93+
angles_2 = self.mc.get_encoders(2)
94+
if angles_1 and angles_2:
95+
self.record_list.append([angles_1,angles_2])
96+
time.sleep(0.1)
97+
print("\r {}".format(time.time() - start_t), end="")
98+
99+
self.echo("Start recording.")
100+
self.record_t = threading.Thread(target=_record, daemon=True)
101+
self.record_t.start()
102+
103+
def stop_record(self):
104+
if self.recording:
105+
self.recording = False
106+
self.record_t.join()
107+
self.echo("Stop record")
108+
109+
def play(self):
110+
self.echo("Start play")
111+
for angles in self.record_list:
112+
# print(angles)
113+
self.mc.set_encoders(angles[0], 80)
114+
self.mc.set_encoders(angles[1], 80)
115+
time.sleep(0.1)
116+
self.echo("Finish play")
117+
118+
def loop_play(self):
119+
self.playing = True
120+
121+
def _loop():
122+
len_ = len(self.record_list)
123+
i = 0
124+
while self.playing:
125+
idx_ = i % len_
126+
i += 1
127+
self.mc.set_encoders(self.record_list[idx_], 80)
128+
time.sleep(0.1)
129+
130+
self.echo("Start loop play.")
131+
self.play_t = threading.Thread(target=_loop, daemon=True)
132+
self.play_t.start()
133+
134+
def stop_loop_play(self):
135+
if self.playing:
136+
self.playing = False
137+
self.play_t.join()
138+
self.echo("Stop loop play.")
139+
140+
def save_to_local(self):
141+
if not self.record_list:
142+
self.echo("No data should save.")
143+
return
144+
145+
with open(os.path.dirname(__file__) + "/record.txt", "w") as f:
146+
json.dump(self.record_list, f, indent=2)
147+
self.echo("save dir: {}".format(os.path.dirname(__file__)))
148+
149+
def load_from_local(self):
150+
151+
with open(os.path.dirname(__file__) + "/record.txt", "r") as f:
152+
try:
153+
data = json.load(f)
154+
self.record_list = data
155+
self.echo("Load data success.")
156+
except Exception:
157+
self.echo("Error: invalid data.")
158+
159+
def print_menu(self):
160+
print(
161+
"""\
162+
\r q: quit
163+
\r r: start record
164+
\r c: stop record
165+
\r p: play once
166+
\r P: loop play / stop loop play
167+
\r s: save to local
168+
\r l: load from local
169+
\r f: release mycobot
170+
\r----------------------------------
171+
"""
172+
)
173+
174+
def start(self):
175+
self.print_menu()
176+
177+
while not False:
178+
with Raw(sys.stdin):
179+
key = sys.stdin.read(1)
180+
if key == "q":
181+
break
182+
elif key == "r": # recorder
183+
self.record()
184+
elif key == "c": # stop recorder
185+
self.stop_record()
186+
elif key == "p": # play
187+
self.play()
188+
elif key == "P": # loop play
189+
if not self.playing:
190+
self.loop_play()
191+
else:
192+
self.stop_loop_play()
193+
elif key == "s": # save to local
194+
self.save_to_local()
195+
elif key == "l": # load from local
196+
self.load_from_local()
197+
elif key == "f": # free move
198+
self.mc.release_all_servos()
199+
self.echo("Released")
200+
else:
201+
print(key)
202+
continue
203+
204+
205+
if __name__ == "__main__":
206+
setup()
207+
recorder = TeachingTest(mc)
208+
recorder.start()

pymycobot/Interface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def get_angles(self, id):
120120
Return:
121121
list: A float list of all degree.
122122
"""
123-
return self._mesg(ProtocolCode.GET_ANGLES, id)
123+
return self._mesg(ProtocolCode.GET_ANGLES, id, has_reply=True)
124124

125125
def send_angle(self, id, joint, angle, speed):
126126
"""Send one degree of joint to robot arm.

pymycobot/common.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,23 +206,23 @@ def _process_received(self, data, genre):
206206
header_i, header_j = 0, 1
207207
while header_j < data_len-4:
208208
if self._is_frame_header(data, header_i, header_j):
209-
cmd_id = data[header_i + 3]
209+
cmd_id = data[header_i + 4]
210210
# compare send header and received header
211211
if cmd_id == genre:
212212
break
213213
header_i += 1
214214
header_j += 1
215215
else:
216216
return []
217-
data_len = data[header_i + 2] - 2
217+
data_len = data[header_i + 3] - 2
218218
unique_data = [ProtocolCode.GET_BASIC_INPUT,
219219
ProtocolCode.GET_DIGITAL_INPUT]
220220

221221
if cmd_id in unique_data:
222222
data_pos = header_i + 5
223223
data_len -= 1
224224
else:
225-
data_pos = header_i + 4
225+
data_pos = header_i + 5
226226
valid_data = data[data_pos: data_pos + data_len]
227227

228228
# process valid data
@@ -291,7 +291,7 @@ def read(self):
291291
k = 0
292292
pre = 0
293293
t = time.time()
294-
while True and time.time() - t < 0.1:
294+
while True:
295295
try:
296296
data = self._serial_port.read()
297297
k+=1

0 commit comments

Comments
 (0)