示例#1
0
def config_talon(talon: WPI_TalonSRX, motor_config: TalonMotorConfig):
    # when deploying it might be a somewhat good idea to actually uncomment this next line
    talon.configFactoryDefault()
    talon.enableVoltageCompensation(True)
    talon.configVoltageCompSaturation(motor_config.voltage_saturation)
    talon.enableCurrentLimit(True)
    talon.configPeakCurrentLimit(motor_config.peak_current)
    talon.configContinuousCurrentLimit(motor_config.continuous_current)
    talon.setNeutralMode(motor_config.default_mode)
    talon.configNeutralDeadband(motor_config.deadband)
    # talon.configOpenLoopRamp(motor_config.ramp_rate)
    talon.setInverted(motor_config.reversed)
示例#2
0
def config_talon(talon: WPI_TalonSRX, motor_config: MotorConfig) -> None:
    talon.enableVoltageCompensation(True)
    talon.configVoltageCompSaturation(motor_config.voltage_saturation)

    talon.enableCurrentLimit(True)
    talon.configPeakCurrentLimit(motor_config.peak_current)
    talon.configContinuousCurrentLimit(motor_config.continuous_current)

    talon.setNeutralMode(motor_config.default_mode)

    talon.configNeutralDeadband(motor_config.deadband)

    talon.configOpenLoopRamp(motor_config.ramp_rate)
示例#3
0
def configure_drivetrain(motor: ctre.WPI_TalonSRX):
    """
    Configure a given motor controller for drivetrain usage
        :param motor:ctre.WPI_TalonSRX: The motor to be configured
    """
    # TODO make sure to uncomment next line on first test/deploy
    # motor.configFactoryDefault()
    motor.configOpenLoopRamp(0.2)
    motor.clearStickyFaults()
    motor.enableCurrentLimit(True)
    motor.configContinuousCurrentLimit(10)
    motor.configPeakCurrentLimit(0)
    motor.setNeutralMode(ctre.NeutralMode.Brake)
示例#4
0
 def configure_drivetrain_cim(motor: ctre.WPI_TalonSRX):
     """
     Configure a given motor controller for drivetrain usage
         :param motor:ctre.WPI_TalonSRX: The motor to be configured
     """
     # TODO Decide if following line is needed
     # motor.configFactoryDefault()
     # 0 is disabled for ramp rates, input is in seconds
     motor.configOpenLoopRamp(0.5)
     motor.clearStickyFaults()
     motor.enableCurrentLimit(True)
     motor.configContinuousCurrentLimit(70)
     motor.configPeakCurrentLimit(0)
     motor.setNeutralMode(ctre.NeutralMode.Brake)
