CommandScheduler loop overruns -- one potential cause

We spent a couple of hours this evening tracking down this behavior and I thought it was worth calling attention to it, since it is easily fixed once it is identified.

In WPILib 2024 there was a change to the way CommandXboxController.button() works, relative to how it worked in 2023. This affects both C++ and Java robot code.

If your code periodically calls, for example, m_controller.a().getAsBoolean() to poll the a button of a controller, it will eventually begin to suffer constant CommandScheduler loop overruns with most of the time being taken by buttons.run() as shown in this image from the DS Log Viewer.

The CPU utilization also increases rapidly as shown in this image.

There is an allwpilib issue (Periodically calling CommandXboxController button functions causes CommandScheduler loop overruns · Issue #5903 · wpilibsuite/allwpilib · GitHub) that thoroughly explains what is happening and how to easily change your code to eliminate the loop overruns and high cpu use.

5 Likes

So this can just be solved by either saving the trigger as a variable or calling controller.getHID.getAButton(); ?

1 Like

Yes, as far as I understand the problem, that is true.

1 Like

Thanks for posting this, I can envision this being a large problem for teams that are doing drive modifications.

For example, we like to give the driver a button that flips the robot controls front to back (meaning, the front becomes the back, and vice versa). We have in the past done that by polling the button state in the default drive method which would have eventually seen these loop overruns.

Looks like controller.getHID.getAButton(); Retruns the state of the button. Lets say you want to recreate toggle on true with this. What is your best bet?

This issue only affects periodically calling controller functions that return a Trigger or a BooleanEvent. It is still safe to use toggleOnTrue in your configureBindings function, since that is only run once.

If you do want to recreate that behavior in a periodic loop, you would use m_controller.getHID().getAButtonPressed() to check when the button is pressed and use that to flip a boolean in your robot code. In general, though, prefer using Triggers to run Commands.

Thanks… We are having these overruns and I am just trying to figure out where they are coming from.

Looks like maybe something in a vision is causing some issue as well as robot period. Could whileTrue() or onTrue() be an issue?

whileTrue() and onTrue() calls would not normally be an issue because they are not called on every robot iteration (i.e. in an execute() or periodic method()).
It is worth pointing out that loop overruns can be caused by many things.

The cause described here is very specifically indicated by seeing buttons.run() listed in the overrun messages as taking 20ms (or at least close to that) and also seeing the cpu utilization increasing in the DS log as in the image that I first posted. If you don’t see those, this is not the cause of your overrun problem and you should look for other things.

2 Likes

Thanks… That is what I needed to know.

We were seeing similar issue, button.runs() loop overrun messages. Looked at the usb tab on driver station and tried rescanning. But then I noticed that order of controllers listed. We had tried out different controllers during build season. The one we settled on was listed but as controller 3. The controllers we had tried in past were listed as 0,1,2 but grayed out. I dragged 3 to 0 and all our overrun messages disappeared. Another clue was an error message about a trigger not being present on joystick port 0. Hope that helps anyone with similar issue.

I found ours. We were putting closed loop error with a . Wait for refresh and that was causing the issue

Hi! We are a new team (well, new coach and new to swerve drive). We are saving our button bindings as either Trigger or Button objects, rather than using CommandXboxController objects. Our Triggers use toggleOnTrue(), and our Buttons chain whileTrue() and whileFalse() together. We are also experiencing loop overrun issues after about 90-100 seconds of continuous teleop, resulting in the robot losing function. We are unsure if our issues lie in the Button objects, Trigger objects, or both. Any advice would be immensely appreciated!

1 Like

What subsystem is causing your overruns. Our was not related to buttons but rather things we were doing in periodic in those subsystems

1 Like

We are having an issue in our TalonEncoderSubsystem, which controls our intake and outtake motors. We also house a color sensor in this subsystem, that we’ve installed to see if a note is present in our intake. In the periodic function of this subsystem, we are constantly updating the value read in by our color sensor. That is the only thing occurring in this periodic method.

One thought I have would be to decrease the number of times we check for color by using a Timer and an if statement of sorts. I’m also wondering if there’s a way to read in these values without the use of the periodic function. (The idea is that a driver taps a button and our intake motor spins for an undetermined amount of time, until the sensor detects that it sees the color orange).

Any thoughts?

What color sensor? If it’s an I2C one, the onboard port has major issues (don’t use it) and teams have reported long delays in reading on the MXP one as well.

We are currently testing, and I can say with certainty that we have a color sensor issue (we use an I2C sensor). If I2Cs aren’t the way to go, and neither are MXPs, then what kind of sensor should we use?

You can use a I2C sensor safely if it’s not hooked up to a Rio port. A workaround that has worked for many people has been to use a Pi Pico (you can buy a pack of 2 for $14 at Amazon) and this code to interface with the sensor: GitHub - ThadHouse/picocolorsensor: Rev V3 Library for Raspberry Pi Pico

1 Like

Beam-break sensors are viable for detecting presence of notes. They connect to DIO ports on the RoboRio completely avoiding the I2C hassles. You need to have wiring on both sides of the intake though so they are less convenient in that regard.
Example: IR Break Beam Sensors with Premium Wire Header Ends - 3mm LEDs : ID 2167 : $2.95 : Adafruit Industries, Unique & fun DIY electronics and kits

1 Like

Thanks, Crofts ordered some at the end of our meeting. The color sensor was what we had on hand and we’ve only just started running the robot for long enough to see the lockups happen.

The symptoms we got are basically that the responses to gamepad inputs are delayed or never happen, we get the “commandscheduler loop overrun” error, and the CPU utilization spikes kind of like it does in the OP here. So it seemed like this was the right issue, except that we weren’t using xbox controllers (we use Logitech gamepads and the joystick class). This and related posts did give us a better understanding of the DS logs, so we were able to isolate the issue to the particular subsystem periodic loop that was the issue (running around 0.27 s) and determine that if we moved where in the code the color sensor is being read, the problem moved with it.

It’ll be a bit of scramble to get the beam break sensor implemented for Thursday’s competition but I expect that to be much more bulletproof going forward.

We have been seeing exactly this. (Well, not exactly— we’ve been seeing buttons.run take upwards of 80 ms). This led to a terrifying issue we’ve been confused about for weeks where the robot would sometimes drive randomly on enable— DS logs show the loop overrun causing the robot to stop sending mode status updates.