Motors
The motors contained in the standard LEGO sets are common DC motors with incremental rotary encoders. However, they must not be mistaken with stepper motors.
You are not required to be familiar with the differences and details of these types, but you should at least know that the motor’s design allows you to precisely determine the position, speed and rotational direction of the motors.
Speed and precision of the motors depend on the robots charge. According to the task it may be useful to implement a corrective factor that models the dependence as a function of the current charge. Therefore, take a look at the following example on how to read the voltages and currents of the brick.
with open('/sys/class/power_supply/lego-ev3-battery/voltage_now') as voltage_file:
voltage = int(voltage_file.read())
print("Current voltage: {}µV".format(voltage))
Current voltage: 8267133µV
with open('/sys/class/power_supply/lego-ev3-battery/current_now') as current_file:
current = int(current_file.read())
print("Current current: {}µA [pun intended]".format(current))
Current current: 149333µA [pun intended]
The API lets you control the motors by providing several modes and options for the behaviour at starts, stops and in motion. Please note that some commands, for instance changing the speed without preceding stop order may not be available in all modes.
Standard LEGO sets come with two different types of motors: Large and Medium.
Large motor
Difference between speed_sp and duty_cycle_sp
By using duty cycle you are able to control the power of the motor directly. The speed_sp mode provides a simpler API. It uses a controller to keep the motor speed at a certain level independent of charge and forces working against the motor.
Example using speed_sp
import ev3dev.ev3 as ev3
import time
m = ev3.LargeMotor("outA")
m.reset()
m.stop_action = "brake"
m.speed_sp = 100
m.command = "run-forever"
time.sleep(3)
m.speed_sp = 200
m.command = "run-forever"
time.sleep(3)
m.stop()
Example using duty_cycle_sp
import ev3dev.ev3 as ev3
import time
m = ev3.LargeMotor("outA")
m.reset()
m.stop_action = "brake"
m.duty_cycle_sp = 40
m.command = "run-direct"
time.sleep(3)
m.duty_cycle_sp = 60
m.command = "run-direct"
time.sleep(3)
m.stop()
Example using run-to-rel-pos
import ev3dev.ev3 as ev3
import time
m = ev3.LargeMotor("outA")
m.reset()
m.stop_action = "brake"
m.position_sp = 200
m.speed_sp = 100
m.command = "run-to-rel-pos"
print(m.state.__repr__())
time.sleep(8)
print(m.state.__repr__())
Specifications of a Large Motor
accuracy | 1° |
max. rotation rate | 160 - 170 r/min |
average torque | 0,2 Nm |
starting torque | 0,4 Nm |
API: duty cyle | [-100, …, 100] percent |
API: position | 32 bit signed integer (int32_t) |
API: speed | [-1050, …, 1050] ticks per second |
Medium Motor
import ev3dev.ev3 as ev3
motor = ev3.MediumMotor('outA') # use the correct port
motor.command = 'run-direct'
motor.duty_cycle_sp = 100 # range \- 100
motor.stop()
Specifications of a Medium Motor
accuracy | 1° |
max. rotation rate | 240 - 250 r/min |
average torque | 0,08 Nm |
starting torque | 0,12 Nm |