Source code for lift.claw
"""
Code for the claw subsystem.
This file contains code for the claw, which is implemented as a finite-state
automaton with these states:
- **neutral**: the claw is fully open and not in action.
- **closing**: the claw is transitioning from the "neutral" state to the
"closed" state.
- **closed**: the claw is in the closed position, but still exerting light
pressure to maintain grip on the cube.
- **opening**: the claw is transitioning from the "closed" state to the
"neutral" state.
- **manual_ctrl**: a disconnected state from the other four; used when the
driver wants full control over the claw without assistance
from the state automaton.
:Authors: Brandon Gong, Sebastian Mobo
:Version: 0.0.1
:Date: January 19, 2018
"""
import wpilib
from ctre.talonsrx import TalonSRX
[docs]class Claw:
"""
Implements a finite-state automaton for manipulating the claw.
Parameters:
talon_id: the ID number of the talon on the claw.
contact_sensor_channel: the channel that the contact sensor is
connected to.
"""
claw_movement_time = 0.5 #: time to allow for the claw to open, in seconds
claw_adjust_time = 0.25
def __init__(self, talon_id):
"""
Create a new instance of the claw subsystem.
This function constructs and configures the CANTalon instance and the
touch sensor. It also sets the state machine to the neutral starting
state.
"""
self.talon = TalonSRX(talon_id)
# Forward limit switch = claw opening limit switch
# self.talon.configForwardLimitSwitchSource(
# TalonSRX.LimitSwitchSource.FeedbackConnector,
# TalonSRX.LimitSwitchNormal.NormallyOpen,
# 0
# )
self.state = 'neutral'
self.closeAdjustTimer = wpilib.Timer()
self.movementTimer = wpilib.Timer()
[docs] def close(self):
"""
Close the claw.
This function does a quick check to make sure it is a valid state
change before actually changing the state to "closing".
For example you cannot set the state to "closing" if the claw is
already gripping the cube.
"""
if self.state != 'closed' and self.state != 'closing':
self.state = 'closing'
self.movementTimer.reset()
self.movementTimer.start()
[docs] def open(self):
"""
Open the claw.
The idea of checking the state change is similar to that of the close()
function, but it also resets the opening start time.
"""
if self.state != 'neutral' and self.state != 'opening':
self.state = 'opening'
self.movementTimer.reset()
self.movementTimer.start()
[docs] def toggle(self):
"""
Toggle the claw state.
If the claw is closed, open it, and if the claw is opened, close it.
"""
if self.state == 'closed' or self.state == 'closing':
self.open()
elif self.state == 'neutral' or self.state == 'opening':
self.close()
[docs] def update(self):
"""
The update function is called periodically and progresses the state
machine.
"""
# if the state is manual control, stop update immediately and return.
if self.state == 'manual_ctrl':
self.movementTimer.reset()
self.movementTimer.stop()
return
# if the state is neutral, clear the start time and set the talon speed
# to 0%
elif self.state == 'neutral':
self.movementTimer.reset()
self.movementTimer.stop()
self.talon.set(TalonSRX.ControlMode.PercentVbus, 0)
# if the state is "closing", set the talon speed to -100%, and if the
# touch sensor is depressed, transition to the "closed" state.
elif self.state == 'closing':
self.talon.set(TalonSRX.ControlMode.PercentVbus, -1.0)
# fwdLim, revLim = self.talon.getLimitSwitchState()
#
# if revLim: # contact sensor pressed?
# self.state = 'closed'
# self.closeAdjustTimer.reset()
# self.closeAdjustTimer.start()
if self.movementTimer.get() > self.claw_movement_time:
self.state = 'closed'
self.closeAdjustTimer.reset()
self.closeAdjustTimer.start()
# if the state is "closed", use less power to the motors--
# Maintain grip, but don't squeeze too hard
elif self.state == 'closed':
if self.closeAdjustTimer.get() > self.claw_adjust_time:
self.talon.set(TalonSRX.ControlMode.PercentVbus, -0.5)
else:
self.talon.set(TalonSRX.ControlMode.PercentVbus, 0)
# if the state is "opening", save the current time if the start time
# is currently empty and set the motor speed to +100%.
# Run until reaching claw_movement_time, then transition to the "neutral"
# state.
elif self.state == 'opening':
self.talon.set(TalonSRX.ControlMode.PercentVbus, 1.0)
if self.movementTimer.get() > self.claw_movement_time:
self.state = 'neutral'