Skip to content

Lobbin loco - #39

Open
pkatzfey wants to merge 126 commits into
mainfrom
LobbinLoco
Open

Lobbin loco#39
pkatzfey wants to merge 126 commits into
mainfrom
LobbinLoco

Conversation

@pkatzfey

@pkatzfey pkatzfey commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

New Computer setup for Team Black

5010TigerDynasty and others added 30 commits October 1, 2025 17:06
Update from FRC5010Example
commit b7f64a1
Author: Curt <clrozeboom@gmail.com>
Date:   Sun Oct 5 15:10:09 2025 -0400

    Remove butterbup

commit 98e3a69
Merge: 80b8424 89a320a
Author: Curt <clrozeboom@gmail.com>
Date:   Sun Oct 5 14:50:00 2025 -0400

    Merge branch 'main' into 7-swerve-updates

commit 80b8424
Author: CameronSkea <cameronskea@icloud.com>
Date:   Wed Oct 1 17:34:36 2025 -0400

    updates

commit 34af230
Merge: 32ac53c 9c5d9d2
Author: 5010 Tiger Dynasty <roboticsteam.fhs@gmail.com>
Date:   Wed Oct 1 17:06:27 2025 -0400

    Merge pull request #10 from FRC5010/main

    Merge fixes from main
for robert
Reorganized import statements in ExampleRobot.java and ExampleSubsystem.java for improved readability and consistency. No functional changes were made.
jasdf;l;lkfh'
claude and others added 30 commits June 22, 2026 23:00
ModuleIOSpark only set inputs.turnAbsolutePosition and never set
inputs.turnPosition, which defaults to zero. On the real robot
Module.getAngle() and Module.runSetpoint's cosineScale() use turnPosition, so
the module looked like it was always at 0 degrees. The drive speed was then
scaled by cos(targetAngle - 0):

  - forward  (0 deg):  cos 0   = 1.0  -> full drive
  - rotate   (~45 deg): cos 45 ~= 0.7 -> drives
  - strafe   (90 deg): cos 90  = 0.0  -> no drive

so the wheels rotated sideways but never spun, and reported module angles
(odometry) were stuck at 0.

These modules steer on the absolute encoder with no separate relative turn
encoder, so mirror turnPosition from turnAbsolutePosition.

Simulation was unaffected because getAngle()/cosineScale use
turnAbsolutePosition in sim.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Documents the Spotless/JDK build workaround, the JSON-config-driven
multi-robot selection flow, and the swerve drivetrain architecture
(YAGSL vs AKit, the Spark IO reading DriveConstants instead of JSON, the
dual odometry threads, and absolute-encoder steering pitfalls).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
…agnostics

ModuleIOSpark now reads its hardware identity from the deploy JSON
(AkitSwerveConfig / SwerveModuleConstants) instead of DriveConstants:
- drive/steer CAN IDs, drive gear ratio, drive current limit
- drive/steer motor inversion and absolute-encoder inversion
- absolute encoder zero offset (JSON absoluteOffset -> EncoderOffset ->
  zeroRotation), so per-module offsets can finally be set from config to move
  modules off the +/-180 wrap seam.
Closed-loop gains and the steer wrapping stay in DriveConstants because they
are in AdvantageKit units (wheel rad/s, module radians), not the YAGSL-native
gains stored elsewhere in the JSON.

Diagnostics for swerve commissioning:
- ModuleIO gains turnRawAbsolutePosition (pre-offset encoder reading). Point a
  wheel forward and copy its logged degrees into the module's absoluteOffset.
- AkitSwerveDrive logs Drive/Diag/Module*/{Setpoint,Measured,AngleError}* and
  chassis speeds setpoint/measured every loop, independent of enable state, so
  wrong-direction and tracking issues are visible even in disabled logs (where
  SwerveStates/Setpoints is blanked).

Spark branch now constructs ModuleIOSpark(config, moduleConstants).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
ModuleIOSpark now reads the drive and steer closed-loop gains from the deploy
JSON (constants.DriveMotorGains / SteerMotorGains, which AkitSwerveConfig builds
from driveMotorControl / steerMotorControl) instead of DriveConstants. The akit
drivetrain owns its own akit-unit PID; it is not the YAGSL pidfproperties gain.
Only universal akit constants (encoder factors, steer wrap range, steer current,
odometry frequency) remain in DriveConstants.

Buttercup JSON now holds proper akit-unit gains (steer kP 2.0, drive kV 0.1)
rather than the YAGSL copies (steer p 0.02).

Black akit config was {"type":"SparkTalon"}, which instantiates a TalonFX drive
motor - wrong for black's NEO-on-SparkMax hardware. Set type "Spark" with a full
constants block from black's YAGSL config (CAN IDs FL 1/2, FR 7/8, BL 3/4,
BR 5/6; drive inverted -> invertLeftSide/invertRightSide true; encoderInverted
true). Switch black_robot/robot.json driveType to AKIT_SWERVE_DRIVE.

