Add FPGA Duty Cycle support (#1987)

This commit is contained in:
Thad House
2019-11-01 23:41:30 -07:00
committed by Peter Johnson
parent 509819d83f
commit 1d695a1660
42 changed files with 1744 additions and 72 deletions

View File

@@ -7,9 +7,6 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.hal.AnalogJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -42,8 +39,8 @@ public class AnalogTrigger implements Sendable, AutoCloseable {
* Where the analog trigger is attached.
*/
protected int m_port;
protected int m_index;
protected AnalogInput m_analogInput;
protected DutyCycle m_dutyCycle;
protected boolean m_ownsAnalog;
/**
@@ -65,15 +62,29 @@ public class AnalogTrigger implements Sendable, AutoCloseable {
*/
public AnalogTrigger(AnalogInput channel) {
m_analogInput = channel;
ByteBuffer index = ByteBuffer.allocateDirect(4);
index.order(ByteOrder.LITTLE_ENDIAN);
m_port =
AnalogJNI.initializeAnalogTrigger(channel.m_port, index.asIntBuffer());
m_index = index.asIntBuffer().get(0);
m_port = AnalogJNI.initializeAnalogTrigger(channel.m_port);
HAL.report(tResourceType.kResourceType_AnalogTrigger, m_index + 1);
SendableRegistry.addLW(this, "AnalogTrigger", channel.getChannel());
int index = getIndex();
HAL.report(tResourceType.kResourceType_AnalogTrigger, index + 1);
SendableRegistry.addLW(this, "AnalogTrigger", index);
}
/**
* Construct an analog trigger given a duty cycle input.
*
* @param input the DutyCycle to use for the analog trigger
*/
public AnalogTrigger(DutyCycle input) {
m_dutyCycle = input;
m_port = AnalogJNI.initializeAnalogTriggerDutyCycle(input.m_handle);
int index = getIndex();
HAL.report(tResourceType.kResourceType_AnalogTrigger, index + 1);
SendableRegistry.addLW(this, "AnalogTrigger", index);
}
@Override
@@ -100,6 +111,20 @@ public class AnalogTrigger implements Sendable, AutoCloseable {
AnalogJNI.setAnalogTriggerLimitsRaw(m_port, lower, upper);
}
/**
* Set the upper and lower limits of the analog trigger. The limits are given as floating point
* values between 0 and 1.
*
* @param lower the lower duty cycle limit
* @param upper the upper duty cycle limit
*/
public void setLimitsDutyCycle(double lower, double upper) {
if (lower > upper) {
throw new BoundaryException("Lower bound is greater than upper bound");
}
AnalogJNI.setAnalogTriggerLimitsDutyCycle(m_port, lower, upper);
}
/**
* Set the upper and lower limits of the analog trigger. The limits are given as floating point
* voltage values.
@@ -141,8 +166,8 @@ public class AnalogTrigger implements Sendable, AutoCloseable {
*
* @return The index of the analog trigger.
*/
public int getIndex() {
return m_index;
public final int getIndex() {
return AnalogJNI.getAnalogTriggerFPGAIndex(m_port);
}
/**

View File

@@ -98,7 +98,7 @@ public class AnalogTriggerOutput extends DigitalSource implements Sendable {
@Override
public int getChannel() {
return m_trigger.m_index;
return m_trigger.getIndex();
}
@Override

View File

@@ -0,0 +1,117 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019 FIRST. 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 edu.wpi.first.hal.DutyCycleJNI;
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 to read a duty cycle PWM input.
*
* <p>PWM input signals are specified with a frequency and a ratio of high to low
* in that frequency. There are 8 of these in the roboRIO, and they can be
* attached to any {@link DigitalSource}.
*
* <p>These can be combined as the input of an AnalogTrigger to a Counter in order
* to implement rollover checking.
*
*/
public class DutyCycle implements Sendable, AutoCloseable {
// Explicitly package private
final int m_handle;
/**
* Constructs a DutyCycle input from a DigitalSource input.
*
* <p>This class does not own the inputted source.
*
* @param digitalSource The DigitalSource to use.
*/
public DutyCycle(DigitalSource digitalSource) {
m_handle = DutyCycleJNI.initialize(digitalSource.getPortHandleForRouting(),
digitalSource.getAnalogTriggerTypeForRouting());
int index = getFPGAIndex();
HAL.report(tResourceType.kResourceType_DutyCycle, index + 1);
SendableRegistry.addLW(this, "Duty Cycle", index);
}
/**
* Close the DutyCycle and free all resources.
*/
@Override
public void close() {
DutyCycleJNI.free(m_handle);
}
/**
* Get the frequency of the duty cycle signal.
*
* @return frequency in Hertz
*/
public int getFrequency() {
return DutyCycleJNI.getFrequency(m_handle);
}
/**
* Get the output ratio of the duty cycle signal.
*
* <p>0 means always low, 1 means always high.
*
* @return output ratio between 0 and 1
*/
public double getOutput() {
return DutyCycleJNI.getOutput(m_handle);
}
/**
* Get the raw output ratio of the duty cycle signal.
*
* <p>0 means always low, an output equal to getOutputScaleFactor() means always
* high.
*
* @return output ratio in raw units
*/
public int getOutputRaw() {
return DutyCycleJNI.getOutputRaw(m_handle);
}
/**
* Get the scale factor of the output.
*
* <p>An output equal to this value is always high, and then linearly scales down
* to 0. Divide the result of getOutputRaw by this in order to get the
* percentage between 0 and 1.
*
* @return the output scale factor
*/
public int getOutputScaleFactor() {
return DutyCycleJNI.getOutputScaleFactor(m_handle);
}
/**
* Get the FPGA index for the DutyCycle.
*
* @return the FPGA index
*/
@SuppressWarnings("AbbreviationAsWordInName")
public final int getFPGAIndex() {
return DutyCycleJNI.getFPGAIndex(m_handle);
}
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("Duty Cycle");
builder.addDoubleProperty("Frequency", this::getFrequency, null);
builder.addDoubleProperty("Output", this::getOutput, null);
}
}