Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- from datetime import time
- import random
- from ev3dev.ev3 import *
- import time
- def current_time():
- return int(round(time.time() * 1000))
- def main():
- robot = Robot("outB", "outC")
- while True:
- directions = robot.process_colors(robot.register_colors(robot.forward_color()))
- print(directions)
- if len(directions) == 0:
- continue
- if Robot.WIN in directions:
- break
- print(directions)
- if len(directions) > 1 and Robot.D_BACKWARD in directions:
- directions.remove(Robot.D_BACKWARD)
- print(directions)
- print("----")
- robot.rotate_to_direction(random.sample(directions, 1)[0])
- robot.forward(duration=500)
- class Robot:
- DEFAULT_SPEED_FORWARD = 90
- DEFAULT_SPEED_BACKWARD = 45
- DEFAULT_ROTATE_SPEED = 90
- DEFAULT_TURN_SPEED = 90
- C_YELLOW = "GREEN_YELLOW"
- C_BLUE = "BLUE"
- C_RED = "RED"
- C_BLACK = "BLACK"
- D_LEFT = "L"
- D_FORWARD = "F"
- D_BACKWARD = "B"
- D_RIGHT = "R"
- WIN = "WIN"
- def __init__(self, left_motor, right_motor):
- """
- Initialise le robot, ses moteurs et capteurs.
- :param left_motor: identifiant du moteur de gauche
- :param right_motor: identifiant du moteur de droite
- """
- self.leftMotor = LargeMotor(left_motor)
- self.leftMotor.stop_action = LargeMotor.STOP_ACTION_HOLD
- self.rightMotor = LargeMotor(right_motor)
- self.rightMotor.stop_action = LargeMotor.STOP_ACTION_HOLD
- self.gyroscope = GyroSensor()
- self.colorSensor = ColorSensor()
- self.colorSensor.mode = ColorSensor.MODE_RGB_RAW
- self.gyroscope.mode = 'GYRO-RATE'
- self.gyroscope.mode = 'GYRO-ANG'
- def stop(self):
- """
- Arrete les moteurs du robot.
- """
- self.leftMotor.stop()
- self.rightMotor.stop()
- def forward(self, speed=DEFAULT_SPEED_FORWARD, duration=0):
- """
- Fait avancer le robot avec une vitesse et une duree parametrable.
- :param speed: vitesse du robot; defaut: DEFAULT_SPEED_WORWARD
- :param duration: duree du trajet; 0 pour infini; defaut: 0
- """
- self.leftMotor.run_forever(speed_sp=speed)
- self.rightMotor.run_forever(speed_sp=speed)
- if duration != 0:
- time.sleep(duration)
- self.stop()
- def backward(self, speed=DEFAULT_SPEED_BACKWARD, duration=0):
- """
- Fait reculer le robot avec une vitesse et une duree parametrable.
- :param speed: vitesse du robot; defaut: DEFAULT_SPEED_BACKWARD
- :param duration: duree du trajet; 0 pour infini; deaut: 0
- """
- self.forward(-speed, duration)
- def get_color(self):
- """
- Retourne la couleur que capte le capteur au moment de l'appel de la fonction.
- :return: couleur detectee
- """
- return self.colorSensor.color
- def turn(self, deg, speed=DEFAULT_TURN_SPEED):
- """
- Fait tourner le robot d'un certain angle puis le fait avance jusqu'a l'arret.
- :param deg: angle du virage
- :param speed: vitesse du virage; defaut: DEFAULT_TURN_SPEED
- """
- speed_left = self.leftMotor.speed
- speed_right = self.rightMotor.speed
- self.stop()
- if deg > 0:
- self.leftMotor.run_forever(speed_sp=speed)
- else:
- self.rightMotor.run_forever(speed_sp=speed)
- start_gyroscope_value = self.gyroscope.value()
- while abs(self.gyroscope.value() - start_gyroscope_value) < abs(deg):
- pass
- self.stop()
- self.leftMotor.run_forever(speed_sp=speed_left)
- self.rightMotor.run_forever(speed_sp=speed_right)
- def rotate(self, deg, speed=DEFAULT_ROTATE_SPEED):
- """
- Fait tourner le robot d'un certain angle autour de lui meme.
- :param deg: angle de la rotation
- :param speed: votesse de la rotation; defaut: DEFAULT_ROTATE_SPEED
- """
- self.stop()
- if deg > 0:
- self.leftMotor.run_forever(speed_sp=speed)
- self.rightMotor.run_forever(speed_sp=-speed)
- else:
- self.leftMotor.run_forever(speed_sp=-speed)
- self.rightMotor.run_forever(speed_sp=speed)
- start_gyroscope_value = self.gyroscope.value()
- while abs(self.gyroscope.value() - start_gyroscope_value) < abs(deg):
- pass
- self.stop()
- def rotate90(self, deg, speed=DEFAULT_ROTATE_SPEED):
- """
- Fait faire une rotation d'exactement 90° au robot.
- :param deg: positif ou negatif: direction de la rotation
- :param speed: vitesse de la rotation; defaut: DEFAULT_ROTATE_SPEED
- """
- self.stop()
- if deg > 0:
- self.leftMotor.run_forever(speed_sp=speed)
- self.rightMotor.run_forever(speed_sp=-speed)
- else:
- self.leftMotor.run_forever(speed_sp=-speed)
- self.rightMotor.run_forever(speed_sp=speed)
- start_gyroscope_value = self.gyroscope.value()
- while abs(self.gyroscope.value() - start_gyroscope_value) < 90:
- pass
- self.stop()
- self.right_angle()
- def rotate_to_direction(self, direction):
- """
- Fait tourner le robot jusqu'a ce qu'il atteigne une direction (D_WORWARD, D_LEFT, D_BACKWARD, D_RIGHT)
- :param direction: direction a laquelle le robot doit faire face
- """
- if direction == self.D_FORWARD:
- pass
- if direction == self.D_LEFT:
- self.rotate90(-1)
- elif direction == self.D_BACKWARD:
- self.rotate90(-1)
- self.rotate90(-1)
- elif direction == self.D_RIGHT:
- self.rotate90(1)
- def forward_color(self):
- """
- Fait avance le robot jusqu'a ce qu'il atteigne une couleur
- :return: couleur obtenue
- """
- self.forward()
- while True:
- red = self.colorSensor.value(0)
- green = self.colorSensor.value(1)
- blue = self.colorSensor.value(2)
- if (red < 120 and green < 120 and blue < 120) or (red > 120 and green < 100 and blue < 80) or (
- red < 120 and green < 200 and blue > 200) or (red > 110 and green > 140 and blue < 70):
- print({"red": red, "green": green, "blue": blue})
- return {"red": red, "green": green, "blue": blue}
- def print_color(self):
- """
- Affiche la couleur que le capteur capte au moment de l'appel de la fonction
- """
- print("(" + str(self.colorSensor.value(0)), end='')
- print(", " + str(self.colorSensor.value(1)), end='')
- print(", ", str(self.colorSensor.value(2)) + ")")
- def register_colors(self, rgb):
- """
- Enregistre les bandes de couleurs detectees par le robot pendant 1750ms
- :param rgb: premiere couleur detectee par forward_color
- :return: liste des couleurs detectes
- """
- colors = list()
- if rgb["red"] < 120 and rgb["green"] < 120 and rgb["blue"] < 120:
- colors.append(self.C_BLACK)
- elif rgb["red"] > 120 and rgb["green"] < 100 and rgb["blue"] < 80:
- colors.append(self.C_RED)
- elif rgb["red"] < 120 and rgb["green"] < 200 and rgb["blue"] > 200:
- colors.append(self.C_BLUE)
- elif rgb["red"] > 110 and rgb["green"] > 140 and rgb["blue"] < 70:
- colors.append(self.C_YELLOW)
- last = True
- start_time = current_time()
- while current_time() < start_time + 1750:
- red = self.colorSensor.value(0)
- green = self.colorSensor.value(1)
- blue = self.colorSensor.value(2)
- if red < 120 and green < 120 and blue < 120:
- if not last:
- last = True
- colors.append(self.C_BLACK)
- elif red > 120 and green < 100 and blue < 80:
- if not last:
- last = True
- colors.append(self.C_RED)
- elif red < 120 and green < 200 and blue > 200:
- if not last:
- last = True
- colors.append(self.C_BLUE)
- elif red > 110 and green > 140 and blue < 70:
- if not last:
- last = True
- colors.append(self.C_YELLOW)
- else:
- last = False
- print(colors)
- return colors
- def right_angle(self):
- """
- S'assure que le robot est à un angle droit
- """
- if (self.gyroscope.value() % 360) % 90 != 0:
- if (self.gyroscope.value() % 360) < 45:
- self.rotate(0 - (self.gyroscope.value() % 360))
- elif (self.gyroscope.value() % 360) < 90:
- self.rotate(90 - (self.gyroscope.value() % 360))
- elif (self.gyroscope.value() % 360) < 135:
- self.rotate(90 - (self.gyroscope.value() % 360))
- elif (self.gyroscope.value() % 360) < 180:
- self.rotate(180 - (self.gyroscope.value() % 360))
- elif (self.gyroscope.value() % 360) < 225:
- self.rotate(180 - (self.gyroscope.value() % 360))
- elif (self.gyroscope.value() % 360) < 270:
- self.rotate(270 - (self.gyroscope.value() % 360))
- elif (self.gyroscope.value() % 360) < 315:
- self.rotate(270 - (self.gyroscope.value() % 360))
- elif (self.gyroscope.value() % 360) < 360:
- self.rotate(360 - (self.gyroscope.value() % 360))
- def process_colors(self, colors):
- """
- Traite les couleurs obtenues et retourne les directions possibles.
- :param colors: liste des oculeurs obtenues par register_color
- :return: directions possibles
- """
- directions = set()
- if colors.count(self.C_BLACK) > 1:
- directions.add(self.WIN)
- else:
- temp = self.gyroscope.value() % 360
- if self.C_BLACK in colors:
- if 45 <= temp < 135:
- directions.add(self.D_LEFT)
- elif 135 <= temp < 225:
- directions.add(self.D_BACKWARD)
- elif 225 <= temp < 315:
- directions.add(self.D_RIGHT)
- else:
- directions.add(self.D_FORWARD)
- if self.C_RED in colors:
- if 45 <= temp < 135:
- directions.add(self.D_BACKWARD)
- elif 135 <= temp < 225:
- directions.add(self.D_RIGHT)
- elif 225 <= temp < 315:
- directions.add(self.D_FORWARD)
- else:
- directions.add(self.D_LEFT)
- if self.C_BLUE in colors:
- if 45 <= temp < 135:
- directions.add(self.D_FORWARD)
- elif 135 <= temp < 225:
- directions.add(self.D_LEFT)
- elif 225 <= temp < 315:
- directions.add(self.D_BACKWARD)
- else:
- directions.add(self.D_RIGHT)
- if self.C_YELLOW in colors:
- if 45 <= temp < 135:
- directions.add(self.D_RIGHT)
- elif 135 <= temp < 225:
- directions.add(self.D_FORWARD)
- elif 225 <= temp < 315:
- directions.add(self.D_LEFT)
- else:
- directions.add(self.D_BACKWARD)
- return directions
- try:
- # point d'entree du programme
- main()
- finally:
- # force le robot a s'arreter si le programme a une erreur ou est brutalement arrete
- left = LargeMotor("outB")
- right = LargeMotor("outC")
- left.stop()
- right.stop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement