Coder Social home page Coder Social logo

lego-hub-tk's Introduction

Logo of the project

LEGO Hub Toolkit

Pythonic connector for the LEGO Mindstorms/Spike Prime robot hub (Linux, Mac, Windows)

The LEGO Mindstorms Robot Inventor kit (51515) is powered by a hub that contains a programmable micropython-based microprocessor. The LEGO Hub Toolkit provides a python communications library that enables a PC to connect to the Hub using USB and/or Bluetooth. On top of this communications library are some tools that let you monitor the reobot's sensors while it runs as well as to download, start, and stop programs on the hub.

The toolkit fulfils a couple of use cases not provided by LEGO's tools.

  1. Writing code for the robot using a linux or Mac PC.
  2. Writing a custom application to monitor the robot state as it moves about the world.

The communications library is designed to maintain a connection with the hub, using either USB or Bluetooth with automatic switchover from USB to Bluetooth and vice-versa. On top of the communications is a client layer that provides classes to encode and decode the hub messages and to maintain the hub state on the PC side. The hub state includes the onboard gyroscope sensor values as well as the motors and sensors currently plugged into the hub's ports. On top of the client layer are a couple of example applications to demonstrate monitoring and control.

The LEGO Spike Prime kit apparently uses the same hub -- this toolkit was inspired by and directly uses code for Spike Prime (see Acknowledgements, below). As such, I expect much of the code to be usable with Spike Prime, though this has not been tested.

Getting started

The example shell commands below are shown as for a linux shell command line.

Python and Bluetooth

The toolkit is written in Python. You will need Python installed (toolkit is currently developed using Python 3.9).

The software can communicate with the hub using either USB or Bluetooth. If you wish to connect to the Hub using Bluetooth, you will need the relevant packages installed.

For linux / raspberry pi:

sudo apt-get install python3.9 bluetooth libbluetooth-dev

Python Packages

Install pre-requisite Python packages.

Either install the minimal set of packages:

pip3 install -r requirements.txt

Or install the full set of packages, which will facilitate optional functionality:

pip3 install -r requirements-full.txt

At the time of writing, the optional functionality includes:

  • autodetection of the Bluetooth link / failover to USB

Check if any errors during install they will need to be corrected before proceeding.

Configuration

Out of the box, the software uses the USB cable to connect to the hub. It will automatically determine the correct USB device.

If the auto-detection does not work on your system, or if you wish to use bluetooth, the connection can be specified by configuration file.

If using Bluetooth:

  1. Pair the hub with your system. Use your system's regular tool for doing this.
  2. Obtain the hub's Bluetooth address -- likely using the same tool as in the previous step. It will be in the form of six hexadecimal number separated by colons; e.g. 38:0B:3C:AA:B6:CE
    • darwin shell can provide a list system_profiler SPBluetoothDataType
    • linux hciconfig

