Skip to content
Snippets Groups Projects
Commit 591889c8 authored by bav6096's avatar bav6096
Browse files

refactored exceptions

parent e760468d
Branches
No related tags found
No related merge requests found
......@@ -4,32 +4,21 @@ import re
import importlib.resources
from . import animations
from visualising.exception import VisualiseException
class Animation:
def __init__(self, frames, frame_time, num_iter):
num_frames = len(frames)
source = "animation.py" # Name of the file that contains the Animation class definition.
if num_frames % 2 != 0:
raise ValueError("Number of frames must be even!")
def __init__(self, frames, frame_time, num_iter):
# Set frames, number of frames and number of ensembles.
try:
animation_len = len(frames)
except TypeError:
raise VisualiseException(source, "The animation is empty!")
if animation_len % 2 != 0:
raise VisualiseException(source, "Animation must contain an even number of frames!")
else:
for frame in frames:
try:
frame_len = len(frame)
except TypeError:
raise VisualiseException(source, "At least one frame is empty!")
num_values = len(frame)
if num_values != 48:
raise ValueError("All frames must have exactly 48 values!")
if frame_len != 48:
raise VisualiseException(source, "At least one frame doesn't have exactly 48 values!")
else:
is_numeric = True
is_positive = True
is_small = True
......@@ -40,46 +29,38 @@ class Animation:
is_small = is_small and value < 256
if not is_numeric:
raise VisualiseException(source, "Not all values in the animation are integers!")
elif not is_positive:
raise VisualiseException(source, "Not all values in the animation are positive!")
elif not is_small:
raise VisualiseException(source, "One or more values in the animation are to large!")
else:
raise TypeError("All frame values must be integers!")
if not is_positive:
raise ValueError("All frame values must be positive!")
if not is_small:
raise ValueError("All frame values must be smaller than 256!")
self.frames = frames
self.num_frames = animation_len
self.num_ensembles = int(animation_len / 2)
self.num_frames = num_frames
self.num_ensembles = int(num_frames / 2)
# Set frame time.
if not isinstance(frame_time, int):
raise VisualiseException(source, "Frame time must be an integer!")
elif frame_time < 0:
raise VisualiseException(source, "Frame time must be positive!")
elif frame_time > 4294967295:
raise VisualiseException(source, "Animation delay is to high!")
else:
raise TypeError("Frame time must be an integer!")
if not frame_time < 0:
raise ValueError("Frame time must be positive!")
if not frame_time > 4294967295:
raise ValueError("Frame time is to high!")
# The frame time is given in milliseconds.
self.frame_time = frame_time
# Set number of iterations.
if not isinstance(num_iter, int):
raise VisualiseException(source, "Number of iterations must be an integer!")
elif num_iter > 255:
raise VisualiseException(source, "Animation has to many iterations!")
elif num_iter <= 0:
raise VisualiseException(source, "Animation must have at least one iteration!")
else:
raise TypeError("Number of iterations must be an integer!")
if num_iter > 255:
raise ValueError("Animation has to many iterations!")
if num_iter <= 0:
raise ValueError("Animation must have at least one iteration!")
self.num_iter = num_iter
@staticmethod
def read_frames_from_file(filename):
try:
file = importlib.resources.open_text(animations, filename)
except AttributeError:
raise VisualiseException(source, "The file is incorrectly formatted!")
except FileNotFoundError:
raise VisualiseException(source, "The specified file does not exist!")
except TypeError:
raise VisualiseException(source, "No animation file was specified!")
animation = []
for line in file:
......@@ -100,23 +81,17 @@ class Animation:
@staticmethod
def set_pixel_color(ensemble, pixel, r, g, b):
try:
ensemble_len = len(ensemble)
except TypeError:
raise VisualiseException(source, "Ensemble is empty!")
if ensemble_len != 2:
raise VisualiseException(source, "Ensemble doesn't contain exactly two frames!")
else:
raise ValueError("Ensemble must contain exactly two frames!")
for frame in ensemble:
try:
frame_len = len(frame)
except TypeError:
raise VisualiseException(source, "At least one frame is empty!")
num_values = len(frame)
if num_values != 48:
raise ValueError("All frames must have exactly 48 values!")
if frame_len != 48:
raise VisualiseException(source, "At least one frame doesn't have exactly 48 values!")
else:
is_numeric = True
is_positive = True
is_small = True
......@@ -127,24 +102,21 @@ class Animation:
is_small = is_small and value < 256
if not is_numeric:
raise VisualiseException(source, "Not all values in the ensemble are integers!")
elif not is_positive:
raise VisualiseException(source, "Not all values in the ensemble are positive!")
elif not is_small:
raise VisualiseException(source, "One or more values in the ensemble are to large!")
else:
raise TypeError("All frame values must be integers!")
if not is_positive:
raise ValueError("All frame values must be positive!")
if not is_small:
raise ValueError("All frame values must be smaller than 256!")
if not isinstance(pixel, int):
raise TypeError("Pixel must be an integer!")
if not (0 < pixel < 33):
raise VisualiseException(source, "Pixel has to be in the range of 1 to 32!")
elif not (0 < r < 256):
raise VisualiseException(source, "Red channel value has to be in the range of 1 "
"to 255!")
elif not (0 < g < 256):
raise VisualiseException(source, "Green channel value has to be in the range of 1 "
"to 255!")
elif not (0 < b < 256):
raise VisualiseException(source, "Blue channel value has to be in the range of 1 "
"to 255!")
else:
raise ValueError("Pixel must be in the range of 1 to 32!")
if not (isinstance(r, int) and isinstance(g, int) and isinstance(b, int)):
raise TypeError("Color values must be integers!")
if not ((0 < r < 256) and (0 < g < 256) and (0 < b < 256)):
raise ValueError("Color values must be in the range of 1 to 255!")
if pixel < 16:
index = 0
else:
......
......@@ -4,57 +4,58 @@ import time
from visualising.message import FrameMsg, InstrMsg
from visualising.animation import Animation
from visualising.exception import VisualiseException
from visualising.connection import ArduinoException
class Arduino:
source = "arduino.py" # Name of the file that contains the Arduino class definition.
resend = 5 # Number of times a message is resend to the Arduino.
def __init__(self, connection):
self.connection = connection
# Creates one instruction messages and multiple frame messages to load an animation
# onto the Arduino.
def load_animation(self, animation):
if animation.num_ensembles > 16:
raise VisualiseException(source, "Animation hast to many frames!")
else:
try:
self.connection.confirm_msg(InstrMsg('A', animation).create_msg(), [b'\x0f'], resend)
except VisualiseException:
raise
for frame in animation.frames:
try:
self.connection.confirm_msg(FrameMsg(frame).create_msg(), [b'\x2f', b'\x3f'], resend)
except VisualiseException:
raise
# Creates instruction message and sends it to the Arduino,
# to play a loaded animation.
def start_playback(self):
try:
self.connection.confirm_msg(InstrMsg('B').create_msg(), [b'\x1f'], resend)
except VisualiseException:
raise
# Creates instruction message and sends it to the Arduino,
# to pause a playing animation.
def pause_playback(self):
try:
self.connection.confirm_msg(InstrMsg('C').create_msg(), [b'\x5f'], resend)
except VisualiseException:
raise
# Creates instruction message and sends it to the Arduino,
# to resume playback of a loaded animation.
def resume_playback(self):
try:
self.connection.confirm_msg(InstrMsg('D').create_msg(), [b'\x6f'], resend)
except VisualiseException:
raise
# Creates one instruction messages and multiple frame messages to load an animation
# onto the Arduino.
def load_animation(self, animation):
if animation.num_ensembles > 16:
raise ValueError("Animation has to many frames!")
else:
self.connection.confirm_msg(InstrMsg('A', animation).create_msg(), [b'\x0f'], resend)
for frame in animation.frames:
self.connection.confirm_msg(FrameMsg(frame).create_msg(), [b'\x2f', b'\x3f'], resend)
# First, an animation is loaded onto the Arduino. The playback of this
# animation is then started. In addition, it is checked whether the
# animation was played successfully.
def play_animation(self, animation):
self.load_animation(animation)
self.start_playback()
# Estimated playback time in seconds.
playback_time = animation.frame_time * animation.num_ensembles * 0.001
# Current time in seconds.
current_time = time.time()
while bytes(self.connection.receive_msg()) != bytes(b'\x4f'):
# Wait 10 times the estimated animation playback time for a response.
if time.time() > current_time + playback_time * 10:
raise ArduinoException("Successful playback of animation can't be confirmed!")
# Streams an animation to the Arduino. For this purpose, two frames of
# the animation are repeatedly sent to the Arduino. The Arduino plays
......@@ -64,11 +65,4 @@ class Arduino:
for _ in range(animation.num_iter):
for i in range(animation.num_ensembles):
ensemble = [animation.frames[2 * i + 0], animation.frames[2 * i + 1]]
self.load_animation(Animation(ensemble, animation.frame_time, 1))
self.start_playback()
curr_time = time.time() # Current time in milliseconds.
# Waits 10 times the animation delay for a response.
while bytes(self.connection.receive_msg()) != bytes(b'\x4F'):
if time.time() > curr_time + animation.frame_time / 100:
raise ArduinoException("P: -- ERROR -- Arduino is not responding!")
self.play_animation(Animation(ensemble, animation.frame_time, 1))
......@@ -7,22 +7,19 @@ from visualising.exception import VisualiseException
from serial.serialutil import SerialException
class Connection:
class ArduinoException(Exception):
def __init__(self, desc):
self.desc = desc
source = "connection.py" # Name of the file that contains the Connection class definition.
class Connection:
def __init__(self, port, baud):
self.connection = serial.Serial()
self.connection.port = port
self.connection.baudrate = baud
self.connection.timeout = 1
try:
self.connection.open() # Establishes a serial connection.
except SerialException:
raise VisualiseException(source, "No serial connection established!")
except FileNotFoundError:
raise VisualiseException(source, "The specified port does not exist!")
time.sleep(2) # Prevents errors regarding pyserial.
......@@ -78,29 +75,31 @@ class Connection:
# If the response is not as expected, try again as often as
# specified. In case any response wasn't even once one of the
# expected responses raise an exception.
def confirm_msg(self, msg, expected_responses, resend):
def confirm_msg(self, msg, expected_responses, num_resend):
def evaluate():
bool = resend > 0
bool = num_resend > 0
for element in expected_responses:
bool = bool and (bytes(element) != bytes(response))
return bool
if not isinstance(expected_responses, list):
raise VisualiseException(source, "Expected responses must be given as a list!")
elif not expected_responses:
raise VisualiseException(source, "There must be at least one expected response!")
elif not resend > 0:
raise VisualiseException(source, "Number of resends must be greater than zero!")
else:
raise TypeError("Expected responses must be given as a list!")
if not expected_responses:
raise ValueError("There must be at least one expected response!")
if not isinstance(num_resend, int):
raise TypeError("Number of resends must be an integer!")
if not num_resend > 0:
raise ValueError("Number of resends must be greater than zero!")
self.connection.send_msg(msg)
response = self.connection.receive_msg()
condition = evaluate()
while condition:
resend = resend - 1
num_resend = num_resend - 1
self.connection.send_msg(msg)
response = self.connection.receive_msg()
condition = evaluate()
if not resend > 0:
raise VisualiseException("Arduino", Connection.translate_msg(response))
if not num_resend > 0:
raise ArduinoException(Connection.translate_msg(response))
#!/usr/bin/env python
class Error(Exception):
pass
class VisualiseException(Error):
def __init__(self, source, description):
self.source = source
self.description = description
#!/usr/bin/env python
import rospy
from monitoring.watchdog import Watchdog
from visualising.exception import *
from visualising.arduino import Arduino
from visualising.connection import Connection
from visualising.connection import Connection, ArduinoException
from visualising.animation import Animation
......@@ -40,9 +40,6 @@ class Visualiser:
else:
self.stream_animation(happy)
def info_mode(self):
print("Hallo!")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment