Add shot tuning mode and improve shooter tuning slightly#82
Add shot tuning mode and improve shooter tuning slightly#82
Conversation
…d flight time analysis Adds a complete shot tuning workflow: record shots via webcam with configurable frame rate (30/60/120 fps), connect to robot NT4 telemetry for live distance/RPM/hood angle, replay videos with frame-by-frame stepping (keyboard shortcuts: j/k, h/l, arrows, space), mark shooter-exit and target-hit timestamps to compute flight time, and export data points to the existing Shot Maps interpolation tables. Uses a raw NT4 WebSocket client (bypassing ntcore-ts-client which crashes on WPILib struct types) to read pose, actual shooter lead/follower velocities, and hood angle. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…' into 80-shot-tuning-mode
|
I think we accidentally collided on this branch. I didn't know you wanted to merge this. BTW, what fps do you think we'll need for this? PS: It looks like I get only 30fps on the webcam I own or that are builtin my laptop. I tried connecting my Pixel 9a via UVC, but that also only supports 30fps. |
Auto-collapses on connect, shows connected address in status chip, and adds expand/collapse toggle. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sorry about that. We can keep this open until we try out the app at shop.
I'm not sure. I think 30 is probably good enough. The flight times are probably all going to be over 1 second anyway, so that's like 3.3% margin of error at the worst. Also, the ThriftyCams at shop are 60, so if we can get those to work it'll probably be even better. |
…01/2026-Robot-Code into 80-shot-tuning-mode
| const dx = poseX - HUB_CENTER.x; | ||
| const dy = poseY - HUB_CENTER.y; | ||
| onTelemetry({ | ||
| distanceMeters: Math.sqrt(dx * dx + dy * dy), |
There was a problem hiding this comment.
@godmar The coordination layer logs a distance from the shooter to the hub whenever the robot is in test mode:
if (DriverStation.isTest()) {
// Log distance to hub for test modes
drive.ifPresent(
drive -> {
Logger.recordOutput(
"CoordinationLayer/distanceToHub",
AllianceBasedFieldConstants.hubInnerCenterPoint()
.toTranslation2d()
.getDistance(new Pose3d(drive.getPose())
.plus(JsonConstants.robotInfo.robotToShooter).getTranslation().toTranslation2d()));
});
}Could this just read that value from the network? that would save us from having to do the robot to shooter calculation in the app and also prevent the poses from getting out of sync with each other if the constants ever change.
There was a problem hiding this comment.
The settings_ui rn outputs both (they should be identical). It uses the CoordinationLayer/distanceToHub value.
- Shooter velocity: now reads setpoint RPM from TunableNumbers/CoordinationLayer/ShotTuning/shooterRPM - Hood angle: now reads setpoint degrees from TunableNumbers/CoordinationLayer/ShotTuning/hoodAngleDegrees - Distance: adds /AdvantageKit/RealOutputs/CoordinationLayer/distanceToHub as primary; pose-computed distance shown in parentheses for comparison - Export to shot map now uses NT distance (falls back to pose-computed), and passes RPM/degrees directly (no unit conversion needed) - Field renames: shooterRPMRadPerSec→shooterRPM, hoodAngleRadians→hoodAngleDegrees Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- RecordingControls: set selected camera ID on mount when restoring from localStorage (dropdown now reflects the remembered camera) - ShotMapsEditor: drain pending store BEFORE the robot API call so exported points are never lost when the robot is offline; handle null data in subscribe callback so live exports also appear without a robot connection - ShotMapsEditor: show exported points even when robot API fails (renders editor with error banner rather than showing only error+retry) - Added shotMapsStore singleton for cross-tab in-memory point sharing - VideoReplayPlayer: export uses store instead of direct file write; re-export button stays enabled (only disabled when flight time missing) - ShotMapTuning: snapshot telemetry at record-start, not store-time - TuningAttempt: rename fields to native units (RPM/degrees), add distanceToHubMeters and fps fields; update HUB_CENTER coordinates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Export from the tuning tab now loads ShotMaps.json fresh, appends the point, and saves back immediately — no caching, safe against concurrent edits. A dirty flag (shotMapsLocalSignal) is set after each save so that the Shot Maps tab automatically reloads from local the next time it mounts, showing the exported point without any user action. Removes the broken module-level subscriber approach (failed because React StrictMode double-fired effects and the component unmounts on tab switch). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…' into 80-shot-tuning-mode
Loads robotToShooter.translation (x, y) from RobotInfo.json at startup and passes it to createNT4Service. The distance to hub is now measured from the shooter position rather than the robot center by rotating the offset into field frame using the robot's heading (3rd float64 in the Pose2d struct). Also adds RobotInfo.json to the Vite local-file allowlist. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Saves vertical space by placing NTConnectionStatus in a flex row alongside the "Shot Map Tuning" h5 instead of a standalone Paper block. The panel already collapses to a compact chip on connect. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rame buttons Chrome: Add HTTP range-request (206 Partial Content) support to the clip-serving middleware. Chrome requires byte-range responses to seek in video files; the previous 200 full-file response made the slider and frame-step buttons silently do nothing. Keyboard: Move keydown handler from window to the container's onKeyDown so it fires via event bubbling regardless of which child has focus. Clicking the video refocuses the container so shortcuts work immediately. Container is also auto-focused on mount and attempt change. Slider and button focus edge cases are handled to avoid double-actions. UI: Add -10 Frames and +10 Frames buttons flanking the -1/+1 Frame buttons. Tooltips updated to show keyboard shortcut hints. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
An 8px tall bar appears below the slider once either timestamp mark is set. It shows a muted base (MUI divider color, theme-aware) with: - Amber highlight spanning the leaves-shooter → hits-target window - Green 2px tick at the leaves-shooter position - Red 2px tick at the hits-target position Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Camera and FPS controls now share a single flex row instead of stacking. FPS ToggleButtonGroup replaced with a compact Select dropdown (80px wide). Actual-fps indicator stays to the right of the dropdowns. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MUI Slider swallows all keydown events while it holds focus, even with onKeyDownCapture. The fix: use onChangeCommitted (fires on mouse-up / key-up) to return focus to the container div so h-j-k-l and arrow keys work again immediately after scrubbing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
s → Mark Leaves Shooter (start of flight) e → Mark Hit Target (end of flight) Moved markLeavesShooter/markHitTarget before handleKeyDown to fix initialization order, and wrapped them in useCallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@aidnem check out the latest improvements. Chrome should now work, and the hot key should work, too. They are
Remember that the "add" button will add to the saved .json file, which is not automatically loaded in the other tab (you have to "Load local" there). |
No description provided.