Projet IHM - Robot

Introduction au sujet

Ce projet est avant tout un projet d'IHM. Vous devrez donc vous focaliser sur cet aspect en priorité puisque l'évaluation de votre travail reposera dessus : respectez les principes ergonomiques listés ci-après, réfléchissez aux interactions possibles, à l'aspect didactique, à l'homogénéité du style graphique, etc. Un fonctionnement parfait de l'application n'est pas demandé.

Le but est de créer une application graphique capable de simuler le déplacement d'un petit robot programmable dans un environnement virtuel. L'application doit permettre :

  • de créer l'environnement (et de le sauvegarder),
  • de programmer le robot,
  • de lancer la simulation (et de la suspendre),
  • d'afficher diverses informations.

L'échelle de la simulation est de 1 pixel pour 1 cm.

L'environnement

C'est une projection en 2D d'un étage d'immeuble constitué de murs et d'obstacles. Les murs sont représentés par des segments et sont d'une épaisseur unique de 10 cm. Ils comportent des ouvertures (en réalité, ces dernières sont le résultat de 2 segments-murs non jointifs). Les obstacles peuvent avoir des dimensions variées mais seront toujours associés à des rectangles (par exemple, il est possible de représenter graphiquement divers objets mais ils seront toujours traités par approximation comme des obstacles rectangulaires). Ces obstacles ne doivent pas chevaucher les murs. Il doit être possible d'effacer des murs ou des obstacles.

Aspect technique

Les murs et les obstacles sont caractérisés par 2 couples (x, y) de coordonnées. En utilisant la puissance des tags et certaines commandes, il est aisé de récupérer ces informations. Les fichiers de sauvegarde de l'environnement auront la structure suivante :

  • si le 1er caractère d'une ligne est # il s'agit d'un commentaire,
  • si le 1er caractère d'une ligne est M il s'agit d'un mur suivi de ses coordonnées (séparées par des espaces),
  • si le 1er caractère d'une ligne est O il s'agit d'un obstacle suivi de ses coordonnées (séparées par des espaces),
  • le 1er caractère D désigne la position initiale du robot et peut être ignoré,
  • le 1er caractère A désigne l'objectif à atteindre et peut être ignoré.

Exemple de fichier :

# premier environnement
M 10 10 110 10
M 110 10 110 50
O 20 20 30 30
D 20 90
A 100 50

En supposant que votre canvas se nomme .c :

  • .c find withtag current permet de retrouver l'objet courant,
  • .c find overlapping $x1 $y1 $x2 $y2 permet de récupérer la liste des objets compris dans l'aire du rectangle défini par les points (x1, y1) et (x2, y2),
  • .c find closest $x $y permet de retrouver la liste des objets les plus proches de la position (x, y),
  • .c coords $id permet de récupérer les coordonnées définissants l'objet id sous la forme d'une liste, et si l'on fournit une liste de coordonnées de modifier la géométrie de l'objet,
  • .c move $id $dx $dy permet de déplacer l'objet "id" relativement à sa position initiale de (dx, dy) (attention : le canvas ne comporte pas de commande de rotation et les calculs trigonométriques se font en radians (rappel : 1 rad = 57,295779513°)),
  • .c delete $id permet d'effacer un objet du canvas.

Si vous souhaitez utiliser des images, sachez que par défaut le canvas ne gère que les fichiers images de type gif ou ppm/pgm (utilisez le package ImageMagick et en particulier la commande convert pour pallier à cette limitation). La création d'une pixmap se fait en deux temps :

  1. chargement du fichier image par image create photo id_image -file fichier,
  2. affichage de l'image par .c create image $x $y -image id_image.

Le robot

Il peut être représenté graphiquement par un simple triangle (afin de donner une indication visuelle sur son orientation) et sa taille ne doit pas dépasser 20 x 20 cm. Il est caractérisé par sa position, son orientation et son programme résident. Il dispose d'un ensemble de fonctionnalités telles que : avancer, reculer, stopper, tourner, faire une mesure de détection dans l'une des 4 directions (devant, derrière, à gauche ou à droite), enregistrer ou lire une information numérique (il embarque une mémoire d'une capacité de 256 cellules auxquelles il a accès via leur adresse). On doit pouvoir aussi charger un programme, démarrer le programme résident, suspendre le programme, fournir des informations internes, etc.

Aspect technique

Il est fortement conseillé de modéliser le robot dans un namespace. Par exemple :

namespace eval Robot {
# les actions du robot
namespace export Avancer Reculer Tourner Programme ...
# var internes : direction, position, id du canvas associe, ...
variable robdir 0 robx 0 roby 0 robfic -1 ...
...
#============================================
proc Avancer {} {
  variable robdir
  ...
}

Exemple d'utilisation du namespace :

button .b5 -text PROG -command { Robot::Programme }

Il subsiste un problème au niveau du widget canvas : l'absence de rotation autour d'un point quelconque d'un objet géométrique. Il faut donc créer cette procédure de toute pièce. L'aspect mathématique est simple : la rotation d'un objet autour d'un point se fait dans le plan par composition de translations et de rotations. Plus précisément, soit p un point défini dans le référentiel de l'objet, le point p' transformé de p est : p' = T-1 . R . T . p avec T la translation qui amène le référentiel de l'objet à l'origine, R la rotation et T-1 la translation inverse qui ramène le référentiel à sa position initiale. Le système d'équations paramétriques est : x' = (x - tx) cos a - (y - ty) sin a + tx ; y' = = (x - tx) sin a - (y - ty) cos a + ty avec (tx, ty) les coordonnées du référentiel local et a l'angle de rotation.

Le programme

Il est écrit en Tcl et comporte des appels aux fonctions du robot. Exemple d'un programme simple :

Robot::Avancer
# s'il y a un obstacle devant (Forward) le robot s'arrete
if {[Robot::Obstacle F]} {
  Robot::Stopper
}

Important : il ne faut jamais mettre de boucle dans ce programme car celui-ci est géré par les évènements générés par le robot.

Aspect technique

La mise en œuvre du programme se fera au niveau du namespace Robot, et prendra la forme suivante : soit le fichier est lu (par l'instruction read), son contenu mémorisé dans une variable et son exécution lancée par l'instruction eval, soit il est exécuté directement (par l'instruction source). Dans les deux cas de figures, son exécution effective se fera par un appel temporisé récursif :

proc Start {} {
...
if {$continuer} {
  # execution du programme
  eval $robprg ;# ou bien source $robfic
  after 100 Robot::Start

Principes ergonomiques

Cohérence : style graphique homogène, si l'interface privilégie un certain type de widgets elle doit le faire pour toutes les facettes de l'application, l'affichage et la correction des erreurs doivent toujours être traités de façon proche quelque soit le type d'erreur.

Concision : le placement initial des murs et des obstacles, la manipulation des paramètres durant la simulation doivent nécessiter le moins d'actions possible.

Retour d'informations : à toute action doit correspondre une réponse visuelle (ou sonore), une aide (si possible contextuelle) doit être mise à disposition.

Structuration des activités : toute action complexe doit être décomposée en suite d'actions simples et intuitives.

Flexibilité : changement de l'aspect du robot, paramétrisation de l'affichage des informations, activation ou non de certains fonctions "spéciales" (i.e non prévues initialement) du robot.

Gestion des erreurs : le placement des murs, des obstacles et du robot doit être contrôlé, la compatibilité du programme vérifiée, l'aspect le plus difficile sur ce point est de déceler un "comportement" inapproprié du robot (coincé dans un angle par exemple).