class TestTourner(unittest.TestCase): def setUp(self): self.angle = rm.random() * rm.choice([-1, 1]) * pi self.strat = Tourner(robot=RobotMotorise(Pave(1,1,1,Point(2,2,0))), angle_max=(self.angle * 180 / pi)) self.arene = Arene() self.arene.add(self.strat.robot) def test_sim(self): print("Initialising rotation of ", self.angle*180/pi, "degres") app = AppAreneThread(self.arene) s = Simulation(strategies=[self.strat]) v = self.strat.robot.direction.clone() s.start() app.start() self.strat.robot.set_wheels_rotation(1, 40) self.strat.robot.set_wheels_rotation(2, 60) sens = self.strat.sens precision = max(self.strat.robot.get_wheels_rotations(1), self.strat.robot.get_wheels_rotations(2)) * ( pi / 180) * PAS_TEMPS * (max(self.strat.robot.rd.diametre, self.strat.robot.rg.diametre) / self.strat.robot.dist_wheels) while not s.stop: pass app.stop() if sens > 0: angle = abs((2 * pi) - v.diff_angle(self.strat.robot.direction, 1)) else: angle = abs(v.diff_angle(self.strat.robot.direction, 1)) print("Error: ", abs(abs(self.angle) - angle)*(180/pi), " degres") print("Maximal error expected: ", precision*180/pi, "degres") self.assertLess(abs(abs(self.angle) - angle), precision)
def setUp(self): self.distance = 1 self.strat = DeplacementDroit( robot=RobotMotorise(forme=Pave(1, 1, 1, Point(3, 3, 0))), distance_max=self.distance) self.arene = Arene() self.arene.add(self.strat.robot)
class TestVueMatriceArene(unittest.TestCase): """ Cette classe sert à tester la vue matricielle d'un pavé On crée une vue matricielle d'une arène dans une direction aléatoire, à une position aléatoire On prend pour les tests des distancees entre 1 et 5 mètres """ def setUp(self): self.arene = Arene() # Création aléatoire des variables l = [random.randint(1, 5) * random.choice([1, -1]) for i in range(2)] origine = Point(l[0], l[1], 0) teta = random.random() * random.choice( [1, -1]) * 2 * pi # Angle du vecteur entre l'origine et le pavé v = Vecteur(1, 0, 0).rotate(teta).norm() # True est obligatoire pour que test_vue_dessus affiche le pavé au centre self.view_mat = VueMatriceArene(self.arene, origine.clone(), v.clone(), True) def test_init(self): self.assertIsInstance(self.view_mat.origine, Point) self.assertIsInstance(self.view_mat.arene, Arene) self.assertIsInstance(self.view_mat.ox, Vecteur) self.assertIsInstance(self.view_mat.ajuste, bool) def test_vue_dessus(self): """ On ajoute à l'arène un pavé de dimensions (1,1,1) dans l'axe Ox de la vue, à une distance comprise entre 1 et 5 mètres S'assure qu'on a bien une matrice carrée, de la bonne taille contenant des entiers, et qu'elle a bien détecté un pavé dans la zone """ teta2 = random.random() * random.choice( [1, -1]) * 2 * pi # Angle de rotation du pavé self.dist = random.randint( 1, 5) # Distance qu'on va mettre entre l'origine et le centre du pavé self.p = Pave(1, 1, 1, self.view_mat.origine + self.view_mat.ox * self.dist) self.p.rotate(teta2) self.arene.add(self.p) print("Evaluatin view of:\n", self.p, "\n") dx = self.dist + max( self.p.width, self.p.length) # On s'assure d'englober tout le pavé m = self.view_mat.vueDessus(dx) self.assertEqual(len(m), int(dx * VueMatriceArene.res)) if self.view_mat is not None: print(repr(self.view_mat)) for i in range(len(m)): for j in range(len(m[0])): self.assertIsInstance(m[i][j], int) self.assertEqual(len(m), len(m[0]))
def setUp(self): self.arene = Arene() # Création aléatoire des variables l = [random.randint(1, 5) * random.choice([1, -1]) for i in range(2)] origine = Point(l[0], l[1], 0) teta = random.random() * random.choice( [1, -1]) * 2 * pi # Angle du vecteur entre l'origine et le pavé v = Vecteur(1, 0, 0).rotate(teta).norm() # True est obligatoire pour que test_vue_dessus affiche le pavé au centre self.view_mat = VueMatriceArene(self.arene, origine.clone(), v.clone(), True)
class TestDroitAmeliore(TestCase): def setUp(self): c = Point(2, 2, 1) v = Vecteur(1, 0, 0) dist = 3.0 self.arene = Arene() self.strat = DeplacementDroitAmeliore(robot=RobotMotorise( forme=Pave(1, 1, 1, c.clone()), direction=v.clone()), arene=self.arene) self.v = self.strat.robot.direction * dist self.p = Pave(0.5, 0.5, 0.5, self.strat.robot.centre + self.v) self.arene.add(self.p) self.arene.add(self.strat.robot) def test_detection_2D(self): print("Testing direct detection with infrared ray...") td = Thread(target=self.strat.robot.tete.sensors["cam"].run) app = AppAreneThread(self.arene) sim = Simulation(strategies=[self.strat], final_actions=[app.stop], tic=2, tic_display=[ (self.strat.robot.tete.sensors["ir"].arena_v, "-v") ]) self.strat.init_movement(3, 60) sim.start() #self.strat.start() app.start() while not sim.stop: pass #self.strat.robot.tete.sensors["cam"].stop() # On s'assure que le pavé est bien entré dans le champ d'alerte dist = (self.p.centre - self.strat.robot.centre ).to_vect().get_mag() - self.p.length / 2 self.assertLess(dist, self.strat.proximite_max, "Object detected too close") # On s'assure qu'on a détecté la limite avec une assez bonne précision diff = abs(self.strat.last_detected - dist) # err_max n'est valide que si le pavé est droit par rapport à la direction du robot err_max = max( self.strat.robot.get_wheels_rotations(1) * (pi / 180) * self.strat.robot.rd.diametre * PAS_TEMPS, PAS_IR) self.assertLess(diff, err_max, "Maximal detection error exceeded") print("Done")
def setUp(self): c = Point(2, 2, 1) v = Vecteur(1, 0, 0) dist = 3.0 self.arene = Arene() self.strat = DeplacementDroitAmeliore(robot=RobotMotorise( forme=Pave(1, 1, 1, c.clone()), direction=v.clone()), arene=self.arene) self.v = self.strat.robot.direction * dist self.p = Pave(0.5, 0.5, 0.5, self.strat.robot.centre + self.v) self.arene.add(self.p) self.arene.add(self.strat.robot)
class TestCapteurIR(unittest.TestCase): def setUp(self): self.obj = CapteurIR(Point(0, 0, 0), Vecteur(1, 1, 0).norm()) self.tete = Tete() self.arene = Arene() def test_init(self): bool_type = type(self.obj.portee) is float or type( self.obj.portee) is int self.assertEqual(bool_type, True, msg="Error initialisation") self.assertIsInstance(self.obj, CapteurIR, msg="Error initialisation") self.assertIsInstance(self.obj, Capteur, msg="Error initialisation") def test_get_mesure(self): """ On met un pavé dans la direction du capteur On prends une mesure, on vérifie qu'elle a été réalisée """ print("Testing detection...") # Mesure dans arène vide res = self.obj.get_mesure(self.arene) self.assertEqual(res, -1) # Mesure arène avec pavé v = Vecteur(1, 0, 0).norm() self.obj.direction, self.obj.centre = v.clone(), Point(0, 0, 0) v2 = v * 2 p = Pave(1, 1, 1, self.obj.centre + v2) self.arene.add(p) res = self.obj.get_mesure(self.arene) # Résultat du bon type bool_type = type(res) is float or type(res) is int self.assertEqual(bool_type, True) # Distance caluclée avec bonne précision diff = abs(v2.get_mag() - p.length / 2 - res) self.assertLess(diff, max(PAS_IR, 1 / RES_M), msg="Precision error") print("Done") def test_json(self): print("Testing json") try: self.obj.save("capteur_ir.json") obj2 = CapteurIR.load("capteur_ir.json") self.assertEqual(self.obj, obj2) except PermissionError: print("PerimissionError") print("Done")
def hook(dct): """ On ne copie pas la liste d'objets à ingorer""" if dct["__class__"] == Point.__name__: return Point.hook(dct) elif dct["__class__"] == Vecteur.__name__: return Vecteur.hook(dct) elif dct["__class__"] == Arene.__name__: return Arene.hook(dct) elif dct["__class__"] == VueMatriceArene.__name__: return VueMatriceArene(dct["arene"], dct["origine"], dct["ox"], dct["ajuste"], dct["matrice"])
def test_view(self): """ Affiche une arène vide en 3D, effectue quelques rotations """ print("Testing video...") td = Thread(target=self.obj.run) p = RobotTarget(forme=Pave(1, 1, 1, Point(3, 3, 0.5))) a = Arene() a.add(p) n_rot = 100 teta = 2 * pi / n_rot self.obj.direction = (p.centre - self.obj.centre).to_vect().norm() td.start() while not self.obj.is_set: pass for i in range(n_rot): p.rotate_all_around(p.centre, teta) sleep(PAS_TEMPS) self.obj.stop() print("Done")
class TestDeplacementDroit(unittest.TestCase): def setUp(self): self.distance = 1 self.strat = DeplacementDroit( robot=RobotMotorise(forme=Pave(1, 1, 1, Point(3, 3, 0))), distance_max=self.distance) self.arene = Arene() self.arene.add(self.strat.robot) def test_sim_2D(self): """ Teste la distance parcourue lors d'un déplacement droit """ p = self.strat.robot.centre.clone() sim = Simulation(strategies=[self.strat], tic=2, tic_display=[self.strat.robot.tete.sensors["acc"]]) app = AppAreneThread(self.arene) sim.start() app.start() dps_wheels = self.strat.robot.get_wheels_rotations(3) while not sim.stop: pass dist = (self.strat.robot.centre - p).to_vect().get_mag() # On s'assure qu'on a la précision souhaitée self.assertLess( abs(dist - self.distance), abs(dps_wheels[0]) * (pi / 180) * PAS_TEMPS * self.strat.robot.rd.diametre / 2) def test_json(self): dda = DeplacementDroit(robot=RobotMotorise()) d = dda.__dict__() dda.save("deplacement_droit.json") dda2 = DeplacementDroit.load("deplacement_droit.json")
def __init__(self, arene: Arene = Arene(), origine: Point = Point(0, 0, 0), ox: Vecteur = Vecteur(1, 0, 0), ajuste: bool = False, matrice: [[int]] = None): """ Initialise la matrice :param arene: Arène dont on prélève une portion :param origine: Origine de la vue, dans le repère de l'arène :param ox: Direction horizontale de la vue, dans le repère de l'arène :param ajuste: On représente la matrice selon Ox tourné de -45 degrés dans le sens trigonométrique """ self.origine = origine self.arene = arene self.ox = ox self.ajuste = ajuste self.matrice = matrice # Destiné à stocker la dernière matrice crée
def __init__(self, arene=None): """ :param arene: Arène à afficher :type arene: Arene """ Tk.__init__(self) if arene is not None: self.vue_arene = Vue2DArene(arene) else: a = Arene() self.vue_arene = Vue2DArene(a) self.stop = True self.canvas = Canvas(self, height=450, width=600, bg='white') self.canvas.bind("<Button-1>", self.start) self.canvas.bind("<Button-2>", self.stop) self.vue_arene.afficher(self.canvas) self.canvas.pack()
class testArene(unittest.TestCase): def setUp(self): self.a = Arene() self.n = 3 self.b = Objet3D() def test_creation_arene(self): self.assertIsInstance(self.a, Arene, msg=None) self.assertIsInstance(self.b, Objet3D, msg=None) self.a.empty() self.assertEqual(len(self.a.objets3D), 0) def test_arene_remplie(self): self.assertEqual(len(self.a.objets3D), 0) for i in range(0, self.n): self.a.add(Objet3D()) print(self.a) self.assertEqual(len(self.a.objets3D), self.n) def test_vide_arene(self): for i in range(0, self.n): self.a.add(Objet3D()) self.a.empty() self.assertEqual(len(self.a.objets3D), 0) def test_add_list(self): self.a.empty() l = [Objet3D(Point(0, 0, 0)).clone() for i in range(self.n)] self.a.add_list(l) self.assertEqual(len(l), len(self.a.objets3D)) for i in range(self.n): self.a.objets3D[i].centre.move(Vecteur(1, 0, 0)) self.assertNotEqual(l[0], self.a.objets3D[0])
return DroitVersBalise(**dct) @staticmethod def load(filename): """ Permet de charger un objet DroitVersbalise depuis un fichier au format json adapté :param filename: Nom du fichier """ with open(filename, 'r', encoding='utf-8') as f: return json.load(f, object_hook=DroitVersBalise.hook) class DroitVersBaliseVision(DroitVersBalise, StrategieVision): def __init__(self, robot, arene): DroitVersBalise.__init__(self, robot=robot, arene=arene) StrategieVision.__init__(self, robot=robot, arene=arene) def update(self): DroitVersBalise.update(self) if __name__=='__main__': st = DroitVersBalise(robot=RobotMotorise(), arene=Arene()) st.save("droitVersBalise.json") st2 = DroitVersBalise.load("droitVersBalise.json") print(st2.clone())
def setUp(self): self.angle = rm.random() * rm.choice([-1, 1]) * pi self.strat = Tourner(robot=RobotMotorise(Pave(1,1,1,Point(2,2,0))), angle_max=(self.angle * 180 / pi)) self.arene = Arene() self.arene.add(self.strat.robot)
def setUp(self): self.a = Arene() self.n = 3 self.b = Objet3D()
pass @staticmethod def hook(dct): res = StrategieVision.hook(dct) if res is not None: return res elif dct["__class__"] == TournerVersBalise.__name__: return TournerVersBalise(**dct) @staticmethod def load(filename): """ Permet de charger un objet TournerVersBalise depuis un fichier au format json adapté :param filename: Nom du fichier """ with open(filename, 'r', encoding='utf-8') as f: return json.load(f, object_hook=TournerVersBalise.hook) if __name__ == '__main__': from gl_lib.sim.robot import RobotMotorise from gl_lib.sim.geometry import Arene, signe st = TournerVersBalise(robot=RobotMotorise(), arene=Arene()) st.save("TournerVersBalise.json") st2 = TournerVersBalise.load("TournerVersBalise.json") print(st2.clone())
def setUp(self): self.obj = CapteurIR(Point(0, 0, 0), Vecteur(1, 1, 0).norm()) self.tete = Tete() self.arene = Arene()
def __init__(self, arene): Thread.__init__(self) self.arene = arene self.window = None def run(self): self.window = AppArene(self.arene) self.window.mainloop() def stop(self): self.window.quit() if __name__ == '__main__': from gl_lib.sim.robot.strategy.deplacement import DeplacementDroitAmeliore from gl_lib.sim.robot import RobotMotorise from gl_lib.sim import Simulation from gl_lib.sim.geometry import Vecteur a = Arene() strat = DeplacementDroitAmeliore( robot=RobotMotorise(direction=Vecteur(1, 1, 0).norm()), distance_max=1, arene=a) a.add(strat.robot) sim = Simulation(strategies=[strat]) app = AppAreneThread(strat.arene) app.start() sim.start()