示例#5
0
class CargoMech():
    kSlotIdx = 0
    kPIDLoopIdx = 0
    kTimeoutMs = 10

    def initialize(self):
        timeout = 15
        SmartDashboard.putNumber("Wrist Power Set", 0)
        self.lastMode = "unknown"
        self.sb = []
        self.targetPosUp = -300  #!!!!!
        self.targetPosDown = -1500  #!!!!!
        self.maxVolts = 10
        self.simpleGain = 0.57
        self.wristUpVolts = 5
        self.wristDownVolts = 2
        self.simpleGainGravity = 0.07
        self.xbox = oi.getJoystick(2)
        self.joystick0 = oi.getJoystick(0)
        #below is the talon on the intake
        self.motor = Talon(map.intake)

        self.gPower = 0
        self.input = 0

        self.motor.configContinuousCurrentLimit(20,
                                                timeout)  #15 Amps per motor
        self.motor.configPeakCurrentLimit(
            30, timeout)  #20 Amps during Peak Duration
        self.motor.configPeakCurrentDuration(
            100, timeout)  #Peak Current for max 100 ms
        self.motor.enableCurrentLimit(True)

        #Talon motor object created
        self.wrist = Talon(map.wrist)
        if not wpilib.RobotBase.isSimulation():
            self.wrist.configFactoryDefault()
        self.wrist.configVoltageCompSaturation(self.maxVolts)
        self.wrist.setInverted(True)
        self.wrist.setNeutralMode(2)
        self.motor.setNeutralMode(2)
        self.motor.configVoltageCompSaturation(self.maxVolts)

        self.wrist.configClearPositionOnLimitF(True)

        #MOTION MAGIC CONFIG
        self.loops = 0
        self.timesInMotionMagic = 0

        #self.wrist.setSelectedSensorPosition(0, self.kPIDLoopIdx, self.kTimeoutMs)

        [self.kP, self.kI, self.kD] = [0, 0, 0]
        cargoController = PIDController(self.kP,
                                        self.kI,
                                        self.kD,
                                        source=self.getAngle,
                                        output=self.__setGravity__)
        self.cargoController = cargoController
        self.cargoController.disable()

    def intake(self, mode):
        #Intake/Outtake/Stop, based on the mode it changes the speed of the motor
        if mode == "intake": self.motor.set(0.9)
        elif mode == "outtake": self.motor.set(-0.9)
        elif mode == "stop": self.motor.set(0)

    def moveWrist(self, mode):
        #move wrist in and out of robot
        '''replace modes up and down with pid and set angles'''
        if mode == "up":
            self.input = (self.getPowerSimple("up")) + self.getGravity()
            self.wrist.set(self.getPowerSimple("up") + self.getGravity())
        elif mode == "down":
            self.input = (-1 * self.getPowerSimple("down")) + self.getGravity()
            self.wrist.set((-1 * self.getPowerSimple("down")) +
                           self.getGravity())
        elif mode == "upVolts":
            self.input = (self.wristUpVolts /
                          self.maxVolts) + self.getGravity()
            self.wrist.set((self.wristUpVolts / self.maxVolts) +
                           self.getGravity())
        elif mode == "downVolts":
            self.input = (-1 * self.wristDownVolts /
                          self.maxVolts) + self.getGravity()
            self.wrist.set((-1 * self.wristDownVolts / self.maxVolts) +
                           self.getGravity())
        elif mode == "stop":
            self.input = 0
            self.wrist.set(0)
        else:
            #self.input = self.getGravity#()
            #self.input = self.getNumber("#Wrist Power Set", 0)
            self.input = 0
            self.wrist.set(self.input)
            #self.cargoController.setSetpoint(self.getAngle())
            #self.cargoController.enable()
            #self.wrist.set(self.gPower)
            '''replace pid here with kF'''

    def periodic(self):
        #0.4 as a deadband
        if self.xbox.getRawAxis(map.intakeCargo) > 0.4: self.intake("intake")
        elif self.xbox.getRawAxis(map.outtakeCargo) > 0.4:
            self.intake("outtake")
        else:
            self.intake("stop")

        if self.xbox.getRawButton(map.wristUp): self.moveWrist("up")
        elif self.xbox.getRawButton(map.wristDown): self.moveWrist("down")
        elif self.joystick0.getRawButton(map.wristUpVolts):
            self.moveWrist("upVolts")
        elif self.joystick0.getRawButton(map.wristDownVolts):
            self.moveWrist("downVolts")
        else:
            self.moveWrist("gravity")

    #disables intake
    def disable(self):
        self.intake("stop")

    #gets the angle, used in other support functions
    def getAngle(self):
        pos = self.getPosition()
        angle = abs(pos * 115 / self.targetPosDown)
        return (angle - 25)
        '''cargo mech vertical is 0 degrees'''
        '''cargo mech down completely is 90 degrees'''
        '''cargo mech has range of -25 to 85 degrees'''

    def getGravity(self):
        '''angle = self.getAngle()
        power = 0
        if angle < -20:
            power = 0
        elif angle > 80:
            power = 0
        else:
            power = math.sin(math.radians(angle)) / 2
        return power'''
        return 0

    def getPosition(self):
        return self.wrist.getQuadraturePosition()

    def getFeedForward(self, gain):
        angle = self.getAngle()
        return angle * gain

    def __setGravity__(self, output):
        self.gPower = output

    def getPowerSimple(self, direction):
        '''true direction is up into robot
        false direction is down out of robot'''
        angle = self.getAngle()
        power = abs(self.simpleGain)
        if angle > 80:
            if direction == "down":
                power = 0
        #if angle < -20:
        #    if direction == "up":
        #        power = 0
        return power

    def setWristPower(self, power):
        self.wrist.set(power)

    def getNumber(self, key, defVal):
        val = SmartDashboard.getNumber(key, None)
        if val == None:
            val = defVal
            SmartDashboard.putNumber(key, val)
        return val

    def dashboardInit(self):
        pass

    def dashboardPeriodic(self):
        #self.wristUp = self.getNumber("WristUpSpeed" , 0.5)
        #self.wristDown = self.getNumber("WristDownSpeed" , 0.2)
        #self.wristUpVolts = self.getNumber("WristUpVoltage" , 5)
        #self.wristDownVolts = self.getNumber("WristDownVoltage" , 2)
        #self.simpleGain = self.getNumber("Wrist Simple Gain", self.simpleGain)
        #self.simpleGainGravity = self.getNumber("Wrist Simple Gain Gravity", self.simpleGainGravity)
        self.kP = self.getNumber("Wrist kP", 0)
        self.kI = self.getNumber("Wrist kI", 0)
        self.kD = self.getNumber("Wrist kD", 0)
        SmartDashboard.putNumber("Wrist Position",
                                 self.wrist.getQuadraturePosition())
        SmartDashboard.putNumber("Wrist Angle", self.getAngle())
        #SmartDashboard.putNumber("Wrist Power", self.input)
        SmartDashboard.putNumber("Wrist Power Up", self.getPowerSimple("up"))
        SmartDashboard.putNumber("Wrist Power Down",
                                 self.getPowerSimple("down"))
