Squelette d'un programme de robotique (III - La classe RobotError)
Cet article constitue le troisième d'une série consacrée à la programmation d'applications robotiques en langage Python. Dans cette série, cinq classes sont présentées successivement :
- La classe Robot.
- La classe RobotTask.
- La classe RobotError.
- La classe RobotExplorer.
- La classe IRControlledTankTask.
Les classes Robot, RobotTask et RobotError sont rassemblées dans un module Python : robot.py. Ce module, téléchargeable ici, doit être inclus dans le projet dans lequel il est utilisé. Bien que les exemples soient donnés dans le contexte d'un robot Lego MindStorm EV3, ce module peut servir de base pour n'importe quel robot programmé en Python.
La classe RobotError
Les classes Robot et RobotTask sont intimement associées dans la programmation robotique. Les différentes méthodes qui les composent contrôlent la nature des paramètres passés. En cas de paramètres erronés, une exception est levée.
Afin de distinguer les exceptions propres à ces classes, un classe d'exception particulière doit être créée : la classe RobotError.
Celle-ci est assez simple à programmer. Elle consiste à dériver la classe Exception qui est la classe racine de toutes les erreurs générées en Python et de surcharger son constructeur pour passer les messages appropriés.
Programmation
# 1 #
class RobotError(Exception):
# 2 #
TYPE_ERROR = "{0} n'est pas une instance de la classe {1}."
ADD_TASK_ERROR = "Impossible d'ajouter une tâche à un robot en marche."
# 3 #
def __init__(self, message, *args):
super().__init__(message.format(*args))
class RobotError(Exception):
# 2 #
TYPE_ERROR = "{0} n'est pas une instance de la classe {1}."
ADD_TASK_ERROR = "Impossible d'ajouter une tâche à un robot en marche."
# 3 #
def __init__(self, message, *args):
super().__init__(message.format(*args))
Explications
- La classe RobotError dérive la classe Exception qui est la classe racine de toutes les erreurs générée en Python.
- TYPE_ERROR et ADD_TASK_ERROR sont des constantes de classes contenant les messages que doit envoyer l'exception lors qu'elle est levée. On garde la possibilité de paramétrer les messages par des marqueurs {0} ou {1} utilisés par la méthode format() de la classe string.
- Pour la construction d'une instance RobotError, on passe une liste de paramètres *args transmis à la fonction __init__() et exploités par la méthode format() invoquée sur le paramètre message passé en paramètre du constructeur de la classe super() (classe Exception).
Utilisation
En Python, une exception esdt levée par l'instruction raise. La classe RobotError est utilisée trois fois dans le module roboto.py. La première fois pour contrôler le paramètre robot dans le constructeur de la classe RobotTask :
def __init__(self, robot, name=DEFAULT_NAME):
if not(isinstance(robot, Robot)):
raise RobotError(RobotError.TYPE_ERROR, repr(robot), Robot)
robot.add_task(self)
self.__robot = robot
self.__is_running = False
self.__name = name
if not(isinstance(robot, Robot)):
raise RobotError(RobotError.TYPE_ERROR, repr(robot), Robot)
robot.add_task(self)
self.__robot = robot
self.__is_running = False
self.__name = name
La deuxième utilisation consiste à contrôler le paramètre task dans la méthode add_task de la classe Robot et la troisième pour contrôler l'état du robot pour ne pas ajouter de nouvelle tâche si le robot est en déjà en marche.
def add_task(self, task):
if not(isinstance(task, RobotTask)):
raise RobotError(RobotError.TYPE_ERROR, repr(task), RobotTask)
if self.running:
raise RobotError(RobotError.ADD_TASK_ERROR)
if name in self.__tasks:
self.__tasks[task.name].stop()
self.__tasks[task.name] = task
if not(isinstance(task, RobotTask)):
raise RobotError(RobotError.TYPE_ERROR, repr(task), RobotTask)
if self.running:
raise RobotError(RobotError.ADD_TASK_ERROR)
if name in self.__tasks:
self.__tasks[task.name].stop()
self.__tasks[task.name] = task
Par défaut, lorsqu'une exception est levée, cela provoque un plantage du programme. Mais, comme pour toutes les exceptions, il est possible de les capturer dans une structure try-except.
try:
robot = Robot()
task = MyRobotTask(robot)
robot.run()
except RobotError:
print("Le robot ne peut pas démarrer.", file=sys.stderr)
robot = Robot()
task = MyRobotTask(robot)
robot.run()
except RobotError:
print("Le robot ne peut pas démarrer.", file=sys.stderr)
Conclusion
Les classes Robot, RobotTask et RobotError constituent les classes de base de toutes les applications robotiques présentées dans ce blog.
Elles sont rassemblées dans le module robot.py téléchargeable ici.
Le prochain article présente la classe RobotExplorer, un exemple de dérivation de la classe Robot pour l'adapter au robot Explorer dont la construction est décrite dans l'article « Construction du robot Explorateur ».
Commentaires
Enregistrer un commentaire