Black's absoluteOffsets are still 0 and will need azimuth-offset calibration
(point wheels forward, read Drive/Module*/TurnRawAbsolutePosition) before it
drives cleanly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Mirror the ModuleIOSpark fixes onto the SparkTalon steer side:
- Populate inputs.turnPosition (= turnAbsolutePosition) and the
  turnRawAbsolutePosition diagnostic. Without turnPosition,
  Module.getAngle()/cosineScale saw the wheel as always at 0 deg, so drive was
  scaled by cos(targetAngle) (no strafe) and odometry module angles were stuck.
- Read steer motor inversion, encoder inversion, steer PID, and the absolute
  encoder offset from the deploy JSON (constants.SteerMotorInverted /
  EncoderInverted / SteerMotorGains / EncoderOffset) instead of DriveConstants,
  matching the now config-driven drive side and ModuleIOSpark.
- Keep universal akit constants (encoder factors, wrap range, steer current,
  odometry frequency) in DriveConstants.

No deploy config currently selects "SparkTalon", so this is a correctness fix
so the type works if selected later.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
The flywheel stop logic called lowerFlyWheel.set(0)/upperFlyWheel.set(0)
inside Runnable lambdas (finallyDo and Commands.runOnce). FlyWheel.set()
returns a RunCommand that must be scheduled to take effect, so those
returned commands were silently discarded and the motors were never
commanded to zero. On button release the held set(SPEED) RunCommand is
interrupted but does not zero its output, leaving the flywheels spinning.

Bind the stop command to onFalse directly (matching the working feeder
pattern), so the set(0) command is actually scheduled. Drop the dead
set(0) calls from the whileTrue finallyDo blocks, leaving only the LED
reset there.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Replace direct button constants with createXButton/createLeftBumper/createRightBumper/createStartButton bindings, consolidate multiple shooter stop onFalse handlers into a single binding, and invert feeder motor speeds for the corresponding button actions. These updates clarify controller mappings and ensure feeder/shooter commands and LED updates trigger and stop correctly.
Replace the hard-coded SmartMotorController/FlyWheel construction in
FeederSubsystem with the config-driven GenericSubsystem pattern used by
UpperFlyWheel: the constructor now calls super("feeder.json") and pulls
the FlyWheel out of the devices map by name.

Add the matching deploy configs (yams_shooter device) for both the
black_robot and buttercup_swerve robot directories, reproducing the
previous feeder tuning: Spark/Neo on CAN 12, 3x4 reduction, 40A stator
limit, brake mode, 0.25s closed-loop ramp, profiled closed loop
(p=0.00016541, 5000 rpm / 2500 rps^2), 3in diameter, 1 lb, +/-500 rpm
soft limits.

Verified in simulation: the feeder mechanism loads and telemeters under
/Mechanisms/feeder alongside the flywheels, and robot startup completes
with no parse errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Replace the feeder LED behavior so it shows a sweeping green "laser"
while feeding and returns to the alliance-color background when done.

- Add LEDStrip.getLaserPattern(color, width, speed): a narrow colored
  band that scrolls along the segment over an unlit background.
- Feeder A/Start buttons now light FEEDER_LED with the green laser on
  press and deactivate the segment on release (instead of leaving it
  solid red and active), so the left half reverts to alliance color.
- Remove the teleop-enabled trigger that force-activated FEEDER_LED with
  its default unlit pattern, which blanked the left half of the strip
  during teleop (and leaked a perpetual command each enable). Drop the
  now-unused DriverStation, Trigger, and Seconds imports.

Verified: compiles and the robot starts cleanly in simulation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
- getBand: the third mask step used bandCenter - percentWidth/2, which
  duplicated the second step's key (Map.of throws on duplicate keys) and
  was geometrically wrong. Use bandCenter + percentWidth/2 so the band's
  right edge is correct and the keys are distinct.
- addSegment overloads: the range parameter was named "length" and
  documented as a length, but it is passed straight to
  AddressableLEDBuffer.createView(start, endIndex), whose second argument
  is an inclusive end index. Rename the parameter to endIndex and fix the
  Javadoc so the contract matches the (correct) behavior the config path
  already relies on. No behavior change to existing callers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Instrument per-module steering so a wheel that fails to reach its
commanded rotation can be diagnosed.

