🤖 Robot Tour C Simulator
Design your track layout (2m × 2.5m), place objects, and calculate your run score
📖 How to use the Simulator (Click to expand)
Purpose
This simulator is designed for the Science Olympiad "Robot Tour" event. It helps competitors design optimal track layouts, plan robot paths (including bonus actions like bottle drops and pickups), and calculate theoretical scores based on current event rules.
How to Use
- Set Parameters: Choose your Tournament Type (Regionals, States, Nationals) to set the appropriate target time range.
- Design Track: Use the "Track Tools" to place your Start, Target, Waypoints, and Bonuses. Click a tool then click the grid to place/toggle items.
- Analyze & Simulate: The simulator calculates distance, required speed, and collision status in real-time. Use the "Simulate" button to watch the robot's movement.
- Export Code: Click "Export to C++" to generate path segment code for your Arduino or ESP32 robot controller.
- Score Calculator: Test "what-if" scenarios by entering time and distance results in the calculator section.
Pro Tips
• Waypoints snap to zone centers, edge midpoints, or corners to ensure competition legality.
• "Bottle Drop" adds a 30cm reverse move. "Bottle Pickup" ensures the turn ends exactly at the bottle.
• Adjust "Turn radius" to match your robot's physical steering capabilities.
Create Path
Waypoints snap to zone center, edge midpoint, or corner. Bottle Drop: reverse 30cm, then turn. Bottle Pickup: turn ends at waypoint, then straight. Click waypoint to remove.
Load / Save / Export Path
Event Parameters
Track Grid (200 cm × 250 cm)
Select Path
Score Calculator
Results
Max Score (current path)
Best possible score if robot follows waypoints exactly. Design path in Trajectory tab.
Scoring Rules
Run Score = 200 + Time Score + Distance Score + Bonuses + Run Penalties
Time: Run < Target → (Target − Run) × 2 | Run ≥ Target → (Run − Target)
Distance = 2.0 pt/cm × robot distance from target
Gate Bonus = −15 pts per gate entered | Water Bottle Bonus = −15 pts per bottle in gate zone
Penalties: Contact +70, No 2×4 +50, Stalling +20, Competition +150, Construction +300
Strategy
This logic runs in the simulator’s Realistic Mode and Stress Test. Use the path from Export C++ in the Trajectory tab.
Strategy: The robot follows a precomputed path of line and arc segments. Each loop, it compares its estimated position to the current segment, computes a target heading and cross-track error, then corrects with a steering term plus feedforward (velocity ratio on arcs). Motor commands are proportional to a base speed chosen to hit the target time. The robot trusts the gyro for heading and uses encoders for distance to update (x, y).
Sensors:
- Wheel encoders — Distance traveled by each wheel (ΔdL, ΔdR) for odometry and speed.
- IMU gyro — Heading θ (degrees). Used as the source of truth for rotation instead of integrating wheel diff, to avoid drift in turns.
LOOP (every 10–20 ms):
seg = path[currentSegmentIdx]
IF currentSegmentIdx >= pathLen: stop; DONE
// 1. Target heading, cross-track error, segment done?
IF seg == LINE:
targetHeading = direction of line (+180° if reverse)
crossTrackError = signed distance from robot to line
segmentDone = past end or very close
ELSE IF seg == ARC:
targetHeading = tangent to circle at robot
crossTrackError = (distToCenter − radius) × side
segmentDone = past end angle
IF segmentDone: currentSegmentIdx++; continue
// 2. Steering correction (P control)
headingError = targetHeading − estHeading
steering = Kp_h × headingError − Kp_d × crossTrackError
power = −1 if reverse else 1
// 3. Feedforward for arcs (wheel speed ratio)
leftFF, rightFF = 1, 1
IF arc: set by (R ± W/2)/(R ∓ W/2), normalize avg
// 4. Motor commands
leftCmd = (power × leftFF − steering/100) × baseSpeed
rightCmd = (power × rightFF + steering/100) × baseSpeed
// 5. Odometry
dDist = (ΔdLeft + ΔdRight) / 2
estHeading = gyroθ
estX += dDist × cos(estHeading)
estY += dDist × sin(estHeading)
drive(leftCmd, rightCmd)
Run this before tuning the path follower. Hold still 2 s to measure IMU drift, then drive a square. Compares encoder heading with drift-corrected IMU to find additional variance.
Strategy: (1) Hold still 2 s—any change in IMU heading is drift; compute drift_rate (°/s). (2) Drive square (4 × 50 cm, 4 × 90°). Use imu_corrected = imu − drift_rate × time and compare to encoder heading. The residual (|imu_corrected − heading_enc|) is variance beyond drift—scale error, turn inconsistency, etc.
Sensors tested:
- Encoders — Heading from wheel differential; position from dead reckoning.
- IMU gyro — Raw heading. Drift measured when still; corrected during run for residual analysis.
// 1. Drift calibration (robot still 2 s)
imu_start = readGyro()
delay(2000)
drift_rate = (readGyro() − imu_start) / 2.0 // °/s
// 2. Square run
FOR each of 4 sides:
drive straight 50 cm, turn 90° CW
imu_corrected = readGyro() − drift_rate × elapsed
residual = |imu_corrected − heading_enc|
max_residual = max(max_residual, residual)
// 3. Report
Serial: drift_rate, max_residual, final_pos_error