OmniRoller Holonomic Drive Tutorial
OmniRoller Holonomic Drive Tutorial
OmniRoller Holonomic Drive Tutorial
Omni wheels have rollers all the way round the tread so they can slip laterally as well as drive in the
direction of a regular wheel. The three-wheeled holonomic drive with omni roller wheels is usually
called a 'Kiwi Drive'. But how to control this robot? We use a bit of trig and some matrices. We also
look at forward kinematics and inverse kinematics.
s1
M2 α2 M1
α1
s2
α3
Y
M3 X
Robot frame
s3 origin is at bot
centre
α is the angle of the motor axis from the x axis of the robot coordinate frame
α1 = 30°; α2 = 150°; α3 = 270°
Say the motor is going to turn clockwise (as seen from the wheel end of the motor) then it will drive
in the direction shown by the arrows 's'. Omni-wheels slip in the direction of the motor axis α. The
wheel drive axis, shown by the 's' arrow, is 90° or π/2 from its respective α.
We will add π/2 to α to get the direction of each wheel. (But you could also subtract the π/2, it's not
important actually). (We are using degrees here, but be aware any calculations with trig in Microsoft
Excel will need radians. We don't use that here.)
w1 = α1 + π/2 = 30° + 90° = 120°
w2 = α3 + π/2 = 150° + 90° = 210°
w3 = α3 + π/2 = 270° + 90° = 0°
When each wheel turns +ve (clockwise) it has a speed 's' in the direction shown. When it turns -ve it
has a speed -s. We need to resolve the vector associated with 's' (the wheel 'drive' orientation) into
x and y components in the robot coordinate frame. In this design with each wheel arranged radially
from the centre it's not necessary to factor in the distance of the wheel from the centre of the robot.
To resolve the vector 's' into x and y components we use some simple trigonometry.
Y
α
s y
x X
α + π/2
π/2
This equation shows that we can take a vector of speed information for all the motors, then pre-
multiply it by the matrix M, to determine a velocity vector that the robot will follow.
M-1 =
As an aside, let's write this inverse matrix in Wolfram Alpha plaintext notation because we will use it
in some examples for driving the robot: M-1 = {{-0.33, 0.58, 0.33}, {-0.33, -0.58, 0.33}, {0.67, 0, 0.33}}
Back to the math: We then multiply the inverse matrix M-1 into both sides of the matrix equation we
had before:
On the right hand side, the product of the matrix and its inverse cancels out leaving:
This can be used to navigate the robot. We can form a command to drive the robot in x, y and ω.
We format the command as = (x, y, ω) then pre-multiply that by the inverse kinematic matrix
to find the set of individual speeds = (s1, s2, s3) that we need to apply for each motor.
The steps would be: for each omni-wheel, decompose the wheel's drive axis into x and y
components in the robot coordinate frame; create the forward kinematic matrix and then invert it;
pick any direction to move in and decompose that into x and y components in the robot coordinate
frame (set ω to 0 for no rotation); then pre-multiply the command by the robot inverse kinematic
matrix to get the speed for each omni-wheel. The omni-wheels will just slip laterally on their rollers
as needed to achieve the desired direction. Easy. But for rotations though, with uneven layouts, it
would be necessary to allow for the distance of each omni-wheel from the robot centre or datum
point. The more asymmetric the layout, the more likely it is that there will be directions that the
robot doesn't easily move along, and it can become mechanically unstable. Symmetric designs are
somewhat easier as regards the math (regarding rotation) and can be more stable.
Coordinate Frames
The robot coordinate frame is a datum point (or origin) with orthogonal X and Y axes, referenced to
the robot chassis. It may be useful to mark this on the robot. It's OK to plan motion by reference to
the robot frame. This allows the robot to plan to move in particular directions relative to its own
orientation and then move accordingly. But to navigate in the world it can be useful to consider the
world coordinate frame as well. This is like having an X and Y on the floor, or a map with a grid
reference system. The robot frame and the world frame can be in arbitrary orientations with
respect to each other. People that use RC models get used to the idea that commands have to be
referenced to the coordinate system (or orientation) of the model. Some models (like Arducopter
drones) have a 'super simple mode' where they use sensors to factor out the model orientation and
allow control inputs to be given the same way regardless of the model orientation: In 'super simple
mode' forwards on the stick will fly the model away from the pilot even if its orientation is facing in
towards the pilot. This is moving in the world coordinate frame.
By knowing the relationship between the robot frame and the world frame, it's possible to plan
robot moves relative to the real world. Measuring the relationship between the robot frame and
the world frame needs sensors like GPS, an electronic compass, a laser-ranging system or like gyros,
accelerometers or odometer wheels. It's possible to easily map between the robot frame and world
frame using matrices. For a robot moving in 2D on the floor, a 3x3 matrix works to fully determine
position and orientation parameters between the robot and world coordinate frames. Values in the
matrix would be constantly updated by sensor readings.
Writing code so that you can easily switch between movements in the robot frame and the world
frame is a good idea. For example this would make it easy to navigation to a target position while
avoiding unexpected or moving obstacles. Details are not covered in this article, which only looks at
motion in the robot coordinate frame.
More than Three Wheels? The Killough Drive
A symmetrical holonomic drive with four omni wheels is usually called a 'Killough Drive'. This is
shown in an 'X' configuration below but it works in a similar way if it's rotated by 45° into a '+'
configuration, where the motor angles would be 0°, 90°, 180° and 270°. One thing to bear in mind
with more than three wheels is that some form of chassis flexibility or suspension will help to keep
all the wheels touching the ground in cases where the floor isn't mirror-flat. Omni-wheel robots
though, are probably somewhat better-behaved than Mecanum wheel robots when a wheel does
lose contact with the ground.
s1
M2 M1
s2 α2 Y
α1
α3
X
α4
Robot frame
s4 origin is at bot
M3 centre
M4
s3
In the 'X' configuration, the angle of each motor axis from the robot coordinate frame 'x' axis is:
α1 = 45°; α2 = 135°; α3 = 225°; α4 = 315°
We add π/2 to α to get the drive direction of each wheel:
w1 = α1 + π/2 = 135°
w2 = α3 + π/2 = 225°
w3 = α3 + π/2 = 315°
w4 = α3 + π/2 = 45°
We use trig to express the direction of each wheel as components in x and y relative to the robot
coordinate frame:
For wheel 1: x1 = cos(α1 + π/2).s1 and y1 = sin(α1 + π/2).s1
and the same for the other three wheels. Then gather up all the individual motor contributions to
the robot motion in x, in y and in ω:
x = x1 + x2 + x3 + x4; y = y1 + y2 + y3 + y4; ω = s1 + s2 + s3 + s4
To use the summed x and y contributions we need to substitute in the trig expressions we worked
out that express the x and y contributions of each motor in terms of 'α' and 's' to get:
x = cos(α1 + π/2).s1 + cos(α2 + π/2).s2 + cos(α3 + π/2).s3 + cos(α4 + π/2).s4
y = sin(α1 + π/2).s1 + sin(α2 + π/2).s2 + sin(α3 + π/2).s3 + sin(α4 + π/2).s4
Or better yet, write the x, y and ω contributions as a matrix equation:
α π α π α π
α π α π α π
ω
In order to navigate the robot we need to rearrange the matrix equation for
To do this we need to calculate the inverse of matrix M and multiply it into both the right and left of
the equation. We can write the forward matrix in Wolfram Alpha plaintext notation in order to
invert it with a mouse-click, via http://www.wolframalpha.com
invert {{cos(45+90), cos(135+90), cos(225+90), cos(315+90)}, {sin(45+90), sin(135+90), sin(225+90),
sin(315+90)}, {1, 1, 1, 1}}
This gives the inverse kinematic matrix M-1
M-1 =
s1
s2 M2 M1
s6
α3 α1
M3 M6
α6
s3 M5 s5
M4
X
Robot frame
origin is at bot
centre
s4
The motor angles are α1 = 60°; α2 = 120°; α3 = 180°; α4 = 240°; α5 = 300°; α6 = 0°
The wheel drive angles are found by adding 90° or π/2 added onto the motor angle.
The matrix equation that expresses the contribution of each wheel to the robot motion is:
M-1 =
=
With this inverse matrix we can command the robot to move in given directions, using a matrix
multiplication to determine the motor speed settings that must be applied in order to accomplish
the required motion.
For example, to move rightward in the +x direction, (x, y, w) = (1,0,0)
This would be multiplied by M-1 in the controller code, but we can test it in Wolfram Alpha:
{{-1/(2 Sqrt[3]), 1/6, 1/6}, {-1/(2 Sqrt[3]), -1/6, 1/6}, {0, -1/3, 1/6}, {1/(2 Sqrt[3]), -1/6, 1/6}, {1/(2
Sqrt[3]), 1/6, 1/6}, {0, 1/3, 1/6}}*{1,0,0}
Octo-Omni-Bot?
Eight omni-wheels is a lot. This would be a fairly unique configuration. With this many wheels the
math needs to be right or the wheels could end up fighting each other.
s2
s3
s1
M3 M2
M4 M1
α4
s4 α1
s8
α8
M5 M8 Robot frame
origin is at bot
centre
M6 M7 Y
s5 s7
X
s6
The math is no more complex than for bots with fewer wheels. The motor angles in this
configuration are:
α1 = 22.5°; α2 = 67.5°; α3 = 112.5°; α4 = 157.5°; α5 = 202.5°; α6 = 247.5°; α7 = 292.5°; α8 = 337.5°
The wheel drive angles are derived by adding 90° or π/2 onto the motor angle.
The matrix equation that expresses the contribution of each wheel to the robot motion is:
ω
We can use Wolfram Alpha to invert the forward kinematic matrix. But in this case we manually
reduce the sin and cos terms to make the expression a bit shorter. So this:
invert {{cos (112.5), cos(157.5), cos(202.5), cos(247.5), cos(292.5), cos(337.5), cos(22.5), cos(67.5)},
{sin (112.5), sin(157.5), sin(202.5), sin(247.5), sin(292.5), sin(337.5), sin(22.5), sin(67.5)}, {1, 1, 1, 1,
1, 1, 1, 1}}
gets reduced to this:
invert {{.924, .383, -.383, -.924, -.924, -.383, .383, .924}, {-.383, -.924, -.924, -.383, .383, .924, .924,
.383}, {1, 1, 1, 1, 1, 1, 1, 1}}
Which in turn gives the inverse kinematic matrix M-1
M-1 =
With this inverse matrix we can command the robot to move in any given direction, using a matrix
multiplication to determine the motor speed settings that must be applied in order to accomplish
the required motion. All the wheels will help, so long as we got the math right.
For example, let's drive the robot on a bearing of 22.5°. If we do this we would expect motors M1
and M5 to have zero rotation and motors M3 and M7 to turn fastest. Motors M2, M3, M4 should
have a negative rotation and motors M6, M7, M8 should have a positive rotation (look at the robot
diagram!)
We need to convert the heading of 22.5° into x and y components. The x component is cos(22.5)
and the y component is sin(22.5), so this is 0.383 and 0.924 respectively. We will set the rotation ω
to zero here.
To drive forwards and right on a heading 22.5°, (x, y, w) = (0.383, 0.924, 0)
This would be multiplied by M-1 in the controller code, but we can test it in Wolfram Alpha:
{{.231, -.096, .125}, {.096, -.231, .125}, {-.096, -.231, .125}, {-.231, -.096, .125}, {-.231, .096, .125}, {-
.096, .231, .125}, {.096, .231, .125}, {.231, .096, .125}}*{.383,.924,0}
It is clear that the speeds came out as we expected. Looking at the eight motor speeds and at the
robot diagram, it's clear that the robot would move in the correct direction given these speed
settings. The octo version is under construction with an Intel Galileo Mk2 controller; Devantech
EM25 motor drives; Devantech EMG30 motors with quadrature shaft encoders and; using modified
Vex omni-wheels. The Vex omni-wheels have custom stainless hubs grafted into them so they fit
nicely on the 5mm shafts of the EMG30 motors.
Raspberry Pi (especially the new Model 2 B version) would also be a great controller for this type of
robot. It probably depends whether you prefer coding in Arduino 'sketches' (for Galileo or any
Arduino type controller) or Python (for Raspberry Pi).