Skip to content

Commit da7ba65

Browse files
committed
general improvements and fixes
1 parent 4e0e1ec commit da7ba65

File tree

17 files changed

+368
-385
lines changed

17 files changed

+368
-385
lines changed

coderbot/api.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ def move(body):
114114
distance=body.get("distance")
115115
if (speed is None or speed == 0) or (elapse is not None and distance is not None):
116116
return 400
117+
speed = max(-100, min(100, speed))
117118
bot.move(speed=speed, elapse=elapse, distance=distance)
118119
return 200
119120

@@ -123,6 +124,7 @@ def turn(body):
123124
distance=body.get("distance")
124125
if (speed is None or speed == 0) or (elapse is not None and distance is not None):
125126
return 400
127+
speed = max(-100, min(100, speed))
126128
bot.turn(speed=speed, elapse=elapse, distance=distance)
127129
return 200
128130

@@ -201,23 +203,26 @@ def listPhotos():
201203

202204
def getPhoto(name):
203205
mimetype = {'jpg': 'image/jpeg', 'mp4': 'video/mp4'}
206+
name = os.path.basename(name)
204207
try:
205208
media_file = cam.get_photo_file(name)
206-
return send_file(media_file, mimetype=mimetype.get(name[:-3], 'image/jpeg'), max_age=0)
209+
return send_file(media_file, mimetype=mimetype.get(name[-3:], 'image/jpeg'), max_age=0)
207210
except picamera.exc.PiCameraError as e:
208211
logging.error("Error: %s", str(e))
209212
return 503
210213
except FileNotFoundError:
211214
return 404
212215

213216
def savePhoto(name, body):
217+
name = os.path.basename(name)
214218
try:
215219
cam.update_photo({"name": name, "tag": body.get("tag")})
216220
except FileNotFoundError:
217221
return 404
218222

219223
def deletePhoto(name):
220224
logging.debug("photo delete")
225+
name = os.path.basename(name)
221226
try:
222227
cam.delete_photo(name)
223228
except FileNotFoundError:
@@ -235,10 +240,10 @@ def saveSettings(body):
235240
return 200
236241

237242
def updateFromPackage():
238-
os.system('sudo bash /home/pi/clean-update.sh')
243+
subprocess.run(['sudo', 'bash', '/home/pi/clean-update.sh'], check=False)
239244
file_to_upload = connexion.request.files['file_to_upload']
240245
file_to_upload.save(os.path.join('/home/pi/', 'update.tar'))
241-
os.system('sudo reboot')
246+
subprocess.run(['sudo', 'reboot'], check=False)
242247
return 200
243248

244249
def listMusicPackages():

coderbot/audio.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from array import array
2222
import time
2323
import logging
24+
import subprocess
2425
import wave
2526
import audioop
2627
import pyaudio
@@ -64,8 +65,16 @@ def exit(self):
6465
def say(self, what, locale='en'):
6566
if what and "$" in what:
6667
self.play(what[1:] + SOUNDEXT)
67-
elif what and what:
68-
os.system('espeak --stdout -v' + locale + ' -p 90 -a 200 -s 150 -g 10 "' + what + '" 2>>/dev/null | aplay -q')
68+
elif what:
69+
try:
70+
espeak = subprocess.Popen(
71+
['espeak', '--stdout', '-v', locale, '-p', '90', '-a', '200', '-s', '150', '-g', '10', what],
72+
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL
73+
)
74+
subprocess.run(['aplay', '-q'], stdin=espeak.stdout, stderr=subprocess.DEVNULL)
75+
espeak.wait()
76+
except FileNotFoundError:
77+
logging.warning("espeak or aplay not found")
6978

7079
def normalize(self, snd_data):
7180
"Average the volume out"

coderbot/camera.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,8 @@ def load_photo_metadata(self):
127127
self.save_photo_metadata()
128128

129129
def save_photo_metadata(self):
130-
f = open(PHOTO_METADATA_FILE, "wt")
131-
json.dump(self._photos, f)
132-
f.close()
130+
with open(PHOTO_METADATA_FILE, "wt") as f:
131+
json.dump(self._photos, f)
133132

