mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
Moves Encoders to Handles and Moves WPILib Encoders to HAL (#124)
This commit is contained in:
committed by
Peter Johnson
parent
b45e0917ae
commit
36ac37db8c
@@ -7,202 +7,428 @@
|
||||
|
||||
#include "HAL/Encoder.h"
|
||||
|
||||
#include "DigitalInternal.h"
|
||||
#include "HAL/cpp/Resource.h"
|
||||
|
||||
static_assert(sizeof(uint32_t) <= sizeof(void*),
|
||||
"This file shoves uint32_ts into pointers.");
|
||||
#include "ChipObject.h"
|
||||
#include "EncoderInternal.h"
|
||||
#include "FPGAEncoder.h"
|
||||
#include "HAL/Counter.h"
|
||||
#include "HAL/Errors.h"
|
||||
#include "handles/LimitedClassedHandleResource.h"
|
||||
|
||||
using namespace hal;
|
||||
|
||||
extern "C" {
|
||||
struct encoder_t {
|
||||
tEncoder* encoder;
|
||||
uint32_t index;
|
||||
};
|
||||
typedef struct encoder_t Encoder;
|
||||
Encoder::Encoder(uint8_t port_a_module, uint32_t port_a_pin,
|
||||
bool port_a_analog_trigger, uint8_t port_b_module,
|
||||
uint32_t port_b_pin, bool port_b_analog_trigger,
|
||||
bool reverseDirection, EncoderEncodingType encodingType,
|
||||
int32_t* status) {
|
||||
m_encodingType = encodingType;
|
||||
switch (encodingType) {
|
||||
case HAL_Encoder_k4X: {
|
||||
m_encodingScale = 4;
|
||||
m_encoder = initializeFPGAEncoder(port_a_module, port_a_pin,
|
||||
port_a_analog_trigger, port_b_module,
|
||||
port_b_pin, port_b_analog_trigger,
|
||||
reverseDirection, &m_index, status);
|
||||
if (*status != 0) {
|
||||
return;
|
||||
}
|
||||
m_counter = HAL_INVALID_HANDLE;
|
||||
SetMaxPeriod(.5, status);
|
||||
break;
|
||||
}
|
||||
case HAL_Encoder_k1X:
|
||||
case HAL_Encoder_k2X: {
|
||||
SetupCounter(port_a_module, port_a_pin, port_a_analog_trigger,
|
||||
port_b_module, port_b_pin, port_b_analog_trigger,
|
||||
reverseDirection, encodingType, status);
|
||||
|
||||
static const double DECODING_SCALING_FACTOR = 0.25;
|
||||
static hal::Resource* quadEncoders = nullptr;
|
||||
|
||||
void* initializeEncoder(uint8_t port_a_module, uint32_t port_a_pin,
|
||||
bool port_a_analog_trigger, uint8_t port_b_module,
|
||||
uint32_t port_b_pin, bool port_b_analog_trigger,
|
||||
bool reverseDirection, int32_t* index,
|
||||
int32_t* status) {
|
||||
// Initialize encoder structure
|
||||
Encoder* encoder = new Encoder();
|
||||
|
||||
remapDigitalSource(port_a_analog_trigger, port_a_pin, port_a_module);
|
||||
remapDigitalSource(port_b_analog_trigger, port_b_pin, port_b_module);
|
||||
|
||||
hal::Resource::CreateResourceObject(&quadEncoders, tEncoder::kNumSystems);
|
||||
encoder->index = quadEncoders->Allocate("4X Encoder");
|
||||
*index = encoder->index;
|
||||
// TODO: if (index == ~0ul) { CloneError(quadEncoders); return; }
|
||||
encoder->encoder = tEncoder::create(encoder->index, status);
|
||||
encoder->encoder->writeConfig_ASource_Module(port_a_module, status);
|
||||
encoder->encoder->writeConfig_ASource_Channel(port_a_pin, status);
|
||||
encoder->encoder->writeConfig_ASource_AnalogTrigger(port_a_analog_trigger,
|
||||
status);
|
||||
encoder->encoder->writeConfig_BSource_Module(port_b_module, status);
|
||||
encoder->encoder->writeConfig_BSource_Channel(port_b_pin, status);
|
||||
encoder->encoder->writeConfig_BSource_AnalogTrigger(port_b_analog_trigger,
|
||||
status);
|
||||
encoder->encoder->strobeReset(status);
|
||||
encoder->encoder->writeConfig_Reverse(reverseDirection, status);
|
||||
encoder->encoder->writeTimerConfig_AverageSize(4, status);
|
||||
|
||||
return encoder;
|
||||
}
|
||||
|
||||
void freeEncoder(void* encoder_pointer, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
if (!encoder) return;
|
||||
quadEncoders->Free(encoder->index);
|
||||
delete encoder->encoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the Encoder distance to zero.
|
||||
* Resets the current count to zero on the encoder.
|
||||
*/
|
||||
void resetEncoder(void* encoder_pointer, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
encoder->encoder->strobeReset(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw value from the encoder.
|
||||
* The raw value is the actual count unscaled by the 1x, 2x, or 4x scale
|
||||
* factor.
|
||||
* @return Current raw count from the encoder
|
||||
*/
|
||||
int32_t getEncoder(void* encoder_pointer, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
return encoder->encoder->readOutput_Value(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the period of the most recent pulse.
|
||||
* Returns the period of the most recent Encoder pulse in seconds.
|
||||
* This method compenstates for the decoding type.
|
||||
*
|
||||
* @deprecated Use GetRate() in favor of this method. This returns unscaled
|
||||
* periods and GetRate() scales using value from SetDistancePerPulse().
|
||||
*
|
||||
* @return Period in seconds of the most recent pulse.
|
||||
*/
|
||||
double getEncoderPeriod(void* encoder_pointer, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
tEncoder::tTimerOutput output = encoder->encoder->readTimerOutput(status);
|
||||
double value;
|
||||
if (output.Stalled) {
|
||||
// Return infinity
|
||||
double zero = 0.0;
|
||||
value = 1.0 / zero;
|
||||
} else {
|
||||
// output.Period is a fixed point number that counts by 2 (24 bits, 25
|
||||
// integer bits)
|
||||
value = (double)(output.Period << 1) / (double)output.Count;
|
||||
m_encodingScale = encodingType == HAL_Encoder_k1X ? 1 : 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
double measuredPeriod = value * 2.5e-8;
|
||||
return measuredPeriod / DECODING_SCALING_FACTOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum period for stopped detection.
|
||||
* Sets the value that represents the maximum period of the Encoder before it
|
||||
* will assume that the attached device is stopped. This timeout allows users
|
||||
* to determine if the wheels or other shaft has stopped rotating.
|
||||
* This method compensates for the decoding type.
|
||||
*
|
||||
* @deprecated Use SetMinRate() in favor of this method. This takes unscaled
|
||||
* periods and SetMinRate() scales using value from SetDistancePerPulse().
|
||||
*
|
||||
* @param maxPeriod The maximum time between rising and falling edges before the
|
||||
* FPGA will
|
||||
* report the device stopped. This is expressed in seconds.
|
||||
*/
|
||||
void setEncoderMaxPeriod(void* encoder_pointer, double maxPeriod,
|
||||
int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
encoder->encoder->writeTimerConfig_StallPeriod(
|
||||
(uint32_t)(maxPeriod * 4.0e8 * DECODING_SCALING_FACTOR), status);
|
||||
void Encoder::SetupCounter(uint8_t port_a_module, uint32_t port_a_pin,
|
||||
bool port_a_analog_trigger, uint8_t port_b_module,
|
||||
uint32_t port_b_pin, bool port_b_analog_trigger,
|
||||
bool reverseDirection,
|
||||
EncoderEncodingType encodingType, int32_t* status) {
|
||||
m_encodingScale = encodingType == HAL_Encoder_k1X ? 1 : 2;
|
||||
m_counter = initializeCounter(kExternalDirection, &m_index, status);
|
||||
if (*status != 0) return;
|
||||
setCounterMaxPeriod(m_counter, 0.5, status);
|
||||
if (*status != 0) return;
|
||||
setCounterUpSource(m_counter, port_a_pin, port_a_analog_trigger, status);
|
||||
if (*status != 0) return;
|
||||
setCounterDownSource(m_counter, port_b_pin, port_b_analog_trigger, status);
|
||||
if (*status != 0) return;
|
||||
if (encodingType == HAL_Encoder_k1X) {
|
||||
setCounterUpSourceEdge(m_counter, true, false, status);
|
||||
setCounterAverageSize(m_counter, 1, status);
|
||||
} else {
|
||||
setCounterUpSourceEdge(m_counter, true, true, status);
|
||||
setCounterAverageSize(m_counter, 2, status);
|
||||
}
|
||||
setCounterDownSourceEdge(m_counter, reverseDirection, true, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the encoder is stopped.
|
||||
* Using the MaxPeriod value, a boolean is returned that is true if the encoder
|
||||
* is considered stopped and false if it is still moving. A stopped encoder is
|
||||
* one where the most recent pulse width exceeds the MaxPeriod.
|
||||
* @return True if the encoder is considered stopped.
|
||||
*/
|
||||
bool getEncoderStopped(void* encoder_pointer, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
return encoder->encoder->readTimerOutput_Stalled(status) != 0;
|
||||
Encoder::~Encoder() {
|
||||
if (m_counter != HAL_INVALID_HANDLE) {
|
||||
int32_t status = 0;
|
||||
freeCounter(m_counter, &status);
|
||||
} else {
|
||||
int32_t status = 0;
|
||||
freeFPGAEncoder(m_encoder, &status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The last direction the encoder value changed.
|
||||
* @return The last direction the encoder value changed.
|
||||
*/
|
||||
bool getEncoderDirection(void* encoder_pointer, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
return encoder->encoder->readOutput_Direction(status);
|
||||
// CounterBase interface
|
||||
int32_t Encoder::Get(int32_t* status) const {
|
||||
return (int32_t)(GetRaw(status) * DecodingScaleFactor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the direction sensing for this encoder.
|
||||
* This sets the direction sensing on the encoder so that it could count in the
|
||||
* correct software direction regardless of the mounting.
|
||||
* @param reverseDirection true if the encoder direction should be reversed
|
||||
*/
|
||||
void setEncoderReverseDirection(void* encoder_pointer, bool reverseDirection,
|
||||
int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
encoder->encoder->writeConfig_Reverse(reverseDirection, status);
|
||||
int32_t Encoder::GetRaw(int32_t* status) const {
|
||||
if (m_counter) {
|
||||
return getCounter(m_counter, status);
|
||||
} else {
|
||||
return getFPGAEncoder(m_encoder, status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Samples to Average which specifies the number of samples of the timer
|
||||
* to average when calculating the period. Perform averaging to account for
|
||||
* mechanical imperfections or as oversampling to increase resolution.
|
||||
* @param samplesToAverage The number of samples to average from 1 to 127.
|
||||
*/
|
||||
void setEncoderSamplesToAverage(void* encoder_pointer,
|
||||
uint32_t samplesToAverage, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
int32_t Encoder::GetEncodingScale(int32_t* status) const {
|
||||
return m_encodingScale;
|
||||
}
|
||||
|
||||
void Encoder::Reset(int32_t* status) {
|
||||
if (m_counter) {
|
||||
resetCounter(m_counter, status);
|
||||
} else {
|
||||
resetFPGAEncoder(m_encoder, status);
|
||||
}
|
||||
}
|
||||
|
||||
double Encoder::GetPeriod(int32_t* status) const {
|
||||
if (m_counter) {
|
||||
return getCounterPeriod(m_counter, status) / DecodingScaleFactor();
|
||||
} else {
|
||||
return getFPGAEncoderPeriod(m_encoder, status);
|
||||
}
|
||||
}
|
||||
|
||||
void Encoder::SetMaxPeriod(double maxPeriod, int32_t* status) {
|
||||
if (m_counter) {
|
||||
setCounterMaxPeriod(m_counter, maxPeriod, status);
|
||||
} else {
|
||||
setFPGAEncoderMaxPeriod(m_encoder, maxPeriod, status);
|
||||
}
|
||||
}
|
||||
|
||||
bool Encoder::GetStopped(int32_t* status) const {
|
||||
if (m_counter) {
|
||||
return getCounterStopped(m_counter, status);
|
||||
} else {
|
||||
return getFPGAEncoderStopped(m_encoder, status);
|
||||
}
|
||||
}
|
||||
|
||||
bool Encoder::GetDirection(int32_t* status) const {
|
||||
if (m_counter) {
|
||||
return getCounterDirection(m_counter, status);
|
||||
} else {
|
||||
return getFPGAEncoderDirection(m_encoder, status);
|
||||
}
|
||||
}
|
||||
|
||||
double Encoder::GetDistance(int32_t* status) const {
|
||||
return GetRaw(status) * DecodingScaleFactor() * m_distancePerPulse;
|
||||
}
|
||||
|
||||
double Encoder::GetRate(int32_t* status) const {
|
||||
return m_distancePerPulse / GetPeriod(status);
|
||||
}
|
||||
|
||||
void Encoder::SetMinRate(double minRate, int32_t* status) {
|
||||
SetMaxPeriod(m_distancePerPulse / minRate, status);
|
||||
}
|
||||
|
||||
void Encoder::SetDistancePerPulse(double distancePerPulse, int32_t* status) {
|
||||
m_distancePerPulse = distancePerPulse;
|
||||
}
|
||||
|
||||
void Encoder::SetReverseDirection(bool reverseDirection, int32_t* status) {
|
||||
if (m_counter) {
|
||||
setCounterReverseDirection(m_counter, reverseDirection, status);
|
||||
} else {
|
||||
setFPGAEncoderReverseDirection(m_encoder, reverseDirection, status);
|
||||
}
|
||||
}
|
||||
|
||||
void Encoder::SetSamplesToAverage(int samplesToAverage, int32_t* status) {
|
||||
if (samplesToAverage < 1 || samplesToAverage > 127) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
if (m_counter) {
|
||||
setCounterSamplesToAverage(m_counter, samplesToAverage, status);
|
||||
} else {
|
||||
setFPGAEncoderSamplesToAverage(m_encoder, samplesToAverage, status);
|
||||
}
|
||||
encoder->encoder->writeTimerConfig_AverageSize(samplesToAverage, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Samples to Average which specifies the number of samples of the timer
|
||||
* to average when calculating the period. Perform averaging to account for
|
||||
* mechanical imperfections or as oversampling to increase resolution.
|
||||
* @return SamplesToAverage The number of samples being averaged (from 1 to 127)
|
||||
*/
|
||||
uint32_t getEncoderSamplesToAverage(void* encoder_pointer, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
return encoder->encoder->readTimerConfig_AverageSize(status);
|
||||
int32_t Encoder::GetSamplesToAverage(int32_t* status) const {
|
||||
if (m_counter) {
|
||||
return getCounterSamplesToAverage(m_counter, status);
|
||||
} else {
|
||||
return getFPGAEncoderSamplesToAverage(m_encoder, status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an index source for an encoder, which is an input that resets the
|
||||
* encoder's count.
|
||||
*/
|
||||
void setEncoderIndexSource(void* encoder_pointer, uint32_t pin,
|
||||
bool analogTrigger, bool activeHigh,
|
||||
bool edgeSensitive, int32_t* status) {
|
||||
Encoder* encoder = (Encoder*)encoder_pointer;
|
||||
encoder->encoder->writeConfig_IndexSource_Channel((unsigned char)pin, status);
|
||||
encoder->encoder->writeConfig_IndexSource_Module((unsigned char)0, status);
|
||||
encoder->encoder->writeConfig_IndexSource_AnalogTrigger(analogTrigger,
|
||||
status);
|
||||
encoder->encoder->writeConfig_IndexActiveHigh(activeHigh, status);
|
||||
encoder->encoder->writeConfig_IndexEdgeSensitive(edgeSensitive, status);
|
||||
void Encoder::SetIndexSource(uint32_t pin, bool analogTrigger,
|
||||
EncoderIndexingType type, int32_t* status) {
|
||||
if (m_counter) {
|
||||
*status = HAL_COUNTER_NOT_SUPPORTED;
|
||||
return;
|
||||
}
|
||||
bool activeHigh =
|
||||
(type == HAL_kResetWhileHigh) || (type == HAL_kResetOnRisingEdge);
|
||||
bool edgeSensitive =
|
||||
(type == HAL_kResetOnFallingEdge) || (type == HAL_kResetOnRisingEdge);
|
||||
setFPGAEncoderIndexSource(m_encoder, pin, analogTrigger, activeHigh,
|
||||
edgeSensitive, status);
|
||||
}
|
||||
|
||||
double Encoder::DecodingScaleFactor() const {
|
||||
switch (m_encodingType) {
|
||||
case HAL_Encoder_k1X:
|
||||
return 1.0;
|
||||
case HAL_Encoder_k2X:
|
||||
return 0.5;
|
||||
case HAL_Encoder_k4X:
|
||||
return 0.25;
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
static LimitedClassedHandleResource<
|
||||
HalEncoderHandle, Encoder, tEncoder::kNumSystems + tCounter::kNumSystems,
|
||||
HalHandleEnum::Encoder>
|
||||
encoderHandles;
|
||||
|
||||
extern "C" {
|
||||
HalEncoderHandle initializeEncoder(
|
||||
uint8_t port_a_module, uint32_t port_a_pin, bool port_a_analog_trigger,
|
||||
uint8_t port_b_module, uint32_t port_b_pin, bool port_b_analog_trigger,
|
||||
bool reverseDirection, EncoderEncodingType encodingType, int32_t* status) {
|
||||
auto encoder = std::make_shared<Encoder>(
|
||||
port_a_module, port_a_pin, port_a_analog_trigger, port_b_module,
|
||||
port_b_pin, port_b_analog_trigger, reverseDirection, encodingType,
|
||||
status);
|
||||
if (*status != 0) return HAL_INVALID_HANDLE; // return in creation error
|
||||
auto handle = encoderHandles.Allocate(encoder);
|
||||
if (handle == HAL_INVALID_HANDLE) {
|
||||
*status = NO_AVAILABLE_RESOURCES;
|
||||
return HAL_INVALID_HANDLE;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void freeEncoder(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
encoderHandles.Free(encoder_handle);
|
||||
}
|
||||
|
||||
int32_t getEncoder(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->Get(status);
|
||||
}
|
||||
|
||||
int32_t getEncoderRaw(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetRaw(status);
|
||||
}
|
||||
|
||||
int32_t getEncoderEncodingScale(HalEncoderHandle encoder_handle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetEncodingScale(status);
|
||||
}
|
||||
|
||||
void resetEncoder(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
encoder->Reset(status);
|
||||
}
|
||||
|
||||
int32_t getEncoderPeriod(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetPeriod(status);
|
||||
}
|
||||
|
||||
void setEncoderMaxPeriod(HalEncoderHandle encoder_handle, double maxPeriod,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
encoder->SetMaxPeriod(maxPeriod, status);
|
||||
}
|
||||
|
||||
uint8_t getEncoderStopped(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetStopped(status);
|
||||
}
|
||||
|
||||
uint8_t getEncoderDirection(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetDirection(status);
|
||||
}
|
||||
|
||||
double getEncoderDistance(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetDistance(status);
|
||||
}
|
||||
|
||||
double getEncoderRate(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetRate(status);
|
||||
}
|
||||
|
||||
void setEncoderMinRate(HalEncoderHandle encoder_handle, double minRate,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
encoder->SetMinRate(minRate, status);
|
||||
}
|
||||
|
||||
void setEncoderDistancePerPulse(HalEncoderHandle encoder_handle,
|
||||
double distancePerPulse, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
encoder->SetDistancePerPulse(distancePerPulse, status);
|
||||
}
|
||||
|
||||
void setEncoderReverseDirection(HalEncoderHandle encoder_handle,
|
||||
uint8_t reverseDirection, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
encoder->SetReverseDirection(reverseDirection, status);
|
||||
}
|
||||
|
||||
void setEncoderSamplesToAverage(HalEncoderHandle encoder_handle,
|
||||
int32_t samplesToAverage, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
encoder->SetSamplesToAverage(samplesToAverage, status);
|
||||
}
|
||||
|
||||
int32_t getEncoderSamplesToAverage(HalEncoderHandle encoder_handle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetSamplesToAverage(status);
|
||||
}
|
||||
|
||||
double getEncoderDecodingScaleFactor(HalEncoderHandle encoder_handle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->DecodingScaleFactor();
|
||||
}
|
||||
|
||||
double getEncoderDistancePerPulse(HalEncoderHandle encoder_handle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetDistancePerPulse();
|
||||
}
|
||||
|
||||
EncoderEncodingType getEncoderEncodingType(HalEncoderHandle encoder_handle,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return HAL_Encoder_k4X; // default to k4X
|
||||
}
|
||||
return encoder->GetEncodingType();
|
||||
}
|
||||
|
||||
void setEncoderIndexSource(HalEncoderHandle encoder_handle, uint32_t pin,
|
||||
uint8_t analogTrigger, EncoderIndexingType type,
|
||||
int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return;
|
||||
}
|
||||
encoder->SetIndexSource(pin, analogTrigger, type, status);
|
||||
}
|
||||
|
||||
int32_t getEncoderFPGAIndex(HalEncoderHandle encoder_handle, int32_t* status) {
|
||||
auto encoder = encoderHandles.Get(encoder_handle);
|
||||
if (encoder == nullptr) {
|
||||
*status = PARAMETER_OUT_OF_RANGE;
|
||||
return 0;
|
||||
}
|
||||
return encoder->GetFPGAIndex();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user