DEV Community

Someone.
Someone.

Posted on

DEVLOG – How to Move Straight in a Line?

Getting a small robot (SPIKE Prime, in my case) to move in a straight line is harder than it looks.

Thus, methods such as PID exist, but I didn't want to use such complicated (and not 100% understood) algorithms just because it's there (Notice that I did not do any research, this was all trail-and-error work).

Problem Statement

To cope with any problem, we first need to tailor it into a problem statement that is explicit and understandable, so here's ours: "How can I make a SPIKE Prime robot move X distance in a straight line, while pulling an external load?"

Center of Mass

It may seem obvious,"Just let it move 0 degrees!", you might say. However, the center of mass (the point at which the total mass of the object is concentrated) is not always in the center. In fact, only regular bodies have their center of mass coinciding with the geometric center; for all other objects, these points do not coincide.

Therefore, commanding the robot to move at angle 0, will let it tilt over time.

PROPOSAL #1: MOVE(0 - YAW)

My initial idea was to let the robot move (0 - yaw) degrees, That is, ensuring that whenever the robot detects any tilting (by it's internal gyroscope), it readjusts accordingly.

However, due to the robot programming limitations, I needed this function to run in a loop, and loops do not support "MOVE UNTIL X DISTANCE", so I had to find a way to move it with a time. Thus, I came up with this idea:

  • Start a timer (T)
  • Let the robot move X cm at 0 degrees.
  • Let speed = X ÷ T

This is the not on the required path, as the track have many tasks:
1 - Move to point A-B straight
2 - Move to point B-C with a load.

so, for task 1, the robot can move in a straight line due to the short distance and that there no external load. Thus, we can calculate the speed of the robot.

Then, for task 2, we need to run a loop for the MOVE(0 - YAW) method to work, and to get the required time the robot needs to run to go to X distance, we can do: time = d/v, which we already have d and v.

PROPOSAL #2: Displacement-based Movement

The first proposal introduced a way to move in a straight line, however, since the robot doesn't move in a linear movement, but in tilting (0 - yaw) movement, Time becomes obsolete, as the total distance will increase, time needed will also increase.

So, instead of relying on time, we track the actual straight-line displacement of the robot from its starting point. This means we care only about the distance “as the crow flies,” not the total path traveled, which may curve slightly due to tilting.

How it works:

  1. Initialize a vector position (Rx, Ry) at (0, 0).

  2. Every small time interval (tick):

  • Measure how far the robot moved since the last tick. This can be done via the wheel encoders.

  • Read the current yaw angle from the gyroscope.

  • Update the vector position along the direction of motion:

Rx = Rx + A × cos(yaw)

Ry = Ry + A × sin(yaw)

Here, A is the distance moved in this tick, computed from the wheel rotation (or, A = v × t).

  1. Calculate the straight-line displacement: R = sqrt(Rx^2 + Ry^2)

  2. Stop the robot when R ≥ X, where X is the desired straight-line distance.

While this is theoretically correct, it didn't work out due to the robot limitations! Well... I guess back to PID 😄.

Top comments (0)