[hal] Add systemcore duty cycle (#7682)

This commit is contained in:
Thad House
2025-01-15 11:57:31 -08:00
committed by GitHub
parent 24d6e87447
commit 58cb395d76
17 changed files with 138 additions and 233 deletions

View File

@@ -13,13 +13,11 @@ public class DutyCycleJNI extends JNIWrapper {
/**
* Initialize a DutyCycle input.
*
* @param digitalSourceHandle the digital source to use (either a Digital Handle or a
* AnalogTrigger Handle)
* @param analogTriggerType the analog trigger type of the source if it is an analog trigger
* @param halPortHandle the port handle to create from
* @return the created duty cycle handle
* @see "HAL_InitializeDutyCycle"
*/
public static native int initialize(int digitalSourceHandle, int analogTriggerType);
public static native int initialize(int halPortHandle);
/**
* Free a DutyCycle.

View File

@@ -4,6 +4,8 @@
#include <jni.h>
#include <wpi/jni_util.h>
#include "HALUtil.h"
#include "edu_wpi_first_hal_DutyCycleJNI.h"
#include "hal/DutyCycle.h"
@@ -14,16 +16,16 @@ extern "C" {
/*
* Class: edu_wpi_first_hal_DutyCycleJNI
* Method: initialize
* Signature: (II)I
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_DutyCycleJNI_initialize
(JNIEnv* env, jclass, jint digitalSourceHandle, jint analogTriggerType)
(JNIEnv* env, jclass, jint portHandle)
{
int32_t status = 0;
auto handle = HAL_InitializeDutyCycle(
static_cast<HAL_Handle>(digitalSourceHandle),
static_cast<HAL_AnalogTriggerType>(analogTriggerType), &status);
auto stack = wpi::java::GetJavaStackTrace(env, "edu.wpi.first");
auto handle = HAL_InitializeDutyCycle(static_cast<HAL_Handle>(portHandle),
stack.c_str(), &status);
CheckStatus(env, status);
return handle;
}

View File

@@ -20,16 +20,14 @@ extern "C" {
/**
* Initialize a DutyCycle input.
*
* @param[in] digitalSourceHandle the digital source to use (either a
* HAL_DigitalHandle or a
* HAL_AnalogTriggerHandle)
* @param[in] triggerType the analog trigger type of the source if it is
* an analog trigger
* @param[in] portHandle the port handle to create from
* @param[in] allocationLocation the location where the allocation is occurring
* (can be null)
* @param[out] status Error status variable. 0 on success.
* @return the created duty cycle handle
*/
HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType triggerType,
HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_PortHandle portHandle,
const char* allocationLocation,
int32_t* status);
/**

View File

@@ -33,8 +33,8 @@ void InitializeDutyCycle() {
} // namespace hal::init
extern "C" {
HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType triggerType,
HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_PortHandle portHandle,
const char* allocationLocation,
int32_t* status) {
hal::init::CheckInit();
@@ -51,7 +51,7 @@ HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
}
int16_t index = getHandleIndex(handle);
SimDutyCycleData[index].digitalChannel = getHandleIndex(digitalSourceHandle);
SimDutyCycleData[index].digitalChannel = getPortHandleChannel(portHandle);
SimDutyCycleData[index].initialized = true;
SimDutyCycleData[index].simDevice = 0;
dutyCycle->index = index;

View File

@@ -4,11 +4,16 @@
#include "hal/DutyCycle.h"
#include <cstdio>
#include <memory>
#include <thread>
#include "HALInitializer.h"
#include "HALInternal.h"
#include "PortsInternal.h"
#include "SmartIo.h"
#include "hal/Errors.h"
#include "hal/cpp/fpga_clock.h"
#include "hal/handles/HandlesInternal.h"
#include "hal/handles/LimitedHandleResource.h"
@@ -19,15 +24,67 @@ void InitializeDutyCycle() {}
} // namespace hal::init
extern "C" {
HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType triggerType,
HAL_DutyCycleHandle HAL_InitializeDutyCycle(HAL_PortHandle portHandle,
const char* allocationLocation,
int32_t* status) {
hal::init::CheckInit();
*status = HAL_HANDLE_ERROR;
return HAL_kInvalidHandle;
int16_t channel = getPortHandleChannel(portHandle);
if (channel == InvalidHandleIndex || channel >= kNumSmartIo) {
*status = RESOURCE_OUT_OF_RANGE;
hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for DutyCycle", 0,
kNumSmartIo, channel);
return HAL_kInvalidHandle;
}
HAL_DigitalHandle handle;
auto port = smartIoHandles->Allocate(channel, HAL_HandleEnum::DutyCycle,
&handle, status);
if (*status != 0) {
if (port) {
hal::SetLastErrorPreviouslyAllocated(status, "SmartIo", channel,
port->previousAllocation);
} else {
hal::SetLastErrorIndexOutOfRange(status, "Invalid Index for DutyCycle", 0,
kNumSmartIo, channel);
}
return HAL_kInvalidHandle; // failed to allocate. Pass error back.
}
port->channel = channel;
*status = port->InitializeMode(SmartIoMode::PwmInput);
if (*status != 0) {
smartIoHandles->Free(handle, HAL_HandleEnum::DutyCycle);
return HAL_kInvalidHandle;
}
port->previousAllocation = allocationLocation ? allocationLocation : "";
return handle;
}
void HAL_FreeDutyCycle(HAL_DutyCycleHandle dutyCycleHandle) {
auto port = smartIoHandles->Get(dutyCycleHandle, HAL_HandleEnum::DutyCycle);
if (port == nullptr) {
return;
}
smartIoHandles->Free(dutyCycleHandle, HAL_HandleEnum::DutyCycle);
// Wait for no other object to hold this handle.
auto start = hal::fpga_clock::now();
while (port.use_count() != 1) {
auto current = hal::fpga_clock::now();
if (start + std::chrono::seconds(1) < current) {
std::puts("DIO handle free timeout");
std::fflush(stdout);
break;
}
std::this_thread::yield();
}
}
void HAL_FreeDutyCycle(HAL_DutyCycleHandle dutyCycleHandle) {}
void HAL_SetDutyCycleSimDevice(HAL_EncoderHandle handle,
HAL_SimDeviceHandle device) {}
@@ -46,8 +103,15 @@ double HAL_GetDutyCycleOutput(HAL_DutyCycleHandle dutyCycleHandle,
int32_t HAL_GetDutyCycleHighTime(HAL_DutyCycleHandle dutyCycleHandle,
int32_t* status) {
*status = HAL_HANDLE_ERROR;
return 0;
auto port = smartIoHandles->Get(dutyCycleHandle, HAL_HandleEnum::DutyCycle);
if (port == nullptr) {
*status = HAL_HANDLE_ERROR;
return false;
}
uint16_t ret = false;
*status = port->GetPwmInputMicroseconds(&ret);
return ret;
}
int32_t HAL_GetDutyCycleOutputScaleFactor(HAL_DutyCycleHandle dutyCycleHandle,

View File

@@ -96,6 +96,17 @@ int32_t SmartIo::GetDigitalInput(bool* value) {
return 0;
}
int32_t SmartIo::GetPwmInputMicroseconds(uint16_t* microseconds) {
if (currentMode != SmartIoMode::PwmInput) {
return INCOMPATIBLE_STATE;
}
int val = getSubscriber.Get();
*microseconds = val;
return 0;
}
int32_t SmartIo::SetPwmOutputPeriod(PwmOutputPeriod period) {
if (currentMode != SmartIoMode::PwmOutput) {
return INCOMPATIBLE_STATE;

View File

@@ -58,6 +58,8 @@ struct SmartIo {
int32_t SetDigitalOutput(bool value);
int32_t GetDigitalInput(bool* value);
int32_t GetPwmInputMicroseconds(uint16_t* microseconds);
int32_t SetPwmOutputPeriod(PwmOutputPeriod period);
int32_t SetPwmMicroseconds(uint16_t microseconds);

View File

@@ -4,50 +4,37 @@
#include "frc/DutyCycle.h"
#include <string>
#include <utility>
#include <hal/DutyCycle.h>
#include <hal/FRCUsageReporting.h>
#include <hal/HALBase.h>
#include <wpi/NullDeleter.h>
#include <wpi/StackTrace.h>
#include <wpi/sendable/SendableBuilder.h>
#include "frc/DigitalSource.h"
#include "frc/Errors.h"
#include "frc/SensorUtil.h"
using namespace frc;
DutyCycle::DutyCycle(DigitalSource* source)
: m_source{source, wpi::NullDeleter<DigitalSource>()} {
if (!m_source) {
throw FRC_MakeError(err::NullParameter, "source");
}
InitDutyCycle();
}
DutyCycle::DutyCycle(DigitalSource& source)
: m_source{&source, wpi::NullDeleter<DigitalSource>()} {
InitDutyCycle();
}
DutyCycle::DutyCycle(std::shared_ptr<DigitalSource> source)
: m_source{std::move(source)} {
if (!m_source) {
throw FRC_MakeError(err::NullParameter, "source");
DutyCycle::DutyCycle(int channel) : m_channel{channel} {
if (!SensorUtil::CheckDigitalChannel(channel)) {
throw FRC_MakeError(err::ChannelIndexOutOfRange, "Channel {}", channel);
}
InitDutyCycle();
}
void DutyCycle::InitDutyCycle() {
int32_t status = 0;
m_handle =
HAL_InitializeDutyCycle(m_source->GetPortHandleForRouting(),
static_cast<HAL_AnalogTriggerType>(
m_source->GetAnalogTriggerTypeForRouting()),
&status);
std::string stackTrace = wpi::GetStackTrace(1);
m_handle = HAL_InitializeDutyCycle(HAL_GetPort(m_channel), stackTrace.c_str(),
&status);
FRC_CheckErrorStatus(status, "Channel {}", GetSourceChannel());
int index = GetFPGAIndex();
HAL_Report(HALUsageReporting::kResourceType_DutyCycle, index + 1);
wpi::SendableRegistry::AddLW(this, "Duty Cycle", index);
HAL_Report(HALUsageReporting::kResourceType_DutyCycle, m_channel + 1);
wpi::SendableRegistry::AddLW(this, "Duty Cycle", m_channel);
}
int DutyCycle::GetFPGAIndex() const {
@@ -86,7 +73,7 @@ unsigned int DutyCycle::GetOutputScaleFactor() const {
}
int DutyCycle::GetSourceChannel() const {
return m_source->GetChannel();
return m_channel;
}
void DutyCycle::InitSendable(wpi::SendableBuilder& builder) {

View File

@@ -18,8 +18,7 @@
using namespace frc;
DutyCycleEncoder::DutyCycleEncoder(int channel)
: m_dutyCycle{std::make_shared<DutyCycle>(
std::make_shared<DigitalInput>(channel))} {
: m_dutyCycle{std::make_shared<DutyCycle>(channel)} {
Init(1.0, 0.0);
}
@@ -38,25 +37,9 @@ DutyCycleEncoder::DutyCycleEncoder(std::shared_ptr<DutyCycle> dutyCycle)
Init(1.0, 0.0);
}
DutyCycleEncoder::DutyCycleEncoder(DigitalSource& digitalSource)
: m_dutyCycle{std::make_shared<DutyCycle>(digitalSource)} {
Init(1.0, 0.0);
}
DutyCycleEncoder::DutyCycleEncoder(DigitalSource* digitalSource)
: m_dutyCycle{std::make_shared<DutyCycle>(digitalSource)} {
Init(1.0, 0.0);
}
DutyCycleEncoder::DutyCycleEncoder(std::shared_ptr<DigitalSource> digitalSource)
: m_dutyCycle{std::make_shared<DutyCycle>(digitalSource)} {
Init(1.0, 0.0);
}
DutyCycleEncoder::DutyCycleEncoder(int channel, double fullRange,
double expectedZero)
: m_dutyCycle{std::make_shared<DutyCycle>(
std::make_shared<DigitalInput>(channel))} {
: m_dutyCycle{std::make_shared<DutyCycle>(channel)} {
Init(fullRange, expectedZero);
}
@@ -78,24 +61,6 @@ DutyCycleEncoder::DutyCycleEncoder(std::shared_ptr<DutyCycle> dutyCycle,
Init(fullRange, expectedZero);
}
DutyCycleEncoder::DutyCycleEncoder(DigitalSource& digitalSource,
double fullRange, double expectedZero)
: m_dutyCycle{std::make_shared<DutyCycle>(digitalSource)} {
Init(fullRange, expectedZero);
}
DutyCycleEncoder::DutyCycleEncoder(DigitalSource* digitalSource,
double fullRange, double expectedZero)
: m_dutyCycle{std::make_shared<DutyCycle>(digitalSource)} {
Init(fullRange, expectedZero);
}
DutyCycleEncoder::DutyCycleEncoder(std::shared_ptr<DigitalSource> digitalSource,
double fullRange, double expectedZero)
: m_dutyCycle{std::make_shared<DutyCycle>(digitalSource)} {
Init(fullRange, expectedZero);
}
void DutyCycleEncoder::Init(double fullRange, double expectedZero) {
m_simDevice = hal::SimDevice{"DutyCycle:DutyCycleEncoder",
m_dutyCycle->GetSourceChannel()};

View File

@@ -36,29 +36,11 @@ class DutyCycle : public wpi::Sendable, public wpi::SendableHelper<DutyCycle> {
public:
/**
* Constructs a DutyCycle input from a DigitalSource input.
* Constructs a DutyCycle input from a smartio channel.
*
* <p> This class does not own the inputted source.
*
* @param source The DigitalSource to use.
* @param source The channel to use.
*/
explicit DutyCycle(DigitalSource& source);
/**
* Constructs a DutyCycle input from a DigitalSource input.
*
* <p> This class does not own the inputted source.
*
* @param source The DigitalSource to use.
*/
explicit DutyCycle(DigitalSource* source);
/**
* Constructs a DutyCycle input from a DigitalSource input.
*
* <p> This class does not own the inputted source.
*
* @param source The DigitalSource to use.
*/
explicit DutyCycle(std::shared_ptr<DigitalSource> source);
explicit DutyCycle(int source);
DutyCycle(DutyCycle&&) = default;
DutyCycle& operator=(DutyCycle&&) = default;
@@ -121,7 +103,7 @@ class DutyCycle : public wpi::Sendable, public wpi::SendableHelper<DutyCycle> {
private:
void InitDutyCycle();
std::shared_ptr<DigitalSource> m_source;
int m_channel;
hal::Handle<HAL_DutyCycleHandle, HAL_FreeDutyCycle> m_handle;
};
} // namespace frc

View File

@@ -61,33 +61,6 @@ class DutyCycleEncoder : public wpi::Sendable,
*/
explicit DutyCycleEncoder(std::shared_ptr<DutyCycle> dutyCycle);
/**
* Construct a new DutyCycleEncoder attached to a DigitalSource object.
*
* <p>This has a fullRange of 1 and an expectedZero of 0.
*
* @param digitalSource the digital source to attach to
*/
explicit DutyCycleEncoder(DigitalSource& digitalSource);
/**
* Construct a new DutyCycleEncoder attached to a DigitalSource object.
*
* <p>This has a fullRange of 1 and an expectedZero of 0.
*
* @param digitalSource the digital source to attach to
*/
explicit DutyCycleEncoder(DigitalSource* digitalSource);
/**
* Construct a new DutyCycleEncoder attached to a DigitalSource object.
*
* <p>This has a fullRange of 1 and an expectedZero of 0.
*
* @param digitalSource the digital source to attach to
*/
explicit DutyCycleEncoder(std::shared_ptr<DigitalSource> digitalSource);
/**
* Construct a new DutyCycleEncoder on a specific channel.
*
@@ -125,36 +98,6 @@ class DutyCycleEncoder : public wpi::Sendable,
DutyCycleEncoder(std::shared_ptr<DutyCycle> dutyCycle, double fullRange,
double expectedZero);
/**
* Construct a new DutyCycleEncoder attached to a DigitalSource object.
*
* @param digitalSource the digital source to attach to
* @param fullRange the value to report at maximum travel
* @param expectedZero the reading where you would expect a 0 from get()
*/
DutyCycleEncoder(DigitalSource& digitalSource, double fullRange,
double expectedZero);
/**
* Construct a new DutyCycleEncoder attached to a DigitalSource object.
*
* @param digitalSource the digital source to attach to
* @param fullRange the value to report at maximum travel
* @param expectedZero the reading where you would expect a 0 from get()
*/
DutyCycleEncoder(DigitalSource* digitalSource, double fullRange,
double expectedZero);
/**
* Construct a new DutyCycleEncoder attached to a DigitalSource object.
*
* @param digitalSource the digital source to attach to
* @param fullRange the value to report at maximum travel
* @param expectedZero the reading where you would expect a 0 from get()
*/
DutyCycleEncoder(std::shared_ptr<DigitalSource> digitalSource,
double fullRange, double expectedZero);
~DutyCycleEncoder() override = default;
DutyCycleEncoder(DutyCycleEncoder&&) = default;

