Skip to content

Birthday Gift Present3r #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8ad6cdd
update Robodoz3r README Update
AntoniLuongPham May 2, 2021
1eb73ab
Merge branch 'master' of https://github.com/pybricks/pybricks-projects
AntoniLuongPham May 14, 2021
2f2ab6f
Merge branch 'master' of https://github.com/pybricks/pybricks-projects
AntoniLuongPham May 18, 2021
699cca5
Merge branch 'master' of https://github.com/pybricks/pybricks-projects
AntoniLuongPham Jun 3, 2021
3c76bfa
Merge branch 'master' of https://github.com/pybricks/pybricks-projects
AntoniLuongPham Jul 29, 2021
a49233b
add mindstorms-ev3/other-models/index.md
AntoniLuongPham Jul 29, 2021
f55b2b3
add Birthday Gift Presenter VSCode settings
AntoniLuongPham Jul 29, 2021
397288c
add Birthday Gift Presenter .GitIgnore
AntoniLuongPham Jul 29, 2021
bd23479
move Birthday-Gift-Presenter to remix
AntoniLuongPham Aug 6, 2021
25fa536
add rc tank util for birthday-gift-presenter
AntoniLuongPham Aug 6, 2021
88a8cf1
add happy birthday song
AntoniLuongPham Aug 6, 2021
9981142
update rc tank util
AntoniLuongPham Aug 6, 2021
5117459
update Birthday-Gift-Presenter VSCode settings
AntoniLuongPham Aug 6, 2021
7cbec2d
update Birthday-Gift-Presenter VSCode settings
AntoniLuongPham Aug 6, 2021
4f0c372
update Birthday-Gift-Presenter VSCode settings
AntoniLuongPham Aug 6, 2021
f7f4b82
update Birthday-Gift-Presenter rc_tank_util
AntoniLuongPham Aug 6, 2021
4d94922
add main program
AntoniLuongPham Aug 6, 2021
9bcfd1f
update Birthday-Gift-Present3r program
AntoniLuongPham Aug 6, 2021
b215535
update Birthday-Gift-Present3r program
AntoniLuongPham Aug 6, 2021
ee01523
add index.md for Birthday-Gift-Presenter
AntoniLuongPham Aug 6, 2021
9be9b53
add photo for Birthday-Gift-Present3r
AntoniLuongPham Aug 6, 2021
4928634
update Birthday-Gift-Present3r VSCode settings
AntoniLuongPham Aug 6, 2021
1e63d22
update Birthday-Gift-Present3r program
AntoniLuongPham Aug 6, 2021
b5e83cf
Merge branch 'pybricks:master' into master
AntoniLuongPham Dec 27, 2021
c26066c
Merge branch 'master' of https://github.com/pybricks/pybricks-projects
LuongTheVinh Dec 26, 2022
1e2572c
update Birthday Gift Presenter program
AntoniLuongPham Feb 5, 2023
1ee4855
Merge branch 'master' of https://github.com/AntoniLuongPham/pybricks-…
AntoniLuongPham Feb 5, 2023
92d6416
Merge branch 'master' of https://github.com/pybricks/pybricks-project…
AntoniLuongPham Feb 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions remix/birthday-gift-present3r/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
venv/
14 changes: 14 additions & 0 deletions remix/birthday-gift-present3r/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp

// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"lego-education.ev3-micropython"
],

// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"ms-python.python"
]
}
17 changes: 17 additions & 0 deletions remix/birthday-gift-present3r/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387

"version": "0.2.0",

