Drivetrain
Brief
Our robot uses a 3-wheel holonomic drive for improved agility over traditional tank drives. This allows us to compete with other teams who also do so, enabling our robot to move in any direction without turning.
Development
From the beginning, we were set on a 3-wheel holonomic drive system, as opposed to the 4-wheel configuration most teams use. This was mainly to reduce weight and allow for more space on the robot. We had trouble figuring out the complicated inverse-kinematic model required to compute each motor's speed given a movement angle, theta, from the front of the robot, a speed, and an angular speed.

After doing some research, we found a very useful video on YouTube that explained this. We also double checked the math with ChatGPT to help us troubleshoot and adjust to our needs. With some effort, we put together the below movement function that is a fundamental part of the robot.
void Move(
Heading direction,
float speed,
Heading rotation,
) {
float ax = cos(direction.as_radians() + PI / 2);
float ay = sin(direction.as_radians() + PI / 2);
float motor_fr = (ax * -0.5 + ay * 0.866 + -rotation.as_radians() * 0.33);
float motor_fl = (ax * -0.5 + ay * -0.866 + -rotation.as_radians() * 0.33);
float motor_rr = (ax * 1.0 + ay * 0 + -rotation.as_radians() * 0.33);
float max = max(abs(motor_fr), max(abs(motor_fl), abs(motor_rr)));
if (max > 1) {
motor_fr /= max;
motor_fl /= max;
motor_rr /= max;
}
motor_fr *= speed / 255;
motor_fl *= speed / 255;
motor_rr *= speed / 255;
SetRawSpeeds(motor_fr, motor_fl, motor_rr);
}
Issues and Improvements
Although we had the function complete, there were some problems when practically applying this. We naively assumed the robot could spin while rotating, without external input. However, we quickly realised that as the robot spins, its frame of reference also rotates, so instead of moving in a straight line while rotating, it moves in a circular path. This can be used to our advantage, however, when using arc-shaped paths to manoeuvre past opponents or for a more unpredictable path to goal, to confuse opponents. To achieve straight line movement while spinning, an external reference point (e.g. a compass heading) can be used.
Furthermore, the discrepancies between motor speed and torque results in inaccurate movement. If we instruct the robot to move in a straight line forward, over time the path bends leftward. This is also true for other directions. A closed-loop system can easily solve this problem, with the use of encoders or hall effect sensors. However, we deemed this unnecessary, as our robot is always reacting to an external setpoint (e.g. ball or goal position) so it ends up having feedback regardless, and so the robot can still successfully navigate to these objects.