示例#6
0
class CargoMech():
    def initialize(self):
        timeout = 15
        SmartDashboard.putNumber("Wrist Power Set", 0)
        SmartDashboard.putNumber("Gravity Power", 0)

        self.F = 0.25
        SmartDashboard.putNumber("F Gain", self.F)

        #self.angle = 0
        #SmartDashboard.putNumber("angle", self.angle)

        self.range = -1200

        self.povPressed = False

        self.maxVolts = 10
        self.wristUpVolts = 4
        self.wristDownVolts = -4
        SmartDashboard.putNumber("Wrist Up Volts", self.wristUpVolts)
        SmartDashboard.putNumber("Wrist Down Volts", self.wristDownVolts)

        self.xbox = oi.getJoystick(2)
        self.joystick0 = oi.getJoystick(0)

        #below is the talon on the intake
        self.intake = Talon(map.intake)
        self.intake.setNeutralMode(2)
        self.intake.configVoltageCompSaturation(self.maxVolts)

        self.intake.configContinuousCurrentLimit(20,
                                                 timeout)  #20 Amps per motor
        self.intake.configPeakCurrentLimit(
            30, timeout)  #30 Amps during Peak Duration
        self.intake.configPeakCurrentDuration(
            100, timeout)  #Peak Current for max 100 ms
        self.intake.enableCurrentLimit(True)

        #Talon motor object created
        self.wrist = Talon(map.wrist)

        if not wpilib.RobotBase.isSimulation():
            self.wrist.configFactoryDefault()

        self.wrist.setInverted(True)

        self.wrist.configVoltageCompSaturation(self.maxVolts)
        self.wrist.setNeutralMode(2)

        self.wrist.configClearPositionOnLimitF(True)

        self.wrist.configContinuousCurrentLimit(20,
                                                timeout)  #20 Amps per motor
        self.wrist.configPeakCurrentLimit(
            30, timeout)  #30 Amps during Peak Duration
        self.wrist.configPeakCurrentDuration(
            100, timeout)  #Peak Current for max 100 ms
        self.wrist.enableCurrentLimit(True)

    def setIntake(self, mode):
        #Intake/Outtake/Stop, based on the mode it changes the speed of the motor
        if mode == "intake": self.intake.set(0.9)
        elif mode == "outtake": self.intake.set(-0.9)
        else: self.intake.set(0)

    def setWrist(self, mode):
        [setpoint, error] = [10, 5]
        mult = abs(
            self.getAngle() - 50
        ) / 100 + 0.5  #increase constant if the arm is not moving enough close to the setpoint
        if mode == "rocket" and self.getAngle() < setpoint - error:
            self.moveWrist(self.wristDownVolts / self.maxVolts * mult, mode)
        elif mode == "rocket" and self.getAngle() > setpoint + error:
            self.moveWrist(self.wristUpVolts / self.maxVolts * mult, mode)
        elif mode == "up":
            self.moveWrist(self.wristUpVolts / self.maxVolts, mode)
        elif mode == "down":
            self.moveWrist(self.wristDownVolts / self.maxVolts, mode)
        elif mode == "rocket" or mode == "gravity":
            self.moveWrist(0, mode)
        else:
            self.moveWrist(-self.getGravity(), "stop")

    def moveWrist(self, power, mode):
        self.out = self.wristBounds(power + self.getGravity(), mode)
        self.wrist.set(self.out)

    def wristBounds(self, power, mode):
        angle = self.getAngle()
        if angle > 80 and (mode == "down" or mode == "gravity"): power = 0
        elif angle < -20 and (mode == "up" or mode == "gravity"): power = 0
        elif angle < 10 and mode == "gravity":
            power = self.F  #if operator lets go of buttons while at top, arm goes back to upper limit sqitch
        return power

    def getGravity(self):
        return math.sin(math.radians(self.getAngle())) * self.F

    def getAngle(self):
        pos = 0
        if self.wrist.isRevLimitSwitchClosed():
            pos = self.range
            self.wrist.setQuadraturePosition(pos)
        else:
            pos = self.getPosition()
        angle = abs(pos * 115 / self.range)
        return (angle - 25)

    '''
    def getAngle(self):
        return self.angle
    '''

    def getPosition(self):
        return self.wrist.getQuadraturePosition()

    def periodic(self):
        if self.xbox.getRawAxis(map.intakeCargo) > 0.4:
            self.setIntake("intake")
        elif self.xbox.getRawAxis(map.outtakeCargo) > 0.4:
            self.setIntake("outtake")
        else:
            self.setIntake("stop")

        if self.xbox.getPOV() >= 0 and self.povPressed: self.povPressed = False
        elif self.xbox.getPOV() >= 0 and not self.povPressed:
            self.povPressed = True

        if self.povPressed: self.setWrist("rocket")
        elif self.xbox.getRawButton(map.wristUp): self.setWrist("up")
        elif self.xbox.getRawButton(map.wristDown): self.setWrist("down")
        else: self.setWrist("gravity")

    #disables intake
    def disable(self):
        self.setIntake("stop")
        self.setWrist("stop")

    def getNumber(self, key, defVal):
        val = SmartDashboard.getNumber(key, None)
        if val == None:
            val = defVal
            SmartDashboard.putNumber(key, val)
        return val

    def dashboardInit(self):
        pass

    def dashboardPeriodic(self):
        #commented out some values. DON'T DELETE THESE VALUES
        #SmartDashboard.putNumber("Wrist Position", self.wrist.getQuadraturePosition())
        SmartDashboard.putNumber("Wrist Angle", self.getAngle())
        #SmartDashboard.putNumber("Output", self.out)
        #self.F = SmartDashboard.getNumber("F Gain", 0)
        #self.wristUpVolts = SmartDashboard.getNumber("Wrist Up Volts", 0)
        #self.wristDownVolts = SmartDashboard.getNumber("Wrist Down Volts", 0)
        SmartDashboard.putBoolean("Limit Switch",
                                  self.wrist.isFwdLimitSwitchClosed())
        SmartDashboard.putBoolean("Limit Switch Reverse",
                                  self.wrist.isRevLimitSwitchClosed())
示例#7
0
class HatchMech(Subsystem):
    def __init__(self, Robot):
        #Create all physical parts used by subsystem.
        super().__init__('Hatch')
        #self.debug = True
        self.robot = Robot

    def initialize(self):
        #makes control objects
        self.xbox = oi.getJoystick(2)
        self.joystick0 = oi.getJoystick(0)
        self.joystick1 = oi.getJoystick(1)

        #makes solenoid objects to be used in kick and slide functions
        self.kicker = Solenoid(map.hatchKick)
        self.slider = Solenoid(map.hatchSlide)

        self.maxVolts = 10
        timeout = 0

        self.wheels = Talon(map.hatchWheels)
        self.wheels.setNeutralMode(2)
        self.wheels.configVoltageCompSaturation(self.maxVolts)

        self.wheels.configContinuousCurrentLimit(20,timeout) #20 Amps per motor
        self.wheels.configPeakCurrentLimit(30,timeout) #30 Amps during Peak Duration
        self.wheels.configPeakCurrentDuration(100,timeout) #Peak Current for max 100 ms
        self.wheels.enableCurrentLimit(True)
        self.wheels.setInverted(True)

        self.powerIn = 0.9
        self.powerOut = -0.9

        #sets kicker and slide solenoids to in
        self.kick("in")
        self.slide("in")

        #starts lastkick/slide booleans
        self.lastKick = False
        self.lastSlide = False

        self.hasHatch = False

        self.outPower = 0

    def periodic(self):
        self.updateHatch()

        self.currKick = self.xbox.getRawButton(map.kickHatch)
        self.currSlide = self.xbox.getRawButton(map.toggleHatch)

        #if the variable is true and it does not equal the lastkick/slide boolean, sets it to the opposite of what it currently is
        if self.currKick and (self.currKick != self.lastKick): self.kick("toggle")
        if self.currSlide and (self.currSlide != self.lastSlide): self.slide("toggle")

        #after the if statement, sets the lastkick/slide to the currkick/slide
        self.lastKick = self.currKick
        self.lastSlide = self.currSlide

        self.setWheels()

    # kick function to activate kicker solenoid
    def kick(self, mode):
        #out mode sets kicker solenoid to true
        if mode == "out": self.setKick(True)
        #in mode sets kicker solenoid to false
        elif mode == "in": self.setKick(False)
        #if neither of them, makes the kicker solenoid to the opposite of what it is
        else: self.setKick(not self.kicker.get())

    # slide function to activate slide solenoid
    def slide(self, mode):
        # out mode sets slider solenoid to true
        if mode == "out": self.slider.set(True)
        # in mode sets slider solenoid to false
        elif mode == "in": self.slider.set(False)
        #if neither of them, makes the slider solenoid to the opposite of what it is
        else: self.slider.set(not self.slider.get())

    def setKick(self, state):
        self.kicker.set(state)
        if state and self.slider.get() and self.hasHatch: self.hasHatch = False

    def setWheels(self):
        if self.kicker.get() and self.slider.get() and self.hasHatch:
            self.wheels.set(self.powerOut)
            self.outPower = self.powerOut
        elif not self.kicker.get() and self.slider.get() and not self.hasHatch:
            #should be "and not self.hasHatch"
            self.wheels.set(self.powerIn)
            self.outPower = self.powerIn
        #elif self.joystick1.getRawButton(1):
        #    self.wheels.set(self.powerIn)
        #    self.outPower = self.powerIn
        else:
            self.wheels.set(0)
            self.outPower = 0

    def updateHatch(self):
        #only checks current to possibly set false to true for hasHatch
        threshold = 10 #10 amp current separates freely spinning and stalled
        if self.slider.get() and self.wheels.getOutputCurrent()>threshold:
            self.hasHatch = True

        if self.joystick0.getRawButton(3) or self.joystick0.getRawButton(4) or self.joystick1.getRawButton(3) or self.joystick1.getRawButton(4):
            self.hasHatch = True

    #disable function runs kick function on in
    def disable(self): self.kick("in")

    def dashboardInit(self): pass

    def dashboardPeriodic(self):
        #commented out some values. DON'T DELETE THESE VALUES
        #SmartDashboard.putNumber("Hatch Current", self.wheels.getOutputCurrent())
        #SmartDashboard.putNumber("Power", self.outPower)
        SmartDashboard.putBoolean("Has Hatch", self.hasHatch)
        SmartDashboard.putBoolean("Slider Out", self.slider.get())
        SmartDashboard.putBoolean("Kicker Out", self.kicker.get())
示例#8
0
class CargoMech():
    kSlotIdx = 0
    kPIDLoopIdx = 0
    kTimeoutMs = 10

    def initialize(self):
        timeout = 15
        self.lastMode = "unknown"
        self.sb = []
        self.targetPosUp = -300 #!!!!!
        self.targetPosDown = -1500 #!!!!!
        self.maxVolts = 10
        self.simpleGain = 0.57
        self.wristUpVolts = 5
        self.wristDownVolts = 2
        self.simpleGainGravity = 0.07
        self.xbox = oi.getJoystick(2)
        self.joystick0 = oi.getJoystick(0)
        self.motor = Talon(map.intake)


        self.motor.configContinuousCurrentLimit(20,timeout) #15 Amps per motor
        self.motor.configPeakCurrentLimit(30,timeout) #20 Amps during Peak Duration
        self.motor.configPeakCurrentDuration(100,timeout) #Peak Current for max 100 ms
        self.motor.enableCurrentLimit(True)


        self.wrist = Talon(map.wrist)
        if not wpilib.RobotBase.isSimulation():
            self.wrist.configFactoryDefault()
        self.wrist.setInverted(True)
        self.wrist.setNeutralMode(2)
        self.motor.setNeutralMode(2)
        self.motor.configVoltageCompSaturation(self.maxVolts)
        self.intakeSpeed = 0.9

        self.wrist.configClearPositionOnLimitF(True)

        #MOTION MAGIC CONFIG
        self.loops = 0
        self.timesInMotionMagic = 0
      

        self.wrist.setSelectedSensorPosition(0, self.kPIDLoopIdx, self.kTimeoutMs)

    def intake(self, mode):
        ''' Intake/Outtake/Stop Intake the cargo (turn wheels inward)'''
        if mode == "intake": self.motor.set(self.intakeSpeed)
        elif mode == "outtake": self.motor.set(-1 * self.intakeSpeed)
        elif mode == "stop": self.motor.set(0)

    def moveWrist(self,mode):
        '''move wrist in and out of robot'''
        if mode == "up": self.wrist.set(self.getPowerSimple("up"))
        elif mode == "down": self.wrist.set(-1 * self.getPowerSimple("down"))
        elif mode == "upVolts": self.wrist.set(self.wristUpVolts/self.maxVolts)
        elif mode == "downVolts": self.wrist.set(-1 * self.wristDownVolts/ self.maxVolts)
        elif mode == "stop":
            self.wrist.set(0)
        else:
            self.wrist.set(self.getGravitySimple())

    def periodic(self):
        deadband = 0.4

        if self.xbox.getRawAxis(map.intakeCargo)>deadband: self.intake("intake")
        elif self.xbox.getRawAxis(map.outtakeCargo)>deadband: self.intake("outtake")
        else:
            self.intake("stop")

        if self.xbox.getRawButton(map.wristUp): self.moveWrist("up")
        elif self.xbox.getRawButton(map.wristDown): self.moveWrist("down")
        elif self.joystick0.getRawButton(map.wristUpVolts): self.moveWrist("upVolts")
        elif self.joystick0.getRawButton(map.wristDownVolts): self.moveWrist("downVolts")
        else:
            self.moveWrist("gravity")

    def disable(self): self.intake("stop")


    def getAngle(self):
        pos = self.getPosition()
        angle = abs(pos * 115/self.targetPosDown)
        return angle - 25

    def getPosition(self):
        return self.wrist.getQuadraturePosition()

    def getFeedForward(self, gain):
        angle = self.getAngle()
        return angle*gain

    def getPowerSimple(self, direction):
        '''true direction is up into robot
        false direction is down out of robot'''
        angle = self.getAngle()
        power = abs(self.simpleGainGravity * math.sin(math.radians(angle)) + self.simpleGain)
        if angle > 80:
            if direction == "down":
                power = 0
        if angle < -20:
            if direction == "up":
                power = 0
        return power

    def getGravitySimple(self):
        angle = self.getAngle()
        power =  self.simpleGainGravity * math.sin(math.radians(angle))
        return power

    def getNumber(self, key, defVal):
        val = SmartDashboard.getNumber(key, None)
        if val == None:
            val = defVal
            SmartDashboard.putNumber(key, val)
        return val

    def dashboardInit(self):
        pass

    def dashboardPeriodic(self):
        self.wristUp = self.getNumber("WristUpSpeed" , 0.5)
        self.wristDown = self.getNumber("WristDownSpeed" , 0.2)
        self.wristUpVolts = self.getNumber("WristUpVoltage" , 5)
        self.wristDownVolts = self.getNumber("WristDownVoltage" , 2)
        self.simpleGain = self.getNumber("Wrist Simple Gain", self.simpleGain)
        self.simpleGainGravity = self.getNumber("Wrist Simple Gain Gravity", self.simpleGainGravity)
        SmartDashboard.putNumber("Wrist Position", self.wrist.getQuadraturePosition())
        SmartDashboard.putNumber("Wrist Angle" , self.getAngle())
        SmartDashboard.putNumber("Wrist Power Up" , self.getPowerSimple("up"))
        SmartDashboard.putNumber("Wrist Power Down" , self.getPowerSimple("down"))
