mirror of
https://github.com/pybricks/pybricks-projects.git
synced 2026-07-28 04:06:07 +00:00
sets/mindstorms-robot-inventor: Add Mini Loader sample
* Add Mini Loader sample Initial commit to add the "Remote-controlled Mini Loader" sample for Inventor, which is controlled by the Bluetooth Remote using a variety of techniques. * Changed video ID Changed the YouTube video ID of this sample to move it to my OneKitProjects channel, where it probably makes sense to make public at some point.
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
---
|
||||
title: "Remote-controlled Mini Loader"
|
||||
maintainer:
|
||||
user: "davecparker"
|
||||
name: "Dave Parker"
|
||||
image:
|
||||
local: "mini-loader.JPG"
|
||||
video:
|
||||
youtube: "L0gnDPXkx4U"
|
||||
description:
|
||||
"Mini Loader controlled with LEGO Bluetooth Remote"
|
||||
building_instructions:
|
||||
external: https://www.onekitprojects.com/51515/mini-loader
|
||||
code: "#program"
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
This Mini Loader has four motors to allow it to drive, steer, lift, and dump.
|
||||
The program connects to the LEGO Bluetooth Remote and uses the remote's buttons
|
||||
in several ways to implement a variety of control features.
|
||||
|
||||
## Instructions
|
||||
|
||||
Twist the controls on the remote to make the left side vertical with + on top,
|
||||
and the right side horizontal with + on the right.
|
||||
|
||||
Establish the connection between the hub and remote using these steps:
|
||||
1. Download the Pybricks program to the hub.
|
||||
2. If the program is running (display animating), press the hub button to stop it.
|
||||
3. Press the green center button on the Remote (light flashes white).
|
||||
4. Immediately press the Inventor hub button to run the program.
|
||||
5. If the connection is successful, both the remote and hub lights turn green.
|
||||
|
||||
The remote has two modes, which you toggle between using the green center button
|
||||
on the remote. The modes are indicated by both the remote and hub lights.
|
||||
Use Drive mode (green) to drive and steer, and Lift mode (Orange) to control the lift.
|
||||
|
||||
### Drive Mode (Green light)
|
||||
|
||||
Use the left side buttons to control the drive direction and the right side buttons
|
||||
to steer. You can drive and steer at the same time, or just steer to pivot in place.
|
||||
|
||||
By holding down either of the two red buttons, you can reduce both the driving and steering
|
||||
speed for more precise positioning. You can do this either by holding a red button
|
||||
with one thumb (like a shift key) while using +/- controls with your other thumb,
|
||||
or with a single thumb, you can roll between pressing both Center and +/- at the same time
|
||||
(slow) or just +/- (fast).
|
||||
|
||||
### Lift Mode (Orange Light)
|
||||
|
||||
Tap the three left side buttons to make the lift and scoop move together to three
|
||||
preset positions: Carrying High, Carrying Middle, or Ready Low.
|
||||
|
||||
Tap -/+ on the right side to dump/undump the scoop without moving the lift.
|
||||
|
||||
The red right center button runs a special feature to help position
|
||||
the mini loader to prepare to dump. Pressing and holding this button will make
|
||||
the robot drive straight forward until the distance sensor measures 5 cm
|
||||
(or until you release the button to cancel). The lights on the ultrasonic sensor
|
||||
are turned on when the robot is using them, so a fun side effect is that quickly
|
||||
tapping the right center button just flashes the sensor lights.
|
||||
|
||||
## Program
|
||||
|
||||
{% include copy-code.html %}
|
||||
```python
|
||||
{% include_relative miniLoader_RC.py %}
|
||||
```
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 361 KiB |
@@ -0,0 +1,133 @@
|
||||
from pybricks.hubs import InventorHub
|
||||
from pybricks.pupdevices import Motor, UltrasonicSensor, Remote
|
||||
from pybricks.parameters import Button, Color, Direction, Port, Stop
|
||||
from pybricks.robotics import DriveBase
|
||||
from pybricks.tools import wait, StopWatch
|
||||
|
||||
# Define objects that correspond to the design of the Mini Loader
|
||||
hub = InventorHub()
|
||||
left_motor = Motor(Port.F, positive_direction=Direction.COUNTERCLOCKWISE)
|
||||
right_motor = Motor(Port.E, positive_direction=Direction.CLOCKWISE)
|
||||
drive_base = DriveBase(left_motor, right_motor, wheel_diameter=56, axle_track=80)
|
||||
lift_motor = Motor(Port.D)
|
||||
scoop_motor = Motor(Port.C)
|
||||
eyes = UltrasonicSensor(Port.A)
|
||||
|
||||
# Motor speeds
|
||||
DRIVE_SPEED = 150 # straight driving speed in mm/sec
|
||||
TURN_RATE = 150 # turning speed in deg/sec
|
||||
LIFT_SPEED = 200 # deg/sec
|
||||
SCOOP_SPEED = 200 # deg/sec
|
||||
|
||||
# Preset lift and scoop positions (degrees relative to starting ready position)
|
||||
LIFT_HIGH_POS = 320
|
||||
LIFT_MIDDLE_POS = 130
|
||||
LIFT_LOW_POS = 0
|
||||
SCOOP_READY_POS = -5
|
||||
SCOOP_DUMP_POS = 10
|
||||
SCOOP_CARRY_POS = -90
|
||||
|
||||
# Connect to the remote (will stop the program if unsuccessful)
|
||||
rc = Remote()
|
||||
|
||||
# Get the set of buttons on the remote that start out pressed
|
||||
pressed = rc.buttons.pressed()
|
||||
was_pressed = pressed # remembers which buttons were previously pressed
|
||||
|
||||
|
||||
# Return True if the specified button is newly pressed (not held down)
|
||||
def new_press(button):
|
||||
return (button in pressed) and not (button in was_pressed)
|
||||
|
||||
|
||||
# This function controls the robot in drive mode
|
||||
def drive_mode():
|
||||
# Pressing and holding either the left or right center button
|
||||
# reduces both the drive and steering speed.
|
||||
speed = DRIVE_SPEED
|
||||
steering = TURN_RATE
|
||||
if (Button.LEFT in pressed) or (Button.RIGHT in pressed):
|
||||
speed *= 0.3
|
||||
steering *= 0.3
|
||||
|
||||
# Determine what speed and steering to use.
|
||||
# The left side controls drive direction, and the right side steers.
|
||||
current_speed = 0
|
||||
current_steering = 0
|
||||
if (Button.LEFT_PLUS in pressed):
|
||||
current_speed += speed
|
||||
if (Button.LEFT_MINUS in pressed):
|
||||
current_speed -= speed
|
||||
if (Button.RIGHT_PLUS in pressed):
|
||||
current_steering += steering
|
||||
if (Button.RIGHT_MINUS in pressed):
|
||||
current_steering -= steering
|
||||
drive_base.drive(current_speed, current_steering)
|
||||
|
||||
|
||||
# This function controls the robot in lift mode
|
||||
def lift_mode():
|
||||
# The three left side buttons set the lift height (high, middle, or low)
|
||||
# and automatically adjust the scoop as appropriate.
|
||||
if new_press(Button.LEFT_PLUS):
|
||||
scoop_motor.run_target(SCOOP_SPEED, SCOOP_CARRY_POS, wait=False)
|
||||
lift_motor.run_target(LIFT_SPEED, LIFT_HIGH_POS)
|
||||
elif new_press(Button.LEFT):
|
||||
scoop_motor.run_target(SCOOP_SPEED, SCOOP_CARRY_POS, wait=False)
|
||||
lift_motor.run_target(LIFT_SPEED, LIFT_MIDDLE_POS)
|
||||
elif new_press(Button.LEFT_MINUS):
|
||||
scoop_motor.run_target(SCOOP_SPEED, SCOOP_READY_POS, wait=False)
|
||||
lift_motor.run_target(LIFT_SPEED, LIFT_LOW_POS)
|
||||
|
||||
# Right side -/+ buttons dump/undump the scoop
|
||||
if new_press(Button.RIGHT_MINUS):
|
||||
scoop_motor.run_target(SCOOP_SPEED, SCOOP_DUMP_POS)
|
||||
if new_press(Button.RIGHT_PLUS):
|
||||
if lift_motor.angle() > LIFT_MIDDLE_POS / 2: # can't carry if low
|
||||
scoop_motor.run_target(SCOOP_SPEED, SCOOP_CARRY_POS)
|
||||
|
||||
# Holding Right Center drives straight forward until the distance sensor
|
||||
# is at 5 cm, or until the button is released.
|
||||
if new_press(Button.RIGHT):
|
||||
eyes.lights.on(100)
|
||||
while (eyes.distance() > 50) and (Button.RIGHT in rc.buttons.pressed()):
|
||||
drive_base.drive(DRIVE_SPEED, 0)
|
||||
drive_base.stop()
|
||||
eyes.lights.off()
|
||||
|
||||
|
||||
# The remote has multiple modes, selected by the center button.
|
||||
# This table lists the different mode functions and which color they show.
|
||||
modes = (
|
||||
(drive_mode, Color.GREEN),
|
||||
(lift_mode, Color.ORANGE),
|
||||
)
|
||||
mode = 0 # index of current mode
|
||||
|
||||
|
||||
# Set the mode to new_mode and update both the remote and hub status lights
|
||||
def set_mode(new_mode):
|
||||
global mode
|
||||
mode = new_mode
|
||||
color = modes[mode][1]
|
||||
hub.light.on(color)
|
||||
rc.light.on(color)
|
||||
|
||||
|
||||
# Set the initial mode
|
||||
set_mode(mode)
|
||||
|
||||
# The main loop repeatedly tests the remote buttons and reacts
|
||||
while True:
|
||||
# Update the set of buttons that are currently pressed,
|
||||
# and also remember which ones were pressed the last time we looked.
|
||||
was_pressed = pressed
|
||||
pressed = rc.buttons.pressed()
|
||||
|
||||
# The green center button changes modes
|
||||
if new_press(Button.CENTER):
|
||||
set_mode((mode + 1) % len(modes)) # next mode and wrap around
|
||||
|
||||
# Execute the current mode
|
||||
modes[mode][0]()
|
||||
|
||||
Reference in New Issue
Block a user