# Introduction

A holonmic drive allows an operator to translate in any direction, independent of rotation. There are several ways to achieve this mechanically, such as through the use of omni-wheels or mecanum wheels. This article explains how to implement a holonomic drive algorithm using a drive consisting of 4 mecanum or omni wheels, such that when the wheels are driven their force vectors are arranged as below:

/\

\/

A holonomic drive is useful for situations requiring higher mobility and lower traction than a standard drive system. When the correct control scheme is used, holonomic drives can be a largely intuitive and reflexive drive choice. Using driver oriented control, joystick mixing, and drive mixing, it requires much less thought to adjusting for various conditions on the part of the driver.

# Drive Mixing

In driving a holonomic robot, it is convenient to have a function which takes a speed, direction, and rotation. This provides a clean interface to the drive for both autonomous programming and operator control. Such an algorithim takes the direction of travel and speed desired for the operation and calculates the speed to drive each wheel to achieve the desired vector. In addition, the algorithim takes in the desired rotation and adjusts the speed of each motor to achieve the given rotation while still maintaining the same velocity vector. WPILib has a function in it RobotDrive class called HolonomicDrive() that does exactly this already - which means that less time is needed to implement the actual mechanics of the program, and more time can be spent on intuitive control systems.

# Joystick Mixing

An intuitive way to drive a holonomic robot is to have the robot drive in the direction that a joystick is pointed, with a magnitude based on the distance that the joystick is from neutral. If a twisting joystick is used, the amount of twist can control the rate of rotation of the robot. In the absence of a twistable joystick, the x-axis of a second joystick can be used to control the rate of rotation. This potentially allows one joystick control of the entire drive system, which reduces the number of input controls the driver must consider while directing the motion of the robot, allowing that much more attention to be on the actual path the driver wishes the robot to take.

## Implementation

To convert the x and y axis inputs of a joystick to magnitude and direction form, it is convenient to use formulas derived to convert Cartesian coordinates to Polar coordinates - namely r2 = x2 + y2 and theta = tan-1(y/x). This will return a radius (the magnitude), and an angle (the direction). The formulas are easily applied because the input from the joystick is in ranges from negative one to one, which is the same range as a unit circle, and therefore requires no conversion to use with trigonometric identities, particularly the tangent identity of opposite over adjacent, which would scale any values outside the x2 + y2 = 1 region (namely in the areas where the joystick goes to the corner regions where both the x and y inputs are near 1 or -1). To obtain the magnitude, the x and y inputs are squared and summed, and the square root of that quantity is the vector's magnitude. The direction can be calculated using the atan2 function from math.h. This function takes an x and y coordinate and returns the angle to that point in radians, and does not break down around Pi/2 and -Pi/2, where a tradition tangent function approaches infinity due to the denominator (cos theta) approaching 0. This would be available for retrieval in degrees or radians , since the mecanum code takes its input in degrees, while the standard output of the atan2 function is in radians.

# Driver Oriented Control

A further intuitive system would be to use a gyro to track the current heading relative to the original heading, and to use this data to adjust the joystick input. The input would be adjusted to drive the robot in a direction relative to the driver, instead of relative to the robot itself. This means the driver would not have to adjust their commands to the robot mentally before sending them to the robot - when the driver move the joystick away from them, the robot always move away from them, no matter which way it is facing. Combined with joystick mixing, this control system is extremely intutive, and requires less "housekeeping" consideration during a match.

## Implementation

To implement driver oriented control, the difference of the joystick's direction input and the heading returned by the gyro can be passed in to the HolonomicDrive() function, instead of just the joystick's calculated direction input. This combination adjusts the input for the current front of the robot, so the input and reaction of the robot is always relative to the driver's frame of reference.