134133
def update_photo(self, photo):
135134
for p in self._photos:
@@ -152,17 +151,14 @@ def photo_take(self):
152151
photo_index = self.get_next_photo_index()
153152
filename = PHOTO_PREFIX + str(photo_index) + self._camera.PHOTO_FILE_EXT
154153
filename_thumb = PHOTO_PREFIX + str(photo_index) + PHOTO_THUMB_SUFFIX + self._camera.PHOTO_FILE_EXT
155-
of = open(PHOTO_PATH + "/" + filename, "wb+")
156-
oft = open(PHOTO_PATH + "/" + filename_thumb, "wb+")
157154
im_str = self.get_image_jpeg()
158-
of.write(im_str)
159-
# thumb
160-
im_pil = PILImage.open(BytesIO(im_str))
161-
im_pil.resize(PHOTO_THUMB_SIZE).save(oft)
155+
with open(PHOTO_PATH + "/" + filename, "wb+") as of:
156+
of.write(im_str)
157+
with open(PHOTO_PATH + "/" + filename_thumb, "wb+") as oft:
158+
im_pil = PILImage.open(BytesIO(im_str))
159+
im_pil.resize(PHOTO_THUMB_SIZE).save(oft)
162160
self._photos.append({"name":filename})
163161
self.save_photo_metadata()
164-
of.close()
165-
oft.close()
166162

167163
def is_recording(self):
168164
return self.recording
@@ -186,15 +182,14 @@ def video_rec(self, video_name=None):
186182
except Exception:
187183
pass
188184

189-
oft = open(PHOTO_PATH + "/" + filename_thumb, "wb")
190-
im_str = self._camera.get_image_jpeg()
191-
im_pil = PILImage.open(BytesIO(im_str))
192-
im_pil.resize(PHOTO_THUMB_SIZE).save(oft)
185+
with open(PHOTO_PATH + "/" + filename_thumb, "wb") as oft:
186+
im_str = self._camera.get_image_jpeg()
187+
im_pil = PILImage.open(BytesIO(im_str))
188+
im_pil.resize(PHOTO_THUMB_SIZE).save(oft)
193189
self._photos.append({"name":filename})
194190
self.save_photo_metadata()
195191
self._camera.video_rec(PHOTO_PATH + "/" + filename)
196192
self.video_start_time = time.time()
197-
oft.close()
198193

199194
def video_stop(self):
200195
if self.recording:

coderbot/coderbot.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1818
############################################################################
1919

20-
import os
21-
import sys
2220
import time
2321
from math import copysign
2422
import logging
@@ -102,11 +100,12 @@ class CoderBot(object):
102100
# pylint: disable=too-many-instance-attributes
103101

104102
def __init__(self, motor_trim_factor=1.0, motor_min_power=0, motor_max_power=100, hw_version="5", pid_params=(0.8, 0.1, 0.01, 200, 0.01)):
103+
self._mpu = None
105104
try:
106105
self._mpu = mpu.AccelGyroMag()
107106
logging.info("MPU available")
108-
except:
109-
logging.info("MPU not available")
107+
except Exception:
108+
logging.warning("MPU not available")
110109

111110
self.GPIOS = HW_VERSIONS.get(hw_version, GPIO_CODERBOT_V_5())
112111
self._pin_out = [self.GPIOS.PIN_LEFT_FORWARD, self.GPIOS.PIN_RIGHT_FORWARD, self.GPIOS.PIN_LEFT_BACKWARD, self.GPIOS.PIN_RIGHT_BACKWARD, self.GPIOS.PIN_SERVO_1, self.GPIOS.PIN_SERVO_2]
@@ -178,11 +177,20 @@ def turn(self, speed=100, elapse=None, distance=None):
178177
self.motor_control(speed_left=speed_left, speed_right=speed_right, time_elapse=elapse, target_distance=distance)
179178

180179
def turn_angle(self, speed=100, angle=0):
181-
z = self._mpu.get_gyro()[2]
180+
if self._mpu is None:
181+
logging.warning("MPU not available, cannot turn by angle")
182+
return
183+
accumulated = 0.0
182184
self.turn(speed, elapse=0)
183-
while abs(z - self._mpu.get_gyro()[2]) < angle:
185+
t = time.time()
186+
while abs(accumulated) < angle:
187+
now = time.time()
188+
dt = now - t
189+
t = now
190+
gyro_z = self._mpu.get_gyro()[2]
191+
accumulated += gyro_z * dt
192+
logging.info("turn_angle: accumulated=%.2f target=%s", accumulated, angle)
184193
time.sleep(0.05)
185-
logging.info(self._mpu.get_gyro()[2])
186194
self.stop()
187195

188196
def forward(self, speed=100, elapse=None, distance=None):
@@ -204,24 +212,32 @@ def get_sonar_distance(self, sonar_id=0):
204212
return self.sonar[sonar_id].get_distance()
205213

