Anth's Computer Cave

Stirling Robot software: RobotMoves

6th February, 2019

In this article we'll cover the RobotMoves primary movement module, To see the other RobotMoves modules available, click the Software Overview button above.

You can download the latest version of the RobotMoves suite of modules here. This was updated on the 6th of March, 2019.

A Stirling robotic vacuum cleaner with added sensors and a new head. Picture: Anthony Hartup.
Stirling in its current form with its new head

Inside the robot_moves folder you'll find, the movement module for all of Stirling's other programs to control.

You may need to modify a few lines in

Firstly, you'll need to change the GPIO pin numbers to suit your motor pins. You'll find the pins array on line 33 of

assigning the PWM pins for motors

There are entries for each motor's forward and reverse pins, plus an enabler pin. If your motor controller doesn't need enabler pins you can remove the enab entries from the pins array.

Also in the folder is a JSON file, moves.txt. This contains the basic details for your motors, such as the default speed and the time in seconds to travel one metre and pivot 360-degrees It also has the callibration offsets to match the speeds of the motors.

There are functions to set most of these properties. The main thing you may wish to change manually is the default speed for the robot. It is currently set to 60%.

[{"speed": 60, "metre": 4.0, "full_turn": 4.0}, {"pwm_1": 1.0, "pwm_2": 1.0, "pwm_3": 1.0, "pwm_4": 1.0}]

Save the Python program and text file and open an SSH terminal to your Raspberry Pi. Navigate to the robot_moves folder and open a Python terminal by typing:


At the prompt type:

import robot_moves


There are three main movement functions.

drive_straight() will drive the robot forwards or backwards for the specified number of centimeters.

turn_in_place() will pivot the robot left or right for the number of degrees specified.

drive_straight_and_veer() will drive forwards or backwards, veering in a given direction.

To test forward movement, type:

robot_moves.drive_straight('forwards', 50)

The first argument tells the robot to move forwards. The next argument is the distance in centimeters.

Your robot should move forward now. I you find it veers in one direction, you have one motor that is faster than the other. We'll callibrate that soon.

Now you can try swiveling the robot in place. Type:

robot_moves.turn_in_place("left", 90)

Here the first argument is rotation direction, the second is number of degrees to pivot.

The robot should rotate. It may not pivot exactly 90 degrees and may also spin unevenly because we haven't callibrated the motor-speeds and turning speeds yet.

The drive_straight_or_veer() function is a multi-purpose movement function with more options. It allows you to veer left or right, set the speed and define the distance in centimeters or seconds.

For example, type:

robot_moves.drive_straight_or_veer("forwards", -20, 60, 5, measurement="seconds")

The first argument tells the robot to move forwards. The next argument, -20, tells it to veer left as if the steering wheel is at 20-degrees. A negative value will veer left, a positive value will veer right. The third argument, 60, sets the PWM duty-cycle to 60%, while the fourth argument, 5, sets the motor run-time to five units. The fifth argument sets the units to either seconds or centimeters.

Your robot should move forward now, veering left.

Callibrate motors

As mentioned above, it is unlikely both of your motors are spinning at the same speeds, so for straight driving and even swiveling we need to callibrate the motors.

We'll start with the straight drive test. Place the robot so it has a few metres clearance in front. Type:

robot_moves.straight_drive_test("forwards", 50)

The robot will move forwards, then prompt for feedback. If the robot veered left type l. If it veered right, type r. If it drove straight, type c.

The robot will repeat these steps until you type c, then ask if you wish to save the new settings. We're not finished yet, so type n.

Many motors will have different speeds spinning clockwise and anti-clockwise. Therefore we need to repeat the test moving backwards. Re-position your robot with enough clearance to the rear, then type:

robot_moves.straight_drive_test("backwards", 50)

Once again, type l or r until the robot drives straight, then type c. When prompted to save, type n.

Now our motors are synced, we'll adjust the time required to drive one metre.

We'll start with the distance drive test. Place the robot so it has a few metres clearance in front, and place a marker at the rear edge. Type:

robot_moves.distance_drive_test("forwards", 50)

The robot will move forwards, then prompt for feedback. Measure how far the robot has moved from the marker, then move the marker to the new position. If the measurement was longer than 50 centimeters, type l. If shorter than 50 centimeters, type s. If exactly 50 centimeters, type c.

The robot will repeat these steps until the distance is correct, then ask if you wish to save the new settings. We're still not finished yet, so type n.

Once the metre time is correct, the final task is to set the turning time for 360-degrees.

Place a marker such as a pencil pointing to the center-front of the robot and type:

robot_moves.turn_test("right", 90)

The robot will perform four approximately 90-degree pivots to make 360-degrees, then prompt for feedback.

If the robot has pivoted beyond your marker, move your marker to the center-front again and type l. If is has not reached the marker, reposition the marker and type s.

As before, it will keep performing the turns until you type c for correct.

Now, when prompted to save the new settings, type y.

Your motors are now callibrated. Note that without using additional sensors like wheel encoders, the movements won't be perfect every time, and they may vary on different surfaces and also according to battery-charge level. You'll also need to re-callibrate the motors if you change the default speed in the speed settingts file.

Drive motors in background

So far we've used robot_moves to drive pre-determined distances, but there are other ways to start and stop the motor.

Using the same functions as before you can start the robot travelling in the background, allowing your programs to do other things while driving. You then stop the motors when needed using the brake() function. You can see a simple example of this in our new CamBot module, where we use the feature to drive the wheels continually while a button is down on the controller, and brake as soon as the button is lifted.

To start the robot moving forward we use the same command as before, but this time we use the leave_on argument in the function call.

An example call would be:

drive_straight("forwards", 40, leave_on="yes")

Because we are using leave_on, the second argument, 40 (usually the distance), is just a placeholder. The robot will ignore the distance and simply start travelling, then exit the function. It will keep moving until you choose to stop it with:


The turn_in_place() function works the same with leave_on enabled. To start pivoting left:

turn_in_place("left", 90, leave_on="yes")

The function will this time ignore the second argument, 90 (usually the degrees), and just exit once the robot is moving.

The robot will keep swivelling untill you call the brake() function.

Closing the program

Before you close the robot_moves program you need to run the cleanup command. This will switch off and clean up the GPIO pins. To close the program, type:


Now press CONTROL + D to exit Python.




Previous: RobotMoves overview

Next: RobotMoves sensor module



Leave a comment on this article