BrickPiLib: A Library For the BrickPi Kit
Learning programming with robots is very motivating. It is like game programming, but the actor is real and may present human aspects of movement and reaction. To maintain the interest and make the effort worthwhile, it is better you owe your personal robot. To build your own robot, you have several choices:
- you provide an industrial robot (very expensive, normally programmed in a special purpose language)
- you provide a fully-assembled educational robot (e.g. Pi2Go Ultimate)
- you provide an educational robot kit with no or little assembly variants (e.g. Pi2Go Kit)
- you provide an educational kit with a given computing brick, but many different assembly variants (e.g. Lego Mindstorm Education EV3)
- you provide a computing unit (Arduino, Raspberry Pi, etc.) and assemble motors and sensors and electronics circuits yourself (e.g. DPKRover [site under construction]).
The BrickPi is some kind of a hybrid: The brick is designed to be used with a Raspberry Pi microcontroller and Lego Mindstorm parts. So it combines the freedom of a standard wide-spread computing unit and the abundance of Lego accessories. It is a good solution if the Lego material (NXT or EV3) is already at hand, and the Raspberry Pi is preferred to the Lego EV3 computing brick.
BrickPi: Hardware Design Concept
It is an engineering challenge to combine the Raspberry Pi as computing engine with Lego Mindstorm accessories. With BrickPi Dexter Industries decided to use extra microcontrollers to link the Raspberry Pi with the Lego accessories.
In the former BrickPi/BrickPi+ two Arduino type microcontrollers (ATMEGA328) communicate with the Lego motors and sensors through two additional motor driver circuits. The Raspberry Pi and the ATMEGA are linked via the Serial (UART) protocol.
The newer BrickPi3 uses a Amtel 32-bit ARM microcontroller (ATSAMD21) and the SPI protocol for the communication link with the Raspberry Pi.
This concepts is elegant because only few pins of the Raspberry Pi GPIO are used for the communication. Fortunately the firmware on the additional microcontroller is fully transparent to the Python programmer of the Raspberry Pi.
BrickPiLib: An Object Oriented And State Based Robotics Library
In our opinion a software library for robotics must be based on the object oriented paradigm. We even think that robotics is one of the best field to demonstrate the strength of OOP and can provide profound insights into OOP for beginners. This is also because a real robot is naturally considered as "an object". So it is evident to model a robot and its accessories by software objects.
We introduced the OOP model for robotics with Lego NXT some ten years ago using Java and ported it to Lego EV3 in Java and Python, then to the Pi2Go (also in Java and Python) and now to the BrickPi (in Python only). But through all the years and many successful robotics courses the concept remained the same:
The robot and all accessories are modelled as objects, e.g. instances of the classes Button, Display, Motor, Gear, Sensor (of different types), etc. Like you "assemble" the real robot by taking a computing brick and "add" motors, sensors, etc., you create software object instances:
robot = LegoRobot()
motor = Motor(MotorPort.A)
ts = TouchSensor(SensorPort.S1)
and add them to the robot:
Actor and sensor methods are used to control motors and read values from the sensors:
Since motor.forward() changes the state of the robot, the library is also based on the state machine (automata) concept that is well-established in software design.
The Python software concept of the BrickPi/BrickPi+ kit implemented by Dexter uses the following pattern based on C programming style:
Import the Python module:
from BrickPi import *
Setup the serial communication (function call to open serial port):
Initialize array like structure SensorType (4 element list for each sensor port) with constants (e.g. touch sensor at port S2):
BrickPi.SensorType = TYPE_SENSOR_TOUCH
Initialize array like structure MotorEnable (4 element list for each motor port) with 0 or 1 (e.g. enable motor at port C):
BrickPi.MotorEnable = 1
Send setup information to BrickPi (function call):
Update motor/sensor information at least every 100 ms
BrickPi.MotorSpeed = power # set speed -255 .. 255
sensor_value = BrickPi.Sensor # get sensor reading
This pattern does not use OOP nor state programming, Our library for the BrickPi+ uses internal synchronized threads to hide these low level C-like hardware issues, but if you like, you can still use all examples from Dexter in our environment.
For the BrickPi3 kit the concept was completely redesigned.
RaspiBrick for BrickPi: A Firmware Shell
In a educational environment, a robot is not always connected to a remote development system and should be able to run user selectable programs at startup. This needs a simple firmware that is automatically started at boot time and at least one or several buttons and a simple display for human interaction. We provide a simple firmware written in Python called RaspiBrick that we adapted from a version running on the Pi2Go robot. As input device two pushbuttons wired to GPIO pin #16 and #18 (and ground) are used. They are managed by our thread-based button handler that supports press, release, click, double-click and long-press events, As output device we assume an OLED display 128x64 pixels based on the SSD1306 chip using the I2C protocol. A Python OLED handler is included in the library distribution (more information here).
For acoustical feed back an active buzzer can be attached to GPIO pin #22 (optional). A thread driven Beeper class is part of the the library.
The firmware is included in our RaspiBrick [BrickPi] SD-card for the Raspberry Pi that can be downloaded from here. You can also install the firmware manually as explained at this site. There are two versions, one for the BrickPi+ and one for the BrickPi3.
The firmware algorithm to select and execute downloaded Python scripts is as follows:
The Python script is always downloaded into the folder /home/pi/scripts as MyApp.py. The previously downloaded scripts are called MyApp_1.py to MyApp_9.py and wrapped upwards when a new script arrives (MyApp_1.py becomes MyApp_2.py, MyApp_9.py is lost). MyApp.py is duplicated as MyApp_1.py. With a double-click you scroll through the scripts, a click executes the selected script.
In order to start a Python script automatically at boot time, name it autostart.py and download it with the option Download module that preserves the file name.
Robotics Programming: A First Example
Let's assume you want to move the robot by rotating both motors until you press the push-button. The Python script becomes extremely simple, because the two motors are modelled as an object called a Gear. First you import the library module ev3brickpi. Then you create the objects robot and and gear and add all parts to the robot. After you set the robot in forward movement and wait in a loop, until the push-button is hit. Finally when you call exit(), the connection between the Raspberry Pi and the BrickPi module is closed and the motors stops automatically.
from ev3brickpi import *
robot = LegoRobot()
gear = Gear()
while not robot.isEscapeHit():
TigerJython: An Python IDE For Remote Microcontroller Development
With the TigerJython Python IDE it becomes very simple to edit/download and execute Python scripts on the Raspberry Pi. For any platform only a single JAR file is needed that can be downloaded from here.
To enable remote development, you select Preferences and click the library tag. There you choose Raspberry Pi and enter the appropriate IP address.
To download and execute a program, you click the black button
Open the Tools menu, and you find more options to manage the Raspberry Pi.
During development you may stop the RaspiBrick firmware by clicking "Terminate Python on Target". In this mode, you get back all output to stdout and they are displayed in the TigerJython Message window. This is very convenient to trace runtime errors or debug your program by adding print statements.
Running the RaspiBrick firmware you can execute up to 9 downloaded Python scripts by selecting them with a push-button double-click without the need of an external PC or an attached screen/keyboard.
RaspiRemoteManager: Remote Microcontroller Development With Any IDE
Many IDE are provided to excecute "external command", among them Geany. We developed a cross-platform application RaspiRemoteManager.jar (download, incl. source) that executes the necessary SSH command to communicate with the RaspiBrick firmware. Copy it in any directory (e.g. c:\rrm) and modify the entries in Geany's Build | Set Build Commands as shown below:
You can Copy&Paste the commands from the following lines:
||python -m py_compile "%d%f"
||java -jar c:\rrm\RaspiRemoteManager.jar -copyrunx "%d%f"
||java -jar c:\rrm\RaspiRemoteManager.jar -copy "%d%f"
|Set _IP Address
||java -jar c:\rrm\RaspiRemoteManager.jar -setip
||java -jar c:\rrm\RaspiRemoteManager.jar -shutdown
||java -jar c:\rrm\RaspiRemoteManager.jar -restart
||python -Qnew "%d%f"
||java -jar c:\rrm\RaspiRemoteManager.jar -rterminal
||java -jar c:\rrm\RaspiRemoteManager.jar -kill