📄 cencoder.cpp
字号:
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#include "Encoder.h"
#include "SensorBase.h"
#include "DigitalModule.h"
#include "CEncoder.h"
static Encoder* encoders[SensorBase::kDigitalModules][SensorBase::kDigitalChannels];
static bool initialized = false;
/**
* Allocate the resources associated with this encoder.
* Allocate an Encoder object and cache the value in the associated table to find it
* in the future.
*
* @param aSlot The digital module slot for the A Channel on the encoder
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bSlot The digital module slot for the B Channel on the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder */
static Encoder *AllocateEncoder(UINT32 aSlot, UINT32 aChannel, UINT32 bSlot, UINT32 bChannel)
{
Encoder *encoder;
if (!initialized)
{
for (unsigned slot = 0; slot < SensorBase::kDigitalModules; slot++)
for (unsigned channel = 0; channel < SensorBase::kDigitalChannels; channel++)
encoders[slot][channel] = NULL;
initialized = true;
}
// check if the channel and slots are valid values
if (!SensorBase::CheckDigitalModule(aSlot)
|| !SensorBase::CheckDigitalChannel(aChannel)
|| !SensorBase::CheckDigitalModule(bSlot)
|| !SensorBase::CheckDigitalChannel(bChannel)) return NULL;
// check if nothing has been allocated to that pair of channels
if (encoders[DigitalModule::SlotToIndex(aSlot)][aChannel - 1] == NULL
&& encoders[DigitalModule::SlotToIndex(bSlot)][bChannel - 1] == NULL)
{
// allocate an encoder and put it into both slots
encoder = new Encoder(aSlot, aChannel, bSlot, bChannel);
encoders[DigitalModule::SlotToIndex(aSlot)][aChannel - 1] = encoder;
encoders[DigitalModule::SlotToIndex(bSlot)][bChannel - 1] = encoder;
return encoder;
}
// if there was the same encoder object allocated to both channels, return it
if ((encoder = encoders[DigitalModule::SlotToIndex(aSlot)][aChannel - 1]) ==
encoders[DigitalModule::SlotToIndex(bSlot)][bChannel - 1])
return encoder;
// Otherwise, one of the channels is allocated and the other isn't, so this is a
// resource allocation error.
return NULL;
}
/**
* Allocate the resources associated with this encoder.
* Allocate an Encoder object and cache the value in the associated table to find it
* in the future.
*
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
static Encoder *AllocateEncoder(UINT32 aChannel, UINT32 bChannel)
{
return AllocateEncoder(SensorBase::GetDefaultDigitalModule(), aChannel,
SensorBase::GetDefaultDigitalModule(), bChannel);
}
/**
* Start the encoder counting.
* * @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
void StartEncoder(UINT32 aChannel, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aChannel, bChannel);
if (encoder != NULL)
{
encoder->Start();
}
}
/**
* Start the encoder counting.
* * @param aSlot The digital module slot for the A Channel on the encoder
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bSlot The digital module slot for the B Channel on the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
void StartEncoder(UINT32 aSlot, UINT32 aChannel, UINT32 bSlot, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aSlot, aChannel, bSlot, bChannel);
if (encoder != NULL)
{
encoder->Start();
}
}
/**
* Gets the current count.
* Returns the current count on the Encoder.
* This method compensates for the decoding type.
* * @deprecated Use GetEncoderDistance() in favor of this method. This returns unscaled pulses and GetDistance() scales using value from SetEncoderDistancePerPulse().
*
* @return Current count from the Encoder.
*
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
INT32 GetEncoder(UINT32 aChannel, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aChannel, bChannel);
if (encoder != NULL)
return encoder->Get();
else
return 0;
}
/**
* Gets the current count.
* Returns the current count on the Encoder.
* This method compensates for the decoding type.
*
* @deprecated Use GetEncoderDistance() in favor of this method. This returns unscaled pulses and GetDistance() scales using value from SetEncoderDistancePerPulse().
*
* @return Current count from the Encoder.
*
* @param aSlot The digital module slot for the A Channel on the encoder
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bSlot The digital module slot for the B Channel on the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
INT32 GetEncoder(UINT32 aSlot, UINT32 aChannel, UINT32 bSlot, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aSlot, aChannel, bSlot, bChannel);
if (encoder != NULL)
return encoder->Get();
else
return 0;
}
/**
* Reset the count for the encoder object.
* Resets the count to zero.
*
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
void ResetEncoder(UINT32 aChannel, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aChannel, bChannel);
if (encoder != NULL)
encoder->Reset();
}
/**
* Reset the count for the encoder object.
* Resets the count to zero.
*
* @param aSlot The digital module slot for the A Channel on the encoder
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bSlot The digital module slot for the B Channel on the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
void ResetEncoder(UINT32 aSlot, UINT32 aChannel, UINT32 bSlot, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aSlot, aChannel, bSlot, bChannel);
if (encoder != NULL)
encoder->Reset();
}
/**
* Stops the counting for the encoder object.
* Stops the counting for the Encoder. It still retains the count, but it doesn't change
* with pulses until it is started again.
*
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
void StopEncoder(UINT32 aChannel, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aChannel, bChannel);
if (encoder != NULL)
encoder->Stop();
}
/**
* Stops the counting for the encoder object.
* Stops the counting for the Encoder. It still retains the count, but it doesn't change
* with pulses until it is started again.
*
* @param aSlot The digital module slot for the A Channel on the encoder
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bSlot The digital module slot for the B Channel on the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
void StopEncoder(UINT32 aSlot, UINT32 aChannel, UINT32 bSlot, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aSlot, aChannel, bSlot, bChannel);
if (encoder != NULL)
encoder->Stop();
}
/**
* 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 GetEncoderRate() in favor of this method. This returns unscaled periods and GetEncoderRate() scales using value from SetEncoderDistancePerPulse().
*
* @return Period in seconds of the most recent pulse.
*
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
double GetEncoderPeriod(UINT32 aChannel, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aChannel, bChannel);
if (encoder != NULL)
return encoder->GetPeriod();
else
return 0.0;
}
/**
* 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 GetEncoderRate() in favor of this method. This returns unscaled periods and GetEncoderRate() scales using value from SetEncoderDistancePerPulse().
*
* @return Period in seconds of the most recent pulse.
*
* @param aSlot The digital module slot for the A Channel on the encoder
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bSlot The digital module slot for the B Channel on the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
double GetEncoderPeriod(UINT32 aSlot, UINT32 aChannel, UINT32 bSlot, UINT32 bChannel)
{
Encoder *encoder = AllocateEncoder(aSlot, aChannel, bSlot, bChannel);
if (encoder != NULL)
return encoder->GetPeriod();
else
return 0.0;
}
/**
* 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 SetEncoderMinRate() in favor of this method. This takes unscaled periods and SetMinEncoderRate() scales using value from SetEncoderDistancePerPulse().
*
* @param maxPeriod The maximum time between rising and falling edges before the FPGA will
* report the device stopped. This is expressed in seconds.
*
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
void SetMaxEncoderPeriod(UINT32 aChannel, UINT32 bChannel, double maxPeriod)
{
Encoder *encoder = AllocateEncoder(aChannel, bChannel);
if (encoder != NULL)
encoder->SetMaxPeriod(maxPeriod);
}
/**
* 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 SetEncoderMinRate() in favor of this method. This takes unscaled periods and SetMinEncoderRate() scales using value from SetEncoderDistancePerPulse().
*
* @param maxPeriod The maximum time between rising and falling edges before the FPGA will
* report the device stopped. This is expressed in seconds.
*
* @param aSlot The digital module slot for the A Channel on the encoder
* @param aChannel The channel on the digital module for the A Channel of the encoder
* @param bSlot The digital module slot for the B Channel on the encoder
* @param bChannel The channel on the digital module for the B Channel of the encoder
*/
void SetMaxEncoderPeriod(UINT32 aSlot, UINT32 aChannel, UINT32 bSlot, UINT32 bChannel, double maxPeriod)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -