forked from michaelliao/learn-python3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7827c77
commit 9abe177
Showing
7 changed files
with
244 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. | ||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp | ||
|
||
// List of extensions which should be recommended for users of this workspace. | ||
"recommendations": [ | ||
"lego-education.ev3-micropython" | ||
], | ||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace. | ||
"unwantedRecommendations": [ | ||
"ms-python.python" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "Download and Run", | ||
"type": "ev3devBrowser", | ||
"request": "launch", | ||
"program": "/home/robot/${workspaceRootFolderName}/main.py" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// Place your settings in this file to overwrite default and user settings. | ||
{ | ||
"files.eol": "\n", | ||
"debug.openDebug": "neverOpen", | ||
"python.linting.enabled": false | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# list input devices | ||
|
||
class InputDevice(): | ||
def __init__(self): | ||
self.name = '' | ||
self.handler = '' | ||
|
||
def __str__(self): | ||
return '<Input Device: name=%s, handler=%s>' % (self.name, self.handler) | ||
|
||
def setName(self, name): | ||
if len(name) >= 2 and name.startswith('"') and name.endswith('"'): | ||
name = name[1:len(name)-1] | ||
self.name = name | ||
|
||
def setHandler(self, handlers): | ||
for handler in handlers.split(' '): | ||
if handler.startswith('event'): | ||
self.handler = handler | ||
|
||
def listDevices(): | ||
devices = [] | ||
with open('/proc/bus/input/devices', 'r') as f: | ||
device = None | ||
while True: | ||
s = f.readline() | ||
if s == '': | ||
break | ||
s = s.strip() | ||
if s == '': | ||
devices.append(device) | ||
device = None | ||
else: | ||
if device is None: | ||
device = InputDevice() | ||
if s.startswith('N: Name='): | ||
device.setName(s[8:]) | ||
elif s.startswith('H: Handlers='): | ||
device.setHandler(s[12:]) | ||
return devices | ||
|
||
def detectJoystick(joystickNames): | ||
for device in listDevices(): | ||
for joystickName in joystickNames: | ||
if joystickName in device.name: | ||
return '/dev/input/%s' % device.handler | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# joystick control: | ||
|
||
import struct | ||
|
||
# define button code: | ||
|
||
BUTTON_A = 305 | ||
BUTTON_B = 304 | ||
BUTTON_X = 307 | ||
BUTTON_Y = 306 | ||
BUTTON_PLUS = 313 | ||
BUTTON_MINUS = 312 | ||
BUTTON_START = 317 | ||
BUTTON_HOME = 316 | ||
|
||
class JoyStick(): | ||
def __init__(self, eventFile): | ||
self.eventFile = eventFile | ||
self.buttonHandler = None | ||
self.joyLeftHandler = None | ||
self.joyRightHandler = None | ||
|
||
def setButtonHandler(self, buttonHandler): | ||
self.buttonHandler = buttonHandler | ||
|
||
def setJoyLeftHandler(self, joyLeftHandler): | ||
self.joyLeftHandler = joyLeftHandler | ||
|
||
def setJoyRightHandler(self, joyRightHandler): | ||
self.joyRightHandler = joyRightHandler | ||
|
||
def startLoop(self): | ||
FORMAT = 'llHHI' | ||
EVENT_SIZE = struct.calcsize(FORMAT) | ||
with open(self.eventFile, 'rb') as infile: | ||
lx, ly, rx, ry = 0, 0, 0, 0 | ||
while True: | ||
event = infile.read(EVENT_SIZE) | ||
_, _, t, c, v = struct.unpack(FORMAT, event) | ||
if t == 1 and v == 1: | ||
# button pressed: | ||
if self.buttonHandler: | ||
if not self.buttonHandler(c): | ||
return | ||
if t == 3: | ||
if c == 0 and self.joyLeftHandler: | ||
# left stick & horizontal: | ||
lx = v - 32768 | ||
self.joyLeftHandler(lx, ly) | ||
elif c == 1 and self.joyLeftHandler: | ||
# left stick & vertical: | ||
ly = v - 32768 | ||
self.joyLeftHandler(lx, ly) | ||
elif c == 3 and self.joyRightHandler: | ||
# right stick & horizontal: | ||
rx = v - 32768 | ||
self.joyRightHandler(rx, ry) | ||
elif c == 4 and self.joyRightHandler: | ||
# right stick & vertical: | ||
ry = v - 32768 | ||
self.joyRightHandler(rx, ry) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#!/usr/bin/env pybricks-micropython | ||
|
||
import struct, threading | ||
|
||
from pybricks import ev3brick as brick | ||
from pybricks.ev3devices import (Motor, TouchSensor, ColorSensor, InfraredSensor, UltrasonicSensor, GyroSensor) | ||
from pybricks.parameters import (Port, Stop, Direction, Button, Color, SoundFile, ImageFile, Align) | ||
from pybricks.tools import print, wait, StopWatch | ||
from pybricks.robotics import DriveBase | ||
|
||
from devices import detectJoystick | ||
from joystick import JoyStick, BUTTON_A, BUTTON_X | ||
|
||
SPEED = 100 | ||
STEERING = 90 | ||
|
||
STATUS_STOPPED = 0 | ||
STATUS_FORWARD = 1 | ||
STATUS_BACKWARD = 2 | ||
STATUS_STEERING = 3 | ||
|
||
COLORS = (None, Color.GREEN, Color.RED, Color.YELLOW) | ||
|
||
class Driver(): | ||
def __init__(self, leftMotor, rightMotor, diameter, axle): | ||
self.driver = DriveBase(leftMotor, rightMotor, diameter, axle) | ||
self.x = 0 | ||
self.y = 0 | ||
self.speed = 0 | ||
self.steering = 0 | ||
|
||
def drive(self, speed, steering): | ||
self.speed = speed | ||
self.steering = steering | ||
if self.speed == 0: | ||
self.driver.stop() | ||
else: | ||
self.driver.drive(self.speed, self.steering) | ||
|
||
class Robot(): | ||
def __init__(self, leftMotor, rightMotor, topMotor, diameter, axle, maxSpeed=300, maxSteering=180, port=Port.S4): | ||
self.driver = Driver(leftMotor, rightMotor, diameter, axle) | ||
self.cannon = topMotor | ||
self.ultrasonic = UltrasonicSensor(port) | ||
self.speedStep = 32767 // maxSpeed | ||
self.steeringStep = 32767 // maxSteering | ||
self.active = True | ||
|
||
def drive(self, x, y): | ||
# map y (-32768 ~ +32767) to speed (+maxSpeed ~ -maxSpeed): | ||
speed = -y // self.speedStep | ||
# map x (-32768 ~ +32767) to steering (-maxSteering ~ +maxSteering): | ||
steering = x // self.steeringStep | ||
self.driver.drive(speed, steering) | ||
|
||
def target(self, x): | ||
self.cannon.run(-x // 327) | ||
|
||
def fire(self): | ||
brick.sound.file('cannon.wav') | ||
|
||
def inactive(self): | ||
self.active = False | ||
self.drive(0, 0) | ||
brick.sound.beep() | ||
|
||
def autoStopLoop(robot): | ||
while robot.active: | ||
if robot.ultrasonic.distance() < 200: | ||
robot.drive(0, 0) | ||
wait(100) | ||
|
||
def main(): | ||
brick.sound.beep() | ||
joystickEvent = detectJoystick(['Controller']) | ||
if joystickEvent: | ||
robot = Robot(Motor(Port.D), Motor(Port.A), Motor(Port.B), 55, 200) | ||
t = threading.Thread(target=autoStopLoop, args=(robot,)) | ||
t.start() | ||
|
||
def onButtonPressed(code): | ||
if code == BUTTON_X: | ||
robot.inactive() | ||
return False | ||
if code == BUTTON_A: | ||
robot.fire() | ||
return True | ||
|
||
def onLeftJoyChanged(x, y): | ||
robot.drive(x, y) | ||
|
||
def onRightJoyChanged(x, y): | ||
robot.target(x) | ||
|
||
joystick = JoyStick(joystickEvent) | ||
joystick.setButtonHandler(onButtonPressed) | ||
joystick.setJoyLeftHandler(onLeftJoyChanged) | ||
joystick.setJoyRightHandler(onRightJoyChanged) | ||
joystick.startLoop() | ||
else: | ||
brick.sound.beep() | ||
|
||
main() |