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 CTRE Power 019 * Distribution Panel (PDP) or REV Power Distribution Hub (PDH) 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 object. 040 * 041 * @param module The CAN ID of the PDP/PDH. 042 * @param moduleType Module type (CTRE or REV). 043 */ 044 @SuppressWarnings("this-escape") 045 public PowerDistribution(int module, ModuleType moduleType) { 046 m_handle = PowerDistributionJNI.initialize(module, moduleType.value); 047 m_module = PowerDistributionJNI.getModuleNumber(m_handle); 048 049 HAL.report(tResourceType.kResourceType_PDP, m_module + 1); 050 SendableRegistry.addLW(this, "PowerDistribution", m_module); 051 } 052 053 /** 054 * Constructs a PowerDistribution object. 055 * 056 * <p>Detects the connected PDP/PDH using the default CAN ID (0 for CTRE and 1 for REV). 057 */ 058 @SuppressWarnings("this-escape") 059 public PowerDistribution() { 060 m_handle = PowerDistributionJNI.initialize(kDefaultModule, PowerDistributionJNI.AUTOMATIC_TYPE); 061 m_module = PowerDistributionJNI.getModuleNumber(m_handle); 062 063 HAL.report(tResourceType.kResourceType_PDP, m_module + 1); 064 SendableRegistry.addLW(this, "PowerDistribution", m_module); 065 } 066 067 @Override 068 public void close() { 069 SendableRegistry.remove(this); 070 } 071 072 /** 073 * Gets the number of channels for this power distribution object. 074 * 075 * @return Number of output channels (16 for PDP, 24 for PDH). 076 */ 077 public int getNumChannels() { 078 return PowerDistributionJNI.getNumChannels(m_handle); 079 } 080 081 /** 082 * Query the input voltage of the PDP/PDH. 083 * 084 * @return The voltage in volts 085 */ 086 public double getVoltage() { 087 return PowerDistributionJNI.getVoltage(m_handle); 088 } 089 090 /** 091 * Query the temperature of the PDP/PDH. 092 * 093 * @return The temperature in degrees Celsius 094 */ 095 public double getTemperature() { 096 return PowerDistributionJNI.getTemperature(m_handle); 097 } 098 099 /** 100 * Query the current of a single channel of the PDP/PDH. 101 * 102 * @param channel The channel (0-15 for PDP, 0-23 for PDH) to query 103 * @return The current of the channel in Amperes 104 */ 105 public double getCurrent(int channel) { 106 return PowerDistributionJNI.getChannelCurrent(m_handle, channel); 107 } 108 109 /** 110 * Query the current of all monitored channels. 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 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 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/PDH 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 /** 156 * Gets the module type for this power distribution object. 157 * 158 * @return The module type 159 */ 160 public ModuleType getType() { 161 int type = PowerDistributionJNI.getType(m_handle); 162 if (type == PowerDistributionJNI.REV_TYPE) { 163 return ModuleType.kRev; 164 } else { 165 return ModuleType.kCTRE; 166 } 167 } 168 169 /** 170 * Gets whether the PDH switchable channel is turned on or off. Returns false with the CTRE PDP. 171 * 172 * @return The output state of the PDH switchable channel 173 */ 174 public boolean getSwitchableChannel() { 175 return PowerDistributionJNI.getSwitchableChannel(m_handle); 176 } 177 178 /** 179 * Sets the PDH switchable channel on or off. Does nothing with the CTRE PDP. 180 * 181 * @param enabled Whether to turn the PDH switchable channel on or off 182 */ 183 public void setSwitchableChannel(boolean enabled) { 184 PowerDistributionJNI.setSwitchableChannel(m_handle, enabled); 185 } 186 187 public PowerDistributionVersion getVersion() { 188 return PowerDistributionJNI.getVersion(m_handle); 189 } 190 191 public PowerDistributionFaults getFaults() { 192 return PowerDistributionJNI.getFaults(m_handle); 193 } 194 195 public PowerDistributionStickyFaults getStickyFaults() { 196 return PowerDistributionJNI.getStickyFaults(m_handle); 197 } 198 199 @Override 200 public void initSendable(SendableBuilder builder) { 201 builder.setSmartDashboardType("PowerDistribution"); 202 int numChannels = getNumChannels(); 203 for (int i = 0; i < numChannels; ++i) { 204 final int chan = i; 205 builder.addDoubleProperty( 206 "Chan" + i, () -> PowerDistributionJNI.getChannelCurrentNoError(m_handle, chan), null); 207 } 208 builder.addDoubleProperty( 209 "Voltage", () -> PowerDistributionJNI.getVoltageNoError(m_handle), null); 210 builder.addDoubleProperty( 211 "TotalCurrent", () -> PowerDistributionJNI.getTotalCurrent(m_handle), null); 212 builder.addBooleanProperty( 213 "SwitchableChannel", 214 () -> PowerDistributionJNI.getSwitchableChannelNoError(m_handle), 215 value -> PowerDistributionJNI.setSwitchableChannel(m_handle, value)); 216 } 217}