[wpilib] Add new counter implementations (#2447)

This commit is contained in:
Thad House
2021-11-23 20:33:36 -08:00
committed by GitHub
parent b156db400d
commit 3aa54fa027
15 changed files with 1052 additions and 0 deletions

View File

@@ -48,6 +48,7 @@ public class DutyCycle implements Sendable, AutoCloseable {
/** Close the DutyCycle and free all resources. */
@Override
public void close() {
SendableRegistry.remove(this);
DutyCycleJNI.free(m_handle);
}

View File

@@ -0,0 +1,23 @@
// 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.counter;
public enum EdgeConfiguration {
kNone(false, false),
kRisingEdge(true, false),
kFallingEdge(false, true),
kBoth(true, true);
@SuppressWarnings("MemberName")
public final boolean rising;
@SuppressWarnings("MemberName")
public final boolean falling;
EdgeConfiguration(boolean rising, boolean falling) {
this.rising = rising;
this.falling = falling;
}
}

View File

@@ -0,0 +1,105 @@
// 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.counter;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.CounterJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.DigitalSource;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** Counter using external direction. */
public class ExternalDirectionCounter implements Sendable, AutoCloseable {
private final DigitalSource m_countSource;
private final DigitalSource m_directionSource;
private final int m_handle;
/**
* Constructs a new ExternalDirectionCounter.
*
* @param countSource The source for counting.
* @param directionSource The source for selecting count direction.
*/
public ExternalDirectionCounter(DigitalSource countSource, DigitalSource directionSource) {
m_countSource = requireNonNullParam(countSource, "countSource", "ExternalDirectionCounter");
m_directionSource =
requireNonNullParam(directionSource, "directionSource", "ExternalDirectionCounter");
ByteBuffer index = ByteBuffer.allocateDirect(4);
// set the byte order
index.order(ByteOrder.LITTLE_ENDIAN);
m_handle = CounterJNI.initializeCounter(CounterJNI.EXTERNAL_DIRECTION, index.asIntBuffer());
CounterJNI.setCounterUpSource(
m_handle,
countSource.getPortHandleForRouting(),
countSource.getAnalogTriggerTypeForRouting());
CounterJNI.setCounterUpSourceEdge(m_handle, true, false);
CounterJNI.setCounterDownSource(
m_handle,
directionSource.getPortHandleForRouting(),
directionSource.getAnalogTriggerTypeForRouting());
CounterJNI.setCounterDownSourceEdge(m_handle, false, true);
CounterJNI.resetCounter(m_handle);
int intIndex = index.getInt();
HAL.report(tResourceType.kResourceType_Counter, intIndex + 1);
SendableRegistry.addLW(this, "External Direction Counter", intIndex);
}
/**
* Gets the current count.
*
* @return The current count.
*/
public int getCount() {
return CounterJNI.getCounter(m_handle);
}
/**
* Sets to revert the counter direction.
*
* @param reverseDirection True to reverse counting direction.
*/
public void setReverseDirection(boolean reverseDirection) {
CounterJNI.setCounterReverseDirection(m_handle, reverseDirection);
}
/** Resets the current count. */
public void reset() {
CounterJNI.resetCounter(m_handle);
}
/**
* Sets the edge configuration for counting.
*
* @param configuration The counting edge configuration.
*/
public void setEdgeConfiguration(EdgeConfiguration configuration) {
CounterJNI.setCounterUpSourceEdge(m_handle, configuration.rising, configuration.falling);
}
@Override
public void close() throws Exception {
SendableRegistry.remove(this);
CounterJNI.freeCounter(m_handle);
CounterJNI.suppressUnused(m_countSource);
CounterJNI.suppressUnused(m_directionSource);
}
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("External Direction Counter");
builder.addDoubleProperty("Count", this::getCount, null);
}
}

View File

@@ -0,0 +1,163 @@
// 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.counter;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.CounterJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.DigitalSource;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** Tachometer. */
public class Tachometer implements Sendable, AutoCloseable {
private final DigitalSource m_source;
private final int m_handle;
private int m_edgesPerRevolution = 1;
/**
* Constructs a new tachometer.
*
* @param source The source.
*/
public Tachometer(DigitalSource source) {
m_source = requireNonNullParam(source, "source", "Tachometer");
ByteBuffer index = ByteBuffer.allocateDirect(4);
// set the byte order
index.order(ByteOrder.LITTLE_ENDIAN);
m_handle = CounterJNI.initializeCounter(CounterJNI.TWO_PULSE, index.asIntBuffer());
CounterJNI.setCounterUpSource(
m_handle, source.getPortHandleForRouting(), source.getAnalogTriggerTypeForRouting());
CounterJNI.setCounterUpSourceEdge(m_handle, true, false);
int intIndex = index.getInt();
HAL.report(tResourceType.kResourceType_Counter, intIndex + 1);
SendableRegistry.addLW(this, "Tachometer", intIndex);
}
@Override
public void close() throws Exception {
SendableRegistry.remove(this);
CounterJNI.freeCounter(m_handle);
CounterJNI.suppressUnused(m_source);
}
/**
* Gets the tachometer period.
*
* @return Current period (in seconds).
*/
public double getPeriod() {
return CounterJNI.getCounterPeriod(m_handle);
}
/**
* Gets the tachometer frequency.
*
* @return Current frequency (in hertz).
*/
public double getFrequency() {
double period = getPeriod();
if (period == 0) {
return 0;
}
return period;
}
/**
* Gets the number of edges per revolution.
*
* @return Edges per revolution.
*/
public int getEdgesPerRevolution() {
return m_edgesPerRevolution;
}
/**
* Sets the number of edges per revolution.
*
* @param edgesPerRevolution Edges per revolution.
*/
public void setEdgesPerRevolution(int edgesPerRevolution) {
m_edgesPerRevolution = edgesPerRevolution;
}
/**
* Gets the current tachometer revolution per minute.
*
* <p>setEdgesPerRevolution must be set with a non 0 value for this to return valid values.
*
* @return Current RPM.
*/
public double getRevolutionsPerMinute() {
double period = getPeriod();
if (period == 0) {
return 0;
}
int edgesPerRevolution = getEdgesPerRevolution();
if (edgesPerRevolution == 0) {
return 0;
}
return ((1.0 / edgesPerRevolution) / period) * 60;
}
/**
* Gets if the tachometer is stopped.
*
* @return True if the tachometer is stopped.
*/
public boolean getStopped() {
return CounterJNI.getCounterStopped(m_handle);
}
/**
* Gets the number of samples to average.
*
* @return Samples to average.
*/
public int getSamplesToAverage() {
return CounterJNI.getCounterSamplesToAverage(m_handle);
}
/**
* Sets the number of samples to average.
*
* @param samplesToAverage Samples to average.
*/
public void setSamplesToAverage(int samplesToAverage) {
CounterJNI.setCounterSamplesToAverage(m_handle, samplesToAverage);
}
/**
* Sets the maximum period before the tachometer is considered stopped.
*
* @param maxPeriod The max period (in seconds).
*/
public void setMaxPeriod(double maxPeriod) {
CounterJNI.setCounterMaxPeriod(m_handle, maxPeriod);
}
/**
* Sets if to update when empty.
*
* @param updateWhenEmpty Update when empty if true.
*/
public void setUpdateWhenEmpty(boolean updateWhenEmpty) {
CounterJNI.setCounterUpdateWhenEmpty(m_handle, updateWhenEmpty);
}
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("Tachometer");
builder.addDoubleProperty("RPM", this::getRevolutionsPerMinute, null);
}
}

