If you go to the RoboClaw downloads page, you’ll see that it recommends using a virtual environment.
1. I set up a virtual environment and installed the basicmicro library and roboclaw-python, but the example code does not work. Because of this, I’m not sure whether we actually need to install those libraries.
sudo apt update sudo apt install python3-venv # Install virtual environment tool python3 -m venv myenv # Create a virtual environment source myenv/bin/activate # Activate it pip install basicmicro # Install the library pip install roboclaw-python pip install pyserial
2. We also need to work in packet serial mode, but the example code provided in the repository does not work either.
You need to place the test file in the same directory as roboclaw.py.
I created a standard_serial.py file to test the motor.
from roboclaw import Roboclaw
from time import sleep
PORT="/dev/ttyACM0"
BAUD=38400
ADDR=0x80
rc = Roboclaw(PORT, BAUD)
rc.Open()
print(rc.ReadVersion(ADDR))
# Try M1
print("M1 forward")
rc.ForwardM1(ADDR, 64)
sleep(2)
rc.ForwardM1(ADDR, 0)
sleep(1)
print("M1 backward")
rc.BackwardM1(ADDR, 64)
sleep(2)
rc.BackwardM1(ADDR, 0)
sleep(1)
# Try M2
print("M2 forward")
rc.ForwardM2(ADDR, 64)
sleep(2)
rc.ForwardM2(ADDR, 0)
sleep(1)
print("M2 backward")
rc.BackwardM2(ADDR, 64)
sleep(2)
rc.BackwardM2(ADDR, 0)
Check the attached file for roboclaw.py.
The "roboclaw.py" file was outdated. In the library, you can find "roboclaw_3.py", which is the updated and working version.
pip install does not work in docker image. Therefore I was not able to run "pip install pyserial". Therefore, I had to go to pyserial official website and download the files ( https://pypi.org/project/pyserial/#files). Once I did that, I went in the folder and copied the folder named "serial" to the same repository as the roboclaw python files. Then the start.py and speed_test.py (either works) call for the roboclaw_3.py and the roboclaw_3.py called for serial from the files in the serial folder. It should run without problems.
TODOs: Figure out how to properly set the min and max battery voltages for roboclaw.
Note: start.py is used to test if the motor moves at all; speed_test.py is used to test the encoder readings as the motor accelerates and decelerates
start.py:
from roboclaw_3 import Roboclaw
from time import sleep
import serial as serial
PORT="/dev/ttyACM0"
BAUD=38400
ADDR=0x80
rc = Roboclaw(PORT, BAUD)
rc.Open()
print(rc.ReadVersion(ADDR))
# Duty cycle in percentage (0-100)
duty = 0
max_speed = 127
rc.SetMinVoltageMainBattery(ADDR,0)
rc.SetMaxVoltageMainBattery(ADDR,127)
addr = 0x80
def m1_forward(addr, duty):
print("M1 forward")
val = int((duty / 100) * max_speed)
rc.ForwardM1(addr, val)
def m1_backward(addr, duty):
print("M1 backward")
val = int((duty / 100) * max_speed)
rc.BackwardM1(addr, val)
def m2_forward(addr, duty):
print("M2 forward")
val = int((duty / 100) * max_speed)
rc.ForwardM2(addr, val)
def m2_backward(addr, duty):
print("M2 backward")
val = int((duty / 100) * max_speed)
rc.BackwardM2(addr, val)
m1_forward(addr, 100)
sleep(10)
print("Stopping M1")
rc.ForwardM1(addr, 0)
speed_test.py
from roboclaw_3 import Roboclaw
from time import sleep
PORT="/dev/ttyACM0"
BAUD=38400
ADDR=0x80
rc = Roboclaw(PORT, BAUD)
rc.Open()
print(rc.ReadVersion(ADDR))
# Duty cycle in percentage (0-100)
duty = 0
max_speed = 127
addr = 0x80
def m1_forward(addr, duty):
print("M1 forward")
val = int((duty / 100) * max_speed)
rc.ForwardM1(addr, val)
def m1_backward(addr, duty):
print("M1 backward")
val = int((duty / 100) * max_speed)
rc.BackwardM1(addr, val)
def m2_forward(addr, duty):
print("M2 forward")
val = int((duty / 100) * max_speed)
rc.ForwardM2(addr, val)
def m2_backward(addr, duty):
print("M2 backward")
val = int((duty / 100) * max_speed)
rc.BackwardM2(addr, val)
for i in range(0, 100):
enc1 = rc.ReadEncM1(addr)
enc1 = str(enc1)
speed1 = rc.ReadSpeedM1(addr)
speed1 = str(speed1)
duty = i
m1_forward(addr, duty)
sleep(0.1)
print(f"Encoder1: {enc1}, Speed1: {speed1}")
for i in range(0, 100):
enc1 = rc.ReadEncM1(addr)
enc1 = str(enc1)
speed1 = rc.ReadSpeedM1(addr)
speed1 = str(speed1)
duty = 100 - i
m1_forward(addr, duty)
sleep(0.1)
print(f"Encoder1: {enc1}, Speed1: {speed1}")
sleep(1)
print("Stopping M1")
rc.ForwardM1(addr, 0)
print(f"Encoder1: {enc1}, Speed1: {speed1}")