示例#9
0
class CargoMech():
    def initialize(self):
        timeout = 15
        self.wristPowerSet = 0
        SmartDashboard.putNumber("Wrist Power Set", self.wristPowerSet)

        self.maxVolts = 10
        self.wristUpVolts = 4
        self.wristDownVolts = -4

        self.xbox = oi.getJoystick(2)
        self.out = 0

        #below is the talon on the intake
        self.intake = Talon(map.intake)
        self.intake.setNeutralMode(2)
        self.intake.configVoltageCompSaturation(self.maxVolts)

        self.intake.configContinuousCurrentLimit(20,
                                                 timeout)  #20 Amps per motor
        self.intake.configPeakCurrentLimit(
            30, timeout)  #30 Amps during Peak Duration
        self.intake.configPeakCurrentDuration(
            100, timeout)  #Peak Current for max 100 ms
        self.intake.enableCurrentLimit(True)

        #Talon motor object created
        self.wrist = Talon(map.wrist)

        if not wpilib.RobotBase.isSimulation():
            self.wrist.configFactoryDefault()

        self.wrist.setInverted(True)

        self.wrist.configVoltageCompSaturation(self.maxVolts)
        self.wrist.setNeutralMode(2)

        self.wrist.configClearPositionOnLimitF(True)

        self.wrist.configContinuousCurrentLimit(20,
                                                timeout)  #20 Amps per motor
        self.wrist.configPeakCurrentLimit(
            30, timeout)  #30 Amps during Peak Duration
        self.wrist.configPeakCurrentDuration(
            100, timeout)  #Peak Current for max 100 ms
        self.wrist.enableCurrentLimit(True)

    def setIntake(self, mode):
        #Intake/Outtake/Stop, based on the mode it changes the speed of the motor
        if mode == "intake": self.intake.set(0.9)
        elif mode == "outtake": self.intake.set(-0.9)
        else: self.intake.set(0)

    def setWrist(self, mode):
        if mode == "up":
            self.out = self.wristUpVolts / self.maxVolts
        elif mode == "down":
            self.out = self.wristDownVolts / self.maxVolts
        else:
            self.out = 0
        self.setWristPower(self.out)

    def setWristPower(power):
        self.wrist.set(power)

    def periodic(self):
        if self.xbox.getRawAxis(map.intakeCargo) > 0.4:
            self.setIntake("intake")
        elif self.xbox.getRawAxis(map.outtakeCargo) > 0.4:
            self.setIntake("outtake")
        else:
            self.setIntake("stop")

        if self.xbox.getRawButton(map.wristUp): self.setWrist("up")
        elif self.xbox.getRawButton(map.wristDown): self.setWrist("down")
        else: self.setWrist("stop")

    #disables intake
    def disable(self):
        self.setIntake("stop")
        self.setWrist("stop")

    def dashboardInit(self):
        pass

    def dashboardPeriodic(self):
        SmartDashboard.putNumber("Cargomech Wrist Output", self.out)
        self.wristPowerSet = SmartDashboard.getNumber("Wrist Power Set", 0)
