MOTIF SCOUT — ESP32 simulation

ESP32 DevKit V1 4WD autonomous utility rover — LINE / EXPLORE / MANUAL modes with a 3D World simulation.

An interactive ESP32 circuit simulation you can run free in your browser on Velxio, by abdelrahman-3zzam.

Components

Sketch code

/*  MOTIF SCOUT - ESP32 DevKit V1 4WD utility rover
    Modes: LINE / EXPLORE / MANUAL.  Author build: MOTIF.

    MOTIF_SIM 1 -> Velxio simulation build.
        Driver   : L293D (EN + IN/IN per side).  SIMULATION ONLY.
        Wi-Fi    : joins the simulator's open "Velxio-GUEST" network.
        Battery  : DFRobot Gravity voltage divider (1/5) on GPIO36, slider driven.
    MOTIF_SIM 0 -> real-hardware build.
        Driver   : Cytron MDD10A, sign-magnitude (PWM + DIR per side).
        Wi-Fi    : SoftAP "MOTIF-SCOUT", dashboard at 192.168.4.1.
        Battery  : 100k/33k divider (ratio 4.03) on GPIO36, 3S pack.

    The L293D is a simulation stand-in only: 600 mA continuous per channel
    cannot drive two TT motors per side on the real chassis.               */

#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <HTTPClient.h>

// One step of a buzzer signal: a frequency (0 = silence) held for ms.
// Declared up here because the Arduino builder writes its auto-prototypes
// straight after the includes, before the rest of the file exists.
struct Note { uint16_t freq; uint16_t ms; };

#define MOTIF_SIM        1
#define SELFTEST         1
// Set to 1 to step through candidate controller gains, one set per RUN, and
// print the lap score for each. This is how the gains below were chosen; it
// is off in the delivered build.
#define TUNE_SWEEP       0
// Temporary instrumentation: a task on core 0 polls the rover's own HTTP API
// the way a phone dashboard does, so the lap report's worstLoop figure shows
// what the single-threaded web server really costs the control loop.
// Measured with it on, one lap of the hard track, a poller at the dashboard's
// own 150 ms rate:
//   web server inside the control loop : 343 Hz average, worst pass 57 ms
//   web server on core 0 (as built)    : 664 Hz average, worst pass 26 ms
// Same lap quality either way - but 57 ms at full speed is 4 cm of blind
// travel, and a client that stalls mid-request costs far more than that.
#define LOADTEST         0
// Simulation only. The delivery band is a real stop the operator clears with
// RUN; for a measured run of twenty laps that is twenty button presses from
// outside the simulator, each one a chance to mistime it. With this set the
// band still stops, chimes and reports the lap, then releases itself.
// TEST HARNESS ONLY, and compiled out entirely when MOTIF_SIM is 0.
// The designed behaviour at a delivery band is to STOP and wait: the rover
// halts, sounds SIG_DELIVERY and stays paused until the RUN button, a Wi-Fi /
// serial command, or a mode change releases it. That is what the real rover
// does and it is not changed by anything here. This flag only lets the
// SIMULATION resume itself 1.5 s after a band so that repeated-lap timing can
// be collected without a human pressing RUN thirty times per configuration.
#define LAP_AUTORESUME   1
#define QUIET            1   // measurement runs: suppress [ST] and [HB]
#define BATTERY_LOCKOUT  (