mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[wpilib] DutyCycleEncoder: add setting of duty cycle range (#3759)
As the sensor needs to maintain an actual duty cycle, it can't go all the way from 0-100, so provide a way to set the min and max and linearly map between the two.
This commit is contained in:
@@ -89,6 +89,14 @@ units::turn_t DutyCycleEncoder::Get() const {
|
||||
auto counter2 = m_counter->Get();
|
||||
auto pos2 = m_dutyCycle->GetOutput();
|
||||
if (counter == counter2 && pos == pos2) {
|
||||
// map sensor range
|
||||
if (pos < m_sensorMin) {
|
||||
pos = m_sensorMin;
|
||||
}
|
||||
if (pos > m_sensorMax) {
|
||||
pos = m_sensorMax;
|
||||
}
|
||||
pos = (pos - m_sensorMin) / (m_sensorMax - m_sensorMin);
|
||||
units::turn_t turns{counter + pos - m_positionOffset};
|
||||
m_lastPosition = turns;
|
||||
return turns;
|
||||
@@ -102,6 +110,11 @@ units::turn_t DutyCycleEncoder::Get() const {
|
||||
return m_lastPosition;
|
||||
}
|
||||
|
||||
void DutyCycleEncoder::SetDutyCycleRange(double min, double max) {
|
||||
m_sensorMin = std::clamp(min, 0.0, 1.0);
|
||||
m_sensorMax = std::clamp(max, 0.0, 1.0);
|
||||
}
|
||||
|
||||
void DutyCycleEncoder::SetDistancePerRotation(double distancePerRotation) {
|
||||
m_distancePerRotation = distancePerRotation;
|
||||
m_simDistancePerRotation.Set(distancePerRotation);
|
||||
|
||||
@@ -121,6 +121,21 @@ class DutyCycleEncoder : public wpi::Sendable,
|
||||
*/
|
||||
units::turn_t Get() const;
|
||||
|
||||
/**
|
||||
* Set the encoder duty cycle range. As the encoder needs to maintain a duty
|
||||
* cycle, the duty cycle cannot go all the way to 0% or all the way to 100%.
|
||||
* For example, an encoder with a 4096 us period might have a minimum duty
|
||||
* cycle of 1 us / 4096 us and a maximum duty cycle of 4095 / 4096 us. Setting
|
||||
* the range will result in an encoder duty cycle less than or equal to the
|
||||
* minimum being output as 0 rotation, the duty cycle greater than or equal to
|
||||
* the maximum being output as 1 rotation, and values in between linearly
|
||||
* scaled from 0 to 1.
|
||||
*
|
||||
* @param min minimum duty cycle (0-1 range)
|
||||
* @param max maximum duty cycle (0-1 range)
|
||||
*/
|
||||
void SetDutyCycleRange(double min, double max);
|
||||
|
||||
/**
|
||||
* Set the distance per rotation of the encoder. This sets the multiplier used
|
||||
* to determine the distance driven based on the rotation value from the
|
||||
@@ -175,6 +190,8 @@ class DutyCycleEncoder : public wpi::Sendable,
|
||||
double m_positionOffset = 0;
|
||||
double m_distancePerRotation = 1.0;
|
||||
mutable units::turn_t m_lastPosition{0.0};
|
||||
double m_sensorMin = 0;
|
||||
double m_sensorMax = 1;
|
||||
|
||||
hal::SimDevice m_simDevice;
|
||||
hal::SimDouble m_simPosition;
|
||||
|
||||
@@ -7,6 +7,7 @@ package edu.wpi.first.wpilibj;
|
||||
import edu.wpi.first.hal.SimBoolean;
|
||||
import edu.wpi.first.hal.SimDevice;
|
||||
import edu.wpi.first.hal.SimDouble;
|
||||
import edu.wpi.first.math.MathUtil;
|
||||
import edu.wpi.first.util.sendable.Sendable;
|
||||
import edu.wpi.first.util.sendable.SendableBuilder;
|
||||
import edu.wpi.first.util.sendable.SendableRegistry;
|
||||
@@ -26,6 +27,8 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
|
||||
private double m_positionOffset;
|
||||
private double m_distancePerRotation = 1.0;
|
||||
private double m_lastPosition;
|
||||
private double m_sensorMin;
|
||||
private double m_sensorMax = 1.0;
|
||||
|
||||
protected SimDevice m_simDevice;
|
||||
protected SimDouble m_simPosition;
|
||||
@@ -105,6 +108,14 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
|
||||
double counter2 = m_counter.get();
|
||||
double pos2 = m_dutyCycle.getOutput();
|
||||
if (counter == counter2 && pos == pos2) {
|
||||
// map sensor range
|
||||
if (pos < m_sensorMin) {
|
||||
pos = m_sensorMin;
|
||||
}
|
||||
if (pos > m_sensorMax) {
|
||||
pos = m_sensorMax;
|
||||
}
|
||||
pos = (pos - m_sensorMin) / (m_sensorMax - m_sensorMin);
|
||||
double position = counter + pos - m_positionOffset;
|
||||
m_lastPosition = position;
|
||||
return position;
|
||||
@@ -129,6 +140,22 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
|
||||
return m_positionOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the encoder duty cycle range. As the encoder needs to maintain a duty cycle, the duty cycle
|
||||
* cannot go all the way to 0% or all the way to 100%. For example, an encoder with a 4096 us
|
||||
* period might have a minimum duty cycle of 1 us / 4096 us and a maximum duty cycle of 4095 /
|
||||
* 4096 us. Setting the range will result in an encoder duty cycle less than or equal to the
|
||||
* minimum being output as 0 rotation, the duty cycle greater than or equal to the maximum being
|
||||
* output as 1 rotation, and values in between linearly scaled from 0 to 1.
|
||||
*
|
||||
* @param min minimum duty cycle (0-1 range)
|
||||
* @param max maximum duty cycle (0-1 range)
|
||||
*/
|
||||
public void setDutyCycleRange(double min, double max) {
|
||||
m_sensorMin = MathUtil.clamp(min, 0.0, 1.0);
|
||||
m_sensorMax = MathUtil.clamp(max, 0.0, 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the distance per rotation of the encoder. This sets the multiplier used to determine the
|
||||
* distance driven based on the rotation value from the encoder. Set this value based on the how
|
||||
|
||||
Reference in New Issue
Block a user