[hal] Add a unified PCM object (#3331)

This commit is contained in:
Thad House
2021-06-05 22:36:39 -07:00
committed by GitHub
parent dea841103d
commit 0e702eb799
103 changed files with 2643 additions and 5676 deletions

View File

@@ -0,0 +1,52 @@
// 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.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class CTREPCMJNI extends JNIWrapper {
public static native int initialize(int module);
public static native void free(int handle);
public static native boolean checkSolenoidChannel(int channel);
public static native boolean getCompressor(int handle);
public static native void setClosedLoopControl(int handle, boolean enabled);
public static native boolean getClosedLoopControl(int handle);
public static native boolean getPressureSwitch(int handle);
public static native double getCompressorCurrent(int handle);
public static native boolean getCompressorCurrentTooHighFault(int handle);
public static native boolean getCompressorCurrentTooHighStickyFault(int handle);
public static native boolean getCompressorShortedFault(int handle);
public static native boolean getCompressorShortedStickyFault(int handle);
public static native boolean getCompressorNotConnectedFault(int handle);
public static native boolean getCompressorNotConnectedStickyFault(int handle);
public static native int getSolenoids(int handle);
public static native void setSolenoids(int handle, int mask, int values);
public static native int getSolenoidDisabledList(int handle);
public static native boolean getSolenoidVoltageFault(int handle);
public static native boolean getSolenoidVoltageStickyFault(int handle);
public static native void clearAllStickyFaults(int handle);
public static native void fireOneShot(int handle, int index);
public static native void setOneShotDuration(int handle, int index, int durMs);
}

View File

@@ -1,35 +0,0 @@
// 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.hal;
public class CompressorJNI extends JNIWrapper {
public static native int initializeCompressor(byte module);
public static native boolean checkCompressorModule(byte module);
public static native boolean getCompressor(int compressorHandle);
public static native void setCompressorClosedLoopControl(int compressorHandle, boolean value);
public static native boolean getCompressorClosedLoopControl(int compressorHandle);
public static native boolean getCompressorPressureSwitch(int compressorHandle);
public static native double getCompressorCurrent(int compressorHandle);
public static native boolean getCompressorCurrentTooHighFault(int compressorHandle);
public static native boolean getCompressorCurrentTooHighStickyFault(int compressorHandle);
public static native boolean getCompressorShortedStickyFault(int compressorHandle);
public static native boolean getCompressorShortedFault(int compressorHandle);
public static native boolean getCompressorNotConnectedStickyFault(int compressorHandle);
public static native boolean getCompressorNotConnectedFault(int compressorHandle);
public static native void clearAllPCMStickyFaults(byte compressorModule);
}

View File

@@ -1,33 +0,0 @@
// 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.hal;
public class SolenoidJNI extends JNIWrapper {
public static native int initializeSolenoidPort(int halPortHandle);
public static native boolean checkSolenoidModule(int module);
public static native boolean checkSolenoidChannel(int channel);
public static native void freeSolenoidPort(int portHandle);
public static native void setSolenoid(int portHandle, boolean on);
public static native boolean getSolenoid(int portHandle);
public static native int getAllSolenoids(int module);
public static native int getPCMSolenoidBlackList(int module);
public static native boolean getPCMSolenoidVoltageStickyFault(int module);
public static native boolean getPCMSolenoidVoltageFault(int module);
public static native void clearAllPCMStickyFaults(int module);
public static native void setOneShotDuration(int portHandle, long durationMS);
public static native void fireOneShot(int portHandle);
}

View File

@@ -6,16 +6,16 @@ package edu.wpi.first.hal.simulation;
import edu.wpi.first.hal.JNIWrapper;
public class PCMDataJNI extends JNIWrapper {
public static native int registerSolenoidInitializedCallback(
int index, int channel, NotifyCallback callback, boolean initialNotify);
@SuppressWarnings("AbbreviationAsWordInName")
public class CTREPCMDataJNI extends JNIWrapper {
public static native int registerInitializedCallback(
int index, NotifyCallback callback, boolean initialNotify);
public static native void cancelSolenoidInitializedCallback(int index, int channel, int uid);
public static native void cancelInitializedCallback(int index, int uid);
public static native boolean getSolenoidInitialized(int index, int channel);
public static native boolean getInitialized(int index);
public static native void setSolenoidInitialized(
int index, int channel, boolean solenoidInitialized);
public static native void setInitialized(int index, boolean initialized);
public static native int registerSolenoidOutputCallback(
int index, int channel, NotifyCallback callback, boolean initialNotify);
@@ -26,15 +26,6 @@ public class PCMDataJNI extends JNIWrapper {
public static native void setSolenoidOutput(int index, int channel, boolean solenoidOutput);
public static native int registerCompressorInitializedCallback(
int index, NotifyCallback callback, boolean initialNotify);
public static native void cancelCompressorInitializedCallback(int index, int uid);
public static native boolean getCompressorInitialized(int index);
public static native void setCompressorInitialized(int index, boolean compressorInitialized);
public static native int registerCompressorOnCallback(
int index, NotifyCallback callback, boolean initialNotify);

View File

@@ -0,0 +1,394 @@
// 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 "hal/CTREPCM.h"
#include "HALInitializer.h"
#include "HALInternal.h"
#include "PortsInternal.h"
#include "hal/CANAPI.h"
#include "hal/Errors.h"
#include "hal/handles/IndexedHandleResource.h"
using namespace hal;
static constexpr HAL_CANManufacturer manufacturer =
HAL_CANManufacturer::HAL_CAN_Man_kCTRE;
static constexpr HAL_CANDeviceType deviceType =
HAL_CANDeviceType::HAL_CAN_Dev_kPneumatics;
static constexpr int32_t Status1 = 0x50;
static constexpr int32_t StatusSolFaults = 0x51;
static constexpr int32_t StatusDebug = 0x52;
static constexpr int32_t Control1 = 0x70;
static constexpr int32_t Control2 = 0x71;
static constexpr int32_t Control3 = 0x72;
static constexpr int32_t TimeoutMs = 100;
static constexpr int32_t SendPeriod = 20;
union PcmStatus {
uint8_t data[8];
struct Bits {
/* Byte 0 */
unsigned SolenoidBits : 8;
/* Byte 1 */
unsigned compressorOn : 1;
unsigned stickyFaultFuseTripped : 1;
unsigned stickyFaultCompCurrentTooHigh : 1;
unsigned faultFuseTripped : 1;
unsigned faultCompCurrentTooHigh : 1;
unsigned faultHardwareFailure : 1;
unsigned isCloseloopEnabled : 1;
unsigned pressureSwitchEn : 1;
/* Byte 2*/
unsigned battVoltage : 8;
/* Byte 3 */
unsigned solenoidVoltageTop8 : 8;
/* Byte 4 */
unsigned compressorCurrentTop6 : 6;
unsigned solenoidVoltageBtm2 : 2;
/* Byte 5 */
unsigned StickyFault_dItooHigh : 1;
unsigned Fault_dItooHigh : 1;
unsigned moduleEnabled : 1;
unsigned closedLoopOutput : 1;
unsigned compressorCurrentBtm4 : 4;
/* Byte 6 */
unsigned tokenSeedTop8 : 8;
/* Byte 7 */
unsigned tokenSeedBtm8 : 8;
} bits;
};
union PcmControl {
uint8_t data[8];
struct Bits {
/* Byte 0 */
unsigned tokenTop8 : 8;
/* Byte 1 */
unsigned tokenBtm8 : 8;
/* Byte 2 */
unsigned solenoidBits : 8;
/* Byte 3*/
unsigned reserved : 4;
unsigned closeLoopOutput : 1;
unsigned compressorOn : 1;
unsigned closedLoopEnable : 1;
unsigned clearStickyFaults : 1;
/* Byte 4 */
unsigned OneShotField_h8 : 8;
/* Byte 5 */
unsigned OneShotField_l8 : 8;
} bits;
};
struct PcmControlSetOneShotDur {
uint8_t sol10MsPerUnit[8];
};
union PcmStatusFault {
uint8_t data[8];
struct Bits {
/* Byte 0 */
unsigned SolenoidDisabledList : 8;
/* Byte 1 */
unsigned reserved_bit0 : 1;
unsigned reserved_bit1 : 1;
unsigned reserved_bit2 : 1;
unsigned reserved_bit3 : 1;
unsigned StickyFault_CompNoCurrent : 1;
unsigned Fault_CompNoCurrent : 1;
unsigned StickyFault_SolenoidJumper : 1;
unsigned Fault_SolenoidJumper : 1;
} bits;
};
union PcmDebug {
uint8_t data[8];
struct Bits {
unsigned tokFailsTop8 : 8;
unsigned tokFailsBtm8 : 8;
unsigned lastFailedTokTop8 : 8;
unsigned lastFailedTokBtm8 : 8;
unsigned tokSuccessTop8 : 8;
unsigned tokSuccessBtm8 : 8;
} bits;
};
namespace {
struct PCM {
HAL_CANHandle canHandle;
wpi::mutex lock;
std::string previousAllocation;
PcmControl control;
PcmControlSetOneShotDur oneShot;
};
} // namespace
static IndexedHandleResource<HAL_CTREPCMHandle, PCM, kNumCTREPCMModules,
HAL_HandleEnum::CTREPCM>* pcmHandles;
namespace hal::init {
void InitializeCTREPCM() {
static IndexedHandleResource<HAL_CTREPCMHandle, PCM, kNumCTREPCMModules,
HAL_HandleEnum::CTREPCM>
pH;
pcmHandles = &pH;
}
} // namespace hal::init
#define READ_PACKET(type, frame, failureValue) \
auto pcm = pcmHandles->Get(handle); \
if (pcm == nullptr) { \
*status = HAL_HANDLE_ERROR; \
return failureValue; \
} \
type pcmStatus; \
int32_t length = 0; \
uint64_t receivedTimestamp = 0; \
HAL_ReadCANPacketTimeout(pcm->canHandle, frame, pcmStatus.data, &length, \
&receivedTimestamp, TimeoutMs, status); \
if (*status != 0) { \
return failureValue; \
}
#define READ_STATUS(failureValue) READ_PACKET(PcmStatus, Status1, failureValue)
#define READ_SOL_FAULTS(failureValue) \
READ_PACKET(PcmStatusFault, StatusSolFaults, failureValue)
static void SendControl(PCM* pcm, int32_t* status) {
HAL_WriteCANPacketRepeating(pcm->canHandle, pcm->control.data, 8, Control1,
SendPeriod, status);
}
extern "C" {
HAL_CTREPCMHandle HAL_InitializeCTREPCM(int32_t module,
const char* allocationLocation,
int32_t* status) {
hal::init::CheckInit();
HAL_CTREPCMHandle handle;
auto pcm = pcmHandles->Allocate(module, &handle, status);
if (*status != 0) {
if (pcm) {
hal::SetLastErrorPreviouslyAllocated(status, "CTRE PCM", module,
pcm->previousAllocation);
} else {
hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for CTRE PCM", 0,
kNumAccumulators, module);
}
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
}
pcm->canHandle = HAL_InitializeCAN(manufacturer, module, deviceType, status);
if (*status != 0) {
pcmHandles->Free(handle);
return HAL_kInvalidHandle;
}
std::memset(&pcm->oneShot, 0, sizeof(pcm->oneShot));
std::memset(&pcm->control, 0, sizeof(pcm->control));
pcm->previousAllocation = allocationLocation ? allocationLocation : "";
// Enable closed loop control
HAL_SetCTREPCMClosedLoopControl(handle, true, status);
if (*status != 0) {
HAL_FreeCTREPCM(handle);
return HAL_kInvalidHandle;
}
return handle;
}
void HAL_FreeCTREPCM(HAL_CTREPCMHandle handle) {
auto pcm = pcmHandles->Get(handle);
if (pcm) {
HAL_CleanCAN(pcm->canHandle);
}
pcmHandles->Free(handle);
}
HAL_Bool HAL_CheckCTREPCMSolenoidChannel(int32_t channel) {
return channel < kNumCTRESolenoidChannels && channel >= 0;
}
HAL_Bool HAL_GetCTREPCMCompressor(HAL_CTREPCMHandle handle, int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.compressorOn;
}
void HAL_SetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle, HAL_Bool enabled,
int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
std::scoped_lock lock{pcm->lock};
pcm->control.bits.closedLoopEnable = enabled ? 1 : 0;
SendControl(pcm.get(), status);
}
HAL_Bool HAL_GetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.isCloseloopEnabled;
}
HAL_Bool HAL_GetCTREPCMPressureSwitch(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.pressureSwitchEn;
}
double HAL_GetCTREPCMCompressorCurrent(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_STATUS(0);
uint32_t result = pcmStatus.bits.compressorCurrentTop6;
result <<= 4;
result |= pcmStatus.bits.compressorCurrentBtm4;
return result * 0.03125; /* 5.5 fixed pt value in Amps */
}
HAL_Bool HAL_GetCTREPCMCompressorCurrentTooHighFault(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.faultCompCurrentTooHigh;
}
HAL_Bool HAL_GetCTREPCMCompressorCurrentTooHighStickyFault(
HAL_CTREPCMHandle handle, int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.stickyFaultCompCurrentTooHigh;
}
HAL_Bool HAL_GetCTREPCMCompressorShortedStickyFault(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.Fault_dItooHigh;
}
HAL_Bool HAL_GetCTREPCMCompressorShortedFault(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.StickyFault_dItooHigh;
}
HAL_Bool HAL_GetCTREPCMCompressorNotConnectedStickyFault(
HAL_CTREPCMHandle handle, int32_t* status) {
READ_SOL_FAULTS(false);
return pcmStatus.bits.StickyFault_CompNoCurrent;
}
HAL_Bool HAL_GetCTREPCMCompressorNotConnectedFault(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_SOL_FAULTS(false);
return pcmStatus.bits.Fault_CompNoCurrent;
}
int32_t HAL_GetCTREPCMSolenoids(HAL_CTREPCMHandle handle, int32_t* status) {
READ_STATUS(0);
return pcmStatus.bits.SolenoidBits & 0xFF;
}
void HAL_SetCTREPCMSolenoids(HAL_CTREPCMHandle handle, int32_t mask,
int32_t values, int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
uint8_t smallMask = mask & 0xFF;
uint8_t smallValues =
(values & 0xFF) & smallMask; // Enforce only masked values are set
uint8_t invertMask = ~smallMask;
std::scoped_lock lock{pcm->lock};
uint8_t existingValue = invertMask & pcm->control.bits.solenoidBits;
pcm->control.bits.solenoidBits = existingValue | smallValues;
SendControl(pcm.get(), status);
}
int32_t HAL_GetCTREPCMSolenoidDisabledList(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_SOL_FAULTS(0);
return pcmStatus.bits.SolenoidDisabledList;
}
HAL_Bool HAL_GetCTREPCMSolenoidVoltageStickyFault(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.stickyFaultFuseTripped;
}
HAL_Bool HAL_GetCTREPCMSolenoidVoltageFault(HAL_CTREPCMHandle handle,
int32_t* status) {
READ_STATUS(false);
return pcmStatus.bits.faultFuseTripped;
}
void HAL_ClearAllCTREPCMStickyFaults(HAL_CTREPCMHandle handle,
int32_t* status) {
uint8_t controlData[] = {0, 0, 0, 0x80};
HAL_WriteCANPacket(handle, controlData, sizeof(controlData), Control2,
status);
}
void HAL_FireCTREPCMOneShot(HAL_CTREPCMHandle handle, int32_t index,
int32_t* status) {
if (index > 7 || index < 0) {
*status = PARAMETER_OUT_OF_RANGE;
hal::SetLastError(status, "Only [0-7] are valid index values. Requested " +
wpi::Twine(index));
return;
}
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
std::scoped_lock lock{pcm->lock};
uint16_t oneShotField = pcm->control.bits.OneShotField_h8;
oneShotField <<= 8;
oneShotField |= pcm->control.bits.OneShotField_l8;
uint16_t shift = 2 * index;
uint16_t mask = 3;
uint8_t chBits = (oneShotField >> shift) & mask;
chBits = (chBits % 3) + 1;
oneShotField &= ~(mask << shift);
oneShotField |= (chBits << shift);
pcm->control.bits.OneShotField_h8 = oneShotField >> 8;
pcm->control.bits.OneShotField_l8 = oneShotField;
SendControl(pcm.get(), status);
}
void HAL_SetCTREPCMOneShotDuration(HAL_CTREPCMHandle handle, int32_t index,
int32_t durMs, int32_t* status) {
if (index > 7 || index < 0) {
*status = PARAMETER_OUT_OF_RANGE;
hal::SetLastError(status, "Only [0-7] are valid index values. Requested " +
wpi::Twine(index));
return;
}
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
std::scoped_lock lock{pcm->lock};
pcm->oneShot.sol10MsPerUnit[index] = (std::min)(
static_cast<uint32_t>(durMs) / 10, static_cast<uint32_t>(0xFF));
HAL_WriteCANPacketRepeating(pcm->canHandle, pcm->oneShot.sol10MsPerUnit, 8,
Control2, SendPeriod, status);
}
} // extern "C"

View File

@@ -1,197 +0,0 @@
// 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 "hal/Compressor.h"
#include "HALInitializer.h"
#include "PCMInternal.h"
#include "PortsInternal.h"
#include "ctre/PCM.h"
#include "hal/Errors.h"
#include "hal/handles/HandlesInternal.h"
using namespace hal;
namespace hal::init {
void InitializeCompressor() {}
} // namespace hal::init
extern "C" {
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {
hal::init::CheckInit();
// Use status to check for invalid index
initializePCM(module, status);
if (*status != 0) {
return HAL_kInvalidHandle;
}
// As compressors can have unlimited objects, just create a
// handle with the module number as the index.
return (HAL_CompressorHandle)createHandle(static_cast<int16_t>(module),
HAL_HandleEnum::Compressor, 0);
}
HAL_Bool HAL_CheckCompressorModule(int32_t module) {
return module < kNumPCMModules && module >= 0;
}
HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetCompressor(value);
return value;
}
void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
HAL_Bool value, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return;
}
*status = PCM_modules[index]->SetClosedLoopControl(value);
}
HAL_Bool HAL_GetCompressorClosedLoopControl(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetClosedLoopControl(value);
return value;
}
HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetPressure(value);
return value;
}
double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return 0;
}
float value;
*status = PCM_modules[index]->GetCompressorCurrent(value);
return value;
}
HAL_Bool HAL_GetCompressorCurrentTooHighFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetCompressorCurrentTooHighFault(value);
return value;
}
HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetCompressorCurrentTooHighStickyFault(value);
return value;
}
HAL_Bool HAL_GetCompressorShortedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetCompressorShortedStickyFault(value);
return value;
}
HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetCompressorShortedFault(value);
return value;
}
HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetCompressorNotConnectedStickyFault(value);
return value;
}
HAL_Bool HAL_GetCompressorNotConnectedFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[index]->GetCompressorNotConnectedFault(value);
return value;
}
} // extern "C"

View File

@@ -22,7 +22,6 @@
#include "HALInitializer.h"
#include "HALInternal.h"
#include "ctre/ctre.h"
#include "hal/ChipObject.h"
#include "hal/DriverStation.h"
#include "hal/Errors.h"
@@ -40,6 +39,7 @@ using namespace hal;
namespace hal {
namespace init {
void InitializeHAL() {
InitializeCTREPCM();
InitializeAddressableLED();
InitializeAccelerometer();
InitializeAnalogAccumulator();
@@ -50,7 +50,6 @@ void InitializeHAL() {
InitializeAnalogTrigger();
InitializeCAN();
InitializeCANAPI();
InitializeCompressor();
InitializeConstants();
InitializeCounter();
InitializeDigitalInternal();
@@ -64,14 +63,12 @@ void InitializeHAL() {
InitializeInterrupts();
InitializeMain();
InitializeNotifier();
InitializePCMInternal();
InitializePDP();
InitializePorts();
InitializePower();
InitializePWM();
InitializeRelay();
InitializeSerialPort();
InitializeSolenoid();
InitializeSPI();
InitializeThreads();
}
@@ -113,18 +110,6 @@ const char* HAL_GetErrorMessage(int32_t code) {
switch (code) {
case 0:
return "";
case CTR_RxTimeout:
return CTR_RxTimeout_MESSAGE;
case CTR_TxTimeout:
return CTR_TxTimeout_MESSAGE;
case CTR_InvalidParamValue:
return CTR_InvalidParamValue_MESSAGE;
case CTR_UnexpectedArbId:
return CTR_UnexpectedArbId_MESSAGE;
case CTR_TxFailed:
return CTR_TxFailed_MESSAGE;
case CTR_SigNotUpdated:
return CTR_SigNotUpdated_MESSAGE;
case NiFpga_Status_FifoTimeout:
return NiFpga_Status_FifoTimeout_MESSAGE;
case NiFpga_Status_TransferAborted:

View File

@@ -16,6 +16,7 @@ inline void CheckInit() {
RunInitialize();
}
extern void InitializeCTREPCM();
extern void InitializeAccelerometer();
extern void InitializeAddressableLED();
extern void InitializeAnalogAccumulator();
@@ -26,7 +27,6 @@ extern void InitializeAnalogOutput();
extern void InitializeAnalogTrigger();
extern void InitializeCAN();
extern void InitializeCANAPI();
extern void InitializeCompressor();
extern void InitializeConstants();
extern void InitializeCounter();
extern void InitializeDigitalInternal();
@@ -41,14 +41,12 @@ extern void InitializeI2C();
extern void InitializeInterrupts();
extern void InitializeMain();
extern void InitializeNotifier();
extern void InitializePCMInternal();
extern void InitializePDP();
extern void InitializePorts();
extern void InitializePower();
extern void InitializePWM();
extern void InitializeRelay();
extern void InitializeSerialPort();
extern void InitializeSolenoid();
extern void InitializeSPI();
extern void InitializeThreads();
} // namespace hal::init

View File

@@ -1,34 +0,0 @@
// 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 "PCMInternal.h"
#include "HALInitializer.h"
#include "hal/Errors.h"
#include "hal/Solenoid.h"
namespace hal {
std::unique_ptr<PCM> PCM_modules[kNumPCMModules];
namespace init {
void InitializePCMInternal() {
for (int i = 0; i < kNumPCMModules; i++) {
PCM_modules[i] = nullptr;
}
}
} // namespace init
void initializePCM(int32_t module, int32_t* status) {
hal::init::CheckInit();
if (!HAL_CheckSolenoidModule(module)) {
*status = RESOURCE_OUT_OF_RANGE;
return;
}
if (!PCM_modules[module]) {
PCM_modules[module] = std::make_unique<PCM>(module);
}
}
} // namespace hal

View File

@@ -1,34 +0,0 @@
// 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 <stdint.h>
#include <memory>
#include "PortsInternal.h"
#include "ctre/PCM.h"
#include "hal/Errors.h"
#include "hal/Solenoid.h"
namespace hal {
extern std::unique_ptr<PCM> PCM_modules[kNumPCMModules];
static inline bool checkPCMInit(int32_t module, int32_t* status) {
if (!HAL_CheckSolenoidModule(module)) {
*status = RESOURCE_OUT_OF_RANGE;
return false;
}
if (!PCM_modules[module]) {
*status = INCOMPATIBLE_STATE;
return false;
}
return true;
}
void initializePCM(int32_t module, int32_t* status);
} // namespace hal

View File

@@ -56,11 +56,11 @@ int32_t HAL_GetNumRelayChannels(void) {
int32_t HAL_GetNumRelayHeaders(void) {
return kNumRelayHeaders;
}
int32_t HAL_GetNumPCMModules(void) {
return kNumPCMModules;
int32_t HAL_GetNumCTREPCMModules(void) {
return kNumCTREPCMModules;
}
int32_t HAL_GetNumSolenoidChannels(void) {
return kNumSolenoidChannels;
return kNumCTRESolenoidChannels;
}
int32_t HAL_GetNumPDPModules(void) {
return kNumPDPModules;

View File

@@ -28,8 +28,8 @@ constexpr int32_t kNumEncoders = tEncoder::kNumSystems;
constexpr int32_t kNumInterrupts = tInterrupt::kNumSystems;
constexpr int32_t kNumRelayChannels = 8;
constexpr int32_t kNumRelayHeaders = kNumRelayChannels / 2;
constexpr int32_t kNumPCMModules = 63;
constexpr int32_t kNumSolenoidChannels = 8;
constexpr int32_t kNumCTREPCMModules = 63;
constexpr int32_t kNumCTRESolenoidChannels = 8;
constexpr int32_t kNumPDPModules = 63;
constexpr int32_t kNumPDPChannels = 16;
constexpr int32_t kNumDutyCycles = tDutyCycle::kNumSystems;

View File

@@ -1,190 +0,0 @@
// 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 "hal/Solenoid.h"
#include "HALInitializer.h"
#include "PCMInternal.h"
#include "PortsInternal.h"
#include "ctre/PCM.h"
#include "hal/Errors.h"
#include "hal/handles/HandlesInternal.h"
#include "hal/handles/IndexedHandleResource.h"
namespace {
struct Solenoid {
uint8_t module;
uint8_t channel;
};
} // namespace
using namespace hal;
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
kNumPCMModules * kNumSolenoidChannels,
HAL_HandleEnum::Solenoid>* solenoidHandles;
namespace hal::init {
void InitializeSolenoid() {
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
kNumPCMModules * kNumSolenoidChannels,
HAL_HandleEnum::Solenoid>
sH;
solenoidHandles = &sH;
}
} // namespace hal::init
extern "C" {
HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
int32_t* status) {
hal::init::CheckInit();
int16_t channel = getPortHandleChannel(portHandle);
int16_t module = getPortHandleModule(portHandle);
if (channel == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
}
// initializePCM will check the module
if (!HAL_CheckSolenoidChannel(channel)) {
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
initializePCM(module, status);
if (*status != 0) {
return HAL_kInvalidHandle;
}
HAL_SolenoidHandle handle;
auto solenoidPort = solenoidHandles->Allocate(
module * kNumSolenoidChannels + channel, &handle, status);
if (*status != 0) {
return HAL_kInvalidHandle;
}
solenoidPort->module = static_cast<uint8_t>(module);
solenoidPort->channel = static_cast<uint8_t>(channel);
return handle;
}
void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
solenoidHandles->Free(solenoidPortHandle);
}
HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
return module < kNumPCMModules && module >= 0;
}
HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
return channel < kNumSolenoidChannels && channel >= 0;
}
HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
int32_t* status) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
}
bool value;
*status = PCM_modules[port->module]->GetSolenoid(port->channel, value);
return value;
}
int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
if (!checkPCMInit(module, status)) {
return 0;
}
uint8_t value;
*status = PCM_modules[module]->GetAllSolenoids(value);
return value;
}
void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
int32_t* status) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
*status = PCM_modules[port->module]->SetSolenoid(port->channel, value);
}
void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status) {
if (!checkPCMInit(module, status)) {
return;
}
*status = PCM_modules[module]->SetAllSolenoids(state);
}
int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
if (!checkPCMInit(module, status)) {
return 0;
}
uint8_t value;
*status = PCM_modules[module]->GetSolenoidBlackList(value);
return value;
}
HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) {
if (!checkPCMInit(module, status)) {
return 0;
}
bool value;
*status = PCM_modules[module]->GetSolenoidStickyFault(value);
return value;
}
HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) {
if (!checkPCMInit(module, status)) {
return false;
}
bool value;
*status = PCM_modules[module]->GetSolenoidFault(value);
return value;
}
void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {
if (!checkPCMInit(module, status)) {
return;
}
*status = PCM_modules[module]->ClearStickyFaults();
}
void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
int32_t durMS, int32_t* status) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
*status =
PCM_modules[port->module]->SetOneShotDurationMs(port->channel, durMS);
}
void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
*status = PCM_modules[port->module]->FireOneShotSolenoid(port->channel);
}
} // extern "C"

View File

@@ -1,157 +0,0 @@
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#include "CtreCanNode.h"
#include "FRC_NetworkCommunication/CANSessionMux.h"
#include <string.h> // memset
static const UINT32 kFullMessageIDMask = 0x1fffffff;
CtreCanNode::CtreCanNode(UINT8 deviceNumber)
{
_deviceNumber = deviceNumber;
}
CtreCanNode::~CtreCanNode()
{
}
void CtreCanNode::RegisterRx(uint32_t arbId)
{
/* no need to do anything, we just use new API to poll last received message */
}
/**
* Schedule a CAN Frame for periodic transmit.
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
* @param dlc Number of bytes to transmit (0 to 8).
* @param initialFrame Ptr to the frame data to schedule for transmitting. Passing null will result
* in defaulting to zero data value.
*/
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs, uint32_t dlc, const uint8_t * initialFrame)
{
int32_t status = 0;
if(dlc > 8)
dlc = 8;
txJob_t job = {0};
job.arbId = arbId;
job.periodMs = periodMs;
job.dlc = dlc;
if(initialFrame){
/* caller wants to specify original data */
memcpy(job.toSend, initialFrame, dlc);
}
_txJobs[arbId] = job;
FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
job.toSend,
job.dlc,
job.periodMs,
&status);
}
/**
* Schedule a CAN Frame for periodic transmit. Assume eight byte DLC and zero value for initial transmission.
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
*/
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
{
RegisterTx(arbId,periodMs, 8, 0);
}
/**
* Remove a CAN frame Arbid to stop transmission.
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
*/
void CtreCanNode::UnregisterTx(uint32_t arbId)
{
/* set period to zero */
ChangeTxPeriod(arbId, 0);
/* look and remove */
txJobs_t::iterator iter = _txJobs.find(arbId);
if(iter != _txJobs.end()) {
_txJobs.erase(iter);
}
}
static int64_t GetTimeMs() {
std::chrono::time_point < std::chrono::system_clock > now;
now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
auto millis = std::chrono::duration_cast < std::chrono::milliseconds
> (duration).count();
return (int64_t) millis;
}
CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
{
CTR_Code retval = CTR_OKAY;
int32_t status = 0;
uint8_t len = 0;
uint32_t timeStamp;
/* cap timeout at 999ms */
if(timeoutMs > 999)
timeoutMs = 999;
FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
std::scoped_lock lock(_lck);
if(status == 0){
/* fresh update */
rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
r.time = GetTimeMs();
memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
}else{
/* did not get the message */
rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
if(i == _rxRxEvents.end()){
/* we've never gotten this mesage */
retval = CTR_RxTimeout;
/* fill caller's buffer with zeros */
memset(dataBytes,0,8);
}else{
/* we've gotten this message before but not recently */
memcpy(dataBytes,i->second.bytes,8);
/* get the time now */
int64_t now = GetTimeMs(); /* get now */
/* how long has it been? */
int64_t temp = now - i->second.time; /* temp = now - last */
if (temp > ((int64_t) timeoutMs)) {
retval = CTR_RxTimeout;
} else {
/* our last update was recent enough */
}
}
}
return retval;
}
void CtreCanNode::FlushTx(uint32_t arbId)
{
int32_t status = 0;
txJobs_t::iterator iter = _txJobs.find(arbId);
if(iter != _txJobs.end())
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
iter->second.toSend,
iter->second.dlc,
iter->second.periodMs,
&status);
}
/**
* Change the transmit period of an already scheduled CAN frame.
* This keeps the frame payload contents the same without caller having to perform
* a read-modify-write.
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
* @return true if scheduled job was found and updated, false if there was no preceding job for the specified arbID.
*/
bool CtreCanNode::ChangeTxPeriod(uint32_t arbId, uint32_t periodMs)
{
int32_t status = 0;
/* lookup the data bytes and period for this message */
txJobs_t::iterator iter = _txJobs.find(arbId);
if(iter != _txJobs.end()) {
/* modify th periodMs */
iter->second.periodMs = periodMs;
/* reinsert into scheduler with the same data bytes, only the period changed. */
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
iter->second.toSend,
iter->second.dlc,
iter->second.periodMs,
&status);
return true;
}
return false;
}

View File

