-
Notifications
You must be signed in to change notification settings - Fork 4
Brownout
https://github.com/spacecookies1868/frc2016/blob/master/robot/trunk/src/PowerController.cpp
https://www.chiefdelphi.com/t/brownout-prevention/152001/
https://docs.wpilib.org/en/stable/docs/software/roborio-info/roborio-brownouts.html
https://docs.wpilib.org/en/stable/docs/software/can-devices/power-distribution-panel.html
I think the general approach is to determine the amount of current available for use, then divide that among each mechanism/subsystem. If the sum of the calculated currents for each subsystem is over the amount available, reduce the amount of current given to certain feature(s).
Brownout occurs when voltage drops below 7V, so you need to proactively calculate the amount of current that each subsystem is attempting to draw and scale that value down if it's too much (I think). WPILib's documentation on detecting and avoiding RoboRIO brownouts (link here). It would probably be very helpful to read, especially the section on "Avoiding Brownouts" with the four steps.
Unfortunately WPILib doesn't have example code (at least, none that I could find), but I did stumble upon a ChiefDelphi thread (link here) which explains some things you can do "electrically" to prevent brownout. For code, though, @chloe's answer led me to SpaceCookies code (FRC Team 1868) where they actually did implement a PowerController (link here). Their code might be a good reference -- read her answer first for more context.
I'm not really sure how to implement brownout stuff, maybe I didn't look hard enough but there do not seem to be a whole lot of resources available on the interwebs. However -- you can take a look at the code I started (in branch brownout
). I'll summarize some relevant stuff from the code here:
- You need to initialize a
PowerDistributionPanel
object:
PowerDistributionPanel PDP = new PowerDistributionPanel(0);
Yes the number is 0 for a reason: "To enable voltage and current logging in the Driver Station, the CAN ID for the PDP must be 0."
- Then, you can do things like
PDP.getVoltage()
,PDP.getTotalCurrent()
andPDP.getCurrent(0 or whatever number you want)
where the number parameter refers to the PDP channel.
All of this is in the documentation for the PDP here.
As for the structure of the code in the brownout
branch:
I attempted to implement a PowerController
class which, for each subsystem, gets the amount of current drawn by the subsystem. Then it theoretically does some magic calculations based on priority and what not (it actually just reduces the amount of power given to the drivetrain if current draw is over the available current).
There are a couple of issues so far:
- Ethan brought up a good point about how brownout prevention may also need to consider the amount of power drawn by pfft (PCM stuff)
Ethan's thoughts/message: What I was imaging before is for us to make our own Motor class so that we can separate the subsystem's target power setting from the actual motor setting, and these two values will be different if we're trying to draw too much power. So in subsystem.update it does GRTMotor.setPower to request a certain amount of power, and in PowerController.update() we can actually distribute how much power we actually have based on those requests and our pretuned weights/priorities
- Also, the goal of brownout prevention is to prevent brownout, not just detect it and scale back motor powers. Therefore you'll probably need to figure out some power-current relationship for the drivetrain motors, for example, so you can scale back motor powers before power is drawn in the subsystem.
- While talking to Phil, he brought up a few ideas:
- Turning on and off subsystems until they actually need to be used (ex: Climb)
- Ranking Subsystems by power usage to see where we can cut down voltage use(run by seth)
- Turning off the compressor/not using it at all in competition/just using the air tanks