blob: 819f79a8d71887689d0d65befee04d300501f6fb [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.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "frc/Solenoid.h"
6
7#include <utility>
8
9#include <hal/FRCUsageReporting.h>
Austin Schuh812d0d12021-11-04 20:16:48 -070010#include <wpi/NullDeleter.h>
11#include <wpi/sendable/SendableBuilder.h>
12#include <wpi/sendable/SendableRegistry.h>
Brian Silverman8fce7482020-01-05 13:18:21 -080013
Austin Schuh812d0d12021-11-04 20:16:48 -070014#include "frc/Errors.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080015#include "frc/SensorUtil.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080016
17using namespace frc;
18
Austin Schuh812d0d12021-11-04 20:16:48 -070019Solenoid::Solenoid(int module, PneumaticsModuleType moduleType, int channel)
20 : m_module{PneumaticsBase::GetForType(module, moduleType)},
21 m_channel{channel} {
22 if (!m_module->CheckSolenoidChannel(m_channel)) {
23 throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080024 }
Austin Schuh812d0d12021-11-04 20:16:48 -070025 m_mask = 1 << channel;
Brian Silverman8fce7482020-01-05 13:18:21 -080026
Austin Schuh812d0d12021-11-04 20:16:48 -070027 if (m_module->CheckAndReserveSolenoids(m_mask) != 0) {
28 throw FRC_MakeError(err::ResourceAlreadyAllocated, "Channel {}", m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080029 }
30
31 HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_channel + 1,
Austin Schuh812d0d12021-11-04 20:16:48 -070032 m_module->GetModuleNumber() + 1);
33 wpi::SendableRegistry::AddLW(this, "Solenoid", m_module->GetModuleNumber(),
34 m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080035}
36
Austin Schuh812d0d12021-11-04 20:16:48 -070037Solenoid::Solenoid(PneumaticsModuleType moduleType, int channel)
38 : Solenoid{PneumaticsBase::GetDefaultForType(moduleType), moduleType,
39 channel} {}
40
41Solenoid::~Solenoid() {
James Kuszmaulcf324122023-01-14 14:07:17 -080042 if (m_module) {
43 m_module->UnreserveSolenoids(m_mask);
44 }
Austin Schuh812d0d12021-11-04 20:16:48 -070045}
Brian Silverman8fce7482020-01-05 13:18:21 -080046
47void Solenoid::Set(bool on) {
Austin Schuh812d0d12021-11-04 20:16:48 -070048 int value = on ? (0xFFFF & m_mask) : 0;
49 m_module->SetSolenoids(m_mask, value);
Brian Silverman8fce7482020-01-05 13:18:21 -080050}
51
52bool Solenoid::Get() const {
Austin Schuh812d0d12021-11-04 20:16:48 -070053 int currentAll = m_module->GetSolenoids();
54 return (currentAll & m_mask) != 0;
Brian Silverman8fce7482020-01-05 13:18:21 -080055}
56
Austin Schuh812d0d12021-11-04 20:16:48 -070057void Solenoid::Toggle() {
58 Set(!Get());
Brian Silverman8fce7482020-01-05 13:18:21 -080059}
60
Austin Schuh812d0d12021-11-04 20:16:48 -070061int Solenoid::GetChannel() const {
62 return m_channel;
63}
64
65bool Solenoid::IsDisabled() const {
66 return (m_module->GetSolenoidDisabledList() & m_mask) != 0;
67}
68
69void Solenoid::SetPulseDuration(units::second_t duration) {
70 m_module->SetOneShotDuration(m_channel, duration);
Brian Silverman8fce7482020-01-05 13:18:21 -080071}
72
73void Solenoid::StartPulse() {
Austin Schuh812d0d12021-11-04 20:16:48 -070074 m_module->FireOneShot(m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080075}
76
Austin Schuh812d0d12021-11-04 20:16:48 -070077void Solenoid::InitSendable(wpi::SendableBuilder& builder) {
Brian Silverman8fce7482020-01-05 13:18:21 -080078 builder.SetSmartDashboardType("Solenoid");
79 builder.SetActuator(true);
James Kuszmaulcf324122023-01-14 14:07:17 -080080 builder.SetSafeState([=, this] { Set(false); });
Austin Schuh1e69f942020-11-14 15:06:14 -080081 builder.AddBooleanProperty(
James Kuszmaulcf324122023-01-14 14:07:17 -080082 "Value", [=, this] { return Get(); },
83 [=, this](bool value) { Set(value); });
Brian Silverman8fce7482020-01-05 13:18:21 -080084}