View File

@@ -0,0 +1,113 @@
// 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.counter;
import edu.wpi.first.hal.CounterJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.DigitalSource;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** Up Down Counter. */
public class UpDownCounter implements Sendable, AutoCloseable {
private DigitalSource m_upSource;
private DigitalSource m_downSource;
private final int m_handle;
/**
* Constructs a new UpDown Counter.
*
* @param upSource The up count source (can be null).
* @param downSource The down count source (can be null).
*/
public UpDownCounter(DigitalSource upSource, DigitalSource downSource) {
ByteBuffer index = ByteBuffer.allocateDirect(4);
// set the byte order
index.order(ByteOrder.LITTLE_ENDIAN);
m_handle = CounterJNI.initializeCounter(CounterJNI.TWO_PULSE, index.asIntBuffer());
if (upSource != null) {
m_upSource = upSource;
CounterJNI.setCounterUpSource(
m_handle, upSource.getPortHandleForRouting(), upSource.getAnalogTriggerTypeForRouting());
CounterJNI.setCounterUpSourceEdge(m_handle, true, false);
}
if (downSource != null) {
m_downSource = downSource;
CounterJNI.setCounterDownSource(
m_handle,
downSource.getPortHandleForRouting(),
downSource.getAnalogTriggerTypeForRouting());
CounterJNI.setCounterDownSourceEdge(m_handle, true, false);
}
reset();
int intIndex = index.getInt();
HAL.report(tResourceType.kResourceType_Counter, intIndex + 1);
SendableRegistry.addLW(this, "UpDown Counter", intIndex);
}
@Override
public void close() throws Exception {
SendableRegistry.remove(this);
CounterJNI.freeCounter(m_handle);
CounterJNI.suppressUnused(m_upSource);
CounterJNI.suppressUnused(m_downSource);
}
/**
* Sets the configuration for the up source.
*
* @param configuration The up source configuration.
*/
public void setUpEdgeConfiguration(EdgeConfiguration configuration) {
CounterJNI.setCounterUpSourceEdge(m_handle, configuration.rising, configuration.falling);
}
/**
* Sets the configuration for the down source.
*
* @param configuration The down source configuration.
*/
public void setDownEdgeConfiguration(EdgeConfiguration configuration) {
CounterJNI.setCounterDownSourceEdge(m_handle, configuration.rising, configuration.falling);
}
/** Resets the current count. */
public void reset() {
CounterJNI.resetCounter(m_handle);
}
/**
* Sets to revert the counter direction.
*
* @param reverseDirection True to reverse counting direction.
*/
public void setReverseDirection(boolean reverseDirection) {
CounterJNI.setCounterReverseDirection(m_handle, reverseDirection);
}
/**
* Gets the current count.
*
* @return The current count.
*/
public int getCount() {
return CounterJNI.getCounter(m_handle);
}
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("UpDown Counter");
builder.addDoubleProperty("Count", this::getCount, null);
}
}