Support for the CAN power distribution panel

Change-Id: If4f8f7f050bf1095221cf16f030a6a8a67532656
This commit is contained in:
thomasclark
2014-05-30 14:04:05 -04:00
parent bf7ef4376c
commit 187aa7a138
13 changed files with 306 additions and 1 deletions

View File

@@ -19,6 +19,7 @@
#include "Notifier.hpp"
#include "Interrupts.hpp"
#include "Errors.hpp"
#include "PDP.hpp"
#include "Utilities.hpp"
#include "Semaphore.hpp"

19
hal/include/HAL/PDP.hpp Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#ifndef __HAL_PDP_H__
#define __HAL_PDP_H__
#ifdef __vxworks
#include <vxWorks.h>
#else
#include <stdint.h>
#endif
extern "C"
{
double getPDPTemperature(int32_t *status);
double getPDPVoltage(int32_t *status);
double getPDPChannelCurrent(uint8_t channel, int32_t *status);
}
#endif /* __HAL_PDP_H__ */

28
hal/lib/Athena/PDP.cpp Normal file
View File

@@ -0,0 +1,28 @@
#include "HAL/PDP.hpp"
#include "ctre/PDP.h"
static PDP pdp;
double getPDPTemperature(int32_t *status) {
double temperature;
*status = pdp.GetTemperature(temperature);
return temperature;
}
double getPDPVoltage(int32_t *status) {
double voltage;
*status = pdp.GetVoltage(voltage);
return voltage;
}
double getPDPChannelCurrent(uint8_t channel, int32_t *status) {
double current;
*status = pdp.GetChannelCurrent(channel, current);
return current;
}

View File

@@ -0,0 +1,27 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#pragma once
#ifndef __WPILIB_POWER_DISTRIBUTION_PANEL_H__
#define __WPILIB_POWER_DISTRIBUTION_PANEL_H__
#include "SensorBase.h"
/**
* Class for getting voltage, current, and temperature from the CAN PDP
* @author Thomas Clark
*/
class PowerDistributionPanel : public SensorBase {
public:
PowerDistributionPanel();
double GetVoltage();
double GetTemperature();
double GetCurrent(uint8_t channel);
};
#endif /* __WPILIB_POWER_DISTRIBUTION_PANEL_H__ */

View File

@@ -42,6 +42,7 @@ public:
static bool CheckPWMChannel(uint32_t channel);
static bool CheckAnalogChannel(uint32_t channel);
static bool CheckSolenoidChannel(uint32_t channel);
static bool CheckPDPChannel(uint32_t channel);
static const uint32_t kDigitalChannels = 14;
static const uint32_t kAnalogChannels = 8;
@@ -51,6 +52,7 @@ public:
static const uint32_t kSolenoidModules = 2;
static const uint32_t kPwmChannels = 10;
static const uint32_t kRelayChannels = 8;
static const uint32_t kPDPChannels = 16;
static const uint32_t kChassisSlots = 8;
protected:
void AddToSingletonList();

View File

@@ -0,0 +1,71 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#include "PowerDistributionPanel.h"
#include "WPIErrors.h"
#include "HAL/PDP.hpp"
/**
* Initialize the PDP.
*/
PowerDistributionPanel::PowerDistributionPanel() {
}
/**
* @return The voltage of the PDP
*/
double
PowerDistributionPanel::GetVoltage() {
int32_t status = 0;
double voltage = getPDPVoltage(&status);
if(status) {
wpi_setWPIErrorWithContext(Timeout, "");
}
return voltage;
}
/**
* @return The temperature of the PDP in degrees Celsius
*/
double
PowerDistributionPanel::GetTemperature() {
int32_t status = 0;
double temperature = getPDPTemperature(&status);
if(status) {
wpi_setWPIErrorWithContext(Timeout, "");
}
return temperature;
}
/**
* @return The current of one of the PDP channels (channels 1-16) in Amperes
*/
double
PowerDistributionPanel::GetCurrent(uint8_t channel) {
int32_t status = 0;
if(!CheckPDPChannel(channel))
{
char buf[64];
snprintf(buf, 64, "PDP Channel %d", channel);
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf);
}
double current = getPDPChannelCurrent(channel, &status);
if(status) {
wpi_setWPIErrorWithContext(Timeout, "");
}
return current;
}

View File

@@ -17,6 +17,7 @@ const uint32_t SensorBase::kSolenoidChannels;
const uint32_t SensorBase::kSolenoidModules;
const uint32_t SensorBase::kPwmChannels;
const uint32_t SensorBase::kRelayChannels;
const uint32_t SensorBase::kPDPChannels;
const uint32_t SensorBase::kChassisSlots;
SensorBase *SensorBase::m_singletonList = NULL;
@@ -189,3 +190,15 @@ bool SensorBase::CheckSolenoidChannel(uint32_t channel)
return false;
}
/**
* Verify that the power distribution channel number is within limits.
*
* @return Solenoid channel is valid
*/
bool SensorBase::CheckPDPChannel(uint32_t channel)
{
if (channel > 0 && channel <= kPDPChannels)
return true;
return false;
}

View File

