The previous discussion of motion profiling wraps up motion control for mechanisms with one degree of freedom. The remainder of the tour will extend these ideas to 2D robot movement.
In order to describe 2D motion, we need a consistent global coordinate frame. Within this global frame, the robot's position can be described using typical Cartesian
coordinates. In addition to the linear position, the robot has a heading
defined as the angle between the front of the robot and the global
axis. The position and heading together constitute the robot's pose.
2D vectors and poses are built into the library and serve as primitives for many other classes.
Vector2d position = new Vector2d(x, y);
Pose2d pose = new Pose2d(position, theta);
val position = Vector2d(x, y)
val pose = Pose2d(position, theta)
In addition to the global coordinate frame, there is a robot coordinate frame that moves along with the robot. Paths are more conveniently described in the global frame while robot velocities are more conveniently described in the robot frame. To accommodate this, Road Runner constantly switches between frames.
Transformation of a velocity vector between frames
Consider a velocity vector
in the global frame. To find the equivalent representation
in the robot frame, we can apply a rotation transformation. This transformation can be represented by the following matrix:
2D rotation matrix
With this matrix, the transformation is simple:
. Since the inverse of
. Note the angular velocity
remains the same between frames.
As you might expect, rotations are built into the
Vector2d v = new Vector2d(x, y);
Vector2d w = v.rotated(rotAngleRad);
val v = Vector2d(x, y)
val w = v.rotated(rotAngleRad)
More sophisticated transformations can be found in
Kinematics. For instance, the aforementioned pose-to-pose velocity transformation is