Create and edit the configuration file:

  1. Locate the correct user_config_dir for your system (see https://pypi.org/project/appdirs/) and create a sub-directory named 'lego-hub-tk'.
    • For linux, this will be mkdir ~/.config/lego-hub-tk/
  2. Copy the template file lego_hub.yaml to the newly-created directory.
    • For linix, this will be cp lego_hub.yaml ~/.config/lego-hub-tk/lego_hub.yaml
  3. Edit your copy of lego_hub.yaml, following the notes in the template file.
    • For linix, this will be nano ~/.config/lego-hub-tk/lego_hub.yaml

First Test

Connect the hub using USB.

List the programs currently stored on the hub:

python3 run_command.py ls
Slot Decoded Name                               Size Last Modified        Project_id   Type      
   0 Zero motors                                733b 2020-12-30 04:02:45  lmlJdiW3kVR2 scratch   
   1 MR1 - Line Follower                       3641b 2020-12-31 17:47:18  T8g7vJ4jYExt python    
   2 MR1 - Wanderer                            2650b 2020-12-31 17:47:49  GzcKr5xPBJrQ python    
   3 MR1 - Connect the Dots                    4375b 2021-01-01 02:11:06  Qm_0zJkWgkGM python    
   4 MR1 - Navigator 1                        13563b 2021-01-04 05:20:15  sUtzpgAokATv python    
   5 Project 3                                  128b 2021-01-02 18:52:18  bGz62LGIzCOl python    
   6 Guard my room 3                           8115b 2020-12-29 17:16:28  kDj0zNTjueJV scratch   
   8 Grab and move                             8949b 2020-12-30 03:49:16  V12C35ra2EdG scratch   
  10 Hi World                                    13b 2021-02-01 04:05:14  50uN1ZaRpHj2 python    
  11 Winner! 6                                 7226b 2020-12-29 22:00:17  cis5eAYFX5bd scratch   

Features

Runing code on the hub - command line

The python3 script run_command.py can

  • list programs stored on the hub
  • upload a program to the hub
  • start a program on the hub
  • stop the program currently running on the hub

Usage:

python3 run_program.py ls
python3 run_program.py cp myprogram.py 4
python3 run_program.py start 4
python3 run_program.py stop

Runing code on the hub - GUI

The GUI program hubcontrol can be used to run a program on the hub and display the console output and status while it runs.

Monitoring running hub

The script hubstatus displays the live hub status.

Usage:

python3 hubstatus.py

A window should open displaying the hub status details of the connection type, on-board sensors (yaw, pitch, roll), and the status of the six ports (A-F). The Hub Gesture value indicates when the hub is tapped, double-tapped, etc.

Python scripting

See the API Design documentation.

After all packages are confirmed installed you may need to add export PATH="$HOME/bin:$PATH"

Contributing

If any the above instructions are unclear or incorrect, please do open an issue.

If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are warmly welcome.

Thanks to:

  • Eric T. (ws1088) for Mac & Windows support and many other improvements!
  • Kelly (SpudGunMan) for design & doc suggestions

Links

Acknowledgements

This project owes a particular debt of gratitude to several other open source projects.

Provided the inspiration -- and the core pyudev code -- for USB autodetect. Additionally, rshell was hugely helpful in exploring the on-board python Read-Evaluate-Print-Loop (REPL) and the hub's file structure.

Provided the core code for decoding the JSON message structure. The script run_command.py in this toolkit started as a copy of spikejsonrpc from spike tools, with the serial handling code replaced by the comm library.

Licensing

The code in this project is licensed under MIT license.

lego-hub-tk's People

Contributors

smr99 avatar spudgunman avatar ws1088 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

lego-hub-tk's Issues

Could not open port, Access is denied.

Hello. On windows it may ask you permission for USB com's.

Configuration file does not exist: C:\Users\partsjoo\AppData\Local\lego-hub-tk\lego-hub-tk\lego_hub.yaml
2022-01-18 04:57:07,836 INFO App LEGO status app starting up
2022-01-18 04:57:08,054 INFO comm.ConnectionMonitor Starting USB autoconnect detection loop
2022-01-18 04:57:08,055 INFO comm.ConnectionMonitor Starting Bluetooth autoconnect detection loop
2022-01-18 04:57:08,055 WARNING comm.BluetoothConnectionMonitor Not scanning: no BlueTooth address configured
2022-01-18 04:57:08,055 INFO comm.ConnectionMonitor End Bluetooth autoconnect detection loop
2022-01-18 04:57:08,062 INFO comm.HubClient Connecting to hub using COM3
2022-01-18 04:57:08,063 INFO root Connection state change ConnectionState.DISCONNECTED --> ConnectionState.CONNECTING
2022-01-18 04:57:08,064 ERROR comm.HubClient connection change failed: could not open port 'COM3': PermissionError(13, 'Access is denied.', None, 5)
Traceback (most recent call last):
  File "C:\Users\partsjoo\AppData\Local\lego-hub-tk-main\comm\HubClient.py", line 85, in _connection_changed
    conn.open()
  File "C:\Users\partsjoo\AppData\Local\lego-hub-tk-main\comm\SerialConnection.py", line 37, in open
    self._serial.open()
  File "C:\Users\partsjoo\AppData\Local\Programs\Python\Python39\lib\site-packages\serial\serialwin32.py", line 64, in open
    raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port 'COM3': PermissionError(13, 'Access is denied.', None, 5)
2022-01-18 04:57:08,067 INFO root Connection state change ConnectionState.CONNECTING --> ConnectionState.DISCONNECTED
2022-01-18 04:57:08,069 INFO comm.ConnectionMonitor End USB autoconnect detection loop

It can happen when something is already using HUB while you are trying to connect to it. To fix the problem, stop other programs from using HUB when you are trying to connect.

It seems like basic knowledge to the knowledgeable, but maybe a hit printed somewhere on these lines could be useful.

Run fails with cannot import name 'IOBluetoothDeviceInquiry'

Hey! Could you assist please with installation, I keep getting these. Tried to reinstall everything I knew.

I'm from Java and quite newbie with python env

ego-hub-tk git:(main) ✗ python3 run_command.py
Traceback (most recent call last):
  File "/Users/artemptushkin/PycharmProjects/lego-hub-tk/run_command.py", line 17, in <module>
    from comm.HubClient import ConnectionState, HubClient
  File "/Users/artemptushkin/PycharmProjects/lego-hub-tk/comm/HubClient.py", line 5, in <module>
    from comm.MultiplexedConnectionMonitor import MultiplexedConnectionMonitor
  File "/Users/artemptushkin/PycharmProjects/lego-hub-tk/comm/MultiplexedConnectionMonitor.py", line 2, in <module>
    from comm.BluetoothConnectionMonitor import BluetoothConnectionMonitor
  File "/Users/artemptushkin/PycharmProjects/lego-hub-tk/comm/BluetoothConnectionMonitor.py", line 4, in <module>
    import bluetooth
  File "/usr/local/lib/python3.9/site-packages/bluetooth/__init__.py", line 13, in <module>
    from bluetooth.macos import *
  File "/usr/local/lib/python3.9/site-packages/bluetooth/macos/__init__.py", line 1, in <module>
    import bluetooth.macos.discovery as discovery
  File "/usr/local/lib/python3.9/site-packages/bluetooth/macos/discovery.py", line 6, in <module>
    from Foundation import NSObject, IOBluetoothDeviceInquiry
ImportError: cannot import name 'IOBluetoothDeviceInquiry' from 'Foundation._context' (/usr/local/lib/python3.9/site-packages/Foundation/_context.py)
➜  lego-hub-tk git:(main) ✗

Establishing an upstream link between HUB and PC

Hello.

I am having trouble establishing an link for upstream/downstream data link. Could you please elaborate, perhaps with some examples, how to establish a 2-way data link between HUB <-> PC or is that something that is not possible with this tool?

The only option that I see, is possibility of activating different slots, but we can not call a function with variables passed down within a program, on a slot - am I correct?

Unhandled message 'm': 14

I was playing around with this today and got

WARNING:data.HubMonitor:unhandled message: {'m': 14, 'p': 0}
WARNING:data.HubMonitor:unhandled message: {'m': 14, 'p': 5}
WARNING:data.HubMonitor:unhandled message: {'m': 14, 'p': 1}
WARNING:data.HubMonitor:unhandled message: {'m': 14, 'p': 2}
WARNING:data.HubMonitor:unhandled message: {'m': 14, 'p': 0}
WARNING:data.HubMonitor:unhandled message: {'m': 14, 'p': 2}
WARNING:data.HubMonitor:unhandled message: {'m': 14, 'p': 1}
WARNING:data.HubMonitor:unhandled message: {'m': 14, 'p': 0}

Any ideas?

Protocol Spec

Hi,

I am the maintainer of sharpbrick/powered-up which is a .NET library for communicating with the Lego Technic Powered Up hubs. In that world, I am used to write software on a PC/Mac/Linux device and instruct the hub what to do. I worked hard with the LWP2 spec and collaborated in the community to get the best experience out of it.

So the question to the Spike/Mindstorm Hub experts: Is the remote protocol of the mindstorms hub a debugging protocol (aka receiving telemetry and messing with the execution of a previous transferred python program) OR is it a true remote control protocol where commands are sent by a controlling PC and then executed by the hub?

I have not found a lot of documentation, so i am bit confused? Also there is a mystical hub to hub protocol which I also found no real information about it.

ModuleNotFoundError: No module named 'bluetooth.linux'

First of all, thanks for your effort to allow programming the Lego Hub on Linux!

This is what happens when I run python3 run_command.py ls:

$ python3 run_command.py ls
Traceback (most recent call last):
  File "/home/ppalaga/orgs/python/lego-hub-tk/run_command.py", line 17, in <module>
    from comm.HubClient import ConnectionState, HubClient
  File "/home/ppalaga/orgs/python/lego-hub-tk/comm/HubClient.py", line 5, in <module>
    from comm.MultiplexedConnectionMonitor import MultiplexedConnectionMonitor
  File "/home/ppalaga/orgs/python/lego-hub-tk/comm/MultiplexedConnectionMonitor.py", line 2, in <module>
    from comm.BluetoothConnectionMonitor import BluetoothConnectionMonitor
  File "/home/ppalaga/orgs/python/lego-hub-tk/comm/BluetoothConnectionMonitor.py", line 4, in <module>
    import bluetooth
  File "/home/ppalaga/.local/lib/python3.9/site-packages/bluetooth/__init__.py", line 18, in <module>
    from bluetooth.linux import *
ModuleNotFoundError: No module named 'bluetooth.linux'

I have installed the prerequisites via pip3 install -r requirements.txt before running run_command.py ls.
I am quite new to Python and pip, maybe I am missing something basic.

I am on Fedora 34.

cannot stop the program

hello, i meet some error when i stop the program
Traceback (most recent call last):
File "protocol/ujsonrpc.py", line 1, in _handle_message
ValueError: syntax error in JSON

Using monitor.events.console_print prints only ERROR level messages

Hello. I am trying to access print("test") being called in a function running on HUB. But I can only receive ERROR level messages (probably not coming from something_changed). However when running toolkit tools like hubcontrol.py I see that "test" gets printed on INFO level. How to access INFO level from monitor event console_print ?

start_monitoring_on_pc.py

import time

from data.HubMonitor import HubMonitor
from comm.HubClient import HubClient, ConnectionState

connection = 0


class Main:
    client = HubClient()
    hm = HubMonitor(client)

    def __init__(self):
        self.hm.events.console_print += self._console_print
        self.client.start()

    def _console_print(self, msg):
        print(msg)


Main()


def send_heartbeat_to_backend(connection):
    # TODO
    if connection == 0:
        print('HUB is offline')
    elif connection == 1:
        print('Connection established to HUB')
    elif connection == 2:
        if not Main.hm.execution_status[1]:
            print('Main program started on HUB')
        if Main.hm.execution_status[1]:
            print('Main program running')


def send_cube_map_to_backend(map):
    # TODO
    print(map)


while True:
    send_heartbeat_to_backend(connection)
    time.sleep(1)
    if Main.hm.connection_state == ConnectionState.TELEMETRY:
        if connection == 0:
            connection = 1
        elif connection == 1:
            Main.client.program_execute(1)
            connection = 2
    else:
        print('waiting...')
HUB is offline
Connection established to HUB
Main program started on HUB
Main program started on HUB
Main program running
ERROR:root:unrecognized motion sensor value: 1
// expecting print("test") to print here

EDIT:
I noticed your commit... d3b8684 after re-adding these lines I got it working as intended. Please update the docs that by default, these events do no fire, instead they are being logged to file (which I saw actually) but I could not find the root cause for it. That - or better yet, make it optional to log to console or file or both. 👍

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.