Ejemplo n.º 1
0
    def __init__(self, robot):
        super().__init__()
        self.robot = robot

        # Map the CIM motors to the TalonSRX's
        self.frontLeft = WPI_TalonSRX(DRIVETRAIN_FRONT_LEFT_MOTOR)
        self.leftTalon = WPI_TalonSRX(DRIVETRAIN_REAR_LEFT_MOTOR)
        self.frontRight = WPI_TalonSRX(DRIVETRAIN_FRONT_RIGHT_MOTOR)
        self.rightTalon = WPI_TalonSRX(DRIVETRAIN_REAR_RIGHT_MOTOR)

        # Set the front motors to be the followers of the rear motors
        self.frontLeft.set(WPI_TalonSRX.ControlMode.Follower,
                           DRIVETRAIN_REAR_LEFT_MOTOR)
        self.frontRight.set(WPI_TalonSRX.ControlMode.Follower,
                            DRIVETRAIN_REAR_RIGHT_MOTOR)

        # Add the motors to the speed controller groups and create the differential drivetrain
        self.leftDrive = SpeedControllerGroup(self.frontLeft, self.leftTalon)
        self.rightDrive = SpeedControllerGroup(self.frontRight,
                                               self.rightTalon)
        self.diffDrive = DifferentialDrive(self.leftDrive, self.rightDrive)

        # Setup the default motor controller setup
        self.initControllerSetup()

        # Map the pigeon.  This will be connected to an unused Talon.
        self.talonPigeon = WPI_TalonSRX(DRIVETRAIN_PIGEON)
        self.pigeonIMU = PigeonIMU(self.talonPigeon)
Ejemplo n.º 2
0
    def robotInit(self):
        # Note the lack of the camera server initialization here.

        # Initializing drive motors
        RLMotor = Spark(self.RLMotorChannel)
        RRMotor = Spark(self.RRMotorChannel)
        FLMotor = Spark(self.FLMotorChannel)
        FRMotor = Spark(self.FRMotorChannel)

        # Grouping drive motors into left and right.
        self.Left = SpeedControllerGroup(RLMotor, FLMotor)
        self.Right = SpeedControllerGroup(RRMotor, FRMotor)

        # Initializing drive Joystick.
        self.DriveStick = Joystick(self.DriveStickChannel)

        # Initializing drive function.
        self.drive = DifferentialDrive(self.Left, self.Right)

        # Sets the right side motors to be inverted.
        self.drive.setRightSideInverted(rightSideInverted=True)

        # Turns the drive off after .1 seconds of inactivity.
        self.drive.setExpiration(0.1)

        # Components is a dictionary that contains any variables you want to put into it. All of the variables put into
        # components dictionary is given to the autonomous modes.
        self.components = {"drive": self.drive}

        # Sets up the autonomous mode selector by telling it where the autonomous modes are at and what the autonomous
        # modes should inherit.
        self.automodes = autonomous.AutonomousModeSelector(
            "Sim_Autonomous", self.components)
Ejemplo n.º 3
0
    def __init__(self):
        left_rear_m = TalonSRX(1)
        self.left_front_m = TalonSRX(2)
        self.right_front_m = TalonSRX(0)
        right_rear_m = TalonSRX(2)

        left_drive = SpeedControllerGroup(self.left_front_m, left_rear_m)
        right_drive = SpeedControllerGroup(self.right_front_m, right_rear_m)

        self.robot_drive = DifferentialDrive(left_drive,right_drive)
Ejemplo n.º 4
0
class Robot(TimedRobot):
    def robotInit(self):
        # Right Motors
        self.RightMotor1 = WPI_TalonFX(1)
        self.RightSensor1 = SensorCollection(self.RightMotor1)
        self.RightMotor2 = WPI_TalonFX(2)
        self.RightMotor3 = WPI_TalonFX(3)
        self.rightDriveMotors = SpeedControllerGroup(self.RightMotor1,
                                                     self.RightMotor2,
                                                     self.RightMotor3)
        # Left Motors
        self.LeftMotor1 = WPI_TalonFX(4)
        self.LeftMotor2 = WPI_TalonFX(5)
        self.LeftMotor3 = WPI_TalonFX(6)
        self.leftDriveMotors = SpeedControllerGroup(self.LeftMotor1,
                                                    self.LeftMotor2,
                                                    self.LeftMotor3)
        
        # self.drive = DifferentialDrive(self.leftDriveMotors,
        #                               self.rightDriveMotors)

        self.testEncoder = Encoder(1, 2, 3, Encoder.EncodingType.k4X)

        self.dashboard = NetworkTables.getTable("SmartDashboard")

    def disabledInit(self):
        pass

    def autonomousInit(self):
        pass

    def teleopInit(self):
        pass

    def testInit(self):
        pass

    def robotPeriodic(self):
        self.dashboard.putNumber("Encoder", self.RightSensor1.getQuadratureVelocity()/2048*60)

    def disabledPeriodic(self):
        pass

    def autonomousPeriodic(self):
        speed = self.testEncoder.get() / 1028
        self.leftDriveMotors.set(speed)
        self.rightDriveMotors.set(speed)

    def teleopPeriodic(self):
        pass

    def testPeriodic(self):
        pass
Ejemplo n.º 5
0
    def __init__(self, controller: XboxController):
        super().__init__()

        frontLeftMotor, backLeftMotor = PWMVictorSPX(0), PWMVictorSPX(1)
        frontRightMotor, backRightMotor = PWMVictorSPX(2), PWMVictorSPX(3)

        self.leftMotors = SpeedControllerGroup(frontLeftMotor, backLeftMotor)

        self.rightMotors = SpeedControllerGroup(frontRightMotor,
                                                backRightMotor)

        self.drivetrain = DifferentialDrive(self.leftMotors, self.rightMotors)

        self.controller = controller
