blob: 49000c2bf6f394515fe3f375690e15cd8bab1bee [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() {
42 m_module->UnreserveSolenoids(m_mask);
43}
Brian Silverman8fce7482020-01-05 13:18:21 -080044
45void Solenoid::Set(bool on) {
Austin Schuh812d0d12021-11-04 20:16:48 -070046 int value = on ? (0xFFFF & m_mask) : 0;
47 m_module->SetSolenoids(m_mask, value);
Brian Silverman8fce7482020-01-05 13:18:21 -080048}
49
50bool Solenoid::Get() const {
Austin Schuh812d0d12021-11-04 20:16:48 -070051 int currentAll = m_module->GetSolenoids();
52 return (currentAll & m_mask) != 0;
Brian Silverman8fce7482020-01-05 13:18:21 -080053}
54
Austin Schuh812d0d12021-11-04 20:16:48 -070055void Solenoid::Toggle() {
56 Set(!Get());
Brian Silverman8fce7482020-01-05 13:18:21 -080057}
58
Austin Schuh812d0d12021-11-04 20:16:48 -070059int Solenoid::GetChannel() const {
60 return m_channel;
61}
62
63bool Solenoid::IsDisabled() const {
64 return (m_module->GetSolenoidDisabledList() & m_mask) != 0;
65}
66
67void Solenoid::SetPulseDuration(units::second_t duration) {
68 m_module->SetOneShotDuration(m_channel, duration);
Brian Silverman8fce7482020-01-05 13:18:21 -080069}
70
71void Solenoid::StartPulse() {
Austin Schuh812d0d12021-11-04 20:16:48 -070072 m_module->FireOneShot(m_channel);
Brian Silverman8fce7482020-01-05 13:18:21 -080073}
74
Austin Schuh812d0d12021-11-04 20:16:48 -070075void Solenoid::InitSendable(wpi::SendableBuilder& builder) {
Brian Silverman8fce7482020-01-05 13:18:21 -080076 builder.SetSmartDashboardType("Solenoid");
77 builder.SetActuator(true);
Austin Schuh812d0d12021-11-04 20:16:48 -070078 builder.SetSafeState([=] { Set(false); });
Austin Schuh1e69f942020-11-14 15:06:14 -080079 builder.AddBooleanProperty(
Austin Schuh812d0d12021-11-04 20:16:48 -070080 "Value", [=] { return Get(); }, [=](bool value) { Set(value); });
Brian Silverman8fce7482020-01-05 13:18:21 -080081}