Skip to content

Commit a9f01d9

Browse files
committed
42131-cat-bulldozer: Add RC project.
1 parent d701476 commit a9f01d9

File tree

6 files changed

+188
-0
lines changed

6 files changed

+188
-0
lines changed

sets/technic/42114_88010.jpg

-198 KB
Binary file not shown.
185 KB
Loading
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: "Cat® D11 Bulldozer"
3+
number: 42131
4+
image:
5+
local: "42131-cat-bulldozer.jpg"
6+
layout: set
7+
description: "Add set description"
8+
---
193 KB
Loading
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: "Powered Up Remote Control"
3+
maintainer:
4+
user: "pybricks"
5+
name: "The Pybricks Team"
6+
image:
7+
local: "42131-cat-bulldozer-remote.jpg"
8+
description:
9+
"Control the Cat Bulldozer with the Powered Up Remote!"
10+
video:
11+
youtube: "N7OmW-7u8fA"
12+
building_instructions:
13+
external:
14+
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6403271.pdf
15+
- https://www.lego.com/cdn/product-assets/product.bi.core.pdf/6403276.pdf
16+
code: "#program"
17+
---
18+
19+
20+
# Program
21+
22+
This program lets you drive and operate the Cat® D11 Bulldozer using the
23+
Powered Up remote control. No smartphone required!
24+
25+
When the program begins, it resets the function selector to the zero position,
26+
corresponding to the blade up and down movement. You can select any function
27+
by pressing the *green button* along with one of the gray buttons. This will
28+
change the remote light and switch the function selector as follows:
29+
30+
* Left + (blue): Moves the blade up and down.
31+
* Left − (red): Tilts the blade back and forth.
32+
* Right + (yellow): Moves the ladder up and down.
33+
* Right − (green): Moves the ripper up and down.
34+
35+
Once the function is selected, use the red buttons to control the motor that
36+
powers the selected function.
37+
38+
Use the gray buttons to control the tracks. You can change
39+
the ``DRIVE_ACCELERATION`` value in the code to a lower value to make the
40+
vehicle start and stop driving more gradually. You can also change the speed
41+
by reducing the ``DRIVE_SPEED`` value.
42+
43+
44+
{% include copy-code.html %}
45+
```python
46+
{% include_relative main.py %}
47+
```
48+
# Credits
49+
50+
This program was inspired by Pybricks user AVCampos' program first shared on
51+
[Eurobricks](https://www.eurobricks.com/forum/index.php?/forums/topic/182012-42131-cat-d11-bulldozer/&page=46&tab=comments#comment-3455837). Be sure
52+
to check out his code and [video](https://www.youtube.com/watch?v=gy3nFvojZ2o)
53+
for additional inspiration.
54+
55+
And thanks to Jim van Gulik who lent his bulldozer to the Pybricks team to
56+
make this program and video.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
from pybricks.pupdevices import Motor, Remote
2+
from pybricks.parameters import Button, Color, Direction, Port
3+
from pybricks.tools import wait, StopWatch
4+
5+
# Connect to the remote.
6+
remote = Remote()
7+
8+
# Default speed and acceleration. You can change
9+
# them to make it more realistic.
10+
SWITCH_SPEED = 720
11+
DRIVE_SPEED = 1000
12+
DRIVE_ACCELERATION = 2500
13+
FUNCTION_POWER = 100
14+
15+
# Initialize the motors.
16+
left_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
17+
right_motor = Motor(Port.B)
18+
function_motor = Motor(Port.C)
19+
switch_motor = Motor(Port.D)
20+
21+
left_motor.control.limits(acceleration=DRIVE_ACCELERATION)
22+
right_motor.control.limits(acceleration=DRIVE_ACCELERATION)
23+
24+
# Buttons paired with the green button to make a command.
25+
COMMANDS = {
26+
Button.LEFT_PLUS: ("Blade up/down", 0, Color.BLUE),
27+
Button.LEFT_MINUS: ("Blade tilt", 270, Color.RED),
28+
Button.RIGHT_PLUS: ("Ladder", 180, Color.YELLOW),
29+
Button.RIGHT_MINUS: ("Ripper", 90, Color.GREEN),
30+
}
31+
32+
# Find the right end left endstop positions
33+
right_end = switch_motor.run_until_stalled(500, duty_limit=50)
34+
left_end = switch_motor.run_until_stalled(-500, duty_limit=50)
35+
36+
# The full switch motion ranges 270 degrees. Everything beyond that
37+
# is play towards the endstops, equal in both directions. Since we
38+
# are currently at the left endpoint, we can reset the angle
39+
# accordingly. This way, the functions # are simply at the
40+
# relative positions 0, 90, 180, 270.
41+
switch_motor.reset_angle(-(right_end - left_end - 270) / 2)
42+
43+
44+
def switch_target(target_angle):
45+
# Try up to 5 times.
46+
for i in range(5):
47+
48+
# Keep track of how long we've tried.
49+
watch = StopWatch()
50+
switch_motor.run_target(SWITCH_SPEED, target, wait=False)
51+
52+
# Wait until the stopwatch times out.
53+
while watch.time() < 2000:
54+
wait(10)
55+
# We're done if the motor is on target, so exit
56+
# this function.
57+
if switch_motor.control.done():
58+
return
59+
60+
# Otherwise, we got stuck, so try wiggling around to
61+
# release it.
62+
print("Getting unstuck.")
63+
switch_motor.run_target(SWITCH_SPEED, 0, wait=False)
64+
wait(1500)
65+
switch_motor.run_target(SWITCH_SPEED, 270, wait=False)
66+
wait(1500)
67+
68+
69+
while True:
70+
71+
# Check which buttons are pressed
72+
wait(10)
73+
pressed = remote.buttons.pressed()
74+
75+
# If the center button is pressed, process the
76+
# corresponding command.
77+
if Button.CENTER in pressed:
78+
79+
# Stop driving
80+
right_motor.stop()
81+
left_motor.stop()
82+
function_motor.stop()
83+
84+
# Go through the commands.
85+
for button, command in COMMANDS.items():
86+
87+
# Check if the command has a matching button.
88+
if button in pressed:
89+
90+
# Now we can unpack the command.
91+
name, target, color = command
92+
93+
# Execute command.
94+
print("Selected:", name)
95+
remote.light.on(color)
96+
switch_target(target)
97+
98+
# Wait for the button to be released.
99+
while button in remote.buttons.pressed():
100+
wait(10)
101+
102+
# Activate function_motor motor based on the red buttons.
103+
if Button.LEFT in pressed:
104+
function_motor.dc(FUNCTION_POWER)
105+
elif Button.RIGHT in pressed:
106+
function_motor.dc(-FUNCTION_POWER)
107+
else:
108+
function_motor.stop()
109+
110+
# Choose drive speed based on +/- buttons.
111+
left_speed = 0
112+
right_speed = 0
113+
if Button.LEFT_PLUS in pressed:
114+
left_speed += DRIVE_SPEED
115+
if Button.LEFT_MINUS in pressed:
116+
left_speed -= DRIVE_SPEED
117+
if Button.RIGHT_PLUS in pressed:
118+
right_speed += DRIVE_SPEED
119+
if Button.RIGHT_MINUS in pressed:
120+
right_speed -= DRIVE_SPEED
121+
122+
# Activate the driving motors.
123+
left_motor.run(left_speed)
124+
right_motor.run(right_speed)

0 commit comments

Comments
 (0)