Ejemplo n.º 6
0
    def __init__(self):

        super().__init__()

        # Create the motor controllers and their respective speed controllers.
        self.leftMotors = SpeedControllerGroup(
            PWMSparkMax(constants.kLeftMotor1Port),
            PWMSparkMax(constants.kLeftMotor2Port),
        )

        self.rightMotors = SpeedControllerGroup(
            PWMSparkMax(constants.kRightMotor1Port),
            PWMSparkMax(constants.kRightMotor2Port),
        )

        # Create the differential drivetrain object, allowing for easy motor control.
        self.drive = DifferentialDrive(self.leftMotors, self.rightMotors)

        # Create the encoder objects.
        self.leftEncoder = Encoder(
            constants.kLeftEncoderPorts[0],
            constants.kLeftEncoderPorts[1],
            constants.kLeftEncoderReversed,
        )

        self.rightEncoder = Encoder(
            constants.kRightEncoderPorts[0],
            constants.kRightEncoderPorts[1],
            constants.kRightEncoderReversed,
        )

        # Configure the encoder so it knows how many encoder units are in one rotation.
        self.leftEncoder.setDistancePerPulse(
            constants.kEncoderDistancePerPulse)
        self.rightEncoder.setDistancePerPulse(
            constants.kEncoderDistancePerPulse)

        # Create the gyro, a sensor which can indicate the heading of the robot relative
        # to a customizable position.
        self.gyro = ADXRS450_Gyro()

        # Create the an object for our odometry, which will utilize sensor data to
        # keep a record of our position on the field.
        self.odometry = DifferentialDriveOdometry(self.gyro.getRotation2d())

        # Reset the encoders upon the initilization of the robot.
        self.resetEncoders()
Ejemplo n.º 7
0
    def __init__(self):
        super().__init__("Chassis")
        self.spark_L1 = Spark(robotmap.spark_L1)
        self.spark_L2 = Spark(robotmap.spark_L2)
        self.spark_R1 = Spark(robotmap.spark_R1)
        self.spark_R2 = Spark(robotmap.spark_R2)
        self.spark_group_L = SpeedControllerGroup(self.spark_L1, self.spark_L2)
        self.spark_group_R = SpeedControllerGroup(self.spark_R1, self.spark_R2)
        self.drive = DifferentialDrive(self.spark_group_L, self.spark_group_R)

        self.gyro = ADXRS450_Gyro(robotmap.gyro)

        self.encoder_L = Encoder(0, 1)
        self.encoder_R = Encoder(2, 3)

        self.dist_pulse_L = pi * 6 / 2048
        self.dist_pulse_R = pi * 6 / 425
Ejemplo n.º 8
0
    def __init__(self, robot):
        super().__init__("drivetrainsim")
        self.robot = robot
        self.counter = 0  # used for updating the log
        self.x, self.y = 0, 0

        # initialize sensors
        self.navx = navx.AHRS.create_spi()

        # initialize motors
        self.spark_neo_left_front = wpilib.Jaguar(1)
        self.spark_neo_left_rear = wpilib.Jaguar(2)
        self.spark_neo_right_front = wpilib.Jaguar(3)
        self.spark_neo_right_rear = wpilib.Jaguar(4)

        motor_type = rev.MotorType.kBrushless
        self.spark_neo_left_front1 = rev.CANSparkMax(1, motor_type)
        self.spark_neo_left_rear1 = rev.CANSparkMax(2, motor_type)
        self.spark_neo_right_front1 = rev.CANSparkMax(3, motor_type)
        self.spark_neo_right_rear1 = rev.CANSparkMax(4, motor_type)
        self.sparkneo_encoder_1 = rev.CANSparkMax.getEncoder(self.spark_neo_left_front1)
        self.sparkneo_encoder_2 = rev.CANSparkMax.getEncoder(self.spark_neo_left_rear1)
        self.sparkneo_encoder_3 = rev.CANSparkMax.getEncoder(self.spark_neo_right_front1)
        self.sparkneo_encoder_4 = rev.CANSparkMax.getEncoder(self.spark_neo_right_rear1)

        # create drivetrain from motors
        self.speedgroup_left = SpeedControllerGroup(self.spark_neo_left_front, self.spark_neo_left_rear)
        self.speedgroup_right = SpeedControllerGroup(self.spark_neo_right_front, self.spark_neo_right_rear)
        self.drive = wpilib.drive.DifferentialDrive(self.speedgroup_left, self.speedgroup_right)
        # self.drive = wpilib.drive.DifferentialDrive(self.spark_neo_left_front, self.spark_neo_right_front)
        self.drive.setMaxOutput(1.0)

        # initialize encoders - doing this after motors because they may be part of the motor controller
        self.l_encoder = wpilib.Encoder(0, 1, True)
        self.r_encoder = wpilib.Encoder(2, 3, True)
        self.l_encoder.setDistancePerPulse(drive_constants.k_encoder_distance_per_pulse_m)
        self.r_encoder.setDistancePerPulse(drive_constants.k_encoder_distance_per_pulse_m)

        # odometry for tracking the robot pose
        self.odometry = wpimath.kinematics.DifferentialDriveOdometry(geo.Rotation2d.fromDegrees( -self.navx.getAngle() ))
Ejemplo n.º 9
0
    def robotInit(self):
        # Right Motors
        self.RightMotor1 = WPI_TalonFX(1)
        self.RightMotor2 = WPI_TalonFX(2)
        self.RightMotor3 = WPI_TalonFX(3)
        self.rightDriveMotors = SpeedControllerGroup(self.RightMotor1,
                                                     self.RightMotor2,
                                                     self.RightMotor3)
        # Left Motors
        self.LeftMotor1 = WPI_TalonFX(4)
        self.LeftMotor2 = WPI_TalonFX(5)
        self.LeftMotor3 = WPI_TalonFX(6)
        self.leftDriveMotors = SpeedControllerGroup(self.LeftMotor1,
                                                    self.LeftMotor2,
                                                    self.LeftMotor3)

        self.drive = DifferentialDrive(self.leftDriveMotors,
                                       self.rightDriveMotors)

        self.testEncoder = Encoder(1, 2, 3)

        self.dashboard = NetworkTables.getTable("SmartDashboard")
Ejemplo n.º 10
0
    def __init__(self, robot, l_f_port=0, l_r_port=1, r_f_port=2, r_r_port=3):
        """
    Initialize ports for bot

    var naming scheme: (side)_(position)_(object), ex: l_f_port is left_front_port
    """
        super().__init__()
        self.robot = robot

        # Motors on Left Side
        self.l_f_motor = Spark(l_f_port)
        self.l_r_motor = Spark(l_r_port)

        # Motors on Right Side
        self.r_f_motor = Spark(r_f_port)
        self.r_r_motor = Spark(r_r_port)

        # Motor groups
        self.l_group = SpeedControllerGroup(self.l_f_motor, self.l_r_motor)
        self.r_group = SpeedControllerGroup(self.r_f_motor, self.r_r_motor)

        self.drive = DifferentialDrive(self.l_group, self.r_group)
