ev3fast – A Python module for faster ev3 interface

Visit the Github page or…

…directly download a zip file containing ev3fast.py


Programing the Lego Mindstorm EV3 using ev3dev and Python can be great fun, but the performance can be very much poorer than LeJOS or EV3-G. For a simple 2 color sensor (…in RGB mode) line follower robot with 2 large motors, we’ve recorded performance as poor as 30+ loops per second, compared to 400+ loops per second using EV3-G.

To improve performance, we’ve created a custom Python module, ev3fast.py, that provides much better performance than the standard ev3dev Python module. As an added bonus, your Python program will load much faster if you use only ev3fast and do not import the standard ev3dev module.

ev3fast currently does not support all features (eg. onboard buttons and screen), but it can be loaded concurrently with the standard ev3dev module. Use ev3fast for your performance critical loops, and the standard ev3dev module for everything else.

The performance comparisons are as follows:

Sensor Benchmark (Loops per second)

Sensor Type ev3dev ev3fast Improvements
Touch  379 1886 5x
Color (Ambient)  179  2343 13x
Color (Color)  157  2375 15x
Color (Raw RGB)  118  1859 16x
Color (Reflected)  178  2021 11x
Ultrasonic (Distance)  48  1882 40x
Ultrasonic (Listen)  60  2094 35x
Gyro (Angle)  45  2314 51x
Gyro (Rate)  231  2174 9x
Gyro (Rate & Angle)  152  2130 14x

Line Follower Benchmark

Program Type Loops per second
EV3-G 427
Python on ev3dev 32
Python on ev3dev with ev3fast 205

The benchmark program (…in Python) is provided here if you want to try it out yourself.

from time import perf_counter
from ev3dev.ev3 import *
#from ev3fast import *

lMotor = LargeMotor('outA')
rMotor = LargeMotor('outD')
lSensor = ColorSensor('in1')
rSensor = ColorSensor('in4')

LOOPS = 1000

startTime = perf_counter()
for a in range(0,LOOPS):
  valueL = lSensor.raw
  valueR = rSensor.raw
  totalL = (valueL[0] + valueL[1] + valueL[2])
  totalR = (valueR[0] + valueR[1] + valueR[2])
  error = totalL - totalR
  lMotor.speed_sp = 200 + error
  rMotor.speed_sp = 200 - error
  lMotor.run_forever()
  rMotor.run_forever()
endTime = perf_counter()

lMotor.stop()
rMotor.stop()

print(str(LOOPS / (endTime - startTime)))

To benchmark the ev3fast version, uncomment the line..

#from ev3fast import *

…and it will override the original ev3dev classes with the faster ev3fast versions.

Currently supported classes are:

class Sensor (address=None)
class TouchSensor (address=None)
class ColorSensor (address=None)
class UltrasonicSensor (address=None)
class GyroSensor (address=None)

class Motor (address=None)
class LargeMotor (address=None)
class MediumMotor
(address=None)

These are replacements for the default ev3dev Python bindings, and all properties and methods documented in http://python-ev3dev.readthedocs.io/en/stable/ are supported. If address isn’t specified, the first device matching the class will be loaded.

Not thoroughly tested. If anything breaks, drop me an email at cort@aposteriori.com.sg.