Moved C++ comments from source files to headers (#1111)

Also sorted functions in C++ sources to match order in related headers.
This commit is contained in:
Tyler Veness
2018-05-31 20:47:15 -07:00
committed by Peter Johnson
parent d9971a705a
commit 8c680a26f8
234 changed files with 9936 additions and 9309 deletions

View File

@@ -15,12 +15,6 @@
using namespace frc;
/**
* Creates a new vision runner. It will take images from the {@code
* videoSource}, and call the virtual DoProcess() method.
*
* @param videoSource the video source to use to supply images for the pipeline
*/
VisionRunnerBase::VisionRunnerBase(cs::VideoSource videoSource)
: m_image(std::make_unique<cv::Mat>()),
m_cvSink("VisionRunner CvSink"),
@@ -31,19 +25,6 @@ VisionRunnerBase::VisionRunnerBase(cs::VideoSource videoSource)
// Located here and not in header due to cv::Mat forward declaration.
VisionRunnerBase::~VisionRunnerBase() {}
/**
* Runs the pipeline one time, giving it the next image from the video source
* specified in the constructor. This will block until the source either has an
* image or throws an error. If the source successfully supplied a frame, the
* pipeline's image input will be set, the pipeline will run, and the listener
* specified in the constructor will be called to notify it that the pipeline
* ran. This must be run in a dedicated thread, and cannot be used in the main
* robot thread because it will freeze the robot program.
*
* <p>This method is exposed to allow teams to add additional functionality or
* have their own ways to run the pipeline. Most teams, however, should just
* use {@link #runForever} in its own thread using a std::thread.</p>
*/
void VisionRunnerBase::RunOnce() {
auto csShared = frc::GetCameraServerShared();
auto res = csShared->GetRobotMainThreadId();
@@ -61,13 +42,6 @@ void VisionRunnerBase::RunOnce() {
}
}
/**
* A convenience method that calls {@link #runOnce()} in an infinite loop. This
* must be run in a dedicated thread, and cannot be used in the main robot
* thread because it will freeze the robot program.
*
* <strong>Do not call this method directly from the main thread.</strong>
*/
void VisionRunnerBase::RunForever() {
auto csShared = frc::GetCameraServerShared();
auto res = csShared->GetRobotMainThreadId();
@@ -82,7 +56,4 @@ void VisionRunnerBase::RunForever() {
}
}
/**
* Stop a RunForever() loop.
*/
void VisionRunnerBase::Stop() { m_enabled = false; }

View File

@@ -21,16 +21,47 @@ namespace frc {
*/
class VisionRunnerBase {
public:
/**
* Creates a new vision runner. It will take images from the {@code
* videoSource}, and call the virtual DoProcess() method.
*
* @param videoSource the video source to use to supply images for the
* pipeline
*/
explicit VisionRunnerBase(cs::VideoSource videoSource);
~VisionRunnerBase();
VisionRunnerBase(const VisionRunnerBase&) = delete;
VisionRunnerBase& operator=(const VisionRunnerBase&) = delete;
/**
* Runs the pipeline one time, giving it the next image from the video source
* specified in the constructor. This will block until the source either has
* an image or throws an error. If the source successfully supplied a frame,
* the pipeline's image input will be set, the pipeline will run, and the
* listener specified in the constructor will be called to notify it that the
* pipeline ran. This must be run in a dedicated thread, and cannot be used in
* the main robot thread because it will freeze the robot program.
*
* <p>This method is exposed to allow teams to add additional functionality or
* have their own ways to run the pipeline. Most teams, however, should just
* use {@link #runForever} in its own thread using a std::thread.</p>
*/
void RunOnce();
/**
* A convenience method that calls {@link #runOnce()} in an infinite loop.
* This must be run in a dedicated thread, and cannot be used in the main
* robot thread because it will freeze the robot program.
*
* <strong>Do not call this method directly from the main thread.</strong>
*/
void RunForever();
/**
* Stop a RunForever() loop.
*/
void Stop();
protected:

View File

@@ -198,10 +198,6 @@ static double unpackAxis(int16_t raw) {
extern "C" {
/**
* Set the accelerometer to active or standby mode. It must be in standby
* mode to change any configuration.
*/
void HAL_SetAccelerometerActive(HAL_Bool active) {
initializeAccelerometer();
@@ -210,10 +206,6 @@ void HAL_SetAccelerometerActive(HAL_Bool active) {
writeRegister(kReg_CtrlReg1, ctrlReg1 | (active ? 1 : 0));
}
/**
* Set the range of values that can be measured (either 2, 4, or 8 g-forces).
* The accelerometer should be in standby mode when this is called.
*/
void HAL_SetAccelerometerRange(HAL_AccelerometerRange range) {
initializeAccelerometer();
@@ -224,11 +216,6 @@ void HAL_SetAccelerometerRange(HAL_AccelerometerRange range) {
writeRegister(kReg_XYZDataCfg, xyzDataCfg | range);
}
/**
* Get the x-axis acceleration
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerX(void) {
initializeAccelerometer();
@@ -237,11 +224,6 @@ double HAL_GetAccelerometerX(void) {
return unpackAxis(raw);
}
/**
* Get the y-axis acceleration
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerY(void) {
initializeAccelerometer();
@@ -250,11 +232,6 @@ double HAL_GetAccelerometerY(void) {
return unpackAxis(raw);
}
/**
* Get the z-axis acceleration
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerZ(void) {
initializeAccelerometer();

View File

@@ -20,12 +20,6 @@ void InitializeAnalogAccumulator() {}
extern "C" {
/**
* Is the channel attached to an accumulator.
*
* @param analogPortHandle Handle to the analog port.
* @return The analog channel is attached to an accumulator.
*/
HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -39,11 +33,6 @@ HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
return false;
}
/**
* Initialize the accumulator.
*
* @param analogPortHandle Handle to the analog port.
*/
void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
if (!HAL_IsAccumulatorChannel(analogPortHandle, status)) {
@@ -54,11 +43,6 @@ void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
HAL_ResetAccumulator(analogPortHandle, status);
}
/**
* Resets the accumulator to the initial value.
*
* @param analogPortHandle Handle to the analog port.
*/
void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -73,21 +57,6 @@ void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
port->accumulator->strobeReset(status);
}
/**
* Set the center value of the accumulator.
*
* The center value is subtracted from each A/D value before it is added to the
* accumulator. This is used for the center value of devices like gyros and
* accelerometers to make integration work and to take the device offset into
* account when integrating.
*
* This center value is based on the output of the oversampled and averaged
* source from channel 1. Because of this, any non-zero oversample bits will
* affect the size of the value for this field.
*
* @param analogPortHandle Handle to the analog port.
* @param center The center value of the accumulator.
*/
void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
int32_t center, int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -102,12 +71,6 @@ void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
port->accumulator->writeCenter(center, status);
}
/**
* Set the accumulator's deadband.
*
* @param analogPortHandle Handle to the analog port.
* @param deadband The deadband of the accumulator.
*/
void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
int32_t deadband, int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -122,15 +85,6 @@ void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
port->accumulator->writeDeadband(deadband, status);
}
/**
* Read the accumulated value.
*
* Read the value that has been accumulating on channel 1.
* The accumulator is attached after the oversample and average engine.
*
* @param analogPortHandle Handle to the analog port.
* @return The 64-bit value accumulated since the last Reset().
*/
int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -146,15 +100,6 @@ int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
return value;
}
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last
* Reset().
*
* @param analogPortHandle Handle to the analog port.
* @return The number of times samples from the channel were accumulated.
*/
int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -169,16 +114,6 @@ int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
return port->accumulator->readOutput_Count(status);
}
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* This function reads the value and count from the FPGA atomically.
* This can be used for averaging.
*
* @param analogPortHandle Handle to the analog port.
* @param value Pointer to the 64-bit accumulated output.
* @param count Pointer to the number of accumulation cycles.
*/
void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
int64_t* value, int64_t* count, int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);

View File

@@ -27,11 +27,6 @@ using namespace hal;
extern "C" {
/**
* Initialize the analog input port using the given port object.
*
* @param portHandle Handle to the port to initialize.
*/
HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
int32_t* status) {
hal::init::CheckInit();
@@ -70,41 +65,17 @@ HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
return handle;
}
/**
* @param analogPortHandle Handle to the analog port.
*/
void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle) {
// no status, so no need to check for a proper free.
analogInputHandles->Free(analogPortHandle);
}
/**
* Check that the analog module number is valid.
*
* @param module The analog module number.
* @return Analog module is valid and present
*/
HAL_Bool HAL_CheckAnalogModule(int32_t module) { return module == 1; }
/**
* Check that the analog output channel number is value.
* Verify that the analog channel number is one of the legal channel numbers.
* Channel numbers are 0-based.
*
* @param channel The analog output channel number.
* @return Analog channel is valid
*/
HAL_Bool HAL_CheckAnalogInputChannel(int32_t channel) {
return channel < kNumAnalogInputs && channel >= 0;
}
/**
* Set the sample rate.
*
* This is a global setting for the Athena and effects all channels.
*
* @param samplesPerSecond The number of samples per channel per second.
*/
void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status) {
// TODO: This will change when variable size scan lists are implemented.
// TODO: Need double comparison with epsilon.
@@ -114,14 +85,6 @@ void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status) {
setAnalogSampleRate(samplesPerSecond, status);
}
/**
* Get the current sample rate.
*
* This assumes one entry in the scan list.
* This is a global setting for the Athena and effects all channels.
*
* @return Sample rate.
*/
double HAL_GetAnalogSampleRate(int32_t* status) {
initializeAnalog(status);
if (*status != 0) return 0;
@@ -131,16 +94,6 @@ double HAL_GetAnalogSampleRate(int32_t* status) {
return static_cast<double>(kTimebase) / static_cast<double>(ticksPerSample);
}
/**
* Set the number of averaging bits.
*
* This sets the number of averaging bits. The actual number of averaged samples
* is 2**bits. Use averaging to improve the stability of your measurement at the
* expense of sampling rate. The averaging is done automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to configure.
* @param bits Number of bits to average.
*/
void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
int32_t bits, int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -152,15 +105,6 @@ void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
status);
}
/**
* Get the number of averaging bits.
*
* This gets the number of averaging bits from the FPGA. The actual number of
* averaged samples is 2**bits. The averaging is done automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @return Bits to average.
*/
int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -172,17 +116,6 @@ int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
return result;
}
/**
* Set the number of oversample bits.
*
* This sets the number of oversample bits. The actual number of oversampled
* values is 2**bits. Use oversampling to improve the resolution of your
* measurements at the expense of sampling rate. The oversampling is done
* automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @param bits Number of bits to oversample.
*/
void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
int32_t bits, int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -194,16 +127,6 @@ void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
static_cast<uint8_t>(bits), status);
}
/**
* Get the number of oversample bits.
*
* This gets the number of oversample bits from the FPGA. The actual number of
* oversampled values is 2**bits. The oversampling is done automatically in the
* FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @return Bits to oversample.
*/
int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -215,16 +138,6 @@ int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
return result;
}
/**
* Get a sample straight from the channel on this module.
*
* The sample is a 12-bit value representing the 0V to 5V range of the A/D
* converter in the module. The units are in A/D converter codes. Use
* GetVoltage() to get the analog value in calibrated units.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A sample straight from the channel on this module.
*/
int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -243,20 +156,6 @@ int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
return static_cast<int16_t>(analogInputSystem->readOutput(status));
}
/**
* Get a sample from the output of the oversample and average engine for the
* channel.
*
* The sample is 12-bit + the value configured in SetOversampleBits().
* The value configured in SetAverageBits() will cause this value to be averaged
* 2**bits number of samples. This is not a sliding window. The sample will not
* change until 2**(OversamplBits + AverageBits) samples have been acquired from
* the module on this channel. Use GetAverageVoltage() to get the analog value
* in calibrated units.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A sample from the oversample and average engine for the channel.
*/
int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -274,62 +173,6 @@ int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
return static_cast<int32_t>(analogInputSystem->readOutput(status));
}
/**
* Get a scaled sample straight from the channel on this module.
*
* The value is scaled to units of Volts using the calibrated scaling data from
* GetLSBWeight() and GetOffset().
*
* @param analogPortHandle Handle to the analog port to use.
* @return A scaled sample straight from the channel on this module.
*/
double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
int32_t value = HAL_GetAnalogValue(analogPortHandle, status);
int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
double voltage = LSBWeight * 1.0e-9 * value - offset * 1.0e-9;
return voltage;
}
/**
* Get a scaled sample from the output of the oversample and average engine for
* the channel.
*
* The value is scaled to units of Volts using the calibrated scaling data from
* GetLSBWeight() and GetOffset(). Using oversampling will cause this value to
* be higher resolution, but it will update more slowly. Using averaging will
* cause this value to be more stable, but it will update more slowly.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A scaled sample from the output of the oversample and average engine
* for the channel.
*/
double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
int32_t value = HAL_GetAnalogAverageValue(analogPortHandle, status);
int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
int32_t oversampleBits =
HAL_GetAnalogOversampleBits(analogPortHandle, status);
double voltage =
LSBWeight * 1.0e-9 * value / static_cast<double>(1 << oversampleBits) -
offset * 1.0e-9;
return voltage;
}
/**
* Convert a voltage to a raw value for a specified channel.
*
* This process depends on the calibration of each channel, so the channel must
* be specified.
*
* @todo This assumes raw values. Oversampling not supported as is.
*
* @param analogPortHandle Handle to the analog port to use.
* @param voltage The voltage to convert.
* @return The raw value for the channel.
*/
int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
double voltage, int32_t* status) {
if (voltage > 5.0) {
@@ -347,16 +190,28 @@ int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
return value;
}
/**
* Get the factory scaling least significant bit weight constant.
* The least significant bit weight constant for the channel that was calibrated
* in manufacturing and stored in an eeprom in the module.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @param analogPortHandle Handle to the analog port to use.
* @return Least significant bit weight.
*/
double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
int32_t value = HAL_GetAnalogValue(analogPortHandle, status);
int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
double voltage = LSBWeight * 1.0e-9 * value - offset * 1.0e-9;
return voltage;
}
double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
int32_t value = HAL_GetAnalogAverageValue(analogPortHandle, status);
int32_t LSBWeight = HAL_GetAnalogLSBWeight(analogPortHandle, status);
int32_t offset = HAL_GetAnalogOffset(analogPortHandle, status);
int32_t oversampleBits =
HAL_GetAnalogOversampleBits(analogPortHandle, status);
double voltage =
LSBWeight * 1.0e-9 * value / static_cast<double>(1 << oversampleBits) -
offset * 1.0e-9;
return voltage;
}
int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);
@@ -369,16 +224,6 @@ int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
return lsbWeight;
}
/**
* Get the factory scaling offset constant.
* The offset constant for the channel that was calibrated in manufacturing and
* stored in an eeprom in the module.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @param analogPortHandle Handle to the analog port to use.
* @return Offset constant.
*/
int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
int32_t* status) {
auto port = analogInputHandles->Get(analogPortHandle);

View File

@@ -41,9 +41,6 @@ void InitializeAnalogInternal() {
}
} // namespace init
/**
* Initialize the analog System.
*/
void initializeAnalog(int32_t* status) {
hal::init::CheckInit();
if (analogSystemInitialized) return;
@@ -56,41 +53,22 @@ void initializeAnalog(int32_t* status) {
analogSystemInitialized = true;
}
/**
* Return the number of channels on the module in use.
*
* @return Active channels.
*/
int32_t getAnalogNumActiveChannels(int32_t* status) {
int32_t scanSize = analogInputSystem->readConfig_ScanSize(status);
if (scanSize == 0) return 8;
return scanSize;
}
/**
* Get the number of active channels.
*
* This is an internal function to allow the atomic update of both the
* number of active channels and the sample rate.
*
* When the number of channels changes, use the new value. Otherwise,
* return the curent value.
*
* @return Value to write to the active channels field.
*/
void setAnalogNumChannelsToActivate(int32_t channels) {
analogNumChannelsToActivate = channels;
}
int32_t getAnalogNumChannelsToActivate(int32_t* status) {
if (analogNumChannelsToActivate == 0)
return getAnalogNumActiveChannels(status);
return analogNumChannelsToActivate;
}
/**
* Set the sample rate.
*
* This is a global setting for the Athena and effects all channels.
*
* @param samplesPerSecond The number of samples per channel per second.
*/
void setAnalogSampleRate(double samplesPerSecond, int32_t* status) {
// TODO: This will change when variable size scan lists are implemented.
// TODO: Need double comparison with epsilon.
@@ -119,17 +97,4 @@ void setAnalogSampleRate(double samplesPerSecond, int32_t* status) {
setAnalogNumChannelsToActivate(0);
}
/**
* Set the number of active channels.
*
* Store the number of active channels to set. Don't actually commit to
* hardware
* until SetSampleRate().
*
* @param channels Number of active channels.
*/
void setAnalogNumChannelsToActivate(int32_t channels) {
analogNumChannelsToActivate = channels;
}
} // namespace hal

View File

@@ -40,10 +40,49 @@ extern IndexedHandleResource<HAL_AnalogInputHandle, hal::AnalogPort,
kNumAnalogInputs, HAL_HandleEnum::AnalogInput>*
analogInputHandles;
int32_t getAnalogNumActiveChannels(int32_t* status);
int32_t getAnalogNumChannelsToActivate(int32_t* status);
void setAnalogNumChannelsToActivate(int32_t channels);
void setAnalogSampleRate(double samplesPerSecond, int32_t* status);
/**
* Initialize the analog System.
*/
void initializeAnalog(int32_t* status);
/**
* Return the number of channels on the module in use.
*
* @return Active channels.
*/
int32_t getAnalogNumActiveChannels(int32_t* status);
/**
* Set the number of active channels.
*
* Store the number of active channels to set. Don't actually commit to
* hardware
* until SetSampleRate().
*
* @param channels Number of active channels.
*/
void setAnalogNumChannelsToActivate(int32_t channels);
/**
* Get the number of active channels.
*
* This is an internal function to allow the atomic update of both the
* number of active channels and the sample rate.
*
* When the number of channels changes, use the new value. Otherwise,
* return the curent value.
*
* @return Value to write to the active channels field.
*/
int32_t getAnalogNumChannelsToActivate(int32_t* status);
/**
* Set the sample rate.
*
* This is a global setting for the Athena and effects all channels.
*
* @param samplesPerSecond The number of samples per channel per second.
*/
void setAnalogSampleRate(double samplesPerSecond, int32_t* status);
} // namespace hal

View File

@@ -41,9 +41,6 @@ void InitializeAnalogOutput() {
extern "C" {
/**
* Initialize the analog output port using the given port object.
*/
HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
int32_t* status) {
hal::init::CheckInit();
@@ -78,17 +75,6 @@ void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle) {
analogOutputHandles->Free(analogOutputHandle);
}
/**
* Check that the analog output channel number is value.
* Verify that the analog channel number is one of the legal channel numbers.
* Channel numbers are 0-based.
*
* @return Analog channel is valid
*/
HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel) {
return channel < kNumAnalogOutputs && channel >= 0;
}
void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
double voltage, int32_t* status) {
auto port = analogOutputHandles->Get(analogOutputHandle);
@@ -120,4 +106,8 @@ double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
return rawValue * 5.0 / 0x1000;
}
HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel) {
return channel < kNumAnalogOutputs && channel >= 0;
}
} // extern "C"

View File

@@ -94,10 +94,6 @@ void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
trigger->trigger->writeUpperLimit(upper, status);
}
/**
* Set the upper and lower limits of the analog trigger.
* The limits are given as floating point voltage values.
*/
void HAL_SetAnalogTriggerLimitsVoltage(
HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
int32_t* status) {
@@ -118,11 +114,6 @@ void HAL_SetAnalogTriggerLimitsVoltage(
HAL_GetAnalogVoltsToValue(trigger->analogHandle, upper, status), status);
}
/**
* Configure the analog trigger to use the averaged vs. raw values.
* If the value is true, then the averaged value is selected for the analog
* trigger, otherwise the immediate value is used.
*/
void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_Bool useAveragedValue, int32_t* status) {
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
@@ -138,12 +129,6 @@ void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
trigger->trigger->writeSourceSelect_Averaged(useAveragedValue, status);
}
/**
* Configure the analog trigger to use a filtered value.
* The analog trigger will operate with a 3 point average rejection filter. This
* is designed to help with 360 degree pot applications for the period where the
* pot crosses through zero.
*/
void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_Bool useFilteredValue, int32_t* status) {
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
@@ -159,11 +144,6 @@ void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
trigger->trigger->writeSourceSelect_Filter(useFilteredValue, status);
}
/**
* Return the InWindow output of the analog trigger.
* True if the analog input is between the upper and lower limits.
* @return The InWindow output of the analog trigger.
*/
HAL_Bool HAL_GetAnalogTriggerInWindow(
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
@@ -174,13 +154,6 @@ HAL_Bool HAL_GetAnalogTriggerInWindow(
return trigger->trigger->readOutput_InHysteresis(trigger->index, status) != 0;
}
/**
* Return the TriggerState output of the analog trigger.
* True if above upper limit.
* False if below lower limit.
* If in Hysteresis, maintain previous state.
* @return The TriggerState output of the analog trigger.
*/
HAL_Bool HAL_GetAnalogTriggerTriggerState(
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status) {
auto trigger = analogTriggerHandles->Get(analogTriggerHandle);
@@ -191,10 +164,6 @@ HAL_Bool HAL_GetAnalogTriggerTriggerState(
return trigger->trigger->readOutput_OverLimit(trigger->index, status) != 0;
}
/**
* Get the state of the analog trigger output.
* @return The state of the analog trigger output.
*/
HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_AnalogTriggerType type,
int32_t* status) {

View File

@@ -77,10 +77,6 @@ void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
counter->counter->writeTimerConfig_AverageSize(size, status);
}
/**
* Set the source object that causes the counter to count up.
* Set the up counting DigitalSource.
*/
void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
@@ -115,10 +111,6 @@ void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
counter->counter->strobeReset(status);
}
/**
* Set the edge sensitivity on an up counting source.
* Set the up source to either detect rising edges or falling edges.
*/
void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {
@@ -131,9 +123,6 @@ void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
counter->counter->writeConfig_UpFallingEdge(fallingEdge, status);
}
/**
* Disable the up counting source to the counter.
*/
void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -148,10 +137,6 @@ void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle,
counter->counter->writeConfig_UpSource_AnalogTrigger(false, status);
}
/**
* Set the source object that causes the counter to count down.
* Set the down counting DigitalSource.
*/
void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
@@ -189,10 +174,6 @@ void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
counter->counter->strobeReset(status);
}
/**
* Set the edge sensitivity on a down counting source.
* Set the down source to either detect rising edges or falling edges.
*/
void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status) {
@@ -205,9 +186,6 @@ void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
counter->counter->writeConfig_DownFallingEdge(fallingEdge, status);
}
/**
* Disable the down counting source to the counter.
*/
void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -222,10 +200,6 @@ void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
counter->counter->writeConfig_DownSource_AnalogTrigger(false, status);
}
/**
* Set standard up / down counting mode on this counter.
* Up and down counts are sourced independently from two inputs.
*/
void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -236,11 +210,6 @@ void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle,
counter->counter->writeConfig_Mode(HAL_Counter_kTwoPulse, status);
}
/**
* Set external direction mode on this counter.
* Counts are sourced on the Up counter input.
* The Down counter input represents the direction to count.
*/
void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -251,10 +220,6 @@ void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
counter->counter->writeConfig_Mode(HAL_Counter_kExternalDirection, status);
}
/**
* Set Semi-period mode on this counter.
* Counts up on both rising and falling edges.
*/
void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
HAL_Bool highSemiPeriod, int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -267,13 +232,6 @@ void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
HAL_SetCounterUpdateWhenEmpty(counterHandle, false, status);
}
/**
* Configure the counter to count in up or down based on the length of the input
* pulse.
* This mode is most useful for direction sensitive gear tooth sensors.
* @param threshold The pulse length beyond which the counter counts the
* opposite direction. Units are seconds.
*/
void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
double threshold, int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -288,13 +246,6 @@ void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
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)
*/
int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -305,12 +256,6 @@ int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
return counter->counter->readTimerConfig_AverageSize(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 HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t samplesToAverage, int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -324,11 +269,6 @@ void HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
counter->counter->writeTimerConfig_AverageSize(samplesToAverage, status);
}
/**
* Reset the Counter to zero.
* Set the counter value to zero. This doesn't effect the running state of the
* counter, just sets the current value to zero.
*/
void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
@@ -338,11 +278,6 @@ void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
counter->counter->strobeReset(status);
}
/**
* Read the current counter value.
* Read the value at this instant. It may still be running, so it reflects the
* current value. Next time it is read, it might have a different value.
*/
int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
@@ -353,12 +288,6 @@ int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status) {
return value;
}
/*
* Get the Period of the most recent count.
* Returns the time interval of the most recent count. This can be used for
* velocity calculations to determine shaft speed.
* @returns The period of the last two pulses in units of seconds.
*/
double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
if (counter == nullptr) {
@@ -381,14 +310,6 @@ double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status) {
2.5e-8); // result * timebase (currently 25ns)
}
/**
* Set the maximum period where the device is still considered "moving".
* Sets the maximum period where the device is considered moving. This value is
* used to determine the "stopped" state of the counter using the GetStopped
* method.
* @param maxPeriod The maximum period where the counted device is considered
* moving in seconds.
*/
void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -400,19 +321,6 @@ void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
static_cast<uint32_t>(maxPeriod * 4.0e8), status);
}
/**
* Select whether you want to continue updating the event timer output when
* there are no samples captured. The output of the event timer has a buffer of
* periods that are averaged and posted to a register on the FPGA. When the
* timer detects that the event source has stopped (based on the MaxPeriod) the
* buffer of samples to be averaged is emptied. If you enable the update when
* empty, you will be notified of the stopped source and the event time will
* report 0 samples. If you disable update when empty, the most recent average
* will remain on the output until a new sample is acquired. You will never see
* 0 samples output (except when there have been no events since an FPGA reset)
* and you will likely not see the stopped bit become true (since it is updated
* at the end of an average and there are no samples to average).
*/
void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
HAL_Bool enabled, int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -423,14 +331,6 @@ void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
counter->counter->writeTimerConfig_UpdateWhenEmpty(enabled, status);
}
/**
* Determine if the clock is stopped.
* Determine if the clocked input is stopped based on the MaxPeriod value set
* using the SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the
* device (and counter) are assumed to be stopped and it returns true.
* @return Returns true if the most recent counter period exceeds the MaxPeriod
* value set by SetMaxPeriod.
*/
HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -441,10 +341,6 @@ HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
return counter->counter->readTimerOutput_Stalled(status);
}
/**
* The last direction the counter value changed.
* @return The last direction the counter value changed.
*/
HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
int32_t* status) {
auto counter = counterHandles->Get(counterHandle);
@@ -456,12 +352,6 @@ HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
return value;
}
/**
* Set the Counter to return reversed sensing on the direction.
* This allows counters to change the direction they are counting in the case of
* 1X and 2X quadrature encoding only. Any other counter mode isn't supported.
* @param reverseDirection true if the value counted should be negated.
*/
void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
HAL_Bool reverseDirection,
int32_t* status) {

View File

@@ -42,9 +42,6 @@ void InitializeDIO() {
extern "C" {
/**
* Create a new instance of a digital port.
*/
HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
HAL_Bool input, int32_t* status) {
hal::init::CheckInit();
@@ -163,12 +160,6 @@ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
}
}
/**
* Allocate a DO PWM Generator.
* Allocate PWM generators so that they are not accidentally reused.
*
* @return PWM Generator handle
*/
HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
auto handle = digitalPWMHandles->Allocate();
if (handle == HAL_kInvalidHandle) {
@@ -186,24 +177,10 @@ HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
return handle;
}
/**
* Free the resource associated with a DO PWM generator.
*
* @param pwmGenerator The pwmGen to free that was allocated with
* allocateDigitalPWM()
*/
void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
digitalPWMHandles->Free(pwmGenerator);
}
/**
* Change the frequency of the DO PWM generator.
*
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is
* logarithmic.
*
* @param rate The frequency to output all digital output PWM signals.
*/
void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
// Currently rounding in the log rate domain... heavy weight toward picking a
// higher freq.
@@ -215,12 +192,6 @@ void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
digitalSystem->writePWMPeriodPower(pwmPeriodPower, status);
}
/**
* Configure the duty-cycle of the PWM generator
*
* @param pwmGenerator The generator index reserved by allocateDigitalPWM()
* @param dutyCycle The percent duty cycle to output [0..1].
*/
void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
double dutyCycle, int32_t* status) {
auto port = digitalPWMHandles->Get(pwmGenerator);
@@ -250,12 +221,6 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
}
}
/**
* Configure which DO channel the PWM signal is output on
*
* @param pwmGenerator The generator index reserved by allocateDigitalPWM()
* @param channel The Digital Output channel to output on
*/
void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
int32_t channel, int32_t* status) {
auto port = digitalPWMHandles->Get(pwmGenerator);
@@ -275,14 +240,6 @@ void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
digitalSystem->writePWMOutputSelect(id, channel, status);
}
/**
* Write a digital I/O bit to the FPGA.
* Set a single value on a digital I/O channel.
*
* @param channel The Digital I/O channel
* @param value The state to set the digital channel (if it is configured as an
* output)
*/
void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
@@ -324,12 +281,6 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
}
}
/**
* Set direction of a DIO channel.
*
* @param channel The Digital I/O channel
* @param input true to set input, false for output
*/
void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
@@ -368,13 +319,6 @@ void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
}
}
/**
* Read a digital I/O bit from the FPGA.
* Get a single value from a digital I/O channel.
*
* @param channel The digital I/O channel
* @return The state of the specified channel
*/
HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -396,13 +340,6 @@ HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
}
}
/**
* Read the direction of a the Digital I/O lines
* A 1 bit means output and a 0 bit means input.
*
* @param channel The digital I/O channel
* @return The direction of the specified channel
*/
HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -427,14 +364,6 @@ HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
}
}
/**
* Generate a single pulse.
* Write a pulse to the specified digital output channel. There can only be a
* single pulse going at any time.
*
* @param channel The Digital Output channel that the pulse should be output on
* @param pulseLength The active length of the pulse (in seconds)
*/
void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
@@ -459,11 +388,6 @@ void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
digitalSystem->writePulse(pulse, status);
}
/**
* Check a DIO line to see if it is currently generating a pulse.
*
* @return A pulse is in progress
*/
HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -481,11 +405,6 @@ HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
}
}
/**
* Check if any DIO line is currently generating a pulse.
*
* @return A pulse on some line is in progress
*/
HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
initializeDigital(status);
if (*status != 0) return false;
@@ -494,14 +413,6 @@ HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
pulseRegister.SPIPort != 0;
}
/**
* Write the filter index from the FPGA.
* Set the filter index used to filter out short pulses.
*
* @param dioPortHandle Handle to the digital I/O channel
* @param filterIndex The filter index. Must be in the range 0 - 3, where 0
* means "none" and 1 - 3 means filter # filterIndex - 1.
*/
void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
@@ -523,14 +434,6 @@ void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
}
}
/**
* Read the filter index from the FPGA.
* Get the filter index used to filter out short pulses.
*
* @param dioPortHandle Handle to the digital I/O channel
* @return filterIndex The filter index. Must be in the range 0 - 3,
* where 0 means "none" and 1 - 3 means filter # filterIndex - 1.
*/
int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -551,17 +454,6 @@ int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
}
}
/**
* Set the filter period for the specified filter index.
*
* Set the filter period in FPGA cycles. Even though there are 2 different
* filter index domains (MXP vs HDR), ignore that distinction for now since it
* compilicates the interface. That can be changed later.
*
* @param filterIndex The filter index, 0 - 2.
* @param value The number of cycles that the signal must not transition to be
* counted as a transition.
*/
void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status) {
initializeDigital(status);
if (*status != 0) return;
@@ -572,18 +464,6 @@ void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status) {
}
}
/**
* Get the filter period for the specified filter index.
*
* Get the filter period in FPGA cycles. Even though there are 2 different
* filter index domains (MXP vs HDR), ignore that distinction for now since it
* compilicates the interface. Set status to NiFpga_Status_SoftwareFault if the
* filter values miss-match.
*
* @param filterIndex The filter index, 0 - 2.
* @param value The number of cycles that the signal must not transition to be
* counted as a transition.
*/
int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status) {
initializeDigital(status);
if (*status != 0) return 0;

View File

@@ -67,9 +67,6 @@ int32_t ComputeDigitalMask(HAL_DigitalHandle handle, int32_t* status) {
}
} // namespace detail
/**
* Initialize the digital system.
*/
void initializeDigital(int32_t* status) {
hal::init::CheckInit();
static std::atomic_bool initialized{false};
@@ -135,32 +132,6 @@ void initializeDigital(int32_t* status) {
initialized = true;
}
/**
* Map SPI channel numbers from their physical number (27 to 31) to their
* position in the bit field.
*/
int32_t remapSPIChannel(int32_t channel) { return channel - 26; }
/**
* Map DIO channel numbers from their physical number (10 to 26) to their
* position in the bit field.
*/
int32_t remapMXPChannel(int32_t channel) { return channel - 10; }
int32_t remapMXPPWMChannel(int32_t channel) {
if (channel < 14) {
return channel - 10; // first block of 4 pwms (MXP 0-3)
} else {
return channel - 6; // block of PWMs after SPI
}
}
/**
* remap the digital source channel and set the module.
* If it's an analog trigger, determine the module from the high order routing
* channel else do normal digital input remapping based on channel number
* (MXP)
*/
bool remapDigitalSource(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
uint8_t& channel, uint8_t& module,
@@ -192,6 +163,18 @@ bool remapDigitalSource(HAL_Handle digitalSourceHandle,
}
}
int32_t remapMXPChannel(int32_t channel) { return channel - 10; }
int32_t remapMXPPWMChannel(int32_t channel) {
if (channel < 14) {
return channel - 10; // first block of 4 pwms (MXP 0-3)
} else {
return channel - 6; // block of PWMs after SPI
}
}
int32_t remapSPIChannel(int32_t channel) { return channel - 26; }
} // namespace hal
// Unused function here to test template compile.

View File

@@ -81,12 +81,33 @@ extern DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
extern wpi::mutex digitalDIOMutex;
/**
* Initialize the digital system.
*/
void initializeDigital(int32_t* status);
/**
* remap the digital source channel and set the module.
* If it's an analog trigger, determine the module from the high order routing
* channel else do normal digital input remapping based on channel number
* (MXP)
*/
bool remapDigitalSource(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
uint8_t& channel, uint8_t& module, bool& analogTrigger);
int32_t remapSPIChannel(int32_t channel);
int32_t remapMXPPWMChannel(int32_t channel);
/**
* Map DIO channel numbers from their physical number (10 to 26) to their
* position in the bit field.
*/
int32_t remapMXPChannel(int32_t channel);
int32_t remapMXPPWMChannel(int32_t channel);
/**
* Map SPI channel numbers from their physical number (27 to 31) to their
* position in the bit field.
*/
int32_t remapSPIChannel(int32_t channel);
} // namespace hal

View File

@@ -102,10 +102,6 @@ void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
fpgaEncoderHandles->Free(fpgaEncoderHandle);
}
/**
* Reset the Encoder distance to zero.
* Resets the current count to zero on the encoder.
*/
void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
@@ -116,12 +112,6 @@ void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
encoder->encoder->strobeReset(status);
}
/**
* Gets the fpga value from the encoder.
* The fpga value is the actual count unscaled by the 1x, 2x, or 4x scale
* factor.
* @return Current fpga count from the encoder
*/
int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
@@ -132,16 +122,6 @@ int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
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 HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
@@ -165,20 +145,6 @@ double HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
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 HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
double maxPeriod, int32_t* status) {
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
@@ -191,13 +157,6 @@ void HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
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.
*/
HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
@@ -208,10 +167,6 @@ HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
return encoder->encoder->readTimerOutput_Stalled(status) != 0;
}
/**
* The last direction the encoder value changed.
* @return The last direction the encoder value changed.
*/
HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status) {
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
@@ -222,12 +177,6 @@ HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
return encoder->encoder->readOutput_Direction(status);
}
/**
* 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 HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
HAL_Bool reverseDirection,
int32_t* status) {
@@ -239,12 +188,6 @@ void HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
encoder->encoder->writeConfig_Reverse(reverseDirection, 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 HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t samplesToAverage,
int32_t* status) {
@@ -259,12 +202,6 @@ void HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
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)
*/
int32_t HAL_GetFPGAEncoderSamplesToAverage(
HAL_FPGAEncoderHandle fpgaEncoderHandle, int32_t* status) {
auto encoder = fpgaEncoderHandles->Get(fpgaEncoderHandle);
@@ -275,10 +212,6 @@ int32_t HAL_GetFPGAEncoderSamplesToAverage(
return encoder->encoder->readTimerConfig_AverageSize(status);
}
/**
* Set an index source for an encoder, which is an input that resets the
* encoder's count.
*/
void HAL_SetFPGAEncoderIndexSource(HAL_FPGAEncoderHandle fpgaEncoderHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,

View File

@@ -20,26 +20,103 @@ HAL_FPGAEncoderHandle HAL_InitializeFPGAEncoder(
HAL_Bool reverseDirection, int32_t* index, int32_t* status);
void HAL_FreeFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status);
/**
* Reset the Encoder distance to zero.
* Resets the current count to zero on the encoder.
*/
void HAL_ResetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status);
/**
* Gets the fpga value from the encoder.
* The fpga value is the actual count unscaled by the 1x, 2x, or 4x scale
* factor.
* @return Current fpga count from the encoder
*/
int32_t HAL_GetFPGAEncoder(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status); // Raw value
/**
* 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 HAL_GetFPGAEncoderPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status);
/**
* 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 HAL_SetFPGAEncoderMaxPeriod(HAL_FPGAEncoderHandle fpgaEncoderHandle,
double maxPeriod, int32_t* 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.
*/
HAL_Bool HAL_GetFPGAEncoderStopped(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status);
/**
* The last direction the encoder value changed.
* @return The last direction the encoder value changed.
*/
HAL_Bool HAL_GetFPGAEncoderDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t* status);
/**
* 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 HAL_SetFPGAEncoderReverseDirection(HAL_FPGAEncoderHandle fpgaEncoderHandle,
HAL_Bool reverseDirection,
int32_t* 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 HAL_SetFPGAEncoderSamplesToAverage(HAL_FPGAEncoderHandle fpgaEncoderHandle,
int32_t samplesToAverage,
int32_t* 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)
*/
int32_t HAL_GetFPGAEncoderSamplesToAverage(
HAL_FPGAEncoderHandle fpgaEncoderHandle, int32_t* status);
/**
* Set an index source for an encoder, which is an input that resets the
* encoder's count.
*/
void HAL_SetFPGAEncoderIndexSource(HAL_FPGAEncoderHandle fpgaEncoderHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,

View File

@@ -146,17 +146,7 @@ int32_t HAL_GetJoystickButtons(int32_t joystickNum,
return FRC_NetworkCommunication_getJoystickButtons(
joystickNum, &buttons->buttons, &buttons->count);
}
/**
* Retrieve the Joystick Descriptor for particular slot
* @param desc [out] descriptor (data transfer object) to fill in. desc is
* filled in regardless of success. In other words, if descriptor is not
* available, desc is filled in with default values matching the init-values in
* Java and C++ Driverstation for when caller requests a too-large joystick
* index.
*
* @return error code reported from Network Comm back-end. Zero is good,
* nonzero is bad.
*/
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
HAL_JoystickDescriptor* desc) {
desc->isXbox = 0;
@@ -333,16 +323,8 @@ bool HAL_IsNewControlData(void) {
return true;
}
/**
* Waits for the newest DS packet to arrive. Note that this is a blocking call.
*/
void HAL_WaitForDSData(void) { HAL_WaitForDSDataTimeout(0); }
/**
* Waits for the newest DS packet to arrive. If timeout is <= 0, this will wait
* forever. Otherwise, it will wait until either a new packet, or the timeout
* time has passed. Returns true on new data, false on timeout.
*/
HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
auto timeoutTime =
std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
@@ -375,11 +357,6 @@ static void newDataOccur(uint32_t refNum) {
newDSDataAvailableCond->notify_all();
}
/*
* Call this to initialize the driver station communication. This will properly
* handle multiple calls. However note that this CANNOT be called from a library
* that interfaces with LabVIEW.
*/
void HAL_InitializeDriverStation(void) {
hal::init::CheckInit();
static std::atomic_bool initialized{false};
@@ -399,10 +376,6 @@ void HAL_InitializeDriverStation(void) {
initialized = true;
}
/*
* Releases the DS Mutex to allow proper shutdown of any threads that are
* waiting on it.
*/
void HAL_ReleaseDSMutex(void) { newDataOccur(refNumber); }
} // extern "C"

View File

@@ -84,9 +84,6 @@ HAL_PortHandle HAL_GetPort(int32_t channel) {
return createPortHandle(channel, 1);
}
/**
* @deprecated Uses module numbers
*/
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel) {
// Dont allow a number that wouldn't fit in a uint8_t
if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
@@ -215,16 +212,8 @@ const char* HAL_GetErrorMessage(int32_t code) {
}
}
/**
* Returns the runtime type of this HAL
*/
HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Athena; }
/**
* Return the FPGA Version number.
* For now, expect this to be competition year.
* @return FPGA Version number.
*/
int32_t HAL_GetFPGAVersion(int32_t* status) {
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
@@ -233,14 +222,6 @@ int32_t HAL_GetFPGAVersion(int32_t* status) {
return global->readVersion(status);
}
/**
* Return the FPGA Revision number.
* The format of the revision is 3 numbers.
* The 12 most significant bits are the Major Revision.
* the next 8 bits are the Minor Revision.
* The 12 least significant bits are the Build Number.
* @return FPGA Revision number.
*/
int64_t HAL_GetFPGARevision(int32_t* status) {
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
@@ -249,12 +230,6 @@ int64_t HAL_GetFPGARevision(int32_t* status) {
return global->readRevision(status);
}
/**
* Read the microsecond-resolution timer on the FPGA.
*
* @return The current time in microseconds according to the FPGA (since FPGA
* reset).
*/
uint64_t HAL_GetFPGATime(int32_t* status) {
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
@@ -273,10 +248,6 @@ uint64_t HAL_GetFPGATime(int32_t* status) {
return (upper2 << 32) + lower;
}
/**
* Get the state of the "USER" button on the roboRIO
* @return true if the button is currently pressed down
*/
HAL_Bool HAL_GetFPGAButton(int32_t* status) {
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
@@ -360,9 +331,6 @@ static bool killExistingProgram(int timeout, int mode) {
return true;
}
/**
* Call this to start up HAL. This is required for robot programs.
*/
HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
static std::atomic_bool initialized{false};
static wpi::mutex initializeMutex;

View File

@@ -41,11 +41,6 @@ void InitializeI2C() {}
extern "C" {
/*
* Initialize the I2C port. Opens the port if necessary and saves the handle.
* If opening the MXP port, also sets up the channel functions appropriately
* @param port The port to open, 0 for the on-board, 1 for the MXP.
*/
void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
hal::init::CheckInit();
initializeDigital(status);
@@ -90,18 +85,6 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
}
}
/**
* Generic transaction.
*
* This is a lower-level interface to the I2C hardware giving you more control
* over each transaction.
*
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
const uint8_t* dataToSend, int32_t sendSize,
uint8_t* dataReceived, int32_t receiveSize) {
@@ -133,17 +116,6 @@ int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
}
}
/**
* Execute a write transaction with the device.
*
* Write a single byte to a register on a device and wait until the
* transaction is complete.
*
* @param registerAddress The address of the register on the device to be
* written.
* @param data The byte to write to the register on the device.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
const uint8_t* dataToSend, int32_t sendSize) {
if (port > 1) {
@@ -170,19 +142,6 @@ int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
}
}
/**
* Execute a read transaction with the device.
*
* Read bytes from a device.
* Most I2C devices will auto-increment the register pointer internally allowing
* you to read consecutive registers on a device in a single transaction.
*
* @param registerAddress The register to read first in the transaction.
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from the
* device.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
int32_t count) {
if (port > 1) {

View File

@@ -123,13 +123,6 @@ void* HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle,
return param;
}
/**
* In synchronous mode, wait for the defined interrupt to occur.
* @param timeout Timeout in seconds
* @param ignorePrevious If true, ignore interrupts that happened before
* waitForInterrupt was called.
* @return The mask of interrupts that fired.
*/
int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
double timeout, HAL_Bool ignorePrevious,
int32_t* status) {
@@ -152,12 +145,6 @@ int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
return result;
}
/**
* Enable interrupts to occur on this input.
* Interrupts are disabled when the RequestInterrupt call is made. This gives
* time to do the setup of the other options before starting to field
* interrupts.
*/
void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles->Get(interruptHandle);
@@ -168,9 +155,6 @@ void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle,
anInterrupt->manager->enable(status);
}
/**
* Disable Interrupts without without deallocating structures.
*/
void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles->Get(interruptHandle);
@@ -181,11 +165,6 @@ void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
anInterrupt->manager->disable(status);
}
/**
* Return the timestamp for the rising interrupt that occurred most recently.
* This is in the same time domain as GetClock().
* @return Timestamp in seconds since boot.
*/
double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles->Get(interruptHandle);
@@ -197,11 +176,6 @@ double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
return timestamp * 1e-6;
}
/**
* Return the timestamp for the falling interrupt that occurred most recently.
* This is in the same time domain as GetClock().
* @return Timestamp in seconds since boot.
*/
double HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status) {
auto anInterrupt = interruptHandles->Get(interruptHandle);

View File

@@ -235,14 +235,6 @@ HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
return port->eliminateDeadband;
}
/**
* Set a PWM channel to the desired value. The values range from 0 to 255 and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The PWM value to set.
*/
void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
@@ -258,15 +250,6 @@ void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
}
}
/**
* Set a PWM channel to the desired scaled value. The values range from -1 to 1
* and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The scaled PWM value to set.
*/
void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
@@ -313,15 +296,6 @@ void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
HAL_SetPWMRaw(pwmPortHandle, rawValue, status);
}
/**
* Set a PWM channel to the desired position value. The values range from 0 to 1
* and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The scaled PWM value to set.
*/
void HAL_SetPWMPosition(HAL_DigitalHandle pwmPortHandle, double pos,
int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
@@ -359,12 +333,6 @@ void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
HAL_SetPWMRaw(pwmPortHandle, kPwmDisabled, status);
}
/**
* Get a value from a PWM channel. The values range from 0 to 255.
*
* @param channel The PWM channel to read from.
* @return The raw PWM value.
*/
int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
@@ -379,12 +347,6 @@ int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
}
}
/**
* Get a scaled value from a PWM channel. The values range from -1 to 1.
*
* @param channel The PWM channel to read from.
* @return The scaled PWM value.
*/
double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
@@ -417,12 +379,6 @@ double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
}
}
/**
* Get a position value from a PWM channel. The values range from 0 to 1.
*
* @param channel The PWM channel to read from.
* @return The scaled PWM value.
*/
double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
@@ -459,12 +415,6 @@ void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
pwmSystem->writeZeroLatch(port->channel, false, status);
}
/**
* Set how how often the PWM signal is squelched, thus scaling the period.
*
* @param channel The PWM channel to configure.
* @param squelchMask The 2-bit mask of outputs to squelch.
*/
void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
@@ -481,22 +431,12 @@ void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
}
}
/**
* Get the loop timing of the PWM system
*
* @return The loop time
*/
int32_t HAL_GetPWMLoopTiming(int32_t* status) {
initializeDigital(status);
if (*status != 0) return 0;
return pwmSystem->readLoopTiming(status);
}
/**
* Get the pwm starting cycle time
*
* @return The pwm cycle start time.
*/
uint64_t HAL_GetPWMCycleStartTime(int32_t* status) {
initializeDigital(status);
if (*status != 0) return 0;

View File

@@ -35,115 +35,73 @@ void InitializePower() {}
extern "C" {
/**
* Get the roboRIO input voltage
*/
double HAL_GetVinVoltage(int32_t* status) {
initializePower(status);
return power->readVinVoltage(status) / 4.096 * 0.025733 - 0.029;
}
/**
* Get the roboRIO input current
*/
double HAL_GetVinCurrent(int32_t* status) {
initializePower(status);
return power->readVinCurrent(status) / 4.096 * 0.017042 - 0.071;
}
/**
* Get the 6V rail voltage
*/
double HAL_GetUserVoltage6V(int32_t* status) {
initializePower(status);
return power->readUserVoltage6V(status) / 4.096 * 0.007019 - 0.014;
}
/**
* Get the 6V rail current
*/
double HAL_GetUserCurrent6V(int32_t* status) {
initializePower(status);
return power->readUserCurrent6V(status) / 4.096 * 0.005566 - 0.009;
}
/**
* Get the active state of the 6V rail
*/
HAL_Bool HAL_GetUserActive6V(int32_t* status) {
initializePower(status);
return power->readStatus_User6V(status) == 4;
}
/**
* Get the fault count for the 6V rail
*/
int32_t HAL_GetUserCurrentFaults6V(int32_t* status) {
initializePower(status);
return static_cast<int32_t>(
power->readFaultCounts_OverCurrentFaultCount6V(status));
}
/**
* Get the 5V rail voltage
*/
double HAL_GetUserVoltage5V(int32_t* status) {
initializePower(status);
return power->readUserVoltage5V(status) / 4.096 * 0.005962 - 0.013;
}
/**
* Get the 5V rail current
*/
double HAL_GetUserCurrent5V(int32_t* status) {
initializePower(status);
return power->readUserCurrent5V(status) / 4.096 * 0.001996 - 0.002;
}
/**
* Get the active state of the 5V rail
*/
HAL_Bool HAL_GetUserActive5V(int32_t* status) {
initializePower(status);
return power->readStatus_User5V(status) == 4;
}
/**
* Get the fault count for the 5V rail
*/
int32_t HAL_GetUserCurrentFaults5V(int32_t* status) {
initializePower(status);
return static_cast<int32_t>(
power->readFaultCounts_OverCurrentFaultCount5V(status));
}
/**
* Get the 3.3V rail voltage
*/
double HAL_GetUserVoltage3V3(int32_t* status) {
initializePower(status);
return power->readUserVoltage3V3(status) / 4.096 * 0.004902 - 0.01;
}
/**
* Get the 3.3V rail current
*/
double HAL_GetUserCurrent3V3(int32_t* status) {
initializePower(status);
return power->readUserCurrent3V3(status) / 4.096 * 0.002486 - 0.003;
}
/**
* Get the active state of the 3.3V rail
*/
HAL_Bool HAL_GetUserActive3V3(int32_t* status) {
initializePower(status);
return power->readStatus_User3V3(status) == 4;
}
/**
* Get the fault count for the 3.3V rail
*/
int32_t HAL_GetUserCurrentFaults3V3(int32_t* status) {
initializePower(status);
return static_cast<int32_t>(

View File

@@ -93,10 +93,6 @@ HAL_Bool HAL_CheckRelayChannel(int32_t channel) {
return channel < kNumRelayHeaders && channel >= 0;
}
/**
* Set the state of a relay.
* Set the state of a relay output.
*/
void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
int32_t* status) {
auto port = relayHandles->Get(relayPortHandle);
@@ -127,9 +123,6 @@ void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
}
}
/**
* Get the current state of the relay channel
*/
HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status) {
auto port = relayHandles->Get(relayPortHandle);
if (port == nullptr) {

View File

@@ -100,11 +100,6 @@ static void CommonSPIPortFree(void) {
}
}
/*
* Initialize the spi port. Opens the port if necessary and saves the handle.
* If opening the MXP port, also sets up the channel functions appropriately
* @param port The number of the port to use. 0-3 for Onboard CS0-CS3, 4 for MXP
*/
void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
hal::init::CheckInit();
if (port < 0 || port >= kSpiMaxHandles) {
@@ -244,18 +239,6 @@ void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status) {
}
}
/**
* Generic transaction.
*
* This is a lower-level interface to the spi hardware giving you more control
* over each transaction.
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param dataToSend Buffer of data to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param size Number of bytes to transfer. [0..7]
* @return Number of bytes transferred, -1 for error
*/
int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
uint8_t* dataReceived, int32_t size) {
if (port < 0 || port >= kSpiMaxHandles) {
@@ -274,16 +257,6 @@ int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
/**
* Execute a write transaction with the device.
*
* Write to a device and wait until the transaction is complete.
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param datToSend The data to write to the register on the device.
* @param sendSize The number of bytes to be written
* @return The number of bytes written. -1 for an error
*/
int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
int32_t sendSize) {
if (port < 0 || port >= kSpiMaxHandles) {
@@ -301,19 +274,6 @@ int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
/**
* Execute a read from the device.
*
* This method does not write any data out to the device
* Most spi devices will require a register address to be written before
* they begin returning data
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param buffer A pointer to the array of bytes to store the data read from the
* device.
* @param count The number of bytes to read in the transaction. [1..7]
* @return Number of bytes read. -1 for error.
*/
int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) {
if (port < 0 || port >= kSpiMaxHandles) {
return -1;
@@ -330,11 +290,6 @@ int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count) {
return ioctl(HAL_GetSPIHandle(port), SPI_IOC_MESSAGE(1), &xfer);
}
/**
* Close the SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
*/
void HAL_CloseSPI(HAL_SPIPort port) {
if (port < 0 || port >= kSpiMaxHandles) {
return;
@@ -375,12 +330,6 @@ void HAL_CloseSPI(HAL_SPIPort port) {
}
}
/**
* Set the clock speed for the SPI bus.
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param speed The speed in Hz (0-1MHz)
*/
void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {
if (port < 0 || port >= kSpiMaxHandles) {
return;
@@ -390,16 +339,6 @@ void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed) {
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MAX_SPEED_HZ, &speed);
}
/**
* Set the SPI options
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param msbFirst True to write the MSB first, False for LSB first
* @param sampleOnTrailing True to sample on the trailing edge, False to sample
* on the leading edge
* @param clkIdleHigh True to set the clock to active low, False to set the
* clock active high
*/
void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh) {
if (port < 0 || port >= kSpiMaxHandles) {
@@ -415,11 +354,6 @@ void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
ioctl(HAL_GetSPIHandle(port), SPI_IOC_WR_MODE, &mode);
}
/**
* Set the CS Active high for a SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
*/
void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
@@ -435,11 +369,6 @@ void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status) {
}
}
/**
* Set the CS Active low for a SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
*/
void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {
if (port < 0 || port >= kSpiMaxHandles) {
*status = PARAMETER_OUT_OF_RANGE;
@@ -455,12 +384,6 @@ void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status) {
}
}
/**
* Get the stored handle for a SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @return The stored handle for the SPI port. 0 represents no stored handle.
*/
int32_t HAL_GetSPIHandle(HAL_SPIPort port) {
if (port < 0 || port >= kSpiMaxHandles) {
return 0;
@@ -483,13 +406,6 @@ int32_t HAL_GetSPIHandle(HAL_SPIPort port) {
}
}
/**
* Set the stored handle for a SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
* MXP.
* @param handle The value of the handle for the port.
*/
void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle) {
if (port < 0 || port >= kSpiMaxHandles) {
return;

View File

@@ -20,14 +20,6 @@ void InitializeThreads() {}
extern "C" {
/**
* Get the thread priority for the specified thread.
*
* @param handle Native handle pointer to the thread to get the priority for
* @param isRealTime Set to true if thread is realtime, otherwise false
* @param status Error status variable. 0 on success
* @return The current thread priority. Scaled 1-99, with 1 being highest.
*/
int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
int32_t* status) {
sched_param sch;
@@ -49,31 +41,11 @@ int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
}
}
/**
* Get the thread priority for the current thread.
*
* @param handle Native handle pointer to the thread to get the priority for
* @param isRealTime Set to true if thread is realtime, otherwise false
* @param status Error status variable. 0 on success
* @return The current thread priority. Scaled 1-99, with 1 being highest.
*/
int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status) {
auto thread = pthread_self();
return HAL_GetThreadPriority(&thread, isRealTime, status);
}
/**
* Sets the thread priority for the specified thread
*
* @param thread Reference to the thread to set the priority of
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest
* @param status Error status variable. 0 on success
*
* @return The success state of setting the priority
*/
HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
int32_t priority, int32_t* status) {
if (handle == nullptr) {
@@ -109,18 +81,6 @@ HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
}
}
/**
* Sets the thread priority for the current thread
*
* @param thread Reference to the thread to set the priority of
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest
* @param status Error status variable. 0 on success
*
* @return The success state of setting the priority
*/
HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
int32_t* status) {
auto thread = pthread_self();

View File

@@ -18,10 +18,37 @@ enum HAL_AccelerometerRange : int32_t {
#ifdef __cplusplus
extern "C" {
#endif
/**
* Set the accelerometer to active or standby mode. It must be in standby
* mode to change any configuration.
*/
void HAL_SetAccelerometerActive(HAL_Bool active);
/**
* Set the range of values that can be measured (either 2, 4, or 8 g-forces).
* The accelerometer should be in standby mode when this is called.
*/
void HAL_SetAccelerometerRange(HAL_AccelerometerRange range);
/**
* Get the x-axis acceleration
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerX(void);
/**
* Get the y-axis acceleration
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerY(void);
/**
* Get the z-axis acceleration
*
* This is a floating point value in units of 1 g-force
*/
double HAL_GetAccelerometerZ(void);
#ifdef __cplusplus
} // extern "C"

View File

@@ -15,20 +15,92 @@
extern "C" {
#endif
/**
* Is the channel attached to an accumulator.
*
* @param analogPortHandle Handle to the analog port.
* @return The analog channel is attached to an accumulator.
*/
HAL_Bool HAL_IsAccumulatorChannel(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Initialize the accumulator.
*
* @param analogPortHandle Handle to the analog port.
*/
void HAL_InitAccumulator(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Resets the accumulator to the initial value.
*
* @param analogPortHandle Handle to the analog port.
*/
void HAL_ResetAccumulator(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Set the center value of the accumulator.
*
* The center value is subtracted from each A/D value before it is added to the
* accumulator. This is used for the center value of devices like gyros and
* accelerometers to make integration work and to take the device offset into
* account when integrating.
*
* This center value is based on the output of the oversampled and averaged
* source from channel 1. Because of this, any non-zero oversample bits will
* affect the size of the value for this field.
*
* @param analogPortHandle Handle to the analog port.
* @param center The center value of the accumulator.
*/
void HAL_SetAccumulatorCenter(HAL_AnalogInputHandle analogPortHandle,
int32_t center, int32_t* status);
/**
* Set the accumulator's deadband.
*
* @param analogPortHandle Handle to the analog port.
* @param deadband The deadband of the accumulator.
*/
void HAL_SetAccumulatorDeadband(HAL_AnalogInputHandle analogPortHandle,
int32_t deadband, int32_t* status);
/**
* Read the accumulated value.
*
* Read the value that has been accumulating on channel 1.
* The accumulator is attached after the oversample and average engine.
*
* @param analogPortHandle Handle to the analog port.
* @return The 64-bit value accumulated since the last Reset().
*/
int64_t HAL_GetAccumulatorValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last
* Reset().
*
* @param analogPortHandle Handle to the analog port.
* @return The number of times samples from the channel were accumulated.
*/
int64_t HAL_GetAccumulatorCount(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* This function reads the value and count from the FPGA atomically.
* This can be used for averaging.
*
* @param analogPortHandle Handle to the analog port.
* @param value Pointer to the 64-bit accumulated output.
* @param count Pointer to the number of accumulation cycles.
*/
void HAL_GetAccumulatorOutput(HAL_AnalogInputHandle analogPortHandle,
int64_t* value, int64_t* count, int32_t* status);
#ifdef __cplusplus

View File

@@ -15,34 +15,204 @@
extern "C" {
#endif
/**
* Initialize the analog input port using the given port object.
*
* @param portHandle Handle to the port to initialize.
*/
HAL_AnalogInputHandle HAL_InitializeAnalogInputPort(HAL_PortHandle portHandle,
int32_t* status);
/**
* @param analogPortHandle Handle to the analog port.
*/
void HAL_FreeAnalogInputPort(HAL_AnalogInputHandle analogPortHandle);
/**
* Check that the analog module number is valid.
*
* @param module The analog module number.
* @return Analog module is valid and present
*/
HAL_Bool HAL_CheckAnalogModule(int32_t module);
/**
* Check that the analog output channel number is value.
* Verify that the analog channel number is one of the legal channel numbers.
* Channel numbers are 0-based.
*
* @param channel The analog output channel number.
* @return Analog channel is valid
*/
HAL_Bool HAL_CheckAnalogInputChannel(int32_t channel);
/**
* Set the sample rate.
*
* This is a global setting for the Athena and effects all channels.
*
* @param samplesPerSecond The number of samples per channel per second.
*/
void HAL_SetAnalogSampleRate(double samplesPerSecond, int32_t* status);
/**
* Get the current sample rate.
*
* This assumes one entry in the scan list.
* This is a global setting for the Athena and effects all channels.
*
* @return Sample rate.
*/
double HAL_GetAnalogSampleRate(int32_t* status);
/**
* Set the number of averaging bits.
*
* This sets the number of averaging bits. The actual number of averaged samples
* is 2**bits. Use averaging to improve the stability of your measurement at the
* expense of sampling rate. The averaging is done automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to configure.
* @param bits Number of bits to average.
*/
void HAL_SetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
int32_t bits, int32_t* status);
/**
* Get the number of averaging bits.
*
* This gets the number of averaging bits from the FPGA. The actual number of
* averaged samples is 2**bits. The averaging is done automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @return Bits to average.
*/
int32_t HAL_GetAnalogAverageBits(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Set the number of oversample bits.
*
* This sets the number of oversample bits. The actual number of oversampled
* values is 2**bits. Use oversampling to improve the resolution of your
* measurements at the expense of sampling rate. The oversampling is done
* automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @param bits Number of bits to oversample.
*/
void HAL_SetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
int32_t bits, int32_t* status);
/**
* Get the number of oversample bits.
*
* This gets the number of oversample bits from the FPGA. The actual number of
* oversampled values is 2**bits. The oversampling is done automatically in the
* FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @return Bits to oversample.
*/
int32_t HAL_GetAnalogOversampleBits(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Get a sample straight from the channel on this module.
*
* The sample is a 12-bit value representing the 0V to 5V range of the A/D
* converter in the module. The units are in A/D converter codes. Use
* GetVoltage() to get the analog value in calibrated units.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A sample straight from the channel on this module.
*/
int32_t HAL_GetAnalogValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Get a sample from the output of the oversample and average engine for the
* channel.
*
* The sample is 12-bit + the value configured in SetOversampleBits().
* The value configured in SetAverageBits() will cause this value to be averaged
* 2**bits number of samples. This is not a sliding window. The sample will not
* change until 2**(OversamplBits + AverageBits) samples have been acquired from
* the module on this channel. Use GetAverageVoltage() to get the analog value
* in calibrated units.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A sample from the oversample and average engine for the channel.
*/
int32_t HAL_GetAnalogAverageValue(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Convert a voltage to a raw value for a specified channel.
*
* This process depends on the calibration of each channel, so the channel must
* be specified.
*
* @todo This assumes raw values. Oversampling not supported as is.
*
* @param analogPortHandle Handle to the analog port to use.
* @param voltage The voltage to convert.
* @return The raw value for the channel.
*/
int32_t HAL_GetAnalogVoltsToValue(HAL_AnalogInputHandle analogPortHandle,
double voltage, int32_t* status);
/**
* Get a scaled sample straight from the channel on this module.
*
* The value is scaled to units of Volts using the calibrated scaling data from
* GetLSBWeight() and GetOffset().
*
* @param analogPortHandle Handle to the analog port to use.
* @return A scaled sample straight from the channel on this module.
*/
double HAL_GetAnalogVoltage(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Get a scaled sample from the output of the oversample and average engine for
* the channel.
*
* The value is scaled to units of Volts using the calibrated scaling data from
* GetLSBWeight() and GetOffset(). Using oversampling will cause this value to
* be higher resolution, but it will update more slowly. Using averaging will
* cause this value to be more stable, but it will update more slowly.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A scaled sample from the output of the oversample and average engine
* for the channel.
*/
double HAL_GetAnalogAverageVoltage(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Get the factory scaling least significant bit weight constant.
* The least significant bit weight constant for the channel that was calibrated
* in manufacturing and stored in an eeprom in the module.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @param analogPortHandle Handle to the analog port to use.
* @return Least significant bit weight.
*/
int32_t HAL_GetAnalogLSBWeight(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
/**
* Get the factory scaling offset constant.
* The offset constant for the channel that was calibrated in manufacturing and
* stored in an eeprom in the module.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @param analogPortHandle Handle to the analog port to use.
* @return Offset constant.
*/
int32_t HAL_GetAnalogOffset(HAL_AnalogInputHandle analogPortHandle,
int32_t* status);
#ifdef __cplusplus

View File

@@ -15,13 +15,27 @@
extern "C" {
#endif
/**
* Initialize the analog output port using the given port object.
*/
HAL_AnalogOutputHandle HAL_InitializeAnalogOutputPort(HAL_PortHandle portHandle,
int32_t* status);
void HAL_FreeAnalogOutputPort(HAL_AnalogOutputHandle analogOutputHandle);
void HAL_SetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
double voltage, int32_t* status);
double HAL_GetAnalogOutput(HAL_AnalogOutputHandle analogOutputHandle,
int32_t* status);
/**
* Check that the analog output channel number is value.
* Verify that the analog channel number is one of the legal channel numbers.
* Channel numbers are 0-based.
*
* @return Analog channel is valid
*/
HAL_Bool HAL_CheckAnalogOutputChannel(int32_t channel);
#ifdef __cplusplus
} // extern "C"

View File

@@ -28,17 +28,54 @@ void HAL_CleanAnalogTrigger(HAL_AnalogTriggerHandle analogTriggerHandle,
void HAL_SetAnalogTriggerLimitsRaw(HAL_AnalogTriggerHandle analogTriggerHandle,
int32_t lower, int32_t upper,
int32_t* status);
/**
* Set the upper and lower limits of the analog trigger.
* The limits are given as floating point voltage values.
*/
void HAL_SetAnalogTriggerLimitsVoltage(
HAL_AnalogTriggerHandle analogTriggerHandle, double lower, double upper,
int32_t* status);
/**
* Configure the analog trigger to use the averaged vs. raw values.
* If the value is true, then the averaged value is selected for the analog
* trigger, otherwise the immediate value is used.
*/
void HAL_SetAnalogTriggerAveraged(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_Bool useAveragedValue, int32_t* status);
/**
* Configure the analog trigger to use a filtered value.
* The analog trigger will operate with a 3 point average rejection filter. This
* is designed to help with 360 degree pot applications for the period where the
* pot crosses through zero.
*/
void HAL_SetAnalogTriggerFiltered(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_Bool useFilteredValue, int32_t* status);
/**
* Return the InWindow output of the analog trigger.
* True if the analog input is between the upper and lower limits.
* @return The InWindow output of the analog trigger.
*/
HAL_Bool HAL_GetAnalogTriggerInWindow(
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status);
/**
* Return the TriggerState output of the analog trigger.
* True if above upper limit.
* False if below lower limit.
* If in Hysteresis, maintain previous state.
* @return The TriggerState output of the analog trigger.
*/
HAL_Bool HAL_GetAnalogTriggerTriggerState(
HAL_AnalogTriggerHandle analogTriggerHandle, int32_t* status);
/**
* Get the state of the analog trigger output.
* @return The state of the analog trigger output.
*/
HAL_Bool HAL_GetAnalogTriggerOutput(HAL_AnalogTriggerHandle analogTriggerHandle,
HAL_AnalogTriggerType type,
int32_t* status);

View File

@@ -27,45 +27,174 @@ HAL_CounterHandle HAL_InitializeCounter(HAL_Counter_Mode mode, int32_t* index,
void HAL_FreeCounter(HAL_CounterHandle counterHandle, int32_t* status);
void HAL_SetCounterAverageSize(HAL_CounterHandle counterHandle, int32_t size,
int32_t* status);
/**
* Set the source object that causes the counter to count up.
* Set the up counting DigitalSource.
*/
void HAL_SetCounterUpSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status);
/**
* Set the edge sensitivity on an up counting source.
* Set the up source to either detect rising edges or falling edges.
*/
void HAL_SetCounterUpSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status);
/**
* Disable the up counting source to the counter.
*/
void HAL_ClearCounterUpSource(HAL_CounterHandle counterHandle, int32_t* status);
/**
* Set the source object that causes the counter to count down.
* Set the down counting DigitalSource.
*/
void HAL_SetCounterDownSource(HAL_CounterHandle counterHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
int32_t* status);
/**
* Set the edge sensitivity on a down counting source.
* Set the down source to either detect rising edges or falling edges.
*/
void HAL_SetCounterDownSourceEdge(HAL_CounterHandle counterHandle,
HAL_Bool risingEdge, HAL_Bool fallingEdge,
int32_t* status);
/**
* Disable the down counting source to the counter.
*/
void HAL_ClearCounterDownSource(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* Set standard up / down counting mode on this counter.
* Up and down counts are sourced independently from two inputs.
*/
void HAL_SetCounterUpDownMode(HAL_CounterHandle counterHandle, int32_t* status);
/**
* Set standard up / down counting mode on this counter.
* Up and down counts are sourced independently from two inputs.
*/
void HAL_SetCounterExternalDirectionMode(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* Set Semi-period mode on this counter.
* Counts up on both rising and falling edges.
*/
void HAL_SetCounterSemiPeriodMode(HAL_CounterHandle counterHandle,
HAL_Bool highSemiPeriod, int32_t* status);
/**
* Configure the counter to count in up or down based on the length of the input
* pulse.
* This mode is most useful for direction sensitive gear tooth sensors.
* @param threshold The pulse length beyond which the counter counts the
* opposite direction. Units are seconds.
*/
void HAL_SetCounterPulseLengthMode(HAL_CounterHandle counterHandle,
double threshold, int32_t* 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)
*/
int32_t HAL_GetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t* 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 HAL_SetCounterSamplesToAverage(HAL_CounterHandle counterHandle,
int32_t samplesToAverage, int32_t* status);
/**
* Reset the Counter to zero.
* Set the counter value to zero. This doesn't effect the running state of the
* counter, just sets the current value to zero.
*/
void HAL_ResetCounter(HAL_CounterHandle counterHandle, int32_t* status);
/**
* Read the current counter value.
* Read the value at this instant. It may still be running, so it reflects the
* current value. Next time it is read, it might have a different value.
*/
int32_t HAL_GetCounter(HAL_CounterHandle counterHandle, int32_t* status);
/*
* Get the Period of the most recent count.
* Returns the time interval of the most recent count. This can be used for
* velocity calculations to determine shaft speed.
* @returns The period of the last two pulses in units of seconds.
*/
double HAL_GetCounterPeriod(HAL_CounterHandle counterHandle, int32_t* status);
/**
* Set the maximum period where the device is still considered "moving".
* Sets the maximum period where the device is considered moving. This value is
* used to determine the "stopped" state of the counter using the GetStopped
* method.
* @param maxPeriod The maximum period where the counted device is considered
* moving in seconds.
*/
void HAL_SetCounterMaxPeriod(HAL_CounterHandle counterHandle, double maxPeriod,
int32_t* status);
/**
* Select whether you want to continue updating the event timer output when
* there are no samples captured. The output of the event timer has a buffer of
* periods that are averaged and posted to a register on the FPGA. When the
* timer detects that the event source has stopped (based on the MaxPeriod) the
* buffer of samples to be averaged is emptied. If you enable the update when
* empty, you will be notified of the stopped source and the event time will
* report 0 samples. If you disable update when empty, the most recent average
* will remain on the output until a new sample is acquired. You will never see
* 0 samples output (except when there have been no events since an FPGA reset)
* and you will likely not see the stopped bit become true (since it is updated
* at the end of an average and there are no samples to average).
*/
void HAL_SetCounterUpdateWhenEmpty(HAL_CounterHandle counterHandle,
HAL_Bool enabled, int32_t* status);
/**
* Determine if the clock is stopped.
* Determine if the clocked input is stopped based on the MaxPeriod value set
* using the SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the
* device (and counter) are assumed to be stopped and it returns true.
* @return Returns true if the most recent counter period exceeds the MaxPeriod
* value set by SetMaxPeriod.
*/
HAL_Bool HAL_GetCounterStopped(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* The last direction the counter value changed.
* @return The last direction the counter value changed.
*/
HAL_Bool HAL_GetCounterDirection(HAL_CounterHandle counterHandle,
int32_t* status);
/**
* Set the Counter to return reversed sensing on the direction.
* This allows counters to change the direction they are counting in the case of
* 1X and 2X quadrature encoding only. Any other counter mode isn't supported.
* @param reverseDirection true if the value counted should be negated.
*/
void HAL_SetCounterReverseDirection(HAL_CounterHandle counterHandle,
HAL_Bool reverseDirection, int32_t* status);
#ifdef __cplusplus

View File

@@ -15,32 +15,169 @@
extern "C" {
#endif
/**
* Create a new instance of a digital port.
*/
HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
HAL_Bool input, int32_t* status);
HAL_Bool HAL_CheckDIOChannel(int32_t channel);
void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle);
/**
* Allocate a DO PWM Generator.
* Allocate PWM generators so that they are not accidentally reused.
*
* @return PWM Generator handle
*/
HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status);
/**
* Free the resource associated with a DO PWM generator.
*
* @param pwmGenerator The pwmGen to free that was allocated with
* allocateDigitalPWM()
*/
void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status);
/**
* Change the frequency of the DO PWM generator.
*
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is
* logarithmic.
*
* @param rate The frequency to output all digital output PWM signals.
*/
void HAL_SetDigitalPWMRate(double rate, int32_t* status);
/**
* Configure the duty-cycle of the PWM generator
*
* @param pwmGenerator The generator index reserved by allocateDigitalPWM()
* @param dutyCycle The percent duty cycle to output [0..1].
*/
void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
double dutyCycle, int32_t* status);
/**
* Configure which DO channel the PWM signal is output on
*
* @param pwmGenerator The generator index reserved by allocateDigitalPWM()
* @param channel The Digital Output channel to output on
*/
void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
int32_t channel, int32_t* status);
/**
* Write a digital I/O bit to the FPGA.
* Set a single value on a digital I/O channel.
*
* @param channel The Digital I/O channel
* @param value The state to set the digital channel (if it is configured as an
* output)
*/
void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
int32_t* status);
/**
* Set direction of a DIO channel.
*
* @param channel The Digital I/O channel
* @param input true to set input, false for output
*/
void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
int32_t* status);
/**
* Read a digital I/O bit from the FPGA.
* Get a single value from a digital I/O channel.
*
* @param channel The digital I/O channel
* @return The state of the specified channel
*/
HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status);
/**
* Read the direction of a the Digital I/O lines
* A 1 bit means output and a 0 bit means input.
*
* @param channel The digital I/O channel
* @return The direction of the specified channel
*/
HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status);
/**
* Generate a single pulse.
* Write a pulse to the specified digital output channel. There can only be a
* single pulse going at any time.
*
* @param channel The Digital Output channel that the pulse should be output on
* @param pulseLength The active length of the pulse (in seconds)
*/
void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
int32_t* status);
/**
* Check a DIO line to see if it is currently generating a pulse.
*
* @return A pulse is in progress
*/
HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status);
/**
* Check if any DIO line is currently generating a pulse.
*
* @return A pulse on some line is in progress
*/
HAL_Bool HAL_IsAnyPulsing(int32_t* status);
/**
* Write the filter index from the FPGA.
* Set the filter index used to filter out short pulses.
*
* @param dioPortHandle Handle to the digital I/O channel
* @param filterIndex The filter index. Must be in the range 0 - 3, where 0
* means "none" and 1 - 3 means filter # filterIndex - 1.
*/
void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
int32_t* status);
/**
* Read the filter index from the FPGA.
* Get the filter index used to filter out short pulses.
*
* @param dioPortHandle Handle to the digital I/O channel
* @return filterIndex The filter index. Must be in the range 0 - 3,
* where 0 means "none" and 1 - 3 means filter # filterIndex - 1.
*/
int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status);
/**
* Set the filter period for the specified filter index.
*
* Set the filter period in FPGA cycles. Even though there are 2 different
* filter index domains (MXP vs HDR), ignore that distinction for now since it
* compilicates the interface. That can be changed later.
*
* @param filterIndex The filter index, 0 - 2.
* @param value The number of cycles that the signal must not transition to be
* counted as a transition.
*/
void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status);
/**
* Get the filter period for the specified filter index.
*
* Get the filter period in FPGA cycles. Even though there are 2 different
* filter index domains (MXP vs HDR), ignore that distinction for now since it
* compilicates the interface. Set status to NiFpga_Status_SoftwareFault if the
* filter values miss-match.
*
* @param filterIndex The filter index, 0 - 2.
* @param value The number of cycles that the signal must not transition to be
* counted as a transition.
*/
int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status);
#ifdef __cplusplus
} // extern "C"

View File

@@ -108,8 +108,21 @@ int32_t HAL_GetJoystickAxes(int32_t joystickNum, HAL_JoystickAxes* axes);
int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs);
int32_t HAL_GetJoystickButtons(int32_t joystickNum,
HAL_JoystickButtons* buttons);
/**
* Retrieve the Joystick Descriptor for particular slot
* @param desc [out] descriptor (data transfer object) to fill in. desc is
* filled in regardless of success. In other words, if descriptor is not
* available, desc is filled in with default values matching the init-values in
* Java and C++ Driverstation for when caller requests a too-large joystick
* index.
*
* @return error code reported from Network Comm back-end. Zero is good,
* nonzero is bad.
*/
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
HAL_JoystickDescriptor* desc);
HAL_Bool HAL_GetJoystickIsXbox(int32_t joystickNum);
int32_t HAL_GetJoystickType(int32_t joystickNum);
char* HAL_GetJoystickName(int32_t joystickNum);
@@ -124,10 +137,31 @@ void HAL_FreeMatchInfo(HAL_MatchInfo* info);
#ifndef HAL_USE_LABVIEW
/**
* Releases the DS Mutex to allow proper shutdown of any threads that are
* waiting on it.
*/
void HAL_ReleaseDSMutex(void);
bool HAL_IsNewControlData(void);
/**
* Waits for the newest DS packet to arrive. Note that this is a blocking call.
*/
void HAL_WaitForDSData(void);
/**
* Waits for the newest DS packet to arrive. If timeout is <= 0, this will wait
* forever. Otherwise, it will wait until either a new packet, or the timeout
* time has passed. Returns true on new data, false on timeout.
*/
HAL_Bool HAL_WaitForDSDataTimeout(double timeout);
/**
* Call this to initialize the driver station communication. This will properly
* handle multiple calls. However note that this CANNOT be called from a library
* that interfaces with LabVIEW.
*/
void HAL_InitializeDriverStation(void);
void HAL_ObserveUserProgramStarting(void);

View File

@@ -21,5 +21,10 @@ typedef int halsim_extension_init_func_t(void);
extern "C" {
int HAL_LoadOneExtension(const char* library);
/**
* Load any extra halsim libraries provided in the HALSIM_EXTENSIONS
* environment variable.
*/
int HAL_LoadExtensions(void);
} // extern "C"

View File

@@ -51,10 +51,29 @@ extern "C" {
const char* HAL_GetErrorMessage(int32_t code);
/**
* Return the FPGA Version number.
* For now, expect this to be competition year.
* @return FPGA Version number.
*/
int32_t HAL_GetFPGAVersion(int32_t* status);
/**
* Return the FPGA Revision number.
* The format of the revision is 3 numbers.
* The 12 most significant bits are the Major Revision.
* the next 8 bits are the Minor Revision.
* The 12 least significant bits are the Build Number.
* @return FPGA Revision number.
*/
int64_t HAL_GetFPGARevision(int32_t* status);
HAL_RuntimeType HAL_GetRuntimeType(void);
/**
* Get the state of the "USER" button on the roboRIO
* @return true if the button is currently pressed down
*/
HAL_Bool HAL_GetFPGAButton(int32_t* status);
HAL_Bool HAL_GetSystemActive(int32_t* status);
@@ -65,10 +84,23 @@ void HAL_BaseInitialize(int32_t* status);
#ifndef HAL_USE_LABVIEW
HAL_PortHandle HAL_GetPort(int32_t channel);
/**
* @deprecated Uses module numbers
*/
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel);
/**
* Read the microsecond-resolution timer on the FPGA.
*
* @return The current time in microseconds according to the FPGA (since FPGA
* reset).
*/
uint64_t HAL_GetFPGATime(int32_t* status);
/**
* Call this to start up HAL. This is required for robot programs.
*/
HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode);
// ifdef's definition is to allow for default parameters in C++.

View File

@@ -15,14 +15,59 @@ enum HAL_I2CPort : int32_t { HAL_I2C_kOnboard = 0, HAL_I2C_kMXP };
extern "C" {
#endif
/**
* Initialize the I2C port. Opens the port if necessary and saves the handle.
* If opening the MXP port, also sets up the channel functions appropriately
* @param port The port to open, 0 for the on-board, 1 for the MXP.
*/
void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status);
/**
* Generic transaction.
*
* This is a lower-level interface to the I2C hardware giving you more control
* over each transaction.
*
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_TransactionI2C(HAL_I2CPort port, int32_t deviceAddress,
const uint8_t* dataToSend, int32_t sendSize,
uint8_t* dataReceived, int32_t receiveSize);
/**
* Execute a write transaction with the device.
*
* Write a single byte to a register on a device and wait until the
* transaction is complete.
*
* @param registerAddress The address of the register on the device to be
* written.
* @param data The byte to write to the register on the device.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_WriteI2C(HAL_I2CPort port, int32_t deviceAddress,
const uint8_t* dataToSend, int32_t sendSize);
/**
* Execute a read transaction with the device.
*
* Read bytes from a device.
* Most I2C devices will auto-increment the register pointer internally allowing
* you to read consecutive registers on a device in a single transaction.
*
* @param registerAddress The register to read first in the transaction.
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from the
* device.
* @return >= 0 on success or -1 on transfer abort.
*/
int32_t HAL_ReadI2C(HAL_I2CPort port, int32_t deviceAddress, uint8_t* buffer,
int32_t count);
void HAL_CloseI2C(HAL_I2CPort port);
#ifdef __cplusplus
} // extern "C"

View File

@@ -22,16 +22,47 @@ typedef void (*HAL_InterruptHandlerFunction)(uint32_t interruptAssertedMask,
HAL_InterruptHandle HAL_InitializeInterrupts(HAL_Bool watcher, int32_t* status);
void* HAL_CleanInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status);
/**
* In synchronous mode, wait for the defined interrupt to occur.
* @param timeout Timeout in seconds
* @param ignorePrevious If true, ignore interrupts that happened before
* waitForInterrupt was called.
* @return The mask of interrupts that fired.
*/
int64_t HAL_WaitForInterrupt(HAL_InterruptHandle interruptHandle,
double timeout, HAL_Bool ignorePrevious,
int32_t* status);
/**
* Enable interrupts to occur on this input.
* Interrupts are disabled when the RequestInterrupt call is made. This gives
* time to do the setup of the other options before starting to field
* interrupts.
*/
void HAL_EnableInterrupts(HAL_InterruptHandle interruptHandle, int32_t* status);
/**
* Disable Interrupts without without deallocating structures.
*/
void HAL_DisableInterrupts(HAL_InterruptHandle interruptHandle,
int32_t* status);
/**
* Return the timestamp for the rising interrupt that occurred most recently.
* This is in the same time domain as GetClock().
* @return Timestamp in seconds since boot.
*/
double HAL_ReadInterruptRisingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status);
/**
* Return the timestamp for the falling interrupt that occurred most recently.
* This is in the same time domain as GetClock().
* @return Timestamp in seconds since boot.
*/
double HAL_ReadInterruptFallingTimestamp(HAL_InterruptHandle interruptHandle,
int32_t* status);
void HAL_RequestInterrupts(HAL_InterruptHandle interruptHandle,
HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,

View File

@@ -36,20 +36,91 @@ void HAL_SetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
HAL_Bool eliminateDeadband, int32_t* status);
HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
int32_t* status);
/**
* Set a PWM channel to the desired value. The values range from 0 to 255 and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The PWM value to set.
*/
void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
int32_t* status);
/**
* Set a PWM channel to the desired scaled value. The values range from -1 to 1
* and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The scaled PWM value to set.
*/
void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
int32_t* status);
/**
* Set a PWM channel to the desired position value. The values range from 0 to 1
* and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The scaled PWM value to set.
*/
void HAL_SetPWMPosition(HAL_DigitalHandle pwmPortHandle, double position,
int32_t* status);
void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status);
/**
* Get a value from a PWM channel. The values range from 0 to 255.
*
* @param channel The PWM channel to read from.
* @return The raw PWM value.
*/
int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status);
/**
* Get a scaled value from a PWM channel. The values range from -1 to 1.
*
* @param channel The PWM channel to read from.
* @return The scaled PWM value.
*/
double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status);
/**
* Get a position value from a PWM channel. The values range from 0 to 1.
*
* @param channel The PWM channel to read from.
* @return The scaled PWM value.
*/
double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status);
void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status);
/**
* Set how how often the PWM signal is squelched, thus scaling the period.
*
* @param channel The PWM channel to configure.
* @param squelchMask The 2-bit mask of outputs to squelch.
*/
void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
int32_t* status);
/**
* Get the loop timing of the PWM system
*
* @return The loop time
*/
int32_t HAL_GetPWMLoopTiming(int32_t* status);
/**
* Get the pwm starting cycle time
*
* @return The pwm cycle start time.
*/
uint64_t HAL_GetPWMCycleStartTime(int32_t* status);
#ifdef __cplusplus
} // extern "C"

View File

@@ -15,19 +15,74 @@
extern "C" {
#endif
/**
* Get the roboRIO input voltage
*/
double HAL_GetVinVoltage(int32_t* status);
/**
* Get the roboRIO input current
*/
double HAL_GetVinCurrent(int32_t* status);
/**
* Get the 6V rail voltage
*/
double HAL_GetUserVoltage6V(int32_t* status);
/**
* Get the 6V rail current
*/
double HAL_GetUserCurrent6V(int32_t* status);
/**
* Get the active state of the 6V rail
*/
HAL_Bool HAL_GetUserActive6V(int32_t* status);
/**
* Get the fault count for the 6V rail
*/
int32_t HAL_GetUserCurrentFaults6V(int32_t* status);
/**
* Get the 5V rail voltage
*/
double HAL_GetUserVoltage5V(int32_t* status);
/**
* Get the 5V rail current
*/
double HAL_GetUserCurrent5V(int32_t* status);
/**
* Get the active state of the 5V rail
*/
HAL_Bool HAL_GetUserActive5V(int32_t* status);
/**
* Get the fault count for the 5V rail
*/
int32_t HAL_GetUserCurrentFaults5V(int32_t* status);
/**
* Get the 3.3V rail voltage
*/
double HAL_GetUserVoltage3V3(int32_t* status);
/**
* Get the 3.3V rail current
*/
double HAL_GetUserCurrent3V3(int32_t* status);
/**
* Get the active state of the 3.3V rail
*/
HAL_Bool HAL_GetUserActive3V3(int32_t* status);
/**
* Get the fault count for the 3.3V rail
*/
int32_t HAL_GetUserCurrentFaults3V3(int32_t* status);
#ifdef __cplusplus
} // extern "C"

View File

@@ -21,8 +21,16 @@ void HAL_FreeRelayPort(HAL_RelayHandle relayPortHandle);
HAL_Bool HAL_CheckRelayChannel(int32_t channel);
/**
* Set the state of a relay.
* Set the state of a relay output.
*/
void HAL_SetRelay(HAL_RelayHandle relayPortHandle, HAL_Bool on,
int32_t* status);
/**
* Get the current state of the relay channel
*/
HAL_Bool HAL_GetRelay(HAL_RelayHandle relayPortHandle, int32_t* status);
#ifdef __cplusplus
} // extern "C"

View File

@@ -24,36 +24,138 @@ enum HAL_SPIPort : int32_t {
extern "C" {
#endif
/**
* Initialize the spi port. Opens the port if necessary and saves the handle.
* If opening the MXP port, also sets up the channel functions appropriately
* @param port The number of the port to use. 0-3 for Onboard CS0-CS3, 4 for MXP
*/
void HAL_InitializeSPI(HAL_SPIPort port, int32_t* status);
/**
* Generic transaction.
*
* This is a lower-level interface to the spi hardware giving you more control
* over each transaction.
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param dataToSend Buffer of data to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param size Number of bytes to transfer. [0..7]
* @return Number of bytes transferred, -1 for error
*/
int32_t HAL_TransactionSPI(HAL_SPIPort port, const uint8_t* dataToSend,
uint8_t* dataReceived, int32_t size);
/**
* Execute a write transaction with the device.
*
* Write to a device and wait until the transaction is complete.
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param datToSend The data to write to the register on the device.
* @param sendSize The number of bytes to be written
* @return The number of bytes written. -1 for an error
*/
int32_t HAL_WriteSPI(HAL_SPIPort port, const uint8_t* dataToSend,
int32_t sendSize);
/**
* Execute a read from the device.
*
* This method does not write any data out to the device
* Most spi devices will require a register address to be written before
* they begin returning data
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param buffer A pointer to the array of bytes to store the data read from the
* device.
* @param count The number of bytes to read in the transaction. [1..7]
* @return Number of bytes read. -1 for error.
*/
int32_t HAL_ReadSPI(HAL_SPIPort port, uint8_t* buffer, int32_t count);
/**
* Close the SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
*/
void HAL_CloseSPI(HAL_SPIPort port);
/**
* Set the clock speed for the SPI bus.
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param speed The speed in Hz (0-1MHz)
*/
void HAL_SetSPISpeed(HAL_SPIPort port, int32_t speed);
/**
* Set the SPI options
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @param msbFirst True to write the MSB first, False for LSB first
* @param sampleOnTrailing True to sample on the trailing edge, False to sample
* on the leading edge
* @param clkIdleHigh True to set the clock to active low, False to set the
* clock active high
*/
void HAL_SetSPIOpts(HAL_SPIPort port, HAL_Bool msbFirst,
HAL_Bool sampleOnTrailing, HAL_Bool clkIdleHigh);
/**
* Set the CS Active high for a SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
*/
void HAL_SetSPIChipSelectActiveHigh(HAL_SPIPort port, int32_t* status);
/**
* Set the CS Active low for a SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
*/
void HAL_SetSPIChipSelectActiveLow(HAL_SPIPort port, int32_t* status);
/**
* Get the stored handle for a SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for MXP
* @return The stored handle for the SPI port. 0 represents no stored handle.
*/
int32_t HAL_GetSPIHandle(HAL_SPIPort port);
/**
* Set the stored handle for a SPI port
*
* @param port The number of the port to use. 0-3 for Onboard CS0-CS2, 4 for
* MXP.
* @param handle The value of the handle for the port.
*/
void HAL_SetSPIHandle(HAL_SPIPort port, int32_t handle);
void HAL_InitSPIAuto(HAL_SPIPort port, int32_t bufferSize, int32_t* status);
void HAL_FreeSPIAuto(HAL_SPIPort port, int32_t* status);
void HAL_StartSPIAutoRate(HAL_SPIPort port, double period, int32_t* status);
void HAL_StartSPIAutoTrigger(HAL_SPIPort port, HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
HAL_Bool triggerRising, HAL_Bool triggerFalling,
int32_t* status);
void HAL_StopSPIAuto(HAL_SPIPort port, int32_t* status);
void HAL_SetSPIAutoTransmitData(HAL_SPIPort port, const uint8_t* dataToSend,
int32_t dataSize, int32_t zeroSize,
int32_t* status);
void HAL_ForceSPIAutoRead(HAL_SPIPort port, int32_t* status);
int32_t HAL_ReadSPIAutoReceivedData(HAL_SPIPort port, uint8_t* buffer,
int32_t numToRead, double timeout,
int32_t* status);
int32_t HAL_GetSPIAutoDroppedCount(HAL_SPIPort port, int32_t* status);
#ifdef __cplusplus

View File

@@ -18,11 +18,54 @@
#include "HAL/Types.h"
extern "C" {
/**
* Get the thread priority for the specified thread.
*
* @param handle Native handle pointer to the thread to get the priority for
* @param isRealTime Set to true if thread is realtime, otherwise false
* @param status Error status variable. 0 on success
* @return The current thread priority. Scaled 1-99, with 1 being highest.
*/
int32_t HAL_GetThreadPriority(NativeThreadHandle handle, HAL_Bool* isRealTime,
int32_t* status);
/**
* Get the thread priority for the current thread.
*
* @param handle Native handle pointer to the thread to get the priority for
* @param isRealTime Set to true if thread is realtime, otherwise false
* @param status Error status variable. 0 on success
* @return The current thread priority. Scaled 1-99, with 1 being highest.
*/
int32_t HAL_GetCurrentThreadPriority(HAL_Bool* isRealTime, int32_t* status);
/**
* Sets the thread priority for the specified thread
*
* @param thread Reference to the thread to set the priority of
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest
* @param status Error status variable. 0 on success
*
* @return The success state of setting the priority
*/
HAL_Bool HAL_SetThreadPriority(NativeThreadHandle handle, HAL_Bool realTime,
int32_t priority, int32_t* status);
/**
* Sets the thread priority for the current thread
*
* @param thread Reference to the thread to set the priority of
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest
* @param status Error status variable. 0 on success
*
* @return The success state of setting the priority
*/
HAL_Bool HAL_SetCurrentThreadPriority(HAL_Bool realTime, int32_t priority,
int32_t* status);
} // extern "C"

View File

@@ -37,9 +37,6 @@ void InitializeDIO() {
extern "C" {
/**
* Create a new instance of a digital port.
*/
HAL_DigitalHandle HAL_InitializeDIOPort(HAL_PortHandle portHandle,
HAL_Bool input, int32_t* status) {
hal::init::CheckInit();
@@ -84,12 +81,6 @@ void HAL_FreeDIOPort(HAL_DigitalHandle dioPortHandle) {
SimDIOData[port->channel].SetInitialized(true);
}
/**
* Allocate a DO PWM Generator.
* Allocate PWM generators so that they are not accidentally reused.
*
* @return PWM Generator handle
*/
HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
auto handle = digitalPWMHandles->Allocate();
if (handle == HAL_kInvalidHandle) {
@@ -109,12 +100,6 @@ HAL_DigitalPWMHandle HAL_AllocateDigitalPWM(int32_t* status) {
return handle;
}
/**
* Free the resource associated with a DO PWM generator.
*
* @param pwmGenerator The pwmGen to free that was allocated with
* allocateDigitalPWM()
*/
void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
auto port = digitalPWMHandles->Get(pwmGenerator);
digitalPWMHandles->Free(pwmGenerator);
@@ -123,14 +108,6 @@ void HAL_FreeDigitalPWM(HAL_DigitalPWMHandle pwmGenerator, int32_t* status) {
SimDigitalPWMData[id].SetInitialized(false);
}
/**
* Change the frequency of the DO PWM generator.
*
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is
* logarithmic.
*
* @param rate The frequency to output all digital output PWM signals.
*/
void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
// Currently rounding in the log rate domain... heavy weight toward picking a
// higher freq.
@@ -143,12 +120,6 @@ void HAL_SetDigitalPWMRate(double rate, int32_t* status) {
// digitalSystem->writePWMPeriodPower(pwmPeriodPower, status);
}
/**
* Configure the duty-cycle of the PWM generator
*
* @param pwmGenerator The generator index reserved by allocateDigitalPWM()
* @param dutyCycle The percent duty cycle to output [0..1].
*/
void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
double dutyCycle, int32_t* status) {
auto port = digitalPWMHandles->Get(pwmGenerator);
@@ -162,12 +133,6 @@ void HAL_SetDigitalPWMDutyCycle(HAL_DigitalPWMHandle pwmGenerator,
SimDigitalPWMData[id].SetDutyCycle(dutyCycle);
}
/**
* Configure which DO channel the PWM signal is output on
*
* @param pwmGenerator The generator index reserved by allocateDigitalPWM()
* @param channel The Digital Output channel to output on
*/
void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
int32_t channel, int32_t* status) {
auto port = digitalPWMHandles->Get(pwmGenerator);
@@ -179,14 +144,6 @@ void HAL_SetDigitalPWMOutputChannel(HAL_DigitalPWMHandle pwmGenerator,
SimDigitalPWMData[id].SetPin(channel);
}
/**
* Write a digital I/O bit to the FPGA.
* Set a single value on a digital I/O channel.
*
* @param channel The Digital I/O channel
* @param value The state to set the digital channel (if it is configured as an
* output)
*/
void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
@@ -200,12 +157,6 @@ void HAL_SetDIO(HAL_DigitalHandle dioPortHandle, HAL_Bool value,
SimDIOData[port->channel].SetValue(value);
}
/**
* Set direction of a DIO channel.
*
* @param channel The Digital I/O channel
* @param input true to set input, false for output
*/
void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
@@ -217,13 +168,6 @@ void HAL_SetDIODirection(HAL_DigitalHandle dioPortHandle, HAL_Bool input,
SimDIOData[port->channel].SetIsInput(input);
}
/**
* Read a digital I/O bit from the FPGA.
* Get a single value from a digital I/O channel.
*
* @param channel The digital I/O channel
* @return The state of the specified channel
*/
HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -236,13 +180,6 @@ HAL_Bool HAL_GetDIO(HAL_DigitalHandle dioPortHandle, int32_t* status) {
return value;
}
/**
* Read the direction of a the Digital I/O lines
* A 1 bit means output and a 0 bit means input.
*
* @param channel The digital I/O channel
* @return The direction of the specified channel
*/
HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -255,14 +192,6 @@ HAL_Bool HAL_GetDIODirection(HAL_DigitalHandle dioPortHandle, int32_t* status) {
return value;
}
/**
* Generate a single pulse.
* Write a pulse to the specified digital output channel. There can only be a
* single pulse going at any time.
*
* @param channel The Digital Output channel that the pulse should be output on
* @param pulseLength The active length of the pulse (in seconds)
*/
void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
@@ -273,11 +202,6 @@ void HAL_Pulse(HAL_DigitalHandle dioPortHandle, double pulseLength,
// TODO (Thad) Add this
}
/**
* Check a DIO line to see if it is currently generating a pulse.
*
* @return A pulse is in progress
*/
HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -288,23 +212,10 @@ HAL_Bool HAL_IsPulsing(HAL_DigitalHandle dioPortHandle, int32_t* status) {
// TODO (Thad) Add this
}
/**
* Check if any DIO line is currently generating a pulse.
*
* @return A pulse on some line is in progress
*/
HAL_Bool HAL_IsAnyPulsing(int32_t* status) {
return false; // TODO(Thad) Figure this out
}
/**
* Write the filter index from the FPGA.
* Set the filter index used to filter out short pulses.
*
* @param dioPortHandle Handle to the digital I/O channel
* @param filterIndex The filter index. Must be in the range 0 - 3, where 0
* means "none" and 1 - 3 means filter # filterIndex - 1.
*/
void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
@@ -316,14 +227,6 @@ void HAL_SetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t filterIndex,
// TODO(Thad) Figure this out
}
/**
* Read the filter index from the FPGA.
* Get the filter index used to filter out short pulses.
*
* @param dioPortHandle Handle to the digital I/O channel
* @return filterIndex The filter index. Must be in the range 0 - 3,
* where 0 means "none" and 1 - 3 means filter # filterIndex - 1.
*/
int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(dioPortHandle, HAL_HandleEnum::DIO);
if (port == nullptr) {
@@ -334,33 +237,10 @@ int32_t HAL_GetFilterSelect(HAL_DigitalHandle dioPortHandle, int32_t* status) {
// TODO(Thad) Figure this out
}
/**
* Set the filter period for the specified filter index.
*
* Set the filter period in FPGA cycles. Even though there are 2 different
* filter index domains (MXP vs HDR), ignore that distinction for now since it
* compilicates the interface. That can be changed later.
*
* @param filterIndex The filter index, 0 - 2.
* @param value The number of cycles that the signal must not transition to be
* counted as a transition.
*/
void HAL_SetFilterPeriod(int32_t filterIndex, int64_t value, int32_t* status) {
// TODO(Thad) figure this out
}
/**
* Get the filter period for the specified filter index.
*
* Get the filter period in FPGA cycles. Even though there are 2 different
* filter index domains (MXP vs HDR), ignore that distinction for now since it
* compilicates the interface. Set status to NiFpga_Status_SoftwareFault if the
* filter values miss-match.
*
* @param filterIndex The filter index, 0 - 2.
* @param value The number of cycles that the signal must not transition to be
* counted as a transition.
*/
int64_t HAL_GetFilterPeriod(int32_t filterIndex, int32_t* status) {
return 0; // TODO(Thad) figure this out
}

View File

@@ -28,26 +28,6 @@ void InitializeDigitalInternal() {
}
} // namespace init
/**
* Map DIO channel numbers from their physical number (10 to 26) to their
* position in the bit field.
*/
int32_t remapMXPChannel(int32_t channel) { return channel - 10; }
int32_t remapMXPPWMChannel(int32_t channel) {
if (channel < 14) {
return channel - 10; // first block of 4 pwms (MXP 0-3)
} else {
return channel - 6; // block of PWMs after SPI
}
}
/**
* remap the digital source channel and set the module.
* If it's an analog trigger, determine the module from the high order routing
* channel else do normal digital input remapping based on channel number
* (MXP)
*/
bool remapDigitalSource(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
uint8_t& channel, uint8_t& module,
@@ -75,6 +55,16 @@ bool remapDigitalSource(HAL_Handle digitalSourceHandle,
}
}
int32_t remapMXPChannel(int32_t channel) { return channel - 10; }
int32_t remapMXPPWMChannel(int32_t channel) {
if (channel < 14) {
return channel - 10; // first block of 4 pwms (MXP 0-3)
} else {
return channel - 6; // block of PWMs after SPI
}
}
int32_t GetDigitalInputChannel(HAL_DigitalHandle handle, int32_t* status) {
auto digital = digitalChannelHandles->Get(handle, HAL_HandleEnum::DIO);
if (digital == nullptr) {

View File

@@ -70,11 +70,24 @@ extern DigitalHandleResource<HAL_DigitalHandle, DigitalPort,
kNumDigitalChannels + kNumPWMHeaders>*
digitalChannelHandles;
/**
* Remap the digital source channel and set the module.
*
* If it's an analog trigger, determine the module from the high order routing
* channel else do normal digital input remapping based on channel number
* (MXP).
*/
bool remapDigitalSource(HAL_Handle digitalSourceHandle,
HAL_AnalogTriggerType analogTriggerType,
uint8_t& channel, uint8_t& module, bool& analogTrigger);
int32_t remapMXPPWMChannel(int32_t channel);
/**
* Map DIO channel numbers from their physical number (10 to 26) to their
* position in the bit field.
*/
int32_t remapMXPChannel(int32_t channel);
int32_t remapMXPPWMChannel(int32_t channel);
int32_t GetDigitalInputChannel(HAL_DigitalHandle handle, int32_t* status);
} // namespace hal

View File

@@ -124,17 +124,7 @@ int32_t HAL_GetJoystickButtons(int32_t joystickNum,
SimDriverStationData->GetJoystickButtons(joystickNum, buttons);
return 0;
}
/**
* Retrieve the Joystick Descriptor for particular slot
* @param desc [out] descriptor (data transfer object) to fill in. desc is
* filled in regardless of success. In other words, if descriptor is not
* available, desc is filled in with default values matching the init-values in
* Java and C++ Driverstation for when caller requests a too-large joystick
* index.
*
* @return error code reported from Network Comm back-end. Zero is good,
* nonzero is bad.
*/
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
HAL_JoystickDescriptor* desc) {
SimDriverStationData->GetJoystickDescriptor(joystickNum, desc);
@@ -241,16 +231,8 @@ bool HAL_IsNewControlData(void) {
return true;
}
/**
* Waits for the newest DS packet to arrive. Note that this is a blocking call.
*/
void HAL_WaitForDSData(void) { HAL_WaitForDSDataTimeout(0); }
/**
* Waits for the newest DS packet to arrive. If timeout is <= 0, this will wait
* forever. Otherwise, it will wait until either a new packet, or the timeout
* time has passed. Returns true on new data, false on timeout.
*/
HAL_Bool HAL_WaitForDSDataTimeout(double timeout) {
auto timeoutTime =
std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
@@ -284,11 +266,6 @@ static int32_t newDataOccur(uint32_t refNum) {
return 0;
}
/*
* Call this to initialize the driver station communication. This will properly
* handle multiple calls. However note that this CANNOT be called from a library
* that interfaces with LabVIEW.
*/
void HAL_InitializeDriverStation(void) {
hal::init::CheckInit();
static std::atomic_bool initialized{false};
@@ -305,10 +282,6 @@ void HAL_InitializeDriverStation(void) {
initialized = true;
}
/*
* Releases the DS Mutex to allow proper shutdown of any threads that are
* waiting on it.
*/
void HAL_ReleaseDSMutex(void) { newDataOccur(refNumber); }
} // extern "C"

View File

@@ -67,10 +67,6 @@ int HAL_LoadOneExtension(const char* library) {
return rc;
}
/**
* Load any extra halsim libraries provided in the HALSIM_EXTENSIONS
* environment variable.
*/
int HAL_LoadExtensions(void) {
int rc = 1;
wpi::SmallVector<wpi::StringRef, 2> libraries;

View File

@@ -83,9 +83,6 @@ HAL_PortHandle HAL_GetPort(int32_t channel) {
return createPortHandle(channel, 1);
}
/**
* @deprecated Uses module numbers
*/
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel) {
// Dont allow a number that wouldn't fit in a uint8_t
if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
@@ -204,44 +201,18 @@ const char* HAL_GetErrorMessage(int32_t code) {
}
}
/**
* Returns the runtime type of this HAL
*/
HAL_RuntimeType HAL_GetRuntimeType(void) { return HAL_Mock; }
/**
* Return the FPGA Version number.
* For now, expect this to be competition year.
* @return FPGA Version number.
*/
int32_t HAL_GetFPGAVersion(int32_t* status) {
return 2018; // Automatically script this at some point
}
/**
* Return the FPGA Revision number.
* The format of the revision is 3 numbers.
* The 12 most significant bits are the Major Revision.
* the next 8 bits are the Minor Revision.
* The 12 least significant bits are the Build Number.
* @return FPGA Revision number.
*/
int64_t HAL_GetFPGARevision(int32_t* status) {
return 0; // TODO: Find a better number to return;
}
/**
* Read the microsecond-resolution timer on the FPGA.
*
* @return The current time in microseconds according to the FPGA (since FPGA
* reset).
*/
uint64_t HAL_GetFPGATime(int32_t* status) { return hal::GetFPGATime(); }
/**
* Get the state of the "USER" button on the roboRIO
* @return true if the button is currently pressed down
*/
HAL_Bool HAL_GetFPGAButton(int32_t* status) {
return SimRoboRioData[0].GetFPGAButton();
}

View File

@@ -166,14 +166,6 @@ HAL_Bool HAL_GetPWMEliminateDeadband(HAL_DigitalHandle pwmPortHandle,
return port->eliminateDeadband;
}
/**
* Set a PWM channel to the desired value. The values range from 0 to 255 and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The PWM value to set.
*/
void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
@@ -185,15 +177,6 @@ void HAL_SetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t value,
SimPWMData[port->channel].SetRawValue(value);
}
/**
* Set a PWM channel to the desired scaled value. The values range from -1 to 1
* and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The scaled PWM value to set.
*/
void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
@@ -215,15 +198,6 @@ void HAL_SetPWMSpeed(HAL_DigitalHandle pwmPortHandle, double speed,
SimPWMData[port->channel].SetSpeed(speed);
}
/**
* Set a PWM channel to the desired position value. The values range from 0 to 1
* and
* the period is controlled
* by the PWM Period and MinHigh registers.
*
* @param channel The PWM channel to set.
* @param value The scaled PWM value to set.
*/
void HAL_SetPWMPosition(HAL_DigitalHandle pwmPortHandle, double pos,
int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
@@ -256,12 +230,6 @@ void HAL_SetPWMDisabled(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
SimPWMData[port->channel].SetSpeed(0);
}
/**
* Get a value from a PWM channel. The values range from 0 to 255.
*
* @param channel The PWM channel to read from.
* @return The raw PWM value.
*/
int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
@@ -272,12 +240,6 @@ int32_t HAL_GetPWMRaw(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
return SimPWMData[port->channel].GetRawValue();
}
/**
* Get a scaled value from a PWM channel. The values range from -1 to 1.
*
* @param channel The PWM channel to read from.
* @return The scaled PWM value.
*/
double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
@@ -295,12 +257,6 @@ double HAL_GetPWMSpeed(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
return speed;
}
/**
* Get a position value from a PWM channel. The values range from 0 to 1.
*
* @param channel The PWM channel to read from.
* @return The scaled PWM value.
*/
double HAL_GetPWMPosition(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
if (port == nullptr) {
@@ -329,12 +285,6 @@ void HAL_LatchPWMZero(HAL_DigitalHandle pwmPortHandle, int32_t* status) {
SimPWMData[port->channel].SetZeroLatch(false);
}
/**
* Set how how often the PWM signal is squelched, thus scaling the period.
*
* @param channel The PWM channel to configure.
* @param squelchMask The 2-bit mask of outputs to squelch.
*/
void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
int32_t* status) {
auto port = digitalChannelHandles->Get(pwmPortHandle, HAL_HandleEnum::PWM);
@@ -346,17 +296,7 @@ void HAL_SetPWMPeriodScale(HAL_DigitalHandle pwmPortHandle, int32_t squelchMask,
SimPWMData[port->channel].SetPeriodScale(squelchMask);
}
/**
* Get the loop timing of the PWM system
*
* @return The loop time
*/
int32_t HAL_GetPWMLoopTiming(int32_t* status) { return kExpectedLoopTiming; }
/**
* Get the pwm starting cycle time
*
* @return The pwm cycle start time.
*/
uint64_t HAL_GetPWMCycleStartTime(int32_t* status) { return 0; }
} // extern "C"

View File

@@ -12,10 +12,8 @@
#include "HALSimPrint.h"
#include "PrintPWM.h"
/**
* Currently, robots never terminate, so we keep a single static object
* and it is never properly released or cleaned up.
*/
// Currently, robots never terminate, so we keep a single static object and it
// is never properly released or cleaned up.
static HALSimPrint halsim;
extern "C" {

View File

@@ -13,13 +13,6 @@
using namespace frc;
/**
* Constructs the ADXL345 Accelerometer over I2C.
*
* @param port The I2C port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure
* @param deviceAddress The I2C address of the accelerometer (0x1D or 0x53)
*/
ADXL345_I2C::ADXL345_I2C(I2C::Port port, Range range, int deviceAddress)
: m_i2c(port, deviceAddress) {
// Turn on the measurements
@@ -43,12 +36,6 @@ double ADXL345_I2C::GetY() { return GetAcceleration(kAxis_Y); }
double ADXL345_I2C::GetZ() { return GetAcceleration(kAxis_Z); }
/**
* Get the acceleration of one axis in Gs.
*
* @param axis The axis to read from.
* @return Acceleration of the ADXL345 in Gs.
*/
double ADXL345_I2C::GetAcceleration(ADXL345_I2C::Axes axis) {
int16_t rawAccel = 0;
m_i2c.Read(kDataRegister + static_cast<int>(axis), sizeof(rawAccel),
@@ -56,12 +43,6 @@ double ADXL345_I2C::GetAcceleration(ADXL345_I2C::Axes axis) {
return rawAccel * kGsPerLSB;
}
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL345 in Gs.
*/
ADXL345_I2C::AllAxes ADXL345_I2C::GetAccelerations() {
AllAxes data = AllAxes();
int16_t rawData[3];

View File

@@ -13,12 +13,6 @@
using namespace frc;
/**
* Constructor.
*
* @param port The SPI port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure
*/
ADXL345_SPI::ADXL345_SPI(SPI::Port port, ADXL345_SPI::Range range)
: m_spi(port) {
m_spi.SetClockRate(500000);
@@ -56,12 +50,6 @@ double ADXL345_SPI::GetY() { return GetAcceleration(kAxis_Y); }
double ADXL345_SPI::GetZ() { return GetAcceleration(kAxis_Z); }
/**
* Get the acceleration of one axis in Gs.
*
* @param axis The axis to read from.
* @return Acceleration of the ADXL345 in Gs.
*/
double ADXL345_SPI::GetAcceleration(ADXL345_SPI::Axes axis) {
uint8_t buffer[3];
uint8_t command[3] = {0, 0, 0};
@@ -74,12 +62,6 @@ double ADXL345_SPI::GetAcceleration(ADXL345_SPI::Axes axis) {
return rawAccel * kGsPerLSB;
}
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL345 in Gs.
*/
ADXL345_SPI::AllAxes ADXL345_SPI::GetAccelerations() {
AllAxes data = AllAxes();
uint8_t dataBuffer[7] = {0, 0, 0, 0, 0, 0, 0};

View File

@@ -31,19 +31,8 @@ static constexpr int kPowerCtl_UltraLowNoise = 0x20;
// static constexpr int kPowerCtl_AutoSleep = 0x04;
static constexpr int kPowerCtl_Measure = 0x02;
/**
* Constructor. Uses the onboard CS1.
*
* @param range The range (+ or -) that the accelerometer will measure.
*/
ADXL362::ADXL362(Range range) : ADXL362(SPI::Port::kOnboardCS1, range) {}
/**
* Constructor.
*
* @param port The SPI port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure.
*/
ADXL362::ADXL362(SPI::Port port, Range range) : m_spi(port) {
m_spi.SetClockRate(3000000);
m_spi.SetMSBFirst();
@@ -108,12 +97,6 @@ double ADXL362::GetY() { return GetAcceleration(kAxis_Y); }
double ADXL362::GetZ() { return GetAcceleration(kAxis_Z); }
/**
* Get the acceleration of one axis in Gs.
*
* @param axis The axis to read from.
* @return Acceleration of the ADXL362 in Gs.
*/
double ADXL362::GetAcceleration(ADXL362::Axes axis) {
if (m_gsPerLSB == 0.0) return 0.0;
@@ -128,12 +111,6 @@ double ADXL362::GetAcceleration(ADXL362::Axes axis) {
return rawAccel * m_gsPerLSB;
}
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL362 in Gs.
*/
ADXL362::AllAxes ADXL362::GetAccelerations() {
AllAxes data = AllAxes();
if (m_gsPerLSB == 0.0) {

View File

@@ -28,39 +28,8 @@ static constexpr int kPIDRegister = 0x0C;
static constexpr int kSNHighRegister = 0x0E;
static constexpr int kSNLowRegister = 0x10;
/**
* Initialize the gyro.
*
* Calibrate the gyro by running for a number of samples and computing the
* center value. Then use the center value as the Accumulator center value for
* subsequent measurements.
*
* It's important to make sure that the robot is not moving while the centering
* calculations are in progress, this is typically done when the robot is first
* turned on while it's sitting at rest before the competition starts.
*/
void ADXRS450_Gyro::Calibrate() {
Wait(0.1);
m_spi.SetAccumulatorCenter(0);
m_spi.ResetAccumulator();
Wait(kCalibrationSampleTime);
m_spi.SetAccumulatorCenter(static_cast<int>(m_spi.GetAccumulatorAverage()));
m_spi.ResetAccumulator();
}
/**
* Gyro constructor on onboard CS0.
*/
ADXRS450_Gyro::ADXRS450_Gyro() : ADXRS450_Gyro(SPI::kOnboardCS0) {}
/**
* Gyro constructor on the specified SPI port.
*
* @param port The SPI port the gyro is attached to.
*/
ADXRS450_Gyro::ADXRS450_Gyro(SPI::Port port) : m_spi(port) {
m_spi.SetClockRate(3000000);
m_spi.SetMSBFirst();
@@ -116,39 +85,25 @@ uint16_t ADXRS450_Gyro::ReadRegister(int reg) {
return static_cast<uint16_t>((BytesToIntBE(buf) >> 5) & 0xffff);
}
/**
* Reset the gyro.
*
* Resets the gyro to a heading of zero. This can be used if there is
* significant drift in the gyro and it needs to be recalibrated after it has
* been running.
*/
void ADXRS450_Gyro::Reset() { m_spi.ResetAccumulator(); }
/**
* Return the actual angle in degrees that the robot is currently facing.
*
* The angle is based on the current accumulator value corrected by the
* oversampling rate, the gyro type and the A/D calibration values.
* The angle is continuous, that is it will continue from 360->361 degrees. This
* allows algorithms that wouldn't want to see a discontinuity in the gyro
* output as it sweeps from 360 to 0 on the second time around.
*
* @return the current heading of the robot in degrees. This heading is based on
* integration of the returned rate from the gyro.
*/
double ADXRS450_Gyro::GetAngle() const {
return m_spi.GetAccumulatorValue() * kDegreePerSecondPerLSB * kSamplePeriod;
}
/**
* Return the rate of rotation of the gyro
*
* The rate is based on the most recent reading of the gyro analog value
*
* @return the current rate in degrees per second
*/
double ADXRS450_Gyro::GetRate() const {
return static_cast<double>(m_spi.GetAccumulatorLastValue()) *
kDegreePerSecondPerLSB;
}
void ADXRS450_Gyro::Reset() { m_spi.ResetAccumulator(); }
void ADXRS450_Gyro::Calibrate() {
Wait(0.1);
m_spi.SetAccumulatorCenter(0);
m_spi.ResetAccumulator();
Wait(kCalibrationSampleTime);
m_spi.SetAccumulatorCenter(static_cast<int>(m_spi.GetAccumulatorAverage()));
m_spi.ResetAccumulator();
}

View File

@@ -14,38 +14,11 @@
using namespace frc;
/**
* Common function for initializing the accelerometer.
*/
void AnalogAccelerometer::InitAccelerometer() {
HAL_Report(HALUsageReporting::kResourceType_Accelerometer,
m_analogInput->GetChannel());
SetName("Accelerometer", m_analogInput->GetChannel());
}
/**
* Create a new instance of an accelerometer.
*
* The constructor allocates desired analog input.
*
* @param channel The channel number for the analog input the accelerometer is
* connected to
*/
AnalogAccelerometer::AnalogAccelerometer(int channel)
: AnalogAccelerometer(std::make_shared<AnalogInput>(channel)) {
AddChild(m_analogInput);
}
/**
* Create a new instance of Accelerometer from an existing AnalogInput.
*
* Make a new instance of accelerometer given an AnalogInput. This is
* particularly useful if the port is going to be read as an analog channel as
* well as through the Accelerometer class.
*
* @param channel The existing AnalogInput object for the analog input the
* accelerometer is connected to
*/
AnalogAccelerometer::AnalogAccelerometer(AnalogInput* channel)
: m_analogInput(channel, NullDeleter<AnalogInput>()) {
if (channel == nullptr) {
@@ -55,16 +28,6 @@ AnalogAccelerometer::AnalogAccelerometer(AnalogInput* channel)
}
}
/**
* Create a new instance of Accelerometer from an existing AnalogInput.
*
* Make a new instance of accelerometer given an AnalogInput. This is
* particularly useful if the port is going to be read as an analog channel as
* well as through the Accelerometer class.
*
* @param channel The existing AnalogInput object for the analog input the
* accelerometer is connected to
*/
AnalogAccelerometer::AnalogAccelerometer(std::shared_ptr<AnalogInput> channel)
: m_analogInput(channel) {
if (channel == nullptr) {
@@ -74,45 +37,16 @@ AnalogAccelerometer::AnalogAccelerometer(std::shared_ptr<AnalogInput> channel)
}
}
/**
* Return the acceleration in Gs.
*
* The acceleration is returned units of Gs.
*
* @return The current acceleration of the sensor in Gs.
*/
double AnalogAccelerometer::GetAcceleration() const {
return (m_analogInput->GetAverageVoltage() - m_zeroGVoltage) / m_voltsPerG;
}
/**
* Set the accelerometer sensitivity.
*
* This sets the sensitivity of the accelerometer used for calculating the
* acceleration. The sensitivity varies by accelerometer model. There are
* constants defined for various models.
*
* @param sensitivity The sensitivity of accelerometer in Volts per G.
*/
void AnalogAccelerometer::SetSensitivity(double sensitivity) {
m_voltsPerG = sensitivity;
}
/**
* Set the voltage that corresponds to 0 G.
*
* The zero G voltage varies by accelerometer model. There are constants defined
* for various models.
*
* @param zero The zero G voltage.
*/
void AnalogAccelerometer::SetZero(double zero) { m_zeroGVoltage = zero; }
/**
* Get the Acceleration for the PID Source parent.
*
* @return The current acceleration in Gs.
*/
double AnalogAccelerometer::PIDGet() { return GetAcceleration(); }
void AnalogAccelerometer::InitSendable(SendableBuilder& builder) {
@@ -120,3 +54,9 @@ void AnalogAccelerometer::InitSendable(SendableBuilder& builder) {
builder.AddDoubleProperty("Value", [=]() { return GetAcceleration(); },
nullptr);
}
void AnalogAccelerometer::InitAccelerometer() {
HAL_Report(HALUsageReporting::kResourceType_Accelerometer,
m_analogInput->GetChannel());
SetName("Accelerometer", m_analogInput->GetChannel());
}

View File

@@ -19,43 +19,15 @@
using namespace frc;
/**
* Gyro constructor using the Analog Input channel number.
*
* @param channel The analog channel the gyro is connected to. Gyros can only
* be used on on-board Analog Inputs 0-1.
*/
AnalogGyro::AnalogGyro(int channel)
: AnalogGyro(std::make_shared<AnalogInput>(channel)) {
AddChild(m_analog);
}
/**
* Gyro constructor with a precreated AnalogInput object.
*
* Use this constructor when the analog channel needs to be shared.
* This object will not clean up the AnalogInput object when using this
* constructor.
*
* Gyros can only be used on on-board channels 0-1.
*
* @param channel A pointer to the AnalogInput object that the gyro is
* connected to.
*/
AnalogGyro::AnalogGyro(AnalogInput* channel)
: AnalogGyro(
std::shared_ptr<AnalogInput>(channel, NullDeleter<AnalogInput>())) {}
/**
* Gyro constructor with a precreated AnalogInput object.
*
* Use this constructor when the analog channel needs to be shared.
* This object will not clean up the AnalogInput object when using this
* constructor.
*
* @param channel A pointer to the AnalogInput object that the gyro is
* connected to.
*/
AnalogGyro::AnalogGyro(std::shared_ptr<AnalogInput> channel)
: m_analog(channel) {
if (channel == nullptr) {
@@ -66,32 +38,11 @@ AnalogGyro::AnalogGyro(std::shared_ptr<AnalogInput> channel)
}
}
/**
* Gyro constructor using the Analog Input channel number with parameters for
* presetting the center and offset values. Bypasses calibration.
*
* @param channel The analog channel the gyro is connected to. Gyros can only
* be used on on-board Analog Inputs 0-1.
* @param center Preset uncalibrated value to use as the accumulator center
* value.
* @param offset Preset uncalibrated value to use as the gyro offset.
*/
AnalogGyro::AnalogGyro(int channel, int center, double offset)
: AnalogGyro(std::make_shared<AnalogInput>(channel), center, offset) {
AddChild(m_analog);
}
/**
* Gyro constructor with a precreated AnalogInput object and calibrated
* parameters.
*
* Use this constructor when the analog channel needs to be shared.
* This object will not clean up the AnalogInput object when using this
* constructor.
*
* @param channel A pointer to the AnalogInput object that the gyro is
* connected to.
*/
AnalogGyro::AnalogGyro(std::shared_ptr<AnalogInput> channel, int center,
double offset)
: m_analog(channel) {
@@ -111,19 +62,54 @@ AnalogGyro::AnalogGyro(std::shared_ptr<AnalogInput> channel, int center,
}
}
/**
* AnalogGyro Destructor
*
*/
AnalogGyro::~AnalogGyro() { HAL_FreeAnalogGyro(m_gyroHandle); }
/**
* Reset the gyro.
*
* Resets the gyro to a heading of zero. This can be used if there is
* significant drift in the gyro and it needs to be recalibrated after it has
* been running.
*/
double AnalogGyro::GetAngle() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
double value = HAL_GetAnalogGyroAngle(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
double AnalogGyro::GetRate() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
double value = HAL_GetAnalogGyroRate(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
int AnalogGyro::GetCenter() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
int value = HAL_GetAnalogGyroCenter(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
double AnalogGyro::GetOffset() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
double value = HAL_GetAnalogGyroOffset(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
void AnalogGyro::SetSensitivity(double voltsPerDegreePerSecond) {
int32_t status = 0;
HAL_SetAnalogGyroVoltsPerDegreePerSecond(m_gyroHandle,
voltsPerDegreePerSecond, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
void AnalogGyro::SetDeadband(double volts) {
if (StatusIsFatal()) return;
int32_t status = 0;
HAL_SetAnalogGyroDeadband(m_gyroHandle, volts, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
void AnalogGyro::Reset() {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -131,9 +117,6 @@ void AnalogGyro::Reset() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Initialize the gyro. Calibration is handled by Calibrate().
*/
void AnalogGyro::InitGyro() {
if (StatusIsFatal()) return;
if (m_gyroHandle == HAL_kInvalidHandle) {
@@ -173,98 +156,3 @@ void AnalogGyro::Calibrate() {
HAL_CalibrateAnalogGyro(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Return the actual angle in degrees that the robot is currently facing.
*
* The angle is based on the current accumulator value corrected by the
* oversampling rate, the gyro type and the A/D calibration values.
* The angle is continuous, that is it will continue from 360->361 degrees. This
* allows algorithms that wouldn't want to see a discontinuity in the gyro
* output as it sweeps from 360 to 0 on the second time around.
*
* @return the current heading of the robot in degrees. This heading is based on
* integration of the returned rate from the gyro.
*/
double AnalogGyro::GetAngle() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
double value = HAL_GetAnalogGyroAngle(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
/**
* Return the rate of rotation of the gyro
*
* The rate is based on the most recent reading of the gyro analog value
*
* @return the current rate in degrees per second
*/
double AnalogGyro::GetRate() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
double value = HAL_GetAnalogGyroRate(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
/**
* Return the gyro offset value. If run after calibration,
* the offset value can be used as a preset later.
*
* @return the current offset value
*/
double AnalogGyro::GetOffset() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
double value = HAL_GetAnalogGyroOffset(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
/**
* Return the gyro center value. If run after calibration,
* the center value can be used as a preset later.
*
* @return the current center value
*/
int AnalogGyro::GetCenter() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
int value = HAL_GetAnalogGyroCenter(m_gyroHandle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
/**
* Set the gyro sensitivity.
*
* This takes the number of volts/degree/second sensitivity of the gyro and uses
* it in subsequent calculations to allow the code to work with multiple gyros.
* This value is typically found in the gyro datasheet.
*
* @param voltsPerDegreePerSecond The sensitivity in Volts/degree/second
*/
void AnalogGyro::SetSensitivity(double voltsPerDegreePerSecond) {
int32_t status = 0;
HAL_SetAnalogGyroVoltsPerDegreePerSecond(m_gyroHandle,
voltsPerDegreePerSecond, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set the size of the neutral zone.
*
* Any voltage from the gyro less than this amount from the center is
* considered stationary. Setting a deadband will decrease the amount of drift
* when the gyro isn't rotating, but will make it less accurate.
*
* @param volts The size of the deadband in volts
*/
void AnalogGyro::SetDeadband(double volts) {
if (StatusIsFatal()) return;
int32_t status = 0;
HAL_SetAnalogGyroDeadband(m_gyroHandle, volts, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}

View File

@@ -19,12 +19,6 @@
using namespace frc;
/**
* Construct an analog input.
*
* @param channel The channel number on the roboRIO to represent. 0-3 are
* on-board 4-7 are on the MXP port.
*/
AnalogInput::AnalogInput(int channel) {
if (!SensorUtil::CheckAnalogInputChannel(channel)) {
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange,
@@ -49,23 +43,11 @@ AnalogInput::AnalogInput(int channel) {
SetName("AnalogInput", channel);
}
/**
* Channel destructor.
*/
AnalogInput::~AnalogInput() {
HAL_FreeAnalogInputPort(m_port);
m_port = HAL_kInvalidHandle;
}
/**
* Get a sample straight from this channel.
*
* The sample is a 12-bit value representing the 0V to 5V range of the A/D
* converter in the module. The units are in A/D converter codes. Use
* GetVoltage() to get the analog value in calibrated units.
*
* @return A sample straight from this channel.
*/
int AnalogInput::GetValue() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
@@ -74,20 +56,6 @@ int AnalogInput::GetValue() const {
return value;
}
/**
* Get a sample from the output of the oversample and average engine for this
* channel.
*
* The sample is 12-bit + the bits configured in SetOversampleBits().
* The value configured in SetAverageBits() will cause this value to be averaged
* 2**bits number of samples.
* This is not a sliding window. The sample will not change until
* 2**(OversampleBits + AverageBits) samples
* have been acquired from the module on this channel.
* Use GetAverageVoltage() to get the analog value in calibrated units.
*
* @return A sample from the oversample and average engine for this channel.
*/
int AnalogInput::GetAverageValue() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
@@ -96,14 +64,6 @@ int AnalogInput::GetAverageValue() const {
return value;
}
/**
* Get a scaled sample straight from this channel.
*
* The value is scaled to units of Volts using the calibrated scaling data from
* GetLSBWeight() and GetOffset().
*
* @return A scaled sample straight from this channel.
*/
double AnalogInput::GetVoltage() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
@@ -112,20 +72,6 @@ double AnalogInput::GetVoltage() const {
return voltage;
}
/**
* Get a scaled sample from the output of the oversample and average engine for
* this channel.
*
* The value is scaled to units of Volts using the calibrated scaling data from
* GetLSBWeight() and GetOffset().
* Using oversampling will cause this value to be higher resolution, but it will
* update more slowly.
* Using averaging will cause this value to be more stable, but it will update
* more slowly.
*
* @return A scaled sample from the output of the oversample and average engine
* for this channel.
*/
double AnalogInput::GetAverageVoltage() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
@@ -134,57 +80,11 @@ double AnalogInput::GetAverageVoltage() const {
return voltage;
}
/**
* Get the factory scaling least significant bit weight constant.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @return Least significant bit weight.
*/
int AnalogInput::GetLSBWeight() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
int lsbWeight = HAL_GetAnalogLSBWeight(m_port, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return lsbWeight;
}
/**
* Get the factory scaling offset constant.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @return Offset constant.
*/
int AnalogInput::GetOffset() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
int offset = HAL_GetAnalogOffset(m_port, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return offset;
}
/**
* Get the channel number.
*
* @return The channel number.
*/
int AnalogInput::GetChannel() const {
if (StatusIsFatal()) return 0;
return m_channel;
}
/**
* Set the number of averaging bits.
*
* This sets the number of averaging bits. The actual number of averaged samples
* is 2^bits.
* Use averaging to improve the stability of your measurement at the expense of
* sampling rate.
* The averaging is done automatically in the FPGA.
*
* @param bits Number of bits of averaging.
*/
void AnalogInput::SetAverageBits(int bits) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -192,14 +92,6 @@ void AnalogInput::SetAverageBits(int bits) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Get the number of averaging bits previously configured.
*
* This gets the number of averaging bits from the FPGA. The actual number of
* averaged samples is 2^bits. The averaging is done automatically in the FPGA.
*
* @return Number of bits of averaging previously configured.
*/
int AnalogInput::GetAverageBits() const {
int32_t status = 0;
int averageBits = HAL_GetAnalogAverageBits(m_port, &status);
@@ -207,16 +99,6 @@ int AnalogInput::GetAverageBits() const {
return averageBits;
}
/**
* Set the number of oversample bits.
*
* This sets the number of oversample bits. The actual number of oversampled
* values is 2^bits. Use oversampling to improve the resolution of your
* measurements at the expense of sampling rate. The oversampling is done
* automatically in the FPGA.
*
* @param bits Number of bits of oversampling.
*/
void AnalogInput::SetOversampleBits(int bits) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -224,15 +106,6 @@ void AnalogInput::SetOversampleBits(int bits) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Get the number of oversample bits previously configured.
*
* This gets the number of oversample bits from the FPGA. The actual number of
* oversampled values is 2^bits. The oversampling is done automatically in the
* FPGA.
*
* @return Number of bits of oversampling previously configured.
*/
int AnalogInput::GetOversampleBits() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
@@ -241,11 +114,22 @@ int AnalogInput::GetOversampleBits() const {
return oversampleBits;
}
/**
* Is the channel attached to an accumulator.
*
* @return The analog input is attached to an accumulator.
*/
int AnalogInput::GetLSBWeight() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
int lsbWeight = HAL_GetAnalogLSBWeight(m_port, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return lsbWeight;
}
int AnalogInput::GetOffset() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
int offset = HAL_GetAnalogOffset(m_port, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return offset;
}
bool AnalogInput::IsAccumulatorChannel() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -254,9 +138,6 @@ bool AnalogInput::IsAccumulatorChannel() const {
return isAccum;
}
/**
* Initialize the accumulator.
*/
void AnalogInput::InitAccumulator() {
if (StatusIsFatal()) return;
m_accumulatorOffset = 0;
@@ -265,22 +146,11 @@ void AnalogInput::InitAccumulator() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set an initial value for the accumulator.
*
* This will be added to all values returned to the user.
*
* @param initialValue The value that the accumulator should start from when
* reset.
*/
void AnalogInput::SetAccumulatorInitialValue(int64_t initialValue) {
if (StatusIsFatal()) return;
m_accumulatorOffset = initialValue;
}
/**
* Resets the accumulator to the initial value.
*/
void AnalogInput::ResetAccumulator() {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -297,17 +167,6 @@ void AnalogInput::ResetAccumulator() {
}
}
/**
* Set the center value of the accumulator.
*
* The center value is subtracted from each A/D value before it is added to the
* accumulator. This is used for the center value of devices like gyros and
* accelerometers to take the device offset into account when integrating.
*
* This center value is based on the output of the oversampled and averaged
* source from the accumulator channel. Because of this, any non-zero
* oversample bits will affect the size of the value for this field.
*/
void AnalogInput::SetAccumulatorCenter(int center) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -315,9 +174,6 @@ void AnalogInput::SetAccumulatorCenter(int center) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set the accumulator's deadband.
*/
void AnalogInput::SetAccumulatorDeadband(int deadband) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -325,14 +181,6 @@ void AnalogInput::SetAccumulatorDeadband(int deadband) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Read the accumulated value.
*
* Read the value that has been accumulating.
* The accumulator is attached after the oversample and average engine.
*
* @return The 64-bit value accumulated since the last Reset().
*/
int64_t AnalogInput::GetAccumulatorValue() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
@@ -341,14 +189,6 @@ int64_t AnalogInput::GetAccumulatorValue() const {
return value + m_accumulatorOffset;
}
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last
* Reset().
*
* @return The number of times samples from the channel were accumulated.
*/
int64_t AnalogInput::GetAccumulatorCount() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
@@ -357,15 +197,6 @@ int64_t AnalogInput::GetAccumulatorCount() const {
return count;
}
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* This function reads the value and count from the FPGA atomically.
* This can be used for averaging.
*
* @param value Reference to the 64-bit accumulated output.
* @param count Reference to the number of accumulation cycles.
*/
void AnalogInput::GetAccumulatorOutput(int64_t& value, int64_t& count) const {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -374,25 +205,12 @@ void AnalogInput::GetAccumulatorOutput(int64_t& value, int64_t& count) const {
value += m_accumulatorOffset;
}
/**
* Set the sample rate per channel for all analog channels.
*
* The maximum rate is 500kS/s divided by the number of channels in use.
* This is 62500 samples/s per channel.
*
* @param samplesPerSecond The number of samples per second.
*/
void AnalogInput::SetSampleRate(double samplesPerSecond) {
int32_t status = 0;
HAL_SetAnalogSampleRate(samplesPerSecond, &status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Get the current sample rate for all channels
*
* @return Sample rate.
*/
double AnalogInput::GetSampleRate() {
int32_t status = 0;
double sampleRate = HAL_GetAnalogSampleRate(&status);
@@ -400,11 +218,6 @@ double AnalogInput::GetSampleRate() {
return sampleRate;
}
/**
* Get the Average value for the PID Source base object.
*
* @return The average voltage.
*/
double AnalogInput::PIDGet() {
if (StatusIsFatal()) return 0.0;
return GetAverageVoltage();

View File

@@ -18,13 +18,6 @@
using namespace frc;
/**
* Construct an analog output on the given channel.
*
* All analog outputs are located on the MXP port.
*
* @param channel The channel number on the roboRIO to represent.
*/
AnalogOutput::AnalogOutput(int channel) {
if (!SensorUtil::CheckAnalogOutputChannel(channel)) {
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange,
@@ -51,23 +44,8 @@ AnalogOutput::AnalogOutput(int channel) {
SetName("AnalogOutput", m_channel);
}
/**
* Destructor.
*
* Frees analog output resource.
*/
AnalogOutput::~AnalogOutput() { HAL_FreeAnalogOutputPort(m_port); }
/**
* Get the channel of this AnalogOutput.
*/
int AnalogOutput::GetChannel() { return m_channel; }
/**
* Set the value of the analog output.
*
* @param voltage The output value in Volts, from 0.0 to +5.0
*/
void AnalogOutput::SetVoltage(double voltage) {
int32_t status = 0;
HAL_SetAnalogOutput(m_port, voltage, &status);
@@ -75,11 +53,6 @@ void AnalogOutput::SetVoltage(double voltage) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Get the voltage of the analog output
*
* @return The value in Volts, from 0.0 to +5.0
*/
double AnalogOutput::GetVoltage() const {
int32_t status = 0;
double voltage = HAL_GetAnalogOutput(m_port, &status);
@@ -89,6 +62,8 @@ double AnalogOutput::GetVoltage() const {
return voltage;
}
int AnalogOutput::GetChannel() { return m_channel; }
void AnalogOutput::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Analog Output");
builder.AddDoubleProperty("Value", [=]() { return GetVoltage(); },

View File

@@ -12,16 +12,6 @@
using namespace frc;
/**
* Construct an Analog Potentiometer object from a channel number.
*
* @param channel The channel number on the roboRIO to represent. 0-3 are
* on-board 4-7 are on the MXP port.
* @param fullRange The angular value (in desired units) representing the full
* 0-5V range of the input.
* @param offset The angular value (in desired units) representing the
* angular output at 0V.
*/
AnalogPotentiometer::AnalogPotentiometer(int channel, double fullRange,
double offset)
: m_analog_input(std::make_shared<AnalogInput>(channel)),
@@ -30,58 +20,24 @@ AnalogPotentiometer::AnalogPotentiometer(int channel, double fullRange,
AddChild(m_analog_input);
}
/**
* Construct an Analog Potentiometer object from an existing Analog Input
* pointer.
*
* @param channel The existing Analog Input pointer
* @param fullRange The angular value (in desired units) representing the full
* 0-5V range of the input.
* @param offset The angular value (in desired units) representing the
* angular output at 0V.
*/
AnalogPotentiometer::AnalogPotentiometer(AnalogInput* input, double fullRange,
double offset)
: m_analog_input(input, NullDeleter<AnalogInput>()),
m_fullRange(fullRange),
m_offset(offset) {}
/**
* Construct an Analog Potentiometer object from an existing Analog Input
* pointer.
*
* @param channel The existing Analog Input pointer
* @param fullRange The angular value (in desired units) representing the full
* 0-5V range of the input.
* @param offset The angular value (in desired units) representing the
* angular output at 0V.
*/
AnalogPotentiometer::AnalogPotentiometer(std::shared_ptr<AnalogInput> input,
double fullRange, double offset)
: m_analog_input(input), m_fullRange(fullRange), m_offset(offset) {}
/**
* Get the current reading of the potentiometer.
*
* @return The current position of the potentiometer (in the units used for
* fullRange and offset).
*/
double AnalogPotentiometer::Get() const {
return (m_analog_input->GetVoltage() / RobotController::GetVoltage5V()) *
m_fullRange +
m_offset;
}
/**
* Implement the PIDSource interface.
*
* @return The current reading.
*/
double AnalogPotentiometer::PIDGet() { return Get(); }
/**
* Live Window code, only does anything if live window is activated.
*/
void AnalogPotentiometer::InitSendable(SendableBuilder& builder) {
m_analog_input->InitSendable(builder);
}

View File

@@ -16,26 +16,12 @@
using namespace frc;
/**
* Constructor for an analog trigger given a channel number.
*
* @param channel The channel number on the roboRIO to represent. 0-3 are
* on-board 4-7 are on the MXP port.
*/
AnalogTrigger::AnalogTrigger(int channel)
: AnalogTrigger(new AnalogInput(channel)) {
m_ownsAnalog = true;
AddChild(m_analogInput);
}
/**
* Construct an analog trigger given an analog input.
*
* This should be used in the case of sharing an analog channel between the
* trigger and an analog input object.
*
* @param channel The pointer to the existing AnalogInput object
*/
AnalogTrigger::AnalogTrigger(AnalogInput* input) {
m_analogInput = input;
int32_t status = 0;
@@ -62,30 +48,6 @@ AnalogTrigger::~AnalogTrigger() {
}
}
/**
* Set the upper and lower limits of the analog trigger.
*
* The limits are given in ADC codes. If oversampling is used, the units must
* be scaled appropriately.
*
* @param lower The lower limit of the trigger in ADC codes (12-bit values).
* @param upper The upper limit of the trigger in ADC codes (12-bit values).
*/
void AnalogTrigger::SetLimitsRaw(int lower, int upper) {
if (StatusIsFatal()) return;
int32_t status = 0;
HAL_SetAnalogTriggerLimitsRaw(m_trigger, lower, upper, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set the upper and lower limits of the analog trigger.
*
* The limits are given as floating point voltage values.
*
* @param lower The lower limit of the trigger in Volts.
* @param upper The upper limit of the trigger in Volts.
*/
void AnalogTrigger::SetLimitsVoltage(double lower, double upper) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -93,15 +55,13 @@ void AnalogTrigger::SetLimitsVoltage(double lower, double upper) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Configure the analog trigger to use the averaged vs. raw values.
*
* If the value is true, then the averaged value is selected for the analog
* trigger, otherwise the immediate value is used.
*
* @param useAveragedValue If true, use the Averaged value, otherwise use the
* instantaneous reading
*/
void AnalogTrigger::SetLimitsRaw(int lower, int upper) {
if (StatusIsFatal()) return;
int32_t status = 0;
HAL_SetAnalogTriggerLimitsRaw(m_trigger, lower, upper, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
void AnalogTrigger::SetAveraged(bool useAveragedValue) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -109,16 +69,6 @@ void AnalogTrigger::SetAveraged(bool useAveragedValue) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Configure the analog trigger to use a filtered value.
*
* The analog trigger will operate with a 3 point average rejection filter. This
* is designed to help with 360 degree pot applications for the period where
* the pot crosses through zero.
*
* @param useFilteredValue If true, use the 3 point rejection filter, otherwise
* use the unfiltered value
*/
void AnalogTrigger::SetFiltered(bool useFilteredValue) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -126,25 +76,11 @@ void AnalogTrigger::SetFiltered(bool useFilteredValue) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Return the index of the analog trigger.
*
* This is the FPGA index of this analog trigger instance.
*
* @return The index of the analog trigger.
*/
int AnalogTrigger::GetIndex() const {
if (StatusIsFatal()) return -1;
return m_index;
}
/**
* Return the InWindow output of the analog trigger.
*
* True if the analog input is between the upper and lower limits.
*
* @return True if the analog input is between the upper and lower limits.
*/
bool AnalogTrigger::GetInWindow() {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -153,16 +89,6 @@ bool AnalogTrigger::GetInWindow() {
return result;
}
/**
* Return the TriggerState output of the analog trigger.
*
* True if above upper limit.
* False if below lower limit.
* If in Hysteresis, maintain previous state.
*
* @return True if above upper limit. False if below lower limit. If in
* Hysteresis, maintain previous state.
*/
bool AnalogTrigger::GetTriggerState() {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -171,15 +97,6 @@ bool AnalogTrigger::GetTriggerState() {
return result;
}
/**
* Creates an AnalogTriggerOutput object.
*
* Gets an output object that can be used for routing.
* Caller is responsible for deleting the AnalogTriggerOutput object.
*
* @param type An enum of the type of output object to create.
* @return A pointer to a new AnalogTriggerOutput object.
*/
std::shared_ptr<AnalogTriggerOutput> AnalogTrigger::CreateOutput(
AnalogTriggerType type) const {
if (StatusIsFatal()) return nullptr;

View File

@@ -14,24 +14,6 @@
using namespace frc;
/**
* Create an object that represents one of the four outputs from an analog
* trigger.
*
* Because this class derives from DigitalSource, it can be passed into routing
* functions for Counter, Encoder, etc.
*
* @param trigger A pointer to the trigger for which this is an output.
* @param outputType An enum that specifies the output on the trigger to
* represent.
*/
AnalogTriggerOutput::AnalogTriggerOutput(const AnalogTrigger& trigger,
AnalogTriggerType outputType)
: m_trigger(trigger), m_outputType(outputType) {
HAL_Report(HALUsageReporting::kResourceType_AnalogTriggerOutput,
trigger.GetIndex(), static_cast<uint8_t>(outputType));
}
AnalogTriggerOutput::~AnalogTriggerOutput() {
if (m_interrupt != HAL_kInvalidHandle) {
int32_t status = 0;
@@ -41,11 +23,6 @@ AnalogTriggerOutput::~AnalogTriggerOutput() {
}
}
/**
* Get the state of the analog trigger output.
*
* @return The state of the analog trigger output.
*/
bool AnalogTriggerOutput::Get() const {
int32_t status = 0;
bool result = HAL_GetAnalogTriggerOutput(
@@ -55,28 +32,23 @@ bool AnalogTriggerOutput::Get() const {
return result;
}
/**
* @return The HAL Handle to the specified source.
*/
HAL_Handle AnalogTriggerOutput::GetPortHandleForRouting() const {
return m_trigger.m_trigger;
}
/**
* Is source an AnalogTrigger
*/
bool AnalogTriggerOutput::IsAnalogTrigger() const { return true; }
/**
* @return The type of analog trigger output to be used.
*/
AnalogTriggerType AnalogTriggerOutput::GetAnalogTriggerTypeForRouting() const {
return m_outputType;
}
/**
* @return The channel of the source.
*/
bool AnalogTriggerOutput::IsAnalogTrigger() const { return true; }
int AnalogTriggerOutput::GetChannel() const { return m_trigger.m_index; }
void AnalogTriggerOutput::InitSendable(SendableBuilder&) {}
AnalogTriggerOutput::AnalogTriggerOutput(const AnalogTrigger& trigger,
AnalogTriggerType outputType)
: m_trigger(trigger), m_outputType(outputType) {
HAL_Report(HALUsageReporting::kResourceType_AnalogTriggerOutput,
trigger.GetIndex(), static_cast<uint8_t>(outputType));
}

View File

@@ -15,11 +15,6 @@
using namespace frc;
/**
* Constructor.
*
* @param range The range the accelerometer will measure
*/
BuiltInAccelerometer::BuiltInAccelerometer(Range range) {
SetRange(range);
@@ -39,19 +34,10 @@ void BuiltInAccelerometer::SetRange(Range range) {
HAL_SetAccelerometerActive(true);
}
/**
* @return The acceleration of the roboRIO along the X axis in g-forces
*/
double BuiltInAccelerometer::GetX() { return HAL_GetAccelerometerX(); }
/**
* @return The acceleration of the roboRIO along the Y axis in g-forces
*/
double BuiltInAccelerometer::GetY() { return HAL_GetAccelerometerY(); }
/**
* @return The acceleration of the roboRIO along the Z axis in g-forces
*/
double BuiltInAccelerometer::GetZ() { return HAL_GetAccelerometerZ(); }
void BuiltInAccelerometer::InitSendable(SendableBuilder& builder) {

View File

@@ -9,42 +9,12 @@
using namespace frc;
/**
* Specifies the command to run when a button is first pressed.
*
* @param command The pointer to the command to run
*/
void Button::WhenPressed(Command* command) { WhenActive(command); }
/**
* Specifies the command to be scheduled while the button is pressed.
*
* The command will be scheduled repeatedly while the button is pressed and will
* be canceled when the button is released.
*
* @param command The pointer to the command to run
*/
void Button::WhileHeld(Command* command) { WhileActive(command); }
/**
* Specifies the command to run when the button is released.
*
* The command will be scheduled a single time.
*
* @param command The pointer to the command to run
*/
void Button::WhenReleased(Command* command) { WhenInactive(command); }
/**
* Cancels the specificed command when the button is pressed.
*
* @param command The command to be canceled
*/
void Button::CancelWhenPressed(Command* command) { CancelWhenActive(command); }
/**
* Toggle the specified command when the button is pressed.
*
* @param command The command to be toggled
*/
void Button::ToggleWhenPressed(Command* command) { ToggleWhenActive(command); }

View File

@@ -11,10 +11,6 @@
using namespace frc;
/**
* Create a new CAN communication interface with the specific device ID.
* The device ID is 6 bits (0-63)
*/
CAN::CAN(int deviceId) {
int32_t status = 0;
m_handle =
@@ -28,9 +24,6 @@ CAN::CAN(int deviceId) {
// HAL_Report(HALUsageReporting::kResourceType_CAN, deviceId);
}
/**
* Closes the CAN communication.
*/
CAN::~CAN() {
if (StatusIsFatal()) return;
if (m_handle != HAL_kInvalidHandle) {
@@ -39,29 +32,12 @@ CAN::~CAN() {
}
}
/**
* Write a packet to the CAN device with a specific ID. This ID is 10 bits.
*
* @param data The data to write (8 bytes max)
* @param length The data length to write
* @param apiId The API ID to write.
*/
void CAN::WritePacket(const uint8_t* data, int length, int apiId) {
int32_t status = 0;
HAL_WriteCANPacket(m_handle, data, length, apiId, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Write a repeating packet to the CAN device with a specific ID. This ID is 10
* bits. The RoboRIO will automatically repeat the packet at the specified
* interval
*
* @param data The data to write (8 bytes max)
* @param length The data length to write
* @param apiId The API ID to write.
* @param repeatMs The period to repeat the packet at.
*/
void CAN::WritePacketRepeating(const uint8_t* data, int length, int apiId,
int repeatMs) {
int32_t status = 0;
@@ -69,25 +45,12 @@ void CAN::WritePacketRepeating(const uint8_t* data, int length, int apiId,
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Stop a repeating packet with a specific ID. This ID is 10 bits.
*
* @param apiId The API ID to stop repeating
*/
void CAN::StopPacketRepeating(int apiId) {
int32_t status = 0;
HAL_StopCANPacketRepeating(m_handle, apiId, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Read a new CAN packet. This will only return properly once per packet
* received. Multiple calls without receiving another packet will return false.
*
* @param apiId The API ID to read.
* @param data Storage for the received data.
* @return True if the data is valid, otherwise false.
*/
bool CAN::ReadPacketNew(int apiId, CANData* data) {
int32_t status = 0;
HAL_ReadCANPacketNew(m_handle, apiId, data->data, &data->length,
@@ -103,14 +66,6 @@ bool CAN::ReadPacketNew(int apiId, CANData* data) {
}
}
/**
* Read a CAN packet. The will continuously return the last packet received,
* without accounting for packet age.
*
* @param apiId The API ID to read.
* @param data Storage for the received data.
* @return True if the data is valid, otherwise false.
*/
bool CAN::ReadPacketLatest(int apiId, CANData* data) {
int32_t status = 0;
HAL_ReadCANPacketLatest(m_handle, apiId, data->data, &data->length,
@@ -126,15 +81,6 @@ bool CAN::ReadPacketLatest(int apiId, CANData* data) {
}
}
/**
* Read a CAN packet. The will return the last packet received until the
* packet is older then the requested timeout. Then it will return false.
*
* @param apiId The API ID to read.
* @param timeoutMs The timeout time for the packet
* @param data Storage for the received data.
* @return True if the data is valid, otherwise false.
*/
bool CAN::ReadPacketTimeout(int apiId, int timeoutMs, CANData* data) {
int32_t status = 0;
HAL_ReadCANPacketTimeout(m_handle, apiId, data->data, &data->length,
@@ -151,20 +97,6 @@ bool CAN::ReadPacketTimeout(int apiId, int timeoutMs, CANData* data) {
}
}
/**
* Read a CAN packet. The will return the last packet received until the
* packet is older then the requested timeout. Then it will return false.
* The period parameter is used when you know the packet is sent at specific
* intervals, so calls will not attempt to read a new packet from the
* network until that period has passed. We do not recommend users use this
* API unless they know the implications.
*
* @param apiId The API ID to read.
* @param timeoutMs The timeout time for the packet
* @param periodMs The usual period for the packet
* @param data Storage for the received data.
* @return True if the data is valid, otherwise false.
*/
bool CAN::ReadPeriodicPacket(int apiId, int timeoutMs, int periodMs,
CANData* data) {
int32_t status = 0;

View File

@@ -21,35 +21,12 @@ using namespace frc;
int Command::m_commandCounter = 0;
/**
* Creates a new command.
*
* The name of this command will be default.
*/
Command::Command() : Command("", -1.0) {}
/**
* Creates a new command with the given name and no timeout.
*
* @param name the name for this command
*/
Command::Command(const wpi::Twine& name) : Command(name, -1.0) {}
/**
* Creates a new command with the given timeout and a default name.
*
* @param timeout the time (in seconds) before this command "times out"
* @see IsTimedOut()
*/
Command::Command(double timeout) : Command("", timeout) {}
/**
* Creates a new command with the given name and timeout.
*
* @param name the name of the command
* @param timeout the time (in seconds) before this command "times out"
* @see IsTimedOut()
*/
Command::Command(const wpi::Twine& name, double timeout) : SendableBase(false) {
// We use -1.0 to indicate no timeout.
if (timeout < 0.0 && timeout != -1.0)
@@ -66,35 +43,6 @@ Command::Command(const wpi::Twine& name, double timeout) : SendableBase(false) {
}
}
/**
* Get the ID (sequence number) for this command.
*
* The ID is a unique sequence number that is incremented for each command.
*
* @return The ID of this command
*/
int Command::GetID() const { return m_commandID; }
/**
* Sets the timeout of this command.
*
* @param timeout the timeout (in seconds)
* @see IsTimedOut()
*/
void Command::SetTimeout(double timeout) {
if (timeout < 0.0)
wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0");
else
m_timeout = timeout;
}
/**
* Returns the time since this command was initialized (in seconds).
*
* This function will work even if there is no specified timeout.
*
* @return the time since this command was initialized (in seconds).
*/
double Command::TimeSinceInitialized() const {
if (m_startTime < 0.0)
return 0.0;
@@ -102,16 +50,6 @@ double Command::TimeSinceInitialized() const {
return Timer::GetFPGATimestamp() - m_startTime;
}
/**
* This method specifies that the given Subsystem is used by this command.
*
* This method is crucial to the functioning of the Command System in general.
*
* Note that the recommended way to call this method is in the constructor.
*
* @param subsystem The Subsystem required
* @see Subsystem
*/
void Command::Requires(Subsystem* subsystem) {
if (!AssertUnlocked("Can not add new requirement to command")) return;
@@ -121,34 +59,6 @@ void Command::Requires(Subsystem* subsystem) {
wpi_setWPIErrorWithContext(NullParameter, "subsystem");
}
/**
* Called when the command has been removed.
*
* This will call Interrupted() or End().
*/
void Command::Removed() {
if (m_initialized) {
if (IsCanceled()) {
Interrupted();
_Interrupted();
} else {
End();
_End();
}
}
m_initialized = false;
m_canceled = false;
m_running = false;
m_completed = true;
}
/**
* Starts up the command. Gets the command ready to start.
*
* Note that the command will eventually start, however it will not necessarily
* do so immediately, and may in fact be canceled before initialize is even
* called.
*/
void Command::Start() {
LockChanges();
if (m_parent != nullptr)
@@ -160,11 +70,6 @@ void Command::Start() {
Scheduler::GetInstance()->AddCommand(this);
}
/**
* The run method is used internally to actually run the commands.
*
* @return Whether or not the command should stay within the Scheduler.
*/
bool Command::Run() {
if (!m_runWhenDisabled && m_parent == nullptr && RobotState::IsDisabled())
Cancel();
@@ -182,86 +87,56 @@ bool Command::Run() {
return !IsFinished();
}
/**
* The initialize method is called the first time this Command is run after
* being started.
*/
void Command::Initialize() {}
void Command::Cancel() {
if (m_parent != nullptr)
wpi_setWPIErrorWithContext(
CommandIllegalUse,
"Can not cancel a command that is part of a command group");
/**
* The execute method is called repeatedly until this Command either finishes
* or is canceled.
*/
void Command::Execute() {}
/**
* Called when the command ended peacefully. This is where you may want to wrap
* up loose ends, like shutting off a motor that was being used in the command.
*/
void Command::End() {}
/**
* Called when the command ends because somebody called Cancel() or another
* command shared the same requirements as this one, and booted it out.
*
* This is where you may want to wrap up loose ends, like shutting off a motor
* that was being used in the command.
*
* Generally, it is useful to simply call the End() method within this method,
* as done here.
*/
void Command::Interrupted() { End(); }
void Command::_Initialize() { m_completed = false; }
void Command::_Interrupted() { m_completed = true; }
void Command::_Execute() {}
void Command::_End() { m_completed = true; }
/**
* Called to indicate that the timer should start.
*
* This is called right before Initialize() is, inside the Run() method.
*/
void Command::StartTiming() { m_startTime = Timer::GetFPGATimestamp(); }
/**
* Returns whether or not the TimeSinceInitialized() method returns a number
* which is greater than or equal to the timeout for the command.
*
* If there is no timeout, this will always return false.
*
* @return whether the time has expired
*/
bool Command::IsTimedOut() const {
return m_timeout != -1 && TimeSinceInitialized() >= m_timeout;
_Cancel();
}
bool Command::IsRunning() const { return m_running; }
bool Command::IsInitialized() const { return m_initialized; }
bool Command::IsCompleted() const { return m_completed; }
bool Command::IsCanceled() const { return m_canceled; }
bool Command::IsInterruptible() const { return m_interruptible; }
void Command::SetInterruptible(bool interruptible) {
m_interruptible = interruptible;
}
bool Command::DoesRequire(Subsystem* system) const {
return m_requirements.count(system) > 0;
}
/**
* Returns the requirements (as an std::set of Subsystem pointers) of this
* command.
*
* @return The requirements (as an std::set of Subsystem pointers) of this
* command
*/
Command::SubsystemSet Command::GetRequirements() const {
return m_requirements;
}
/**
* Prevents further changes from being made.
*/
void Command::LockChanges() { m_locked = true; }
CommandGroup* Command::GetGroup() const { return m_parent; }
void Command::SetRunWhenDisabled(bool run) { m_runWhenDisabled = run; }
bool Command::WillRunWhenDisabled() const { return m_runWhenDisabled; }
int Command::GetID() const { return m_commandID; }
void Command::SetTimeout(double timeout) {
if (timeout < 0.0)
wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0");
else
m_timeout = timeout;
}
bool Command::IsTimedOut() const {
return m_timeout != -1 && TimeSinceInitialized() >= m_timeout;
}
/**
* If changes are locked, then this will generate a CommandIllegalUse error.
*
* @param message The message to report on error (it is appended by a default
* message)
* @return True if assert passed, false if assert failed.
*/
bool Command::AssertUnlocked(const std::string& message) {
if (m_locked) {
std::string buf =
@@ -272,11 +147,6 @@ bool Command::AssertUnlocked(const std::string& message) {
return true;
}
/**
* Sets the parent of this command. No actual change is made to the group.
*
* @param parent the parent
*/
void Command::SetParent(CommandGroup* parent) {
if (parent == nullptr) {
wpi_setWPIErrorWithContext(NullParameter, "parent");
@@ -290,153 +160,55 @@ void Command::SetParent(CommandGroup* parent) {
}
}
/**
* Returns whether the command has a parent.
*
* @param True if the command has a parent.
*/
bool Command::IsParented() const { return m_parent != nullptr; }
/**
* Clears list of subsystem requirements.
*
* This is only used by ConditionalCommand so cancelling the chosen command
* works properly in CommandGroup.
*/
void Command::ClearRequirements() { m_requirements.clear(); }
/**
* This is used internally to mark that the command has been started.
*
* The lifecycle of a command is:
*
* StartRunning() is called. Run() is called (multiple times potentially).
* Removed() is called.
*
* It is very important that StartRunning() and Removed() be called in order or
* some assumptions of the code will be broken.
*/
void Command::Initialize() {}
void Command::Execute() {}
void Command::End() {}
void Command::Interrupted() { End(); }
void Command::_Initialize() { m_completed = false; }
void Command::_Interrupted() { m_completed = true; }
void Command::_Execute() {}
void Command::_End() { m_completed = true; }
void Command::_Cancel() {
if (IsRunning()) m_canceled = true;
}
void Command::LockChanges() { m_locked = true; }
void Command::Removed() {
if (m_initialized) {
if (IsCanceled()) {
Interrupted();
_Interrupted();
} else {
End();
_End();
}
}
m_initialized = false;
m_canceled = false;
m_running = false;
m_completed = true;
}
void Command::StartRunning() {
m_running = true;
m_startTime = -1;
m_completed = false;
}
/**
* Returns whether or not the command is running.
*
* This may return true even if the command has just been canceled, as it may
* not have yet called Interrupted().
*
* @return whether or not the command is running
*/
bool Command::IsRunning() const { return m_running; }
/**
* Returns whether or not the command has been initialized.
*
* @return whether or not the command has been initialized.
*/
bool Command::IsInitialized() const { return m_initialized; }
/**
* Returns whether or not the command has completed running.
*
* @return whether or not the command has completed running.
*/
bool Command::IsCompleted() const { return m_completed; }
/**
* This will cancel the current command.
*
* This will cancel the current command eventually. It can be called multiple
* times. And it can be called when the command is not running. If the command
* is running though, then the command will be marked as canceled and eventually
* removed.
*
* A command can not be canceled if it is a part of a command group, you must
* cancel the command group instead.
*/
void Command::Cancel() {
if (m_parent != nullptr)
wpi_setWPIErrorWithContext(
CommandIllegalUse,
"Can not cancel a command that is part of a command group");
_Cancel();
}
/**
* This works like Cancel(), except that it doesn't throw an exception if it is
* a part of a command group.
*
* Should only be called by the parent command group.
*/
void Command::_Cancel() {
if (IsRunning()) m_canceled = true;
}
/**
* Returns whether or not this has been canceled.
*
* @return whether or not this has been canceled
*/
bool Command::IsCanceled() const { return m_canceled; }
/**
* Returns whether or not this command can be interrupted.
*
* @return whether or not this command can be interrupted
*/
bool Command::IsInterruptible() const { return m_interruptible; }
/**
* Sets whether or not this command can be interrupted.
*
* @param interruptible whether or not this command can be interrupted
*/
void Command::SetInterruptible(bool interruptible) {
m_interruptible = interruptible;
}
/**
* Checks if the command requires the given Subsystem.
*
* @param system the system
* @return whether or not the subsystem is required (false if given nullptr)
*/
bool Command::DoesRequire(Subsystem* system) const {
return m_requirements.count(system) > 0;
}
/**
* Returns the CommandGroup that this command is a part of.
*
* Will return null if this Command is not in a group.
*
* @return The CommandGroup that this command is a part of (or null if not in
* group)
*/
CommandGroup* Command::GetGroup() const { return m_parent; }
/**
* Sets whether or not this Command should run when the robot is disabled.
*
* By default a command will not run when the robot is disabled, and will in
* fact be canceled.
*
* @param run Whether this command should run when the robot is disabled.
*/
void Command::SetRunWhenDisabled(bool run) { m_runWhenDisabled = run; }
/**
* Returns whether or not this Command will run when the robot is disabled, or
* if it will cancel itself.
*
* @return Whether this Command will run when the robot is disabled, or if it
* will cancel itself.
*/
bool Command::WillRunWhenDisabled() const { return m_runWhenDisabled; }
void Command::StartTiming() { m_startTime = Timer::GetFPGATimestamp(); }
void Command::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Command");

View File

@@ -11,25 +11,8 @@
using namespace frc;
/**
* Creates a new CommandGroup with the given name.
*
* @param name The name for this command group
*/
CommandGroup::CommandGroup(const wpi::Twine& name) : Command(name) {}
/**
* Adds a new Command to the group. The Command will be started after all the
* previously added Commands.
*
* Note that any requirements the given Command has will be added to the group.
* For this reason, a Command's requirements can not be changed after being
* added to a group.
*
* It is recommended that this method be called in the constructor.
*
* @param command The Command to be added
*/
void CommandGroup::AddSequential(Command* command) {
if (command == nullptr) {
wpi_setWPIErrorWithContext(NullParameter, "command");
@@ -48,23 +31,6 @@ void CommandGroup::AddSequential(Command* command) {
Requires(*iter);
}
/**
* Adds a new Command to the group with a given timeout. The Command will be
* started after all the previously added commands.
*
* Once the Command is started, it will be run until it finishes or the time
* expires, whichever is sooner. Note that the given Command will have no
* knowledge that it is on a timer.
*
* Note that any requirements the given Command has will be added to the group.
* For this reason, a Command's requirements can not be changed after being
* added to a group.
*
* It is recommended that this method be called in the constructor.
*
* @param command The Command to be added
* @param timeout The timeout (in seconds)
*/
void CommandGroup::AddSequential(Command* command, double timeout) {
if (command == nullptr) {
wpi_setWPIErrorWithContext(NullParameter, "command");
@@ -87,24 +53,6 @@ void CommandGroup::AddSequential(Command* command, double timeout) {
Requires(*iter);
}
/**
* Adds a new child Command to the group. The Command will be started after all
* the previously added Commands.
*
* Instead of waiting for the child to finish, a CommandGroup will have it run
* at the same time as the subsequent Commands. The child will run until either
* it finishes, a new child with conflicting requirements is started, or the
* main sequence runs a Command with conflicting requirements. In the latter two
* cases, the child will be canceled even if it says it can't be interrupted.
*
* Note that any requirements the given Command has will be added to the group.
* For this reason, a Command's requirements can not be changed after being
* added to a group.
*
* It is recommended that this method be called in the constructor.
*
* @param command The command to be added
*/
void CommandGroup::AddParallel(Command* command) {
if (command == nullptr) {
wpi_setWPIErrorWithContext(NullParameter, "command");
@@ -123,30 +71,6 @@ void CommandGroup::AddParallel(Command* command) {
Requires(*iter);
}
/**
* Adds a new child Command to the group with the given timeout. The Command
* will be started after all the previously added Commands.
*
* Once the Command is started, it will run until it finishes, is interrupted,
* or the time expires, whichever is sooner. Note that the given Command will
* have no knowledge that it is on a timer.
*
* Instead of waiting for the child to finish, a CommandGroup will have it run
* at the same time as the subsequent Commands. The child will run until either
* it finishes, the timeout expires, a new child with conflicting requirements
* is started, or the main sequence runs a Command with conflicting
* requirements. In the latter two cases, the child will be canceled even if it
* says it can't be interrupted.
*
* Note that any requirements the given Command has will be added to the group.
* For this reason, a Command's requirements can not be changed after being
* added to a group.
*
* It is recommended that this method be called in the constructor.
*
* @param command The command to be added
* @param timeout The timeout (in seconds)
*/
void CommandGroup::AddParallel(Command* command, double timeout) {
if (command == nullptr) {
wpi_setWPIErrorWithContext(NullParameter, "command");
@@ -169,6 +93,37 @@ void CommandGroup::AddParallel(Command* command, double timeout) {
Requires(*iter);
}
bool CommandGroup::IsInterruptible() const {
if (!Command::IsInterruptible()) return false;
if (m_currentCommandIndex != -1 &&
static_cast<size_t>(m_currentCommandIndex) < m_commands.size()) {
Command* cmd = m_commands[m_currentCommandIndex].m_command;
if (!cmd->IsInterruptible()) return false;
}
for (auto iter = m_children.cbegin(); iter != m_children.cend(); iter++) {
if (!iter->m_command->IsInterruptible()) return false;
}
return true;
}
int CommandGroup::GetSize() const { return m_children.size(); }
void CommandGroup::Initialize() {}
void CommandGroup::Execute() {}
bool CommandGroup::IsFinished() {
return static_cast<size_t>(m_currentCommandIndex) >= m_commands.size() &&
m_children.empty();
}
void CommandGroup::End() {}
void CommandGroup::Interrupted() {}
void CommandGroup::_Initialize() { m_currentCommandIndex = -1; }
void CommandGroup::_Execute() {
@@ -258,39 +213,6 @@ void CommandGroup::_End() {
void CommandGroup::_Interrupted() { _End(); }
// Can be overwritten by teams
void CommandGroup::Initialize() {}
// Can be overwritten by teams
void CommandGroup::Execute() {}
// Can be overwritten by teams
void CommandGroup::End() {}
// Can be overwritten by teams
void CommandGroup::Interrupted() {}
bool CommandGroup::IsFinished() {
return static_cast<size_t>(m_currentCommandIndex) >= m_commands.size() &&
m_children.empty();
}
bool CommandGroup::IsInterruptible() const {
if (!Command::IsInterruptible()) return false;
if (m_currentCommandIndex != -1 &&
static_cast<size_t>(m_currentCommandIndex) < m_commands.size()) {
Command* cmd = m_commands[m_currentCommandIndex].m_command;
if (!cmd->IsInterruptible()) return false;
}
for (auto iter = m_children.cbegin(); iter != m_children.cend(); iter++) {
if (!iter->m_command->IsInterruptible()) return false;
}
return true;
}
void CommandGroup::CancelConflicts(Command* command) {
for (auto childIter = m_children.begin(); childIter != m_children.end();) {
Command* child = childIter->m_command;
@@ -310,5 +232,3 @@ void CommandGroup::CancelConflicts(Command* command) {
if (!erased) childIter++;
}
}
int CommandGroup::GetSize() const { return m_children.size(); }

View File

@@ -24,12 +24,6 @@ static void RequireAll(Command& command, Command* onTrue, Command* onFalse) {
}
}
/**
* Creates a new ConditionalCommand with given onTrue and onFalse Commands.
*
* @param onTrue The Command to execute if Condition() returns true
* @param onFalse The Command to execute if Condition() returns false
*/
ConditionalCommand::ConditionalCommand(Command* onTrue, Command* onFalse) {
m_onTrue = onTrue;
m_onFalse = onFalse;
@@ -37,13 +31,6 @@ ConditionalCommand::ConditionalCommand(Command* onTrue, Command* onFalse) {
RequireAll(*this, onTrue, onFalse);
}
/**
* Creates a new ConditionalCommand with given onTrue and onFalse Commands.
*
* @param name The name for this command group
* @param onTrue The Command to execute if Condition() returns true
* @param onFalse The Command to execute if Condition() returns false
*/
ConditionalCommand::ConditionalCommand(const wpi::Twine& name, Command* onTrue,
Command* onFalse)
: Command(name) {

View File

@@ -9,11 +9,6 @@
using namespace frc;
/**
* Creates a new InstantCommand with the given name.
*
* @param name The name for this command
*/
InstantCommand::InstantCommand(const wpi::Twine& name) : Command(name) {}
bool InstantCommand::IsFinished() { return true; }

View File

@@ -11,29 +11,12 @@
using namespace frc;
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* @param name the name
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
*/
PIDSubsystem::PIDSubsystem(const wpi::Twine& name, double p, double i, double d)
: Subsystem(name) {
m_controller = std::make_shared<PIDController>(p, i, d, this, this);
AddChild("PIDController", m_controller);
}
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* @param name the name
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
* @param f the feedforward value
*/
PIDSubsystem::PIDSubsystem(const wpi::Twine& name, double p, double i, double d,
double f)
: Subsystem(name) {
@@ -41,19 +24,6 @@ PIDSubsystem::PIDSubsystem(const wpi::Twine& name, double p, double i, double d,
AddChild("PIDController", m_controller);
}
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* It will also space the time between PID loop calculations to be equal to the
* given period.
*
* @param name the name
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
* @param f the feedfoward value
* @param period the time (in seconds) between calculations
*/
PIDSubsystem::PIDSubsystem(const wpi::Twine& name, double p, double i, double d,
double f, double period)
: Subsystem(name) {
@@ -62,49 +32,18 @@ PIDSubsystem::PIDSubsystem(const wpi::Twine& name, double p, double i, double d,
AddChild("PIDController", m_controller);
}
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* It will use the class name as its name.
*
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
*/
PIDSubsystem::PIDSubsystem(double p, double i, double d)
: Subsystem("PIDSubsystem") {
m_controller = std::make_shared<PIDController>(p, i, d, this, this);
AddChild("PIDController", m_controller);
}
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* It will use the class name as its name.
*
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
* @param f the feedforward value
*/
PIDSubsystem::PIDSubsystem(double p, double i, double d, double f)
: Subsystem("PIDSubsystem") {
m_controller = std::make_shared<PIDController>(p, i, d, f, this, this);
AddChild("PIDController", m_controller);
}
/**
* Instantiates a PIDSubsystem that will use the given P, I, and D values.
*
* It will use the class name as its name. It will also space the time
* between PID loop calculations to be equal to the given period.
*
* @param p the proportional value
* @param i the integral value
* @param d the derivative value
* @param f the feedforward value
* @param period the time (in seconds) between calculations
*/
PIDSubsystem::PIDSubsystem(double p, double i, double d, double f,
double period)
: Subsystem("PIDSubsystem") {
@@ -113,128 +52,46 @@ PIDSubsystem::PIDSubsystem(double p, double i, double d, double f,
AddChild("PIDController", m_controller);
}
/**
* Enables the internal PIDController.
*/
void PIDSubsystem::Enable() { m_controller->Enable(); }
/**
* Disables the internal PIDController.
*/
void PIDSubsystem::Disable() { m_controller->Disable(); }
/**
* Returns the PIDController used by this PIDSubsystem.
*
* Use this if you would like to fine tune the PID loop.
*
* @return The PIDController used by this PIDSubsystem
*/
std::shared_ptr<PIDController> PIDSubsystem::GetPIDController() {
return m_controller;
}
/**
* Sets the setpoint to the given value.
*
* If SetRange() was called, then the given setpoint will be trimmed to fit
* within the range.
*
* @param setpoint the new setpoint
*/
void PIDSubsystem::SetSetpoint(double setpoint) {
m_controller->SetSetpoint(setpoint);
}
/**
* Adds the given value to the setpoint.
*
* If SetRange() was used, then the bounds will still be honored by this method.
*
* @param deltaSetpoint the change in the setpoint
*/
void PIDSubsystem::SetSetpointRelative(double deltaSetpoint) {
SetSetpoint(GetSetpoint() + deltaSetpoint);
}
/**
* Return the current setpoint.
*
* @return The current setpoint
*/
double PIDSubsystem::GetSetpoint() { return m_controller->GetSetpoint(); }
/**
* Sets the maximum and minimum values expected from the input.
*
* @param minimumInput the minimum value expected from the input
* @param maximumInput the maximum value expected from the output
*/
void PIDSubsystem::SetInputRange(double minimumInput, double maximumInput) {
m_controller->SetInputRange(minimumInput, maximumInput);
}
/**
* Sets the maximum and minimum values to write.
*
* @param minimumOutput the minimum value to write to the output
* @param maximumOutput the maximum value to write to the output
*/
void PIDSubsystem::SetOutputRange(double minimumOutput, double maximumOutput) {
m_controller->SetOutputRange(minimumOutput, maximumOutput);
}
/**
* Set the absolute error which is considered tolerable for use with
* OnTarget.
*
* @param absValue absolute error which is tolerable
*/
void PIDSubsystem::SetAbsoluteTolerance(double absValue) {
m_controller->SetAbsoluteTolerance(absValue);
}
/**
* Set the percentage error which is considered tolerable for use with
* OnTarget().
*
* @param percent percentage error which is tolerable
*/
void PIDSubsystem::SetPercentTolerance(double percent) {
m_controller->SetPercentTolerance(percent);
}
/**
* Return true if the error is within the percentage of the total input range,
* determined by SetTolerance().
*
* This asssumes that the maximum and minimum input were set using SetInput().
* Use OnTarget() in the IsFinished() method of commands that use this
* subsystem.
*
* Currently this just reports on target as the actual value passes through the
* setpoint. Ideally it should be based on being within the tolerance for some
* period of time.
*
* @return True if the error is within the percentage tolerance of the input
* range
*/
bool PIDSubsystem::OnTarget() const { return m_controller->OnTarget(); }
/**
* Returns the current position.
*
* @return the current position
*/
double PIDSubsystem::GetPosition() { return ReturnPIDInput(); }
/**
* Returns the current rate.
*
* @return the current rate
*/
double PIDSubsystem::GetRate() { return ReturnPIDInput(); }
void PIDSubsystem::PIDWrite(double output) { UsePIDOutput(output); }
double PIDSubsystem::PIDGet() { return ReturnPIDInput(); }
void PIDSubsystem::SetSetpoint(double setpoint) {
m_controller->SetSetpoint(setpoint);
}
void PIDSubsystem::SetSetpointRelative(double deltaSetpoint) {
SetSetpoint(GetSetpoint() + deltaSetpoint);
}
void PIDSubsystem::SetInputRange(double minimumInput, double maximumInput) {
m_controller->SetInputRange(minimumInput, maximumInput);
}
void PIDSubsystem::SetOutputRange(double minimumOutput, double maximumOutput) {
m_controller->SetOutputRange(minimumOutput, maximumOutput);
}
double PIDSubsystem::GetSetpoint() { return m_controller->GetSetpoint(); }
double PIDSubsystem::GetPosition() { return ReturnPIDInput(); }
double PIDSubsystem::GetRate() { return ReturnPIDInput(); }
void PIDSubsystem::SetAbsoluteTolerance(double absValue) {
m_controller->SetAbsoluteTolerance(absValue);
}
void PIDSubsystem::SetPercentTolerance(double percent) {
m_controller->SetPercentTolerance(percent);
}
bool PIDSubsystem::OnTarget() const { return m_controller->OnTarget(); }
std::shared_ptr<PIDController> PIDSubsystem::GetPIDController() {
return m_controller;
}

View File

@@ -18,31 +18,11 @@
using namespace frc;
Scheduler::Scheduler() {
HLUsageReporting::ReportScheduler();
SetName("Scheduler");
}
/**
* Returns the Scheduler, creating it if one does not exist.
*
* @return the Scheduler
*/
Scheduler* Scheduler::GetInstance() {
static Scheduler instance;
return &instance;
}
void Scheduler::SetEnabled(bool enabled) { m_enabled = enabled; }
/**
* Add a command to be scheduled later.
*
* In any pass through the scheduler, all commands are added to the additions
* list, then at the end of the pass, they are all scheduled.
*
* @param command The command to be scheduled
*/
void Scheduler::AddCommand(Command* command) {
std::lock_guard<wpi::mutex> lock(m_additionsMutex);
if (std::find(m_additions.begin(), m_additions.end(), command) !=
@@ -56,63 +36,14 @@ void Scheduler::AddButton(ButtonScheduler* button) {
m_buttons.push_back(button);
}
void Scheduler::ProcessCommandAddition(Command* command) {
if (command == nullptr) return;
// Check to make sure no adding during adding
if (m_adding) {
wpi_setWPIErrorWithContext(IncompatibleState,
"Can not start command from cancel method");
void Scheduler::RegisterSubsystem(Subsystem* subsystem) {
if (subsystem == nullptr) {
wpi_setWPIErrorWithContext(NullParameter, "subsystem");
return;
}
// Only add if not already in
auto found = m_commands.find(command);
if (found == m_commands.end()) {
// Check that the requirements can be had
Command::SubsystemSet requirements = command->GetRequirements();
for (Command::SubsystemSet::iterator iter = requirements.begin();
iter != requirements.end(); iter++) {
Subsystem* lock = *iter;
if (lock->GetCurrentCommand() != nullptr &&
!lock->GetCurrentCommand()->IsInterruptible())
return;
}
// Give it the requirements
m_adding = true;
for (Command::SubsystemSet::iterator iter = requirements.begin();
iter != requirements.end(); iter++) {
Subsystem* lock = *iter;
if (lock->GetCurrentCommand() != nullptr) {
lock->GetCurrentCommand()->Cancel();
Remove(lock->GetCurrentCommand());
}
lock->SetCurrentCommand(command);
}
m_adding = false;
m_commands.insert(command);
command->StartRunning();
m_runningCommandsChanged = true;
}
m_subsystems.insert(subsystem);
}
/**
* Runs a single iteration of the loop.
*
* This method should be called often in order to have a functioning
* Command system. The loop has five stages:
*
* <ol>
* <li>Poll the Buttons</li>
* <li>Execute/Remove the Commands</li>
* <li>Send values to SmartDashboard</li>
* <li>Add Commands</li>
* <li>Add Defaults</li>
* </ol>
*/
void Scheduler::Run() {
// Get button input (going backwards preserves button priority)
{
@@ -167,27 +98,6 @@ void Scheduler::Run() {
}
}
/**
* Registers a Subsystem to this Scheduler, so that the Scheduler might know if
* a default Command needs to be run.
*
* All Subsystems should call this.
*
* @param system the system
*/
void Scheduler::RegisterSubsystem(Subsystem* subsystem) {
if (subsystem == nullptr) {
wpi_setWPIErrorWithContext(NullParameter, "subsystem");
return;
}
m_subsystems.insert(subsystem);
}
/**
* Removes the Command from the Scheduler.
*
* @param command the command to remove
*/
void Scheduler::Remove(Command* command) {
if (command == nullptr) {
wpi_setWPIErrorWithContext(NullParameter, "command");
@@ -211,9 +121,6 @@ void Scheduler::RemoveAll() {
}
}
/**
* Completely resets the scheduler. Undefined behavior if running.
*/
void Scheduler::ResetAll() {
RemoveAll();
m_subsystems.clear();
@@ -225,6 +132,8 @@ void Scheduler::ResetAll() {
m_cancelEntry = nt::NetworkTableEntry();
}
void Scheduler::SetEnabled(bool enabled) { m_enabled = enabled; }
void Scheduler::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Scheduler");
m_namesEntry = builder.GetEntry("Names");
@@ -268,3 +177,51 @@ void Scheduler::InitSendable(SendableBuilder& builder) {
}
});
}
Scheduler::Scheduler() {
HLUsageReporting::ReportScheduler();
SetName("Scheduler");
}
void Scheduler::ProcessCommandAddition(Command* command) {
if (command == nullptr) return;
// Check to make sure no adding during adding
if (m_adding) {
wpi_setWPIErrorWithContext(IncompatibleState,
"Can not start command from cancel method");
return;
}
// Only add if not already in
auto found = m_commands.find(command);
if (found == m_commands.end()) {
// Check that the requirements can be had
Command::SubsystemSet requirements = command->GetRequirements();
for (Command::SubsystemSet::iterator iter = requirements.begin();
iter != requirements.end(); iter++) {
Subsystem* lock = *iter;
if (lock->GetCurrentCommand() != nullptr &&
!lock->GetCurrentCommand()->IsInterruptible())
return;
}
// Give it the requirements
m_adding = true;
for (Command::SubsystemSet::iterator iter = requirements.begin();
iter != requirements.end(); iter++) {
Subsystem* lock = *iter;
if (lock->GetCurrentCommand() != nullptr) {
lock->GetCurrentCommand()->Cancel();
Remove(lock->GetCurrentCommand());
}
lock->SetCurrentCommand(command);
}
m_adding = false;
m_commands.insert(command);
command->StartRunning();
m_runningCommandsChanged = true;
}
}

View File

@@ -15,37 +15,11 @@
using namespace frc;
/**
* Creates a subsystem with the given name.
*
* @param name the name of the subsystem
*/
Subsystem::Subsystem(const wpi::Twine& name) {
SetName(name, name);
Scheduler::GetInstance()->RegisterSubsystem(this);
}
/**
* Initialize the default command for this subsystem.
*
* This is meant to be the place to call SetDefaultCommand in a subsystem and
* will be called on all the subsystems by the CommandBase method before the
* program starts running by using the list of all registered Subsystems inside
* the Scheduler.
*
* This should be overridden by a Subsystem that has a default Command
*/
void Subsystem::InitDefaultCommand() {}
/**
* Sets the default command. If this is not called or is called with null,
* then there will be no default command for the subsystem.
*
* <b>WARNING:</b> This should <b>NOT</b> be called in a constructor if the
* subsystem is a singleton.
*
* @param command the default command (or null if there should be none)
*/
void Subsystem::SetDefaultCommand(Command* command) {
if (command == nullptr) {
m_defaultCommand = nullptr;
@@ -69,11 +43,6 @@ void Subsystem::SetDefaultCommand(Command* command) {
}
}
/**
* Returns the default command (or null if there is none).
*
* @return the default command
*/
Command* Subsystem::GetDefaultCommand() {
if (!m_initializedDefaultCommand) {
m_initializedDefaultCommand = true;
@@ -82,11 +51,6 @@ Command* Subsystem::GetDefaultCommand() {
return m_defaultCommand;
}
/**
* Returns the default command name, or empty string is there is none.
*
* @return the default command name
*/
wpi::StringRef Subsystem::GetDefaultCommandName() {
Command* defaultCommand = GetDefaultCommand();
if (defaultCommand) {
@@ -96,28 +60,13 @@ wpi::StringRef Subsystem::GetDefaultCommandName() {
}
}
/**
* Sets the current command.
*
* @param command the new current command
*/
void Subsystem::SetCurrentCommand(Command* command) {
m_currentCommand = command;
m_currentCommandChanged = true;
}
/**
* Returns the command which currently claims this subsystem.
*
* @return the command which currently claims this subsystem
*/
Command* Subsystem::GetCurrentCommand() const { return m_currentCommand; }
/**
* Returns the current command name, or empty string if no current command.
*
* @return the current command name
*/
wpi::StringRef Subsystem::GetCurrentCommandName() const {
Command* currentCommand = GetCurrentCommand();
if (currentCommand) {
@@ -127,82 +76,37 @@ wpi::StringRef Subsystem::GetCurrentCommandName() const {
}
}
/**
* When the run method of the scheduler is called this method will be called.
*/
void Subsystem::Periodic() {}
/**
* Call this to alert Subsystem that the current command is actually the
* command.
*
* Sometimes, the Subsystem is told that it has no command while the Scheduler
* is going through the loop, only to be soon after given a new one. This will
* avoid that situation.
*/
void Subsystem::ConfirmCommand() {
if (m_currentCommandChanged) m_currentCommandChanged = false;
}
void Subsystem::InitDefaultCommand() {}
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void Subsystem::AddChild(const wpi::Twine& name,
std::shared_ptr<Sendable> child) {
AddChild(name, *child);
}
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void Subsystem::AddChild(const wpi::Twine& name, Sendable* child) {
AddChild(name, *child);
}
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void Subsystem::AddChild(const wpi::Twine& name, Sendable& child) {
child.SetName(GetSubsystem(), name);
LiveWindow::GetInstance()->Add(&child);
}
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void Subsystem::AddChild(std::shared_ptr<Sendable> child) { AddChild(*child); }
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void Subsystem::AddChild(Sendable* child) { AddChild(*child); }
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void Subsystem::AddChild(Sendable& child) {
child.SetSubsystem(GetSubsystem());
LiveWindow::GetInstance()->Add(&child);
}
void Subsystem::ConfirmCommand() {
if (m_currentCommandChanged) m_currentCommandChanged = false;
}
void Subsystem::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Subsystem");

View File

@@ -9,23 +9,9 @@
using namespace frc;
/**
* Creates a new TimedCommand with the given name and timeout.
*
* @param name the name of the command
* @param timeout the time (in seconds) before this command "times out"
*/
TimedCommand::TimedCommand(const wpi::Twine& name, double timeout)
: Command(name, timeout) {}
/**
* Creates a new WaitCommand with the given timeout.
*
* @param timeout the time (in seconds) before this command "times out"
*/
TimedCommand::TimedCommand(double timeout) : Command(timeout) {}
/**
* Ends command when timed out.
*/
bool TimedCommand::IsFinished() { return IsTimedOut(); }

View File

@@ -9,19 +9,8 @@
using namespace frc;
/**
* Creates a new WaitCommand with the given name and timeout.
*
* @param name the name of the command
* @param timeout the time (in seconds) before this command "times out"
*/
WaitCommand::WaitCommand(double timeout)
: TimedCommand("Wait(" + std::to_string(timeout) + ")", timeout) {}
/**
* Creates a new WaitCommand with the given timeout.
*
* @param timeout the time (in seconds) before this command "times out"
*/
WaitCommand::WaitCommand(const wpi::Twine& name, double timeout)
: TimedCommand(name, timeout) {}

View File

@@ -11,13 +11,6 @@
using namespace frc;
/**
* A WaitCommand will wait until a certain match time before finishing.
*
* This will wait until the game clock reaches some value, then continue to the
* next command.
* @see CommandGroup
*/
WaitUntilCommand::WaitUntilCommand(double time)
: Command("WaitUntilCommand", time) {
m_time = time;
@@ -28,7 +21,4 @@ WaitUntilCommand::WaitUntilCommand(const wpi::Twine& name, double time)
m_time = time;
}
/**
* Check if we've reached the actual finish time.
*/
bool WaitUntilCommand::IsFinished() { return Timer::GetMatchTime() >= m_time; }

View File

@@ -17,11 +17,6 @@
using namespace frc;
/**
* Constructor.
*
* @param module The PCM ID to use (0-62)
*/
Compressor::Compressor(int pcmID) : m_module(pcmID) {
int32_t status = 0;
m_compressorHandle = HAL_InitializeCompressor(m_module, &status);
@@ -36,29 +31,16 @@ Compressor::Compressor(int pcmID) : m_module(pcmID) {
SetName("Compressor", pcmID);
}
/**
* Starts closed-loop control. Note that closed loop control is enabled by
* default.
*/
void Compressor::Start() {
if (StatusIsFatal()) return;
SetClosedLoopControl(true);
}
/**
* Stops closed-loop control. Note that closed loop control is enabled by
* default.
*/
void Compressor::Stop() {
if (StatusIsFatal()) return;
SetClosedLoopControl(false);
}
/**
* Check if compressor output is active.
*
* @return true if the compressor is on
*/
bool Compressor::Enabled() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -73,11 +55,6 @@ bool Compressor::Enabled() const {
return value;
}
/**
* Check if the pressure switch is triggered.
*
* @return true if pressure is low
*/
bool Compressor::GetPressureSwitchValue() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -92,11 +69,6 @@ bool Compressor::GetPressureSwitchValue() const {
return value;
}
/**
* Query how much current the compressor is drawing.
*
* @return The current through the compressor, in amps
*/
double Compressor::GetCompressorCurrent() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
@@ -111,13 +83,6 @@ double Compressor::GetCompressorCurrent() const {
return value;
}
/**
* Enables or disables automatically turning the compressor on when the
* pressure is low.
*
* @param on Set to true to enable closed loop control of the compressor. False
* to disable.
*/
void Compressor::SetClosedLoopControl(bool on) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -129,13 +94,6 @@ void Compressor::SetClosedLoopControl(bool on) {
}
}
/**
* Returns true if the compressor will automatically turn on when the
* pressure is low.
*
* @return True if closed loop control of the compressor is enabled. False if
* disabled.
*/
bool Compressor::GetClosedLoopControl() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -150,12 +108,6 @@ bool Compressor::GetClosedLoopControl() const {
return value;
}
/**
* Query if the compressor output has been disabled due to high current draw.
*
* @return true if PCM is in fault state : Compressor Drive is
* disabled due to compressor current being too high.
*/
bool Compressor::GetCompressorCurrentTooHighFault() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -170,16 +122,6 @@ bool Compressor::GetCompressorCurrentTooHighFault() const {
return value;
}
/**
* Query if the compressor output has been disabled due to high current draw
* (sticky).
*
* A sticky fault will not clear on device reboot, it must be cleared through
* code or the webdash.
*
* @return true if PCM sticky fault is set : Compressor Drive is
* disabled due to compressor current being too high.
*/
bool Compressor::GetCompressorCurrentTooHighStickyFault() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -195,16 +137,6 @@ bool Compressor::GetCompressorCurrentTooHighStickyFault() const {
return value;
}
/**
* Query if the compressor output has been disabled due to a short circuit
* (sticky).
*
* A sticky fault will not clear on device reboot, it must be cleared through
* code or the webdash.
*
* @return true if PCM sticky fault is set : Compressor output
* appears to be shorted.
*/
bool Compressor::GetCompressorShortedStickyFault() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -219,12 +151,6 @@ bool Compressor::GetCompressorShortedStickyFault() const {
return value;
}
/**
* Query if the compressor output has been disabled due to a short circuit.
*
* @return true if PCM is in fault state : Compressor output
* appears to be shorted.
*/
bool Compressor::GetCompressorShortedFault() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -239,15 +165,6 @@ bool Compressor::GetCompressorShortedFault() const {
return value;
}
/**
* Query if the compressor output does not appear to be wired (sticky).
*
* A sticky fault will not clear on device reboot, it must be cleared through
* code or the webdash.
*
* @return true if PCM sticky fault is set : Compressor does not
* appear to be wired, i.e. compressor is not drawing enough current.
*/
bool Compressor::GetCompressorNotConnectedStickyFault() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -262,12 +179,6 @@ bool Compressor::GetCompressorNotConnectedStickyFault() const {
return value;
}
/**
* Query if the compressor output does not appear to be wired.
*
* @return true if PCM is in fault state : Compressor does not
* appear to be wired, i.e. compressor is not drawing enough current.
*/
bool Compressor::GetCompressorNotConnectedFault() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -282,16 +193,6 @@ bool Compressor::GetCompressorNotConnectedFault() const {
return value;
}
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* If a sticky fault is set, then it will be persistently cleared. Compressor
* drive maybe momentarily disable while flags are being cleared. Care should
* be taken to not call this too frequently, otherwise normal compressor
* functionality may be prevented.
*
* If no sticky faults are set then this call will have no effect.
*/
void Compressor::ClearAllPCMStickyFaults() {
if (StatusIsFatal()) return;
int32_t status = 0;

View File

@@ -16,12 +16,6 @@
using namespace frc;
/**
* Get the input voltage to the robot controller.
*
* @return The controller input voltage value in Volts
* @deprecated Use RobotController static class method
*/
double ControllerPower::GetInputVoltage() {
int32_t status = 0;
double retVal = HAL_GetVinVoltage(&status);
@@ -29,12 +23,6 @@ double ControllerPower::GetInputVoltage() {
return retVal;
}
/**
* Get the input current to the robot controller.
*
* @return The controller input current value in Amps
* @deprecated Use RobotController static class method
*/
double ControllerPower::GetInputCurrent() {
int32_t status = 0;
double retVal = HAL_GetVinCurrent(&status);
@@ -42,120 +30,6 @@ double ControllerPower::GetInputCurrent() {
return retVal;
}
/**
* Get the voltage of the 6V rail.
*
* @return The controller 6V rail voltage value in Volts
* @deprecated Use RobotController static class method
*/
double ControllerPower::GetVoltage6V() {
int32_t status = 0;
double retVal = HAL_GetUserVoltage6V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Get the current output of the 6V rail.
*
* @return The controller 6V rail output current value in Amps
* @deprecated Use RobotController static class method
*/
double ControllerPower::GetCurrent6V() {
int32_t status = 0;
double retVal = HAL_GetUserCurrent6V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Get the enabled state of the 6V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller over-voltage.
*
* @return The controller 6V rail enabled value. True for enabled.
* @deprecated Use RobotController static class method
*/
bool ControllerPower::GetEnabled6V() {
int32_t status = 0;
bool retVal = HAL_GetUserActive6V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Get the count of the total current faults on the 6V rail since the controller
* has booted.
*
* @return The number of faults.
* @deprecated Use RobotController static class method
*/
int ControllerPower::GetFaultCount6V() {
int32_t status = 0;
int retVal = HAL_GetUserCurrentFaults6V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Get the voltage of the 5V rail.
*
* @return The controller 5V rail voltage value in Volts
* @deprecated Use RobotController static class method
*/
double ControllerPower::GetVoltage5V() {
int32_t status = 0;
double retVal = HAL_GetUserVoltage5V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Get the current output of the 5V rail.
*
* @return The controller 5V rail output current value in Amps
* @deprecated Use RobotController static class method
*/
double ControllerPower::GetCurrent5V() {
int32_t status = 0;
double retVal = HAL_GetUserCurrent5V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Get the enabled state of the 5V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller over-voltage.
*
* @return The controller 5V rail enabled value. True for enabled.
* @deprecated Use RobotController static class method
*/
bool ControllerPower::GetEnabled5V() {
int32_t status = 0;
bool retVal = HAL_GetUserActive5V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Get the count of the total current faults on the 5V rail since the controller
* has booted.
*
* @return The number of faults
* @deprecated Use RobotController static class method
*/
int ControllerPower::GetFaultCount5V() {
int32_t status = 0;
int retVal = HAL_GetUserCurrentFaults5V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
/**
* Get the voltage of the 3.3V rail.
*
* @return The controller 3.3V rail voltage value in Volts
* @deprecated Use RobotController static class method
*/
double ControllerPower::GetVoltage3V3() {
int32_t status = 0;
double retVal = HAL_GetUserVoltage3V3(&status);
@@ -163,12 +37,6 @@ double ControllerPower::GetVoltage3V3() {
return retVal;
}
/**
* Get the current output of the 3.3V rail.
*
* @return The controller 3.3V rail output current value in Amps
* @deprecated Use RobotController static class method
*/
double ControllerPower::GetCurrent3V3() {
int32_t status = 0;
double retVal = HAL_GetUserCurrent3V3(&status);
@@ -176,13 +44,6 @@ double ControllerPower::GetCurrent3V3() {
return retVal;
}
/**
* Get the enabled state of the 3.3V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller over-voltage.
*
* @return The controller 3.3V rail enabled value. True for enabled.
* @deprecated Use RobotController static class method
*/
bool ControllerPower::GetEnabled3V3() {
int32_t status = 0;
bool retVal = HAL_GetUserActive3V3(&status);
@@ -190,16 +51,65 @@ bool ControllerPower::GetEnabled3V3() {
return retVal;
}
/**
* Get the count of the total current faults on the 3.3V rail since the
* controller has booted.
*
* @return The number of faults
* @deprecated Use RobotController static class method
*/
int ControllerPower::GetFaultCount3V3() {
int32_t status = 0;
int retVal = HAL_GetUserCurrentFaults3V3(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
double ControllerPower::GetVoltage5V() {
int32_t status = 0;
double retVal = HAL_GetUserVoltage5V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
double ControllerPower::GetCurrent5V() {
int32_t status = 0;
double retVal = HAL_GetUserCurrent5V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
bool ControllerPower::GetEnabled5V() {
int32_t status = 0;
bool retVal = HAL_GetUserActive5V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
int ControllerPower::GetFaultCount5V() {
int32_t status = 0;
int retVal = HAL_GetUserCurrentFaults5V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
double ControllerPower::GetVoltage6V() {
int32_t status = 0;
double retVal = HAL_GetUserVoltage6V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
double ControllerPower::GetCurrent6V() {
int32_t status = 0;
double retVal = HAL_GetUserCurrent6V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
bool ControllerPower::GetEnabled6V() {
int32_t status = 0;
bool retVal = HAL_GetUserActive6V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}
int ControllerPower::GetFaultCount6V() {
int32_t status = 0;
int retVal = HAL_GetUserCurrentFaults6V(&status);
wpi_setGlobalErrorWithContext(status, HAL_GetErrorMessage(status));
return retVal;
}

View File

@@ -16,19 +16,6 @@
using namespace frc;
/**
* Create an instance of a counter where no sources are selected.
*
* They all must be selected by calling functions to specify the upsource and
* the downsource independently.
*
* This creates a ChipObject counter and initializes status variables
* appropriately.
*
* The counter will start counting immediately.
*
* @param mode The counter mode
*/
Counter::Counter(Mode mode) {
int32_t status = 0;
m_counter = HAL_InitializeCounter((HAL_Counter_Mode)mode, &m_index, &status);
@@ -40,82 +27,26 @@ Counter::Counter(Mode mode) {
SetName("Counter", m_index);
}
/**
* Create an instance of a counter from a Digital Source (such as a Digital
* Input).
*
* This is used if an existing digital input is to be shared by multiple other
* objects such as encoders or if the Digital Source is not a Digital Input
* channel (such as an Analog Trigger).
*
* The counter will start counting immediately.
* @param source A pointer to the existing DigitalSource object. It will be set
* as the Up Source.
*/
Counter::Counter(DigitalSource* source) : Counter(kTwoPulse) {
SetUpSource(source);
ClearDownSource();
}
/**
* Create an instance of a counter from a Digital Source (such as a Digital
* Input).
*
* This is used if an existing digital input is to be shared by multiple other
* objects such as encoders or if the Digital Source is not a Digital Input
* channel (such as an Analog Trigger).
*
* The counter will start counting immediately.
*
* @param source A pointer to the existing DigitalSource object. It will be
* set as the Up Source.
*/
Counter::Counter(std::shared_ptr<DigitalSource> source) : Counter(kTwoPulse) {
SetUpSource(source);
ClearDownSource();
}
/**
* Create an instance of a Counter object.
*
* Create an up-Counter instance given a channel.
*
* The counter will start counting immediately.
*
* @param channel The DIO channel to use as the up source. 0-9 are on-board,
* 10-25 are on the MXP
*/
Counter::Counter(int channel) : Counter(kTwoPulse) {
SetUpSource(channel);
ClearDownSource();
}
/**
* Create an instance of a Counter object.
*
* Create an instance of a simple up-Counter given an analog trigger.
* Use the trigger state output from the analog trigger.
*
* The counter will start counting immediately.
*
* @param trigger The reference to the existing AnalogTrigger object.
*/
Counter::Counter(DigitalSource* source) : Counter(kTwoPulse) {
SetUpSource(source);
ClearDownSource();
}
Counter::Counter(std::shared_ptr<DigitalSource> source) : Counter(kTwoPulse) {
SetUpSource(source);
ClearDownSource();
}
Counter::Counter(const AnalogTrigger& trigger) : Counter(kTwoPulse) {
SetUpSource(trigger.CreateOutput(AnalogTriggerType::kState));
ClearDownSource();
}
/**
* Create an instance of a Counter object.
*
* Creates a full up-down counter given two Digital Sources.
*
* @param encodingType The quadrature decoding mode (1x or 2x)
* @param upSource The pointer to the DigitalSource to set as the up source
* @param downSource The pointer to the DigitalSource to set as the down
* source
* @param inverted True to invert the output (reverse the direction)
*/
Counter::Counter(EncodingType encodingType, DigitalSource* upSource,
DigitalSource* downSource, bool inverted)
: Counter(encodingType,
@@ -125,17 +56,6 @@ Counter::Counter(EncodingType encodingType, DigitalSource* upSource,
NullDeleter<DigitalSource>()),
inverted) {}
/**
* Create an instance of a Counter object.
*
* Creates a full up-down counter given two Digital Sources.
*
* @param encodingType The quadrature decoding mode (1x or 2x)
* @param upSource The pointer to the DigitalSource to set as the up source
* @param downSource The pointer to the DigitalSource to set as the down
* source
* @param inverted True to invert the output (reverse the direction)
*/
Counter::Counter(EncodingType encodingType,
std::shared_ptr<DigitalSource> upSource,
std::shared_ptr<DigitalSource> downSource, bool inverted)
@@ -162,9 +82,6 @@ Counter::Counter(EncodingType encodingType,
SetDownSourceEdge(inverted, true);
}
/**
* Delete the Counter object.
*/
Counter::~Counter() {
SetUpdateWhenEmpty(true);
@@ -174,24 +91,12 @@ Counter::~Counter() {
m_counter = HAL_kInvalidHandle;
}
/**
* Set the upsource for the counter as a digital input channel.
*
* @param channel The DIO channel to use as the up source. 0-9 are on-board,
* 10-25 are on the MXP
*/
void Counter::SetUpSource(int channel) {
if (StatusIsFatal()) return;
SetUpSource(std::make_shared<DigitalInput>(channel));
AddChild(m_upSource);
}
/**
* Set the up counting source to be an analog trigger.
*
* @param analogTrigger The analog trigger object that is used for the Up Source
* @param triggerType The analog trigger output that will trigger the counter.
*/
void Counter::SetUpSource(AnalogTrigger* analogTrigger,
AnalogTriggerType triggerType) {
SetUpSource(std::shared_ptr<AnalogTrigger>(analogTrigger,
@@ -199,25 +104,17 @@ void Counter::SetUpSource(AnalogTrigger* analogTrigger,
triggerType);
}
/**
* Set the up counting source to be an analog trigger.
*
* @param analogTrigger The analog trigger object that is used for the Up Source
* @param triggerType The analog trigger output that will trigger the counter.
*/
void Counter::SetUpSource(std::shared_ptr<AnalogTrigger> analogTrigger,
AnalogTriggerType triggerType) {
if (StatusIsFatal()) return;
SetUpSource(analogTrigger->CreateOutput(triggerType));
}
/**
* Set the source object that causes the counter to count up.
*
* Set the up counting DigitalSource.
*
* @param source Pointer to the DigitalSource object to set as the up source
*/
void Counter::SetUpSource(DigitalSource* source) {
SetUpSource(
std::shared_ptr<DigitalSource>(source, NullDeleter<DigitalSource>()));
}
void Counter::SetUpSource(std::shared_ptr<DigitalSource> source) {
if (StatusIsFatal()) return;
m_upSource = source;
@@ -233,31 +130,11 @@ void Counter::SetUpSource(std::shared_ptr<DigitalSource> source) {
}
}
void Counter::SetUpSource(DigitalSource* source) {
SetUpSource(
std::shared_ptr<DigitalSource>(source, NullDeleter<DigitalSource>()));
}
/**
* Set the source object that causes the counter to count up.
*
* Set the up counting DigitalSource.
*
* @param source Reference to the DigitalSource object to set as the up source
*/
void Counter::SetUpSource(DigitalSource& source) {
SetUpSource(
std::shared_ptr<DigitalSource>(&source, NullDeleter<DigitalSource>()));
}
/**
* Set the edge sensitivity on an up counting source.
*
* Set the up source to either detect rising edges or falling edges or both.
*
* @param risingEdge True to trigger on rising edges
* @param fallingEdge True to trigger on falling edges
*/
void Counter::SetUpSourceEdge(bool risingEdge, bool fallingEdge) {
if (StatusIsFatal()) return;
if (m_upSource == nullptr) {
@@ -270,9 +147,6 @@ void Counter::SetUpSourceEdge(bool risingEdge, bool fallingEdge) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Disable the up counting source to the counter.
*/
void Counter::ClearUpSource() {
if (StatusIsFatal()) return;
m_upSource.reset();
@@ -281,25 +155,12 @@ void Counter::ClearUpSource() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set the down counting source to be a digital input channel.
*
* @param channel The DIO channel to use as the up source. 0-9 are on-board,
* 10-25 are on the MXP
*/
void Counter::SetDownSource(int channel) {
if (StatusIsFatal()) return;
SetDownSource(std::make_shared<DigitalInput>(channel));
AddChild(m_downSource);
}
/**
* Set the down counting source to be an analog trigger.
*
* @param analogTrigger The analog trigger object that is used for the Down
* Source
* @param triggerType The analog trigger output that will trigger the counter.
*/
void Counter::SetDownSource(AnalogTrigger* analogTrigger,
AnalogTriggerType triggerType) {
SetDownSource(std::shared_ptr<AnalogTrigger>(analogTrigger,
@@ -307,26 +168,22 @@ void Counter::SetDownSource(AnalogTrigger* analogTrigger,
triggerType);
}
/**
* Set the down counting source to be an analog trigger.
*
* @param analogTrigger The analog trigger object that is used for the Down
* Source
* @param triggerType The analog trigger output that will trigger the counter.
*/
void Counter::SetDownSource(std::shared_ptr<AnalogTrigger> analogTrigger,
AnalogTriggerType triggerType) {
if (StatusIsFatal()) return;
SetDownSource(analogTrigger->CreateOutput(triggerType));
}
/**
* Set the source object that causes the counter to count down.
*
* Set the down counting DigitalSource.
*
* @param source Pointer to the DigitalSource object to set as the down source
*/
void Counter::SetDownSource(DigitalSource* source) {
SetDownSource(
std::shared_ptr<DigitalSource>(source, NullDeleter<DigitalSource>()));
}
void Counter::SetDownSource(DigitalSource& source) {
SetDownSource(
std::shared_ptr<DigitalSource>(&source, NullDeleter<DigitalSource>()));
}
void Counter::SetDownSource(std::shared_ptr<DigitalSource> source) {
if (StatusIsFatal()) return;
m_downSource = source;
@@ -342,31 +199,6 @@ void Counter::SetDownSource(std::shared_ptr<DigitalSource> source) {
}
}
void Counter::SetDownSource(DigitalSource* source) {
SetDownSource(
std::shared_ptr<DigitalSource>(source, NullDeleter<DigitalSource>()));
}
/**
* Set the source object that causes the counter to count down.
*
* Set the down counting DigitalSource.
*
* @param source Reference to the DigitalSource object to set as the down source
*/
void Counter::SetDownSource(DigitalSource& source) {
SetDownSource(
std::shared_ptr<DigitalSource>(&source, NullDeleter<DigitalSource>()));
}
/**
* Set the edge sensitivity on a down counting source.
*
* Set the down source to either detect rising edges or falling edges.
*
* @param risingEdge True to trigger on rising edges
* @param fallingEdge True to trigger on falling edges
*/
void Counter::SetDownSourceEdge(bool risingEdge, bool fallingEdge) {
if (StatusIsFatal()) return;
if (m_downSource == nullptr) {
@@ -379,9 +211,6 @@ void Counter::SetDownSourceEdge(bool risingEdge, bool fallingEdge) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Disable the down counting source to the counter.
*/
void Counter::ClearDownSource() {
if (StatusIsFatal()) return;
m_downSource.reset();
@@ -390,11 +219,6 @@ void Counter::ClearDownSource() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set standard up / down counting mode on this counter.
*
* Up and down counts are sourced independently from two inputs.
*/
void Counter::SetUpDownCounterMode() {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -402,12 +226,6 @@ void Counter::SetUpDownCounterMode() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set external direction mode on this counter.
*
* Counts are sourced on the Up counter input.
* The Down counter input represents the direction to count.
*/
void Counter::SetExternalDirectionMode() {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -415,11 +233,6 @@ void Counter::SetExternalDirectionMode() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set Semi-period mode on this counter.
*
* Counts up on both rising and falling edges.
*/
void Counter::SetSemiPeriodMode(bool highSemiPeriod) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -427,15 +240,6 @@ void Counter::SetSemiPeriodMode(bool highSemiPeriod) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Configure the counter to count in up or down based on the length of the input
* pulse.
*
* This mode is most useful for direction sensitive gear tooth sensors.
*
* @param threshold The pulse length beyond which the counter counts the
* opposite direction. Units are seconds.
*/
void Counter::SetPulseLengthMode(double threshold) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -443,29 +247,13 @@ void Counter::SetPulseLengthMode(double threshold) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(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 The number of samples being averaged (from 1 to 127)
*/
int Counter::GetSamplesToAverage() const {
void Counter::SetReverseDirection(bool reverseDirection) {
if (StatusIsFatal()) return;
int32_t status = 0;
int samples = HAL_GetCounterSamplesToAverage(m_counter, &status);
HAL_SetCounterReverseDirection(m_counter, reverseDirection, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return samples;
}
/**
* 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 Counter::SetSamplesToAverage(int samplesToAverage) {
if (samplesToAverage < 1 || samplesToAverage > 127) {
wpi_setWPIErrorWithContext(
@@ -477,12 +265,15 @@ void Counter::SetSamplesToAverage(int samplesToAverage) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Read the current counter value.
*
* Read the value at this instant. It may still be running, so it reflects the
* current value. Next time it is read, it might have a different value.
*/
int Counter::GetSamplesToAverage() const {
int32_t status = 0;
int samples = HAL_GetCounterSamplesToAverage(m_counter, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return samples;
}
int Counter::GetFPGAIndex() const { return m_index; }
int Counter::Get() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
@@ -491,12 +282,6 @@ int Counter::Get() const {
return value;
}
/**
* Reset the Counter to zero.
*
* Set the counter value to zero. This doesn't effect the running state of the
* counter, just sets the current value to zero.
*/
void Counter::Reset() {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -504,14 +289,6 @@ void Counter::Reset() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Get the Period of the most recent count.
*
* Returns the time interval of the most recent count. This can be used for
* velocity calculations to determine shaft speed.
*
* @returns The period between the last two pulses in units of seconds.
*/
double Counter::GetPeriod() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
@@ -520,16 +297,6 @@ double Counter::GetPeriod() const {
return value;
}
/**
* Set the maximum period where the device is still considered "moving".
*
* Sets the maximum period where the device is considered moving. This value is
* used to determine the "stopped" state of the counter using the GetStopped
* method.
*
* @param maxPeriod The maximum period where the counted device is considered
* moving in seconds.
*/
void Counter::SetMaxPeriod(double maxPeriod) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -537,23 +304,6 @@ void Counter::SetMaxPeriod(double maxPeriod) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Select whether you want to continue updating the event timer output when
* there are no samples captured.
*
* The output of the event timer has a buffer of periods that are averaged and
* posted to a register on the FPGA. When the timer detects that the event
* source has stopped (based on the MaxPeriod) the buffer of samples to be
* averaged is emptied. If you enable the update when empty, you will be
* notified of the stopped source and the event time will report 0 samples.
* If you disable update when empty, the most recent average will remain on
* the output until a new sample is acquired. You will never see 0 samples
* output (except when there have been no events since an FPGA reset) and you
* will likely not see the stopped bit become true (since it is updated at the
* end of an average and there are no samples to average).
*
* @param enabled True to enable update when empty
*/
void Counter::SetUpdateWhenEmpty(bool enabled) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -561,16 +311,6 @@ void Counter::SetUpdateWhenEmpty(bool enabled) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Determine if the clock is stopped.
*
* Determine if the clocked input is stopped based on the MaxPeriod value set
* using the SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the
* device (and counter) are assumed to be stopped and it returns true.
*
* @return Returns true if the most recent counter period exceeds the MaxPeriod
* value set by SetMaxPeriod.
*/
bool Counter::GetStopped() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -579,11 +319,6 @@ bool Counter::GetStopped() const {
return value;
}
/**
* The last direction the counter value changed.
*
* @return The last direction the counter value changed.
*/
bool Counter::GetDirection() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -592,21 +327,6 @@ bool Counter::GetDirection() const {
return value;
}
/**
* Set the Counter to return reversed sensing on the direction.
*
* This allows counters to change the direction they are counting in the case of
* 1X and 2X quadrature encoding only. Any other counter mode isn't supported.
*
* @param reverseDirection true if the value counted should be negated.
*/
void Counter::SetReverseDirection(bool reverseDirection) {
if (StatusIsFatal()) return;
int32_t status = 0;
HAL_SetCounterReverseDirection(m_counter, reverseDirection, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
void Counter::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Counter");
builder.AddDoubleProperty("Value", [=]() { return Get(); }, nullptr);

View File

@@ -11,14 +11,8 @@
using namespace frc;
/**
* Constructor for a Digilent DMC 60.
*
* @param channel The PWM channel that the DMC 60 is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
*/
DMC60::DMC60(int channel) : PWMSpeedController(channel) {
/**
/*
* Note that the DMC 60 uses the following bounds for PWM values. These
* values should work reasonably well for most controllers, but if users
* experience issues such as asymmetric behavior around the deadband or

View File

@@ -46,11 +46,6 @@ DigitalGlitchFilter::~DigitalGlitchFilter() {
}
}
/**
* Assigns the DigitalSource to this glitch filter.
*
* @param input The DigitalSource to add.
*/
void DigitalGlitchFilter::Add(DigitalSource* input) {
DoAdd(input, m_channelIndex + 1);
}
@@ -80,11 +75,6 @@ void DigitalGlitchFilter::DoAdd(DigitalSource* input, int requestedIndex) {
}
}
/**
* Assigns the Encoder to this glitch filter.
*
* @param input The Encoder to add.
*/
void DigitalGlitchFilter::Add(Encoder* input) {
Add(input->m_aSource.get());
if (StatusIsFatal()) {
@@ -93,11 +83,6 @@ void DigitalGlitchFilter::Add(Encoder* input) {
Add(input->m_bSource.get());
}
/**
* Assigns the Counter to this glitch filter.
*
* @param input The Counter to add.
*/
void DigitalGlitchFilter::Add(Counter* input) {
Add(input->m_upSource.get());
if (StatusIsFatal()) {
@@ -106,24 +91,8 @@ void DigitalGlitchFilter::Add(Counter* input) {
Add(input->m_downSource.get());
}
/**
* Removes a digital input from this filter.
*
* Removes the DigitalSource from this glitch filter and re-assigns it to
* the default filter.
*
* @param input The DigitalSource to remove.
*/
void DigitalGlitchFilter::Remove(DigitalSource* input) { DoAdd(input, 0); }
/**
* Removes an encoder from this filter.
*
* Removes the Encoder from this glitch filter and re-assigns it to
* the default filter.
*
* @param input The Encoder to remove.
*/
void DigitalGlitchFilter::Remove(Encoder* input) {
Remove(input->m_aSource.get());
if (StatusIsFatal()) {
@@ -132,14 +101,6 @@ void DigitalGlitchFilter::Remove(Encoder* input) {
Remove(input->m_bSource.get());
}
/**
* Removes a counter from this filter.
*
* Removes the Counter from this glitch filter and re-assigns it to
* the default filter.
*
* @param input The Counter to remove.
*/
void DigitalGlitchFilter::Remove(Counter* input) {
Remove(input->m_upSource.get());
if (StatusIsFatal()) {
@@ -148,22 +109,12 @@ void DigitalGlitchFilter::Remove(Counter* input) {
Remove(input->m_downSource.get());
}
/**
* Sets the number of cycles that the input must not change state for.
*
* @param fpgaCycles The number of FPGA cycles.
*/
void DigitalGlitchFilter::SetPeriodCycles(int fpgaCycles) {
int32_t status = 0;
HAL_SetFilterPeriod(m_channelIndex, fpgaCycles, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Sets the number of nanoseconds that the input must not change state for.
*
* @param nanoseconds The number of nanoseconds.
*/
void DigitalGlitchFilter::SetPeriodNanoSeconds(uint64_t nanoseconds) {
int32_t status = 0;
int fpgaCycles =
@@ -173,11 +124,6 @@ void DigitalGlitchFilter::SetPeriodNanoSeconds(uint64_t nanoseconds) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Gets the number of cycles that the input must not change state for.
*
* @return The number of cycles.
*/
int DigitalGlitchFilter::GetPeriodCycles() {
int32_t status = 0;
int fpgaCycles = HAL_GetFilterPeriod(m_channelIndex, &status);
@@ -187,11 +133,6 @@ int DigitalGlitchFilter::GetPeriodCycles() {
return fpgaCycles;
}
/**
* Gets the number of nanoseconds that the input must not change state for.
*
* @return The number of nanoseconds.
*/
uint64_t DigitalGlitchFilter::GetPeriodNanoSeconds() {
int32_t status = 0;
int fpgaCycles = HAL_GetFilterPeriod(m_channelIndex, &status);

View File

@@ -19,13 +19,6 @@
using namespace frc;
/**
* Create an instance of a Digital Input class.
*
* Creates a digital input given a channel.
*
* @param channel The DIO channel 0-9 are on-board, 10-25 are on the MXP port
*/
DigitalInput::DigitalInput(int channel) {
if (!SensorUtil::CheckDigitalChannel(channel)) {
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange,
@@ -49,9 +42,6 @@ DigitalInput::DigitalInput(int channel) {
SetName("DigitalInput", channel);
}
/**
* Free resources associated with the Digital Input class.
*/
DigitalInput::~DigitalInput() {
if (StatusIsFatal()) return;
if (m_interrupt != HAL_kInvalidHandle) {
@@ -64,11 +54,6 @@ DigitalInput::~DigitalInput() {
HAL_FreeDIOPort(m_handle);
}
/**
* Get the value from a digital input channel.
*
* Retrieve the value of a single digital input channel from the FPGA.
*/
bool DigitalInput::Get() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -77,28 +62,16 @@ bool DigitalInput::Get() const {
return value;
}
/**
* @return The GPIO channel number that this object represents.
*/
int DigitalInput::GetChannel() const { return m_channel; }
/**
* @return The HAL Handle to the specified source.
*/
HAL_Handle DigitalInput::GetPortHandleForRouting() const { return m_handle; }
/**
* Is source an AnalogTrigger
*/
bool DigitalInput::IsAnalogTrigger() const { return false; }
/**
* @return The type of analog trigger output to be used. 0 for Digitals
*/
AnalogTriggerType DigitalInput::GetAnalogTriggerTypeForRouting() const {
return (AnalogTriggerType)0;
}
bool DigitalInput::IsAnalogTrigger() const { return false; }
int DigitalInput::GetChannel() const { return m_channel; }
void DigitalInput::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Digital Input");
builder.AddBooleanProperty("Value", [=]() { return Get(); }, nullptr);

View File

@@ -19,14 +19,6 @@
using namespace frc;
/**
* Create an instance of a digital output.
*
* Create a digital output given a channel.
*
* @param channel The digital channel 0-9 are on-board, 10-25 are on the MXP
* port
*/
DigitalOutput::DigitalOutput(int channel) {
m_pwmGenerator = HAL_kInvalidHandle;
if (!SensorUtil::CheckDigitalChannel(channel)) {
@@ -51,9 +43,6 @@ DigitalOutput::DigitalOutput(int channel) {
SetName("DigitalOutput", channel);
}
/**
* Free the resources associated with a digital output.
*/
DigitalOutput::~DigitalOutput() {
if (StatusIsFatal()) return;
// Disable the PWM in case it was running.
@@ -62,13 +51,6 @@ DigitalOutput::~DigitalOutput() {
HAL_FreeDIOPort(m_handle);
}
/**
* Set the value of a digital output.
*
* Set the value of a digital output to either one (true) or zero (false).
*
* @param value 1 (true) for high, 0 (false) for disabled
*/
void DigitalOutput::Set(bool value) {
if (StatusIsFatal()) return;
@@ -77,11 +59,6 @@ void DigitalOutput::Set(bool value) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Gets the value being output from the Digital Output.
*
* @return the state of the digital output.
*/
bool DigitalOutput::Get() const {
if (StatusIsFatal()) return false;
@@ -91,19 +68,8 @@ bool DigitalOutput::Get() const {
return val;
}
/**
* @return The GPIO channel number that this object represents.
*/
int DigitalOutput::GetChannel() const { return m_channel; }
/**
* Output a single pulse on the digital output line.
*
* Send a single pulse on the digital output line where the pulse duration is
* specified in seconds. Maximum pulse length is 0.0016 seconds.
*
* @param length The pulse length in seconds
*/
void DigitalOutput::Pulse(double length) {
if (StatusIsFatal()) return;
@@ -112,11 +78,6 @@ void DigitalOutput::Pulse(double length) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Determine if the pulse is still going.
*
* Determine if a previously started pulse is still going.
*/
bool DigitalOutput::IsPulsing() const {
if (StatusIsFatal()) return false;
@@ -126,16 +87,6 @@ bool DigitalOutput::IsPulsing() const {
return value;
}
/**
* Change the PWM frequency of the PWM output on a Digital Output line.
*
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is
* logarithmic.
*
* There is only one PWM frequency for all digital channels.
*
* @param rate The frequency to output all digital output PWM signals.
*/
void DigitalOutput::SetPWMRate(double rate) {
if (StatusIsFatal()) return;
@@ -144,19 +95,6 @@ void DigitalOutput::SetPWMRate(double rate) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Enable a PWM Output on this line.
*
* Allocate one of the 6 DO PWM generator resources from this module.
*
* Supply the initial duty-cycle to output so as to avoid a glitch when first
* starting.
*
* The resolution of the duty cycle is 8-bit for low frequencies (1kHz or less)
* but is reduced the higher the frequency of the PWM signal is.
*
* @param initialDutyCycle The duty-cycle to start generating. [0..1]
*/
void DigitalOutput::EnablePWM(double initialDutyCycle) {
if (m_pwmGenerator != HAL_kInvalidHandle) return;
@@ -175,11 +113,6 @@ void DigitalOutput::EnablePWM(double initialDutyCycle) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Change this line from a PWM output back to a static Digital Output line.
*
* Free up one of the 6 DO PWM generator resources that were in use.
*/
void DigitalOutput::DisablePWM() {
if (StatusIsFatal()) return;
if (m_pwmGenerator == HAL_kInvalidHandle) return;
@@ -197,14 +130,6 @@ void DigitalOutput::DisablePWM() {
m_pwmGenerator = HAL_kInvalidHandle;
}
/**
* Change the duty-cycle that is being generated on the line.
*
* The resolution of the duty cycle is 8-bit for low frequencies (1kHz or less)
* but is reduced the higher the frequency of the PWM signal is.
*
* @param dutyCycle The duty-cycle to change to. [0..1]
*/
void DigitalOutput::UpdateDutyCycle(double dutyCycle) {
if (StatusIsFatal()) return;

View File

@@ -17,25 +17,10 @@
using namespace frc;
/**
* Constructor.
*
* Uses the default PCM ID of 0.
*
* @param forwardChannel The forward channel number on the PCM (0..7).
* @param reverseChannel The reverse channel number on the PCM (0..7).
*/
DoubleSolenoid::DoubleSolenoid(int forwardChannel, int reverseChannel)
: DoubleSolenoid(SensorUtil::GetDefaultSolenoidModule(), forwardChannel,
reverseChannel) {}
/**
* Constructor.
*
* @param moduleNumber The CAN ID of the PCM.
* @param forwardChannel The forward channel on the PCM to control (0..7).
* @param reverseChannel The reverse channel on the PCM to control (0..7).
*/
DoubleSolenoid::DoubleSolenoid(int moduleNumber, int forwardChannel,
int reverseChannel)
: SolenoidBase(moduleNumber),
@@ -91,19 +76,11 @@ DoubleSolenoid::DoubleSolenoid(int moduleNumber, int forwardChannel,
SetName("DoubleSolenoid", m_moduleNumber, m_forwardChannel);
}
/**
* Destructor.
*/
DoubleSolenoid::~DoubleSolenoid() {
HAL_FreeSolenoidPort(m_forwardHandle);
HAL_FreeSolenoidPort(m_reverseHandle);
}
/**
* Set the value of a solenoid.
*
* @param value The value to set (Off, Forward or Reverse)
*/
void DoubleSolenoid::Set(Value value) {
if (StatusIsFatal()) return;
@@ -132,11 +109,6 @@ void DoubleSolenoid::Set(Value value) {
wpi_setErrorWithContext(rstatus, HAL_GetErrorMessage(rstatus));
}
/**
* Read the current value of the solenoid.
*
* @return The current value of the solenoid.
*/
DoubleSolenoid::Value DoubleSolenoid::Get() const {
if (StatusIsFatal()) return kOff;
int fstatus = 0;
@@ -152,29 +124,11 @@ DoubleSolenoid::Value DoubleSolenoid::Get() const {
return kOff;
}
/**
* Check if the forward solenoid is blacklisted.
*
* If a solenoid is shorted, it is added to the blacklist and
* disabled until power cycle, or until faults are cleared.
* @see ClearAllPCMStickyFaults()
*
* @return If solenoid is disabled due to short.
*/
bool DoubleSolenoid::IsFwdSolenoidBlackListed() const {
int blackList = GetPCMSolenoidBlackList(m_moduleNumber);
return (blackList & m_forwardMask) != 0;
}
/**
* Check if the reverse solenoid is blacklisted.
*
* If a solenoid is shorted, it is added to the blacklist and
* disabled until power cycle, or until faults are cleared.
*
* @see ClearAllPCMStickyFaults()
* @return If solenoid is disabled due to short.
*/
bool DoubleSolenoid::IsRevSolenoidBlackListed() const {
int blackList = GetPCMSolenoidBlackList(m_moduleNumber);
return (blackList & m_reverseMask) != 0;

View File

@@ -17,12 +17,6 @@
using namespace frc;
/**
* Construct a DifferentialDrive.
*
* To pass multiple motors per side, use a SpeedControllerGroup. If a motor
* needs to be inverted, do so before passing it in.
*/
DifferentialDrive::DifferentialDrive(SpeedController& leftMotor,
SpeedController& rightMotor)
: m_leftMotor(leftMotor), m_rightMotor(rightMotor) {
@@ -33,18 +27,6 @@ DifferentialDrive::DifferentialDrive(SpeedController& leftMotor,
SetName("DifferentialDrive", instances);
}
/**
* Arcade drive method for differential drive platform.
*
* Note: Some drivers may prefer inverted rotation controls. This can be done by
* negating the value passed for rotation.
*
* @param xSpeed The speed at which the robot should drive along the X
* axis [-1.0..1.0]. Forward is negative.
* @param zRotation The rotation rate of the robot around the Z axis
* [-1.0..1.0]. Clockwise is positive.
* @param squaredInputs If set, decreases the input sensitivity at low speeds.
*/
void DifferentialDrive::ArcadeDrive(double xSpeed, double zRotation,
bool squaredInputs) {
static bool reported = false;
@@ -100,21 +82,6 @@ void DifferentialDrive::ArcadeDrive(double xSpeed, double zRotation,
m_safetyHelper.Feed();
}
/**
* Curvature drive method for differential drive platform.
*
* The rotation argument controls the curvature of the robot's path rather than
* its rate of heading change. This makes the robot more controllable at high
* speeds. Also handles the robot's quick turn functionality - "quick turn"
* overrides constant-curvature turning for turn-in-place maneuvers.
*
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is
* positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0].
* Clockwise is positive.
* @param isQuickTurn If set, overrides constant-curvature turning for
* turn-in-place maneuvers.
*/
void DifferentialDrive::CurvatureDrive(double xSpeed, double zRotation,
bool isQuickTurn) {
static bool reported = false;
@@ -188,15 +155,6 @@ void DifferentialDrive::CurvatureDrive(double xSpeed, double zRotation,
m_safetyHelper.Feed();
}
/**
* Tank drive method for differential drive platform.
*
* @param leftSpeed The robot left side's speed along the X axis
* [-1.0..1.0]. Forward is positive.
* @param rightSpeed The robot right side's speed along the X axis
* [-1.0..1.0]. Forward is positive.
* @param squaredInputs If set, decreases the input sensitivity at low speeds.
*/
void DifferentialDrive::TankDrive(double leftSpeed, double rightSpeed,
bool squaredInputs) {
static bool reported = false;
@@ -225,55 +183,18 @@ void DifferentialDrive::TankDrive(double leftSpeed, double rightSpeed,
m_safetyHelper.Feed();
}
/**
* Sets the QuickStop speed threshold in curvature drive.
*
* QuickStop compensates for the robot's moment of inertia when stopping after a
* QuickTurn.
*
* While QuickTurn is enabled, the QuickStop accumulator takes on the rotation
* rate value outputted by the low-pass filter when the robot's speed along the
* X axis is below the threshold. When QuickTurn is disabled, the accumulator's
* value is applied against the computed angular power request to slow the
* robot's rotation.
*
* @param threshold X speed below which quick stop accumulator will receive
* rotation rate values [0..1.0].
*/
void DifferentialDrive::SetQuickStopThreshold(double threshold) {
m_quickStopThreshold = threshold;
}
/**
* Sets the low-pass filter gain for QuickStop in curvature drive.
*
* The low-pass filter filters incoming rotation rate commands to smooth out
* high frequency changes.
*
* @param alpha Low-pass filter gain [0.0..2.0]. Smaller values result in slower
* output changes. Values between 1.0 and 2.0 result in output
* oscillation. Values below 0.0 and above 2.0 are unstable.
*/
void DifferentialDrive::SetQuickStopAlpha(double alpha) {
m_quickStopAlpha = alpha;
}
/**
* Gets if the power sent to the right side of the drivetrain is multipled by
* -1.
*
* @return true if the right side is inverted
*/
bool DifferentialDrive::IsRightSideInverted() const {
return m_rightSideInvertMultiplier == -1.0;
}
/**
* Sets if the power sent to the right side of the drivetrain should be
* multipled by -1.
*
* @param rightSideInverted true if right side power should be multipled by -1
*/
void DifferentialDrive::SetRightSideInverted(bool rightSideInverted) {
m_rightSideInvertMultiplier = rightSideInverted ? -1.0 : 1.0;
}

View File

@@ -19,39 +19,12 @@ using namespace frc;
constexpr double kPi = 3.14159265358979323846;
/**
* Construct a Killough drive with the given motors and default motor angles.
*
* The default motor angles make the wheels on each corner parallel to their
* respective opposite sides.
*
* If a motor needs to be inverted, do so before passing it in.
*
* @param leftMotor The motor on the left corner.
* @param rightMotor The motor on the right corner.
* @param backMotor The motor on the back corner.
*/
KilloughDrive::KilloughDrive(SpeedController& leftMotor,
SpeedController& rightMotor,
SpeedController& backMotor)
: KilloughDrive(leftMotor, rightMotor, backMotor, kDefaultLeftMotorAngle,
kDefaultRightMotorAngle, kDefaultBackMotorAngle) {}
/**
* Construct a Killough drive with the given motors.
*
* Angles are measured in degrees clockwise from the positive X axis.
*
* @param leftMotor The motor on the left corner.
* @param rightMotor The motor on the right corner.
* @param backMotor The motor on the back corner.
* @param leftMotorAngle The angle of the left wheel's forward direction of
* travel.
* @param rightMotorAngle The angle of the right wheel's forward direction of
* travel.
* @param backMotorAngle The angle of the back wheel's forward direction of
* travel.
*/
KilloughDrive::KilloughDrive(SpeedController& leftMotor,
SpeedController& rightMotor,
SpeedController& backMotor, double leftMotorAngle,
@@ -71,21 +44,6 @@ KilloughDrive::KilloughDrive(SpeedController& leftMotor,
SetName("KilloughDrive", instances);
}
/**
* Drive method for Killough platform.
*
* Angles are measured clockwise from the positive X axis. The robot's speed is
* independent from its angle or rotation rate.
*
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is
* positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is
* positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0].
* Clockwise is positive.
* @param gyroAngle The current angle reading from the gyro in degrees around
* the Z axis. Use this to implement field-oriented controls.
*/
void KilloughDrive::DriveCartesian(double ySpeed, double xSpeed,
double zRotation, double gyroAngle) {
if (!reported) {
@@ -118,19 +76,6 @@ void KilloughDrive::DriveCartesian(double ySpeed, double xSpeed,
m_safetyHelper.Feed();
}
/**
* Drive method for Killough platform.
*
* Angles are measured clockwise from the positive X axis. The robot's speed is
* independent from its angle or rotation rate.
*
* @param magnitude The robot's speed at a given angle [-1.0..1.0]. Forward is
* positive.
* @param angle The angle around the Z axis at which the robot drives in
* degrees [-180..180].
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0].
* Clockwise is positive.
*/
void KilloughDrive::DrivePolar(double magnitude, double angle,
double zRotation) {
if (!reported) {

View File

@@ -20,11 +20,6 @@ using namespace frc;
constexpr double kPi = 3.14159265358979323846;
/**
* Construct a MecanumDrive.
*
* If a motor needs to be inverted, do so before passing it in.
*/
MecanumDrive::MecanumDrive(SpeedController& frontLeftMotor,
SpeedController& rearLeftMotor,
SpeedController& frontRightMotor,
@@ -42,21 +37,6 @@ MecanumDrive::MecanumDrive(SpeedController& frontLeftMotor,
SetName("MecanumDrive", instances);
}
/**
* Drive method for Mecanum platform.
*
* Angles are measured clockwise from the positive X axis. The robot's speed is
* independent from its angle or rotation rate.
*
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is
* positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is
* positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0].
* Clockwise is positive.
* @param gyroAngle The current angle reading from the gyro in degrees around
* the Z axis. Use this to implement field-oriented controls.
*/
void MecanumDrive::DriveCartesian(double ySpeed, double xSpeed,
double zRotation, double gyroAngle) {
if (!reported) {
@@ -93,19 +73,6 @@ void MecanumDrive::DriveCartesian(double ySpeed, double xSpeed,
m_safetyHelper.Feed();
}
/**
* Drive method for Mecanum platform.
*
* Angles are measured clockwise from the positive X axis. The robot's speed is
* independent from its angle or rotation rate.
*
* @param magnitude The robot's speed at a given angle [-1.0..1.0]. Forward is
* positive.
* @param angle The angle around the Z axis at which the robot drives in
* degrees [-180..180].
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0].
* Clockwise is positive.
*/
void MecanumDrive::DrivePolar(double magnitude, double angle,
double zRotation) {
if (!reported) {
@@ -118,22 +85,10 @@ void MecanumDrive::DrivePolar(double magnitude, double angle,
magnitude * std::cos(angle * (kPi / 180.0)), zRotation, 0.0);
}
/**
* Gets if the power sent to the right side of the drivetrain is multipled by
* -1.
*
* @return true if the right side is inverted
*/
bool MecanumDrive::IsRightSideInverted() const {
return m_rightSideInvertMultiplier == -1.0;
}
/**
* Sets if the power sent to the right side of the drivetrain should be
* multipled by -1.
*
* @param rightSideInverted true if right side power should be multipled by -1
*/
void MecanumDrive::SetRightSideInverted(bool rightSideInverted) {
m_rightSideInvertMultiplier = rightSideInverted ? -1.0 : 1.0;
}

View File

@@ -20,32 +20,10 @@ using namespace frc;
RobotDriveBase::RobotDriveBase() { m_safetyHelper.SetSafetyEnabled(true); }
/**
* Sets the deadband applied to the drive inputs (e.g., joystick values).
*
* The default value is 0.02. Inputs smaller than the deadband are set to 0.0
* while inputs larger than the deadband are scaled from 0.0 to 1.0. See
* ApplyDeadband().
*
* @param deadband The deadband to set.
*/
void RobotDriveBase::SetDeadband(double deadband) { m_deadband = deadband; }
/**
* Configure the scaling factor for using RobotDrive with motor controllers in a
* mode other than PercentVbus or to limit the maximum output.
*
* @param maxOutput Multiplied with the output percentage computed by the drive
* functions.
*/
void RobotDriveBase::SetMaxOutput(double maxOutput) { m_maxOutput = maxOutput; }
/**
* Feed the motor safety object. Resets the timer that will stop the motors if
* it completes.
*
* @see MotorSafetyHelper::Feed()
*/
void RobotDriveBase::FeedWatchdog() { m_safetyHelper.Feed(); }
void RobotDriveBase::SetExpiration(double timeout) {
@@ -66,9 +44,6 @@ void RobotDriveBase::SetSafetyEnabled(bool enabled) {
m_safetyHelper.SetSafetyEnabled(enabled);
}
/**
* Limit motor values to the -1.0 to +1.0 range.
*/
double RobotDriveBase::Limit(double value) {
if (value > 1.0) {
return 1.0;
@@ -79,13 +54,6 @@ double RobotDriveBase::Limit(double value) {
return value;
}
/**
* Returns 0.0 if the given value is within the specified range around zero. The
* remaining range between the deadband and 1.0 is scaled from 0.0 to 1.0.
*
* @param value value to clip
* @param deadband range around zero
*/
double RobotDriveBase::ApplyDeadband(double value, double deadband) {
if (std::abs(value) > deadband) {
if (value > 0.0) {
@@ -98,9 +66,6 @@ double RobotDriveBase::ApplyDeadband(double value, double deadband) {
}
}
/**
* Normalize all wheel speeds if the magnitude of any wheel is greater than 1.0.
*/
void RobotDriveBase::Normalize(wpi::MutableArrayRef<double> wheelSpeeds) {
double maxMagnitude = std::abs(wheelSpeeds[0]);
for (size_t i = 1; i < wheelSpeeds.size(); i++) {

View File

@@ -18,11 +18,6 @@ Vector2d::Vector2d(double x, double y) {
this->y = y;
}
/**
* Rotate a vector in Cartesian space.
*
* @param angle angle in degrees by which to rotate vector counter-clockwise.
*/
void Vector2d::Rotate(double angle) {
double cosA = std::cos(angle * (kPi / 180.0));
double sinA = std::sin(angle * (kPi / 180.0));
@@ -33,25 +28,12 @@ void Vector2d::Rotate(double angle) {
y = out[1];
}
/**
* Returns dot product of this vector with argument.
*
* @param vec Vector with which to perform dot product.
*/
double Vector2d::Dot(const Vector2d& vec) const {
return x * vec.x + y * vec.y;
}
/**
* Returns magnitude of vector.
*/
double Vector2d::Magnitude() const { return std::sqrt(x * x + y * y); }
/**
* Returns scalar projection of this vector onto argument.
*
* @param vec Vector onto which to project this vector.
*/
double Vector2d::ScalarProject(const Vector2d& vec) const {
return Dot(vec) / vec.Magnitude();
}

View File

@@ -81,43 +81,23 @@ DriverStation::~DriverStation() {
m_dsThread.join();
}
/**
* Return a pointer to the singleton DriverStation.
*
* @return Pointer to the DS instance
*/
DriverStation& DriverStation::GetInstance() {
static DriverStation instance;
return instance;
}
/**
* Report an error to the DriverStation messages window.
*
* The error is also printed to the program console.
*/
void DriverStation::ReportError(const wpi::Twine& error) {
wpi::SmallString<128> temp;
HAL_SendError(1, 1, 0, error.toNullTerminatedStringRef(temp).data(), "", "",
1);
}
/**
* Report a warning to the DriverStation messages window.
*
* The warning is also printed to the program console.
*/
void DriverStation::ReportWarning(const wpi::Twine& error) {
wpi::SmallString<128> temp;
HAL_SendError(0, 1, 0, error.toNullTerminatedStringRef(temp).data(), "", "",
1);
}
/**
* Report an error to the DriverStation messages window.
*
* The error is also printed to the program console.
*/
void DriverStation::ReportError(bool isError, int32_t code,
const wpi::Twine& error,
const wpi::Twine& location,
@@ -131,13 +111,6 @@ void DriverStation::ReportError(bool isError, int32_t code,
stack.toNullTerminatedStringRef(stackTemp).data(), 1);
}
/**
* The state of one joystick button. Button indexes begin at 1.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return The state of the joystick button.
*/
bool DriverStation::GetStickButton(int stick, int button) {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -161,14 +134,6 @@ bool DriverStation::GetStickButton(int stick, int button) {
return m_joystickButtons[stick].buttons & 1 << (button - 1);
}
/**
* Whether one joystick button was pressed since the last check. Button indexes
* begin at 1.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return Whether the joystick button was pressed since the last check.
*/
bool DriverStation::GetStickButtonPressed(int stick, int button) {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -198,14 +163,6 @@ bool DriverStation::GetStickButtonPressed(int stick, int button) {
}
}
/**
* Whether one joystick button was released since the last check. Button indexes
* begin at 1.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return Whether the joystick button was released since the last check.
*/
bool DriverStation::GetStickButtonReleased(int stick, int button) {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -235,15 +192,6 @@ bool DriverStation::GetStickButtonReleased(int stick, int button) {
}
}
/**
* Get the value of the axis on a joystick.
*
* This depends on the mapping of the joystick connected to the specified port.
*
* @param stick The joystick to read.
* @param axis The analog axis value to read from the joystick.
* @return The value of the axis on the joystick.
*/
double DriverStation::GetStickAxis(int stick, int axis) {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -266,11 +214,6 @@ double DriverStation::GetStickAxis(int stick, int axis) {
return m_joystickAxes[stick].axes[axis];
}
/**
* Get the state of a POV on the joystick.
*
* @return the angle of the POV in degrees, or -1 if the POV is not pressed.
*/
int DriverStation::GetStickPOV(int stick, int pov) {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -293,12 +236,6 @@ int DriverStation::GetStickPOV(int stick, int pov) {
return m_joystickPOVs[stick].povs[pov];
}
/**
* The state of the buttons on the joystick.
*
* @param stick The joystick to read.
* @return The state of the buttons on the joystick.
*/
int DriverStation::GetStickButtons(int stick) const {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -309,12 +246,6 @@ int DriverStation::GetStickButtons(int stick) const {
return m_joystickButtons[stick].buttons;
}
/**
* Returns the number of axes on a given joystick port.
*
* @param stick The joystick port number
* @return The number of axes on the indicated joystick
*/
int DriverStation::GetStickAxisCount(int stick) const {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -325,12 +256,6 @@ int DriverStation::GetStickAxisCount(int stick) const {
return m_joystickAxes[stick].count;
}
/**
* Returns the number of POVs on a given joystick port.
*
* @param stick The joystick port number
* @return The number of POVs on the indicated joystick
*/
int DriverStation::GetStickPOVCount(int stick) const {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -341,12 +266,6 @@ int DriverStation::GetStickPOVCount(int stick) const {
return m_joystickPOVs[stick].count;
}
/**
* Returns the number of buttons on a given joystick port.
*
* @param stick The joystick port number
* @return The number of buttons on the indicated joystick
*/
int DriverStation::GetStickButtonCount(int stick) const {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -357,12 +276,6 @@ int DriverStation::GetStickButtonCount(int stick) const {
return m_joystickButtons[stick].count;
}
/**
* Returns a boolean indicating if the controller is an xbox controller.
*
* @param stick The joystick port number
* @return A boolean that is true if the controller is an xbox controller.
*/
bool DriverStation::GetJoystickIsXbox(int stick) const {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -373,12 +286,6 @@ bool DriverStation::GetJoystickIsXbox(int stick) const {
return static_cast<bool>(m_joystickDescriptor[stick].isXbox);
}
/**
* Returns the type of joystick at a given port.
*
* @param stick The joystick port number
* @return The HID type of joystick at the given port
*/
int DriverStation::GetJoystickType(int stick) const {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -389,12 +296,6 @@ int DriverStation::GetJoystickType(int stick) const {
return static_cast<int>(m_joystickDescriptor[stick].type);
}
/**
* Returns the name of the joystick at the given port.
*
* @param stick The joystick port number
* @return The name of the joystick at the given port
*/
std::string DriverStation::GetJoystickName(int stick) const {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -404,12 +305,6 @@ std::string DriverStation::GetJoystickName(int stick) const {
return m_joystickDescriptor[stick].name;
}
/**
* Returns the types of Axes on a given joystick port.
*
* @param stick The joystick port number and the target axis
* @return What type of axis the axis is reporting to be
*/
int DriverStation::GetJoystickAxisType(int stick, int axis) const {
if (stick < 0 || stick >= kJoystickPorts) {
wpi_setWPIError(BadJoystickIndex);
@@ -420,104 +315,50 @@ int DriverStation::GetJoystickAxisType(int stick, int axis) const {
return m_joystickDescriptor[stick].axisTypes[axis];
}
/**
* Check if the DS has enabled the robot.
*
* @return True if the robot is enabled and the DS is connected
*/
bool DriverStation::IsEnabled() const {
HAL_ControlWord controlWord;
UpdateControlWord(false, controlWord);
return controlWord.enabled && controlWord.dsAttached;
}
/**
* Check if the robot is disabled.
*
* @return True if the robot is explicitly disabled or the DS is not connected
*/
bool DriverStation::IsDisabled() const {
HAL_ControlWord controlWord;
UpdateControlWord(false, controlWord);
return !(controlWord.enabled && controlWord.dsAttached);
}
/**
* Check if the DS is commanding autonomous mode.
*
* @return True if the robot is being commanded to be in autonomous mode
*/
bool DriverStation::IsAutonomous() const {
HAL_ControlWord controlWord;
UpdateControlWord(false, controlWord);
return controlWord.autonomous;
}
/**
* Check if the DS is commanding teleop mode.
*
* @return True if the robot is being commanded to be in teleop mode
*/
bool DriverStation::IsOperatorControl() const {
HAL_ControlWord controlWord;
UpdateControlWord(false, controlWord);
return !(controlWord.autonomous || controlWord.test);
}
/**
* Check if the DS is commanding test mode.
*
* @return True if the robot is being commanded to be in test mode
*/
bool DriverStation::IsTest() const {
HAL_ControlWord controlWord;
UpdateControlWord(false, controlWord);
return controlWord.test;
}
/**
* Check if the DS is attached.
*
* @return True if the DS is connected to the robot
*/
bool DriverStation::IsDSAttached() const {
HAL_ControlWord controlWord;
UpdateControlWord(false, controlWord);
return controlWord.dsAttached;
}
/**
* Has a new control packet from the driver station arrived since the last time
* this function was called?
*
* Warning: If you call this function from more than one place at the same time,
* you will not get the intended behavior.
*
* @return True if the control data has been updated since the last call.
*/
bool DriverStation::IsNewControlData() const { return HAL_IsNewControlData(); }
/**
* Is the driver station attached to a Field Management System?
*
* @return True if the robot is competing on a field being controlled by a Field
* Management System
*/
bool DriverStation::IsFMSAttached() const {
HAL_ControlWord controlWord;
UpdateControlWord(false, controlWord);
return controlWord.fmsAttached;
}
/**
* Check if the FPGA outputs are enabled.
*
* The outputs may be disabled if the robot is disabled or e-stopped, the
* watchdog has expired, or if the roboRIO browns out.
*
* @return True if the FPGA outputs are enabled.
* @deprecated Use RobotController static class method
*/
bool DriverStation::IsSysActive() const {
int32_t status = 0;
bool retVal = HAL_GetSystemActive(&status);
@@ -525,12 +366,6 @@ bool DriverStation::IsSysActive() const {
return retVal;
}
/**
* Check if the system is browned out.
*
* @return True if the system is browned out
* @deprecated Use RobotController static class method
*/
bool DriverStation::IsBrownedOut() const {
int32_t status = 0;
bool retVal = HAL_GetBrownedOut(&status);
@@ -563,13 +398,6 @@ int DriverStation::GetReplayNumber() const {
return m_matchInfo->replayNumber;
}
/**
* Return the alliance that the driver station says it is on.
*
* This could return kRed or kBlue.
*
* @return The Alliance enum (kRed, kBlue or kInvalid)
*/
DriverStation::Alliance DriverStation::GetAlliance() const {
int32_t status = 0;
auto allianceStationID = HAL_GetAllianceStation(&status);
@@ -587,13 +415,6 @@ DriverStation::Alliance DriverStation::GetAlliance() const {
}
}
/**
* Return the driver station location on the field.
*
* This could return 1, 2, or 3.
*
* @return The location of the driver station (1-3, 0 for invalid)
*/
int DriverStation::GetLocation() const {
int32_t status = 0;
auto allianceStationID = HAL_GetAllianceStation(&status);
@@ -612,32 +433,8 @@ int DriverStation::GetLocation() const {
}
}
/**
* Wait until a new packet comes from the driver station.
*
* This blocks on a semaphore, so the waiting is efficient.
*
* This is a good way to delay processing until there is new driver station data
* to act on.
*/
void DriverStation::WaitForData() { WaitForData(0); }
/**
* Wait until a new packet comes from the driver station, or wait for a timeout.
*
* If the timeout is less then or equal to 0, wait indefinitely.
*
* Timeout is in milliseconds
*
* This blocks on a semaphore, so the waiting is efficient.
*
* This is a good way to delay processing until there is new driver station data
* to act on.
*
* @param timeout Timeout time in seconds
*
* @return true if new data, otherwise false
*/
bool DriverStation::WaitForData(double timeout) {
auto timeoutTime =
std::chrono::steady_clock::now() + std::chrono::duration<double>(timeout);
@@ -657,31 +454,11 @@ bool DriverStation::WaitForData(double timeout) {
return true;
}
/**
* Return the approximate match time.
*
* The FMS does not send an official match time to the robots, but does send an
* approximate match time. The value will count down the time remaining in the
* current period (auto or teleop).
*
* Warning: This is not an official time (so it cannot be used to dispute ref
* calls or guarantee that a function will trigger before the match ends).
*
* The Practice Match function of the DS approximates the behaviour seen on the
* field.
*
* @return Time remaining in current match period (auto or teleop)
*/
double DriverStation::GetMatchTime() const {
int32_t status;
return HAL_GetMatchTime(&status);
}
/**
* Read the battery voltage.
*
* @return The battery voltage in Volts.
*/
double DriverStation::GetBatteryVoltage() const {
int32_t status = 0;
double voltage = HAL_GetVinVoltage(&status);
@@ -690,6 +467,155 @@ double DriverStation::GetBatteryVoltage() const {
return voltage;
}
void DriverStation::GetData() {
// Get the status of all of the joysticks, and save to the cache
for (uint8_t stick = 0; stick < kJoystickPorts; stick++) {
HAL_GetJoystickAxes(stick, &m_joystickAxesCache[stick]);
HAL_GetJoystickPOVs(stick, &m_joystickPOVsCache[stick]);
HAL_GetJoystickButtons(stick, &m_joystickButtonsCache[stick]);
HAL_GetJoystickDescriptor(stick, &m_joystickDescriptorCache[stick]);
}
// Grab match specific data
HAL_MatchInfo matchInfo;
auto status = HAL_GetMatchInfo(&matchInfo);
if (status == 0) {
m_matchInfoCache->eventName = matchInfo.eventName;
m_matchInfoCache->matchNumber = matchInfo.matchNumber;
m_matchInfoCache->replayNumber = matchInfo.replayNumber;
m_matchInfoCache->matchType =
static_cast<DriverStation::MatchType>(matchInfo.matchType);
m_matchInfoCache->gameSpecificMessage = matchInfo.gameSpecificMessage;
}
HAL_FreeMatchInfo(&matchInfo);
// Force a control word update, to make sure the data is the newest.
HAL_ControlWord controlWord;
UpdateControlWord(true, controlWord);
{
// Obtain a write lock on the data, swap the cached data into the
// main data arrays
std::lock_guard<wpi::mutex> lock(m_cacheDataMutex);
for (int32_t i = 0; i < kJoystickPorts; i++) {
// If buttons weren't pressed and are now, set flags in m_buttonsPressed
m_joystickButtonsPressed[i] |=
~m_joystickButtons[i].buttons & m_joystickButtonsCache[i].buttons;
// If buttons were pressed and aren't now, set flags in m_buttonsReleased
m_joystickButtonsReleased[i] |=
m_joystickButtons[i].buttons & ~m_joystickButtonsCache[i].buttons;
}
m_joystickAxes.swap(m_joystickAxesCache);
m_joystickPOVs.swap(m_joystickPOVsCache);
m_joystickButtons.swap(m_joystickButtonsCache);
m_joystickDescriptor.swap(m_joystickDescriptorCache);
m_matchInfo.swap(m_matchInfoCache);
}
{
std::lock_guard<wpi::mutex> waitLock(m_waitForDataMutex);
// Nofify all threads
m_waitForDataCounter++;
m_waitForDataCond.notify_all();
}
SendMatchData();
}
DriverStation::DriverStation() {
HAL_Initialize(500, 0);
m_waitForDataCounter = 0;
m_joystickAxes = std::make_unique<HAL_JoystickAxes[]>(kJoystickPorts);
m_joystickPOVs = std::make_unique<HAL_JoystickPOVs[]>(kJoystickPorts);
m_joystickButtons = std::make_unique<HAL_JoystickButtons[]>(kJoystickPorts);
m_joystickDescriptor =
std::make_unique<HAL_JoystickDescriptor[]>(kJoystickPorts);
m_matchInfo = std::make_unique<MatchInfoData>();
m_joystickAxesCache = std::make_unique<HAL_JoystickAxes[]>(kJoystickPorts);
m_joystickPOVsCache = std::make_unique<HAL_JoystickPOVs[]>(kJoystickPorts);
m_joystickButtonsCache =
std::make_unique<HAL_JoystickButtons[]>(kJoystickPorts);
m_joystickDescriptorCache =
std::make_unique<HAL_JoystickDescriptor[]>(kJoystickPorts);
m_matchInfoCache = std::make_unique<MatchInfoData>();
m_matchDataSender = std::make_unique<MatchDataSender>();
// All joysticks should default to having zero axes, povs and buttons, so
// uninitialized memory doesn't get sent to speed controllers.
for (unsigned int i = 0; i < kJoystickPorts; i++) {
m_joystickAxes[i].count = 0;
m_joystickPOVs[i].count = 0;
m_joystickButtons[i].count = 0;
m_joystickDescriptor[i].isXbox = 0;
m_joystickDescriptor[i].type = -1;
m_joystickDescriptor[i].name[0] = '\0';
m_joystickAxesCache[i].count = 0;
m_joystickPOVsCache[i].count = 0;
m_joystickButtonsCache[i].count = 0;
m_joystickDescriptorCache[i].isXbox = 0;
m_joystickDescriptorCache[i].type = -1;
m_joystickDescriptorCache[i].name[0] = '\0';
m_joystickButtonsPressed[i] = 0;
m_joystickButtonsReleased[i] = 0;
}
m_dsThread = std::thread(&DriverStation::Run, this);
}
void DriverStation::ReportJoystickUnpluggedError(const wpi::Twine& message) {
double currentTime = Timer::GetFPGATimestamp();
if (currentTime > m_nextMessageTime) {
ReportError(message);
m_nextMessageTime = currentTime + kJoystickUnpluggedMessageInterval;
}
}
void DriverStation::ReportJoystickUnpluggedWarning(const wpi::Twine& message) {
double currentTime = Timer::GetFPGATimestamp();
if (currentTime > m_nextMessageTime) {
ReportWarning(message);
m_nextMessageTime = currentTime + kJoystickUnpluggedMessageInterval;
}
}
void DriverStation::Run() {
m_isRunning = true;
int safetyCounter = 0;
while (m_isRunning) {
HAL_WaitForDSData();
GetData();
if (IsDisabled()) safetyCounter = 0;
if (++safetyCounter >= 4) {
MotorSafetyHelper::CheckMotors();
safetyCounter = 0;
}
if (m_userInDisabled) HAL_ObserveUserProgramDisabled();
if (m_userInAutonomous) HAL_ObserveUserProgramAutonomous();
if (m_userInTeleop) HAL_ObserveUserProgramTeleop();
if (m_userInTest) HAL_ObserveUserProgramTest();
}
}
void DriverStation::UpdateControlWord(bool force,
HAL_ControlWord& controlWord) const {
auto now = std::chrono::steady_clock::now();
std::lock_guard<wpi::mutex> lock(m_controlWordMutex);
// Update every 50 ms or on force.
if ((now - m_lastControlWordUpdate > std::chrono::milliseconds(50)) ||
force) {
HAL_GetControlWord(&m_controlWordCache);
m_lastControlWordUpdate = now;
}
controlWord = m_controlWordCache;
}
void DriverStation::SendMatchData() {
int32_t status = 0;
HAL_AllianceStationID alliance = HAL_GetAllianceStation(&status);
@@ -748,181 +674,3 @@ void DriverStation::SendMatchData() {
std::memcpy(&wordInt, &ctlWord, sizeof(wordInt));
m_matchDataSender->controlWord.SetDouble(wordInt);
}
/**
* Copy data from the DS task for the user.
*
* If no new data exists, it will just be returned, otherwise
* the data will be copied from the DS polling loop.
*/
void DriverStation::GetData() {
// Get the status of all of the joysticks, and save to the cache
for (uint8_t stick = 0; stick < kJoystickPorts; stick++) {
HAL_GetJoystickAxes(stick, &m_joystickAxesCache[stick]);
HAL_GetJoystickPOVs(stick, &m_joystickPOVsCache[stick]);
HAL_GetJoystickButtons(stick, &m_joystickButtonsCache[stick]);
HAL_GetJoystickDescriptor(stick, &m_joystickDescriptorCache[stick]);
}
// Grab match specific data
HAL_MatchInfo matchInfo;
auto status = HAL_GetMatchInfo(&matchInfo);
if (status == 0) {
m_matchInfoCache->eventName = matchInfo.eventName;
m_matchInfoCache->matchNumber = matchInfo.matchNumber;
m_matchInfoCache->replayNumber = matchInfo.replayNumber;
m_matchInfoCache->matchType =
static_cast<DriverStation::MatchType>(matchInfo.matchType);
m_matchInfoCache->gameSpecificMessage = matchInfo.gameSpecificMessage;
}
HAL_FreeMatchInfo(&matchInfo);
// Force a control word update, to make sure the data is the newest.
HAL_ControlWord controlWord;
UpdateControlWord(true, controlWord);
{
// Obtain a write lock on the data, swap the cached data into the
// main data arrays
std::lock_guard<wpi::mutex> lock(m_cacheDataMutex);
for (int32_t i = 0; i < kJoystickPorts; i++) {
// If buttons weren't pressed and are now, set flags in m_buttonsPressed
m_joystickButtonsPressed[i] |=
~m_joystickButtons[i].buttons & m_joystickButtonsCache[i].buttons;
// If buttons were pressed and aren't now, set flags in m_buttonsReleased
m_joystickButtonsReleased[i] |=
m_joystickButtons[i].buttons & ~m_joystickButtonsCache[i].buttons;
}
m_joystickAxes.swap(m_joystickAxesCache);
m_joystickPOVs.swap(m_joystickPOVsCache);
m_joystickButtons.swap(m_joystickButtonsCache);
m_joystickDescriptor.swap(m_joystickDescriptorCache);
m_matchInfo.swap(m_matchInfoCache);
}
{
std::lock_guard<wpi::mutex> waitLock(m_waitForDataMutex);
// Nofify all threads
m_waitForDataCounter++;
m_waitForDataCond.notify_all();
}
SendMatchData();
}
/**
* DriverStation constructor.
*
* This is only called once the first time GetInstance() is called
*/
DriverStation::DriverStation() {
HAL_Initialize(500, 0);
m_waitForDataCounter = 0;
m_joystickAxes = std::make_unique<HAL_JoystickAxes[]>(kJoystickPorts);
m_joystickPOVs = std::make_unique<HAL_JoystickPOVs[]>(kJoystickPorts);
m_joystickButtons = std::make_unique<HAL_JoystickButtons[]>(kJoystickPorts);
m_joystickDescriptor =
std::make_unique<HAL_JoystickDescriptor[]>(kJoystickPorts);
m_matchInfo = std::make_unique<MatchInfoData>();
m_joystickAxesCache = std::make_unique<HAL_JoystickAxes[]>(kJoystickPorts);
m_joystickPOVsCache = std::make_unique<HAL_JoystickPOVs[]>(kJoystickPorts);
m_joystickButtonsCache =
std::make_unique<HAL_JoystickButtons[]>(kJoystickPorts);
m_joystickDescriptorCache =
std::make_unique<HAL_JoystickDescriptor[]>(kJoystickPorts);
m_matchInfoCache = std::make_unique<MatchInfoData>();
m_matchDataSender = std::make_unique<MatchDataSender>();
// All joysticks should default to having zero axes, povs and buttons, so
// uninitialized memory doesn't get sent to speed controllers.
for (unsigned int i = 0; i < kJoystickPorts; i++) {
m_joystickAxes[i].count = 0;
m_joystickPOVs[i].count = 0;
m_joystickButtons[i].count = 0;
m_joystickDescriptor[i].isXbox = 0;
m_joystickDescriptor[i].type = -1;
m_joystickDescriptor[i].name[0] = '\0';
m_joystickAxesCache[i].count = 0;
m_joystickPOVsCache[i].count = 0;
m_joystickButtonsCache[i].count = 0;
m_joystickDescriptorCache[i].isXbox = 0;
m_joystickDescriptorCache[i].type = -1;
m_joystickDescriptorCache[i].name[0] = '\0';
m_joystickButtonsPressed[i] = 0;
m_joystickButtonsReleased[i] = 0;
}
m_dsThread = std::thread(&DriverStation::Run, this);
}
/**
* Reports errors related to unplugged joysticks
* Throttles the errors so that they don't overwhelm the DS
*/
void DriverStation::ReportJoystickUnpluggedError(const wpi::Twine& message) {
double currentTime = Timer::GetFPGATimestamp();
if (currentTime > m_nextMessageTime) {
ReportError(message);
m_nextMessageTime = currentTime + kJoystickUnpluggedMessageInterval;
}
}
/**
* Reports errors related to unplugged joysticks.
*
* Throttles the errors so that they don't overwhelm the DS.
*/
void DriverStation::ReportJoystickUnpluggedWarning(const wpi::Twine& message) {
double currentTime = Timer::GetFPGATimestamp();
if (currentTime > m_nextMessageTime) {
ReportWarning(message);
m_nextMessageTime = currentTime + kJoystickUnpluggedMessageInterval;
}
}
void DriverStation::Run() {
m_isRunning = true;
int safetyCounter = 0;
while (m_isRunning) {
HAL_WaitForDSData();
GetData();
if (IsDisabled()) safetyCounter = 0;
if (++safetyCounter >= 4) {
MotorSafetyHelper::CheckMotors();
safetyCounter = 0;
}
if (m_userInDisabled) HAL_ObserveUserProgramDisabled();
if (m_userInAutonomous) HAL_ObserveUserProgramAutonomous();
if (m_userInTeleop) HAL_ObserveUserProgramTeleop();
if (m_userInTest) HAL_ObserveUserProgramTest();
}
}
/**
* Gets ControlWord data from the cache. If 50ms has passed, or the force
* parameter is set, the cached data is updated. Otherwise the data is just
* copied from the cache.
*
* @param force True to force an update to the cache, otherwise update if 50ms
* have passed.
* @param controlWord Structure to put the return control word data into.
*/
void DriverStation::UpdateControlWord(bool force,
HAL_ControlWord& controlWord) const {
auto now = std::chrono::steady_clock::now();
std::lock_guard<wpi::mutex> lock(m_controlWordMutex);
// Update every 50 ms or on force.
if ((now - m_lastControlWordUpdate > std::chrono::milliseconds(50)) ||
force) {
HAL_GetControlWord(&m_controlWordCache);
m_lastControlWordUpdate = now;
}
controlWord = m_controlWordCache;
}

View File

@@ -15,62 +15,6 @@
using namespace frc;
/**
* Common initialization code for Encoders.
*
* This code allocates resources for Encoders and is common to all constructors.
*
* The counter will start counting immediately.
*
* @param reverseDirection If true, counts down instead of up (this is all
* relative)
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
* decoding. If 4X is selected, then an encoder FPGA
* object is used and the returned counts will be 4x
* the encoder spec'd value since all rising and
* falling edges are counted. If 1X or 2X are selected
* then a counter object will be used and the returned
* value will either exactly match the spec'd count or
* be double (2x) the spec'd count.
*/
void Encoder::InitEncoder(bool reverseDirection, EncodingType encodingType) {
int32_t status = 0;
m_encoder = HAL_InitializeEncoder(
m_aSource->GetPortHandleForRouting(),
(HAL_AnalogTriggerType)m_aSource->GetAnalogTriggerTypeForRouting(),
m_bSource->GetPortHandleForRouting(),
(HAL_AnalogTriggerType)m_bSource->GetAnalogTriggerTypeForRouting(),
reverseDirection, (HAL_EncoderEncodingType)encodingType, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
HAL_Report(HALUsageReporting::kResourceType_Encoder, GetFPGAIndex(),
encodingType);
SetName("Encoder", m_aSource->GetChannel());
}
/**
* Encoder constructor.
*
* Construct a Encoder given a and b channels.
*
* The counter will start counting immediately.
*
* @param aChannel The a channel DIO channel. 0-9 are on-board, 10-25
* are on the MXP port
* @param bChannel The b channel DIO channel. 0-9 are on-board, 10-25
* are on the MXP port
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward
* represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
* decoding. If 4X is selected, then an encoder FPGA
* object is used and the returned counts will be 4x
* the encoder spec'd value since all rising and
* falling edges are counted. If 1X or 2X are selected
* then a counter object will be used and the returned
* value will either exactly match the spec'd count or
* be double (2x) the spec'd count.
*/
Encoder::Encoder(int aChannel, int bChannel, bool reverseDirection,
EncodingType encodingType) {
m_aSource = std::make_shared<DigitalInput>(aChannel);
@@ -80,29 +24,6 @@ Encoder::Encoder(int aChannel, int bChannel, bool reverseDirection,
AddChild(m_bSource);
}
/**
* Encoder constructor.
*
* Construct a Encoder given a and b channels as digital inputs. This is used in
* the case where the digital inputs are shared. The Encoder class will not
* allocate the digital inputs and assume that they already are counted.
*
* The counter will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource the source that should be used for the b channel.
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward
* represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
* decoding. If 4X is selected, then an encoder FPGA
* object is used and the returned counts will be 4x
* the encoder spec'd value since all rising and
* falling edges are counted. If 1X or 2X are selected
* then a counter object will be used and the returned
* value will either exactly match the spec'd count or
* be double (2x) the spec'd count.
*/
Encoder::Encoder(DigitalSource* aSource, DigitalSource* bSource,
bool reverseDirection, EncodingType encodingType)
: m_aSource(aSource, NullDeleter<DigitalSource>()),
@@ -113,6 +34,13 @@ Encoder::Encoder(DigitalSource* aSource, DigitalSource* bSource,
InitEncoder(reverseDirection, encodingType);
}
Encoder::Encoder(DigitalSource& aSource, DigitalSource& bSource,
bool reverseDirection, EncodingType encodingType)
: m_aSource(&aSource, NullDeleter<DigitalSource>()),
m_bSource(&bSource, NullDeleter<DigitalSource>()) {
InitEncoder(reverseDirection, encodingType);
}
Encoder::Encoder(std::shared_ptr<DigitalSource> aSource,
std::shared_ptr<DigitalSource> bSource, bool reverseDirection,
EncodingType encodingType)
@@ -123,84 +51,12 @@ Encoder::Encoder(std::shared_ptr<DigitalSource> aSource,
InitEncoder(reverseDirection, encodingType);
}
/**
* Encoder constructor.
*
* Construct a Encoder given a and b channels as digital inputs. This is used in
* the case where the digital inputs are shared. The Encoder class will not
* allocate the digital inputs and assume that they already are counted.
*
* The counter will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource the source that should be used for the b channel.
* @param reverseDirection represents the orientation of the encoder and
* inverts the output values if necessary so forward
* represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X
* decoding. If 4X is selected, then an encoder FPGA
* object is used and the returned counts will be 4x
* the encoder spec'd value since all rising and
* falling edges are counted. If 1X or 2X are selected
* then a counter object will be used and the returned
* value will either exactly match the spec'd count or
* be double (2x) the spec'd count.
*/
Encoder::Encoder(DigitalSource& aSource, DigitalSource& bSource,
bool reverseDirection, EncodingType encodingType)
: m_aSource(&aSource, NullDeleter<DigitalSource>()),
m_bSource(&bSource, NullDeleter<DigitalSource>()) {
InitEncoder(reverseDirection, encodingType);
}
/**
* Free the resources for an Encoder.
*
* Frees the FPGA resources associated with an Encoder.
*/
Encoder::~Encoder() {
int32_t status = 0;
HAL_FreeEncoder(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* The encoding scale factor 1x, 2x, or 4x, per the requested encodingType.
*
* Used to divide raw edge counts down to spec'd counts.
*/
int Encoder::GetEncodingScale() const {
int32_t status = 0;
int val = HAL_GetEncoderEncodingScale(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return val;
}
/**
* 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
*/
int Encoder::GetRaw() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
int value = HAL_GetEncoderRaw(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
/**
* Gets the current count.
*
* Returns the current count on the Encoder. This method compensates for the
* decoding type.
*
* @return Current count from the Encoder adjusted for the 1x, 2x, or 4x scale
* factor.
*/
int Encoder::Get() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
@@ -209,11 +65,6 @@ int Encoder::Get() const {
return value;
}
/**
* Reset the Encoder distance to zero.
*
* Resets the current count to zero on the encoder.
*/
void Encoder::Reset() {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -221,17 +72,6 @@ void Encoder::Reset() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Returns the period of the most recent pulse.
*
* Returns the period of the most recent Encoder pulse in seconds. This method
* compensates for the decoding type.
*
* Warning: This returns unscaled periods. Use GetRate() for rates that are
* scaled using the value from SetDistancePerPulse().
*
* @return Period in seconds of the most recent pulse.
*/
double Encoder::GetPeriod() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
@@ -240,22 +80,6 @@ double Encoder::GetPeriod() const {
return value;
}
/**
* 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 Encoder::SetMaxPeriod(double maxPeriod) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -263,15 +87,6 @@ void Encoder::SetMaxPeriod(double maxPeriod) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(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 Encoder::GetStopped() const {
if (StatusIsFatal()) return true;
int32_t status = 0;
@@ -280,11 +95,6 @@ bool Encoder::GetStopped() const {
return value;
}
/**
* The last direction the encoder value changed.
*
* @return The last direction the encoder value changed.
*/
bool Encoder::GetDirection() const {
if (StatusIsFatal()) return false;
int32_t status = 0;
@@ -293,24 +103,21 @@ bool Encoder::GetDirection() const {
return value;
}
/**
* The scale needed to convert a raw counter value into a number of encoder
* pulses.
*/
double Encoder::DecodingScaleFactor() const {
if (StatusIsFatal()) return 0.0;
int Encoder::GetRaw() const {
if (StatusIsFatal()) return 0;
int32_t status = 0;
double val = HAL_GetEncoderDecodingScaleFactor(m_encoder, &status);
int value = HAL_GetEncoderRaw(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return value;
}
int Encoder::GetEncodingScale() const {
int32_t status = 0;
int val = HAL_GetEncoderEncodingScale(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return val;
}
/**
* Get the distance the robot has driven since the last reset.
*
* @return The distance driven since the last reset as scaled by the value from
* SetDistancePerPulse().
*/
double Encoder::GetDistance() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
@@ -319,14 +126,6 @@ double Encoder::GetDistance() const {
return value;
}
/**
* Get the current rate of the encoder.
*
* Units are distance per second as scaled by the value from
* SetDistancePerPulse().
*
* @return The current rate of the encoder.
*/
double Encoder::GetRate() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
@@ -335,12 +134,6 @@ double Encoder::GetRate() const {
return value;
}
/**
* Set the minimum rate of the device before the hardware reports it stopped.
*
* @param minRate The minimum rate. The units are in distance per second as
* scaled by the value from SetDistancePerPulse().
*/
void Encoder::SetMinRate(double minRate) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -348,23 +141,6 @@ void Encoder::SetMinRate(double minRate) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Set the distance per pulse for this encoder.
*
* This sets the multiplier used to determine the distance driven based on the
* count value from the encoder.
*
* Do not include the decoding type in this scale. The library already
* compensates for the decoding type.
*
* Set this value based on the encoder's rated Pulses per Revolution and
* factor in gearing reductions following the encoder shaft.
*
* This distance can be in any units you like, linear or angular.
*
* @param distancePerPulse The scale factor that will be used to convert pulses
* to useful units.
*/
void Encoder::SetDistancePerPulse(double distancePerPulse) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -372,11 +148,6 @@ void Encoder::SetDistancePerPulse(double distancePerPulse) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Get the distance per pulse for this encoder.
*
* @return The scale factor that will be used to convert pulses to useful units.
*/
double Encoder::GetDistancePerPulse() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
@@ -385,14 +156,6 @@ double Encoder::GetDistancePerPulse() const {
return distancePerPulse;
}
/**
* 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 Encoder::SetReverseDirection(bool reverseDirection) {
if (StatusIsFatal()) return;
int32_t status = 0;
@@ -400,15 +163,6 @@ void Encoder::SetReverseDirection(bool reverseDirection) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(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 Encoder::SetSamplesToAverage(int samplesToAverage) {
if (samplesToAverage < 1 || samplesToAverage > 127) {
wpi_setWPIErrorWithContext(
@@ -421,15 +175,6 @@ void Encoder::SetSamplesToAverage(int samplesToAverage) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(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 The number of samples being averaged (from 1 to 127)
*/
int Encoder::GetSamplesToAverage() const {
int32_t status = 0;
int result = HAL_GetEncoderSamplesToAverage(m_encoder, &status);
@@ -437,11 +182,6 @@ int Encoder::GetSamplesToAverage() const {
return result;
}
/**
* Implement the PIDSource interface.
*
* @return The current value of the selected source parameter.
*/
double Encoder::PIDGet() {
if (StatusIsFatal()) return 0.0;
switch (GetPIDSourceType()) {
@@ -454,14 +194,6 @@ double Encoder::PIDGet() {
}
}
/**
* Set the index source for the encoder.
*
* When this source is activated, the encoder count automatically resets.
*
* @param channel A DIO channel to set as the encoder index
* @param type The state that will cause the encoder to reset
*/
void Encoder::SetIndexSource(int channel, Encoder::IndexingType type) {
// Force digital input if just given an index
m_indexSource = std::make_shared<DigitalInput>(channel);
@@ -469,14 +201,6 @@ void Encoder::SetIndexSource(int channel, Encoder::IndexingType type) {
SetIndexSource(*m_indexSource.get(), type);
}
/**
* Set the index source for the encoder.
*
* When this source is activated, the encoder count automatically resets.
*
* @param channel A digital source to set as the encoder index
* @param type The state that will cause the encoder to reset
*/
void Encoder::SetIndexSource(const DigitalSource& source,
Encoder::IndexingType type) {
int32_t status = 0;
@@ -509,3 +233,26 @@ void Encoder::InitSendable(SendableBuilder& builder) {
builder.AddDoubleProperty("Distance per Tick",
[=]() { return GetDistancePerPulse(); }, nullptr);
}
void Encoder::InitEncoder(bool reverseDirection, EncodingType encodingType) {
int32_t status = 0;
m_encoder = HAL_InitializeEncoder(
m_aSource->GetPortHandleForRouting(),
(HAL_AnalogTriggerType)m_aSource->GetAnalogTriggerTypeForRouting(),
m_bSource->GetPortHandleForRouting(),
(HAL_AnalogTriggerType)m_bSource->GetAnalogTriggerTypeForRouting(),
reverseDirection, (HAL_EncoderEncodingType)encodingType, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
HAL_Report(HALUsageReporting::kResourceType_Encoder, GetFPGAIndex(),
encodingType);
SetName("Encoder", m_aSource->GetChannel());
}
double Encoder::DecodingScaleFactor() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
double val = HAL_GetEncoderDecodingScaleFactor(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return val;
}

View File

@@ -26,29 +26,12 @@ Error ErrorBase::_globalError;
ErrorBase::ErrorBase() { HAL_Initialize(500, 0); }
/**
* @brief Retrieve the current error.
*
* Get the current error information associated with this sensor.
*/
Error& ErrorBase::GetError() { return m_error; }
const Error& ErrorBase::GetError() const { return m_error; }
/**
* @brief Clear the current error information associated with this sensor.
*/
void ErrorBase::ClearError() const { m_error.Clear(); }
/**
* @brief Set error information associated with a C library call that set an
* error to the "errno" global variable.
*
* @param contextMessage A custom message from the code that set the error.
* @param filename Filename of the error source
* @param function Function of the error source
* @param lineNumber Line number of the error source
*/
void ErrorBase::SetErrnoError(const wpi::Twine& contextMessage,
wpi::StringRef filename, wpi::StringRef function,
int lineNumber) const {
@@ -73,16 +56,6 @@ void ErrorBase::SetErrnoError(const wpi::Twine& contextMessage,
}
}
/**
* @brief Set the current error information associated from the nivision Imaq
* API.
*
* @param success The return from the function
* @param contextMessage A custom message from the code that set the error.
* @param filename Filename of the error source
* @param function Function of the error source
* @param lineNumber Line number of the error source
*/
void ErrorBase::SetImaqError(int success, const wpi::Twine& contextMessage,
wpi::StringRef filename, wpi::StringRef function,
int lineNumber) const {
@@ -100,15 +73,6 @@ void ErrorBase::SetImaqError(int success, const wpi::Twine& contextMessage,
}
}
/**
* @brief Set the current error information associated with this sensor.
*
* @param code The error code
* @param contextMessage A custom message from the code that set the error.
* @param filename Filename of the error source
* @param function Function of the error source
* @param lineNumber Line number of the error source
*/
void ErrorBase::SetError(Error::Code code, const wpi::Twine& contextMessage,
wpi::StringRef filename, wpi::StringRef function,
int lineNumber) const {
@@ -125,19 +89,6 @@ void ErrorBase::SetError(Error::Code code, const wpi::Twine& contextMessage,
}
}
/**
* @brief Set the current error information associated with this sensor.
* Range versions use for initialization code.
*
* @param code The error code
* @param minRange The minimum allowed allocation range
* @param maxRange The maximum allowed allocation range
* @param requestedValue The requested value to allocate
* @param contextMessage A custom message from the code that set the error.
* @param filename Filename of the error source
* @param function Function of the error source
* @param lineNumber Line number of the error source
*/
void ErrorBase::SetErrorRange(Error::Code code, int32_t minRange,
int32_t maxRange, int32_t requestedValue,
const wpi::Twine& contextMessage,
@@ -160,15 +111,6 @@ void ErrorBase::SetErrorRange(Error::Code code, int32_t minRange,
}
}
/**
* @brief Set the current error information associated with this sensor.
*
* @param errorMessage The error message from WPIErrors.h
* @param contextMessage A custom message from the code that set the error.
* @param filename Filename of the error source
* @param function Function of the error source
* @param lineNumber Line number of the error source
*/
void ErrorBase::SetWPIError(const wpi::Twine& errorMessage, Error::Code code,
const wpi::Twine& contextMessage,
wpi::StringRef filename, wpi::StringRef function,
@@ -188,11 +130,6 @@ void ErrorBase::CloneError(const ErrorBase& rhs) const {
m_error.Clone(rhs.GetError());
}
/**
* @brief Check if the current error code represents a fatal error.
*
* @return true if the current error is fatal.
*/
bool ErrorBase::StatusIsFatal() const { return m_error.GetCode() < 0; }
void ErrorBase::SetGlobalError(Error::Code code,
@@ -221,9 +158,6 @@ void ErrorBase::SetGlobalWPIError(const wpi::Twine& errorMessage,
lineNumber, nullptr);
}
/**
* Retrieve the current global error.
*/
Error& ErrorBase::GetGlobalError() {
std::lock_guard<wpi::mutex> mutex(_globalErrorMutex);
return _globalError;

View File

@@ -12,13 +12,6 @@
using namespace frc;
/**
* Create a linear FIR or IIR filter.
*
* @param source The PIDSource object that is used to get values
* @param ffGains The "feed forward" or FIR gains
* @param fbGains The "feed back" or IIR gains
*/
LinearDigitalFilter::LinearDigitalFilter(PIDSource& source,
wpi::ArrayRef<double> ffGains,
wpi::ArrayRef<double> fbGains)
@@ -28,13 +21,6 @@ LinearDigitalFilter::LinearDigitalFilter(PIDSource& source,
m_inputGains(ffGains),
m_outputGains(fbGains) {}
/**
* Create a linear FIR or IIR filter.
*
* @param source The PIDSource object that is used to get values
* @param ffGains The "feed forward" or FIR gains
* @param fbGains The "feed back" or IIR gains
*/
LinearDigitalFilter::LinearDigitalFilter(std::shared_ptr<PIDSource> source,
wpi::ArrayRef<double> ffGains,
wpi::ArrayRef<double> fbGains)
@@ -44,17 +30,6 @@ LinearDigitalFilter::LinearDigitalFilter(std::shared_ptr<PIDSource> source,
m_inputGains(ffGains),
m_outputGains(fbGains) {}
/**
* Creates a one-pole IIR low-pass filter of the form:<br>
* y[n] = (1 - gain) * x[n] + gain * y[n-1]<br>
* where gain = e<sup>-dt / T</sup>, T is the time constant in seconds
*
* This filter is stable for time constants greater than zero.
*
* @param source The PIDSource object that is used to get values
* @param timeConstant The discrete-time time constant in seconds
* @param period The period in seconds between samples taken by the user
*/
LinearDigitalFilter LinearDigitalFilter::SinglePoleIIR(PIDSource& source,
double timeConstant,
double period) {
@@ -62,17 +37,6 @@ LinearDigitalFilter LinearDigitalFilter::SinglePoleIIR(PIDSource& source,
return LinearDigitalFilter(source, {1.0 - gain}, {-gain});
}
/**
* Creates a first-order high-pass filter of the form:<br>
* y[n] = gain * x[n] + (-gain) * x[n-1] + gain * y[n-1]<br>
* where gain = e<sup>-dt / T</sup>, T is the time constant in seconds
*
* This filter is stable for time constants greater than zero.
*
* @param source The PIDSource object that is used to get values
* @param timeConstant The discrete-time time constant in seconds
* @param period The period in seconds between samples taken by the user
*/
LinearDigitalFilter LinearDigitalFilter::HighPass(PIDSource& source,
double timeConstant,
double period) {
@@ -80,16 +44,6 @@ LinearDigitalFilter LinearDigitalFilter::HighPass(PIDSource& source,
return LinearDigitalFilter(source, {gain, -gain}, {-gain});
}
/**
* Creates a K-tap FIR moving average filter of the form:<br>
* y[n] = 1/k * (x[k] + x[k-1] + … + x[0])
*
* This filter is always stable.
*
* @param source The PIDSource object that is used to get values
* @param taps The number of samples to average over. Higher = smoother but
* slower
*/
LinearDigitalFilter LinearDigitalFilter::MovingAverage(PIDSource& source,
int taps) {
assert(taps > 0);
@@ -98,50 +52,18 @@ LinearDigitalFilter LinearDigitalFilter::MovingAverage(PIDSource& source,
return LinearDigitalFilter(source, gains, {});
}
/**
* Creates a one-pole IIR low-pass filter of the form:<br>
* y[n] = (1 - gain) * x[n] + gain * y[n-1]<br>
* where gain = e<sup>-dt / T</sup>, T is the time constant in seconds
*
* This filter is stable for time constants greater than zero.
*
* @param source The PIDSource object that is used to get values
* @param timeConstant The discrete-time time constant in seconds
* @param period The period in seconds between samples taken by the user
*/
LinearDigitalFilter LinearDigitalFilter::SinglePoleIIR(
std::shared_ptr<PIDSource> source, double timeConstant, double period) {
double gain = std::exp(-period / timeConstant);
return LinearDigitalFilter(std::move(source), {1.0 - gain}, {-gain});
}
/**
* Creates a first-order high-pass filter of the form:<br>
* y[n] = gain * x[n] + (-gain) * x[n-1] + gain * y[n-1]<br>
* where gain = e<sup>-dt / T</sup>, T is the time constant in seconds
*
* This filter is stable for time constants greater than zero.
*
* @param source The PIDSource object that is used to get values
* @param timeConstant The discrete-time time constant in seconds
* @param period The period in seconds between samples taken by the user
*/
LinearDigitalFilter LinearDigitalFilter::HighPass(
std::shared_ptr<PIDSource> source, double timeConstant, double period) {
double gain = std::exp(-period / timeConstant);
return LinearDigitalFilter(std::move(source), {gain, -gain}, {-gain});
}
/**
* Creates a K-tap FIR moving average filter of the form:<br>
* y[n] = 1/k * (x[k] + x[k-1] + … + x[0])
*
* This filter is always stable.
*
* @param source The PIDSource object that is used to get values
* @param taps The number of samples to average over. Higher = smoother but
* slower
*/
LinearDigitalFilter LinearDigitalFilter::MovingAverage(
std::shared_ptr<PIDSource> source, int taps) {
assert(taps > 0);
@@ -169,11 +91,6 @@ void LinearDigitalFilter::Reset() {
m_outputs.reset();
}
/**
* Calculates the next value of the filter
*
* @return The filtered value at this step
*/
double LinearDigitalFilter::PIDGet() {
double retVal = 0.0;

View File

@@ -13,54 +13,17 @@ using namespace frc;
constexpr double GearTooth::kGearToothThreshold;
/**
* Common code called by the constructors.
*/
void GearTooth::EnableDirectionSensing(bool directionSensitive) {
if (directionSensitive) {
SetPulseLengthMode(kGearToothThreshold);
}
}
/**
* Construct a GearTooth sensor given a channel.
*
* @param channel The DIO channel that the sensor is connected to.
* 0-9 are on-board, 10-25 are on the MXP.
* @param directionSensitive True to enable the pulse length decoding in
* hardware to specify count direction.
*/
GearTooth::GearTooth(int channel, bool directionSensitive) : Counter(channel) {
EnableDirectionSensing(directionSensitive);
SetName("GearTooth", channel);
}
/**
* Construct a GearTooth sensor given a digital input.
*
* This should be used when sharing digital inputs.
*
* @param source A pointer to the existing DigitalSource object
* (such as a DigitalInput)
* @param directionSensitive True to enable the pulse length decoding in
* hardware to specify count direction.
*/
GearTooth::GearTooth(DigitalSource* source, bool directionSensitive)
: Counter(source) {
EnableDirectionSensing(directionSensitive);
SetName("GearTooth", source->GetChannel());
}
/**
* Construct a GearTooth sensor given a digital input.
*
* This should be used when sharing digital inputs.
*
* @param source A reference to the existing DigitalSource object
* (such as a DigitalInput)
* @param directionSensitive True to enable the pulse length decoding in
* hardware to specify count direction.
*/
GearTooth::GearTooth(std::shared_ptr<DigitalSource> source,
bool directionSensitive)
: Counter(source) {
@@ -68,6 +31,12 @@ GearTooth::GearTooth(std::shared_ptr<DigitalSource> source,
SetName("GearTooth", source->GetChannel());
}
void GearTooth::EnableDirectionSensing(bool directionSensitive) {
if (directionSensitive) {
SetPulseLengthMode(kGearToothThreshold);
}
}
void GearTooth::InitSendable(SendableBuilder& builder) {
Counter::InitSendable(builder);
builder.SetSmartDashboardType("Gear Tooth");

View File

@@ -21,125 +21,44 @@ GenericHID::GenericHID(int port) : m_ds(DriverStation::GetInstance()) {
m_port = port;
}
/**
* Get the button value (starting at button 1).
*
* The buttons are returned in a single 16 bit value with one bit representing
* the state of each button. The appropriate button is returned as a boolean
* value.
*
* @param button The button number to be read (starting at 1)
* @return The state of the button.
*/
bool GenericHID::GetRawButton(int button) const {
return m_ds.GetStickButton(m_port, button);
}
/**
* Whether the button was pressed since the last check. Button indexes begin at
* 1.
*
* @param button The button index, beginning at 1.
* @return Whether the button was pressed since the last check.
*/
bool GenericHID::GetRawButtonPressed(int button) {
return m_ds.GetStickButtonPressed(m_port, button);
}
/**
* Whether the button was released since the last check. Button indexes begin at
* 1.
*
* @param button The button index, beginning at 1.
* @return Whether the button was released since the last check.
*/
bool GenericHID::GetRawButtonReleased(int button) {
return m_ds.GetStickButtonReleased(m_port, button);
}
/**
* Get the value of the axis.
*
* @param axis The axis to read, starting at 0.
* @return The value of the axis.
*/
double GenericHID::GetRawAxis(int axis) const {
return m_ds.GetStickAxis(m_port, axis);
}
/**
* Get the angle in degrees of a POV on the HID.
*
* The POV angles start at 0 in the up direction, and increase clockwise
* (e.g. right is 90, upper-left is 315).
*
* @param pov The index of the POV to read (starting at 0)
* @return the angle of the POV in degrees, or -1 if the POV is not pressed.
*/
int GenericHID::GetPOV(int pov) const { return m_ds.GetStickPOV(m_port, pov); }
/**
* Get the number of axes for the HID.
*
* @return the number of axis for the current HID
*/
int GenericHID::GetAxisCount() const { return m_ds.GetStickAxisCount(m_port); }
/**
* Get the number of POVs for the HID.
*
* @return the number of POVs for the current HID
*/
int GenericHID::GetPOVCount() const { return m_ds.GetStickPOVCount(m_port); }
/**
* Get the number of buttons for the HID.
*
* @return the number of buttons on the current HID
*/
int GenericHID::GetButtonCount() const {
return m_ds.GetStickButtonCount(m_port);
}
/**
* Get the type of the HID.
*
* @return the type of the HID.
*/
GenericHID::HIDType GenericHID::GetType() const {
return static_cast<HIDType>(m_ds.GetJoystickType(m_port));
}
/**
* Get the name of the HID.
*
* @return the name of the HID.
*/
std::string GenericHID::GetName() const { return m_ds.GetJoystickName(m_port); }
/**
* Get the axis type of a joystick axis.
*
* @return the axis type of a joystick axis.
*/
int GenericHID::GetAxisType(int axis) const {
return m_ds.GetJoystickAxisType(m_port, axis);
}
/**
* Get the port number of the HID.
*
* @return The port number of the HID.
*/
int GenericHID::GetPort() const { return m_port; }
/**
* Set a single HID output value for the HID.
*
* @param outputNumber The index of the output to set (1-32)
* @param value The value to set the output to
*/
void GenericHID::SetOutput(int outputNumber, bool value) {
m_outputs =
(m_outputs & ~(1 << (outputNumber - 1))) | (value << (outputNumber - 1));
@@ -147,24 +66,11 @@ void GenericHID::SetOutput(int outputNumber, bool value) {
HAL_SetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
}
/**
* Set all output values for the HID.
*
* @param value The 32 bit output value (1 bit for each output)
*/
void GenericHID::SetOutputs(int value) {
m_outputs = value;
HAL_SetJoystickOutputs(m_port, m_outputs, m_leftRumble, m_rightRumble);
}
/**
* Set the rumble output for the HID.
*
* The DS currently supports 2 rumble values, left rumble and right rumble.
*
* @param type Which rumble value to set
* @param value The normalized value (0 to 1) to set the rumble to
*/
void GenericHID::SetRumble(RumbleType type, double value) {
if (value < 0)
value = 0;

View File

@@ -12,12 +12,6 @@
using namespace frc;
/**
* Get the PIDOutput for the PIDSource base object. Can be set to return
* angle or rate using SetPIDSourceType(). Defaults to angle.
*
* @return The PIDOutput (angle or rate, defaults to angle)
*/
double GyroBase::PIDGet() {
switch (GetPIDSourceType()) {
case PIDSourceType::kRate:

View File

@@ -14,12 +14,6 @@
using namespace frc;
/**
* Constructor.
*
* @param port The I2C port to which the device is connected.
* @param deviceAddress The address of the device on the I2C bus.
*/
I2C::I2C(Port port, int deviceAddress)
: m_port(static_cast<HAL_I2CPort>(port)), m_deviceAddress(deviceAddress) {
int32_t status = 0;
@@ -29,23 +23,8 @@ I2C::I2C(Port port, int deviceAddress)
HAL_Report(HALUsageReporting::kResourceType_I2C, deviceAddress);
}
/**
* Destructor.
*/
I2C::~I2C() { HAL_CloseI2C(m_port); }
/**
* Generic transaction.
*
* This is a lower-level interface to the I2C hardware giving you more control
* over each transaction.
*
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool I2C::Transaction(uint8_t* dataToSend, int sendSize, uint8_t* dataReceived,
int receiveSize) {
int32_t status = 0;
@@ -55,27 +34,8 @@ bool I2C::Transaction(uint8_t* dataToSend, int sendSize, uint8_t* dataReceived,
return status < 0;
}
/**
* Attempt to address a device on the I2C bus.
*
* This allows you to figure out if there is a device on the I2C bus that
* responds to the address specified in the constructor.
*
* @return Transfer Aborted... false for success, true for aborted.
*/
bool I2C::AddressOnly() { return Transaction(nullptr, 0, nullptr, 0); }
/**
* Execute a write transaction with the device.
*
* Write a single byte to a register on a device and wait until the
* transaction is complete.
*
* @param registerAddress The address of the register on the device to be
* written.
* @param data The byte to write to the register on the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool I2C::Write(int registerAddress, uint8_t data) {
uint8_t buffer[2];
buffer[0] = registerAddress;
@@ -85,35 +45,12 @@ bool I2C::Write(int registerAddress, uint8_t data) {
return status < 0;
}
/**
* Execute a bulk write transaction with the device.
*
* Write multiple bytes to a device and wait until the
* transaction is complete.
*
* @param data The data to write to the register on the device.
* @param count The number of bytes to be written.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool I2C::WriteBulk(uint8_t* data, int count) {
int32_t status = 0;
status = HAL_WriteI2C(m_port, m_deviceAddress, data, count);
return status < 0;
}
/**
* Execute a read transaction with the device.
*
* Read bytes from a device.
* Most I2C devices will auto-increment the register pointer internally allowing
* you to read consecutive registers on a device in a single transaction.
*
* @param registerAddress The register to read first in the transaction.
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data
* read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool I2C::Read(int registerAddress, int count, uint8_t* buffer) {
if (count < 1) {
wpi_setWPIErrorWithContext(ParameterOutOfRange, "count");
@@ -127,17 +64,6 @@ bool I2C::Read(int registerAddress, int count, uint8_t* buffer) {
return Transaction(&regAddr, sizeof(regAddr), buffer, count);
}
/**
* Execute a read only transaction with the device.
*
* Read bytes from a device. This method does not write any data to prompt the
* device.
*
* @param buffer A pointer to the array of bytes to store the data read from
* the device.
* @param count The number of bytes to read in the transaction.
* @return Transfer Aborted... false for success, true for aborted.
*/
bool I2C::ReadOnly(int count, uint8_t* buffer) {
if (count < 1) {
wpi_setWPIErrorWithContext(ParameterOutOfRange, "count");
@@ -150,21 +76,6 @@ bool I2C::ReadOnly(int count, uint8_t* buffer) {
return HAL_ReadI2C(m_port, m_deviceAddress, buffer, count) < 0;
}
/**
* Verify that a device's registers contain expected values.
*
* Most devices will have a set of registers that contain a known value that
* can be used to identify them. This allows an I2C device driver to easily
* verify that the device contains the expected value.
*
* @pre The device must support and be configured to use register
* auto-increment.
*
* @param registerAddress The base register to start reading from the device.
* @param count The size of the field to be verified.
* @param expected A buffer containing the values expected from the
* device.
*/
bool I2C::VerifySensor(int registerAddress, int count,
const uint8_t* expected) {
// TODO: Make use of all 7 read bytes

View File

@@ -14,14 +14,6 @@
using namespace frc;
/**
* Request one of the 8 interrupts asynchronously on this digital input.
*
* Request interrupts in asynchronous mode where the user's interrupt handler
* will be called when the interrupt fires. Users that want control over the
* thread priority should use the synchronous method with their own spawned
* thread. The default is interrupt on rising edges only.
*/
void InterruptableSensorBase::RequestInterrupts(
HAL_InterruptHandlerFunction handler, void* param) {
if (StatusIsFatal()) return;
@@ -40,13 +32,6 @@ void InterruptableSensorBase::RequestInterrupts(
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Request one of the 8 interrupts synchronously on this digital input.
*
* Request interrupts in synchronous mode where the user program will have to
* explicitly wait for the interrupt to occur using WaitForInterrupt.
* The default is interrupt on rising edges only.
*/
void InterruptableSensorBase::RequestInterrupts() {
if (StatusIsFatal()) return;
@@ -63,19 +48,6 @@ void InterruptableSensorBase::RequestInterrupts() {
SetUpSourceEdge(true, false);
}
void InterruptableSensorBase::AllocateInterrupts(bool watcher) {
wpi_assert(m_interrupt == HAL_kInvalidHandle);
// Expects the calling leaf class to allocate an interrupt index.
int32_t status = 0;
m_interrupt = HAL_InitializeInterrupts(watcher, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Cancel interrupts on this device.
*
* This deallocates all the chipobject structures and disables any interrupts.
*/
void InterruptableSensorBase::CancelInterrupts() {
if (StatusIsFatal()) return;
wpi_assert(m_interrupt != HAL_kInvalidHandle);
@@ -85,18 +57,6 @@ void InterruptableSensorBase::CancelInterrupts() {
m_interrupt = HAL_kInvalidHandle;
}
/**
* In synchronous mode, wait for the defined interrupt to occur.
*
* You should <b>NOT</b> attempt to read the sensor from another thread while
* waiting for an interrupt. This is not threadsafe, and can cause memory
* corruption
*
* @param timeout Timeout in seconds
* @param ignorePrevious If true, ignore interrupts that happened before
* WaitForInterrupt was called.
* @return What interrupts fired
*/
InterruptableSensorBase::WaitResult InterruptableSensorBase::WaitForInterrupt(
double timeout, bool ignorePrevious) {
if (StatusIsFatal()) return InterruptableSensorBase::kTimeout;
@@ -116,13 +76,6 @@ InterruptableSensorBase::WaitResult InterruptableSensorBase::WaitForInterrupt(
return static_cast<WaitResult>(falling | rising);
}
/**
* Enable interrupts to occur on this input.
*
* Interrupts are disabled when the RequestInterrupt call is made. This gives
* time to do the setup of the other options before starting to field
* interrupts.
*/
void InterruptableSensorBase::EnableInterrupts() {
if (StatusIsFatal()) return;
wpi_assert(m_interrupt != HAL_kInvalidHandle);
@@ -131,9 +84,6 @@ void InterruptableSensorBase::EnableInterrupts() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Disable Interrupts without without deallocating structures.
*/
void InterruptableSensorBase::DisableInterrupts() {
if (StatusIsFatal()) return;
wpi_assert(m_interrupt != HAL_kInvalidHandle);
@@ -142,15 +92,6 @@ void InterruptableSensorBase::DisableInterrupts() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Return the timestamp for the rising interrupt that occurred most recently.
*
* This is in the same time domain as GetClock().
* The rising-edge interrupt should be enabled with
* {@link #DigitalInput.SetUpSourceEdge}
*
* @return Timestamp in seconds since boot.
*/
double InterruptableSensorBase::ReadRisingTimestamp() {
if (StatusIsFatal()) return 0.0;
wpi_assert(m_interrupt != HAL_kInvalidHandle);
@@ -160,15 +101,6 @@ double InterruptableSensorBase::ReadRisingTimestamp() {
return timestamp;
}
/**
* Return the timestamp for the falling interrupt that occurred most recently.
*
* This is in the same time domain as GetClock().
* The falling-edge interrupt should be enabled with
* {@link #DigitalInput.SetUpSourceEdge}
*
* @return Timestamp in seconds since boot.
*/
double InterruptableSensorBase::ReadFallingTimestamp() {
if (StatusIsFatal()) return 0.0;
wpi_assert(m_interrupt != HAL_kInvalidHandle);
@@ -178,12 +110,6 @@ double InterruptableSensorBase::ReadFallingTimestamp() {
return timestamp;
}
/**
* Set which edge to trigger interrupts on
*
* @param risingEdge true to interrupt on rising edge
* @param fallingEdge true to interrupt on falling edge
*/
void InterruptableSensorBase::SetUpSourceEdge(bool risingEdge,
bool fallingEdge) {
if (StatusIsFatal()) return;
@@ -199,3 +125,11 @@ void InterruptableSensorBase::SetUpSourceEdge(bool risingEdge,
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
}
void InterruptableSensorBase::AllocateInterrupts(bool watcher) {
wpi_assert(m_interrupt == HAL_kInvalidHandle);
// Expects the calling leaf class to allocate an interrupt index.
int32_t status = 0;
m_interrupt = HAL_InitializeInterrupts(watcher, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}

View File

@@ -18,12 +18,6 @@ IterativeRobot::IterativeRobot() {
HALUsageReporting::kFramework_Iterative);
}
/**
* Provide an alternate "main loop" via StartCompetition().
*
* This specific StartCompetition() implements "main loop" behaviour synced with
* the DS packets.
*/
void IterativeRobot::StartCompetition() {
RobotInit();

View File

@@ -18,69 +18,26 @@
using namespace frc;
/**
* Robot-wide initialization code should go here.
*
* Users should override this method for default Robot-wide initialization which
* will be called when the robot is first powered on. It will be called exactly
* one time.
*
* Warning: the Driver Station "Robot Code" light and FMS "Robot Ready"
* indicators will be off until RobotInit() exits. Code in RobotInit() that
* waits for enable will cause the robot to never indicate that the code is
* ready, causing the robot to be bypassed in a match.
*/
void IterativeRobotBase::RobotInit() {
wpi::outs() << "Default " << __FUNCTION__ << "() method... Overload me!\n";
}
/**
* Initialization code for disabled mode should go here.
*
* Users should override this method for initialization code which will be
* called each time
* the robot enters disabled mode.
*/
void IterativeRobotBase::DisabledInit() {
wpi::outs() << "Default " << __FUNCTION__ << "() method... Overload me!\n";
}
/**
* Initialization code for autonomous mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters autonomous mode.
*/
void IterativeRobotBase::AutonomousInit() {
wpi::outs() << "Default " << __FUNCTION__ << "() method... Overload me!\n";
}
/**
* Initialization code for teleop mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters teleop mode.
*/
void IterativeRobotBase::TeleopInit() {
wpi::outs() << "Default " << __FUNCTION__ << "() method... Overload me!\n";
}
/**
* Initialization code for test mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters test mode.
*/
void IterativeRobotBase::TestInit() {
wpi::outs() << "Default " << __FUNCTION__ << "() method... Overload me!\n";
}
/**
* Periodic code for all modes should go here.
*
* This function is called each time a new packet is received from the driver
* station.
*/
void IterativeRobotBase::RobotPeriodic() {
static bool firstRun = true;
if (firstRun) {
@@ -89,13 +46,6 @@ void IterativeRobotBase::RobotPeriodic() {
}
}
/**
* Periodic code for disabled mode should go here.
*
* Users should override this method for code which will be called each time a
* new packet is received from the driver station and the robot is in disabled
* mode.
*/
void IterativeRobotBase::DisabledPeriodic() {
static bool firstRun = true;
if (firstRun) {
@@ -104,13 +54,6 @@ void IterativeRobotBase::DisabledPeriodic() {
}
}
/**
* Periodic code for autonomous mode should go here.
*
* Users should override this method for code which will be called each time a
* new packet is received from the driver station and the robot is in autonomous
* mode.
*/
void IterativeRobotBase::AutonomousPeriodic() {
static bool firstRun = true;
if (firstRun) {
@@ -119,13 +62,6 @@ void IterativeRobotBase::AutonomousPeriodic() {
}
}
/**
* Periodic code for teleop mode should go here.
*
* Users should override this method for code which will be called each time a
* new packet is received from the driver station and the robot is in teleop
* mode.
*/
void IterativeRobotBase::TeleopPeriodic() {
static bool firstRun = true;
if (firstRun) {
@@ -134,12 +70,6 @@ void IterativeRobotBase::TeleopPeriodic() {
}
}
/**
* Periodic code for test mode should go here.
*
* Users should override this method for code which will be called each time a
* new packet is received from the driver station and the robot is in test mode.
*/
void IterativeRobotBase::TestPeriodic() {
static bool firstRun = true;
if (firstRun) {

View File

@@ -11,15 +11,8 @@
using namespace frc;
/**
* Constructor for a Jaguar connected via PWM.
*
* @param channel The PWM channel that the Jaguar is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
*/
Jaguar::Jaguar(int channel) : PWMSpeedController(channel) {
/**
* Input profile defined by Luminary Micro.
/* Input profile defined by Luminary Micro.
*
* Full reverse ranges from 0.671325ms to 0.6972211ms
* Proportional reverse ranges from 0.6972211ms to 1.4482078ms

View File

@@ -18,14 +18,6 @@ using namespace frc;
constexpr double kPi = 3.14159265358979323846;
/**
* Construct an instance of a joystick.
*
* The joystick index is the USB port on the Driver Station.
*
* @param port The port on the Driver Station that the joystick is plugged into
* (0-5).
*/
Joystick::Joystick(int port) : GenericHID(port) {
m_axes[Axis::kX] = kDefaultXChannel;
m_axes[Axis::kY] = kDefaultYChannel;
@@ -36,149 +28,48 @@ Joystick::Joystick(int port) : GenericHID(port) {
HAL_Report(HALUsageReporting::kResourceType_Joystick, port);
}
/**
* Set the channel associated with a specified axis.
*
* @param axis The axis to set the channel for.
* @param channel The channel to set the axis to.
*/
void Joystick::SetAxisChannel(AxisType axis, int channel) {
m_axes[axis] = channel;
}
/**
* Set the channel associated with the X axis.
*
* @param channel The channel to set the axis to.
*/
void Joystick::SetXChannel(int channel) { m_axes[Axis::kX] = channel; }
/**
* Set the channel associated with the Y axis.
*
* @param axis The axis to set the channel for.
* @param channel The channel to set the axis to.
*/
void Joystick::SetYChannel(int channel) { m_axes[Axis::kY] = channel; }
/**
* Set the channel associated with the Z axis.
*
* @param axis The axis to set the channel for.
* @param channel The channel to set the axis to.
*/
void Joystick::SetZChannel(int channel) { m_axes[Axis::kZ] = channel; }
/**
* Set the channel associated with the twist axis.
*
* @param axis The axis to set the channel for.
* @param channel The channel to set the axis to.
*/
void Joystick::SetTwistChannel(int channel) { m_axes[Axis::kTwist] = channel; }
/**
* Set the channel associated with the throttle axis.
*
* @param axis The axis to set the channel for.
* @param channel The channel to set the axis to.
*/
void Joystick::SetThrottleChannel(int channel) {
m_axes[Axis::kThrottle] = channel;
}
/**
* Get the channel currently associated with the X axis.
*
* @return The channel for the axis.
*/
void Joystick::SetAxisChannel(AxisType axis, int channel) {
m_axes[axis] = channel;
}
int Joystick::GetXChannel() const { return m_axes[Axis::kX]; }
/**
* Get the channel currently associated with the Y axis.
*
* @return The channel for the axis.
*/
int Joystick::GetYChannel() const { return m_axes[Axis::kY]; }
/**
* Get the channel currently associated with the Z axis.
*
* @return The channel for the axis.
*/
int Joystick::GetZChannel() const { return m_axes[Axis::kZ]; }
/**
* Get the channel currently associated with the twist axis.
*
* @return The channel for the axis.
*/
int Joystick::GetTwistChannel() const { return m_axes[Axis::kTwist]; }
/**
* Get the channel currently associated with the throttle axis.
*
* @return The channel for the axis.
*/
int Joystick::GetThrottleChannel() const { return m_axes[Axis::kThrottle]; }
/**
* Get the X value of the joystick.
*
* This depends on the mapping of the joystick connected to the current port.
*
* @param hand This parameter is ignored for the Joystick class and is only
* here to complete the GenericHID interface.
*/
double Joystick::GetX(JoystickHand hand) const {
return GetRawAxis(m_axes[Axis::kX]);
}
/**
* Get the Y value of the joystick.
*
* This depends on the mapping of the joystick connected to the current port.
*
* @param hand This parameter is ignored for the Joystick class and is only
* here to complete the GenericHID interface.
*/
double Joystick::GetY(JoystickHand hand) const {
return GetRawAxis(m_axes[Axis::kY]);
}
/**
* Get the Z value of the current joystick.
*
* This depends on the mapping of the joystick connected to the current port.
*/
double Joystick::GetZ() const { return GetRawAxis(m_axes[Axis::kZ]); }
/**
* Get the twist value of the current joystick.
*
* This depends on the mapping of the joystick connected to the current port.
*/
double Joystick::GetTwist() const { return GetRawAxis(m_axes[Axis::kTwist]); }
/**
* Get the throttle value of the current joystick.
*
* This depends on the mapping of the joystick connected to the current port.
*/
double Joystick::GetThrottle() const {
return GetRawAxis(m_axes[Axis::kThrottle]);
}
/**
* For the current joystick, return the axis determined by the argument.
*
* This is for cases where the joystick axis is returned programatically,
* otherwise one of the previous functions would be preferable (for example
* GetX()).
*
* @param axis The axis to read.
* @return The value of the axis.
*/
double Joystick::GetAxis(AxisType axis) const {
switch (axis) {
case kXAxis:
@@ -197,54 +88,20 @@ double Joystick::GetAxis(AxisType axis) const {
}
}
/**
* Read the state of the trigger on the joystick.
*
* Look up which button has been assigned to the trigger and read its state.
*
* @return The state of the trigger.
*/
bool Joystick::GetTrigger() const { return GetRawButton(Button::kTrigger); }
/**
* Whether the trigger was pressed since the last check.
*
* @return Whether the button was pressed since the last check.
*/
bool Joystick::GetTriggerPressed() {
return GetRawButtonPressed(Button::kTrigger);
}
/**
* Whether the trigger was released since the last check.
*
* @return Whether the button was released since the last check.
*/
bool Joystick::GetTriggerReleased() {
return GetRawButtonReleased(Button::kTrigger);
}
/**
* Read the state of the top button on the joystick.
*
* Look up which button has been assigned to the top and read its state.
*
* @return The state of the top button.
*/
bool Joystick::GetTop() const { return GetRawButton(Button::kTop); }
/**
* Whether the top button was pressed since the last check.
*
* @return Whether the button was pressed since the last check.
*/
bool Joystick::GetTopPressed() { return GetRawButtonPressed(Button::kTop); }
/**
* Whether the top button was released since the last check.
*
* @return Whether the button was released since the last check.
*/
bool Joystick::GetTopReleased() { return GetRawButtonReleased(Button::kTop); }
Joystick* Joystick::GetStickForPort(int port) {
@@ -258,45 +115,19 @@ Joystick* Joystick::GetStickForPort(int port) {
return stick;
}
/**
* Get buttons based on an enumerated type.
*
* The button type will be looked up in the list of buttons and then read.
*
* @param button The type of button to read.
* @return The state of the button.
*/
bool Joystick::GetButton(ButtonType button) const {
int temp = button;
return GetRawButton(static_cast<Button>(temp));
}
/**
* Get the magnitude of the direction vector formed by the joystick's
* current position relative to its origin.
*
* @return The magnitude of the direction vector
*/
double Joystick::GetMagnitude() const {
return std::sqrt(std::pow(GetX(), 2) + std::pow(GetY(), 2));
}
/**
* Get the direction of the vector formed by the joystick and its origin
* in radians.
*
* @return The direction of the vector in radians
*/
double Joystick::GetDirectionRadians() const {
return std::atan2(GetX(), -GetY());
}
/**
* Get the direction of the vector formed by the joystick and its origin
* in degrees.
*
* @return The direction of the vector in degrees
*/
double Joystick::GetDirectionDegrees() const {
return (180 / kPi) * GetDirectionRadians();
}

View File

@@ -55,34 +55,122 @@ LiveWindow::Impl::Impl()
enabledEntry = statusTable->GetEntry("LW Enabled");
}
/**
* Get an instance of the LiveWindow main class.
*
* This is a singleton to guarantee that there is only a single instance
* regardless of how many times GetInstance is called.
*/
LiveWindow* LiveWindow::GetInstance() {
static LiveWindow instance;
return &instance;
}
/**
* LiveWindow constructor.
*
* Allocate the necessary tables.
*/
LiveWindow::LiveWindow() : m_impl(new Impl) {}
void LiveWindow::Run() { UpdateValues(); }
void LiveWindow::AddSensor(const wpi::Twine& subsystem, const wpi::Twine& name,
Sendable* component) {
Add(component);
component->SetName(subsystem, name);
}
void LiveWindow::AddSensor(const wpi::Twine& subsystem, const wpi::Twine& name,
Sendable& component) {
Add(&component);
component.SetName(subsystem, name);
}
void LiveWindow::AddSensor(const wpi::Twine& subsystem, const wpi::Twine& name,
std::shared_ptr<Sendable> component) {
Add(component);
component->SetName(subsystem, name);
}
void LiveWindow::AddActuator(const wpi::Twine& subsystem,
const wpi::Twine& name, Sendable* component) {
Add(component);
component->SetName(subsystem, name);
}
void LiveWindow::AddActuator(const wpi::Twine& subsystem,
const wpi::Twine& name, Sendable& component) {
Add(&component);
component.SetName(subsystem, name);
}
void LiveWindow::AddActuator(const wpi::Twine& subsystem,
const wpi::Twine& name,
std::shared_ptr<Sendable> component) {
Add(component);
component->SetName(subsystem, name);
}
void LiveWindow::AddSensor(const wpi::Twine& type, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped",
type + Twine('[') + Twine(channel) + Twine(']'));
}
void LiveWindow::AddActuator(const wpi::Twine& type, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped",
type + Twine('[') + Twine(channel) + Twine(']'));
}
void LiveWindow::AddActuator(const wpi::Twine& type, int module, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped", type + Twine('[') + Twine(module) +
Twine(',') + Twine(channel) + Twine(']'));
}
void LiveWindow::Add(std::shared_ptr<Sendable> sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto& comp = m_impl->components[sendable.get()];
comp.sendable = sendable;
}
void LiveWindow::Add(Sendable* sendable) {
Add(std::shared_ptr<Sendable>(sendable, NullDeleter<Sendable>()));
}
void LiveWindow::AddChild(Sendable* parent, std::shared_ptr<Sendable> child) {
AddChild(parent, child.get());
}
void LiveWindow::AddChild(Sendable* parent, void* child) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto& comp = m_impl->components[child];
comp.parent = parent;
comp.telemetryEnabled = false;
}
void LiveWindow::Remove(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
m_impl->components.erase(sendable);
}
void LiveWindow::EnableTelemetry(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
// Re-enable global setting in case DisableAllTelemetry() was called.
m_impl->telemetryEnabled = true;
auto i = m_impl->components.find(sendable);
if (i != m_impl->components.end()) i->getSecond().telemetryEnabled = true;
}
void LiveWindow::DisableTelemetry(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto i = m_impl->components.find(sendable);
if (i != m_impl->components.end()) i->getSecond().telemetryEnabled = false;
}
void LiveWindow::DisableAllTelemetry() {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
m_impl->telemetryEnabled = false;
for (auto& i : m_impl->components) i.getSecond().telemetryEnabled = false;
}
bool LiveWindow::IsEnabled() const {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
return m_impl->liveWindowEnabled;
}
/**
* Change the enabled status of LiveWindow.
*
* If it changes to enabled, start livewindow running otherwise stop it
*/
void LiveWindow::SetEnabled(bool enabled) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
if (m_impl->liveWindowEnabled == enabled) return;
@@ -101,214 +189,6 @@ void LiveWindow::SetEnabled(bool enabled) {
m_impl->enabledEntry.SetBoolean(enabled);
}
/**
* @name AddSensor(subsystem, name, component)
*
* Add a Sensor associated with the subsystem and call it by the given name.
*
* @param subsystem The subsystem this component is part of.
* @param name The name of this component.
* @param component A Sendable component that represents a sensor.
*/
//@{
/**
* @brief Use a STL smart pointer to share ownership of component.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddSensor(const wpi::Twine& subsystem, const wpi::Twine& name,
std::shared_ptr<Sendable> component) {
Add(component);
component->SetName(subsystem, name);
}
/**
* @brief Pass a reference to LiveWindow and retain ownership of the component.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddSensor(const wpi::Twine& subsystem, const wpi::Twine& name,
Sendable& component) {
Add(&component);
component.SetName(subsystem, name);
}
/**
* @brief Use a raw pointer to the LiveWindow.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddSensor(const wpi::Twine& subsystem, const wpi::Twine& name,
Sendable* component) {
Add(component);
component->SetName(subsystem, name);
}
//@}
/**
* @name AddActuator(subsystem, name, component)
*
* Add an Actuator associated with the subsystem and call it by the given name.
* @deprecated Use Sendable::SetName() instead.
*
* @param subsystem The subsystem this component is part of.
* @param name The name of this component.
* @param component A Sendable component that represents a actuator.
*/
//@{
/**
* @brief Use a STL smart pointer to share ownership of component.
*/
void LiveWindow::AddActuator(const wpi::Twine& subsystem,
const wpi::Twine& name,
std::shared_ptr<Sendable> component) {
Add(component);
component->SetName(subsystem, name);
}
/**
* @brief Pass a reference to LiveWindow and retain ownership of the component.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddActuator(const wpi::Twine& subsystem,
const wpi::Twine& name, Sendable& component) {
Add(&component);
component.SetName(subsystem, name);
}
/**
* @brief Use a raw pointer to the LiveWindow.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddActuator(const wpi::Twine& subsystem,
const wpi::Twine& name, Sendable* component) {
Add(component);
component->SetName(subsystem, name);
}
//@}
/**
* Meant for internal use in other WPILib classes.
* @deprecated Use SendableBase::SetName() instead.
*/
void LiveWindow::AddSensor(const wpi::Twine& type, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped",
type + Twine('[') + Twine(channel) + Twine(']'));
}
/**
* Meant for internal use in other WPILib classes.
* @deprecated Use SendableBase::SetName() instead.
*/
void LiveWindow::AddActuator(const wpi::Twine& type, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped",
type + Twine('[') + Twine(channel) + Twine(']'));
}
/**
* Meant for internal use in other WPILib classes.
* @deprecated Use SendableBase::SetName() instead.
*/
void LiveWindow::AddActuator(const wpi::Twine& type, int module, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped", type + Twine('[') + Twine(module) +
Twine(',') + Twine(channel) + Twine(']'));
}
/**
* Add a component to the LiveWindow.
*
* @param sendable component to add
*/
void LiveWindow::Add(std::shared_ptr<Sendable> sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto& comp = m_impl->components[sendable.get()];
comp.sendable = sendable;
}
/**
* Add a component to the LiveWindow.
*
* @param sendable component to add
*/
void LiveWindow::Add(Sendable* sendable) {
Add(std::shared_ptr<Sendable>(sendable, NullDeleter<Sendable>()));
}
/**
* Add a child component to a component.
*
* @param parent parent component
* @param child child component
*/
void LiveWindow::AddChild(Sendable* parent, std::shared_ptr<Sendable> child) {
AddChild(parent, child.get());
}
/**
* Add a child component to a component.
*
* @param parent parent component
* @param child child component
*/
void LiveWindow::AddChild(Sendable* parent, void* child) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto& comp = m_impl->components[child];
comp.parent = parent;
comp.telemetryEnabled = false;
}
/**
* Remove the component from the LiveWindow.
*
* @param sendable component to remove
*/
void LiveWindow::Remove(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
m_impl->components.erase(sendable);
}
/**
* Enable telemetry for a single component.
*
* @param sendable component
*/
void LiveWindow::EnableTelemetry(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
// Re-enable global setting in case DisableAllTelemetry() was called.
m_impl->telemetryEnabled = true;
auto i = m_impl->components.find(sendable);
if (i != m_impl->components.end()) i->getSecond().telemetryEnabled = true;
}
/**
* Disable telemetry for a single component.
*
* @param sendable component
*/
void LiveWindow::DisableTelemetry(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto i = m_impl->components.find(sendable);
if (i != m_impl->components.end()) i->getSecond().telemetryEnabled = false;
}
/**
* Disable ALL telemetry.
*/
void LiveWindow::DisableAllTelemetry() {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
m_impl->telemetryEnabled = false;
for (auto& i : m_impl->components) i.getSecond().telemetryEnabled = false;
}
/**
* Tell all the sensors to update (send) their values.
*
* Actuators are handled through callbacks on their value changing from the
* SmartDashboard widgets.
*/
void LiveWindow::UpdateValues() {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
// Only do this if either LiveWindow mode or telemetry is enabled.
@@ -348,3 +228,5 @@ void LiveWindow::UpdateValues() {
m_impl->startLiveWindow = false;
}
LiveWindow::LiveWindow() : m_impl(new Impl) {}

Some files were not shown because too many files have changed in this diff Show More