Ejemplo n.º 11
0
    def __init__(self):
        left_front = WPI_TalonSRX(6)
        left_rear = WPI_TalonSRX(1)
        right_front = WPI_TalonSRX(4)
        right_rear = WPI_TalonSRX(7)

        left = SpeedControllerGroup(left_front, left_rear)
        right = SpeedControllerGroup(right_front, right_rear)

        self.left_encoder_motor = left_rear
        self.right_encoder_motor = right_front
        self.gear_solenoid = DoubleSolenoid(0, 1)
        self.driver_gyro = ADXRS450_Gyro()

        self.drive_train = DifferentialDrive(left, right)

        # setup encoders
        self.left_encoder_motor.setSensorPhase(True)
        self.drive_train.setDeadband(0.1)

        self.moving_linear = [0] * DriverComponent.LINEAR_SAMPLE_RATE
        self.moving_angular = [0] * DriverComponent.ANGULAR_SAMPLE_RATE
Ejemplo n.º 12
0
    def __init__(self,
                 timer: Timer,
                 left_motors: list,
                 right_motors: list,
                 control_system: int = ControlSystem.BASIC,
                 invert_left: bool = True,
                 invert_right: bool = False):
        self.CONTROL_SYSTEM = control_system

        self.timer = timer

        self.left_motors = left_motors
        self.right_motors = right_motors

        # Set control mode
        if self.CONTROL_SYSTEM == ControlSystem.BUILTIN:
            self.left_master = SpeedControllerGroup(*self.left_motors)
            self.right_master = SpeedControllerGroup(*self.right_motors)

            self.drivetrain = wpilib.drive.DifferentialDrive(
                self.left_master, self.right_master)

            self.drivetrain.setSafetyEnabled(True)
            self.drivetrain.tankDrive(0.0, 0.0)
            self.drivetrain.setExpiration(0.5)

        else:
            for motor in self.left_motors:
                motor: TalonSRX
                motor.setNeutralMode(NeutralMode.Brake)
                motor.set(motor.ControlMode.PercentOutput, 0.0)
                motor.setInverted(invert_left)

            for motor in self.right_motors:
                motor: TalonSRX
                motor.setNeutralMode(NeutralMode.Brake)
                motor.set(motor.ControlMode.PercentOutput, 0.0)
                motor.setInverted(invert_right)
Ejemplo n.º 13
0
  def robotInit(self):
    """ Initalizes all subsystems and user controls. """
    if self.numSubsystems > 0:
      # Create drive subsystems
      pwmOfs: int = 0
      if self.enableDrive:
        leftMotors = SpeedControllerGroup(wpilib.VictorSP(0), wpilib.VictorSP(1))
        rightMotors = SpeedControllerGroup(wpilib.VictorSP(2), wpilib.VictorSP(3))
        gamePad: GenericHID = XboxController(0)
        drive: Drive = Drive(99, leftMotors, rightMotors)
        drive.setDefaultCommand(DriveArcade(drive, leftMotors, rightMotors, gamePad))
        pwmOfs += 4

      for i in range(0, self.numSubsystems):
        pwm: int = pwmOfs + i * 2
        leftMotor: SpeedController = wpilib.VictorSP(pwm)
        rightMotor: SpeedController = wpilib.VictorSP(pwm + 1)
        drive = Drive(i, leftMotor, rightMotor)
        SmartDashboard.putData("Forward " + str(i), DrivePower(drive, 0.2, 0.2))
        SmartDashboard.putData("Backward " + str(i), DrivePower(drive, -0.2, -0.2))

    # Add command to dashboard to track time for one periodic pass
    self.performance = Performance()
    SmartDashboard.putData("Measure Performance", self.performance)