- YAGSLSwerveDrivetrain.periodic() now logs Swerve/Diag/* every loop when
  the YAGSL telemetry verbosity is HIGH or above (same flag the rest of
  the swerve high-verbosity logging uses): desired vs measured azimuth and
  error, absolute-minus-relative encoder divergence, steer applied output,
  voltage and velocity, the absolute-encoder read-issue flag, a derived
  per-module "misaligned" flag, and the max absolute error. Desired angle
  comes from YAGSL's post-optimization commanded state. Logged through
  AdvantageKit so it lands in the .wpilog for replay, not just live NT.
- Add SwerveDriveFunctions.pointModulesAt(degrees) (YAGSL override points
  every module's azimuth, drive motors untouched).
- Add GenericSwerveDrivetrain.azimuthStepTestCommand(): a deterministic
  routine that steps all modules through a fixed angle sequence with a
  fixed dwell, logging Swerve/Diag/StepTest/targetDeg, for on-blocks
  diagnosis.

Verified in simulation: all Swerve/Diag/* outputs are recorded with no
periodic exceptions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
- Expose azimuthStepTestCommand() on GenericDrivetrain (default no-op,
  overridden by GenericSwerveDrivetrain) and bind it to the driver A
  button in BlackRobot's test-mode bindings (configureAltButtonBindings),
  so the deterministic azimuth diagnostic can be run on blocks in Test.
- Fix GenericSwerveModuleInfo.expectedSteerDegrees so the Glass "expected"
  dial shows the actual commanded (post-optimization) steer angle from
  YAGSL telemetry instead of the measured state angle. Falls back to the
  measured angle before any command has been issued.

Verified: compiles and the robot starts and loops cleanly in simulation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Register the deterministic azimuth diagnostic on SmartDashboard from the
GenericSwerveDrivetrain constructor so it can be triggered from the
dashboard (while enabled, robot on blocks) without entering Test mode, in
addition to the Test-mode A-button binding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Brings in the SparkFishers work (feeder/flywheel JSON-driven subsystems, driver
button binding refactor, LED green-laser sweep, swerve azimuth diagnostics +
step-test command and dashboard button, controller axis 2<->4 remap).

This branch stays on AdvantageKit swerve: SparkFishers touches no robot.json or
akit config, so both robots keep driveType AKIT_SWERVE_DRIVE with the "Spark"
module IO. The only content overlap, buttercup driver_right_x.json, auto-resolved
to SparkFishers's channel 2 with invert false (both branches set invert false).

Note: the merged Azimuth Step Test drives modules via
SwerveDriveFunctions.pointModulesAt, which only YAGSLSwerveDrivetrain overrides,
so the step test is currently a no-op on the akit drivetrains.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
SparkFishers' azimuth step test drives modules via
SwerveDriveFunctions.pointModulesAt, which only YAGSL overrode, so it was a
no-op on the akit drivetrains. Override it in AkitSwerveDrive:
- Add Module.pointAt(Rotation2d): commands the steer position directly with the
  drive stopped, bypassing runSetpoint's nearest-equivalent optimize so the
  module physically rotates to the commanded angle (not a 180 deg flip) - which
  is what the diagnostic needs to measure.
- AkitSwerveDrive.pointModulesAt points all modules and records the commanded
  angle in lastSetpointStates, so the always-on Drive/Diag/Module*/AngleErrorDeg
  reports target-vs-measured during the test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Second merge of SparkFishers, which adds "Updates to Elphaba CAN" (34ce7ba):
new black_robot YAGSL module CAN IDs plus BlackRobot/GenericDrivetrain/
GenericSwerveDrivetrain/LEDStrip tweaks. Black runs on AdvantageKit, which reads
akit_swerve_drivetrain.json (not the YAGSL modules), so propagate the updated CAN
IDs into black's akit config:
  frontLeft drive 18/steer 2, frontRight drive 17/steer 6,
  backLeft drive 16/steer 3, backRight drive 4/steer 15.
black_robot/robot.json stays driveType AKIT_SWERVE_DRIVE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Third merge of SparkFishers ("Other updates", 62f55df): swaps black backRight
YAGSL ids (drive 15 / angle 4), bumps the YAGSL angle PID, and adjusts
BlackRobot. Black runs on AdvantageKit (reads akit_swerve_drivetrain.json), so
sync black's akit backRight to drive 15 / steer 4. The YAGSL angle-PID bump is
not propagated: the akit steer loop uses a different unit basis (akit steer kP
stays 2.0). black_robot/robot.json stays driveType AKIT_SWERVE_DRIVE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
tools/swerve_log_analysis.py reads an AdvantageKit .wpilog (stdlib only)
and summarizes the Swerve/Diag/* signals: per-module desired/measured
angle and error, absolute-vs-relative encoder gap, absolute-encoder read
issues, and steer effort. It lists the timestamps where a module is
flagged misaligned (settled but off target) with the concurrent signals
so a miss can be mapped to encoder desync, a read failure, output
saturation, or weak PID. Warns when a log was never enabled.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HmeQnHETe7J9KFoKXG56PM
Brings in 8516b88 (tools/swerve_log_analysis.py), a stdlib-only AdvantageKit
.wpilog analyzer for the Swerve/Diag/* azimuth signals. Adds only the tool; no
code or config changes. This branch stays on AKIT_SWERVE_DRIVE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NuiJsExocjmTcG2zKNJNYx
Switch the robot deploy config to the YAGSL swerve drive. Implement deterministic per-move steering in YAGSLSwerveDrivetrain.pointModulesAt by tracking the last target, synchronizing module encoders on a new target, and issuing a zero-drive setDesiredState for a fresh, re-seeded command; repeated calls hold angle via setAngle. Bump BuildConstants (git revision/sha/branch/dates/build time). Include minor whitespace/javadoc formatting tweaks in ModuleIO/ModuleIOSpark.
Setup for Logitech JS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants