mirror of
https://github.com/pybricks/pybricks-projects.git
synced 2026-09-14 18:44:20 +00:00
ev3/gyro_boy: Add sensor input task
Functionality is still not quite the same as EV3-G/Scratch. action_update() should remember the old speed during ultrasonic reaction and then restore it. Also, tuning is a bit off since loop time is ~26ms compared to ~18 in EV3-G/Scratch.
This commit is contained in:
committed by
Laurens Valk
parent
355c526412
commit
e07d3d05e8
@@ -11,6 +11,8 @@ Building instructions can be found at:
|
||||
https://education.lego.com/en-us/support/mindstorms-ev3/building-instructions#building-core
|
||||
"""
|
||||
|
||||
import urandom
|
||||
|
||||
from pybricks.hubs import EV3Brick
|
||||
from pybricks.ev3devices import Motor, UltrasonicSensor, ColorSensor, GyroSensor
|
||||
from pybricks.parameters import Port, Button, Color, ImageFile, SoundFile
|
||||
@@ -21,6 +23,7 @@ ev3 = EV3Brick()
|
||||
|
||||
left_motor = Motor(Port.D)
|
||||
right_motor = Motor(Port.A)
|
||||
arm_motor = Motor(Port.C)
|
||||
|
||||
# Initialize the Color Sensor. It is used to detect the colors that command
|
||||
# which way the robot should move
|
||||
@@ -33,19 +36,92 @@ ultrasonic_sensor = UltrasonicSensor(Port.S4)
|
||||
|
||||
fall_timer = StopWatch()
|
||||
control_loop_timer = StopWatch()
|
||||
action_timer = StopWatch()
|
||||
|
||||
GYRO_CALIBRATION_LOOP_COUNT = 200
|
||||
GYRO_OFFSET_FACTOR = 0.0005
|
||||
TARGET_LOOP_PERIOD = 15 # ms
|
||||
TARGET_LOOP_PERIOD = 25 # ms
|
||||
ARM_MOTOR_SPEED = 600 # deg/s
|
||||
|
||||
# The colors on the stand are mapped to steering and drive speed values.
|
||||
# ACTION_MAP = {
|
||||
# Color.RED: (0, 0), # stop
|
||||
# Color.GREEN: (0, 150), # drive forward
|
||||
# Color.BLUE: (-70, 0), # turn left
|
||||
# Color.YELLOW: (70, 0), # turn right
|
||||
# Color.WHITE: (0, -75), # drive backward
|
||||
# }
|
||||
ACTION_MAP = {
|
||||
Color.RED: (0, 0), # stop
|
||||
Color.GREEN: (0, 150), # drive forward
|
||||
Color.BLUE: (-70, 0), # turn left
|
||||
Color.YELLOW: (70, 0), # turn right
|
||||
Color.WHITE: (0, -75), # drive backward
|
||||
}
|
||||
|
||||
|
||||
# This function monitors the color sensor and ultrasonic sensor. It is important
|
||||
# that no blocking calls are made in this function, otherwise it will affect the
|
||||
# control loop time in the main program.
|
||||
def update_action():
|
||||
arm_motor.reset_angle(0)
|
||||
action_timer.reset()
|
||||
|
||||
# drive forward for 4 seconds to leave stand
|
||||
yield 0, 40
|
||||
while action_timer.time() < 4000:
|
||||
yield
|
||||
|
||||
# stop
|
||||
yield 0, 0
|
||||
|
||||
# start checking sensors on arms
|
||||
while True:
|
||||
# Look up the detected color in the action map
|
||||
action = ACTION_MAP.get(color_sensor.color())
|
||||
|
||||
# If the color was found, beep for 0.1 seconds and then yield the action
|
||||
if action is not None:
|
||||
action_timer.reset()
|
||||
ev3.speaker.beep(1000, -1)
|
||||
while action_timer.time() < 100:
|
||||
yield
|
||||
ev3.speaker.beep(0, -1)
|
||||
yield action
|
||||
|
||||
# If the measured distance of the ultrasonic sensor is less than 250
|
||||
# millimeters, then back up slowly.
|
||||
if ultrasonic_sensor.distance() < 250:
|
||||
yield 0, -10
|
||||
|
||||
# Wiggle the arms back and forth
|
||||
arm_motor.run_angle(ARM_MOTOR_SPEED, 30, wait=False)
|
||||
while not arm_motor.control.done():
|
||||
yield
|
||||
arm_motor.run_angle(ARM_MOTOR_SPEED, -60, wait=False)
|
||||
while not arm_motor.control.done():
|
||||
yield
|
||||
arm_motor.run_angle(ARM_MOTOR_SPEED, 30, wait=False)
|
||||
while not arm_motor.control.done():
|
||||
yield
|
||||
|
||||
# Randomly turn left or right for 4 seconds
|
||||
yield urandom.choice([70, -70]), -10
|
||||
action_timer.reset()
|
||||
while action_timer.time() < 4000:
|
||||
yield
|
||||
|
||||
action_timer.reset()
|
||||
ev3.speaker.beep(1000, -1)
|
||||
while action_timer.time() < 100:
|
||||
yield
|
||||
ev3.speaker.beep(0, -1)
|
||||
|
||||
yield 0, 0
|
||||
|
||||
action_timer.reset()
|
||||
while action_timer.time() < 100:
|
||||
yield
|
||||
|
||||
|
||||
# If we fall over in the middle of an action, the arm motors could be moving or
|
||||
# the speaker could be beeping, so we need to stop those.
|
||||
def stop_action():
|
||||
ev3.speaker.beep(0, -1)
|
||||
arm_motor.run_target(ARM_MOTOR_SPEED, 0)
|
||||
|
||||
|
||||
while True:
|
||||
@@ -64,6 +140,8 @@ while True:
|
||||
control_loop_count = 0
|
||||
robot_body_angle = -0.25
|
||||
|
||||
action_task = update_action()
|
||||
|
||||
# Calibrate gyro offset
|
||||
while True:
|
||||
gyro_minimum_rate, gyro_maximum_rate = 440, -440
|
||||
@@ -132,12 +210,15 @@ while True:
|
||||
elif fall_timer.time() > 1000:
|
||||
break
|
||||
|
||||
# TODO: add sensor checks to control drive_speed and steering
|
||||
action = next(action_task)
|
||||
if action is not None:
|
||||
steering, drive_speed = action
|
||||
|
||||
# make sure loop time is at least TARGET_LOOP_PERIOD
|
||||
wait(TARGET_LOOP_PERIOD - control_loop_period)
|
||||
|
||||
# Handle falling over
|
||||
stop_action()
|
||||
left_motor.stop()
|
||||
right_motor.stop()
|
||||
ev3.light.on(Color.RED)
|
||||
|
||||
Reference in New Issue
Block a user