示例#10
0
class CargoMech():
    kSlotIdx = 0
    kPIDLoopIdx = 0
    kTimeoutMs = 10

    def initialize(self):
        timeout = 15
        self.lastMode = "unknown"
        self.sb = []
        self.targetPosUp = -300 #!!!!!
        self.targetPosDown = -1500 #!!!!!
        self.maxVolts = 10
        self.simpleGain = 0.1
        self.wristUpVolts = 5
        self.wristDownVolts = 2
        self.simpleGainGravity = 0.05
        self.xbox = oi.getJoystick(2)
        self.joystick0 = oi.getJoystick(0)
        self.motor = Talon(map.intake)


        self.motor.configContinuousCurrentLimit(20,timeout) #15 Amps per motor
        self.motor.configPeakCurrentLimit(30,timeout) #20 Amps during Peak Duration
        self.motor.configPeakCurrentDuration(100,timeout) #Peak Current for max 100 ms
        self.motor.enableCurrentLimit(True)


        self.wrist = Talon(map.wrist)
        if not wpilib.RobotBase.isSimulation():
            self.wrist.configFactoryDefault()
        self.wrist.setInverted(True)
        self.wrist.setNeutralMode(2)
        self.motor.setNeutralMode(2)
        self.motor.configVoltageCompSaturation(self.maxVolts)
        self.intakeSpeed = 0.9

        self.wrist.configClearPositionOnLimitF(True)

        #MOTION MAGIC CONFIG
        self.loops = 0
        self.timesInMotionMagic = 0
        #choose sensor
        self.wrist.configSelectedFeedbackSensor(
            Talon.FeedbackDevice.CTRE_MagEncoder_Relative,
            self.kPIDLoopIdx,
            self.kTimeoutMs,)
        self.wrist.setSensorPhase(False) #!!!!!

        # Set relevant frame periods to be at least as fast as periodic rate
        self.wrist.setStatusFramePeriod(
            Talon.StatusFrameEnhanced.Status_13_Base_PIDF0, 10, self.kTimeoutMs)
        self.wrist.setStatusFramePeriod(
            Talon.StatusFrameEnhanced.Status_10_MotionMagic, 10, self.kTimeoutMs)
        # set the peak and nominal outputs
        self.wrist.configNominalOutputForward(0, self.kTimeoutMs)
        self.wrist.configNominalOutputReverse(0, self.kTimeoutMs)
        self.wrist.configPeakOutputForward(0.6, self.kTimeoutMs)
        self.wrist.configPeakOutputReverse(-0.25, self.kTimeoutMs)

        self.kF = self.getFeedForward(self.getNumber("Wrist F Gain" , 0))
        self.kP = self.getNumber("Wrist kP" , 0)
        self.kI = self.getNumber("Wrist kI" , 0)
        self.kD = self.getNumber("Wrist kD" , 0)

        # set closed loop gains in slot0 - see documentation */
        self.wrist.selectProfileSlot(self.kSlotIdx, self.kPIDLoopIdx)
        self.wrist.config_kF(0, self.kF, self.kTimeoutMs)
        self.wrist.config_kP(0, self.kP, self.kTimeoutMs)
        self.wrist.config_kI(0, 0, self.kTimeoutMs)
        self.wrist.config_kD(0, 0, self.kTimeoutMs)
        # set acceleration and vcruise velocity - see documentation
        self.wrist.configMotionCruiseVelocity(400, self.kTimeoutMs) #!!!!!
        self.wrist.configMotionAcceleration(500, self.kTimeoutMs) #!!!!!
        # zero the sensor
        self.wrist.setSelectedSensorPosition(0, self.kPIDLoopIdx, self.kTimeoutMs)

    def intake(self, mode):
        ''' Intake/Outtake/Stop Intake the cargo (turn wheels inward)'''
        if mode == "intake": self.motor.set(self.intakeSpeed)
        elif mode == "outtake": self.motor.set(-1 * self.intakeSpeed)
        elif mode == "stop": self.motor.set(0)

    def moveWrist(self,mode):
        '''move wrist in and out of robot'''
        if mode == "up": self.wrist.set(self.getPowerSimple("up"))
        elif mode == "down": self.wrist.set(-1 * self.getPowerSimple("down"))
        elif mode == "upVolts": self.wrist.set(self.wristUpVolts/self.maxVolts)
        elif mode == "downVolts": self.wrist.set(-1 * self.wristDownVolts/ self.maxVolts)
        elif mode == "upMagic":

            if self.lastMode != mode:
                self.wrist.config_kF(0, self.kF, self.kTimeoutMs)
                self.wrist.config_kP(0, self.kP, self.kTimeoutMs)
                self.wrist.config_kI(0, 0, self.kTimeoutMs)
                self.wrist.config_kD(0, 0, self.kTimeoutMs)
            # Motion Magic - 4096 ticks/rev * 10 Rotations in either direction
            self.wrist.set(Talon.ControlMode.MotionMagic, self.targetPosUp)

            # append more signals to print when in speed mode.
            self.sb.append("\terr: %s" % self.wrist.getClosedLoopError(self.kPIDLoopIdx))
            self.sb.append("\ttrg: %.3f" % self.targetPosUp)

        elif mode == "downMagic":

            if self.lastMode != mode:
                self.wrist.config_kF(0, self.kF, self.kTimeoutMs)
                self.wrist.config_kP(0, self.kP, self.kTimeoutMs)
                self.wrist.config_kI(0, 0, self.kTimeoutMs)
                self.wrist.config_kD(0, 0, self.kTimeoutMs)
            # Motion Magic - 4096 ticks/rev * 10 Rotations in either direction
            self.wrist.set(Talon.ControlMode.MotionMagic, self.targetPosDown)

            # append more signals to print when in speed mode.
            self.sb.append("\terr: %s" % self.wrist.getClosedLoopError(self.kPIDLoopIdx))
            self.sb.append("\ttrg: %.3f" % self.targetPosDown)
        elif mode == "stop":
            self.wrist.set(0)
        else:
            self.wrist.set(self.getGravitySimple())

        self.lastMode = mode


    def periodic(self):
        deadband = 0.4

        if self.xbox.getRawAxis(map.intakeCargo)>deadband: self.intake("intake")
        elif self.xbox.getRawAxis(map.outtakeCargo)>deadband: self.intake("outtake")
        else:
            self.intake("stop")

        if self.xbox.getRawButton(map.wristUp): self.moveWrist("up")
        elif self.xbox.getRawButton(map.wristDown): self.moveWrist("down")
        elif self.joystick0.getRawButton(map.wristUpVolts): self.moveWrist("upVolts")
        elif self.joystick0.getRawButton(map.wristDownVolts): self.moveWrist("downVolts")
        elif self.joystick0.getRawButton(map.wristUpMagic): self.moveWrist("upMagic")
        elif self.joystick0.getRawButton(map.wristDownMagic): self.moveWrist("downMagic")
        else:
            self.moveWrist("gravity")

        # calculate the percent motor output
        motorOutput = self.wrist.getMotorOutputPercent()

        self.sb = []
        # prepare line to print
        self.sb.append("\tOut%%: %.3f" % motorOutput)
        self.sb.append("\tVel: %.3f" % self.wrist.getSelectedSensorVelocity(self.kPIDLoopIdx))

        # instrumentation
        self.processInstrumentation(self.wrist, self.sb)

    def disable(self): self.intake("stop")

    def processInstrumentation(self, tal, sb):
        # smart dash plots
        wpilib.SmartDashboard.putNumber("SensorVel", tal.getSelectedSensorVelocity(self.kPIDLoopIdx))
        wpilib.SmartDashboard.putNumber("SensorPos", tal.getSelectedSensorPosition(self.kPIDLoopIdx))
        wpilib.SmartDashboard.putNumber("MotorOutputPercent", tal.getMotorOutputPercent())
        wpilib.SmartDashboard.putNumber("ClosedLoopError", tal.getClosedLoopError(self.kPIDLoopIdx))

        # check if we are motion-magic-ing
        if tal.getControlMode() == Talon.ControlMode.MotionMagic:
            self.timesInMotionMagic += 1
        else:
            self.timesInMotionMagic = 0

        if self.timesInMotionMagic > 10:
            # print the Active Trajectory Point Motion Magic is servoing towards
            wpilib.SmartDashboard.putNumber(
                "ClosedLoopTarget", tal.getClosedLoopTarget(self.kPIDLoopIdx)
            )

        if not wpilib.RobotBase.isSimulation():
            wpilib.SmartDashboard.putNumber(
                "ActTrajVelocity", tal.getActiveTrajectoryVelocity()
            )
            wpilib.SmartDashboard.putNumber(
                "ActTrajPosition", tal.getActiveTrajectoryPosition()
            )
            wpilib.SmartDashboard.putNumber(
                "ActTrajHeading", tal.getActiveTrajectoryHeading()
            )

        # periodically print to console
        self.loops += 1
        if self.loops >= 10:
            self.loops = 0
            print(" ".join(self.sb))

        # clear line cache
        self.sb.clear()

    def getAngle(self):
        pos = self.getPosition()
        angle = abs(pos * 115/self.targetPosDown)
        return angle - 25

    def getPosition(self):
        return self.wrist.getQuadraturePosition()

    def getFeedForward(self, gain):
        angle = self.getAngle()
        return angle*gain

    def getPowerSimple(self, direction):
        '''true direction is up into robot
        false direction is down out of robot'''
        angle = self.getAngle()
        power = abs(self.simpleGainGravity * math.sin(math.radians(angle)) + self.simpleGain)
        if angle > 80:
            if direction == "down":
                power = 0
        if angle < -20:
            if direction == "up":
                power = 0
        return power

    def getGravitySimple(self):
        angle = self.getAngle()
        power =  self.simpleGainGravity * math.sin(math.radians(angle))
        return power

    def getNumber(self, key, defVal):
        val = SmartDashboard.getNumber(key, None)
        if val == None:
            val = defVal
            SmartDashboard.putNumber(key, val)
        return val

    def dashboardInit(self):
        pass

    def dashboardPeriodic(self):
        self.wristUp = self.getNumber("WristUpSpeed" , 0.5)
        self.wristDown = self.getNumber("WristDownSpeed" , 0.2)
        self.wristUpVolts = self.getNumber("WristUpVoltage" , 5)
        self.wristDownVolts = self.getNumber("WristDownVoltage" , 2)
        self.kF = self.getFeedForward(self.getNumber("Wrist F Gain" , 0))
        self.kP = self.getNumber("Wrist kP" , 0)
        self.kI = self.getNumber("Wrist kI" , 0)
        self.kD = self.getNumber("Wrist kD" , 0)
        self.simpleGain = self.getNumber("Wrist Simple Gain", 0.5)
        self.simpleGainGravity = self.getNumber("Wrist Simple Gain Gravity", 0.07)
        SmartDashboard.putNumber("Wrist Position", self.wrist.getQuadraturePosition())
        SmartDashboard.putNumber("Wrist Angle" , self.getAngle())
        SmartDashboard.putNumber("Wrist Power Up" , self.getPowerSimple("up"))
        SmartDashboard.putNumber("Wrist Power Down" , self.getPowerSimple("down"))