View File

@@ -21,8 +21,7 @@ TEST(DutyCycleSimTest, Initialization) {
BooleanCallback callback;
auto cb = sim.RegisterInitializedCallback(callback.GetCallback(), false);
DigitalInput di{2};
DutyCycle dc{&di};
DutyCycle dc{2};
EXPECT_TRUE(sim.GetInitialized());
EXPECT_TRUE(callback.WasTriggered());
EXPECT_TRUE(callback.GetLastValue());
@@ -36,8 +35,7 @@ TEST(DutyCycleSimTest, Initialization) {
TEST(DutyCycleSimTest, SetFrequency) {
HAL_Initialize(500, 0);
DigitalInput di{2};
DutyCycle dc{di};
DutyCycle dc{2};
DutyCycleSim sim(dc);
IntCallback callback;
@@ -53,8 +51,7 @@ TEST(DutyCycleSimTest, SetFrequency) {
TEST(DutyCycleSimTest, SetOutput) {
HAL_Initialize(500, 0);
DigitalInput di{2};
DutyCycle dc{di};
DutyCycle dc{2};
DutyCycleSim sim(dc);
DoubleCallback callback;

View File

@@ -8,8 +8,7 @@
#include <frc/smartdashboard/SmartDashboard.h>
class Robot : public frc::TimedRobot {
frc::DigitalInput m_input{0}; // Input channel
frc::DutyCycle m_dutyCycle{m_input}; // Duty cycle input
frc::DutyCycle m_dutyCycle{0}; // Duty cycle input
public:
Robot() {}

View File

@@ -23,27 +23,20 @@ import edu.wpi.first.util.sendable.SendableRegistry;
public class DutyCycle implements Sendable, AutoCloseable {
// Explicitly package private
final int m_handle;
private final DigitalSource m_source;
private final int m_channel;
/**
* Constructs a DutyCycle input from a DigitalSource input.
* Constructs a DutyCycle input from a smartio channel.
*
* <p>This class does not own the inputted source.
*
* @param digitalSource The DigitalSource to use.
* @param channel The channel to use.
*/
@SuppressWarnings("this-escape")
public DutyCycle(DigitalSource digitalSource) {
m_handle =
DutyCycleJNI.initialize(
digitalSource.getPortHandleForRouting(),
digitalSource.getAnalogTriggerTypeForRouting());
public DutyCycle(int channel) {
m_handle = DutyCycleJNI.initialize(HAL.getPort((byte) channel));
m_source = digitalSource;
int index = getFPGAIndex();
HAL.report(tResourceType.kResourceType_DutyCycle, index + 1);
SendableRegistry.addLW(this, "Duty Cycle", index);
m_channel = channel;
HAL.report(tResourceType.kResourceType_DutyCycle, channel + 1);
SendableRegistry.addLW(this, "Duty Cycle", channel);
}
/** Close the DutyCycle and free all resources. */
@@ -109,7 +102,7 @@ public class DutyCycle implements Sendable, AutoCloseable {
* @return the source channel
*/
public int getSourceChannel() {
return m_source.getChannel();
return m_channel;
}
@Override

View File

@@ -19,7 +19,6 @@ import edu.wpi.first.util.sendable.SendableRegistry;
public class DutyCycleEncoder implements Sendable, AutoCloseable {
private final DutyCycle m_dutyCycle;
private boolean m_ownsDutyCycle;
private DigitalInput m_digitalInput;
private int m_frequencyThreshold = 100;
private double m_fullRange;
private double m_expectedZero;
@@ -41,9 +40,8 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
*/
@SuppressWarnings("this-escape")
public DutyCycleEncoder(int channel, double fullRange, double expectedZero) {
m_digitalInput = new DigitalInput(channel);
m_ownsDutyCycle = true;
m_dutyCycle = new DutyCycle(m_digitalInput);
m_dutyCycle = new DutyCycle(channel);
init(fullRange, expectedZero);
}
@@ -60,20 +58,6 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
init(fullRange, expectedZero);
}
/**
* Construct a new DutyCycleEncoder attached to a DigitalSource object.
*
* @param source the digital source to attach to
* @param fullRange the value to report at maximum travel
* @param expectedZero the reading where you would expect a 0 from get()
*/
@SuppressWarnings("this-escape")
public DutyCycleEncoder(DigitalSource source, double fullRange, double expectedZero) {
m_ownsDutyCycle = true;
m_dutyCycle = new DutyCycle(source);
init(fullRange, expectedZero);
}
/**
* Construct a new DutyCycleEncoder on a specific channel.
*
@@ -98,18 +82,6 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
this(dutyCycle, 1.0, 0.0);
}
/**
* Construct a new DutyCycleEncoder attached to a DigitalSource object.
*
* <p>This has a fullRange of 1 and an expectedZero of 0.
*
* @param source the digital source to attach to
*/
@SuppressWarnings("this-escape")
public DutyCycleEncoder(DigitalSource source) {
this(source, 1.0, 0.0);
}
private void init(double fullRange, double expectedZero) {
m_simDevice = SimDevice.create("DutyCycle:DutyCycleEncoder", m_dutyCycle.getSourceChannel());
@@ -258,9 +230,6 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
if (m_ownsDutyCycle) {
m_dutyCycle.close();
}
if (m_digitalInput != null) {
m_digitalInput.close();
}
if (m_simDevice != null) {
m_simDevice.close();
}

View File

@@ -9,7 +9,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.DigitalInput;
import edu.wpi.first.wpilibj.DutyCycle;
import edu.wpi.first.wpilibj.simulation.testutils.BooleanCallback;
import edu.wpi.first.wpilibj.simulation.testutils.DoubleCallback;
@@ -25,8 +24,7 @@ class DutyCycleSimTest {
BooleanCallback callback = new BooleanCallback();
try (CallbackStore cb = sim.registerInitializedCallback(callback, false);
DigitalInput di = new DigitalInput(2);
DutyCycle dc = new DutyCycle(di)) {
DutyCycle dc = new DutyCycle(2)) {
assertTrue(sim.getInitialized());
assertTrue(callback.wasTriggered());
assertTrue(callback.getSetValue());
@@ -37,8 +35,7 @@ class DutyCycleSimTest {
void setFrequencyTest() {
HAL.initialize(500, 0);
try (DigitalInput di = new DigitalInput(2);
DutyCycle dc = new DutyCycle(di)) {
try (DutyCycle dc = new DutyCycle(2)) {
IntCallback callback = new IntCallback();
DutyCycleSim sim = new DutyCycleSim(dc);
try (CallbackStore cb = sim.registerFrequencyCallback(callback, false)) {
@@ -55,8 +52,7 @@ class DutyCycleSimTest {
void setOutputTest() {
HAL.initialize(500, 0);
try (DigitalInput di = new DigitalInput(2);
DutyCycle dc = new DutyCycle(di)) {
try (DutyCycle dc = new DutyCycle(2)) {
DoubleCallback callback = new DoubleCallback();
DutyCycleSim sim = new DutyCycleSim(dc);
try (CallbackStore cb = sim.registerOutputCallback(callback, false)) {

View File

@@ -4,7 +4,6 @@
package edu.wpi.first.wpilibj.examples.dutycycleinput;
import edu.wpi.first.wpilibj.DigitalInput;
import edu.wpi.first.wpilibj.DutyCycle;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
@@ -13,7 +12,7 @@ public class Robot extends TimedRobot {
private final DutyCycle m_dutyCycle;
public Robot() {
m_dutyCycle = new DutyCycle(new DigitalInput(0));
m_dutyCycle = new DutyCycle(0);
}
@Override