A localhost-first telemetry analysis dashboard for tuning an FTC turret with PID control, signal feature extraction, and an ML-ready recommendation pipeline.
This project helps FTC teams collect turret telemetry, visualize control behavior, catch obvious control issues, and get suggested PID adjustments from recorded runs.
It is built for a practical workflow:
- Add a logging snippet to your FTC turret control loop.
- Run a repeatable step-response test.
- Copy telemetry from Android Studio Logcat.
- Paste or upload the log into a local dashboard.
- Review charts, metrics, warnings, and suggested
P / I / Dchanges.
The current system is ML-inspired rather than fully model-trained. It extracts features from telemetry and applies rule-based inference to recommend gain changes. That makes it a strong foundation for a future learned tuner.
- Paste raw Logcat lines directly into the app
- Upload a
.txttelemetry file - Enter current PID values
- View a live chart of:
- target
- position
- error
- See backend-generated plot images
- Compute basic control metrics:
- overshoot
- steady-state error
- oscillation score
- mean absolute error
- improving / not improving
- Catch likely sign problems before trusting tuning output
- Guided black/yellow dashboard UI for setup and analysis
- Run history and comparison mode
- Step segmentation when target changes
- Data-quality warnings
- Confidence scoring
- Trained regression model for PID multipliers
- Extension to drive, arm, slide, or heading PID tuning
- React
- Chart.js via
react-chartjs-2 - Custom black/yellow dashboard styling
- FastAPI
- pandas for parsing and analysis
- NumPy for signal-style calculations
- matplotlib for generated plots
- FTC SDK Java
- Android Logcat telemetry collection
FTC-Turret-PID-Tuner/
├── backend/
│ ├── main.py
│ ├── requirements.txt
│ └── saved_runs/
└── frontend/
└── src/
├── App.js
└── App.css
The backend expects telemetry in this format:
time:<float> target:<float> position:<float> error:<float> power:<float>
Example:
time:93.38 target:0.0 position:18.1 error:-18.1 power:0.30
The parser is designed to work even when full Android Logcat prefixes are present, such as:
2026-03-11 17:07:05.833 1300-1552 RobotCore com.qualcomm.ftcrobotcontroller I time:93.38 target:0.0 position:18.1 error:-18.1 power:0.30
Add logging inside your turret control loop after computing error and motor power.
String logLine = String.format(
"time:%.3f target:%.3f position:%.3f error:%.3f power:%.3f",
currentTime,
targetPosition,
currentPosition,
error,
power
);
Log.i("TURRET_PID", logLine);
telemetry.addLine(logLine);Use repeatable runs such as:
0 -> 90 -> 0
0 -> -90 -> 0
For best results:
- keep the robot stationary during the test
- start from a known turret angle each run
- keep payload conditions consistent
- capture enough time to include movement, overshoot, and settling
git clone <your-repo-url>
cd FTC-Turret-PID-Tunercd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload --port 8000On Windows:
venv\Scripts\activateThe backend should now be available at:
http://127.0.0.1:8000
In a new terminal:
cd frontend
npm install
npm startThe frontend should now be available at:
http://localhost:3000
Use a repeatable test setup.
Suggested checklist:
- robot is stationary
- turret starts from a known angle
- target angles are predetermined
- load state is consistent
- battery is reasonably consistent across runs
Install the FTC logging code in your TeleOp or test op mode.
Trigger the turret through one or more fixed target changes.
In Android Studio:
- Open Logcat
- Filter by
TURRET_PID - Copy the lines
- Paste them into the dashboard or save them as a
.txtfile
In the dashboard:
- paste telemetry or upload a
.txt - enter your current
P,I,D - click Analyze
The app returns:
- metric cards
- target/position/error chart
- backend plot image
- suggested PID values
- reasons behind the suggestion
This project does not currently use a trained machine learning model.
Instead, it uses a telemetry pipeline that looks like this:
- Parse telemetry into structured data
- Extract signal features from the run
- Infer controller adjustments from those features
- Return recommended PID values and explanations
The current backend derives features such as:
- overshoot percentage
- steady-state error
- oscillation score
- mean absolute error
- whether the turret is improving toward the target
The backend then applies rules such as:
- high overshoot → decrease
P, increaseD - steady-state error remains → increase
Islightly - oscillation present → increase
D, reduceP - motion away from target → flag likely sign issue instead of pretending the tuning is valid
So the current system is best described as:
A data-driven PID tuning assistant with ML-style feature extraction and rule-based inference.
That is a practical first phase because it creates:
- structured datasets
- repeatable feature generation
- measurable output quality
- a future path to supervised learning
Although it is rule-based today, the architecture already supports a future learned model.
- current
P,I,D - overshoot
- rise time
- settling time
- steady-state error
- oscillation count
- mean absolute error
- target magnitude
- battery voltage
- payload state
- motion direction
PmultiplierImultiplierDmultiplier
A future model could learn patterns like:
- input: high overshoot, mild oscillation, current
P=0.01,D=0.001 - output: recommend
P * 0.92,D * 1.18
- linear regression
- random forest regressor
- gradient boosting / XGBoost
- small neural network
The long-term goal is to move from:
- hand-written heuristics
to:
- learned gain recommendations from historical successful tuning runs
The current backend follows simple heuristics similar to this:
if overshoot > 10:
new_p *= 0.90
new_d *= 1.20
if steady_state_error > threshold:
new_i *= 1.10
if oscillation_score >= 4:
new_d *= 1.15
new_p *= 0.95This is intentionally transparent and easy to debug.
time:0.00 target:90.0 position:0.0 error:90.0 power:1.00
time:0.05 target:90.0 position:12.0 error:78.0 power:1.00
time:0.10 target:90.0 position:25.0 error:65.0 power:0.95
time:0.15 target:90.0 position:40.0 error:50.0 power:0.78
time:0.20 target:90.0 position:58.0 error:32.0 power:0.52
time:0.25 target:90.0 position:74.0 error:16.0 power:0.26
time:0.30 target:90.0 position:88.0 error:2.0 power:0.08
time:0.35 target:90.0 position:96.0 error:-6.0 power:-0.05
time:0.40 target:90.0 position:101.0 error:-11.0 power:-0.12
time:0.45 target:90.0 position:99.0 error:-9.0 power:-0.08
time:0.50 target:90.0 position:95.0 error:-5.0 power:-0.03
time:0.55 target:90.0 position:92.0 error:-2.0 power:0.01
time:0.60 target:90.0 position:90.5 error:-0.5 power:0.01
time:0.65 target:90.0 position:90.0 error:0.0 power:0.00
Expected behavior for a run like this:
- detect moderate overshoot
- detect settling back to target
- recommend slightly lower
Pand slightly higherD
The tuner is only as good as the run quality.
Bad data examples:
- target never changes
- too few samples
- power clipped at the same value the whole time
- turret moves away from the target
- encoder sign or motor direction is reversed
One of the most useful early checks is whether the turret is actually improving toward the target. If not, the app should warn you to fix sign conventions before tuning further.
- Save run history locally
- Add run comparison mode
- Detect target step segments automatically
- Show data-quality warnings in the UI
- Add a copy button for suggested PID values
- Compute rise time and settling time explicitly
- Support battery-voltage-aware analysis
- Add confidence scoring
- Add export to CSV / JSON
- Train a regression model on successful tuning runs
- Extend to arm, slide, heading, and drive PID tuning
- Build a reusable subsystem tuning dashboard for FTC seasons
POST /analyze
Accepts:
- pasted telemetry text
- optional uploaded
.txtfile - current
P,I,D
Returns:
- parsed metrics
- suggested PID values
- chart-ready arrays
- backend-generated plot image
The React app:
- collects user input
- posts logs to the backend
- renders metric cards
- renders Chart.js graphs
- shows returned PID recommendations and explanations
Useful contributions would include:
- step segmentation
- better signal metrics
- run history storage
- side-by-side comparison UI
- learned model training pipeline
- unit tests for telemetry parsing and feature extraction
Add your preferred license here, for example:
MIT License
You can add screenshots here later:
This project is currently a practical local PID tuning dashboard for FTC turrets.
It already provides:
- telemetry ingestion
- signal feature extraction
- automated PID suggestions
- visualization
- an ML-ready architecture
Today it is rule-based. Tomorrow it can become a trained telemetry-to-gain recommendation system.