Ejemplo n.º 14
0
    def __init__(self, robot):
        super().__init__("drivetrain")
        self.robot = robot
        self.counter = 0  # used for updating the log
        self.x, self.y = 0, 0
        self.error_dict = {}

        # initialize sensors
        self.navx = navx.AHRS.create_spi()

        # initialize motors and encoders
        motor_type = rev.MotorType.kBrushless
        #self.spark_neo_left_front = rev.CANSparkMax(1, motor_type)
        #self.spark_neo_left_rear = rev.CANSparkMax(2, motor_type)
        #self.spark_neo_right_front = rev.CANSparkMax(3, motor_type)
        #self.spark_neo_right_rear = rev.CANSparkMax(4, motor_type)
        self.spark_neo_left_front = rev.CANSparkMax(4, motor_type)
        self.spark_neo_left_rear = rev.CANSparkMax(3, motor_type)
        self.spark_neo_right_front = rev.CANSparkMax(2, motor_type)
        self.spark_neo_right_rear = rev.CANSparkMax(1, motor_type)
        self.controllers = [
            self.spark_neo_left_front, self.spark_neo_left_rear,
            self.spark_neo_right_front, self.spark_neo_right_rear
        ]

        self.spark_PID_controller_right_front = self.spark_neo_right_front.getPIDController(
        )
        self.spark_PID_controller_right_rear = self.spark_neo_right_rear.getPIDController(
        )
        self.spark_PID_controller_left_front = self.spark_neo_left_front.getPIDController(
        )
        self.spark_PID_controller_left_rear = self.spark_neo_left_rear.getPIDController(
        )
        self.pid_controllers = [
            self.spark_PID_controller_left_front,
            self.spark_PID_controller_left_rear,
            self.spark_PID_controller_right_front,
            self.spark_PID_controller_right_rear
        ]

        # swap encoders to get sign right
        # changing them up for mecanum vs WCD
        self.sparkneo_encoder_1 = rev.CANSparkMax.getEncoder(
            self.spark_neo_left_front)
        self.sparkneo_encoder_2 = rev.CANSparkMax.getEncoder(
            self.spark_neo_left_rear)
        self.sparkneo_encoder_3 = rev.CANSparkMax.getEncoder(
            self.spark_neo_right_front)
        self.sparkneo_encoder_4 = rev.CANSparkMax.getEncoder(
            self.spark_neo_right_rear)
        self.encoders = [
            self.sparkneo_encoder_1, self.sparkneo_encoder_2,
            self.sparkneo_encoder_3, self.sparkneo_encoder_4
        ]
        # copy these so the sim and the real reference the same encoders
        self.l_encoder = self.sparkneo_encoder_1
        self.r_encoder = self.sparkneo_encoder_3
        # Configure encoders and controllers
        # should be wheel_diameter * pi / gear_ratio - and for the old double reduction gear box
        # the gear ratio was 4.17:1.  With the shifter (low gear) I think it was a 12.26.
        # the new 2020 gearbox is 9.52'
        #gear_ratio = 12.75
        #gear_ratio = 4.17  # pretty fast WCD gearbox
        #conversion_factor = 6.0 * 0.0254 * 3.1416 / gear_ratio  # do this in meters from now on
        conversion_factor = drive_constants.k_sparkmax_conversion_factor_meters
        for ix, encoder in enumerate(self.encoders):
            self.error_dict.update({
                'conv_pos_' + str(ix):
                encoder.setPositionConversionFactor(conversion_factor)
            })
            self.error_dict.update({
                'conv_vel_' + str(ix):
                encoder.setVelocityConversionFactor(conversion_factor / 60.0)
            })  # native is rpm
        burn_flash = False
        if burn_flash:
            for ix, controller in enumerate(self.controllers):
                self.error_dict.update(
                    {'burn_' + str(ix): controller.burnFlash()})

        # TODO - figure out if I want to invert the motors or the encoders
        #inverted = False  # needs this to be True for the toughbox
        #self.spark_neo_left_front.setInverted(inverted)  # inverting a controller
        #self.r_encoder.setInverted(True)  # inverting an encoder

        # create drivetrain from motors
        self.speedgroup_left = SpeedControllerGroup(self.spark_neo_left_front,
                                                    self.spark_neo_left_rear)
        self.speedgroup_right = SpeedControllerGroup(
            self.spark_neo_right_front, self.spark_neo_right_rear)
        self.drive = wpilib.drive.DifferentialDrive(self.speedgroup_left,
                                                    self.speedgroup_right)
        # self.drive = wpilib.drive.DifferentialDrive(self.spark_neo_left_front, self.spark_neo_right_front)
        self.drive.setMaxOutput(1.0)
        self.drive.setSafetyEnabled(True)
        self.drive.setExpiration(0.1)

        # odometry for tracking the robot pose
        self.odometry = wpimath.kinematics.DifferentialDriveOdometry(
            geo.Rotation2d.fromDegrees(-self.navx.getAngle()))
Ejemplo n.º 15
0
class Drivetrain(SubsystemBase):
    def __init__(self):

        super().__init__()

        # Create the motor controllers and their respective speed controllers.
        self.leftMotors = SpeedControllerGroup(
            PWMSparkMax(constants.kLeftMotor1Port),
            PWMSparkMax(constants.kLeftMotor2Port),
        )

        self.rightMotors = SpeedControllerGroup(
            PWMSparkMax(constants.kRightMotor1Port),
            PWMSparkMax(constants.kRightMotor2Port),
        )

        # Create the differential drivetrain object, allowing for easy motor control.
        self.drive = DifferentialDrive(self.leftMotors, self.rightMotors)

        # Create the encoder objects.
        self.leftEncoder = Encoder(
            constants.kLeftEncoderPorts[0],
            constants.kLeftEncoderPorts[1],
            constants.kLeftEncoderReversed,
        )

        self.rightEncoder = Encoder(
            constants.kRightEncoderPorts[0],
            constants.kRightEncoderPorts[1],
            constants.kRightEncoderReversed,
        )

        # Configure the encoder so it knows how many encoder units are in one rotation.
        self.leftEncoder.setDistancePerPulse(
            constants.kEncoderDistancePerPulse)
        self.rightEncoder.setDistancePerPulse(
            constants.kEncoderDistancePerPulse)

        # Create the gyro, a sensor which can indicate the heading of the robot relative
        # to a customizable position.
        self.gyro = ADXRS450_Gyro()

        # Create the an object for our odometry, which will utilize sensor data to
        # keep a record of our position on the field.
        self.odometry = DifferentialDriveOdometry(self.gyro.getRotation2d())

        # Reset the encoders upon the initilization of the robot.
        self.resetEncoders()

    def periodic(self):
        """
        Called periodically when it can be called. Updates the robot's
        odometry with sensor data.
        """
        self.odometry.update(
            self.gyro.getRotation2d(),
            self.leftEncoder.getDistance(),
            self.rightEncoder.getDistance(),
        )

    def getPose(self):
        """Returns the current position of the robot using it's odometry."""
        return self.odometry.getPose()

    def getWheelSpeeds(self):
        """Return an object which represents the wheel speeds of our drivetrain."""
        speeds = DifferentialDriveWheelSpeeds(self.leftEncoder.getRate(),
                                              self.rightEncoder.getRate())
        return speeds

    def resetOdometry(self, pose):
        """ Resets the robot's odometry to a given position."""
        self.resetEncoders()
        self.odometry.resetPosition(pose, self.gyro.getRotation2d())

    def arcadeDrive(self, fwd, rot):
        """Drive the robot with standard arcade controls."""
        self.drive.arcadeDrive(fwd, rot)

    def tankDriveVolts(self, leftVolts, rightVolts):
        """Control the robot's drivetrain with voltage inputs for each side."""
        # Set the voltage of the left side.
        self.leftMotors.setVoltage(leftVolts)

        # Set the voltage of the right side. It's
        # inverted with a negative sign because it's motors need to spin in the negative direction
        # to move forward.
        self.rightMotors.setVoltage(-rightVolts)

        # Resets the timer for this motor's MotorSafety
        self.drive.feed()

    def resetEncoders(self):
        """Resets the encoders of the drivetrain."""
        self.leftEncoder.reset()
        self.rightEncoder.reset()

    def getAverageEncoderDistance(self):
        """
        Take the sum of each encoder's traversed distance and divide it by two,
        since we have two encoder values, to find the average value of the two.
        """
        return (self.leftEncoder.getDistance() +
                self.rightEncoder.getDistance()) / 2

    def getLeftEncoder(self):
        """Returns the left encoder object."""
        return self.leftEncoder

    def getRightEncoder(self):
        """Returns the right encoder object."""
        return self.rightEncoder

    def setMaxOutput(self, maxOutput):
        """Set the max percent output of the drivetrain, allowing for slower control."""
        self.drive.setMaxOutput(maxOutput)

    def zeroHeading(self):
        """Zeroes the gyro's heading."""
        self.gyro.reset()

    def getHeading(self):
        """Return the current heading of the robot."""
        return self.gyro.getRotation2d().getDegrees()

    def getTurnRate(self):
        """Returns the turning rate of the robot using the gyro."""

        # The minus sign negates the value.
        return -self.gyro.getRate()
