Skip to content

Birthday Cake Cutter #67

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 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 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
213ed37
add index for Cake-Cutter
AntoniLuongPham Jul 29, 2021
91f1ba0
move Birthday-Cake-Cutter to remix
AntoniLuongPham Aug 6, 2021
28bf190
add main program
AntoniLuongPham Aug 11, 2021
277f16d
add index.md
AntoniLuongPham Aug 11, 2021
5c92d98
update index.md
AntoniLuongPham Aug 11, 2021
bc14115
update settings
AntoniLuongPham Aug 11, 2021
9d51739
update Birthday-Cake-Cutter program
AntoniLuongPham Aug 11, 2021
6a9c2b1
add Birthday Cake Cutter
AntoniLuongPham Aug 11, 2021
60f7438
update Birthday-Cake-Cutter index.md
AntoniLuongPham Aug 11, 2021
9468c11
refactor Birthday Cake Cutter
AntoniLuongPham Aug 11, 2021
1570bda
remove wrong file
AntoniLuongPham Aug 11, 2021
819927d
refactor Birthday-Cake-Cutter program
AntoniLuongPham Aug 11, 2021
2c702eb
update Birthday-Cake-Cutter index.md
LuongTheVinh Aug 11, 2021
5fda84c
fix positive direction of Birthday Cake Cutter's knife-control motor
AntoniLuongPham Aug 13, 2021
769c545
fix positive directions of Birthday Cake Cutter's wheel motors
AntoniLuongPham Aug 13, 2021
8fb1a63
fix hub.display.image argument in Birthday Cake Cutter
AntoniLuongPham Aug 13, 2021
0106f37
Revert "fix positive directions of Birthday Cake Cutter's wheel motors"
LuongTheVinh Aug 14, 2021
9c4f5b2
update index.md
AntoniLuongPham Aug 17, 2021
64f9ac0
update index.md and jpg
AntoniLuongPham Aug 17, 2021
438d22e
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
4 changes: 4 additions & 0 deletions .prospector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pylint:
disable:
- assignment-from-no-return
- too-many-arguments
32 changes: 31 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,43 @@
{
"editor.rulers": [70],

"files.exclude": {
"**/.git": true,
"**/.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-few-public-methods",
"--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

"python.linting.banditEnabled": true,
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions remix/birthday-cake-cutter/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: "Birthday Bot: Cake Cutter"
maintainer:
user: "TheVinhLuong102"
name: "The Lương-Phạm Family"
image:
local: "birthday-cake-cutter.jpg"
video:
youtube: "yckg0h2E-Ac"
description:
"Strong with a lot of torque, this robot is ready to cut the cake with a knife wielded by its powerful arm. It drives around on four wheels and also sings Happy Birthday. Member of the Lương-Phạm family's Birthday Bots squad, alongside Birthday Candle Blower and Birthday Gift Presenter."
building_instructions:
local: TODO
code: "#program"
---


Control the Birthday Cake Cutter by the Powered-Up Remote as follows:

- Switch between two modes:
- Left Red Button: Driving Mode (center button of Hub will turn green)
- Right Red Button: Cake-Cutting Mode (center button of Hub will turn red)

- Driving Mode: (refer to the `RemoteControlledDriveBase` code below)
- 2 Top/Plus buttons together: drive forward
- 2 Bottom/Minus buttons together: drive backward
- Top-Left/Left-Plus and Bottom-Right/Right-Minus together: turn left on the spot
- Top-Right/Right-Plus and Bottom-Left/Left-Minus together: turn right on the spot
- Top-Left/Left-Plus: turn left forward
- Top-Right/Right-Plus: turn right forward
- Bottom-Left/Left-Minus: turn left backward
- Bottom-Right/Right-Minus: turn right backward

- Cake-Cutting Mode:
- Arm Control:
- Bottom-Left/Left-Minus: bring arm backward
- Top-Left/Left-Plus: bring arm forward
- Knife Control:
- Bottom-Right/Right-Minus: bring knife backward
- Top-Right/Right-Plus: bring knife forward

- Singing Happy Birthday: green Center button


## Technical Design and Safety Notes

For the Arm and Knife to cut hard cakes, we design them with high torque. (The opposite is true for its friend Candle Blower, which needs high speed and low torque for its fan.)

For safety, this robot uses a plastic butter knife. If you want a big, sharp metal knife instead, you have to re-design the knife holder (and operate at your own risk!).


## Program

{% include copy-code.html %}
```python
{% include_relative main.py %}
```
192 changes: 192 additions & 0 deletions remix/birthday-cake-cutter/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
from pybricks.hubs import InventorHub
from pybricks.pupdevices import Motor, Remote
from pybricks.robotics import DriveBase
from pybricks.geometry import Axis
from pybricks.parameters import (
Button,
Color,
Direction as Dir,
Icon,
Port
)


HAPPY_BIRTHDAY_SONG = [
'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'
]


class RemoteControlledDriveBase:
def __init__(self,
wheel_diameter: float, # milimeters
axle_track: float, # milimeters
left_motor_port: Port = Port.A,
left_motor_pos_dir: Dir = Dir.COUNTERCLOCKWISE,
right_motor_port: Port = Port.B,
right_motor_pos_dir: Dir = Dir.CLOCKWISE):
self.drive_base = \
DriveBase(left_motor=Motor(left_motor_port,
left_motor_pos_dir),
right_motor=Motor(right_motor_port,
right_motor_pos_dir),
wheel_diameter=wheel_diameter,
axle_track=axle_track)

self.remote = Remote()
print('Remote Connected!')

def drive_by_remote(self,
speed: float = 1000, # mm/s
turn_rate: float = 90 # rotational deg/s
):
remote_button_pressed = self.remote.buttons.pressed()

# forward
if remote_button_pressed == (Button.LEFT_PLUS,
Button.RIGHT_PLUS):
self.drive_base.drive(speed=speed, turn_rate=0)

# backward
elif remote_button_pressed == (Button.LEFT_MINUS,
Button.RIGHT_MINUS):
self.drive_base.drive(speed=-speed, turn_rate=0)

# turn left on the spot
elif remote_button_pressed == (Button.RIGHT_MINUS,
Button.LEFT_PLUS):
self.drive_base.drive(speed=0, turn_rate=-turn_rate)

# turn right on the spot
elif remote_button_pressed == (Button.LEFT_MINUS,
Button.RIGHT_PLUS):
self.drive_base.drive(speed=0, turn_rate=turn_rate)

# turn left forward
elif remote_button_pressed == (Button.LEFT_PLUS,):
self.drive_base.drive(speed=speed, turn_rate=-turn_rate)

# turn right forward
elif remote_button_pressed == (Button.RIGHT_PLUS,):
self.drive_base.drive(speed=speed, turn_rate=turn_rate)

# turn left backward
elif remote_button_pressed == (Button.LEFT_MINUS,):
self.drive_base.drive(speed=-speed, turn_rate=turn_rate)

# turn right backward
elif remote_button_pressed == (Button.RIGHT_MINUS,):
self.drive_base.drive(speed=-speed, turn_rate=-turn_rate)

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


class BirthdayCakeCutter(RemoteControlledDriveBase):
WHEEL_DIAMETER = 44 # milimeters
AXLE_TRACK = 75 # milimeters

def __init__(self,
left_motor_port: Port = Port.D,
right_motor_port: Port = Port.C,
arm_control_motor_port: Port = Port.A,
knife_control_motor_port: Port = Port.B):
super().__init__(wheel_diameter=self.WHEEL_DIAMETER,
axle_track=self.AXLE_TRACK,
left_motor_port=left_motor_port,
left_motor_pos_dir=Dir.COUNTERCLOCKWISE,
right_motor_port=right_motor_port,
right_motor_pos_dir=Dir.CLOCKWISE)

self.hub = InventorHub(top_side=Axis.X, front_side=Axis.Z)

self.arm_control_motor = \
Motor(port=arm_control_motor_port,
positive_direction=Dir.CLOCKWISE)

self.knife_control_motor = \
Motor(port=knife_control_motor_port,
positive_direction=Dir.COUNTERCLOCKWISE)

self.cake_cutting_mode = False

self.switch_to_driving_mode()

def switch_to_driving_mode(self):
self.cake_cutting_mode = False

self.hub.light.on(color=Color.GREEN)

def switch_to_cake_cutting_mode(self):
self.cake_cutting_mode = True

self.hub.light.on(color=Color.RED)

def switch_mode_by_remote_red_buttons(self):
remote_button_pressed = self.remote.buttons.pressed()

if remote_button_pressed == (Button.LEFT,):
if self.cake_cutting_mode:
self.switch_to_driving_mode()

elif remote_button_pressed == (Button.RIGHT,):
if not self.cake_cutting_mode:
self.switch_to_cake_cutting_mode()

def smile(self):
self.hub.display.image(Icon.HAPPY)

def sing_happy_birthday_by_remote_center_button(self):
if self.remote.buttons.pressed() == (Button.CENTER,):
self.hub.speaker.play_notes(
notes=HAPPY_BIRTHDAY_SONG,
tempo=120)

def control_arm_by_remote_left_buttons(self):
remote_button_pressed = self.remote.buttons.pressed()

if remote_button_pressed == (Button.LEFT_MINUS,):
self.arm_control_motor.run(speed=-100)

elif remote_button_pressed == (Button.LEFT_PLUS,):
self.arm_control_motor.run(speed=100)

else:
self.arm_control_motor.hold()

def control_knife_by_remote_right_buttons(self):
remote_button_pressed = self.remote.buttons.pressed()

if remote_button_pressed == (Button.RIGHT_MINUS,):
self.knife_control_motor.run(speed=-100)

elif remote_button_pressed == (Button.RIGHT_PLUS,):
self.knife_control_motor.run(speed=100)

else:
self.knife_control_motor.hold()


# initialize Birthday Cake Cutter
birthday_cake_cutter = BirthdayCakeCutter()

# make it smile
birthday_cake_cutter.smile()

# remote-control it to drive around, sing and cut the cake
while True:
birthday_cake_cutter.switch_mode_by_remote_red_buttons()

birthday_cake_cutter.sing_happy_birthday_by_remote_center_button()

if birthday_cake_cutter.cake_cutting_mode:
birthday_cake_cutter.control_arm_by_remote_left_buttons()
birthday_cake_cutter.control_knife_by_remote_right_buttons()

else:
# drive slowly to reduce risk of colliding with cake
birthday_cake_cutter.drive_by_remote(speed=50)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# [Disk Color Maze](https://docs.google.com/document/d/1hUiUxl1xtpDF-aG0GPg1tKvbY4T_vwGVMXpsKVLn4AI)