001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.wpilibj; 006 007import edu.wpi.first.hal.FRCNetComm.tResourceType; 008import edu.wpi.first.hal.HAL; 009import edu.wpi.first.hal.PowerDistributionFaults; 010import edu.wpi.first.hal.PowerDistributionJNI; 011import edu.wpi.first.hal.PowerDistributionStickyFaults; 012import edu.wpi.first.hal.PowerDistributionVersion; 013import edu.wpi.first.util.sendable.Sendable; 014import edu.wpi.first.util.sendable.SendableBuilder; 015import edu.wpi.first.util.sendable.SendableRegistry; 016 017/** 018 * Class for getting voltage, current, temperature, power and energy from the Power Distribution 019 * Panel over CAN. 020 */ 021public class PowerDistribution implements Sendable, AutoCloseable { 022 private final int m_handle; 023 private final int m_module; 024 025 public static final int kDefaultModule = PowerDistributionJNI.DEFAULT_MODULE; 026 027 public enum ModuleType { 028 kCTRE(PowerDistributionJNI.CTRE_TYPE), 029 kRev(PowerDistributionJNI.REV_TYPE); 030 031 public final int value; 032 033 ModuleType(int value) { 034 this.value = value; 035 } 036 } 037 038 /** 039 * Constructs a PowerDistribution. 040 * 041 * @param module The CAN ID of the PDP. 042 * @param moduleType Module type (CTRE or REV). 043 */ 044 public PowerDistribution(int module, ModuleType moduleType) { 045 m_handle = PowerDistributionJNI.initialize(module, moduleType.value); 046 m_module = PowerDistributionJNI.getModuleNumber(m_handle); 047 048 HAL.report(tResourceType.kResourceType_PDP, m_module + 1); 049 SendableRegistry.addLW(this, "PowerDistribution", m_module); 050 } 051 052 /** 053 * Constructs a PowerDistribution. 054 * 055 * <p>Uses the default CAN ID (0 for CTRE and 1 for REV). 056 */ 057 public PowerDistribution() { 058 m_handle = PowerDistributionJNI.initialize(kDefaultModule, PowerDistributionJNI.AUTOMATIC_TYPE); 059 m_module = PowerDistributionJNI.getModuleNumber(m_handle); 060 061 HAL.report(tResourceType.kResourceType_PDP, m_module + 1); 062 SendableRegistry.addLW(this, "PowerDistribution", m_module); 063 } 064 065 @Override 066 public void close() { 067 SendableRegistry.remove(this); 068 } 069 070 /** 071 * Gets the number of channel for this power distribution. 072 * 073 * @return Number of output channels. 074 */ 075 public int getNumChannels() { 076 return PowerDistributionJNI.getNumChannels(m_handle); 077 } 078 079 /** 080 * Query the input voltage of the PDP. 081 * 082 * @return The voltage of the PDP in volts 083 */ 084 public double getVoltage() { 085 return PowerDistributionJNI.getVoltage(m_handle); 086 } 087 088 /** 089 * Query the temperature of the PDP. 090 * 091 * @return The temperature of the PDP in degrees Celsius 092 */ 093 public double getTemperature() { 094 return PowerDistributionJNI.getTemperature(m_handle); 095 } 096 097 /** 098 * Query the current of a single channel of the PDP. 099 * 100 * @param channel The PDP channel to query. 101 * @return The current of one of the PDP channels (channels 0-15) in Amperes 102 */ 103 public double getCurrent(int channel) { 104 double current = PowerDistributionJNI.getChannelCurrent(m_handle, channel); 105 106 return current; 107 } 108 109 /** 110 * Query the current of all monitored PDP channels (0-15). 111 * 112 * @return The current of all the channels in Amperes 113 */ 114 public double getTotalCurrent() { 115 return PowerDistributionJNI.getTotalCurrent(m_handle); 116 } 117 118 /** 119 * Query the total power drawn from the monitored PDP channels. 120 * 121 * @return the total power in Watts 122 */ 123 public double getTotalPower() { 124 return PowerDistributionJNI.getTotalPower(m_handle); 125 } 126 127 /** 128 * Query the total energy drawn from the monitored PDP channels. 129 * 130 * @return the total energy in Joules 131 */ 132 public double getTotalEnergy() { 133 return PowerDistributionJNI.getTotalEnergy(m_handle); 134 } 135 136 /** Reset the total energy to 0. */ 137 public void resetTotalEnergy() { 138 PowerDistributionJNI.resetTotalEnergy(m_handle); 139 } 140 141 /** Clear all PDP sticky faults. */ 142 public void clearStickyFaults() { 143 PowerDistributionJNI.clearStickyFaults(m_handle); 144 } 145 146 /** 147 * Gets module number (CAN ID). 148 * 149 * @return The module number (CAN ID). 150 */ 151 public int getModule() { 152 return m_module; 153 } 154 155 public boolean getSwitchableChannel() { 156 return PowerDistributionJNI.getSwitchableChannel(m_handle); 157 } 158 159 public void setSwitchableChannel(boolean enabled) { 160 PowerDistributionJNI.setSwitchableChannel(m_handle, enabled); 161 } 162 163 PowerDistributionVersion getVersion() { 164 return PowerDistributionJNI.getVersion(m_handle); 165 } 166 167 PowerDistributionFaults getFaults() { 168 return PowerDistributionJNI.getFaults(m_handle); 169 } 170 171 PowerDistributionStickyFaults getStickyFaults() { 172 return PowerDistributionJNI.getStickyFaults(m_handle); 173 } 174 175 @Override 176 public void initSendable(SendableBuilder builder) { 177 builder.setSmartDashboardType("PowerDistribution"); 178 int numChannels = getNumChannels(); 179 for (int i = 0; i < numChannels; ++i) { 180 final int chan = i; 181 builder.addDoubleProperty( 182 "Chan" + i, () -> PowerDistributionJNI.getChannelCurrentNoError(m_handle, chan), null); 183 } 184 builder.addDoubleProperty( 185 "Voltage", () -> PowerDistributionJNI.getVoltageNoError(m_handle), null); 186 builder.addDoubleProperty( 187 "TotalCurrent", () -> PowerDistributionJNI.getTotalCurrent(m_handle), null); 188 builder.addBooleanProperty( 189 "SwitchableChannel", 190 () -> PowerDistributionJNI.getSwitchableChannelNoError(m_handle), 191 value -> PowerDistributionJNI.setSwitchableChannel(m_handle, value)); 192 } 193}