Ejemplo n.º 16
0
class Intake(Subsystem):
    def __init__(self):
        super().__init__("Intake")
        self.talon_1 = WPI_TalonSRX(robotmap.talon_intake_1)
        self.talon_2 = WPI_TalonSRX(robotmap.talon_intake_2)
        self.talon_group = SpeedControllerGroup(self.talon_1, self.talon_2)

    @classmethod
    def setSpd(cls, spd_new):
        robotmap.spd_intake = spd_new

    def intake(self, spd_temp=None, is_fixed=None):
        self.talon_1.setInverted(True)
        self.talon_2.setInverted(False)
        if (spd_temp is None) and (is_fixed is None):
            if oi.joystick.getAxis(2) - oi.joystick.getAxis(3) >= 0.8:
                self.talon_group.set(0.8)
            elif oi.joystick.getAxis(2) - oi.joystick.getAxis(3) < 0.8:
                self.talon_group.set(
                    oi.joystick.getAxis(2) - oi.joystick.getAxis(3))
        elif (spd_temp is not None) and (is_fixed is None):
            self.talon_group.set(spd_temp)
        elif (spd_temp is not None) and (is_fixed is not None):
            self.talon_group.set(robotmap.spd_intake)
        else:
            raise ("intake() fail!")

    def eject(self, spd_temp=None, is_fixed=None):
        self.talon_1.setInverted(False)
        self.talon_2.setInverted(True)
        if (spd_temp is None) and (is_fixed is None):
            self.talon_group.set(oi.joystick.getAxis(3))
        elif (spd_temp is not None) and (is_fixed is None):
            self.talon_group.set(spd_temp)
        elif (spd_temp is not None) and (is_fixed is not None):
            self.talon_group.set(robotmap.spd_intake)
        else:
            raise ("eject() fail!")

    def dislodge(self):
        self.eject(True)
        time.sleep(0.1)
        self.intake(True)
        time.sleep(0.2)

    def stop(self):
        self.talon_group.stopMotor()

    def initDefaultCommand(self):
        pass
Ejemplo n.º 17
0
class DriveTrainSim(Subsystem):
    # ----------------- INITIALIZATION -----------------------
    def __init__(self, robot):
        super().__init__("drivetrainsim")
        self.robot = robot
        self.counter = 0  # used for updating the log
        self.x, self.y = 0, 0

        # initialize sensors
        self.navx = navx.AHRS.create_spi()

        # initialize motors
        self.spark_neo_left_front = wpilib.Jaguar(1)
        self.spark_neo_left_rear = wpilib.Jaguar(2)
        self.spark_neo_right_front = wpilib.Jaguar(3)
        self.spark_neo_right_rear = wpilib.Jaguar(4)

        motor_type = rev.MotorType.kBrushless
        self.spark_neo_left_front1 = rev.CANSparkMax(1, motor_type)
        self.spark_neo_left_rear1 = rev.CANSparkMax(2, motor_type)
        self.spark_neo_right_front1 = rev.CANSparkMax(3, motor_type)
        self.spark_neo_right_rear1 = rev.CANSparkMax(4, motor_type)
        self.sparkneo_encoder_1 = rev.CANSparkMax.getEncoder(self.spark_neo_left_front1)
        self.sparkneo_encoder_2 = rev.CANSparkMax.getEncoder(self.spark_neo_left_rear1)
        self.sparkneo_encoder_3 = rev.CANSparkMax.getEncoder(self.spark_neo_right_front1)
        self.sparkneo_encoder_4 = rev.CANSparkMax.getEncoder(self.spark_neo_right_rear1)

        # create drivetrain from motors
        self.speedgroup_left = SpeedControllerGroup(self.spark_neo_left_front, self.spark_neo_left_rear)
        self.speedgroup_right = SpeedControllerGroup(self.spark_neo_right_front, self.spark_neo_right_rear)
        self.drive = wpilib.drive.DifferentialDrive(self.speedgroup_left, self.speedgroup_right)
        # self.drive = wpilib.drive.DifferentialDrive(self.spark_neo_left_front, self.spark_neo_right_front)
        self.drive.setMaxOutput(1.0)

        # initialize encoders - doing this after motors because they may be part of the motor controller
        self.l_encoder = wpilib.Encoder(0, 1, True)
        self.r_encoder = wpilib.Encoder(2, 3, True)
        self.l_encoder.setDistancePerPulse(drive_constants.k_encoder_distance_per_pulse_m)
        self.r_encoder.setDistancePerPulse(drive_constants.k_encoder_distance_per_pulse_m)

        # odometry for tracking the robot pose
        self.odometry = wpimath.kinematics.DifferentialDriveOdometry(geo.Rotation2d.fromDegrees( -self.navx.getAngle() ))

    def initDefaultCommand(self):
        """ When other commands aren't using the drivetrain, allow arcade drive with the joystick. """
        self.setDefaultCommand(DriveByJoystick(self.robot))

    # ----------------- DRIVE METHODS -----------------------
    def arcade_drive(self, thrust, twist):
        """ wrapper for the current drive mode, really should just be called drive or move """
        self.drive.arcadeDrive(xSpeed=thrust, zRotation=twist, squareInputs=True)

    def stop(self):
        """ stop the robot """
        self.drive.arcadeDrive(xSpeed=0, zRotation=0, squareInputs=True)

    # ----------------- SIMULATION AND TELEMETRY METHODS -----------------------
    def get_pose(self):
        # return self.odometry.getPoseMeters() # 2021 only?
        return self.odometry.getPose()

    def get_wheel_speeds(self):
        return wpimath.kinematics.DifferentialDriveWheelSpeeds(self.l_encoder.getRate(), self.r_encoder.getRate())

    def reset_encoders(self):
        self.l_encoder.reset()
        self.r_encoder.reset()

    def get_rate(self, encoder): # spark maxes and regular encoders use different calls... annoying
        return encoder.getRate()
    def get_position(self, encoder):
        return encoder.getDistance()
    def set_position(self, encoder, position):
        encoder.setDistance(position)

    def reset_odometry(self, pose):
        self.reset_encoders()
        self.odometry.resetPosition(pose, geo.Rotation2d.fromDegrees(-self.navx.getAngle()))

    def tank_drive_volts(self, left_volts, right_volts):
        self.speedgroup_left.setVoltage(left_volts)
        self.speedgroup_right.setVoltage(right_volts)
        self.drive.feed()

    def get_rotation2d(self):
        return geo.Rotation2d.fromDegrees(-self.navx.getAngle())

    def get_average_encoder_distance(self):
        return (self.l_encoder.getDistance() - self.r_encoder.getDistance())/2  #  used in PID drive straight

    def get_average_encoder_rate(self):
        return (self.l_encoder.getRate() + self.r_encoder.getRate())/2

    def zero_heading(self):
        self.navx.reset()

    def reset(self):
        pass

    def periodic(self) -> None:
        """Perform odometry and update dash with telemetry"""
        self.counter += 1
        self.odometry.update(geo.Rotation2d.fromDegrees(-self.navx.getAngle()), self.l_encoder.getDistance(), -self.r_encoder.getDistance())

        if self.counter % 10 == 0:
            # start keeping track of where the robot is with an x and y position (only good for WCD)'
            pose = self.get_pose()
            SmartDashboard.putString('drive_pose', f'[{pose.X():2.2f}, {pose.Y():2.2f}, {pose.rotation().degrees():2.2f}]' )

        if self.counter % 100 == 0:
            pass
Ejemplo n.º 18
0
    def __init__(self, robot):
        super().__init__("drivetrain")
        #Subsystem.__init__("drivetrain")
        self.robot = robot
        self.error_dict = {}
        # Add constants and helper variables
        self.twist_power_maximum = 0.5
        self.strafe_power_maximum = 0.5
        self.thrust_power_maximum = 0.5
        self.mecanum_power_limit = 1.0
        self.max_velocity = 500  # rpm for mecanum velocity

        self.current_thrust = 0
        self.current_twist = 0
        self.current_strafe = 0
        self.acceleration_limit = 0.05
        self.counter = 0

        # due to limitations in displaying digits in the Shuffleboard, we'll multiply these by 1000 and divide when updating the controllers
        self.PID_multiplier = 1000.
        self.PID_dict_pos = {
            'kP': 0.010,
            'kI': 5.0e-7,
            'kD': 0.40,
            'kIz': 0,
            'kFF': 0.002,
            'kMaxOutput': 0.99,
            'kMinOutput': -0.99
        }
        self.PID_dict_vel = {
            'kP': 2 * 0.00015,
            'kI': 1.5 * 8.0e-7,
            'kD': 0.00,
            'kIz': 0,
            'kFF': 0.00022,
            'kMaxOutput': 0.99,
            'kMinOutput': -0.99
        }
        self.encoder_offsets = [
            0, 0, 0, 0
        ]  # added because the encoders do not reset fast enough for autonomous

        # Smart Motion Coefficients - these don't seem to be writing for some reason... python is old?  just set with rev's program for now
        self.smartmotion_maxvel = 1000  # rpm
        self.smartmotion_maxacc = 500
        self.current_limit = 100
        self.ramp_rate = 0.0
        # tracking the robot across the field... easier with WCD
        self.x = 0
        self.y = 0
        self.previous_distance = 0
        self.is_limited = False
        self.deadband = 0.05

        # Configure drive motors
        #if True:  # or could be if self.robot.isReal():
        if self.robot.isReal():
            motor_type = rev.MotorType.kBrushless
            self.spark_neo_right_front = rev.CANSparkMax(1, motor_type)
            self.spark_neo_right_rear = rev.CANSparkMax(2, motor_type)
            self.spark_neo_left_front = rev.CANSparkMax(3, motor_type)
            self.spark_neo_left_rear = rev.CANSparkMax(4, motor_type)
            self.controllers = [
                self.spark_neo_left_front, self.spark_neo_left_rear,
                self.spark_neo_right_front, self.spark_neo_right_rear
            ]

            self.spark_PID_controller_right_front = self.spark_neo_right_front.getPIDController(
            )
            self.spark_PID_controller_right_rear = self.spark_neo_right_rear.getPIDController(
            )
            self.spark_PID_controller_left_front = self.spark_neo_left_front.getPIDController(
            )
            self.spark_PID_controller_left_rear = self.spark_neo_left_rear.getPIDController(
            )
            self.pid_controllers = [
                self.spark_PID_controller_left_front,
                self.spark_PID_controller_left_rear,
                self.spark_PID_controller_right_front,
                self.spark_PID_controller_right_rear
            ]
            # wpilib.Timer.delay(0.02)

            # swap encoders to get sign right
            # changing them up for mechanum vs WCD
            self.sparkneo_encoder_1 = rev.CANSparkMax.getEncoder(
                self.spark_neo_left_front)
            self.sparkneo_encoder_2 = rev.CANSparkMax.getEncoder(
                self.spark_neo_left_rear)
            self.sparkneo_encoder_3 = rev.CANSparkMax.getEncoder(
                self.spark_neo_right_front)
            self.sparkneo_encoder_4 = rev.CANSparkMax.getEncoder(
                self.spark_neo_right_rear)
            self.encoders = [
                self.sparkneo_encoder_1, self.sparkneo_encoder_2,
                self.sparkneo_encoder_3, self.sparkneo_encoder_4
            ]

            # Configure encoders and controllers
            # should be wheel_diameter * pi / gear_ratio - and for the old double reduction gear box
            # the gear ratio was 4.17:1.  With the shifter (low gear) I think it was a 12.26.
            # then new 2020 gearbox is 9.52
            gear_ratio = 9.52
            #gear_ratio = 12.75
            conversion_factor = 8.0 * 3.141 / gear_ratio
            for ix, encoder in enumerate(self.encoders):
                self.error_dict.update({
                    'conv_' + str(ix):
                    encoder.setPositionConversionFactor(conversion_factor)
                })

            # wpilib.Timer.delay(0.02)
            # TODO - figure out if I want to invert the motors or the encoders
            inverted = False  # needs this to be True for the toughbox
            self.spark_neo_left_front.setInverted(inverted)
            self.spark_neo_left_rear.setInverted(inverted)
            self.spark_neo_right_front.setInverted(inverted)
            self.spark_neo_right_rear.setInverted(inverted)

            self.configure_controllers()
            #self.display_PIDs()

        else:  # for simulation only, but the CANSpark is getting closer to behaving in sim
            # get a pretend drivetrain for the simulator
            self.spark_neo_left_front = wpilib.Talon(1)
            self.spark_neo_left_rear = wpilib.Talon(2)
            self.spark_neo_right_front = wpilib.Talon(3)
            self.spark_neo_right_rear = wpilib.Talon(4)

        # Not sure if speedcontrollergroups work with the single sparkmax in python - seems to complain
        # drive_type = 'mechanum'  # comp bot
        drive_type = 'wcd'  # practice bot, sim as of 1/16/2021

        if drive_type == 'wcd':
            # WCD
            print("Enabling WCD drive!")
            if robot.isReal():
                err_1 = self.spark_neo_left_rear.follow(
                    self.spark_neo_left_front)
                err_2 = self.spark_neo_right_rear.follow(
                    self.spark_neo_right_front)
                if err_1 != rev.CANError.kOk or err_2 != rev.CANError.kOk:
                    print(
                        f"Warning: drivetrain follower issue with neo2 returning {err_1} and neo4 returning {err_2}"
                    )
            self.speedgroup_left = SpeedControllerGroup(
                self.spark_neo_left_front)
            self.speedgroup_right = SpeedControllerGroup(
                self.spark_neo_right_front)
            self.differential_drive = DifferentialDrive(
                self.speedgroup_left, self.speedgroup_right)
            self.drive = self.differential_drive
            self.differential_drive.setMaxOutput(1.0)
        if drive_type == 'mechanum':
            # Mechanum
            # TODO: Reset followers in software
            print("Enabling mechanum drive!")
            self.speedgroup_lfront = SpeedControllerGroup(
                self.spark_neo_left_front)
            self.speedgroup_lrear = SpeedControllerGroup(
                self.spark_neo_left_rear)
            self.speedgroup_rfront = SpeedControllerGroup(
                self.spark_neo_right_front)
            self.speedgroup_rrear = SpeedControllerGroup(
                self.spark_neo_right_rear)
            self.mechanum_drive = MecanumDrive(self.speedgroup_lfront,
                                               self.speedgroup_lrear,
                                               self.speedgroup_rfront,
                                               self.speedgroup_rrear)
            # self.mechanum_drive = MecanumDrive(self.spark_neo_left_front, self.spark_neo_left_rear, self.spark_neo_right_front, self.spark_neo_right_rear)
            self.mechanum_drive.setMaxOutput(self.mecanum_power_limit)
            self.drive = self.mechanum_drive

        self.drive.setSafetyEnabled(True)
        self.drive.setExpiration(0.1)
