Hardware components | ||||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 |
1…Make two robots according to file(mycar.lxf)
*Caution…prey robot do not need touch sensor.
2…Install OS into each intelligent block
Killer Robot Setup1…Use ev3 device browser and pass motionmodule.py and main.py to intelligent block of killer robot.
2...Connect killer robot to PC2 using bluetooth and complete internet sharing setting.(like picture below)
1…Set up Alexa and LEGO MindStorm according to the following URL
https://www.hackster.io/alexagadgets/lego-mindstorms-voice-challenge-setup-17300f
2…After finishing setup, you should do as mission3 do. Refer this URL.
https://www.hackster.io/alexagadgets/lego-mindstorms-voice-challenge-mission-3-4ed812
3…At Alexa developer console, replace model.json with one I uploaded.
*Caution … in the uploaded file, model.json is a little bit different from what you get when you downloaded agt-missions in Setup session, but in this project, you do not use this change.
To prevent error, make same environment.
4…In mission-03 folder at PC1, replace mission-03.py with one I uploaded and add alexa_move.py in the same hierarchy.(picture below)
(index.js,common.js,util.js,package.json is not changed from one you download.)
5…Connect one robot to PC1 and download mission-03 folder in EV3.
6…Push WIfi-dongle in USB port of EV3 intelligent block. Connect same wifi as PC1 is connecting to.
7…Use PC1 and build SSH connection. If you had a success in wifi-dongle process, intelligent block will be showing IP address. In the terminal, execute {ssh robot@”IP address”}.
Other SetupUse white and red color tape and make field like picture below.
1…At PC2, execute server_alexa.py on the terminal.
*Caution … in the function “client_connect” of mission-03.py, replace variable “host” and “port” with your PC2 IP address and port.(picture below) Same in “main.py”,”server_alexa.py”.
2…At PC1, execute"cd mission-03" and “sudo python3 mission-03.py” through SSH connection.
3…Wait until Alexa is ready and beeps sound. Put each robot at the corner like picture 3.
4…Say “Alexa open mindstorms” and you can tell the prey 3 commands.
At the same time, open debug page on visual studio code and execute main.py on PC2. When you open visual studio code, open folder like picture below.
・killer and prey move around 5×5 square freely.
・each robot can do only 3 actions, go straight 1 square, turn left 90° and turn right 90°.
・Killer do his best automatically according to Q-learing. We have already made Q-table (csv file),so what you have to do is just using it. Place Q_table.csv in the same hierarchy as server.py is.
・Prey move as you command. You command through Alexa. When you say "go forward now", robot go straight, "go left now", turn left 90° and "go right now", turn right 90°.
Demonstration Videomodel.json
JSON{
"interactionModel": {
"languageModel": {
"invocationName": "mindstorms",
"intents": [{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "MoveIntent",
"slots": [{
"name": "Direction",
"type": "DirectionType"
},
{
"name": "Duration",
"type": "AMAZON.NUMBER"
}
],
"samples": [
"{Direction} now",
"{Direction} {Duration} seconds",
"move {Direction} for {Duration} seconds"
]
},
{
"name": "SetSpeedIntent",
"slots": [{
"name": "Speed",
"type": "AMAZON.NUMBER"
}],
"samples": [
"set speed {Speed} percent",
"set {Speed} percent speed",
"set speed to {Speed} percent"
]
},
{
"name": "SetCommandIntent",
"slots": [{
"name": "Command",
"type": "CommandType"
}],
"samples": [
"activate {Command} mode",
"move in a {Command}",
"fire {Command}",
"activate {Command}",
"turn {Command}"
]
}
],
"types": [{
"name": "DirectionType",
"values": [{
"name": {
"value": "brake"
}
},
{
"name": {
"value": "go backward"
}
},
{
"name": {
"value": "go forward"
}
},
{
"name": {
"value": "go right"
}
},
{
"name": {
"value": "go left"
}
},
{
"name": {
"value": "right"
}
},
{
"name": {
"value": "left"
}
},
{
"name": {
"value": "backwards"
}
},
{
"name": {
"value": "backward"
}
},
{
"name": {
"value": "forwards"
}
},
{
"name": {
"value": "forward"
}
}
]
},
{
"name": "CommandType",
"values": [{
"name": {
"value": "circle"
}
},
{
"name": {
"value": "square"
}
},
{
"name": {
"value": "patrol"
}
},
{
"name": {
"value": "cannon"
}
},
{
"name": {
"value": "all shot"
}
},
{
"name": {
"value": "one shot"
}
}
]
}
]
}
}
}
#!/usr/bin/env pybricks-micropython
import sys
import socket
import motion_module
from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase
#Motor
motor_l = Motor(Port.D)
motor_r = Motor(Port.A)
#Sensor
color_l = ColorSensor(Port.S4)
color_r = ColorSensor(Port.S1)
touch = TouchSensor(Port.S2)
#error
def error_exit(err_str):
print(err_str, file=sys.stderr)
sys.exit(1)
#client
def client():
# make client socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect to server
#use IP address and port of server
host = '127.0.0.1'
port = 40000
bufsize = 1
if s.connect((host, port)) == -1:
error_exit('Error: client_p.connect')
# first : receive the action
# second : act in practice
# finally : send the signal of end of action
while True:
# receive the action from server
act = s.recv(bufsize)
if act == -1:
error_exit('Error: client_p.recv')
# at the end of game
if act.decode() == '':
break
act = int(act.decode())
# robot acts in practice
motion_module.adjust_position(color_l, color_r, motor_l, motor_r)
motion_module.move(act, color_l, color_r, motor_l, motor_r, touch)
# send the signal to server to tell the end of action
if s.send(str(act).encode()) == -1:
error_exit('Error: client_p.send')
client()
#!/usr/bin/env pybricks-micropython
from pybricks import ev3brick as brick
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor,
InfraredSensor, UltrasonicSensor, GyroSensor)
from pybricks.parameters import (Port, Stop, Direction, Button, Color,
SoundFile, ImageFile, Align)
from pybricks.tools import print, wait, StopWatch
from pybricks.robotics import DriveBase
# trace WHITE line and stop RED point
# WHITE : course RED : lattice point BLACK : outside
# action ( 0 : go straight, 1 : turn left, 2 :turn right 3 : stay )
def move(action, color_l, color_r, motor_l, motor_r, touch):
if action == 0:
trace_line(color_l, color_r, motor_l, motor_r, touch)
elif action == 1:
turn_l(color_l, color_r, motor_l, motor_r)
elif action == 2:
turn_r(color_l, color_r, motor_l, motor_r)
elif action == 3:
pass
else:
print("move error")
exit(1)
# car moves until RED point
def trace_line(color_l, color_r, motor_l, motor_r, touch):
while color_l.color() != Color.RED and color_r.color() != Color.RED :
if touch.pressed() : # when touch sensor is pressed, stop moving
break
sl = 300 # speed left and right
sr = 300
if color_l.color() == Color.BLACK:
sr /= 3
if color_r.color() == Color.BLACK:
sl /= 3
t = 350
motor_l.run_time(sl, t, Stop.COAST, False)
motor_r.run_time(sr, t, Stop.COAST, True)
# turn left
def turn_l(color_l, color_r, motor_l, motor_r) :
spd = 200
tim = 150
tim2 = 150
while color_l.color() == Color.WHITE:
motor_l.run_time(-spd, tim, Stop.COAST, False)
motor_r.run_time(spd, tim, Stop.COAST, True)
motor_l.run_time(-spd, 1.5*tim, Stop.COAST, False)
motor_r.run_time(spd, 1.5*tim, Stop.COAST, True)
while color_l.color() == Color.BLACK :
motor_l.run_time(-spd, tim, Stop.COAST, False)
motor_r.run_time(spd, tim, Stop.COAST, True)
while color_r.color() == Color.BLACK :
motor_l.run_time(-spd, tim, Stop.COAST, False)
motor_r.run_time(spd, tim, Stop.COAST, True)
motor_l.run_time(-spd, tim2, Stop.COAST, False)
motor_r.run_time(spd, tim2, Stop.COAST, True)
# turn right
def turn_r(color_l, color_r, motor_l, motor_r) :
spd = 200
tim = 150
tim2 = 150
while color_r.color() == Color.WHITE:
motor_l.run_time(spd, tim, Stop.COAST, False)
motor_r.run_time(-spd, tim, Stop.COAST, True)
motor_l.run_time(spd, 1.5*tim, Stop.COAST, False)
motor_r.run_time(-spd, 1.5*tim, Stop.COAST, True)
while color_r.color() == Color.BLACK :
motor_l.run_time(spd, tim, Stop.COAST, False)
motor_r.run_time(-spd, tim, Stop.COAST, True)
while color_l.color() == Color.BLACK :
motor_l.run_time(spd, tim, Stop.COAST, False)
motor_r.run_time(-spd, tim, Stop.COAST, True)
motor_l.run_time(spd, tim2, Stop.COAST, False)
motor_r.run_time(-spd, tim2, Stop.COAST, True)
# adjust position
def adjust_position(color_l, color_r, motor_l, motor_r):
spd = 200
tim0 = 150
tim1 = 450
if color_l.color() == Color.RED or color_r.color() == Color.RED:
while color_l.color() == Color.RED or color_r.color() == Color.RED:
motor_l.run_time(spd, tim0, Stop.COAST, False)
motor_r.run_time(spd, tim0, Stop.COAST, True)
motor_l.run_time(spd, tim1, Stop.COAST, False)
motor_r.run_time(spd, tim1, Stop.COAST, True)
# server used when prey is controlled by human'sinstructions with alexa
import sys
import socket
import threading
import random
import csv
# byte per socket communication
bufsize = 1
# [x, y, direction]
# 0 <= x, y <= 4, direction[0:> 1:^ 2:< 3:v]
state_hun = [4, 0, 1]
state_pre = [0, 4, 3]
# action 0 : go, 1 : turn left, 2 :turn right
Q_table = [[[[[[[0 for act in range(4)] for me_x in range(5)] for me_y in range( \
5)] for op_x in range(5)] for op_y in range(5)] for me_dir in range(4)] for op_dir in range(4)]
# error
def error_exit(err_str):
print(err_str, file=sys.stderr)
sys.exit(1)
# rebuilding QTable from array
def make_Q_table(row, table_number):
for i in range(4): # op_dir
for j in range(4): # me_dir
for a in range(5): # op_y
for b in range(5): # op_x
for c in range(5): # me_y
for d in range(5): # me_x
for k in range(4):
value = k + d * 4 + c * 4 * 5 + b * 4 * 5 * 5 + \
a * 4 * 5 * 5 * 5 + j * 4 * 5 * 5 * 5 * 5 + i * 4 * 5 * 5 * 5 * 5 * 4
if table_number == 1:
Q_table[i][j][a][b][c][d][k] = float(row[value])
elif table_number == -1:
Q_table_escape[i][j][a][b][c][d][k] = row[value]
# opne csv file of array of Q value
def openfile(path, table_number):
with open(path) as fp:
reader = csv.reader(fp)
for row in reader:
make_Q_table(row, table_number)
# decide hunter's action
# hunter acts according to max value of QTalbe
def decide_move():
action = -1
max_Q = -100
for k in range(3):
tmp_Q = Q_table[state_pre[2]][state_hun[2]][state_pre[1] \
][state_pre[0]][state_hun[1]][state_hun[0]][k]
if tmp_Q > max_Q:
max_Q = tmp_Q
action = k
return action
# change the state of hunter from current state and action
def change_state_hunter(act) :
dir = state_hun[2]
if act == 0 :
if dir == 0 :
state_hun[0] += 1
elif dir == 1 :
state_hun[1] += 1
elif dir == 2 :
state_hun[0] -= 1
else :
state_hun[1] -= 1
elif act == 1 :
state_hun[2] = (state_hun[2]+1) % 4
elif act == 2 :
state_hun[2] = (state_hun[2]-1) % 4
# function to communicate with prey
# argument is socket of prey
def escape(sp) :
# first : receive the action from prey
# second : change state of prey
while state_hun[:2] != state_pre[:2] :
# get the signal and change the state of prey
act = sp.recv(bufsize)
if act == -1 :
error_exit('Error: server.recv from prey')
# decode and change (char -> int)
act = int(act.decode())
print('prey : ', act) #test
# change the state of prey according to action
change_state_prey(act)
# close socket of prey
if sp.close() == -1 :
error_exit('Error: server_p.close')
# main function of server
def server() :
# make QTable from csv.file
openfile('./Q_table.csv',1)
# make server socket
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if ss == -1 :
error_exit('Error: socket.socket')
# assign IP address and port num
host = '127.0.0.1'
port = 40000
if ss.bind((host, port)) == -1 :
error_exit('Error: socket.bind')
# the number of client
if ss.listen(2) == -1 :
error_exit('Error: server.bind')
# wait the connection from prey client
print('please start prey')
prey, (cli_add_p, cli_port_p) = ss.accept()
if prey == -1 :
error_exit('Error: server.accept of prey')
# make thread to communicate with prey
threadp = threading.Thread(target = escape, args = (prey,) )
threadp.start()
# wait the connection from hunter client
print('please start hunter')
hunter, (cli_add_h, cli_port_h) = ss.accept()
if hunter == -1 :
error_exit('Error: server.accept of hunter')
# don't accept the connection from now
if ss.close() == -1 :
error_exit('Error: server.close')
print('game start')
# loop of hunter
# first : decide hunter's action
# second : send it to hunter
# third : receive the signal of the end of robot's action
# last : change hunter's state
while state_hun[:2] != state_pre[:2] :
# select action of hunter
act = decide_move()
print('hunter : ', act) #test
# send action to hunter
if hunter.send(str(act).encode()) == -1 :
error_exit('Error: server.send to prey')
# get the signal and change the state of hunter
if hunter.recv(bufsize) == -1 :
error_exit('Error: server.recv from prey')
change_state_hunter(act)
# close socket of hunter
if hunter.close() == -1 :
error_exit('Error: server_p.close')
server()
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# You may not use this file except in compliance with the terms and conditions
# set forth in the accompanying LICENSE.TXT file.
#
# THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS. AMAZON SPECIFICALLY DISCLAIMS, WITH
# RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
import time
import logging
import json
import random
import threading
import alexa_move
import sys
import socket
from enum import Enum
from agt import AlexaGadget
from ev3dev2.led import Leds
from ev3dev2.sound import Sound
from ev3dev2.motor import OUTPUT_A, OUTPUT_B, OUTPUT_D, MoveTank, SpeedPercent, MediumMotor
# Set the logging level to INFO to see messages from AlexaGadget
logging.basicConfig(level=logging.INFO)
# socket
def error_exit(err_str):
print(err_str, file=sys.stderr)
sys.exit(1)
def client_connect():
# make client socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect to server
host = '*********'
port = 40000
if s.connect((host, port)) == -1:
error_exit('Error: client_p.connect')
return s
def client_send(act):
# send the signal to server
if s.send(str(act).encode()) == -1:
error_exit('Error: client_p.send')
class Direction(Enum):
"""
The list of directional commands and their variations.
These variations correspond to the skill slot values.
"""
FORWARD = ['forward', 'forwards', 'go forward']
BACKWARD = ['back', 'backward', 'backwards', 'go backward']
LEFT = ['left', 'go left']
RIGHT = ['right', 'go right']
STOP = ['stop', 'brake']
class Command(Enum):
"""
The list of preset commands and their invocation variation.
These variations correspond to the skill slot values.
"""
MOVE_CIRCLE = ['circle', 'spin']
MOVE_SQUARE = ['square']
PATROL = ['patrol', 'guard mode', 'sentry mode']
FIRE_ONE = ['cannon', '1 shot', 'one shot']
FIRE_ALL = ['all shot']
LEFT = ['left']
RIGHT = ['right']
class MindstormsGadget(AlexaGadget):
"""
A Mindstorms gadget that performs movement based on voice commands.
Two types of commands are supported, directional movement and preset.
"""
def __init__(self):
"""
Performs Alexa Gadget initialization routines and ev3dev resource allocation.
"""
super().__init__()
# Gadget state
self.patrol_mode = False
# Ev3dev initialization
self.leds = Leds()
self.sound = Sound()
self.drive = MoveTank(OUTPUT_A, OUTPUT_D)
self.weapon = MediumMotor(OUTPUT_B)
# Start threads
threading.Thread(target=self._patrol_thread, daemon=True).start()
def on_connected(self, device_addr):
"""
Gadget connected to the paired Echo device.
:param device_addr: the address of the device we connected to
"""
self.leds.set_color("LEFT", "GREEN")
self.leds.set_color("RIGHT", "GREEN")
print("{} connected to Echo device".format(self.friendly_name))
def on_disconnected(self, device_addr):
"""
Gadget disconnected from the paired Echo device.
:param device_addr: the address of the device we disconnected from
"""
self.leds.set_color("LEFT", "BLACK")
self.leds.set_color("RIGHT", "BLACK")
print("{} disconnected from Echo device".format(self.friendly_name))
def on_custom_mindstorms_gadget_control(self, directive):
"""
Handles the Custom.Mindstorms.Gadget control directive.
:param directive: the custom directive with the matching namespace and name
"""
try:
payload = json.loads(directive.payload.decode("utf-8"))
print("Control payload: {}".format(payload))
control_type = payload["type"]
if control_type == "move":
# Expected params: [direction, duration, speed]
self._move(payload["direction"], int(
payload["duration"]), int(payload["speed"]))
if control_type == "command":
# Expected params: [command]
self._activate(payload["command"])
except KeyError:
print("Missing expected parameters: {}".format(directive))
def _move(self, direction, duration: int, speed: int, is_blocking=False):
"""
Handles move commands from the directive.
Right and left movement can under or over turn depending on the surface type.
:param direction: the move direction
:param duration: the duration in seconds
:param speed: the speed percentage as an integer
:param is_blocking: if set, motor run until duration expired before accepting another command
"""
print("Move command: ({}, {}, {}, {})".format(
direction, speed, duration, is_blocking))
if direction in Direction.FORWARD.value:
# self.drive.on_for_seconds(SpeedPercent(speed), SpeedPercent(
# speed), duration, block=is_blocking)
# *******************************************************************
alexa_move.move(0)
alexa_move.adjust_position()
client_send(0)
if direction in Direction.LEFT.value:
alexa_move.move(1)
alexa_move.adjust_position() # changed
client_send(1)
if direction in Direction.RIGHT.value:
alexa_move.move(2)
alexa_move.adjust_position()
client_send(2)
# ***********************************************************************
if direction in Direction.BACKWARD.value:
self.drive.on_for_seconds(
SpeedPercent(-speed), SpeedPercent(-speed), duration, block=is_blocking)
'''
if direction in (Direction.RIGHT.value + Direction.LEFT.value):
self._turn(direction, speed)
self.drive.on_for_seconds(SpeedPercent(speed), SpeedPercent(
speed), duration, block=is_blocking)
'''
if direction in Direction.STOP.value:
self.drive.off()
self.patrol_mode = False
def _activate(self, command, speed=50):
"""
Handles preset commands.
:param command: the preset command
:param speed: the speed if applicable
"""
print("Activate command: ({}, {})".format(command, speed))
if command in Command.MOVE_CIRCLE.value:
self.drive.on_for_seconds(SpeedPercent(
int(speed)), SpeedPercent(5), 12)
if command in Command.MOVE_SQUARE.value:
for i in range(4):
self._move("right", 2, speed, is_blocking=True)
if command in Command.PATROL.value:
# Set patrol mode to resume patrol thread processing
self.patrol_mode = True
if command in Command.FIRE_ONE.value:
print("called")
#self.weapon.on_for_rotations(SpeedPercent(100), 3)
alexa_move.move(2)
if command in Command.FIRE_ALL.value:
self.weapon.on_for_rotations(SpeedPercent(100), 10)
if command in Command.LEFT.value:
self.drive.on_for_seconds(SpeedPercent(0), SpeedPercent(speed), 2)
if command in Command.RIGHT.value:
self.drive.on_for_seconds(SpeedPercent(speed), SpeedPercent(0), 2)
def _turn(self, direction, speed):
"""
Turns based on the specified direction and speed.
Calibrated for hard smooth surface.
:param direction: the turn direction
:param speed: the turn speed
"""
if direction in Direction.LEFT.value:
self.drive.on_for_seconds(SpeedPercent(0), SpeedPercent(speed), 2)
if direction in Direction.RIGHT.value:
self.drive.on_for_seconds(SpeedPercent(speed), SpeedPercent(0), 2)
def _patrol_thread(self):
"""
Performs random movement when patrol mode is activated.
"""
while True:
while self.patrol_mode:
print("Patrol mode activated randomly picks a path")
direction = random.choice(list(Direction))
duration = random.randint(1, 5)
speed = random.randint(1, 4) * 25
while direction == Direction.STOP:
direction = random.choice(list(Direction))
# direction: all except stop, duration: 1-5s, speed: 25, 50, 75, 100
self._move(direction.value[0], duration, speed)
time.sleep(duration)
time.sleep(1)
if __name__ == '__main__':
# Startup sequence
gadget = MindstormsGadget()
gadget.sound.play_song((('C4', 'e'), ('D4', 'e'), ('E5', 'q')))
gadget.leds.set_color("LEFT", "GREEN")
gadget.leds.set_color("RIGHT", "GREEN")
s = client_connect()
# Gadget main entry point
alexa_move.adjust_position()
gadget.main()
# Shutdown sequence
gadget.sound.play_song((('E5', 'e'), ('C4', 'e')))
gadget.leds.set_color("LEFT", "BLACK")
gadget.leds.set_color("RIGHT", "BLACK")
from ev3dev2.motor import LargeMotor, OUTPUT_A, OUTPUT_C, SpeedPercent, MoveTank, Motor, OUTPUT_D
from ev3dev2.sensor import INPUT_1, INPUT_2, INPUT_4
from ev3dev2.sensor.lego import GyroSensor, ColorSensor
from ev3dev2.led import Leds
from ev3dev2.sound import Sound
# Motor
motor_l = Motor(OUTPUT_D)
motor_r = Motor(OUTPUT_A)
# Sensor
color_l = ColorSensor(INPUT_4)
color_r = ColorSensor(INPUT_1)
def judge_red(color):
if color.color == ColorSensor.COLOR_RED:
return True
else:
return False
def judge_white(color):
if color.color == ColorSensor.COLOR_WHITE:
return True
else:
return False
# call function referring argument
# 0...go forward now, 1...go left now, 2...go right now
def move(action):
if action == 0:
trace_line()
elif action == 1:
turn_l()
elif action == 2:
turn_r()
else:
print("move error")
exit(1)
# until colorsensor detect red, keep going
# if the direction of robot is incorrect, fix direction.
def trace_line():
while color_l.color != ColorSensor.COLOR_RED and color_r.color != ColorSensor.COLOR_RED:
print(color_r, color_l)
tank_drive = MoveTank(OUTPUT_A, OUTPUT_D)
sl = 20
sr = 20
if color_l.color == 1:
sr /= 3
if color_r.color == 1:
sl /= 3
tank_drive.on_for_seconds(SpeedPercent(sr), SpeedPercent(sl), 0.5)
# turn right about 90 degree
def turn_r():
spd = 10
tim = 0.15
tank_drive = MoveTank(OUTPUT_A, OUTPUT_D)
while color_r.color == ColorSensor.COLOR_WHITE:
tank_drive.on_for_seconds(SpeedPercent(-spd), SpeedPercent(spd), tim)
tank_drive.on_for_seconds(SpeedPercent(-spd), SpeedPercent(spd), tim)
while color_r.color == ColorSensor.COLOR_BLACK:
tank_drive.on_for_seconds(SpeedPercent(-spd), SpeedPercent(spd), tim)
while color_l.color == ColorSensor.COLOR_BLACK:
tank_drive.on_for_seconds(SpeedPercent(-spd), SpeedPercent(spd), tim)
tank_drive.on_for_seconds(SpeedPercent(-spd), SpeedPercent(spd), tim)
# turn left about 90 degree
def turn_l():
spd = 10
tim = 0.15
tank_drive = MoveTank(OUTPUT_A, OUTPUT_D)
while color_l.color == ColorSensor.COLOR_WHITE:
tank_drive.on_for_seconds(SpeedPercent(spd), SpeedPercent(-spd), tim)
tank_drive.on_for_seconds(SpeedPercent(spd), SpeedPercent(-spd), tim * 1.5)
while color_l.color == ColorSensor.COLOR_BLACK:
tank_drive.on_for_seconds(SpeedPercent(spd), SpeedPercent(-spd), tim)
while color_r.color == ColorSensor.COLOR_BLACK:
tank_drive.on_for_seconds(SpeedPercent(spd), SpeedPercent(-spd), tim)
tank_drive.on_for_seconds(SpeedPercent(spd), SpeedPercent(-spd), tim)
# After detecting red, adjust position to place the body of robot in the center of red square.
def adjust_position():
spd = 10
tim0 = 0.15
tim1 = 0.75
tank_drive = MoveTank(OUTPUT_A, OUTPUT_D)
if color_l.color == ColorSensor.COLOR_RED or color_r.color == ColorSensor.COLOR_RED:
while color_l.color == ColorSensor.COLOR_RED or color_r.color == ColorSensor.COLOR_RED:
tank_drive.on_for_seconds(
SpeedPercent(spd), SpeedPercent(spd), tim0)
tank_drive.on_for_seconds(SpeedPercent(spd), SpeedPercent(spd), tim1)
Comments