206214
def get_mpu_accel(self, axis=None):
215+
if self._mpu is None:
216+
return None
207217
acc = self._mpu.get_acc()
208218
if axis is None:
209219
return acc
210220
else:
211221
return int(acc[axis]*100.0)/100.0
212222

213223
def get_mpu_gyro(self, axis=None):
224+
if self._mpu is None:
225+
return None
214226
gyro = self._mpu.get_gyro()
215227
if axis is None:
216228
return gyro
217229
else:
218-
return int(gyro[axis]*100.0)/200.0
230+
return int(gyro[axis]*100.0)/100.0
219231

220232
def get_mpu_heading(self):
233+
if self._mpu is None:
234+
return None
221235
hdg = self._mpu.get_hdg()
222236
return int(hdg)
223237

224238
def get_mpu_temp(self):
239+
if self._mpu is None:
240+
return None
225241
temp = self._mpu.get_temp()
226242
return int(temp*100.0)/100.0
227243

@@ -242,7 +258,7 @@ def stop(self):
242258
self._twin_motors_enc.stop()
243259

244260
def is_moving(self):
245-
return self._twin_motors_enc._is_moving
261+
return self._twin_motors_enc.is_moving()
246262

247263
# Distance travelled getter
248264
def distance(self):
@@ -254,7 +270,7 @@ def speed(self):
254270

255271
# CoderBot direction getter
256272
def direction(self):
257-
return self._twin_motors_enc.speed()
273+
return self._twin_motors_enc.direction()
258274

259275
def set_callback(self, gpio, callback, elapse):
260276
self._cb_elapse[gpio] = elapse * 1000

coderbot/config.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,13 @@ def read(cls):
3737
cls.restore()
3838
with open(CONFIG_FILE, 'r') as f:
3939
cls._config = json.load(f)
40-
f.close()
4140
return cls._config
4241

4342
@classmethod
4443
def write(cls, config):
4544
cls._config = config
46-
f = open(CONFIG_FILE, 'w')
47-
json.dump(cls._config, f)
45+
with open(CONFIG_FILE, 'w') as f:
46+
json.dump(cls._config, f)
4847
return cls._config
4948

5049
@classmethod

coderbot/cv/camera.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ def get_image_bgr(self):
122122
def set_overlay_text(self, text):
123123
try:
124124
self.camera.annotate_text = text
125-
except picamera.PiCameraValueError:
126-
logging.info("PiCameraValueError")
125+
except Exception:
126+
logging.info("Unable to set overlay text")
127127

128128
def close(self):
129129
self.camera.close()

coderbot/cv/image.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929

3030
try:
3131
from pyzbar.pyzbar import decode
32-
except:
33-
logging.info("zbar not availabe")
32+
except Exception:
33+
logging.info("zbar not available")
3434

3535
class Image():
3636
r_from = np.float32([[0, 0], [640, 0], [640, 480], [0, 480]])
@@ -123,7 +123,7 @@ def grayscale(self):
123123
return Image(data)
124124

125125
def blackwhite(self):
126-
data = cv2.threshold(self._data, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
126+
_, data = cv2.threshold(self._data, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
127127
return Image(data)
128128

129129
def invert(self):

coderbot/main.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,16 @@ def run_server():
9595
CNNManager.get_instance()
9696
EventManager.get_instance("coderbot")
9797

98-
if app.bot_config.get('load_at_start') and app.bot_config.get('load_at_start'):
98+
if app.bot_config.get('load_at_start'):
9999
prog = app.prog_engine.load(app.bot_config.get('load_at_start'))
100100
prog.execute()
101+
102+
bot.set_callback(bot.GPIOS.PIN_PUSHBUTTON, button_pushed, 100)
103+
101104
except ValueError as e:
102105
app.bot_config = {}
103106
logging.error(e)
104107

105-
bot.set_callback(bot.GPIOS.PIN_PUSHBUTTON, button_pushed, 100)
106-
107108
remove_doreset_file()
108109

109110
app.run(host="0.0.0.0", port=5000)

coderbot/motion.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,9 @@ def track_keypoints(self, prev_image, cur_image, tracks):
170170
#print "initial tp: ", len(self.tracks), " current tp: ", len(new_tracks)
171171
#print len(new_tracks), len(tracks)
172172
tracks[:] = new_tracks[:]
173-
if tracks is False:
173+
if not tracks:
174174
logging.warning("lost ALL tp!")
175175
self.bot.stop()
176-
#exit(0)
177176
#cv2.polylines(self.vis, [np.int32(tr) for tr in self.tracks], False, (0, 255, 0))
178177

179178
def calc_motion(self):

0 commit comments

Comments
 (0)