From 816aa4e465084f682f22e333ee6d9e9fc735324a Mon Sep 17 00:00:00 2001 From: Starlight220 <53231611+Starlight220@users.noreply.github.com> Date: Sun, 22 May 2022 17:21:40 +0300 Subject: [PATCH] [wpilib] Add Pneumatics sim classes (#4033) --- .../main/native/cpp/simulation/CTREPCMSim.cpp | 7 +- .../cpp/simulation/DoubleSolenoidSim.cpp | 48 ++++ .../cpp/simulation/PneumaticsBaseSim.cpp | 33 +++ .../main/native/cpp/simulation/REVPHSim.cpp | 6 +- .../native/cpp/simulation/SolenoidSim.cpp | 41 +++ .../include/frc/simulation/CTREPCMSim.h | 121 ++------- .../frc/simulation/DoubleSolenoidSim.h | 33 +++ .../frc/simulation/PneumaticsBaseSim.h | 183 +++++++++++++ .../native/include/frc/simulation/REVPHSim.h | 137 ++-------- .../include/frc/simulation/SolenoidSim.h | 42 +++ .../first/wpilibj/simulation/CTREPCMSim.java | 248 ++++++------------ .../wpilibj/simulation/DoubleSolenoidSim.java | 88 +++++++ .../wpilibj/simulation/PneumaticsBaseSim.java | 171 ++++++++++++ .../first/wpilibj/simulation/REVPHSim.java | 248 ++++++------------ .../first/wpilibj/simulation/SolenoidSim.java | 86 ++++++ 15 files changed, 946 insertions(+), 546 deletions(-) create mode 100644 wpilibc/src/main/native/cpp/simulation/DoubleSolenoidSim.cpp create mode 100644 wpilibc/src/main/native/cpp/simulation/PneumaticsBaseSim.cpp create mode 100644 wpilibc/src/main/native/cpp/simulation/SolenoidSim.cpp create mode 100644 wpilibc/src/main/native/include/frc/simulation/DoubleSolenoidSim.h create mode 100644 wpilibc/src/main/native/include/frc/simulation/PneumaticsBaseSim.h create mode 100644 wpilibc/src/main/native/include/frc/simulation/SolenoidSim.h create mode 100644 wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DoubleSolenoidSim.java create mode 100644 wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PneumaticsBaseSim.java create mode 100644 wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SolenoidSim.java diff --git a/wpilibc/src/main/native/cpp/simulation/CTREPCMSim.cpp b/wpilibc/src/main/native/cpp/simulation/CTREPCMSim.cpp index 9c7450b36a..0081928782 100644 --- a/wpilibc/src/main/native/cpp/simulation/CTREPCMSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/CTREPCMSim.cpp @@ -14,12 +14,13 @@ using namespace frc; using namespace frc::sim; -CTREPCMSim::CTREPCMSim() : m_index{SensorUtil::GetDefaultCTREPCMModule()} {} +CTREPCMSim::CTREPCMSim() + : PneumaticsBaseSim{SensorUtil::GetDefaultCTREPCMModule()} {} -CTREPCMSim::CTREPCMSim(int module) : m_index{module} {} +CTREPCMSim::CTREPCMSim(int module) : PneumaticsBaseSim{module} {} CTREPCMSim::CTREPCMSim(const PneumaticsBase& pneumatics) - : m_index{pneumatics.GetModuleNumber()} {} + : PneumaticsBaseSim{pneumatics.GetModuleNumber()} {} std::unique_ptr CTREPCMSim::RegisterInitializedCallback( NotifyCallback callback, bool initialNotify) { diff --git a/wpilibc/src/main/native/cpp/simulation/DoubleSolenoidSim.cpp b/wpilibc/src/main/native/cpp/simulation/DoubleSolenoidSim.cpp new file mode 100644 index 0000000000..da99867b2e --- /dev/null +++ b/wpilibc/src/main/native/cpp/simulation/DoubleSolenoidSim.cpp @@ -0,0 +1,48 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include "frc/simulation/DoubleSolenoidSim.h" + +#include "frc/PneumaticsBase.h" + +using namespace frc; +using namespace frc::sim; + +DoubleSolenoidSim::DoubleSolenoidSim( + std::shared_ptr moduleSim, int fwd, int rev) + : m_module{std::move(moduleSim)}, m_fwd{fwd}, m_rev{rev} {} + +DoubleSolenoidSim::DoubleSolenoidSim(int module, PneumaticsModuleType type, + int fwd, int rev) + : m_module{PneumaticsBaseSim::GetForType(module, type)}, + m_fwd{fwd}, + m_rev{rev} {} + +DoubleSolenoidSim::DoubleSolenoidSim(PneumaticsModuleType type, int fwd, + int rev) + : m_module{PneumaticsBaseSim::GetForType( + PneumaticsBase::GetDefaultForType(type), type)}, + m_fwd{fwd}, + m_rev{rev} {} + +DoubleSolenoid::Value DoubleSolenoidSim::Get() const { + bool fwdState = m_module->GetSolenoidOutput(m_fwd); + bool revState = m_module->GetSolenoidOutput(m_rev); + if (fwdState && !revState) { + return DoubleSolenoid::Value::kForward; + } else if (!fwdState && revState) { + return DoubleSolenoid::Value::kReverse; + } else { + return DoubleSolenoid::Value::kOff; + } +} + +void DoubleSolenoidSim::Set(DoubleSolenoid::Value output) { + m_module->SetSolenoidOutput(m_fwd, output == DoubleSolenoid::Value::kForward); + m_module->SetSolenoidOutput(m_rev, output == DoubleSolenoid::Value::kReverse); +} + +std::shared_ptr DoubleSolenoidSim::GetModuleSim() const { + return m_module; +} diff --git a/wpilibc/src/main/native/cpp/simulation/PneumaticsBaseSim.cpp b/wpilibc/src/main/native/cpp/simulation/PneumaticsBaseSim.cpp new file mode 100644 index 0000000000..476d07ae73 --- /dev/null +++ b/wpilibc/src/main/native/cpp/simulation/PneumaticsBaseSim.cpp @@ -0,0 +1,33 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include "frc/simulation/PneumaticsBaseSim.h" + +#include "frc/Errors.h" +#include "frc/PneumaticsModuleType.h" +#include "frc/simulation/CTREPCMSim.h" +#include "frc/simulation/REVPHSim.h" + +using namespace frc; +using namespace frc::sim; + +PneumaticsBaseSim::PneumaticsBaseSim(int module) : m_index{module} {} + +PneumaticsBaseSim::PneumaticsBaseSim(const PneumaticsBase& module) + : m_index{module.GetModuleNumber()} {} + +std::shared_ptr PneumaticsBaseSim::GetForType( + int module, PneumaticsModuleType type) { + switch (type) { + case PneumaticsModuleType::REVPH: + return std::make_shared(module); + + case PneumaticsModuleType::CTREPCM: + return std::make_shared(module); + + default: + throw FRC_MakeError(err::InvalidParameter, "{}", + static_cast(module)); + } +} diff --git a/wpilibc/src/main/native/cpp/simulation/REVPHSim.cpp b/wpilibc/src/main/native/cpp/simulation/REVPHSim.cpp index ca7384a494..df7bc0284f 100644 --- a/wpilibc/src/main/native/cpp/simulation/REVPHSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/REVPHSim.cpp @@ -14,12 +14,12 @@ using namespace frc; using namespace frc::sim; -REVPHSim::REVPHSim() : m_index{SensorUtil::GetDefaultREVPHModule()} {} +REVPHSim::REVPHSim() : PneumaticsBaseSim{SensorUtil::GetDefaultREVPHModule()} {} -REVPHSim::REVPHSim(int module) : m_index{module} {} +REVPHSim::REVPHSim(int module) : PneumaticsBaseSim{module} {} REVPHSim::REVPHSim(const PneumaticsBase& pneumatics) - : m_index{pneumatics.GetModuleNumber()} {} + : PneumaticsBaseSim{pneumatics} {} std::unique_ptr REVPHSim::RegisterInitializedCallback( NotifyCallback callback, bool initialNotify) { diff --git a/wpilibc/src/main/native/cpp/simulation/SolenoidSim.cpp b/wpilibc/src/main/native/cpp/simulation/SolenoidSim.cpp new file mode 100644 index 0000000000..29d820783e --- /dev/null +++ b/wpilibc/src/main/native/cpp/simulation/SolenoidSim.cpp @@ -0,0 +1,41 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include "frc/simulation/SolenoidSim.h" + +#include "frc/PneumaticsBase.h" + +using namespace frc; +using namespace frc::sim; + +SolenoidSim::SolenoidSim(std::shared_ptr moduleSim, + int channel) + : m_module{std::move(moduleSim)}, m_channel{channel} {} + +SolenoidSim::SolenoidSim(int module, PneumaticsModuleType type, int channel) + : m_module{PneumaticsBaseSim::GetForType(module, type)}, + m_channel{channel} {} + +SolenoidSim::SolenoidSim(PneumaticsModuleType type, int channel) + : m_module{PneumaticsBaseSim::GetForType( + PneumaticsBase::GetDefaultForType(type), type)}, + m_channel{channel} {} + +bool SolenoidSim::GetOutput() const { + return m_module->GetSolenoidOutput(m_channel); +} + +void SolenoidSim::SetOutput(bool output) { + m_module->SetSolenoidOutput(m_channel, output); +} + +std::unique_ptr SolenoidSim::RegisterOutputCallback( + NotifyCallback callback, bool initialNotify) { + return m_module->RegisterSolenoidOutputCallback(m_channel, callback, + initialNotify); +} + +std::shared_ptr SolenoidSim::GetModuleSim() const { + return m_module; +} diff --git a/wpilibc/src/main/native/include/frc/simulation/CTREPCMSim.h b/wpilibc/src/main/native/include/frc/simulation/CTREPCMSim.h index 0929308d86..96959edafd 100644 --- a/wpilibc/src/main/native/include/frc/simulation/CTREPCMSim.h +++ b/wpilibc/src/main/native/include/frc/simulation/CTREPCMSim.h @@ -8,17 +8,14 @@ #include "frc/PneumaticsBase.h" #include "frc/simulation/CallbackStore.h" +#include "frc/simulation/PneumaticsBaseSim.h" -namespace frc { - -class Compressor; - -namespace sim { +namespace frc::sim { /** * Class to control a simulated Pneumatic Control Module (PCM). */ -class CTREPCMSim { +class CTREPCMSim : public PneumaticsBaseSim { public: /** * Constructs with the default PCM module number (CAN ID). @@ -34,81 +31,28 @@ class CTREPCMSim { explicit CTREPCMSim(const PneumaticsBase& pneumatics); - /** - * Register a callback to be run when a solenoid is initialized on a channel. - * - * @param callback the callback - * @param initialNotify should the callback be run with the initial state - * @return the CallbackStore object associated with this callback - */ + ~CTREPCMSim() override = default; + [[nodiscard]] std::unique_ptr RegisterInitializedCallback( - NotifyCallback callback, bool initialNotify); + NotifyCallback callback, bool initialNotify) override; - /** - * Check if a solenoid has been initialized on a specific channel. - * - * @return true if initialized - */ - bool GetInitialized() const; + bool GetInitialized() const override; - /** - * Define whether a solenoid has been initialized on a specific channel. - * - * @param solenoidInitialized is there a solenoid initialized on that channel - */ - void SetInitialized(bool solenoidInitialized); + void SetInitialized(bool initialized) override; - /** - * Register a callback to be run when the solenoid output on a channel - * changes. - * - * @param channel the channel to monitor - * @param callback the callback - * @param initialNotify should the callback be run with the initial value - * @return the CallbackStore object associated with this callback - */ [[nodiscard]] std::unique_ptr RegisterSolenoidOutputCallback( - int channel, NotifyCallback callback, bool initialNotify); + int channel, NotifyCallback callback, bool initialNotify) override; - /** - * Check the solenoid output on a specific channel. - * - * @param channel the channel to check - * @return the solenoid output - */ - bool GetSolenoidOutput(int channel) const; + bool GetSolenoidOutput(int channel) const override; - /** - * Change the solenoid output on a specific channel. - * - * @param channel the channel to check - * @param solenoidOutput the new solenoid output - */ - void SetSolenoidOutput(int channel, bool solenoidOutput); + void SetSolenoidOutput(int channel, bool solenoidOutput) override; - /** - * Register a callback to be run when the compressor activates. - * - * @param callback the callback - * @param initialNotify whether to run the callback with the initial state - * @return the CallbackStore object associated with this callback - */ [[nodiscard]] std::unique_ptr RegisterCompressorOnCallback( - NotifyCallback callback, bool initialNotify); + NotifyCallback callback, bool initialNotify) override; - /** - * Check if the compressor is on. - * - * @return true if the compressor is active - */ - bool GetCompressorOn() const; + bool GetCompressorOn() const override; - /** - * Set whether the compressor is active. - * - * @param compressorOn the new value - */ - void SetCompressorOn(bool compressorOn); + void SetCompressorOn(bool compressorOn) override; /** * Register a callback to be run whenever the closed loop state changes. @@ -145,21 +89,21 @@ class CTREPCMSim { * @return the CallbackStore object associated with this callback */ [[nodiscard]] std::unique_ptr RegisterPressureSwitchCallback( - NotifyCallback callback, bool initialNotify); + NotifyCallback callback, bool initialNotify) override; /** * Check the value of the pressure switch. * * @return the pressure switch value */ - bool GetPressureSwitch() const; + bool GetPressureSwitch() const override; /** * Set the value of the pressure switch. * * @param pressureSwitch the new value */ - void SetPressureSwitch(bool pressureSwitch); + void SetPressureSwitch(bool pressureSwitch) override; /** * Register a callback to be run whenever the compressor current changes. @@ -170,43 +114,26 @@ class CTREPCMSim { */ [[nodiscard]] std::unique_ptr RegisterCompressorCurrentCallback(NotifyCallback callback, - bool initialNotify); + bool initialNotify) override; /** * Read the compressor current. * * @return the current of the compressor connected to this module */ - double GetCompressorCurrent() const; + double GetCompressorCurrent() const override; /** * Set the compressor current. * * @param compressorCurrent the new compressor current */ - void SetCompressorCurrent(double compressorCurrent); + void SetCompressorCurrent(double compressorCurrent) override; - /** - * Get the current value of all solenoid outputs. - * - * @return the solenoid outputs (1 bit per output) - */ - uint8_t GetAllSolenoidOutputs() const; + uint8_t GetAllSolenoidOutputs() const override; - /** - * Change all of the solenoid outputs. - * - * @param outputs the new solenoid outputs (1 bit per output) - */ - void SetAllSolenoidOutputs(uint8_t outputs); + void SetAllSolenoidOutputs(uint8_t outputs) override; - /** - * Reset all simulation data for this object. - */ - void ResetData(); - - private: - int m_index; + void ResetData() override; }; -} // namespace sim -} // namespace frc +} // namespace frc::sim diff --git a/wpilibc/src/main/native/include/frc/simulation/DoubleSolenoidSim.h b/wpilibc/src/main/native/include/frc/simulation/DoubleSolenoidSim.h new file mode 100644 index 0000000000..eaa697f679 --- /dev/null +++ b/wpilibc/src/main/native/include/frc/simulation/DoubleSolenoidSim.h @@ -0,0 +1,33 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include + +#include "frc/DoubleSolenoid.h" +#include "frc/PneumaticsModuleType.h" +#include "frc/simulation/PneumaticsBaseSim.h" + +namespace frc::sim { + +class DoubleSolenoidSim { + public: + DoubleSolenoidSim(std::shared_ptr moduleSim, int fwd, + int rev); + DoubleSolenoidSim(int module, PneumaticsModuleType type, int fwd, int rev); + DoubleSolenoidSim(PneumaticsModuleType type, int fwd, int rev); + + DoubleSolenoid::Value Get() const; + void Set(DoubleSolenoid::Value output); + + std::shared_ptr GetModuleSim() const; + + private: + std::shared_ptr m_module; + int m_fwd; + int m_rev; +}; + +} // namespace frc::sim diff --git a/wpilibc/src/main/native/include/frc/simulation/PneumaticsBaseSim.h b/wpilibc/src/main/native/include/frc/simulation/PneumaticsBaseSim.h new file mode 100644 index 0000000000..11110e3478 --- /dev/null +++ b/wpilibc/src/main/native/include/frc/simulation/PneumaticsBaseSim.h @@ -0,0 +1,183 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include + +#include "frc/PneumaticsBase.h" +#include "frc/PneumaticsModuleType.h" +#include "frc/simulation/CallbackStore.h" + +namespace frc::sim { + +class PneumaticsBaseSim { + public: + virtual ~PneumaticsBaseSim() = default; + + static std::shared_ptr GetForType( + int module, PneumaticsModuleType type); + + /** + * Check whether the PCM/PH has been initialized. + * + * @return true if initialized + */ + virtual bool GetInitialized() const = 0; + + /** + * Define whether the PCM/PH has been initialized. + * + * @param initialized true for initialized + */ + virtual void SetInitialized(bool initialized) = 0; + + /** + * Register a callback to be run when the PCM/PH is initialized. + * + * @param callback the callback + * @param initialNotify whether to run the callback with the initial state + * @return the {@link CallbackStore} object associated with this callback. + * Save a reference to this object; it being deconstructed cancels the + * callback. + */ + [[nodiscard]] virtual std::unique_ptr + RegisterInitializedCallback(NotifyCallback callback, bool initialNotify) = 0; + + /** + * Check if the compressor is on. + * + * @return true if the compressor is active + */ + virtual bool GetCompressorOn() const = 0; + + /** + * Set whether the compressor is active. + * + * @param compressorOn the new value + */ + virtual void SetCompressorOn(bool compressorOn) = 0; + + /** + * Register a callback to be run when the compressor activates. + * + * @param callback the callback + * @param initialNotify whether to run the callback with the initial state + * @return the {@link CallbackStore} object associated with this callback. + * Save a reference to this object; it being deconstructed cancels the + * callback. + */ + [[nodiscard]] virtual std::unique_ptr + RegisterCompressorOnCallback(NotifyCallback callback, bool initialNotify) = 0; + + /** + * Check the solenoid output on a specific channel. + * + * @param channel the channel to check + * @return the solenoid output + */ + virtual bool GetSolenoidOutput(int channel) const = 0; + + /** + * Change the solenoid output on a specific channel. + * + * @param channel the channel to check + * @param solenoidOutput the new solenoid output + */ + virtual void SetSolenoidOutput(int channel, bool solenoidOutput) = 0; + + /** + * Register a callback to be run when the solenoid output on a channel + * changes. + * + * @param channel the channel to monitor + * @param callback the callback + * @param initialNotify should the callback be run with the initial value + * @return the {@link CallbackStore} object associated with this callback. + * Save a reference to this object; it being deconstructed cancels the + * callback. + */ + [[nodiscard]] virtual std::unique_ptr + RegisterSolenoidOutputCallback(int channel, NotifyCallback callback, + bool initialNotify) = 0; + + /** + * Check the value of the pressure switch. + * + * @return the pressure switch value + */ + virtual bool GetPressureSwitch() const = 0; + + /** + * Set the value of the pressure switch. + * + * @param pressureSwitch the new value + */ + virtual void SetPressureSwitch(bool pressureSwitch) = 0; + + /** + * Register a callback to be run whenever the pressure switch value changes. + * + * @param callback the callback + * @param initialNotify whether the callback should be called with the initial + * value + * @return the {@link CallbackStore} object associated with this callback. + * Save a reference to this object; it being deconstructed cancels the + * callback. + */ + [[nodiscard]] virtual std::unique_ptr + RegisterPressureSwitchCallback(NotifyCallback callback, + bool initialNotify) = 0; + + /** + * Read the compressor current. + * + * @return the current of the compressor connected to this module + */ + virtual double GetCompressorCurrent() const = 0; + + /** + * Set the compressor current. + * + * @param compressorCurrent the new compressor current + */ + virtual void SetCompressorCurrent(double compressorCurrent) = 0; + + /** + * Register a callback to be run whenever the compressor current changes. + * + * @param callback the callback + * @param initialNotify whether to call the callback with the initial state + * @return the {@link CallbackStore} object associated with this callback. + * Save a reference to this object; it being deconstructed cancels the + * callback. + */ + [[nodiscard]] virtual std::unique_ptr + RegisterCompressorCurrentCallback(NotifyCallback callback, + bool initialNotify) = 0; + + /** + * Get the current value of all solenoid outputs. + * + * @return the solenoid outputs (1 bit per output) + */ + virtual uint8_t GetAllSolenoidOutputs() const = 0; + + /** + * Change all of the solenoid outputs. + * + * @param outputs the new solenoid outputs (1 bit per output) + */ + virtual void SetAllSolenoidOutputs(uint8_t outputs) = 0; + + /** Reset all simulation data for this object. */ + virtual void ResetData() = 0; + + protected: + const int m_index; + explicit PneumaticsBaseSim(const PneumaticsBase& module); + explicit PneumaticsBaseSim(const int index); +}; + +} // namespace frc::sim diff --git a/wpilibc/src/main/native/include/frc/simulation/REVPHSim.h b/wpilibc/src/main/native/include/frc/simulation/REVPHSim.h index e5f4efe75f..fe305ba907 100644 --- a/wpilibc/src/main/native/include/frc/simulation/REVPHSim.h +++ b/wpilibc/src/main/native/include/frc/simulation/REVPHSim.h @@ -8,6 +8,7 @@ #include "frc/PneumaticsBase.h" #include "frc/simulation/CallbackStore.h" +#include "frc/simulation/PneumaticsBaseSim.h" namespace frc { @@ -18,7 +19,7 @@ namespace sim { /** * Class to control a simulated Pneumatic Control Module (PCM). */ -class REVPHSim { +class REVPHSim : public PneumaticsBaseSim { public: /** * Constructs with the default PCM module number (CAN ID). @@ -34,81 +35,38 @@ class REVPHSim { explicit REVPHSim(const PneumaticsBase& pneumatics); - /** - * Register a callback to be run when a solenoid is initialized on a channel. - * - * @param callback the callback - * @param initialNotify should the callback be run with the initial state - * @return the CallbackStore object associated with this callback - */ + ~REVPHSim() override = default; + [[nodiscard]] std::unique_ptr RegisterInitializedCallback( - NotifyCallback callback, bool initialNotify); + NotifyCallback callback, bool initialNotify) override; - /** - * Check if a solenoid has been initialized on a specific channel. - * - * @return true if initialized - */ - bool GetInitialized() const; + bool GetInitialized() const override; - /** - * Define whether a solenoid has been initialized on a specific channel. - * - * @param solenoidInitialized is there a solenoid initialized on that channel - */ - void SetInitialized(bool solenoidInitialized); + void SetInitialized(bool solenoidInitialized) override; - /** - * Register a callback to be run when the solenoid output on a channel - * changes. - * - * @param channel the channel to monitor - * @param callback the callback - * @param initialNotify should the callback be run with the initial value - * @return the CallbackStore object associated with this callback - */ [[nodiscard]] std::unique_ptr RegisterSolenoidOutputCallback( - int channel, NotifyCallback callback, bool initialNotify); + int channel, NotifyCallback callback, bool initialNotify) override; - /** - * Check the solenoid output on a specific channel. - * - * @param channel the channel to check - * @return the solenoid output - */ - bool GetSolenoidOutput(int channel) const; + bool GetSolenoidOutput(int channel) const override; - /** - * Change the solenoid output on a specific channel. - * - * @param channel the channel to check - * @param solenoidOutput the new solenoid output - */ - void SetSolenoidOutput(int channel, bool solenoidOutput); + void SetSolenoidOutput(int channel, bool solenoidOutput) override; - /** - * Register a callback to be run when the compressor activates. - * - * @param callback the callback - * @param initialNotify whether to run the callback with the initial state - * @return the CallbackStore object associated with this callback - */ [[nodiscard]] std::unique_ptr RegisterCompressorOnCallback( - NotifyCallback callback, bool initialNotify); + NotifyCallback callback, bool initialNotify) override; /** * Check if the compressor is on. * * @return true if the compressor is active */ - bool GetCompressorOn() const; + bool GetCompressorOn() const override; /** * Set whether the compressor is active. * * @param compressorOn the new value */ - void SetCompressorOn(bool compressorOn); + void SetCompressorOn(bool compressorOn) override; /** * Register a callback to be run whenever the closed loop state changes. @@ -136,77 +94,26 @@ class REVPHSim { */ void SetCompressorConfigType(int compressorConfigType); - /** - * Register a callback to be run whenever the pressure switch value changes. - * - * @param callback the callback - * @param initialNotify whether the callback should be called with the - * initial value - * @return the CallbackStore object associated with this callback - */ [[nodiscard]] std::unique_ptr RegisterPressureSwitchCallback( - NotifyCallback callback, bool initialNotify); + NotifyCallback callback, bool initialNotify) override; - /** - * Check the value of the pressure switch. - * - * @return the pressure switch value - */ - bool GetPressureSwitch() const; + bool GetPressureSwitch() const override; - /** - * Set the value of the pressure switch. - * - * @param pressureSwitch the new value - */ - void SetPressureSwitch(bool pressureSwitch); + void SetPressureSwitch(bool pressureSwitch) override; - /** - * Register a callback to be run whenever the compressor current changes. - * - * @param callback the callback - * @param initialNotify whether to call the callback with the initial state - * @return the CallbackStore object associated with this callback - */ [[nodiscard]] std::unique_ptr RegisterCompressorCurrentCallback(NotifyCallback callback, - bool initialNotify); + bool initialNotify) override; - /** - * Read the compressor current. - * - * @return the current of the compressor connected to this module - */ - double GetCompressorCurrent() const; + double GetCompressorCurrent() const override; - /** - * Set the compressor current. - * - * @param compressorCurrent the new compressor current - */ - void SetCompressorCurrent(double compressorCurrent); + void SetCompressorCurrent(double compressorCurrent) override; - /** - * Get the current value of all solenoid outputs. - * - * @return the solenoid outputs (1 bit per output) - */ - uint8_t GetAllSolenoidOutputs() const; + uint8_t GetAllSolenoidOutputs() const override; - /** - * Change all of the solenoid outputs. - * - * @param outputs the new solenoid outputs (1 bit per output) - */ - void SetAllSolenoidOutputs(uint8_t outputs); + void SetAllSolenoidOutputs(uint8_t outputs) override; - /** - * Reset all simulation data for this object. - */ - void ResetData(); - - private: - int m_index; + void ResetData() override; }; } // namespace sim } // namespace frc diff --git a/wpilibc/src/main/native/include/frc/simulation/SolenoidSim.h b/wpilibc/src/main/native/include/frc/simulation/SolenoidSim.h new file mode 100644 index 0000000000..66e35891bd --- /dev/null +++ b/wpilibc/src/main/native/include/frc/simulation/SolenoidSim.h @@ -0,0 +1,42 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#pragma once + +#include + +#include "frc/PneumaticsModuleType.h" +#include "frc/simulation/PneumaticsBaseSim.h" + +namespace frc::sim { + +class SolenoidSim { + public: + SolenoidSim(std::shared_ptr moduleSim, int channel); + SolenoidSim(int module, PneumaticsModuleType type, int channel); + SolenoidSim(PneumaticsModuleType type, int channel); + + bool GetOutput() const; + void SetOutput(bool output); + + /** + * Register a callback to be run when the output of this solenoid has changed. + * + * @param callback the callback + * @param initialNotify whether to run the callback with the initial state + * @return the {@link CallbackStore} object associated with this callback. + * Save a reference to this object; it being deconstructed cancels the + * callback. + */ + [[nodiscard]] virtual std::unique_ptr RegisterOutputCallback( + NotifyCallback callback, bool initialNotify); + + std::shared_ptr GetModuleSim() const; + + private: + std::shared_ptr m_module; + int m_channel; +}; + +} // namespace frc::sim diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/CTREPCMSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/CTREPCMSim.java index 12ae1536ff..005b68a0d0 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/CTREPCMSim.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/CTREPCMSim.java @@ -6,17 +6,15 @@ package edu.wpi.first.wpilibj.simulation; import edu.wpi.first.hal.simulation.CTREPCMDataJNI; import edu.wpi.first.hal.simulation.NotifyCallback; -import edu.wpi.first.wpilibj.PneumaticsBase; +import edu.wpi.first.wpilibj.PneumaticsControlModule; import edu.wpi.first.wpilibj.SensorUtil; /** Class to control a simulated Pneumatic Control Module (PCM). */ @SuppressWarnings("AbbreviationAsWordInName") -public class CTREPCMSim { - private final int m_index; - +public class CTREPCMSim extends PneumaticsBaseSim { /** Constructs for the default PCM. */ public CTREPCMSim() { - m_index = SensorUtil.getDefaultCTREPCMModule(); + super(SensorUtil.getDefaultCTREPCMModule()); } /** @@ -25,129 +23,16 @@ public class CTREPCMSim { * @param module module number */ public CTREPCMSim(int module) { - m_index = module; + super(module); } /** - * Constructs from a Compressor object. + * Constructs from a PneumaticsControlModule object. * * @param module PCM module to simulate */ - public CTREPCMSim(PneumaticsBase module) { - m_index = module.getModuleNumber(); - } - - /** - * Register a callback to be run when the solenoid output on a channel changes. - * - * @param channel the channel to monitor - * @param callback the callback - * @param initialNotify should the callback be run with the initial value - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ - public CallbackStore registerSolenoidOutputCallback( - int channel, NotifyCallback callback, boolean initialNotify) { - int uid = - CTREPCMDataJNI.registerSolenoidOutputCallback(m_index, channel, callback, initialNotify); - return new CallbackStore(m_index, channel, uid, CTREPCMDataJNI::cancelSolenoidOutputCallback); - } - - /** - * Check the solenoid output on a specific channel. - * - * @param channel the channel to check - * @return the solenoid output - */ - public boolean getSolenoidOutput(int channel) { - return CTREPCMDataJNI.getSolenoidOutput(m_index, channel); - } - - /** - * Change the solenoid output on a specific channel. - * - * @param channel the channel to check - * @param solenoidOutput the new solenoid output - */ - public void setSolenoidOutput(int channel, boolean solenoidOutput) { - CTREPCMDataJNI.setSolenoidOutput(m_index, channel, solenoidOutput); - } - - /** - * Register a callback to be run when the compressor is initialized. - * - * @param callback the callback - * @param initialNotify whether to run the callback with the initial state - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ - public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) { - int uid = CTREPCMDataJNI.registerInitializedCallback(m_index, callback, initialNotify); - return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelInitializedCallback); - } - - /** - * Check whether the compressor has been initialized. - * - * @return true if initialized - */ - public boolean getInitialized() { - return CTREPCMDataJNI.getInitialized(m_index); - } - - /** - * Define whether the compressor has been initialized. - * - * @param initialized whether the compressor is initialized - */ - public void setInitialized(boolean initialized) { - CTREPCMDataJNI.setInitialized(m_index, initialized); - } - - /** - * Register a callback to be run when the compressor activates. - * - * @param callback the callback - * @param initialNotify whether to run the callback with the initial state - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ - public CallbackStore registerCompressorOnCallback( - NotifyCallback callback, boolean initialNotify) { - int uid = CTREPCMDataJNI.registerCompressorOnCallback(m_index, callback, initialNotify); - return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelCompressorOnCallback); - } - - /** - * Check if the compressor is on. - * - * @return true if the compressor is active - */ - public boolean getCompressorOn() { - return CTREPCMDataJNI.getCompressorOn(m_index); - } - - /** - * Set whether the compressor is active. - * - * @param compressorOn the new value - */ - public void setCompressorOn(boolean compressorOn) { - CTREPCMDataJNI.setCompressorOn(m_index, compressorOn); - } - - /** - * Register a callback to be run whenever the closed loop state changes. - * - * @param callback the callback - * @param initialNotify whether the callback should be called with the initial value - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ - public CallbackStore registerClosedLoopEnabledCallback( - NotifyCallback callback, boolean initialNotify) { - int uid = CTREPCMDataJNI.registerClosedLoopEnabledCallback(m_index, callback, initialNotify); - return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelClosedLoopEnabledCallback); + public CTREPCMSim(PneumaticsControlModule module) { + super(module); } /** @@ -169,70 +54,105 @@ public class CTREPCMSim { } /** - * Register a callback to be run whenever the pressure switch value changes. + * Register a callback to be run whenever the closed loop state changes. * * @param callback the callback * @param initialNotify whether the callback should be called with the initial value * @return the {@link CallbackStore} object associated with this callback. Save a reference to * this object so GC doesn't cancel the callback. */ + public CallbackStore registerClosedLoopEnabledCallback( + NotifyCallback callback, boolean initialNotify) { + int uid = CTREPCMDataJNI.registerClosedLoopEnabledCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelClosedLoopEnabledCallback); + } + + @Override + public boolean getInitialized() { + return CTREPCMDataJNI.getInitialized(m_index); + } + + @Override + public void setInitialized(boolean initialized) { + CTREPCMDataJNI.setInitialized(m_index, initialized); + } + + @Override + public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) { + int uid = CTREPCMDataJNI.registerInitializedCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelInitializedCallback); + } + + @Override + public boolean getCompressorOn() { + return CTREPCMDataJNI.getCompressorOn(m_index); + } + + @Override + public void setCompressorOn(boolean compressorOn) { + CTREPCMDataJNI.setCompressorOn(m_index, compressorOn); + } + + @Override + public CallbackStore registerCompressorOnCallback( + NotifyCallback callback, boolean initialNotify) { + int uid = CTREPCMDataJNI.registerCompressorOnCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelCompressorOnCallback); + } + + @Override + public boolean getSolenoidOutput(int channel) { + return CTREPCMDataJNI.getSolenoidOutput(m_index, channel); + } + + @Override + public void setSolenoidOutput(int channel, boolean solenoidOutput) { + CTREPCMDataJNI.setSolenoidOutput(m_index, channel, solenoidOutput); + } + + @Override + public CallbackStore registerSolenoidOutputCallback( + int channel, NotifyCallback callback, boolean initialNotify) { + int uid = + CTREPCMDataJNI.registerSolenoidOutputCallback(m_index, channel, callback, initialNotify); + return new CallbackStore(m_index, channel, uid, CTREPCMDataJNI::cancelSolenoidOutputCallback); + } + + @Override + public boolean getPressureSwitch() { + return CTREPCMDataJNI.getPressureSwitch(m_index); + } + + @Override + public void setPressureSwitch(boolean pressureSwitch) { + CTREPCMDataJNI.setPressureSwitch(m_index, pressureSwitch); + } + + @Override public CallbackStore registerPressureSwitchCallback( NotifyCallback callback, boolean initialNotify) { int uid = CTREPCMDataJNI.registerPressureSwitchCallback(m_index, callback, initialNotify); return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelPressureSwitchCallback); } - /** - * Check the value of the pressure switch. - * - * @return the pressure switch value - */ - public boolean getPressureSwitch() { - return CTREPCMDataJNI.getPressureSwitch(m_index); + @Override + public double getCompressorCurrent() { + return CTREPCMDataJNI.getCompressorCurrent(m_index); } - /** - * Set the value of the pressure switch. - * - * @param pressureSwitch the new value - */ - public void setPressureSwitch(boolean pressureSwitch) { - CTREPCMDataJNI.setPressureSwitch(m_index, pressureSwitch); + @Override + public void setCompressorCurrent(double compressorCurrent) { + CTREPCMDataJNI.setCompressorCurrent(m_index, compressorCurrent); } - /** - * Register a callback to be run whenever the compressor current changes. - * - * @param callback the callback - * @param initialNotify whether to call the callback with the initial state - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ + @Override public CallbackStore registerCompressorCurrentCallback( NotifyCallback callback, boolean initialNotify) { int uid = CTREPCMDataJNI.registerCompressorCurrentCallback(m_index, callback, initialNotify); return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelCompressorCurrentCallback); } - /** - * Read the compressor current. - * - * @return the current of the compressor connected to this module - */ - public double getCompressorCurrent() { - return CTREPCMDataJNI.getCompressorCurrent(m_index); - } - - /** - * Set the compressor current. - * - * @param compressorCurrent the new compressor current - */ - public void setCompressorCurrent(double compressorCurrent) { - CTREPCMDataJNI.setCompressorCurrent(m_index, compressorCurrent); - } - - /** Reset all simulation data for this object. */ + @Override public void resetData() { CTREPCMDataJNI.resetData(m_index); } diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DoubleSolenoidSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DoubleSolenoidSim.java new file mode 100644 index 0000000000..baf3b0235b --- /dev/null +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DoubleSolenoidSim.java @@ -0,0 +1,88 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.wpilibj.simulation; + +import edu.wpi.first.wpilibj.DoubleSolenoid; +import edu.wpi.first.wpilibj.PneumaticsBase; +import edu.wpi.first.wpilibj.PneumaticsModuleType; + +/** Class to control a simulated {@link edu.wpi.first.wpilibj.DoubleSolenoid}. */ +public class DoubleSolenoidSim { + private final PneumaticsBaseSim m_module; + private final int m_fwd; + private final int m_rev; + + /** + * Constructs for a solenoid on the given pneumatics module. + * + * @param moduleSim the PCM the solenoid is connected to. + * @param fwd the forward solenoid channel. + * @param rev the reverse solenoid channel. + */ + public DoubleSolenoidSim(PneumaticsBaseSim moduleSim, int fwd, int rev) { + m_module = moduleSim; + m_fwd = fwd; + m_rev = rev; + } + + /** + * Constructs for a solenoid on a pneumatics module of the given type and ID. + * + * @param module the CAN ID of the pneumatics module the solenoid is connected to. + * @param moduleType the module type (PH or PCM) + * @param fwd the forward solenoid channel. + * @param rev the reverse solenoid channel. + */ + public DoubleSolenoidSim(int module, PneumaticsModuleType moduleType, int fwd, int rev) { + this(PneumaticsBaseSim.getForType(module, moduleType), fwd, rev); + } + + /** + * Constructs for a solenoid on a pneumatics module of the given type and default ID. + * + * @param moduleType the module type (PH or PCM) + * @param fwd the forward solenoid channel. + * @param rev the reverse solenoid channel. + */ + public DoubleSolenoidSim(PneumaticsModuleType moduleType, int fwd, int rev) { + this(PneumaticsBase.getDefaultForType(moduleType), moduleType, fwd, rev); + } + + /** + * Check the value of the double solenoid output. + * + * @return the output value of the double solenoid. + */ + public DoubleSolenoid.Value get() { + boolean fwdState = m_module.getSolenoidOutput(m_fwd); + boolean revState = m_module.getSolenoidOutput(m_rev); + if (fwdState && !revState) { + return DoubleSolenoid.Value.kForward; + } else if (!fwdState && revState) { + return DoubleSolenoid.Value.kReverse; + } else { + return DoubleSolenoid.Value.kOff; + } + } + + /** + * Set the value of the double solenoid output. + * + * @param value The value to set (Off, Forward, Reverse) + */ + public void set(final DoubleSolenoid.Value value) { + m_module.setSolenoidOutput(m_fwd, value == DoubleSolenoid.Value.kForward); + m_module.setSolenoidOutput(m_rev, value == DoubleSolenoid.Value.kReverse); + } + + /** + * Get the wrapped {@link PneumaticsBaseSim} object. + * + * @return the wrapped {@link PneumaticsBaseSim} object. + */ + public PneumaticsBaseSim getModuleSim() { + return m_module; + } +} diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PneumaticsBaseSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PneumaticsBaseSim.java new file mode 100644 index 0000000000..156562b48a --- /dev/null +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PneumaticsBaseSim.java @@ -0,0 +1,171 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.wpilibj.simulation; + +import edu.wpi.first.hal.simulation.NotifyCallback; +import edu.wpi.first.wpilibj.PneumaticsBase; +import edu.wpi.first.wpilibj.PneumaticsModuleType; + +/** Common base class for pneumatics module simulation classes. */ +public abstract class PneumaticsBaseSim { + protected final int m_index; + + /** + * Get a module sim for a specific type. + * + * @param module the module number / CAN ID. + * @param type the module type. + * @return the module object. + */ + public static PneumaticsBaseSim getForType(int module, PneumaticsModuleType type) { + switch (type) { + case CTREPCM: + return new CTREPCMSim(module); + case REVPH: + return new REVPHSim(module); + default: + throw new IllegalArgumentException("Unknown module type"); + } + } + + protected PneumaticsBaseSim(int index) { + m_index = index; + } + + protected PneumaticsBaseSim(PneumaticsBase module) { + this(module.getModuleNumber()); + } + + /** + * Check whether the PCM/PH has been initialized. + * + * @return true if initialized + */ + public abstract boolean getInitialized(); + + /** + * Define whether the PCM/PH has been initialized. + * + * @param initialized true for initialized + */ + public abstract void setInitialized(boolean initialized); + + /** + * Register a callback to be run when the PCM/PH is initialized. + * + * @param callback the callback + * @param initialNotify whether to run the callback with the initial state + * @return the {@link CallbackStore} object associated with this callback. Save a reference to + * this object so GC doesn't cancel the callback. + */ + public abstract CallbackStore registerInitializedCallback( + NotifyCallback callback, boolean initialNotify); + + /** + * Check if the compressor is on. + * + * @return true if the compressor is active + */ + public abstract boolean getCompressorOn(); + + /** + * Set whether the compressor is active. + * + * @param compressorOn the new value + */ + public abstract void setCompressorOn(boolean compressorOn); + + /** + * Register a callback to be run when the compressor activates. + * + * @param callback the callback + * @param initialNotify whether to run the callback with the initial state + * @return the {@link CallbackStore} object associated with this callback. Save a reference to + * this object so GC doesn't cancel the callback. + */ + public abstract CallbackStore registerCompressorOnCallback( + NotifyCallback callback, boolean initialNotify); + + /** + * Check the solenoid output on a specific channel. + * + * @param channel the channel to check + * @return the solenoid output + */ + public abstract boolean getSolenoidOutput(int channel); + + /** + * Change the solenoid output on a specific channel. + * + * @param channel the channel to check + * @param solenoidOutput the new solenoid output + */ + public abstract void setSolenoidOutput(int channel, boolean solenoidOutput); + + /** + * Register a callback to be run when the solenoid output on a channel changes. + * + * @param channel the channel to monitor + * @param callback the callback + * @param initialNotify should the callback be run with the initial value + * @return the {@link CallbackStore} object associated with this callback. Save a reference to + * this object so GC doesn't cancel the callback. + */ + public abstract CallbackStore registerSolenoidOutputCallback( + int channel, NotifyCallback callback, boolean initialNotify); + + /** + * Check the value of the pressure switch. + * + * @return the pressure switch value + */ + public abstract boolean getPressureSwitch(); + + /** + * Set the value of the pressure switch. + * + * @param pressureSwitch the new value + */ + public abstract void setPressureSwitch(boolean pressureSwitch); + + /** + * Register a callback to be run whenever the pressure switch value changes. + * + * @param callback the callback + * @param initialNotify whether the callback should be called with the initial value + * @return the {@link CallbackStore} object associated with this callback. Save a reference to + * this object so GC doesn't cancel the callback. + */ + public abstract CallbackStore registerPressureSwitchCallback( + NotifyCallback callback, boolean initialNotify); + + /** + * Read the compressor current. + * + * @return the current of the compressor connected to this module + */ + public abstract double getCompressorCurrent(); + + /** + * Set the compressor current. + * + * @param compressorCurrent the new compressor current + */ + public abstract void setCompressorCurrent(double compressorCurrent); + + /** + * Register a callback to be run whenever the compressor current changes. + * + * @param callback the callback + * @param initialNotify whether to call the callback with the initial state + * @return the {@link CallbackStore} object associated with this callback. Save a reference to + * this object so GC doesn't cancel the callback. + */ + public abstract CallbackStore registerCompressorCurrentCallback( + NotifyCallback callback, boolean initialNotify); + + /** Reset all simulation data for this object. */ + public abstract void resetData(); +} diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/REVPHSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/REVPHSim.java index 8e07da3819..b170050ff9 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/REVPHSim.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/REVPHSim.java @@ -6,17 +6,15 @@ package edu.wpi.first.wpilibj.simulation; import edu.wpi.first.hal.simulation.NotifyCallback; import edu.wpi.first.hal.simulation.REVPHDataJNI; -import edu.wpi.first.wpilibj.PneumaticsBase; +import edu.wpi.first.wpilibj.PneumaticHub; import edu.wpi.first.wpilibj.SensorUtil; /** Class to control a simulated PneumaticHub (PH). */ @SuppressWarnings("AbbreviationAsWordInName") -public class REVPHSim { - private final int m_index; - +public class REVPHSim extends PneumaticsBaseSim { /** Constructs for the default PH. */ public REVPHSim() { - m_index = SensorUtil.getDefaultREVPHModule(); + super(SensorUtil.getDefaultREVPHModule()); } /** @@ -25,129 +23,16 @@ public class REVPHSim { * @param module module number */ public REVPHSim(int module) { - m_index = module; + super(module); } /** - * Constructs from a Compressor object. + * Constructs from a PneumaticHum object. * * @param module PCM module to simulate */ - public REVPHSim(PneumaticsBase module) { - m_index = module.getModuleNumber(); - } - - /** - * Register a callback to be run when the solenoid output on a channel changes. - * - * @param channel the channel to monitor - * @param callback the callback - * @param initialNotify should the callback be run with the initial value - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ - public CallbackStore registerSolenoidOutputCallback( - int channel, NotifyCallback callback, boolean initialNotify) { - int uid = - REVPHDataJNI.registerSolenoidOutputCallback(m_index, channel, callback, initialNotify); - return new CallbackStore(m_index, channel, uid, REVPHDataJNI::cancelSolenoidOutputCallback); - } - - /** - * Check the solenoid output on a specific channel. - * - * @param channel the channel to check - * @return the solenoid output - */ - public boolean getSolenoidOutput(int channel) { - return REVPHDataJNI.getSolenoidOutput(m_index, channel); - } - - /** - * Change the solenoid output on a specific channel. - * - * @param channel the channel to check - * @param solenoidOutput the new solenoid output - */ - public void setSolenoidOutput(int channel, boolean solenoidOutput) { - REVPHDataJNI.setSolenoidOutput(m_index, channel, solenoidOutput); - } - - /** - * Register a callback to be run when the compressor is initialized. - * - * @param callback the callback - * @param initialNotify whether to run the callback with the initial state - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ - public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) { - int uid = REVPHDataJNI.registerInitializedCallback(m_index, callback, initialNotify); - return new CallbackStore(m_index, uid, REVPHDataJNI::cancelInitializedCallback); - } - - /** - * Check whether the compressor has been initialized. - * - * @return true if initialized - */ - public boolean getInitialized() { - return REVPHDataJNI.getInitialized(m_index); - } - - /** - * Define whether the compressor has been initialized. - * - * @param initialized whether the compressor is initialized - */ - public void setInitialized(boolean initialized) { - REVPHDataJNI.setInitialized(m_index, initialized); - } - - /** - * Register a callback to be run when the compressor activates. - * - * @param callback the callback - * @param initialNotify whether to run the callback with the initial state - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ - public CallbackStore registerCompressorOnCallback( - NotifyCallback callback, boolean initialNotify) { - int uid = REVPHDataJNI.registerCompressorOnCallback(m_index, callback, initialNotify); - return new CallbackStore(m_index, uid, REVPHDataJNI::cancelCompressorOnCallback); - } - - /** - * Check if the compressor is on. - * - * @return true if the compressor is active - */ - public boolean getCompressorOn() { - return REVPHDataJNI.getCompressorOn(m_index); - } - - /** - * Set whether the compressor is active. - * - * @param compressorOn the new value - */ - public void setCompressorOn(boolean compressorOn) { - REVPHDataJNI.setCompressorOn(m_index, compressorOn); - } - - /** - * Register a callback to be run whenever the closed loop state changes. - * - * @param callback the callback - * @param initialNotify whether the callback should be called with the initial value - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ - public CallbackStore registerCompressorConfigTypeCallback( - NotifyCallback callback, boolean initialNotify) { - int uid = REVPHDataJNI.registerCompressorConfigTypeCallback(m_index, callback, initialNotify); - return new CallbackStore(m_index, uid, REVPHDataJNI::cancelCompressorConfigTypeCallback); + public REVPHSim(PneumaticHub module) { + super(module); } /** @@ -169,70 +54,105 @@ public class REVPHSim { } /** - * Register a callback to be run whenever the pressure switch value changes. + * Register a callback to be run whenever the closed loop state changes. * * @param callback the callback * @param initialNotify whether the callback should be called with the initial value * @return the {@link CallbackStore} object associated with this callback. Save a reference to * this object so GC doesn't cancel the callback. */ + public CallbackStore registerCompressorConfigTypeCallback( + NotifyCallback callback, boolean initialNotify) { + int uid = REVPHDataJNI.registerCompressorConfigTypeCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, REVPHDataJNI::cancelCompressorConfigTypeCallback); + } + + @Override + public boolean getInitialized() { + return REVPHDataJNI.getInitialized(m_index); + } + + @Override + public void setInitialized(boolean initialized) { + REVPHDataJNI.setInitialized(m_index, initialized); + } + + @Override + public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) { + int uid = REVPHDataJNI.registerInitializedCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, REVPHDataJNI::cancelInitializedCallback); + } + + @Override + public boolean getCompressorOn() { + return REVPHDataJNI.getCompressorOn(m_index); + } + + @Override + public void setCompressorOn(boolean compressorOn) { + REVPHDataJNI.setCompressorOn(m_index, compressorOn); + } + + @Override + public CallbackStore registerCompressorOnCallback( + NotifyCallback callback, boolean initialNotify) { + int uid = REVPHDataJNI.registerCompressorOnCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, REVPHDataJNI::cancelCompressorOnCallback); + } + + @Override + public boolean getSolenoidOutput(int channel) { + return REVPHDataJNI.getSolenoidOutput(m_index, channel); + } + + @Override + public void setSolenoidOutput(int channel, boolean solenoidOutput) { + REVPHDataJNI.setSolenoidOutput(m_index, channel, solenoidOutput); + } + + @Override + public CallbackStore registerSolenoidOutputCallback( + int channel, NotifyCallback callback, boolean initialNotify) { + int uid = + REVPHDataJNI.registerSolenoidOutputCallback(m_index, channel, callback, initialNotify); + return new CallbackStore(m_index, channel, uid, REVPHDataJNI::cancelSolenoidOutputCallback); + } + + @Override + public boolean getPressureSwitch() { + return REVPHDataJNI.getPressureSwitch(m_index); + } + + @Override + public void setPressureSwitch(boolean pressureSwitch) { + REVPHDataJNI.setPressureSwitch(m_index, pressureSwitch); + } + + @Override public CallbackStore registerPressureSwitchCallback( NotifyCallback callback, boolean initialNotify) { int uid = REVPHDataJNI.registerPressureSwitchCallback(m_index, callback, initialNotify); return new CallbackStore(m_index, uid, REVPHDataJNI::cancelPressureSwitchCallback); } - /** - * Check the value of the pressure switch. - * - * @return the pressure switch value - */ - public boolean getPressureSwitch() { - return REVPHDataJNI.getPressureSwitch(m_index); + @Override + public double getCompressorCurrent() { + return REVPHDataJNI.getCompressorCurrent(m_index); } - /** - * Set the value of the pressure switch. - * - * @param pressureSwitch the new value - */ - public void setPressureSwitch(boolean pressureSwitch) { - REVPHDataJNI.setPressureSwitch(m_index, pressureSwitch); + @Override + public void setCompressorCurrent(double compressorCurrent) { + REVPHDataJNI.setCompressorCurrent(m_index, compressorCurrent); } - /** - * Register a callback to be run whenever the compressor current changes. - * - * @param callback the callback - * @param initialNotify whether to call the callback with the initial state - * @return the {@link CallbackStore} object associated with this callback. Save a reference to - * this object so GC doesn't cancel the callback. - */ + @Override public CallbackStore registerCompressorCurrentCallback( NotifyCallback callback, boolean initialNotify) { int uid = REVPHDataJNI.registerCompressorCurrentCallback(m_index, callback, initialNotify); return new CallbackStore(m_index, uid, REVPHDataJNI::cancelCompressorCurrentCallback); } - /** - * Read the compressor current. - * - * @return the current of the compressor connected to this module - */ - public double getCompressorCurrent() { - return REVPHDataJNI.getCompressorCurrent(m_index); - } - - /** - * Set the compressor current. - * - * @param compressorCurrent the new compressor current - */ - public void setCompressorCurrent(double compressorCurrent) { - REVPHDataJNI.setCompressorCurrent(m_index, compressorCurrent); - } - - /** Reset all simulation data for this object. */ + @Override public void resetData() { REVPHDataJNI.resetData(m_index); } diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SolenoidSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SolenoidSim.java new file mode 100644 index 0000000000..39d3cc2c5c --- /dev/null +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SolenoidSim.java @@ -0,0 +1,86 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +package edu.wpi.first.wpilibj.simulation; + +import edu.wpi.first.hal.simulation.NotifyCallback; +import edu.wpi.first.wpilibj.PneumaticsBase; +import edu.wpi.first.wpilibj.PneumaticsModuleType; + +/** Class to control a simulated {@link edu.wpi.first.wpilibj.Solenoid}. */ +public class SolenoidSim { + private final PneumaticsBaseSim m_module; + private final int m_channel; + + /** + * Constructs for a solenoid on the given pneumatics module. + * + * @param moduleSim the PCM the solenoid is connected to. + * @param channel the solenoid channel. + */ + public SolenoidSim(PneumaticsBaseSim moduleSim, int channel) { + m_module = moduleSim; + m_channel = channel; + } + + /** + * Constructs for a solenoid on a pneumatics module of the given type and ID. + * + * @param module the CAN ID of the pneumatics module the solenoid is connected to. + * @param moduleType the module type (PH or PCM) + * @param channel the solenoid channel. + */ + public SolenoidSim(int module, PneumaticsModuleType moduleType, int channel) { + this(PneumaticsBaseSim.getForType(module, moduleType), channel); + } + + /** + * Constructs for a solenoid on a pneumatics module of the given type and default ID. + * + * @param moduleType the module type (PH or PCM) + * @param channel the solenoid channel. + */ + public SolenoidSim(PneumaticsModuleType moduleType, int channel) { + this(PneumaticsBase.getDefaultForType(moduleType), moduleType, channel); + } + + /** + * Check the solenoid output. + * + * @return the solenoid output + */ + public boolean getOutput() { + return m_module.getSolenoidOutput(m_channel); + } + + /** + * Change the solenoid output. + * + * @param output the new solenoid output + */ + public void setOutput(boolean output) { + m_module.setSolenoidOutput(m_channel, output); + } + + /** + * Register a callback to be run when the output of this solenoid has changed. + * + * @param callback the callback + * @param initialNotify should the callback be run with the initial value + * @return the {@link CallbackStore} object associated with this callback. Save a reference to + * this object so GC doesn't cancel the callback. + */ + public CallbackStore registerOutputCallback(NotifyCallback callback, boolean initialNotify) { + return m_module.registerSolenoidOutputCallback(m_channel, callback, initialNotify); + } + + /** + * Get the wrapped {@link PneumaticsBaseSim} object. + * + * @return the wrapped {@link PneumaticsBaseSim} object. + */ + public PneumaticsBaseSim getPCMSim() { + return m_module; + } +}