[BrickPi+] Deadly accurate & reliable (hopefully) Python motor driving function


After many, many hours of fun, here’s my version (python 2 & 3 friendly) of the BrickPi.py driver (won’t poll an Arduino if no motors/sensors on it, good error recovery), MultiMotorDriving.py (it stops on the mark, & will keep two motors at the same speed), and a test program. I have only tested on an RPi3, with 2 motors, and only with color & touch sensors.
Before donloading this, rename your BrickPi.py to BrickPiDI.py
I hope you find this useful.
BrickPi.py (36.9 KB)
MultiMotorDriving.py (18.4 KB)
rotationMotorTest.py (2.9 KB)


Cool, thank you so much @rolly we will test it out and maybe merge it into our code base!


I am using the brickpi+ for a class at my college. Your work has made my life so much easier now that I have angular motor control. THanks!:grinning:


Your comment gives me 72 year old mind great pleasure - thanks for it.


Your work will definitely will be put to go use, Rolly. I took control theory, but between the poor instructor, the material itself, and my own skills, I did not get much from the class. Therefore, I was not looking forward to having to come up with a feedback control system by scratch. Can I ask you how you come up with yours? Like how did you break up the problem and come to the conclusions/solutions that you did?


I’m afraid there’s nothing high & mathy about the logic, just a basic, horse sense approach that worked well for my mobile RPi3 based robot.
To stop on the mark, I thought it best to slow down before reaching it. How soon before, and how much, could be learned from past behavior, given to robot’s characteristics.
Keeping two motors in sync required a combination of how soon to correct for a difference, and how much. Amusingly, early versions waddled like an old man.
Sorry I’m not able to offer up any particular insights on the subject.
It’s going to be interesting to see how much better BrickPi3 will perform in these respects, with the control logic moved from the RPi to the BrickPi3.


I am new to this forum and have just seen this post.

Hopefully this is just what I am looking for.

Will this keep constant motor speed even as the batteries have different charge level?

I am having the problem that as the battery level changes the speed of the motor changes.


It’ll try to maintain equal speed.


I really need to see your code!!! I’ll perhaps try to to port over for the new brickpi.


It’s attached to the beginning of this thread.


Ok to use your code I have to replace my current BrickPi.py with your BrickPi.py and also add MultiMotorCriving.py?

in your routine “motorRotateDeg (power, deg, port, sampling_time=.01)” the power variable isn’t a power setting then it’s a speed setting? i.e routine will adjust power to give rotated degrees per time.

Anther question is does it do this function on the scheduler? or does it ties up the program until it has finished running the function? Can I call your routine then the rest of my routine still computes while your routine runs in the background? The reason that I ask is that I am really enjoying playing with computer vision for my robot but the downside is that the speed in which that I can move the robot is governed by the speed that I can process the frames at i.e the higher the frame rates the quicker that the robot can move.

1 last question. Your routine has a deg variable for the end point of the routine. I basically want to turn it on and have it keep doing this till I need to change it to something else (this is usually a very short time as the motor speeds and steering will be updated every frame processed atm I have it getting up around 15FPS) So if I call your routine every frame and update will it abandon where it was up to in ther last call of the function when I give it a new call of the function?


Yes, those are the files you need.
MultiMotorDriving.py will adjust the power setting for each motor (holding close to, and not exceeding the initial power setting), to keep their speeds the same.
It will also start slowing down the motor so as to hit the targeted degrees. It learns about the inertia of your robot by tracking how well it does.
The motorRotateDeg does block. If your running on a RPi 2 or 3, you might consider carving off parts of your application to the other 3 CPUs (my recent posting can get you started in this direction). I’d carve off parts that only need a few shared variables (I don’t think motor driving would qualify).
The calls block so you can’t recall on top of a previous unfinished operation.
Thanks for your interest,


Will this work on the BrickPi3? From what I’ve read that uses a brickpi3.py file instead of brickpi.py.


Sorry it won’t. My understanding (I don’t have a BrickPi 3) is that the BrickPi 3 does a much better job of what my code was wanting to do for the BrickPi+.


From what I’ve seen in the brickpi3.py file, there is no command to rotate the motors for a specific amount of degrees, which I feel is a huge omission… I was hoping your code would work. Oh well, I’ll have to find a workaround.


There is, its just called something else. Its called set_motor_position(port, deg)
Speed for that motor is set with set_motor limits(port, speed)


Ohh, gotcha. So if I do set_motor_position(PORT_A, 720) will that work as expected and rotate it twice?


So sorry, so busy, so late. :frowning.

Yes that will rotate it twice! :slight_smile:

Sorry about the late reply. :frowning: