-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from Arctos6135/develop
2020 Initial Release
- Loading branch information
Showing
14 changed files
with
646 additions
and
16 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
144 changes: 144 additions & 0 deletions
144
src/main/java/com/arctos6135/robotlib/newcommands/motors/ProtectedMotor.java
This file contains 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,144 @@ | ||
package com.arctos6135.robotlib.newcommands.motors; | ||
|
||
import com.arctos6135.robotlib.motors.Motor; | ||
import com.arctos6135.robotlib.newcommands.triggers.CurrentMonitoringTrigger; | ||
|
||
import edu.wpi.first.wpilibj.PowerDistributionPanel; | ||
|
||
/** | ||
* A motor with software overcurrent protection. The {@code ProtectedMotor} acts | ||
* as a wrapper around a normal motor. | ||
* <p> | ||
* When the maximum current allowed for this motor is exceeded for a specified | ||
* period of time, the motor becomes blacklisted. When a motor is blacklisted, | ||
* it will be set to 0 and will not respond to any operations. Once blacklisted, | ||
* a motor stays blacklisted unless it is overridden with | ||
* {@link #clearBlacklist()}. | ||
* </p> | ||
* | ||
* @author Tyler Tian | ||
*/ | ||
public class ProtectedMotor { | ||
|
||
private Motor motor; | ||
|
||
// A motor is blacklisted when the current limit is exceeded for a set period of | ||
// time | ||
// After it is blacklisted, it will be set to 0 and will not respond to setting | ||
// Blacklist status will stick around forever unless cleared | ||
private boolean blacklisted = false; | ||
|
||
// Whether the protection system is enabled | ||
// If protection is not enabled, the motor will ignore overcurrent permanently | ||
private boolean enabled = true; | ||
|
||
/** | ||
* Creates a new protected motor object. | ||
* | ||
* @param pdp The PDP to get current readings from | ||
* @param channel The PDP channel to get current readings from | ||
* @param motor The internal {@link Motor} object controlled | ||
* @param currentLimit The current limit in amps | ||
* @param overcurrentTime The time allowed to exceed the current limit before | ||
* the motor is blacklisted | ||
* @param callback A callback function to be run when the motor is | ||
* blacklisted | ||
*/ | ||
@SuppressWarnings("resource") | ||
public ProtectedMotor(PowerDistributionPanel pdp, int channel, Motor motor, double currentLimit, | ||
double overcurrentTime, Runnable callback) { | ||
this.motor = motor; | ||
|
||
new CurrentMonitoringTrigger(pdp, channel, currentLimit, overcurrentTime, () -> { | ||
if (enabled) { | ||
blacklisted = true; | ||
motor.set(0); | ||
|
||
if (callback != null) { | ||
callback.run(); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Creates a new protected motor object. | ||
* | ||
* @param pdp The PDP to get current readings from | ||
* @param channel The PDP channel to get current readings from | ||
* @param motor The internal {@link Motor} object controlled | ||
* @param currentLimit The current limit in amps | ||
* @param overcurrentTime The time allowed to exceed the current limit before | ||
* the motor is blacklisted | ||
*/ | ||
public ProtectedMotor(PowerDistributionPanel pdp, int channel, Motor motor, double currentLimit, | ||
double overcurrentTime) { | ||
this(pdp, channel, motor, currentLimit, overcurrentTime, null); | ||
} | ||
|
||
/** | ||
* Sets the motor. If the motor is blacklisted, this method will set it to 0 | ||
* instead. | ||
* | ||
* @param value The value to set the motor to | ||
*/ | ||
public void set(double value) { | ||
if (!blacklisted || !enabled) { | ||
motor.set(value); | ||
} else { | ||
motor.set(0); | ||
} | ||
} | ||
|
||
/** | ||
* Returns whether the motor is blacklisted. | ||
* | ||
* @return Whether the motor is blacklisted | ||
*/ | ||
public boolean isBlacklisted() { | ||
return blacklisted; | ||
} | ||
|
||
/** | ||
* Overrides the blacklisted status of the motor. This is the only way to get | ||
* rid of blacklisted status. | ||
*/ | ||
public void clearBlacklist() { | ||
blacklisted = false; | ||
} | ||
|
||
/** | ||
* Manually sets the motor to be blacklisted. | ||
*/ | ||
public void blacklist() { | ||
blacklisted = true; | ||
} | ||
|
||
/** | ||
* Returns whether overcurrent protection is on for the motor. | ||
* | ||
* <p> | ||
* If overcurrent protection is off, the motor will never be blacklisted, and | ||
* will still be controllable even if it is. | ||
* </p> | ||
* | ||
* @return Whether overcurrent protection is on | ||
*/ | ||
public boolean getProtectionState() { | ||
return enabled; | ||
} | ||
|
||
/** | ||
* Enables or disables the overcurrent protection. | ||
* | ||
* <p> | ||
* If overcurrent protection is off, the motor will never be blacklisted, and | ||
* will still be controllable even if it is. | ||
* </p> | ||
* | ||
* @param enabled Whether overcurrent protection is on | ||
*/ | ||
public void setProtectionState(boolean enabled) { | ||
this.enabled = enabled; | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
src/main/java/com/arctos6135/robotlib/newcommands/motors/package-info.java
This file contains 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,5 @@ | ||
/** | ||
* This package contains classes related to motors offered by RobotLib <b>with | ||
* the new command-based framework</b>. | ||
*/ | ||
package com.arctos6135.robotlib.newcommands.motors; |
87 changes: 87 additions & 0 deletions
87
src/main/java/com/arctos6135/robotlib/newcommands/triggers/AnalogTrigger.java
This file contains 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,87 @@ | ||
package com.arctos6135.robotlib.newcommands.triggers; | ||
|
||
import edu.wpi.first.wpilibj.GenericHID; | ||
import edu.wpi.first.wpilibj.Timer; | ||
import edu.wpi.first.wpilibj2.command.button.Trigger; | ||
|
||
/** | ||
* The {@code AnalogTrigger} class is a {@link Trigger} that activates when the | ||
* value of some analog axis on a joystick exceeds a given threshold. | ||
* | ||
* @author Tyler Tian | ||
*/ | ||
public class AnalogTrigger extends Trigger { | ||
|
||
private int axis; | ||
private double threshold; | ||
private GenericHID joystick; | ||
private boolean reverse; | ||
|
||
private double pressedAt = Double.NaN; | ||
private double timeRequired = 0.1; | ||
|
||
/** | ||
* Creates a new {@link AnalogTrigger}. | ||
* | ||
* @param joystick The controller | ||
* @param trigger The specific axis to read from | ||
* @param threshold The threshold that needs to be reached for this trigger to | ||
* activate | ||
*/ | ||
public AnalogTrigger(GenericHID joystick, int trigger, double threshold) { | ||
axis = trigger; | ||
this.joystick = joystick; | ||
this.threshold = threshold; | ||
} | ||
|
||
/** | ||
* Creates a new {@link AnalogTrigger}. | ||
* | ||
* @param joystick The controller | ||
* @param trigger The specific axis to read from | ||
* @param threshold The threshold that needs to be reached for this trigger to | ||
* activate | ||
* @param reverse If true, the value must be less than the threshold for the | ||
* trigger to activate | ||
*/ | ||
public AnalogTrigger(GenericHID joystick, int trigger, double threshold, boolean reverse) { | ||
axis = trigger; | ||
this.joystick = joystick; | ||
this.threshold = threshold; | ||
this.reverse = reverse; | ||
} | ||
|
||
/** | ||
* Sets the minimum amount of time the axis value is required to exceed the | ||
* threshold for before this trigger activates. | ||
* | ||
* <p> | ||
* This minimum time requirement is to prevent the trigger from being activated | ||
* too many times due to an unstable analog reading. | ||
* </p> | ||
* | ||
* @param required The minimum required time for activation, in seconds | ||
*/ | ||
public void setMinTimeRequired(double required) { | ||
timeRequired = required; | ||
} | ||
|
||
@Override | ||
public boolean get() { | ||
boolean exceeded = reverse ? joystick.getRawAxis(axis) <= threshold : joystick.getRawAxis(axis) >= threshold; | ||
// If trigger is pressed down: | ||
if (exceeded) { | ||
// Pressed down since is NaN (trigger not pressed down before), set the value | ||
if (Double.isNaN(pressedAt)) { | ||
pressedAt = Timer.getFPGATimestamp(); | ||
} | ||
// Return whether the trigger has been pressed for more than the specified | ||
// duration | ||
return Timer.getFPGATimestamp() - pressedAt >= timeRequired; | ||
} else { | ||
// If the trigger is not pressed, reset the last pressed down time | ||
pressedAt = Double.NaN; | ||
return false; | ||
} | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
src/main/java/com/arctos6135/robotlib/newcommands/triggers/ConditionalTrigger.java
This file contains 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 @@ | ||
package com.arctos6135.robotlib.newcommands.triggers; | ||
|
||
import java.util.concurrent.atomic.AtomicBoolean; | ||
|
||
import edu.wpi.first.wpilibj2.command.button.Trigger; | ||
|
||
/** | ||
* The {@code ConditionalTrigger} class is a wrapper around a normal | ||
* {@link Trigger} that can only be activated when its "condition" evaluates to | ||
* {@code true}. | ||
* | ||
* <p> | ||
* The "condition" is passed in the form of an {@link AtomicBoolean}, so that it | ||
* can be modified outside of this class. | ||
* </p> | ||
* <p> | ||
* Example Usage: | ||
* | ||
* <pre> | ||
* AtomicBoolean allowInput = new AtomicBoolean(true); | ||
* Trigger b = new ConditionalTrigger(new JoystickButton(joystick, number), allowInput); | ||
* b.whenActive(new SomeCommand()); // After this point, SomeCommand will run when the trigger is pressed | ||
* // ... | ||
* allowInput.set(false); // After this point, SomeCommand will not run, even if the trigger is pressed | ||
* </pre> | ||
* </p> | ||
* | ||
* @author Tyler Tian | ||
*/ | ||
public class ConditionalTrigger extends Trigger { | ||
|
||
private Trigger trigger; | ||
private AtomicBoolean condition; | ||
private boolean required = true; | ||
|
||
/** | ||
* Creates a new {@link ConditionalTrigger}. | ||
* | ||
* <p> | ||
* This trigger can only be activated when {@code condition.get()} evaluates to | ||
* {@code true}. | ||
* </p> | ||
* | ||
* @param trigger The trigger to wrap around | ||
* @param condition The condition for this trigger | ||
*/ | ||
public ConditionalTrigger(Trigger trigger, AtomicBoolean condition) { | ||
this.trigger = trigger; | ||
this.condition = condition; | ||
} | ||
|
||
/** | ||
* Create a new {@link ConditionalTrigger}. | ||
* | ||
* <p> | ||
* This trigger can only be activated when {@code condition.get() == required}. | ||
* </p> | ||
* | ||
* @param trigger The trigger to wrap around | ||
* @param condition The condition for this trigger | ||
* @param required The state the condition is required to be in for this | ||
* trigger to activate | ||
*/ | ||
public ConditionalTrigger(Trigger trigger, AtomicBoolean condition, boolean required) { | ||
this(trigger, condition); | ||
this.required = required; | ||
} | ||
|
||
@Override | ||
public boolean get() { | ||
return trigger.get() && (condition.get() == required); | ||
} | ||
} |
Oops, something went wrong.