This repository contains example programs for official and unofficial LEGO models, made using Pybricks MicroPython
For suggestions and troubleshooting, please create an issue on our support issue tracker.
Example programs for Pybricks
License: MIT License
This repository contains example programs for official and unofficial LEGO models, made using Pybricks MicroPython
For suggestions and troubleshooting, please create an issue on our support issue tracker.
We need to add a CONTRIBUTING.md
guide with instructions to submit projects or fixes to existing projects.
Hello,
Could you help me to identify which page of the instructions plan shows me how to Integrate the color sensor required by the python source code?
My guess is that some building instructions are missing for the color sensor https://pybricks.com/projects/sets/mindstorms-ev3/home-bonus/dinor3x/
Please advise.
Thank you in advance for your feedback.
Regards,
Sam & Lenny (4 yrs old), Lego fans
It would be nice to add READMEs to each folder with pictures and descriptions for easier navigation of the repository.
So I have 3 scripts that I need a location for.
a script for trains with lights.
purpose: make a remote optional for trains:
hub button can start/stop motor, stop script or turn off hub.
dynamically re-connects to a remote when available (fill in name for a specific one)
speed / brightness is loaded from flash on start and saved on change.
location proposed: projects->sets->city & train->"trains with lights and optional remote"
a diagnostics script.
purpose: dynamically scans all ports for devices and sets motors and reads sensors.
can run on any hub with any motor/sensor attached.
location: does not fit under sets, tutorials or remix.
right now there is a pull request open for pybricks-api but I agree that it IS a large script.
Might be interesting though to get a reference to it from pybricks-api: pupdevices page as well.
single button example (short script).
purpose: a more universal version of https://docs.pybricks.com/en/latest/hubs/cityhub.html -> "Using the stop button during your program" and similar ones for other hubs.
it checks the button during runtime and has different actions for
short press, 2s press (exit) and 5s press (power off).
location: if you are ok with it I could replace the existing example with this one.
Let me know if you agree with the locations.
It looks like it should be possible to create links to download individual folders instead of having to download the entire repository.
https://stackoverflow.com/questions/7106012/download-a-single-folder-or-directory-from-a-github-repo
Hi everybody
I get errors, until I changed the drive.settings on line 53 from drive.settings(1000, 5000) to drive.settings(500, 5000)
Is there a new limit in the latest firmware?
A half a year ago the code was running fine on my R2D2.
Best Regards
Jonas
Hi,
when I tried to load the newest code
from pybricks.pupdevices import Motor, Remote
from pybricks.parameters import Port, Direction, Stop, Button
from pybricks.tools import wait
# Initialize the motors.
steer = Motor(Port.C)
# Initialize the motors with increased smoothness profile.
front = Motor(Port.A, Direction.COUNTERCLOCKWISE, profile=360)
rear = Motor(Port.B, Direction.COUNTERCLOCKWISE, profile=360)
# Lower the acceleration so the car starts and stops realistically.
front.control.limits(acceleration=1000)
rear.control.limits(acceleration=1000)
# Connect to the remote.
remote = Remote()
# Find the steering endpoint on the left and right.
# The middle is in between.
left_end = steer.run_until_stalled(-200, then=Stop.HOLD)
right_end = steer.run_until_stalled(200, then=Stop.HOLD)
# We are now at the right. Reset this angle to be half the difference.
# That puts zero in the middle.
steer.reset_angle((right_end - left_end) / 2)
steer.run_target(speed=200, target_angle=0, wait=False)
# Now we can start driving!
while True:
# Check which buttons are pressed.
pressed = remote.buttons.pressed()
# Choose the steer angle based on the right controls.
steer_angle = 0
if Button.RIGHT_MINUS in pressed:
steer_angle -= 75
if Button.RIGHT_PLUS in pressed:
steer_angle += 75
# Steer to the selected angle.
steer.run_target(500, steer_angle, wait=False)
# Choose the drive speed based on the left controls.
drive_speed = 0
if Button.LEFT_PLUS in pressed:
drive_speed += 1000
if Button.LEFT_MINUS in pressed:
drive_speed -= 1000
# Apply the selected speed.
front.run(drive_speed)
rear.run(drive_speed)
# Wait.
wait(10)
It says
Traceback (most recent call last):
File "TechnicOffRoader42099.py", line 9, in <module>
TypeError: extra keyword arguments given
IMU acceleration units have changed to mm/s/s, so any projects that use it should be updated.
Originally posted by @laurensvalk in pybricks/pybricks-api#94 (comment)
Hi,
I have put together some code to allow the powered-up remote to control the LEGO transformation vehicle (item #42140). I used the Cat bulldozer project as a template. It's configured to drive like a car, i.e. left PLUS/MINUS control moving forward/backward and right PLUS/MINUS controls turning. This was more intuitive for me and my son than making each side control the respective track as is done in the app.
When the vehicle is moving either forward or backward, turns are more gradual. If the vehicle is stopped, turns are quicker (tracks are rotated in opposite direction with the max speed). If the vehicle is flipped the motors are run in reverse direction so that controls are unchanged (pressing forward still moves the vehicle forward).
I hope that this helps people to use the remote with this LEGO set. Maybe it could be added to the projects page.
from pybricks.pupdevices import Motor, Remote
from pybricks.hubs import TechnicHub
from pybricks.parameters import Button, Color, Direction, Port
from pybricks.tools import wait, StopWatch
# This drives like a car.
# Left +/- control going forwards/backwards, and right +/- turn.
# When the vehicle is moving turn is gradual, when it's stationary turn is faster.
remote = Remote()
hub = TechnicHub()
# TODO: I'm not sure what the max speed is, below is definitely a gross over
# exaggeration. The only thing that's important is that TURN_SPEED be the same
# percentage of the max speed.
DRIVE_SPEED = 10000
TURN_SPEED = 650
DRIVE_ACCELERATION = 7000
# Initialize the motors.
right_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
left_motor = Motor(Port.B)
left_motor.control.limits(acceleration=DRIVE_ACCELERATION)
right_motor.control.limits(acceleration=DRIVE_ACCELERATION)
while True:
# Check which buttons are pressed
wait(10)
pressed = remote.buttons.pressed()
# Choose forward/backward and turn right/left based on pressed buttons
left_speed = 0
right_speed = 0
pitch, roll = hub.imu.tilt()
sign = -1 if abs(roll) > 90 else 1
speed = sign*DRIVE_SPEED
turn = sign*TURN_SPEED
if Button.LEFT_PLUS in pressed or Button.LEFT_MINUS in pressed:
# Going forwards/backwards
left_speed = speed
right_speed = speed
# Turn slowly when moving
turn_right = Button.RIGHT_PLUS in pressed
turn_left = Button.RIGHT_MINUS in pressed
if (turn_right and sign > 0) or (turn_left and sign < 0):
right_speed = turn
elif turn_right or turn_left:
left_speed = turn
if Button.LEFT_MINUS in pressed:
left_speed *= -1
right_speed *= -1
else:
# Not moving, fast turn
if Button.RIGHT_PLUS in pressed:
left_speed = DRIVE_SPEED
right_speed = -DRIVE_SPEED
if Button.RIGHT_MINUS in pressed:
left_speed = -DRIVE_SPEED
right_speed = DRIVE_SPEED
# Activate the driving motors.
left_motor.run(left_speed)
right_motor.run(right_speed)
In the Projects pages, categories and sub-categories are shown with a name and also an image. When the image is one of the actual projects, it can look to the user like just a gallery with only one item in it rather than a category. I suggest more abstract images for categories, or perhaps no images.
For example, on the starting Projects page, there appears at first glance to be just the little race car. If you make it past this, the next choice of hubs is more clear, but then inside Inventor it again looks like few choices, and you have to be persistent to make it all the way to seeing the Mini Loader sample for example.
A related issue is to consider whether the sub-category structure is more complex than necessary for now.
Hi,
I've created a project to control the Cat D11 bulldozer with keyboard to get aquatinted with pybricks. Since it works rather nicely I would like to share it with the community. Could you please add it to the project page?
the code (I used other examples from the pybrick page if some stuff seems familiar):
# Import required MicroPython libraries.
from usys import stdin
from uselect import poll
from pybricks.pupdevices import Motor, Remote
from pybricks.parameters import Button, Color, Direction, Port
from pybricks.tools import wait, StopWatch
from pybricks.hubs import TechnicHub
# Register hub and set light to soft white (gray)
hub = TechnicHub()
hub.light.on(Color.GRAY)
# Register the standard input so we can read keyboard presses.
keyboard = poll()
keyboard.register(stdin)
# Set defaults
left_speed = 0
right_speed = 0
function = "Blade up/down"
functionID = 1
key = None
state = "Idle"
# Default speed and acceleration. You can change
# them to make it more realistic.
SWITCH_SPEED = 720
DRIVE_SPEED = 100
DRIVE_ACCELERATION = 1000
FUNCTION_POWER = 100
MAX_LOAD = 75
# 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)
# Define Functions
COMMANDS = {
1: ("Blade up/down", 0, Color.BLUE),
2: ("Blade tilt", 270, Color.RED),
3: ("Ladder", 180, Color.YELLOW),
4: ("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=True)
# Wait until the stopwatch times out.
while watch.time() < 2000:
# We're done if the motor is on target, so exit
# this function.
if switch_motor.control.done():
switch_motor.stop()
return
wait(10)
# 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)
# Always turn off motor to safe power
switch_motor.stop()
# Print usage information
print(
"\n\n\nKeys (FWD/REV/STP):\tw/s/x: Left track, e/d/c: Right Track, r/f/v: Both tracks full speed,",
"\n\t\t\tq/a/z: Function, 0: Full stop, !: Shutdown.",
"\nFuntions:\t\t1: Blade up/down 2: Blade tilt, 3: Ladder, 4: Ripper\n\n")
inc=0
while True:
wait(10)
# Stop function motor when jammed or blocked
if function_motor.load() > MAX_LOAD or function_motor.load() < -MAX_LOAD:
function_motor.stop()
# Print statistical information
inc += 1
if inc % 50 == 0:
LINE_CLEAR = '\x1b[2K'
print(LINE_CLEAR,
" State", state, "| Left: ",left_motor.speed(), left_motor.load(), "[", left_speed,
"], Right: ", right_motor.speed(), right_motor.load(), "[", right_speed,
"] | Func.:", function,
"| Bat:", hub.battery.voltage(), hub.battery.current(), end="\r"
)
inc = 0
# Turn of motors when state it stopped for more then 5 seconds
if state == "Stopped":
if stopInc > 500:
right_motor.stop()
left_motor.stop()
state = "Idle"
stopInc += 1
else:
stopInc = 0
# Restart loop of no keyboard input is given
if not keyboard.poll(0):
continue
# Register key press
if keyboard.poll(0):
key = stdin.read(1)
# Full stop
if key == "0":
state = "Idle"
right_speed = 0
left_speed = 0
right_motor.stop()
left_motor.stop()
function_motor.stop()
switch_motor.stop()
# Shutdown hub
if key == '!':
print(LINE_CLEAR, "Good Bye!")
wait(100)
hub.system.shutdown()
if key == "1" or key == "2" or key == "3" or key == "4":
# Stop function motor and switch motor
function_motor.stop()
switch_motor.stop()
# Go through the commands.
for button, command in COMMANDS.items():
# Check if the command has a matching button.
if int(key) == button:
# Now we can unpack the command.
name, target, color = command
# Execute command.
switch_target(target)
# Set color
hub.light.on(color)
# Update status info
function = name
functionID = button
# Full speed ahead
if key == "r":
right_speed = 1000
left_speed = 1000
state = "Running"
# Full speed reverse
if key == "f":
right_speed = -1000
left_speed = -1000
state = "Running"
# Full stop
if key == "v":
right_speed = 0
left_speed = 0
# Increase left track speed
if key == "w":
left_speed += DRIVE_SPEED
if left_speed > 1000:
left_speed = 1000
state = "Running"
# Decrase left track speed
if key == "s":
left_speed -= DRIVE_SPEED
if left_speed < -1000:
left_speed = -1000
state = "Running"
# Stop left track
if key == "x":
left_speed = 0
# Increate right track speed
if key == "e":
right_speed += DRIVE_SPEED
if right_speed > 1000:
right_speed = 1000
state = "Running"
# Decrease right track speed
if key == "d":
right_speed -= DRIVE_SPEED
if right_speed < -1000:
right_speed = -1000
state = "Running"
# Stop right track
if key == "c":
right_speed = 0
# Function motor up
if key == "q":
function_motor.dc(-FUNCTION_POWER)
if functionID == 1:
MAX_LOAD = 150
else:
MAX_LOAD = 75
# Function motor down
if key == "a":
function_motor.dc(FUNCTION_POWER)
MAX_LOAD = 170
# Stop function motor
if key == "z":
function_motor.stop()
# Activate the driving motors.
if state != "Idle":
left_motor.run(left_speed)
right_motor.run(right_speed)
# Set state to idle when speed is 0 on both tracks
if left_speed == 0 and right_speed == 0 and state == "Running":
state = "Stopped"
Some trains are long and need multiple "engines". One way of doing that is to have multiple hubs, each driving one or two motors.
This can be done by one "leading" train and any number of "followers". They are mechanically coupled using magnets. This terminology just signifies which train is doing most of the logic.
The lead train connects to the remote, or could do things based on a color sensor, and so on. When it powers its own motor, it also broadcasts the power value so the "follower" hubs can apply the same power level to their own motors.
With recent firmware updates, this is very quick so there are pretty much no delays at all. Here is a screenshot of the current state of the program. The left +/- keys instantly apply 50% or -50% power. The right +/- keys can be used to gradually change the power level.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.