From 51aa74f0c7048b5b64e42fbe75b54b441cd7e609 Mon Sep 17 00:00:00 2001 From: Vinh Luong Date: Fri, 28 Aug 2020 10:55:50 -0700 Subject: [PATCH] official_models/ev3: refactoring --- .../ev3/home/ev3rstorm/.vscode/launch.json | 2 +- .../ev3/home/ev3rstorm/.vscode/settings.json | 3 +- .../ev3/home/ev3rstorm/ev3rstorm.py | 112 ++++++++ official_models/ev3/home/ev3rstorm/main.py | 186 ------------- .../ev3/home/ev3rstorm/rc_tank_util.py | 86 ++++++ .../ev3/home/gripp3r/.vscode/launch.json | 2 +- .../ev3/home/gripp3r/.vscode/settings.json | 3 +- official_models/ev3/home/gripp3r/gripp3r.py | 100 +++++++ official_models/ev3/home/gripp3r/main.py | 172 ------------ .../ev3/home/gripp3r/rc_tank_util.py | 86 ++++++ .../ev3/home/r3ptar/.vscode/launch.json | 2 +- .../ev3/home/r3ptar/.vscode/settings.json | 3 +- .../ev3/home/r3ptar/{main.py => r3ptar.py} | 82 +++--- .../ev3/home/spik3r/.vscode/launch.json | 2 +- .../ev3/home/spik3r/.vscode/settings.json | 3 +- .../ev3/home/spik3r/{main.py => spik3r.py} | 86 +++--- .../ev3/home/track3r/.vscode/launch.json | 2 +- .../ev3/home/track3r/.vscode/settings.json | 3 +- official_models/ev3/home/track3r/main.py | 259 ------------------ .../ev3/home/track3r/rc_tank_util.py | 86 ++++++ .../ev3/home/track3r/track3r_base.py | 57 ++++ .../track3r/track3r_with_biblade_spinner.py | 42 +++ .../track3r/track3r_with_blasting_bazooka.py | 52 ++++ .../track3r/track3r_with_gripping_claw.py | 54 ++++ .../home/track3r/track3r_with_heavy_hammer.py | 60 ++++ 25 files changed, 835 insertions(+), 710 deletions(-) create mode 100644 official_models/ev3/home/ev3rstorm/ev3rstorm.py delete mode 100644 official_models/ev3/home/ev3rstorm/main.py create mode 100644 official_models/ev3/home/ev3rstorm/rc_tank_util.py create mode 100644 official_models/ev3/home/gripp3r/gripp3r.py delete mode 100644 official_models/ev3/home/gripp3r/main.py create mode 100644 official_models/ev3/home/gripp3r/rc_tank_util.py rename official_models/ev3/home/r3ptar/{main.py => r3ptar.py} (51%) rename official_models/ev3/home/spik3r/{main.py => spik3r.py} (54%) delete mode 100644 official_models/ev3/home/track3r/main.py create mode 100644 official_models/ev3/home/track3r/rc_tank_util.py create mode 100644 official_models/ev3/home/track3r/track3r_base.py create mode 100644 official_models/ev3/home/track3r/track3r_with_biblade_spinner.py create mode 100644 official_models/ev3/home/track3r/track3r_with_blasting_bazooka.py create mode 100644 official_models/ev3/home/track3r/track3r_with_gripping_claw.py create mode 100644 official_models/ev3/home/track3r/track3r_with_heavy_hammer.py diff --git a/official_models/ev3/home/ev3rstorm/.vscode/launch.json b/official_models/ev3/home/ev3rstorm/.vscode/launch.json index d933aeb..93c9411 100644 --- a/official_models/ev3/home/ev3rstorm/.vscode/launch.json +++ b/official_models/ev3/home/ev3rstorm/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Download and Run", "type": "ev3devBrowser", "request": "launch", - "program": "/home/robot/${workspaceRootFolderName}/main.py", + "program": "/home/robot/${workspaceRootFolderName}/ev3rstorm.py", "interactiveTerminal": false } ] diff --git a/official_models/ev3/home/ev3rstorm/.vscode/settings.json b/official_models/ev3/home/ev3rstorm/.vscode/settings.json index 37c9a5d..42a109f 100644 --- a/official_models/ev3/home/ev3rstorm/.vscode/settings.json +++ b/official_models/ev3/home/ev3rstorm/.vscode/settings.json @@ -2,5 +2,6 @@ { "files.eol": "\n", "debug.openDebug": "neverOpen", - "python.linting.enabled": false + "editor.rulers": [79], + "python.linting.enabled": true } diff --git a/official_models/ev3/home/ev3rstorm/ev3rstorm.py b/official_models/ev3/home/ev3rstorm/ev3rstorm.py new file mode 100644 index 0000000..4ffedf2 --- /dev/null +++ b/official_models/ev3/home/ev3rstorm/ev3rstorm.py @@ -0,0 +1,112 @@ +#!/usr/bin/env pybricks-micropython + +""" +Example LEGO® MINDSTORMS® EV3 Ev3rstorm Program +----------------------------------------------- + +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 + +Building instructions can be found at: +https://www.lego.com/en-us/themes/mindstorms/buildarobot +""" + +from pybricks.hubs import EV3Brick +from pybricks.ev3devices import Motor, TouchSensor, ColorSensor +from pybricks.media.ev3dev import ImageFile, SoundFile +from pybricks.parameters import Button, Direction, Port, Stop +from pybricks.tools import wait + +from random import randint + +from rc_tank_util import RemoteControlledTank + + +class Ev3rstorm(RemoteControlledTank): + WHEEL_DIAMETER = 26 # milimeters + AXLE_TRACK = 102 # milimeters + + def __init__( + self, + left_track_motor_port: Port = Port.B, + right_track_motor_port: Port = Port.C, + bazooka_blast_motor_port: Port = Port.A, + touch_sensor_port: Port = Port.S1, + color_sensor_port: Port = Port.S3, + ir_sensor_port: Port = Port.S4, + ir_beacon_channel: int = 1): + super().__init__( + wheel_diameter=self.WHEEL_DIAMETER, + axle_track=self.AXLE_TRACK, + left_motor_port=left_track_motor_port, + right_motor_port=right_track_motor_port, + ir_sensor_port=ir_sensor_port, + ir_beacon_channel=ir_beacon_channel) + + self.ev3_brick = EV3Brick() + + self.bazooka_blast_motor = \ + Motor(port=bazooka_blast_motor_port, + positive_direction=Direction.CLOCKWISE) + + self.touch_sensor = TouchSensor(port=touch_sensor_port) + self.color_sensor = ColorSensor(port=color_sensor_port) + + def dance_randomly_if_ir_beacon_button_pressed(self): + """ + Ev3rstorm dances by turning by random angles on the spot + when the Beacon button is pressed + """ + while Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + self.drive_base.turn(angle=randint(-360, 360)) + + def blast_bazooka_if_touched(self): + """ + Ev3rstorm blasts his bazooka when his Touch Sensor is pressed + (inspiration from LEGO Mindstorms EV3 Home Ed.: Ev3rstorm: Tutorial #5) + """ + MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST = 3 * 360 + + if self.touch_sensor.pressed(): + if self.color_sensor.ambient() < 15: + self.ev3_brick.speaker.play_file(file=SoundFile.UP) + + self.bazooka_blast_motor.run_angle( + speed=2 * MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST, + rotation_angle=-MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST, + then=Stop.HOLD, + wait=True) + + self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_1) + + else: + self.ev3_brick.speaker.play_file(file=SoundFile.DOWN) + + self.bazooka_blast_motor.run_angle( + speed=2 * MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST, + rotation_angle=MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST, + then=Stop.HOLD, + wait=True) + + self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_2) + + def main( + self, + driving_speed: float = 1000 # mm/s + ): + """ + Ev3rstorm's main program performing various capabilities + """ + self.ev3_brick.screen.load_image(ImageFile.TARGET) + + while True: + self.drive_by_ir_beacon(speed=driving_speed) + self.dance_randomly_if_ir_beacon_button_pressed() + self.blast_bazooka_if_touched() + wait(1) + + +if __name__ == '__main__': + EV3RSTORM = Ev3rstorm() + EV3RSTORM.main(driving_speed=1000) diff --git a/official_models/ev3/home/ev3rstorm/main.py b/official_models/ev3/home/ev3rstorm/main.py deleted file mode 100644 index e144025..0000000 --- a/official_models/ev3/home/ev3rstorm/main.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env pybricks-micropython - -""" -Example LEGO® MINDSTORMS® EV3 Ev3rstorm Program ------------------------------------------------ - -This program requires LEGO® EV3 MicroPython v2.0. -Download: https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 - -Building instructions can be found at: -https://www.lego.com/en-us/themes/mindstorms/buildarobot -""" - -from pybricks.hubs import EV3Brick -from pybricks.ev3devices import Motor, TouchSensor, ColorSensor, InfraredSensor -from pybricks.media.ev3dev import ImageFile, SoundFile -from pybricks.robotics import DriveBase -from pybricks.parameters import Button, Direction, Port, Stop -from pybricks.tools import wait - -from random import randint - - -class RemoteControlledTank: - """ - This reusable mixin provides the capability of driving a robot with a Driving Base by the IR beacon - """ - def __init__( - self, - wheel_diameter: float, axle_track: float, # both in milimeters - left_motor_port: Port = Port.B, right_motor_port: Port = Port.C, - ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): - self.drive_base = DriveBase(left_motor=Motor(port=left_motor_port, - positive_direction=Direction.CLOCKWISE), - right_motor=Motor(port=right_motor_port, - positive_direction=Direction.CLOCKWISE), - wheel_diameter=wheel_diameter, - axle_track=axle_track) - - self.ir_sensor = InfraredSensor(port=ir_sensor_port) - self.ir_beacon_channel = ir_beacon_channel - - - def drive_by_ir_beacon( - self, - speed: float = 1000, # mm/s - turn_rate: float = 90 # rotational speed deg/s - ): - ir_beacon_button_pressed = set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) - - # forward - if ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_UP}: - self.drive_base.drive( - speed=speed, - turn_rate=0) - - # backward - elif ir_beacon_button_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}: - self.drive_base.drive( - speed=-speed, - turn_rate=0) - - # turn left on the spot - elif ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_DOWN}: - self.drive_base.drive( - speed=0, - turn_rate=-turn_rate) - - # turn right on the spot - elif ir_beacon_button_pressed == {Button.RIGHT_UP, Button.LEFT_DOWN}: - self.drive_base.drive( - speed=0, - turn_rate=turn_rate) - - # turn left forward - elif ir_beacon_button_pressed == {Button.LEFT_UP}: - self.drive_base.drive( - speed=speed, - turn_rate=-turn_rate) - - # turn right forward - elif ir_beacon_button_pressed == {Button.RIGHT_UP}: - self.drive_base.drive( - speed=speed, - turn_rate=turn_rate) - - # turn left backward - elif ir_beacon_button_pressed == {Button.LEFT_DOWN}: - self.drive_base.drive( - speed=-speed, - turn_rate=turn_rate) - - # turn right backward - elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}: - self.drive_base.drive( - speed=-speed, - turn_rate=-turn_rate) - - # otherwise stop - else: - self.drive_base.stop() - - -class Ev3rstorm(RemoteControlledTank): - WHEEL_DIAMETER = 26 # milimeters - AXLE_TRACK = 102 # milimeters - - - def __init__( - self, - left_track_motor_port: Port = Port.B, right_track_motor_port: Port = Port.C, - bazooka_blast_motor_port: Port = Port.A, - touch_sensor_port: Port = Port.S1, color_sensor_port: Port = Port.S3, - ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): - super().__init__( - wheel_diameter=self.WHEEL_DIAMETER, axle_track=self.AXLE_TRACK, - left_motor_port=left_track_motor_port, right_motor_port=right_track_motor_port, - ir_sensor_port=ir_sensor_port, ir_beacon_channel=ir_beacon_channel) - - self.ev3_brick = EV3Brick() - - self.bazooka_blast_motor = Motor(port=bazooka_blast_motor_port, - positive_direction=Direction.CLOCKWISE) - - self.touch_sensor = TouchSensor(port=touch_sensor_port) - self.color_sensor = ColorSensor(port=color_sensor_port) - - - def dance_randomly_if_ir_beacon_button_pressed(self): - """ - Ev3rstorm dances by turning by random angles on the spot when the Beacon button is pressed - """ - while Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - self.drive_base.turn(angle=randint(-360, 360)) - - - def blast_bazooka_if_touched(self): - """ - Ev3rstorm blasts his bazooka when his Touch Sensor is pressed - (inspiration from LEGO Mindstorms EV3 Home Edition: Ev3rstorm: Tutorial #5) - """ - MEDIUM_MOTOR_N_ROTATIONS_PER_BLAST = 3 - MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST = MEDIUM_MOTOR_N_ROTATIONS_PER_BLAST * 360 - - if self.touch_sensor.pressed(): - if self.color_sensor.ambient() < 15: - self.ev3_brick.speaker.play_file(file=SoundFile.UP) - - self.bazooka_blast_motor.run_angle( - speed=2 * MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST, # shoot quickly in half a second - rotation_angle=-MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST, - then=Stop.HOLD, - wait=True) - - self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_1) - - else: - self.ev3_brick.speaker.play_file(file=SoundFile.DOWN) - - self.bazooka_blast_motor.run_angle( - speed=2 * MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST, # shoot quickly in half a second - rotation_angle=MEDIUM_MOTOR_ROTATIONAL_DEGREES_PER_BLAST, - then=Stop.HOLD, - wait=True) - - self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_2) - - - def main(self, - driving_speed: float = 1000 # mm/s - ): - """ - Ev3rstorm's main program performing various capabilities - """ - self.ev3_brick.screen.load_image(ImageFile.TARGET) - - while True: - self.drive_by_ir_beacon(speed=driving_speed) - self.dance_randomly_if_ir_beacon_button_pressed() - self.blast_bazooka_if_touched() - wait(1) - - -if __name__ == '__main__': - EV3RSTORM = Ev3rstorm() - EV3RSTORM.main(driving_speed=1000) diff --git a/official_models/ev3/home/ev3rstorm/rc_tank_util.py b/official_models/ev3/home/ev3rstorm/rc_tank_util.py new file mode 100644 index 0000000..a61394d --- /dev/null +++ b/official_models/ev3/home/ev3rstorm/rc_tank_util.py @@ -0,0 +1,86 @@ +from pybricks.ev3devices import Motor, InfraredSensor +from pybricks.robotics import DriveBase +from pybricks.parameters import Button, Direction, Port + + +class RemoteControlledTank: + """ + This reusable mixin provides the capability of driving a robot + with a Driving Base by the IR beacon + """ + def __init__( + self, + wheel_diameter: float, axle_track: float, # both in milimeters + left_motor_port: Port = Port.B, right_motor_port: Port = Port.C, + ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): + self.drive_base = \ + DriveBase( + left_motor=Motor(port=left_motor_port, + positive_direction=Direction.CLOCKWISE), + right_motor=Motor(port=right_motor_port, + positive_direction=Direction.CLOCKWISE), + wheel_diameter=wheel_diameter, + axle_track=axle_track) + + self.ir_sensor = InfraredSensor(port=ir_sensor_port) + self.ir_beacon_channel = ir_beacon_channel + + def drive_by_ir_beacon( + self, + speed: float = 1000, # mm/s + turn_rate: float = 90 # rotational speed deg/s + ): + ir_beacon_button_pressed = \ + set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) + + # forward + if ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_UP}: + self.drive_base.drive( + speed=speed, + turn_rate=0) + + # backward + elif ir_beacon_button_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}: + self.drive_base.drive( + speed=-speed, + turn_rate=0) + + # turn left on the spot + elif ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_DOWN}: + self.drive_base.drive( + speed=0, + turn_rate=-turn_rate) + + # turn right on the spot + elif ir_beacon_button_pressed == {Button.RIGHT_UP, Button.LEFT_DOWN}: + self.drive_base.drive( + speed=0, + turn_rate=turn_rate) + + # turn left forward + elif ir_beacon_button_pressed == {Button.LEFT_UP}: + self.drive_base.drive( + speed=speed, + turn_rate=-turn_rate) + + # turn right forward + elif ir_beacon_button_pressed == {Button.RIGHT_UP}: + self.drive_base.drive( + speed=speed, + turn_rate=turn_rate) + + # turn left backward + elif ir_beacon_button_pressed == {Button.LEFT_DOWN}: + self.drive_base.drive( + speed=-speed, + turn_rate=turn_rate) + + # turn right backward + elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}: + self.drive_base.drive( + speed=-speed, + turn_rate=-turn_rate) + + # otherwise stop + else: + self.drive_base.stop() diff --git a/official_models/ev3/home/gripp3r/.vscode/launch.json b/official_models/ev3/home/gripp3r/.vscode/launch.json index d933aeb..18fa898 100644 --- a/official_models/ev3/home/gripp3r/.vscode/launch.json +++ b/official_models/ev3/home/gripp3r/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Download and Run", "type": "ev3devBrowser", "request": "launch", - "program": "/home/robot/${workspaceRootFolderName}/main.py", + "program": "/home/robot/${workspaceRootFolderName}/gripp3r.py", "interactiveTerminal": false } ] diff --git a/official_models/ev3/home/gripp3r/.vscode/settings.json b/official_models/ev3/home/gripp3r/.vscode/settings.json index 37c9a5d..42a109f 100644 --- a/official_models/ev3/home/gripp3r/.vscode/settings.json +++ b/official_models/ev3/home/gripp3r/.vscode/settings.json @@ -2,5 +2,6 @@ { "files.eol": "\n", "debug.openDebug": "neverOpen", - "python.linting.enabled": false + "editor.rulers": [79], + "python.linting.enabled": true } diff --git a/official_models/ev3/home/gripp3r/gripp3r.py b/official_models/ev3/home/gripp3r/gripp3r.py new file mode 100644 index 0000000..bf8015b --- /dev/null +++ b/official_models/ev3/home/gripp3r/gripp3r.py @@ -0,0 +1,100 @@ +#!/usr/bin/env pybricks-micropython + +""" +Example LEGO® MINDSTORMS® EV3 Gripp3r Program +--------------------------------------------- + +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 + +Building instructions can be found at: +https://www.lego.com/en-us/themes/mindstorms/buildarobot +""" + +from pybricks.hubs import EV3Brick +from pybricks.ev3devices import Motor, TouchSensor, InfraredSensor +from pybricks.media.ev3dev import SoundFile +from pybricks.parameters import Button, Direction, Port, Stop +from pybricks.tools import wait + +from rc_tank_util import RemoteControlledTank + + +class Gripp3r(RemoteControlledTank): + WHEEL_DIAMETER = 26 # milimeters + AXLE_TRACK = 115 # milimeters + + def __init__( + self, + left_track_motor_port: Port = Port.B, + right_track_motor_port: Port = Port.C, + gripping_motor_port: Port = Port.A, + touch_sensor_port: Port = Port.S1, + ir_sensor_port: Port = Port.S4, + ir_beacon_channel: int = 1): + super().__init__( + wheel_diameter=self.WHEEL_DIAMETER, + axle_track=self.AXLE_TRACK, + left_motor_port=left_track_motor_port, + right_motor_port=right_track_motor_port, + ir_sensor_port=ir_sensor_port, + ir_beacon_channel=ir_beacon_channel) + + self.ev3_brick = EV3Brick() + + self.gripping_motor = Motor(port=gripping_motor_port, + positive_direction=Direction.CLOCKWISE) + + self.touch_sensor = TouchSensor(port=touch_sensor_port) + + self.ir_sensor = InfraredSensor(port=ir_sensor_port) + self.ir_beacon_channel = ir_beacon_channel + + def grip_or_release_by_ir_beacon(self, speed: float = 500): + if Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + if self.touch_sensor.pressed(): + self.ev3_brick.speaker.play_file(file=SoundFile.AIR_RELEASE) + + self.gripping_motor.run_time( + speed=speed, + time=1000, + then=Stop.COAST, + wait=True) + + else: + self.ev3_brick.speaker.play_file(file=SoundFile.AIRBRAKE) + + self.gripping_motor.run(speed=-speed) + + while not self.touch_sensor.pressed(): + pass + + self.gripping_motor.stop() + + while Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + pass + + def main( + self, + driving_speed: float = 1000 # mm/s + ): + """ + Gripp3r's main program performing various capabilities + """ + self.gripping_motor.run_time( + speed=-500, + time=1000, + then=Stop.COAST, + wait=True) + + while True: + self.drive_by_ir_beacon(speed=driving_speed) + self.grip_or_release_by_ir_beacon(speed=500) + wait(1) + + +if __name__ == '__main__': + GRIPP3R = Gripp3r() + GRIPP3R.main(driving_speed=1000) diff --git a/official_models/ev3/home/gripp3r/main.py b/official_models/ev3/home/gripp3r/main.py deleted file mode 100644 index e6592db..0000000 --- a/official_models/ev3/home/gripp3r/main.py +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env pybricks-micropython - -""" -Example LEGO® MINDSTORMS® EV3 Gripp3r Program ---------------------------------------------- - -This program requires LEGO® EV3 MicroPython v2.0. -Download: https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 - -Building instructions can be found at: -https://www.lego.com/en-us/themes/mindstorms/buildarobot -""" - -from pybricks.hubs import EV3Brick -from pybricks.ev3devices import Motor, TouchSensor, InfraredSensor -from pybricks.robotics import DriveBase -from pybricks.media.ev3dev import SoundFile -from pybricks.parameters import Button, Direction, Port, Stop -from pybricks.tools import wait - - -class RemoteControlledTank: - """ - This reusable mixin provides the capability of driving a robot with a Driving Base by the IR beacon - """ - def __init__( - self, - wheel_diameter: float, axle_track: float, # both in milimeters - left_motor_port: Port = Port.B, right_motor_port: Port = Port.C, - ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): - self.driver = DriveBase(left_motor=Motor(port=left_motor_port, - positive_direction=Direction.CLOCKWISE), - right_motor=Motor(port=right_motor_port, - positive_direction=Direction.CLOCKWISE), - wheel_diameter=wheel_diameter, - axle_track=axle_track) - - self.ir_sensor = InfraredSensor(port=ir_sensor_port) - self.ir_beacon_channel = ir_beacon_channel - - - def drive_by_ir_beacon( - self, - speed: float = 1000, # mm/s - turn_rate: float = 90 # rotational speed deg/s - ): - ir_beacon_button_pressed = set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) - - # forward - if ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_UP}: - self.driver.drive( - speed=speed, - turn_rate=0) - - # backward - elif ir_beacon_button_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}: - self.driver.drive( - speed=-speed, - turn_rate=0) - - # turn left on the spot - elif ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_DOWN}: - self.driver.drive( - speed=0, - turn_rate=-turn_rate) - - # turn right on the spot - elif ir_beacon_button_pressed == {Button.RIGHT_UP, Button.LEFT_DOWN}: - self.driver.drive( - speed=0, - turn_rate=turn_rate) - - # turn left forward - elif ir_beacon_button_pressed == {Button.LEFT_UP}: - self.driver.drive( - speed=speed, - turn_rate=-turn_rate) - - # turn right forward - elif ir_beacon_button_pressed == {Button.RIGHT_UP}: - self.driver.drive( - speed=speed, - turn_rate=turn_rate) - - # turn left backward - elif ir_beacon_button_pressed == {Button.LEFT_DOWN}: - self.driver.drive( - speed=-speed, - turn_rate=turn_rate) - - # turn right backward - elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}: - self.driver.drive( - speed=-speed, - turn_rate=-turn_rate) - - # otherwise stop - else: - self.driver.stop() - - -class Gripp3r(RemoteControlledTank): - WHEEL_DIAMETER = 26 # milimeters - AXLE_TRACK = 115 # milimeters - - - def __init__( - self, - left_track_motor_port: Port = Port.B, right_track_motor_port: Port = Port.C, - grip_motor_port: Port = Port.A, - touch_sensor_port: Port = Port.S1, - ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): - super().__init__( - wheel_diameter=self.WHEEL_DIAMETER, axle_track=self.AXLE_TRACK, - left_motor_port=left_track_motor_port, right_motor_port=right_track_motor_port, - ir_sensor_port=ir_sensor_port, ir_beacon_channel=ir_beacon_channel) - - self.ev3_brick = EV3Brick() - - self.grip_motor = Motor(port=grip_motor_port, - positive_direction=Direction.CLOCKWISE) - - self.touch_sensor = TouchSensor(port=touch_sensor_port) - - self.ir_sensor = InfraredSensor(port=ir_sensor_port) - self.ir_beacon_channel = ir_beacon_channel - - - def grip_or_release_by_ir_beacon(self, speed: float = 500): - if Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - if self.touch_sensor.pressed(): - self.ev3_brick.speaker.play_file(file=SoundFile.AIR_RELEASE) - - self.grip_motor.run_time( - speed=speed, - time=1000, - then=Stop.BRAKE, - wait=True) - - else: - self.ev3_brick.speaker.play_file(file=SoundFile.AIRBRAKE) - - self.grip_motor.run(speed=-speed) - - while not self.touch_sensor.pressed(): - pass - - self.grip_motor.stop() - - while Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - pass - - - def main(self): - """ - Gripp3r's main program performing various capabilities - """ - self.grip_motor.run_time( - speed=-500, - time=1000, - then=Stop.BRAKE, - wait=True) - - while True: - self.drive_by_ir_beacon(speed=1000) - self.grip_or_release_by_ir_beacon(speed=500) - wait(1) - - -if __name__ == '__main__': - GRIPP3R = Gripp3r() - GRIPP3R.main() diff --git a/official_models/ev3/home/gripp3r/rc_tank_util.py b/official_models/ev3/home/gripp3r/rc_tank_util.py new file mode 100644 index 0000000..416cffa --- /dev/null +++ b/official_models/ev3/home/gripp3r/rc_tank_util.py @@ -0,0 +1,86 @@ +from pybricks.ev3devices import Motor, InfraredSensor +from pybricks.robotics import DriveBase +from pybricks.parameters import Button, Direction, Port + + +class RemoteControlledTank: + """ + This reusable mixin provides the capability of driving a robot + with a Driving Base by the IR beacon + """ + def __init__( + self, + wheel_diameter: float, axle_track: float, # both in milimeters + left_motor_port: Port = Port.B, right_motor_port: Port = Port.C, + ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): + self.driver = \ + DriveBase( + left_motor=Motor(port=left_motor_port, + positive_direction=Direction.CLOCKWISE), + right_motor=Motor(port=right_motor_port, + positive_direction=Direction.CLOCKWISE), + wheel_diameter=wheel_diameter, + axle_track=axle_track) + + self.ir_sensor = InfraredSensor(port=ir_sensor_port) + self.ir_beacon_channel = ir_beacon_channel + + def drive_by_ir_beacon( + self, + speed: float = 1000, # mm/s + turn_rate: float = 90 # rotational speed deg/s + ): + ir_beacon_button_pressed = \ + set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) + + # forward + if ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_UP}: + self.driver.drive( + speed=speed, + turn_rate=0) + + # backward + elif ir_beacon_button_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}: + self.driver.drive( + speed=-speed, + turn_rate=0) + + # turn left on the spot + elif ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_DOWN}: + self.driver.drive( + speed=0, + turn_rate=-turn_rate) + + # turn right on the spot + elif ir_beacon_button_pressed == {Button.RIGHT_UP, Button.LEFT_DOWN}: + self.driver.drive( + speed=0, + turn_rate=turn_rate) + + # turn left forward + elif ir_beacon_button_pressed == {Button.LEFT_UP}: + self.driver.drive( + speed=speed, + turn_rate=-turn_rate) + + # turn right forward + elif ir_beacon_button_pressed == {Button.RIGHT_UP}: + self.driver.drive( + speed=speed, + turn_rate=turn_rate) + + # turn left backward + elif ir_beacon_button_pressed == {Button.LEFT_DOWN}: + self.driver.drive( + speed=-speed, + turn_rate=turn_rate) + + # turn right backward + elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}: + self.driver.drive( + speed=-speed, + turn_rate=-turn_rate) + + # otherwise stop + else: + self.driver.stop() diff --git a/official_models/ev3/home/r3ptar/.vscode/launch.json b/official_models/ev3/home/r3ptar/.vscode/launch.json index d933aeb..644382d 100644 --- a/official_models/ev3/home/r3ptar/.vscode/launch.json +++ b/official_models/ev3/home/r3ptar/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Download and Run", "type": "ev3devBrowser", "request": "launch", - "program": "/home/robot/${workspaceRootFolderName}/main.py", + "program": "/home/robot/${workspaceRootFolderName}/r3ptar.py", "interactiveTerminal": false } ] diff --git a/official_models/ev3/home/r3ptar/.vscode/settings.json b/official_models/ev3/home/r3ptar/.vscode/settings.json index 37c9a5d..42a109f 100644 --- a/official_models/ev3/home/r3ptar/.vscode/settings.json +++ b/official_models/ev3/home/r3ptar/.vscode/settings.json @@ -2,5 +2,6 @@ { "files.eol": "\n", "debug.openDebug": "neverOpen", - "python.linting.enabled": false + "editor.rulers": [79], + "python.linting.enabled": true } diff --git a/official_models/ev3/home/r3ptar/main.py b/official_models/ev3/home/r3ptar/r3ptar.py similarity index 51% rename from official_models/ev3/home/r3ptar/main.py rename to official_models/ev3/home/r3ptar/r3ptar.py index e81cf2f..28bc355 100644 --- a/official_models/ev3/home/r3ptar/main.py +++ b/official_models/ev3/home/r3ptar/r3ptar.py @@ -4,8 +4,8 @@ Example LEGO® MINDSTORMS® EV3 R3ptar Program -------------------------------------------- -This program requires LEGO® EV3 MicroPython v2.0. -Download: https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 Building instructions can be found at: https://www.lego.com/en-us/themes/mindstorms/buildarobot @@ -28,91 +28,89 @@ class R3ptar: def __init__( self, - steer_motor_port: Port = Port.A, - drive_motor_port: Port = Port.B, - strike_motor_port: Port = Port.D, + steering_motor_port: Port = Port.A, + driving_motor_port: Port = Port.B, + striking_motor_port: Port = Port.D, touch_sensor_port: Port = Port.S1, - ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): + ir_sensor_port: Port = Port.S4, + ir_beacon_channel: int = 1): self.ev3_brick = EV3Brick() - self.steer_motor = Motor(port=steer_motor_port, - positive_direction=Direction.CLOCKWISE) - self.drive_motor = Motor(port=drive_motor_port, - positive_direction=Direction.CLOCKWISE) - self.strike_motor = Motor(port=strike_motor_port, - positive_direction=Direction.CLOCKWISE) + self.steering_motor = Motor(port=steering_motor_port, + positive_direction=Direction.CLOCKWISE) + self.driving_motor = Motor(port=driving_motor_port, + positive_direction=Direction.CLOCKWISE) + self.striking_motor = Motor(port=striking_motor_port, + positive_direction=Direction.CLOCKWISE) self.touch_sensor = TouchSensor(port=touch_sensor_port) self.ir_sensor = InfraredSensor(port=ir_sensor_port) self.ir_beacon_channel = ir_beacon_channel - - def drive_by_ir_beacon(self, speed: float = 1000): - ir_beacons_pressed = set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) + def drive_by_ir_beacon( + self, + speed: float = 1000, # mm/s + ): + ir_beacons_pressed = \ + set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) if ir_beacons_pressed == {Button.LEFT_UP, Button.RIGHT_UP}: - self.drive_motor.run(speed=speed) + self.driving_motor.run(speed=speed) elif ir_beacons_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}: - self.drive_motor.run(speed=-speed) + self.driving_motor.run(speed=-speed) elif ir_beacons_pressed == {Button.LEFT_UP}: - self.steer_motor.run(speed=-500) - - self.drive_motor.run(speed=speed) + self.steering_motor.run(speed=-500) + self.driving_motor.run(speed=speed) elif ir_beacons_pressed == {Button.RIGHT_UP}: - self.steer_motor.run(speed=500) - - self.drive_motor.run(speed=speed) + self.steering_motor.run(speed=500) + self.driving_motor.run(speed=speed) elif ir_beacons_pressed == {Button.LEFT_DOWN}: - self.steer_motor.run(speed=-500) - - self.drive_motor.run(speed=-speed) + self.steering_motor.run(speed=-500) + self.driving_motor.run(speed=-speed) elif ir_beacons_pressed == {Button.RIGHT_DOWN}: - self.steer_motor.run(speed=500) - - self.drive_motor.run(speed=-speed) + self.steering_motor.run(speed=500) + self.driving_motor.run(speed=-speed) else: - self.steer_motor.hold() + self.steering_motor.hold() + self.driving_motor.stop() - self.drive_motor.stop() - - - def bite_by_ir_beacon(self, speed: float = 1000): - if Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - self.strike_motor.run_time( + def strike_by_ir_beacon(self, speed: float = 1000): + if Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + self.striking_motor.run_time( speed=speed, time=1000, - then=Stop.HOLD, + then=Stop.COAST, wait=True) - self.strike_motor.run_time( + self.striking_motor.run_time( speed=-speed, time=1000, then=Stop.COAST, wait=True) - while Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): + while Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): pass - def hiss_if_touched(self): if self.touch_sensor.pressed(): self.ev3_brick.speaker.play_file(file=SoundFile.SNAKE_HISS) - def main(self, speed: float = 1000): """ R3ptar's main program performing various capabilities """ while True: self.drive_by_ir_beacon(speed=speed) - self.bite_by_ir_beacon(speed=speed) + self.strike_by_ir_beacon(speed=speed) self.hiss_if_touched() wait(1) diff --git a/official_models/ev3/home/spik3r/.vscode/launch.json b/official_models/ev3/home/spik3r/.vscode/launch.json index d933aeb..967ea5b 100644 --- a/official_models/ev3/home/spik3r/.vscode/launch.json +++ b/official_models/ev3/home/spik3r/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Download and Run", "type": "ev3devBrowser", "request": "launch", - "program": "/home/robot/${workspaceRootFolderName}/main.py", + "program": "/home/robot/${workspaceRootFolderName}/spik3r.py", "interactiveTerminal": false } ] diff --git a/official_models/ev3/home/spik3r/.vscode/settings.json b/official_models/ev3/home/spik3r/.vscode/settings.json index 37c9a5d..42a109f 100644 --- a/official_models/ev3/home/spik3r/.vscode/settings.json +++ b/official_models/ev3/home/spik3r/.vscode/settings.json @@ -2,5 +2,6 @@ { "files.eol": "\n", "debug.openDebug": "neverOpen", - "python.linting.enabled": false + "editor.rulers": [79], + "python.linting.enabled": true } diff --git a/official_models/ev3/home/spik3r/main.py b/official_models/ev3/home/spik3r/spik3r.py similarity index 54% rename from official_models/ev3/home/spik3r/main.py rename to official_models/ev3/home/spik3r/spik3r.py index b91a870..71d45cb 100644 --- a/official_models/ev3/home/spik3r/main.py +++ b/official_models/ev3/home/spik3r/spik3r.py @@ -4,8 +4,8 @@ Example LEGO® MINDSTORMS® EV3 Spik3r Program -------------------------------------------- -This program requires LEGO® EV3 MicroPython v2.0. -Download: https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 Building instructions can be found at: https://www.lego.com/en-us/themes/mindstorms/buildarobot @@ -25,16 +25,21 @@ class Spik3r: crushing_claw_motor_port: Port = Port.A, moving_motor_port: Port = Port.B, lightning_tail_motor_port: Port = Port.D, - touch_sensor_port: Port = Port.S1, color_sensor_port: Port = Port.S3, - ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): + touch_sensor_port: Port = Port.S1, + color_sensor_port: Port = Port.S3, + ir_sensor_port: Port = Port.S4, + ir_beacon_channel: int = 1): self.ev3_brick = EV3Brick() - self.crushing_claw_motor = Motor(port=crushing_claw_motor_port, - positive_direction=Direction.CLOCKWISE) - self.moving_motor = Motor(port=moving_motor_port, - positive_direction=Direction.CLOCKWISE) - self.lightning_tail_motor = Motor(port=lightning_tail_motor_port, - positive_direction=Direction.CLOCKWISE) + self.crushing_claw_motor = \ + Motor(port=crushing_claw_motor_port, + positive_direction=Direction.CLOCKWISE) + self.moving_motor = \ + Motor(port=moving_motor_port, + positive_direction=Direction.CLOCKWISE) + self.lightning_tail_motor = \ + Motor(port=lightning_tail_motor_port, + positive_direction=Direction.CLOCKWISE) self.ir_sensor = InfraredSensor(port=ir_sensor_port) self.ir_beacon_channel = ir_beacon_channel @@ -42,13 +47,13 @@ class Spik3r: self.touch_sensor = TouchSensor(port=touch_sensor_port) self.color_sensor = ColorSensor(port=color_sensor_port) - - def sting_by_ir_beacon(self): + def sting_by_ir_beacon(self, speed: float = 1000): """ Spik3r stings with its Lightning Tail when the Beacon button is pressed - (inspiration from LEGO Mindstorms EV3 Home Edition: Spik3r: Tutorial #1) + (inspiration from LEGO Mindstorms EV3 Home Ed.: Spik3r: Tutorial #1) """ - if Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): + if Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): self.lightning_tail_motor.run_angle( speed=-750, rotation_angle=220, @@ -58,71 +63,70 @@ class Spik3r: self.ev3_brick.speaker.play_file(file=SoundFile.ERROR_ALARM) self.lightning_tail_motor.run_time( - speed=-1000, + speed=-speed, time=1000, - then=Stop.HOLD, + then=Stop.COAST, wait=True) self.lightning_tail_motor.run_time( - speed=1000, + speed=speed, time=1000, - then=Stop.HOLD, + then=Stop.COAST, wait=True) - while Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): + while Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): pass - - - def move_by_ir_beacon(self): + + def move_by_ir_beacon(self, speed: float = 1000): """ Spik3r moves forward when the IR Beacon's two Up buttons are pressed, and turns right when only the Right Up button is pressed - (inspiration from LEGO Mindstorms EV3 Home Edition: Spik3r: Tutorial #2) + (inspiration from LEGO Mindstorms EV3 Home Ed.: Spik3r: Tutorial #2) """ - ir_buttons_pressed = set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) + ir_buttons_pressed = \ + set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) if ir_buttons_pressed == {Button.RIGHT_UP, Button.LEFT_UP}: - self.moving_motor.run(speed=1000) + self.moving_motor.run(speed=speed) elif ir_buttons_pressed == {Button.RIGHT_UP}: - self.moving_motor.run(speed=-1000) + self.moving_motor.run(speed=-speed) else: self.moving_motor.stop() - - def pinch_if_touched(self): + def pinch_if_touched(self, speed: float = 1000): """ Spik3r crushes objects with its Claw when the Touch Sensor is pressed - (inspiration from LEGO Mindstorms EV3 Home Edition: Spik3r: Tutorial #3) + (inspiration from LEGO Mindstorms EV3 Home Ed.: Spik3r: Tutorial #3) """ if self.touch_sensor.pressed(): self.crushing_claw_motor.run_time( - speed=500, + speed=speed, time=1000, - then=Stop.HOLD, + then=Stop.COAST, wait=True) self.crushing_claw_motor.run_time( - speed=-500, - time=0.3 * 1000, - then=Stop.HOLD, + speed=-speed, + time=1000, + then=Stop.COAST, wait=True) - - def main(self): + def main(self, speed: float = 1000): """ Spik3r's main program performing various capabilities """ self.ev3_brick.screen.load_image(ImageFile.WARNING) - + while True: - self.move_by_ir_beacon() - self.sting_by_ir_beacon() - self.pinch_if_touched() + self.move_by_ir_beacon(speed=speed) + self.sting_by_ir_beacon(speed=speed) + self.pinch_if_touched(speed=speed) wait(1) if __name__ == '__main__': SPIK3R = Spik3r() - SPIK3R.main() + SPIK3R.main(speed=1000) diff --git a/official_models/ev3/home/track3r/.vscode/launch.json b/official_models/ev3/home/track3r/.vscode/launch.json index d933aeb..fdbf744 100644 --- a/official_models/ev3/home/track3r/.vscode/launch.json +++ b/official_models/ev3/home/track3r/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Download and Run", "type": "ev3devBrowser", "request": "launch", - "program": "/home/robot/${workspaceRootFolderName}/main.py", + "program": "/home/robot/${workspaceRootFolderName}/track3r_base.py", "interactiveTerminal": false } ] diff --git a/official_models/ev3/home/track3r/.vscode/settings.json b/official_models/ev3/home/track3r/.vscode/settings.json index 37c9a5d..42a109f 100644 --- a/official_models/ev3/home/track3r/.vscode/settings.json +++ b/official_models/ev3/home/track3r/.vscode/settings.json @@ -2,5 +2,6 @@ { "files.eol": "\n", "debug.openDebug": "neverOpen", - "python.linting.enabled": false + "editor.rulers": [79], + "python.linting.enabled": true } diff --git a/official_models/ev3/home/track3r/main.py b/official_models/ev3/home/track3r/main.py deleted file mode 100644 index 5a0c74b..0000000 --- a/official_models/ev3/home/track3r/main.py +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/env pybricks-micropython - -""" -Example LEGO® MINDSTORMS® EV3 Track3r Program ---------------------------------------------- - -This program requires LEGO® EV3 MicroPython v2.0. -Download: https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 - -Building instructions can be found at: -https://www.lego.com/en-us/themes/mindstorms/buildarobot -""" - -from pybricks.hubs import EV3Brick -from pybricks.ev3devices import Motor, InfraredSensor -from pybricks.media.ev3dev import ImageFile, SoundFile -from pybricks.robotics import DriveBase -from pybricks.parameters import Button, Direction, Port, Stop -from pybricks.tools import wait - - -class RemoteControlledTank: - """ - This reusable mixin provides the capability of driving a robot with a Driving Base by the IR beacon - """ - def __init__( - self, - wheel_diameter: float, axle_track: float, # both in milimeters - left_motor_port: Port = Port.B, right_motor_port: Port = Port.C, - ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): - self.driver = DriveBase(left_motor=Motor(port=left_motor_port, - positive_direction=Direction.CLOCKWISE), - right_motor=Motor(port=right_motor_port, - positive_direction=Direction.CLOCKWISE), - wheel_diameter=wheel_diameter, - axle_track=axle_track) - - self.ir_sensor = InfraredSensor(port=ir_sensor_port) - self.ir_beacon_channel = ir_beacon_channel - - - def drive_by_ir_beacon( - self, - speed: float = 1000, # mm/s - turn_rate: float = 90 # rotational speed deg/s - ): - ir_beacon_button_pressed = set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) - - # forward - if ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_UP}: - self.driver.drive( - speed=speed, - turn_rate=0) - - # backward - elif ir_beacon_button_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}: - self.driver.drive( - speed=-speed, - turn_rate=0) - - # turn left on the spot - elif ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_DOWN}: - self.driver.drive( - speed=0, - turn_rate=-turn_rate) - - # turn right on the spot - elif ir_beacon_button_pressed == {Button.RIGHT_UP, Button.LEFT_DOWN}: - self.driver.drive( - speed=0, - turn_rate=turn_rate) - - # turn left forward - elif ir_beacon_button_pressed == {Button.LEFT_UP}: - self.driver.drive( - speed=speed, - turn_rate=-turn_rate) - - # turn right forward - elif ir_beacon_button_pressed == {Button.RIGHT_UP}: - self.driver.drive( - speed=speed, - turn_rate=turn_rate) - - # turn left backward - elif ir_beacon_button_pressed == {Button.LEFT_DOWN}: - self.driver.drive( - speed=-speed, - turn_rate=turn_rate) - - # turn right backward - elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}: - self.driver.drive( - speed=-speed, - turn_rate=-turn_rate) - - # otherwise stop - else: - self.driver.stop() - - -class Track3r(RemoteControlledTank): - WHEEL_DIAMETER = 26 # milimeters - AXLE_TRACK = 140 # milimeters - - - def __init__( - self, - left_track_motor_port: Port = Port.B, right_track_motor_port: Port = Port.C, - medium_motor_port: Port = Port.A, - ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): - super().__init__( - wheel_diameter=self.WHEEL_DIAMETER, axle_track=self.AXLE_TRACK, - left_motor_port=left_track_motor_port, right_motor_port=right_track_motor_port, - ir_sensor_port=ir_sensor_port, ir_beacon_channel=ir_beacon_channel) - - self.ev3_brick = EV3Brick() - - self.medium_motor = Motor(port=medium_motor_port, - positive_direction=Direction.CLOCKWISE) - - - def main(self): - """ - Driving Track3r around by the IR beacon - """ - while True: - self.drive_by_ir_beacon(speed=1000) - wait(1) - - -class Track3rWithBlastingBazooka(Track3r): - """ - Track3r blasts his bazooka when the Beacon button is pressed - (inspiration from LEGO Mindstorms EV3 Home Edition: Track3r: Tutorial #2) - """ - def blast_bazooka_by_ir_beacon( - self, - speed: float = 1000 # degrees per second - ): - if Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - self.medium_motor.run_angle( - speed=speed, - rotation_angle=3 * 360, # about 3 rotations for 1 shot - then=Stop.HOLD, - wait=True) - - self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_1) - - while Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - pass - - - def main(self): - self.ev3_brick.screen.load_image(ImageFile.PINCHED_MIDDLE) - - while True: - self.drive_by_ir_beacon() - self.blast_bazooka_by_ir_beacon() - wait(1) - - -class Track3rWithGrippingClaw(Track3r): - """ - Track3r grips or releases its claw when the Beacon button is pressed - (inspiration from LEGO Mindstorms EV3 Home Edition: Track3r: Tutorial #3) - """ - - is_gripping = False - - def grip_or_release_claw_by_ir_beacon( - self, - speed: float = 1000 # degrees per second - ): - if Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - if self.is_gripping: - self.medium_motor.run(speed=-speed) - self.ev3_brick.speaker.play_file(file=SoundFile.AIR_RELEASE) - self.is_gripping = False - - else: - self.medium_motor.run(speed=speed) - self.ev3_brick.speaker.play_file(file=SoundFile.AIRBRAKE) - self.is_gripping = True - - while Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - pass - - - def main(self): - while True: - self.drive_by_ir_beacon() - self.grip_or_release_claw_by_ir_beacon() - wait(1) - - -class Track3rWithHeavyHammer(Track3r): - """ - Track3r hammers down when the Beacon button is pressed - (inspiration from LEGO Mindstorms EV3 Home Edition: Track3r: Tutorial #4) - """ - def hammer_by_ir_beacon(self): - if Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - self.ev3_brick.screen.load_image(ImageFile.ANGRY) - - self.medium_motor.run_time( - speed=1000, - time=1000, - then=Stop.HOLD, - wait=True) - - self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_2) - - self.medium_motor.run_time( - speed=-1000, - time=1000, - then=Stop.HOLD, - wait=True) - - - def main(self): - self.medium_motor.run_time( - speed=-200, - time=1000, - then=Stop.HOLD, - wait=True) - - while True: - self.drive_by_ir_beacon() - self.hammer_by_ir_beacon() - wait(1) - - -class Track3rWithBiBladeSpinner(Track3r): - """ - Track3r spins its blade when the Beacon button is pressed - (inspiration from LEGO Mindstorms EV3 Home Edition: Track3r: Tutorial #5) - """ - def spin_blade_by_ir_beacon( - self, - speed: float = 1000 # degrees per second - ): - if Button.BEACON in self.ir_sensor.buttons(channel=self.ir_beacon_channel): - self.medium_motor.run(speed=speed) - - else: - self.medium_motor.stop() - - - def main(self): - while True: - self.drive_by_ir_beacon() - self.spin_blade_by_ir_beacon() - wait(1) - - -if __name__ == '__main__': - TRACK3R = Track3rWithBlastingBazooka() - TRACK3R.main() diff --git a/official_models/ev3/home/track3r/rc_tank_util.py b/official_models/ev3/home/track3r/rc_tank_util.py new file mode 100644 index 0000000..a61394d --- /dev/null +++ b/official_models/ev3/home/track3r/rc_tank_util.py @@ -0,0 +1,86 @@ +from pybricks.ev3devices import Motor, InfraredSensor +from pybricks.robotics import DriveBase +from pybricks.parameters import Button, Direction, Port + + +class RemoteControlledTank: + """ + This reusable mixin provides the capability of driving a robot + with a Driving Base by the IR beacon + """ + def __init__( + self, + wheel_diameter: float, axle_track: float, # both in milimeters + left_motor_port: Port = Port.B, right_motor_port: Port = Port.C, + ir_sensor_port: Port = Port.S4, ir_beacon_channel: int = 1): + self.drive_base = \ + DriveBase( + left_motor=Motor(port=left_motor_port, + positive_direction=Direction.CLOCKWISE), + right_motor=Motor(port=right_motor_port, + positive_direction=Direction.CLOCKWISE), + wheel_diameter=wheel_diameter, + axle_track=axle_track) + + self.ir_sensor = InfraredSensor(port=ir_sensor_port) + self.ir_beacon_channel = ir_beacon_channel + + def drive_by_ir_beacon( + self, + speed: float = 1000, # mm/s + turn_rate: float = 90 # rotational speed deg/s + ): + ir_beacon_button_pressed = \ + set(self.ir_sensor.buttons(channel=self.ir_beacon_channel)) + + # forward + if ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_UP}: + self.drive_base.drive( + speed=speed, + turn_rate=0) + + # backward + elif ir_beacon_button_pressed == {Button.LEFT_DOWN, Button.RIGHT_DOWN}: + self.drive_base.drive( + speed=-speed, + turn_rate=0) + + # turn left on the spot + elif ir_beacon_button_pressed == {Button.LEFT_UP, Button.RIGHT_DOWN}: + self.drive_base.drive( + speed=0, + turn_rate=-turn_rate) + + # turn right on the spot + elif ir_beacon_button_pressed == {Button.RIGHT_UP, Button.LEFT_DOWN}: + self.drive_base.drive( + speed=0, + turn_rate=turn_rate) + + # turn left forward + elif ir_beacon_button_pressed == {Button.LEFT_UP}: + self.drive_base.drive( + speed=speed, + turn_rate=-turn_rate) + + # turn right forward + elif ir_beacon_button_pressed == {Button.RIGHT_UP}: + self.drive_base.drive( + speed=speed, + turn_rate=turn_rate) + + # turn left backward + elif ir_beacon_button_pressed == {Button.LEFT_DOWN}: + self.drive_base.drive( + speed=-speed, + turn_rate=turn_rate) + + # turn right backward + elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}: + self.drive_base.drive( + speed=-speed, + turn_rate=-turn_rate) + + # otherwise stop + else: + self.drive_base.stop() diff --git a/official_models/ev3/home/track3r/track3r_base.py b/official_models/ev3/home/track3r/track3r_base.py new file mode 100644 index 0000000..438460a --- /dev/null +++ b/official_models/ev3/home/track3r/track3r_base.py @@ -0,0 +1,57 @@ +#!/usr/bin/env pybricks-micropython + +""" +Example LEGO® MINDSTORMS® EV3 Track3r Program +--------------------------------------------- + +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 + +Building instructions can be found at: +https://www.lego.com/en-us/themes/mindstorms/buildarobot +""" + +from pybricks.hubs import EV3Brick +from pybricks.ev3devices import Motor +from pybricks.parameters import Direction, Port +from pybricks.tools import wait + +from rc_tank_util import RemoteControlledTank + + +class Track3r(RemoteControlledTank): + WHEEL_DIAMETER = 26 # milimeters + AXLE_TRACK = 140 # milimeters + + def __init__( + self, + left_track_motor_port: Port = Port.B, + right_track_motor_port: Port = Port.C, + medium_motor_port: Port = Port.A, + ir_sensor_port: Port = Port.S4, + ir_beacon_channel: int = 1): + super().__init__( + wheel_diameter=self.WHEEL_DIAMETER, + axle_track=self.AXLE_TRACK, + left_motor_port=left_track_motor_port, + right_motor_port=right_track_motor_port, + ir_sensor_port=ir_sensor_port, + ir_beacon_channel=ir_beacon_channel) + + self.ev3_brick = EV3Brick() + + self.medium_motor = Motor(port=medium_motor_port, + positive_direction=Direction.CLOCKWISE) + + def main(self, speed: float = 1000): + """ + Driving Track3r around by the IR beacon + """ + while True: + self.drive_by_ir_beacon(speed=speed) + wait(1) + + +if __name__ == '__main__': + TRACK3R = Track3r() + TRACK3R.main(speed=1000) diff --git a/official_models/ev3/home/track3r/track3r_with_biblade_spinner.py b/official_models/ev3/home/track3r/track3r_with_biblade_spinner.py new file mode 100644 index 0000000..280b569 --- /dev/null +++ b/official_models/ev3/home/track3r/track3r_with_biblade_spinner.py @@ -0,0 +1,42 @@ +#!/usr/bin/env pybricks-micropython + +""" +Example LEGO® MINDSTORMS® EV3 Track3r Program +--------------------------------------------- + +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 + +Building instructions can be found at: +https://www.lego.com/en-us/themes/mindstorms/buildarobot +""" + +from pybricks.parameters import Button +from pybricks.tools import wait + +from track3r_base import Track3r + + +class Track3rWithBiBladeSpinner(Track3r): + """ + Track3r spins its blade when the Beacon button is pressed + (inspiration from LEGO Mindstorms EV3 Home Edition: Track3r: Tutorial #5) + """ + def spin_blade_by_ir_beacon(self, speed: float = 1000): + if Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + self.medium_motor.run(speed=speed) + + else: + self.medium_motor.stop() + + def main(self, speed: float = 1000): + while True: + self.drive_by_ir_beacon(speed=speed) + self.spin_blade_by_ir_beacon(speed=speed) + wait(1) + + +if __name__ == '__main__': + TRACK3R = Track3rWithBiBladeSpinner() + TRACK3R.main(speed=1000) diff --git a/official_models/ev3/home/track3r/track3r_with_blasting_bazooka.py b/official_models/ev3/home/track3r/track3r_with_blasting_bazooka.py new file mode 100644 index 0000000..d6c2e8f --- /dev/null +++ b/official_models/ev3/home/track3r/track3r_with_blasting_bazooka.py @@ -0,0 +1,52 @@ +#!/usr/bin/env pybricks-micropython + +""" +Example LEGO® MINDSTORMS® EV3 Track3r Program +--------------------------------------------- + +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 + +Building instructions can be found at: +https://www.lego.com/en-us/themes/mindstorms/buildarobot +""" + +from pybricks.media.ev3dev import ImageFile, SoundFile +from pybricks.parameters import Button, Stop +from pybricks.tools import wait + +from track3r_base import Track3r + + +class Track3rWithBlastingBazooka(Track3r): + """ + Track3r blasts his bazooka when the Beacon button is pressed + (inspiration from LEGO Mindstorms EV3 Home Edition: Track3r: Tutorial #2) + """ + def blast_bazooka_by_ir_beacon(self, speed: float = 1000): + if Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + self.medium_motor.run_angle( + speed=speed, + rotation_angle=3 * 360, # about 3 rotations for 1 shot + then=Stop.HOLD, + wait=True) + + self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_1) + + while Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + pass + + def main(self, speed: float = 1000): + self.ev3_brick.screen.load_image(ImageFile.PINCHED_MIDDLE) + + while True: + self.drive_by_ir_beacon(speed=speed) + self.blast_bazooka_by_ir_beacon(speed=speed) + wait(1) + + +if __name__ == '__main__': + TRACK3R = Track3rWithBlastingBazooka() + TRACK3R.main(speed=1000) diff --git a/official_models/ev3/home/track3r/track3r_with_gripping_claw.py b/official_models/ev3/home/track3r/track3r_with_gripping_claw.py new file mode 100644 index 0000000..815daa1 --- /dev/null +++ b/official_models/ev3/home/track3r/track3r_with_gripping_claw.py @@ -0,0 +1,54 @@ +#!/usr/bin/env pybricks-micropython + +""" +Example LEGO® MINDSTORMS® EV3 Track3r Program +--------------------------------------------- + +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 + +Building instructions can be found at: +https://www.lego.com/en-us/themes/mindstorms/buildarobot +""" + +from pybricks.media.ev3dev import SoundFile +from pybricks.parameters import Button +from pybricks.tools import wait + +from track3r_base import Track3r + + +class Track3rWithGrippingClaw(Track3r): + """ + Track3r grips or releases its claw when the Beacon button is pressed + (inspiration from LEGO Mindstorms EV3 Home Edition: Track3r: Tutorial #3) + """ + is_gripping = False + + def grip_or_release_claw_by_ir_beacon(self, speed: float = 1000): + if Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + if self.is_gripping: + self.medium_motor.run(speed=-speed) + self.ev3_brick.speaker.play_file(file=SoundFile.AIR_RELEASE) + self.is_gripping = False + + else: + self.medium_motor.run(speed=speed) + self.ev3_brick.speaker.play_file(file=SoundFile.AIRBRAKE) + self.is_gripping = True + + while Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + pass + + def main(self, speed: float = 1000): + while True: + self.drive_by_ir_beacon(speed=speed) + self.grip_or_release_claw_by_ir_beacon(speed=speed) + wait(1) + + +if __name__ == '__main__': + TRACK3R = Track3rWithGrippingClaw() + TRACK3R.main(speed=1000) diff --git a/official_models/ev3/home/track3r/track3r_with_heavy_hammer.py b/official_models/ev3/home/track3r/track3r_with_heavy_hammer.py new file mode 100644 index 0000000..39ba933 --- /dev/null +++ b/official_models/ev3/home/track3r/track3r_with_heavy_hammer.py @@ -0,0 +1,60 @@ +#!/usr/bin/env pybricks-micropython + +""" +Example LEGO® MINDSTORMS® EV3 Track3r Program +--------------------------------------------- + +This program requires LEGO® EV3 MicroPython v2.0 downloadable at: +https://education.lego.com/en-us/support/mindstorms-ev3/python-for-ev3 + +Building instructions can be found at: +https://www.lego.com/en-us/themes/mindstorms/buildarobot +""" + +from pybricks.media.ev3dev import ImageFile, SoundFile +from pybricks.parameters import Button, Stop +from pybricks.tools import wait + +from track3r_base import Track3r + + +class Track3rWithHeavyHammer(Track3r): + """ + Track3r hammers down when the Beacon button is pressed + (inspiration from LEGO Mindstorms EV3 Home Edition: Track3r: Tutorial #4) + """ + def hammer_by_ir_beacon(self, speed: float = 1000): + if Button.BEACON in \ + self.ir_sensor.buttons(channel=self.ir_beacon_channel): + self.ev3_brick.screen.load_image(ImageFile.ANGRY) + + self.medium_motor.run_time( + speed=speed, + time=1000, + then=Stop.COAST, + wait=True) + + self.ev3_brick.speaker.play_file(file=SoundFile.LAUGHING_2) + + self.medium_motor.run_time( + speed=-speed, + time=1000, + then=Stop.COAST, + wait=True) + + def main(self, speed: float = 1000): + self.medium_motor.run_time( + speed=-200, + time=1000, + then=Stop.COAST, + wait=True) + + while True: + self.drive_by_ir_beacon(speed=speed) + self.hammer_by_ir_beacon(speed=speed) + wait(1) + + +if __name__ == '__main__': + TRACK3R = Track3rWithHeavyHammer() + TRACK3R.main(speed=1000)