diff --git a/wpilibc/src/main/native/cpp/DutyCycleEncoder.cpp b/wpilibc/src/main/native/cpp/DutyCycleEncoder.cpp index 2aae3aff36..f2ac77fb82 100644 --- a/wpilibc/src/main/native/cpp/DutyCycleEncoder.cpp +++ b/wpilibc/src/main/native/cpp/DutyCycleEncoder.cpp @@ -164,6 +164,9 @@ void DutyCycleEncoder::Reset() { if (m_counter) { m_counter->Reset(); } + if (m_simPosition) { + m_simPosition.Set(0); + } m_positionOffset = GetAbsolutePosition(); } diff --git a/wpilibc/src/main/native/cpp/simulation/DutyCycleEncoderSim.cpp b/wpilibc/src/main/native/cpp/simulation/DutyCycleEncoderSim.cpp index 9e578b09fa..3df775df9a 100644 --- a/wpilibc/src/main/native/cpp/simulation/DutyCycleEncoderSim.cpp +++ b/wpilibc/src/main/native/cpp/simulation/DutyCycleEncoderSim.cpp @@ -16,12 +16,42 @@ DutyCycleEncoderSim::DutyCycleEncoderSim(int channel) { frc::sim::SimDeviceSim deviceSim{"DutyCycle:DutyCycleEncoder", channel}; m_simPosition = deviceSim.GetDouble("position"); m_simDistancePerRotation = deviceSim.GetDouble("distance_per_rot"); + m_simAbsolutePosition = deviceSim.GetDouble("absPosition"); + m_simIsConnected = deviceSim.GetBoolean("connected"); +} + +double DutyCycleEncoderSim::Get() { + return m_simPosition.Get(); } void DutyCycleEncoderSim::Set(units::turn_t turns) { m_simPosition.Set(turns.value()); } +double DutyCycleEncoderSim::GetDistance() { + return m_simPosition.Get() * m_simDistancePerRotation.Get(); +} + void DutyCycleEncoderSim::SetDistance(double distance) { m_simPosition.Set(distance / m_simDistancePerRotation.Get()); } + +double DutyCycleEncoderSim::GetAbsolutePosition() { + return m_simAbsolutePosition.Get(); +} + +void DutyCycleEncoderSim::SetAbsolutePosition(double position) { + m_simAbsolutePosition.Set(position); +} + +double DutyCycleEncoderSim::GetDistancePerRotation() { + return m_simDistancePerRotation.Get(); +} + +bool DutyCycleEncoderSim::IsConnected() { + return m_simIsConnected.Get(); +} + +void DutyCycleEncoderSim::SetConnected(bool isConnected) { + m_simIsConnected.Set(isConnected); +} diff --git a/wpilibc/src/main/native/include/frc/simulation/DutyCycleEncoderSim.h b/wpilibc/src/main/native/include/frc/simulation/DutyCycleEncoderSim.h index d7c6186b87..18c04f0562 100644 --- a/wpilibc/src/main/native/include/frc/simulation/DutyCycleEncoderSim.h +++ b/wpilibc/src/main/native/include/frc/simulation/DutyCycleEncoderSim.h @@ -32,6 +32,13 @@ class DutyCycleEncoderSim { */ explicit DutyCycleEncoderSim(int channel); + /** + * Get the position in turns. + * + * @return The position. + */ + double Get(); + /** * Set the position in turns. * @@ -40,13 +47,61 @@ class DutyCycleEncoderSim { void Set(units::turn_t turns); /** - * Set the position. + * Get the distance. + * + * @return The distance. + */ + + double GetDistance(); + + /** + * Set the distance. + * + * @param distance The distance. */ void SetDistance(double distance); + /** + * Get the absolute position. + * + * @return The absolute position + */ + double GetAbsolutePosition(); + + /** + * Set the absolute position. + * + * @param position The absolute position + */ + void SetAbsolutePosition(double position); + + /** + * Get the distance per rotation for this encoder. + * + * @return The scale factor that will be used to convert rotation to useful + * units. + */ + double GetDistancePerRotation(); + + /** + * Get if the encoder is connected. + * + * @return true if the encoder is connected. + */ + bool IsConnected(); + + /** + * Set if the encoder is connected. + * + * @param isConnected Whether or not the sensor is connected. + */ + void SetConnected(bool isConnected); + private: hal::SimDouble m_simPosition; hal::SimDouble m_simDistancePerRotation; + hal::SimDouble m_simAbsolutePosition; + hal::SimBoolean m_simIsConnected; }; } // namespace sim diff --git a/wpilibc/src/test/native/cpp/simulation/DutyCycleEncoderSimTest.cpp b/wpilibc/src/test/native/cpp/simulation/DutyCycleEncoderSimTest.cpp index 8249499b02..f5218c67a2 100644 --- a/wpilibc/src/test/native/cpp/simulation/DutyCycleEncoderSimTest.cpp +++ b/wpilibc/src/test/native/cpp/simulation/DutyCycleEncoderSimTest.cpp @@ -32,4 +32,45 @@ TEST(DutyCycleEncoderSimTest, SetDistance) { EXPECT_EQ(19.1, enc.GetDistance()); } +TEST(DutyCycleEncoderSimTest, SetDistancePerRotation) { + HAL_Initialize(500, 0); + + DutyCycleEncoder enc{0}; + DutyCycleEncoderSim sim(enc); + sim.Set(units::turn_t{1.5}); + enc.SetDistancePerRotation(42); + EXPECT_EQ(63, enc.GetDistance()); +} + +TEST(DutyCycleEncoderSimTest, SetAbsolutePosition) { + HAL_Initialize(500, 0); + + DutyCycleEncoder enc{0}; + DutyCycleEncoderSim sim(enc); + sim.SetAbsolutePosition(0.75); + EXPECT_EQ(0.75, enc.GetAbsolutePosition()); +} + +TEST(DutyCycleEncoderSimTest, SetIsConnected) { + HAL_Initialize(500, 0); + + DutyCycleEncoder enc{0}; + DutyCycleEncoderSim sim(enc); + sim.SetConnected(true); + EXPECT_TRUE(enc.IsConnected()); + sim.SetConnected(false); + EXPECT_FALSE(enc.IsConnected()); +} + +TEST(DutyCycleEncoderSimTest, Reset) { + HAL_Initialize(500, 0); + + DutyCycleEncoder enc{0}; + DutyCycleEncoderSim sim(enc); + sim.SetDistance(2.5); + EXPECT_EQ(2.5, enc.GetDistance()); + enc.Reset(); + EXPECT_EQ(0, enc.GetDistance()); +} + } // namespace frc::sim diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycleEncoder.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycleEncoder.java index f2bfeee3ca..afdcb3f3be 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycleEncoder.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycleEncoder.java @@ -246,6 +246,9 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable { if (m_counter != null) { m_counter.reset(); } + if (m_simPosition != null) { + m_simPosition.set(0); + } m_positionOffset = getAbsolutePosition(); } diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DutyCycleEncoderSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DutyCycleEncoderSim.java index a89b185532..3c2c741b62 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DutyCycleEncoderSim.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DutyCycleEncoderSim.java @@ -4,6 +4,7 @@ package edu.wpi.first.wpilibj.simulation; +import edu.wpi.first.hal.SimBoolean; import edu.wpi.first.hal.SimDouble; import edu.wpi.first.wpilibj.DutyCycleEncoder; @@ -11,6 +12,8 @@ import edu.wpi.first.wpilibj.DutyCycleEncoder; public class DutyCycleEncoderSim { private final SimDouble m_simPosition; private final SimDouble m_simDistancePerRotation; + private final SimDouble m_simAbsolutePosition; + private final SimBoolean m_simIsConnected; /** * Constructs from an DutyCycleEncoder object. @@ -30,6 +33,17 @@ public class DutyCycleEncoderSim { SimDeviceSim wrappedSimDevice = new SimDeviceSim("DutyCycle:DutyCycleEncoder", channel); m_simPosition = wrappedSimDevice.getDouble("position"); m_simDistancePerRotation = wrappedSimDevice.getDouble("distance_per_rot"); + m_simAbsolutePosition = wrappedSimDevice.getDouble("absPosition"); + m_simIsConnected = wrappedSimDevice.getBoolean("connected"); + } + + /** + * Get the position in turns. + * + * @return The position. + */ + public double get() { + return m_simPosition.get(); } /** @@ -42,11 +56,65 @@ public class DutyCycleEncoderSim { } /** - * Set the position. + * Get the distance. * - * @param distance The position. + * @return The distance. + */ + public double getDistance() { + return m_simPosition.get() * m_simDistancePerRotation.get(); + } + + /** + * Set the distance. + * + * @param distance The distance. */ public void setDistance(double distance) { m_simPosition.set(distance / m_simDistancePerRotation.get()); } + + /** + * Get the absolute position. + * + * @return The absolute position + */ + public double getAbsolutePosition() { + return m_simAbsolutePosition.get(); + } + + /** + * Set the absolute position. + * + * @param position The absolute position + */ + public void setAbsolutePosition(double position) { + m_simAbsolutePosition.set(position); + } + + /** + * Get the distance per rotation for this encoder. + * + * @return The scale factor that will be used to convert rotation to useful units. + */ + public double getDistancePerRotation() { + return m_simDistancePerRotation.get(); + } + + /** + * Get if the encoder is connected. + * + * @return true if the encoder is connected. + */ + public boolean getConnected() { + return m_simIsConnected.get(); + } + + /** + * Set if the encoder is connected. + * + * @param isConnected Whether or not the sensor is connected. + */ + public void setConnected(boolean isConnected) { + m_simIsConnected.set(isConnected); + } } diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DutyCycleEncoderSimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DutyCycleEncoderSimTest.java index 49f8e779b2..42a6faa628 100644 --- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DutyCycleEncoderSimTest.java +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DutyCycleEncoderSimTest.java @@ -5,6 +5,8 @@ package edu.wpi.first.wpilibj.simulation; import static org.junit.jupiter.api.Assertions.assertEquals; +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.DutyCycleEncoder; @@ -32,4 +34,56 @@ class DutyCycleEncoderSimTest { assertEquals(19.1, encoder.getDistance()); } } + + @Test + void setDistancePerRotationTest() { + HAL.initialize(500, 0); + + try (DutyCycleEncoder encoder = new DutyCycleEncoder(0)) { + DutyCycleEncoderSim sim = new DutyCycleEncoderSim(encoder); + sim.set(1.5); + encoder.setDistancePerRotation(42); + assertEquals(63.0, encoder.getDistance()); + } + } + + @Test + void setAbsolutePositionTest() { + HAL.initialize(500, 0); + + try (DutyCycleEncoder encoder = new DutyCycleEncoder(0)) { + DutyCycleEncoderSim sim = new DutyCycleEncoderSim(encoder); + + sim.setAbsolutePosition(0.75); + assertEquals(0.75, encoder.getAbsolutePosition()); + } + } + + @Test + void setIsConnectedTest() { + HAL.initialize(500, 0); + + try (DutyCycleEncoder encoder = new DutyCycleEncoder(0)) { + DutyCycleEncoderSim sim = new DutyCycleEncoderSim(encoder); + + sim.setConnected(true); + assertTrue(encoder.isConnected()); + sim.setConnected(false); + assertFalse(encoder.isConnected()); + } + } + + @Test + void resetTest() { + HAL.initialize(500, 0); + + try (DutyCycleEncoder encoder = new DutyCycleEncoder(0)) { + DutyCycleEncoderSim sim = new DutyCycleEncoderSim(encoder); + + sim.setDistance(2.5); + assertEquals(2.5, encoder.getDistance()); + encoder.reset(); + assertEquals(0.0, encoder.getDistance()); + } + } }