示例#11
0
class CargoMech():
    kSlotIdx = 0
    kPIDLoopIdx = 0
    kTimeoutMs = 10

    def initialize(self):
        timeout = 15
        SmartDashboard.putNumber("Wrist Power Set", 0)
        SmartDashboard.putNumber("Gravity Power", 0)
        self.sb = []
        self.targetPosUp = -300  #!!!!!
        self.targetPosDown = -1500  #!!!!!
        self.maxVolts = 10
        self.simpleGain = 0.57
        self.wristUpVolts = 5
        self.wristDownVolts = 2
        self.simpleGainGravity = 0.07
        self.xbox = oi.getJoystick(2)
        self.joystick0 = oi.getJoystick(0)
        #below is the talon on the intake
        self.motor = Talon(map.intake)

        self.input = 0
        self.input2 = 0
        self.lastCargoCommand = "unknown"

        self.motor.configContinuousCurrentLimit(20,
                                                timeout)  #15 Amps per motor
        self.motor.configPeakCurrentLimit(
            30, timeout)  #20 Amps during Peak Duration
        self.motor.configPeakCurrentDuration(
            100, timeout)  #Peak Current for max 100 ms
        self.motor.enableCurrentLimit(True)

        #Talon motor object created
        self.wrist = Talon(map.wrist)
        if not wpilib.RobotBase.isSimulation():
            self.wrist.configFactoryDefault()
        self.wrist.configVoltageCompSaturation(self.maxVolts)
        self.wrist.setInverted(True)
        self.wrist.setNeutralMode(2)
        self.motor.setNeutralMode(2)
        self.motor.configVoltageCompSaturation(self.maxVolts)

        self.wrist.configClearPositionOnLimitF(True)

        #MOTION MAGIC CONFIG
        self.loops = 0
        self.timesInMotionMagic = 0

        #self.wrist.setSelectedSensorPosition(0, self.kPIDLoopIdx, self.kTimeoutMs)

        self.F = 0
        #should be 0.4
        SmartDashboard.putNumber("F Gain", self.F)

        [self.kP, self.kI, self.kD, self.kF] = [0, 0, 0, 0]
        cargoController = PIDController(self.kP, self.kI, self.kD, self.kF,
                                        self, self)
        self.cargoController = cargoController
        self.cargoController.disable()

        self.pidValuesForMode = {
            "resting": [-50, self.kP, self.kI, self.kD, 0.15 / -50],
            "cargoship": [-28, self.kP, self.kI, self.kD, 0.0],
            "intake": [50, self.kP, self.kI, self.kD, 0.0],
            "rocket": [5, self.kP, self.kI, self.kD, 0.19 / 5],
        }

    def intake(self, mode):
        #Intake/Outtake/Stop, based on the mode it changes the speed of the motor
        if mode == "intake": self.motor.set(0.9)
        elif mode == "outtake": self.motor.set(-0.9)
        elif mode == "stop": self.motor.set(0)

    def pidWrite(self, output):
        maxPower = 0.3
        if output < -maxPower:
            output = -maxPower
        elif output > maxPower:
            output = maxPower
        self.wrist.set(output)
        self.input = output

    def pidGet(self):
        return self.getAngle()

    def setPIDSourceType(self):
        pass

    def getPIDSourceType(self):
        return 0

    def moveWrist(self, mode):
        if mode != self.lastCargoCommand:
            self.lastCargoCommand = mode
            if mode in self.pidValuesForMode:
                array = self.pidValuesForMode[mode]
                self.cargoController.setP(array[1])
                self.cargoController.setI(array[2])
                self.cargoController.setD(array[3])
                self.cargoController.setF(
                    math.sin(self.getAngle() / 180 * math.pi) * self.F)
                self.cargoController.setSetpoint(array[0])
                self.cargoController.enable()
            else:
                self.cargoController.disable()
        elif (mode not in self.pidValuesForMode):
            self.wrist.set(math.sin(self.getAngle() / 180 * math.pi) * self.F)
            self.input2 = math.sin(self.getAngle() / 180 * math.pi) * self.F

    def periodic(self):
        #0.4 as a deadband
        if self.xbox.getRawAxis(map.intakeCargo) > 0.4: self.intake("intake")
        elif self.xbox.getRawAxis(map.outtakeCargo) > 0.4:
            self.intake("outtake")
        else:
            self.intake("stop")

        if self.xbox.getPOV() == 0:
            self.moveWrist("resting")
            self.lastCargoCommand = "resting"
        elif self.xbox.getPOV() == 90:
            self.moveWrist("cargoship")
            self.lastCargoCommand = "cargoship"
        elif self.xbox.getPOV() == 180:
            self.moveWrist("intake")
            self.lastCargoCommand = "intake"
        elif self.xbox.getPOV() == 270:
            self.moveWrist("rocket")
            self.lastCargoCommand = "rocket"
        else:
            self.moveWrist(self.lastCargoCommand)

    #disables intake
    def disable(self):
        self.intake("stop")

    #gets the angle, used in other support functions
    def getAngle(self):
        pos = self.getPosition()
        angle = abs(pos * 115 / self.targetPosDown)
        return (angle - 20)

    def getPosition(self):
        return self.wrist.getQuadraturePosition()

    def getNumber(self, key, defVal):
        val = SmartDashboard.getNumber(key, None)
        if val == None:
            val = defVal
            SmartDashboard.putNumber(key, val)
        return val

    def dashboardInit(self):
        pass

    def dashboardPeriodic(self):
        #self.wristUp = self.getNumber("WristUpSpeed" , 0.5)
        #self.wristDown = self.getNumber("WristDownSpeed" , 0.2)
        #self.wristUpVolts = self.getNumber("WristUpVoltage" , 5)
        #self.wristDownVolts = self.getNumber("WristDownVoltage" , 2)
        #self.simpleGain = self.getNumber("Wrist Simple Gain", self.simpleGain)
        #self.simpleGainGravity = self.getNumber("Wrist Simple Gain Gravity", self.simpleGainGravity)
        SmartDashboard.putNumber("Wrist Position",
                                 self.wrist.getQuadraturePosition())
        SmartDashboard.putData("PID Controller", self.cargoController)
        SmartDashboard.putNumber("Wrist Angle", self.getAngle())
        SmartDashboard.putNumber("Wrist Power", self.input)
        SmartDashboard.putNumber("Wrist Power2", self.input2)
        SmartDashboard.putString("Last Cargo Command", self.lastCargoCommand)
        SmartDashboard.putBoolean("Wrist PinState Quad A",
                                  self.wrist.getPinStateQuadA())
        SmartDashboard.putBoolean("Wrist PinState Quad B",
                                  self.wrist.getPinStateQuadB())
        self.F = SmartDashboard.getNumber("F Gain", 0)