Пример #1
0
    def __init__(self, *args, **kwargs) -> None:
        """Encoder constructor. Construct a Encoder given a and b channels
        and optionally an index channel.

        The encoder will start counting immediately.

        The a, b, and optional index channel arguments may be either channel
        numbers or :class:`.DigitalSource` sources. There may also be a boolean
        reverseDirection, and an encodingType according to the following
        list.
        
        - aSource, bSource
        - aSource, bSource, reverseDirection
        - aSource, bSource, reverseDirection, encodingType
        - aSource, bSource, indexSource, reverseDirection
        - aSource, bSource, indexSource
        - aChannel, bChannel
        - aChannel, bChannel, reverseDirection
        - aChannel, bChannel, reverseDirection, encodingType
        - aChannel, bChannel, indexChannel, reverseDirection
        - aChannel, bChannel, indexChannel

        For positional arguments, if the passed object has a
        `getPortHandleForRouting` function, it is assumed to be a DigitalSource.

        Alternatively, sources and/or channels may be passed as keyword
        arguments.  The behavior of specifying both a source and a number
        for the same channel is undefined, as is passing both a positional
        and a keyword argument for the same channel.

        In addition, keyword parameters may be provided for reverseDirection
        and inputType.

        :param aSource: The source that should be used for the a channel.
        :type aSource: :class:`.DigitalSource`
        :param bSource: The source that should be used for the b channel.
        :type bSource: :class:`.DigitalSource`
        :param indexSource: The source that should be used for the index
            channel.
        :type indexSource: :class:`.DigitalSource`
        :param aChannel: The digital input index that should be used for
            the a channel.
        :type aChannel: int
        :param bChannel: The digital input index that should be used for
            the b channel.
        :type bChannel: int
        :param indexChannel: The digital input index that should be used
            for the index channel.
        :type indexChannel: int
        :param reverseDirection:
            Represents the orientation of the encoder and inverts the
            output values if necessary so forward represents positive
            values.  Defaults to False if unspecified.
        :type reverseDirection: bool
        :param encodingType:
            Either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If
            4X is selected, then an encoder FPGA object is used and the
            returned counts will be 4x the encoder spec'd value since all
            rising and falling edges are counted. If 1X or 2X are selected
            then a counter object will be used and the returned value will
            either exactly match the spec'd count or be double (2x) the
            spec'd count.  Defaults to k4X if unspecified.
        :type encodingType: :class:`Encoder.EncodingType`
        """
        super().__init__()
        a_source_arg = ("aSource", HasAttribute("getPortHandleForRouting"))
        b_source_arg = ("bSource", HasAttribute("getPortHandleForRouting"))
        index_source_arg = ("indexSource",
                            HasAttribute("getPortHandleForRouting"))
        a_channel_arg = ("aChannel", int)
        b_channel_arg = ("bChannel", int)
        index_channel_arg = ("indexChannel", int)

        # fmt: off
        argument_templates = [
            [a_source_arg, b_source_arg],
            [a_source_arg, b_source_arg, ("reverseDirection", bool)],
            [
                a_source_arg, b_source_arg, ("reverseDirection", bool),
                ("encodingType", int)
            ], [a_source_arg, b_source_arg, index_source_arg],
            [
                a_source_arg, b_source_arg, index_source_arg,
                ("reverseDirection", bool)
            ], [a_channel_arg, b_channel_arg],
            [a_channel_arg, b_channel_arg, ("reverseDirection", bool)],
            [
                a_channel_arg, b_channel_arg, ("reverseDirection", bool),
                ("encodingType", int)
            ], [a_channel_arg, b_channel_arg, index_channel_arg],
            [
                a_channel_arg, b_channel_arg, index_channel_arg,
                ("reverseDirection", bool)
            ]
        ]
        # fmt: on

        _, results = match_arglist("Encoder.__init__", args, kwargs,
                                   argument_templates)

        # keyword arguments
        aSource = results.pop("aSource", None)
        bSource = results.pop("bSource", None)
        indexSource = results.pop("indexSource", None)
        aChannel = results.pop("aChannel", None)
        bChannel = results.pop("bChannel", None)
        indexChannel = results.pop("indexChannel", None)
        reverseDirection = results.pop("reverseDirection", False)
        encodingType = results.pop("encodingType", self.EncodingType.k4X)

        # convert channels into sources
        self.allocatedA = False
        self.allocatedB = False
        self.allocatedIndex = False

        if aSource is None:
            if aChannel is None:
                raise ValueError("didn't specify A channel")
            aSource = DigitalInput(aChannel)
            self.allocatedA = True
            self.addChild(aSource)
        if bSource is None:
            if bChannel is None:
                raise ValueError("didn't specify B channel")
            bSource = DigitalInput(bChannel)
            self.allocatedB = True
            self.addChild(bSource)
        if indexSource is None and indexChannel is not None:
            indexSource = DigitalInput(indexChannel)
            self.allocatedIndex = True
            self.addChild(indexSource)

        # save to instance variables
        self.aSource = aSource
        self.bSource = bSource
        self.indexSource = indexSource
        self.encodingType = encodingType
        self.pidSource = self.PIDSourceType.kDisplacement
        self._encoder = None
        self.counter = None
        self.speedEntry = None
        self.distanceEntry = None
        self.distancePerTickEntry = None

        self._encoder = hal.initializeEncoder(
            aSource.getPortHandleForRouting(),
            aSource.getAnalogTriggerTypeForRouting(),
            bSource.getPortHandleForRouting(),
            bSource.getAnalogTriggerTypeForRouting(),
            reverseDirection,
            encodingType,
        )

        self.__finalizer = weakref.finalize(self, _freeEncoder, self._encoder)

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

        if self.indexSource is not None:
            self.setIndexSource(self.indexSource)

        self.index = self.getFPGAIndex()
        hal.report(hal.UsageReporting.kResourceType_Encoder, self.index,
                   encodingType)
        self.setName("Encoder", self.index)
Пример #2
0
    def __init__(self, *args, **kwargs) -> None:
        """Encoder constructor. Construct a Encoder given a and b channels
        and optionally an index channel.

        The encoder will start counting immediately.

        The a, b, and optional index channel arguments may be either channel
        numbers or :class:`.DigitalSource` sources. There may also be a boolean
        reverseDirection, and an encodingType according to the following
        list.
        
        - aSource, bSource
        - aSource, bSource, reverseDirection
        - aSource, bSource, reverseDirection, encodingType
        - aSource, bSource, indexSource, reverseDirection
        - aSource, bSource, indexSource
        - aChannel, bChannel
        - aChannel, bChannel, reverseDirection
        - aChannel, bChannel, reverseDirection, encodingType
        - aChannel, bChannel, indexChannel, reverseDirection
        - aChannel, bChannel, indexChannel

        For positional arguments, if the passed object has a
        `getPortHandleForRouting` function, it is assumed to be a DigitalSource.

        Alternatively, sources and/or channels may be passed as keyword
        arguments.  The behavior of specifying both a source and a number
        for the same channel is undefined, as is passing both a positional
        and a keyword argument for the same channel.

        In addition, keyword parameters may be provided for reverseDirection
        and inputType.

        :param aSource: The source that should be used for the a channel.
        :type aSource: :class:`.DigitalSource`
        :param bSource: The source that should be used for the b channel.
        :type bSource: :class:`.DigitalSource`
        :param indexSource: The source that should be used for the index
            channel.
        :type indexSource: :class:`.DigitalSource`
        :param aChannel: The digital input index that should be used for
            the a channel.
        :type aChannel: int
        :param bChannel: The digital input index that should be used for
            the b channel.
        :type bChannel: int
        :param indexChannel: The digital input index that should be used
            for the index channel.
        :type indexChannel: int
        :param reverseDirection:
            Represents the orientation of the encoder and inverts the
            output values if necessary so forward represents positive
            values.  Defaults to False if unspecified.
        :type reverseDirection: bool
        :param encodingType:
            Either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If
            4X is selected, then an encoder FPGA object is used and the
            returned counts will be 4x the encoder spec'd value since all
            rising and falling edges are counted. If 1X or 2X are selected
            then a counter object will be used and the returned value will
            either exactly match the spec'd count or be double (2x) the
            spec'd count.  Defaults to k4X if unspecified.
        :type encodingType: :class:`Encoder.EncodingType`
        """
        super().__init__()
        a_source_arg = ("aSource", HasAttribute("getPortHandleForRouting"))
        b_source_arg = ("bSource", HasAttribute("getPortHandleForRouting"))
        index_source_arg = ("indexSource", HasAttribute("getPortHandleForRouting"))
        a_channel_arg = ("aChannel", int)
        b_channel_arg = ("bChannel", int)
        index_channel_arg = ("indexChannel", int)

        # fmt: off
        argument_templates = [[a_source_arg, b_source_arg],
                              [a_source_arg, b_source_arg, ("reverseDirection", bool)],
                              [a_source_arg, b_source_arg, ("reverseDirection", bool), ("encodingType", int)],
                              [a_source_arg, b_source_arg, index_source_arg],
                              [a_source_arg, b_source_arg, index_source_arg, ("reverseDirection", bool)],
                              [a_channel_arg, b_channel_arg],
                              [a_channel_arg, b_channel_arg, ("reverseDirection", bool)],
                              [a_channel_arg, b_channel_arg, ("reverseDirection", bool), ("encodingType", int)],
                              [a_channel_arg, b_channel_arg, index_channel_arg],
                              [a_channel_arg, b_channel_arg, index_channel_arg, ("reverseDirection", bool)]]
        # fmt: on

        _, results = match_arglist("Encoder.__init__", args, kwargs, argument_templates)

        # keyword arguments
        aSource = results.pop("aSource", None)
        bSource = results.pop("bSource", None)
        indexSource = results.pop("indexSource", None)
        aChannel = results.pop("aChannel", None)
        bChannel = results.pop("bChannel", None)
        indexChannel = results.pop("indexChannel", None)
        reverseDirection = results.pop("reverseDirection", False)
        encodingType = results.pop("encodingType", self.EncodingType.k4X)

        # convert channels into sources
        self.allocatedA = False
        self.allocatedB = False
        self.allocatedIndex = False

        if aSource is None:
            if aChannel is None:
                raise ValueError("didn't specify A channel")
            aSource = DigitalInput(aChannel)
            self.allocatedA = True
            self.addChild(aSource)
        if bSource is None:
            if bChannel is None:
                raise ValueError("didn't specify B channel")
            bSource = DigitalInput(bChannel)
            self.allocatedB = True
            self.addChild(bSource)
        if indexSource is None and indexChannel is not None:
            indexSource = DigitalInput(indexChannel)
            self.allocatedIndex = True
            self.addChild(indexSource)

        # save to instance variables
        self.aSource = aSource
        self.bSource = bSource
        self.indexSource = indexSource
        self.encodingType = encodingType
        self.pidSource = self.PIDSourceType.kDisplacement
        self.encoder = None
        self.counter = None
        self.speedEntry = None
        self.distanceEntry = None
        self.distancePerTickEntry = None

        self.encoder = hal.initializeEncoder(
            aSource.getPortHandleForRouting(),
            aSource.getAnalogTriggerTypeForRouting(),
            bSource.getPortHandleForRouting(),
            bSource.getAnalogTriggerTypeForRouting(),
            reverseDirection,
            encodingType,
        )

        self.__finalizer = weakref.finalize(self, _freeEncoder, self.encoder)

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

        if self.indexSource is not None:
            self.setIndexSource(self.indexSource)

        self.index = self.getFPGAIndex()
        hal.report(hal.UsageReporting.kResourceType_Encoder, self.index, encodingType)
        self.setName("Encoder", self.index)