Ejemplo n.º 1
0
    def getTable(cls) -> NetworkTable:
        if cls.table is None:
            from networktables import NetworkTables

            cls.table = NetworkTables.getTable("SmartDashboard")
            hal.report(hal.UsageReporting.kResourceType_SmartDashboard, 0)
        return cls.table
Ejemplo n.º 2
0
    def __init__(self, channel: int) -> None:
        """Allocate a PWM given a channel.

        :param channel: The PWM channel number. 0-9 are on-board, 10-19 are on the MXP port
        """
        super().__init__()
        SendableBase.__init__(self)

        SensorUtil.checkPWMChannel(channel)
        self.channel = channel

        self.handle = hal.initializePWMPort(hal.getPort(channel))
        self.__finalizer = weakref.finalize(self, _freePWM, self.handle)

        self.setDisabled()

        hal.setPWMEliminateDeadband(self.handle, False)

        hal.report(hal.UsageReporting.kResourceType_PWM, channel)
        self.setName("PWM", channel)

        self.setSafetyEnabled(False)

        # Python-specific: Need this to free on unit test wpilib reset
        Resource._add_global_resource(self)
Ejemplo n.º 3
0
    def drivePolar(self, magnitude: float, angle: float, zRotation: float) -> None:
        """Drive method for Mecanum platform.

        Angles are measured counter-clockwise from straight ahead. The speed at which the robot
        drives (translation) is independent from its angle or rotation rate.

        :param magnitude: The robot's speed at a given angle [-1.0..1.0]. Forward is positive.
        :param angle: The angle around the Z axis at which the robot drives in degrees [-180..180].
        :param zRotation: The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
                          positive.
        """
        if not self.reported:
            hal.report(
                hal.UsageReporting.kResourceType_RobotDrive,
                4,
                hal.UsageReporting.kRobotDrive2_MecanumPolar,
            )
            self.reported = True

        magnitude = RobotDriveBase.limit(magnitude) * math.sqrt(2)

        self.driveCartesian(
            magnitude * math.cos(math.radians(angle)),
            magnitude * math.sin(math.radians(angle)),
            zRotation,
            0.0,
        )
Ejemplo n.º 4
0
    def __init__(self, port, range):
        """Constructor. Use this when the device is the first/only device on
        the bus

        :param port: The SPI port that the accelerometer is connected to
        :type port: :class:`.SPI.Port`
        :param range: The range (+ or -) that the accelerometer will measure.
        :type range: :class:`.ADXL345_SPI.Range`
        """
        self.spi = SPI(port)
        self.spi.setClockRate(500000)
        self.spi.setMSBFirst()
        self.spi.setSampleDataOnTrailingEdge()
        self.spi.setClockActiveLow()
        self.spi.setChipSelectActiveHigh()

        # Turn on the measurements
        self.spi.write([self.kPowerCtlRegister, self.kPowerCtl_Measure])

        self.setRange(range)

        hal.report(hal.UsageReporting.kResourceType_ADXL345,
                      hal.UsageReporting.kADXL345_SPI)

        self.setName("ADXL345_SPI", port)
Ejemplo n.º 5
0
    def __init__(self):
        RobotBase.__init__(self)
        self.iterator = None
        self.earlyStop = False

        hal.report(hal.UsageReporting.kResourceType_Framework,
                   hal.UsageReporting.kFramework_Iterative)
Ejemplo n.º 6
0
    def tankDrive(self, left, right, squaredInputs=True):
        """Provide tank steering using the stored robot configuration.

        :param left: The value to use for the left side motors. [-1.0..1.0]
        :param right: The value to use for the right side motors. [-1.0..1.0]
        :param squaredInputs: If set, decreases the input sensitivity at low speeds
        """

        if not self.reported:
            hal.report(hal.UsageReporting.kResourceType_RobotDrive, 2,
                       hal.UsageReporting.kRobotDrive_Tank)
            self.reported = True

        left = RobotDriveBase.limit(left)
        left = RobotDriveBase.applyDeadband(left, self.deadband)

        right = RobotDriveBase.limit(right)
        right = RobotDriveBase.applyDeadband(right, self.deadband)

        # square the inputs (while preserving the sign) to increase fine
        # control while permitting full power
        if squaredInputs:
            left = math.copysign(left * left, left)
            right = math.copysign(right * right, right)

        self.leftMotor.set(left * self.maxOutput)
        self.rightMotor.set(-right * self.maxOutput)

        self.feed()
Ejemplo n.º 7
0
    def _initRelay(self) -> None:
        SensorUtil.checkRelayChannel(self.channel)
        portHandle = hal.getPort(self.channel)

        try:
            if (
                self.direction == self.Direction.kBoth
                or self.direction == self.Direction.kForward
            ):
                Relay.relayChannels.allocate(self, self.channel * 2)
                self._forwardHandle = hal.initializeRelayPort(portHandle, True)
                hal.report(hal.UsageReporting.kResourceType_Relay, self.channel)

            if (
                self.direction == self.Direction.kBoth
                or self.direction == self.Direction.kReverse
            ):
                Relay.relayChannels.allocate(self, self.channel * 2 + 1)
                self._reverseHandle = hal.initializeRelayPort(portHandle, False)
                hal.report(hal.UsageReporting.kResourceType_Relay, self.channel + 128)
        except IndexError as e:
            raise IndexError(
                "Relay channel %d is already allocated" % self.channel
            ) from e

        self.__finalizer = weakref.finalize(
            self, _freeRelay, self._forwardHandle, self._reverseHandle
        )

        self.setSafetyEnabled(False)

        self.setName("Relay", self.channel)
Ejemplo n.º 8
0
    def __init__(self, port):
        """Construct an instance of a joystick.

        The joystick index is the USB port on the Driver Station.

        This constructor is intended for use by subclasses to configure the
        number of constants for axes and buttons.

        :param port: The port on the Driver Station that the joystick is
            plugged into.
        :type  port: int
        :param numAxisTypes: The number of axis types.
        :type  numAxisTypes: int
        :param numButtonTypes: The number of button types.
        :type  numButtonTypes: int
        """
        super().__init__(port)
        from .driverstation import DriverStation
        self.ds = DriverStation.getInstance()

        self.axes = [0] * self.Axis.kNumAxis
        self.axes[self.Axis.kX] = self.kDefaultXAxis
        self.axes[self.Axis.kY] = self.kDefaultYAxis
        self.axes[self.Axis.kZ] = self.kDefaultZAxis
        self.axes[self.Axis.kTwist] = self.kDefaultTwistAxis
        self.axes[self.Axis.kThrottle] = self.kDefaultThrottleAxis

        self.outputs = 0
        self.leftRumble = 0
        self.rightRumble = 0

        hal.report(hal.UsageReporting.kResourceType_Joystick, port)
Ejemplo n.º 9
0
    def __init__(self, channel: int, directionSensitive: bool = False) -> None:
        """Construct a GearTooth sensor.

        :param channel: The DIO channel index or DigitalSource that the sensor
            is connected to.
        :param directionSensitive: True to enable the pulse length decoding in
            hardware to specify count direction.  Defaults to False.
        """
        super().__init__(channel)
        self.enableDirectionSensing(directionSensitive)
        if hasattr(self.upSource, "getChannel"):
            if directionSensitive:
                hal.report(
                    hal.UsageReporting.kResourceType_GearTooth,
                    self.upSource.getChannel(),
                    0,
                    "D",
                )
            else:
                hal.report(
                    hal.UsageReporting.kResourceType_GearTooth,
                    self.upSource.getChannel(),
                    0,
                )
        self.setName("GearTooth", self.upSource.getChannel())
Ejemplo n.º 10
0
    def _initRelay(self) -> None:
        SensorUtil.checkRelayChannel(self.channel)
        portHandle = hal.getPort(self.channel)

        try:
            if (
                self.direction == self.Direction.kBoth
                or self.direction == self.Direction.kForward
            ):
                Relay.relayChannels.allocate(self, self.channel * 2)
                self.forwardHandle = hal.initializeRelayPort(portHandle, True)
                hal.report(hal.UsageReporting.kResourceType_Relay, self.channel)

            if (
                self.direction == self.Direction.kBoth
                or self.direction == self.Direction.kReverse
            ):
                Relay.relayChannels.allocate(self, self.channel * 2 + 1)
                self.reverseHandle = hal.initializeRelayPort(portHandle, False)
                hal.report(hal.UsageReporting.kResourceType_Relay, self.channel + 128)
        except IndexError as e:
            raise IndexError(
                "Relay channel %d is already allocated" % self.channel
            ) from e

        self.__finalizer = weakref.finalize(
            self, _freeRelay, self.forwardHandle, self.reverseHandle
        )

        self.setSafetyEnabled(False)

        self.setName("Relay", self.channel)
Ejemplo n.º 11
0
    def __init__(self, channel):
        """Constructor.

        :param channel: The PWM channel that the SPARK is attached to. 0-9 are on-board, 10-19 are on the MXP port
        
        .. note ::
        
           Note that the SD540 uses the following bounds for PWM values. These
           values should work reasonably well for most controllers, but if users
           experience issues such as asymmetric behavior around the deadband or
           inability to saturate the controller in either direction, calibration is
           recommended. The calibration procedure can be found in the SD540 User
           Manual available from Mindsensors.
           
           - 2.003ms = full "forward"
           - 1.55ms = the "high end" of the deadband range
           - 1.50ms = center of the deadband range (off)
           - 1.46ms = the "low end" of the deadband range
           - .999ms = full "reverse"
        
        """
        super().__init__(channel)
        self.setBounds(2.003, 1.55, 1.50, 1.46, .999)
        self.setPeriodMultiplier(self.PeriodMultiplier.k1X)
        self.setSpeed(0)
        self.setZeroLatch()

        hal.report(hal.UsageReporting.kResourceType_RevSPARK,
                   self.getChannel())
        self.setName("Spark", self.getChannel())
Ejemplo n.º 12
0
    def __init__(self, channel):
        """Constructor for an analog trigger given a channel number or analog
        input.

        :param channel: the port index or :class:`.AnalogInput` to use for the analog
            trigger.  Treated as an AnalogInput if the provided object has a
            getChannel function.
        """
        super().__init__()
        if not hasattr(channel, "getChannel"):
            self.analogInput = AnalogInput(channel)
            self.ownsAnalog = True
            self.addChild(self.analogInput)
        else:
            self.analogInput = channel

        self._port, self.index = hal.initializeAnalogTrigger(
            self.analogInput.port)
        self.__finalizer = \
            weakref.finalize(self, _freeAnalogTrigger, self._port)

        # Need this to free on unit test wpilib reset
        Resource._add_global_resource(self)

        hal.report(hal.UsageReporting.kResourceType_AnalogTrigger, channel)

        self.setName("AnalogTrigger", self.analogInput.getChannel())
Ejemplo n.º 13
0
    def __init__(self, channel: int) -> None:
        """Allocate a PWM given a channel.

        :param channel: The PWM channel number. 0-9 are on-board, 10-19 are on the MXP port
        """
        super().__init__()
        SendableBase.__init__(self)

        SensorUtil.checkPWMChannel(channel)
        self.channel = channel

        self._handle = hal.initializePWMPort(hal.getPort(channel))
        self.__finalizer = weakref.finalize(self, _freePWM, self._handle)

        self.setDisabled()

        hal.setPWMEliminateDeadband(self.handle, False)

        hal.report(hal.UsageReporting.kResourceType_PWM, channel)
        self.setName("PWM", channel)

        self.setSafetyEnabled(False)

        # Python-specific: Need this to free on unit test wpilib reset
        Resource._add_global_resource(self)
Ejemplo n.º 14
0
 def getTable(cls):
     if cls.table is None:
         from networktables import NetworkTable
         cls.table = NetworkTable.getTable("SmartDashboard")
         hal.report(hal.UsageReporting.kResourceType_SmartDashboard,
                    hal.UsageReporting.kSmartDashboard_Instance)
     return cls.table
Ejemplo n.º 15
0
    def __init__(self, channel: int) -> None:
        """Constructor for a TalonSRX connected via PWM.

        :param channel: The PWM channel that the PWMTalonSRX is attached to. 0-9 are on-board, 10-19 are on the MXP port.

        .. note ::

            The PWMTalonSRX uses the following bounds for PWM values. These values
            should work reasonably well for most controllers, but if users
            experience issues such as asymmetric behavior around the deadband
            or inability to saturate the controller in either direction,
            calibration is recommended.  The calibration procedure can be
            found in the TalonSRX User Manual available from CTRE.

            - 2.004ms = full "forward"
            - 1.520ms = the "high end" of the deadband range
            - 1.500ms = center of the deadband range (off)
            - 1.480ms = the "low end" of the deadband range
            - 0.997ms = full "reverse"
        """
        super().__init__(channel)
        self.setBounds(2.004, 1.52, 1.50, 1.48, 0.997)
        self.setPeriodMultiplier(self.PeriodMultiplier.k1X)
        self.setSpeed(0)
        self.setZeroLatch()

        hal.report(hal.UsageReporting.kResourceType_PWMTalonSRX, self.getChannel())
        self.setName("PWMTalonSRX", self.getChannel())
Ejemplo n.º 16
0
    def __init__(self, channel):
        """Constructor for a Talon (original or Talon SR)

        :param channel: The PWM channel that the Talon is attached to. 0-9 are on-board, 10-19 are on the MXP port
        :type  channel: int

        .. note ::

            The Talon uses the following bounds for PWM values. These values
            should work reasonably well for most controllers, but if users
            experience issues such as asymmetric behavior around the deadband
            or inability to saturate the controller in either direction,
            calibration is recommended.  The calibration procedure can be
            found in the Talon User Manual available from CTRE.

            - 2.037ms = full "forward"
            - 1.539ms = the "high end" of the deadband range
            - 1.513ms = center of the deadband range (off)
            - 1.487ms = the "low end" of the deadband range
            - 0.989ms = full "reverse"
        """
        super().__init__(channel)
        self.setBounds(2.037, 1.539, 1.513, 1.487, 0.989)
        self.setPeriodMultiplier(self.PeriodMultiplier.k1X)
        self.setSpeed(0.0)
        self.setZeroLatch()

        hal.report(hal.UsageReporting.kResourceType_Talon, self.getChannel())
        self.setName("Talon", self.getChannel())
Ejemplo n.º 17
0
    def __init__(self):
        super().__init__()
        hal.report(hal.UsageReporting.kResourceType_Framework,
                   hal.UsageReporting.kFramework_Iterative)

        self._loop = asyncio.get_event_loop()
        self._active_commands = []
Ejemplo n.º 18
0
    def __init__(self):
        """Creates a preference class that will automatically read the file in
        a different thread. Any call to its methods will be blocked until the
        thread is finished reading.
        """
        # The actual values (str->str)
        self.values = {}
        # The keys in the order they were read from the file
        self.keylist = []
        # The comments that were in the file sorted by which key they appeared
        # over (str->str)
        self.comments = {}
        # The comment at the end of the file
        self.endComment = ""

        # The semaphore for beginning reads and writes to the file
        self.fileLock = threading.Condition()
        # The semaphore for reading from the table
        self.lock = threading.RLock()

        # We synchronized on fileLock and then wait
        # for it to know that the reading thread has started
        with self.fileLock:
            reader = threading.Thread(target=self._read,
                                      name="Preferences Read")
            reader.start()
            self.fileLock.wait()

        hal.report(hal.UsageReporting.kResourceType_Preferences, 0)
Ejemplo n.º 19
0
    def __init__(self, channel):
        """Constructor.

        :param channel: The PWM channel that the SPARK is attached to. 0-9 are on-board, 10-19 are on the MXP port
        
        .. note ::
        
           Note that the SD540 uses the following bounds for PWM values. These
           values should work reasonably well for most controllers, but if users
           experience issues such as asymmetric behavior around the deadband or
           inability to saturate the controller in either direction, calibration is
           recommended. The calibration procedure can be found in the SD540 User
           Manual available from Mindsensors.
           
           - 2.003ms = full "forward"
           - 1.55ms = the "high end" of the deadband range
           - 1.50ms = center of the deadband range (off)
           - 1.46ms = the "low end" of the deadband range
           - .999ms = full "reverse"
        
        """
        super().__init__(channel)
        self.setBounds(2.003, 1.55, 1.50, 1.46, .999)
        self.setPeriodMultiplier(self.PeriodMultiplier.k1X)
        self.setSpeed(0)
        self.setZeroLatch()

        LiveWindow.addActuatorChannel("Spark", self.getChannel(), self)
        hal.report(hal.UsageReporting.kResourceType_RevSPARK,
                   self.getChannel())
Ejemplo n.º 20
0
    def __init__(self, channel):
        """Constructor.

        :param channel: The PWM channel that the VictorSP is attached to. 0-9 are on-board, 10-19 are on the MXP port.
        :type  channel: int

        .. note ::

            The Talon uses the following bounds for PWM values. These values
            should work reasonably well for most controllers, but if users
            experience issues such as asymmetric behavior around the deadband
            or inability to saturate the controller in either direction,
            calibration is recommended.  The calibration procedure can be
            found in the VictorSP User Manual.

            - 2.004ms = full "forward"
            - 1.520ms = the "high end" of the deadband range
            - 1.500ms = center of the deadband range (off)
            - 1.480ms = the "low end" of the deadband range
            - 0.997ms = full "reverse"
        """
        super().__init__(channel)
        self.setBounds(2.004, 1.52, 1.50, 1.48, .997)
        self.setPeriodMultiplier(self.PeriodMultiplier.k1X)
        self.setSpeed(0)
        self.setZeroLatch()

        LiveWindow.addActuatorChannel("VictorSP", self.getChannel(), self)
        hal.report(hal.UsageReporting.kResourceType_VictorSP,
                   self.getChannel())
Ejemplo n.º 21
0
    def drivePolar(self, magnitude: float, angle: float,
                   zRotation: float) -> None:
        """Drive method for Mecanum platform.

        Angles are measured counter-clockwise from straight ahead. The speed at which the robot
        drives (translation) is independent from its angle or rotation rate.

        :param magnitude: The robot's speed at a given angle [-1.0..1.0]. Forward is positive.
        :param angle: The angle around the Z axis at which the robot drives in degrees [-180..180].
        :param zRotation: The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
                          positive.
        """
        if not self.reported:
            hal.report(
                hal.UsageReporting.kResourceType_RobotDrive,
                4,
                hal.UsageReporting.kRobotDrive2_MecanumPolar,
            )
            self.reported = True

        magnitude = RobotDriveBase.limit(magnitude) * math.sqrt(2)

        self.driveCartesian(
            magnitude * math.cos(math.radians(angle)),
            magnitude * math.sin(math.radians(angle)),
            zRotation,
            0.0,
        )
Ejemplo n.º 22
0
    def __init__(self, *args, **kwargs):
        """
        Arguments can be structured as follows:

        - deviceNumber
        - talonSrx
        
        :param deviceNumber:
            CAN Device Id of Pigeon [0,62]
        :param talonSrx:
            Object for the TalonSRX connected via ribbon cable.
        """
        super().__init__()

        deviceNumber_arg = ("deviceNumber", [int])
        talonSrx_arg = ("talonSrx", [TalonSRX])
        templates = [[deviceNumber_arg], [talonSrx_arg]]
        index, results = match_arglist('PigeonIMU.__init__', args, kwargs,
                                       templates)
        self.generalStatus = [0] * 10
        self.fusionStatus = [0] * 10

        if index == 0:
            self.deviceNumber = results['deviceNumber']
            self._create1(self.deviceNumber)
        elif index == 1:
            self.deviceNumber = results['talonSrx'].getDeviceID()
            self._create2(self.deviceNumber)
            hal.report(64, self.deviceNumber + 1)
        hal.report(hal.UsageReporting.kResourceType_PigeonIMU,
                   self.deviceNumber + 1)
Ejemplo n.º 23
0
    def main(robot_cls):
        """Starting point for the applications."""
        RobotBase.initializeHardwareConfiguration()

        hal.report(hal.UsageReporting.kResourceType_Language,
                   hal.UsageReporting.kLanguage_Python)

        try:
            robot = robot_cls()
        except:
            from .driverstation import DriverStation
            DriverStation.reportError(
                "Unhandled exception instantiating robot " +
                robot_cls.__name__, True)
            DriverStation.reportWarning(
                "Robots should not quit, but yours did!", False)
            DriverStation.reportError(
                "Could not instantiate robot " + robot_cls.__name__ + "!",
                False)
            return False

        # Add a check to see if the user forgot to call super().__init__()
        if not hasattr(robot, '_RobotBase__initialized'):
            logger.error(
                "If your robot class has an __init__ function, it must call super().__init__()!"
            )
            return False

        if not hal.isSimulation():
            try:
                import wpilib
                with open('/tmp/frc_versions/FRC_Lib_Version.ini', 'w') as fp:
                    fp.write('RobotPy %s' % wpilib.__version__)
            except:
                logger.warning("Could not write FRC version file to disk")

        try:
            robot.startCompetition()
        except KeyboardInterrupt:
            logger.exception(
                "THIS IS NOT AN ERROR: The user hit CTRL-C to kill the robot")
            logger.info("Exiting because of keyboard interrupt")
            return True
        except:
            from .driverstation import DriverStation
            DriverStation.reportError("Unhandled exception", True)
            DriverStation.reportWarning(
                "Robots should not quit, but yours did!", False)
            DriverStation.reportError(
                "The startCompetition() method (or methods called by it) should have handled the exception above.",
                False)
            return False
        else:
            # startCompetition never returns unless exception occurs....
            from .driverstation import DriverStation
            DriverStation.reportWarning(
                "Robots should not quit, but yours did!", False)
            DriverStation.reportError(
                "Unexpected return from startCompetition() method.", False)
            return False
Ejemplo n.º 24
0
    def __init__(self, port, range):
        """Constructor. Use this when the device is the first/only device on
        the bus

        :param port: The SPI port that the accelerometer is connected to
        :type port: :class:`.SPI.Port`
        :param range: The range (+ or -) that the accelerometer will measure.
        :type range: :class:`.ADXL345_SPI.Range`
        """
        self.spi = SPI(port)
        self.spi.setClockRate(500000)
        self.spi.setMSBFirst()
        self.spi.setSampleDataOnFalling()
        self.spi.setClockActiveLow()
        self.spi.setChipSelectActiveHigh()

        # Turn on the measurements
        self.spi.write([self.kPowerCtlRegister, self.kPowerCtl_Measure])

        self.setRange(range)

        hal.report(hal.UsageReporting.kResourceType_ADXL345,
                      hal.UsageReporting.kADXL345_SPI)

        LiveWindow.addSensor("ADXL345_SPI", port, self)
Ejemplo n.º 25
0
    def __init__(self, channel):
        """Constructor for a Talon (original or Talon SR)

        :param channel: The PWM channel that the Talon is attached to. 0-9 are on-board, 10-19 are on the MXP port
        :type  channel: int

        .. note ::

            The Talon uses the following bounds for PWM values. These values
            should work reasonably well for most controllers, but if users
            experience issues such as asymmetric behavior around the deadband
            or inability to saturate the controller in either direction,
            calibration is recommended.  The calibration procedure can be
            found in the Talon User Manual available from CTRE.

            - 2.037ms = full "forward"
            - 1.539ms = the "high end" of the deadband range
            - 1.513ms = center of the deadband range (off)
            - 1.487ms = the "low end" of the deadband range
            - 0.989ms = full "reverse"
        """
        super().__init__(channel)
        self.setBounds(2.037, 1.539, 1.513, 1.487, 0.989)
        self.setPeriodMultiplier(self.PeriodMultiplier.k1X)
        self.setSpeed(0.0)
        self.setZeroLatch()

        LiveWindow.addActuatorChannel("Talon", self.getChannel(), self)
        hal.report(hal.UsageReporting.kResourceType_Talon,
                   self.getChannel())
 def getTable(cls):
     if cls.table is None:
         from networktables import NetworkTable
         cls.table = NetworkTable.getTable("SmartDashboard")
         hal.report(hal.UsageReporting.kResourceType_SmartDashboard,
                    hal.UsageReporting.kSmartDashboard_Instance)
     return cls.table
Ejemplo n.º 27
0
    def tankDrive(self, leftSpeed, rightSpeed, squaredInputs=True):
        """Provide tank steering using the stored robot configuration.

        :param leftSpeed: The robot's left side speed along the X axis `[-1.0..1.0]`. Forward is positive.
        :param rightSpeed: The robot's right side speed along the X axis`[-1.0..1.0]`. Forward is positive.
        :param squaredInputs: If set, decreases the input sensitivity at low speeds
        """

        if not self.reported:
            hal.report(hal.UsageReporting.kResourceType_RobotDrive,
                       2,
                       hal.UsageReporting.kRobotDrive_Tank)
            self.reported = True

        leftSpeed = RobotDriveBase.limit(leftSpeed)
        leftSpeed = RobotDriveBase.applyDeadband(leftSpeed, self.deadband)

        rightSpeed = RobotDriveBase.limit(rightSpeed)
        rightSpeed = RobotDriveBase.applyDeadband(rightSpeed, self.deadband)

        # square the inputs (while preserving the sign) to increase fine
        # control while permitting full power
        if squaredInputs:
            leftSpeed = math.copysign(leftSpeed * leftSpeed, leftSpeed)
            rightSpeed = math.copysign(rightSpeed * rightSpeed, rightSpeed)

        self.leftMotor.set(leftSpeed * self.maxOutput)
        self.rightMotor.set(-rightSpeed * self.maxOutput)

        self.feed()
Ejemplo n.º 28
0
    def __init__(self):
        """Instantiates a Scheduler.
        """
        super().__init__()
        hal.report(hal.UsageReporting.kResourceType_Command,
                   hal.UsageReporting.kCommand_Scheduler)
        self.setName("Scheduler")

        # Active Commands
        self.commandTable = collections.OrderedDict()
        # The set of all Subsystems
        self.subsystems = set()
        # Whether or not we are currently adding a command
        self.adding = False
        # Whether or not we are currently disabled
        self.disabled = False
        # A list of all Commands which need to be added
        self.additions = []
        # A list of all Buttons. It is created lazily.
        self.buttons = []
        self.runningCommandsChanged = False

        self.namesEntry = None
        self.idsEntry = None
        self.cancelEntry = None
Ejemplo n.º 29
0
    def getTable(cls) -> NetworkTable:
        if cls.table is None:
            from networktables import NetworkTables

            cls.table = NetworkTables.getTable("SmartDashboard")
            hal.report(hal.UsageReporting.kResourceType_SmartDashboard, 0)
        return cls.table
Ejemplo n.º 30
0
    def launch(cls, vision_py=None):
        """
            Launches the CameraServer process in autocapture mode or
            using a user-specified python script
        
            :param vision_py: If specified, this is the relative path to
                              a filename with a function in it
                              
            Example usage::
            
                wpilib.CameraServer.launch("vision.py:main")
            
            .. warning:: You must have robotpy-cscore installed, or this
                         function will fail without returning an error
                         (you will see an error in the console).
                         
        """

        if cls._launched:
            return

        cls._launched = True

        if hal.isSimulation():
            logger.info("Would launch CameraServer with vision_py=%s",
                        vision_py)
            cls._alive = True
        else:
            logger.info("Launching CameraServer process")

            # Launch the cscore launcher in a separate process

            import subprocess
            import sys

            args = [sys.executable, "-m", "cscore"]

            # TODO: Get accurate reporting data from the other cscore process. For
            # now, just differentiate between users with a custom py file and those
            # who do not. cscore handle values indicate type with bits 24-30

            if vision_py:
                if not vision_py.startswith("/"):
                    vision_py = "/home/lvuser/py/" + vision_py
                args.append(vision_py)
                hal.report(hal.UsageReporting.kResourceType_PCVideoServer,
                           0x51)
            else:
                hal.report(hal.UsageReporting.kResourceType_PCVideoServer,
                           0x52)

            # We open a pipe to it so that when this process exits, it dies
            proc = subprocess.Popen(args,
                                    close_fds=True,
                                    stdin=subprocess.PIPE,
                                    cwd="/home/lvuser/py")
            th = threading.Thread(target=cls._monitor_child, args=(proc, ))
            th.daemon = True
            th.start()
Ejemplo n.º 31
0
    def __init__(self, port: int) -> None:
        """Construct an instance of an XBoxController. The XBoxController index is the USB port on the Driver Station.

        :param port: The port on the Driver Station that the joystick is plugged into
        """
        super().__init__(port)

        hal.report(hal.UsageReporting.kResourceType_XboxController, port)
Ejemplo n.º 32
0
    def __init__(self, port: int) -> None:
        """Construct an instance of an XBoxController. The XBoxController index is the USB port on the Driver Station.

        :param port: The port on the Driver Station that the joystick is plugged into
        """
        super().__init__(port)

        hal.report(hal.UsageReporting.kResourceType_XboxController, port)
Ejemplo n.º 33
0
    def __init__(self, *args, **kwargs):
        """Constructor.

        Arguments can be supplied as positional or keyword.  Acceptable
        positional argument combinations are:
        
        - channel
        - moduleNumber, channel

        Alternatively, the above names can be used as keyword arguments.

        :param moduleNumber: The CAN ID of the PCM the solenoid is attached to
        :type moduleNumber: int
        :param channel: The channel on the PCM to control (0..7)
        :type channel: int
        """
        # keyword arguments
        channel = kwargs.pop("channel", None)
        moduleNumber = kwargs.pop("moduleNumber", None)

        if kwargs:
            warnings.warn("unknown keyword arguments: %s" % kwargs.keys(),
                          RuntimeWarning)

        # positional arguments
        if len(args) == 1:
            channel = args[0]
        elif len(args) == 2:
            moduleNumber, channel = args
        elif len(args) != 0:
            raise ValueError(
                "don't know how to handle %d positional arguments" % len(args))

        if moduleNumber is None:
            moduleNumber = SensorBase.getDefaultSolenoidModule()
        if channel is None:
            raise ValueError("must specify channel")

        super().__init__(moduleNumber)
        self.channel = channel
        self.valueEntry = None

        SensorBase.checkSolenoidModule(moduleNumber)
        SensorBase.checkSolenoidChannel(channel)

        portHandle = hal.getPortWithModule(moduleNumber, channel)
        self._solenoidHandle = hal.initializeSolenoidPort(portHandle)

        LiveWindow.addActuatorModuleChannel("Solenoid", moduleNumber, channel,
                                            self)
        hal.report(hal.UsageReporting.kResourceType_Solenoid, channel,
                   moduleNumber)

        self.__finalizer = weakref.finalize(self, _freeSolenoid,
                                            self._solenoidHandle)

        # Need this to free on unit test wpilib reset
        Resource._add_global_resource(self)
Ejemplo n.º 34
0
    def __init__(self):
        super().__init__()
        hal.report(hal.UsageReporting.kResourceType_Framework,
                   hal.UsageReporting.kFramework_Iterative)

        self.period = TimedRobot.DEFAULT_PERIOD
        # Prevents loop from starting if user calls setPeriod() in robotInit()
        self.startLoop = False
        self.loop = Notifier(self.loopFunc)
Ejemplo n.º 35
0
    def __init__(self):
        """Creates a preference class that will automatically read the file in
        a different thread. Any call to its methods will be blocked until the
        thread is finished reading.
        """
        self.table = NetworkTables.getTable(self.TABLE_NAME)
        self.table.addTableListenerEx(self.valueChangedEx, NetworkTables.NotifyFlags.NEW | NetworkTables.NotifyFlags.IMMEDIATE)

        hal.report(hal.UsageReporting.kResourceType_Preferences, 0)
Ejemplo n.º 36
0
    def __init__(self, deviceNumber: int) -> None:
        """Constructor

        :param deviceNumber:
            [0,62]
        """
        super().__init__(deviceNumber | 0x01040000)
        hal.report(hal.UsageReporting.kResourceType_CTRE_future1,
                   deviceNumber + 1)
 def __init__(self, module: int = 0) -> None:
     """
         :param module: CAN ID of the PDP
     """
     super().__init__()
     SensorUtil.checkPDPModule(module)
     self.handle = hal.initializePDP(module)
     hal.report(hal.UsageReporting.kResourceType_PDP, module)
     self.setName("PowerDistributionPanel", module)
Ejemplo n.º 38
0
    def driveCartesian(self,
                       ySpeed: float,
                       xSpeed: float,
                       zRotation: float,
                       gyroAngle: float = 0.0) -> None:
        """Drive method for Mecanum platform.

        Angles are measured clockwise from the positive X axis. The robot's speed is independent
        from its angle or rotation rate.

        :param ySpeed: The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
        :param xSpeed: The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
        :param zRotation: The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is positive.
        :param gyroAngle: The current angle reading from the gyro in degrees around the Z axis. Use
                          this to implement field-oriented controls.
        """
        if not self.reported:
            hal.report(
                hal.UsageReporting.kResourceType_RobotDrive,
                4,
                hal.UsageReporting.kRobotDrive2_MecanumCartesian,
            )
            self.reported = True

        ySpeed = RobotDriveBase.limit(ySpeed)
        ySpeed = RobotDriveBase.applyDeadband(ySpeed, self.deadband)

        xSpeed = RobotDriveBase.limit(xSpeed)
        xSpeed = RobotDriveBase.applyDeadband(xSpeed, self.deadband)

        # Compensate for gyro angle
        input = Vector2d(ySpeed, xSpeed)
        input.rotate(gyroAngle)

        wheelSpeeds = [
            # Front Left
            input.x + input.y + zRotation,
            # Rear Left
            -input.x + input.y + zRotation,
            # Front Right
            -input.x + input.y - zRotation,
            # Rear Right
            input.x + input.y - zRotation,
        ]

        RobotDriveBase.normalize(wheelSpeeds)

        wheelSpeeds = [speed * self.maxOutput for speed in wheelSpeeds]

        self.frontLeftMotor.set(wheelSpeeds[0])
        self.rearLeftMotor.set(wheelSpeeds[1])
        self.frontRightMotor.set(wheelSpeeds[2] *
                                 self.rightSideInvertMultiplier)
        self.rearRightMotor.set(wheelSpeeds[3] *
                                self.rightSideInvertMultiplier)

        self.feed()
 def __init__(self, module: int = 0) -> None:
     """
         :param module: CAN ID of the PDP
     """
     super().__init__()
     SensorUtil.checkPDPModule(module)
     self.handle = hal.initializePDP(module)
     hal.report(hal.UsageReporting.kResourceType_PDP, module)
     self.setName("PowerDistributionPanel", module)
Ejemplo n.º 40
0
    def __init__(self, *args, **kwargs):
        """Constructor.

        Arguments can be supplied as positional or keyword.  Acceptable
        positional argument combinations are:
        
        - channel
        - moduleNumber, channel

        Alternatively, the above names can be used as keyword arguments.

        :param moduleNumber: The CAN ID of the PCM the solenoid is attached to
        :type moduleNumber: int
        :param channel: The channel on the PCM to control (0..7)
        :type channel: int
        """
        # keyword arguments
        channel = kwargs.pop("channel", None)
        moduleNumber = kwargs.pop("moduleNumber", None)

        if kwargs:
            warnings.warn("unknown keyword arguments: %s" % kwargs.keys(),
                          RuntimeWarning)

        # positional arguments
        if len(args) == 1:
            channel = args[0]
        elif len(args) == 2:
            moduleNumber, channel = args
        elif len(args) != 0:
            raise ValueError("don't know how to handle %d positional arguments" % len(args))

        if moduleNumber is None:
            moduleNumber = SensorBase.getDefaultSolenoidModule()
        if channel is None:
            raise ValueError("must specify channel")

        SensorBase.checkSolenoidModule(moduleNumber)
        SensorBase.checkSolenoidChannel(channel)

        super().__init__(moduleNumber)
        self.channel = channel

        try:
            self.allocated.allocate(self, channel)
        except IndexError as e:
            raise IndexError("Solenoid channel %d on module %d is already allocated" % (channel, moduleNumber)) from e

        portHandle= hal.getPortWithModule(moduleNumber, channel)
        self._solenoidHandle = hal.initializeSolenoidPort(portHandle)

        LiveWindow.addActuatorModuleChannel("Solenoid", moduleNumber, channel,
                                            self)
        hal.report(hal.UsageReporting.kResourceType_Solenoid, channel,
                   moduleNumber)
        
        self.__finalizer = weakref.finalize(self, _freeSolenoid, self._solenoidHandle)
Ejemplo n.º 41
0
    def arcadeDrive(self,
                    xSpeed: float,
                    zRotation: float,
                    squareInputs: bool = True) -> None:
        """Arcade drive method for differential drive platform.

        :param xSpeed: The robot's speed along the X axis `[-1.0..1.0]`. Forward is positive
        :param zRotation: The robot's zRotation rate around the Z axis `[-1.0..1.0]`. Clockwise is positive
        :param squareInputs: If set, decreases the sensitivity at low speeds.
        """

        if not self.reported:
            hal.report(
                hal.UsageReporting.kResourceType_RobotDrive,
                2,
                hal.UsageReporting.kRobotDrive_ArcadeStandard,
            )
            self.reported = True

        xSpeed = RobotDriveBase.limit(xSpeed)
        xSpeed = RobotDriveBase.applyDeadband(xSpeed, self.deadband)

        zRotation = RobotDriveBase.limit(zRotation)
        zRotation = RobotDriveBase.applyDeadband(zRotation, self.deadband)

        if squareInputs:
            # Square the inputs (while preserving the sign) to increase fine
            # control while permitting full power.
            xSpeed = math.copysign(xSpeed * xSpeed, xSpeed)
            zRotation = math.copysign(zRotation * zRotation, zRotation)

        maxInput = math.copysign(max(abs(xSpeed), abs(zRotation)), xSpeed)

        if xSpeed >= 0.0:
            if zRotation >= 0.0:
                leftMotorSpeed = maxInput
                rightMotorSpeed = xSpeed - zRotation
            else:
                leftMotorSpeed = xSpeed + zRotation
                rightMotorSpeed = maxInput
        else:
            if zRotation >= 0.0:
                leftMotorSpeed = xSpeed + zRotation
                rightMotorSpeed = maxInput
            else:
                leftMotorSpeed = maxInput
                rightMotorSpeed = xSpeed - zRotation

        leftMotorSpeed = RobotDriveBase.limit(leftMotorSpeed) * self.maxOutput
        rightMotorSpeed = RobotDriveBase.limit(
            rightMotorSpeed) * self.maxOutput

        self.leftMotor.set(leftMotorSpeed)
        self.rightMotor.set(rightMotorSpeed * self.rightSideInvertMultiplier)

        self.feed()
Ejemplo n.º 42
0
    def __init__(self, pingChannel, echoChannel, units=Unit.kInches):
        """Create an instance of the Ultrasonic Sensor.
        This is designed to supchannel the Daventech SRF04 and Vex ultrasonic
        sensors.

        :param pingChannel: The digital output channel that sends the pulse
            to initiate the sensor sending the ping.
        :param echoChannel: The digital input channel that receives the echo.
            The length of time that the echo is high represents the round
            trip time of the ping, and the distance.
        :param units: The units returned in either kInches or kMillimeters
        """
        super().__init__()
        # Convert to DigitalInput and DigitalOutput if necessary
        self.pingAllocated = False
        self.echoAllocated = False

        if not hasattr(pingChannel, "channel"):
            from .digitaloutput import DigitalOutput

            pingChannel = DigitalOutput(pingChannel)
            self.pingAllocated = True

        if not hasattr(echoChannel, "channel"):
            from .digitalinput import DigitalInput

            echoChannel = DigitalInput(echoChannel)
            self.echoAllocated = True

        self.pingChannel = pingChannel
        self.echoChannel = echoChannel
        self.units = units
        self.pidSource = self.PIDSourceType.kDisplacement
        self.enabled = True  # make it available for round robin scheduling

        self.valueEntry = None

        # set up counter for this sensor
        self.counter = Counter(self.echoChannel)
        self.counter.setMaxPeriod(1.0)
        self.counter.setSemiPeriodMode(True)
        self.counter.reset()

        isAutomatic = Ultrasonic.isAutomaticMode()
        self.setAutomaticMode(False)

        Ultrasonic.sensors.add(self)
        if isAutomatic:
            self.setAutomaticMode(True)

        Resource._add_global_resource(self)

        Ultrasonic.instances += 1
        hal.report(hal.UsageReporting.kResourceType_Ultrasonic,
                   Ultrasonic.instances)
        LiveWindow.addSensor("Ultrasonic", self.echoChannel.getChannel(), self)
Ejemplo n.º 43
0
    def __init__(
        self,
        pingChannel: Union[DigitalOutput, int],
        echoChannel: Union[DigitalInput, int],
        units: Unit = Unit.kInches,
    ) -> None:
        """Create an instance of the Ultrasonic Sensor.
        This is designed to supchannel the Daventech SRF04 and Vex ultrasonic
        sensors.

        :param pingChannel: The digital output channel that sends the pulse
            to initiate the sensor sending the ping.
        :param echoChannel: The digital input channel that receives the echo.
            The length of time that the echo is high represents the round
            trip time of the ping, and the distance.
        :param units: The units returned in either kInches or kMillimeters
        """
        super().__init__()
        # Convert to DigitalInput and DigitalOutput if necessary
        self.pingAllocated = False
        self.echoAllocated = False

        if not hasattr(pingChannel, "channel"):
            pingChannel = DigitalOutput(pingChannel)
            self.pingAllocated = True

        if not hasattr(echoChannel, "channel"):
            echoChannel = DigitalInput(echoChannel)
            self.echoAllocated = True

        self.pingChannel = pingChannel
        self.echoChannel = echoChannel
        self.units = units
        self.pidSource = self.PIDSourceType.kDisplacement
        self.enabled = True  # make it available for round robin scheduling

        self.valueEntry = None

        # set up counter for this sensor
        self.counter = Counter(self.echoChannel)
        self.counter.setMaxPeriod(1.0)
        self.counter.setSemiPeriodMode(True)
        self.counter.reset()

        isAutomatic = Ultrasonic.isAutomaticMode()
        self.setAutomaticMode(False)

        Ultrasonic.sensors.add(self)
        if isAutomatic:
            self.setAutomaticMode(True)

        Resource._add_global_resource(self)

        Ultrasonic.instances += 1
        hal.report(hal.UsageReporting.kResourceType_Ultrasonic, Ultrasonic.instances)
        self.setName("Ultrasonic", echoChannel.getChannel())
Ejemplo n.º 44
0
    def __init__(self, port: Optional[SPI.Port] = None) -> None:
        """
            Constructor.

            :param port: The SPI port that the gyro is connected to
        """
        super().__init__()

        if port is None:
            port = SPI.Port.kOnboardCS0

        simPort = None
        if hal.HALIsSimulation():
            from hal_impl.spi_helpers import ADXRS450_Gyro_Sim

            simPort = ADXRS450_Gyro_Sim(self)

        self.spi = SPI(port, simPort=simPort)

        self.spi.setClockRate(3000000)
        self.spi.setMSBFirst()
        self.spi.setSampleDataOnLeadingEdge()
        self.spi.setClockActiveHigh()
        self.spi.setChipSelectActiveLow()

        # Validate the part ID
        if (self._readRegister(self.kPIDRegister) & 0xFF00) != 0x5200:
            self.spi.close()
            self.spi = None
            DriverStation.reportError(
                "could not find ADXRS450 gyro on SPI port %s" % port, False
            )
            return

        # python-specific: make this easier to simulate
        if hal.isSimulation():
            self.spi.initAccumulator(
                self.kSamplePeriod, 0x20000000, 4, 0x0, 0x0, 0, 32, True, True
            )
        else:
            self.spi.initAccumulator(
                self.kSamplePeriod,
                0x20000000,
                4,
                0x0C00000E,
                0x04000000,
                10,
                16,
                True,
                True,
            )

        self.calibrate()

        hal.report(hal.UsageReporting.kResourceType_ADXRS450, port)
        self.setName("ADXRS450_Gyro", port)
Ejemplo n.º 45
0
    def __init__(self, *args, **kwargs) -> None:
        """Constructor.

        Arguments can be supplied as positional or keyword.  Acceptable
        positional argument combinations are:
        
        - channel
        - moduleNumber, channel

        Alternatively, the above names can be used as keyword arguments.

        :param moduleNumber: The CAN ID of the PCM the solenoid is attached to
        :type moduleNumber: int
        :param channel: The channel on the PCM to control (0..7)
        :type channel: int
        """
        # keyword arguments
        channel = kwargs.pop("channel", None)
        moduleNumber = kwargs.pop("moduleNumber", None)

        if kwargs:
            warnings.warn(
                "unknown keyword arguments: %s" % kwargs.keys(), RuntimeWarning
            )

        # positional arguments
        if len(args) == 1:
            channel = args[0]
        elif len(args) == 2:
            moduleNumber, channel = args
        elif len(args) != 0:
            raise ValueError(
                "don't know how to handle %d positional arguments" % len(args)
            )

        if moduleNumber is None:
            moduleNumber = SensorUtil.getDefaultSolenoidModule()
        if channel is None:
            raise ValueError("must specify channel")

        super().__init__(moduleNumber)
        self.channel = channel

        SensorUtil.checkSolenoidModule(moduleNumber)
        SensorUtil.checkSolenoidChannel(channel)

        portHandle = hal.getPortWithModule(moduleNumber, channel)
        self.solenoidHandle = hal.initializeSolenoidPort(portHandle)

        hal.report(hal.UsageReporting.kResourceType_Solenoid, channel, moduleNumber)
        self.setName("Solenoid", self.moduleNumber, self.channel)

        self.__finalizer = weakref.finalize(self, _freeSolenoid, self.solenoidHandle)

        # Need this to free on unit test wpilib reset
        Resource._add_global_resource(self)
Ejemplo n.º 46
0
    def __init__(self, channel):
        """Create an instance of a digital output.

        :param channel: the DIO channel for the digital output. 0-9 are on-board, 10-25 are on the MXP
        """
        super().__init__(channel, False)
        self._pwmGenerator = None
        self._pwmGenerator_finalizer = None

        hal.report(hal.UsageReporting.kResourceType_DigitalOutput, channel)
Ejemplo n.º 47
0
    def arcadeDrive(
        self, xSpeed: float, zRotation: float, squareInputs: bool = True
    ) -> None:
        """Arcade drive method for differential drive platform.

        :param xSpeed: The robot's speed along the X axis `[-1.0..1.0]`. Forward is positive
        :param zRotation: The robot's zRotation rate around the Z axis `[-1.0..1.0]`. Clockwise is positive
        :param squareInputs: If set, decreases the sensitivity at low speeds.
        """

        if not self.reported:
            hal.report(
                hal.UsageReporting.kResourceType_RobotDrive,
                2,
                hal.UsageReporting.kRobotDrive_ArcadeStandard,
            )
            self.reported = True

        xSpeed = RobotDriveBase.limit(xSpeed)
        xSpeed = RobotDriveBase.applyDeadband(xSpeed, self.deadband)

        zRotation = RobotDriveBase.limit(zRotation)
        zRotation = RobotDriveBase.applyDeadband(zRotation, self.deadband)

        if squareInputs:
            # Square the inputs (while preserving the sign) to increase fine
            # control while permitting full power.
            xSpeed = math.copysign(xSpeed * xSpeed, xSpeed)
            zRotation = math.copysign(zRotation * zRotation, zRotation)

        maxInput = math.copysign(max(abs(xSpeed), abs(zRotation)), xSpeed)

        if xSpeed >= 0.0:
            if zRotation >= 0.0:
                leftMotorSpeed = maxInput
                rightMotorSpeed = xSpeed - zRotation
            else:
                leftMotorSpeed = xSpeed + zRotation
                rightMotorSpeed = maxInput
        else:
            if zRotation >= 0.0:
                leftMotorSpeed = xSpeed + zRotation
                rightMotorSpeed = maxInput
            else:
                leftMotorSpeed = maxInput
                rightMotorSpeed = xSpeed - zRotation

        leftMotorSpeed = RobotDriveBase.limit(leftMotorSpeed) * self.maxOutput
        rightMotorSpeed = RobotDriveBase.limit(rightMotorSpeed) * self.maxOutput

        self.leftMotor.set(leftMotorSpeed)
        self.rightMotor.set(rightMotorSpeed * self.rightSideInvertMultiplier)

        self.feed()
 def __init__(self, range=Accelerometer.Range.k8G):
     """Constructor.
     
     :param range: The range the accelerometer will measure.  Defaults to
         +/-8g if unspecified.
     :type  range: :class:`.Accelerometer.Range`
     """
     self.setRange(range)
     hal.report(hal.UsageReporting.kResourceType_Accelerometer, 0, 0,
                   "Built-in accelerometer")
     LiveWindow.addSensor("BuiltInAccel", 0, self)
    def __init__(self, channel):
        """Create an instance of a digital output.

        :param channel: the DIO channel for the digital output. 0-9 are on-board, 10-25 are on the MXP
        """
        super().__init__(channel, False)
        self._pwmGenerator = None
        self._pwmGenerator_finalizer = None

        hal.report(hal.UsageReporting.kResourceType_DigitalOutput,
                      channel)
Ejemplo n.º 50
0
    def mecanumDrive_Cartesian(
        self, x: float, y: float, rotation: float, gyroAngle: float
    ) -> None:
        """Drive method for Mecanum wheeled robots.

        A method for driving with Mecanum wheeled robots. There are 4 wheels
        on the robot, arranged so that the front and back wheels are toed in
        45 degrees.  When looking at the wheels from the top, the roller
        axles should form an X across the robot.

        This is designed to be directly driven by joystick axes.

        :param x: The speed that the robot should drive in the X direction.
            [-1.0..1.0]
        :param y: The speed that the robot should drive in the Y direction.
            This input is inverted to match the forward == -1.0 that
            joysticks produce. [-1.0..1.0]
        :param rotation: The rate of rotation for the robot that is
            completely independent of the translation. [-1.0..1.0]
        :param gyroAngle: The current angle reading from the gyro.  Use this
            to implement field-oriented controls.
        """
        if not RobotDrive.kMecanumCartesian_Reported:
            hal.report(
                hal.UsageReporting.kResourceType_RobotDrive,
                self.getNumMotors(),
                hal.UsageReporting.kRobotDrive_MecanumCartesian,
            )
            RobotDrive.kMecanumCartesian_Reported = True

        xIn = x
        yIn = y
        # Negate y for the joystick.
        yIn = -yIn
        # Compensate for gyro angle.
        xIn, yIn = RobotDrive.rotateVector(xIn, yIn, gyroAngle)

        wheelSpeeds = [0] * self.kMaxNumberOfMotors
        wheelSpeeds[self.MotorType.kFrontLeft] = xIn + yIn + rotation
        wheelSpeeds[self.MotorType.kFrontRight] = -xIn + yIn - rotation
        wheelSpeeds[self.MotorType.kRearLeft] = -xIn + yIn + rotation
        wheelSpeeds[self.MotorType.kRearRight] = xIn + yIn - rotation

        RobotDrive.normalize(wheelSpeeds)

        self.frontLeftMotor.set(wheelSpeeds[self.MotorType.kFrontLeft] * self.maxOutput)
        self.frontRightMotor.set(
            wheelSpeeds[self.MotorType.kFrontRight] * self.maxOutput
        )
        self.rearLeftMotor.set(wheelSpeeds[self.MotorType.kRearLeft] * self.maxOutput)
        self.rearRightMotor.set(wheelSpeeds[self.MotorType.kRearRight] * self.maxOutput)

        self.feed()
