VingVing Robot LogoVingVing Robot

Documentation v0.0.3

VingVing Robot Docs

Bezier Curves Deep Dive

Understanding the mathematics and control of Bezier curve paths

What Are Bezier Curves?

Bezier curves are parametric curves defined by control points. They create smooth, predictable paths that are perfect for robot navigation. VingVing Robot supports both quadratic (3 points) and cubic (5 points) Bezier curves.

Cubic Bezier Curves

Anatomy of a Cubic Bezier:

new BezierCurve(
    new Point(0, 0, Point.CARTESIAN),      // P0: Start point
    new Point(0, 0, Point.CARTESIAN),      // P1: Start point (duplicated for continuity)
    new Point(12, 12, Point.CARTESIAN),    // P2: First control point
    new Point(36, 12, Point.CARTESIAN),    // P3: Second control point
    new Point(48, 0, Point.CARTESIAN)      // P4: End point
)

// 5 points total:
// - 2 identical start points (P0, P1)
// - 2 control points (P2, P3) that shape the curve
// - 1 end point (P4)

How Control Points Work:

  • P2 (first control): Pulls curve in direction from start - determines initial curve direction
  • P3 (second control): Pulls curve toward itself from end - determines final approach angle
  • Distance matters: Control points farther from start/end create gentler curves
  • Positioning: Control points don't have to lie on the curve - they define its shape

Example: S-Curve

// Create smooth S-shaped path
new BezierCurve(
    new Point(0, 0, Point.CARTESIAN),
    new Point(0, 0, Point.CARTESIAN),
    new Point(16, 16, Point.CARTESIAN),    // Pull up-right from start
    new Point(32, -16, Point.CARTESIAN),   // Pull down-right to end
    new Point(48, 0, Point.CARTESIAN)
).setTangentHeadingInterpolation()

Quadratic Bezier Curves

// Simpler 3-point Bezier
new BezierCurve(
    new Point(0, 0, Point.CARTESIAN),      // Start
    new Point(24, 24, Point.CARTESIAN),    // Single control point
    new Point(48, 0, Point.CARTESIAN)      // End
)

// Creates symmetric arc with peak at control point projection

When to Use Quadratic:

  • Simple arc paths (avoid obstacle, round corner)
  • Symmetric curves (same curvature in and out)
  • Easier to visualize and plan than cubic
  • Less control than cubic but simpler to tune

Designing Effective Curves

Rule 1: Control Point Distance = Curve Gentleness

// Tight curve - control points close to endpoints
new BezierCurve(
    new Point(0, 0, Point.CARTESIAN),
    new Point(0, 0, Point.CARTESIAN),
    new Point(6, 6, Point.CARTESIAN),      // Close
    new Point(42, 6, Point.CARTESIAN),     // Close
    new Point(48, 0, Point.CARTESIAN)
) // Sharp S-curve

// Gentle curve - control points far from endpoints
new BezierCurve(
    new Point(0, 0, Point.CARTESIAN),
    new Point(0, 0, Point.CARTESIAN),
    new Point(20, 20, Point.CARTESIAN),    // Far
    new Point(28, 20, Point.CARTESIAN),    // Far
    new Point(48, 0, Point.CARTESIAN)
) // Smooth, wide S-curve

Rule 2: Symmetrical Control = Balanced Curve

// Symmetrical control points create balanced curves
new BezierCurve(
    new Point(0, 0, Point.CARTESIAN),
    new Point(0, 0, Point.CARTESIAN),
    new Point(12, 18, Point.CARTESIAN),    // Distance from start: ~21 inches
    new Point(36, 18, Point.CARTESIAN),    // Distance from end: ~21 inches
    new Point(48, 0, Point.CARTESIAN)
) // Smooth, predictable curve

// Asymmetrical = unbalanced (but sometimes useful!)
new BezierCurve(
    new Point(0, 0, Point.CARTESIAN),
    new Point(0, 0, Point.CARTESIAN),
    new Point(6, 12, Point.CARTESIAN),     // Close to start
    new Point(42, 24, Point.CARTESIAN),    // Far from end
    new Point(48, 0, Point.CARTESIAN)
) // Sharp initial turn, gentle approach

Rule 3: Approximate Circles

// Magic number for circular arcs: 0.551915024494
double radius = 24.0;
double controlDist = radius * 0.551915024494;

// Quarter circle (90° arc)
new BezierCurve(
    new Point(0, radius, Point.CARTESIAN),
    new Point(0, radius, Point.CARTESIAN),
    new Point(controlDist, radius, Point.CARTESIAN),
    new Point(radius, controlDist, Point.CARTESIAN),
    new Point(radius, 0, Point.CARTESIAN)
) // Perfect 90° arc

// Chain 4 of these for complete circle

Chaining Bezier Curves

Smooth Transitions Between Curves:

// Each curve's end point = next curve's start point
follower.followPath(
    // Curve 1
    new BezierCurve(
        new Point(0, 0, Point.CARTESIAN),
        new Point(0, 0, Point.CARTESIAN),
        new Point(12, 8, Point.CARTESIAN),
        new Point(20, 12, Point.CARTESIAN),
        new Point(24, 12, Point.CARTESIAN)  // End here
    ).setTangentHeadingInterpolation(),

    // Curve 2 starts where Curve 1 ended
    new BezierCurve(
        new Point(24, 12, Point.CARTESIAN),  // Start here
        new Point(24, 12, Point.CARTESIAN),
        new Point(30, 12, Point.CARTESIAN),
        new Point(42, 24, Point.CARTESIAN),
        new Point(48, 24, Point.CARTESIAN)
    ).setTangentHeadingInterpolation()
);

// Robot smoothly transitions between curves

Visualization and Debugging

Using FTC Dashboard:

FTC Dashboard shows your Bezier curves as green lines before running. Use this to verify:

  • Curve doesn't intersect obstacles or go out of bounds
  • Control points create desired shape (adjust if too sharp/gentle)
  • Path length is reasonable for time constraints
  • Multiple curves chain smoothly without kinks

Common Issues:

Sharp kinks: Control points too close to endpoints - move them farther away

Curve goes backward: Control points placed behind start/end - reposition forward

Not smooth enough: Control points too far - bring them closer for tighter curve

Bezier Tips

💡 Start with Simple Arcs

Use quadratic (3-point) Beziers first to get comfortable. Graduate to cubic (5-point) when you need more control over curve shape.

💡 Measure on Field

Place tape or markers on field tiles for your endpoints and control points. Easier than guessing coordinates.

💡 Use Tangent Heading on Curves

Bezier curves work best with tangent heading interpolation - robot naturally follows the curve direction.

💡 Test One Curve at a Time

When designing complex paths with multiple curves, test each curve individually before chaining them together.