Created
June 9, 2018 21:17
-
-
Save janmasarik/c3bb34739134d5966453b71aa6671eb0 to your computer and use it in GitHub Desktop.
Source code of IA158 homework - Lego EV3(dev) sumo robot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
from ev3dev.ev3 import LargeMotor, ColorSensor, InfraredSensor, TouchSensor, Button, Sound | |
from time import sleep | |
from threading import Thread | |
m1 = LargeMotor('outA') | |
m2 = LargeMotor('outD') | |
cl = ColorSensor() | |
ir = InfraredSensor() | |
# ts = TouchSensor() | |
btn = Button() | |
cl.mode = 'COL-REFLECT' | |
ir.mode = 'IR-PROX' | |
gonna_fly_now_lyrics = """ | |
Trying hard now | |
It's so hard now | |
Trying hard now | |
Gettin' strong now | |
Coming on, now | |
Gettin' strong now | |
Gonna fly now | |
Flyin' high now | |
Gonna fly, fly, fly | |
""" | |
AVOID_LINE = 0 # used as a "global lock" - indicator that maneuver to stay in field is performed | |
def timed_charge(seconds, turn=False, speed=800, ignore_avoid=False): | |
"""Helper function for control of the motors""" | |
if not ignore_avoid and AVOID_LINE: | |
return | |
m1.stop() | |
m2.stop() | |
m1.run_timed(time_sp=seconds * 1000, speed_sp=speed) | |
m2.run_timed(time_sp=seconds * 1000, speed_sp=-speed if turn else speed) | |
sleep(seconds) | |
def turn_around(): | |
"""Reverse and turn robot if he hits the edge of the playground.""" | |
Sound.speak('OHHH OUUUU') | |
print('Turning') | |
global AVOID_LINE | |
AVOID_LINE = 1 | |
timed_charge(2, speed=-1000, ignore_avoid=True) | |
timed_charge(1.3, speed=1000, turn=True, ignore_avoid=True) | |
AVOID_LINE = 0 | |
def fake_and_hit(): | |
"""Robot fakes turn to get off his enemy and then hit him from the side.""" | |
if AVOID_LINE: | |
return | |
m1.stop() | |
m2.stop() | |
print('AMBUSH') | |
m1.run_timed(time_sp=1800, speed_sp=-700) | |
sleep(1.8) | |
Sound.speak('AMBUSH MOTHERF**KER!') | |
timed_charge(2) | |
def charge(): | |
"""Speed up the robot to highest possible speed and aggresively shout.""" | |
if AVOID_LINE: | |
return | |
print('CHAARGE') | |
Sound.speak('DESTROY' * 10) | |
timed_charge(4) | |
Sound.speak(gonna_fly_now_lyrics) # war song | |
def check_line(): | |
"""Assures that robot will detect edge of the battlefield and back off. | |
This is supposed to be run in separate thread to assure that we won't | |
get out of the field in some of the maneuvers. | |
""" | |
while not btn.any(): | |
if cl.value() > 50: # If line is detected, back off and turn around | |
print('line_detected') | |
m1.stop() | |
m2.stop() | |
turn_around() | |
sleep(0.001) | |
class Worker(Thread): | |
def run(self): | |
"""Main function of the robot which contains the offensive functionality.""" | |
c = 0 | |
while not btn.any(): | |
if AVOID_LINE: | |
sleep(0.1) | |
continue | |
# mod 50 to prevent permanent turning of the robot | |
if c % 50 == 0: | |
distances = [] | |
for i in range(42): | |
distance = ir.value() | |
if distance < 60: | |
break # stops turning in case we detect someone close enough | |
timed_charge(0.1, turn=True, speed=1000) | |
distances.append(distance) | |
else: | |
# otherwise gets the minimum and turns to given direction | |
timed_charge(0.1 * distances.index(min(distances)) + 0.1, turn=True, speed=1000) | |
m1.run_forever(speed_sp=900) | |
m2.run_forever(speed_sp=900) | |
# disabled because it wasn't efficient enough in battle conditions | |
# if ts.value(): # on touch of the front sensor, ambush the robot | |
# fake_and_hit() | |
if ir.value() < 60: # charge in case robot is near of us | |
charge() | |
c += 1 | |
sleep(0.1) # to help with counter and assure context switch to more important thread | |
if __name__ == '__main__': | |
Thread(target=check_line).start() | |
Worker().start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment