Skip to content

Commit

Permalink
42131-cat-bulldozer: Add RC project.
Browse files Browse the repository at this point in the history
  • Loading branch information
laurensvalk committed Feb 28, 2022
1 parent d701476 commit a9f01d9
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 0 deletions.
Binary file removed sets/technic/42114_88010.jpg
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions sets/technic/42131-cat-bulldozer/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: "Cat® D11 Bulldozer"
number: 42131
image:
local: "42131-cat-bulldozer.jpg"
layout: set
description: "Add set description"
---
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions sets/technic/42131-cat-bulldozer/powered-up-remote/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: "Powered Up Remote Control"
maintainer:
user: "pybricks"
name: "The Pybricks Team"
image:
local: "42131-cat-bulldozer-remote.jpg"
description:
"Control the Cat Bulldozer with the Powered Up Remote!"
video:
youtube: "N7OmW-7u8fA"
building_instructions:
external:
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6403271.pdf
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6403276.pdf
code: "#program"
---


# Program

This program lets you drive and operate the Cat® D11 Bulldozer using the
Powered Up remote control. No smartphone required!

When the program begins, it resets the function selector to the zero position,
corresponding to the blade up and down movement. You can select any function
by pressing the *green button* along with one of the gray buttons. This will
change the remote light and switch the function selector as follows:

* Left + (blue): Moves the blade up and down.
* Left − (red): Tilts the blade back and forth.
* Right + (yellow): Moves the ladder up and down.
* Right − (green): Moves the ripper up and down.

Once the function is selected, use the red buttons to control the motor that
powers the selected function.

Use the gray buttons to control the tracks. You can change
the ``DRIVE_ACCELERATION`` value in the code to a lower value to make the
vehicle start and stop driving more gradually. You can also change the speed
by reducing the ``DRIVE_SPEED`` value.


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

This program was inspired by Pybricks user AVCampos' program first shared on
[Eurobricks](https://www.eurobricks.com/forum/index.php?/forums/topic/182012-42131-cat-d11-bulldozer/&page=46&tab=comments#comment-3455837). Be sure
to check out his code and [video](https://www.youtube.com/watch?v=gy3nFvojZ2o)
for additional inspiration.

And thanks to Jim van Gulik who lent his bulldozer to the Pybricks team to
make this program and video.
124 changes: 124 additions & 0 deletions sets/technic/42131-cat-bulldozer/powered-up-remote/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
from pybricks.pupdevices import Motor, Remote
from pybricks.parameters import Button, Color, Direction, Port
from pybricks.tools import wait, StopWatch

# Connect to the remote.
remote = Remote()

# Default speed and acceleration. You can change
# them to make it more realistic.
SWITCH_SPEED = 720
DRIVE_SPEED = 1000
DRIVE_ACCELERATION = 2500
FUNCTION_POWER = 100

# Initialize the motors.
left_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.B)
function_motor = Motor(Port.C)
switch_motor = Motor(Port.D)

left_motor.control.limits(acceleration=DRIVE_ACCELERATION)
right_motor.control.limits(acceleration=DRIVE_ACCELERATION)

# Buttons paired with the green button to make a command.
COMMANDS = {
Button.LEFT_PLUS: ("Blade up/down", 0, Color.BLUE),
Button.LEFT_MINUS: ("Blade tilt", 270, Color.RED),
Button.RIGHT_PLUS: ("Ladder", 180, Color.YELLOW),
Button.RIGHT_MINUS: ("Ripper", 90, Color.GREEN),
}

# Find the right end left endstop positions
right_end = switch_motor.run_until_stalled(500, duty_limit=50)
left_end = switch_motor.run_until_stalled(-500, duty_limit=50)

# The full switch motion ranges 270 degrees. Everything beyond that
# is play towards the endstops, equal in both directions. Since we
# are currently at the left endpoint, we can reset the angle
# accordingly. This way, the functions # are simply at the
# relative positions 0, 90, 180, 270.
switch_motor.reset_angle(-(right_end - left_end - 270) / 2)


def switch_target(target_angle):
# Try up to 5 times.
for i in range(5):

# Keep track of how long we've tried.
watch = StopWatch()
switch_motor.run_target(SWITCH_SPEED, target, wait=False)

# Wait until the stopwatch times out.
while watch.time() < 2000:
wait(10)
# We're done if the motor is on target, so exit
# this function.
if switch_motor.control.done():
return

# Otherwise, we got stuck, so try wiggling around to
# release it.
print("Getting unstuck.")
switch_motor.run_target(SWITCH_SPEED, 0, wait=False)
wait(1500)
switch_motor.run_target(SWITCH_SPEED, 270, wait=False)
wait(1500)


while True:

# Check which buttons are pressed
wait(10)
pressed = remote.buttons.pressed()

# If the center button is pressed, process the
# corresponding command.
if Button.CENTER in pressed:

# Stop driving
right_motor.stop()
left_motor.stop()
function_motor.stop()

# Go through the commands.
for button, command in COMMANDS.items():

# Check if the command has a matching button.
if button in pressed:

# Now we can unpack the command.
name, target, color = command

# Execute command.
print("Selected:", name)
remote.light.on(color)
switch_target(target)

# Wait for the button to be released.
while button in remote.buttons.pressed():
wait(10)

# Activate function_motor motor based on the red buttons.
if Button.LEFT in pressed:
function_motor.dc(FUNCTION_POWER)
elif Button.RIGHT in pressed:
function_motor.dc(-FUNCTION_POWER)
else:
function_motor.stop()

# Choose drive speed based on +/- buttons.
left_speed = 0
right_speed = 0
if Button.LEFT_PLUS in pressed:
left_speed += DRIVE_SPEED
if Button.LEFT_MINUS in pressed:
left_speed -= DRIVE_SPEED
if Button.RIGHT_PLUS in pressed:
right_speed += DRIVE_SPEED
if Button.RIGHT_MINUS in pressed:
right_speed -= DRIVE_SPEED

# Activate the driving motors.
left_motor.run(left_speed)
right_motor.run(right_speed)

0 comments on commit a9f01d9

Please sign in to comment.