Skip to content

Conversation

@MichaelLesirge
Copy link
Contributor

@MichaelLesirge MichaelLesirge commented Oct 26, 2025

Add a simple tap counting filter for boolean streams.

The filter activates when the input has risen (transitioned from false to true, like when a button is tapped) the required number of times within the time window after the first rising edge. Once activated, the output remains true as long as the input is true. The tap count resets when the time window expires or when the input goes false after activation.

Example usage:

    xbox.a()
      .multiPress(2, 0.2) // Detect a double tap within 0.2 seconds
      .onTrue(Commands.print("Double tapped A button"));
      
     xbox.a()
      .debounce(0.2)
      .whileTrue(Commands.print("A held").repeatedly());

This is not a noise reduction and/or input smoothing filter, but it is similar in usage to debounce, so I believe it could be considered a filter, but am open to a better location.

I believe this would be a useful addition, as double/triple tapping a button is a common control option in games, yet is not often utilized by newer FRC teams. I believe adding it to WPILib in a standard way will allow more teams to make the most out of their controls.

@MichaelLesirge MichaelLesirge requested review from a team as code owners October 26, 2025 23:28
@github-actions
Copy link
Contributor

This PR modifies commands. Please open a corresponding PR in Python Commands and include a link to this PR.

@github-actions github-actions bot added component: command-based WPILib Command Based Library component: wpimath Math library labels Oct 26, 2025
@MichaelLesirge MichaelLesirge changed the title Multi tap filter and trigger modifier. Add multi tap boolean stream filter and multi tap trigger modifier Oct 26, 2025

namespace frc {
/**
* A simple tap counting filter for boolean streams. Requires that the boolean
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"tap" already has a specific meaning in DSP, so using an alternate meaning for this class name would be unwise.
https://dspguru.com/dsp/faqs/fir/basics/

The DriverStation class uses "press" for button presses.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MultipressDetector or PressSequenceDetector?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can think of it as a generic edge counter filter, where at least n edges must be detected within a particular time period for the filter to have a positive output. So EdgeCounterFilter could be a more accurate name than MultiTapFilter, and be applicable to more than just button presses.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What other situations would someone need that in?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe for detecting if some sort of sensor (beam break?) has a number of items pass though it in a time period, for detecting radio/brownout issues that tend to rapidly go on and off, or for detecting other oscillation issues.

I'm sure other tools could do those jobs, but just listing ideas.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This filter feels too niche to belong in wpimath's general filter library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think there is a space for it, maybe in the general command\button section of the library since it is really only meant for triggers, or do you think it would be best to leave it out?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make it a private implementation detail of the trigger factory.

Copy link
Member

@SamCarlberg SamCarlberg Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it complements Debouncer; instead of requiring a signal to be high for at least n seconds, it requires a signal to oscillate above a certain frequency for at least n seconds. The language needs to be more generic to belong in the filter library, though

@MichaelLesirge
Copy link
Contributor Author

I left it as a filter named EdgeCounterFilter for now, and renamed the trigger factory to .multiPress() since that is the main use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: command-based WPILib Command Based Library component: wpimath Math library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants