From 53d8d33bca9b3a3e944a360aa9d459e2743098f8 Mon Sep 17 00:00:00 2001 From: Ryan Blue Date: Wed, 11 Jan 2023 14:43:56 -0500 Subject: [PATCH] [hal, wpilibj] Add missing distance per pulse functions to EncoderSim (#4928) Also fix C++ and Java EncoderSim.setDistancePerPulse() not propagating value to SimEncoderData. --- .../first/hal/simulation/EncoderDataJNI.java | 9 ++++ .../cpp/jni/simulation/EncoderDataJNI.cpp | 50 +++++++++++++++++++ hal/src/main/native/sim/Encoder.cpp | 2 +- .../native/cpp/simulation/EncoderSimTest.cpp | 2 +- .../first/wpilibj/simulation/EncoderSim.java | 32 ++++++++++++ .../wpilibj/simulation/EncoderSimTest.java | 19 +++++++ 6 files changed, 112 insertions(+), 2 deletions(-) diff --git a/hal/src/main/java/edu/wpi/first/hal/simulation/EncoderDataJNI.java b/hal/src/main/java/edu/wpi/first/hal/simulation/EncoderDataJNI.java index fc9d2e5c21..e48607a8c1 100644 --- a/hal/src/main/java/edu/wpi/first/hal/simulation/EncoderDataJNI.java +++ b/hal/src/main/java/edu/wpi/first/hal/simulation/EncoderDataJNI.java @@ -79,6 +79,15 @@ public class EncoderDataJNI extends JNIWrapper { public static native void setSamplesToAverage(int index, int samplesToAverage); + public static native int registerDistancePerPulseCallback( + int index, NotifyCallback callback, boolean initialNotify); + + public static native void cancelDistancePerPulseCallback(int index, int uid); + + public static native double getDistancePerPulse(int index); + + public static native void setDistancePerPulse(int index, double distancePerPulse); + public static native void setDistance(int index, double distance); public static native double getDistance(int index); diff --git a/hal/src/main/native/cpp/jni/simulation/EncoderDataJNI.cpp b/hal/src/main/native/cpp/jni/simulation/EncoderDataJNI.cpp index 69549a1105..a33458fab7 100644 --- a/hal/src/main/native/cpp/jni/simulation/EncoderDataJNI.cpp +++ b/hal/src/main/native/cpp/jni/simulation/EncoderDataJNI.cpp @@ -412,6 +412,56 @@ Java_edu_wpi_first_hal_simulation_EncoderDataJNI_setSamplesToAverage HALSIM_SetEncoderSamplesToAverage(index, value); } +/* + * Class: edu_wpi_first_hal_simulation_EncoderDataJNI + * Method: registerDistancePerPulseCallback + * Signature: (ILjava/lang/Object;Z)I + */ +JNIEXPORT jint JNICALL +Java_edu_wpi_first_hal_simulation_EncoderDataJNI_registerDistancePerPulseCallback + (JNIEnv* env, jclass, jint index, jobject callback, jboolean initialNotify) +{ + return sim::AllocateCallback(env, index, callback, initialNotify, + &HALSIM_RegisterEncoderDistancePerPulseCallback); +} + +/* + * Class: edu_wpi_first_hal_simulation_EncoderDataJNI + * Method: cancelDistancePerPulseCallback + * Signature: (II)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_simulation_EncoderDataJNI_cancelDistancePerPulseCallback + (JNIEnv* env, jclass, jint index, jint handle) +{ + return sim::FreeCallback(env, handle, index, + &HALSIM_CancelEncoderDistancePerPulseCallback); +} + +/* + * Class: edu_wpi_first_hal_simulation_EncoderDataJNI + * Method: getDistancePerPulse + * Signature: (I)D + */ +JNIEXPORT jdouble JNICALL +Java_edu_wpi_first_hal_simulation_EncoderDataJNI_getDistancePerPulse + (JNIEnv*, jclass, jint index) +{ + return HALSIM_GetEncoderDistancePerPulse(index); +} + +/* + * Class: edu_wpi_first_hal_simulation_EncoderDataJNI + * Method: setDistancePerPulse + * Signature: (ID)V + */ +JNIEXPORT void JNICALL +Java_edu_wpi_first_hal_simulation_EncoderDataJNI_setDistancePerPulse + (JNIEnv*, jclass, jint index, jdouble value) +{ + HALSIM_SetEncoderDistancePerPulse(index, value); +} + /* * Class: edu_wpi_first_hal_simulation_EncoderDataJNI * Method: setDistance diff --git a/hal/src/main/native/sim/Encoder.cpp b/hal/src/main/native/sim/Encoder.cpp index 137ee7811d..964777dece 100644 --- a/hal/src/main/native/sim/Encoder.cpp +++ b/hal/src/main/native/sim/Encoder.cpp @@ -363,7 +363,7 @@ double HAL_GetEncoderDistancePerPulse(HAL_EncoderHandle encoderHandle, return 0.0; } - return encoder->distancePerPulse; + return SimEncoderData[encoder->index].distancePerPulse; } HAL_EncoderEncodingType HAL_GetEncoderEncodingType( diff --git a/wpilibc/src/test/native/cpp/simulation/EncoderSimTest.cpp b/wpilibc/src/test/native/cpp/simulation/EncoderSimTest.cpp index 7722ccc9f0..3da140b033 100644 --- a/wpilibc/src/test/native/cpp/simulation/EncoderSimTest.cpp +++ b/wpilibc/src/test/native/cpp/simulation/EncoderSimTest.cpp @@ -198,7 +198,7 @@ TEST(EncoderSimTest, SetDistancePerPulse) { DoubleCallback callback; auto cb = sim.RegisterDistancePerPulseCallback(callback.GetCallback(), false); - encoder.SetDistancePerPulse(.03405); + sim.SetDistancePerPulse(.03405); EXPECT_EQ(.03405, sim.GetDistancePerPulse()); EXPECT_EQ(.03405, encoder.GetDistancePerPulse()); EXPECT_TRUE(callback.WasTriggered()); diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/EncoderSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/EncoderSim.java index 924ba991e1..310dbf6c49 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/EncoderSim.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/EncoderSim.java @@ -303,6 +303,38 @@ public class EncoderSim { EncoderDataJNI.setSamplesToAverage(m_index, samplesToAverage); } + /** + * Register a callback on the distance per pulse value of this encoder. + * + * @param callback the callback that will be called whenever the distance per pulse is changed + * @param initialNotify if true, the callback will be run on 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 registerDistancePerPulseCallback( + NotifyCallback callback, boolean initialNotify) { + int uid = EncoderDataJNI.registerDistancePerPulseCallback(m_index, callback, initialNotify); + return new CallbackStore(m_index, uid, EncoderDataJNI::cancelDistancePerPulseCallback); + } + + /** + * Get the distance per pulse value. + * + * @return the distance per pulse value + */ + public double getDistancePerPulse() { + return EncoderDataJNI.getDistancePerPulse(m_index); + } + + /** + * Set the distance per pulse value. + * + * @param samplesToAverage the new value + */ + public void setDistancePerPulse(double samplesToAverage) { + EncoderDataJNI.setDistancePerPulse(m_index, samplesToAverage); + } + /** * Change the encoder distance. * diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/EncoderSimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/EncoderSimTest.java index eebabeb5f8..7d3fe73b64 100644 --- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/EncoderSimTest.java +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/EncoderSimTest.java @@ -89,4 +89,23 @@ class EncoderSimTest { } } } + + @Test + void testDistancePerPulse() { + HAL.initialize(500, 0); + + try (Encoder encoder = new Encoder(0, 1)) { + EncoderSim sim = new EncoderSim(encoder); + sim.resetData(); + + DoubleCallback callback = new DoubleCallback(); + try (CallbackStore cb = sim.registerDistancePerPulseCallback(callback, false)) { + sim.setDistancePerPulse(0.03405); + assertEquals(0.03405, sim.getDistancePerPulse()); + assertEquals(0.03405, encoder.getDistancePerPulse()); + assertTrue(callback.wasTriggered()); + assertEquals(0.03405, callback.getSetValue()); + } + } + } }