@@ -1,132 +0,0 @@
#ifndef CtreCanNode_H_
#define CtreCanNode_H_
#include "ctre.h" //BIT Defines + Typedefs
#include <map>
#include <wpi/mutex.h>
class CtreCanNode
{
public:
CtreCanNode(UINT8 deviceNumber);
~CtreCanNode();
UINT8 GetDeviceNumber()
{
return _deviceNumber;
}
protected:
template <typename T> class txTask{
public:
uint32_t arbId;
T * toSend;
T * operator -> ()
{
return toSend;
}
T & operator*()
{
return *toSend;
}
bool IsEmpty()
{
if(toSend == 0)
return true;
return false;
}
};
template <typename T> class recMsg{
public:
uint32_t arbId;
uint8_t bytes[8];
CTR_Code err;
T * operator -> ()
{
return (T *)bytes;
}
T & operator*()
{
return *(T *)bytes;
}
};
UINT8 _deviceNumber;
void RegisterRx(uint32_t arbId);
/**
* Schedule a CAN Frame for periodic transmit. Assume eight byte DLC and zero value for initial transmission.
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
*/
void RegisterTx(uint32_t arbId, uint32_t periodMs);
/**
* Schedule a CAN Frame for periodic transmit.
* @param arbId CAN Frame Arbitration ID. Set BIT31 for 11bit ids, otherwise we use 29bit ids.
* @param periodMs Period to transmit CAN frame. Pass 0 for one-shot, which also disables that ArbID's preceding periodic transmit.
* @param dlc Number of bytes to transmit (0 to 8).
* @param initialFrame Ptr to the frame data to schedule for transmitting. Passing null will result
* in defaulting to zero data value.
*/
void RegisterTx(uint32_t arbId, uint32_t periodMs, uint32_t dlc, const uint8_t * initialFrame);
void UnregisterTx(uint32_t arbId);
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
void FlushTx(uint32_t arbId);
bool ChangeTxPeriod(uint32_t arbId, uint32_t periodMs);
template<typename T> txTask<T> GetTx(uint32_t arbId)
{
txTask<T> retval = {0, nullptr};
txJobs_t::iterator i = _txJobs.find(arbId);
if(i != _txJobs.end()){
retval.arbId = i->second.arbId;
retval.toSend = (T*)i->second.toSend;
}
return retval;
}
template<class T> void FlushTx(T & par)
{
FlushTx(par.arbId);
}
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
{
recMsg<T> retval;
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
return retval;
}
private:
class txJob_t {
public:
uint32_t arbId;
uint8_t toSend[8];
uint32_t periodMs;
uint8_t dlc;
};
class rxEvent_t{
public:
uint8_t bytes[8];
int64_t time;
rxEvent_t()
{
bytes[0] = 0;
bytes[1] = 0;
bytes[2] = 0;
bytes[3] = 0;
bytes[4] = 0;
bytes[5] = 0;
bytes[6] = 0;
bytes[7] = 0;
}
};
typedef std::map<uint32_t,txJob_t> txJobs_t;
txJobs_t _txJobs;
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
rxRxEvents_t _rxRxEvents;
wpi::mutex _lck;
};
#endif

View File