Ejemplo n.º 51
0
    def launch(cls, vision_py: Optional[str] = None) -> None:
        """
            Launches the CameraServer process in autocapture mode or
            using a user-specified python script
        
            :param vision_py: If specified, this is the relative path to
                              a filename with a function in it
                              
            Example usage::
            
                wpilib.CameraServer.launch("vision.py:main")
            
            .. warning:: You must have robotpy-cscore installed, or this
                         function will fail without returning an error
                         (you will see an error in the console).
                         
        """

        if cls._launched:
            return

        cls._launched = True

        if hal.isSimulation():
            logger.info("Would launch CameraServer with vision_py=%s", vision_py)
            cls._alive = True
        else:
            logger.info("Launching CameraServer process")

            # Launch the cscore launcher in a separate process
            import sys

            args = [sys.executable, "-m", "cscore"]

            # TODO: Get accurate reporting data from the other cscore process. For
            # now, just differentiate between users with a custom py file and those
            # who do not. cscore handle values indicate type with bits 24-30

            if vision_py:
                if not vision_py.startswith("/"):
                    vision_py = "/home/lvuser/py/" + vision_py
                args.append(vision_py)
                hal.report(hal.UsageReporting.kResourceType_PCVideoServer, 0x51)
            else:
                hal.report(hal.UsageReporting.kResourceType_PCVideoServer, 0x52)

            # We open a pipe to it so that when this process exits, it dies
            proc = subprocess.Popen(
                args, close_fds=True, stdin=subprocess.PIPE, cwd="/home/lvuser/py"
            )
            th = threading.Thread(target=cls._monitor_child, args=(proc,))
            th.daemon = True
            th.start()
 def __init__(self):
     self.channelIndex = -1
     with self.mutex:
         for i, v in enumerate(self.filterAllocated):
             if not v:
                 self.channelIndex = i
                 self.filterAllocated[i] = True
                 hal.report(hal.UsageReporting.kResourceType_DigitalFilter,
                            self.channelIndex, 0)
                 break
         else:
             raise ValueError("No more filters available")
Ejemplo n.º 53
0
    def driveCartesian(
        self, ySpeed: float, xSpeed: float, zRotation: float, gyroAngle: float = 0.0
    ) -> None:
        """Drive method for Mecanum platform.

        Angles are measured clockwise from the positive X axis. The robot's speed is independent
        from its angle or rotation rate.

        :param ySpeed: The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
        :param xSpeed: The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
        :param zRotation: The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is positive.
        :param gyroAngle: The current angle reading from the gyro in degrees around the Z axis. Use
                          this to implement field-oriented controls.
        """
        if not self.reported:
            hal.report(
                hal.UsageReporting.kResourceType_RobotDrive,
                4,
                hal.UsageReporting.kRobotDrive2_MecanumCartesian,
            )
            self.reported = True

        ySpeed = RobotDriveBase.limit(ySpeed)
        ySpeed = RobotDriveBase.applyDeadband(ySpeed, self.deadband)

        xSpeed = RobotDriveBase.limit(xSpeed)
        xSpeed = RobotDriveBase.applyDeadband(xSpeed, self.deadband)

        # Compensate for gyro angle
        input = Vector2d(ySpeed, xSpeed)
        input.rotate(gyroAngle)

        wheelSpeeds = [
            # Front Left
            input.x + input.y + zRotation,
            # Rear Left
            -input.x + input.y + zRotation,
            # Front Right
            -input.x + input.y - zRotation,
            # Rear Right
            input.x + input.y - zRotation,
        ]

        RobotDriveBase.normalize(wheelSpeeds)

        wheelSpeeds = [speed * self.maxOutput for speed in wheelSpeeds]

        self.frontLeftMotor.set(wheelSpeeds[0])
        self.rearLeftMotor.set(wheelSpeeds[1])
        self.frontRightMotor.set(wheelSpeeds[2] * self.rightSideInvertMultiplier)
        self.rearRightMotor.set(wheelSpeeds[3] * self.rightSideInvertMultiplier)

        self.feed()
    def __init__(self, port):
        '''
        :param port: The port on the driver station that the controller is
            plugged into.
        :type  port: int
        '''
    
        warnings.warn('robotpy_ext.control.xbox_controller is deprecated, use wpilib.XboxController instead', category=DeprecationWarning, stacklevel=2)

        self.ds = wpilib.DriverStation.getInstance()
        self.port = port
        
        hal.report(hal.HALUsageReporting.kResourceType_Joystick, port)
Ejemplo n.º 55
0
 def __init__(self, module: Optional[int] = None) -> None:
     """Makes a new instance of the compressor using the provided CAN device ID.
     
     :param module: The PCM CAN device ID. (0 - 62 inclusive)
     """
     super().__init__()
     self.table = None
     if module is None:
         module = SensorUtil.getDefaultSolenoidModule()
     self.compressorHandle = hal.initializeCompressor(module)
     hal.report(hal.UsageReporting.kResourceType_Compressor, module)
     self.setName("Compressor", module)
     self.module = module
Ejemplo n.º 56
0
    def __init__(self, period: Optional[float] = None) -> None:
        if period is None:
            period = TimedRobot.kDefaultPeriod
        super().__init__(period)
        hal.report(
            hal.UsageReporting.kResourceType_Framework,
            hal.UsageReporting.kFramework_Timed,
        )

        self._expirationTime = 0
        self._notifier = hal.initializeNotifier()

        Resource._add_global_resource(self)
    def startCompetition(self):
        """
        Provide an alternate "main loop" via startCompetition(). Rewritten
        from IterativeRobot for readability and to initialize scheduler.
        """

        hal.report(hal.HALUsageReporting.kResourceType_Framework,
                   hal.HALUsageReporting.kFramework_Iterative)

        self.scheduler = Scheduler.getInstance()
        self.robotInit()

        # Tell the DS that the robot is ready to be enabled
        hal.observeUserProgramStarting()

        # loop forever, calling the appropriate mode-dependent function
        while True:
            if self.ds.isDisabled():
                hal.observeUserProgramDisabled()
                self.disabledInit()
                while self.ds.isDisabled():
                    self.disabledPeriodic()
                    self.ds.waitForData()

            elif self.ds.isAutonomous():
                hal.observeUserProgramAutonomous()
                self.autonomousInit()
                while self.ds.isEnabled() and self.ds.isAutonomous():
                    self.autonomousPeriodic()
                    self.ds.waitForData()

            elif self.ds.isTest():
                hal.observeUserProgramTest()
                LiveWindow.setEnabled(True)

                self.testInit()
                while self.ds.isEnabled() and self.ds.isTest():
                    self.testPeriodic()
                    self.ds.waitForData()

                LiveWindow.setEnabled(False)

            else:
                hal.observeUserProgramTeleop()
                self.teleopInit()
                # isOperatorControl checks "not autonomous or test", so we need
                # to check isEnabled as well, since otherwise it will continue
                # looping while disabled.
                while self.ds.isEnabled() and self.ds.isOperatorControl():
                    self.teleopPeriodic()
                    self.ds.waitForData()
Ejemplo n.º 58
0
    def __init__(self, channel):
        """Create an instance of a Digital Input class. Creates a digital
        input given a channel.

        :param channel: the DIO channel for the digital input. 0-9 are on-board, 10-25 are on the MXP
        :type  channel: int
        """
        # Store the channel and generate the handle in the constructor of the parent class
        # This is different from the Java implementation
        super().__init__(channel, True)

        hal.report(hal.UsageReporting.kResourceType_DigitalInput,
                      channel)
        LiveWindow.addSensor("DigitalInput", channel, self)
    def __init__(self, port):
        """Construct an instance of an XBoxController. The XBoxController index is the USB port on the Driver Station.

        :param port: The port on the Driver Station that the joystick is plugged into
        """

        super().__init__(port)
        self.ds = DriverStation.getInstance()

        self.outputs = 0
        self.leftRumble = 0
        self.rightRumble = 0

        hal.report(hal.UsageReporting.kResourceType_Joystick, port)