-
Notifications
You must be signed in to change notification settings - Fork 0
First draft outreach bot 16.0, drive only #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
build.gradle
Outdated
| // AdvantageKit log replay from the command line. Set the | ||
| // value to "true" to enable the sim GUI by default (this | ||
| // is the standard WPILib behavior). | ||
| wpi.sim.addGui().defaultEnabled = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be true
| // or from command line. If not found an exception will be thrown. | ||
| // You can use getTeamOrDefault(team) instead of getTeamNumber if you | ||
| // want to store a team number in this file. | ||
| team = project.frc.getTeamOrDefault(540) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave this as it was, not technically necessary but can help in a pinch during comp if you need to swap to a new computer without being able to transfer everything.
| // Disable LEDs, will reduce software and electrical overhead but disable hardware alerts | ||
| public static final boolean ENABLE_LEDs = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove
| // Disable the AdvantageKit logger from running | ||
| public static final boolean ENABLE_LOGGING = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feature not implemented, either implement or remove
| static final double mk4iDriveGearing = (50.0 / 14.0) * (19.0 / 25.0) * (45.0 / 15.0); | ||
| static final double mk4iTurnGearing = 12.8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be renamed to MK4, im assuming you have confirmed we are using L1 ratio
| .turnMotorId(2) | ||
| .driveMotorId(3) | ||
| .encoderChannel(0) | ||
| .encoderOffset( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Encoder offset should be done on module for CTRE CANCoders.
https://v6.docs.ctr-electronics.com/en/stable/docs/hardware-reference/cancoder/index.html#zeroing-the-cancoder
| .encoderOffset(Rotation2d.fromRadians(-1.7285578862473199)) // .rotateBy(Rotation2d.kPi)) | ||
| .driveGearing(mk4iDriveGearing) | ||
| .turnGearing(mk4iTurnGearing) | ||
| .turnInverted(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if turn should be inverted on MK4, look into that in previous code.
| turnKd.initDefault(0.0); | ||
| switch (Constants.getRobot()) { | ||
| case OUTREACHBOT -> { | ||
| drivekP.initDefault(0.1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ALWAYS ALWAYS reset to zero before you have tuned the values for safety purposes. If you arent sure the code works, these values could casue the robot to hurt others, or more importantly, itself.
| private final SparkMax turnSpark; | ||
| private final RelativeEncoder driveEncoder; | ||
| private final RelativeEncoder turnRelativeEncoder; | ||
| private final AnalogEncoder turnAbsoluteEncoder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
16.0 uses a CTRE CANCoder, not an analog enocder. This code needs to be updated and rewritten to support the CANCoder per the current CTRE docs. It may be beneficial to reference the AdvantageKit TalonFX Swerve Template which uses CANCoders
srimanachanta
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work on making the changes you made, you addressed most of the issues that were present. The main issue here is understanding working with the CANcoder and the Phoenix 6 API.
Some additional recommendations:
- Get in the habit of making multiple smaller commits instead of one big commit, this allows you to split up changes and your work into more digestible segments. It also allows others to understand your process of working through stuff.
- Git already allows you to go back and get older versions of your code. Get in the habit of deleting unneeded code instead of just commenting it out. Commenting out a lot of code like how you have done here leads to the code base just being unreadable overall. As a general rule of thumb, if you're commenting out more than a block of code, you probably should be making a commit instead.
- You have a lot of really good questions throughout this code and I can somewhat see your thought process based on the decision you made in designing your code. I suggest you sit with Aayan and see if you can research the answers to some of these questions if he doesn't already know the answer.
| } | ||
|
|
||
| @Builder | ||
| record ModuleConfig( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seems to be some confusion about the actual module configuration based on what I've seen in your code so far. There are two NEOs used for turn and steer and a single CANCoder used as the absolute encoder for the module. Based on this, you should refactor this record to reflect the following:
@Builder
record ModuleConfig(
int turnMotorId,
int driveMotorId,
int absoluteEncoderId,
double driveGearing,
double turnGearing,
) {}
| private final SparkMax turnSpark; | ||
| private final RelativeEncoder driveEncoder; | ||
| private final RelativeEncoder turnRelativeEncoder; | ||
| private final AbsoluteEncoder turnAbsoluteEncoder; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto on my previous comment on the module configuration. I'm going to assume you got this idea from a REV-only template/example code. Remember that the module you are defining uses REV's APIs for the SparkMax and CTRE's API for the CANCoder. Because the hardware belongs to both vendors, there is no natural/built in way to integrate the two like how you have done here. Instead, you need to define an instance of CANCoder and manually call the refresh and update methods to update a StatusSignal<Double> which you then use to seed the PID algorithm on the SparkMax by setting the initial position of the RelativeEncoder as you previously had.
Here is the rough idea:
With your hardware objects:
https://v6.docs.ctr-electronics.com/en/stable/docs/api-reference/api-usage/status-signals.html
https://v6.docs.ctr-electronics.com/en/stable/docs/api-reference/api-usage/configuration.html
private final CANcoder turnAbsoluteEncoder;
// Define needed StatusSignals
// Later down in the constructor
turnAbsoluteEncoder = new CANcoder(config.encoderId());
// Configure other non-persistant settings on the CANcoder like unit conversion and polling rates. You can find this is the AdvantageKit templates for some sensible values.In the IO Update Call:
https://v6.docs.ctr-electronics.com/en/stable/docs/api-reference/api-usage/status-signals.html#refreshing-the-signal-value
// Refresh the status signal for needed signalsFinally, the helper method to get the absolute encoder position
// Update to get value from the CANcoder instead of from a REV API Encoder.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand how the StatusSignal object fits into this structure. I tried adding a StatusSignal object, but I'm not sure how it gets used later in the code or how to reconcile the fact that getAbsolutePosition returns a StatusSignal < Angle > object, but we initialize a StatusSignal < Double > object.
Everything else makes sense and is complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I googled and AI searched for solutions, but didn't find anything that worked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry StatusSignal<Double> was me speculating. The correct initialization is to use StatusSignal<Angle>. See here for example.
As for why we need the status signal:
Unlike the REV API which uses getters to get the last value updated by the encoder, Phoenix uses an object to represent the specific signal/sensor value you want to poll and basically "caches" this value in the form of a status signal. Basically, just a wrapper around the signal you want to use. The thing that makes this tricky is that this status signals always points towards the signal value at the time it was created. In order to update it to the last available sensor value, and update or "refresh" method must be called.
If you're curious why have this system as apposed to REV's getter setter system, by using a status signal, you can associate the sensor value with a bunch of other important metadata markers like timestamp, latency, units, or error condition of the data. Unlike Phoenix, REV's API doesn't guarantee that these values would be synchronized with the sensor value reported by the getter, making the metadata markers pretty useless.
…onfigure other non-persistant settings on the CANcoder like unit conversion and polling rates. You can find this is the AdvantageKit templates for some sensible values.
It built successfully on my machine.
It did not build successfully when I pushed to GitHub.