"configurations": [
{
"name": "Download and Run",
"type": "ev3devBrowser",
"request": "launch",
"program": "/home/robot/${workspaceRootFolderName}/main.py",
"interactiveTerminal": false
}
]
}
45 changes: 45 additions & 0 deletions remix/birthday-gift-present3r/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Place your settings in this file to overwrite default and user settings.
{
"editor.rulers": [70],

"ev3devBrowser.download.exclude": "{**/*.md,**/*.jpg,**/*.jpeg,**/*.png,**/*.pdf,.vscode/*}",
"ev3devBrowser.download.include": "{**/*.py,**/*.json}",

"files.exclude": {
"**/.mypy_cache": true,
"**/*.pyc": {"when": "$(basename).py"},
"**/__pycache__": true,
"**/.ropeproject": true,
},

"python.analysis.diagnosticSeverityOverrides": {
"reportMissingImports": "none",
},

"python.linting.enabled": true,

"python.linting.pylintEnabled": true,
"python.linting.pylintArgs": [
"--disable", "assignment-from-no-return",
"--disable", "import-error",
"--disable", "missing-class-docstring",
"--disable", "missing-function-docstring",
"--disable", "missing-module-docstring",
"--disable", "no-name-in-module",
"--disable", "too-many-arguments",
],

"python.linting.flake8Enabled": true,

"python.linting.mypyEnabled": true,

"python.linting.pydocstyleEnabled": false,

"python.linting.pycodestyleEnabled": true,

"python.linting.prospectorEnabled": true,

"python.linting.pylamaEnabled": true,

"python.linting.banditEnabled": true,
}
7 changes: 7 additions & 0 deletions remix/birthday-gift-present3r/Happy-Birthday-Song.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
"G3/8", "G3/8", "A3/4", "G3/4", "C4/4", "B3/2",
"G3/8", "G3/8", "A3/4", "G3/4", "D4/4", "C4/2",
"G3/8", "G3/8", "G4/4", "E4/4",
"C4/8", "C4/8", "B3/4", "A3/4",
"F4/8", "F4/8", "E4/4", "C4/4", "D4/4", "C4/2"
]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions remix/birthday-gift-present3r/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: "Birthday Bot: Gift Presenter"
maintainer:
user: "TheVinhLuong102"
name: "The Lương-Phạm Family"
image:
local: "birthday-gift-present3r.jpg"
video:
youtube: "PAk9mxus1Nk"
description:
"A gentlemanly robot who wheels around, sings Happy Birthday and presents gifts with its arms! Member of the Lương-Phạm family's Birthday Bots squad, alongside Birthday Candle Blower and Birthday Cake Cutter."
building_instructions:
local: TODO
code: "#program"
---


Control the Birthday Gift Present3r by the IR Beacon as follows:

- Driving by IR Beacon channel #1: (refer to the `rc_tank_util.RemoteControlledTank` code below)
- 2 Top/Up buttons together: drive forward
- 2 Bottom/Down buttons together: drive backward
- Top-Left/Red-Up and Bottom-Right/Blue-Down together: turn left on the spot
- Top-Right/Blue-Up and Bottom-Left/Red-Down together: turn right on the spot
- Top-Left/Red-Up: turn left forward
- Top-Right/Blue-Up: turn right forward
- Bottom-Left/Red-Down: turn left backward
- Bottom-Right/Blue-Down: turn right backward

- Singing Happy Birthday: IR Beacon button (any channel)

- Controlling the arms by IR Beacon channel #4:
- Lowering the arms: Bottom-Left/Red-Down or Bottom-Right/Blue-Down
- Raising the arms: Top-Left/Red-Up or Top-Right/Blue-Up


## Program

{% include copy-code.html %}
```python
{% include_relative main.py %}
```

`BirthdayGiftPresent3r` uses a remote-controlled tank driving utility whose code is in `rc_tank_util.py` as follows:

{% include copy-code.html %}
```python
{% include_relative rc_tank_util.py %}
```
120 changes: 120 additions & 0 deletions remix/birthday-gift-present3r/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env pybricks-micropython


import json

from pybricks.hubs import EV3Brick
from pybricks.ev3devices import Motor, TouchSensor
from pybricks.media.ev3dev import ImageFile
from pybricks.parameters import Button, Direction, Port

from pybricks.experimental import run_parallel

from rc_tank_util import RemoteControlledTank


HAPPY_BIRTHDAY_SONG = json.load(open('Happy-Birthday-Song.json'))


class BirthdayGiftPresent3r(RemoteControlledTank):
WHEEL_DIAMETER = 44 # milimeters
AXLE_TRACK = 88 # milimeters

def __init__(
self,
left_motor_port: Port = Port.C,
right_motor_port: Port = Port.B,
medium_motor_port: Port = Port.A,
touch_sensor_port: Port = Port.S1,
ir_sensor_port: Port = Port.S4,
driving_ir_beacon_channel: int = 1,
non_driving_ir_beacon_channel: int = 4):
super().__init__(
wheel_diameter=self.WHEEL_DIAMETER,
axle_track=self.AXLE_TRACK,
left_motor_port=left_motor_port,
right_motor_port=right_motor_port,
polarity='inversed',
ir_sensor_port=ir_sensor_port,
ir_beacon_channel=driving_ir_beacon_channel)

self.ev3_brick = EV3Brick()

self.arm_control_motor = \
Motor(port=medium_motor_port,
positive_direction=Direction.COUNTERCLOCKWISE)

self.touch_sensor = TouchSensor(port=touch_sensor_port)

self.non_driving_ir_beacon_channel = \
non_driving_ir_beacon_channel

def start_up(self):
self.ev3_brick.screen.load_image(ImageFile.NEUTRAL)

self.ev3_brick.speaker.set_speech_options(
language='en',
voice='m3',
speed=None,
pitch=None)

self.ev3_brick.speaker.set_volume(
volume=100,
which='_all_')

def lower_or_raise_arms_by_ir_beacon(self):
non_driving_ir_beacon_button_pressed = \
self.ir_sensor.buttons(
channel=self.non_driving_ir_beacon_channel)

if {Button.LEFT_DOWN, Button.RIGHT_DOWN}.intersection(
non_driving_ir_beacon_button_pressed):
self.arm_control_motor.run(speed=-100)

elif {Button.LEFT_UP, Button.RIGHT_UP}.intersection(
non_driving_ir_beacon_button_pressed):
self.arm_control_motor.run(speed=100)

else:
self.arm_control_motor.hold()

def keep_controlling_arms_by_ir_beacon(self):
while True:
self.lower_or_raise_arms_by_ir_beacon()

def say_happy_birthday_if_touch_sensor_pressed(self):
if self.touch_sensor.pressed():
self.ev3_brick.speaker.say(
text='Happy Birthday, My Love!')

def say_happy_birthday_whenever_touch_sensor_pressed(self):
while True:
self.say_happy_birthday_if_touch_sensor_pressed()

def sing_happy_birthday_if_ir_beacon_button_pressed(self):
if Button.BEACON in (self.ir_sensor.buttons(channel=1) +
self.ir_sensor.buttons(channel=2) +
self.ir_sensor.buttons(channel=3) +
self.ir_sensor.buttons(channel=4)):
self.ev3_brick.speaker.play_notes(
notes=HAPPY_BIRTHDAY_SONG,
tempo=120)

def sing_whenever_ir_beacon_button_pressed(self):
while True:
self.sing_happy_birthday_if_ir_beacon_button_pressed()

def main(self):
self.start_up()

run_parallel(
self.keep_driving_by_ir_beacon,
self.keep_controlling_arms_by_ir_beacon,
self.say_happy_birthday_whenever_touch_sensor_pressed,
self.sing_whenever_ir_beacon_button_pressed)


if __name__ == '__main__':
birthday_gift_present3r = BirthdayGiftPresent3r()

birthday_gift_present3r.main()
109 changes: 109 additions & 0 deletions remix/birthday-gift-present3r/rc_tank_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
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, # in milimeters
axle_track: float, # in milimeters
left_motor_port: Port = Port.B,
right_motor_port: Port = Port.C,
polarity: str = 'normal',
ir_sensor_port: Port = Port.S4,
ir_beacon_channel: int = 1):
motor_positive_direction = \
Direction.CLOCKWISE \
if polarity == 'normal' \
else Direction.COUNTERCLOCKWISE
left_motor = \
Motor(port=left_motor_port,
positive_direction=motor_positive_direction)
right_motor = \
Motor(port=right_motor_port,
positive_direction=motor_positive_direction)
self.drive_base = DriveBase(left_motor=left_motor,
right_motor=right_motor,
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 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_DOWN, Button.RIGHT_UP}:
self.drive_base.drive(
speed=0,
turn_rate=-turn_rate)

# turn right on the spot
elif ir_beacon_button_pressed == \
{Button.RIGHT_DOWN, Button.LEFT_UP}:
self.drive_base.drive(
speed=0,
turn_rate=turn_rate)

# turn left forward
elif ir_beacon_button_pressed == {Button.RIGHT_UP}:
self.drive_base.drive(
speed=speed,
turn_rate=-turn_rate)

# turn right forward
elif ir_beacon_button_pressed == {Button.LEFT_UP}:
self.drive_base.drive(
speed=speed,
turn_rate=turn_rate)

# turn left backward
elif ir_beacon_button_pressed == {Button.RIGHT_DOWN}:
self.drive_base.drive(
speed=-speed,
turn_rate=turn_rate)

# turn right backward
elif ir_beacon_button_pressed == {Button.LEFT_DOWN}:
self.drive_base.drive(
speed=-speed,
turn_rate=-turn_rate)

# otherwise stop
else:
self.drive_base.stop()

def keep_driving_by_ir_beacon(self,
speed: float = 1000, # mm/s
turn_rate: float = 90 # deg/s
):
while True:
self.drive_by_ir_beacon(
speed=speed,
turn_rate=turn_rate)