arctos6135 / frc-2024 Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
Rewrite FeedforwardCharacterization to ramp up from 0 to full voltage, and then set the voltage to fully negative. Additionally, make sure that the command monitors the result of position.getAsDouble()
and that the robot never goes further forward than the maximum distance, or further backward than the initial starting position.
The drivetrain is constantly moving slightly to the left (most likely due to our drivetrain correction). Figure out why it's happening and fix it.
Currently advantagescope is getting very polluted with calls to Logger.recordOutput, which makes it tricky to find the values we are looking for. Solve this problem by changing the field name of calls to recordOutput according to subsystem.
For example, in the Arm subsystem, we call Logger.recordOutput("Arm Mechanism", ) and Logger.recordOutput("Arm Voltage", ). These calls should be replaced with Logger.recordOutput("Arm/Mechanism", ) and Logger.recordOutput("Arm/Voltage", ).
In logging calls we have abbreviated the names of some subsystems, such as DT for drivetrain and Shoot for Shooter. It isn't necessary to keep these abbreviations when we switch to subfolder logging, because the longer names will be folder names and won't get in the way.
Similar to the amp scoring command, it should use ArmPID
to move the arm to the correct angle (which is just the default stow angle, hopefully it's already there), that is run alongside a call to the Launch
command to spin up the shooter wheels, then a Feed
command to pass the note from the intake into the shooter.
Should be similar to DrivetrainIOSparkMax, but implementing IntakeIOSparkMax instead. To get the current flowing through the motor, try using CANSparkMax.getOutputCurrent
.
change intake constants file to reflect the actually robot.
Under the util
folder, add a MathUtils
class to contain static methods to do common math tasks. Currently we only need two math util methods, but we'll probably need more later.
clamp
This clamps a number so that it is at most the provided max and at least the provided min. Use this method to replace the somewhat confusing clamping code in PIDSetAngle
's execute method.
closeEnough
This checks if two doubles are "close enough" that they are practically equal. A good threshold would be if they are within 0.01 of each other.
Go through and find import fields that frequently change, and important method calls (like DrivetrainIO.setVoltage), and use Logger.recordOutput()
to log them.
A lot of this is similar (but not copy-pastable) from last year
Add the Intake
subsystem to RobotContainer
. Add a field for the subsystem, and call the constructor just like how we construct Drivetrain
(we don't have an IntakeIOSim
yet, so just use IntakeIO
in simulation mode).
Bind the IntakePiece
command to a reasonable button of the operator controller.
Add a setSpeeds
method that uses a combination of a V = kS + kv v + ka a
feedforward controller and a PID controller for each side of the drivetrain to set the left and right speeds.
WPILib has classes for doing PID and simple feedforward.
We need soft stops on the arm so that we don't accidentally command it to try and push past the hard stop in the stowed position, or flip the robot over by going in the other direction. Since ArmIOSim
has built-in soft stops, it makes sense to add the soft stops to ArmIOSparkMax
. Luckily, SparkMax
s have a built in tool to do this with the SparkMax
onboard processor. Check out this method.
The PIDSetAngle
command requires the following drivetrain methods:
public double getYaw()
method that provides information about the current yaw of the current drivetrain. Could use gyros or encoders?
We should have a rotation PIDController in the Drivetrain that every command uses when it is needed to calculate a specific angle the drivetrain should face. This should be accessible through the public PIDController getRotationController()
method (or something similar)
Add a Shooter.characterize
method similar to Drivetrain.characterize
that calculates the feedforward coefficients for the Shooter.
I've noticed that it is sometimes difficult to determine the use case of a command just by looking at the name of the file/class. As a result, I encourage everyone to write a comment detailing the purpose of the command they're working on as well as any ambiguous constructor arguments. This command should be placed above the constructor.
Also, I encourage everyone to provide information about the unit of measurement and the upper+lower bounds when declaring method parameters so everyone understands the valid values.
For each subsystem, add a current
, temperature
, and voltage
field to the Inputs
class for each motor. For example, when we have a left and right motor, there should be six new fields: leftCurrent
, rightCurrent
, etc.
The current readings should be measured in Amps, and can be gotten with the motor.getOutputCurrent
method. The current readings should be measured in Celsius and can be gotten with the motor.getMotorTemperature
method.
The voltage readings should represent the voltage the motor is running at rather than the voltage we command it to. To get that value, use the motor.getBusVoltage
to measure the max voltage the motor could be running at, and multiply it by motor.get
to get the percent of max power the motor is running at.
Write some code to stop the robot from climbing before the last 20 seconds of the match.
Change the shouldFlipPath lambda being passed to AutoBuilder in drivetrain to flip paths when appropriate. Relevant code can be taken from MechanicalAdvantage's differential drivetrain example code.
Add an Arm.characterize
method similar to Drivetrain.characterize
that calculates the feedforward coefficient for the arm.
Get LTV controller working :)
Check for consistent units. Everything should be measured in:
Add an IntakeIO class similar to DrivetrainIO. It should have a method to set the voltage, and its Inputs inner class should have fields for the encoder position and the current flowing through the motor.
Later on we'll use the motor current to detect a gamepiece has entered the intake.
This year we want to focus on using SmartDashboard as a tool for the drivers. Logging anything that they don't actively need to drive the robot isn't useful, because we can view the data in AdvantageScope. There are only a couple things that the drivers need:
LoggedDashboardChooser
to select the starting position of the robotLoggedDashboardChooser
to select the auto we are runningLoggedDashboardBoolean
to stop ArmPID
from moving the arm in case the arm encoder is brokenLoggedDashboardBoolean
to reset the arm encoder to the starting positionLoggedDashboardBoolean
to stop the IntakePiece
command from turning off when it detects a current spike (the operator instead would have to stop holding down the intake button)AdvantageKit docs appear to be harder to find than birds for #17 but all the relevant code is here
Use the algorithm described in the Network Working Group RFC 2549 IP over Avian Carriers with Quality of Service to make log packet transfer more efficient.
It would be nice if the battery could output 14 volts. Increased control authority and a larger current budget would be amazing for our robot's versitility.
Make a Vision subsystem that uses Photonvision to detect a note on the ground in front of the robot. There should be a hasTarget
method to check if a note is detected, a getNoteDistance
method to return the approximate distance in m to the note, and a getNoteAngle
method to return the yaw of the note in radians.
Should use ArmPID, Launch, and deadlines + sequences to score in the amp.
This will require a lot of reading rather poorly written documentation, so good luck.
Use wpilib's Single Jointed Arm Sim to create a simulation implementation of ArmIO. You should only need to set up the simulation using the constructor, call the setInputVoltage
method when the voltage is set, and call the update
method during the updateInputs
call of ArmIOSim
, similar to in DrivetrainIOSim
.
The center of mass of the Arm is 0.35 m away from the pivot point, and the mass is [waiting on design].
Create a Shooter subsystem for our robot's shooter (the wheels on the arm). Just like the Intake subsystem, most of the low level logic should be handled by ShooterIO: currently the only necessary fields should be an ShooterIO and the ShooterInputs. The subsystem should have a method to get the velocity of the left and right sides and a method to set the voltages of the left and right sides.
Set up PathPlanner
for this project, and add a basic PathPlanner
auto. The docs might prove helpful.
In all of our *IOSparkMax setVoltage methods, we call motor.set(targetVoltage) instead of motor.setVoltage(targetVoltage). .set is supposed to take a parameter in the range -1 to 1, not -12 to 12, so we need to switch to .setVoltage.
Add a AutoIntake
command that uses vision and a PID controller to drive the robot toward a detected note while spinning the intake.
We should be able to run this command to get a big CSV file of voltage + velocity + acceleration data that we can fit a curve to. A good scheme would be to ramp the voltage up, then ramp it down, then set it high, then set it low.
Make a command called ArmPID
that controls the angle of the arm. It should use a combination of motion profiles, feedforward, and pid to move the arm to a goal angle. The command should keep running even after the arm has reached its target to hold the arm in place.
Should be similar to IntakeIOSparkMax
, but implementing ShooterIO
instead.
Should run the Shooter
flywheels at a given speed
. This command should have no end condition: we'll either stop it with a timeout or by canceling with a button press.
Create a new Member object in the the Dashboard Class, and initialize the name field to Allan, the role field to Mentor, and the age field to 100.
We want to detect current spikes in the Intake
, as the current of the motor will jump whenever we intake a game piece. To filter out noise, we want to use a Median Filter. You'll need to add 2 fields to Intake
, one to store the filter (maybe put the size of the filter in a constant!), and one to store the current median, which should get overwritten with each call to periodic.
Also add a method to Intake
that returns the current filtered current.
Add a command that advances the shooter wheel by a certain number of radians. Rather than using PID or feedforward, it should be enough to run it at a low voltage (like 2 ish) until it has passed the target number of radians.
Add all the possible starting poses to the auto chooser for starting positions (each side of the subwoofer should be fine).
Add an Arm
subsystem. It should use ArmInputsAutoLogged
and ArmIO
to control the robot's arm. Similar to Intake
, it should have a method to set the voltage of the motors. Unlike Intake
, it doesn't need to do current filtering.
This will require a lot of reading rather poorly written documentation, so good luck.
Use wpilib's FlywheelSim to create a simulation implementation of ShooterIO
. You should only need to set up the simulation using the constructor, call the setInputVoltage
method when the voltage is set, and call the update
method during the updateInputs
call of ShooterIOSim
, similar to in DrivetrainIOSim
.
Add a command called Feed
that uses a clamped PIDController
to move the belts on the intake a certain distance.
Use feedforward to control the speed of the shooter wheels instead of just setting the voltage.
Add two SimpleMotorFeedforward
s to the Shooter
subsystem, one for the left side and one for the right.
Add a setSpeeds
method to set the speeds of the left and right shooter wheels by calculating the appropriate voltage using feedforward.
Create an Intake subsystem for our robot's intake! Just like the Drivetrain
subsystem, most of the low level logic should be handled by IntakeIO
: currently the only necessary fields should be an IntakeIO
and the IntakeIO
Inputs. The subsystem should have methods to get the position (which is stored in the Inputs
field), and set the voltage (through the IntakeIO
field).
Make sure you override periodic similarly to the way its done in Drivetrain
to properly log appropriate data!
Make a command that runs the intake backward. Bind it to an out-of-the-way button on the Xbox controller.
Add a command that moves the note from the intake into the shooter so that we can then score in the amp. It should use a parallel race group between one of the Feed
commands and AdvanceShooter
.
Running armPID in simulation, the setpoint for armPID is behaving weirdly: probably using the TrapezoidalProfile API incorrectly.
Add an ShooterIO class similar to IntakeIO. It should have a method to set the voltages of the two motors (1 left, 1 right), and its Inputs inner class should have a field for the left velocity and the right velocity.
Use WPILib's odometry class to maintain an estimate of the robot's pose on the field.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.