@@ -0,0 +1,75 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2014. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.hal.PDPJNI;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.can.CANTimeoutException;
/**
* Class for getting voltage, current, and temperature from the CAN PDP
* @author Thomas Clark
*/
public class PowerDistributionPanel extends SensorBase {
public PowerDistributionPanel() {
}
/**
* @return The voltage of the PDP
*/
public double getVoltage() throws CANTimeoutException {
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
double voltage = PDPJNI.getPDPVoltage(status.asIntBuffer());
if(status.asIntBuffer().get(0) != 0) {
throw new CANTimeoutException();
}
return voltage;
}
/**
* @return The temperature of the PDP in degrees Celsius
*/
public double getTemperature() throws CANTimeoutException {
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
double temperature = PDPJNI.getPDPTemperature(status.asIntBuffer());
if(status.asIntBuffer().get(0) != 0) {
throw new CANTimeoutException();
}
return temperature;
}
/**
* @return The current of one of the PDP channels (channels 1-16) in Amperes
*/
public double getCurrent(int channel) throws CANTimeoutException {
ByteBuffer status = ByteBuffer.allocateDirect(4);
status.order(ByteOrder.LITTLE_ENDIAN);
double current = PDPJNI.getPDPChannelCurrent((byte)channel, status.asIntBuffer());
checkPDPChannel(channel);
if(status.asIntBuffer().get(0) != 0) {
throw new CANTimeoutException();
}
return current;
}
}

View File

@@ -58,6 +58,10 @@ public abstract class SensorBase { // TODO: Refactor
* Number of relay channels per sidecar
*/
public static final int kRelayChannels = 4;
/**
* Number of power distribution channels
*/
public static final int kPDPChannels = 16;
private static int m_defaultAnalogModule = 1;
private static int m_defaultDigitalModule = 1;
@@ -226,6 +230,18 @@ public abstract class SensorBase { // TODO: Refactor
}
}
/**
* Verify that the power distribution channel number is within limits.
* Channel numbers are 1-based.
*
* @param channel The channel number to check.
*/
protected static void checkPDPChannel(final int channel) {
if (channel <= 0 || channel > kPDPChannels) {
System.err.println("Requested solenoid channel number is out of range.");
}
}
/**
* Get the number of the default analog module.
*

View File

@@ -0,0 +1,10 @@
package edu.wpi.first.wpilibj.hal;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
public class PDPJNI extends JNIWrapper {
public static native double getPDPTemperature(IntBuffer status);
public static native double getPDPVoltage(IntBuffer status);
public static native double getPDPChannelCurrent(byte channel, IntBuffer status);
}

View File

@@ -0,0 +1,42 @@
#include "edu_wpi_first_wpilibj_hal_PDPJNI.h"
#include "HAL/PDP.hpp"
/*
* Class: edu_wpi_first_wpilibj_hal_PDPJNI
* Method: getPDPTemperature
* Signature: (Ljava/nio/IntBuffer;)D
*/
JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_getPDPTemperature
(JNIEnv *env, jclass, jobject status)
{
jint *status_ptr = (jint *)env->GetDirectBufferAddress(status);
return getPDPTemperature(status_ptr);
}
/*
* Class: edu_wpi_first_wpilibj_hal_PDPJNI
* Method: getPDPVoltage
* Signature: (Ljava/nio/IntBuffer;)D
*/
JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_getPDPVoltage
(JNIEnv *env, jclass, jobject status)
{
jint *status_ptr = (jint *)env->GetDirectBufferAddress(status);
return getPDPVoltage(status_ptr);
}
/*
* Class: edu_wpi_first_wpilibj_hal_PDPJNI
* Method: getPDPChannelCurrent
* Signature: (BLjava/nio/IntBuffer;)D
*/
JNIEXPORT jdouble JNICALL Java_edu_wpi_first_wpilibj_hal_PDPJNI_getPDPChannelCurrent
(JNIEnv *env, jclass, jbyte channel, jobject status)
{
jint *status_ptr = (jint *)env->GetDirectBufferAddress(status);
return getPDPChannelCurrent(channel, status_ptr);
}

View File

@@ -4,7 +4,7 @@
#include "edu_wpi_first_wpilibj_hal_SolenoidJNI.h"
TLogLevel solenoidJNILogLevel = logWARNING;
TLogLevel solenoidJNILogLevel = logERROR;
#define SOLENOIDJNI_LOG(level) \
if (level > solenoidJNILogLevel) ; \

View File

@@ -124,6 +124,7 @@ this default location, specify a value for the 'embeddedJDKHome' property at the
<javahClassName>edu.wpi.first.wpilibj.hal.SPIJNI</javahClassName>
<javahClassName>edu.wpi.first.wpilibj.hal.SolenoidJNI</javahClassName>
<javahClassName>edu.wpi.first.wpilibj.hal.CompressorJNI</javahClassName>
<javahClassName>edu.wpi.first.wpilibj.hal.PDPJNI</javahClassName>
</javahClassNames>
<!-- enable additional javah interface in dependencies list -->
<!-- javahSearchJNIFromDependencies>true</javahSearchJNIFromDependencies -->