Intro

Abstract

Implement a Fuzzy Logic Agent to control a physically simulated racecar on procedurally generated racetracks.
The objective is to maximize sustained speed while avoiding crashes, stalls, or reversing.
Control is achieved by designing fuzzy rules that output Throttle and Steering in the range [-1, 1], using only the provided fuzzy logic framework.

TODO

  • Implement fuzzy steering control
  • Implement fuzzy throttle control
  • Ensure full rule coverage (no gaps)
  • Tune for all 4 tracks
  • Remove all debug/hardcoded controls before submission

Setup

  • Work in:
    Assets/Scripts/GameAIStudentWork/FuzzyVehicle.cs

  • Use provided:

    • AIVehicle API (vehicle control + telemetry)
    • Fuzzy Logic Library (rule system + defuzzification)
    • Racetrack API (track sampling, curvature, forward direction)
  • Test scenes:

    • RaceTrackFZ (very curvy)
    • WindingRaceTrackFZ (moderate)
    • FastSweepersRaceTrackFZ (fast turns)
    • DragRaceFZ (straight)
  • Optional:

    • Use human driving scene to understand physics: /Scenes/<TrackType>RaceTrackHuman

Implementation

  • Starter code: FuzzyVehicle.cs

Core Idea

  • Compute crisp inputs from:
    • Speed
    • Angle to track direction
    • Distance from center line
    • Future/lookahead position
  • Convert to fuzzy values
  • Apply rules → defuzzify → output control

Core API (DO NOT BYPASS)

ApplyFuzzyRules(
    throttleFRS,
    steerFRS,
    fuzzyInput,
    out throttleRuleOutput,
    out steeringRuleOutput,
    ref mergedThrottle,
    ref mergedSteering
);
  • This is the ONLY valid way to set:

    • Throttle
    • Steering

Key Inputs to Consider

  • Speed
  • Signed angle to track forward
  • Distance from center
  • Lookahead direction
futurePos = currentPos + velocity * lookaheadT;

Example Rule Ideas

  • Steering:

    • “If angle is left → steer left”
    • “If far right of track → steer left”
  • Throttle:

    • “If slow → accelerate”
    • “If turning sharply → reduce throttle”
    • “If straight + aligned → max throttle”

Requirements

  • Smooth continuous control (no hard switches)
  • Overlapping fuzzy sets (for interpolation)
  • ≥ 3 output states per control
  • Multiple rules firing simultaneously
  • Full input coverage (no dead zones)

Important Restrictions

  • ❌ No direct setting of Throttle or Steering
  • ❌ No HardCodeThrottle/Steering in final submission
  • ❌ No accessing INTERNAL variables
  • ❌ No decision trees outside fuzzy logic


Debugging Tools

  • Debug.DrawLine() / DrawRay()

  • HUD (vizText)

  • Fuzzy diagnostics:

    • RenderFuzzySetAscii
    • DiagnosticPrintFuzzyValueSet
    • DiagnosticPrintRuleSet

Tests

Completed

TODO

  • Read assignment spec
  • Basic steering rules
  • Basic throttle rules
  • Lookahead tuning
  • Pass all 4 tracks
  • Final cleanup (remove debug)

Racetrack + Physics Notes

Warning

Do not call anything marked INTERNAL or directly manipulate wheels or performance metrics.


Procedurally Generated Tracks

  • Based on Seb Lague’s Path-Creator
  • Modified for:
    • real-time procedural generation
    • runtime sampling

Racetrack API (key idea)

Use Racetrack to get:

  • curvature
  • position along track
  • forward direction
  • lookahead info

👉 These should be your crisp inputs to fuzzy logic


Physics and Vector Math Overview

Distance–Velocity–Time

Fundamental relation:

  • Turning behavior:

    • High speed → risk of understeer/oversteer
  • Turning radius:

    radius = wheelbase / tan(steerAngle)
    
  • Predict future position:
Vector3 futurePos = currentPos + velocity * lookaheadT;

👉 Critical for lookahead steering

Vectors and Points

Unity’s Vector3 represents both points and vectors, though conceptually they are different:

  • A point identifies a location
  • A vector represents a direction and magnitude

Key relationships

Direction from A to B:

Translate a point:

Average of two points:

Adding two points directly is undefined (except for averages like above)


Useful Unity Functions

  • Vector3.SignedAngle(a, b, axis) → signed angle (use for steering)

  • Vector3.Distance(a, b) → distance

  • Vector3.Normalize(v) → unit vector

  • Vector3.Project(a, b) → projection (useful for track alignment)


Important Edge Case

If velocity = (0,0,0):

  • No direction
  • Normalization may break
  • Can cause NaNs

👉 Always guard against:

  • division by zero
  • invalid normalization

Tips

Strategy Tips

  • Start simple:

    • Stabilize steering first
    • Then add throttle logic
  • Use lookahead steering for smoother turns

  • Reduce throttle when:

    • angle error is large
    • curvature is high
  • Increase throttle when:

    • aligned with track
    • low curvature