-
Notifications
You must be signed in to change notification settings - Fork 18
Add non-PWM examples #22
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
Merged
Merged
Changes from 2 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
cc34b45
init
e0a8806
added black formatting
eeb8855
fixed errors
809d2ac
Fixed errors and added black formatting
2bf945d
Uncommented lines that led to erroneous testing
70ef3d8
Tweaked velocity-pid example
eeb8690
Added can-tank-drive example
50bc75b
Fixed SmartDashboard configuration
346064a
Fixed testing environment configuration.
ddb80c6
Removed unnecessary imports
Tyler-Duckworth 26e93ee
Removed unnecessary imports
Tyler-Duckworth 78ef1de
Merge branch 'master' into master
Tyler-Duckworth 7451939
Merge branch 'master' into master
Tyler-Duckworth c9d61ff
Fixed enum changes in get-set-params
Tyler-Duckworth d03829a
Reformatted get-set-params to pass black CI check
Tyler-Duckworth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#!/usr/bin/env python3 | ||
# ---------------------------------------------------------------------------- | ||
# Copyright (c) 2017-2018 FIRST. All Rights Reserved. | ||
# Open Source Software - may be modified and shared by FRC teams. The code | ||
# must be accompanied by the FIRST BSD license file in the root directory of | ||
# the project. | ||
# ---------------------------------------------------------------------------- | ||
|
||
import rev | ||
import wpilib | ||
from wpilib.drive import DifferentialDrive | ||
|
||
|
||
class Robot(wpilib.TimedRobot): | ||
# SPARK MAX controllers are intialized over CAN by constructing a | ||
# CANSparkMax object | ||
# | ||
# The CAN ID, which can be configured using the SPARK MAX Client, is passed | ||
# as the first parameter | ||
# | ||
# The motor type is passed as the second parameter. | ||
# Motor type can either be: | ||
# rev.MotorType.kBrushless | ||
# rev.MotorType.kBrushed | ||
# | ||
# The example below initializes four brushless motors with CAN IDs | ||
# 1, 2, 3 and 4. Change these parameters to match your setup | ||
|
||
def robotInit(self): | ||
# Create motors | ||
self.leftLeadMotor = rev.CANSparkMax(1, rev.MotorType.kBrushless) | ||
self.rightLeadMotor = rev.CANSparkMax(0, rev.MotorType.kBrushless) | ||
self.leftFollowMotor = rev.CANSparkMax(2, rev.MotorType.kBrushless) | ||
self.rightFollowMotor = rev.CANSparkMax(3, rev.MotorType.kBrushless) | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Passing in the lead motors into DifferentialDrive allows any | ||
# commmands sent to the lead motors to be sent to the follower motors. | ||
self.driveTrain = DifferentialDrive(self.leftLeadMotor, self.rightLeadMotor) | ||
self.joystick = wpilib.Joystick(0) | ||
|
||
# The RestoreFactoryDefaults method can be used to reset the | ||
# configuration parameters in the SPARK MAX to their factory default | ||
# state. If no argument is passed, these parameters will not persist | ||
# between power cycles | ||
self.leftLeadMotor.restoreFactoryDefaults() | ||
self.rightLeadMotor.restoreFactoryDefaults() | ||
self.leftFollowMotor.restoreFactoryDefaults() | ||
self.rightFollowMotor.restoreFactoryDefaults() | ||
|
||
# In CAN mode, one SPARK MAX can be configured to follow another. This | ||
# is done by calling the follow() method on the SPARK MAX you want to | ||
# configure as a follower, and by passing as a parameter the SPARK MAX | ||
# you want to configure as a leader. | ||
# | ||
# This is shown in the example below, where one motor on each side of | ||
# our drive train is configured to follow a lead motor. | ||
self.leftFollowMotor.follow(self.leftLeadMotor) | ||
self.rightFollowMotor.follow(self.rightLeadMotor) | ||
|
||
def teleopPeriodic(self): | ||
# Drive with arcade style | ||
self.driveTrain.arcadeDrive(-self.joystick.getY(), self.joystick.getX()) | ||
|
||
|
||
if __name__ == "__main__": | ||
wpilib.run(Robot) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#!/usr/bin/env python3 | ||
# ---------------------------------------------------------------------------- | ||
# Copyright (c) 2017-2018 FIRST. All Rights Reserved. | ||
# Open Source Software - may be modified and shared by FRC teams. The code | ||
# must be accompanied by the FIRST BSD license file in the root directory of | ||
# the project. | ||
# ---------------------------------------------------------------------------- | ||
|
||
import rev | ||
import wpilib | ||
|
||
|
||
class Robot(wpilib.TimedRobot): | ||
def robotInit(self): | ||
# Create motor | ||
self.motor = rev.CANSparkMax(1, rev.MotorType.kBrushless) | ||
|
||
self.joystick = wpilib.Joystick(0) | ||
|
||
# The restoreFactoryDefaults method can be used to reset the | ||
# configuration parameters in the SPARK MAX to their factory default | ||
# state. If no argument is passed, these parameters will not persist | ||
# between power cycles | ||
self.motor.restoreFactoryDefaults() | ||
|
||
# Parameters can be set by calling the appropriate set() method on the | ||
# CANSparkMax object whose properties you want to change | ||
# | ||
# Set methods will return one of three CANError values which will let | ||
# you know if the parameter was successfully set: | ||
# CANError.kOk | ||
# CANError.kError | ||
# CANError.kTimeout | ||
if self.motor.setIdleMode(rev.IdleMode.kCoast) != rev.CANError.kOK: | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
wpilib.SmartDashboard.putString("Idle Mode", "Error") | ||
|
||
# Similarly, parameters will have a get() method which allows you to | ||
# retrieve their values from the controller | ||
if self.motor.getIdleMode() == rev.IdleMode.kCoast: | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
wpilib.SmartDashboard.putString("Idle Mode", "Coast") | ||
else: | ||
wpilib.SmartDashboard.putString("Idle Mode", "Brake") | ||
|
||
# Set ramp rate to 0 | ||
if self.motor.setOpenLoopRampRate(0) != rev.CANError.kOK: | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
wpilib.SmartDashboard.putString("Ramp Rate", "Error") | ||
|
||
# Read back ramp value | ||
wpilib.SmartDashboard.putString("Ramp Rate", self.motor.getOpenLoopRampRate()) | ||
|
||
def teleopPeriodic(self): | ||
# Pair motor and the joystick's Y Axis | ||
self.motor.set(self.joystick.getY()) | ||
|
||
# Put Voltage, Temperature, and Motor Output onto SmartDashboard | ||
wpilib.SmartDashboard.putNumber("Voltage", self.motor.getBusVoltage()) | ||
wpilib.SmartDashboard.putNumber("Temperature", self.motor.getMotorTemperature()) | ||
wpilib.SmartDashboard.putNumber("Output", self.motor.getAppliedOutput()) | ||
|
||
|
||
if __name__ == "__main__": | ||
wpilib.run(Robot) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#!/usr/bin/env python3 | ||
# ---------------------------------------------------------------------------- | ||
# Copyright (c) 2017-2018 FIRST. All Rights Reserved. | ||
# Open Source Software - may be modified and shared by FRC teams. The code | ||
# must be accompanied by the FIRST BSD license file in the root directory of | ||
# the project. | ||
# ---------------------------------------------------------------------------- | ||
|
||
import rev | ||
import wpilib | ||
|
||
|
||
class Robot(wpilib.TimedRobot): | ||
def robotInit(self): | ||
# Create motor | ||
self.motor = rev.CANSparkMax(1, rev.MotorType.kBrushless) | ||
|
||
self.joystick = wpilib.Joystick(0) | ||
|
||
# A CANDigitalInput object is constructed using the | ||
# GetForwardLimitSwitch() or | ||
# GetReverseLimitSwitch() method on an existing CANSparkMax object, | ||
# depending on which direction you would like to limit | ||
# | ||
# Limit switches can be configured to one of two polarities: | ||
# rev.CANDigitalInput.LimitSwitchPolarity.kNormallyOpen | ||
# rev.CANDigitalInput.LimitSwitchPolarity.kNormallyClosed | ||
self.forwardLimit = self.motor.getForwardLimitSwitch( | ||
rev.LimitSwitchPolarity.kNormallyClosed | ||
) | ||
self.reverseLimit = self.motor.getReverseLimitSwitch( | ||
rev.LimitSwitchPolarity.kNormallyClosed | ||
) | ||
|
||
self.forwardLimit.enableLimitSwitch(False) | ||
self.reverseLimit.enableLimitSwitch(False) | ||
|
||
wpilib.SmartDashboard.putBoolean( | ||
"Forward Limit Enabled", self.forwardLimit.isLimitSwitchEnabled() | ||
) | ||
wpilib.SmartDashboard.putBoolean( | ||
"Reverse Limit Enabled", self.forwardLimit.isLimitSwitchEnabled() | ||
) | ||
|
||
def teleopPeriodic(self): | ||
# Pair motor and the joystick's Y Axis | ||
self.motor.set(self.joystick.getY()) | ||
|
||
# enable/disable limit switches based on value read from SmartDashboard | ||
self.forwardLimit.enableLimitSwitch( | ||
wpilib.SmartDashboard.getBoolean("Forward Limit Enabled", False) | ||
) | ||
self.reverseLimit.enableLimitSwitch( | ||
wpilib.SmartDashboard.getBoolean("Reverse Limit Enabled", False) | ||
) | ||
|
||
# The get() method can be used on a CANDigitalInput object to read the | ||
# state of the switch. | ||
# | ||
# In this example, the polarity of the switches are set to normally | ||
# closed. In this case, get() will return true if the switch is | ||
# pressed. It will also return true if you do not have a switch | ||
# connected. get() will return false when the switch is released. | ||
wpilib.SmartDashboard.putBoolean( | ||
"Forward Limit Enabled", self.forwardLimit.get() | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
wpilib.SmartDashboard.putBoolean( | ||
"Reverse Limit Enabled", self.reverseLimit.get() | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
wpilib.run(Robot) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#!/usr/bin/env python3 | ||
# ---------------------------------------------------------------------------- | ||
# Copyright (c) 2017-2018 FIRST. All Rights Reserved. | ||
# Open Source Software - may be modified and shared by FRC teams. The code | ||
# must be accompanied by the FIRST BSD license file in the root directory of | ||
# the project. | ||
# ---------------------------------------------------------------------------- | ||
|
||
import rev | ||
import wpilib | ||
from wpilib.drive import DifferentialDrive | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
class Robot(wpilib.TimedRobot): | ||
def robotInit(self): | ||
# Create motors | ||
self.motor = rev.CANSparkMax(0, rev.MotorType.kBrushless) | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# You must call getPIDController() on an existing CANSparkMax or | ||
# SparkMax object to fully use PID functionality | ||
self.pidController = self.motor.getPIDController() | ||
|
||
# Instantiate built-in encoder to display position | ||
self.encoder = self.motor.getEncoder() | ||
|
||
# PID Coefficents and Controller Output Range | ||
self.coeff = {"p": 0.1, "i": 1e-4, "d": 0, "iz": 0, "ff": 0} | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.kMinOutput = -1 | ||
self.kMaxOutput = 1 | ||
|
||
# The restoreFactoryDefaults() method can be used to reset the | ||
# configuration parameters in the SPARK MAX to their factory default | ||
# state. If no argument is passed, these parameters will not persist | ||
# between power cycles | ||
self.motor.restoreFactoryDefaults() | ||
|
||
# Set PID Coefficents | ||
self.pidController.setP(self.coeff["p"]) | ||
self.pidController.setI(self.coeff["i"]) | ||
self.pidController.setD(self.coeff["d"]) | ||
self.pidController.setIZone(self.coeff["iz"]) | ||
self.pidController.setFF(self.coeff["ff"]) | ||
self.pidController.setOutputRange(self.kMinOutput, self.kMaxOutput) | ||
|
||
# Push PID Coefficients to SmartDashboard | ||
wpilib.SmartDashboard.putNumber("P Gain", self.coeff["p"]) | ||
wpilib.SmartDashboard.putNumber("I Gain", self.coeff["i"]) | ||
wpilib.SmartDashboard.putNumber("D Gain", self.coeff["d"]) | ||
wpilib.SmartDashboard.putNumber("I Zone", self.coeff["iz"]) | ||
wpilib.SmartDashboard.putNumber("Feed Forward", self.coeff["ff"]) | ||
wpilib.SmartDashboard.putNumber("Min Output", self.kMinOutput) | ||
wpilib.SmartDashboard.putNumber("Max Output", self.kMaxOutput) | ||
wpilib.SmartDashboard.putNumber("Set Rotations", 0) | ||
|
||
def teleopPeriodic(self): | ||
# Read data from SmartDashboard | ||
p = wpilib.SmartDashboard.getNumber("P Gain", 0) | ||
i = wpilib.SmartDashboard.getNumber("I Gain", 0) | ||
d = wpilib.SmartDashboard.getNumber("D Gain", 0) | ||
iz = wpilib.SmartDashboard.getNumber("I Zone", 0) | ||
ff = wpilib.SmartDashboard.getNumber("Feed Forward", 0) | ||
min_out = wpilib.SmartDashboard.getNumber("Min Output", 0) | ||
max_out = wpilib.SmartDashboard.getNumber("Max Output", 0) | ||
rotations = wpilib.SmartDashboard.getNumber("Set Rotations", 0) | ||
|
||
# Update PIDController datapoints with the latest from SmartDashboard | ||
if p is not self.coeff["p"]: | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.pidController.setP(p) | ||
self.coeff["p"] = p | ||
if i is not self.coeff["i"]: | ||
self.pidController.setI(pi) | ||
self.coeff["i"] = i | ||
if d is not self.coeff["d"]: | ||
self.pidController.setD(d) | ||
self.coeff["d"] = d | ||
if iz is not self.coeff["iz"]: | ||
self.pidController.setIZone(iz) | ||
self.coeff["iz"] = iz | ||
if ff is not self.coeff["ff"]: | ||
self.pidController.setFF(ff) | ||
self.coeff["ff"] = ff | ||
if (min_out is not self.kMinOutput) or (max_out is not self.kMaxOutput): | ||
self.pidController.setOutputRange(min_out, max_out) | ||
self.kMinOutput = min_out, self.kMaxOutput = max_out | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# PIDController objects are commanded to a set point using the | ||
# setReference() method. | ||
# | ||
# The first parameter is the value of the set point, whose units vary | ||
# depending on the control type set in the second parameter. | ||
# | ||
# The second parameter is the control type can be set to one of four | ||
# parameters: | ||
# rev.ControlType.kDutyCycle | ||
# rev.ControlType.kPosition | ||
# rev.ControlType.kVelocity | ||
# rev.ControlType.kVoltage | ||
# | ||
# For more information on what these types are, refer to the Spark Max | ||
# documentation. | ||
self.pidController.setReference(rotations, rev.ControlType.kPosition) | ||
|
||
# Push Setpoint and the motor's current position to SmartDashboard. | ||
wpilib.SmartDashboard.putNumber("Setpoint", rotations) | ||
wpilib.SmartDashboard.putNumber("Process Variable", self.encoder.getPosition()) | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
if __name__ == "__main__": | ||
wpilib.run(Robot) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#!/usr/bin/env python3 | ||
# ---------------------------------------------------------------------------- | ||
# Copyright (c) 2017-2018 FIRST. All Rights Reserved. | ||
# Open Source Software - may be modified and shared by FRC teams. The code | ||
# must be accompanied by the FIRST BSD license file in the root directory of | ||
# the project. | ||
# ---------------------------------------------------------------------------- | ||
|
||
import rev | ||
import wpilib | ||
|
||
|
||
class Robot(wpilib.TimedRobot): | ||
# This sample program displays the position and velocity of the integrated | ||
# encoder onto the SmartDashboard. | ||
# | ||
# Position is displayed in revolutions (of the motor's axle) and velocity | ||
# is displayed in revolutions per minute (RPM) | ||
# | ||
# Optionally, if you call the setPositionConversionFactor() method on the | ||
# encoder and give it a measurement of how far one revolution is, the | ||
# getVelocity() and getPosition() methods return a scaled output in the | ||
# units of your choice. | ||
def robotInit(self): | ||
# Instantiate SPARK MAX object | ||
self.motor = rev.CANSparkMax(0, rev.MotorType.kBrushless) | ||
Tyler-Duckworth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
self.encoder = self.motor.getEncoder() | ||
|
||
self.joystick = wpilib.Joystick(0) | ||
|
||
def teleopPeriodic(self): | ||
# Set motor output to the joystick's Y-axis | ||
self.motor.set(self.joystick.getY()) | ||
|
||
# Encoder position is read from a CANEncoder object by calling the | ||
# getPosition() method. | ||
# | ||
# getPosition() returns the position of the encoder in units of | ||
# revolutions (unless overridden) | ||
wpilib.SmartDashboard.putNumber("Encoder Position", self.encoder.getPosition()) | ||
|
||
# Encoder velocity is read from a CANEncoder object by calling the | ||
# getVelocity() method. | ||
# | ||
# getVelocity() returns the position of the encoder in units of | ||
# revolutions (unless overridden) | ||
wpilib.SmartDashboard.putNumber("Encoder Velocity", self.encoder.getVelocity()) | ||
|
||
|
||
if __name__ == "__main__": | ||
wpilib.run(Robot) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.