Ejemplo n.º 19
0
class DriveTrain(Subsystem):
    # ----------------- INITIALIZATION -----------------------
    def __init__(self, robot):
        super().__init__("drivetrain")
        self.robot = robot
        self.counter = 0  # used for updating the log
        self.x, self.y = 0, 0
        self.error_dict = {}

        # initialize sensors
        self.navx = navx.AHRS.create_spi()

        # initialize motors and encoders
        motor_type = rev.MotorType.kBrushless
        #self.spark_neo_left_front = rev.CANSparkMax(1, motor_type)
        #self.spark_neo_left_rear = rev.CANSparkMax(2, motor_type)
        #self.spark_neo_right_front = rev.CANSparkMax(3, motor_type)
        #self.spark_neo_right_rear = rev.CANSparkMax(4, motor_type)
        self.spark_neo_left_front = rev.CANSparkMax(4, motor_type)
        self.spark_neo_left_rear = rev.CANSparkMax(3, motor_type)
        self.spark_neo_right_front = rev.CANSparkMax(2, motor_type)
        self.spark_neo_right_rear = rev.CANSparkMax(1, motor_type)
        self.controllers = [
            self.spark_neo_left_front, self.spark_neo_left_rear,
            self.spark_neo_right_front, self.spark_neo_right_rear
        ]

        self.spark_PID_controller_right_front = self.spark_neo_right_front.getPIDController(
        )
        self.spark_PID_controller_right_rear = self.spark_neo_right_rear.getPIDController(
        )
        self.spark_PID_controller_left_front = self.spark_neo_left_front.getPIDController(
        )
        self.spark_PID_controller_left_rear = self.spark_neo_left_rear.getPIDController(
        )
        self.pid_controllers = [
            self.spark_PID_controller_left_front,
            self.spark_PID_controller_left_rear,
            self.spark_PID_controller_right_front,
            self.spark_PID_controller_right_rear
        ]

        # swap encoders to get sign right
        # changing them up for mecanum vs WCD
        self.sparkneo_encoder_1 = rev.CANSparkMax.getEncoder(
            self.spark_neo_left_front)
        self.sparkneo_encoder_2 = rev.CANSparkMax.getEncoder(
            self.spark_neo_left_rear)
        self.sparkneo_encoder_3 = rev.CANSparkMax.getEncoder(
            self.spark_neo_right_front)
        self.sparkneo_encoder_4 = rev.CANSparkMax.getEncoder(
            self.spark_neo_right_rear)
        self.encoders = [
            self.sparkneo_encoder_1, self.sparkneo_encoder_2,
            self.sparkneo_encoder_3, self.sparkneo_encoder_4
        ]
        # copy these so the sim and the real reference the same encoders
        self.l_encoder = self.sparkneo_encoder_1
        self.r_encoder = self.sparkneo_encoder_3
        # Configure encoders and controllers
        # should be wheel_diameter * pi / gear_ratio - and for the old double reduction gear box
        # the gear ratio was 4.17:1.  With the shifter (low gear) I think it was a 12.26.
        # the new 2020 gearbox is 9.52'
        #gear_ratio = 12.75
        #gear_ratio = 4.17  # pretty fast WCD gearbox
        #conversion_factor = 6.0 * 0.0254 * 3.1416 / gear_ratio  # do this in meters from now on
        conversion_factor = drive_constants.k_sparkmax_conversion_factor_meters
        for ix, encoder in enumerate(self.encoders):
            self.error_dict.update({
                'conv_pos_' + str(ix):
                encoder.setPositionConversionFactor(conversion_factor)
            })
            self.error_dict.update({
                'conv_vel_' + str(ix):
                encoder.setVelocityConversionFactor(conversion_factor / 60.0)
            })  # native is rpm
        burn_flash = False
        if burn_flash:
            for ix, controller in enumerate(self.controllers):
                self.error_dict.update(
                    {'burn_' + str(ix): controller.burnFlash()})

        # TODO - figure out if I want to invert the motors or the encoders
        #inverted = False  # needs this to be True for the toughbox
        #self.spark_neo_left_front.setInverted(inverted)  # inverting a controller
        #self.r_encoder.setInverted(True)  # inverting an encoder

        # create drivetrain from motors
        self.speedgroup_left = SpeedControllerGroup(self.spark_neo_left_front,
                                                    self.spark_neo_left_rear)
        self.speedgroup_right = SpeedControllerGroup(
            self.spark_neo_right_front, self.spark_neo_right_rear)
        self.drive = wpilib.drive.DifferentialDrive(self.speedgroup_left,
                                                    self.speedgroup_right)
        # self.drive = wpilib.drive.DifferentialDrive(self.spark_neo_left_front, self.spark_neo_right_front)
        self.drive.setMaxOutput(1.0)
        self.drive.setSafetyEnabled(True)
        self.drive.setExpiration(0.1)

        # odometry for tracking the robot pose
        self.odometry = wpimath.kinematics.DifferentialDriveOdometry(
            geo.Rotation2d.fromDegrees(-self.navx.getAngle()))

    def initDefaultCommand(self):
        """ When other commands aren't using the drivetrain, allow arcade drive with the joystick. """
        self.setDefaultCommand(DriveByJoystick(self.robot))

    # ----------------- DRIVE METHODS -----------------------
    def arcade_drive(self, thrust, twist):
        """ wrapper for the current drive mode, really should just be called drive or move """
        self.drive.arcadeDrive(xSpeed=thrust,
                               zRotation=twist,
                               squareInputs=True)
        #[controller.setVoltage(thrust) for controller in self.controllers]
        #self.drive.feed()

    def stop(self):
        """ stop the robot """
        self.drive.arcadeDrive(xSpeed=0, zRotation=0, squareInputs=True)

    # ----------------- SIMULATION AND TELEMETRY METHODS -----------------------
    def get_pose(self):
        # return self.odometry.getPoseMeters() # 2021 only?
        return self.odometry.getPose()

    def get_wheel_speeds(self):
        return wpimath.kinematics.DifferentialDriveWheelSpeeds(
            self.l_encoder.getVelocity(), self.r_encoder.getVelocity())

    def reset_encoders(self):
        self.l_encoder.setPosition(0)
        self.r_encoder.setPosition(0)

    def get_rate(
        self, encoder
    ):  # spark maxes and regular encoders use different calls... annoying
        return encoder.getVelocity()

    def get_position(self, encoder):
        return encoder.getPosition()

    def set_position(self, encoder, position):
        encoder.setPosition(position)

    def reset_odometry(self, pose):
        self.reset_encoders()
        self.odometry.resetPosition(
            pose, geo.Rotation2d.fromDegrees(-self.navx.getAngle()))

    def tank_drive_volts(self, left_volts, right_volts):
        self.speedgroup_left.setVoltage(left_volts)
        self.speedgroup_right.setVoltage(right_volts)
        self.drive.feed()

    def get_rotation2d(self):
        return geo.Rotation2d.fromDegrees(-self.navx.getAngle())

    def get_average_encoder_distance(self):
        return (self.l_encoder.getPosition() -
                self.r_encoder.getPosition()) / 2

    def get_average_encoder_rate(self):
        return (self.l_encoder.getVelocity() +
                self.r_encoder.getVelocity()) / 2

    def zero_heading(self):
        self.navx.reset()

    def reset(self):
        self.zero_heading()
        self.reset_encoders()

    def periodic(self) -> None:
        """Perform odometry and update dash with telemetry"""
        self.counter += 1
        self.odometry.update(geo.Rotation2d.fromDegrees(-self.navx.getAngle()),
                             self.l_encoder.getPosition(),
                             -self.r_encoder.getPosition())

        if self.counter % 10 == 0:
            # start keeping track of where the robot is with an x and y position (only good for WCD)'
            pose = self.get_pose()
            SmartDashboard.putString(
                'drive_pose',
                f'[{pose.X():2.2f}, {pose.Y():2.2f}, {pose.rotation().degrees():2.2f}]'
            )
            SmartDashboard.putString(
                'drive_encoders LR',
                f'[{self.get_position(self.l_encoder):2.3f}, {self.get_position(self.r_encoder):2.2f}]'
            )
            SmartDashboard.putString('drive_heading',
                                     f'[{-self.navx.getAngle():2.3f}]')

        if self.counter % 100 == 0:
            pass
            # self.display_PIDs()
            msg = f"Positions: ({self.l_encoder.getPosition():2.2f}, {self.r_encoder.getPosition():2.2}, {self.navx.getAngle():2.2})"
            msg = msg + f" Rates: ({self.l_encoder.getVelocity():2.2f}, {self.r_encoder.getVelocity():2.2f})  Time: {Timer.getFPGATimestamp() - self.robot.enabled_time:2.1f}"
            SmartDashboard.putString("alert", msg)
            SmartDashboard.putString("sparks", str(self.error_dict))
Ejemplo n.º 20
0
 def __init__(self):
     super().__init__("Intake")
     self.talon_1 = WPI_TalonSRX(robotmap.talon_intake_1)
     self.talon_2 = WPI_TalonSRX(robotmap.talon_intake_2)
     self.talon_group = SpeedControllerGroup(self.talon_1, self.talon_2)