@@ -1,573 +0,0 @@
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#include "PCM.h"
#include "FRC_NetworkCommunication/CANSessionMux.h"
/* This can be a constant, as long as nobody needs to update solenoids within
1/50 of a second. */
static const INT32 kCANPeriod = 20;
#define STATUS_1 0x9041400
#define STATUS_SOL_FAULTS 0x9041440
#define STATUS_DEBUG 0x9041480
#define EXPECTED_RESPONSE_TIMEOUT_MS (50)
#define GET_PCM_STATUS() CtreCanNode::recMsg<PcmStatus_t> rx = GetRx<PcmStatus_t> (STATUS_1|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
#define GET_PCM_SOL_FAULTS() CtreCanNode::recMsg<PcmStatusFault_t> rx = GetRx<PcmStatusFault_t> (STATUS_SOL_FAULTS|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
#define GET_PCM_DEBUG() CtreCanNode::recMsg<PcmDebug_t> rx = GetRx<PcmDebug_t> (STATUS_DEBUG|GetDeviceNumber(),EXPECTED_RESPONSE_TIMEOUT_MS)
#define CONTROL_1 0x09041C00 /* PCM_Control */
#define CONTROL_2 0x09041C40 /* PCM_SupplemControl */
#define CONTROL_3 0x09041C80 /* PcmControlSetOneShotDur_t */
/* encoder/decoders */
typedef struct _PcmStatus_t{
/* Byte 0 */
unsigned SolenoidBits:8;
/* Byte 1 */
unsigned compressorOn:1;
unsigned stickyFaultFuseTripped:1;
unsigned stickyFaultCompCurrentTooHigh:1;
unsigned faultFuseTripped:1;
unsigned faultCompCurrentTooHigh:1;
unsigned faultHardwareFailure:1;
unsigned isCloseloopEnabled:1;
unsigned pressureSwitchEn:1;
/* Byte 2*/
unsigned battVoltage:8;
/* Byte 3 */
unsigned solenoidVoltageTop8:8;
/* Byte 4 */
unsigned compressorCurrentTop6:6;
unsigned solenoidVoltageBtm2:2;
/* Byte 5 */
unsigned StickyFault_dItooHigh :1;
unsigned Fault_dItooHigh :1;
unsigned moduleEnabled:1;
unsigned closedLoopOutput:1;
unsigned compressorCurrentBtm4:4;
/* Byte 6 */
unsigned tokenSeedTop8:8;
/* Byte 7 */
unsigned tokenSeedBtm8:8;
}PcmStatus_t;
typedef struct _PcmControl_t{
/* Byte 0 */
unsigned tokenTop8:8;
/* Byte 1 */
unsigned tokenBtm8:8;
/* Byte 2 */
unsigned solenoidBits:8;
/* Byte 3*/
unsigned reserved:4;
unsigned closeLoopOutput:1;
unsigned compressorOn:1;
unsigned closedLoopEnable:1;
unsigned clearStickyFaults:1;
/* Byte 4 */
unsigned OneShotField_h8:8;
/* Byte 5 */
unsigned OneShotField_l8:8;
}PcmControl_t;
typedef struct _PcmControlSetOneShotDur_t{
uint8_t sol10MsPerUnit[8];
}PcmControlSetOneShotDur_t;
typedef struct _PcmStatusFault_t{
/* Byte 0 */
unsigned SolenoidBlacklist:8;
/* Byte 1 */
unsigned reserved_bit0 :1;
unsigned reserved_bit1 :1;
unsigned reserved_bit2 :1;
unsigned reserved_bit3 :1;
unsigned StickyFault_CompNoCurrent :1;
unsigned Fault_CompNoCurrent :1;
unsigned StickyFault_SolenoidJumper :1;
unsigned Fault_SolenoidJumper :1;
}PcmStatusFault_t;
typedef struct _PcmDebug_t{
unsigned tokFailsTop8:8;
unsigned tokFailsBtm8:8;
unsigned lastFailedTokTop8:8;
unsigned lastFailedTokBtm8:8;
unsigned tokSuccessTop8:8;
unsigned tokSuccessBtm8:8;
}PcmDebug_t;
/* PCM Constructor - Clears all vars, establishes default settings, starts PCM background process
*
* @Return - void
*
* @Param - deviceNumber - Device ID of PCM to be controlled
*/
PCM::PCM(UINT8 deviceNumber): CtreCanNode(deviceNumber)
{
RegisterRx(STATUS_1 | deviceNumber );
RegisterRx(STATUS_SOL_FAULTS | deviceNumber );
RegisterRx(STATUS_DEBUG | deviceNumber );
RegisterTx(CONTROL_1 | deviceNumber, kCANPeriod);
/* enable close loop */
SetClosedLoopControl(1);
}
/* PCM D'tor
*/
PCM::~PCM()
{
}
/* Set PCM solenoid state
*
* @Return - CTR_Code - Error code (if any) for setting solenoid
*
* @Param - idx - ID of solenoid (0-7)
* @Param - en - Enable / Disable identified solenoid
*/
CTR_Code PCM::SetSolenoid(unsigned char idx, bool en)
{
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
if (en)
toFill->solenoidBits |= (1ul << (idx));
else
toFill->solenoidBits &= ~(1ul << (idx));
FlushTx(toFill);
return CTR_OKAY;
}
/* Set all PCM solenoid states
*
* @Return - CTR_Code - Error code (if any) for setting solenoids
* @Param - state Bitfield to set all solenoids to
*/
CTR_Code PCM::SetAllSolenoids(UINT8 state) {
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
toFill->solenoidBits = state;
FlushTx(toFill);
return CTR_OKAY;
}
/* Clears PCM sticky faults (indicators of past faults
*
* @Return - CTR_Code - Error code (if any) for setting solenoid
*
* @Param - clr - Clear / do not clear faults
*/
CTR_Code PCM::ClearStickyFaults()
{
int32_t status = 0;
uint8_t pcmSupplemControl[] = { 0, 0, 0, 0x80 }; /* only bit set is ClearStickyFaults */
FRC_NetworkCommunication_CANSessionMux_sendMessage(CONTROL_2 | GetDeviceNumber(), pcmSupplemControl, sizeof(pcmSupplemControl), 0, &status);
if(status)
return CTR_TxFailed;
return CTR_OKAY;
}
/* Enables PCM Closed Loop Control of Compressor via pressure switch
*
* @Return - CTR_Code - Error code (if any) for setting solenoid
*
* @Param - en - Enable / Disable Closed Loop Control
*/
CTR_Code PCM::SetClosedLoopControl(bool en)
{
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
toFill->closedLoopEnable = en;
FlushTx(toFill);
return CTR_OKAY;
}
/* Get solenoid Blacklist status
* @Return - CTR_Code - Error code (if any)
* @Param - idx - ID of solenoid [0,7] to fire one shot pulse.
*/
CTR_Code PCM::FireOneShotSolenoid(UINT8 idx)
{
CtreCanNode::txTask<PcmControl_t> toFill = GetTx<PcmControl_t>(CONTROL_1 | GetDeviceNumber());
if(toFill.IsEmpty())return CTR_UnexpectedArbId;
/* grab field as it is now */
uint16_t oneShotField;
oneShotField = toFill->OneShotField_h8;
oneShotField <<= 8;
oneShotField |= toFill->OneShotField_l8;
/* get the caller's channel */
uint16_t shift = 2*idx;
uint16_t mask = 3; /* two bits wide */
uint8_t chBits = (oneShotField >> shift) & mask;
/* flip it */
chBits = (chBits)%3 + 1;
/* clear out 2bits for this channel*/
oneShotField &= ~(mask << shift);
/* put new field in */
oneShotField |= chBits << shift;
/* apply field as it is now */
toFill->OneShotField_h8 = oneShotField >> 8;
toFill->OneShotField_l8 = oneShotField;
FlushTx(toFill);
return CTR_OKAY;
}
/* Configure the pulse width of a solenoid channel for one-shot pulse.
* Preprogrammed pulsewidth is 10ms resolution and can be between 10ms and
* 2.55s.
*
* @Return - CTR_Code - Error code (if any)
* @Param - idx - ID of solenoid [0,7] to configure.
* @Param - durMs - pulse width in ms.
*/
CTR_Code PCM::SetOneShotDurationMs(UINT8 idx,uint32_t durMs)
{
/* sanity check caller's param */
if(idx > 7)
return CTR_InvalidParamValue;
/* get latest tx frame */
CtreCanNode::txTask<PcmControlSetOneShotDur_t> toFill = GetTx<PcmControlSetOneShotDur_t>(CONTROL_3 | GetDeviceNumber());
if(toFill.IsEmpty()){
/* only send this out if caller wants to do one-shots */
RegisterTx(CONTROL_3 | _deviceNumber, kCANPeriod);
/* grab it */
toFill = GetTx<PcmControlSetOneShotDur_t>(CONTROL_3 | GetDeviceNumber());
}
toFill->sol10MsPerUnit[idx] = std::min(durMs/10,(uint32_t)0xFF);
/* apply the new data bytes */
FlushTx(toFill);
return CTR_OKAY;
}
/* Get solenoid state
*
* @Return - True/False - True if solenoid enabled, false otherwise
*
* @Param - idx - ID of solenoid (0-7) to return status of
*/
CTR_Code PCM::GetSolenoid(UINT8 idx, bool &status)
{
GET_PCM_STATUS();
status = (rx->SolenoidBits & (1ul<<(idx)) ) ? 1 : 0;
return rx.err;
}
/* Get solenoid state for all solenoids on the PCM
*
* @Return - Bitfield of solenoid states
*/
CTR_Code PCM::GetAllSolenoids(UINT8 &status)
{
GET_PCM_STATUS();
status = rx->SolenoidBits;
return rx.err;
}
/* Get pressure switch state
*
* @Return - True/False - True if pressure adequate, false if low
*/
CTR_Code PCM::GetPressure(bool &status)
{
GET_PCM_STATUS();
status = (rx->pressureSwitchEn ) ? 1 : 0;
return rx.err;
}
/* Get compressor state
*
* @Return - True/False - True if enabled, false if otherwise
*/
CTR_Code PCM::GetCompressor(bool &status)
{
GET_PCM_STATUS();
status = (rx->compressorOn);
return rx.err;
}
/* Get closed loop control state
*
* @Return - True/False - True if closed loop enabled, false if otherwise
*/
CTR_Code PCM::GetClosedLoopControl(bool &status)
{
GET_PCM_STATUS();
status = (rx->isCloseloopEnabled);
return rx.err;
}
/* Get compressor current draw
*
* @Return - Amperes - Compressor current
*/
CTR_Code PCM::GetCompressorCurrent(float &status)
{
GET_PCM_STATUS();
uint32_t temp =(rx->compressorCurrentTop6);
temp <<= 4;
temp |= rx->compressorCurrentBtm4;
status = temp * 0.03125; /* 5.5 fixed pt value in Amps */
return rx.err;
}
/* Get voltage across solenoid rail
*
* @Return - Volts - Voltage across solenoid rail
*/
CTR_Code PCM::GetSolenoidVoltage(float &status)
{
GET_PCM_STATUS();
uint32_t raw =(rx->solenoidVoltageTop8);
raw <<= 2;
raw |= rx->solenoidVoltageBtm2;
status = (double) raw * 0.03125; /* 5.5 fixed pt value in Volts */
return rx.err;
}
/* Get hardware fault value
*
* @Return - True/False - True if hardware failure detected, false if otherwise
*/
CTR_Code PCM::GetHardwareFault(bool &status)
{
GET_PCM_STATUS();
status = rx->faultHardwareFailure;
return rx.err;
}
/* Get compressor fault value
*
* @Return - True/False - True if shorted compressor detected, false if otherwise
*/
CTR_Code PCM::GetCompressorCurrentTooHighFault(bool &status)
{
GET_PCM_STATUS();
status = rx->faultCompCurrentTooHigh;
return rx.err;
}
CTR_Code PCM::GetCompressorShortedStickyFault(bool &status)
{
GET_PCM_STATUS();
status = rx->StickyFault_dItooHigh;
return rx.err;
}
CTR_Code PCM::GetCompressorShortedFault(bool &status)
{
GET_PCM_STATUS();
status = rx->Fault_dItooHigh;
return rx.err;
}
CTR_Code PCM::GetCompressorNotConnectedStickyFault(bool &status)
{
GET_PCM_SOL_FAULTS();
status = rx->StickyFault_CompNoCurrent;
return rx.err;
}
CTR_Code PCM::GetCompressorNotConnectedFault(bool &status)
{
GET_PCM_SOL_FAULTS();
status = rx->Fault_CompNoCurrent;
return rx.err;
}
/* Get solenoid fault value
*
* @Return - True/False - True if shorted solenoid detected, false if otherwise
*/
CTR_Code PCM::GetSolenoidFault(bool &status)
{
GET_PCM_STATUS();
status = rx->faultFuseTripped;
return rx.err;
}
/* Get compressor sticky fault value
*
* @Return - True/False - True if solenoid had previously been shorted
* (and sticky fault was not cleared), false if otherwise
*/
CTR_Code PCM::GetCompressorCurrentTooHighStickyFault(bool &status)
{
GET_PCM_STATUS();
status = rx->stickyFaultCompCurrentTooHigh;
return rx.err;
}
/* Get solenoid sticky fault value
*
* @Return - True/False - True if compressor had previously been shorted
* (and sticky fault was not cleared), false if otherwise
*/
CTR_Code PCM::GetSolenoidStickyFault(bool &status)
{
GET_PCM_STATUS();
status = rx->stickyFaultFuseTripped;
return rx.err;
}
/* Get battery voltage
*
* @Return - Volts - Voltage across PCM power ports
*/
CTR_Code PCM::GetBatteryVoltage(float &status)
{
GET_PCM_STATUS();
status = (float)rx->battVoltage * 0.05 + 4.0; /* 50mV per unit plus 4V. */
return rx.err;
}
/* Return status of module enable/disable
*
* @Return - bool - Returns TRUE if PCM is enabled, FALSE if disabled
*/
CTR_Code PCM::isModuleEnabled(bool &status)
{
GET_PCM_STATUS();
status = rx->moduleEnabled;
return rx.err;
}
/* Get number of total failed PCM Control Frame
*
* @Return - Failed Control Frames - Number of failed control frames (tokenization fails)
*
* @WARNING - Return only valid if [SeekDebugFrames] is enabled
* See function SeekDebugFrames
* See function EnableSeekDebugFrames
*/
CTR_Code PCM::GetNumberOfFailedControlFrames(UINT16 &status)
{
GET_PCM_DEBUG();
status = rx->tokFailsTop8;
status <<= 8;
status |= rx->tokFailsBtm8;
return rx.err;
}
/* Get raw Solenoid Blacklist
*
* @Return - BINARY - Raw binary breakdown of Solenoid Blacklist
* BIT7 = Solenoid 1, BIT6 = Solenoid 2, etc.
*
* @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
* See function SeekStatusFaultFrames
* See function EnableSeekStatusFaultFrames
*/
CTR_Code PCM::GetSolenoidBlackList(UINT8 &status)
{
GET_PCM_SOL_FAULTS();
status = rx->SolenoidBlacklist;
return rx.err;
}
/* Get solenoid Blacklist status
* - Blacklisted solenoids cannot be enabled until PCM is power cycled
*
* @Return - True/False - True if Solenoid is blacklisted, false if otherwise
*
* @Param - idx - ID of solenoid [0,7]
*
* @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
* See function SeekStatusFaultFrames
* See function EnableSeekStatusFaultFrames
*/
CTR_Code PCM::IsSolenoidBlacklisted(UINT8 idx, bool &status)
{
GET_PCM_SOL_FAULTS();
status = (rx->SolenoidBlacklist & (1ul<<(idx)) )? 1 : 0;
return rx.err;
}
//------------------ C interface --------------------------------------------//
extern "C" {
void * c_PCM_Init(void) {
return new PCM();
}
CTR_Code c_SetSolenoid(void * handle, unsigned char idx, INT8 param) {
return ((PCM*) handle)->SetSolenoid(idx, param);
}
CTR_Code c_SetAllSolenoids(void * handle, UINT8 state) {
return ((PCM*) handle)->SetAllSolenoids(state);
}
CTR_Code c_SetClosedLoopControl(void * handle, INT8 param) {
return ((PCM*) handle)->SetClosedLoopControl(param);
}
CTR_Code c_ClearStickyFaults(void * handle, INT8 param) {
return ((PCM*) handle)->ClearStickyFaults();
}
CTR_Code c_GetSolenoid(void * handle, UINT8 idx, INT8 * status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetSolenoid(idx, bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetAllSolenoids(void * handle, UINT8 * status) {
return ((PCM*) handle)->GetAllSolenoids(*status);
}
CTR_Code c_GetPressure(void * handle, INT8 * status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetPressure(bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetCompressor(void * handle, INT8 * status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetCompressor(bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetClosedLoopControl(void * handle, INT8 * status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetClosedLoopControl(bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetCompressorCurrent(void * handle, float * status) {
CTR_Code retval = ((PCM*) handle)->GetCompressorCurrent(*status);
return retval;
}
CTR_Code c_GetSolenoidVoltage(void * handle, float*status) {
return ((PCM*) handle)->GetSolenoidVoltage(*status);
}
CTR_Code c_GetHardwareFault(void * handle, INT8*status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetHardwareFault(bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetCompressorFault(void * handle, INT8*status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetCompressorCurrentTooHighFault(bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetSolenoidFault(void * handle, INT8*status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetSolenoidFault(bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetCompressorStickyFault(void * handle, INT8*status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetCompressorCurrentTooHighStickyFault(bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetSolenoidStickyFault(void * handle, INT8*status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->GetSolenoidStickyFault(bstatus);
*status = bstatus;
return retval;
}
CTR_Code c_GetBatteryVoltage(void * handle, float*status) {
CTR_Code retval = ((PCM*) handle)->GetBatteryVoltage(*status);
return retval;
}
void c_SetDeviceNumber_PCM(void * handle, UINT8 deviceNumber) {
}
CTR_Code c_GetNumberOfFailedControlFrames(void * handle, UINT16*status) {
return ((PCM*) handle)->GetNumberOfFailedControlFrames(*status);
}
CTR_Code c_GetSolenoidBlackList(void * handle, UINT8 *status) {
return ((PCM*) handle)->GetSolenoidBlackList(*status);
}
CTR_Code c_IsSolenoidBlacklisted(void * handle, UINT8 idx, INT8*status) {
bool bstatus;
CTR_Code retval = ((PCM*) handle)->IsSolenoidBlacklisted(idx, bstatus);
*status = bstatus;
return retval;
}
}

View File

@@ -1,226 +0,0 @@
#ifndef PCM_H_
#define PCM_H_
#include "ctre.h" //BIT Defines + Typedefs
#include "CtreCanNode.h"
class PCM : public CtreCanNode
{
public:
PCM(UINT8 deviceNumber=0);
~PCM();
/* Set PCM solenoid state
*
* @Return - CTR_Code - Error code (if any) for setting solenoid
* @Param - idx - ID of solenoid (0-7)
* @Param - en - Enable / Disable identified solenoid
*/
CTR_Code SetSolenoid(unsigned char idx, bool en);
/* Set all PCM solenoid states
*
* @Return - CTR_Code - Error code (if any) for setting solenoids
* @Param - state Bitfield to set all solenoids to
*/
CTR_Code SetAllSolenoids(UINT8 state);
/* Enables PCM Closed Loop Control of Compressor via pressure switch
* @Return - CTR_Code - Error code (if any) for setting solenoid
* @Param - en - Enable / Disable Closed Loop Control
*/
CTR_Code SetClosedLoopControl(bool en);
/* Clears PCM sticky faults (indicators of past faults
* @Return - CTR_Code - Error code (if any) for setting solenoid
*/
CTR_Code ClearStickyFaults();
/* Get solenoid state
*
* @Return - CTR_Code - Error code (if any)
* @Param - idx - ID of solenoid (0-7) to return if solenoid is on.
* @Param - status - true if solenoid enabled, false otherwise
*/
CTR_Code GetSolenoid(UINT8 idx, bool &status);
/* Get state of all solenoids
*
* @Return - CTR_Code - Error code (if any)
* @Param - status - bitfield of solenoid states
*/
CTR_Code GetAllSolenoids(UINT8 &status);
/* Get pressure switch state
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if pressure adequate, false if low
*/
CTR_Code GetPressure(bool &status);
/* Get compressor state
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if compress output is on, false if otherwise
*/
CTR_Code GetCompressor(bool &status);
/* Get closed loop control state
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if closed loop enabled, false if otherwise
*/
CTR_Code GetClosedLoopControl(bool &status);
/* Get compressor current draw
* @Return - CTR_Code - Error code (if any)
* @Param - status - Compressor current returned in Amperes (A)
*/
CTR_Code GetCompressorCurrent(float &status);
/* Get voltage across solenoid rail
* @Return - CTR_Code - Error code (if any)
* @Param - status - Voltage across solenoid rail in Volts (V)
*/
CTR_Code GetSolenoidVoltage(float &status);
/* Get hardware fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if hardware failure detected, false if otherwise
*/
CTR_Code GetHardwareFault(bool &status);
/* Get compressor fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if abnormally high compressor current detected, false if otherwise
*/
CTR_Code GetCompressorCurrentTooHighFault(bool &status);
/* Get solenoid fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if shorted solenoid detected, false if otherwise
*/
CTR_Code GetSolenoidFault(bool &status);
/* Get compressor sticky fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if solenoid had previously been shorted
* (and sticky fault was not cleared), false if otherwise
*/
CTR_Code GetCompressorCurrentTooHighStickyFault(bool &status);
/* Get compressor shorted sticky fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if compressor output is shorted, false if otherwise
*/
CTR_Code GetCompressorShortedStickyFault(bool &status);
/* Get compressor shorted fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if compressor output is shorted, false if otherwise
*/
CTR_Code GetCompressorShortedFault(bool &status);
/* Get compressor is not connected sticky fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if compressor current is too low,
* indicating compressor is not connected, false if otherwise
*/
CTR_Code GetCompressorNotConnectedStickyFault(bool &status);
/* Get compressor is not connected fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if compressor current is too low,
* indicating compressor is not connected, false if otherwise
*/
CTR_Code GetCompressorNotConnectedFault(bool &status);
/* Get solenoid sticky fault value
* @Return - CTR_Code - Error code (if any)
* @Param - status - True if compressor had previously been shorted
* (and sticky fault was not cleared), false if otherwise
*/
CTR_Code GetSolenoidStickyFault(bool &status);
/* Get battery voltage
* @Return - CTR_Code - Error code (if any)
* @Param - status - Voltage across PCM power ports in Volts (V)
*/
CTR_Code GetBatteryVoltage(float &status);
/* Set PCM Device Number and according CAN frame IDs
* @Return - void
* @Param - deviceNumber - Device number of PCM to control
*/
void SetDeviceNumber(UINT8 deviceNumber);
/* Get number of total failed PCM Control Frame
* @Return - CTR_Code - Error code (if any)
* @Param - status - Number of failed control frames (tokenization fails)
* @WARNING - Return only valid if [SeekDebugFrames] is enabled
* See function SeekDebugFrames
* See function EnableSeekDebugFrames
*/
CTR_Code GetNumberOfFailedControlFrames(UINT16 &status);
/* Get raw Solenoid Blacklist
* @Return - CTR_Code - Error code (if any)
* @Param - status - Raw binary breakdown of Solenoid Blacklist
* BIT7 = Solenoid 1, BIT6 = Solenoid 2, etc.
* @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
* See function SeekStatusFaultFrames
* See function EnableSeekStatusFaultFrames
*/
CTR_Code GetSolenoidBlackList(UINT8 &status);
/* Get solenoid Blacklist status
* - Blacklisted solenoids cannot be enabled until PCM is power cycled
* @Return - CTR_Code - Error code (if any)
* @Param - idx - ID of solenoid [0,7]
* @Param - status - True if Solenoid is blacklisted, false if otherwise
* @WARNING - Return only valid if [SeekStatusFaultFrames] is enabled
* See function SeekStatusFaultFrames
* See function EnableSeekStatusFaultFrames
*/
CTR_Code IsSolenoidBlacklisted(UINT8 idx, bool &status);
/* Return status of module enable/disable
* @Return - CTR_Code - Error code (if any)
* @Param - status - Returns TRUE if PCM is enabled, FALSE if disabled
*/
CTR_Code isModuleEnabled(bool &status);
/* Get solenoid Blacklist status
* @Return - CTR_Code - Error code (if any)
* @Param - idx - ID of solenoid [0,7] to fire one shot pulse.
*/
CTR_Code FireOneShotSolenoid(UINT8 idx);
/* Configure the pulse width of a solenoid channel for one-shot pulse.
* Preprogrammed pulsewidth is 10ms resolute and can be between 20ms and 5.1s.
* @Return - CTR_Code - Error code (if any)
* @Param - idx - ID of solenoid [0,7] to configure.
* @Param - durMs - pulse width in ms.
*/
CTR_Code SetOneShotDurationMs(UINT8 idx,uint32_t durMs);
};
//------------------ C interface --------------------------------------------//
extern "C" {
void * c_PCM_Init(void);
CTR_Code c_SetSolenoid(void * handle,unsigned char idx,INT8 param);
CTR_Code c_SetAllSolenoids(void * handle,UINT8 state);
CTR_Code c_SetClosedLoopControl(void * handle,INT8 param);
CTR_Code c_ClearStickyFaults(void * handle,INT8 param);
CTR_Code c_GetSolenoid(void * handle,UINT8 idx,INT8 * status);
CTR_Code c_GetAllSolenoids(void * handle,UINT8 * status);
CTR_Code c_GetPressure(void * handle,INT8 * status);
CTR_Code c_GetCompressor(void * handle,INT8 * status);
CTR_Code c_GetClosedLoopControl(void * handle,INT8 * status);
CTR_Code c_GetCompressorCurrent(void * handle,float * status);
CTR_Code c_GetSolenoidVoltage(void * handle,float*status);
CTR_Code c_GetHardwareFault(void * handle,INT8*status);
CTR_Code c_GetCompressorFault(void * handle,INT8*status);
CTR_Code c_GetSolenoidFault(void * handle,INT8*status);
CTR_Code c_GetCompressorStickyFault(void * handle,INT8*status);
CTR_Code c_GetSolenoidStickyFault(void * handle,INT8*status);
CTR_Code c_GetBatteryVoltage(void * handle,float*status);
void c_SetDeviceNumber_PCM(void * handle,UINT8 deviceNumber);
void c_EnableSeekStatusFrames(void * handle,INT8 enable);
void c_EnableSeekStatusFaultFrames(void * handle,INT8 enable);
void c_EnableSeekDebugFrames(void * handle,INT8 enable);
CTR_Code c_GetNumberOfFailedControlFrames(void * handle,UINT16*status);
CTR_Code c_GetSolenoidBlackList(void * handle,UINT8 *status);
CTR_Code c_IsSolenoidBlacklisted(void * handle,UINT8 idx,INT8*status);
}
#endif

View File

@@ -1,55 +0,0 @@
/**
* @file ctre.h
* Common header for all CTRE HAL modules.
*/
#ifndef CTRE_H
#define CTRE_H
//Bit Defines
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
//Signed
typedef signed char INT8;
typedef signed short INT16;
typedef signed int INT32;
typedef signed long long INT64;
//Unsigned
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned long long UINT64;
//Other
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef enum {
CTR_OKAY, //!< No Error - Function executed as expected
CTR_RxTimeout, //!< CAN frame has not been received within specified period of time.
CTR_TxTimeout, //!< Not used.
CTR_InvalidParamValue, //!< Caller passed an invalid param
CTR_UnexpectedArbId, //!< Specified CAN Id is invalid.
CTR_TxFailed, //!< Could not transmit the CAN frame.
CTR_SigNotUpdated, //!< Have not received an value response for signal.
CTR_BufferFull, //!< Caller attempted to insert data into a buffer that is full.
}CTR_Code;
#endif /* CTRE_H */

View File

@@ -0,0 +1,38 @@
// 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 "hal/simulation/CTREPCMData.h"
#include "hal/simulation/SimDataValue.h"
extern "C" {
void HALSIM_ResetCTREPCMData(int32_t index) {}
#define DEFINE_CAPI(TYPE, CAPINAME, RETURN) \
HAL_SIMDATAVALUE_STUB_CAPI(TYPE, HALSIM, CTREPCM##CAPINAME, RETURN)
HAL_SIMDATAVALUE_STUB_CAPI_CHANNEL(HAL_Bool, HALSIM, CTREPCMSolenoidOutput,
false)
DEFINE_CAPI(HAL_Bool, Initialized, false)
DEFINE_CAPI(HAL_Bool, CompressorOn, false)
DEFINE_CAPI(HAL_Bool, ClosedLoopEnabled, false)
DEFINE_CAPI(HAL_Bool, PressureSwitch, false)
DEFINE_CAPI(double, CompressorCurrent, 0)
void HALSIM_GetCTREPCMAllSolenoids(int32_t index, uint8_t* values) {
*values = 0;
}
void HALSIM_SetCTREPCMAllSolenoids(int32_t index, uint8_t values) {}
void HALSIM_RegisterCTREPCMAllNonSolenoidCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {}
void HALSIM_RegisterCTREPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {}
} // extern "C"

View File

@@ -1,39 +0,0 @@
// 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 "hal/simulation/PCMData.h"
#include "hal/simulation/SimDataValue.h"
extern "C" {
void HALSIM_ResetPCMData(int32_t index) {}
#define DEFINE_CAPI(TYPE, CAPINAME, RETURN) \
HAL_SIMDATAVALUE_STUB_CAPI(TYPE, HALSIM, PCM##CAPINAME, RETURN)
HAL_SIMDATAVALUE_STUB_CAPI_CHANNEL(HAL_Bool, HALSIM, PCMSolenoidInitialized,
false)
HAL_SIMDATAVALUE_STUB_CAPI_CHANNEL(HAL_Bool, HALSIM, PCMSolenoidOutput, false)
DEFINE_CAPI(HAL_Bool, CompressorInitialized, false)
DEFINE_CAPI(HAL_Bool, CompressorOn, false)
DEFINE_CAPI(HAL_Bool, ClosedLoopEnabled, false)
DEFINE_CAPI(HAL_Bool, PressureSwitch, false)
DEFINE_CAPI(double, CompressorCurrent, 0)
void HALSIM_GetPCMAllSolenoids(int32_t index, uint8_t* values) {
*values = 0;
}
void HALSIM_SetPCMAllSolenoids(int32_t index, uint8_t values) {}
void HALSIM_RegisterPCMAllNonSolenoidCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {}
void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {}
} // extern "C"

View File

@@ -0,0 +1,340 @@
// 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 <jni.h>
#include <wpi/jni_util.h>
#include "HALUtil.h"
#include "edu_wpi_first_hal_CTREPCMJNI.h"
#include "hal/CTREPCM.h"
#include "hal/Ports.h"
#include "hal/handles/HandlesInternal.h"
using namespace hal;
extern "C" {
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: initialize
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_initialize
(JNIEnv* env, jclass, jint module)
{
int32_t status = 0;
auto stack = wpi::java::GetJavaStackTrace(env, "edu.wpi.first");
auto handle = HAL_InitializeCTREPCM(module, stack.c_str(), &status);
CheckStatusForceThrow(env, status);
return handle;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: free
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_free
(JNIEnv* env, jclass, jint handle)
{
HAL_FreeCTREPCM(handle);
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: checkSolenoidChannel
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_checkSolenoidChannel
(JNIEnv*, jclass, jint channel)
{
return HAL_CheckCTREPCMSolenoidChannel(channel);
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getCompressor
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getCompressor
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressor(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: setClosedLoopControl
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_setClosedLoopControl
(JNIEnv* env, jclass, jint handle, jboolean enabled)
{
int32_t status = 0;
HAL_SetCTREPCMClosedLoopControl(handle, enabled, &status);
CheckStatus(env, status, false);
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getClosedLoopControl
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getClosedLoopControl
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMClosedLoopControl(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getPressureSwitch
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getPressureSwitch
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMPressureSwitch(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getCompressorCurrent
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getCompressorCurrent
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorCurrent(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getCompressorCurrentTooHighFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getCompressorCurrentTooHighFault
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorCurrentTooHighFault(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getCompressorCurrentTooHighStickyFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getCompressorCurrentTooHighStickyFault
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result =
HAL_GetCTREPCMCompressorCurrentTooHighStickyFault(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getCompressorShortedFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getCompressorShortedFault
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorShortedFault(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getCompressorShortedStickyFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getCompressorShortedStickyFault
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorShortedStickyFault(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getCompressorNotConnectedFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getCompressorNotConnectedFault
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorNotConnectedFault(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getCompressorNotConnectedStickyFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getCompressorNotConnectedStickyFault
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result =
HAL_GetCTREPCMCompressorNotConnectedStickyFault(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getSolenoids
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getSolenoids
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMSolenoids(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: setSolenoids
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_setSolenoids
(JNIEnv* env, jclass, jint handle, jint mask, jint value)
{
int32_t status = 0;
HAL_SetCTREPCMSolenoids(handle, mask, value, &status);
CheckStatus(env, status, false);
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getSolenoidDisabledList
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getSolenoidDisabledList
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMSolenoidDisabledList(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getSolenoidVoltageFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getSolenoidVoltageFault
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMSolenoidVoltageFault(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: getSolenoidVoltageStickyFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_getSolenoidVoltageStickyFault
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto result = HAL_GetCTREPCMSolenoidVoltageStickyFault(handle, &status);
CheckStatus(env, status, false);
return result;
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: clearAllStickyFaults
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_clearAllStickyFaults
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
HAL_ClearAllCTREPCMStickyFaults(handle, &status);
CheckStatus(env, status, false);
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: fireOneShot
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_fireOneShot
(JNIEnv* env, jclass, jint handle, jint index)
{
int32_t status = 0;
HAL_FireCTREPCMOneShot(handle, index, &status);
CheckStatus(env, status, false);
}
/*
* Class: edu_wpi_first_hal_CTREPCMJNI
* Method: setOneShotDuration
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CTREPCMJNI_setOneShotDuration
(JNIEnv* env, jclass, jint handle, jint index, jint durMs)
{
int32_t status = 0;
HAL_SetCTREPCMOneShotDuration(handle, index, durMs, &status);
CheckStatus(env, status, false);
}
} // extern "C"

View File

@@ -1,230 +0,0 @@
// 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 "HALUtil.h"
#include "edu_wpi_first_hal_CompressorJNI.h"
#include "hal/Compressor.h"
#include "hal/Ports.h"
#include "hal/Solenoid.h"
using namespace hal;
extern "C" {
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: initializeCompressor
* Signature: (B)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_CompressorJNI_initializeCompressor
(JNIEnv* env, jclass, jbyte module)
{
int32_t status = 0;
auto handle = HAL_InitializeCompressor(module, &status);
CheckStatusRange(env, status, 0, HAL_GetNumPCMModules(), module);
return (jint)handle;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: checkCompressorModule
* Signature: (B)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_checkCompressorModule
(JNIEnv* env, jclass, jbyte module)
{
return HAL_CheckCompressorModule(module);
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressor
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressor
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressor((HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: setCompressorClosedLoopControl
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CompressorJNI_setCompressorClosedLoopControl
(JNIEnv* env, jclass, jint compressorHandle, jboolean value)
{
int32_t status = 0;
HAL_SetCompressorClosedLoopControl((HAL_CompressorHandle)compressorHandle,
value, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorClosedLoopControl
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorClosedLoopControl
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressorClosedLoopControl(
(HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorPressureSwitch
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorPressureSwitch
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressorPressureSwitch(
(HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorCurrent
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorCurrent
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
double val =
HAL_GetCompressorCurrent((HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorCurrentTooHighFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorCurrentTooHighFault
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressorCurrentTooHighFault(
(HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorCurrentTooHighStickyFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorCurrentTooHighStickyFault
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressorCurrentTooHighStickyFault(
(HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorShortedStickyFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorShortedStickyFault
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressorShortedStickyFault(
(HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorShortedFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorShortedFault
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressorShortedFault(
(HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorNotConnectedStickyFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorNotConnectedStickyFault
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressorNotConnectedStickyFault(
(HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: getCompressorNotConnectedFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_CompressorJNI_getCompressorNotConnectedFault
(JNIEnv* env, jclass, jint compressorHandle)
{
int32_t status = 0;
bool val = HAL_GetCompressorNotConnectedFault(
(HAL_CompressorHandle)compressorHandle, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_CompressorJNI
* Method: clearAllPCMStickyFaults
* Signature: (B)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_CompressorJNI_clearAllPCMStickyFaults
(JNIEnv* env, jclass, jbyte module)
{
int32_t status = 0;
HAL_ClearAllPCMStickyFaults(static_cast<int32_t>(module), &status);
CheckStatus(env, status);
}
} // extern "C"

View File

@@ -204,7 +204,7 @@ JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_PortsJNI_getNumPCMModules
(JNIEnv* env, jclass)
{
jint value = HAL_GetNumPCMModules();
jint value = HAL_GetNumCTREPCMModules();
return value;
}

View File

@@ -1,200 +0,0 @@
// 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 <jni.h>
#include "HALUtil.h"
#include "edu_wpi_first_hal_SolenoidJNI.h"
#include "hal/Ports.h"
#include "hal/Solenoid.h"
#include "hal/handles/HandlesInternal.h"
using namespace hal;
extern "C" {
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: initializeSolenoidPort
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_initializeSolenoidPort
(JNIEnv* env, jclass, jint id)
{
int32_t status = 0;
HAL_SolenoidHandle handle =
HAL_InitializeSolenoidPort((HAL_PortHandle)id, &status);
// Use solenoid channels, as we have to pick one.
CheckStatusRange(env, status, 0, HAL_GetNumSolenoidChannels(),
hal::getPortHandleChannel((HAL_PortHandle)id));
return (jint)handle;
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: checkSolenoidChannel
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_checkSolenoidChannel
(JNIEnv* env, jclass, jint channel)
{
return HAL_CheckSolenoidChannel(channel);
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: checkSolenoidModule
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_checkSolenoidModule
(JNIEnv* env, jclass, jint module)
{
return HAL_CheckSolenoidModule(module);
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: freeSolenoidPort
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_freeSolenoidPort
(JNIEnv* env, jclass, jint id)
{
HAL_FreeSolenoidPort((HAL_SolenoidHandle)id);
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: setSolenoid
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_setSolenoid
(JNIEnv* env, jclass, jint solenoid_port, jboolean value)
{
int32_t status = 0;
HAL_SetSolenoid((HAL_SolenoidHandle)solenoid_port, value, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: getSolenoid
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_getSolenoid
(JNIEnv* env, jclass, jint solenoid_port)
{
int32_t status = 0;
jboolean val = HAL_GetSolenoid((HAL_SolenoidHandle)solenoid_port, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: getAllSolenoids
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_getAllSolenoids
(JNIEnv* env, jclass, jint module)
{
int32_t status = 0;
jint val = HAL_GetAllSolenoids(module, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: getPCMSolenoidBlackList
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_getPCMSolenoidBlackList
(JNIEnv* env, jclass, jint module)
{
int32_t status = 0;
jint val = HAL_GetPCMSolenoidBlackList(module, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: getPCMSolenoidVoltageStickyFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_getPCMSolenoidVoltageStickyFault
(JNIEnv* env, jclass, jint module)
{
int32_t status = 0;
bool val = HAL_GetPCMSolenoidVoltageStickyFault(module, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: getPCMSolenoidVoltageFault
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_getPCMSolenoidVoltageFault
(JNIEnv* env, jclass, jint module)
{
int32_t status = 0;
bool val = HAL_GetPCMSolenoidVoltageFault(module, &status);
CheckStatus(env, status);
return val;
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: clearAllPCMStickyFaults
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_clearAllPCMStickyFaults
(JNIEnv* env, jclass, jint module)
{
int32_t status = 0;
HAL_ClearAllPCMStickyFaults(module, &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: setOneShotDuration
* Signature: (IJ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_setOneShotDuration
(JNIEnv* env, jclass, jint solenoid_port, jlong durationMS)
{
int32_t status = 0;
HAL_SetOneShotDuration((HAL_SolenoidHandle)solenoid_port, durationMS,
&status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_SolenoidJNI
* Method: fireOneShot
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_SolenoidJNI_fireOneShot
(JNIEnv* env, jclass, jint solenoid_port)
{
int32_t status = 0;
HAL_FireOneShot((HAL_SolenoidHandle)solenoid_port, &status);
CheckStatus(env, status);
}
} // extern "C"

View File

@@ -0,0 +1,368 @@
// 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 <jni.h>
#include "CallbackStore.h"
#include "edu_wpi_first_hal_simulation_CTREPCMDataJNI.h"
#include "hal/simulation/CTREPCMData.h"
using namespace hal;
extern "C" {
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: registerInitializedCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_registerInitializedCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(env, index, callback, initialNotify,
&HALSIM_RegisterCTREPCMInitializedCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: cancelInitializedCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_cancelInitializedCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelCTREPCMInitializedCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: getInitialized
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_getInitialized
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetCTREPCMInitialized(index);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: setInitialized
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_setInitialized
(JNIEnv*, jclass, jint index, jboolean value)
{
HALSIM_SetCTREPCMInitialized(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: registerSolenoidOutputCallback
* Signature: (IILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_registerSolenoidOutputCallback
(JNIEnv* env, jclass, jint index, jint channel, jobject callback,
jboolean initialNotify)
{
return sim::AllocateChannelCallback(
env, index, channel, callback, initialNotify,
&HALSIM_RegisterCTREPCMSolenoidOutputCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: cancelSolenoidOutputCallback
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_cancelSolenoidOutputCallback
(JNIEnv* env, jclass, jint index, jint channel, jint handle)
{
return sim::FreeChannelCallback(env, handle, index, channel,
&HALSIM_CancelCTREPCMSolenoidOutputCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: getSolenoidOutput
* Signature: (II)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_getSolenoidOutput
(JNIEnv*, jclass, jint index, jint channel)
{
return HALSIM_GetCTREPCMSolenoidOutput(index, channel);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: setSolenoidOutput
* Signature: (IIZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_setSolenoidOutput
(JNIEnv*, jclass, jint index, jint channel, jboolean value)
{
HALSIM_SetCTREPCMSolenoidOutput(index, channel, value);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: registerCompressorOnCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_registerCompressorOnCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(env, index, callback, initialNotify,
&HALSIM_RegisterCTREPCMCompressorOnCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: cancelCompressorOnCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_cancelCompressorOnCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelCTREPCMCompressorOnCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: getCompressorOn
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_getCompressorOn
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetCTREPCMCompressorOn(index);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: setCompressorOn
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_setCompressorOn
(JNIEnv*, jclass, jint index, jboolean value)
{
HALSIM_SetCTREPCMCompressorOn(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: registerClosedLoopEnabledCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_registerClosedLoopEnabledCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(
env, index, callback, initialNotify,
&HALSIM_RegisterCTREPCMClosedLoopEnabledCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: cancelClosedLoopEnabledCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_cancelClosedLoopEnabledCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelCTREPCMClosedLoopEnabledCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: getClosedLoopEnabled
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_getClosedLoopEnabled
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetCTREPCMClosedLoopEnabled(index);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: setClosedLoopEnabled
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_setClosedLoopEnabled
(JNIEnv*, jclass, jint index, jboolean value)
{
HALSIM_SetCTREPCMClosedLoopEnabled(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: registerPressureSwitchCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_registerPressureSwitchCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(env, index, callback, initialNotify,
&HALSIM_RegisterCTREPCMPressureSwitchCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: cancelPressureSwitchCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_cancelPressureSwitchCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelCTREPCMPressureSwitchCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: getPressureSwitch
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_getPressureSwitch
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetCTREPCMPressureSwitch(index);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: setPressureSwitch
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_setPressureSwitch
(JNIEnv*, jclass, jint index, jboolean value)
{
HALSIM_SetCTREPCMPressureSwitch(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: registerCompressorCurrentCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_registerCompressorCurrentCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(
env, index, callback, initialNotify,
&HALSIM_RegisterCTREPCMCompressorCurrentCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: cancelCompressorCurrentCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_cancelCompressorCurrentCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelCTREPCMCompressorCurrentCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: getCompressorCurrent
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_getCompressorCurrent
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetCTREPCMCompressorCurrent(index);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: setCompressorCurrent
* Signature: (ID)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_setCompressorCurrent
(JNIEnv*, jclass, jint index, jdouble value)
{
HALSIM_SetCTREPCMCompressorCurrent(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: registerAllNonSolenoidCallbacks
* Signature: (ILjava/lang/Object;Z)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_registerAllNonSolenoidCallbacks
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
sim::AllocateCallback(
env, index, callback, initialNotify,
[](int32_t index, HAL_NotifyCallback cb, void* param, HAL_Bool in) {
HALSIM_RegisterCTREPCMAllNonSolenoidCallbacks(index, cb, param, in);
return 0;
});
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: registerAllSolenoidCallbacks
* Signature: (IILjava/lang/Object;Z)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_registerAllSolenoidCallbacks
(JNIEnv* env, jclass, jint index, jint channel, jobject callback,
jboolean initialNotify)
{
sim::AllocateChannelCallback(
env, index, channel, callback, initialNotify,
[](int32_t index, int32_t channel, HAL_NotifyCallback cb, void* param,
HAL_Bool in) {
HALSIM_RegisterCTREPCMAllSolenoidCallbacks(index, channel, cb, param,
in);
return 0;
});
}
/*
* Class: edu_wpi_first_hal_simulation_CTREPCMDataJNI
* Method: resetData
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_CTREPCMDataJNI_resetData
(JNIEnv*, jclass, jint index)
{
HALSIM_ResetCTREPCMData(index);
}
} // extern "C"

View File

@@ -1,418 +0,0 @@
// 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 <jni.h>
#include "CallbackStore.h"
#include "edu_wpi_first_hal_simulation_PCMDataJNI.h"
#include "hal/simulation/PCMData.h"
using namespace hal;
extern "C" {
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerSolenoidInitializedCallback
* Signature: (IILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerSolenoidInitializedCallback
(JNIEnv* env, jclass, jint index, jint channel, jobject callback,
jboolean initialNotify)
{
return sim::AllocateChannelCallback(
env, index, channel, callback, initialNotify,
&HALSIM_RegisterPCMSolenoidInitializedCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: cancelSolenoidInitializedCallback
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_cancelSolenoidInitializedCallback
(JNIEnv* env, jclass, jint index, jint channel, jint handle)
{
return sim::FreeChannelCallback(env, handle, index, channel,
&HALSIM_CancelPCMSolenoidInitializedCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: getSolenoidInitialized
* Signature: (II)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_getSolenoidInitialized
(JNIEnv*, jclass, jint index, jint channel)
{
return HALSIM_GetPCMSolenoidInitialized(index, channel);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: setSolenoidInitialized
* Signature: (IIZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_setSolenoidInitialized
(JNIEnv*, jclass, jint index, jint channel, jboolean value)
{
HALSIM_SetPCMSolenoidInitialized(index, channel, value);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerSolenoidOutputCallback
* Signature: (IILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerSolenoidOutputCallback
(JNIEnv* env, jclass, jint index, jint channel, jobject callback,
jboolean initialNotify)
{
return sim::AllocateChannelCallback(
env, index, channel, callback, initialNotify,
&HALSIM_RegisterPCMSolenoidOutputCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: cancelSolenoidOutputCallback
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_cancelSolenoidOutputCallback
(JNIEnv* env, jclass, jint index, jint channel, jint handle)
{
return sim::FreeChannelCallback(env, handle, index, channel,
&HALSIM_CancelPCMSolenoidOutputCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: getSolenoidOutput
* Signature: (II)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_getSolenoidOutput
(JNIEnv*, jclass, jint index, jint channel)
{
return HALSIM_GetPCMSolenoidOutput(index, channel);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: setSolenoidOutput
* Signature: (IIZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_setSolenoidOutput
(JNIEnv*, jclass, jint index, jint channel, jboolean value)
{
HALSIM_SetPCMSolenoidOutput(index, channel, value);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerCompressorInitializedCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerCompressorInitializedCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(
env, index, callback, initialNotify,
&HALSIM_RegisterPCMCompressorInitializedCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: cancelCompressorInitializedCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_cancelCompressorInitializedCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelPCMCompressorInitializedCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: getCompressorInitialized
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_getCompressorInitialized
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetPCMCompressorInitialized(index);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: setCompressorInitialized
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_setCompressorInitialized
(JNIEnv*, jclass, jint index, jboolean value)
{
HALSIM_SetPCMCompressorInitialized(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerCompressorOnCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerCompressorOnCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(env, index, callback, initialNotify,
&HALSIM_RegisterPCMCompressorOnCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: cancelCompressorOnCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_cancelCompressorOnCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelPCMCompressorOnCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: getCompressorOn
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_getCompressorOn
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetPCMCompressorOn(index);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: setCompressorOn
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_setCompressorOn
(JNIEnv*, jclass, jint index, jboolean value)
{
HALSIM_SetPCMCompressorOn(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerClosedLoopEnabledCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerClosedLoopEnabledCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(env, index, callback, initialNotify,
&HALSIM_RegisterPCMClosedLoopEnabledCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: cancelClosedLoopEnabledCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_cancelClosedLoopEnabledCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelPCMClosedLoopEnabledCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: getClosedLoopEnabled
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_getClosedLoopEnabled
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetPCMClosedLoopEnabled(index);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: setClosedLoopEnabled
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_setClosedLoopEnabled
(JNIEnv*, jclass, jint index, jboolean value)
{
HALSIM_SetPCMClosedLoopEnabled(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerPressureSwitchCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerPressureSwitchCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(env, index, callback, initialNotify,
&HALSIM_RegisterPCMPressureSwitchCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: cancelPressureSwitchCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_cancelPressureSwitchCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelPCMPressureSwitchCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: getPressureSwitch
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_getPressureSwitch
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetPCMPressureSwitch(index);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: setPressureSwitch
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_setPressureSwitch
(JNIEnv*, jclass, jint index, jboolean value)
{
HALSIM_SetPCMPressureSwitch(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerCompressorCurrentCallback
* Signature: (ILjava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerCompressorCurrentCallback
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallback(env, index, callback, initialNotify,
&HALSIM_RegisterPCMCompressorCurrentCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: cancelCompressorCurrentCallback
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_cancelCompressorCurrentCallback
(JNIEnv* env, jclass, jint index, jint handle)
{
return sim::FreeCallback(env, handle, index,
&HALSIM_CancelPCMCompressorCurrentCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: getCompressorCurrent
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_getCompressorCurrent
(JNIEnv*, jclass, jint index)
{
return HALSIM_GetPCMCompressorCurrent(index);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: setCompressorCurrent
* Signature: (ID)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_setCompressorCurrent
(JNIEnv*, jclass, jint index, jdouble value)
{
HALSIM_SetPCMCompressorCurrent(index, value);
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerAllNonSolenoidCallbacks
* Signature: (ILjava/lang/Object;Z)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerAllNonSolenoidCallbacks
(JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify)
{
sim::AllocateCallback(
env, index, callback, initialNotify,
[](int32_t index, HAL_NotifyCallback cb, void* param, HAL_Bool in) {
HALSIM_RegisterPCMAllNonSolenoidCallbacks(index, cb, param, in);
return 0;
});
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: registerAllSolenoidCallbacks
* Signature: (IILjava/lang/Object;Z)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_registerAllSolenoidCallbacks
(JNIEnv* env, jclass, jint index, jint channel, jobject callback,
jboolean initialNotify)
{
sim::AllocateChannelCallback(
env, index, channel, callback, initialNotify,
[](int32_t index, int32_t channel, HAL_NotifyCallback cb, void* param,
HAL_Bool in) {
HALSIM_RegisterPCMAllSolenoidCallbacks(index, channel, cb, param, in);
return 0;
});
}
/*
* Class: edu_wpi_first_hal_simulation_PCMDataJNI
* Method: resetData
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_PCMDataJNI_resetData
(JNIEnv*, jclass, jint index)
{
HALSIM_ResetPCMData(index);
}
} // extern "C"

View File

@@ -0,0 +1,72 @@
// 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 <stdint.h>
#include "hal/Types.h"
/**
* @defgroup hal_ctre_pcm CTRE PCM Functions
* @ingroup hal_capi
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
HAL_CTREPCMHandle HAL_InitializeCTREPCM(int32_t module,
const char* allocationLocation,
int32_t* status);
void HAL_FreeCTREPCM(HAL_CTREPCMHandle handle);
HAL_Bool HAL_CheckCTREPCMSolenoidChannel(int32_t channel);
HAL_Bool HAL_GetCTREPCMCompressor(HAL_CTREPCMHandle handle, int32_t* status);
void HAL_SetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle, HAL_Bool enabled,
int32_t* status);
HAL_Bool HAL_GetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle,
int32_t* status);
HAL_Bool HAL_GetCTREPCMPressureSwitch(HAL_CTREPCMHandle handle,
int32_t* status);
double HAL_GetCTREPCMCompressorCurrent(HAL_CTREPCMHandle handle,
int32_t* status);
HAL_Bool HAL_GetCTREPCMCompressorCurrentTooHighFault(HAL_CTREPCMHandle handle,
int32_t* status);
HAL_Bool HAL_GetCTREPCMCompressorCurrentTooHighStickyFault(
HAL_CTREPCMHandle handle, int32_t* status);
HAL_Bool HAL_GetCTREPCMCompressorShortedStickyFault(HAL_CTREPCMHandle handle,
int32_t* status);
HAL_Bool HAL_GetCTREPCMCompressorShortedFault(HAL_CTREPCMHandle handle,
int32_t* status);
HAL_Bool HAL_GetCTREPCMCompressorNotConnectedStickyFault(
HAL_CTREPCMHandle handle, int32_t* status);
HAL_Bool HAL_GetCTREPCMCompressorNotConnectedFault(HAL_CTREPCMHandle handle,
int32_t* status);
int32_t HAL_GetCTREPCMSolenoids(HAL_CTREPCMHandle handle, int32_t* status);
void HAL_SetCTREPCMSolenoids(HAL_CTREPCMHandle handle, int32_t mask,
int32_t values, int32_t* status);
int32_t HAL_GetCTREPCMSolenoidDisabledList(HAL_CTREPCMHandle handle,
int32_t* status);
HAL_Bool HAL_GetCTREPCMSolenoidVoltageStickyFault(HAL_CTREPCMHandle handle,
int32_t* status);
HAL_Bool HAL_GetCTREPCMSolenoidVoltageFault(HAL_CTREPCMHandle handle,
int32_t* status);
void HAL_ClearAllCTREPCMStickyFaults(HAL_CTREPCMHandle handle, int32_t* status);
void HAL_FireCTREPCMOneShot(HAL_CTREPCMHandle handle, int32_t index,
int32_t* status);
void HAL_SetCTREPCMOneShotDuration(HAL_CTREPCMHandle handle, int32_t index,
int32_t durMs, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif
/** @} */

View File

@@ -1,140 +0,0 @@
// 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 <stdint.h>
#include "hal/Types.h"
/**
* @defgroup hal_compressor Compressor Functions
* @ingroup hal_capi
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initializes a compressor on the given PCM module.
*
* @param module the module number
* @return the created handle
*/
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status);
/**
* Gets if a compressor module is valid.
*
* @param module the module number
* @return true if the module is valid, otherwise false
*/
HAL_Bool HAL_CheckCompressorModule(int32_t module);
/**
* Gets the compressor state (on or off).
*
* @param compressorHandle the compressor handle
* @return true if the compressor is on, otherwise false
*/
HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
int32_t* status);
/**
* Sets the compressor to closed loop mode.
*
* @param compressorHandle the compressor handle
* @param value true for closed loop mode, false for off
*/
void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
HAL_Bool value, int32_t* status);
/**
* Gets if the compressor is in closed loop mode.
*
* @param compressorHandle the compressor handle
* @return true if the compressor is in closed loop mode,
* otherwise false
*/
HAL_Bool HAL_GetCompressorClosedLoopControl(
HAL_CompressorHandle compressorHandle, int32_t* status);
/**
* Gets the compressor pressure switch state.
*
* @param compressorHandle the compressor handle
* @return true if the pressure switch is triggered, otherwise
* false
*/
HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
int32_t* status);
/**
* Gets the compressor current.
*
* @param compressorHandle the compressor handle
* @return the compressor current in amps
*/
double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
int32_t* status);
/**
* Gets if the compressor is faulted because of too high of current.
*
* @param compressorHandle the compressor handle
* @return true if falted, otherwise false
*/
HAL_Bool HAL_GetCompressorCurrentTooHighFault(
HAL_CompressorHandle compressorHandle, int32_t* status);
/**
* Gets if a sticky fauly is triggered because of too high of current.
*
* @param compressorHandle the compressor handle
* @return true if falted, otherwise false
*/
HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status);
/**
* Gets if a sticky fauly is triggered because of a short.
*
* @param compressorHandle the compressor handle
* @return true if falted, otherwise false
*/
HAL_Bool HAL_GetCompressorShortedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status);
/**
* Gets if the compressor is faulted because of a short.
*
* @param compressorHandle the compressor handle
* @return true if shorted, otherwise false
*/
HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
int32_t* status);
/**
* Gets if a sticky fault is triggered of the compressor not connected.
*
* @param compressorHandle the compressor handle
* @return true if falted, otherwise false
*/
HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status);
/**
* Gets if the compressor is not connected.
*
* @param compressorHandle the compressor handle
* @return true if not connected, otherwise false
*/
HAL_Bool HAL_GetCompressorNotConnectedFault(
HAL_CompressorHandle compressorHandle, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif
/** @} */

View File

@@ -14,7 +14,7 @@
#include "hal/AnalogTrigger.h"
#include "hal/CAN.h"
#include "hal/CANAPI.h"
#include "hal/Compressor.h"
#include "hal/CTREPCM.h"
#include "hal/Constants.h"
#include "hal/Counter.h"
#include "hal/DIO.h"
@@ -35,7 +35,6 @@
#include "hal/SPI.h"
#include "hal/SerialPort.h"
#include "hal/SimDevice.h"
#include "hal/Solenoid.h"
#include "hal/Threads.h"
#include "hal/Types.h"
#include "hal/Value.h"

View File

@@ -119,7 +119,7 @@ int32_t HAL_GetNumRelayHeaders(void);
*
* @return the number of PCM modules
*/
int32_t HAL_GetNumPCMModules(void);
int32_t HAL_GetNumCTREPCMModules(void);
/**
* Gets the number of solenoid channels in the current system.

View File

@@ -1,138 +0,0 @@
// 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 <stdint.h>
#include "hal/Types.h"
/**
* @defgroup hal_solenoid Solenoid Output Functions
* @ingroup hal_capi
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initializes a solenoid port.
*
* @param portHandle the port handle of the module and channel to initialize
* @return the created solenoid handle
*/
HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
int32_t* status);
/**
* Frees a solenoid port.
*
* @param solenoidPortHandle the solenoid handle
*/
void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle);
/**
* Checks if a solenoid module is in the valid range.
*
* @param module the module number to check
* @return true if the module number is valid, otherwise false
*/
HAL_Bool HAL_CheckSolenoidModule(int32_t module);
/**
* Checks if a solenoid channel is in the valid range.
*
* @param channel the channel number to check
* @return true if the channel number is valid, otherwise false
*/
HAL_Bool HAL_CheckSolenoidChannel(int32_t channel);
/**
* Gets the current solenoid output value.
*
* @param solenoidPortHandle the solenoid handle
* @return true if the solenoid is on, otherwise false
*/
HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
int32_t* status);
/**
* Gets the status of all solenoids on a specific module.
*
* @param module the module to check
* @return bitmask of the channels, 1 for on 0 for off
*/
int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status);
/**
* Sets a solenoid output value.
*
* @param solenoidPortHandle the solenoid handle
* @param value true for on, false for off
*/
void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
int32_t* status);
/**
* Sets all channels on a specific module.
*
* @param module the module to set the channels on
* @param state bitmask of the channels to set, 1 for on 0 for off
*/
void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status);
/**
* Gets the channels blacklisted from being enabled on a module.
*
* @param module the module to check
* @retur bitmask of the blacklisted channels, 1 for true 0 for false
*/
int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status);
/**
* Gets if a specific module has an over or under voltage sticky fault.
*
* @param module the module to check
* @return true if a stick fault is set, otherwise false
*/
HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status);
/**
* Gets if a specific module has an over or under voltage fault.
*
* @param module the module to check
* @return true if faulted, otherwise false
*/
HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status);
/**
* Clears all faults on a module.
*
* @param module the module to clear
*/
void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status);
/**
* Sets the one shot duration on a solenoid channel.
*
* @param solenoidPortHandle the solenoid handle
* @param durMS the one shot duration in ms
*/
void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
int32_t durMS, int32_t* status);
/**
* Fires a single pulse on a solenoid channel.
*
* The pulse is the duration set by HAL_SetOneShotDuration().
*
* @param solenoidPortHandle the solenoid handle
*/
void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif
/** @} */

View File

@@ -62,6 +62,8 @@ typedef HAL_Handle HAL_AddressableLEDHandle;
typedef HAL_CANHandle HAL_PDPHandle;
typedef HAL_Handle HAL_CTREPCMHandle;
typedef int32_t HAL_Bool;
#ifdef __cplusplus

View File

@@ -66,6 +66,7 @@ enum class HAL_HandleEnum {
DutyCycle = 21,
DMA = 22,
AddressableLED = 23,
CTREPCM = 24,
};
/**

View File

@@ -0,0 +1,78 @@
// 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 "hal/Types.h"
#include "hal/simulation/NotifyListener.h"
#ifdef __cplusplus
extern "C" {
#endif
void HALSIM_ResetCTREPCMData(int32_t index);
int32_t HALSIM_RegisterCTREPCMInitializedCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelCTREPCMInitializedCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetCTREPCMInitialized(int32_t index);
void HALSIM_SetCTREPCMInitialized(int32_t index, HAL_Bool solenoidInitialized);
int32_t HALSIM_RegisterCTREPCMSolenoidOutputCallback(
int32_t index, int32_t channel, HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
void HALSIM_CancelCTREPCMSolenoidOutputCallback(int32_t index, int32_t channel,
int32_t uid);
HAL_Bool HALSIM_GetCTREPCMSolenoidOutput(int32_t index, int32_t channel);
void HALSIM_SetCTREPCMSolenoidOutput(int32_t index, int32_t channel,
HAL_Bool solenoidOutput);
int32_t HALSIM_RegisterCTREPCMCompressorOnCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelCTREPCMCompressorOnCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetCTREPCMCompressorOn(int32_t index);
void HALSIM_SetCTREPCMCompressorOn(int32_t index, HAL_Bool compressorOn);
int32_t HALSIM_RegisterCTREPCMClosedLoopEnabledCallback(
int32_t index, HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
void HALSIM_CancelCTREPCMClosedLoopEnabledCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetCTREPCMClosedLoopEnabled(int32_t index);
void HALSIM_SetCTREPCMClosedLoopEnabled(int32_t index,
HAL_Bool closedLoopEnabled);
int32_t HALSIM_RegisterCTREPCMPressureSwitchCallback(
int32_t index, HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
void HALSIM_CancelCTREPCMPressureSwitchCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetCTREPCMPressureSwitch(int32_t index);
void HALSIM_SetCTREPCMPressureSwitch(int32_t index, HAL_Bool pressureSwitch);
int32_t HALSIM_RegisterCTREPCMCompressorCurrentCallback(
int32_t index, HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
void HALSIM_CancelCTREPCMCompressorCurrentCallback(int32_t index, int32_t uid);
double HALSIM_GetCTREPCMCompressorCurrent(int32_t index);
void HALSIM_SetCTREPCMCompressorCurrent(int32_t index,
double compressorCurrent);
void HALSIM_GetCTREPCMAllSolenoids(int32_t index, uint8_t* values);
void HALSIM_SetCTREPCMAllSolenoids(int32_t index, uint8_t values);
void HALSIM_RegisterCTREPCMAllNonSolenoidCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_RegisterCTREPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -1,97 +0,0 @@
// 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 "hal/Types.h"
#include "hal/simulation/NotifyListener.h"
#ifdef __cplusplus
extern "C" {
#endif
void HALSIM_ResetPCMData(int32_t index);
int32_t HALSIM_RegisterPCMSolenoidInitializedCallback(
int32_t index, int32_t channel, HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
void HALSIM_CancelPCMSolenoidInitializedCallback(int32_t index, int32_t channel,
int32_t uid);
HAL_Bool HALSIM_GetPCMSolenoidInitialized(int32_t index, int32_t channel);
void HALSIM_SetPCMSolenoidInitialized(int32_t index, int32_t channel,
HAL_Bool solenoidInitialized);
int32_t HALSIM_RegisterPCMSolenoidOutputCallback(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelPCMSolenoidOutputCallback(int32_t index, int32_t channel,
int32_t uid);
HAL_Bool HALSIM_GetPCMSolenoidOutput(int32_t index, int32_t channel);
void HALSIM_SetPCMSolenoidOutput(int32_t index, int32_t channel,
HAL_Bool solenoidOutput);
int32_t HALSIM_RegisterPCMAnySolenoidInitializedCallback(
int32_t index, HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
void HALSIM_CancelPCMAnySolenoidInitializedCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetPCMAnySolenoidInitialized(int32_t index);
void HALSIM_SetPCMAnySolenoidInitialized(int32_t index,
HAL_Bool anySolenoidInitialized);
int32_t HALSIM_RegisterPCMCompressorInitializedCallback(
int32_t index, HAL_NotifyCallback callback, void* param,
HAL_Bool initialNotify);
void HALSIM_CancelPCMCompressorInitializedCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetPCMCompressorInitialized(int32_t index);
void HALSIM_SetPCMCompressorInitialized(int32_t index,
HAL_Bool compressorInitialized);
int32_t HALSIM_RegisterPCMCompressorOnCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelPCMCompressorOnCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetPCMCompressorOn(int32_t index);
void HALSIM_SetPCMCompressorOn(int32_t index, HAL_Bool compressorOn);
int32_t HALSIM_RegisterPCMClosedLoopEnabledCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelPCMClosedLoopEnabledCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetPCMClosedLoopEnabled(int32_t index);
void HALSIM_SetPCMClosedLoopEnabled(int32_t index, HAL_Bool closedLoopEnabled);
int32_t HALSIM_RegisterPCMPressureSwitchCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelPCMPressureSwitchCallback(int32_t index, int32_t uid);
HAL_Bool HALSIM_GetPCMPressureSwitch(int32_t index);
void HALSIM_SetPCMPressureSwitch(int32_t index, HAL_Bool pressureSwitch);
int32_t HALSIM_RegisterPCMCompressorCurrentCallback(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelPCMCompressorCurrentCallback(int32_t index, int32_t uid);
double HALSIM_GetPCMCompressorCurrent(int32_t index);
void HALSIM_SetPCMCompressorCurrent(int32_t index, double compressorCurrent);
void HALSIM_GetPCMAllSolenoids(int32_t index, uint8_t* values);
void HALSIM_SetPCMAllSolenoids(int32_t index, uint8_t values);
void HALSIM_RegisterPCMAllNonSolenoidCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -0,0 +1,212 @@
// 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 "hal/CTREPCM.h"
#include "HALInitializer.h"
#include "HALInternal.h"
#include "PortsInternal.h"
#include "hal/CANAPI.h"
#include "hal/Errors.h"
#include "hal/handles/IndexedHandleResource.h"
#include "mockdata/CTREPCMDataInternal.h"
using namespace hal;
namespace {
struct PCM {
int32_t module;
wpi::mutex lock;
std::string previousAllocation;
};
} // namespace
static IndexedHandleResource<HAL_CTREPCMHandle, PCM, kNumCTREPCMModules,
HAL_HandleEnum::CTREPCM>* pcmHandles;
namespace hal::init {
void InitializeCTREPCM() {
static IndexedHandleResource<HAL_CTREPCMHandle, PCM, kNumCTREPCMModules,
HAL_HandleEnum::CTREPCM>
pH;
pcmHandles = &pH;
}
} // namespace hal::init
HAL_CTREPCMHandle HAL_InitializeCTREPCM(int32_t module,
const char* allocationLocation,
int32_t* status) {
hal::init::CheckInit();
HAL_CTREPCMHandle handle;
auto pcm = pcmHandles->Allocate(module, &handle, status);
if (*status != 0) {
if (pcm) {
hal::SetLastErrorPreviouslyAllocated(status, "CTRE PCM", module,
pcm->previousAllocation);
} else {
hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for CTRE PCM", 0,
kNumAccumulators, module);
}
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
}
pcm->previousAllocation = allocationLocation ? allocationLocation : "";
pcm->module = module;
SimCTREPCMData[module].initialized = true;
// Enable closed loop
SimCTREPCMData[module].closedLoopEnabled = true;
return handle;
}
void HAL_FreeCTREPCM(HAL_CTREPCMHandle handle) {
pcmHandles->Free(handle);
}
HAL_Bool HAL_CheckCTREPCMSolenoidChannel(int32_t channel) {
return channel < kNumCTRESolenoidChannels && channel >= 0;
}
HAL_Bool HAL_GetCTREPCMCompressor(HAL_CTREPCMHandle handle, int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimCTREPCMData[pcm->module].compressorOn;
}
void HAL_SetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle, HAL_Bool enabled,
int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
SimCTREPCMData[pcm->module].closedLoopEnabled = enabled;
}
HAL_Bool HAL_GetCTREPCMClosedLoopControl(HAL_CTREPCMHandle handle,
int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimCTREPCMData[pcm->module].closedLoopEnabled;
}
HAL_Bool HAL_GetCTREPCMPressureSwitch(HAL_CTREPCMHandle handle,
int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimCTREPCMData[pcm->module].pressureSwitch;
}
double HAL_GetCTREPCMCompressorCurrent(HAL_CTREPCMHandle handle,
int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
return SimCTREPCMData[pcm->module].compressorCurrent;
}
HAL_Bool HAL_GetCTREPCMCompressorCurrentTooHighFault(HAL_CTREPCMHandle handle,
int32_t* status) {
return false;
}
HAL_Bool HAL_GetCTREPCMCompressorCurrentTooHighStickyFault(
HAL_CTREPCMHandle handle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCTREPCMCompressorShortedStickyFault(HAL_CTREPCMHandle handle,
int32_t* status) {
return false;
}
HAL_Bool HAL_GetCTREPCMCompressorShortedFault(HAL_CTREPCMHandle handle,
int32_t* status) {
return false;
}
HAL_Bool HAL_GetCTREPCMCompressorNotConnectedStickyFault(
HAL_CTREPCMHandle handle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCTREPCMCompressorNotConnectedFault(HAL_CTREPCMHandle handle,
int32_t* status) {
return false;
}
int32_t HAL_GetCTREPCMSolenoids(HAL_CTREPCMHandle handle, int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
std::scoped_lock lock{pcm->lock};
auto& data = SimCTREPCMData[pcm->module].solenoidOutput;
uint8_t ret = 0;
for (int i = 0; i < kNumCTRESolenoidChannels; i++) {
ret |= (data[i] << i);
}
return ret;
}
void HAL_SetCTREPCMSolenoids(HAL_CTREPCMHandle handle, int32_t mask,
int32_t values, int32_t* status) {
auto pcm = pcmHandles->Get(handle);
if (pcm == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
auto& data = SimCTREPCMData[pcm->module].solenoidOutput;
std::scoped_lock lock{pcm->lock};
for (int i = 0; i < kNumCTRESolenoidChannels; i++) {
auto indexMask = (1 << i);
if ((mask & indexMask) != 0) {
data[i] = (values & indexMask) != 0;
}
}
}
int32_t HAL_GetCTREPCMSolenoidDisabledList(HAL_CTREPCMHandle handle,
int32_t* status) {
return 0;
}
HAL_Bool HAL_GetCTREPCMSolenoidVoltageStickyFault(HAL_CTREPCMHandle handle,
int32_t* status) {
return false;
}
HAL_Bool HAL_GetCTREPCMSolenoidVoltageFault(HAL_CTREPCMHandle handle,
int32_t* status) {
return false;
}
void HAL_ClearAllCTREPCMStickyFaults(HAL_CTREPCMHandle handle,
int32_t* status) {}
void HAL_FireCTREPCMOneShot(HAL_CTREPCMHandle handle, int32_t index,
int32_t* status) {}
void HAL_SetCTREPCMOneShotDuration(HAL_CTREPCMHandle handle, int32_t index,
int32_t durMs, int32_t* status) {}

View File

@@ -1,118 +0,0 @@
// 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 "hal/Compressor.h"
#include "HALInitializer.h"
#include "PortsInternal.h"
#include "hal/Errors.h"
#include "hal/handles/HandlesInternal.h"
#include "mockdata/PCMDataInternal.h"
using namespace hal;
namespace hal::init {
void InitializeCompressor() {}
} // namespace hal::init
extern "C" {
HAL_CompressorHandle HAL_InitializeCompressor(int32_t module, int32_t* status) {
hal::init::CheckInit();
// As compressors can have unlimited objects, just create a
// handle with the module number as the index.
SimPCMData[module].compressorInitialized = true;
return (HAL_CompressorHandle)createHandle(static_cast<int16_t>(module),
HAL_HandleEnum::Compressor, 0);
}
HAL_Bool HAL_CheckCompressorModule(int32_t module) {
return module < kNumPCMModules && module >= 0;
}
HAL_Bool HAL_GetCompressor(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].compressorOn;
}
void HAL_SetCompressorClosedLoopControl(HAL_CompressorHandle compressorHandle,
HAL_Bool value, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return;
}
SimPCMData[index].closedLoopEnabled = value;
}
HAL_Bool HAL_GetCompressorClosedLoopControl(
HAL_CompressorHandle compressorHandle, int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].closedLoopEnabled;
}
HAL_Bool HAL_GetCompressorPressureSwitch(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return false;
}
return SimPCMData[index].pressureSwitch;
}
double HAL_GetCompressorCurrent(HAL_CompressorHandle compressorHandle,
int32_t* status) {
int16_t index =
getHandleTypedIndex(compressorHandle, HAL_HandleEnum::Compressor, 0);
if (index == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return 0;
}
return SimPCMData[index].compressorCurrent;
}
HAL_Bool HAL_GetCompressorCurrentTooHighFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorCurrentTooHighStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorShortedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorShortedFault(HAL_CompressorHandle compressorHandle,
int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorNotConnectedStickyFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
HAL_Bool HAL_GetCompressorNotConnectedFault(
HAL_CompressorHandle compressorHandle, int32_t* status) {
return false;
}
} // extern "C"

View File

@@ -73,7 +73,7 @@ void InitializeHAL() {
InitializeDriverStationData();
InitializeEncoderData();
InitializeI2CData();
InitializePCMData();
InitializeCTREPCMData();
InitializePDPData();
InitializePWMData();
InitializeRelayData();
@@ -90,7 +90,6 @@ void InitializeHAL() {
InitializeAnalogOutput();
InitializeAnalogTrigger();
InitializeCAN();
InitializeCompressor();
InitializeConstants();
InitializeCounter();
InitializeDigitalInternal();
@@ -107,11 +106,11 @@ void InitializeHAL() {
InitializePDP();
InitializePorts();
InitializePower();
InitializeCTREPCM();
InitializePWM();
InitializeRelay();
InitializeSerialPort();
InitializeSimDevice();
InitializeSolenoid();
InitializeSPI();
InitializeThreads();
}

View File

@@ -31,7 +31,7 @@ extern void InitializeDutyCycle();
extern void InitializeDriverStationData();
extern void InitializeEncoderData();
extern void InitializeI2CData();
extern void InitializePCMData();
extern void InitializeCTREPCMData();
extern void InitializePDPData();
extern void InitializePWMData();
extern void InitializeRelayData();
@@ -48,7 +48,6 @@ extern void InitializeAnalogInternal();
extern void InitializeAnalogOutput();
extern void InitializeAnalogTrigger();
extern void InitializeCAN();
extern void InitializeCompressor();
extern void InitializeConstants();
extern void InitializeCounter();
extern void InitializeDigitalInternal();
@@ -65,11 +64,11 @@ extern void InitializeNotifier();
extern void InitializePDP();
extern void InitializePorts();
extern void InitializePower();
extern void InitializeCTREPCM();
extern void InitializePWM();
extern void InitializeRelay();
extern void InitializeSerialPort();
extern void InitializeSimDevice();
extern void InitializeSolenoid();
extern void InitializeSPI();
extern void InitializeThreads();

View File

@@ -55,11 +55,11 @@ int32_t HAL_GetNumRelayChannels(void) {
int32_t HAL_GetNumRelayHeaders(void) {
return kNumRelayHeaders;
}
int32_t HAL_GetNumPCMModules(void) {
return kNumPCMModules;
int32_t HAL_GetNumCTREPCMModules(void) {
return kNumCTREPCMModules;
}
int32_t HAL_GetNumSolenoidChannels(void) {
return kNumSolenoidChannels;
return kNumCTRESolenoidChannels;
}
int32_t HAL_GetNumPDPModules(void) {
return kNumPDPModules;

View File

@@ -21,8 +21,8 @@ constexpr int32_t kNumEncoders = 8;
constexpr int32_t kNumInterrupts = 8;
constexpr int32_t kNumRelayChannels = 8;
constexpr int32_t kNumRelayHeaders = kNumRelayChannels / 2;
constexpr int32_t kNumPCMModules = 63;
constexpr int32_t kNumSolenoidChannels = 8;
constexpr int32_t kNumCTREPCMModules = 63;
constexpr int32_t kNumCTRESolenoidChannels = 8;
constexpr int32_t kNumPDPModules = 63;
constexpr int32_t kNumPDPChannels = 16;
constexpr int32_t kNumDutyCycles = 8;

View File

@@ -1,148 +0,0 @@
// 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 "hal/Solenoid.h"
#include "HALInitializer.h"
#include "PortsInternal.h"
#include "hal/Errors.h"
#include "hal/handles/HandlesInternal.h"
#include "hal/handles/IndexedHandleResource.h"
#include "hal/simulation/PCMData.h"
namespace {
struct Solenoid {
uint8_t module;
uint8_t channel;
};
} // namespace
using namespace hal;
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
kNumPCMModules * kNumSolenoidChannels,
HAL_HandleEnum::Solenoid>* solenoidHandles;
namespace hal::init {
void InitializeSolenoid() {
static IndexedHandleResource<HAL_SolenoidHandle, Solenoid,
kNumPCMModules * kNumSolenoidChannels,
HAL_HandleEnum::Solenoid>
sH;
solenoidHandles = &sH;
}
} // namespace hal::init
extern "C" {
HAL_SolenoidHandle HAL_InitializeSolenoidPort(HAL_PortHandle portHandle,
int32_t* status) {
hal::init::CheckInit();
int16_t channel = getPortHandleChannel(portHandle);
int16_t module = getPortHandleModule(portHandle);
if (channel == InvalidHandleIndex) {
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
}
if (!HAL_CheckSolenoidChannel(channel)) {
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
if (!HAL_CheckSolenoidModule(module)) {
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
HAL_SolenoidHandle handle;
auto solenoidPort = solenoidHandles->Allocate(
module * kNumSolenoidChannels + channel, &handle, status);
if (handle == HAL_kInvalidHandle) { // out of resources
*status = NO_AVAILABLE_RESOURCES;
return HAL_kInvalidHandle;
}
solenoidPort->module = static_cast<uint8_t>(module);
solenoidPort->channel = static_cast<uint8_t>(channel);
HALSIM_SetPCMSolenoidInitialized(module, channel, true);
HALSIM_SetPCMAnySolenoidInitialized(module, true);
return handle;
}
void HAL_FreeSolenoidPort(HAL_SolenoidHandle solenoidPortHandle) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
return;
}
solenoidHandles->Free(solenoidPortHandle);
HALSIM_SetPCMSolenoidInitialized(port->module, port->channel, false);
int count = 0;
for (int i = 0; i < kNumSolenoidChannels; ++i) {
if (HALSIM_GetPCMSolenoidInitialized(port->module, i)) {
++count;
}
}
if (count == 0) {
HALSIM_SetPCMAnySolenoidInitialized(port->module, false);
}
}
HAL_Bool HAL_CheckSolenoidModule(int32_t module) {
return module < kNumPCMModules && module >= 0;
}
HAL_Bool HAL_CheckSolenoidChannel(int32_t channel) {
return channel < kNumSolenoidChannels && channel >= 0;
}
HAL_Bool HAL_GetSolenoid(HAL_SolenoidHandle solenoidPortHandle,
int32_t* status) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
}
return HALSIM_GetPCMSolenoidOutput(port->module, port->channel);
}
int32_t HAL_GetAllSolenoids(int32_t module, int32_t* status) {
int32_t total = 0;
for (int i = 0; i < kNumSolenoidChannels; i++) {
int32_t channel = HALSIM_GetPCMSolenoidOutput(module, i) ? 1 : 0;
total = total + (channel << i);
}
return total;
}
void HAL_SetSolenoid(HAL_SolenoidHandle solenoidPortHandle, HAL_Bool value,
int32_t* status) {
auto port = solenoidHandles->Get(solenoidPortHandle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
HALSIM_SetPCMSolenoidOutput(port->module, port->channel, value);
}
void HAL_SetAllSolenoids(int32_t module, int32_t state, int32_t* status) {
for (int i = 0; i < kNumSolenoidChannels; i++) {
int set = state & 1;
HALSIM_SetPCMSolenoidOutput(module, i, set);
state >>= 1;
}
}
int32_t HAL_GetPCMSolenoidBlackList(int32_t module, int32_t* status) {
return 0;
}
HAL_Bool HAL_GetPCMSolenoidVoltageStickyFault(int32_t module, int32_t* status) {
return 0;
}
HAL_Bool HAL_GetPCMSolenoidVoltageFault(int32_t module, int32_t* status) {
return 0;
}
void HAL_ClearAllPCMStickyFaults(int32_t module, int32_t* status) {}
void HAL_SetOneShotDuration(HAL_SolenoidHandle solenoidPortHandle,
int32_t durMS, int32_t* status) {}
void HAL_FireOneShot(HAL_SolenoidHandle solenoidPortHandle, int32_t* status) {}
} // extern "C"

View File

@@ -0,0 +1,83 @@
// 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 "../PortsInternal.h"
#include "CTREPCMDataInternal.h"
using namespace hal;
namespace hal::init {
void InitializeCTREPCMData() {
static CTREPCMData spd[kNumCTREPCMModules];
::hal::SimCTREPCMData = spd;
}
} // namespace hal::init
CTREPCMData* hal::SimCTREPCMData;
void CTREPCMData::ResetData() {
for (int i = 0; i < kNumCTRESolenoidChannels; i++) {
solenoidOutput[i].Reset(false);
}
initialized.Reset(false);
compressorOn.Reset(false);
closedLoopEnabled.Reset(true);
pressureSwitch.Reset(false);
compressorCurrent.Reset(0.0);
}
extern "C" {
void HALSIM_ResetCTREPCMData(int32_t index) {
SimCTREPCMData[index].ResetData();
}
#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, CTREPCM##CAPINAME, \
SimCTREPCMData, LOWERNAME)
HAL_SIMDATAVALUE_DEFINE_CAPI_CHANNEL(HAL_Bool, HALSIM, CTREPCMSolenoidOutput,
SimCTREPCMData, solenoidOutput)
DEFINE_CAPI(HAL_Bool, Initialized, initialized)
DEFINE_CAPI(HAL_Bool, CompressorOn, compressorOn)
DEFINE_CAPI(HAL_Bool, ClosedLoopEnabled, closedLoopEnabled)
DEFINE_CAPI(HAL_Bool, PressureSwitch, pressureSwitch)
DEFINE_CAPI(double, CompressorCurrent, compressorCurrent)
void HALSIM_GetCTREPCMAllSolenoids(int32_t index, uint8_t* values) {
auto& data = SimCTREPCMData[index].solenoidOutput;
uint8_t ret = 0;
for (int i = 0; i < kNumCTRESolenoidChannels; i++) {
ret |= (data[i] << i);
}
*values = ret;
}
void HALSIM_SetCTREPCMAllSolenoids(int32_t index, uint8_t values) {
auto& data = SimCTREPCMData[index].solenoidOutput;
for (int i = 0; i < kNumCTRESolenoidChannels; i++) {
data[i] = (values & 0x1) != 0;
values >>= 1;
}
}
#define REGISTER(NAME) \
SimCTREPCMData[index].NAME.RegisterCallback(callback, param, initialNotify)
void HALSIM_RegisterCTREPCMAllNonSolenoidCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {
REGISTER(initialized);
REGISTER(compressorOn);
REGISTER(closedLoopEnabled);
REGISTER(pressureSwitch);
REGISTER(compressorCurrent);
}
void HALSIM_RegisterCTREPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {
REGISTER(solenoidOutput[channel]);
}
} // extern "C"

View File

@@ -5,40 +5,29 @@
#pragma once
#include "../PortsInternal.h"
#include "hal/simulation/PCMData.h"
#include "hal/simulation/CTREPCMData.h"
#include "hal/simulation/SimDataValue.h"
namespace hal {
class PCMData {
HAL_SIMDATAVALUE_DEFINE_NAME(SolenoidInitialized)
class CTREPCMData {
HAL_SIMDATAVALUE_DEFINE_NAME(Initialized)
HAL_SIMDATAVALUE_DEFINE_NAME(SolenoidOutput)
HAL_SIMDATAVALUE_DEFINE_NAME(AnySolenoidInitialized)
HAL_SIMDATAVALUE_DEFINE_NAME(CompressorInitialized)
HAL_SIMDATAVALUE_DEFINE_NAME(CompressorOn)
HAL_SIMDATAVALUE_DEFINE_NAME(ClosedLoopEnabled)
HAL_SIMDATAVALUE_DEFINE_NAME(PressureSwitch)
HAL_SIMDATAVALUE_DEFINE_NAME(CompressorCurrent)
static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr HAL_Bool
GetSolenoidInitializedDefault() {
return false;
}
static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr HAL_Bool
GetSolenoidOutputDefault() {
return false;
}
public:
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetSolenoidInitializedName,
GetSolenoidInitializedDefault>
solenoidInitialized[kNumSolenoidChannels];
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetInitializedName> initialized{
false};
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetSolenoidOutputName,
GetSolenoidOutputDefault>
solenoidOutput[kNumSolenoidChannels];
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetAnySolenoidInitializedName>
anySolenoidInitialized{false};
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetCompressorInitializedName>
compressorInitialized{false};
solenoidOutput[kNumCTRESolenoidChannels];
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetCompressorOnName> compressorOn{
false};
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetClosedLoopEnabledName>
@@ -50,5 +39,5 @@ class PCMData {
virtual void ResetData();
};
extern PCMData* SimPCMData;
extern CTREPCMData* SimCTREPCMData;
} // namespace hal

View File

@@ -1,89 +0,0 @@
// 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 "../PortsInternal.h"
#include "PCMDataInternal.h"
using namespace hal;
namespace hal::init {
void InitializePCMData() {
static PCMData spd[kNumPCMModules];
::hal::SimPCMData = spd;
}
} // namespace hal::init
PCMData* hal::SimPCMData;
void PCMData::ResetData() {
for (int i = 0; i < kNumSolenoidChannels; i++) {
solenoidInitialized[i].Reset(false);
solenoidOutput[i].Reset(false);
}
anySolenoidInitialized.Reset(false);
compressorInitialized.Reset(false);
compressorOn.Reset(false);
closedLoopEnabled.Reset(true);
pressureSwitch.Reset(false);
compressorCurrent.Reset(0.0);
}
extern "C" {
void HALSIM_ResetPCMData(int32_t index) {
SimPCMData[index].ResetData();
}
#define DEFINE_CAPI(TYPE, CAPINAME, LOWERNAME) \
HAL_SIMDATAVALUE_DEFINE_CAPI(TYPE, HALSIM, PCM##CAPINAME, SimPCMData, \
LOWERNAME)
HAL_SIMDATAVALUE_DEFINE_CAPI_CHANNEL(HAL_Bool, HALSIM, PCMSolenoidInitialized,
SimPCMData, solenoidInitialized)
HAL_SIMDATAVALUE_DEFINE_CAPI_CHANNEL(HAL_Bool, HALSIM, PCMSolenoidOutput,
SimPCMData, solenoidOutput)
DEFINE_CAPI(HAL_Bool, AnySolenoidInitialized, anySolenoidInitialized)
DEFINE_CAPI(HAL_Bool, CompressorInitialized, compressorInitialized)
DEFINE_CAPI(HAL_Bool, CompressorOn, compressorOn)
DEFINE_CAPI(HAL_Bool, ClosedLoopEnabled, closedLoopEnabled)
DEFINE_CAPI(HAL_Bool, PressureSwitch, pressureSwitch)
DEFINE_CAPI(double, CompressorCurrent, compressorCurrent)
void HALSIM_GetPCMAllSolenoids(int32_t index, uint8_t* values) {
auto& data = SimPCMData[index].solenoidOutput;
uint8_t ret = 0;
for (int i = 0; i < kNumSolenoidChannels; i++) {
ret |= (data[i] << i);
}
*values = ret;
}
void HALSIM_SetPCMAllSolenoids(int32_t index, uint8_t values) {
auto& data = SimPCMData[index].solenoidOutput;
for (int i = 0; i < kNumSolenoidChannels; i++) {
data[i] = (values & 0x1) != 0;
values >>= 1;
}
}
#define REGISTER(NAME) \
SimPCMData[index].NAME.RegisterCallback(callback, param, initialNotify)
void HALSIM_RegisterPCMAllNonSolenoidCallbacks(int32_t index,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {
REGISTER(compressorInitialized);
REGISTER(compressorOn);
REGISTER(closedLoopEnabled);
REGISTER(pressureSwitch);
REGISTER(compressorCurrent);
}
void HALSIM_RegisterPCMAllSolenoidCallbacks(int32_t index, int32_t channel,
HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {
REGISTER(solenoidInitialized[channel]);
REGISTER(solenoidOutput[channel]);
}
} // extern "C"

View File

@@ -4,16 +4,9 @@
#include "gtest/gtest.h"
#include "hal/HAL.h"
#include "hal/Solenoid.h"
namespace hal {
TEST(HALTests, RuntimeType) {
EXPECT_EQ(HAL_RuntimeType::HAL_Mock, HAL_GetRuntimeType());
}
TEST(HALSOLENOID, SolenoidTest) {
int32_t status = 0;
HAL_InitializeSolenoidPort(0, &status);
EXPECT_NE(status, 0);
}
} // namespace hal

View File

@@ -6,7 +6,6 @@
#include "gtest/gtest.h"
#include "hal/HAL.h"
#include "hal/Solenoid.h"
#include "hal/simulation/DriverStationData.h"
namespace hal {

View File

@@ -3,10 +3,10 @@
// the WPILib BSD license file in the root directory of this project.
#include "gtest/gtest.h"
#include "hal/CTREPCM.h"
#include "hal/HAL.h"
#include "hal/Solenoid.h"
#include "hal/handles/HandlesInternal.h"
#include "hal/simulation/PCMData.h"
#include "hal/simulation/CTREPCMData.h"
namespace hal {
@@ -19,62 +19,65 @@ void TestSolenoidInitializationCallback(const char* name, void* param,
gTestSolenoidCallbackValue = *value;
}
TEST(SolenoidSimTests, TestSolenoidInitialization) {
TEST(SolenoidSimTests, TestPCMInitialization) {
const int MODULE_TO_TEST = 2;
const int CHANNEL_TO_TEST = 3;
int callbackParam = 0;
int callbackId = HALSIM_RegisterPCMSolenoidInitializedCallback(
MODULE_TO_TEST, CHANNEL_TO_TEST, &TestSolenoidInitializationCallback,
&callbackParam, false);
int callbackId = HALSIM_RegisterCTREPCMInitializedCallback(
MODULE_TO_TEST, &TestSolenoidInitializationCallback, &callbackParam,
false);
ASSERT_TRUE(0 != callbackId);
int32_t status;
HAL_PortHandle portHandle;
HAL_DigitalHandle solenoidHandle;
int32_t module;
HAL_CTREPCMHandle pcmHandle;
// Use out of range index
status = 0;
portHandle = 8000;
module = 8000;
gTestSolenoidCallbackName = "Unset";
solenoidHandle = HAL_InitializeSolenoidPort(portHandle, &status);
EXPECT_EQ(HAL_kInvalidHandle, solenoidHandle);
EXPECT_EQ(HAL_HANDLE_ERROR, status);
pcmHandle = HAL_InitializeCTREPCM(module, nullptr, &status);
EXPECT_EQ(HAL_kInvalidHandle, pcmHandle);
EXPECT_EQ(HAL_USE_LAST_ERROR, status);
HAL_GetLastError(&status);
EXPECT_EQ(RESOURCE_OUT_OF_RANGE, status);
EXPECT_STREQ("Unset", gTestSolenoidCallbackName.c_str());
// Successful setup
status = 0;
portHandle = HAL_GetPortWithModule(MODULE_TO_TEST, CHANNEL_TO_TEST);
module = MODULE_TO_TEST;
gTestSolenoidCallbackName = "Unset";
solenoidHandle = HAL_InitializeSolenoidPort(portHandle, &status);
EXPECT_TRUE(HAL_kInvalidHandle != solenoidHandle);
pcmHandle = HAL_InitializeCTREPCM(module, nullptr, &status);
EXPECT_TRUE(HAL_kInvalidHandle != pcmHandle);
EXPECT_EQ(0, status);
EXPECT_STREQ("SolenoidInitialized", gTestSolenoidCallbackName.c_str());
EXPECT_STREQ("Initialized", gTestSolenoidCallbackName.c_str());
// Double initialize... should fail
status = 0;
portHandle = HAL_GetPortWithModule(MODULE_TO_TEST, CHANNEL_TO_TEST);
module = MODULE_TO_TEST;
gTestSolenoidCallbackName = "Unset";
solenoidHandle = HAL_InitializeSolenoidPort(portHandle, &status);
EXPECT_EQ(HAL_kInvalidHandle, solenoidHandle);
EXPECT_EQ(NO_AVAILABLE_RESOURCES, status);
pcmHandle = HAL_InitializeCTREPCM(module, nullptr, &status);
EXPECT_EQ(HAL_kInvalidHandle, pcmHandle);
EXPECT_EQ(HAL_USE_LAST_ERROR, status);
HAL_GetLastError(&status);
EXPECT_EQ(RESOURCE_IS_ALLOCATED, status);
EXPECT_STREQ("Unset", gTestSolenoidCallbackName.c_str());
// Reset, should allow you to re-register
hal::HandleBase::ResetGlobalHandles();
HALSIM_ResetPCMData(MODULE_TO_TEST);
callbackId = HALSIM_RegisterPCMSolenoidInitializedCallback(
MODULE_TO_TEST, CHANNEL_TO_TEST, &TestSolenoidInitializationCallback,
&callbackParam, false);
HALSIM_ResetCTREPCMData(MODULE_TO_TEST);
callbackId = HALSIM_RegisterCTREPCMInitializedCallback(
MODULE_TO_TEST, &TestSolenoidInitializationCallback, &callbackParam,
false);
ASSERT_TRUE(0 != callbackId);
status = 0;
portHandle = HAL_GetPortWithModule(MODULE_TO_TEST, CHANNEL_TO_TEST);
module = MODULE_TO_TEST;
gTestSolenoidCallbackName = "Unset";
solenoidHandle = HAL_InitializeSolenoidPort(portHandle, &status);
EXPECT_TRUE(HAL_kInvalidHandle != solenoidHandle);
pcmHandle = HAL_InitializeCTREPCM(module, nullptr, &status);
EXPECT_TRUE(HAL_kInvalidHandle != pcmHandle);
EXPECT_EQ(0, status);
EXPECT_STREQ("SolenoidInitialized", gTestSolenoidCallbackName.c_str());
EXPECT_STREQ("Initialized", gTestSolenoidCallbackName.c_str());
}
} // namespace hal

View File

@@ -7,8 +7,8 @@
#include <string>
#include <hal/Value.h>
#include <hal/simulation/CTREPCMData.h>
#include <hal/simulation/NotifyListener.h>
#include <hal/simulation/PCMData.h>
#include "simulation/gz_msgs/msgs.h"
@@ -30,10 +30,9 @@ GazeboPCM::GazeboPCM(int index, int channel, HALSimGazebo* halsim) {
m_channel = channel;
m_halsim = halsim;
m_pub = NULL;
HALSIM_RegisterPCMSolenoidInitializedCallback(index, channel, init_callback,
this, true);
HALSIM_RegisterPCMSolenoidOutputCallback(index, channel, output_callback,
this, true);
HALSIM_RegisterCTREPCMInitializedCallback(index, init_callback, this, true);
HALSIM_RegisterCTREPCMSolenoidOutputCallback(index, channel, output_callback,
this, true);
}
void GazeboPCM::Publish(bool value) {
@@ -50,5 +49,5 @@ void GazeboPCM::Publish(bool value) {
}
void GazeboPCM_SetPressureSwitch(int index, bool value) {
HALSIM_SetPCMPressureSwitch(index, value);
HALSIM_SetCTREPCMPressureSwitch(index, value);
}

View File

@@ -13,7 +13,7 @@
#include <hal/Ports.h>
#include <hal/Value.h>
#include <hal/simulation/PCMData.h>
#include <hal/simulation/CTREPCMData.h>
#include "HALDataSource.h"
#include "HALSimGui.h"
@@ -22,11 +22,11 @@
using namespace halsimgui;
namespace {
HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED(PCMCompressorOn, "Compressor On");
HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED(PCMClosedLoopEnabled, "Closed Loop");
HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED(PCMPressureSwitch, "Pressure Switch");
HALSIMGUI_DATASOURCE_DOUBLE_INDEXED(PCMCompressorCurrent, "Comp Current");
HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED2(PCMSolenoidOutput, "Solenoid");
HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED(CTREPCMCompressorOn, "Compressor On");
HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED(CTREPCMClosedLoopEnabled, "Closed Loop");
HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED(CTREPCMPressureSwitch, "Pressure Switch");
HALSIMGUI_DATASOURCE_DOUBLE_INDEXED(CTREPCMCompressorCurrent, "Comp Current");
HALSIMGUI_DATASOURCE_BOOLEAN_INDEXED2(CTREPCMSolenoidOutput, "Solenoid");
class CompressorSimModel : public glass::CompressorModel {
public:
@@ -39,7 +39,7 @@ class CompressorSimModel : public glass::CompressorModel {
void Update() override {}
bool Exists() override { return HALSIM_GetPCMCompressorInitialized(m_index); }
bool Exists() override { return HALSIM_GetCTREPCMInitialized(m_index); }
glass::DataSource* GetRunningData() override { return &m_running; }
glass::DataSource* GetEnabledData() override { return &m_enabled; }
@@ -49,24 +49,24 @@ class CompressorSimModel : public glass::CompressorModel {
glass::DataSource* GetCurrentData() override { return &m_current; }
void SetRunning(bool val) override {
HALSIM_SetPCMCompressorOn(m_index, val);
HALSIM_SetCTREPCMCompressorOn(m_index, val);
}
void SetEnabled(bool val) override {
HALSIM_SetPCMClosedLoopEnabled(m_index, val);
HALSIM_SetCTREPCMClosedLoopEnabled(m_index, val);
}
void SetPressureSwitch(bool val) override {
HALSIM_SetPCMPressureSwitch(m_index, val);
HALSIM_SetCTREPCMPressureSwitch(m_index, val);
}
void SetCurrent(double val) override {
HALSIM_SetPCMCompressorCurrent(m_index, val);
HALSIM_SetCTREPCMCompressorCurrent(m_index, val);
}
private:
int32_t m_index;
PCMCompressorOnSource m_running;
PCMClosedLoopEnabledSource m_enabled;
PCMPressureSwitchSource m_pressureSwitch;
PCMCompressorCurrentSource m_current;
CTREPCMCompressorOnSource m_running;
CTREPCMClosedLoopEnabledSource m_enabled;
CTREPCMPressureSwitchSource m_pressureSwitch;
CTREPCMCompressorCurrentSource m_current;
};
class SolenoidSimModel : public glass::SolenoidModel {
@@ -76,20 +76,18 @@ class SolenoidSimModel : public glass::SolenoidModel {
void Update() override {}
bool Exists() override {
return HALSIM_GetPCMSolenoidInitialized(m_index, m_channel);
}
bool Exists() override { return HALSIM_GetCTREPCMInitialized(m_index); }
glass::DataSource* GetOutputData() override { return &m_output; }
void SetOutput(bool val) override {
HALSIM_SetPCMSolenoidOutput(m_index, m_channel, val);
HALSIM_SetCTREPCMSolenoidOutput(m_index, m_channel, val);
}
private:
int32_t m_index;
int32_t m_channel;
PCMSolenoidOutputSource m_output;
CTREPCMSolenoidOutputSource m_output;
};
class PCMSimModel : public glass::PCMModel {
@@ -120,7 +118,7 @@ class PCMSimModel : public glass::PCMModel {
class PCMsSimModel : public glass::PCMsModel {
public:
PCMsSimModel() : m_models(HAL_GetNumPCMModules()) {}
PCMsSimModel() : m_models(HAL_GetNumCTREPCMModules()) {}
void Update() override;
@@ -139,7 +137,7 @@ void PCMSimModel::Update() {
m_solenoidInitCount = 0;
for (int32_t i = 0; i < numChannels; ++i) {
auto& model = m_solenoids[i];
if (HALSIM_GetPCMSolenoidInitialized(m_index, i)) {
if (HALSIM_GetCTREPCMInitialized(m_index)) {
if (!model) {
model = std::make_unique<SolenoidSimModel>(m_index, i);
}
@@ -167,8 +165,7 @@ void PCMsSimModel::Update() {
for (int32_t i = 0, iend = static_cast<int32_t>(m_models.size()); i < iend;
++i) {
auto& model = m_models[i];
if (HALSIM_GetPCMCompressorInitialized(i) ||
HALSIM_GetPCMAnySolenoidInitialized(i)) {
if (HALSIM_GetCTREPCMInitialized(i)) {
if (!model) {
model = std::make_unique<PCMSimModel>(i);
}
@@ -181,8 +178,8 @@ void PCMsSimModel::Update() {
void PCMsSimModel::ForEachPCM(
wpi::function_ref<void(glass::PCMModel& model, int index)> func) {
int32_t numPCMs = m_models.size();
for (int32_t i = 0; i < numPCMs; ++i) {
int32_t numCTREPCMs = m_models.size();
for (int32_t i = 0; i < numCTREPCMs; ++i) {
if (auto model = m_models[i].get()) {
func(*model, i);
}
@@ -190,10 +187,9 @@ void PCMsSimModel::ForEachPCM(
}
static bool PCMsAnyInitialized() {
static const int32_t num = HAL_GetNumPCMModules();
static const int32_t num = HAL_GetNumCTREPCMModules();
for (int32_t i = 0; i < num; ++i) {
if (HALSIM_GetPCMCompressorInitialized(i) ||
HALSIM_GetPCMAnySolenoidInitialized(i)) {
if (HALSIM_GetCTREPCMInitialized(i)) {
return true;
}
}
@@ -201,16 +197,16 @@ static bool PCMsAnyInitialized() {
}
void PCMSimGui::Initialize() {
HALSimGui::halProvider.RegisterModel("PCMs", PCMsAnyInitialized, [] {
HALSimGui::halProvider.RegisterModel("CTREPCMs", PCMsAnyInitialized, [] {
return std::make_unique<PCMsSimModel>();
});
HALSimGui::halProvider.RegisterView(
"Solenoids", "PCMs",
"Solenoids", "CTREPCMs",
[](glass::Model* model) {
bool any = false;
static_cast<PCMsSimModel*>(model)->ForEachPCM(
[&](glass::PCMModel& pcm, int) {
if (static_cast<PCMSimModel*>(&pcm)->GetNumSolenoids() > 0) {
[&](glass::PCMModel& CTREPCM, int) {
if (static_cast<PCMSimModel*>(&CTREPCM)->GetNumSolenoids() > 0) {
any = true;
}
});
@@ -227,7 +223,7 @@ void PCMSimGui::Initialize() {
});
SimDeviceGui::GetDeviceTree().Add(
HALSimGui::halProvider.GetModel("PCMs"), [](glass::Model* model) {
HALSimGui::halProvider.GetModel("CTREPCMs"), [](glass::Model* model) {
glass::DisplayCompressorsDevice(
static_cast<PCMsSimModel*>(model),
HALSimGui::halProvider.AreOutputsEnabled());

View File

@@ -5,10 +5,10 @@
#include "WSProvider_PCM.h"
#include <hal/Ports.h>
#include <hal/simulation/PCMData.h>
#include <hal/simulation/CTREPCMData.h>
#define REGISTER_PCM(halsim, jsonid, ctype, haltype) \
HALSIM_RegisterPCM##halsim##Callback( \
#define REGISTER_CTREPCM(halsim, jsonid, ctype, haltype) \
HALSIM_RegisterCTREPCM##halsim##Callback( \
m_channel, \
[](const char* name, void* param, const struct HAL_Value* value) { \
static_cast<HALSimWSProviderPCM*>(param)->ProcessHalCallback( \
@@ -17,7 +17,7 @@
this, true)
namespace wpilibws {
void HALSimWSProviderPCM::Initialize(WSRegisterFunc webRegisterFunc) {
CreateProviders<HALSimWSProviderPCM>("PCM", HAL_GetNumPCMModules(),
CreateProviders<HALSimWSProviderPCM>("CTREPCM", HAL_GetNumCTREPCMModules(),
webRegisterFunc);
}
@@ -26,13 +26,14 @@ HALSimWSProviderPCM::~HALSimWSProviderPCM() {
}
void HALSimWSProviderPCM::RegisterCallbacks() {
m_initCbKey = REGISTER_PCM(CompressorInitialized, "<init", bool, boolean);
m_onCbKey = REGISTER_PCM(CompressorInitialized, ">on", bool, boolean);
m_initCbKey = REGISTER_CTREPCM(Initialized, "<init", bool, boolean);
m_onCbKey = REGISTER_CTREPCM(CompressorOn, ">on", bool, boolean);
m_closedLoopCbKey =
REGISTER_PCM(ClosedLoopEnabled, "<closed_loop", bool, boolean);
REGISTER_CTREPCM(ClosedLoopEnabled, "<closed_loop", bool, boolean);
m_pressureSwitchCbKey =
REGISTER_PCM(PressureSwitch, ">pressure_switch", bool, boolean);
m_currentCbKey = REGISTER_PCM(CompressorCurrent, ">current", double, double);
REGISTER_CTREPCM(PressureSwitch, ">pressure_switch", bool, boolean);
m_currentCbKey =
REGISTER_CTREPCM(CompressorCurrent, ">current", double, double);
}
void HALSimWSProviderPCM::CancelCallbacks() {
@@ -40,11 +41,11 @@ void HALSimWSProviderPCM::CancelCallbacks() {
}
void HALSimWSProviderPCM::DoCancelCallbacks() {
HALSIM_CancelPCMCompressorInitializedCallback(m_channel, m_initCbKey);
HALSIM_CancelPCMCompressorOnCallback(m_channel, m_onCbKey);
HALSIM_CancelPCMClosedLoopEnabledCallback(m_channel, m_closedLoopCbKey);
HALSIM_CancelPCMPressureSwitchCallback(m_channel, m_pressureSwitchCbKey);
HALSIM_CancelPCMCompressorCurrentCallback(m_channel, m_currentCbKey);
HALSIM_CancelCTREPCMInitializedCallback(m_channel, m_initCbKey);
HALSIM_CancelCTREPCMCompressorOnCallback(m_channel, m_onCbKey);
HALSIM_CancelCTREPCMClosedLoopEnabledCallback(m_channel, m_closedLoopCbKey);
HALSIM_CancelCTREPCMPressureSwitchCallback(m_channel, m_pressureSwitchCbKey);
HALSIM_CancelCTREPCMCompressorCurrentCallback(m_channel, m_currentCbKey);
m_initCbKey = 0;
m_onCbKey = 0;

View File

@@ -5,10 +5,10 @@
#include "WSProvider_Solenoid.h"
#include <hal/Ports.h>
#include <hal/simulation/PCMData.h>
#include <hal/simulation/CTREPCMData.h>
#define REGISTER_SOLENOID(halsim, jsonid, ctype, haltype) \
HALSIM_RegisterPCMSolenoid##halsim##Callback( \
HALSIM_RegisterCTREPCMSolenoid##halsim##Callback( \
m_pcmIndex, m_solenoidIndex, \
[](const char* name, void* param, const struct HAL_Value* value) { \
static_cast<HALSimWSProviderSolenoid*>(param)->ProcessHalCallback( \
@@ -18,25 +18,26 @@
namespace wpilibws {
void HALSimWSProviderSolenoid::Initialize(WSRegisterFunc webRegisterFunc) {
for (int32_t pcmIndex = 0; pcmIndex < HAL_GetNumPCMModules(); ++pcmIndex) {
for (int32_t CTREPCMIndex = 0; CTREPCMIndex < HAL_GetNumCTREPCMModules();
++CTREPCMIndex) {
for (int32_t solenoidIndex = 0;
solenoidIndex < HAL_GetNumSolenoidChannels(); ++solenoidIndex) {
auto key =
("Solenoid/" + wpi::Twine(pcmIndex) + "," + wpi::Twine(solenoidIndex))
.str();
auto key = ("Solenoid/" + wpi::Twine(CTREPCMIndex) + "," +
wpi::Twine(solenoidIndex))
.str();
auto ptr = std::make_unique<HALSimWSProviderSolenoid>(
pcmIndex, solenoidIndex, key, "Solenoid");
CTREPCMIndex, solenoidIndex, key, "Solenoid");
webRegisterFunc(key, std::move(ptr));
}
}
}
HALSimWSProviderSolenoid::HALSimWSProviderSolenoid(int32_t pcmChannel,
HALSimWSProviderSolenoid::HALSimWSProviderSolenoid(int32_t CTREPCMChannel,
int32_t solenoidChannel,
const std::string& key,
const std::string& type)
: HALSimWSHalProvider(key, type),
m_pcmIndex(pcmChannel),
m_pcmIndex(CTREPCMChannel),
m_solenoidIndex(solenoidChannel) {
m_deviceId =
std::to_string(m_pcmIndex) + "," + std::to_string(solenoidChannel);
@@ -47,7 +48,7 @@ HALSimWSProviderSolenoid::~HALSimWSProviderSolenoid() {
}
void HALSimWSProviderSolenoid::RegisterCallbacks() {
m_initCbKey = REGISTER_SOLENOID(Initialized, "<init", bool, boolean);
// m_initCbKey = REGISTER_SOLENOID(Initialized, "<init", bool, boolean);
m_outputCbKey = REGISTER_SOLENOID(Output, "<output", bool, boolean);
}
@@ -56,10 +57,11 @@ void HALSimWSProviderSolenoid::CancelCallbacks() {
}
void HALSimWSProviderSolenoid::DoCancelCallbacks() {
HALSIM_CancelPCMSolenoidInitializedCallback(m_pcmIndex, m_solenoidIndex,
m_initCbKey);
HALSIM_CancelPCMSolenoidOutputCallback(m_pcmIndex, m_solenoidIndex,
m_outputCbKey);
// HALSIM_CancelCTREPCMSolenoidInitializedCallback(m_pcmIndex,
// m_solenoidIndex,
// m_initCbKey);
HALSIM_CancelCTREPCMSolenoidOutputCallback(m_pcmIndex, m_solenoidIndex,
m_outputCbKey);
m_initCbKey = 0;
m_outputCbKey = 0;

View File

@@ -1,134 +0,0 @@
// 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/Compressor.h"
#include <hal/Compressor.h>
#include <hal/FRCUsageReporting.h>
#include <hal/Ports.h>
#include <hal/Solenoid.h>
#include "frc/Errors.h"
#include "frc/smartdashboard/SendableBuilder.h"
#include "frc/smartdashboard/SendableRegistry.h"
using namespace frc;
Compressor::Compressor(int pcmID) : m_module(pcmID) {
int32_t status = 0;
m_compressorHandle = HAL_InitializeCompressor(m_module, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
SetClosedLoopControl(true);
HAL_Report(HALUsageReporting::kResourceType_Compressor, pcmID + 1);
SendableRegistry::GetInstance().AddLW(this, "Compressor", pcmID);
}
void Compressor::Start() {
SetClosedLoopControl(true);
}
void Compressor::Stop() {
SetClosedLoopControl(false);
}
bool Compressor::Enabled() const {
int32_t status = 0;
bool value = HAL_GetCompressor(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
bool Compressor::GetPressureSwitchValue() const {
int32_t status = 0;
bool value = HAL_GetCompressorPressureSwitch(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
double Compressor::GetCompressorCurrent() const {
int32_t status = 0;
double value = HAL_GetCompressorCurrent(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
void Compressor::SetClosedLoopControl(bool on) {
int32_t status = 0;
HAL_SetCompressorClosedLoopControl(m_compressorHandle, on, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
}
bool Compressor::GetClosedLoopControl() const {
int32_t status = 0;
bool value = HAL_GetCompressorClosedLoopControl(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
bool Compressor::GetCompressorCurrentTooHighFault() const {
int32_t status = 0;
bool value =
HAL_GetCompressorCurrentTooHighFault(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
bool Compressor::GetCompressorCurrentTooHighStickyFault() const {
int32_t status = 0;
bool value =
HAL_GetCompressorCurrentTooHighStickyFault(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
bool Compressor::GetCompressorShortedStickyFault() const {
int32_t status = 0;
bool value = HAL_GetCompressorShortedStickyFault(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
bool Compressor::GetCompressorShortedFault() const {
int32_t status = 0;
bool value = HAL_GetCompressorShortedFault(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
bool Compressor::GetCompressorNotConnectedStickyFault() const {
int32_t status = 0;
bool value =
HAL_GetCompressorNotConnectedStickyFault(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
bool Compressor::GetCompressorNotConnectedFault() const {
int32_t status = 0;
bool value = HAL_GetCompressorNotConnectedFault(m_compressorHandle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return value;
}
void Compressor::ClearAllPCMStickyFaults() {
int32_t status = 0;
HAL_ClearAllPCMStickyFaults(m_module, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
}
int Compressor::GetModule() const {
return m_module;
}
void Compressor::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Compressor");
builder.AddBooleanProperty(
"Closed Loop Control", [=]() { return GetClosedLoopControl(); },
[=](bool value) { SetClosedLoopControl(value); });
builder.AddBooleanProperty(
"Enabled", [=] { return Enabled(); }, nullptr);
builder.AddBooleanProperty(
"Pressure switch", [=]() { return GetPressureSwitchValue(); }, nullptr);
}

View File

@@ -9,7 +9,7 @@
#include <hal/FRCUsageReporting.h>
#include <hal/HALBase.h>
#include <hal/Ports.h>
#include <hal/Solenoid.h>
#include <wpi/NullDeleter.h>
#include "frc/Errors.h"
#include "frc/SensorUtil.h"
@@ -18,107 +18,74 @@
using namespace frc;
DoubleSolenoid::DoubleSolenoid(int forwardChannel, int reverseChannel)
: DoubleSolenoid(SensorUtil::GetDefaultSolenoidModule(), forwardChannel,
reverseChannel) {}
DoubleSolenoid::DoubleSolenoid(int moduleNumber, int forwardChannel,
DoubleSolenoid::DoubleSolenoid(PneumaticsBase& module, int forwardChannel,
int reverseChannel)
: SolenoidBase(moduleNumber),
m_forwardChannel(forwardChannel),
m_reverseChannel(reverseChannel) {
if (!SensorUtil::CheckSolenoidModule(m_moduleNumber)) {
throw FRC_MakeError(err::ModuleIndexOutOfRange, "Module {}",
m_moduleNumber);
}
if (!SensorUtil::CheckSolenoidChannel(m_forwardChannel)) {
throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}",
m_forwardChannel);
}
if (!SensorUtil::CheckSolenoidChannel(m_reverseChannel)) {
throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}",
m_reverseChannel);
}
int32_t status = 0;
m_forwardHandle = HAL_InitializeSolenoidPort(
HAL_GetPortWithModule(moduleNumber, m_forwardChannel), &status);
FRC_CheckErrorStatus(status, "Module {} Channel {}", m_moduleNumber,
m_forwardChannel);
: DoubleSolenoid{std::shared_ptr<PneumaticsBase>{
&module, wpi::NullDeleter<PneumaticsBase>()},
forwardChannel, reverseChannel} {}
m_reverseHandle = HAL_InitializeSolenoidPort(
HAL_GetPortWithModule(moduleNumber, m_reverseChannel), &status);
if (status != 0) {
// free forward solenoid
HAL_FreeSolenoidPort(m_forwardHandle);
FRC_CheckErrorStatus(status, "Module {} Channel {}", m_moduleNumber,
m_reverseChannel);
return;
DoubleSolenoid::DoubleSolenoid(PneumaticsBase* module, int forwardChannel,
int reverseChannel)
: DoubleSolenoid{std::shared_ptr<PneumaticsBase>{
module, wpi::NullDeleter<PneumaticsBase>()},
forwardChannel, reverseChannel} {}
DoubleSolenoid::DoubleSolenoid(std::shared_ptr<PneumaticsBase> module,
int forwardChannel, int reverseChannel)
: m_module{std::move(module)} {
if (!m_module->CheckSolenoidChannel(forwardChannel)) {
throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}",
forwardChannel);
}
if (!m_module->CheckSolenoidChannel(reverseChannel)) {
throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}",
reverseChannel);
}
m_forwardMask = 1 << m_forwardChannel;
m_reverseMask = 1 << m_reverseChannel;
m_forwardChannel = forwardChannel;
m_reverseChannel = reverseChannel;
m_forwardMask = 1 << forwardChannel;
m_reverseMask = 1 << reverseChannel;
m_mask = m_forwardMask | m_reverseMask;
HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_forwardChannel + 1,
m_moduleNumber + 1);
m_module->GetModuleNumber() + 1);
HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_reverseChannel + 1,
m_moduleNumber + 1);
SendableRegistry::GetInstance().AddLW(this, "DoubleSolenoid", m_moduleNumber,
m_forwardChannel);
m_module->GetModuleNumber() + 1);
SendableRegistry::GetInstance().AddLW(
this, "DoubleSolenoid", m_module->GetModuleNumber(), m_forwardChannel);
}
DoubleSolenoid::~DoubleSolenoid() {
HAL_FreeSolenoidPort(m_forwardHandle);
HAL_FreeSolenoidPort(m_reverseHandle);
}
DoubleSolenoid::~DoubleSolenoid() {}
void DoubleSolenoid::Set(Value value) {
bool forward = false;
bool reverse = false;
int setValue = 0;
switch (value) {
case kOff:
forward = false;
reverse = false;
setValue = 0;
break;
case kForward:
forward = true;
reverse = false;
setValue = m_forwardMask;
break;
case kReverse:
forward = false;
reverse = true;
setValue = m_reverseMask;
break;
}
int fstatus = 0;
HAL_SetSolenoid(m_forwardHandle, forward, &fstatus);
int rstatus = 0;
HAL_SetSolenoid(m_reverseHandle, reverse, &rstatus);
FRC_CheckErrorStatus(fstatus, "Module {} Channel {}", m_moduleNumber,
m_forwardChannel);
FRC_CheckErrorStatus(rstatus, "Module {} Channel {}", m_moduleNumber,
m_reverseChannel);
m_module->SetSolenoids(m_mask, setValue);
}
DoubleSolenoid::Value DoubleSolenoid::Get() const {
int fstatus = 0;
int rstatus = 0;
bool valueForward = HAL_GetSolenoid(m_forwardHandle, &fstatus);
bool valueReverse = HAL_GetSolenoid(m_reverseHandle, &rstatus);
auto values = m_module->GetSolenoids();
FRC_CheckErrorStatus(fstatus, "Module {} Channel {}", m_moduleNumber,
m_forwardChannel);
FRC_CheckErrorStatus(rstatus, "Module {} Channel {}", m_moduleNumber,
m_reverseChannel);
if (valueForward) {
return kForward;
} else if (valueReverse) {
return kReverse;
if ((values & m_forwardMask) != 0) {
return Value::kForward;
} else if ((values & m_reverseMask) != 0) {
return Value::kReverse;
} else {
return kOff;
return Value::kOff;
}
}
@@ -140,14 +107,12 @@ int DoubleSolenoid::GetRevChannel() const {
return m_reverseChannel;
}
bool DoubleSolenoid::IsFwdSolenoidBlackListed() const {
int blackList = GetPCMSolenoidBlackList(m_moduleNumber);
return (blackList & m_forwardMask) != 0;
bool DoubleSolenoid::IsFwdSolenoidDisabled() const {
return (m_module->GetSolenoidDisabledList() & m_forwardMask) != 0;
}
bool DoubleSolenoid::IsRevSolenoidBlackListed() const {
int blackList = GetPCMSolenoidBlackList(m_moduleNumber);
return (blackList & m_reverseMask) != 0;
bool DoubleSolenoid::IsRevSolenoidDisabled() const {
return (m_module->GetSolenoidDisabledList() & m_reverseMask) != 0;
}
void DoubleSolenoid::InitSendable(SendableBuilder& builder) {

View File

@@ -0,0 +1,162 @@
// 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/PneumaticsControlModule.h"
#include <hal/CTREPCM.h>
#include <wpi/StackTrace.h>
#include "frc/Errors.h"
#include "frc/SensorUtil.h"
using namespace frc;
PneumaticsControlModule::PneumaticsControlModule()
: PneumaticsControlModule{SensorUtil::GetDefaultCTREPCMModule()} {}
PneumaticsControlModule::PneumaticsControlModule(int module) {
int32_t status = 0;
std::string stackTrace = wpi::GetStackTrace(1);
m_handle = HAL_InitializeCTREPCM(module, stackTrace.c_str(), &status);
FRC_CheckErrorStatus(status, "Module {}", module);
m_module = module;
}
PneumaticsControlModule::~PneumaticsControlModule() {
HAL_FreeCTREPCM(m_handle);
}
bool PneumaticsControlModule::GetCompressor() {
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressor(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
void PneumaticsControlModule::SetClosedLoopControl(bool enabled) {
int32_t status = 0;
HAL_SetCTREPCMClosedLoopControl(m_handle, enabled, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
}
bool PneumaticsControlModule::GetClosedLoopControl() {
int32_t status = 0;
auto result = HAL_GetCTREPCMClosedLoopControl(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetPressureSwitch() {
int32_t status = 0;
auto result = HAL_GetCTREPCMPressureSwitch(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
double PneumaticsControlModule::GetCompressorCurrent() {
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorCurrent(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetCompressorCurrentTooHighFault() {
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorCurrentTooHighFault(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetCompressorCurrentTooHighStickyFault() {
int32_t status = 0;
auto result =
HAL_GetCTREPCMCompressorCurrentTooHighStickyFault(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetCompressorShortedFault() {
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorShortedFault(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetCompressorShortedStickyFault() {
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorShortedStickyFault(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetCompressorNotConnectedFault() {
int32_t status = 0;
auto result = HAL_GetCTREPCMCompressorNotConnectedFault(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetCompressorNotConnectedStickyFault() {
int32_t status = 0;
auto result =
HAL_GetCTREPCMCompressorNotConnectedStickyFault(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetSolenoidVoltageFault() {
int32_t status = 0;
auto result = HAL_GetCTREPCMSolenoidVoltageFault(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
bool PneumaticsControlModule::GetSolenoidVoltageStickyFault() {
int32_t status = 0;
auto result = HAL_GetCTREPCMSolenoidVoltageStickyFault(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
void PneumaticsControlModule::ClearAllStickyFaults() {
int32_t status = 0;
HAL_ClearAllCTREPCMStickyFaults(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
}
void PneumaticsControlModule::SetSolenoids(int mask, int values) {
int32_t status = 0;
HAL_SetCTREPCMSolenoids(m_handle, mask, values, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
}
int PneumaticsControlModule::GetSolenoids() const {
int32_t status = 0;
auto result = HAL_GetCTREPCMSolenoids(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
int PneumaticsControlModule::GetModuleNumber() const {
return m_module;
}
int PneumaticsControlModule::GetSolenoidDisabledList() const {
int32_t status = 0;
auto result = HAL_GetCTREPCMSolenoidDisabledList(m_handle, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
return result;
}
void PneumaticsControlModule::FireOneShot(int index) {
int32_t status = 0;
HAL_FireCTREPCMOneShot(m_handle, index, &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
}
void PneumaticsControlModule::SetOneShotDuration(int index,
units::second_t duration) {
int32_t status = 0;
units::millisecond_t millis = duration;
HAL_SetCTREPCMOneShotDuration(m_handle, index, millis.to<int32_t>(), &status);
FRC_CheckErrorStatus(status, "Module {}", m_module);
}
bool PneumaticsControlModule::CheckSolenoidChannel(int channel) const {
return HAL_CheckCTREPCMSolenoidChannel(channel);
}

View File

@@ -11,7 +11,6 @@
#include <hal/PWM.h>
#include <hal/Ports.h>
#include <hal/Relay.h>
#include <hal/Solenoid.h>
using namespace frc;
@@ -19,19 +18,15 @@ const int SensorUtil::kDigitalChannels = HAL_GetNumDigitalChannels();
const int SensorUtil::kAnalogInputs = HAL_GetNumAnalogInputs();
const int SensorUtil::kAnalogOutputs = HAL_GetNumAnalogOutputs();
const int SensorUtil::kSolenoidChannels = HAL_GetNumSolenoidChannels();
const int SensorUtil::kSolenoidModules = HAL_GetNumPCMModules();
const int SensorUtil::kSolenoidModules = HAL_GetNumCTREPCMModules();
const int SensorUtil::kPwmChannels = HAL_GetNumPWMChannels();
const int SensorUtil::kRelayChannels = HAL_GetNumRelayHeaders();
const int SensorUtil::kPDPChannels = HAL_GetNumPDPChannels();
int SensorUtil::GetDefaultSolenoidModule() {
int SensorUtil::GetDefaultCTREPCMModule() {
return 0;
}
bool SensorUtil::CheckSolenoidModule(int moduleNumber) {
return HAL_CheckSolenoidModule(moduleNumber);
}
bool SensorUtil::CheckDigitalChannel(int channel) {
return HAL_CheckDIOChannel(channel);
}
@@ -52,10 +47,6 @@ bool SensorUtil::CheckAnalogOutputChannel(int channel) {
return HAL_CheckAnalogOutputChannel(channel);
}
bool SensorUtil::CheckSolenoidChannel(int channel) {
return HAL_CheckSolenoidChannel(channel);
}
bool SensorUtil::CheckPDPChannel(int channel) {
return HAL_CheckPDPChannel(channel);
}

View File

@@ -7,9 +7,7 @@
#include <utility>
#include <hal/FRCUsageReporting.h>
#include <hal/HALBase.h>
#include <hal/Ports.h>
#include <hal/Solenoid.h>
#include <wpi/NullDeleter.h>
#include "frc/Errors.h"
#include "frc/SensorUtil.h"
@@ -18,49 +16,40 @@
using namespace frc;
Solenoid::Solenoid(int channel)
: Solenoid(SensorUtil::GetDefaultSolenoidModule(), channel) {}
Solenoid::Solenoid(PneumaticsBase& module, int channel)
: Solenoid{std::shared_ptr<PneumaticsBase>{
&module, wpi::NullDeleter<PneumaticsBase>()},
channel} {}
Solenoid::Solenoid(int moduleNumber, int channel)
: SolenoidBase(moduleNumber), m_channel(channel) {
if (!SensorUtil::CheckSolenoidModule(m_moduleNumber)) {
throw FRC_MakeError(err::ModuleIndexOutOfRange, "Module {}",
m_moduleNumber);
}
if (!SensorUtil::CheckSolenoidChannel(m_channel)) {
Solenoid::Solenoid(PneumaticsBase* module, int channel)
: Solenoid{std::shared_ptr<PneumaticsBase>{
module, wpi::NullDeleter<PneumaticsBase>()},
channel} {}
Solenoid::Solenoid(std::shared_ptr<PneumaticsBase> module, int channel)
: m_module{std::move(module)} {
if (!m_module->CheckSolenoidChannel(m_channel)) {
throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}", m_channel);
}
int32_t status = 0;
m_solenoidHandle = HAL_InitializeSolenoidPort(
HAL_GetPortWithModule(moduleNumber, channel), &status);
FRC_CheckErrorStatus(status, "Module {} Channel {}", m_moduleNumber,
m_channel);
m_channel = channel;
m_mask = 1 << channel;
HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_channel + 1,
m_moduleNumber + 1);
SendableRegistry::GetInstance().AddLW(this, "Solenoid", m_moduleNumber,
m_channel);
m_module->GetModuleNumber() + 1);
SendableRegistry::GetInstance().AddLW(this, "Solenoid",
m_module->GetModuleNumber(), m_channel);
}
Solenoid::~Solenoid() {
HAL_FreeSolenoidPort(m_solenoidHandle);
}
Solenoid::~Solenoid() {}
void Solenoid::Set(bool on) {
int32_t status = 0;
HAL_SetSolenoid(m_solenoidHandle, on, &status);
FRC_CheckErrorStatus(status, "Module {} Channel {}", m_moduleNumber,
m_channel);
int value = on ? (0xFFFF & m_mask) : 0;
m_module->SetSolenoids(m_mask, value);
}
bool Solenoid::Get() const {
int32_t status = 0;
bool value = HAL_GetSolenoid(m_solenoidHandle, &status);
FRC_CheckErrorStatus(status, "Module {} Channel {}", m_moduleNumber,
m_channel);
return value;
int currentAll = m_module->GetSolenoids();
return (currentAll & m_mask) != 0;
}
void Solenoid::Toggle() {
@@ -71,24 +60,16 @@ int Solenoid::GetChannel() const {
return m_channel;
}
bool Solenoid::IsBlackListed() const {
int value = GetPCMSolenoidBlackList(m_moduleNumber) & (1 << m_channel);
return (value != 0);
bool Solenoid::IsDisabled() const {
return (m_module->GetSolenoidDisabledList() & m_mask) != 0;
}
void Solenoid::SetPulseDuration(units::second_t duration) {
int32_t status = 0;
HAL_SetOneShotDuration(m_solenoidHandle,
units::millisecond_t{duration}.to<int32_t>(), &status);
FRC_CheckErrorStatus(status, "Module {} Channel {}", m_moduleNumber,
m_channel);
m_module->SetOneShotDuration(m_channel, duration);
}
void Solenoid::StartPulse() {
int32_t status = 0;
HAL_FireOneShot(m_solenoidHandle, &status);
FRC_CheckErrorStatus(status, "Module {} Channel {}", m_moduleNumber,
m_channel);
m_module->FireOneShot(m_channel);
}
void Solenoid::InitSendable(SendableBuilder& builder) {

View File

@@ -1,73 +0,0 @@
// 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/SolenoidBase.h"
#include <hal/FRCUsageReporting.h>
#include <hal/Solenoid.h>
#include "frc/Errors.h"
using namespace frc;
int SolenoidBase::GetAll(int module) {
int value = 0;
int32_t status = 0;
value = HAL_GetAllSolenoids(module, &status);
FRC_CheckErrorStatus(status, "Module {}", module);
return value;
}
int SolenoidBase::GetAll() const {
return SolenoidBase::GetAll(m_moduleNumber);
}
int SolenoidBase::GetPCMSolenoidBlackList(int module) {
int32_t status = 0;
int rv = HAL_GetPCMSolenoidBlackList(module, &status);
FRC_CheckErrorStatus(status, "Module {}", module);
return rv;
}
int SolenoidBase::GetPCMSolenoidBlackList() const {
return SolenoidBase::GetPCMSolenoidBlackList(m_moduleNumber);
}
bool SolenoidBase::GetPCMSolenoidVoltageStickyFault(int module) {
int32_t status = 0;
bool rv = HAL_GetPCMSolenoidVoltageStickyFault(module, &status);
FRC_CheckErrorStatus(status, "Module {}", module);
return rv;
}
bool SolenoidBase::GetPCMSolenoidVoltageStickyFault() const {
return SolenoidBase::GetPCMSolenoidVoltageStickyFault(m_moduleNumber);
}
bool SolenoidBase::GetPCMSolenoidVoltageFault(int module) {
int32_t status = 0;
bool rv = HAL_GetPCMSolenoidVoltageFault(module, &status);
FRC_CheckErrorStatus(status, "Module {}", module);
return rv;
}
bool SolenoidBase::GetPCMSolenoidVoltageFault() const {
return SolenoidBase::GetPCMSolenoidVoltageFault(m_moduleNumber);
}
void SolenoidBase::ClearAllPCMStickyFaults(int module) {
int32_t status = 0;
HAL_ClearAllPCMStickyFaults(module, &status);
FRC_CheckErrorStatus(status, "Module {}", module);
}
void SolenoidBase::ClearAllPCMStickyFaults() {
SolenoidBase::ClearAllPCMStickyFaults(m_moduleNumber);
}
SolenoidBase::SolenoidBase(int moduleNumber) : m_moduleNumber(moduleNumber) {}
int SolenoidBase::GetModuleNumber() const {
return m_moduleNumber;
}

View File

@@ -0,0 +1,139 @@
// 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/CTREPCMSim.h"
#include <memory>
#include <utility>
#include <hal/simulation/CTREPCMData.h>
#include "frc/SensorUtil.h"
using namespace frc;
using namespace frc::sim;
CTREPCMSim::CTREPCMSim() : m_index{SensorUtil::GetDefaultCTREPCMModule()} {}
CTREPCMSim::CTREPCMSim(int module) : m_index{module} {}
CTREPCMSim::CTREPCMSim(const PneumaticsBase& pneumatics)
: m_index{pneumatics.GetModuleNumber()} {}
std::unique_ptr<CallbackStore> CTREPCMSim::RegisterInitializedCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelCTREPCMInitializedCallback);
store->SetUid(HALSIM_RegisterCTREPCMInitializedCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool CTREPCMSim::GetInitialized() const {
return HALSIM_GetCTREPCMInitialized(m_index);
}
void CTREPCMSim::SetInitialized(bool solenoidInitialized) {
HALSIM_SetCTREPCMInitialized(m_index, solenoidInitialized);
}
std::unique_ptr<CallbackStore> CTREPCMSim::RegisterSolenoidOutputCallback(
int channel, NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, channel, -1, callback,
&HALSIM_CancelCTREPCMSolenoidOutputCallback);
store->SetUid(HALSIM_RegisterCTREPCMSolenoidOutputCallback(
m_index, channel, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool CTREPCMSim::GetSolenoidOutput(int channel) const {
return HALSIM_GetCTREPCMSolenoidOutput(m_index, channel);
}
void CTREPCMSim::SetSolenoidOutput(int channel, bool solenoidOutput) {
HALSIM_SetCTREPCMSolenoidOutput(m_index, channel, solenoidOutput);
}
std::unique_ptr<CallbackStore> CTREPCMSim::RegisterCompressorOnCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelCTREPCMCompressorOnCallback);
store->SetUid(HALSIM_RegisterCTREPCMCompressorOnCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool CTREPCMSim::GetCompressorOn() const {
return HALSIM_GetCTREPCMCompressorOn(m_index);
}
void CTREPCMSim::SetCompressorOn(bool compressorOn) {
HALSIM_SetCTREPCMCompressorOn(m_index, compressorOn);
}
std::unique_ptr<CallbackStore> CTREPCMSim::RegisterClosedLoopEnabledCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelCTREPCMClosedLoopEnabledCallback);
store->SetUid(HALSIM_RegisterCTREPCMClosedLoopEnabledCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool CTREPCMSim::GetClosedLoopEnabled() const {
return HALSIM_GetCTREPCMClosedLoopEnabled(m_index);
}
void CTREPCMSim::SetClosedLoopEnabled(bool closedLoopEnabled) {
HALSIM_SetCTREPCMClosedLoopEnabled(m_index, closedLoopEnabled);
}
std::unique_ptr<CallbackStore> CTREPCMSim::RegisterPressureSwitchCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelCTREPCMPressureSwitchCallback);
store->SetUid(HALSIM_RegisterCTREPCMPressureSwitchCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool CTREPCMSim::GetPressureSwitch() const {
return HALSIM_GetCTREPCMPressureSwitch(m_index);
}
void CTREPCMSim::SetPressureSwitch(bool pressureSwitch) {
HALSIM_SetCTREPCMPressureSwitch(m_index, pressureSwitch);
}
std::unique_ptr<CallbackStore> CTREPCMSim::RegisterCompressorCurrentCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelCTREPCMCompressorCurrentCallback);
store->SetUid(HALSIM_RegisterCTREPCMCompressorCurrentCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
double CTREPCMSim::GetCompressorCurrent() const {
return HALSIM_GetCTREPCMCompressorCurrent(m_index);
}
void CTREPCMSim::SetCompressorCurrent(double compressorCurrent) {
HALSIM_SetCTREPCMCompressorCurrent(m_index, compressorCurrent);
}
uint8_t CTREPCMSim::GetAllSolenoidOutputs() const {
uint8_t ret = 0;
HALSIM_GetCTREPCMAllSolenoids(m_index, &ret);
return ret;
}
void CTREPCMSim::SetAllSolenoidOutputs(uint8_t outputs) {
HALSIM_SetCTREPCMAllSolenoids(m_index, outputs);
}
void CTREPCMSim::ResetData() {
HALSIM_ResetCTREPCMData(m_index);
}

View File

@@ -1,91 +0,0 @@
// 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/SensorUtil.h"
#include "frc/simulation/PCMSim.h"
using namespace frc;
using namespace frc::sim;
DoubleSolenoidSim::DoubleSolenoidSim(int fwd, int rev)
: m_fwd{fwd}, m_rev{rev} {}
DoubleSolenoidSim::DoubleSolenoidSim(int module, int fwd, int rev)
: m_pcm{module}, m_fwd{fwd}, m_rev{rev} {}
DoubleSolenoidSim::DoubleSolenoidSim(PCMSim& pcm, int fwd, int rev)
: m_pcm{pcm}, m_fwd{fwd}, m_rev{rev} {}
DoubleSolenoidSim::DoubleSolenoidSim(DoubleSolenoid& solenoid)
: m_pcm{solenoid.GetModuleNumber()},
m_fwd{solenoid.GetFwdChannel()},
m_rev{solenoid.GetRevChannel()} {}
std::unique_ptr<CallbackStore>
DoubleSolenoidSim::RegisterFwdInitializedCallback(NotifyCallback callback,
bool initialNotify) {
return m_pcm.RegisterSolenoidInitializedCallback(m_fwd, callback,
initialNotify);
}
bool DoubleSolenoidSim::GetFwdInitialized() const {
return m_pcm.GetSolenoidInitialized(m_fwd);
}
void DoubleSolenoidSim::SetFwdInitialized(bool initialized) {
m_pcm.SetSolenoidInitialized(m_fwd, initialized);
}
std::unique_ptr<CallbackStore>
DoubleSolenoidSim::RegisterRevInitializedCallback(NotifyCallback callback,
bool initialNotify) {
return m_pcm.RegisterSolenoidInitializedCallback(m_rev, callback,
initialNotify);
}
bool DoubleSolenoidSim::GetRevInitialized() const {
return m_pcm.GetSolenoidInitialized(m_rev);
}
void DoubleSolenoidSim::SetRevInitialized(bool initialized) {
m_pcm.SetSolenoidInitialized(m_rev, initialized);
}
void DoubleSolenoidSim::Set(DoubleSolenoid::Value value) {
bool forward = false;
bool reverse = false;
switch (value) {
case DoubleSolenoid::Value::kOff:
forward = false;
reverse = false;
break;
case DoubleSolenoid::Value::kForward:
forward = true;
reverse = false;
break;
case DoubleSolenoid::Value::kReverse:
forward = false;
reverse = true;
break;
}
m_pcm.SetSolenoidOutput(m_fwd, forward);
m_pcm.SetSolenoidOutput(m_rev, reverse);
}
DoubleSolenoid::Value DoubleSolenoidSim::Get() const {
bool valueForward = m_pcm.GetSolenoidOutput(m_fwd);
bool valueReverse = m_pcm.GetSolenoidOutput(m_rev);
if (valueForward) {
return DoubleSolenoid::Value::kForward;
} else if (valueReverse) {
return DoubleSolenoid::Value::kReverse;
} else {
return DoubleSolenoid::Value::kOff;
}
}

View File

@@ -1,157 +0,0 @@
// 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/PCMSim.h"
#include <memory>
#include <utility>
#include <hal/simulation/PCMData.h>
#include "frc/Compressor.h"
#include "frc/SensorUtil.h"
using namespace frc;
using namespace frc::sim;
PCMSim::PCMSim() : m_index{SensorUtil::GetDefaultSolenoidModule()} {}
PCMSim::PCMSim(int module) : m_index{module} {}
PCMSim::PCMSim(const Compressor& compressor)
: m_index{compressor.GetModule()} {}
std::unique_ptr<CallbackStore> PCMSim::RegisterSolenoidInitializedCallback(
int channel, NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, channel, -1, callback,
&HALSIM_CancelPCMSolenoidInitializedCallback);
store->SetUid(HALSIM_RegisterPCMSolenoidInitializedCallback(
m_index, channel, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool PCMSim::GetSolenoidInitialized(int channel) const {
return HALSIM_GetPCMSolenoidInitialized(m_index, channel);
}
void PCMSim::SetSolenoidInitialized(int channel, bool solenoidInitialized) {
HALSIM_SetPCMSolenoidInitialized(m_index, channel, solenoidInitialized);
}
std::unique_ptr<CallbackStore> PCMSim::RegisterSolenoidOutputCallback(
int channel, NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, channel, -1, callback, &HALSIM_CancelPCMSolenoidOutputCallback);
store->SetUid(HALSIM_RegisterPCMSolenoidOutputCallback(
m_index, channel, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool PCMSim::GetSolenoidOutput(int channel) const {
return HALSIM_GetPCMSolenoidOutput(m_index, channel);
}
void PCMSim::SetSolenoidOutput(int channel, bool solenoidOutput) {
HALSIM_SetPCMSolenoidOutput(m_index, channel, solenoidOutput);
}
std::unique_ptr<CallbackStore> PCMSim::RegisterCompressorInitializedCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelPCMCompressorInitializedCallback);
store->SetUid(HALSIM_RegisterPCMCompressorInitializedCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool PCMSim::GetCompressorInitialized() const {
return HALSIM_GetPCMCompressorInitialized(m_index);
}
void PCMSim::SetCompressorInitialized(bool compressorInitialized) {
HALSIM_SetPCMCompressorInitialized(m_index, compressorInitialized);
}
std::unique_ptr<CallbackStore> PCMSim::RegisterCompressorOnCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelPCMCompressorOnCallback);
store->SetUid(HALSIM_RegisterPCMCompressorOnCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool PCMSim::GetCompressorOn() const {
return HALSIM_GetPCMCompressorOn(m_index);
}
void PCMSim::SetCompressorOn(bool compressorOn) {
HALSIM_SetPCMCompressorOn(m_index, compressorOn);
}
std::unique_ptr<CallbackStore> PCMSim::RegisterClosedLoopEnabledCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelPCMClosedLoopEnabledCallback);
store->SetUid(HALSIM_RegisterPCMClosedLoopEnabledCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool PCMSim::GetClosedLoopEnabled() const {
return HALSIM_GetPCMClosedLoopEnabled(m_index);
}
void PCMSim::SetClosedLoopEnabled(bool closedLoopEnabled) {
HALSIM_SetPCMClosedLoopEnabled(m_index, closedLoopEnabled);
}
std::unique_ptr<CallbackStore> PCMSim::RegisterPressureSwitchCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelPCMPressureSwitchCallback);
store->SetUid(HALSIM_RegisterPCMPressureSwitchCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
bool PCMSim::GetPressureSwitch() const {
return HALSIM_GetPCMPressureSwitch(m_index);
}
void PCMSim::SetPressureSwitch(bool pressureSwitch) {
HALSIM_SetPCMPressureSwitch(m_index, pressureSwitch);
}
std::unique_ptr<CallbackStore> PCMSim::RegisterCompressorCurrentCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
m_index, -1, callback, &HALSIM_CancelPCMCompressorCurrentCallback);
store->SetUid(HALSIM_RegisterPCMCompressorCurrentCallback(
m_index, &CallbackStoreThunk, store.get(), initialNotify));
return store;
}
double PCMSim::GetCompressorCurrent() const {
return HALSIM_GetPCMCompressorCurrent(m_index);
}
void PCMSim::SetCompressorCurrent(double compressorCurrent) {
HALSIM_SetPCMCompressorCurrent(m_index, compressorCurrent);
}
uint8_t PCMSim::GetAllSolenoidOutputs() const {
uint8_t ret = 0;
HALSIM_GetPCMAllSolenoids(m_index, &ret);
return ret;
}
void PCMSim::SetAllSolenoidOutputs(uint8_t outputs) {
HALSIM_SetPCMAllSolenoids(m_index, outputs);
}
void PCMSim::ResetData() {
HALSIM_ResetPCMData(m_index);
}

View File

@@ -1,50 +0,0 @@
// 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/SensorUtil.h"
#include "frc/simulation/PCMSim.h"
using namespace frc;
using namespace frc::sim;
SolenoidSim::SolenoidSim(int channel) : m_channel{channel} {}
SolenoidSim::SolenoidSim(int module, int channel)
: m_pcm{module}, m_channel{channel} {}
SolenoidSim::SolenoidSim(PCMSim& pcm, int channel)
: m_pcm{pcm}, m_channel{channel} {}
SolenoidSim::SolenoidSim(Solenoid& solenoid)
: m_pcm{solenoid.GetModuleNumber()}, m_channel{solenoid.GetChannel()} {}
std::unique_ptr<CallbackStore> SolenoidSim::RegisterInitializedCallback(
NotifyCallback callback, bool initialNotify) {
return m_pcm.RegisterSolenoidInitializedCallback(m_channel, callback,
initialNotify);
}
bool SolenoidSim::GetInitialized() const {
return m_pcm.GetSolenoidInitialized(m_channel);
}
void SolenoidSim::SetInitialized(bool initialized) {
m_pcm.SetSolenoidInitialized(m_channel, initialized);
}
std::unique_ptr<CallbackStore> SolenoidSim::RegisterOutputCallback(
NotifyCallback callback, bool initialNotify) {
return m_pcm.RegisterSolenoidOutputCallback(m_channel, callback,
initialNotify);
}
bool SolenoidSim::GetOutput() const {
return m_pcm.GetSolenoidOutput(m_channel);
}
void SolenoidSim::SetOutput(bool output) {
m_pcm.SetSolenoidOutput(m_channel, output);
}

View File

@@ -1,185 +0,0 @@
// 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 <hal/Types.h>
#include "frc/SensorUtil.h"
#include "frc/smartdashboard/Sendable.h"
#include "frc/smartdashboard/SendableHelper.h"
namespace frc {
class SendableBuilder;
/**
* Class for operating a compressor connected to a %PCM (Pneumatic Control
* Module).
*
* The PCM will automatically run in closed loop mode by default whenever a
* Solenoid object is created. For most cases, a Compressor object does not need
* to be instantiated or used in a robot program. This class is only required in
* cases where the robot program needs a more detailed status of the compressor
* or to enable/disable closed loop control.
*
* Note: you cannot operate the compressor directly from this class as doing so
* would circumvent the safety provided by using the pressure switch and closed
* loop control. You can only turn off closed loop control, thereby stopping
* the compressor from operating.
*/
class Compressor : public Sendable, public SendableHelper<Compressor> {
public:
/**
* Constructor. The default PCM ID is 0.
*
* @param module The PCM ID to use (0-62)
*/
explicit Compressor(int pcmID = SensorUtil::GetDefaultSolenoidModule());
~Compressor() override = default;
Compressor(Compressor&&) = default;
Compressor& operator=(Compressor&&) = default;
/**
* Starts closed-loop control. Note that closed loop control is enabled by
* default.
*/
void Start();
/**
* Stops closed-loop control. Note that closed loop control is enabled by
* default.
*/
void Stop();
/**
* Check if compressor output is active.
*
* @return true if the compressor is on
*/
bool Enabled() const;
/**
* Check if the pressure switch is triggered.
*
* @return true if pressure is low
*/
bool GetPressureSwitchValue() const;
/**
* Query how much current the compressor is drawing.
*
* @return The current through the compressor, in amps
*/
double GetCompressorCurrent() const;
/**
* Enables or disables automatically turning the compressor on when the
* pressure is low.
*
* @param on Set to true to enable closed loop control of the compressor.
* False to disable.
*/
void SetClosedLoopControl(bool on);
/**
* Returns true if the compressor will automatically turn on when the
* pressure is low.
*
* @return True if closed loop control of the compressor is enabled. False if
* disabled.
*/
bool GetClosedLoopControl() const;
/**
* Query if the compressor output has been disabled due to high current draw.
*
* @return true if PCM is in fault state : Compressor Drive is
* disabled due to compressor current being too high.
*/
bool GetCompressorCurrentTooHighFault() const;
/**
* Query if the compressor output has been disabled due to high current draw
* (sticky).
*
* A sticky fault will not clear on device reboot, it must be cleared through
* code or the webdash.
*
* @return true if PCM sticky fault is set : Compressor Drive is
* disabled due to compressor current being too high.
*/
bool GetCompressorCurrentTooHighStickyFault() const;
/**
* Query if the compressor output has been disabled due to a short circuit
* (sticky).
*
* A sticky fault will not clear on device reboot, it must be cleared through
* code or the webdash.
*
* @return true if PCM sticky fault is set : Compressor output
* appears to be shorted.
*/
bool GetCompressorShortedStickyFault() const;
/**
* Query if the compressor output has been disabled due to a short circuit.
*
* @return true if PCM is in fault state : Compressor output
* appears to be shorted.
*/
bool GetCompressorShortedFault() const;
/**
* Query if the compressor output does not appear to be wired (sticky).
*
* A sticky fault will not clear on device reboot, it must be cleared through
* code or the webdash.
*
* @return true if PCM sticky fault is set : Compressor does not
* appear to be wired, i.e. compressor is not drawing enough current.
*/
bool GetCompressorNotConnectedStickyFault() const;
/**
* Query if the compressor output does not appear to be wired.
*
* @return true if PCM is in fault state : Compressor does not
* appear to be wired, i.e. compressor is not drawing enough current.
*/
bool GetCompressorNotConnectedFault() const;
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* If a sticky fault is set, then it will be persistently cleared. Compressor
* drive maybe momentarily disable while flags are being cleared. Care should
* be taken to not call this too frequently, otherwise normal compressor
* functionality may be prevented.
*
* If no sticky faults are set then this call will have no effect.
*/
void ClearAllPCMStickyFaults();
/**
* Gets module number (CAN ID).
*
* @return Module number
*/
int GetModule() const;
void InitSendable(SendableBuilder& builder) override;
protected:
hal::Handle<HAL_CompressorHandle> m_compressorHandle;
private:
void SetCompressor(bool on);
int m_module;
};
} // namespace frc

View File

@@ -4,9 +4,11 @@
#pragma once
#include <memory>
#include <hal/Types.h>
#include "frc/SolenoidBase.h"
#include "frc/PneumaticsBase.h"
#include "frc/smartdashboard/Sendable.h"
#include "frc/smartdashboard/SendableHelper.h"
@@ -21,30 +23,16 @@ class SendableBuilder;
* The DoubleSolenoid class is typically used for pneumatics solenoids that
* have two positions controlled by two separate channels.
*/
class DoubleSolenoid : public SolenoidBase,
public Sendable,
public SendableHelper<DoubleSolenoid> {
class DoubleSolenoid : public Sendable, public SendableHelper<DoubleSolenoid> {
public:
enum Value { kOff, kForward, kReverse };
/**
* Constructor.
*
* Uses the default PCM ID of 0.
*
* @param forwardChannel The forward channel number on the PCM (0..7).
* @param reverseChannel The reverse channel number on the PCM (0..7).
*/
explicit DoubleSolenoid(int forwardChannel, int reverseChannel);
/**
* Constructor.
*
* @param moduleNumber The CAN ID of the PCM.
* @param forwardChannel The forward channel on the PCM to control (0..7).
* @param reverseChannel The reverse channel on the PCM to control (0..7).
*/
DoubleSolenoid(int moduleNumber, int forwardChannel, int reverseChannel);
DoubleSolenoid(PneumaticsBase& module, int forwardChannel,
int reverseChannel);
DoubleSolenoid(PneumaticsBase* module, int forwardChannel,
int reverseChannel);
DoubleSolenoid(std::shared_ptr<PneumaticsBase> module, int forwardChannel,
int reverseChannel);
~DoubleSolenoid() override;
@@ -89,26 +77,26 @@ class DoubleSolenoid : public SolenoidBase,
int GetRevChannel() const;
/**
* Check if the forward solenoid is blacklisted.
* Check if the forward solenoid is Disabled.
*
* If a solenoid is shorted, it is added to the blacklist and disabled until
* power cycle, or until faults are cleared.
* If a solenoid is shorted, it is added to the DisabledList and disabled
* until power cycle, or until faults are cleared.
*
* @see ClearAllPCMStickyFaults()
* @return If solenoid is disabled due to short.
*/
bool IsFwdSolenoidBlackListed() const;
bool IsFwdSolenoidDisabled() const;
/**
* Check if the reverse solenoid is blacklisted.
* Check if the reverse solenoid is Disabled.
*
* If a solenoid is shorted, it is added to the blacklist and disabled until
* power cycle, or until faults are cleared.
* If a solenoid is shorted, it is added to the DisabledList and disabled
* until power cycle, or until faults are cleared.
*
* @see ClearAllPCMStickyFaults()
* @return If solenoid is disabled due to short.
*/
bool IsRevSolenoidBlackListed() const;
bool IsRevSolenoidDisabled() const;
void InitSendable(SendableBuilder& builder) override;
@@ -117,8 +105,8 @@ class DoubleSolenoid : public SolenoidBase,
int m_reverseChannel; // The reverse channel on the module to control.
int m_forwardMask; // The mask for the forward channel.
int m_reverseMask; // The mask for the reverse channel.
hal::Handle<HAL_SolenoidHandle> m_forwardHandle;
hal::Handle<HAL_SolenoidHandle> m_reverseHandle;
int m_mask;
std::shared_ptr<PneumaticsBase> m_module;
};
} // namespace frc

View File

@@ -0,0 +1,28 @@
// 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 <units/time.h>
namespace frc {
class PneumaticsBase {
public:
virtual ~PneumaticsBase() = default;
virtual void SetSolenoids(int mask, int values) = 0;
virtual int GetSolenoids() const = 0;
virtual int GetModuleNumber() const = 0;
virtual int GetSolenoidDisabledList() const = 0;
virtual void FireOneShot(int index) = 0;
virtual void SetOneShotDuration(int index, units::second_t duration) = 0;
virtual bool CheckSolenoidChannel(int channel) const = 0;
};
} // namespace frc

View File

@@ -0,0 +1,62 @@
// 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 <hal/Types.h>
#include "PneumaticsBase.h"
namespace frc {
class PneumaticsControlModule : public PneumaticsBase {
public:
PneumaticsControlModule();
explicit PneumaticsControlModule(int module);
~PneumaticsControlModule() override;
PneumaticsControlModule(PneumaticsControlModule&&) = default;
PneumaticsControlModule& operator=(PneumaticsControlModule&&) = default;
bool GetCompressor();
void SetClosedLoopControl(bool enabled);
bool GetClosedLoopControl();
bool GetPressureSwitch();
double GetCompressorCurrent();
bool GetCompressorCurrentTooHighFault();
bool GetCompressorCurrentTooHighStickyFault();
bool GetCompressorShortedFault();
bool GetCompressorShortedStickyFault();
bool GetCompressorNotConnectedFault();
bool GetCompressorNotConnectedStickyFault();
bool GetSolenoidVoltageFault();
bool GetSolenoidVoltageStickyFault();
void ClearAllStickyFaults();
void SetSolenoids(int mask, int values) override;
int GetSolenoids() const override;
int GetModuleNumber() const override;
int GetSolenoidDisabledList() const override;
void FireOneShot(int index) override;
void SetOneShotDuration(int index, units::second_t duration) override;
bool CheckSolenoidChannel(int channel) const override;
private:
int m_module;
hal::Handle<HAL_CTREPCMHandle> m_handle;
};
} // namespace frc

View File

@@ -19,14 +19,7 @@ class SensorUtil final {
*
* @return The number of the default solenoid module.
*/
static int GetDefaultSolenoidModule();
/**
* Check that the solenoid module number is valid. module numbers are 0-based
*
* @return Solenoid module is valid and present
*/
static bool CheckSolenoidModule(int moduleNumber);
static int GetDefaultCTREPCMModule();
/**
* Check that the digital channel number is valid.
@@ -78,13 +71,6 @@ class SensorUtil final {
*/
static bool CheckAnalogOutputChannel(int channel);
/**
* Verify that the solenoid channel number is within limits.
*
* @return Solenoid channel is valid
*/
static bool CheckSolenoidChannel(int channel);
/**
* Verify that the power distribution channel number is within limits.
*

View File

@@ -4,10 +4,12 @@
#pragma once
#include <memory>
#include <hal/Types.h>
#include <units/time.h>
#include "frc/SolenoidBase.h"
#include "frc/PneumaticsBase.h"
#include "frc/smartdashboard/Sendable.h"
#include "frc/smartdashboard/SendableHelper.h"
@@ -21,24 +23,11 @@ class SendableBuilder;
* The Solenoid class is typically used for pneumatics solenoids, but could be
* used for any device within the current spec of the PCM.
*/
class Solenoid : public SolenoidBase,
public Sendable,
public SendableHelper<Solenoid> {
class Solenoid : public Sendable, public SendableHelper<Solenoid> {
public:
/**
* Constructor using the default PCM ID (0).
*
* @param channel The channel on the PCM to control (0..7).
*/
explicit Solenoid(int channel);
/**
* Constructor.
*
* @param moduleNumber The CAN ID of the PCM the solenoid is attached to
* @param channel The channel on the PCM to control (0..7).
*/
Solenoid(int moduleNumber, int channel);
Solenoid(PneumaticsBase& module, int channel);
Solenoid(PneumaticsBase* module, int channel);
Solenoid(std::shared_ptr<PneumaticsBase> module, int channel);
~Solenoid() override;
@@ -73,16 +62,16 @@ class Solenoid : public SolenoidBase,
int GetChannel() const;
/**
* Check if solenoid is blacklisted.
* Check if solenoid is Disabled.
*
* If a solenoid is shorted, it is added to the blacklist and
* If a solenoid is shorted, it is added to the DisabledList and
* disabled until power cycle, or until faults are cleared.
*
* @see ClearAllPCMStickyFaults()
*
* @return If solenoid is disabled due to short.
*/
bool IsBlackListed() const;
bool IsDisabled() const;
/**
* Set the pulse duration in the PCM. This is used in conjunction with
@@ -107,8 +96,9 @@ class Solenoid : public SolenoidBase,
void InitSendable(SendableBuilder& builder) override;
private:
hal::Handle<HAL_SolenoidHandle> m_solenoidHandle;
int m_channel; // The channel on the module to control
std::shared_ptr<PneumaticsBase> m_module;
int m_mask;
int m_channel;
};
} // namespace frc

View File

@@ -1,131 +0,0 @@
// 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
namespace frc {
/**
* SolenoidBase class is the common base class for the Solenoid and
* DoubleSolenoid classes.
*/
class SolenoidBase {
public:
virtual ~SolenoidBase() = default;
/**
* Get the CAN ID of the module this solenoid is connected to.
*
* @return the module number.
*/
int GetModuleNumber() const;
/**
* Read all 8 solenoids as a single byte
*
* @param module the module to read from
* @return The current value of all 8 solenoids on the module.
*/
static int GetAll(int module);
/**
* Read all 8 solenoids as a single byte
*
* @return The current value of all 8 solenoids on the module.
*/
int GetAll() const;
/**
* Reads complete solenoid blacklist for all 8 solenoids as a single byte.
*
* If a solenoid is shorted, it is added to the blacklist and
* disabled until power cycle, or until faults are cleared.
* @see ClearAllPCMStickyFaults()
*
* @param module the module to read from
* @return The solenoid blacklist of all 8 solenoids on the module.
*/
static int GetPCMSolenoidBlackList(int module);
/**
* Reads complete solenoid blacklist for all 8 solenoids as a single byte.
*
* If a solenoid is shorted, it is added to the blacklist and
* disabled until power cycle, or until faults are cleared.
* @see ClearAllPCMStickyFaults()
*
* @return The solenoid blacklist of all 8 solenoids on the module.
*/
int GetPCMSolenoidBlackList() const;
/**
* @param module the module to read from
* @return true if PCM sticky fault is set : The common highside solenoid
* voltage rail is too low, most likely a solenoid channel is shorted.
*/
static bool GetPCMSolenoidVoltageStickyFault(int module);
/**
* @return true if PCM sticky fault is set : The common highside solenoid
* voltage rail is too low, most likely a solenoid channel is shorted.
*/
bool GetPCMSolenoidVoltageStickyFault() const;
/**
* @param module the module to read from
* @return true if PCM is in fault state : The common highside solenoid
* voltage rail is too low, most likely a solenoid channel is shorted.
*/
static bool GetPCMSolenoidVoltageFault(int module);
/**
* @return true if PCM is in fault state : The common highside solenoid
* voltage rail is too low, most likely a solenoid channel is shorted.
*/
bool GetPCMSolenoidVoltageFault() const;
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* If a sticky fault is set, then it will be persistently cleared. Compressor
* drive maybe momentarily disable while flags are being cleared. Care should
* be taken to not call this too frequently, otherwise normal compressor
* functionality may be prevented.
*
* If no sticky faults are set then this call will have no effect.
*
* @param module the module to read from
*/
static void ClearAllPCMStickyFaults(int module);
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* If a sticky fault is set, then it will be persistently cleared. Compressor
* drive maybe momentarily disable while flags are being cleared. Care should
* be taken to not call this too frequently, otherwise normal compressor
* functionality may be prevented.
*
* If no sticky faults are set then this call will have no effect.
*/
void ClearAllPCMStickyFaults();
protected:
/**
* Constructor.
*
* @param moduleNumber The CAN PCM ID.
*/
explicit SolenoidBase(int pcmID);
SolenoidBase(SolenoidBase&&) = default;
SolenoidBase& operator=(SolenoidBase&&) = default;
static constexpr int m_maxModules = 63;
static constexpr int m_maxPorts = 8;
int m_moduleNumber; // PCM module number
};
} // namespace frc

View File

@@ -6,6 +6,7 @@
#include <memory>
#include "frc/PneumaticsBase.h"
#include "frc/simulation/CallbackStore.h"
namespace frc {
@@ -17,26 +18,21 @@ namespace sim {
/**
* Class to control a simulated Pneumatic Control Module (PCM).
*/
class PCMSim {
class CTREPCMSim {
public:
/**
* Constructs with the default PCM module number (CAN ID).
*/
PCMSim();
CTREPCMSim();
/**
* Constructs from a PCM module number (CAN ID).
*
* @param module module number
*/
explicit PCMSim(int module);
explicit CTREPCMSim(int module);
/**
* Constructs from a Compressor object.
*
* @param compressor Compressor connected to PCM to simulate
*/
explicit PCMSim(const Compressor& compressor);
explicit CTREPCMSim(const PneumaticsBase& pneumatics);
/**
* Register a callback to be run when a solenoid is initialized on a channel.
@@ -46,17 +42,15 @@ class PCMSim {
* @param initialNotify should the callback be run with the initial state
* @return the CallbackStore object associated with this callback
*/
[[nodiscard]] std::unique_ptr<CallbackStore>
RegisterSolenoidInitializedCallback(int channel, NotifyCallback callback,
bool initialNotify);
[[nodiscard]] std::unique_ptr<CallbackStore> RegisterInitializedCallback(
NotifyCallback callback, bool initialNotify);
/**
* Check if a solenoid has been initialized on a specific channel.
*
* @param channel the channel to check
* @return true if initialized
*/
bool GetSolenoidInitialized(int channel) const;
bool GetInitialized() const;
/**
* Define whether a solenoid has been initialized on a specific channel.
@@ -64,7 +58,7 @@ class PCMSim {
* @param channel the channel
* @param solenoidInitialized is there a solenoid initialized on that channel
*/
void SetSolenoidInitialized(int channel, bool solenoidInitialized);
void SetInitialized(bool solenoidInitialized);
/**
* Register a callback to be run when the solenoid output on a channel
@@ -94,31 +88,6 @@ class PCMSim {
*/
void SetSolenoidOutput(int channel, bool 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 CallbackStore object associated with this callback
*/
[[nodiscard]] std::unique_ptr<CallbackStore>
RegisterCompressorInitializedCallback(NotifyCallback callback,
bool initialNotify);
/**
* Check whether the compressor has been initialized.
*
* @return true if initialized
*/
bool GetCompressorInitialized() const;
/**
* Define whether the compressor has been initialized.
*
* @param compressorInitialized whether the compressor is initialized
*/
void SetCompressorInitialized(bool compressorInitialized);
/**
* Register a callback to be run when the compressor activates.
*

View File

@@ -1,116 +0,0 @@
// 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 <memory>
#include "frc/DoubleSolenoid.h"
#include "frc/simulation/CallbackStore.h"
#include "frc/simulation/PCMSim.h"
namespace frc::sim {
/**
* Class to control a simulated Pneumatic Control Module (PCM).
*/
class DoubleSolenoidSim {
public:
/**
* Constructs for a solenoid on the default PCM.
*
* @param channel the solenoid channel.
*/
DoubleSolenoidSim(int fwd, int rev);
/**
* Constructs for a solenoid on the given PCM.
*
* @param pcm the PCM the solenoid is connected to.
* @param channel the solenoid channel.
*/
DoubleSolenoidSim(int module, int fwd, int rev);
/**
* Constructs from a PCMSim object.
*
* @param pcm the PCM the solenoid is connected to.
*/
DoubleSolenoidSim(PCMSim& pcm, int fwd, int rev);
/**
* Constructs for the given solenoid.
*
* @param solenoid the solenoid to simulate.
*/
explicit DoubleSolenoidSim(DoubleSolenoid& solenoid);
/**
* Register a callback to be run when the forward solenoid is initialized.
*
* @param callback the callback
* @param initialNotify should the callback be run with the initial state
* @return the {@link CallbackStore} object associated with this callback.
*/
[[nodiscard]] std::unique_ptr<CallbackStore> RegisterFwdInitializedCallback(
NotifyCallback callback, bool initialNotify);
/**
* Check if the forward solenoid has been initialized.
*
* @return true if initialized
*/
bool GetFwdInitialized() const;
/**
* Define whether the forward solenoid has been initialized.
*
* @param initialized whether the solenoid is intiialized.
*/
void SetFwdInitialized(bool initialized);
/**
* Register a callback to be run when the reverse solenoid is initialized.
*
* @param callback the callback
* @param initialNotify should the callback be run with the initial state
* @return the {@link CallbackStore} object associated with this callback.
*/
[[nodiscard]] std::unique_ptr<CallbackStore> RegisterRevInitializedCallback(
NotifyCallback callback, bool initialNotify);
/**
* Define whether the reverse solenoid has been initialized.
*
* @param initialized whether the solenoid is intiialized.
*/
void SetRevInitialized(bool initialized);
/**
* Check if the reverse solenoid has been initialized.
*
* @return true if initialized
*/
bool GetRevInitialized() const;
/**
* Set the value of the double solenoid output.
*
* @param value The value to set (Off, Forward, Reverse)
*/
void Set(DoubleSolenoid::Value value);
/**
* Check the value of the double solenoid output.
*
* @return the output value of the double solenoid.
*/
DoubleSolenoid::Value Get() const;
private:
PCMSim m_pcm;
int m_fwd;
int m_rev;
};
} // namespace frc::sim

View File

@@ -1,104 +0,0 @@
// 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 <memory>
#include "frc/Solenoid.h"
#include "frc/simulation/CallbackStore.h"
#include "frc/simulation/PCMSim.h"
namespace frc::sim {
/**
* Class to control a simulated Pneumatic Control Module (PCM).
*/
class SolenoidSim {
public:
/**
* Constructs for a solenoid on the default PCM.
*
* @param channel the solenoid channel.
*/
explicit SolenoidSim(int channel);
/**
* Constructs for the given solenoid.
*
* @param doubleSolenoid the solenoid to simulate.
*/
explicit SolenoidSim(Solenoid& solenoid);
/**
* Constructs for a solenoid.
*
* @param module the CAN ID of the PCM the solenoid is connected to.
* @param channel the solenoid channel.
*
* @see PCMSim#PCMSim(int)
*/
SolenoidSim(int module, int channel);
/**
* Constructs for a solenoid on the given PCM.
*
* @param pcm the PCM the solenoid is connected to.
* @param channel the solenoid channel.
*/
SolenoidSim(PCMSim& pcm, int channel);
/**
* Register a callback to be run when this solenoid is initialized.
*
* @param callback the callback
* @param initialNotify should the callback be run with the initial state
* @return the {@link CallbackStore} object associated with this callback.
*/
[[nodiscard]] std::unique_ptr<CallbackStore> RegisterInitializedCallback(
NotifyCallback callback, bool initialNotify);
/**
* Check if this solenoid has been initialized.
*
* @return true if initialized
*/
bool GetInitialized() const;
/**
* Define whether this solenoid has been initialized.
*
* @param initialized whether the solenoid is intiialized.
*/
void SetInitialized(bool initialized);
/**
* 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.
*/
[[nodiscard]] std::unique_ptr<CallbackStore> RegisterOutputCallback(
NotifyCallback callback, bool initialNotify);
/**
* Check the solenoid output.
*
* @return the solenoid output
*/
bool GetOutput() const;
/**
* Change the solenoid output.
*
* @param output the new solenoid output
*/
void SetOutput(bool output);
private:
PCMSim m_pcm;
int m_channel;
};
} // namespace frc::sim

View File

@@ -12,12 +12,12 @@
#include "frc/simulation/AnalogOutputSim.h"
#include "frc/simulation/AnalogTriggerSim.h"
#include "frc/simulation/BuiltInAccelerometerSim.h"
#include "frc/simulation/CTREPCMSim.h"
#include "frc/simulation/DIOSim.h"
#include "frc/simulation/DigitalPWMSim.h"
#include "frc/simulation/DriverStationSim.h"
#include "frc/simulation/DutyCycleSim.h"
#include "frc/simulation/EncoderSim.h"
#include "frc/simulation/PCMSim.h"
#include "frc/simulation/PDPSim.h"
#include "frc/simulation/PWMSim.h"
#include "frc/simulation/RelaySim.h"
@@ -40,7 +40,7 @@ TEST(SimInitializationTests, TestAllInitialize) {
(void)dssim;
EncoderSim esim = EncoderSim::CreateForIndex(0);
(void)esim;
PCMSim pcmsim{0};
CTREPCMSim pcmsim{0};
PDPSim pdpsim{0};
PWMSim pwmsim{0};
RelaySim rsim{0};

View File

@@ -7,7 +7,8 @@
using namespace HatchConstants;
HatchSubsystem::HatchSubsystem()
: m_hatchSolenoid{kHatchSolenoidPorts[0], kHatchSolenoidPorts[1]} {}
: m_hatchSolenoid{m_pneumaticsModule, kHatchSolenoidPorts[0],
kHatchSolenoidPorts[1]} {}
void HatchSubsystem::GrabHatch() {
m_hatchSolenoid.Set(frc::DoubleSolenoid::kForward);

View File

@@ -5,6 +5,7 @@
#pragma once
#include <frc/DoubleSolenoid.h>
#include <frc/PneumaticsControlModule.h>
#include <frc2/command/SubsystemBase.h>
#include "Constants.h"
@@ -28,5 +29,6 @@ class HatchSubsystem : public frc2::SubsystemBase {
private:
// Components (e.g. motor controllers and sensors) should generally be
// declared private and exposed only through public methods.
frc::PneumaticsControlModule m_pneumaticsModule;
frc::DoubleSolenoid m_hatchSolenoid;
};

View File

@@ -7,7 +7,8 @@
using namespace HatchConstants;
HatchSubsystem::HatchSubsystem()
: m_hatchSolenoid{kHatchSolenoidPorts[0], kHatchSolenoidPorts[1]} {}
: m_hatchSolenoid{m_pneumaticsModule, kHatchSolenoidPorts[0],
kHatchSolenoidPorts[1]} {}
void HatchSubsystem::GrabHatch() {
m_hatchSolenoid.Set(frc::DoubleSolenoid::kForward);

View File

@@ -5,6 +5,7 @@
#pragma once
#include <frc/DoubleSolenoid.h>
#include <frc/PneumaticsControlModule.h>
#include <frc2/command/SubsystemBase.h>
#include "Constants.h"
@@ -28,5 +29,6 @@ class HatchSubsystem : public frc2::SubsystemBase {
private:
// Components (e.g. motor controllers and sensors) should generally be
// declared private and exposed only through public methods.
frc::PneumaticsControlModule m_pneumaticsModule;
frc::DoubleSolenoid m_hatchSolenoid;
};

View File

@@ -10,6 +10,8 @@
#include <frc/livewindow/LiveWindow.h>
#include <frc/smartdashboard/SmartDashboard.h>
#include "PneumaticsModule.h"
DriveTrain Robot::drivetrain;
Pivot Robot::pivot;
Collector Robot::collector;
@@ -81,6 +83,11 @@ void Robot::Log() {
drivetrain.GetRightEncoder().GetDistance());
}
frc::PneumaticsControlModule* pac::GetPneumatics() {
static frc::PneumaticsControlModule pcm;
return &pcm;
}
#ifndef RUNNING_FRC_TESTS
int main() {
return frc::StartRobot<Robot>();

View File

@@ -6,6 +6,8 @@
#include <frc/smartdashboard/SmartDashboard.h>
#include "PneumaticsModule.h"
Pneumatics::Pneumatics() : frc::Subsystem("Pneumatics") {
AddChild("Pressure Sensor", m_pressureSensor);
}
@@ -16,7 +18,7 @@ void Pneumatics::InitDefaultCommand() {
void Pneumatics::Start() {
#ifndef SIMULATION
m_compressor.Start();
pac::GetPneumatics()->SetClosedLoopControl(true);
#endif
}

View File

@@ -0,0 +1,11 @@
// 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 <frc/PneumaticsControlModule.h>
namespace pac {
frc::PneumaticsControlModule* GetPneumatics();
} // namespace pac

View File

@@ -4,6 +4,7 @@
#pragma once
#include <frc/PneumaticsControlModule.h>
#include <frc/TimedRobot.h>
#include <frc/commands/Command.h>
#include <frc/smartdashboard/SendableChooser.h>

View File

@@ -9,6 +9,8 @@
#include <frc/commands/Subsystem.h>
#include <frc/motorcontrol/PWMSparkMax.h>
#include "PneumaticsModule.h"
/**
* The Collector subsystem has one motor for the rollers, a limit switch for
* ball
@@ -68,6 +70,6 @@ class Collector : public frc::Subsystem {
// Subsystem devices
frc::PWMSparkMax m_rollerMotor{6};
frc::DigitalInput m_ballDetector{10};
frc::Solenoid m_piston{1};
frc::Solenoid m_piston{pac::GetPneumatics(), 1};
frc::DigitalInput m_openDetector{6};
};

View File

@@ -5,7 +5,6 @@
#pragma once
#include <frc/AnalogInput.h>
#include <frc/Compressor.h>
#include <frc/commands/Subsystem.h>
/**
@@ -42,9 +41,5 @@ class Pneumatics : public frc::Subsystem {
private:
frc::AnalogInput m_pressureSensor{3};
#ifndef SIMULATION
frc::Compressor m_compressor{1}; // TODO: (1, 14, 1, 8);
#endif
static constexpr double kMaxPressure = 2.55;
};

View File

@@ -9,6 +9,8 @@
#include <frc/Solenoid.h>
#include <frc/commands/Subsystem.h>
#include "PneumaticsModule.h"
/**
* The Shooter subsystem handles shooting. The mechanism for shooting is
* slightly complicated because it has to pneumatic cylinders for shooting, and
@@ -114,9 +116,9 @@ class Shooter : public frc::Subsystem {
private:
// Devices
frc::DoubleSolenoid m_piston1{3, 4};
frc::DoubleSolenoid m_piston2{5, 6};
frc::Solenoid m_latchPiston{1, 2};
frc::DoubleSolenoid m_piston1{pac::GetPneumatics(), 3, 4};
frc::DoubleSolenoid m_piston2{pac::GetPneumatics(), 5, 6};
frc::Solenoid m_latchPiston{pac::GetPneumatics(), 2};
frc::DigitalInput m_piston1ReedSwitchFront{9};
frc::DigitalInput m_piston1ReedSwitchBack{11};
frc::DigitalInput m_hotGoalSensor{

View File

@@ -4,6 +4,7 @@
#include <frc/DoubleSolenoid.h>
#include <frc/Joystick.h>
#include <frc/PneumaticsControlModule.h>
#include <frc/Solenoid.h>
#include <frc/TimedRobot.h>
@@ -53,11 +54,13 @@ class Robot : public frc::TimedRobot {
private:
frc::Joystick m_stick{0};
frc::PneumaticsControlModule m_pneumaticsModule;
// Solenoid corresponds to a single solenoid.
frc::Solenoid m_solenoid{0};
frc::Solenoid m_solenoid{m_pneumaticsModule, 0};
// DoubleSolenoid corresponds to a double solenoid.
frc::DoubleSolenoid m_doubleSolenoid{1, 2};
frc::DoubleSolenoid m_doubleSolenoid{m_pneumaticsModule, 1, 2};
static constexpr int kSolenoidButton = 1;
static constexpr int kDoubleSolenoidForward = 2;

View File

@@ -4,10 +4,10 @@
#include "TestBench.h"
#include "frc/AnalogInput.h"
#include "frc/Compressor.h"
#include "frc/DigitalInput.h"
#include "frc/DigitalOutput.h"
#include "frc/DoubleSolenoid.h"
#include "frc/PneumaticsControlModule.h"
#include "frc/Solenoid.h"
#include "frc/Timer.h"
#include "gtest/gtest.h"
@@ -26,7 +26,7 @@ static const double kCompressorOffVoltage = 1.68;
class PCMTest : public testing::Test {
protected:
frc::Compressor m_compressor;
frc::PneumaticsControlModule m_pneumaticsModule;
frc::DigitalOutput m_fakePressureSwitch{
TestBench::kFakePressureSwitchChannel};
@@ -35,7 +35,7 @@ class PCMTest : public testing::Test {
frc::DigitalInput m_fakeSolenoid2{TestBench::kFakeSolenoid2Channel};
void Reset() {
m_compressor.Stop();
m_pneumaticsModule.SetClosedLoopControl(false);
m_fakePressureSwitch.Set(false);
}
};
@@ -46,7 +46,7 @@ class PCMTest : public testing::Test {
TEST_F(PCMTest, PressureSwitch) {
Reset();
m_compressor.SetClosedLoopControl(true);
m_pneumaticsModule.SetClosedLoopControl(true);
// Turn on the compressor
m_fakePressureSwitch.Set(true);
@@ -66,8 +66,8 @@ TEST_F(PCMTest, PressureSwitch) {
*/
TEST_F(PCMTest, Solenoid) {
Reset();
frc::Solenoid solenoid1{TestBench::kSolenoidChannel1};
frc::Solenoid solenoid2{TestBench::kSolenoidChannel2};
frc::Solenoid solenoid1{m_pneumaticsModule, TestBench::kSolenoidChannel1};
frc::Solenoid solenoid2{m_pneumaticsModule, TestBench::kSolenoidChannel2};
// Turn both solenoids off
solenoid1.Set(false);
@@ -111,7 +111,7 @@ TEST_F(PCMTest, Solenoid) {
* with the DoubleSolenoid class.
*/
TEST_F(PCMTest, DoubleSolenoid) {
frc::DoubleSolenoid solenoid{TestBench::kSolenoidChannel1,
frc::DoubleSolenoid solenoid{m_pneumaticsModule, TestBench::kSolenoidChannel1,
TestBench::kSolenoidChannel2};
solenoid.Set(frc::DoubleSolenoid::kOff);
@@ -138,8 +138,8 @@ TEST_F(PCMTest, DoubleSolenoid) {
TEST_F(PCMTest, OneShot) {
Reset();
frc::Solenoid solenoid1{TestBench::kSolenoidChannel1};
frc::Solenoid solenoid2{TestBench::kSolenoidChannel2};
frc::Solenoid solenoid1{m_pneumaticsModule, TestBench::kSolenoidChannel1};
frc::Solenoid solenoid2{m_pneumaticsModule, TestBench::kSolenoidChannel2};
// Turn both solenoids off
solenoid1.Set(false);

View File

@@ -1,212 +0,0 @@
// 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;
import edu.wpi.first.hal.CompressorJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class for operating a compressor connected to a PCM (Pneumatic Control Module). The PCM will
* automatically run in closed loop mode by default whenever a {@link Solenoid} object is created.
* For most cases, a Compressor object does not need to be instantiated or used in a robot program.
* This class is only required in cases where the robot program needs a more detailed status of the
* compressor or to enable/disable closed loop control.
*
* <p>Note: you cannot operate the compressor directly from this class as doing so would circumvent
* the safety provided by using the pressure switch and closed loop control. You can only turn off
* closed loop control, thereby stopping the compressor from operating.
*/
public class Compressor implements Sendable, AutoCloseable {
private int m_compressorHandle;
private byte m_module;
/**
* Makes a new instance of the compressor using the provided CAN device ID. Use this constructor
* when you have more than one PCM.
*
* @param module The PCM CAN device ID (0 - 62 inclusive)
*/
public Compressor(int module) {
m_module = (byte) module;
m_compressorHandle = CompressorJNI.initializeCompressor((byte) module);
HAL.report(tResourceType.kResourceType_Compressor, module + 1);
SendableRegistry.addLW(this, "Compressor", module);
}
/**
* Makes a new instance of the compressor using the default PCM ID of 0.
*
* <p>Additional modules can be supported by making a new instance and {@link #Compressor(int)
* specifying the CAN ID.}
*/
public Compressor() {
this(SensorUtil.getDefaultSolenoidModule());
}
@Override
public void close() {
SendableRegistry.remove(this);
}
/**
* Start the compressor running in closed loop control mode.
*
* <p>Use the method in cases where you would like to manually stop and start the compressor for
* applications such as conserving battery or making sure that the compressor motor doesn't start
* during critical operations.
*/
public void start() {
setClosedLoopControl(true);
}
/**
* Stop the compressor from running in closed loop control mode.
*
* <p>Use the method in cases where you would like to manually stop and start the compressor for
* applications such as conserving battery or making sure that the compressor motor doesn't start
* during critical operations.
*/
public void stop() {
setClosedLoopControl(false);
}
/**
* Get the status of the compressor.
*
* @return true if the compressor is on
*/
public boolean enabled() {
return CompressorJNI.getCompressor(m_compressorHandle);
}
/**
* Get the pressure switch value.
*
* @return true if the pressure is low
*/
public boolean getPressureSwitchValue() {
return CompressorJNI.getCompressorPressureSwitch(m_compressorHandle);
}
/**
* Get the current being used by the compressor.
*
* @return current consumed by the compressor in amps
*/
public double getCompressorCurrent() {
return CompressorJNI.getCompressorCurrent(m_compressorHandle);
}
/**
* Set the PCM in closed loop control mode.
*
* @param on if true sets the compressor to be in closed loop control mode (default)
*/
public void setClosedLoopControl(boolean on) {
CompressorJNI.setCompressorClosedLoopControl(m_compressorHandle, on);
}
/**
* Gets the current operating mode of the PCM.
*
* @return true if compressor is operating on closed-loop mode
*/
public boolean getClosedLoopControl() {
return CompressorJNI.getCompressorClosedLoopControl(m_compressorHandle);
}
/**
* If PCM is in fault state : Compressor Drive is disabled due to compressor current being too
* high.
*
* @return true if PCM is in fault state.
*/
public boolean getCompressorCurrentTooHighFault() {
return CompressorJNI.getCompressorCurrentTooHighFault(m_compressorHandle);
}
/**
* If PCM sticky fault is set : Compressor is disabled due to compressor current being too high.
*
* @return true if PCM sticky fault is set.
*/
public boolean getCompressorCurrentTooHighStickyFault() {
return CompressorJNI.getCompressorCurrentTooHighStickyFault(m_compressorHandle);
}
/**
* If PCM sticky fault is set : Compressor output appears to be shorted.
*
* @return true if PCM sticky fault is set.
*/
public boolean getCompressorShortedStickyFault() {
return CompressorJNI.getCompressorShortedStickyFault(m_compressorHandle);
}
/**
* If PCM is in fault state : Compressor output appears to be shorted.
*
* @return true if PCM is in fault state.
*/
public boolean getCompressorShortedFault() {
return CompressorJNI.getCompressorShortedFault(m_compressorHandle);
}
/**
* If PCM sticky fault is set : Compressor does not appear to be wired, i.e. compressor is not
* drawing enough current.
*
* @return true if PCM sticky fault is set.
*/
public boolean getCompressorNotConnectedStickyFault() {
return CompressorJNI.getCompressorNotConnectedStickyFault(m_compressorHandle);
}
/**
* If PCM is in fault state : Compressor does not appear to be wired, i.e. compressor is not
* drawing enough current.
*
* @return true if PCM is in fault state.
*/
public boolean getCompressorNotConnectedFault() {
return CompressorJNI.getCompressorNotConnectedFault(m_compressorHandle);
}
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* <p>If a sticky fault is set, then it will be persistently cleared. The compressor might
* momentarily disable while the flags are being cleared. Doo not call this method too frequently,
* otherwise normal compressor functionality may be prevented.
*
* <p>If no sticky faults are set then this call will have no effect.
*/
public void clearAllPCMStickyFaults() {
CompressorJNI.clearAllPCMStickyFaults(m_module);
}
/**
* Gets the module number (CAN ID).
*
* @return Module number
*/
public int getModule() {
return m_module;
}
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("Compressor");
builder.addBooleanProperty(
"Closed Loop Control", this::getClosedLoopControl, this::setClosedLoopControl);
builder.addBooleanProperty("Enabled", this::enabled, null);
builder.addBooleanProperty("Pressure switch", this::getPressureSwitchValue, null);
}
}

View File

@@ -6,10 +6,9 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SolenoidJNI;
import edu.wpi.first.hal.util.UncleanStatusException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import java.util.Objects;
/**
* DoubleSolenoid class for running 2 channels of high voltage Digital Output on the PCM.
@@ -17,7 +16,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* <p>The DoubleSolenoid class is typically used for pneumatics solenoids that have two positions
* controlled by two separate channels.
*/
public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoCloseable {
public class DoubleSolenoid implements Sendable, AutoCloseable {
/** Possible values for a DoubleSolenoid. */
public enum Value {
kOff,
@@ -25,68 +24,44 @@ public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoClosea
kReverse
}
private byte m_forwardMask; // The mask for the forward channel.
private byte m_reverseMask; // The mask for the reverse channel.
private int m_forwardHandle;
private int m_reverseHandle;
private final int m_forwardMask; // The mask for the forward channel.
private final int m_reverseMask; // The mask for the reverse channel.
private final int m_mask; // The channel mask
private PneumaticsBase m_module;
private final int m_forwardChannel;
private final int m_reverseChannel;
/**
* Constructor. Uses the default PCM ID (defaults to 0).
*
* @param forwardChannel The forward channel number on the PCM (0..7).
* @param reverseChannel The reverse channel number on the PCM (0..7).
*/
public DoubleSolenoid(final int forwardChannel, final int reverseChannel) {
this(SensorUtil.getDefaultSolenoidModule(), forwardChannel, reverseChannel);
}
/**
* Constructor.
*
* @param moduleNumber The module number of the solenoid module to use.
* @param module The module of the solenoid module to use.
* @param forwardChannel The forward channel on the module to control (0..7).
* @param reverseChannel The reverse channel on the module to control (0..7).
*/
public DoubleSolenoid(
final int moduleNumber, final int forwardChannel, final int reverseChannel) {
super(moduleNumber);
public DoubleSolenoid(PneumaticsBase module, final int forwardChannel, final int reverseChannel) {
m_module = Objects.requireNonNull(module, "Module cannot be null");
// TODO check channels
m_forwardChannel = forwardChannel;
m_reverseChannel = reverseChannel;
SensorUtil.checkSolenoidModule(m_moduleNumber);
SensorUtil.checkSolenoidChannel(forwardChannel);
SensorUtil.checkSolenoidChannel(reverseChannel);
m_forwardMask = 1 << forwardChannel;
m_reverseMask = 1 << reverseChannel;
m_mask = m_forwardMask | m_reverseMask;
int portHandle = HAL.getPortWithModule((byte) m_moduleNumber, (byte) forwardChannel);
m_forwardHandle = SolenoidJNI.initializeSolenoidPort(portHandle);
try {
portHandle = HAL.getPortWithModule((byte) m_moduleNumber, (byte) reverseChannel);
m_reverseHandle = SolenoidJNI.initializeSolenoidPort(portHandle);
} catch (UncleanStatusException ex) {
// free the forward handle on exception, then rethrow
SolenoidJNI.freeSolenoidPort(m_forwardHandle);
m_forwardHandle = 0;
m_reverseHandle = 0;
throw ex;
}
m_forwardMask = (byte) (1 << forwardChannel);
m_reverseMask = (byte) (1 << reverseChannel);
HAL.report(tResourceType.kResourceType_Solenoid, forwardChannel + 1, m_moduleNumber + 1);
HAL.report(tResourceType.kResourceType_Solenoid, reverseChannel + 1, m_moduleNumber + 1);
SendableRegistry.addLW(this, "DoubleSolenoid", m_moduleNumber, forwardChannel);
HAL.report(
tResourceType.kResourceType_Solenoid, forwardChannel + 1, module.getModuleNumber() + 1);
HAL.report(
tResourceType.kResourceType_Solenoid, reverseChannel + 1, module.getModuleNumber() + 1);
SendableRegistry.addLW(this, "DoubleSolenoid", module.getModuleNumber(), forwardChannel);
}
@Override
public synchronized void close() {
SendableRegistry.remove(this);
SolenoidJNI.freeSolenoidPort(m_forwardHandle);
SolenoidJNI.freeSolenoidPort(m_reverseHandle);
m_module = null;
}
/**
@@ -95,28 +70,23 @@ public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoClosea
* @param value The value to set (Off, Forward, Reverse)
*/
public void set(final Value value) {
boolean forward = false;
boolean reverse = false;
int setValue;
switch (value) {
case kOff:
forward = false;
reverse = false;
setValue = 0;
break;
case kForward:
forward = true;
reverse = false;
setValue = m_forwardMask;
break;
case kReverse:
forward = false;
reverse = true;
setValue = m_reverseMask;
break;
default:
throw new AssertionError("Illegal value: " + value);
}
SolenoidJNI.setSolenoid(m_forwardHandle, forward);
SolenoidJNI.setSolenoid(m_reverseHandle, reverse);
m_module.setSolenoids(m_mask, setValue);
}
/**
@@ -125,12 +95,11 @@ public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoClosea
* @return The current value of the solenoid.
*/
public Value get() {
boolean valueForward = SolenoidJNI.getSolenoid(m_forwardHandle);
boolean valueReverse = SolenoidJNI.getSolenoid(m_reverseHandle);
int values = m_module.getSolenoids();
if (valueForward) {
if ((values & m_forwardMask) != 0) {
return Value.kForward;
} else if (valueReverse) {
} else if ((values & m_reverseMask) != 0) {
return Value.kReverse;
} else {
return Value.kOff;
@@ -172,27 +141,23 @@ public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoClosea
}
/**
* Check if the forward solenoid is blacklisted. If a solenoid is shorted, it is added to the
* blacklist and disabled until power cycle, or until faults are cleared.
* Check if the forward solenoid is Disabled. If a solenoid is shorted, it is added to the
* DisabledList and disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isFwdSolenoidBlackListed() {
int blackList = getPCMSolenoidBlackList();
return (blackList & m_forwardMask) != 0;
public boolean isFwdSolenoidDisabled() {
return (m_module.getSolenoidDisabledList() & m_forwardMask) != 0;
}
/**
* Check if the reverse solenoid is blacklisted. If a solenoid is shorted, it is added to the
* blacklist and disabled until power cycle, or until faults are cleared.
* Check if the reverse solenoid is Disabled. If a solenoid is shorted, it is added to the
* DisabledList and disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isRevSolenoidBlackListed() {
int blackList = getPCMSolenoidBlackList();
return (blackList & m_reverseMask) != 0;
public boolean isRevSolenoidDisabled() {
return (m_module.getSolenoidDisabledList() & m_reverseMask) != 0;
}
@Override

View File

@@ -0,0 +1,54 @@
// 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;
public interface PneumaticsBase extends AutoCloseable {
/**
* Sets solenoids on a pneumatics module.
*
* @param mask mask
* @param values values
*/
void setSolenoids(int mask, int values);
/**
* Gets solenoid values.
*
* @return values
*/
int getSolenoids();
/**
* Get module number for this module.
*
* @return module number
*/
int getModuleNumber();
/**
* Get the disabled solenoids.
*
* @return disabled list
*/
int getSolenoidDisabledList();
/**
* Fire a single solenoid shot.
*
* @param index solenoid index
*/
void fireOneShot(int index);
/**
* Set the duration for a single solenoid shot.
*
* @param index solenoid index
* @param durMs shot duration
*/
void setOneShotDuration(int index, int durMs);
boolean checkSolenoidChannel(int channel);
}

View File

@@ -0,0 +1,117 @@
// 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;
import edu.wpi.first.hal.CTREPCMJNI;
public class PneumaticsControlModule implements PneumaticsBase {
private final int m_handle;
private final int m_module;
public PneumaticsControlModule() {
this(SensorUtil.getDefaultCTREPCMModule());
}
public PneumaticsControlModule(int module) {
m_handle = CTREPCMJNI.initialize(module);
m_module = module;
}
@Override
public void close() throws Exception {
CTREPCMJNI.free(m_handle);
}
public boolean getCompressor() {
return CTREPCMJNI.getCompressor(m_handle);
}
public void setClosedLoopControl(boolean enabled) {
CTREPCMJNI.setClosedLoopControl(m_handle, enabled);
}
public boolean getClosedLoopControl() {
return CTREPCMJNI.getClosedLoopControl(m_handle);
}
public boolean getPressureSwitch() {
return CTREPCMJNI.getPressureSwitch(m_handle);
}
public double getCompressorCurrent() {
return CTREPCMJNI.getCompressorCurrent(m_handle);
}
public boolean getCompressorCurrentTooHighFault() {
return CTREPCMJNI.getCompressorCurrentTooHighFault(m_handle);
}
public boolean getCompressorCurrentTooHighStickyFault() {
return CTREPCMJNI.getCompressorCurrentTooHighStickyFault(m_handle);
}
public boolean getCompressorShortedFault() {
return CTREPCMJNI.getCompressorShortedFault(m_handle);
}
public boolean getCompressorShortedStickyFault() {
return CTREPCMJNI.getCompressorShortedStickyFault(m_handle);
}
public boolean getCompressorNotConnectedFault() {
return CTREPCMJNI.getCompressorNotConnectedFault(m_handle);
}
public boolean getCompressorNotConnectedStickyFault() {
return CTREPCMJNI.getCompressorNotConnectedStickyFault(m_handle);
}
@Override
public void setSolenoids(int mask, int values) {
CTREPCMJNI.setSolenoids(m_handle, mask, values);
}
@Override
public int getSolenoids() {
return CTREPCMJNI.getSolenoids(m_handle);
}
@Override
public int getModuleNumber() {
return m_module;
}
@Override
public int getSolenoidDisabledList() {
return CTREPCMJNI.getSolenoidDisabledList(m_handle);
}
public boolean getSolenoidVoltageFault() {
return CTREPCMJNI.getSolenoidVoltageFault(m_handle);
}
public boolean getSolenoidVoltageStickyFault() {
return CTREPCMJNI.getSolenoidVoltageStickyFault(m_handle);
}
public void clearAllStickyFaults() {
CTREPCMJNI.clearAllStickyFaults(m_handle);
}
@Override
public void fireOneShot(int index) {
CTREPCMJNI.fireOneShot(m_handle, index);
}
@Override
public void setOneShotDuration(int index, int durMs) {
CTREPCMJNI.setOneShotDuration(m_handle, index, durMs);
}
@Override
public boolean checkSolenoidChannel(int channel) {
return CTREPCMJNI.checkSolenoidChannel(channel);
}
}

View File

@@ -11,7 +11,6 @@ import edu.wpi.first.hal.PDPJNI;
import edu.wpi.first.hal.PWMJNI;
import edu.wpi.first.hal.PortsJNI;
import edu.wpi.first.hal.RelayJNI;
import edu.wpi.first.hal.SolenoidJNI;
/**
* Stores most recent status information as well as containing utility functions for checking
@@ -49,22 +48,6 @@ public final class SensorUtil {
/** Number of PCM Modules. */
public static final int kPCMModules = PortsJNI.getNumPCMModules();
/**
* Verify that the solenoid module is correct.
*
* @param moduleNumber The solenoid module module number to check.
*/
public static void checkSolenoidModule(final int moduleNumber) {
if (!SolenoidJNI.checkSolenoidModule(moduleNumber)) {
StringBuilder buf = new StringBuilder();
buf.append("Requested solenoid module is out of range. Minimum: 0, Maximum: ")
.append(kPCMModules)
.append(", Requested: ")
.append(moduleNumber);
throw new IllegalArgumentException(buf.toString());
}
}
/**
* Check that the digital channel number is valid. Verify that the channel number is one of the
* legal channel numbers. Channel numbers are 0-based.
@@ -150,22 +133,6 @@ public final class SensorUtil {
}
}
/**
* Verify that the solenoid channel number is within limits. Channel numbers are 0-based.
*
* @param channel The channel number to check.
*/
public static void checkSolenoidChannel(final int channel) {
if (!SolenoidJNI.checkSolenoidChannel(channel)) {
StringBuilder buf = new StringBuilder();
buf.append("Requested solenoid channel is out of range. Minimum: 0, Maximum: ")
.append(kSolenoidChannels)
.append(", Requested: ")
.append(channel);
throw new IllegalArgumentException(buf.toString());
}
}
/**
* Verify that the power distribution channel number is within limits. Channel numbers are
* 0-based.
@@ -204,7 +171,8 @@ public final class SensorUtil {
*
* @return The number of the default solenoid module.
*/
public static int getDefaultSolenoidModule() {
@SuppressWarnings("AbbreviationAsWordInName")
public static int getDefaultCTREPCMModule() {
return 0;
}

View File

@@ -6,9 +6,9 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SolenoidJNI;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import java.util.Objects;
/**
* Solenoid class for running high voltage Digital Output on the PCM.
@@ -16,44 +16,35 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* <p>The Solenoid class is typically used for pneumatic solenoids, but could be used for any device
* within the current spec of the PCM.
*/
public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
private final int m_channel; // The channel to control.
private int m_solenoidHandle;
/**
* Constructor using the default PCM ID (defaults to 0).
*
* @param channel The channel on the PCM to control (0..7).
*/
public Solenoid(final int channel) {
this(SensorUtil.getDefaultSolenoidModule(), channel);
}
public class Solenoid implements Sendable, AutoCloseable {
private final int m_mask; // The channel mask
private final int m_channel;
private PneumaticsBase m_module;
/**
* Constructor.
*
* @param moduleNumber The CAN ID of the PCM the solenoid is attached to.
* @param module The PCM the solenoid is attached to.
* @param channel The channel on the PCM to control (0..7).
*/
public Solenoid(final int moduleNumber, final int channel) {
super(moduleNumber);
public Solenoid(PneumaticsBase module, final int channel) {
m_module = Objects.requireNonNull(module, "Module cannot be null");
if (!module.checkSolenoidChannel(channel)) {
throw new IllegalArgumentException(); // TODO fix me
}
m_mask = 1 << channel;
m_channel = channel;
SensorUtil.checkSolenoidModule(m_moduleNumber);
SensorUtil.checkSolenoidChannel(m_channel);
int portHandle = HAL.getPortWithModule((byte) m_moduleNumber, (byte) m_channel);
m_solenoidHandle = SolenoidJNI.initializeSolenoidPort(portHandle);
HAL.report(tResourceType.kResourceType_Solenoid, m_channel + 1, m_moduleNumber + 1);
SendableRegistry.addLW(this, "Solenoid", m_moduleNumber, m_channel);
HAL.report(tResourceType.kResourceType_Solenoid, channel + 1, module.getModuleNumber() + 1);
SendableRegistry.addLW(this, "Solenoid", module.getModuleNumber(), channel);
}
@Override
public void close() {
SendableRegistry.remove(this);
SolenoidJNI.freeSolenoidPort(m_solenoidHandle);
m_solenoidHandle = 0;
m_module = null;
}
/**
@@ -62,7 +53,8 @@ public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
* @param on True will turn the solenoid output on. False will turn the solenoid output off.
*/
public void set(boolean on) {
SolenoidJNI.setSolenoid(m_solenoidHandle, on);
int value = on ? (0xFFFF & m_mask) : 0;
m_module.setSolenoids(m_mask, value);
}
/**
@@ -71,7 +63,8 @@ public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
* @return True if the solenoid output is on or false if the solenoid output is off.
*/
public boolean get() {
return SolenoidJNI.getSolenoid(m_solenoidHandle);
int currentAll = m_module.getSolenoids();
return (currentAll & m_mask) != 0;
}
/**
@@ -90,15 +83,13 @@ public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
}
/**
* Check if solenoid is blacklisted. If a solenoid is shorted, it is added to the blacklist and
* disabled until power cycle, or until faults are cleared.
* Check if solenoid is DisabledListed. If a solenoid is shorted, it is added to the Disabled List
* and disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isBlackListed() {
int value = getPCMSolenoidBlackList() & (1 << m_channel);
return value != 0;
public boolean isDisabled() {
return (m_module.getSolenoidDisabledList() & m_mask) != 0;
}
/**
@@ -111,7 +102,7 @@ public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
*/
public void setPulseDuration(double durationSeconds) {
long durationMS = (long) (durationSeconds * 1000);
SolenoidJNI.setOneShotDuration(m_solenoidHandle, durationMS);
m_module.setOneShotDuration(m_channel, (int) durationMS);
}
/**
@@ -120,7 +111,7 @@ public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
* @see #setPulseDuration(double)
*/
public void startPulse() {
SolenoidJNI.fireOneShot(m_solenoidHandle);
m_module.fireOneShot(m_channel);
}
@Override

View File

@@ -1,147 +0,0 @@
// 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;
import edu.wpi.first.hal.SolenoidJNI;
/**
* SolenoidBase class is the common base class for the {@link Solenoid} and {@link DoubleSolenoid}
* classes.
*/
public class SolenoidBase {
protected final int m_moduleNumber; // The number of the solenoid module being used.
/**
* Constructor.
*
* @param moduleNumber The PCM CAN ID
*/
protected SolenoidBase(final int moduleNumber) {
m_moduleNumber = moduleNumber;
}
/**
* Get the CAN ID of the module this solenoid is connected to.
*
* @return the module number.
*/
public int getModuleNumber() {
return m_moduleNumber;
}
/**
* Read all 8 solenoids from the specified module as a single byte.
*
* @param moduleNumber the module number to read
* @return The current value of all 8 solenoids on the module.
*/
public static int getAll(int moduleNumber) {
return SolenoidJNI.getAllSolenoids(moduleNumber);
}
/**
* Read all 8 solenoids from the module used by this solenoid as a single byte.
*
* @return The current value of all 8 solenoids on this module.
*/
public int getAll() {
return SolenoidBase.getAll(m_moduleNumber);
}
/**
* Reads complete solenoid blacklist for all 8 solenoids as a single byte. If a solenoid is
* shorted, it is added to the blacklist and disabled until power cycle, or until faults are
* cleared.
*
* @param moduleNumber the module number to read
* @return The solenoid blacklist of all 8 solenoids on the module.
* @see #clearAllPCMStickyFaults()
*/
public static int getPCMSolenoidBlackList(int moduleNumber) {
return SolenoidJNI.getPCMSolenoidBlackList(moduleNumber);
}
/**
* Reads complete solenoid blacklist for all 8 solenoids as a single byte. If a solenoid is
* shorted, it is added to the blacklist and disabled until power cycle, or until faults are
* cleared.
*
* @return The solenoid blacklist of all 8 solenoids on the module.
* @see #clearAllPCMStickyFaults()
*/
public int getPCMSolenoidBlackList() {
return SolenoidBase.getPCMSolenoidBlackList(m_moduleNumber);
}
/**
* If true, the common highside solenoid voltage rail is too low, most likely a solenoid channel
* is shorted.
*
* @param moduleNumber the module number to read
* @return true if PCM sticky fault is set
*/
public static boolean getPCMSolenoidVoltageStickyFault(int moduleNumber) {
return SolenoidJNI.getPCMSolenoidVoltageStickyFault(moduleNumber);
}
/**
* If true, the common highside solenoid voltage rail is too low, most likely a solenoid channel
* is shorted.
*
* @return true if PCM sticky fault is set
*/
public boolean getPCMSolenoidVoltageStickyFault() {
return SolenoidBase.getPCMSolenoidVoltageStickyFault(m_moduleNumber);
}
/**
* The common highside solenoid voltage rail is too low, most likely a solenoid channel is
* shorted.
*
* @param moduleNumber the module number to read
* @return true if PCM is in fault state.
*/
public static boolean getPCMSolenoidVoltageFault(int moduleNumber) {
return SolenoidJNI.getPCMSolenoidVoltageFault(moduleNumber);
}
/**
* The common highside solenoid voltage rail is too low, most likely a solenoid channel is
* shorted.
*
* @return true if PCM is in fault state.
*/
public boolean getPCMSolenoidVoltageFault() {
return SolenoidBase.getPCMSolenoidVoltageFault(m_moduleNumber);
}
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* <p>If a sticky fault is set, then it will be persistently cleared. Compressor drive maybe
* momentarily disable while flags are being cleared. Care should be taken to not call this too
* frequently, otherwise normal compressor functionality may be prevented.
*
* <p>If no sticky faults are set then this call will have no effect.
*
* @param moduleNumber the module number to read
*/
public static void clearAllPCMStickyFaults(int moduleNumber) {
SolenoidJNI.clearAllPCMStickyFaults(moduleNumber);
}
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* <p>If a sticky fault is set, then it will be persistently cleared. Compressor drive maybe
* momentarily disable while flags are being cleared. Care should be taken to not call this too
* frequently, otherwise normal compressor functionality may be prevented.
*
* <p>If no sticky faults are set then this call will have no effect.
*/
public void clearAllPCMStickyFaults() {
SolenoidBase.clearAllPCMStickyFaults(m_moduleNumber);
}
}

View File

@@ -4,18 +4,19 @@
package edu.wpi.first.wpilibj.simulation;
import edu.wpi.first.hal.simulation.CTREPCMDataJNI;
import edu.wpi.first.hal.simulation.NotifyCallback;
import edu.wpi.first.hal.simulation.PCMDataJNI;
import edu.wpi.first.wpilibj.Compressor;
import edu.wpi.first.wpilibj.PneumaticsBase;
import edu.wpi.first.wpilibj.SensorUtil;
/** Class to control a simulated Pneumatic Control Module (PCM). */
public class PCMSim {
@SuppressWarnings("AbbreviationAsWordInName")
public class CTREPCMSim {
private final int m_index;
/** Constructs for the default PCM. */
public PCMSim() {
m_index = SensorUtil.getDefaultSolenoidModule();
public CTREPCMSim() {
m_index = SensorUtil.getDefaultCTREPCMModule();
}
/**
@@ -23,53 +24,17 @@ public class PCMSim {
*
* @param module module number
*/
public PCMSim(int module) {
public CTREPCMSim(int module) {
m_index = module;
}
/**
* Constructs from a Compressor object.
*
* @param compressor Compressor connected to PCM to simulate
* @param module PCM module to simulate
*/
public PCMSim(Compressor compressor) {
m_index = compressor.getModule();
}
/**
* Register a callback to be run when a solenoid is initialized on a channel.
*
* @param channel the channel to monitor
* @param callback the callback
* @param initialNotify should the callback be run 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 registerSolenoidInitializedCallback(
int channel, NotifyCallback callback, boolean initialNotify) {
int uid =
PCMDataJNI.registerSolenoidInitializedCallback(m_index, channel, callback, initialNotify);
return new CallbackStore(m_index, channel, uid, PCMDataJNI::cancelSolenoidInitializedCallback);
}
/**
* Check if a solenoid has been initialized on a specific channel.
*
* @param channel the channel to check
* @return true if initialized
*/
public boolean getSolenoidInitialized(int channel) {
return PCMDataJNI.getSolenoidInitialized(m_index, channel);
}
/**
* Define whether a solenoid has been initialized on a specific channel.
*
* @param channel the channel
* @param solenoidInitialized is there a solenoid initialized on that channel
*/
public void setSolenoidInitialized(int channel, boolean solenoidInitialized) {
PCMDataJNI.setSolenoidInitialized(m_index, channel, solenoidInitialized);
public CTREPCMSim(PneumaticsBase module) {
m_index = module.getModuleNumber();
}
/**
@@ -83,8 +48,9 @@ public class PCMSim {
*/
public CallbackStore registerSolenoidOutputCallback(
int channel, NotifyCallback callback, boolean initialNotify) {
int uid = PCMDataJNI.registerSolenoidOutputCallback(m_index, channel, callback, initialNotify);
return new CallbackStore(m_index, channel, uid, PCMDataJNI::cancelSolenoidOutputCallback);
int uid =
CTREPCMDataJNI.registerSolenoidOutputCallback(m_index, channel, callback, initialNotify);
return new CallbackStore(m_index, channel, uid, CTREPCMDataJNI::cancelSolenoidOutputCallback);
}
/**
@@ -94,7 +60,7 @@ public class PCMSim {
* @return the solenoid output
*/
public boolean getSolenoidOutput(int channel) {
return PCMDataJNI.getSolenoidOutput(m_index, channel);
return CTREPCMDataJNI.getSolenoidOutput(m_index, channel);
}
/**
@@ -104,7 +70,7 @@ public class PCMSim {
* @param solenoidOutput the new solenoid output
*/
public void setSolenoidOutput(int channel, boolean solenoidOutput) {
PCMDataJNI.setSolenoidOutput(m_index, channel, solenoidOutput);
CTREPCMDataJNI.setSolenoidOutput(m_index, channel, solenoidOutput);
}
/**
@@ -115,10 +81,9 @@ public class PCMSim {
* @return the {@link CallbackStore} object associated with this callback. Save a reference to
* this object so GC doesn't cancel the callback.
*/
public CallbackStore registerCompressorInitializedCallback(
NotifyCallback callback, boolean initialNotify) {
int uid = PCMDataJNI.registerCompressorInitializedCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, PCMDataJNI::cancelCompressorInitializedCallback);
public CallbackStore registerInitializedCallback(NotifyCallback callback, boolean initialNotify) {
int uid = CTREPCMDataJNI.registerInitializedCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelInitializedCallback);
}
/**
@@ -126,17 +91,17 @@ public class PCMSim {
*
* @return true if initialized
*/
public boolean getCompressorInitialized() {
return PCMDataJNI.getCompressorInitialized(m_index);
public boolean getInitialized() {
return CTREPCMDataJNI.getInitialized(m_index);
}
/**
* Define whether the compressor has been initialized.
*
* @param compressorInitialized whether the compressor is initialized
* @param initialized whether the compressor is initialized
*/
public void setCompressorInitialized(boolean compressorInitialized) {
PCMDataJNI.setCompressorInitialized(m_index, compressorInitialized);
public void setInitialized(boolean initialized) {
CTREPCMDataJNI.setInitialized(m_index, initialized);
}
/**
@@ -149,8 +114,8 @@ public class PCMSim {
*/
public CallbackStore registerCompressorOnCallback(
NotifyCallback callback, boolean initialNotify) {
int uid = PCMDataJNI.registerCompressorOnCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, PCMDataJNI::cancelCompressorOnCallback);
int uid = CTREPCMDataJNI.registerCompressorOnCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelCompressorOnCallback);
}
/**
@@ -159,7 +124,7 @@ public class PCMSim {
* @return true if the compressor is active
*/
public boolean getCompressorOn() {
return PCMDataJNI.getCompressorOn(m_index);
return CTREPCMDataJNI.getCompressorOn(m_index);
}
/**
@@ -168,7 +133,7 @@ public class PCMSim {
* @param compressorOn the new value
*/
public void setCompressorOn(boolean compressorOn) {
PCMDataJNI.setCompressorOn(m_index, compressorOn);
CTREPCMDataJNI.setCompressorOn(m_index, compressorOn);
}
/**
@@ -181,8 +146,8 @@ public class PCMSim {
*/
public CallbackStore registerClosedLoopEnabledCallback(
NotifyCallback callback, boolean initialNotify) {
int uid = PCMDataJNI.registerClosedLoopEnabledCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, PCMDataJNI::cancelClosedLoopEnabledCallback);
int uid = CTREPCMDataJNI.registerClosedLoopEnabledCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelClosedLoopEnabledCallback);
}
/**
@@ -191,7 +156,7 @@ public class PCMSim {
* @return true if active
*/
public boolean getClosedLoopEnabled() {
return PCMDataJNI.getClosedLoopEnabled(m_index);
return CTREPCMDataJNI.getClosedLoopEnabled(m_index);
}
/**
@@ -200,7 +165,7 @@ public class PCMSim {
* @param closedLoopEnabled whether the control loop is active
*/
public void setClosedLoopEnabled(boolean closedLoopEnabled) {
PCMDataJNI.setClosedLoopEnabled(m_index, closedLoopEnabled);
CTREPCMDataJNI.setClosedLoopEnabled(m_index, closedLoopEnabled);
}
/**
@@ -213,8 +178,8 @@ public class PCMSim {
*/
public CallbackStore registerPressureSwitchCallback(
NotifyCallback callback, boolean initialNotify) {
int uid = PCMDataJNI.registerPressureSwitchCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, PCMDataJNI::cancelPressureSwitchCallback);
int uid = CTREPCMDataJNI.registerPressureSwitchCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelPressureSwitchCallback);
}
/**
@@ -223,7 +188,7 @@ public class PCMSim {
* @return the pressure switch value
*/
public boolean getPressureSwitch() {
return PCMDataJNI.getPressureSwitch(m_index);
return CTREPCMDataJNI.getPressureSwitch(m_index);
}
/**
@@ -232,7 +197,7 @@ public class PCMSim {
* @param pressureSwitch the new value
*/
public void setPressureSwitch(boolean pressureSwitch) {
PCMDataJNI.setPressureSwitch(m_index, pressureSwitch);
CTREPCMDataJNI.setPressureSwitch(m_index, pressureSwitch);
}
/**
@@ -245,8 +210,8 @@ public class PCMSim {
*/
public CallbackStore registerCompressorCurrentCallback(
NotifyCallback callback, boolean initialNotify) {
int uid = PCMDataJNI.registerCompressorCurrentCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, PCMDataJNI::cancelCompressorCurrentCallback);
int uid = CTREPCMDataJNI.registerCompressorCurrentCallback(m_index, callback, initialNotify);
return new CallbackStore(m_index, uid, CTREPCMDataJNI::cancelCompressorCurrentCallback);
}
/**
@@ -255,7 +220,7 @@ public class PCMSim {
* @return the current of the compressor connected to this module
*/
public double getCompressorCurrent() {
return PCMDataJNI.getCompressorCurrent(m_index);
return CTREPCMDataJNI.getCompressorCurrent(m_index);
}
/**
@@ -264,11 +229,11 @@ public class PCMSim {
* @param compressorCurrent the new compressor current
*/
public void setCompressorCurrent(double compressorCurrent) {
PCMDataJNI.setCompressorCurrent(m_index, compressorCurrent);
CTREPCMDataJNI.setCompressorCurrent(m_index, compressorCurrent);
}
/** Reset all simulation data for this object. */
public void resetData() {
PCMDataJNI.resetData(m_index);
CTREPCMDataJNI.resetData(m_index);
}
}

View File

@@ -1,182 +0,0 @@
// 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.DoubleSolenoid;
/** Class to control a simulated {@link edu.wpi.first.wpilibj.DoubleSolenoid}. */
public class DoubleSolenoidSim {
private final PCMSim m_pcm;
private final int m_fwd;
private final int m_rev;
/**
* Constructs for a double solenoid on the default PCM.
*
* @param fwd the forward solenoid channel.
* @param rev the reverse solenoid channel.
* @see PCMSim#PCMSim()
*/
public DoubleSolenoidSim(int fwd, int rev) {
this.m_pcm = new PCMSim();
this.m_fwd = fwd;
this.m_rev = rev;
}
/**
* Constructs for a double solenoid.
*
* @param fwd the forward solenoid channel.
* @param rev the reverse solenoid channel.
* @see PCMSim#PCMSim(int)
*/
public DoubleSolenoidSim(int module, int fwd, int rev) {
this(new PCMSim(module), fwd, rev);
}
/**
* Constructs for a double solenoid on the given PCM.
*
* @param pcm the PCM the double solenoid is on.
* @param fwd the forward solenoid channel.
* @param rev the reverse solenoid channel.
*/
public DoubleSolenoidSim(PCMSim pcm, int fwd, int rev) {
this.m_pcm = pcm;
this.m_fwd = fwd;
this.m_rev = rev;
}
/**
* Constructs for the given solenoid.
*
* @param solenoid the solenoid to simulate.
*/
public DoubleSolenoidSim(DoubleSolenoid solenoid) {
this(solenoid.getModuleNumber(), solenoid.getFwdChannel(), solenoid.getRevChannel());
}
/**
* Register a callback to be run when the forward solenoid is initialized.
*
* @param callback the callback
* @param initialNotify should the callback be run 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 registerFwdInitializedCallback(
NotifyCallback callback, boolean initialNotify) {
return m_pcm.registerSolenoidInitializedCallback(m_fwd, callback, initialNotify);
}
/**
* Check if the forward solenoid has been initialized.
*
* @return true if initialized
*/
public boolean getFwdInitialized() {
return m_pcm.getSolenoidInitialized(m_fwd);
}
/**
* Define whether the forward solenoid has been initialized.
*
* @param initialized whether the solenoid is intiialized.
*/
public void setFwdInitialized(boolean initialized) {
m_pcm.setSolenoidInitialized(m_fwd, initialized);
}
/**
* Register a callback to be run when the reverse solenoid is initialized.
*
* @param callback the callback
* @param initialNotify should the callback be run 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 registerRevInitializedCallback(
NotifyCallback callback, boolean initialNotify) {
return m_pcm.registerSolenoidInitializedCallback(m_rev, callback, initialNotify);
}
/**
* Check if the reverse solenoid has been initialized.
*
* @return true if initialized
*/
public boolean getRevInitialized() {
return m_pcm.getSolenoidInitialized(m_rev);
}
/**
* Define whether the reverse solenoid has been initialized.
*
* @param initialized whether the solenoid is intiialized.
*/
public void setRevInitialized(boolean initialized) {
m_pcm.setSolenoidInitialized(m_rev, initialized);
}
/**
* Set the value of the double solenoid output.
*
* @param value The value to set (Off, Forward, Reverse)
*/
public void set(final DoubleSolenoid.Value value) {
boolean forward = false;
boolean reverse = false;
switch (value) {
case kOff:
forward = false;
reverse = false;
break;
case kForward:
forward = true;
reverse = false;
break;
case kReverse:
forward = false;
reverse = true;
break;
default:
throw new AssertionError("Illegal value: " + value);
}
m_pcm.setSolenoidOutput(m_fwd, forward);
m_pcm.setSolenoidOutput(m_rev, reverse);
}
/**
* Check the value of the double solenoid output.
*
* @return the output value of the double solenoid.
*/
public DoubleSolenoid.Value get() {
boolean fwdState = m_pcm.getSolenoidOutput(m_fwd);
boolean revState = m_pcm.getSolenoidOutput(m_rev);
if (!fwdState && !revState) {
return DoubleSolenoid.Value.kOff;
} else if (fwdState && !revState) {
return DoubleSolenoid.Value.kForward;
} else if (!fwdState && revState) {
return DoubleSolenoid.Value.kReverse;
} else {
throw new AssertionError(
"In a double solenoid, both fwd and rev can't be on at the same time.");
}
}
/**
* Get the wrapped {@link PCMSim} object.
*
* @return the wrapped {@link PCMSim} object.
*/
public PCMSim getPCMSim() {
return m_pcm;
}
}

View File

@@ -1,125 +0,0 @@
// 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.Solenoid;
/** Class to control a simulated {@link edu.wpi.first.wpilibj.Solenoid}. */
public class SolenoidSim {
private final PCMSim m_pcm;
private final int m_channel;
/**
* Constructs for a solenoid on the default PCM.
*
* @param channel the solenoid channel.
* @see PCMSim#PCMSim()
*/
public SolenoidSim(int channel) {
this.m_pcm = new PCMSim();
this.m_channel = channel;
}
/**
* Constructs for a solenoid.
*
* @param module the CAN ID of the PCM the solenoid is connected to.
* @param channel the solenoid channel.
* @see PCMSim#PCMSim(int)
*/
public SolenoidSim(int module, int channel) {
this(new PCMSim(module), channel);
}
/**
* Constructs for a solenoid on the given PCM.
*
* @param pcm the PCM the solenoid is connected to.
* @param channel the solenoid channel.
*/
public SolenoidSim(PCMSim pcm, int channel) {
this.m_pcm = pcm;
this.m_channel = channel;
}
/**
* Constructs for the given solenoid.
*
* @param solenoid the solenoid to simulate.
*/
public SolenoidSim(Solenoid solenoid) {
this(solenoid.getModuleNumber(), solenoid.getChannel());
}
/**
* Register a callback to be run when this solenoid is initialized.
*
* @param callback the callback
* @param initialNotify should the callback be run 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) {
return m_pcm.registerSolenoidInitializedCallback(m_channel, callback, initialNotify);
}
/**
* Check if this solenoid has been initialized.
*
* @return true if initialized
*/
public boolean getInitialized() {
return m_pcm.getSolenoidInitialized(m_channel);
}
/**
* Define whether this solenoid has been initialized.
*
* @param initialized whether the solenoid is intiialized.
*/
public void setInitialized(boolean initialized) {
m_pcm.setSolenoidInitialized(m_channel, initialized);
}
/**
* 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_pcm.registerSolenoidOutputCallback(m_channel, callback, initialNotify);
}
/**
* Check the solenoid output.
*
* @return the solenoid output
*/
public boolean getOutput() {
return m_pcm.getSolenoidOutput(m_channel);
}
/**
* Change the solenoid output.
*
* @param output the new solenoid output
*/
public void setOutput(boolean output) {
m_pcm.setSolenoidOutput(m_channel, output);
}
/**
* Get the wrapped {@link PCMSim} object.
*
* @return the wrapped {@link PCMSim} object.
*/
public PCMSim getPCMSim() {
return m_pcm;
}
}

View File

@@ -8,14 +8,17 @@ import static edu.wpi.first.wpilibj.DoubleSolenoid.Value.kForward;
import static edu.wpi.first.wpilibj.DoubleSolenoid.Value.kReverse;
import edu.wpi.first.wpilibj.DoubleSolenoid;
import edu.wpi.first.wpilibj.PneumaticsControlModule;
import edu.wpi.first.wpilibj.examples.hatchbotinlined.Constants.HatchConstants;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
/** A hatch mechanism actuated by a single {@link edu.wpi.first.wpilibj.DoubleSolenoid}. */
public class HatchSubsystem extends SubsystemBase {
private final PneumaticsControlModule m_controlModule =
new PneumaticsControlModule(HatchConstants.kHatchSolenoidModule);
private final DoubleSolenoid m_hatchSolenoid =
new DoubleSolenoid(
HatchConstants.kHatchSolenoidModule,
m_controlModule,
HatchConstants.kHatchSolenoidPorts[0],
HatchConstants.kHatchSolenoidPorts[1]);

View File

@@ -8,14 +8,17 @@ import static edu.wpi.first.wpilibj.DoubleSolenoid.Value.kForward;
import static edu.wpi.first.wpilibj.DoubleSolenoid.Value.kReverse;
import edu.wpi.first.wpilibj.DoubleSolenoid;
import edu.wpi.first.wpilibj.PneumaticsControlModule;
import edu.wpi.first.wpilibj.examples.hatchbottraditional.Constants.HatchConstants;
import edu.wpi.first.wpilibj2.command.SubsystemBase;
/** A hatch mechanism actuated by a single {@link DoubleSolenoid}. */
public class HatchSubsystem extends SubsystemBase {
private final PneumaticsControlModule m_controlModule =
new PneumaticsControlModule(HatchConstants.kHatchSolenoidModule);
private final DoubleSolenoid m_hatchSolenoid =
new DoubleSolenoid(
HatchConstants.kHatchSolenoidModule,
m_controlModule,
HatchConstants.kHatchSolenoidPorts[0],
HatchConstants.kHatchSolenoidPorts[1]);

View File

@@ -4,6 +4,7 @@
package edu.wpi.first.wpilibj.examples.pacgoat;
import edu.wpi.first.wpilibj.PneumaticsControlModule;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.command.Scheduler;
@@ -29,6 +30,8 @@ public class Robot extends TimedRobot {
Command m_autonomousCommand;
public static OI oi;
public static PneumaticsControlModule pneumaticsModule = new PneumaticsControlModule(1);
// Initialize the subsystems
public static DriveTrain drivetrain = new DriveTrain();
public static Collector collector = new Collector();

View File

@@ -7,6 +7,7 @@ package edu.wpi.first.wpilibj.examples.pacgoat.subsystems;
import edu.wpi.first.wpilibj.DigitalInput;
import edu.wpi.first.wpilibj.Solenoid;
import edu.wpi.first.wpilibj.command.Subsystem;
import edu.wpi.first.wpilibj.examples.pacgoat.Robot;
import edu.wpi.first.wpilibj.motorcontrol.MotorController;
import edu.wpi.first.wpilibj.motorcontrol.Victor;
@@ -24,7 +25,7 @@ public class Collector extends Subsystem {
private final MotorController m_rollerMotor = new Victor(6);
private final DigitalInput m_ballDetector = new DigitalInput(10);
private final DigitalInput m_openDetector = new DigitalInput(6);
private final Solenoid m_piston = new Solenoid(1, 1);
private final Solenoid m_piston = new Solenoid(Robot.pneumaticsModule, 1);
/** Create a new collector subsystem. */
public Collector() {

Some files were not shown because too many files have changed in this diff Show More