mirror of
https://github.com/undera/pylgbst.git
synced 2020-11-18 19:37:26 -08:00
215 lines
7.5 KiB
Markdown
215 lines
7.5 KiB
Markdown
# Python library to interact with Move Hub
|
|
|
|
_Move Hub is central robotic controller block of [LEGO Boost](https://www.lego.com/en-us/boost) Set._
|
|
|
|
Best way to start with this library is to look into [`demo.py`](demo.py) file, and run it.
|
|
|
|
If you have Vernie assembled, you might look into and run scripts from [`vernie`](vernie/) directory.
|
|
|
|
## Features
|
|
|
|
- auto-detect and connect for Bluetooth device
|
|
- auto-detects devices connected to Hub
|
|
- angled and timed movement for motors
|
|
- LED color change
|
|
- motors: angled and timed movement, rotation sensor subscription
|
|
- push button status subscription
|
|
- tilt sensor subscription: 2 axis, 3 axis, bump detect modes
|
|
- color & distance sensor: several modes to measure distance, color and luminosity
|
|
- battery voltage subscription available
|
|
- permanent Bluetooth connection server for faster debugging
|
|
|
|
## Usage
|
|
|
|
Install library like this:
|
|
```bash
|
|
pip install https://github.com/undera/pylgbst/archive/0.2.tar.gz
|
|
```
|
|
|
|
Then instantiate MoveHub object and start invoking its methods. Following is example to just print peripherals detected on Hub:
|
|
|
|
```python
|
|
from pylgbst import MoveHub
|
|
|
|
hub = MoveHub()
|
|
|
|
for device in hub.devices:
|
|
print(device)
|
|
```
|
|
|
|
TODO: more usage instructions
|
|
|
|
### General Information
|
|
connection params
|
|
hub's devices detect process & fields to access them
|
|
general subscription modes & granularity info
|
|
good practice is to unsubscribe, especially when used with `DebugServer`
|
|
|
|
Only one, very last subscribe mode is in effect, with many subscriber callbacks allowed.
|
|
|
|
### Motors
|
|
|
|
### Motor Rotation Sensors
|
|
|
|
### Tilt Sensor
|
|
|
|
MoveHub's internal tilt sensor is available through `tilt_sensor` field. There are several modes to subscribe to sensor, providing 2-axis, 3-axis and bump detect data.
|
|
|
|
An example:
|
|
|
|
```python
|
|
from pylgbst import MoveHub, TiltSensor
|
|
import time
|
|
|
|
def callback(pitch, roll, yaw):
|
|
print("Pitch: %s / Roll: %s / Yaw: %s" % (pitch, roll, yaw))
|
|
|
|
hub = MoveHub()
|
|
|
|
hub.tilt_sensor.subscribe(callback, mode=TiltSensor.MODE_3AXIS_FULL)
|
|
time.sleep(60) # turn MoveHub block in different ways
|
|
hub.tilt_sensor.unsubscribe(callback)
|
|
```
|
|
|
|
`TiltSensor` sensor mode constants:
|
|
- MODE_2AXIS_SIMPLE - use `callback(state)` for 2-axis simple state detect
|
|
- MODE_2AXIS_FULL - use `callback(roll, pitch)` for 2-axis roll&pitch degree values
|
|
- MODE_3AXIS_SIMPLE - use `callback(state)` for 3-axis simple state detect
|
|
- MODE_3AXIS_FULL - use `callback(roll, pitch)` for 2-axis roll&pitch degree values
|
|
- MODE_BUMP_COUNT - use `callback(count)` to detect bumps
|
|
|
|
### Color & Distance Sensor
|
|
|
|
Field named `color_distance_sensor` holds instance of `ColorDistanceSensor`, if one is attached to MoveHub. Sensor has number of different modes to subscribe.
|
|
|
|
Colors that are detected are part of `COLORS` map (see [LED](#LED) section). Only several colors are possible to detect: `BLACK`, `BLUE`, `CYAN`, `YELLOW`, `RED`, `WHITE`. Sensor does its best to detect best color, but only works when sample is very close to sensor.
|
|
|
|
Distance works in range of 0-10 inches, with ability to measure last inch in higher detail.
|
|
|
|
Simple example of subscribing to sensor:
|
|
|
|
```python
|
|
from pylgbst import MoveHub, ColorDistanceSensor
|
|
import time
|
|
|
|
def callback(clr, distance):
|
|
print("Color: %s / Distance: %s" % (clr, distance))
|
|
|
|
hub = MoveHub()
|
|
|
|
hub.color_distance_sensor.subscribe(callback, mode=ColorDistanceSensor.COLOR_DISTANCE_FLOAT)
|
|
time.sleep(60) # play with sensor while it waits
|
|
hub.color_distance_sensor.unsubscribe(callback)
|
|
```
|
|
|
|
Subscription mode constants in class `ColorDistanceSensor` are:
|
|
- `COLOR_DISTANCE_FLOAT` - default mode, use `callback(color, distance)` where `distance` is float value in inches
|
|
- `COLOR_ONLY` - use `callback(color)`
|
|
- `DISTANCE_INCHES` - use `callback(color)` measures distance in integer inches count
|
|
- `COUNT_2INCH` - use `callback(count)` - it counts crossing distance ~2 inches in front of sensor
|
|
- `DISTANCE_HOW_CLOSE` - use `callback(value)` - value of 0 to 255 for 30 inches, larger with closer distance
|
|
- `DISTANCE_SUBINCH_HOW_CLOSE` - use `callback(value)` - value of 0 to 255 for 1 inch, larger with closer distance
|
|
- `LUMINOSITY` - use `callback(luminosity)` where `luminosity` is float value from 0 to 1
|
|
- `OFF1` and `OFF2` - seems to turn sensor LED and notifications off
|
|
- `STREAM_3_VALUES` - use `callback(val1, val2, val3)`, sends some values correlating to distance, not well understood at the moment
|
|
|
|
Tip: laser pointer pointing to sensor makes it to trigger distance sensor
|
|
|
|
### LED
|
|
|
|
`MoveHub` class has field `led` to access color LED near push button. To change its color, use `set_color(color)` method.
|
|
|
|
You can obtain colors are present as constants `COLOR_*` and also a map of available color-to-name as `COLORS`. There are 12 color values, including `COLOR_BLACK` and `COLOR_NONE` which turn LED off.
|
|
|
|
Additionally, you can subscribe to LED color change events, using callback function as shown in example below.
|
|
|
|
|
|
```python
|
|
from pylgbst import MoveHub, COLORS, COLOR_NONE, COLOR_RED
|
|
import time
|
|
|
|
def callback(clr):
|
|
print("Color has changed: %s" % clr)
|
|
|
|
hub = MoveHub()
|
|
hub.led.subscribe(callback)
|
|
|
|
hub.led.set_color(COLOR_RED)
|
|
for color in COLORS:
|
|
hub.led.set_color(color)
|
|
time.sleep(0.5)
|
|
|
|
hub.led.set_color(COLOR_NONE)
|
|
hub.led.unsubscribe(callback)
|
|
```
|
|
|
|
Tip: blinking orange color of LED means battery is low.
|
|
|
|
### Push Button
|
|
|
|
`MoveHub` class has field `button` to subscribe to button press and release events.
|
|
|
|
Note that `Button` class is not real `Peripheral`, as it has no port and not listed in `devices` field of Hub. Still, subscribing to button is done usual way:
|
|
|
|
```python
|
|
from pylgbst import MoveHub
|
|
|
|
def callback(is_pressed):
|
|
print("Btn pressed: %s" % is_pressed)
|
|
|
|
hub = MoveHub()
|
|
hub.button.subscribe(callback)
|
|
```
|
|
|
|
### Power Voltage & Battery
|
|
|
|
`MoveHub` class has field `battery` to subscribe to battery voltage status. Callback accepts single parameter with current value. The range of values is unknown, it's 2-byte integer. Every time data is received, value is also written into `last_value` field of Battery object.
|
|
|
|
```python
|
|
from pylgbst import MoveHub
|
|
import time
|
|
|
|
def callback(value):
|
|
print("Voltage: %s" % value)
|
|
|
|
hub = MoveHub()
|
|
hub.battery.subscribe(callback)
|
|
time.sleep(1)
|
|
print ("Value: " % hub.battery.last_value)
|
|
```
|
|
|
|
## Debug Server
|
|
Running debug server opens permanent BLE connection to Hub and listening on TCP port for communications. This avoids the need to re-start Hub all the time.
|
|
|
|
There is `DebugServerConnection` class that you can use with it, instead of `BLEConnection`.
|
|
|
|
Starting debug server is done like this:
|
|
```bash
|
|
sudo python -c "from pylgbst.comms import *; \
|
|
import logging; logging.basicConfig(level=logging.DEBUG); \
|
|
DebugServer(BLEConnection().connect()).start()"
|
|
```
|
|
|
|
Then push green button on MoveHub, so permanent BLE connection will be established.
|
|
|
|
## TODO
|
|
|
|
- Give nice documentation examples, don't forget to mention logging
|
|
- document all API methods
|
|
- make sure unit tests cover all important code
|
|
- handle device detach and device attach events on ports C/D
|
|
- generalize getting device info + give constants (low priority)
|
|
- organize requesting and printing device info on startup - firmware version at least
|
|
- make debug server to re-establish BLE connection on loss
|
|
|
|
## Links
|
|
|
|
- https://github.com/JorgePe/BOOSTreveng - source of protocol knowledge
|
|
- https://github.com/spezifisch/sphero-python/blob/master/BB8joyDrive.py - example with another approach to bluetooth libs
|
|
|
|
Some things around visual programming:
|
|
- https://github.com/RealTimeWeb/blockpy
|
|
- https://ru.wikipedia.org/wiki/App_Inventor
|
|
- https://en.wikipedia.org/wiki/Blockly
|
|
|