blob: ba4cb383c30347dc2c31ef1cb867ccdc097f9c72 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#include "frc/PowerDistribution.h"
6
7#include <fmt/format.h>
8#include <hal/FRCUsageReporting.h>
9#include <hal/Ports.h>
10#include <hal/PowerDistribution.h>
11#include <wpi/StackTrace.h>
12#include <wpi/sendable/SendableBuilder.h>
13#include <wpi/sendable/SendableRegistry.h>
14
15#include "frc/Errors.h"
16#include "frc/SensorUtil.h"
17
18static_assert(static_cast<HAL_PowerDistributionType>(
Austin Schuh812d0d12021-11-04 20:16:48 -070019 frc::PowerDistribution::ModuleType::kCTRE) ==
20 HAL_PowerDistributionType::HAL_PowerDistributionType_kCTRE);
21static_assert(static_cast<HAL_PowerDistributionType>(
22 frc::PowerDistribution::ModuleType::kRev) ==
23 HAL_PowerDistributionType::HAL_PowerDistributionType_kRev);
24static_assert(frc::PowerDistribution::kDefaultModule ==
25 HAL_DEFAULT_POWER_DISTRIBUTION_MODULE);
26
27using namespace frc;
28
Austin Schuh75263e32022-02-22 18:05:32 -080029PowerDistribution::PowerDistribution() {
30 auto stack = wpi::GetStackTrace(1);
31
32 int32_t status = 0;
33 m_handle = HAL_InitializePowerDistribution(
34 kDefaultModule,
35 HAL_PowerDistributionType::HAL_PowerDistributionType_kAutomatic,
36 stack.c_str(), &status);
37 FRC_CheckErrorStatus(status, "Module {}", kDefaultModule);
38 m_module = HAL_GetPowerDistributionModuleNumber(m_handle, &status);
39 FRC_ReportError(status, "Module {}", m_module);
40
41 HAL_Report(HALUsageReporting::kResourceType_PDP, m_module + 1);
42 wpi::SendableRegistry::AddLW(this, "PowerDistribution", m_module);
43}
Austin Schuh812d0d12021-11-04 20:16:48 -070044
45PowerDistribution::PowerDistribution(int module, ModuleType moduleType) {
46 auto stack = wpi::GetStackTrace(1);
47
48 int32_t status = 0;
49 m_handle = HAL_InitializePowerDistribution(
50 module, static_cast<HAL_PowerDistributionType>(moduleType), stack.c_str(),
51 &status);
52 FRC_CheckErrorStatus(status, "Module {}", module);
53 m_module = HAL_GetPowerDistributionModuleNumber(m_handle, &status);
54 FRC_ReportError(status, "Module {}", module);
55
56 HAL_Report(HALUsageReporting::kResourceType_PDP, m_module + 1);
57 wpi::SendableRegistry::AddLW(this, "PowerDistribution", m_module);
58}
59
60PowerDistribution::~PowerDistribution() {
61 if (m_handle != HAL_kInvalidHandle) {
62 HAL_CleanPowerDistribution(m_handle);
63 m_handle = HAL_kInvalidHandle;
64 }
65}
66
67double PowerDistribution::GetVoltage() const {
68 int32_t status = 0;
69 double voltage = HAL_GetPowerDistributionVoltage(m_handle, &status);
70 FRC_ReportError(status, "Module {}", m_module);
71 return voltage;
72}
73
74double PowerDistribution::GetTemperature() const {
75 int32_t status = 0;
76 double temperature = HAL_GetPowerDistributionTemperature(m_handle, &status);
77 FRC_ReportError(status, "Module {}", m_module);
78 return temperature;
79}
80
81double PowerDistribution::GetCurrent(int channel) const {
82 int32_t status = 0;
83 double current =
84 HAL_GetPowerDistributionChannelCurrent(m_handle, channel, &status);
85 FRC_ReportError(status, "Module {} Channel {}", m_module, channel);
86
87 return current;
88}
89
90double PowerDistribution::GetTotalCurrent() const {
91 int32_t status = 0;
92 double current = HAL_GetPowerDistributionTotalCurrent(m_handle, &status);
93 FRC_ReportError(status, "Module {}", m_module);
94 return current;
95}
96
97double PowerDistribution::GetTotalPower() const {
98 int32_t status = 0;
99 double power = HAL_GetPowerDistributionTotalPower(m_handle, &status);
100 FRC_ReportError(status, "Module {}", m_module);
101 return power;
102}
103
104double PowerDistribution::GetTotalEnergy() const {
105 int32_t status = 0;
106 double energy = HAL_GetPowerDistributionTotalEnergy(m_handle, &status);
107 FRC_ReportError(status, "Module {}", m_module);
108 return energy;
109}
110
111void PowerDistribution::ResetTotalEnergy() {
112 int32_t status = 0;
113 HAL_ResetPowerDistributionTotalEnergy(m_handle, &status);
114 FRC_ReportError(status, "Module {}", m_module);
115}
116
117void PowerDistribution::ClearStickyFaults() {
118 int32_t status = 0;
119 HAL_ClearPowerDistributionStickyFaults(m_handle, &status);
120 FRC_ReportError(status, "Module {}", m_module);
121}
122
123int PowerDistribution::GetModule() const {
124 return m_module;
125}
126
Austin Schuh75263e32022-02-22 18:05:32 -0800127PowerDistribution::ModuleType PowerDistribution::GetType() const {
128 int32_t status = 0;
129 auto type = HAL_GetPowerDistributionType(m_handle, &status);
130 FRC_ReportError(status, "Module {}", m_module);
131 return static_cast<ModuleType>(type);
132}
133
Austin Schuh812d0d12021-11-04 20:16:48 -0700134bool PowerDistribution::GetSwitchableChannel() const {
135 int32_t status = 0;
136 bool state = HAL_GetPowerDistributionSwitchableChannel(m_handle, &status);
137 FRC_ReportError(status, "Module {}", m_module);
138 return state;
139}
140
141void PowerDistribution::SetSwitchableChannel(bool enabled) {
142 int32_t status = 0;
143 HAL_SetPowerDistributionSwitchableChannel(m_handle, enabled, &status);
144 FRC_ReportError(status, "Module {}", m_module);
145}
146
Austin Schuh75263e32022-02-22 18:05:32 -0800147PowerDistribution::Version PowerDistribution::GetVersion() const {
148 int32_t status = 0;
149 HAL_PowerDistributionVersion halVersion;
150 std::memset(&halVersion, 0, sizeof(halVersion));
151 HAL_GetPowerDistributionVersion(m_handle, &halVersion, &status);
152 FRC_ReportError(status, "Module {}", m_module);
153 PowerDistribution::Version version;
154 static_assert(sizeof(halVersion) == sizeof(version));
155 static_assert(std::is_standard_layout_v<decltype(version)>);
156 static_assert(std::is_trivial_v<decltype(version)>);
157 std::memcpy(&version, &halVersion, sizeof(version));
158 return version;
159}
160
161PowerDistribution::Faults PowerDistribution::GetFaults() const {
162 int32_t status = 0;
163 HAL_PowerDistributionFaults halFaults;
164 std::memset(&halFaults, 0, sizeof(halFaults));
165 HAL_GetPowerDistributionFaults(m_handle, &halFaults, &status);
166 FRC_ReportError(status, "Module {}", m_module);
167 PowerDistribution::Faults faults;
168 static_assert(sizeof(halFaults) == sizeof(faults));
169 static_assert(std::is_standard_layout_v<decltype(faults)>);
170 static_assert(std::is_trivial_v<decltype(faults)>);
171 std::memcpy(&faults, &halFaults, sizeof(faults));
172 return faults;
173}
174
175PowerDistribution::StickyFaults PowerDistribution::GetStickyFaults() const {
176 int32_t status = 0;
177 HAL_PowerDistributionStickyFaults halStickyFaults;
178 std::memset(&halStickyFaults, 0, sizeof(halStickyFaults));
179 HAL_GetPowerDistributionStickyFaults(m_handle, &halStickyFaults, &status);
180 FRC_ReportError(status, "Module {}", m_module);
181 PowerDistribution::StickyFaults stickyFaults;
182 static_assert(sizeof(halStickyFaults) == sizeof(stickyFaults));
183 static_assert(std::is_standard_layout_v<decltype(stickyFaults)>);
184 static_assert(std::is_trivial_v<decltype(stickyFaults)>);
185 std::memcpy(&stickyFaults, &halStickyFaults, sizeof(stickyFaults));
186 return stickyFaults;
187}
188
Austin Schuh812d0d12021-11-04 20:16:48 -0700189void PowerDistribution::InitSendable(wpi::SendableBuilder& builder) {
190 builder.SetSmartDashboardType("PowerDistribution");
191 int32_t status = 0;
192 int numChannels = HAL_GetPowerDistributionNumChannels(m_handle, &status);
193 FRC_ReportError(status, "Module {}", m_module);
Austin Schuh75263e32022-02-22 18:05:32 -0800194 // Use manual reads to avoid printing errors
Austin Schuh812d0d12021-11-04 20:16:48 -0700195 for (int i = 0; i < numChannels; ++i) {
196 builder.AddDoubleProperty(
Austin Schuh75263e32022-02-22 18:05:32 -0800197 fmt::format("Chan{}", i),
James Kuszmaulcf324122023-01-14 14:07:17 -0800198 [=, this] {
Austin Schuh75263e32022-02-22 18:05:32 -0800199 int32_t lStatus = 0;
200 return HAL_GetPowerDistributionChannelCurrent(m_handle, i, &lStatus);
201 },
202 nullptr);
Austin Schuh812d0d12021-11-04 20:16:48 -0700203 }
204 builder.AddDoubleProperty(
Austin Schuh75263e32022-02-22 18:05:32 -0800205 "Voltage",
James Kuszmaulcf324122023-01-14 14:07:17 -0800206 [=, this] {
Austin Schuh75263e32022-02-22 18:05:32 -0800207 int32_t lStatus = 0;
208 return HAL_GetPowerDistributionVoltage(m_handle, &lStatus);
209 },
210 nullptr);
Austin Schuh812d0d12021-11-04 20:16:48 -0700211 builder.AddDoubleProperty(
Austin Schuh75263e32022-02-22 18:05:32 -0800212 "TotalCurrent",
James Kuszmaulcf324122023-01-14 14:07:17 -0800213 [=, this] {
Austin Schuh75263e32022-02-22 18:05:32 -0800214 int32_t lStatus = 0;
215 return HAL_GetPowerDistributionTotalCurrent(m_handle, &lStatus);
216 },
217 nullptr);
Austin Schuh812d0d12021-11-04 20:16:48 -0700218 builder.AddBooleanProperty(
Austin Schuh75263e32022-02-22 18:05:32 -0800219 "SwitchableChannel",
James Kuszmaulcf324122023-01-14 14:07:17 -0800220 [=, this] {
Austin Schuh75263e32022-02-22 18:05:32 -0800221 int32_t lStatus = 0;
222 return HAL_GetPowerDistributionSwitchableChannel(m_handle, &lStatus);
223 },
James Kuszmaulcf324122023-01-14 14:07:17 -0800224 [=, this](bool value) {
Austin Schuh75263e32022-02-22 18:05:32 -0800225 int32_t lStatus = 0;
226 HAL_SetPowerDistributionSwitchableChannel(m_handle, value, &lStatus);
227 });
Austin Schuh812d0d12021-11-04 20:16:48 -0700228}