Add format script which invokes clang-format on the C++ source code (#41)

On Windows machines, clang-format.exe must be in the PATH environment variable.
This commit is contained in:
Tyler Veness
2016-05-20 17:30:37 -07:00
committed by Peter Johnson
parent 68690643d2
commit e14e45da76
383 changed files with 13787 additions and 13198 deletions

90
.clang-format Normal file
View File

@@ -0,0 +1,90 @@
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 8
UseTab: Never
...

View File

@@ -1,15 +1,15 @@
#pragma once
enum AccelerometerRange {
kRange_2G = 0,
kRange_4G = 1,
kRange_8G = 2,
kRange_2G = 0,
kRange_4G = 1,
kRange_8G = 2,
};
extern "C" {
void setAccelerometerActive(bool);
void setAccelerometerRange(AccelerometerRange);
double getAccelerometerX();
double getAccelerometerY();
double getAccelerometerZ();
void setAccelerometerActive(bool);
void setAccelerometerRange(AccelerometerRange);
double getAccelerometerX();
double getAccelerometerY();
double getAccelerometerZ();
}

View File

@@ -2,77 +2,85 @@
#include <stdint.h>
enum AnalogTriggerType
{
kInWindow = 0,
kState = 1,
kRisingPulse = 2,
kFallingPulse = 3
enum AnalogTriggerType {
kInWindow = 0,
kState = 1,
kRisingPulse = 2,
kFallingPulse = 3
};
extern "C"
{
// Analog output functions
void* initializeAnalogOutputPort(void* port_pointer, int32_t *status);
void freeAnalogOutputPort(void* analog_port_pointer);
void setAnalogOutput(void* analog_port_pointer, double voltage, int32_t *status);
double getAnalogOutput(void* analog_port_pointer, int32_t *status);
bool checkAnalogOutputChannel(uint32_t pin);
extern "C" {
// Analog output functions
void* initializeAnalogOutputPort(void* port_pointer, int32_t* status);
void freeAnalogOutputPort(void* analog_port_pointer);
void setAnalogOutput(void* analog_port_pointer, double voltage,
int32_t* status);
double getAnalogOutput(void* analog_port_pointer, int32_t* status);
bool checkAnalogOutputChannel(uint32_t pin);
// Analog input functions
void* initializeAnalogInputPort(void* port_pointer, int32_t *status);
void freeAnalogInputPort(void* analog_port_pointer);
bool checkAnalogModule(uint8_t module);
bool checkAnalogInputChannel(uint32_t pin);
// Analog input functions
void* initializeAnalogInputPort(void* port_pointer, int32_t* status);
void freeAnalogInputPort(void* analog_port_pointer);
bool checkAnalogModule(uint8_t module);
bool checkAnalogInputChannel(uint32_t pin);
void setAnalogSampleRate(double samplesPerSecond, int32_t *status);
float getAnalogSampleRate(int32_t *status);
void setAnalogAverageBits(void* analog_port_pointer, uint32_t bits, int32_t *status);
uint32_t getAnalogAverageBits(void* analog_port_pointer, int32_t *status);
void setAnalogOversampleBits(void* analog_port_pointer, uint32_t bits, int32_t *status);
uint32_t getAnalogOversampleBits(void* analog_port_pointer, int32_t *status);
int16_t getAnalogValue(void* analog_port_pointer, int32_t *status);
int32_t getAnalogAverageValue(void* analog_port_pointer, int32_t *status);
int32_t getAnalogVoltsToValue(void* analog_port_pointer, double voltage, int32_t *status);
float getAnalogVoltage(void* analog_port_pointer, int32_t *status);
float getAnalogAverageVoltage(void* analog_port_pointer, int32_t *status);
uint32_t getAnalogLSBWeight(void* analog_port_pointer, int32_t *status);
int32_t getAnalogOffset(void* analog_port_pointer, int32_t *status);
void setAnalogSampleRate(double samplesPerSecond, int32_t* status);
float getAnalogSampleRate(int32_t* status);
void setAnalogAverageBits(void* analog_port_pointer, uint32_t bits,
int32_t* status);
uint32_t getAnalogAverageBits(void* analog_port_pointer, int32_t* status);
void setAnalogOversampleBits(void* analog_port_pointer, uint32_t bits,
int32_t* status);
uint32_t getAnalogOversampleBits(void* analog_port_pointer, int32_t* status);
int16_t getAnalogValue(void* analog_port_pointer, int32_t* status);
int32_t getAnalogAverageValue(void* analog_port_pointer, int32_t* status);
int32_t getAnalogVoltsToValue(void* analog_port_pointer, double voltage,
int32_t* status);
float getAnalogVoltage(void* analog_port_pointer, int32_t* status);
float getAnalogAverageVoltage(void* analog_port_pointer, int32_t* status);
uint32_t getAnalogLSBWeight(void* analog_port_pointer, int32_t* status);
int32_t getAnalogOffset(void* analog_port_pointer, int32_t* status);
bool isAccumulatorChannel(void* analog_port_pointer, int32_t *status);
void initAccumulator(void* analog_port_pointer, int32_t *status);
void resetAccumulator(void* analog_port_pointer, int32_t *status);
void setAccumulatorCenter(void* analog_port_pointer, int32_t center, int32_t *status);
void setAccumulatorDeadband(void* analog_port_pointer, int32_t deadband, int32_t *status);
int64_t getAccumulatorValue(void* analog_port_pointer, int32_t *status);
uint32_t getAccumulatorCount(void* analog_port_pointer, int32_t *status);
void getAccumulatorOutput(void* analog_port_pointer, int64_t *value, uint32_t *count,
int32_t *status);
bool isAccumulatorChannel(void* analog_port_pointer, int32_t* status);
void initAccumulator(void* analog_port_pointer, int32_t* status);
void resetAccumulator(void* analog_port_pointer, int32_t* status);
void setAccumulatorCenter(void* analog_port_pointer, int32_t center,
int32_t* status);
void setAccumulatorDeadband(void* analog_port_pointer, int32_t deadband,
int32_t* status);
int64_t getAccumulatorValue(void* analog_port_pointer, int32_t* status);
uint32_t getAccumulatorCount(void* analog_port_pointer, int32_t* status);
void getAccumulatorOutput(void* analog_port_pointer, int64_t* value,
uint32_t* count, int32_t* status);
void* initializeAnalogTrigger(void* port_pointer, uint32_t *index, int32_t *status);
void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t *status);
void setAnalogTriggerLimitsRaw(void* analog_trigger_pointer, int32_t lower, int32_t upper,
int32_t *status);
void setAnalogTriggerLimitsVoltage(void* analog_trigger_pointer, double lower, double upper,
int32_t *status);
void setAnalogTriggerAveraged(void* analog_trigger_pointer, bool useAveragedValue,
int32_t *status);
void setAnalogTriggerFiltered(void* analog_trigger_pointer, bool useFilteredValue,
int32_t *status);
bool getAnalogTriggerInWindow(void* analog_trigger_pointer, int32_t *status);
bool getAnalogTriggerTriggerState(void* analog_trigger_pointer, int32_t *status);
bool getAnalogTriggerOutput(void* analog_trigger_pointer, AnalogTriggerType type,
int32_t *status);
void* initializeAnalogTrigger(void* port_pointer, uint32_t* index,
int32_t* status);
void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t* status);
void setAnalogTriggerLimitsRaw(void* analog_trigger_pointer, int32_t lower,
int32_t upper, int32_t* status);
void setAnalogTriggerLimitsVoltage(void* analog_trigger_pointer, double lower,
double upper, int32_t* status);
void setAnalogTriggerAveraged(void* analog_trigger_pointer,
bool useAveragedValue, int32_t* status);
void setAnalogTriggerFiltered(void* analog_trigger_pointer,
bool useFilteredValue, int32_t* status);
bool getAnalogTriggerInWindow(void* analog_trigger_pointer, int32_t* status);
bool getAnalogTriggerTriggerState(void* analog_trigger_pointer,
int32_t* status);
bool getAnalogTriggerOutput(void* analog_trigger_pointer,
AnalogTriggerType type, int32_t* status);
//// Float JNA Hack
// Float
int getAnalogSampleRateIntHack(int32_t *status);
int getAnalogVoltageIntHack(void* analog_port_pointer, int32_t *status);
int getAnalogAverageVoltageIntHack(void* analog_port_pointer, int32_t *status);
//// Float JNA Hack
// Float
int getAnalogSampleRateIntHack(int32_t* status);
int getAnalogVoltageIntHack(void* analog_port_pointer, int32_t* status);
int getAnalogAverageVoltageIntHack(void* analog_port_pointer, int32_t* status);
// Doubles
void setAnalogSampleRateIntHack(int samplesPerSecond, int32_t *status);
int32_t getAnalogVoltsToValueIntHack(void* analog_port_pointer, int voltage, int32_t *status);
void setAnalogTriggerLimitsVoltageIntHack(void* analog_trigger_pointer, int lower, int upper,
int32_t *status);
// Doubles
void setAnalogSampleRateIntHack(int samplesPerSecond, int32_t* status);
int32_t getAnalogVoltsToValueIntHack(void* analog_port_pointer, int voltage,
int32_t* status);
void setAnalogTriggerLimitsVoltageIntHack(void* analog_trigger_pointer,
int lower, int upper,
int32_t* status);
}

View File

@@ -3,24 +3,25 @@
#include <stdint.h>
#include "FRC_NetworkCommunication/CANSessionMux.h"
void canTxSend(uint32_t arbID, uint8_t length, int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
void canTxSend(uint32_t arbID, uint8_t length,
int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
void canTxPackInt8 (uint32_t arbID, uint8_t offset, uint8_t value);
void canTxPackInt8(uint32_t arbID, uint8_t offset, uint8_t value);
void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value);
void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value);
void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value);
void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value);
void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value);
void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value);
uint8_t canTxUnpackInt8 (uint32_t arbID, uint8_t offset);
uint8_t canTxUnpackInt8(uint32_t arbID, uint8_t offset);
uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset);
uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset);
double canTxUnpackFXP16(uint32_t arbID, uint8_t offset);
double canTxUnpackFXP32(uint32_t arbID, uint8_t offset);
double canTxUnpackFXP16(uint32_t arbID, uint8_t offset);
double canTxUnpackFXP32(uint32_t arbID, uint8_t offset);
bool canRxReceive(uint32_t arbID);
uint8_t canRxUnpackInt8 (uint32_t arbID, uint8_t offset);
uint8_t canRxUnpackInt8(uint32_t arbID, uint8_t offset);
uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset);
uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset);
double canRxUnpackFXP16(uint32_t arbID, uint8_t offset);
double canRxUnpackFXP32(uint32_t arbID, uint8_t offset);
double canRxUnpackFXP16(uint32_t arbID, uint8_t offset);
double canRxUnpackFXP32(uint32_t arbID, uint8_t offset);

View File

@@ -9,25 +9,24 @@
#define __HAL_COMPRESSOR_H__
extern "C" {
void *initializeCompressor(uint8_t module);
bool checkCompressorModule(uint8_t module);
bool getCompressor(void *pcm_pointer, int32_t *status);
void setClosedLoopControl(void *pcm_pointer, bool value, int32_t *status);
bool getClosedLoopControl(void *pcm_pointer, int32_t *status);
bool getPressureSwitch(void *pcm_pointer, int32_t *status);
float getCompressorCurrent(void *pcm_pointer, int32_t *status);
void* initializeCompressor(uint8_t module);
bool checkCompressorModule(uint8_t module);
bool getCompressorCurrentTooHighFault(void *pcm_pointer, int32_t *status);
bool getCompressorCurrentTooHighStickyFault(void *pcm_pointer, int32_t *status);
bool getCompressorShortedStickyFault(void *pcm_pointer, int32_t *status);
bool getCompressorShortedFault(void *pcm_pointer, int32_t *status);
bool getCompressorNotConnectedStickyFault(void *pcm_pointer, int32_t *status);
bool getCompressorNotConnectedFault(void *pcm_pointer, int32_t *status);
void clearAllPCMStickyFaults(void *pcm_pointer, int32_t *status);
bool getCompressor(void* pcm_pointer, int32_t* status);
void setClosedLoopControl(void* pcm_pointer, bool value, int32_t* status);
bool getClosedLoopControl(void* pcm_pointer, int32_t* status);
bool getPressureSwitch(void* pcm_pointer, int32_t* status);
float getCompressorCurrent(void* pcm_pointer, int32_t* status);
bool getCompressorCurrentTooHighFault(void* pcm_pointer, int32_t* status);
bool getCompressorCurrentTooHighStickyFault(void* pcm_pointer, int32_t* status);
bool getCompressorShortedStickyFault(void* pcm_pointer, int32_t* status);
bool getCompressorShortedFault(void* pcm_pointer, int32_t* status);
bool getCompressorNotConnectedStickyFault(void* pcm_pointer, int32_t* status);
bool getCompressorNotConnectedFault(void* pcm_pointer, int32_t* status);
void clearAllPCMStickyFaults(void* pcm_pointer, int32_t* status);
}
#endif

View File

@@ -3,137 +3,157 @@
#include "HAL/cpp/priority_mutex.h"
enum Mode
{
kTwoPulse = 0,
kSemiperiod = 1,
kPulseLength = 2,
kExternalDirection = 3
enum Mode {
kTwoPulse = 0,
kSemiperiod = 1,
kPulseLength = 2,
kExternalDirection = 3
};
priority_recursive_mutex& spiGetSemaphore(uint8_t port);
extern "C"
{
void* initializeDigitalPort(void* port_pointer, int32_t *status);
void freeDigitalPort(void* digital_port_pointer);
bool checkPWMChannel(void* digital_port_pointer);
bool checkRelayChannel(void* digital_port_pointer);
extern "C" {
void* initializeDigitalPort(void* port_pointer, int32_t* status);
void freeDigitalPort(void* digital_port_pointer);
bool checkPWMChannel(void* digital_port_pointer);
bool checkRelayChannel(void* digital_port_pointer);
void setPWM(void* digital_port_pointer, unsigned short value, int32_t *status);
bool allocatePWMChannel(void* digital_port_pointer, int32_t *status);
void freePWMChannel(void* digital_port_pointer, int32_t *status);
unsigned short getPWM(void* digital_port_pointer, int32_t *status);
void latchPWMZero(void* digital_port_pointer, int32_t *status);
void setPWMPeriodScale(void* digital_port_pointer, uint32_t squelchMask, int32_t *status);
void* allocatePWM(int32_t *status);
void freePWM(void* pwmGenerator, int32_t *status);
void setPWMRate(double rate, int32_t *status);
void setPWMDutyCycle(void* pwmGenerator, double dutyCycle, int32_t *status);
void setPWMOutputChannel(void* pwmGenerator, uint32_t pin, int32_t *status);
void setPWM(void* digital_port_pointer, unsigned short value, int32_t* status);
bool allocatePWMChannel(void* digital_port_pointer, int32_t* status);
void freePWMChannel(void* digital_port_pointer, int32_t* status);
unsigned short getPWM(void* digital_port_pointer, int32_t* status);
void latchPWMZero(void* digital_port_pointer, int32_t* status);
void setPWMPeriodScale(void* digital_port_pointer, uint32_t squelchMask,
int32_t* status);
void* allocatePWM(int32_t* status);
void freePWM(void* pwmGenerator, int32_t* status);
void setPWMRate(double rate, int32_t* status);
void setPWMDutyCycle(void* pwmGenerator, double dutyCycle, int32_t* status);
void setPWMOutputChannel(void* pwmGenerator, uint32_t pin, int32_t* status);
void setRelayForward(void* digital_port_pointer, bool on, int32_t *status);
void setRelayReverse(void* digital_port_pointer, bool on, int32_t *status);
bool getRelayForward(void* digital_port_pointer, int32_t *status);
bool getRelayReverse(void* digital_port_pointer, int32_t *status);
void setRelayForward(void* digital_port_pointer, bool on, int32_t* status);
void setRelayReverse(void* digital_port_pointer, bool on, int32_t* status);
bool getRelayForward(void* digital_port_pointer, int32_t* status);
bool getRelayReverse(void* digital_port_pointer, int32_t* status);
bool allocateDIO(void* digital_port_pointer, bool input, int32_t *status);
void freeDIO(void* digital_port_pointer, int32_t *status);
void setDIO(void* digital_port_pointer, short value, int32_t *status);
bool getDIO(void* digital_port_pointer, int32_t *status);
bool getDIODirection(void* digital_port_pointer, int32_t *status);
void pulse(void* digital_port_pointer, double pulseLength, int32_t *status);
bool isPulsing(void* digital_port_pointer, int32_t *status);
bool isAnyPulsing(int32_t *status);
bool allocateDIO(void* digital_port_pointer, bool input, int32_t* status);
void freeDIO(void* digital_port_pointer, int32_t* status);
void setDIO(void* digital_port_pointer, short value, int32_t* status);
bool getDIO(void* digital_port_pointer, int32_t* status);
bool getDIODirection(void* digital_port_pointer, int32_t* status);
void pulse(void* digital_port_pointer, double pulseLength, int32_t* status);
bool isPulsing(void* digital_port_pointer, int32_t* status);
bool isAnyPulsing(int32_t* status);
void setFilterSelect(void* digital_port_pointer, int filter_index,
void setFilterSelect(void* digital_port_pointer, int filter_index,
int32_t* status);
int getFilterSelect(void* digital_port_pointer, int32_t* status);
void setFilterPeriod(int filter_index, uint32_t value, int32_t* status);
uint32_t getFilterPeriod(int filter_index, int32_t* status);
void* initializeCounter(Mode mode, uint32_t* index, int32_t* status);
void freeCounter(void* counter_pointer, int32_t* status);
void setCounterAverageSize(void* counter_pointer, int32_t size,
int32_t* status);
void setCounterUpSource(void* counter_pointer, uint32_t pin, bool analogTrigger,
int32_t* status);
void setCounterUpSourceEdge(void* counter_pointer, bool risingEdge,
bool fallingEdge, int32_t* status);
void clearCounterUpSource(void* counter_pointer, int32_t* status);
void setCounterDownSource(void* counter_pointer, uint32_t pin,
bool analogTrigger, int32_t* status);
void setCounterDownSourceEdge(void* counter_pointer, bool risingEdge,
bool fallingEdge, int32_t* status);
void clearCounterDownSource(void* counter_pointer, int32_t* status);
void setCounterUpDownMode(void* counter_pointer, int32_t* status);
void setCounterExternalDirectionMode(void* counter_pointer, int32_t* status);
void setCounterSemiPeriodMode(void* counter_pointer, bool highSemiPeriod,
int32_t* status);
void setCounterPulseLengthMode(void* counter_pointer, double threshold,
int32_t* status);
int32_t getCounterSamplesToAverage(void* counter_pointer, int32_t* status);
void setCounterSamplesToAverage(void* counter_pointer, int samplesToAverage,
int32_t* status);
void resetCounter(void* counter_pointer, int32_t* status);
int32_t getCounter(void* counter_pointer, int32_t* status);
double getCounterPeriod(void* counter_pointer, int32_t* status);
void setCounterMaxPeriod(void* counter_pointer, double maxPeriod,
int32_t* status);
int getFilterSelect(void* digital_port_pointer, int32_t* status);
void setCounterUpdateWhenEmpty(void* counter_pointer, bool enabled,
int32_t* status);
bool getCounterStopped(void* counter_pointer, int32_t* status);
bool getCounterDirection(void* counter_pointer, int32_t* status);
void setCounterReverseDirection(void* counter_pointer, bool reverseDirection,
int32_t* status);
void setFilterPeriod(int filter_index, uint32_t value, int32_t* status);
uint32_t getFilterPeriod(int filter_index, int32_t* status);
void* initializeEncoder(uint8_t port_a_module, uint32_t port_a_pin,
bool port_a_analog_trigger, uint8_t port_b_module,
uint32_t port_b_pin, bool port_b_analog_trigger,
bool reverseDirection, int32_t* index,
int32_t* status); // TODO: fix routing
void freeEncoder(void* encoder_pointer, int32_t* status);
void resetEncoder(void* encoder_pointer, int32_t* status);
int32_t getEncoder(void* encoder_pointer, int32_t* status); // Raw value
double getEncoderPeriod(void* encoder_pointer, int32_t* status);
void setEncoderMaxPeriod(void* encoder_pointer, double maxPeriod,
int32_t* status);
bool getEncoderStopped(void* encoder_pointer, int32_t* status);
bool getEncoderDirection(void* encoder_pointer, int32_t* status);
void setEncoderReverseDirection(void* encoder_pointer, bool reverseDirection,
int32_t* status);
void setEncoderSamplesToAverage(void* encoder_pointer,
uint32_t samplesToAverage, int32_t* status);
uint32_t getEncoderSamplesToAverage(void* encoder_pointer, int32_t* status);
void setEncoderIndexSource(void* encoder_pointer, uint32_t pin,
bool analogTrigger, bool activeHigh,
bool edgeSensitive, int32_t* status);
void* initializeCounter(Mode mode, uint32_t *index, int32_t *status);
void freeCounter(void* counter_pointer, int32_t *status);
void setCounterAverageSize(void* counter_pointer, int32_t size, int32_t *status);
void setCounterUpSource(void* counter_pointer, uint32_t pin, bool analogTrigger, int32_t *status);
void setCounterUpSourceEdge(void* counter_pointer, bool risingEdge, bool fallingEdge,
int32_t *status);
void clearCounterUpSource(void* counter_pointer, int32_t *status);
void setCounterDownSource(void* counter_pointer, uint32_t pin, bool analogTrigger, int32_t *status);
void setCounterDownSourceEdge(void* counter_pointer, bool risingEdge, bool fallingEdge,
int32_t *status);
void clearCounterDownSource(void* counter_pointer, int32_t *status);
void setCounterUpDownMode(void* counter_pointer, int32_t *status);
void setCounterExternalDirectionMode(void* counter_pointer, int32_t *status);
void setCounterSemiPeriodMode(void* counter_pointer, bool highSemiPeriod, int32_t *status);
void setCounterPulseLengthMode(void* counter_pointer, double threshold, int32_t *status);
int32_t getCounterSamplesToAverage(void* counter_pointer, int32_t *status);
void setCounterSamplesToAverage(void* counter_pointer, int samplesToAverage, int32_t *status);
void resetCounter(void* counter_pointer, int32_t *status);
int32_t getCounter(void* counter_pointer, int32_t *status);
double getCounterPeriod(void* counter_pointer, int32_t *status);
void setCounterMaxPeriod(void* counter_pointer, double maxPeriod, int32_t *status);
void setCounterUpdateWhenEmpty(void* counter_pointer, bool enabled, int32_t *status);
bool getCounterStopped(void* counter_pointer, int32_t *status);
bool getCounterDirection(void* counter_pointer, int32_t *status);
void setCounterReverseDirection(void* counter_pointer, bool reverseDirection, int32_t *status);
uint16_t getLoopTiming(int32_t* status);
void* initializeEncoder(uint8_t port_a_module, uint32_t port_a_pin, bool port_a_analog_trigger,
uint8_t port_b_module, uint32_t port_b_pin, bool port_b_analog_trigger,
bool reverseDirection, int32_t *index, int32_t *status); // TODO: fix routing
void freeEncoder(void* encoder_pointer, int32_t *status);
void resetEncoder(void* encoder_pointer, int32_t *status);
int32_t getEncoder(void* encoder_pointer, int32_t *status); // Raw value
double getEncoderPeriod(void* encoder_pointer, int32_t *status);
void setEncoderMaxPeriod(void* encoder_pointer, double maxPeriod, int32_t *status);
bool getEncoderStopped(void* encoder_pointer, int32_t *status);
bool getEncoderDirection(void* encoder_pointer, int32_t *status);
void setEncoderReverseDirection(void* encoder_pointer, bool reverseDirection, int32_t *status);
void setEncoderSamplesToAverage(void* encoder_pointer, uint32_t samplesToAverage,
int32_t *status);
uint32_t getEncoderSamplesToAverage(void* encoder_pointer, int32_t *status);
void setEncoderIndexSource(void *encoder_pointer, uint32_t pin, bool analogTrigger, bool activeHigh,
bool edgeSensitive, int32_t *status);
void spiInitialize(uint8_t port, int32_t* status);
int32_t spiTransaction(uint8_t port, uint8_t* dataToSend, uint8_t* dataReceived,
uint8_t size);
int32_t spiWrite(uint8_t port, uint8_t* dataToSend, uint8_t sendSize);
int32_t spiRead(uint8_t port, uint8_t* buffer, uint8_t count);
void spiClose(uint8_t port);
void spiSetSpeed(uint8_t port, uint32_t speed);
void spiSetOpts(uint8_t port, int msb_first, int sample_on_trailing,
int clk_idle_high);
void spiSetChipSelectActiveHigh(uint8_t port, int32_t* status);
void spiSetChipSelectActiveLow(uint8_t port, int32_t* status);
int32_t spiGetHandle(uint8_t port);
void spiSetHandle(uint8_t port, int32_t handle);
uint16_t getLoopTiming(int32_t *status);
void spiInitAccumulator(uint8_t port, uint32_t period, uint32_t cmd,
uint8_t xfer_size, uint32_t valid_mask,
uint32_t valid_value, uint8_t data_shift,
uint8_t data_size, bool is_signed, bool big_endian,
int32_t* status);
void spiFreeAccumulator(uint8_t port, int32_t* status);
void spiResetAccumulator(uint8_t port, int32_t* status);
void spiSetAccumulatorCenter(uint8_t port, int32_t center, int32_t* status);
void spiSetAccumulatorDeadband(uint8_t port, int32_t deadband, int32_t* status);
int32_t spiGetAccumulatorLastValue(uint8_t port, int32_t* status);
int64_t spiGetAccumulatorValue(uint8_t port, int32_t* status);
uint32_t spiGetAccumulatorCount(uint8_t port, int32_t* status);
double spiGetAccumulatorAverage(uint8_t port, int32_t* status);
void spiGetAccumulatorOutput(uint8_t port, int64_t* value, uint32_t* count,
int32_t* status);
void spiInitialize(uint8_t port, int32_t *status);
int32_t spiTransaction(uint8_t port, uint8_t *dataToSend, uint8_t *dataReceived, uint8_t size);
int32_t spiWrite(uint8_t port, uint8_t* dataToSend, uint8_t sendSize);
int32_t spiRead(uint8_t port, uint8_t *buffer, uint8_t count);
void spiClose(uint8_t port);
void spiSetSpeed(uint8_t port, uint32_t speed);
void spiSetOpts(uint8_t port, int msb_first, int sample_on_trailing, int clk_idle_high);
void spiSetChipSelectActiveHigh(uint8_t port, int32_t *status);
void spiSetChipSelectActiveLow(uint8_t port, int32_t *status);
int32_t spiGetHandle(uint8_t port);
void spiSetHandle(uint8_t port, int32_t handle);
void i2CInitialize(uint8_t port, int32_t* status);
int32_t i2CTransaction(uint8_t port, uint8_t deviceAddress, uint8_t* dataToSend,
uint8_t sendSize, uint8_t* dataReceived,
uint8_t receiveSize);
int32_t i2CWrite(uint8_t port, uint8_t deviceAddress, uint8_t* dataToSend,
uint8_t sendSize);
int32_t i2CRead(uint8_t port, uint8_t deviceAddress, uint8_t* buffer,
uint8_t count);
void i2CClose(uint8_t port);
void spiInitAccumulator(uint8_t port, uint32_t period, uint32_t cmd,
uint8_t xfer_size, uint32_t valid_mask,
uint32_t valid_value, uint8_t data_shift,
uint8_t data_size, bool is_signed, bool big_endian,
int32_t *status);
void spiFreeAccumulator(uint8_t port, int32_t *status);
void spiResetAccumulator(uint8_t port, int32_t *status);
void spiSetAccumulatorCenter(uint8_t port, int32_t center, int32_t *status);
void spiSetAccumulatorDeadband(uint8_t port, int32_t deadband, int32_t *status);
int32_t spiGetAccumulatorLastValue(uint8_t port, int32_t *status);
int64_t spiGetAccumulatorValue(uint8_t port, int32_t *status);
uint32_t spiGetAccumulatorCount(uint8_t port, int32_t *status);
double spiGetAccumulatorAverage(uint8_t port, int32_t *status);
void spiGetAccumulatorOutput(uint8_t port, int64_t *value, uint32_t *count,
int32_t *status);
void i2CInitialize(uint8_t port, int32_t *status);
int32_t i2CTransaction(uint8_t port, uint8_t deviceAddress, uint8_t *dataToSend, uint8_t sendSize, uint8_t *dataReceived, uint8_t receiveSize);
int32_t i2CWrite(uint8_t port, uint8_t deviceAddress, uint8_t *dataToSend, uint8_t sendSize);
int32_t i2CRead(uint8_t port, uint8_t deviceAddress, uint8_t *buffer, uint8_t count);
void i2CClose(uint8_t port);
//// Float JNA Hack
// double
void setPWMRateIntHack(int rate, int32_t *status);
void setPWMDutyCycleIntHack(void* pwmGenerator, int32_t dutyCycle, int32_t *status);
//// Float JNA Hack
// double
void setPWMRateIntHack(int rate, int32_t* status);
void setPWMDutyCycleIntHack(void* pwmGenerator, int32_t dutyCycle,
int32_t* status);
}

View File

@@ -3,17 +3,20 @@
#define CTR_RxTimeout_MESSAGE "CTRE CAN Recieve Timeout"
#define CTR_TxTimeout_MESSAGE "CTRE CAN Transmit Timeout"
#define CTR_InvalidParamValue_MESSAGE "CTRE CAN Invalid Parameter"
#define CTR_UnexpectedArbId_MESSAGE "CTRE Unexpected Arbitration ID (CAN Node ID)"
#define CTR_UnexpectedArbId_MESSAGE \
"CTRE Unexpected Arbitration ID (CAN Node ID)"
#define CTR_TxFailed_MESSAGE "CTRE CAN Transmit Error"
#define CTR_SigNotUpdated_MESSAGE "CTRE CAN Signal Not Updated"
#define NiFpga_Status_FifoTimeout_MESSAGE "NIFPGA: FIFO timeout error"
#define NiFpga_Status_TransferAborted_MESSAGE "NIFPGA: Transfer aborted error"
#define NiFpga_Status_MemoryFull_MESSAGE "NIFPGA: Memory Allocation failed, memory full"
#define NiFpga_Status_MemoryFull_MESSAGE \
"NIFPGA: Memory Allocation failed, memory full"
#define NiFpga_Status_SoftwareFault_MESSAGE "NIFPGA: Unexepected software error"
#define NiFpga_Status_InvalidParameter_MESSAGE "NIFPGA: Invalid Parameter"
#define NiFpga_Status_ResourceNotFound_MESSAGE "NIFPGA: Resource not found"
#define NiFpga_Status_ResourceNotInitialized_MESSAGE "NIFPGA: Resource not initialized"
#define NiFpga_Status_ResourceNotInitialized_MESSAGE \
"NIFPGA: Resource not initialized"
#define NiFpga_Status_HardwareFault_MESSAGE "NIFPGA: Hardware Fault"
#define NiFpga_Status_IrqTimeout_MESSAGE "NIFPGA: Interrupt timeout"
@@ -21,30 +24,38 @@
#define ERR_CANSessionMux_MessageNotFound_MESSAGE "CAN: Message not found"
#define WARN_CANSessionMux_NoToken_MESSAGE "CAN: No token"
#define ERR_CANSessionMux_NotAllowed_MESSAGE "CAN: Not allowed"
#define ERR_CANSessionMux_NotInitialized_MESSAGE "CAN: Not initialized"
#define ERR_CANSessionMux_NotInitialized_MESSAGE "CAN: Not initialized"
#define SAMPLE_RATE_TOO_HIGH 1001
#define SAMPLE_RATE_TOO_HIGH_MESSAGE "HAL: Analog module sample rate is too high"
#define SAMPLE_RATE_TOO_HIGH_MESSAGE \
"HAL: Analog module sample rate is too high"
#define VOLTAGE_OUT_OF_RANGE 1002
#define VOLTAGE_OUT_OF_RANGE_MESSAGE "HAL: Voltage to convert to raw value is out of range [0; 5]"
#define VOLTAGE_OUT_OF_RANGE_MESSAGE \
"HAL: Voltage to convert to raw value is out of range [0; 5]"
#define LOOP_TIMING_ERROR 1004
#define LOOP_TIMING_ERROR_MESSAGE "HAL: Digital module loop timing is not the expected value"
#define LOOP_TIMING_ERROR_MESSAGE \
"HAL: Digital module loop timing is not the expected value"
#define SPI_WRITE_NO_MOSI 1012
#define SPI_WRITE_NO_MOSI_MESSAGE "HAL: Cannot write to SPI port with no MOSI output"
#define SPI_WRITE_NO_MOSI_MESSAGE \
"HAL: Cannot write to SPI port with no MOSI output"
#define SPI_READ_NO_MISO 1013
#define SPI_READ_NO_MISO_MESSAGE "HAL: Cannot read from SPI port with no MISO input"
#define SPI_READ_NO_MISO_MESSAGE \
"HAL: Cannot read from SPI port with no MISO input"
#define SPI_READ_NO_DATA 1014
#define SPI_READ_NO_DATA_MESSAGE "HAL: No data available to read from SPI"
#define INCOMPATIBLE_STATE 1015
#define INCOMPATIBLE_STATE_MESSAGE "HAL: Incompatible State: The operation cannot be completed"
#define INCOMPATIBLE_STATE_MESSAGE \
"HAL: Incompatible State: The operation cannot be completed"
#define NO_AVAILABLE_RESOURCES -1004
#define NO_AVAILABLE_RESOURCES_MESSAGE "HAL: No available resources to allocate"
#define NULL_PARAMETER -1005
#define NULL_PARAMETER_MESSAGE "HAL: A pointer parameter to a method is NULL"
#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR -1010
#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE "HAL: AnalogTrigger limits error. Lower limit > Upper Limit"
#define ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE \
"HAL: AnalogTrigger limits error. Lower limit > Upper Limit"
#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR -1011
#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE "HAL: Attempted to read AnalogTrigger pulse output."
#define ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE \
"HAL: Attempted to read AnalogTrigger pulse output."
#define PARAMETER_OUT_OF_RANGE -1028
#define PARAMETER_OUT_OF_RANGE_MESSAGE "HAL: A parameter is out of range."
#define RESOURCE_IS_ALLOCATED -1029
@@ -54,11 +65,11 @@
#define VI_ERROR_INV_OBJECT_MESSAGE "HAL - VISA: Invalid Object"
#define VI_ERROR_RSRC_LOCKED_MESSAGE "HAL - VISA: Resource Locked"
#define VI_ERROR_RSRC_NFOUND_MESSAGE "HAL - VISA: Resource Not Found"
#define VI_ERROR_INV_RSRC_NAME_MESSAGE "HAL - VISA: Invalid Resource Name"
#define VI_ERROR_QUEUE_OVERFLOW_MESSAGE "HAL - VISA: Queue Overflow"
#define VI_ERROR_INV_RSRC_NAME_MESSAGE "HAL - VISA: Invalid Resource Name"
#define VI_ERROR_QUEUE_OVERFLOW_MESSAGE "HAL - VISA: Queue Overflow"
#define VI_ERROR_IO_MESSAGE "HAL - VISA: General IO Error"
#define VI_ERROR_ASRL_PARITY_MESSAGE "HAL - VISA: Parity Error"
#define VI_ERROR_ASRL_FRAMING_MESSAGE "HAL - VISA: Framing Error"
#define VI_ERROR_ASRL_OVERRUN_MESSAGE "HAL - VISA: Buffer Overrun Error"
#define VI_ERROR_ASRL_OVERRUN_MESSAGE "HAL - VISA: Buffer Overrun Error"
#define VI_ERROR_RSRC_BUSY_MESSAGE "HAL - VISA: Resource Busy"
#define VI_ERROR_INV_PARAMETER_MESSAGE "HAL - VISA: Invalid Parameter"
#define VI_ERROR_INV_PARAMETER_MESSAGE "HAL - VISA: Invalid Parameter"

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2013. All Rights Reserved. */
/* Copyright (c) FIRST 2013. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
@@ -12,21 +12,22 @@
#include "Analog.hpp"
#include "Compressor.hpp"
#include "Digital.hpp"
#include "Solenoid.hpp"
#include "Notifier.hpp"
#include "Interrupts.hpp"
#include "Errors.hpp"
#include "Interrupts.hpp"
#include "Notifier.hpp"
#include "PDP.hpp"
#include "Power.hpp"
#include "SerialPort.hpp"
#include "Solenoid.hpp"
#include "Utilities.hpp"
#include "Semaphore.hpp"
#include "Task.hpp"
#include "Utilities.hpp"
#define HAL_IO_CONFIG_DATA_SIZE 32
#define HAL_SYS_STATUS_DATA_SIZE 44
#define HAL_USER_STATUS_DATA_SIZE (984 - HAL_IO_CONFIG_DATA_SIZE - HAL_SYS_STATUS_DATA_SIZE)
#define HAL_USER_STATUS_DATA_SIZE \
(984 - HAL_IO_CONFIG_DATA_SIZE - HAL_SYS_STATUS_DATA_SIZE)
#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Input 17
#define HALFRC_NetworkCommunication_DynamicType_DSEnhancedIO_Output 18
@@ -38,234 +39,225 @@
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Joystick 24
#define HALFRC_NetworkCommunication_DynamicType_Kinect_Custom 25
namespace HALUsageReporting
{
enum tResourceType
{
kResourceType_Controller,
kResourceType_Module,
kResourceType_Language,
kResourceType_CANPlugin,
kResourceType_Accelerometer,
kResourceType_ADXL345,
kResourceType_AnalogChannel,
kResourceType_AnalogTrigger,
kResourceType_AnalogTriggerOutput,
kResourceType_CANJaguar,
kResourceType_Compressor,
kResourceType_Counter,
kResourceType_Dashboard,
kResourceType_DigitalInput,
kResourceType_DigitalOutput,
kResourceType_DriverStationCIO,
kResourceType_DriverStationEIO,
kResourceType_DriverStationLCD,
kResourceType_Encoder,
kResourceType_GearTooth,
kResourceType_Gyro,
kResourceType_I2C,
kResourceType_Framework,
kResourceType_Jaguar,
kResourceType_Joystick,
kResourceType_Kinect,
kResourceType_KinectStick,
kResourceType_PIDController,
kResourceType_Preferences,
kResourceType_PWM,
kResourceType_Relay,
kResourceType_RobotDrive,
kResourceType_SerialPort,
kResourceType_Servo,
kResourceType_Solenoid,
kResourceType_SPI,
kResourceType_Task,
kResourceType_Ultrasonic,
kResourceType_Victor,
kResourceType_Button,
kResourceType_Command,
kResourceType_AxisCamera,
kResourceType_PCVideoServer,
kResourceType_SmartDashboard,
kResourceType_Talon,
kResourceType_HiTechnicColorSensor,
kResourceType_HiTechnicAccel,
kResourceType_HiTechnicCompass,
kResourceType_SRF08,
kResourceType_AnalogOutput,
kResourceType_VictorSP,
kResourceType_TalonSRX,
kResourceType_CANTalonSRX,
kResourceType_ADXL362,
kResourceType_ADXRS450,
kResourceType_RevSPARK,
kResourceType_MindsensorsSD540,
kResourceType_DigitalFilter,
};
namespace HALUsageReporting {
enum tResourceType {
kResourceType_Controller,
kResourceType_Module,
kResourceType_Language,
kResourceType_CANPlugin,
kResourceType_Accelerometer,
kResourceType_ADXL345,
kResourceType_AnalogChannel,
kResourceType_AnalogTrigger,
kResourceType_AnalogTriggerOutput,
kResourceType_CANJaguar,
kResourceType_Compressor,
kResourceType_Counter,
kResourceType_Dashboard,
kResourceType_DigitalInput,
kResourceType_DigitalOutput,
kResourceType_DriverStationCIO,
kResourceType_DriverStationEIO,
kResourceType_DriverStationLCD,
kResourceType_Encoder,
kResourceType_GearTooth,
kResourceType_Gyro,
kResourceType_I2C,
kResourceType_Framework,
kResourceType_Jaguar,
kResourceType_Joystick,
kResourceType_Kinect,
kResourceType_KinectStick,
kResourceType_PIDController,
kResourceType_Preferences,
kResourceType_PWM,
kResourceType_Relay,
kResourceType_RobotDrive,
kResourceType_SerialPort,
kResourceType_Servo,
kResourceType_Solenoid,
kResourceType_SPI,
kResourceType_Task,
kResourceType_Ultrasonic,
kResourceType_Victor,
kResourceType_Button,
kResourceType_Command,
kResourceType_AxisCamera,
kResourceType_PCVideoServer,
kResourceType_SmartDashboard,
kResourceType_Talon,
kResourceType_HiTechnicColorSensor,
kResourceType_HiTechnicAccel,
kResourceType_HiTechnicCompass,
kResourceType_SRF08,
kResourceType_AnalogOutput,
kResourceType_VictorSP,
kResourceType_TalonSRX,
kResourceType_CANTalonSRX,
kResourceType_ADXL362,
kResourceType_ADXRS450,
kResourceType_RevSPARK,
kResourceType_MindsensorsSD540,
kResourceType_DigitalFilter,
};
enum tInstances
{
kLanguage_LabVIEW = 1,
kLanguage_CPlusPlus = 2,
kLanguage_Java = 3,
kLanguage_Python = 4,
enum tInstances {
kLanguage_LabVIEW = 1,
kLanguage_CPlusPlus = 2,
kLanguage_Java = 3,
kLanguage_Python = 4,
kCANPlugin_BlackJagBridge = 1,
kCANPlugin_2CAN = 2,
kCANPlugin_BlackJagBridge = 1,
kCANPlugin_2CAN = 2,
kFramework_Iterative = 1,
kFramework_Sample = 2,
kFramework_CommandControl = 3,
kFramework_Iterative = 1,
kFramework_Sample = 2,
kFramework_CommandControl = 3,
kRobotDrive_ArcadeStandard = 1,
kRobotDrive_ArcadeButtonSpin = 2,
kRobotDrive_ArcadeRatioCurve = 3,
kRobotDrive_Tank = 4,
kRobotDrive_MecanumPolar = 5,
kRobotDrive_MecanumCartesian = 6,
kRobotDrive_ArcadeStandard = 1,
kRobotDrive_ArcadeButtonSpin = 2,
kRobotDrive_ArcadeRatioCurve = 3,
kRobotDrive_Tank = 4,
kRobotDrive_MecanumPolar = 5,
kRobotDrive_MecanumCartesian = 6,
kDriverStationCIO_Analog = 1,
kDriverStationCIO_DigitalIn = 2,
kDriverStationCIO_DigitalOut = 3,
kDriverStationCIO_Analog = 1,
kDriverStationCIO_DigitalIn = 2,
kDriverStationCIO_DigitalOut = 3,
kDriverStationEIO_Acceleration = 1,
kDriverStationEIO_AnalogIn = 2,
kDriverStationEIO_AnalogOut = 3,
kDriverStationEIO_Button = 4,
kDriverStationEIO_LED = 5,
kDriverStationEIO_DigitalIn = 6,
kDriverStationEIO_DigitalOut = 7,
kDriverStationEIO_FixedDigitalOut = 8,
kDriverStationEIO_PWM = 9,
kDriverStationEIO_Encoder = 10,
kDriverStationEIO_TouchSlider = 11,
kDriverStationEIO_Acceleration = 1,
kDriverStationEIO_AnalogIn = 2,
kDriverStationEIO_AnalogOut = 3,
kDriverStationEIO_Button = 4,
kDriverStationEIO_LED = 5,
kDriverStationEIO_DigitalIn = 6,
kDriverStationEIO_DigitalOut = 7,
kDriverStationEIO_FixedDigitalOut = 8,
kDriverStationEIO_PWM = 9,
kDriverStationEIO_Encoder = 10,
kDriverStationEIO_TouchSlider = 11,
kADXL345_SPI = 1,
kADXL345_I2C = 2,
kADXL345_SPI = 1,
kADXL345_I2C = 2,
kCommand_Scheduler = 1,
kCommand_Scheduler = 1,
kSmartDashboard_Instance = 1,
};
kSmartDashboard_Instance = 1,
};
}
struct HALControlWord {
uint32_t enabled : 1;
uint32_t autonomous : 1;
uint32_t test :1;
uint32_t eStop : 1;
uint32_t fmsAttached:1;
uint32_t dsAttached:1;
uint32_t control_reserved : 26;
uint32_t enabled : 1;
uint32_t autonomous : 1;
uint32_t test : 1;
uint32_t eStop : 1;
uint32_t fmsAttached : 1;
uint32_t dsAttached : 1;
uint32_t control_reserved : 26;
};
enum HALAllianceStationID {
kHALAllianceStationID_red1,
kHALAllianceStationID_red2,
kHALAllianceStationID_red3,
kHALAllianceStationID_blue1,
kHALAllianceStationID_blue2,
kHALAllianceStationID_blue3,
kHALAllianceStationID_red1,
kHALAllianceStationID_red2,
kHALAllianceStationID_red3,
kHALAllianceStationID_blue1,
kHALAllianceStationID_blue2,
kHALAllianceStationID_blue3,
};
/* The maximum number of axes that will be stored in a single HALJoystickAxes
struct. This is used for allocating buffers, not bounds checking, since
there are usually less axes in practice. */
* struct. This is used for allocating buffers, not bounds checking, since
* there are usually less axes in practice.
*/
static const size_t kMaxJoystickAxes = 12;
static const size_t kMaxJoystickPOVs = 12;
struct HALJoystickAxes {
uint16_t count;
int16_t axes[kMaxJoystickAxes];
uint16_t count;
int16_t axes[kMaxJoystickAxes];
};
struct HALJoystickPOVs {
uint16_t count;
int16_t povs[kMaxJoystickPOVs];
uint16_t count;
int16_t povs[kMaxJoystickPOVs];
};
struct HALJoystickButtons {
uint32_t buttons;
uint8_t count;
uint32_t buttons;
uint8_t count;
};
struct HALJoystickDescriptor {
uint8_t isXbox;
uint8_t type;
char name[256];
uint8_t axisCount;
uint8_t axisTypes[kMaxJoystickAxes];
uint8_t buttonCount;
uint8_t povCount;
uint8_t isXbox;
uint8_t type;
char name[256];
uint8_t axisCount;
uint8_t axisTypes[kMaxJoystickAxes];
uint8_t buttonCount;
uint8_t povCount;
};
inline float intToFloat(int value)
{
return (float)value;
}
inline float intToFloat(int value) { return (float)value; }
inline int floatToInt(float value)
{
return round(value);
}
inline int floatToInt(float value) { return round(value); }
extern "C"
{
extern const uint32_t dio_kNumSystems;
extern const uint32_t solenoid_kNumDO7_0Elements;
extern const uint32_t interrupt_kNumSystems;
extern const uint32_t kSystemClockTicksPerMicrosecond;
extern "C" {
extern const uint32_t dio_kNumSystems;
extern const uint32_t solenoid_kNumDO7_0Elements;
extern const uint32_t interrupt_kNumSystems;
extern const uint32_t kSystemClockTicksPerMicrosecond;
void* getPort(uint8_t pin);
void* getPortWithModule(uint8_t module, uint8_t pin);
void freePort(void* port);
const char* getHALErrorMessage(int32_t code);
void* getPort(uint8_t pin);
void* getPortWithModule(uint8_t module, uint8_t pin);
void freePort(void* port);
const char* getHALErrorMessage(int32_t code);
uint16_t getFPGAVersion(int32_t *status);
uint32_t getFPGARevision(int32_t *status);
uint64_t getFPGATime(int32_t *status);
uint16_t getFPGAVersion(int32_t* status);
uint32_t getFPGARevision(int32_t* status);
uint64_t getFPGATime(int32_t* status);
bool getFPGAButton(int32_t *status);
bool getFPGAButton(int32_t* status);
int HALSetErrorData(const char *errors, int errorsLength, int wait_ms);
int HALSendError(int isError, int32_t errorCode, int isLVCode,
const char *details, const char *location, const char *callStack,
int printMsg);
int HALSetErrorData(const char* errors, int errorsLength, int wait_ms);
int HALSendError(int isError, int32_t errorCode, int isLVCode,
const char* details, const char* location,
const char* callStack, int printMsg);
int HALGetControlWord(HALControlWord *data);
int HALGetAllianceStation(enum HALAllianceStationID *allianceStation);
int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes *axes);
int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs);
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons);
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc);
int HALGetJoystickIsXbox(uint8_t joystickNum);
int HALGetJoystickType(uint8_t joystickNum);
char* HALGetJoystickName(uint8_t joystickNum);
int HALGetJoystickAxisType(uint8_t joystickNum, uint8_t axis);
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble);
int HALGetMatchTime(float *matchTime);
int HALGetControlWord(HALControlWord* data);
int HALGetAllianceStation(enum HALAllianceStationID* allianceStation);
int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes* axes);
int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs* povs);
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons* buttons);
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor* desc);
int HALGetJoystickIsXbox(uint8_t joystickNum);
int HALGetJoystickType(uint8_t joystickNum);
char* HALGetJoystickName(uint8_t joystickNum);
int HALGetJoystickAxisType(uint8_t joystickNum, uint8_t axis);
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs,
uint16_t leftRumble, uint16_t rightRumble);
int HALGetMatchTime(float* matchTime);
void HALSetNewDataSem(MULTIWAIT_ID sem);
void HALSetNewDataSem(MULTIWAIT_ID sem);
bool HALGetSystemActive(int32_t *status);
bool HALGetBrownedOut(int32_t *status);
bool HALGetSystemActive(int32_t* status);
bool HALGetBrownedOut(int32_t* status);
int HALInitialize(int mode = 0);
void HALNetworkCommunicationObserveUserProgramStarting();
void HALNetworkCommunicationObserveUserProgramDisabled();
void HALNetworkCommunicationObserveUserProgramAutonomous();
void HALNetworkCommunicationObserveUserProgramTeleop();
void HALNetworkCommunicationObserveUserProgramTest();
int HALInitialize(int mode = 0);
void HALNetworkCommunicationObserveUserProgramStarting();
void HALNetworkCommunicationObserveUserProgramDisabled();
void HALNetworkCommunicationObserveUserProgramAutonomous();
void HALNetworkCommunicationObserveUserProgramTeleop();
void HALNetworkCommunicationObserveUserProgramTest();
uint32_t HALReport(uint8_t resource, uint8_t instanceNumber, uint8_t context = 0,
const char *feature = NULL);
uint32_t HALReport(uint8_t resource, uint8_t instanceNumber,
uint8_t context = 0, const char* feature = NULL);
}
// TODO: HACKS for now...
extern "C"
{
extern "C" {
void NumericArrayResize();
void RTSetCleanupProc();
void EDVR_CreateReference();
void Occur();
void NumericArrayResize();
void RTSetCleanupProc();
void EDVR_CreateReference();
void Occur();
}

View File

@@ -5,22 +5,26 @@
#include <iostream>
#include "errno.h"
extern "C"
{
typedef void (*InterruptHandlerFunction)(uint32_t interruptAssertedMask, void *param);
extern "C" {
typedef void (*InterruptHandlerFunction)(uint32_t interruptAssertedMask,
void* param);
void* initializeInterrupts(uint32_t interruptIndex, bool watcher, int32_t *status);
void cleanInterrupts(void* interrupt_pointer, int32_t *status);
void* initializeInterrupts(uint32_t interruptIndex, bool watcher,
int32_t* status);
void cleanInterrupts(void* interrupt_pointer, int32_t* status);
uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, bool ignorePrevious, int32_t *status);
void enableInterrupts(void* interrupt_pointer, int32_t *status);
void disableInterrupts(void* interrupt_pointer, int32_t *status);
double readRisingTimestamp(void* interrupt_pointer, int32_t *status);
double readFallingTimestamp(void* interrupt_pointer, int32_t *status);
void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, uint32_t routing_pin,
bool routing_analog_trigger, int32_t *status);
void attachInterruptHandler(void* interrupt_pointer, InterruptHandlerFunction handler,
void* param, int32_t *status);
void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge, bool fallingEdge,
int32_t *status);
uint32_t waitForInterrupt(void* interrupt_pointer, double timeout,
bool ignorePrevious, int32_t* status);
void enableInterrupts(void* interrupt_pointer, int32_t* status);
void disableInterrupts(void* interrupt_pointer, int32_t* status);
double readRisingTimestamp(void* interrupt_pointer, int32_t* status);
double readFallingTimestamp(void* interrupt_pointer, int32_t* status);
void requestInterrupts(void* interrupt_pointer, uint8_t routing_module,
uint32_t routing_pin, bool routing_analog_trigger,
int32_t* status);
void attachInterruptHandler(void* interrupt_pointer,
InterruptHandlerFunction handler, void* param,
int32_t* status);
void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge,
bool fallingEdge, int32_t* status);
}

View File

@@ -2,11 +2,12 @@
#include <stdint.h>
extern "C"
{
void* initializeNotifier(void (*process)(uint64_t, void*), void* param, int32_t *status);
void cleanNotifier(void* notifier_pointer, int32_t *status);
void* getNotifierParam(void* notifier_pointer, int32_t *status);
void updateNotifierAlarm(void* notifier_pointer, uint64_t triggerTime, int32_t *status);
void stopNotifierAlarm(void* notifier_pointer, int32_t *status);
extern "C" {
void* initializeNotifier(void (*process)(uint64_t, void*), void* param,
int32_t* status);
void cleanNotifier(void* notifier_pointer, int32_t* status);
void* getNotifierParam(void* notifier_pointer, int32_t* status);
void updateNotifierAlarm(void* notifier_pointer, uint64_t triggerTime,
int32_t* status);
void stopNotifierAlarm(void* notifier_pointer, int32_t* status);
}

View File

@@ -2,15 +2,14 @@
#include <stdint.h>
extern "C"
{
void initializePDP(uint8_t module);
double getPDPTemperature(uint8_t module, int32_t *status);
double getPDPVoltage(uint8_t module, int32_t *status);
double getPDPChannelCurrent(uint8_t module, uint8_t channel, int32_t *status);
double getPDPTotalCurrent(uint8_t module, int32_t *status);
double getPDPTotalPower(uint8_t module, int32_t *status);
double getPDPTotalEnergy(uint8_t module, int32_t *status);
void resetPDPTotalEnergy(uint8_t module, int32_t *status);
void clearPDPStickyFaults(uint8_t module, int32_t *status);
extern "C" {
void initializePDP(uint8_t module);
double getPDPTemperature(uint8_t module, int32_t* status);
double getPDPVoltage(uint8_t module, int32_t* status);
double getPDPChannelCurrent(uint8_t module, uint8_t channel, int32_t* status);
double getPDPTotalCurrent(uint8_t module, int32_t* status);
double getPDPTotalPower(uint8_t module, int32_t* status);
double getPDPTotalEnergy(uint8_t module, int32_t* status);
void resetPDPTotalEnergy(uint8_t module, int32_t* status);
void clearPDPStickyFaults(uint8_t module, int32_t* status);
}

View File

@@ -7,8 +7,7 @@
#pragma once
typedef struct port_t
{
uint8_t pin;
uint8_t module;
typedef struct port_t {
uint8_t pin;
uint8_t module;
} Port;

View File

@@ -2,20 +2,19 @@
#include <stdint.h>
extern "C"
{
float getVinVoltage(int32_t *status);
float getVinCurrent(int32_t *status);
float getUserVoltage6V(int32_t *status);
float getUserCurrent6V(int32_t *status);
bool getUserActive6V(int32_t *status);
int getUserCurrentFaults6V(int32_t *status);
float getUserVoltage5V(int32_t *status);
float getUserCurrent5V(int32_t *status);
bool getUserActive5V(int32_t *status);
int getUserCurrentFaults5V(int32_t *status);
float getUserVoltage3V3(int32_t *status);
float getUserCurrent3V3(int32_t *status);
bool getUserActive3V3(int32_t *status);
int getUserCurrentFaults3V3(int32_t *status);
extern "C" {
float getVinVoltage(int32_t* status);
float getVinCurrent(int32_t* status);
float getUserVoltage6V(int32_t* status);
float getUserCurrent6V(int32_t* status);
bool getUserActive6V(int32_t* status);
int getUserCurrentFaults6V(int32_t* status);
float getUserVoltage5V(int32_t* status);
float getUserCurrent5V(int32_t* status);
bool getUserActive5V(int32_t* status);
int getUserCurrentFaults5V(int32_t* status);
float getUserVoltage3V3(int32_t* status);
float getUserCurrent3V3(int32_t* status);
bool getUserActive3V3(int32_t* status);
int getUserCurrentFaults3V3(int32_t* status);
}

View File

@@ -8,14 +8,14 @@ typedef priority_condition_variable* MULTIWAIT_ID;
typedef priority_condition_variable::native_handle_type NATIVE_MULTIWAIT_ID;
extern "C" {
MUTEX_ID initializeMutexNormal();
void deleteMutex(MUTEX_ID sem);
void takeMutex(MUTEX_ID sem);
bool tryTakeMutex(MUTEX_ID sem);
void giveMutex(MUTEX_ID sem);
MUTEX_ID initializeMutexNormal();
void deleteMutex(MUTEX_ID sem);
void takeMutex(MUTEX_ID sem);
bool tryTakeMutex(MUTEX_ID sem);
void giveMutex(MUTEX_ID sem);
MULTIWAIT_ID initializeMultiWait();
void deleteMultiWait(MULTIWAIT_ID sem);
void takeMultiWait(MULTIWAIT_ID sem, MUTEX_ID m);
void giveMultiWait(MULTIWAIT_ID sem);
MULTIWAIT_ID initializeMultiWait();
void deleteMultiWait(MULTIWAIT_ID sem);
void takeMultiWait(MULTIWAIT_ID sem, MUTEX_ID m);
void giveMultiWait(MULTIWAIT_ID sem);
}

View File

@@ -2,24 +2,24 @@
#include <stdint.h>
extern "C"
{
void serialInitializePort(uint8_t port, int32_t *status);
void serialSetBaudRate(uint8_t port, uint32_t baud, int32_t *status);
void serialSetDataBits(uint8_t port, uint8_t bits, int32_t *status);
void serialSetParity(uint8_t port, uint8_t parity, int32_t *status);
void serialSetStopBits(uint8_t port, uint8_t stopBits, int32_t *status);
void serialSetWriteMode(uint8_t port, uint8_t mode, int32_t *status);
void serialSetFlowControl(uint8_t port, uint8_t flow, int32_t *status);
void serialSetTimeout(uint8_t port, float timeout, int32_t *status);
void serialEnableTermination(uint8_t port, char terminator, int32_t *status);
void serialDisableTermination(uint8_t port, int32_t *status);
void serialSetReadBufferSize(uint8_t port, uint32_t size, int32_t *status);
void serialSetWriteBufferSize(uint8_t port, uint32_t size, int32_t *status);
int32_t serialGetBytesReceived(uint8_t port, int32_t *status);
uint32_t serialRead(uint8_t port, char* buffer, int32_t count, int32_t *status);
uint32_t serialWrite(uint8_t port, const char *buffer, int32_t count, int32_t *status);
void serialFlush(uint8_t port, int32_t *status);
void serialClear(uint8_t port, int32_t *status);
void serialClose(uint8_t port, int32_t *status);
extern "C" {
void serialInitializePort(uint8_t port, int32_t* status);
void serialSetBaudRate(uint8_t port, uint32_t baud, int32_t* status);
void serialSetDataBits(uint8_t port, uint8_t bits, int32_t* status);
void serialSetParity(uint8_t port, uint8_t parity, int32_t* status);
void serialSetStopBits(uint8_t port, uint8_t stopBits, int32_t* status);
void serialSetWriteMode(uint8_t port, uint8_t mode, int32_t* status);
void serialSetFlowControl(uint8_t port, uint8_t flow, int32_t* status);
void serialSetTimeout(uint8_t port, float timeout, int32_t* status);
void serialEnableTermination(uint8_t port, char terminator, int32_t* status);
void serialDisableTermination(uint8_t port, int32_t* status);
void serialSetReadBufferSize(uint8_t port, uint32_t size, int32_t* status);
void serialSetWriteBufferSize(uint8_t port, uint32_t size, int32_t* status);
int32_t serialGetBytesReceived(uint8_t port, int32_t* status);
uint32_t serialRead(uint8_t port, char* buffer, int32_t count, int32_t* status);
uint32_t serialWrite(uint8_t port, const char* buffer, int32_t count,
int32_t* status);
void serialFlush(uint8_t port, int32_t* status);
void serialClear(uint8_t port, int32_t* status);
void serialClose(uint8_t port, int32_t* status);
}

View File

@@ -2,18 +2,18 @@
#include <stdint.h>
extern "C"
{
void* initializeSolenoidPort(void* port_pointer, int32_t *status);
void freeSolenoidPort(void* solenoid_port_pointer);
bool checkSolenoidModule(uint8_t module);
extern "C" {
void* initializeSolenoidPort(void* port_pointer, int32_t* status);
void freeSolenoidPort(void* solenoid_port_pointer);
bool checkSolenoidModule(uint8_t module);
bool getSolenoid(void* solenoid_port_pointer, int32_t *status);
uint8_t getAllSolenoids(void* solenoid_port_pointer, int32_t *status);
void setSolenoid(void* solenoid_port_pointer, bool value, int32_t *status);
bool getSolenoid(void* solenoid_port_pointer, int32_t* status);
uint8_t getAllSolenoids(void* solenoid_port_pointer, int32_t* status);
void setSolenoid(void* solenoid_port_pointer, bool value, int32_t* status);
int getPCMSolenoidBlackList(void* solenoid_port_pointer, int32_t *status);
bool getPCMSolenoidVoltageStickyFault(void* solenoid_port_pointer, int32_t *status);
bool getPCMSolenoidVoltageFault(void* solenoid_port_pointer, int32_t *status);
void clearAllPCMStickyFaults_sol(void *solenoid_port_pointer, int32_t *status);
int getPCMSolenoidBlackList(void* solenoid_port_pointer, int32_t* status);
bool getPCMSolenoidVoltageStickyFault(void* solenoid_port_pointer,
int32_t* status);
bool getPCMSolenoidVoltageFault(void* solenoid_port_pointer, int32_t* status);
void clearAllPCMStickyFaults_sol(void* solenoid_port_pointer, int32_t* status);
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include <stdint.h>
#include <pthread.h>
#include <stdint.h>
#ifndef _FUNCPTR_DEFINED
#define _FUNCPTR_DEFINED
@@ -9,7 +9,7 @@
typedef int (*FUNCPTR)(...);
/* ptr to function returning int */
#else
typedef int (*FUNCPTR) (); /* ptr to function returning int */
typedef int (*FUNCPTR)(); /* ptr to function returning int */
#endif /* __cplusplus */
#endif /* _FUNCPTR_DEFINED */
@@ -29,12 +29,12 @@ typedef int STATUS;
typedef pthread_t* TASK;
extern "C" {
// Note: These constants used to be declared extern and were defined in
// Task.cpp. This caused issues with the JNI bindings for java, and so the
// instantiations were moved here.
const int32_t HAL_taskLib_ILLEGAL_PRIORITY = 22; // 22 is EINVAL
// Note: These constants used to be declared extern and were defined in
// Task.cpp. This caused issues with the JNI bindings for java, and so the
// instantiations were moved here.
const int32_t HAL_taskLib_ILLEGAL_PRIORITY = 22; // 22 is EINVAL
STATUS verifyTaskID(TASK task);
STATUS setTaskPriority(TASK task, int priority); // valid priority [1..99]
STATUS getTaskPriority(TASK task, int* priority);
STATUS verifyTaskID(TASK task);
STATUS setTaskPriority(TASK task, int priority); // valid priority [1..99]
STATUS getTaskPriority(TASK task, int* priority);
}

View File

@@ -2,12 +2,11 @@
#include <stdint.h>
extern "C"
{
extern const int32_t HAL_NO_WAIT;
extern const int32_t HAL_WAIT_FOREVER;
extern "C" {
extern const int32_t HAL_NO_WAIT;
extern const int32_t HAL_WAIT_FOREVER;
void delayTicks(int32_t ticks);
void delayMillis(double ms);
void delaySeconds(double s);
void delayTicks(int32_t ticks);
void delayMillis(double ms);
void delaySeconds(double s);
}

View File

@@ -1,13 +1,14 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved. */
/* Copyright (c) FIRST 2008. All Rights Reserved.
*/
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
/*----------------------------------------------------------------------------*/
#pragma once
#include <stdint.h>
#include "../Errors.hpp"
#include "HAL/cpp/priority_mutex.h"
#include <stdint.h>
#include <vector>
@@ -24,23 +25,22 @@ namespace hal {
* resources; it just tracks which indices were marked in use by
* Allocate and not yet freed by Free.
*/
class Resource
{
public:
Resource(const Resource&) = delete;
Resource& operator=(const Resource&) = delete;
explicit Resource(uint32_t size);
virtual ~Resource() = default;
static void CreateResourceObject(Resource **r, uint32_t elements);
uint32_t Allocate(const char *resourceDesc);
uint32_t Allocate(uint32_t index, const char *resourceDesc);
void Free(uint32_t index);
class Resource {
public:
Resource(const Resource&) = delete;
Resource& operator=(const Resource&) = delete;
explicit Resource(uint32_t size);
virtual ~Resource() = default;
static void CreateResourceObject(Resource** r, uint32_t elements);
uint32_t Allocate(const char* resourceDesc);
uint32_t Allocate(uint32_t index, const char* resourceDesc);
void Free(uint32_t index);
private:
std::vector<bool> m_isAllocated;
priority_recursive_mutex m_allocateLock;
private:
std::vector<bool> m_isAllocated;
priority_recursive_mutex m_allocateLock;
static priority_recursive_mutex m_createLock;
static priority_recursive_mutex m_createLock;
};
} // namespace hal

View File

@@ -1,7 +1,7 @@
#pragma once
#include <cstdint>
#include <condition_variable>
#include <cstdint>
#include "HAL/cpp/priority_mutex.h"

View File

@@ -30,7 +30,8 @@ class priority_condition_variable {
~priority_condition_variable() = default;
priority_condition_variable(const priority_condition_variable&) = delete;
priority_condition_variable& operator=(const priority_condition_variable&) = delete;
priority_condition_variable& operator=(const priority_condition_variable&) =
delete;
void notify_one() noexcept {
std::lock_guard<std::mutex> lock(*m_mutex);
@@ -42,7 +43,7 @@ class priority_condition_variable {
m_cond.notify_all();
}
template<typename Lock>
template <typename Lock>
void wait(Lock& _lock) {
std::shared_ptr<std::mutex> _mutex = m_mutex;
std::unique_lock<std::mutex> my_lock(*_mutex);
@@ -54,14 +55,16 @@ class priority_condition_variable {
m_cond.wait(my_lock2);
}
template<typename Lock, typename Predicate>
template <typename Lock, typename Predicate>
void wait(Lock& lock, Predicate p) {
while (!p()) { wait(lock); }
while (!p()) {
wait(lock);
}
}
template<typename Lock, typename Clock, typename Duration>
std::cv_status wait_until(Lock& _lock,
const std::chrono::time_point<Clock, Duration>& atime) {
template <typename Lock, typename Clock, typename Duration>
std::cv_status wait_until(
Lock& _lock, const std::chrono::time_point<Clock, Duration>& atime) {
std::shared_ptr<std::mutex> _mutex = m_mutex;
std::unique_lock<std::mutex> my_lock(*_mutex);
Unlock<Lock> unlock(_lock);
@@ -72,9 +75,11 @@ class priority_condition_variable {
return m_cond.wait_until(my_lock2, atime);
}
template<typename Lock, typename Clock, typename Duration, typename Predicate>
template <typename Lock, typename Clock, typename Duration,
typename Predicate>
bool wait_until(Lock& lock,
const std::chrono::time_point<Clock, Duration>& atime, Predicate p) {
const std::chrono::time_point<Clock, Duration>& atime,
Predicate p) {
while (!p()) {
if (wait_until(lock, atime) == std::cv_status::timeout) {
return p();
@@ -83,35 +88,36 @@ class priority_condition_variable {
return true;
}
template<typename Lock, typename Rep, typename Period>
std::cv_status wait_for(Lock& lock, const std::chrono::duration<Rep, Period>& rtime) {
template <typename Lock, typename Rep, typename Period>
std::cv_status wait_for(Lock& lock,
const std::chrono::duration<Rep, Period>& rtime) {
return wait_until(lock, clock_t::now() + rtime);
}
template<typename Lock, typename Rep, typename Period, typename Predicate>
template <typename Lock, typename Rep, typename Period, typename Predicate>
bool wait_for(Lock& lock, const std::chrono::duration<Rep, Period>& rtime,
Predicate p) {
Predicate p) {
return wait_until(lock, clock_t::now() + rtime, std::move(p));
}
native_handle_type native_handle() {
return m_cond.native_handle();
}
native_handle_type native_handle() { return m_cond.native_handle(); }
private:
std::condition_variable m_cond;
std::shared_ptr<std::mutex> m_mutex;
// scoped unlock - unlocks in ctor, re-locks in dtor
template<typename Lock>
template <typename Lock>
struct Unlock {
explicit Unlock(Lock& lk) : m_lock(lk) { lk.unlock(); }
~Unlock() /*noexcept(false)*/ {
if (std::uncaught_exception()) {
try { m_lock.lock(); } catch(...) {}
}
else {
try {
m_lock.lock();
} catch (...) {
}
} else {
m_lock.lock();
}
}

View File

@@ -15,17 +15,17 @@
// simulator, we do not care about priority inversion.
typedef std::mutex priority_mutex;
typedef std::recursive_mutex priority_recursive_mutex;
#else // Covers rest of file.
#else // Covers rest of file.
#include <pthread.h>
class priority_recursive_mutex {
public:
typedef pthread_mutex_t *native_handle_type;
typedef pthread_mutex_t* native_handle_type;
constexpr priority_recursive_mutex() noexcept = default;
priority_recursive_mutex(const priority_recursive_mutex &) = delete;
priority_recursive_mutex &operator=(const priority_recursive_mutex &) = delete;
priority_recursive_mutex(const priority_recursive_mutex&) = delete;
priority_recursive_mutex& operator=(const priority_recursive_mutex&) = delete;
// Lock the mutex, blocking until it's available.
void lock();
@@ -36,11 +36,11 @@ class priority_recursive_mutex {
// Tries to lock the mutex.
bool try_lock() noexcept;
pthread_mutex_t *native_handle();
pthread_mutex_t* native_handle();
private:
// Do the equivalent of setting PTHREAD_PRIO_INHERIT and
// PTHREAD_MUTEX_RECURSIVE_NP.
// Do the equivalent of setting PTHREAD_PRIO_INHERIT and
// PTHREAD_MUTEX_RECURSIVE_NP.
#if __WORDSIZE == 64
pthread_mutex_t m_mutex = {
{0, 0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, 0, {0, 0}}};
@@ -52,11 +52,11 @@ class priority_recursive_mutex {
class priority_mutex {
public:
typedef pthread_mutex_t *native_handle_type;
typedef pthread_mutex_t* native_handle_type;
constexpr priority_mutex() noexcept = default;
priority_mutex(const priority_mutex &) = delete;
priority_mutex &operator=(const priority_mutex &) = delete;
priority_mutex(const priority_mutex&) = delete;
priority_mutex& operator=(const priority_mutex&) = delete;
// Lock the mutex, blocking until it's available.
void lock();
@@ -67,16 +67,14 @@ class priority_mutex {
// Tries to lock the mutex.
bool try_lock() noexcept;
pthread_mutex_t *native_handle();
pthread_mutex_t* native_handle();
private:
// Do the equivalent of setting PTHREAD_PRIO_INHERIT.
// Do the equivalent of setting PTHREAD_PRIO_INHERIT.
#if __WORDSIZE == 64
pthread_mutex_t m_mutex = {
{0, 0, 0, 0, 0x20, 0, 0, {0, 0}}};
pthread_mutex_t m_mutex = {{0, 0, 0, 0, 0x20, 0, 0, {0, 0}}};
#else
pthread_mutex_t m_mutex = {
{0, 0, 0, 0x20, 0, {0}}};
pthread_mutex_t m_mutex = {{0, 0, 0, 0x20, 0, {0}}};
#endif
};

View File

@@ -1,119 +1,118 @@
#pragma once
#include <sstream>
#include <iomanip>
#include <string>
#include <stdio.h>
#include <iomanip>
#include <sstream>
#include <string>
#ifdef _WIN32
#include <Windows.h>
#include <Windows.h>
#else
#include <sys/time.h>
#include <sys/time.h>
#endif
inline std::string NowTime();
enum TLogLevel {logNONE, logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
class Log
{
public:
Log();
virtual ~Log();
std::ostringstream& Get(TLogLevel level = logINFO);
public:
static TLogLevel& ReportingLevel();
static std::string ToString(TLogLevel level);
static TLogLevel FromString(const std::string& level);
protected:
std::ostringstream os;
private:
Log(const Log&);
Log& operator =(const Log&);
enum TLogLevel {
logNONE,
logERROR,
logWARNING,
logINFO,
logDEBUG,
logDEBUG1,
logDEBUG2,
logDEBUG3,
logDEBUG4
};
inline Log::Log()
{
class Log {
public:
Log();
virtual ~Log();
std::ostringstream& Get(TLogLevel level = logINFO);
public:
static TLogLevel& ReportingLevel();
static std::string ToString(TLogLevel level);
static TLogLevel FromString(const std::string& level);
protected:
std::ostringstream os;
private:
Log(const Log&);
Log& operator=(const Log&);
};
inline Log::Log() {}
inline std::ostringstream& Log::Get(TLogLevel level) {
os << "- " << NowTime();
os << " " << ToString(level) << ": ";
os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
return os;
}
inline std::ostringstream& Log::Get(TLogLevel level)
{
os << "- " << NowTime();
os << " " << ToString(level) << ": ";
os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
return os;
inline Log::~Log() {
os << std::endl;
fprintf(stderr, "%s", os.str().c_str());
fflush(stderr);
}
inline Log::~Log()
{
os << std::endl;
fprintf(stderr, "%s", os.str().c_str());
fflush(stderr);
inline TLogLevel& Log::ReportingLevel() {
static TLogLevel reportingLevel = logDEBUG4;
return reportingLevel;
}
inline TLogLevel& Log::ReportingLevel()
{
static TLogLevel reportingLevel = logDEBUG4;
return reportingLevel;
inline std::string Log::ToString(TLogLevel level) {
static const char* const buffer[] = {"NONE", "ERROR", "WARNING",
"INFO", "DEBUG", "DEBUG1",
"DEBUG2", "DEBUG3", "DEBUG4"};
return buffer[level];
}
inline std::string Log::ToString(TLogLevel level)
{
static const char* const buffer[] = {"NONE", "ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"};
return buffer[level];
}
inline TLogLevel Log::FromString(const std::string& level)
{
if (level == "DEBUG4")
return logDEBUG4;
if (level == "DEBUG3")
return logDEBUG3;
if (level == "DEBUG2")
return logDEBUG2;
if (level == "DEBUG1")
return logDEBUG1;
if (level == "DEBUG")
return logDEBUG;
if (level == "INFO")
return logINFO;
if (level == "WARNING")
return logWARNING;
if (level == "ERROR")
return logERROR;
if (level == "NONE")
return logNONE;
Log().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
return logINFO;
inline TLogLevel Log::FromString(const std::string& level) {
if (level == "DEBUG4") return logDEBUG4;
if (level == "DEBUG3") return logDEBUG3;
if (level == "DEBUG2") return logDEBUG2;
if (level == "DEBUG1") return logDEBUG1;
if (level == "DEBUG") return logDEBUG;
if (level == "INFO") return logINFO;
if (level == "WARNING") return logWARNING;
if (level == "ERROR") return logERROR;
if (level == "NONE") return logNONE;
Log().Get(logWARNING) << "Unknown logging level '" << level
<< "'. Using INFO level as default.";
return logINFO;
}
typedef Log FILELog;
#define FILE_LOG(level) \
if (level > FILELog::ReportingLevel()) ; \
else Log().Get(level)
#define FILE_LOG(level) \
if (level > FILELog::ReportingLevel()) \
; \
else \
Log().Get(level)
#ifdef _WIN32
inline std::string NowTime()
{
SYSTEMTIME st;
GetLocalTime(&st);
char result[100] = {0};
sprintf(result, "%d:%d:%d.%d", st.wHour , st.wMinute , st.wSecond , st.wMilliseconds);
return result;
inline std::string NowTime() {
SYSTEMTIME st;
GetLocalTime(&st);
char result[100] = {0};
sprintf(result, "%d:%d:%d.%d", st.wHour, st.wMinute, st.wSecond,
st.wMilliseconds);
return result;
}
#else
inline std::string NowTime()
{
char buffer[11];
time_t t;
time(&t);
tm * r = gmtime(&t);
strftime(buffer, sizeof(buffer), "%H:%M:%S", r);
struct timeval tv;
gettimeofday(&tv, 0);
char result[100] = {0};
sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000);
return result;
inline std::string NowTime() {
char buffer[11];
time_t t;
time(&t);
tm* r = gmtime(&t);
strftime(buffer, sizeof(buffer), "%H:%M:%S", r);
struct timeval tv;
gettimeofday(&tv, 0);
char result[100] = {0};
sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000);
return result;
}
#endif

View File

@@ -7,10 +7,10 @@
#include "HAL/Accelerometer.hpp"
#include "ChipObject.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include "ChipObject.h"
// The 7-bit I2C address with a 0 "send" bit
static const uint8_t kSendAddress = (0x1c << 1) | 0;
@@ -22,56 +22,56 @@ static const uint8_t kControlTxRx = 1;
static const uint8_t kControlStart = 2;
static const uint8_t kControlStop = 4;
static tAccel *accel = 0;
static tAccel* accel = 0;
static AccelerometerRange accelerometerRange;
// Register addresses
enum Register {
kReg_Status = 0x00,
kReg_OutXMSB = 0x01,
kReg_OutXLSB = 0x02,
kReg_OutYMSB = 0x03,
kReg_OutYLSB = 0x04,
kReg_OutZMSB = 0x05,
kReg_OutZLSB = 0x06,
kReg_Sysmod = 0x0B,
kReg_IntSource = 0x0C,
kReg_WhoAmI = 0x0D,
kReg_XYZDataCfg = 0x0E,
kReg_HPFilterCutoff = 0x0F,
kReg_PLStatus = 0x10,
kReg_PLCfg = 0x11,
kReg_PLCount = 0x12,
kReg_PLBfZcomp = 0x13,
kReg_PLThsReg = 0x14,
kReg_FFMtCfg = 0x15,
kReg_FFMtSrc = 0x16,
kReg_FFMtThs = 0x17,
kReg_FFMtCount = 0x18,
kReg_TransientCfg = 0x1D,
kReg_TransientSrc = 0x1E,
kReg_TransientThs = 0x1F,
kReg_TransientCount = 0x20,
kReg_PulseCfg = 0x21,
kReg_PulseSrc = 0x22,
kReg_PulseThsx = 0x23,
kReg_PulseThsy = 0x24,
kReg_PulseThsz = 0x25,
kReg_PulseTmlt = 0x26,
kReg_PulseLtcy = 0x27,
kReg_PulseWind = 0x28,
kReg_ASlpCount = 0x29,
kReg_CtrlReg1 = 0x2A,
kReg_CtrlReg2 = 0x2B,
kReg_CtrlReg3 = 0x2C,
kReg_CtrlReg4 = 0x2D,
kReg_CtrlReg5 = 0x2E,
kReg_OffX = 0x2F,
kReg_OffY = 0x30,
kReg_OffZ = 0x31
kReg_Status = 0x00,
kReg_OutXMSB = 0x01,
kReg_OutXLSB = 0x02,
kReg_OutYMSB = 0x03,
kReg_OutYLSB = 0x04,
kReg_OutZMSB = 0x05,
kReg_OutZLSB = 0x06,
kReg_Sysmod = 0x0B,
kReg_IntSource = 0x0C,
kReg_WhoAmI = 0x0D,
kReg_XYZDataCfg = 0x0E,
kReg_HPFilterCutoff = 0x0F,
kReg_PLStatus = 0x10,
kReg_PLCfg = 0x11,
kReg_PLCount = 0x12,
kReg_PLBfZcomp = 0x13,
kReg_PLThsReg = 0x14,
kReg_FFMtCfg = 0x15,
kReg_FFMtSrc = 0x16,
kReg_FFMtThs = 0x17,
kReg_FFMtCount = 0x18,
kReg_TransientCfg = 0x1D,
kReg_TransientSrc = 0x1E,
kReg_TransientThs = 0x1F,
kReg_TransientCount = 0x20,
kReg_PulseCfg = 0x21,
kReg_PulseSrc = 0x22,
kReg_PulseThsx = 0x23,
kReg_PulseThsy = 0x24,
kReg_PulseThsz = 0x25,
kReg_PulseTmlt = 0x26,
kReg_PulseLtcy = 0x27,
kReg_PulseWind = 0x28,
kReg_ASlpCount = 0x29,
kReg_CtrlReg1 = 0x2A,
kReg_CtrlReg2 = 0x2B,
kReg_CtrlReg3 = 0x2C,
kReg_CtrlReg4 = 0x2D,
kReg_CtrlReg5 = 0x2E,
kReg_OffX = 0x2F,
kReg_OffY = 0x30,
kReg_OffZ = 0x31
};
extern "C" uint32_t getFPGATime(int32_t *status);
extern "C" uint32_t getFPGATime(int32_t* status);
static void writeRegister(Register reg, uint8_t data);
static uint8_t readRegister(Register reg);
@@ -80,83 +80,83 @@ static uint8_t readRegister(Register reg);
* Initialize the accelerometer.
*/
static void initializeAccelerometer() {
int32_t status;
int32_t status;
if(!accel) {
accel = tAccel::create(&status);
if (!accel) {
accel = tAccel::create(&status);
// Enable I2C
accel->writeCNFG(1, &status);
// Enable I2C
accel->writeCNFG(1, &status);
// Set the counter to 100 kbps
accel->writeCNTR(213, &status);
// Set the counter to 100 kbps
accel->writeCNTR(213, &status);
// The device identification number should be 0x2a
assert(readRegister(kReg_WhoAmI) == 0x2a);
}
// The device identification number should be 0x2a
assert(readRegister(kReg_WhoAmI) == 0x2a);
}
}
static void writeRegister(Register reg, uint8_t data) {
int32_t status = 0;
uint32_t initialTime;
int32_t status = 0;
uint32_t initialTime;
accel->writeADDR(kSendAddress, &status);
accel->writeADDR(kSendAddress, &status);
// Send a start transmit/receive message with the register address
accel->writeCNTL(kControlStart | kControlTxRx, &status);
accel->writeDATO(reg, &status);
accel->strobeGO(&status);
// Send a start transmit/receive message with the register address
accel->writeCNTL(kControlStart | kControlTxRx, &status);
accel->writeDATO(reg, &status);
accel->strobeGO(&status);
// Execute and wait until it's done (up to a millisecond)
initialTime = getFPGATime(&status);
while(accel->readSTAT(&status) & 1) {
if(getFPGATime(&status) > initialTime + 1000) break;
}
// Execute and wait until it's done (up to a millisecond)
initialTime = getFPGATime(&status);
while (accel->readSTAT(&status) & 1) {
if (getFPGATime(&status) > initialTime + 1000) break;
}
// Send a stop transmit/receive message with the data
accel->writeCNTL(kControlStop | kControlTxRx, &status);
accel->writeDATO(data, &status);
accel->strobeGO(&status);
// Send a stop transmit/receive message with the data
accel->writeCNTL(kControlStop | kControlTxRx, &status);
accel->writeDATO(data, &status);
accel->strobeGO(&status);
// Execute and wait until it's done (up to a millisecond)
initialTime = getFPGATime(&status);
while(accel->readSTAT(&status) & 1) {
if(getFPGATime(&status) > initialTime + 1000) break;
}
// Execute and wait until it's done (up to a millisecond)
initialTime = getFPGATime(&status);
while (accel->readSTAT(&status) & 1) {
if (getFPGATime(&status) > initialTime + 1000) break;
}
fflush(stdout);
fflush(stdout);
}
static uint8_t readRegister(Register reg) {
int32_t status = 0;
uint32_t initialTime;
int32_t status = 0;
uint32_t initialTime;
// Send a start transmit/receive message with the register address
accel->writeADDR(kSendAddress, &status);
accel->writeCNTL(kControlStart | kControlTxRx, &status);
accel->writeDATO(reg, &status);
accel->strobeGO(&status);
// Send a start transmit/receive message with the register address
accel->writeADDR(kSendAddress, &status);
accel->writeCNTL(kControlStart | kControlTxRx, &status);
accel->writeDATO(reg, &status);
accel->strobeGO(&status);
// Execute and wait until it's done (up to a millisecond)
initialTime = getFPGATime(&status);
while(accel->readSTAT(&status) & 1) {
if(getFPGATime(&status) > initialTime + 1000) break;
}
// Execute and wait until it's done (up to a millisecond)
initialTime = getFPGATime(&status);
while (accel->readSTAT(&status) & 1) {
if (getFPGATime(&status) > initialTime + 1000) break;
}
// Receive a message with the data and stop
accel->writeADDR(kReceiveAddress, &status);
accel->writeCNTL(kControlStart | kControlStop | kControlTxRx, &status);
accel->strobeGO(&status);
// Receive a message with the data and stop
accel->writeADDR(kReceiveAddress, &status);
accel->writeCNTL(kControlStart | kControlStop | kControlTxRx, &status);
accel->strobeGO(&status);
// Execute and wait until it's done (up to a millisecond)
initialTime = getFPGATime(&status);
while(accel->readSTAT(&status) & 1) {
if(getFPGATime(&status) > initialTime + 1000) break;
}
// Execute and wait until it's done (up to a millisecond)
initialTime = getFPGATime(&status);
while (accel->readSTAT(&status) & 1) {
if (getFPGATime(&status) > initialTime + 1000) break;
}
fflush(stdout);
fflush(stdout);
return accel->readDATI(&status);
return accel->readDATI(&status);
}
/**
@@ -164,18 +164,22 @@ static uint8_t readRegister(Register reg) {
* 1 g-force, taking into account the accelerometer range.
*/
static double unpackAxis(int16_t raw) {
// The raw value is actually 12 bits, not 16, so we need to propogate the
// 2's complement sign bit to the unused 4 bits for this to work with
// negative numbers.
raw <<= 4;
raw >>= 4;
// The raw value is actually 12 bits, not 16, so we need to propogate the
// 2's complement sign bit to the unused 4 bits for this to work with
// negative numbers.
raw <<= 4;
raw >>= 4;
switch(accelerometerRange) {
case kRange_2G: return raw / 1024.0;
case kRange_4G: return raw / 512.0;
case kRange_8G: return raw / 256.0;
default: return 0.0;
}
switch (accelerometerRange) {
case kRange_2G:
return raw / 1024.0;
case kRange_4G:
return raw / 512.0;
case kRange_8G:
return raw / 256.0;
default:
return 0.0;
}
}
extern "C" {
@@ -185,11 +189,11 @@ extern "C" {
* mode to change any configuration.
*/
void setAccelerometerActive(bool active) {
initializeAccelerometer();
initializeAccelerometer();
uint8_t ctrlReg1 = readRegister(kReg_CtrlReg1);
ctrlReg1 &= ~1; // Clear the existing active bit
writeRegister(kReg_CtrlReg1, ctrlReg1 | (active? 1 : 0));
uint8_t ctrlReg1 = readRegister(kReg_CtrlReg1);
ctrlReg1 &= ~1; // Clear the existing active bit
writeRegister(kReg_CtrlReg1, ctrlReg1 | (active ? 1 : 0));
}
/**
@@ -197,13 +201,13 @@ void setAccelerometerActive(bool active) {
* The accelerometer should be in standby mode when this is called.
*/
void setAccelerometerRange(AccelerometerRange range) {
initializeAccelerometer();
initializeAccelerometer();
accelerometerRange = range;
accelerometerRange = range;
uint8_t xyzDataCfg = readRegister(kReg_XYZDataCfg);
xyzDataCfg &= ~3; // Clear the existing two range bits
writeRegister(kReg_XYZDataCfg, xyzDataCfg | range);
uint8_t xyzDataCfg = readRegister(kReg_XYZDataCfg);
xyzDataCfg &= ~3; // Clear the existing two range bits
writeRegister(kReg_XYZDataCfg, xyzDataCfg | range);
}
/**
@@ -212,10 +216,11 @@ void setAccelerometerRange(AccelerometerRange range) {
* This is a floating point value in units of 1 g-force
*/
double getAccelerometerX() {
initializeAccelerometer();
initializeAccelerometer();
int raw = (readRegister(kReg_OutXMSB) << 4) | (readRegister(kReg_OutXLSB) >> 4);
return unpackAxis(raw);
int raw =
(readRegister(kReg_OutXMSB) << 4) | (readRegister(kReg_OutXLSB) >> 4);
return unpackAxis(raw);
}
/**
@@ -224,10 +229,11 @@ double getAccelerometerX() {
* This is a floating point value in units of 1 g-force
*/
double getAccelerometerY() {
initializeAccelerometer();
initializeAccelerometer();
int raw = (readRegister(kReg_OutYMSB) << 4) | (readRegister(kReg_OutYLSB) >> 4);
return unpackAxis(raw);
int raw =
(readRegister(kReg_OutYMSB) << 4) | (readRegister(kReg_OutYLSB) >> 4);
return unpackAxis(raw);
}
/**
@@ -236,10 +242,11 @@ double getAccelerometerY() {
* This is a floating point value in units of 1 g-force
*/
double getAccelerometerZ() {
initializeAccelerometer();
initializeAccelerometer();
int raw = (readRegister(kReg_OutZMSB) << 4) | (readRegister(kReg_OutZLSB) >> 4);
return unpackAxis(raw);
int raw =
(readRegister(kReg_OutZMSB) << 4) | (readRegister(kReg_OutZLSB) >> 4);
return unpackAxis(raw);
}
} // extern "C"

View File

@@ -7,15 +7,15 @@
#include "HAL/Analog.hpp"
#include "HAL/cpp/priority_mutex.h"
#include "HAL/Port.h"
#include "HAL/HAL.hpp"
#include "ChipObject.h"
#include "HAL/cpp/Resource.hpp"
#include "FRC_NetworkCommunication/AICalibration.h"
#include "FRC_NetworkCommunication/LoadOut.h"
#include "HAL/HAL.hpp"
#include "HAL/Port.h"
#include "HAL/cpp/Resource.hpp"
#include "HAL/cpp/priority_mutex.h"
static const long kTimebase = 40000000; ///< 40 MHz clock
static const long kTimebase = 40000000; ///< 40 MHz clock
static const long kDefaultOversampleBits = 0;
static const long kDefaultAverageBits = 7;
static const float kDefaultSampleRate = 50000.0;
@@ -27,7 +27,7 @@ static const uint32_t kAccumulatorChannels[] = {0, 1};
struct AnalogPort {
Port port;
tAccumulator *accumulator;
tAccumulator* accumulator;
};
static bool analogSampleRateSet = false;
@@ -39,8 +39,8 @@ static uint32_t analogNumChannelsToActivate = 0;
extern "C" {
// Utility methods defined below.
static uint32_t getAnalogNumActiveChannels(int32_t *status);
static uint32_t getAnalogNumChannelsToActivate(int32_t *status);
static uint32_t getAnalogNumActiveChannels(int32_t* status);
static uint32_t getAnalogNumChannelsToActivate(int32_t* status);
static void setAnalogNumChannelsToActivate(uint32_t channels);
static bool analogSystemInitialized = false;
@@ -48,7 +48,7 @@ static bool analogSystemInitialized = false;
/**
* Initialize the analog System.
*/
void initializeAnalog(int32_t *status) {
void initializeAnalog(int32_t* status) {
std::lock_guard<priority_recursive_mutex> sync(analogRegisterWindowMutex);
if (analogSystemInitialized) return;
analogInputSystem = tAI::create(status);
@@ -61,16 +61,17 @@ void initializeAnalog(int32_t *status) {
/**
* Initialize the analog input port using the given port object.
*/
void* initializeAnalogInputPort(void* port_pointer, int32_t *status) {
void* initializeAnalogInputPort(void* port_pointer, int32_t* status) {
initializeAnalog(status);
Port* port = (Port*) port_pointer;
Port* port = (Port*)port_pointer;
// Initialize port structure
AnalogPort* analog_port = new AnalogPort();
analog_port->port = *port;
if (isAccumulatorChannel(analog_port, status)) {
analog_port->accumulator = tAccumulator::create(port->pin, status);
} else analog_port->accumulator = NULL;
} else
analog_port->accumulator = NULL;
// Set default configuration
analogInputSystem->writeScanList(port->pin, port->pin, status);
@@ -80,7 +81,7 @@ void* initializeAnalogInputPort(void* port_pointer, int32_t *status) {
}
void freeAnalogInputPort(void* analog_port_pointer) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
AnalogPort* port = (AnalogPort*)analog_port_pointer;
if (!port) return;
delete port->accumulator;
delete port;
@@ -89,9 +90,9 @@ void freeAnalogInputPort(void* analog_port_pointer) {
/**
* Initialize the analog output port using the given port object.
*/
void* initializeAnalogOutputPort(void* port_pointer, int32_t *status) {
void* initializeAnalogOutputPort(void* port_pointer, int32_t* status) {
initializeAnalog(status);
Port* port = (Port*) port_pointer;
Port* port = (Port*)port_pointer;
// Initialize port structure
AnalogPort* analog_port = new AnalogPort();
@@ -101,61 +102,59 @@ void* initializeAnalogOutputPort(void* port_pointer, int32_t *status) {
}
void freeAnalogOutputPort(void* analog_port_pointer) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
AnalogPort* port = (AnalogPort*)analog_port_pointer;
if (!port) return;
delete port->accumulator;
delete port;
}
/**
* Check that the analog module number is valid.
*
* @return Analog module is valid and present
*/
bool checkAnalogModule(uint8_t module) {
return module == 1;
}
bool checkAnalogModule(uint8_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.
* Verify that the analog channel number is one of the legal channel numbers.
* Channel numbers are 0-based.
*
* @return Analog channel is valid
*/
bool checkAnalogInputChannel(uint32_t pin) {
if (pin < kAnalogInputPins)
return true;
if (pin < kAnalogInputPins) return true;
return false;
}
/**
* 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.
* Verify that the analog channel number is one of the legal channel numbers.
* Channel numbers are 0-based.
*
* @return Analog channel is valid
*/
bool checkAnalogOutputChannel(uint32_t pin) {
if (pin < kAnalogOutputPins)
return true;
if (pin < kAnalogOutputPins) return true;
return false;
}
void setAnalogOutput(void* analog_port_pointer, double voltage, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
void setAnalogOutput(void* analog_port_pointer, double voltage,
int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
uint16_t rawValue = (uint16_t)(voltage / 5.0 * 0x1000);
if(voltage < 0.0) rawValue = 0;
else if(voltage > 5.0) rawValue = 0x1000;
if (voltage < 0.0)
rawValue = 0;
else if (voltage > 5.0)
rawValue = 0x1000;
analogOutputSystem->writeMXP(port->port.pin, rawValue, status);
}
double getAnalogOutput(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
double getAnalogOutput(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
uint16_t rawValue = analogOutputSystem->readMXP(port->port.pin, status);
@@ -169,22 +168,24 @@ double getAnalogOutput(void* analog_port_pointer, int32_t *status) {
*
* @param samplesPerSecond The number of samples per channel per second.
*/
void setAnalogSampleRate(double samplesPerSecond, int32_t *status) {
void setAnalogSampleRate(double samplesPerSecond, int32_t* status) {
// TODO: This will change when variable size scan lists are implemented.
// TODO: Need float comparison with epsilon.
//wpi_assert(!sampleRateSet || GetSampleRate() == samplesPerSecond);
// wpi_assert(!sampleRateSet || GetSampleRate() == samplesPerSecond);
analogSampleRateSet = true;
// Compute the convert rate
uint32_t ticksPerSample = (uint32_t)((float)kTimebase / samplesPerSecond);
uint32_t ticksPerConversion = ticksPerSample / getAnalogNumChannelsToActivate(status);
uint32_t ticksPerConversion =
ticksPerSample / getAnalogNumChannelsToActivate(status);
// ticksPerConversion must be at least 80
if (ticksPerConversion < 80) {
if ((*status) >= 0) *status = SAMPLE_RATE_TOO_HIGH;
ticksPerConversion = 80;
}
// Atomically set the scan size and the convert rate so that the sample rate is constant
// Atomically set the scan size and the convert rate so that the sample rate
// is constant
tAI::tConfig config;
config.ScanSize = getAnalogNumChannelsToActivate(status);
config.ConvertRate = ticksPerConversion;
@@ -202,38 +203,40 @@ void setAnalogSampleRate(double samplesPerSecond, int32_t *status) {
*
* @return Sample rate.
*/
float getAnalogSampleRate(int32_t *status) {
float getAnalogSampleRate(int32_t* status) {
uint32_t ticksPerConversion = analogInputSystem->readLoopTiming(status);
uint32_t ticksPerSample = ticksPerConversion * getAnalogNumActiveChannels(status);
uint32_t ticksPerSample =
ticksPerConversion * getAnalogNumActiveChannels(status);
return (float)kTimebase / (float)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.
* 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 analog_port_pointer Pointer to the analog port to configure.
* @param bits Number of bits to average.
*/
void setAnalogAverageBits(void* analog_port_pointer, uint32_t bits, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
void setAnalogAverageBits(void* analog_port_pointer, uint32_t bits,
int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
analogInputSystem->writeAverageBits(port->port.pin, bits, 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.
* 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 analog_port_pointer Pointer to the analog port to use.
* @return Bits to average.
*/
uint32_t getAnalogAverageBits(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
uint32_t getAnalogAverageBits(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
uint32_t result = analogInputSystem->readAverageBits(port->port.pin, status);
return result;
}
@@ -241,45 +244,49 @@ uint32_t getAnalogAverageBits(void* analog_port_pointer, 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.
* 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 analog_port_pointer Pointer to the analog port to use.
* @param bits Number of bits to oversample.
*/
void setAnalogOversampleBits(void* analog_port_pointer, uint32_t bits, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
void setAnalogOversampleBits(void* analog_port_pointer, uint32_t bits,
int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
analogInputSystem->writeOversampleBits(port->port.pin, 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.
* 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 analog_port_pointer Pointer to the analog port to use.
* @return Bits to oversample.
*/
uint32_t getAnalogOversampleBits(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
uint32_t result = analogInputSystem->readOversampleBits(port->port.pin, status);
uint32_t getAnalogOversampleBits(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
uint32_t result =
analogInputSystem->readOversampleBits(port->port.pin, status);
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.
* 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 analog_port_pointer Pointer to the analog port to use.
* @return A sample straight from the channel on this module.
*/
int16_t getAnalogValue(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
int16_t getAnalogValue(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
int16_t value;
if (!checkAnalogInputChannel(port->port.pin)) {
return 0;
@@ -293,26 +300,28 @@ int16_t getAnalogValue(void* analog_port_pointer, int32_t *status) {
std::lock_guard<priority_recursive_mutex> sync(analogRegisterWindowMutex);
analogInputSystem->writeReadSelect(readSelect, status);
analogInputSystem->strobeLatchOutput(status);
value = (int16_t) analogInputSystem->readOutput(status);
value = (int16_t)analogInputSystem->readOutput(status);
}
return value;
}
/**
* Get a sample from the output of the oversample and average engine for the channel.
* 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.
* 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 analog_port_pointer Pointer to the analog port to use.
* @return A sample from the oversample and average engine for the channel.
*/
int32_t getAnalogAverageValue(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
int32_t getAnalogAverageValue(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
int32_t value;
if (!checkAnalogInputChannel(port->port.pin)) {
return 0;
@@ -326,7 +335,7 @@ int32_t getAnalogAverageValue(void* analog_port_pointer, int32_t *status) {
std::lock_guard<priority_recursive_mutex> sync(analogRegisterWindowMutex);
analogInputSystem->writeReadSelect(readSelect, status);
analogInputSystem->strobeLatchOutput(status);
value = (int32_t) analogInputSystem->readOutput(status);
value = (int32_t)analogInputSystem->readOutput(status);
}
return value;
@@ -335,12 +344,13 @@ int32_t getAnalogAverageValue(void* analog_port_pointer, 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().
* The value is scaled to units of Volts using the calibrated scaling data from
* GetLSBWeight() and GetOffset().
*
* @param analog_port_pointer Pointer to the analog port to use.
* @return A scaled sample straight from the channel on this module.
*/
float getAnalogVoltage(void* analog_port_pointer, int32_t *status) {
float getAnalogVoltage(void* analog_port_pointer, int32_t* status) {
int16_t value = getAnalogValue(analog_port_pointer, status);
uint32_t LSBWeight = getAnalogLSBWeight(analog_port_pointer, status);
int32_t offset = getAnalogOffset(analog_port_pointer, status);
@@ -349,21 +359,27 @@ float getAnalogVoltage(void* analog_port_pointer, int32_t *status) {
}
/**
* Get a scaled sample from the output of the oversample and average engine for the channel.
* 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.
* 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 analog_port_pointer Pointer to the analog port to use.
* @return A scaled sample from the output of the oversample and average engine for the channel.
* @return A scaled sample from the output of the oversample and average engine
* for the channel.
*/
float getAnalogAverageVoltage(void* analog_port_pointer, int32_t *status) {
float getAnalogAverageVoltage(void* analog_port_pointer, int32_t* status) {
int32_t value = getAnalogAverageValue(analog_port_pointer, status);
uint32_t LSBWeight = getAnalogLSBWeight(analog_port_pointer, status);
int32_t offset = getAnalogOffset(analog_port_pointer, status);
uint32_t oversampleBits = getAnalogOversampleBits(analog_port_pointer, status);
float voltage = ((LSBWeight * 1.0e-9 * value) / (float)(1 << oversampleBits)) - offset * 1.0e-9;
uint32_t oversampleBits =
getAnalogOversampleBits(analog_port_pointer, status);
float voltage =
((LSBWeight * 1.0e-9 * value) / (float)(1 << oversampleBits)) -
offset * 1.0e-9;
return voltage;
}
@@ -379,7 +395,8 @@ float getAnalogAverageVoltage(void* analog_port_pointer, int32_t *status) {
* @param voltage The voltage to convert.
* @return The raw value for the channel.
*/
int32_t getAnalogVoltsToValue(void* analog_port_pointer, double voltage, int32_t *status) {
int32_t getAnalogVoltsToValue(void* analog_port_pointer, double voltage,
int32_t* status) {
if (voltage > 5.0) {
voltage = 5.0;
*status = VOLTAGE_OUT_OF_RANGE;
@@ -390,52 +407,52 @@ int32_t getAnalogVoltsToValue(void* analog_port_pointer, double voltage, int32_t
}
uint32_t LSBWeight = getAnalogLSBWeight(analog_port_pointer, status);
int32_t offset = getAnalogOffset(analog_port_pointer, status);
int32_t value = (int32_t) ((voltage + offset * 1.0e-9) / (LSBWeight * 1.0e-9));
int32_t value = (int32_t)((voltage + offset * 1.0e-9) / (LSBWeight * 1.0e-9));
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.
* 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 analog_port_pointer Pointer to the analog port to use.
* @return Least significant bit weight.
*/
uint32_t getAnalogLSBWeight(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
uint32_t lsbWeight = FRC_NetworkCommunication_nAICalibration_getLSBWeight(0, port->port.pin, status); // XXX: aiSystemIndex == 0?
uint32_t getAnalogLSBWeight(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
uint32_t lsbWeight = FRC_NetworkCommunication_nAICalibration_getLSBWeight(
0, port->port.pin, status); // XXX: aiSystemIndex == 0?
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.
* 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 analog_port_pointer Pointer to the analog port to use.
* @return Offset constant.
*/
int32_t getAnalogOffset(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
int32_t offset = FRC_NetworkCommunication_nAICalibration_getOffset(0, port->port.pin, status); // XXX: aiSystemIndex == 0?
int32_t getAnalogOffset(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
int32_t offset = FRC_NetworkCommunication_nAICalibration_getOffset(
0, port->port.pin, status); // XXX: aiSystemIndex == 0?
return offset;
}
/**
* Return the number of channels on the module in use.
*
* @return Active channels.
*/
static uint32_t getAnalogNumActiveChannels(int32_t *status) {
static uint32_t getAnalogNumActiveChannels(int32_t* status) {
uint32_t scanSize = analogInputSystem->readConfig_ScanSize(status);
if (scanSize == 0)
return 8;
if (scanSize == 0) return 8;
return scanSize;
}
@@ -450,15 +467,17 @@ static uint32_t getAnalogNumActiveChannels(int32_t *status) {
*
* @return Value to write to the active channels field.
*/
static uint32_t getAnalogNumChannelsToActivate(int32_t *status) {
if(analogNumChannelsToActivate == 0) return getAnalogNumActiveChannels(status);
static uint32_t getAnalogNumChannelsToActivate(int32_t* status) {
if (analogNumChannelsToActivate == 0)
return getAnalogNumActiveChannels(status);
return analogNumChannelsToActivate;
}
/**
* Set the number of active channels.
*
* Store the number of active channels to set. Don't actually commit to hardware
* Store the number of active channels to set. Don't actually commit to
* hardware
* until SetSampleRate().
*
* @param channels Number of active channels.
@@ -474,9 +493,9 @@ static void setAnalogNumChannelsToActivate(uint32_t channels) {
*
* @return The analog channel is attached to an accumulator.
*/
bool isAccumulatorChannel(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
for (uint32_t i=0; i < kAccumulatorNumChannels; i++) {
bool isAccumulatorChannel(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
for (uint32_t i = 0; i < kAccumulatorNumChannels; i++) {
if (port->port.pin == kAccumulatorChannels[i]) return true;
}
return false;
@@ -485,7 +504,7 @@ bool isAccumulatorChannel(void* analog_port_pointer, int32_t *status) {
/**
* Initialize the accumulator.
*/
void initAccumulator(void* analog_port_pointer, int32_t *status) {
void initAccumulator(void* analog_port_pointer, int32_t* status) {
setAccumulatorCenter(analog_port_pointer, 0, status);
resetAccumulator(analog_port_pointer, status);
}
@@ -493,8 +512,8 @@ void initAccumulator(void* analog_port_pointer, int32_t *status) {
/**
* Resets the accumulator to the initial value.
*/
void resetAccumulator(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
void resetAccumulator(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
if (port->accumulator == NULL) {
*status = NULL_PARAMETER;
return;
@@ -505,15 +524,18 @@ void resetAccumulator(void* analog_port_pointer, 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.
* 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.
* 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.
*/
void setAccumulatorCenter(void* analog_port_pointer, int32_t center, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
void setAccumulatorCenter(void* analog_port_pointer, int32_t center,
int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
if (port->accumulator == NULL) {
*status = NULL_PARAMETER;
return;
@@ -524,8 +546,9 @@ void setAccumulatorCenter(void* analog_port_pointer, int32_t center, int32_t *st
/**
* Set the accumulator's deadband.
*/
void setAccumulatorDeadband(void* analog_port_pointer, int32_t deadband, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
void setAccumulatorDeadband(void* analog_port_pointer, int32_t deadband,
int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
if (port->accumulator == NULL) {
*status = NULL_PARAMETER;
return;
@@ -541,8 +564,8 @@ void setAccumulatorDeadband(void* analog_port_pointer, int32_t deadband, int32_t
*
* @return The 64-bit value accumulated since the last Reset().
*/
int64_t getAccumulatorValue(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
int64_t getAccumulatorValue(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
if (port->accumulator == NULL) {
*status = NULL_PARAMETER;
return 0;
@@ -554,12 +577,13 @@ int64_t getAccumulatorValue(void* analog_port_pointer, int32_t *status) {
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last Reset().
* Read the count of the accumulated values since the accumulator was last
* Reset().
*
* @return The number of times samples from the channel were accumulated.
*/
uint32_t getAccumulatorCount(void* analog_port_pointer, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
uint32_t getAccumulatorCount(void* analog_port_pointer, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
if (port->accumulator == NULL) {
*status = NULL_PARAMETER;
return 0;
@@ -576,8 +600,9 @@ uint32_t getAccumulatorCount(void* analog_port_pointer, int32_t *status) {
* @param value Pointer to the 64-bit accumulated output.
* @param count Pointer to the number of accumulation cycles.
*/
void getAccumulatorOutput(void* analog_port_pointer, int64_t *value, uint32_t *count, int32_t *status) {
AnalogPort* port = (AnalogPort*) analog_port_pointer;
void getAccumulatorOutput(void* analog_port_pointer, int64_t* value,
uint32_t* count, int32_t* status) {
AnalogPort* port = (AnalogPort*)analog_port_pointer;
if (port->accumulator == NULL) {
*status = NULL_PARAMETER;
return;
@@ -593,7 +618,6 @@ void getAccumulatorOutput(void* analog_port_pointer, int64_t *value, uint32_t *c
*count = output.Count;
}
struct trigger_t {
tAnalogTrigger* trigger;
AnalogPort* port;
@@ -601,14 +625,15 @@ struct trigger_t {
};
typedef struct trigger_t AnalogTrigger;
static hal::Resource *triggers = NULL;
static hal::Resource* triggers = NULL;
void* initializeAnalogTrigger(void* port_pointer, uint32_t *index, int32_t *status) {
Port* port = (Port*) port_pointer;
void* initializeAnalogTrigger(void* port_pointer, uint32_t* index,
int32_t* status) {
Port* port = (Port*)port_pointer;
hal::Resource::CreateResourceObject(&triggers, tAnalogTrigger::kNumSystems);
AnalogTrigger* trigger = new AnalogTrigger();
trigger->port = (AnalogPort*) initializeAnalogInputPort(port, status);
trigger->port = (AnalogPort*)initializeAnalogInputPort(port, status);
trigger->index = triggers->Allocate("Analog Trigger");
*index = trigger->index;
// TODO: if (index == ~0ul) { CloneError(triggers); return; }
@@ -619,8 +644,8 @@ void* initializeAnalogTrigger(void* port_pointer, uint32_t *index, int32_t *stat
return trigger;
}
void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t *status) {
AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer;
void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t* status) {
AnalogTrigger* trigger = (AnalogTrigger*)analog_trigger_pointer;
if (!trigger) return;
triggers->Free(trigger->index);
delete trigger->trigger;
@@ -628,10 +653,11 @@ void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t *status) {
delete trigger;
}
void setAnalogTriggerLimitsRaw(void* analog_trigger_pointer, int32_t lower, int32_t upper, int32_t *status) {
AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer;
void setAnalogTriggerLimitsRaw(void* analog_trigger_pointer, int32_t lower,
int32_t upper, int32_t* status) {
AnalogTrigger* trigger = (AnalogTrigger*)analog_trigger_pointer;
if (lower > upper) {
*status = ANALOG_TRIGGER_LIMIT_ORDER_ERROR;
*status = ANALOG_TRIGGER_LIMIT_ORDER_ERROR;
}
trigger->trigger->writeLowerLimit(lower, status);
trigger->trigger->writeUpperLimit(upper, status);
@@ -641,40 +667,49 @@ void setAnalogTriggerLimitsRaw(void* analog_trigger_pointer, int32_t lower, int3
* Set the upper and lower limits of the analog trigger.
* The limits are given as floating point voltage values.
*/
void setAnalogTriggerLimitsVoltage(void* analog_trigger_pointer, double lower, double upper, int32_t *status) {
AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer;
void setAnalogTriggerLimitsVoltage(void* analog_trigger_pointer, double lower,
double upper, int32_t* status) {
AnalogTrigger* trigger = (AnalogTrigger*)analog_trigger_pointer;
if (lower > upper) {
*status = ANALOG_TRIGGER_LIMIT_ORDER_ERROR;
*status = ANALOG_TRIGGER_LIMIT_ORDER_ERROR;
}
// TODO: This depends on the averaged setting. Only raw values will work as is.
trigger->trigger->writeLowerLimit(getAnalogVoltsToValue(trigger->port, lower, status), status);
trigger->trigger->writeUpperLimit(getAnalogVoltsToValue(trigger->port, upper, status), status);
// TODO: This depends on the averaged setting. Only raw values will work as
// is.
trigger->trigger->writeLowerLimit(
getAnalogVoltsToValue(trigger->port, lower, status), status);
trigger->trigger->writeUpperLimit(
getAnalogVoltsToValue(trigger->port, 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.
* If the value is true, then the averaged value is selected for the analog
* trigger, otherwise the immediate value is used.
*/
void setAnalogTriggerAveraged(void* analog_trigger_pointer, bool useAveragedValue, int32_t *status) {
AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer;
void setAnalogTriggerAveraged(void* analog_trigger_pointer,
bool useAveragedValue, int32_t* status) {
AnalogTrigger* trigger = (AnalogTrigger*)analog_trigger_pointer;
if (trigger->trigger->readSourceSelect_Filter(status) != 0) {
*status = INCOMPATIBLE_STATE;
// TODO: wpi_setWPIErrorWithContext(IncompatibleMode, "Hardware does not support average and filtering at the same time.");
*status = INCOMPATIBLE_STATE;
// TODO: wpi_setWPIErrorWithContext(IncompatibleMode, "Hardware does not
// support average and filtering at the same time.");
}
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.
* 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 setAnalogTriggerFiltered(void* analog_trigger_pointer, bool useFilteredValue, int32_t *status) {
AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer;
void setAnalogTriggerFiltered(void* analog_trigger_pointer,
bool useFilteredValue, int32_t* status) {
AnalogTrigger* trigger = (AnalogTrigger*)analog_trigger_pointer;
if (trigger->trigger->readSourceSelect_Averaged(status) != 0) {
*status = INCOMPATIBLE_STATE;
// TODO: wpi_setWPIErrorWithContext(IncompatibleMode, "Hardware does not support average and filtering at the same time.");
*status = INCOMPATIBLE_STATE;
// TODO: wpi_setWPIErrorWithContext(IncompatibleMode, "Hardware does not "
// "support average and filtering at the same time.");
}
trigger->trigger->writeSourceSelect_Filter(useFilteredValue, status);
}
@@ -684,8 +719,8 @@ void setAnalogTriggerFiltered(void* analog_trigger_pointer, bool useFilteredValu
* True if the analog input is between the upper and lower limits.
* @return The InWindow output of the analog trigger.
*/
bool getAnalogTriggerInWindow(void* analog_trigger_pointer, int32_t *status) {
AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer;
bool getAnalogTriggerInWindow(void* analog_trigger_pointer, int32_t* status) {
AnalogTrigger* trigger = (AnalogTrigger*)analog_trigger_pointer;
return trigger->trigger->readOutput_InHysteresis(trigger->index, status) != 0;
}
@@ -696,8 +731,9 @@ bool getAnalogTriggerInWindow(void* analog_trigger_pointer, int32_t *status) {
* If in Hysteresis, maintain previous state.
* @return The TriggerState output of the analog trigger.
*/
bool getAnalogTriggerTriggerState(void* analog_trigger_pointer, int32_t *status) {
AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer;
bool getAnalogTriggerTriggerState(void* analog_trigger_pointer,
int32_t* status) {
AnalogTrigger* trigger = (AnalogTrigger*)analog_trigger_pointer;
return trigger->trigger->readOutput_OverLimit(trigger->index, status) != 0;
}
@@ -705,52 +741,56 @@ bool getAnalogTriggerTriggerState(void* analog_trigger_pointer, int32_t *status)
* Get the state of the analog trigger output.
* @return The state of the analog trigger output.
*/
bool getAnalogTriggerOutput(void* analog_trigger_pointer, AnalogTriggerType type, int32_t *status) {
AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer;
bool getAnalogTriggerOutput(void* analog_trigger_pointer,
AnalogTriggerType type, int32_t* status) {
AnalogTrigger* trigger = (AnalogTrigger*)analog_trigger_pointer;
bool result = false;
switch(type) {
case kInWindow:
result = trigger->trigger->readOutput_InHysteresis(trigger->index, status);
break; // XXX: Backport
case kState:
result = trigger->trigger->readOutput_OverLimit(trigger->index, status);
break; // XXX: Backport
case kRisingPulse:
case kFallingPulse:
*status = ANALOG_TRIGGER_PULSE_OUTPUT_ERROR;
return false;
switch (type) {
case kInWindow:
result =
trigger->trigger->readOutput_InHysteresis(trigger->index, status);
break; // XXX: Backport
case kState:
result = trigger->trigger->readOutput_OverLimit(trigger->index, status);
break; // XXX: Backport
case kRisingPulse:
case kFallingPulse:
*status = ANALOG_TRIGGER_PULSE_OUTPUT_ERROR;
return false;
}
return result;
}
//// Float JNA Hack
// Float
int getAnalogSampleRateIntHack(int32_t *status) {
int getAnalogSampleRateIntHack(int32_t* status) {
return floatToInt(getAnalogSampleRate(status));
}
int getAnalogVoltageIntHack(void* analog_port_pointer, int32_t *status) {
int getAnalogVoltageIntHack(void* analog_port_pointer, int32_t* status) {
return floatToInt(getAnalogVoltage(analog_port_pointer, status));
}
int getAnalogAverageVoltageIntHack(void* analog_port_pointer, int32_t *status) {
int getAnalogAverageVoltageIntHack(void* analog_port_pointer, int32_t* status) {
return floatToInt(getAnalogAverageVoltage(analog_port_pointer, status));
}
// Doubles
void setAnalogSampleRateIntHack(int samplesPerSecond, int32_t *status) {
void setAnalogSampleRateIntHack(int samplesPerSecond, int32_t* status) {
setAnalogSampleRate(intToFloat(samplesPerSecond), status);
}
int32_t getAnalogVoltsToValueIntHack(void* analog_port_pointer, int voltage, int32_t *status) {
return getAnalogVoltsToValue(analog_port_pointer, intToFloat(voltage), status);
int32_t getAnalogVoltsToValueIntHack(void* analog_port_pointer, int voltage,
int32_t* status) {
return getAnalogVoltsToValue(analog_port_pointer, intToFloat(voltage),
status);
}
void setAnalogTriggerLimitsVoltageIntHack(void* analog_trigger_pointer, int lower, int upper, int32_t *status) {
setAnalogTriggerLimitsVoltage(analog_trigger_pointer, intToFloat(lower), intToFloat(upper), status);
void setAnalogTriggerLimitsVoltageIntHack(void* analog_trigger_pointer,
int lower, int upper,
int32_t* status) {
setAnalogTriggerLimitsVoltage(analog_trigger_pointer, intToFloat(lower),
intToFloat(upper), status);
}
} // extern "C"

View File

@@ -20,12 +20,12 @@
#include "FRC_FPGA_ChipObject/tSystemInterface.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/nInterfaceGlobals.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAI.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAO.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAccel.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAccumulator.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAI.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAlarm.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAnalogTrigger.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tAO.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tBIST.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tCounter.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tDIO.h"
@@ -33,8 +33,8 @@
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tEncoder.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tGlobal.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tInterrupt.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPower.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPWM.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tPower.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tRelay.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSPI.h"
#include "FRC_FPGA_ChipObject/nRoboRIO_FPGANamespace/tSysWatchdog.h"

View File

@@ -6,122 +6,119 @@
/*----------------------------------------------------------------------------*/
#include "HAL/Compressor.hpp"
#include "ctre/PCM.h"
#include <iostream>
#include "ctre/PCM.h"
static const int NUM_MODULE_NUMBERS = 63;
extern PCM *PCM_modules[NUM_MODULE_NUMBERS];
extern PCM* PCM_modules[NUM_MODULE_NUMBERS];
extern void initializePCM(int module);
extern "C" {
void *initializeCompressor(uint8_t module) {
initializePCM(module);
return PCM_modules[module];
void* initializeCompressor(uint8_t module) {
initializePCM(module);
return PCM_modules[module];
}
bool checkCompressorModule(uint8_t module) {
return module < NUM_MODULE_NUMBERS;
return module < NUM_MODULE_NUMBERS;
}
bool getCompressor(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetCompressor(value);
return value;
bool getCompressor(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
*status = module->GetCompressor(value);
return value;
}
void setClosedLoopControl(void* pcm_pointer, bool value, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
void setClosedLoopControl(void *pcm_pointer, bool value, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
*status = module->SetClosedLoopControl(value);
*status = module->SetClosedLoopControl(value);
}
bool getClosedLoopControl(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
bool getClosedLoopControl(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetClosedLoopControl(value);
return value;
*status = module->GetClosedLoopControl(value);
return value;
}
bool getPressureSwitch(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
bool getPressureSwitch(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetPressure(value);
return value;
*status = module->GetPressure(value);
return value;
}
float getCompressorCurrent(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
float value;
float getCompressorCurrent(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
float value;
*status = module->GetCompressorCurrent(value);
return value;
*status = module->GetCompressorCurrent(value);
return value;
}
bool getCompressorCurrentTooHighFault(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetCompressorCurrentTooHighFault(value);
return value;
bool getCompressorCurrentTooHighFault(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
*status = module->GetCompressorCurrentTooHighFault(value);
return value;
}
bool getCompressorCurrentTooHighStickyFault(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetCompressorCurrentTooHighStickyFault(value);
return value;
bool getCompressorCurrentTooHighStickyFault(void* pcm_pointer,
int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
*status = module->GetCompressorCurrentTooHighStickyFault(value);
return value;
}
bool getCompressorShortedStickyFault(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetCompressorShortedStickyFault(value);
return value;
bool getCompressorShortedStickyFault(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
*status = module->GetCompressorShortedStickyFault(value);
return value;
}
bool getCompressorShortedFault(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetCompressorShortedFault(value);
return value;
bool getCompressorShortedFault(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
*status = module->GetCompressorShortedFault(value);
return value;
}
bool getCompressorNotConnectedStickyFault(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetCompressorNotConnectedStickyFault(value);
return value;
bool getCompressorNotConnectedStickyFault(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
*status = module->GetCompressorNotConnectedStickyFault(value);
return value;
}
bool getCompressorNotConnectedFault(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
bool value;
*status = module->GetCompressorNotConnectedFault(value);
return value;
bool getCompressorNotConnectedFault(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
bool value;
*status = module->GetCompressorNotConnectedFault(value);
return value;
}
void clearAllPCMStickyFaults(void *pcm_pointer, int32_t *status) {
PCM *module = (PCM *)pcm_pointer;
*status = module->ClearStickyFaults();
void clearAllPCMStickyFaults(void* pcm_pointer, int32_t* status) {
PCM* module = (PCM*)pcm_pointer;
*status = module->ClearStickyFaults();
}
} // extern "C"

File diff suppressed because it is too large Load Diff

View File

@@ -7,29 +7,29 @@
#include "HAL/HAL.hpp"
#include "HAL/Port.h"
#include "HAL/Errors.hpp"
#include "ctre/ctre.h"
#include "visa/visa.h"
#include "ChipObject.h"
#include "FRC_NetworkCommunication/FRCComm.h"
#include "FRC_NetworkCommunication/UsageReporting.h"
#include "FRC_NetworkCommunication/LoadOut.h"
#include "FRC_NetworkCommunication/CANSessionMux.h"
#include <signal.h> // linux for kill
#include <sys/prctl.h>
#include <unistd.h>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <mutex>
#include <unistd.h>
#include <sys/prctl.h>
#include <signal.h> // linux for kill
#include "ChipObject.h"
#include "FRC_NetworkCommunication/CANSessionMux.h"
#include "FRC_NetworkCommunication/FRCComm.h"
#include "FRC_NetworkCommunication/LoadOut.h"
#include "FRC_NetworkCommunication/UsageReporting.h"
#include "HAL/Errors.hpp"
#include "HAL/Port.h"
#include "ctre/ctre.h"
#include "visa/visa.h"
const uint32_t solenoid_kNumDO7_0Elements = 8;
const uint32_t dio_kNumSystems = tDIO::kNumSystems;
const uint32_t interrupt_kNumSystems = tInterrupt::kNumSystems;
const uint32_t kSystemClockTicksPerMicrosecond = 40;
static tGlobal *global = nullptr;
static tSysWatchdog *watchdog = nullptr;
static tGlobal* global = nullptr;
static tSysWatchdog* watchdog = nullptr;
static priority_mutex timeMutex;
static priority_mutex msgMutex;
@@ -39,129 +39,125 @@ static void* rolloverNotifier = nullptr;
extern "C" {
void* getPort(uint8_t pin)
{
Port* port = new Port();
port->pin = pin;
port->module = 1;
return port;
void* getPort(uint8_t pin) {
Port* port = new Port();
port->pin = pin;
port->module = 1;
return port;
}
/**
* @deprecated Uses module numbers
*/
void* getPortWithModule(uint8_t module, uint8_t pin)
{
Port* port = new Port();
port->pin = pin;
port->module = module;
return port;
void* getPortWithModule(uint8_t module, uint8_t pin) {
Port* port = new Port();
port->pin = pin;
port->module = module;
return port;
}
void freePort(void* port_pointer)
{
Port* port = (Port*) port_pointer;
delete port;
void freePort(void* port_pointer) {
Port* port = (Port*)port_pointer;
delete port;
}
const char* getHALErrorMessage(int32_t code)
{
switch(code) {
case 0:
return "";
case CTR_RxTimeout:
return CTR_RxTimeout_MESSAGE;
case CTR_TxTimeout:
return CTR_TxTimeout_MESSAGE;
case CTR_InvalidParamValue:
return CTR_InvalidParamValue_MESSAGE;
case CTR_UnexpectedArbId:
return CTR_UnexpectedArbId_MESSAGE;
case CTR_TxFailed:
return CTR_TxFailed_MESSAGE;
case CTR_SigNotUpdated:
return CTR_SigNotUpdated_MESSAGE;
case NiFpga_Status_FifoTimeout:
return NiFpga_Status_FifoTimeout_MESSAGE;
case NiFpga_Status_TransferAborted:
return NiFpga_Status_TransferAborted_MESSAGE;
case NiFpga_Status_MemoryFull:
return NiFpga_Status_MemoryFull_MESSAGE;
case NiFpga_Status_SoftwareFault:
return NiFpga_Status_SoftwareFault_MESSAGE;
case NiFpga_Status_InvalidParameter:
return NiFpga_Status_InvalidParameter_MESSAGE;
case NiFpga_Status_ResourceNotFound:
return NiFpga_Status_ResourceNotFound_MESSAGE;
case NiFpga_Status_ResourceNotInitialized:
return NiFpga_Status_ResourceNotInitialized_MESSAGE;
case NiFpga_Status_HardwareFault:
return NiFpga_Status_HardwareFault_MESSAGE;
case NiFpga_Status_IrqTimeout:
return NiFpga_Status_IrqTimeout_MESSAGE;
case SAMPLE_RATE_TOO_HIGH:
return SAMPLE_RATE_TOO_HIGH_MESSAGE;
case VOLTAGE_OUT_OF_RANGE:
return VOLTAGE_OUT_OF_RANGE_MESSAGE;
case LOOP_TIMING_ERROR:
return LOOP_TIMING_ERROR_MESSAGE;
case SPI_WRITE_NO_MOSI:
return SPI_WRITE_NO_MOSI_MESSAGE;
case SPI_READ_NO_MISO:
return SPI_READ_NO_MISO_MESSAGE;
case SPI_READ_NO_DATA:
return SPI_READ_NO_DATA_MESSAGE;
case INCOMPATIBLE_STATE:
return INCOMPATIBLE_STATE_MESSAGE;
case NO_AVAILABLE_RESOURCES:
return NO_AVAILABLE_RESOURCES_MESSAGE;
case RESOURCE_IS_ALLOCATED:
return RESOURCE_IS_ALLOCATED_MESSAGE;
case NULL_PARAMETER:
return NULL_PARAMETER_MESSAGE;
case ANALOG_TRIGGER_LIMIT_ORDER_ERROR:
return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE;
case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR:
return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE;
case PARAMETER_OUT_OF_RANGE:
return PARAMETER_OUT_OF_RANGE_MESSAGE;
case ERR_CANSessionMux_InvalidBuffer:
return ERR_CANSessionMux_InvalidBuffer_MESSAGE;
case ERR_CANSessionMux_MessageNotFound:
return ERR_CANSessionMux_MessageNotFound_MESSAGE;
case WARN_CANSessionMux_NoToken:
return WARN_CANSessionMux_NoToken_MESSAGE;
case ERR_CANSessionMux_NotAllowed:
return ERR_CANSessionMux_NotAllowed_MESSAGE;
case ERR_CANSessionMux_NotInitialized:
return ERR_CANSessionMux_NotInitialized_MESSAGE;
case VI_ERROR_SYSTEM_ERROR:
return VI_ERROR_SYSTEM_ERROR_MESSAGE;
case VI_ERROR_INV_OBJECT:
return VI_ERROR_INV_OBJECT_MESSAGE;
case VI_ERROR_RSRC_LOCKED:
return VI_ERROR_RSRC_LOCKED_MESSAGE;
case VI_ERROR_RSRC_NFOUND:
return VI_ERROR_RSRC_NFOUND_MESSAGE;
case VI_ERROR_INV_RSRC_NAME:
return VI_ERROR_INV_RSRC_NAME_MESSAGE;
case VI_ERROR_QUEUE_OVERFLOW:
return VI_ERROR_QUEUE_OVERFLOW_MESSAGE;
case VI_ERROR_IO:
return VI_ERROR_IO_MESSAGE;
case VI_ERROR_ASRL_PARITY:
return VI_ERROR_ASRL_PARITY_MESSAGE;
case VI_ERROR_ASRL_FRAMING:
return VI_ERROR_ASRL_FRAMING_MESSAGE;
case VI_ERROR_ASRL_OVERRUN:
return VI_ERROR_ASRL_OVERRUN_MESSAGE;
case VI_ERROR_RSRC_BUSY:
return VI_ERROR_RSRC_BUSY_MESSAGE;
case VI_ERROR_INV_PARAMETER:
return VI_ERROR_INV_PARAMETER_MESSAGE;
default:
return "Unknown error status";
}
const char* getHALErrorMessage(int32_t code) {
switch (code) {
case 0:
return "";
case CTR_RxTimeout:
return CTR_RxTimeout_MESSAGE;
case CTR_TxTimeout:
return CTR_TxTimeout_MESSAGE;
case CTR_InvalidParamValue:
return CTR_InvalidParamValue_MESSAGE;
case CTR_UnexpectedArbId:
return CTR_UnexpectedArbId_MESSAGE;
case CTR_TxFailed:
return CTR_TxFailed_MESSAGE;
case CTR_SigNotUpdated:
return CTR_SigNotUpdated_MESSAGE;
case NiFpga_Status_FifoTimeout:
return NiFpga_Status_FifoTimeout_MESSAGE;
case NiFpga_Status_TransferAborted:
return NiFpga_Status_TransferAborted_MESSAGE;
case NiFpga_Status_MemoryFull:
return NiFpga_Status_MemoryFull_MESSAGE;
case NiFpga_Status_SoftwareFault:
return NiFpga_Status_SoftwareFault_MESSAGE;
case NiFpga_Status_InvalidParameter:
return NiFpga_Status_InvalidParameter_MESSAGE;
case NiFpga_Status_ResourceNotFound:
return NiFpga_Status_ResourceNotFound_MESSAGE;
case NiFpga_Status_ResourceNotInitialized:
return NiFpga_Status_ResourceNotInitialized_MESSAGE;
case NiFpga_Status_HardwareFault:
return NiFpga_Status_HardwareFault_MESSAGE;
case NiFpga_Status_IrqTimeout:
return NiFpga_Status_IrqTimeout_MESSAGE;
case SAMPLE_RATE_TOO_HIGH:
return SAMPLE_RATE_TOO_HIGH_MESSAGE;
case VOLTAGE_OUT_OF_RANGE:
return VOLTAGE_OUT_OF_RANGE_MESSAGE;
case LOOP_TIMING_ERROR:
return LOOP_TIMING_ERROR_MESSAGE;
case SPI_WRITE_NO_MOSI:
return SPI_WRITE_NO_MOSI_MESSAGE;
case SPI_READ_NO_MISO:
return SPI_READ_NO_MISO_MESSAGE;
case SPI_READ_NO_DATA:
return SPI_READ_NO_DATA_MESSAGE;
case INCOMPATIBLE_STATE:
return INCOMPATIBLE_STATE_MESSAGE;
case NO_AVAILABLE_RESOURCES:
return NO_AVAILABLE_RESOURCES_MESSAGE;
case RESOURCE_IS_ALLOCATED:
return RESOURCE_IS_ALLOCATED_MESSAGE;
case NULL_PARAMETER:
return NULL_PARAMETER_MESSAGE;
case ANALOG_TRIGGER_LIMIT_ORDER_ERROR:
return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE;
case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR:
return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE;
case PARAMETER_OUT_OF_RANGE:
return PARAMETER_OUT_OF_RANGE_MESSAGE;
case ERR_CANSessionMux_InvalidBuffer:
return ERR_CANSessionMux_InvalidBuffer_MESSAGE;
case ERR_CANSessionMux_MessageNotFound:
return ERR_CANSessionMux_MessageNotFound_MESSAGE;
case WARN_CANSessionMux_NoToken:
return WARN_CANSessionMux_NoToken_MESSAGE;
case ERR_CANSessionMux_NotAllowed:
return ERR_CANSessionMux_NotAllowed_MESSAGE;
case ERR_CANSessionMux_NotInitialized:
return ERR_CANSessionMux_NotInitialized_MESSAGE;
case VI_ERROR_SYSTEM_ERROR:
return VI_ERROR_SYSTEM_ERROR_MESSAGE;
case VI_ERROR_INV_OBJECT:
return VI_ERROR_INV_OBJECT_MESSAGE;
case VI_ERROR_RSRC_LOCKED:
return VI_ERROR_RSRC_LOCKED_MESSAGE;
case VI_ERROR_RSRC_NFOUND:
return VI_ERROR_RSRC_NFOUND_MESSAGE;
case VI_ERROR_INV_RSRC_NAME:
return VI_ERROR_INV_RSRC_NAME_MESSAGE;
case VI_ERROR_QUEUE_OVERFLOW:
return VI_ERROR_QUEUE_OVERFLOW_MESSAGE;
case VI_ERROR_IO:
return VI_ERROR_IO_MESSAGE;
case VI_ERROR_ASRL_PARITY:
return VI_ERROR_ASRL_PARITY_MESSAGE;
case VI_ERROR_ASRL_FRAMING:
return VI_ERROR_ASRL_FRAMING_MESSAGE;
case VI_ERROR_ASRL_OVERRUN:
return VI_ERROR_ASRL_OVERRUN_MESSAGE;
case VI_ERROR_RSRC_BUSY:
return VI_ERROR_RSRC_BUSY_MESSAGE;
case VI_ERROR_INV_PARAMETER:
return VI_ERROR_INV_PARAMETER_MESSAGE;
default:
return "Unknown error status";
}
}
/**
@@ -169,13 +165,12 @@ const char* getHALErrorMessage(int32_t code)
* For now, expect this to be competition year.
* @return FPGA Version number.
*/
uint16_t getFPGAVersion(int32_t *status)
{
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
}
return global->readVersion(status);
uint16_t getFPGAVersion(int32_t* status) {
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
}
return global->readVersion(status);
}
/**
@@ -186,243 +181,210 @@ uint16_t getFPGAVersion(int32_t *status)
* The 12 least significant bits are the Build Number.
* @return FPGA Revision number.
*/
uint32_t getFPGARevision(int32_t *status)
{
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
}
return global->readRevision(status);
uint32_t getFPGARevision(int32_t* status) {
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
}
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).
* @return The current time in microseconds according to the FPGA (since FPGA
* reset).
*/
uint64_t getFPGATime(int32_t *status)
{
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
}
std::lock_guard<priority_mutex> lock(timeMutex);
uint32_t fpgaTime = global->readLocalTime(status);
if (*status != 0) return 0;
// check for rollover
if (fpgaTime < prevFPGATime) ++timeEpoch;
prevFPGATime = fpgaTime;
return (((uint64_t)timeEpoch) << 32) | ((uint64_t)fpgaTime);
uint64_t getFPGATime(int32_t* status) {
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return 0;
}
std::lock_guard<priority_mutex> lock(timeMutex);
uint32_t fpgaTime = global->readLocalTime(status);
if (*status != 0) return 0;
// check for rollover
if (fpgaTime < prevFPGATime) ++timeEpoch;
prevFPGATime = fpgaTime;
return (((uint64_t)timeEpoch) << 32) | ((uint64_t)fpgaTime);
}
/**
* Get the state of the "USER" button on the RoboRIO
* @return true if the button is currently pressed down
*/
bool getFPGAButton(int32_t *status)
{
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
}
return global->readUserButton(status);
bool getFPGAButton(int32_t* status) {
if (!global) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
}
return global->readUserButton(status);
}
int HALSetErrorData(const char *errors, int errorsLength, int wait_ms)
{
return setErrorData(errors, errorsLength, wait_ms);
int HALSetErrorData(const char* errors, int errorsLength, int wait_ms) {
return setErrorData(errors, errorsLength, wait_ms);
}
int HALSendError(int isError, int32_t errorCode, int isLVCode,
const char *details, const char *location, const char *callStack,
int printMsg)
{
// Avoid flooding console by keeping track of previous 5 error
// messages and only printing again if they're longer than 1 second old.
static constexpr int KEEP_MSGS = 5;
std::lock_guard<priority_mutex> lock(msgMutex);
static std::string prev_msg[KEEP_MSGS];
static uint64_t prev_msg_time[KEEP_MSGS] = { 0, 0, 0 };
const char* details, const char* location,
const char* callStack, int printMsg) {
// Avoid flooding console by keeping track of previous 5 error
// messages and only printing again if they're longer than 1 second old.
static constexpr int KEEP_MSGS = 5;
std::lock_guard<priority_mutex> lock(msgMutex);
static std::string prev_msg[KEEP_MSGS];
static uint64_t prev_msg_time[KEEP_MSGS] = {0, 0, 0};
int32_t status = 0;
uint64_t curTime = getFPGATime(&status);
int i;
for (i=0; i<KEEP_MSGS; ++i) {
if (prev_msg[i] == details) break;
}
int retval = 0;
if (i == KEEP_MSGS || (curTime - prev_msg_time[i]) >= 1000000) {
retval = FRC_NetworkCommunication_sendError(isError, errorCode, isLVCode, details, location, callStack);
if (printMsg) {
if (location && location[0] != '\0') {
fprintf(stderr, "%s at %s: ",
isError ? "Error" : "Warning",
location);
}
fprintf(stderr, "%s\n", details);
if (callStack && callStack[0] != '\0') {
fprintf(stderr, "%s\n", callStack);
}
}
if (i == KEEP_MSGS) {
// replace the oldest one
i = 0;
uint64_t first = prev_msg_time[0];
for (int j=1; j<KEEP_MSGS; ++j) {
if (prev_msg_time[j] < first) {
first = prev_msg_time[j];
i = j;
}
}
prev_msg[i] = details;
}
prev_msg_time[i] = curTime;
}
return retval;
int32_t status = 0;
uint64_t curTime = getFPGATime(&status);
int i;
for (i = 0; i < KEEP_MSGS; ++i) {
if (prev_msg[i] == details) break;
}
int retval = 0;
if (i == KEEP_MSGS || (curTime - prev_msg_time[i]) >= 1000000) {
retval = FRC_NetworkCommunication_sendError(isError, errorCode, isLVCode,
details, location, callStack);
if (printMsg) {
if (location && location[0] != '\0') {
fprintf(stderr, "%s at %s: ", isError ? "Error" : "Warning", location);
}
fprintf(stderr, "%s\n", details);
if (callStack && callStack[0] != '\0') {
fprintf(stderr, "%s\n", callStack);
}
}
if (i == KEEP_MSGS) {
// replace the oldest one
i = 0;
uint64_t first = prev_msg_time[0];
for (int j = 1; j < KEEP_MSGS; ++j) {
if (prev_msg_time[j] < first) {
first = prev_msg_time[j];
i = j;
}
}
prev_msg[i] = details;
}
prev_msg_time[i] = curTime;
}
return retval;
}
bool HALGetSystemActive(int32_t *status)
{
if (!watchdog) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
}
return watchdog->readStatus_SystemActive(status);
bool HALGetSystemActive(int32_t* status) {
if (!watchdog) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
}
return watchdog->readStatus_SystemActive(status);
}
bool HALGetBrownedOut(int32_t *status)
{
if (!watchdog) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
}
return !(watchdog->readStatus_PowerAlive(status));
bool HALGetBrownedOut(int32_t* status) {
if (!watchdog) {
*status = NiFpga_Status_ResourceNotInitialized;
return false;
}
return !(watchdog->readStatus_PowerAlive(status));
}
static void HALCleanupAtExit() {
global = nullptr;
watchdog = nullptr;
global = nullptr;
watchdog = nullptr;
}
static void timerRollover(uint64_t currentTime, void*) {
// reschedule timer for next rollover
int32_t status = 0;
updateNotifierAlarm(rolloverNotifier, currentTime + 0x80000000ULL, &status);
// reschedule timer for next rollover
int32_t status = 0;
updateNotifierAlarm(rolloverNotifier, currentTime + 0x80000000ULL, &status);
}
/**
* Call this to start up HAL. This is required for robot programs.
*/
int HALInitialize(int mode)
{
setlinebuf(stdin);
setlinebuf(stdout);
int HALInitialize(int mode) {
setlinebuf(stdin);
setlinebuf(stdout);
prctl(PR_SET_PDEATHSIG, SIGTERM);
prctl(PR_SET_PDEATHSIG, SIGTERM);
FRC_NetworkCommunication_Reserve(nullptr);
// image 4; Fixes errors caused by multiple processes. Talk to NI about this
nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
nLoadOut::kTargetClass_RoboRIO;
FRC_NetworkCommunication_Reserve(nullptr);
// image 4; Fixes errors caused by multiple processes. Talk to NI about this
nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
nLoadOut::kTargetClass_RoboRIO;
int32_t status = 0;
global = tGlobal::create(&status);
watchdog = tSysWatchdog::create(&status);
int32_t status = 0;
global = tGlobal::create(&status);
watchdog = tSysWatchdog::create(&status);
std::atexit(HALCleanupAtExit);
std::atexit(HALCleanupAtExit);
if (!rolloverNotifier)
rolloverNotifier = initializeNotifier(timerRollover, nullptr, &status);
if (status == 0) {
uint64_t curTime = getFPGATime(&status);
if (status == 0)
updateNotifierAlarm(rolloverNotifier, curTime + 0x80000000ULL, &status);
}
if (!rolloverNotifier)
rolloverNotifier = initializeNotifier(timerRollover, nullptr, &status);
if (status == 0) {
uint64_t curTime = getFPGATime(&status);
if (status == 0)
updateNotifierAlarm(rolloverNotifier, curTime + 0x80000000ULL, &status);
}
// Kill any previous robot programs
std::fstream fs;
// By making this both in/out, it won't give us an error if it doesnt exist
fs.open("/var/lock/frc.pid", std::fstream::in | std::fstream::out);
if (fs.bad())
return 0;
// Kill any previous robot programs
std::fstream fs;
// By making this both in/out, it won't give us an error if it doesnt exist
fs.open("/var/lock/frc.pid", std::fstream::in | std::fstream::out);
if (fs.bad()) return 0;
pid_t pid = 0;
if (!fs.eof() && !fs.fail())
{
fs >> pid;
//see if the pid is around, but we don't want to mess with init id=1, or ourselves
if (pid >= 2 && kill(pid, 0) == 0 && pid != getpid())
{
std::cout << "Killing previously running FRC program..."
<< std::endl;
kill(pid, SIGTERM); // try to kill it
delayMillis(100);
if (kill(pid, 0) == 0)
{
// still not successfull
if (mode == 0)
{
std::cout << "FRC pid " << pid
<< " did not die within 110ms. Aborting"
<< std::endl;
return 0; // just fail
}
else if (mode == 1) // kill -9 it
kill(pid, SIGKILL);
else
{
std::cout << "WARNING: FRC pid " << pid
<< " did not die within 110ms." << std::endl;
}
}
pid_t pid = 0;
if (!fs.eof() && !fs.fail()) {
fs >> pid;
// see if the pid is around, but we don't want to mess with init id=1, or
// ourselves
if (pid >= 2 && kill(pid, 0) == 0 && pid != getpid()) {
std::cout << "Killing previously running FRC program..." << std::endl;
kill(pid, SIGTERM); // try to kill it
delayMillis(100);
if (kill(pid, 0) == 0) {
// still not successfull
if (mode == 0) {
std::cout << "FRC pid " << pid
<< " did not die within 110ms. Aborting" << std::endl;
return 0; // just fail
} else if (mode == 1) // kill -9 it
kill(pid, SIGKILL);
else {
std::cout << "WARNING: FRC pid " << pid
<< " did not die within 110ms." << std::endl;
}
}
}
}
fs.close();
// we will re-open it write only to truncate the file
fs.open("/var/lock/frc.pid", std::fstream::out | std::fstream::trunc);
fs.seekp(0);
pid = getpid();
fs << pid << std::endl;
fs.close();
}
}
fs.close();
// we will re-open it write only to truncate the file
fs.open("/var/lock/frc.pid", std::fstream::out | std::fstream::trunc);
fs.seekp(0);
pid = getpid();
fs << pid << std::endl;
fs.close();
return 1;
return 1;
}
uint32_t HALReport(uint8_t resource, uint8_t instanceNumber, uint8_t context,
const char *feature)
{
if(feature == NULL)
{
feature = "";
}
const char* feature) {
if (feature == NULL) {
feature = "";
}
return FRC_NetworkCommunication_nUsageReporting_report(resource, instanceNumber, context, feature);
return FRC_NetworkCommunication_nUsageReporting_report(
resource, instanceNumber, context, feature);
}
// TODO: HACKS
void NumericArrayResize()
{
}
void RTSetCleanupProc()
{
}
void EDVR_CreateReference()
{
}
void Occur()
{
}
void NumericArrayResize() {}
void RTSetCleanupProc() {}
void EDVR_CreateReference() {}
void Occur() {}
void imaqGetErrorText()
{
}
void imaqGetLastError()
{
}
void niTimestamp64()
{
}
void imaqGetErrorText() {}
void imaqGetLastError() {}
void niTimestamp64() {}
} // extern "C"

View File

@@ -8,34 +8,34 @@
#include "HAL/Interrupts.hpp"
#include "ChipObject.h"
extern void remapDigitalSource(bool analogTrigger, uint32_t &pin, uint8_t &module);
extern void remapDigitalSource(bool analogTrigger, uint32_t& pin,
uint8_t& module);
struct Interrupt // FIXME: why is this internal?
struct Interrupt // FIXME: why is this internal?
{
tInterrupt *anInterrupt;
tInterruptManager *manager;
tInterrupt* anInterrupt;
tInterruptManager* manager;
};
extern "C" {
void* initializeInterrupts(uint32_t interruptIndex, bool watcher, int32_t *status)
{
Interrupt* anInterrupt = new Interrupt();
// Expects the calling leaf class to allocate an interrupt index.
anInterrupt->anInterrupt = tInterrupt::create(interruptIndex, status);
anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
anInterrupt->manager = new tInterruptManager(
(1 << interruptIndex) | (1 << (interruptIndex + 8)), watcher, status);
return anInterrupt;
void* initializeInterrupts(uint32_t interruptIndex, bool watcher,
int32_t* status) {
Interrupt* anInterrupt = new Interrupt();
// Expects the calling leaf class to allocate an interrupt index.
anInterrupt->anInterrupt = tInterrupt::create(interruptIndex, status);
anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
anInterrupt->manager = new tInterruptManager(
(1 << interruptIndex) | (1 << (interruptIndex + 8)), watcher, status);
return anInterrupt;
}
void cleanInterrupts(void* interrupt_pointer, int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
delete anInterrupt->anInterrupt;
delete anInterrupt->manager;
anInterrupt->anInterrupt = NULL;
anInterrupt->manager = NULL;
void cleanInterrupts(void* interrupt_pointer, int32_t* status) {
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
delete anInterrupt->anInterrupt;
delete anInterrupt->manager;
anInterrupt->anInterrupt = NULL;
anInterrupt->manager = NULL;
}
/**
@@ -45,40 +45,40 @@ void cleanInterrupts(void* interrupt_pointer, int32_t *status)
* waitForInterrupt was called.
* @return The mask of interrupts that fired.
*/
uint32_t waitForInterrupt(void* interrupt_pointer, double timeout, bool ignorePrevious, int32_t *status)
{
uint32_t result;
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
uint32_t waitForInterrupt(void* interrupt_pointer, double timeout,
bool ignorePrevious, int32_t* status) {
uint32_t result;
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
result = anInterrupt->manager->watch((int32_t)(timeout * 1e3), ignorePrevious, status);
result = anInterrupt->manager->watch((int32_t)(timeout * 1e3), ignorePrevious,
status);
// Don't report a timeout as an error - the return code is enough to tell
// that a timeout happened.
if(*status == -NiFpga_Status_IrqTimeout) {
*status = NiFpga_Status_Success;
}
// Don't report a timeout as an error - the return code is enough to tell
// that a timeout happened.
if (*status == -NiFpga_Status_IrqTimeout) {
*status = NiFpga_Status_Success;
}
return result;
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.
* 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 enableInterrupts(void* interrupt_pointer, int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->manager->enable(status);
void enableInterrupts(void* interrupt_pointer, int32_t* status) {
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->manager->enable(status);
}
/**
* Disable Interrupts without without deallocating structures.
*/
void disableInterrupts(void* interrupt_pointer, int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->manager->disable(status);
void disableInterrupts(void* interrupt_pointer, int32_t* status) {
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->manager->disable(status);
}
/**
@@ -86,11 +86,10 @@ void disableInterrupts(void* interrupt_pointer, int32_t *status)
* This is in the same time domain as GetClock().
* @return Timestamp in seconds since boot.
*/
double readRisingTimestamp(void* interrupt_pointer, int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
uint32_t timestamp = anInterrupt->anInterrupt->readRisingTimeStamp(status);
return timestamp * 1e-6;
double readRisingTimestamp(void* interrupt_pointer, int32_t* status) {
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
uint32_t timestamp = anInterrupt->anInterrupt->readRisingTimeStamp(status);
return timestamp * 1e-6;
}
/**
@@ -98,37 +97,36 @@ double readRisingTimestamp(void* interrupt_pointer, int32_t *status)
* This is in the same time domain as GetClock().
* @return Timestamp in seconds since boot.
*/
double readFallingTimestamp(void* interrupt_pointer, int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
uint32_t timestamp = anInterrupt->anInterrupt->readFallingTimeStamp(status);
return timestamp * 1e-6;
double readFallingTimestamp(void* interrupt_pointer, int32_t* status) {
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
uint32_t timestamp = anInterrupt->anInterrupt->readFallingTimeStamp(status);
return timestamp * 1e-6;
}
void requestInterrupts(void* interrupt_pointer, uint8_t routing_module, uint32_t routing_pin,
bool routing_analog_trigger, int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
remapDigitalSource(routing_analog_trigger, routing_pin, routing_module);
anInterrupt->anInterrupt->writeConfig_Source_AnalogTrigger(routing_analog_trigger, status);
anInterrupt->anInterrupt->writeConfig_Source_Channel(routing_pin, status);
anInterrupt->anInterrupt->writeConfig_Source_Module(routing_module, status);
void requestInterrupts(void* interrupt_pointer, uint8_t routing_module,
uint32_t routing_pin, bool routing_analog_trigger,
int32_t* status) {
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->anInterrupt->writeConfig_WaitForAck(false, status);
remapDigitalSource(routing_analog_trigger, routing_pin, routing_module);
anInterrupt->anInterrupt->writeConfig_Source_AnalogTrigger(
routing_analog_trigger, status);
anInterrupt->anInterrupt->writeConfig_Source_Channel(routing_pin, status);
anInterrupt->anInterrupt->writeConfig_Source_Module(routing_module, status);
}
void attachInterruptHandler(void* interrupt_pointer, InterruptHandlerFunction handler, void* param,
int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->manager->registerHandler(handler, param, status);
void attachInterruptHandler(void* interrupt_pointer,
InterruptHandlerFunction handler, void* param,
int32_t* status) {
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->manager->registerHandler(handler, param, status);
}
void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge, bool fallingEdge,
int32_t *status)
{
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->anInterrupt->writeConfig_RisingEdge(risingEdge, status);
anInterrupt->anInterrupt->writeConfig_FallingEdge(fallingEdge, status);
void setInterruptUpSourceEdge(void* interrupt_pointer, bool risingEdge,
bool fallingEdge, int32_t* status) {
Interrupt* anInterrupt = (Interrupt*)interrupt_pointer;
anInterrupt->anInterrupt->writeConfig_RisingEdge(risingEdge, status);
anInterrupt->anInterrupt->writeConfig_FallingEdge(fallingEdge, status);
}
} // extern "C"

View File

@@ -6,163 +6,159 @@
/*----------------------------------------------------------------------------*/
#include "HAL/Notifier.hpp"
#include "ChipObject.h"
#include "HAL/HAL.hpp"
#include "HAL/cpp/priority_mutex.h"
#include <atomic>
#include <cstdlib>
#include <mutex>
#include "ChipObject.h"
#include "HAL/HAL.hpp"
#include "HAL/cpp/priority_mutex.h"
static const uint32_t kTimerInterruptNumber = 28;
static priority_mutex notifierInterruptMutex;
static priority_recursive_mutex notifierMutex;
static tAlarm *notifierAlarm = nullptr;
static tInterruptManager *notifierManager = nullptr;
static tAlarm* notifierAlarm = nullptr;
static tInterruptManager* notifierManager = nullptr;
static uint64_t closestTrigger = UINT64_MAX;
struct Notifier {
Notifier *prev, *next;
void *param;
void (*process)(uint64_t, void*);
uint64_t triggerTime = UINT64_MAX;
Notifier *prev, *next;
void* param;
void (*process)(uint64_t, void*);
uint64_t triggerTime = UINT64_MAX;
};
static Notifier *notifiers = nullptr;
static Notifier* notifiers = nullptr;
static std::atomic_flag notifierAtexitRegistered = ATOMIC_FLAG_INIT;
static std::atomic_int notifierRefCount{0};
static void alarmCallback(uint32_t, void*)
{
std::unique_lock<priority_recursive_mutex> sync(notifierMutex);
static void alarmCallback(uint32_t, void*) {
std::unique_lock<priority_recursive_mutex> sync(notifierMutex);
int32_t status = 0;
uint64_t currentTime = 0;
int32_t status = 0;
uint64_t currentTime = 0;
// the hardware disables itself after each alarm
closestTrigger = UINT64_MAX;
// the hardware disables itself after each alarm
closestTrigger = UINT64_MAX;
// process all notifiers
Notifier *notifier = notifiers;
while (notifier) {
if (notifier->triggerTime != UINT64_MAX) {
if (currentTime == 0)
currentTime = getFPGATime(&status);
if (notifier->triggerTime < currentTime) {
notifier->triggerTime = UINT64_MAX;
auto process = notifier->process;
auto param = notifier->param;
sync.unlock();
process(currentTime, param);
sync.lock();
} else if (notifier->triggerTime < closestTrigger) {
updateNotifierAlarm(notifier, notifier->triggerTime, &status);
}
}
notifier = notifier->next;
}
// process all notifiers
Notifier* notifier = notifiers;
while (notifier) {
if (notifier->triggerTime != UINT64_MAX) {
if (currentTime == 0) currentTime = getFPGATime(&status);
if (notifier->triggerTime < currentTime) {
notifier->triggerTime = UINT64_MAX;
auto process = notifier->process;
auto param = notifier->param;
sync.unlock();
process(currentTime, param);
sync.lock();
} else if (notifier->triggerTime < closestTrigger) {
updateNotifierAlarm(notifier, notifier->triggerTime, &status);
}
}
notifier = notifier->next;
}
}
static void cleanupNotifierAtExit() {
notifierAlarm = nullptr;
notifierManager = nullptr;
notifierAlarm = nullptr;
notifierManager = nullptr;
}
extern "C" {
void* initializeNotifier(void (*process)(uint64_t, void*), void *param, int32_t *status)
{
if (!process) {
*status = NULL_PARAMETER;
return nullptr;
}
if (!notifierAtexitRegistered.test_and_set())
std::atexit(cleanupNotifierAtExit);
if (notifierRefCount.fetch_add(1) == 0) {
std::lock_guard<priority_mutex> sync(notifierInterruptMutex);
// create manager and alarm if not already created
if (!notifierManager) {
notifierManager = new tInterruptManager(1 << kTimerInterruptNumber, false, status);
notifierManager->registerHandler(alarmCallback, NULL, status);
notifierManager->enable(status);
}
if (!notifierAlarm) notifierAlarm = tAlarm::create(status);
}
void* initializeNotifier(void (*process)(uint64_t, void*), void* param,
int32_t* status) {
if (!process) {
*status = NULL_PARAMETER;
return nullptr;
}
if (!notifierAtexitRegistered.test_and_set())
std::atexit(cleanupNotifierAtExit);
if (notifierRefCount.fetch_add(1) == 0) {
std::lock_guard<priority_mutex> sync(notifierInterruptMutex);
// create manager and alarm if not already created
if (!notifierManager) {
notifierManager =
new tInterruptManager(1 << kTimerInterruptNumber, false, status);
notifierManager->registerHandler(alarmCallback, NULL, status);
notifierManager->enable(status);
}
if (!notifierAlarm) notifierAlarm = tAlarm::create(status);
}
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
// create notifier structure and add to list
Notifier* notifier = new Notifier();
notifier->prev = nullptr;
notifier->next = notifiers;
if (notifier->next) notifier->next->prev = notifier;
notifier->param = param;
notifier->process = process;
notifiers = notifier;
return notifier;
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
// create notifier structure and add to list
Notifier* notifier = new Notifier();
notifier->prev = nullptr;
notifier->next = notifiers;
if (notifier->next) notifier->next->prev = notifier;
notifier->param = param;
notifier->process = process;
notifiers = notifier;
return notifier;
}
void cleanNotifier(void* notifier_pointer, int32_t *status)
{
{
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
Notifier* notifier = (Notifier*)notifier_pointer;
void cleanNotifier(void* notifier_pointer, int32_t* status) {
{
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
Notifier* notifier = (Notifier*)notifier_pointer;
// remove from list and delete
if (notifier->prev) notifier->prev->next = notifier->next;
if (notifier->next) notifier->next->prev = notifier->prev;
if (notifiers == notifier) notifiers = notifier->next;
delete notifier;
}
// remove from list and delete
if (notifier->prev) notifier->prev->next = notifier->next;
if (notifier->next) notifier->next->prev = notifier->prev;
if (notifiers == notifier) notifiers = notifier->next;
delete notifier;
}
if (notifierRefCount.fetch_sub(1) == 1) {
std::lock_guard<priority_mutex> sync(notifierInterruptMutex);
// if this was the last notifier, clean up alarm and manager
if (notifierAlarm) {
notifierAlarm->writeEnable(false, status);
delete notifierAlarm;
notifierAlarm = nullptr;
}
if (notifierManager) {
notifierManager->disable(status);
delete notifierManager;
notifierManager = nullptr;
}
closestTrigger = UINT64_MAX;
}
if (notifierRefCount.fetch_sub(1) == 1) {
std::lock_guard<priority_mutex> sync(notifierInterruptMutex);
// if this was the last notifier, clean up alarm and manager
if (notifierAlarm) {
notifierAlarm->writeEnable(false, status);
delete notifierAlarm;
notifierAlarm = nullptr;
}
if (notifierManager) {
notifierManager->disable(status);
delete notifierManager;
notifierManager = nullptr;
}
closestTrigger = UINT64_MAX;
}
}
void* getNotifierParam(void* notifier_pointer, int32_t *status)
{
return ((Notifier*)notifier_pointer)->param;
void* getNotifierParam(void* notifier_pointer, int32_t* status) {
return ((Notifier*)notifier_pointer)->param;
}
void updateNotifierAlarm(void* notifier_pointer, uint64_t triggerTime, int32_t *status)
{
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
void updateNotifierAlarm(void* notifier_pointer, uint64_t triggerTime,
int32_t* status) {
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
Notifier* notifier = (Notifier*)notifier_pointer;
notifier->triggerTime = triggerTime;
bool wasActive = (closestTrigger != UINT64_MAX);
Notifier* notifier = (Notifier*)notifier_pointer;
notifier->triggerTime = triggerTime;
bool wasActive = (closestTrigger != UINT64_MAX);
if (!notifierInterruptMutex.try_lock() || notifierRefCount == 0 ||
!notifierAlarm)
return;
if (!notifierInterruptMutex.try_lock() || notifierRefCount == 0 ||
!notifierAlarm)
return;
// Update alarm time if closer than current.
if (triggerTime < closestTrigger) {
closestTrigger = triggerTime;
// Simply truncate the hardware trigger time to 32-bit.
notifierAlarm->writeTriggerTime((uint32_t)triggerTime, status);
}
// Enable the alarm. The hardware disables itself after each alarm.
if (!wasActive) notifierAlarm->writeEnable(true, status);
// Update alarm time if closer than current.
if (triggerTime < closestTrigger) {
closestTrigger = triggerTime;
// Simply truncate the hardware trigger time to 32-bit.
notifierAlarm->writeTriggerTime((uint32_t)triggerTime, status);
}
// Enable the alarm. The hardware disables itself after each alarm.
if (!wasActive) notifierAlarm->writeEnable(true, status);
notifierInterruptMutex.unlock();
notifierInterruptMutex.unlock();
}
void stopNotifierAlarm(void* notifier_pointer, int32_t *status)
{
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
Notifier* notifier = (Notifier*)notifier_pointer;
notifier->triggerTime = UINT64_MAX;
void stopNotifierAlarm(void* notifier_pointer, int32_t* status) {
std::lock_guard<priority_recursive_mutex> sync(notifierMutex);
Notifier* notifier = (Notifier*)notifier_pointer;
notifier->triggerTime = UINT64_MAX;
}
} // extern "C"

View File

@@ -7,74 +7,74 @@
#include "HAL/PDP.hpp"
#include "ctre/PDP.h"
//static PDP pdp;
// static PDP pdp;
static const int NUM_MODULE_NUMBERS = 63;
static PDP *pdp[NUM_MODULE_NUMBERS] = { NULL };
static PDP* pdp[NUM_MODULE_NUMBERS] = {NULL};
extern "C" {
void initializePDP(uint8_t module) {
if(!pdp[module]) {
pdp[module] = new PDP(module);
}
if (!pdp[module]) {
pdp[module] = new PDP(module);
}
}
double getPDPTemperature(uint8_t module, int32_t *status) {
double temperature;
double getPDPTemperature(uint8_t module, int32_t* status) {
double temperature;
*status = pdp[module]->GetTemperature(temperature);
*status = pdp[module]->GetTemperature(temperature);
return temperature;
return temperature;
}
double getPDPVoltage(uint8_t module, int32_t *status) {
double voltage;
double getPDPVoltage(uint8_t module, int32_t* status) {
double voltage;
*status = pdp[module]->GetVoltage(voltage);
*status = pdp[module]->GetVoltage(voltage);
return voltage;
return voltage;
}
double getPDPChannelCurrent(uint8_t module, uint8_t channel, int32_t *status) {
double current;
double getPDPChannelCurrent(uint8_t module, uint8_t channel, int32_t* status) {
double current;
*status = pdp[module]->GetChannelCurrent(channel, current);
*status = pdp[module]->GetChannelCurrent(channel, current);
return current;
return current;
}
double getPDPTotalCurrent(uint8_t module, int32_t *status) {
double current;
double getPDPTotalCurrent(uint8_t module, int32_t* status) {
double current;
*status = pdp[module]->GetTotalCurrent(current);
*status = pdp[module]->GetTotalCurrent(current);
return current;
return current;
}
double getPDPTotalPower(uint8_t module, int32_t *status) {
double power;
double getPDPTotalPower(uint8_t module, int32_t* status) {
double power;
*status = pdp[module]->GetTotalPower(power);
*status = pdp[module]->GetTotalPower(power);
return power;
return power;
}
double getPDPTotalEnergy(uint8_t module, int32_t *status) {
double energy;
double getPDPTotalEnergy(uint8_t module, int32_t* status) {
double energy;
*status = pdp[module]->GetTotalEnergy(energy);
*status = pdp[module]->GetTotalEnergy(energy);
return energy;
return energy;
}
void resetPDPTotalEnergy(uint8_t module, int32_t *status) {
*status = pdp[module]->ResetEnergy();
void resetPDPTotalEnergy(uint8_t module, int32_t* status) {
*status = pdp[module]->ResetEnergy();
}
void clearPDPStickyFaults(uint8_t module, int32_t *status) {
*status = pdp[module]->ClearStickyFaults();
void clearPDPStickyFaults(uint8_t module, int32_t* status) {
*status = pdp[module]->ClearStickyFaults();
}
} // extern "C"

View File

@@ -8,12 +8,12 @@
#include "HAL/Power.hpp"
#include "ChipObject.h"
static tPower *power = NULL;
static tPower* power = NULL;
static void initializePower(int32_t *status) {
if(power == NULL) {
power = tPower::create(status);
}
static void initializePower(int32_t* status) {
if (power == NULL) {
power = tPower::create(status);
}
}
extern "C" {
@@ -21,118 +21,118 @@ extern "C" {
/**
* Get the roboRIO input voltage
*/
float getVinVoltage(int32_t *status) {
initializePower(status);
return power->readVinVoltage(status) / 4.096f * 0.025733f - 0.029f;
float getVinVoltage(int32_t* status) {
initializePower(status);
return power->readVinVoltage(status) / 4.096f * 0.025733f - 0.029f;
}
/**
* Get the roboRIO input current
*/
float getVinCurrent(int32_t *status) {
initializePower(status);
return power->readVinCurrent(status) / 4.096f * 0.017042 - 0.071f;
float getVinCurrent(int32_t* status) {
initializePower(status);
return power->readVinCurrent(status) / 4.096f * 0.017042 - 0.071f;
}
/**
* Get the 6V rail voltage
*/
float getUserVoltage6V(int32_t *status) {
initializePower(status);
return power->readUserVoltage6V(status) / 4.096f * 0.007019f - 0.014f;
float getUserVoltage6V(int32_t* status) {
initializePower(status);
return power->readUserVoltage6V(status) / 4.096f * 0.007019f - 0.014f;
}
/**
* Get the 6V rail current
*/
float getUserCurrent6V(int32_t *status) {
initializePower(status);
return power->readUserCurrent6V(status) / 4.096f * 0.005566f - 0.009f;
float getUserCurrent6V(int32_t* status) {
initializePower(status);
return power->readUserCurrent6V(status) / 4.096f * 0.005566f - 0.009f;
}
/**
* Get the active state of the 6V rail
*/
bool getUserActive6V(int32_t *status) {
initializePower(status);
return power->readStatus_User6V(status) == 4;
bool getUserActive6V(int32_t* status) {
initializePower(status);
return power->readStatus_User6V(status) == 4;
}
/**
* Get the fault count for the 6V rail
*/
int getUserCurrentFaults6V(int32_t *status) {
initializePower(status);
return (int)power->readFaultCounts_OverCurrentFaultCount6V(status);
int getUserCurrentFaults6V(int32_t* status) {
initializePower(status);
return (int)power->readFaultCounts_OverCurrentFaultCount6V(status);
}
/**
* Get the 5V rail voltage
*/
float getUserVoltage5V(int32_t *status) {
initializePower(status);
return power->readUserVoltage5V(status) / 4.096f * 0.005962f - 0.013f;
float getUserVoltage5V(int32_t* status) {
initializePower(status);
return power->readUserVoltage5V(status) / 4.096f * 0.005962f - 0.013f;
}
/**
* Get the 5V rail current
*/
float getUserCurrent5V(int32_t *status) {
initializePower(status);
return power->readUserCurrent5V(status) / 4.096f * 0.001996f - 0.002f;
float getUserCurrent5V(int32_t* status) {
initializePower(status);
return power->readUserCurrent5V(status) / 4.096f * 0.001996f - 0.002f;
}
/**
* Get the active state of the 5V rail
*/
bool getUserActive5V(int32_t *status) {
initializePower(status);
return power->readStatus_User5V(status) == 4;
bool getUserActive5V(int32_t* status) {
initializePower(status);
return power->readStatus_User5V(status) == 4;
}
/**
* Get the fault count for the 5V rail
*/
int getUserCurrentFaults5V(int32_t *status) {
initializePower(status);
return (int)power->readFaultCounts_OverCurrentFaultCount5V(status);
int getUserCurrentFaults5V(int32_t* status) {
initializePower(status);
return (int)power->readFaultCounts_OverCurrentFaultCount5V(status);
}
unsigned char getUserStatus5V(int32_t *status) {
initializePower(status);
return power->readStatus_User5V(status);
unsigned char getUserStatus5V(int32_t* status) {
initializePower(status);
return power->readStatus_User5V(status);
}
/**
* Get the 3.3V rail voltage
*/
float getUserVoltage3V3(int32_t *status) {
initializePower(status);
return power->readUserVoltage3V3(status) / 4.096f * 0.004902f - 0.01f;
float getUserVoltage3V3(int32_t* status) {
initializePower(status);
return power->readUserVoltage3V3(status) / 4.096f * 0.004902f - 0.01f;
}
/**
* Get the 3.3V rail current
*/
float getUserCurrent3V3(int32_t *status) {
initializePower(status);
return power->readUserCurrent3V3(status) / 4.096f * 0.002486f - 0.003f;
float getUserCurrent3V3(int32_t* status) {
initializePower(status);
return power->readUserCurrent3V3(status) / 4.096f * 0.002486f - 0.003f;
}
/**
* Get the active state of the 3.3V rail
*/
bool getUserActive3V3(int32_t *status) {
initializePower(status);
return power->readStatus_User3V3(status) == 4;
bool getUserActive3V3(int32_t* status) {
initializePower(status);
return power->readStatus_User3V3(status) == 4;
}
/**
* Get the fault count for the 3.3V rail
*/
int getUserCurrentFaults3V3(int32_t *status) {
initializePower(status);
return (int)power->readFaultCounts_OverCurrentFaultCount3V3(status);
int getUserCurrentFaults3V3(int32_t* status) {
initializePower(status);
return (int)power->readFaultCounts_OverCurrentFaultCount3V3(status);
}
} // extern "C"

View File

@@ -12,9 +12,11 @@
// set the logging level
TLogLevel semaphoreLogLevel = logDEBUG;
#define SEMAPHORE_LOG(level) \
if (level > semaphoreLogLevel) ; \
else Log().Get(level)
#define SEMAPHORE_LOG(level) \
if (level > semaphoreLogLevel) \
; \
else \
Log().Get(level)
extern "C" {

View File

@@ -8,150 +8,140 @@
#include "HAL/SerialPort.hpp"
#include "visa/visa.h"
static uint32_t m_resourceManagerHandle;
static uint32_t m_portHandle[2];
extern "C" {
void serialInitializePort(uint8_t port, int32_t *status) {
char const * portName;
void serialInitializePort(uint8_t port, int32_t* status) {
char const* portName;
if (m_resourceManagerHandle ==0)
viOpenDefaultRM((ViSession*)&m_resourceManagerHandle);
if(port == 0)
portName = "ASRL1::INSTR";
else if (port == 1)
portName = "ASRL2::INSTR";
else
portName = "ASRL3::INSTR";
if (m_resourceManagerHandle == 0)
viOpenDefaultRM((ViSession*)&m_resourceManagerHandle);
*status = viOpen(m_resourceManagerHandle, const_cast<char*>(portName), VI_NULL, VI_NULL, (ViSession*)&m_portHandle[port]);
if(*status > 0)
*status = 0;
if (port == 0)
portName = "ASRL1::INSTR";
else if (port == 1)
portName = "ASRL2::INSTR";
else
portName = "ASRL3::INSTR";
*status = viOpen(m_resourceManagerHandle, const_cast<char*>(portName),
VI_NULL, VI_NULL, (ViSession*)&m_portHandle[port]);
if (*status > 0) *status = 0;
}
void serialSetBaudRate(uint8_t port, uint32_t baud, int32_t *status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_BAUD, baud);
if(*status > 0)
*status = 0;
}
void serialSetDataBits(uint8_t port, uint8_t bits, int32_t *status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_DATA_BITS, bits);
if(*status > 0)
*status = 0;
void serialSetBaudRate(uint8_t port, uint32_t baud, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_BAUD, baud);
if (*status > 0) *status = 0;
}
void serialSetParity(uint8_t port, uint8_t parity, int32_t *status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_PARITY, parity);
if(*status > 0)
*status = 0;
}
void serialSetStopBits(uint8_t port, uint8_t stopBits, int32_t *status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_STOP_BITS, stopBits);
if(*status > 0)
*status = 0;
void serialSetDataBits(uint8_t port, uint8_t bits, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_DATA_BITS, bits);
if (*status > 0) *status = 0;
}
void serialSetWriteMode(uint8_t port, uint8_t mode, int32_t *status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_WR_BUF_OPER_MODE, mode);
if(*status > 0)
*status = 0;
}
void serialSetFlowControl(uint8_t port, uint8_t flow, int32_t *status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_FLOW_CNTRL, flow);
if(*status > 0)
*status = 0;
void serialSetParity(uint8_t port, uint8_t parity, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_PARITY, parity);
if (*status > 0) *status = 0;
}
void serialSetTimeout(uint8_t port, float timeout, int32_t *status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_TMO_VALUE, (uint32_t)(timeout * 1e3));
if(*status > 0)
*status = 0;
}
void serialEnableTermination(uint8_t port, char terminator, int32_t *status) {
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR, terminator);
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_END_IN, VI_ASRL_END_TERMCHAR);
if(*status > 0)
*status = 0;
void serialSetStopBits(uint8_t port, uint8_t stopBits, int32_t* status) {
*status =
viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_STOP_BITS, stopBits);
if (*status > 0) *status = 0;
}
void serialDisableTermination(uint8_t port, int32_t *status) {
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR_EN, VI_FALSE);
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_END_IN, VI_ASRL_END_NONE);
if(*status > 0)
*status = 0;
void serialSetWriteMode(uint8_t port, uint8_t mode, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_WR_BUF_OPER_MODE, mode);
if (*status > 0) *status = 0;
}
void serialSetReadBufferSize(uint8_t port, uint32_t size, int32_t *status) {
*status = viSetBuf(m_portHandle[port], VI_READ_BUF, size);
if(*status > 0)
*status = 0;
}
void serialSetWriteBufferSize(uint8_t port, uint32_t size, int32_t *status) {
*status = viSetBuf(m_portHandle[port], VI_WRITE_BUF, size);
if(*status > 0)
*status = 0;
void serialSetFlowControl(uint8_t port, uint8_t flow, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_FLOW_CNTRL, flow);
if (*status > 0) *status = 0;
}
int32_t serialGetBytesReceived(uint8_t port, int32_t *status) {
int32_t bytes = 0;
*status = viGetAttribute(m_portHandle[port], VI_ATTR_ASRL_AVAIL_NUM, &bytes);
if(*status > 0)
*status = 0;
return bytes;
}
uint32_t serialRead(uint8_t port, char* buffer, int32_t count, int32_t *status) {
uint32_t retCount = 0;
*status = viRead(m_portHandle[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
if(*status == VI_ERROR_IO || *status == VI_ERROR_ASRL_OVERRUN || *status == VI_ERROR_ASRL_FRAMING || *status == VI_ERROR_ASRL_PARITY)
{
int32_t localStatus = 0;
serialClear(port, &localStatus);
}
if(*status == VI_ERROR_TMO || *status > 0)
*status = 0;
return retCount;
}
uint32_t serialWrite(uint8_t port, const char *buffer, int32_t count, int32_t *status) {
uint32_t retCount = 0;
*status = viWrite(m_portHandle[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
if(*status > 0)
*status = 0;
return retCount;
void serialSetTimeout(uint8_t port, float timeout, int32_t* status) {
*status = viSetAttribute(m_portHandle[port], VI_ATTR_TMO_VALUE,
(uint32_t)(timeout * 1e3));
if (*status > 0) *status = 0;
}
void serialFlush(uint8_t port, int32_t *status) {
*status = viFlush(m_portHandle[port], VI_WRITE_BUF);
if(*status > 0)
*status = 0;
void serialEnableTermination(uint8_t port, char terminator, int32_t* status) {
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR, terminator);
*status = viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_END_IN,
VI_ASRL_END_TERMCHAR);
if (*status > 0) *status = 0;
}
void serialClear(uint8_t port, int32_t *status) {
*status = viClear(m_portHandle[port]);
if(*status > 0)
*status = 0;
void serialDisableTermination(uint8_t port, int32_t* status) {
viSetAttribute(m_portHandle[port], VI_ATTR_TERMCHAR_EN, VI_FALSE);
*status =
viSetAttribute(m_portHandle[port], VI_ATTR_ASRL_END_IN, VI_ASRL_END_NONE);
if (*status > 0) *status = 0;
}
void serialClose(uint8_t port, int32_t *status) {
*status = viClose(m_portHandle[port]);
if(*status > 0)
*status = 0;
void serialSetReadBufferSize(uint8_t port, uint32_t size, int32_t* status) {
*status = viSetBuf(m_portHandle[port], VI_READ_BUF, size);
if (*status > 0) *status = 0;
}
void serialSetWriteBufferSize(uint8_t port, uint32_t size, int32_t* status) {
*status = viSetBuf(m_portHandle[port], VI_WRITE_BUF, size);
if (*status > 0) *status = 0;
}
int32_t serialGetBytesReceived(uint8_t port, int32_t* status) {
int32_t bytes = 0;
*status = viGetAttribute(m_portHandle[port], VI_ATTR_ASRL_AVAIL_NUM, &bytes);
if (*status > 0) *status = 0;
return bytes;
}
uint32_t serialRead(uint8_t port, char* buffer, int32_t count,
int32_t* status) {
uint32_t retCount = 0;
*status =
viRead(m_portHandle[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
if (*status == VI_ERROR_IO || *status == VI_ERROR_ASRL_OVERRUN ||
*status == VI_ERROR_ASRL_FRAMING || *status == VI_ERROR_ASRL_PARITY) {
int32_t localStatus = 0;
serialClear(port, &localStatus);
}
if (*status == VI_ERROR_TMO || *status > 0) *status = 0;
return retCount;
}
uint32_t serialWrite(uint8_t port, const char* buffer, int32_t count,
int32_t* status) {
uint32_t retCount = 0;
*status =
viWrite(m_portHandle[port], (ViPBuf)buffer, count, (ViPUInt32)&retCount);
if (*status > 0) *status = 0;
return retCount;
}
void serialFlush(uint8_t port, int32_t* status) {
*status = viFlush(m_portHandle[port], VI_WRITE_BUF);
if (*status > 0) *status = 0;
}
void serialClear(uint8_t port, int32_t* status) {
*status = viClear(m_portHandle[port]);
if (*status > 0) *status = 0;
}
void serialClose(uint8_t port, int32_t* status) {
*status = viClose(m_portHandle[port]);
if (*status > 0) *status = 0;
}
} // extern "C"

View File

@@ -7,101 +7,100 @@
#include "HAL/Solenoid.hpp"
#include "HAL/Port.h"
#include "HAL/Errors.hpp"
#include "ChipObject.h"
#include "FRC_NetworkCommunication/LoadOut.h"
#include "HAL/Errors.hpp"
#include "HAL/Port.h"
#include "ctre/PCM.h"
static const int NUM_MODULE_NUMBERS = 63;
PCM *PCM_modules[NUM_MODULE_NUMBERS] = { NULL };
PCM* PCM_modules[NUM_MODULE_NUMBERS] = {NULL};
struct solenoid_port_t {
PCM *module;
uint32_t pin;
PCM* module;
uint32_t pin;
};
void initializePCM(int module) {
if(!PCM_modules[module]) {
PCM_modules[module] = new PCM(module);
}
if (!PCM_modules[module]) {
PCM_modules[module] = new PCM(module);
}
}
extern "C" {
void* initializeSolenoidPort(void *port_pointer, int32_t *status) {
Port* port = (Port*) port_pointer;
initializePCM(port->module);
solenoid_port_t *solenoid_port = new solenoid_port_t;
solenoid_port->module = PCM_modules[port->module];
solenoid_port->pin = port->pin;
void* initializeSolenoidPort(void* port_pointer, int32_t* status) {
Port* port = (Port*)port_pointer;
initializePCM(port->module);
return solenoid_port;
solenoid_port_t* solenoid_port = new solenoid_port_t;
solenoid_port->module = PCM_modules[port->module];
solenoid_port->pin = port->pin;
return solenoid_port;
}
void freeSolenoidPort(void* solenoid_port_pointer) {
solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer;
delete port;
solenoid_port_t* port = (solenoid_port_t*)solenoid_port_pointer;
delete port;
}
bool checkSolenoidModule(uint8_t module) {
return module < NUM_MODULE_NUMBERS;
bool checkSolenoidModule(uint8_t module) { return module < NUM_MODULE_NUMBERS; }
bool getSolenoid(void* solenoid_port_pointer, int32_t* status) {
solenoid_port_t* port = (solenoid_port_t*)solenoid_port_pointer;
bool value;
*status = port->module->GetSolenoid(port->pin, value);
return value;
}
bool getSolenoid(void* solenoid_port_pointer, int32_t *status) {
solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer;
bool value;
uint8_t getAllSolenoids(void* solenoid_port_pointer, int32_t* status) {
solenoid_port_t* port = (solenoid_port_t*)solenoid_port_pointer;
uint8_t value;
*status = port->module->GetSolenoid(port->pin, value);
*status = port->module->GetAllSolenoids(value);
return value;
return value;
}
uint8_t getAllSolenoids(void* solenoid_port_pointer, int32_t *status) {
solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer;
uint8_t value;
void setSolenoid(void* solenoid_port_pointer, bool value, int32_t* status) {
solenoid_port_t* port = (solenoid_port_t*)solenoid_port_pointer;
*status = port->module->GetAllSolenoids(value);
return value;
*status = port->module->SetSolenoid(port->pin, value);
}
void setSolenoid(void* solenoid_port_pointer, bool value, int32_t *status) {
solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer;
int getPCMSolenoidBlackList(void* solenoid_port_pointer, int32_t* status) {
solenoid_port_t* port = (solenoid_port_t*)solenoid_port_pointer;
UINT8 value;
*status = port->module->SetSolenoid(port->pin, value);
*status = port->module->GetSolenoidBlackList(value);
return value;
}
bool getPCMSolenoidVoltageStickyFault(void* solenoid_port_pointer,
int32_t* status) {
solenoid_port_t* port = (solenoid_port_t*)solenoid_port_pointer;
bool value;
int getPCMSolenoidBlackList(void* solenoid_port_pointer, int32_t *status){
solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer;
UINT8 value;
*status = port->module->GetSolenoidBlackList(value);
*status = port->module->GetSolenoidStickyFault(value);
return value;
return value;
}
bool getPCMSolenoidVoltageStickyFault(void* solenoid_port_pointer, int32_t *status){
solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer;
bool value;
bool getPCMSolenoidVoltageFault(void* solenoid_port_pointer, int32_t* status) {
solenoid_port_t* port = (solenoid_port_t*)solenoid_port_pointer;
bool value;
*status = port->module->GetSolenoidStickyFault(value);
*status = port->module->GetSolenoidFault(value);
return value;
return value;
}
bool getPCMSolenoidVoltageFault(void* solenoid_port_pointer, int32_t *status){
solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer;
bool value;
void clearAllPCMStickyFaults_sol(void* solenoid_port_pointer, int32_t* status) {
solenoid_port_t* port = (solenoid_port_t*)solenoid_port_pointer;
*status = port->module->GetSolenoidFault(value);
return value;
}
void clearAllPCMStickyFaults_sol(void *solenoid_port_pointer, int32_t *status){
solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer;
*status = port->module->ClearStickyFaults();
*status = port->module->ClearStickyFaults();
}
} // extern "C"

View File

@@ -8,10 +8,10 @@
#include "HAL/Task.hpp"
#ifndef OK
#define OK 0
#define OK 0
#endif /* OK */
#ifndef ERROR
#define ERROR (-1)
#define ERROR (-1)
#endif /* ERROR */
#include <signal.h>
@@ -20,9 +20,9 @@ extern "C" {
STATUS verifyTaskID(TASK task) {
if (task != nullptr && pthread_kill(*task, 0) == 0) {
return OK;
return OK;
} else {
return ERROR;
return ERROR;
}
}
@@ -35,12 +35,10 @@ STATUS setTaskPriority(TASK task, int priority) {
param.sched_priority = priority;
if (pthread_setschedparam(*task, SCHED_FIFO, &param) == 0) {
return OK;
}
else {
} else {
return ERROR;
}
}
else {
} else {
return ERROR;
}
}
@@ -50,11 +48,10 @@ STATUS getTaskPriority(TASK task, int* priority) {
struct sched_param param;
if (verifyTaskID(task) == OK &&
pthread_getschedparam(*task, &policy, &param) == 0) {
pthread_getschedparam(*task, &policy, &param) == 0) {
*priority = param.sched_priority;
return OK;
}
else {
} else {
return ERROR;
}
}

View File

@@ -13,43 +13,40 @@ const int32_t HAL_WAIT_FOREVER = -1;
extern "C" {
void delayTicks(int32_t ticks)
{
struct timespec test, remaining;
test.tv_sec = 0;
test.tv_nsec = ticks * 3;
void delayTicks(int32_t ticks) {
struct timespec test, remaining;
test.tv_sec = 0;
test.tv_nsec = ticks * 3;
/* Sleep until the requested number of ticks has passed, with additional
time added if nanosleep is interrupted. */
while(nanosleep(&test, &remaining) == -1) {
test = remaining;
}
/* Sleep until the requested number of ticks has passed, with additional
time added if nanosleep is interrupted. */
while (nanosleep(&test, &remaining) == -1) {
test = remaining;
}
}
void delayMillis(double ms)
{
struct timespec test, remaining;
test.tv_sec = ms / 1000;
test.tv_nsec = 1000 * (((uint64_t)ms) % 1000000);
void delayMillis(double ms) {
struct timespec test, remaining;
test.tv_sec = ms / 1000;
test.tv_nsec = 1000 * (((uint64_t)ms) % 1000000);
/* Sleep until the requested number of milliseconds has passed, with
additional time added if nanosleep is interrupted. */
while(nanosleep(&test, &remaining) == -1) {
test = remaining;
}
/* Sleep until the requested number of milliseconds has passed, with
additional time added if nanosleep is interrupted. */
while (nanosleep(&test, &remaining) == -1) {
test = remaining;
}
}
void delaySeconds(double s)
{
struct timespec test, remaining;
test.tv_sec = (int)s;
test.tv_nsec = (s - (int)s) * 1000000000.0;
void delaySeconds(double s) {
struct timespec test, remaining;
test.tv_sec = (int)s;
test.tv_nsec = (s - (int)s) * 1000000000.0;
/* Sleep until the requested number of seconds has passed, with additional
time added if nanosleep is interrupted. */
while(nanosleep(&test, &remaining) == -1) {
test = remaining;
}
/* Sleep until the requested number of seconds has passed, with additional
time added if nanosleep is interrupted. */
while (nanosleep(&test, &remaining) == -1) {
test = remaining;
}
}
} // extern "C"

View File

@@ -6,8 +6,8 @@
/*----------------------------------------------------------------------------*/
#include "HAL/cpp/Resource.hpp"
#include "HAL/Errors.hpp"
#include <cstddef>
#include "HAL/Errors.hpp"
#include "HAL/cpp/priority_mutex.h"
namespace hal {
@@ -16,8 +16,9 @@ priority_recursive_mutex Resource::m_createLock;
/**
* Allocate storage for a new instance of Resource.
* Allocate a bool array of values that will get initialized to indicate that no resources
* have been allocated yet. The indicies of the resources are [0 .. elements - 1].
* Allocate a bool array of values that will get initialized to indicate that no
* resources have been allocated yet. The indicies of the resources are [0 ..
* elements - 1].
*/
Resource::Resource(uint32_t elements) {
std::lock_guard<priority_recursive_mutex> sync(m_createLock);
@@ -34,78 +35,69 @@ Resource::Resource(uint32_t elements) {
* track, that is, it will allocate resource numbers in the range
* [0 .. elements - 1].
*/
/*static*/ void Resource::CreateResourceObject(Resource **r, uint32_t elements)
{
std::lock_guard<priority_recursive_mutex> sync(m_createLock);
if (*r == NULL)
{
*r = new Resource(elements);
}
/*static*/ void Resource::CreateResourceObject(Resource** r,
uint32_t elements) {
std::lock_guard<priority_recursive_mutex> sync(m_createLock);
if (*r == NULL) {
*r = new Resource(elements);
}
}
/**
* Allocate a resource.
* When a resource is requested, mark it allocated. In this case, a free resource value
* When a resource is requested, mark it allocated. In this case, a free
* resource value
* within the range is located and returned after it is marked allocated.
*/
uint32_t Resource::Allocate(const char *resourceDesc)
{
std::lock_guard<priority_recursive_mutex> sync(m_allocateLock);
for (uint32_t i=0; i < m_isAllocated.size(); i++)
{
if (!m_isAllocated[i])
{
m_isAllocated[i] = true;
return i;
}
}
// TODO: wpi_setWPIErrorWithContext(NoAvailableResources, resourceDesc);
return ~0ul;
uint32_t Resource::Allocate(const char* resourceDesc) {
std::lock_guard<priority_recursive_mutex> sync(m_allocateLock);
for (uint32_t i = 0; i < m_isAllocated.size(); i++) {
if (!m_isAllocated[i]) {
m_isAllocated[i] = true;
return i;
}
}
// TODO: wpi_setWPIErrorWithContext(NoAvailableResources, resourceDesc);
return ~0ul;
}
/**
* Allocate a specific resource value.
* The user requests a specific resource value, i.e. channel number and it is verified
* unallocated, then returned.
* The user requests a specific resource value, i.e. channel number and it is
* verified unallocated, then returned.
*/
uint32_t Resource::Allocate(uint32_t index, const char *resourceDesc)
{
std::lock_guard<priority_recursive_mutex> sync(m_allocateLock);
if (index >= m_isAllocated.size())
{
// TODO: wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, resourceDesc);
return ~0ul;
}
if ( m_isAllocated[index] )
{
// TODO: wpi_setWPIErrorWithContext(ResourceAlreadyAllocated, resourceDesc);
return ~0ul;
}
m_isAllocated[index] = true;
return index;
uint32_t Resource::Allocate(uint32_t index, const char* resourceDesc) {
std::lock_guard<priority_recursive_mutex> sync(m_allocateLock);
if (index >= m_isAllocated.size()) {
// TODO: wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, resourceDesc);
return ~0ul;
}
if (m_isAllocated[index]) {
// TODO: wpi_setWPIErrorWithContext(ResourceAlreadyAllocated, resourceDesc);
return ~0ul;
}
m_isAllocated[index] = true;
return index;
}
/**
* Free an allocated resource.
* After a resource is no longer needed, for example a destructor is called for a channel assignment
* class, Free will release the resource value so it can be reused somewhere else in the program.
* After a resource is no longer needed, for example a destructor is called for
* a channel assignment class, Free will release the resource value so it can
* be reused somewhere else in the program.
*/
void Resource::Free(uint32_t index)
{
std::lock_guard<priority_recursive_mutex> sync(m_allocateLock);
if (index == ~0ul) return;
if (index >= m_isAllocated.size())
{
// TODO: wpi_setWPIError(NotAllocated);
return;
}
if (!m_isAllocated[index])
{
// TODO: wpi_setWPIError(NotAllocated);
return;
}
m_isAllocated[index] = false;
void Resource::Free(uint32_t index) {
std::lock_guard<priority_recursive_mutex> sync(m_allocateLock);
if (index == ~0ul) return;
if (index >= m_isAllocated.size()) {
// TODO: wpi_setWPIError(NotAllocated);
return;
}
if (!m_isAllocated[index]) {
// TODO: wpi_setWPIError(NotAllocated);
return;
}
m_isAllocated[index] = false;
}
} // namespace hal

View File

@@ -7,9 +7,7 @@
#include "HAL/cpp/Semaphore.hpp"
Semaphore::Semaphore(uint32_t count) {
m_count = count;
}
Semaphore::Semaphore(uint32_t count) { m_count = count; }
void Semaphore::give() {
std::lock_guard<priority_mutex> lock(m_mutex);
@@ -19,7 +17,7 @@ void Semaphore::give() {
void Semaphore::take() {
std::unique_lock<priority_mutex> lock(m_mutex);
m_condition.wait(lock, [this] { return m_count; } );
m_condition.wait(lock, [this] { return m_count; });
--m_count;
}
@@ -28,8 +26,7 @@ bool Semaphore::tryTake() {
if (m_count) {
--m_count;
return true;
}
else {
} else {
return false;
}
}

View File

@@ -7,34 +7,22 @@
#include "HAL/cpp/priority_mutex.h"
void priority_recursive_mutex::lock() {
pthread_mutex_lock(&m_mutex);
}
void priority_recursive_mutex::lock() { pthread_mutex_lock(&m_mutex); }
void priority_recursive_mutex::unlock() {
pthread_mutex_unlock(&m_mutex);
}
void priority_recursive_mutex::unlock() { pthread_mutex_unlock(&m_mutex); }
bool priority_recursive_mutex::try_lock() noexcept {
return !pthread_mutex_trylock(&m_mutex);
}
pthread_mutex_t* priority_recursive_mutex::native_handle() {
return &m_mutex;
}
pthread_mutex_t* priority_recursive_mutex::native_handle() { return &m_mutex; }
void priority_mutex::lock() {
pthread_mutex_lock(&m_mutex);
}
void priority_mutex::lock() { pthread_mutex_lock(&m_mutex); }
void priority_mutex::unlock() {
pthread_mutex_unlock(&m_mutex);
}
void priority_mutex::unlock() { pthread_mutex_unlock(&m_mutex); }
bool priority_mutex::try_lock() noexcept {
return !pthread_mutex_trylock(&m_mutex);
}
pthread_mutex_t* priority_mutex::native_handle() {
return &m_mutex;
}
pthread_mutex_t* priority_mutex::native_handle() { return &m_mutex; }

View File

@@ -1 +1 @@
//nothing here yet!
// nothing here yet!

View File

@@ -1,153 +1,137 @@
//This file must compile on ALL PLATFORMS. Be very careful what you put in here.
// This file must compile on ALL PLATFORMS. Be very careful what you put in
// here.
#include "HAL/HAL.hpp"
#include "FRC_NetworkCommunication/FRCComm.h"
#include <cstring>
#include "FRC_NetworkCommunication/FRCComm.h"
extern "C" {
int HALGetControlWord(HALControlWord *data)
{
return FRC_NetworkCommunication_getControlWord((ControlWord_t*) data);
int HALGetControlWord(HALControlWord* data) {
return FRC_NetworkCommunication_getControlWord((ControlWord_t*)data);
}
void HALSetNewDataSem(MULTIWAIT_ID sem)
{
setNewDataSem(sem->native_handle());
void HALSetNewDataSem(MULTIWAIT_ID sem) { setNewDataSem(sem->native_handle()); }
int HALGetAllianceStation(enum HALAllianceStationID* allianceStation) {
return FRC_NetworkCommunication_getAllianceStation(
(AllianceStationID_t*)allianceStation);
}
int HALGetAllianceStation(enum HALAllianceStationID *allianceStation)
{
return FRC_NetworkCommunication_getAllianceStation((AllianceStationID_t*) allianceStation);
int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes* axes) {
return FRC_NetworkCommunication_getJoystickAxes(
joystickNum, (JoystickAxes_t*)axes, kMaxJoystickAxes);
}
int HALGetJoystickAxes(uint8_t joystickNum, HALJoystickAxes *axes)
{
return FRC_NetworkCommunication_getJoystickAxes(joystickNum, (JoystickAxes_t*) axes, kMaxJoystickAxes);
int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs* povs) {
return FRC_NetworkCommunication_getJoystickPOVs(
joystickNum, (JoystickPOV_t*)povs, kMaxJoystickPOVs);
}
int HALGetJoystickPOVs(uint8_t joystickNum, HALJoystickPOVs *povs)
{
return FRC_NetworkCommunication_getJoystickPOVs(joystickNum, (JoystickPOV_t*) povs, kMaxJoystickPOVs);
}
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons *buttons)
{
return FRC_NetworkCommunication_getJoystickButtons(joystickNum, &buttons->buttons, &buttons->count);
int HALGetJoystickButtons(uint8_t joystickNum, HALJoystickButtons* buttons) {
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.
* @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.
* @return error code reported from Network Comm back-end. Zero is good,
* nonzero is bad.
*/
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor *desc)
{
desc->isXbox = 0;
desc->type = -1;
desc->name[0] = '\0';
desc->axisCount = kMaxJoystickAxes; /* set to the desc->axisTypes's capacity */
desc->buttonCount = 0;
desc->povCount = 0;
int retval = FRC_NetworkCommunication_getJoystickDesc(joystickNum, &desc->isXbox, &desc->type, (char *)(&desc->name),
&desc->axisCount, (uint8_t *)&desc->axisTypes, &desc->buttonCount, &desc->povCount);
/* check the return, if there is an error and the RIOimage predates FRC2017, then axisCount needs to be cleared */
if(retval != 0)
{
/* set count to zero so downstream code doesn't decode invalid axisTypes. */
desc->axisCount = 0;
}
return retval;
int HALGetJoystickDescriptor(uint8_t joystickNum, HALJoystickDescriptor* desc) {
desc->isXbox = 0;
desc->type = -1;
desc->name[0] = '\0';
desc->axisCount =
kMaxJoystickAxes; /* set to the desc->axisTypes's capacity */
desc->buttonCount = 0;
desc->povCount = 0;
int retval = FRC_NetworkCommunication_getJoystickDesc(
joystickNum, &desc->isXbox, &desc->type, (char*)(&desc->name),
&desc->axisCount, (uint8_t*)&desc->axisTypes, &desc->buttonCount,
&desc->povCount);
/* check the return, if there is an error and the RIOimage predates FRC2017,
* then axisCount needs to be cleared */
if (retval != 0) {
/* set count to zero so downstream code doesn't decode invalid axisTypes. */
desc->axisCount = 0;
}
return retval;
}
int HALGetJoystickIsXbox(uint8_t joystickNum)
{
HALJoystickDescriptor joystickDesc;
if(HALGetJoystickDescriptor(joystickNum, &joystickDesc)<0)
{
return 0;
}else
{
return joystickDesc.isXbox;
}
int HALGetJoystickIsXbox(uint8_t joystickNum) {
HALJoystickDescriptor joystickDesc;
if (HALGetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
return 0;
} else {
return joystickDesc.isXbox;
}
}
int HALGetJoystickType(uint8_t joystickNum)
{
HALJoystickDescriptor joystickDesc;
if(HALGetJoystickDescriptor(joystickNum, &joystickDesc)<0)
{
return -1;
} else
{
return joystickDesc.type;
}
int HALGetJoystickType(uint8_t joystickNum) {
HALJoystickDescriptor joystickDesc;
if (HALGetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
return -1;
} else {
return joystickDesc.type;
}
}
char* HALGetJoystickName(uint8_t joystickNum)
{
HALJoystickDescriptor joystickDesc;
if(HALGetJoystickDescriptor(joystickNum, &joystickDesc)<0)
{
char* name = (char*)std::malloc(1);
name[0] = '\0';
return name;
} else
{
size_t len = std::strlen(joystickDesc.name);
char* name = (char*)std::malloc(len+1);
std::strcpy(name, joystickDesc.name);
return name;
}
char* HALGetJoystickName(uint8_t joystickNum) {
HALJoystickDescriptor joystickDesc;
if (HALGetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
char* name = (char*)std::malloc(1);
name[0] = '\0';
return name;
} else {
size_t len = std::strlen(joystickDesc.name);
char* name = (char*)std::malloc(len + 1);
std::strcpy(name, joystickDesc.name);
return name;
}
}
int HALGetJoystickAxisType(uint8_t joystickNum, uint8_t axis)
{
HALJoystickDescriptor joystickDesc;
if(HALGetJoystickDescriptor(joystickNum, &joystickDesc)<0)
{
return -1;
} else
{
return joystickDesc.axisTypes[axis];
}
int HALGetJoystickAxisType(uint8_t joystickNum, uint8_t axis) {
HALJoystickDescriptor joystickDesc;
if (HALGetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
return -1;
} else {
return joystickDesc.axisTypes[axis];
}
}
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble)
{
return FRC_NetworkCommunication_setJoystickOutputs(joystickNum, outputs, leftRumble, rightRumble);
int HALSetJoystickOutputs(uint8_t joystickNum, uint32_t outputs,
uint16_t leftRumble, uint16_t rightRumble) {
return FRC_NetworkCommunication_setJoystickOutputs(joystickNum, outputs,
leftRumble, rightRumble);
}
int HALGetMatchTime(float *matchTime)
{
return FRC_NetworkCommunication_getMatchTime(matchTime);
int HALGetMatchTime(float* matchTime) {
return FRC_NetworkCommunication_getMatchTime(matchTime);
}
void HALNetworkCommunicationObserveUserProgramStarting(void)
{
FRC_NetworkCommunication_observeUserProgramStarting();
void HALNetworkCommunicationObserveUserProgramStarting(void) {
FRC_NetworkCommunication_observeUserProgramStarting();
}
void HALNetworkCommunicationObserveUserProgramDisabled(void)
{
FRC_NetworkCommunication_observeUserProgramDisabled();
void HALNetworkCommunicationObserveUserProgramDisabled(void) {
FRC_NetworkCommunication_observeUserProgramDisabled();
}
void HALNetworkCommunicationObserveUserProgramAutonomous(void)
{
FRC_NetworkCommunication_observeUserProgramAutonomous();
void HALNetworkCommunicationObserveUserProgramAutonomous(void) {
FRC_NetworkCommunication_observeUserProgramAutonomous();
}
void HALNetworkCommunicationObserveUserProgramTeleop(void)
{
FRC_NetworkCommunication_observeUserProgramTeleop();
void HALNetworkCommunicationObserveUserProgramTeleop(void) {
FRC_NetworkCommunication_observeUserProgramTeleop();
}
void HALNetworkCommunicationObserveUserProgramTest(void)
{
FRC_NetworkCommunication_observeUserProgramTest();
void HALNetworkCommunicationObserveUserProgramTest(void) {
FRC_NetworkCommunication_observeUserProgramTest();
}
} // extern "C"

View File

@@ -20,13 +20,14 @@ void Clock::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
gzmsg << "Initializing clock: " << topic << std::endl;
// Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
@@ -34,10 +35,11 @@ void Clock::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
// Connect to the world update event.
// This will trigger the Update function every Gazebo iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&Clock::Update, this, _1));
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&Clock::Update, this, _1));
}
void Clock::Update(const common::UpdateInfo &info) {
void Clock::Update(const common::UpdateInfo& info) {
msgs::Float64 msg;
msg.set_data(info.simTime.Double());
pub->Publish(msg);

View File

@@ -7,13 +7,11 @@
#pragma once
#include "simulation/gz_msgs/msgs.h"
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <gazebo/gazebo.hh>
using namespace gazebo;
@@ -34,8 +32,8 @@ using namespace gazebo;
*
* \todo Make WorldPlugin?
*/
class Clock: public ModelPlugin {
public:
class Clock : public ModelPlugin {
public:
Clock();
~Clock();
@@ -43,13 +41,13 @@ public:
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Sends out time each timestep.
void Update(const common::UpdateInfo &info);
void Update(const common::UpdateInfo& info);
private:
std::string topic; ///< \brief Publish the time on this topic.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::PublisherPtr pub; ///< \brief Publisher handle.
private:
std::string topic; ///< \brief Publish the time on this topic.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr
updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::PublisherPtr pub; ///< \brief Publisher handle.
};

View File

@@ -22,7 +22,7 @@ void DCMotor::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
if (sdf->HasElement("multiplier")) {
@@ -35,7 +35,8 @@ void DCMotor::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
<< " multiplier=" << multiplier << std::endl;
// Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
@@ -43,15 +44,19 @@ void DCMotor::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
// Connect to the world update event.
// This will trigger the Update function every Gazebo iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&DCMotor::Update, this, _1));
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&DCMotor::Update, this, _1));
}
void DCMotor::Update(const common::UpdateInfo &info) {
joint->SetForce(0, signal*multiplier);
void DCMotor::Update(const common::UpdateInfo& info) {
joint->SetForce(0, signal * multiplier);
}
void DCMotor::Callback(const msgs::ConstFloat64Ptr &msg) {
void DCMotor::Callback(const msgs::ConstFloat64Ptr& msg) {
signal = msg->data();
if (signal < -1) { signal = -1; }
else if (signal > 1) { signal = 1; }
if (signal < -1) {
signal = -1;
} else if (signal > 1) {
signal = 1;
}
}

View File

@@ -9,12 +9,9 @@
#include "simulation/gz_msgs/msgs.h"
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <gazebo/gazebo.hh>
using namespace gazebo;
@@ -38,8 +35,8 @@ using namespace gazebo;
* - `topic`: Optional. Message type should be gazebo.msgs.Float64.
* - `multiplier`: Optional. Defaults to 1.
*/
class DCMotor: public ModelPlugin {
public:
class DCMotor : public ModelPlugin {
public:
DCMotor();
~DCMotor();
@@ -47,9 +44,9 @@ public:
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Update the torque on the joint from the dc motor each timestep.
void Update(const common::UpdateInfo &info);
void Update(const common::UpdateInfo& info);
private:
private:
/// \brief Topic to read control signal from.
std::string topic;
@@ -63,11 +60,11 @@ private:
physics::JointPtr joint;
/// \brief Callback for receiving msgs and storing the signal.
void Callback(const msgs::ConstFloat64Ptr &msg);
void Callback(const msgs::ConstFloat64Ptr& msg);
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::SubscriberPtr sub; ///< \brief Subscriber handle.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr
updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::SubscriberPtr sub; ///< \brief Subscriber handle.
};

View File

@@ -21,7 +21,7 @@ void Encoder::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
if (sdf->HasElement("units")) {
@@ -37,20 +37,22 @@ void Encoder::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
<< " radians=" << radians << std::endl;
// Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
command_sub = node->Subscribe(topic+"/control", &Encoder::Callback, this);
pos_pub = node->Advertise<msgs::Float64>(topic+"/position");
vel_pub = node->Advertise<msgs::Float64>(topic+"/velocity");
command_sub = node->Subscribe(topic + "/control", &Encoder::Callback, this);
pos_pub = node->Advertise<msgs::Float64>(topic + "/position");
vel_pub = node->Advertise<msgs::Float64>(topic + "/velocity");
// Connect to the world update event.
// This will trigger the Update function every Gazebo iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&Encoder::Update, this, _1));
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&Encoder::Update, this, _1));
}
void Encoder::Update(const common::UpdateInfo &info) {
void Encoder::Update(const common::UpdateInfo& info) {
msgs::Float64 pos_msg, vel_msg;
if (stopped) {
pos_msg.set_data(stop_value);
@@ -65,18 +67,19 @@ void Encoder::Update(const common::UpdateInfo &info) {
}
}
void Encoder::Callback(const msgs::ConstStringPtr &msg) {
void Encoder::Callback(const msgs::ConstStringPtr& msg) {
std::string command = msg->data();
if (command == "reset") {
zero = GetAngle();
} else if (command == "start") {
stopped = false;
zero = (GetAngle() - stop_value);
} else if (command == "stop") {
} else if (command == "stop") {
stopped = true;
stop_value = GetAngle();
} else {
gzerr << "WARNING: Encoder got unknown command '" << command << "'." << std::endl;
gzerr << "WARNING: Encoder got unknown command '" << command << "'."
<< std::endl;
}
}
@@ -95,4 +98,3 @@ double Encoder::GetVelocity() {
return joint->GetVelocity(0) * (180.0 / M_PI);
}
}

View File

@@ -9,10 +9,9 @@
#include "simulation/gz_msgs/msgs.h"
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <gazebo/gazebo.hh>
using namespace gazebo;
@@ -38,12 +37,14 @@ using namespace gazebo;
* </plugin>
*
* - `joint`: Name of the joint this encoder is attached to.
* - `topic`: Optional. Used as the root for subtopics. `topic`/position (gazebo.msgs.Float64),
* `topic`/velocity (gazebo.msgs.Float64), `topic`/control (gazebo.msgs.String)
* - `topic`: Optional. Used as the root for subtopics. `topic`/position
* (gazebo.msgs.Float64),
* `topic`/velocity (gazebo.msgs.Float64), `topic`/control
* (gazebo.msgs.String)
* - `units`: Optional. Defaults to radians.
*/
class Encoder: public ModelPlugin {
public:
class Encoder : public ModelPlugin {
public:
Encoder();
~Encoder();
@@ -51,9 +52,9 @@ public:
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Sends out the encoder reading each timestep.
void Update(const common::UpdateInfo &info);
void Update(const common::UpdateInfo& info);
private:
private:
/// \brief Root topic for subtopics on this topic.
std::string topic;
@@ -73,7 +74,7 @@ private:
physics::JointPtr joint;
/// \brief Callback for handling control data
void Callback(const msgs::ConstStringPtr &msg);
void Callback(const msgs::ConstStringPtr& msg);
/// \brief Gets the current angle, taking into account whether to
/// return radians or degrees.
@@ -83,9 +84,10 @@ private:
/// return radians/second or degrees/second.
double GetVelocity();
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::SubscriberPtr command_sub; ///< \brief Subscriber handle.
transport::PublisherPtr pos_pub, vel_pub; ///< \brief Publisher handles.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr
updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::SubscriberPtr command_sub; ///< \brief Subscriber handle.
transport::PublisherPtr pos_pub, vel_pub; ///< \brief Publisher handles.
};

View File

@@ -7,7 +7,6 @@
#include "gyro.h"
GZ_REGISTER_MODEL_PLUGIN(Gyro)
Gyro::Gyro() {}
@@ -22,7 +21,7 @@ void Gyro::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
std::string axisString = sdf->Get<std::string>("axis");
@@ -41,20 +40,22 @@ void Gyro::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
<< " axis=" << axis << " radians=" << radians << std::endl;
// Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
command_sub = node->Subscribe(topic+"/control", &Gyro::Callback, this);
pos_pub = node->Advertise<msgs::Float64>(topic+"/position");
vel_pub = node->Advertise<msgs::Float64>(topic+"/velocity");
command_sub = node->Subscribe(topic + "/control", &Gyro::Callback, this);
pos_pub = node->Advertise<msgs::Float64>(topic + "/position");
vel_pub = node->Advertise<msgs::Float64>(topic + "/velocity");
// Connect to the world update event.
// This will trigger the Update function every Gazebo iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&Gyro::Update, this, _1));
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&Gyro::Update, this, _1));
}
void Gyro::Update(const common::UpdateInfo &info) {
void Gyro::Update(const common::UpdateInfo& info) {
msgs::Float64 pos_msg, vel_msg;
pos_msg.set_data(Limit(GetAngle() - zero));
pos_pub->Publish(pos_msg);
@@ -62,12 +63,13 @@ void Gyro::Update(const common::UpdateInfo &info) {
vel_pub->Publish(vel_msg);
}
void Gyro::Callback(const msgs::ConstStringPtr &msg) {
void Gyro::Callback(const msgs::ConstStringPtr& msg) {
std::string command = msg->data();
if (command == "reset") {
zero = GetAngle();
} else {
gzerr << "WARNING: Gyro got unknown command '" << command << "'." << std::endl;
gzerr << "WARNING: Gyro got unknown command '" << command << "'."
<< std::endl;
}
}
@@ -90,15 +92,21 @@ double Gyro::GetVelocity() {
double Gyro::Limit(double value) {
if (radians) {
while (true) {
if (value < -M_PI) value += 2*M_PI;
else if (value > M_PI) value -= 2*M_PI;
else break;
if (value < -M_PI)
value += 2 * M_PI;
else if (value > M_PI)
value -= 2 * M_PI;
else
break;
}
} else {
while (true) {
if (value < -180) value += 360;
else if (value > 180) value -= 360;
else break;
if (value < -180)
value += 360;
else if (value > 180)
value -= 360;
else
break;
}
}
return value;

View File

@@ -9,16 +9,14 @@
#include "simulation/gz_msgs/msgs.h"
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <gazebo/gazebo.hh>
using namespace gazebo;
/// \brief The axis about which to measure rotation.
typedef enum {Roll /*X*/, Pitch /*Y*/, Yaw /*Z*/} ROTATION;
typedef enum { Roll /*X*/, Pitch /*Y*/, Yaw /*Z*/ } ROTATION;
/**
* \brief Plugin for reading the speed and relative angle of a link.
@@ -38,12 +36,14 @@ typedef enum {Roll /*X*/, Pitch /*Y*/, Yaw /*Z*/} ROTATION;
* </plugin>
*
* - `link`: Name of the link this potentiometer is attached to.
* - `topic`: Optional. Used as the root for subtopics. `topic`/position (gazebo.msgs.Float64),
* `topic`/velocity (gazebo.msgs.Float64), `topic`/control (gazebo.msgs.String)
* - `topic`: Optional. Used as the root for subtopics. `topic`/position
* (gazebo.msgs.Float64),
* `topic`/velocity (gazebo.msgs.Float64), `topic`/control
* (gazebo.msgs.String)
* - `units`; Optional, defaults to radians.
*/
class Gyro: public ModelPlugin {
public:
class Gyro : public ModelPlugin {
public:
Gyro();
~Gyro();
@@ -51,9 +51,9 @@ public:
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Sends out the gyro reading each timestep.
void Update(const common::UpdateInfo &info);
void Update(const common::UpdateInfo& info);
private:
private:
/// \brief Publish the angle on this topic.
std::string topic;
@@ -70,7 +70,7 @@ private:
physics::LinkPtr link;
/// \brief Callback for handling control data
void Callback(const msgs::ConstStringPtr &msg);
void Callback(const msgs::ConstStringPtr& msg);
/// \brief Gets the current angle, taking into account whether to
/// return radians or degrees.
@@ -84,9 +84,10 @@ private:
/// depending on whether or radians or degrees are being used.
double Limit(double value);
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::SubscriberPtr command_sub; ///< \brief Subscriber handle.
transport::PublisherPtr pos_pub, vel_pub; ///< \brief Publisher handles.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr
updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::SubscriberPtr command_sub; ///< \brief Subscriber handle.
transport::PublisherPtr pos_pub, vel_pub; ///< \brief Publisher handles.
};

View File

@@ -7,12 +7,12 @@
#include "external_limit_switch.h"
ExternalLimitSwitch::ExternalLimitSwitch(sdf::ElementPtr sdf) {
sensor = boost::dynamic_pointer_cast<sensors::ContactSensor>(
sensors::get_sensor(sdf->Get<std::string>("sensor")));
sensors::get_sensor(sdf->Get<std::string>("sensor")));
gzmsg << "\texternal limit switch: " << " sensor=" << sensor->GetName() << std::endl;
gzmsg << "\texternal limit switch: "
<< " sensor=" << sensor->GetName() << std::endl;
}
ExternalLimitSwitch::~ExternalLimitSwitch() {}

View File

@@ -10,23 +10,23 @@
#include "switch.h"
#ifdef _WIN32
#include <Winsock2.h>
#include <Winsock2.h>
#endif
#include <gazebo/sensors/sensors.hh>
#include <boost/pointer_cast.hpp>
#include <gazebo/gazebo.hh>
#include <gazebo/sensors/sensors.hh>
using namespace gazebo;
class ExternalLimitSwitch : public Switch {
public:
public:
ExternalLimitSwitch(sdf::ElementPtr sdf);
~ExternalLimitSwitch();
/// \brief Returns true when the switch is triggered.
virtual bool Get();
private:
private:
sensors::ContactSensorPtr sensor;
};

View File

@@ -7,7 +7,8 @@
#include "internal_limit_switch.h"
InternalLimitSwitch::InternalLimitSwitch(physics::ModelPtr model, sdf::ElementPtr sdf) {
InternalLimitSwitch::InternalLimitSwitch(physics::ModelPtr model,
sdf::ElementPtr sdf) {
joint = model->GetJoint(sdf->Get<std::string>("joint"));
min = sdf->Get<double>("min");
max = sdf->Get<double>("max");
@@ -18,8 +19,9 @@ InternalLimitSwitch::InternalLimitSwitch(physics::ModelPtr model, sdf::ElementPt
radians = true;
}
gzmsg << "\tinternal limit switch: " << " type=" << joint->GetName()
<< " range=[" << min << "," << max << "] radians=" << radians << std::endl;
gzmsg << "\tinternal limit switch: "
<< " type=" << joint->GetName() << " range=[" << min << "," << max
<< "] radians=" << radians << std::endl;
}
InternalLimitSwitch::~InternalLimitSwitch() {}

View File

@@ -10,22 +10,22 @@
#include "switch.h"
#ifdef _WIN32
#include <Winsock2.h>
#include <Winsock2.h>
#endif
#include <gazebo/physics/physics.hh>
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
using namespace gazebo;
class InternalLimitSwitch : public Switch {
public:
public:
InternalLimitSwitch(physics::ModelPtr model, sdf::ElementPtr sdf);
~InternalLimitSwitch();
/// \brief Returns true when the switch is triggered.
virtual bool Get();
private:
private:
physics::JointPtr joint;
double min, max;
bool radians;

View File

@@ -20,11 +20,12 @@ void LimitSwitch::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
std::string type = sdf->Get<std::string>("type");
gzmsg << "Initializing limit switch: " << topic << " type=" << type << std::endl;
gzmsg << "Initializing limit switch: " << topic << " type=" << type
<< std::endl;
if (type == "internal") {
ls = new InternalLimitSwitch(model, sdf);
} else if (type == "external") {
@@ -34,7 +35,8 @@ void LimitSwitch::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
}
// Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
@@ -42,10 +44,11 @@ void LimitSwitch::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
// Connect to the world update event.
// This will trigger the Update function every Gazebo iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&LimitSwitch::Update, this, _1));
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&LimitSwitch::Update, this, _1));
}
void LimitSwitch::Update(const common::UpdateInfo &info) {
void LimitSwitch::Update(const common::UpdateInfo& info) {
msgs::Bool msg;
msg.set_data(ls->Get());
pub->Publish(msg);

View File

@@ -11,12 +11,12 @@
#include "switch.h"
#include "internal_limit_switch.h"
#include "external_limit_switch.h"
#include "internal_limit_switch.h"
#include <gazebo/gazebo.hh>
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <gazebo/gazebo.hh>
using namespace gazebo;
@@ -66,8 +66,8 @@ using namespace gazebo;
* External
* - `sensor`: Name of the contact sensor that this limit switch uses.
*/
class LimitSwitch: public ModelPlugin {
public:
class LimitSwitch : public ModelPlugin {
public:
LimitSwitch();
~LimitSwitch();
@@ -75,18 +75,18 @@ public:
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Sends out the limit switch reading each timestep.
void Update(const common::UpdateInfo &info);
void Update(const common::UpdateInfo& info);
private:
private:
/// \brief Publish the limit switch value on this topic.
std::string topic;
/// \brief LimitSwitch object, currently internal or external.
Switch* ls;
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::PublisherPtr pub; ///< \brief Publisher handle.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr
updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::PublisherPtr pub; ///< \brief Publisher handle.
};

View File

@@ -8,7 +8,7 @@
#pragma once
class Switch {
public:
public:
virtual ~Switch() {}
/// \brief Returns true when the switch is triggered.

View File

@@ -6,9 +6,9 @@
/*----------------------------------------------------------------------------*/
#ifdef _WIN32
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
#endif
#include "pneumatic_piston.h"
@@ -31,23 +31,25 @@ void PneumaticPiston::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
forward_force = sdf->Get<double>("forward-force");
reverse_force = sdf->Get<double>("reverse-force");
if (sdf->HasElement("direction") && sdf->Get<std::string>("direction") == "reversed") {
if (sdf->HasElement("direction") &&
sdf->Get<std::string>("direction") == "reversed") {
forward_force = -forward_force;
reverse_force = -reverse_force;
}
gzmsg << "Initializing piston: " << topic << " joint=" << joint->GetName()
<< " forward_force=" << forward_force
<< " reverse_force=" << reverse_force<< std::endl;
<< " reverse_force=" << reverse_force << std::endl;
// Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
@@ -55,14 +57,18 @@ void PneumaticPiston::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
// Connect to the world update event.
// This will trigger the Update function every Gazebo iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&PneumaticPiston::Update, this, _1));
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&PneumaticPiston::Update, this, _1));
}
void PneumaticPiston::Update(const common::UpdateInfo &info) {
void PneumaticPiston::Update(const common::UpdateInfo& info) {
joint->SetForce(0, signal);
}
void PneumaticPiston::Callback(const msgs::ConstFloat64Ptr &msg) {
if (msg->data() < -0.001) { signal = -reverse_force; }
else if (msg->data() > 0.001) { signal = forward_force; }
void PneumaticPiston::Callback(const msgs::ConstFloat64Ptr& msg) {
if (msg->data() < -0.001) {
signal = -reverse_force;
} else if (msg->data() > 0.001) {
signal = forward_force;
}
}

View File

@@ -47,8 +47,8 @@ using namespace gazebo;
*
* \todo Signal should probably be made a tri-state message.
*/
class PneumaticPiston: public ModelPlugin {
public:
class PneumaticPiston : public ModelPlugin {
public:
PneumaticPiston();
~PneumaticPiston();
@@ -56,9 +56,9 @@ public:
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Updat the force the piston applies on the joint.
void Update(const common::UpdateInfo &info);
void Update(const common::UpdateInfo& info);
private:
private:
/// \brief Topic to read control signal from.
std::string topic;
@@ -72,11 +72,11 @@ private:
physics::JointPtr joint;
/// \brief Callback for receiving msgs and updating the torque.
void Callback(const msgs::ConstFloat64Ptr &msg);
void Callback(const msgs::ConstFloat64Ptr& msg);
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::SubscriberPtr sub; ///< \brief Subscriber handle.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr
updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::SubscriberPtr sub; ///< \brief Subscriber handle.
};

View File

@@ -6,17 +6,16 @@
/*----------------------------------------------------------------------------*/
#ifdef _WIN32
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
#endif
#include "potentiometer.h"
#include <boost/algorithm/string.hpp>
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <boost/algorithm/string.hpp>
GZ_REGISTER_MODEL_PLUGIN(Potentiometer)
@@ -32,7 +31,7 @@ void Potentiometer::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
if (sdf->HasElement("units")) {
@@ -41,11 +40,12 @@ void Potentiometer::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
radians = true;
}
gzmsg << "Initializing potentiometer: " << topic << " joint=" << joint->GetName()
<< " radians=" << radians << std::endl;
gzmsg << "Initializing potentiometer: " << topic
<< " joint=" << joint->GetName() << " radians=" << radians << std::endl;
// Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
@@ -53,10 +53,11 @@ void Potentiometer::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
// Connect to the world update event.
// This will trigger the Update function every Gazebo iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&Potentiometer::Update, this, _1));
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&Potentiometer::Update, this, _1));
}
void Potentiometer::Update(const common::UpdateInfo &info) {
void Potentiometer::Update(const common::UpdateInfo& info) {
joint->GetAngle(0).Normalize();
msgs::Float64 msg;
if (radians) {

View File

@@ -32,8 +32,8 @@ using namespace gazebo;
* - `topic`: Optional. Message will be published as a gazebo.msgs.Float64.
* - `units`: Optional. Defaults to radians.
*/
class Potentiometer: public ModelPlugin {
public:
class Potentiometer : public ModelPlugin {
public:
Potentiometer();
~Potentiometer();
@@ -41,9 +41,9 @@ public:
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Sends out the potentiometer reading each timestep.
void Update(const common::UpdateInfo &info);
void Update(const common::UpdateInfo& info);
private:
private:
/// \brief Publish the angle on this topic.
std::string topic;
@@ -53,9 +53,9 @@ private:
/// \brief The joint that this potentiometer measures
physics::JointPtr joint;
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::PublisherPtr pub; ///< \brief Publisher handle.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr
updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::PublisherPtr pub; ///< \brief Publisher handle.
};

View File

@@ -6,16 +6,16 @@
/*----------------------------------------------------------------------------*/
#ifdef _WIN32
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
#endif
#include "rangefinder.h"
#include <gazebo/physics/physics.hh>
#include <gazebo/transport/transport.hh>
#include <gazebo/sensors/sensors.hh>
#include <gazebo/transport/transport.hh>
#include <boost/pointer_cast.hpp>
@@ -30,17 +30,19 @@ void Rangefinder::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
// Parse SDF properties
sensor = boost::dynamic_pointer_cast<sensors::SonarSensor>(
sensors::get_sensor(sdf->Get<std::string>("sensor")));
sensors::get_sensor(sdf->Get<std::string>("sensor")));
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
gzmsg << "Initializing rangefinder: " << topic << " sensor=" << sensor->GetName() << std::endl;
gzmsg << "Initializing rangefinder: " << topic
<< " sensor=" << sensor->GetName() << std::endl;
// Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
@@ -48,10 +50,11 @@ void Rangefinder::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
// Connect to the world update event.
// This will trigger the Update function every Gazebo iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&Rangefinder::Update, this, _1));
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&Rangefinder::Update, this, _1));
}
void Rangefinder::Update(const common::UpdateInfo &info) {
void Rangefinder::Update(const common::UpdateInfo& info) {
msgs::Float64 msg;
msg.set_data(sensor->GetRange());
pub->Publish(msg);

View File

@@ -30,8 +30,8 @@ using namespace gazebo;
* - `sensor`: Name of the sonar sensor that this rangefinder uses.
* - `topic`: Optional. Message will be published as a gazebo.msgs.Float64.
*/
class Rangefinder: public ModelPlugin {
public:
class Rangefinder : public ModelPlugin {
public:
Rangefinder();
~Rangefinder();
@@ -39,17 +39,18 @@ public:
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Sends out the rangefinder reading each timestep.
void Update(const common::UpdateInfo &info);
void Update(const common::UpdateInfo& info);
private:
private:
/// \brief Publish the range on this topic.
std::string topic;
/// \brief The sonar sensor that this rangefinder uses
sensors::SonarSensorPtr sensor;
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::PublisherPtr pub; ///< \brief Publisher handle.
physics::ModelPtr model; ///< \brief The model that this is attached to.
event::ConnectionPtr
updateConn; ///< \brief Pointer to the world update function.
transport::NodePtr node; ///< \brief The node we're advertising on.
transport::PublisherPtr pub; ///< \brief Publisher handle.
};

View File

@@ -6,9 +6,9 @@
/*----------------------------------------------------------------------------*/
#ifdef _WIN32
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
#endif
#include "servo.h"
@@ -22,56 +22,57 @@ Servo::Servo() {}
Servo::~Servo() {}
void Servo::Load(physics::ModelPtr model, sdf::ElementPtr sdf){
this->model = model;
signal = 0;
void Servo::Load(physics::ModelPtr model, sdf::ElementPtr sdf) {
this->model = model;
signal = 0;
//parse SDF Properries
joint = model->GetJoint(sdf->Get<std::string>("joint"));
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
}
else {
topic = "~/"+sdf->GetAttribute("name")->GetAsString();
}
if (sdf->HasElement("torque")) {
torque = sdf->Get<double>("torque");
}
else {
torque = 5;
}
gzmsg << "initializing awesome servo: " << topic
<< " joint=" << joint->GetName()
<< " torque=" << torque << std::endl;
//Connect to Gazebo transport for messaging
std::string scoped_name = model->GetWorld()->GetName()+"::"+model->GetScopedName();
boost::replace_all(scoped_name, "::","/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
sub = node->Subscribe(topic, &Servo::Callback, this);
//connect to the world update event
//this will call update every iteration
updateConn = event::Events::ConnectWorldUpdateBegin(boost::bind(&Servo::Update, this, _1));
}
void Servo::Update(const common::UpdateInfo &info){
//torque is in kg*cm
//joint->SetAngle(0,signal*180);
if (joint->GetAngle(0) < signal){
joint->SetForce(0,torque);
// parse SDF Properries
joint = model->GetJoint(sdf->Get<std::string>("joint"));
if (sdf->HasElement("topic")) {
topic = sdf->Get<std::string>("topic");
} else {
topic = "~/" + sdf->GetAttribute("name")->GetAsString();
}
else if (joint->GetAngle(0) > signal){
joint->SetForce(0,torque);
if (sdf->HasElement("torque")) {
torque = sdf->Get<double>("torque");
} else {
torque = 5;
}
joint->SetForce(0,0);
gzmsg << "initializing awesome servo: " << topic
<< " joint=" << joint->GetName() << " torque=" << torque << std::endl;
// Connect to Gazebo transport for messaging
std::string scoped_name =
model->GetWorld()->GetName() + "::" + model->GetScopedName();
boost::replace_all(scoped_name, "::", "/");
node = transport::NodePtr(new transport::Node());
node->Init(scoped_name);
sub = node->Subscribe(topic, &Servo::Callback, this);
// connect to the world update event
// this will call update every iteration
updateConn = event::Events::ConnectWorldUpdateBegin(
boost::bind(&Servo::Update, this, _1));
}
void Servo::Callback(const msgs::ConstFloat64Ptr &msg){
signal = msg->data();
if (signal < -1) { signal = -1; }
else if (signal > 1) { signal = 1; }
void Servo::Update(const common::UpdateInfo& info) {
// torque is in kg*cm
// joint->SetAngle(0,signal*180);
if (joint->GetAngle(0) < signal) {
joint->SetForce(0, torque);
} else if (joint->GetAngle(0) > signal) {
joint->SetForce(0, torque);
}
joint->SetForce(0, 0);
}
void Servo::Callback(const msgs::ConstFloat64Ptr& msg) {
signal = msg->data();
if (signal < -1) {
signal = -1;
} else if (signal > 1) {
signal = 1;
}
}

View File

@@ -31,36 +31,36 @@ using namespace gazebo;
* - `link`: Name of the link the servo is attached to.
* - `topic`: Optional. Message type should be gazebo.msgs.Float64.
*/
class Servo: public ModelPlugin {
public:
Servo();
~Servo();
class Servo : public ModelPlugin {
public:
Servo();
~Servo();
/// \brief load the servo and configure it according to the sdf
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief load the servo and configure it according to the sdf
void Load(physics::ModelPtr model, sdf::ElementPtr sdf);
/// \brief Update the torque on the joint from the dc motor each timestep.
void Update(const common::UpdateInfo &info);
/// \brief Update the torque on the joint from the dc motor each timestep.
void Update(const common::UpdateInfo& info);
private:
/// \brief Topic to read control signal from.
std::string topic;
private:
/// \brief Topic to read control signal from.
std::string topic;
/// \brief the pwm signal limited to the range [-1,1]
double signal;
/// \brief the pwm signal limited to the range [-1,1]
double signal;
/// \brief the torque of the motor in kg/cm
double torque;
/// \brief the torque of the motor in kg/cm
double torque;
/// \brief the joint that this servo moves
physics::JointPtr joint;
/// \brief the joint that this servo moves
physics::JointPtr joint;
/// \brief Callback for receiving msgs and storing the signal
void Callback(const msgs::ConstFloat64Ptr &msg);
physics::ModelPtr model; ///< \brief The model that this is attached to
event::ConnectionPtr updateConn; ///< \brief The Pointer to the world update function
transport::NodePtr node; ///< \brief The node we're advertising torque on
transport::SubscriberPtr sub; ///< \brief the Subscriber for the pwm signal
/// \brief Callback for receiving msgs and storing the signal
void Callback(const msgs::ConstFloat64Ptr& msg);
physics::ModelPtr model; ///< \brief The model that this is attached to
event::ConnectionPtr
updateConn; ///< \brief The Pointer to the world update function
transport::NodePtr node; ///< \brief The node we're advertising torque on
transport::SubscriberPtr sub; ///< \brief the Subscriber for the pwm signal
};

47
styleguide/format.py Executable file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env python3
from subprocess import call
import os
import re
import sys
sep = os.sep
# If directory separator is backslash, escape it for regexes
if sep == "\\":
sep += "\\"
# Files and directories which should be included in or excluded from the update
regexInclude = re.compile("\.cpp$|\.h$|\.hpp$|\.inc$")
folderExclude = "build" + sep + "|\.git" + sep + "|gradle" + sep + \
"|\.gradle" + sep + "|ni-libraries" + sep + "|ctre" + sep + \
"|frccansae" + sep + "|FRC_FPGA_ChipObject" + sep + \
"|gtest" + sep + "|i2clib" + sep + \
"|NetworkCommunication" + sep + "|spilib" + sep + \
"|visa" + sep + "|wpilibj" + sep
regexExclude = re.compile(folderExclude +
"|NIIMAQdx\.h$|nivision\.h$|can_proto\.h$|"
"CanTalonSRX\.h$")
# Handle running in either the root or styleguide directories
configPath = ""
if os.getcwd().rpartition("/")[2] == "styleguide":
configPath = ".."
else:
configPath = "."
# Recursively create list of files in given directory
files = [os.path.join(dp, f) for dp, dn, fn in
os.walk(os.path.expanduser(configPath)) for f in fn]
# Apply regex filters to list
files = [f for f in files if regexInclude.search(f)]
files = [f for f in files if not regexExclude.search(f)]
# Set clang-format name for platform
clangExec = "clang-format"
if sys.platform.startswith("win32"):
clangExec += ".exe"
for name in files:
print("Processing", name,)
call([clangExec, "-i", "-style=file", name])

View File

@@ -7,10 +7,10 @@
#pragma once
#include "interfaces/Accelerometer.h"
#include <memory>
#include "I2C.h"
#include "LiveWindow/LiveWindowSendable.h"
#include <memory>
#include "interfaces/Accelerometer.h"
/**
* ADXL345 Accelerometer on I2C.
@@ -52,7 +52,8 @@ class ADXL345_I2C : public Accelerometer,
};
public:
explicit ADXL345_I2C(Port port, Range range = kRange_2G, int deviceAddress = kAddress);
explicit ADXL345_I2C(Port port, Range range = kRange_2G,
int deviceAddress = kAddress);
virtual ~ADXL345_I2C() = default;
ADXL345_I2C(const ADXL345_I2C&) = delete;

View File

@@ -7,10 +7,10 @@
#pragma once
#include "interfaces/Accelerometer.h"
#include "SensorBase.h"
#include "SPI.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SPI.h"
#include "SensorBase.h"
#include "interfaces/Accelerometer.h"
#include <memory>

View File

@@ -7,10 +7,10 @@
#pragma once
#include "interfaces/Accelerometer.h"
#include "SensorBase.h"
#include "SPI.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SPI.h"
#include "SensorBase.h"
#include "interfaces/Accelerometer.h"
#include <memory>

View File

@@ -8,9 +8,9 @@
#pragma once
#include "GyroBase.h"
#include "HAL/cpp/priority_mutex.h"
#include "Notifier.h"
#include "SPI.h"
#include "HAL/cpp/priority_mutex.h"
#include <memory>

View File

@@ -8,26 +8,24 @@
#pragma once
#include "AnalogInput.h"
#include "SensorBase.h"
#include "PIDSource.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "PIDSource.h"
#include "SensorBase.h"
#include <memory>
/**
* Handle operation of an analog accelerometer.
* The accelerometer reads acceleration directly through the sensor. Many
* sensors have
* multiple axis and can be treated as multiple devices. Each is calibrated by
* finding
* the center value over a period of time.
* sensors have multiple axis and can be treated as multiple devices. Each is
* calibrated by finding the center value over a period of time.
*/
class AnalogAccelerometer : public SensorBase,
public PIDSource,
public LiveWindowSendable {
public:
explicit AnalogAccelerometer(int32_t channel);
explicit AnalogAccelerometer(AnalogInput *channel);
explicit AnalogAccelerometer(AnalogInput* channel);
explicit AnalogAccelerometer(std::shared_ptr<AnalogInput> channel);
virtual ~AnalogAccelerometer() = default;

View File

@@ -14,18 +14,13 @@ class AnalogInput;
/**
* Use a rate gyro to return the robots heading relative to a starting position.
* The Gyro class tracks the robots heading based on the starting position. As
* the robot
* rotates the new heading is computed by integrating the rate of rotation
* returned
* by the sensor. When the class is instantiated, it does a short calibration
* routine
* where it samples the gyro while at rest to determine the default offset. This
* is
* subtracted from each sample to determine the heading. This gyro class must be
* used
* with a channel that is assigned one of the Analog accumulators from the FPGA.
* See
* AnalogInput for the current accumulator assignments.
* the robot rotates the new heading is computed by integrating the rate of
* rotation returned by the sensor. When the class is instantiated, it does a
* short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to
* determine the heading. This gyro class must be used with a channel that is
* assigned one of the Analog accumulators from the FPGA. See AnalogInput for
* the current accumulator assignments.
*
* This class is for gyro sensors that connect to an analog input.
*/
@@ -38,10 +33,11 @@ class AnalogGyro : public GyroBase {
static constexpr float kDefaultVoltsPerDegreePerSecond = 0.007;
explicit AnalogGyro(int32_t channel);
explicit AnalogGyro(AnalogInput *channel);
explicit AnalogGyro(AnalogInput* channel);
explicit AnalogGyro(std::shared_ptr<AnalogInput> channel);
AnalogGyro(int32_t channel, uint32_t center, float offset);
AnalogGyro(std::shared_ptr<AnalogInput> channel, uint32_t center, float offset);
AnalogGyro(std::shared_ptr<AnalogInput> channel, uint32_t center,
float offset);
virtual ~AnalogGyro() = default;
float GetAngle() const override;

View File

@@ -8,9 +8,9 @@
#pragma once
#include "HAL/HAL.hpp"
#include "SensorBase.h"
#include "PIDSource.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "PIDSource.h"
#include "SensorBase.h"
#include <memory>
@@ -18,16 +18,13 @@
* Analog input class.
*
* Connected to each analog channel is an averaging and oversampling engine.
* This engine accumulates
* the specified ( by SetAverageBits() and SetOversampleBits() ) number of
* samples before returning a new
* value. This is not a sliding window average. The only difference between
* the oversampled samples and
* the averaged samples is that the oversampled samples are simply accumulated
* effectively increasing the
* resolution, while the averaged samples are divided by the number of samples
* to retain the resolution,
* but get more stable values.
* This engine accumulates the specified ( by SetAverageBits() and
* SetOversampleBits() ) number of samples before returning a new value. This
* is not a sliding window average. The only difference between the oversampled
* samples and the averaged samples is that the oversampled samples are simply
* accumulated effectively increasing the resolution, while the averaged samples
* are divided by the number of samples to retain the resolution, but get more
* stable values.
*/
class AnalogInput : public SensorBase,
public PIDSource,
@@ -64,7 +61,7 @@ class AnalogInput : public SensorBase,
void SetAccumulatorDeadband(int32_t deadband);
int64_t GetAccumulatorValue() const;
uint32_t GetAccumulatorCount() const;
void GetAccumulatorOutput(int64_t &value, uint32_t &count) const;
void GetAccumulatorOutput(int64_t& value, uint32_t& count) const;
static void SetSampleRate(float samplesPerSecond);
static float GetSampleRate();
@@ -80,8 +77,8 @@ class AnalogInput : public SensorBase,
private:
uint32_t m_channel;
//TODO: Adjust HAL to avoid use of raw pointers.
void *m_port;
// TODO: Adjust HAL to avoid use of raw pointers.
void* m_port;
int64_t m_accumulatorOffset;
std::shared_ptr<ITable> m_table;

View File

@@ -7,11 +7,11 @@
#pragma once
#include "HAL/HAL.hpp"
#include "SensorBase.h"
#include "LiveWindow/LiveWindowSendable.h"
#include <memory>
#include <cstdint>
#include <memory>
#include "HAL/HAL.hpp"
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
/**
* MXP analog output class.
@@ -33,7 +33,7 @@ class AnalogOutput : public SensorBase, public LiveWindowSendable {
protected:
uint32_t m_channel;
void *m_port;
void* m_port;
std::shared_ptr<ITable> m_table;
};

View File

@@ -6,8 +6,8 @@
/*----------------------------------------------------------------------------*/
#include "AnalogInput.h"
#include "interfaces/Potentiometer.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "interfaces/Potentiometer.h"
#include <memory>
@@ -43,7 +43,7 @@ class AnalogPotentiometer : public Potentiometer, public LiveWindowSendable {
explicit AnalogPotentiometer(int channel, double fullRange = 1.0,
double offset = 0.0);
explicit AnalogPotentiometer(AnalogInput *input, double fullRange = 1.0,
explicit AnalogPotentiometer(AnalogInput* input, double fullRange = 1.0,
double offset = 0.0);
explicit AnalogPotentiometer(std::shared_ptr<AnalogInput> input,

View File

@@ -7,8 +7,8 @@
#pragma once
#include "HAL/HAL.hpp"
#include "AnalogTriggerOutput.h"
#include "HAL/HAL.hpp"
#include "SensorBase.h"
class AnalogInput;
@@ -18,7 +18,7 @@ class AnalogTrigger : public SensorBase {
public:
explicit AnalogTrigger(int32_t channel);
explicit AnalogTrigger(AnalogInput *channel);
explicit AnalogTrigger(AnalogInput* channel);
virtual ~AnalogTrigger();
void SetLimitsVoltage(float lower, float upper);
@@ -28,9 +28,10 @@ class AnalogTrigger : public SensorBase {
uint32_t GetIndex() const;
bool GetInWindow();
bool GetTriggerState();
std::shared_ptr<AnalogTriggerOutput> CreateOutput(AnalogTriggerType type) const;
std::shared_ptr<AnalogTriggerOutput> CreateOutput(
AnalogTriggerType type) const;
private:
uint8_t m_index;
void *m_trigger;
void* m_trigger;
};

View File

@@ -11,48 +11,34 @@
class AnalogTrigger;
/**
* Class to represent a specific output from an analog trigger.
* This class is used to get the current output value and also as a
* DigitalSource
* to provide routing of an output to digital subsystems on the FPGA such as
* Counter, Encoder, and Interrupt.
/** Class to represent a specific output from an analog trigger.
* This class is used to get the current output value and also as a
* DigitalSource to provide routing of an output to digital subsystems on the
* FPGA such as Counter, Encoder, and Interrupt.
*
* The TriggerState output indicates the primary output value of the trigger.
* If the analog
* signal is less than the lower limit, the output is false. If the analog
* value is greater
* than the upper limit, then the output is true. If the analog value is in
* between, then
* the trigger output state maintains its most recent value.
* If the analog signal is less than the lower limit, the output is false. If
* the analog value is greater than the upper limit, then the output is true.
* If the analog value is in between, then the trigger output state maintains
* its most recent value.
*
* The InWindow output indicates whether or not the analog signal is inside the
* range defined
* by the limits.
* range defined by the limits.
*
* The RisingPulse and FallingPulse outputs detect an instantaneous transition
* from above the
* upper limit to below the lower limit, and vise versa. These pulses represent
* a rollover
* condition of a sensor and can be routed to an up / down couter or to
* interrupts. Because
* the outputs generate a pulse, they cannot be read directly. To help ensure
* that a rollover
* condition is not missed, there is an average rejection filter available that
* operates on the
* from above the upper limit to below the lower limit, and vise versa. These
* pulses represent a rollover condition of a sensor and can be routed to an up
* / down couter or to interrupts. Because the outputs generate a pulse, they
* cannot be read directly. To help ensure that a rollover condition is not
* missed, there is an average rejection filter available that operates on the
* upper 8 bits of a 12 bit number and selects the nearest outlyer of 3 samples.
* This will reject
* a sample that is (due to averaging or sampling) errantly between the two
* limits. This filter
* will fail if more than one sample in a row is errantly in between the two
* limits. You may see
* this problem if attempting to use this feature with a mechanical rollover
* sensor, such as a
* This will reject a sample that is (due to averaging or sampling) errantly
* between the two limits. This filter will fail if more than one sample in a
* row is errantly in between the two limits. You may see this problem if
* attempting to use this feature with a mechanical rollover sensor, such as a
* 360 degree no-stop potentiometer without signal conditioning, because the
* rollover transition
* is not sharp / clean enough. Using the averaging engine may help with this,
* but rotational speeds of
* the sensor will then be limited.
* rollover transition is not sharp / clean enough. Using the averaging engine
* may help with this, but rotational speeds of the sensor will then be limited.
*/
class AnalogTriggerOutput : public DigitalSource {
friend class AnalogTrigger;
@@ -67,12 +53,13 @@ class AnalogTriggerOutput : public DigitalSource {
virtual bool GetAnalogTriggerForRouting() const override;
protected:
AnalogTriggerOutput(const AnalogTrigger &trigger, AnalogTriggerType outputType);
AnalogTriggerOutput(const AnalogTrigger& trigger,
AnalogTriggerType outputType);
private:
// Uses reference rather than smart pointer because a user can not construct
// an AnalogTriggerOutput themselves and because the AnalogTriggerOutput
// should always be in scope at the same time as an AnalogTrigger.
const AnalogTrigger &m_trigger;
const AnalogTrigger& m_trigger;
AnalogTriggerType m_outputType;
};

View File

@@ -7,9 +7,9 @@
#pragma once
#include "interfaces/Accelerometer.h"
#include "SensorBase.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "interfaces/Accelerometer.h"
#include <memory>

View File

@@ -7,24 +7,24 @@
#pragma once
#include "ErrorBase.h"
#include "MotorSafety.h"
#include "Resource.h"
#include "MotorSafetyHelper.h"
#include "PIDOutput.h"
#include "CANSpeedController.h"
#include "HAL/cpp/Semaphore.hpp"
#include "HAL/HAL.hpp"
#include "LiveWindow/LiveWindowSendable.h"
#include "tables/ITableListener.h"
#include "NetworkCommunication/CANSessionMux.h"
#include "CAN/can_proto.h"
#include "CANSpeedController.h"
#include "ErrorBase.h"
#include "HAL/HAL.hpp"
#include "HAL/cpp/Semaphore.hpp"
#include "LiveWindow/LiveWindowSendable.h"
#include "MotorSafety.h"
#include "MotorSafetyHelper.h"
#include "NetworkCommunication/CANSessionMux.h"
#include "PIDOutput.h"
#include "Resource.h"
#include "tables/ITableListener.h"
#include <atomic>
#include "HAL/cpp/priority_mutex.h"
#include <memory>
#include <utility>
#include <sstream>
#include <utility>
#include "HAL/cpp/priority_mutex.h"
/**
* Luminary Micro / Vex Robotics Jaguar Speed Control
@@ -152,23 +152,23 @@ class CANJaguar : public MotorSafety,
void SetPositionReference(uint8_t reference);
uint8_t GetPositionReference() const;
uint8_t packPercentage(uint8_t *buffer, double value);
uint8_t packFXP8_8(uint8_t *buffer, double value);
uint8_t packFXP16_16(uint8_t *buffer, double value);
uint8_t packint16_t(uint8_t *buffer, int16_t value);
uint8_t packint32_t(uint8_t *buffer, int32_t value);
double unpackPercentage(uint8_t *buffer) const;
double unpackFXP8_8(uint8_t *buffer) const;
double unpackFXP16_16(uint8_t *buffer) const;
int16_t unpackint16_t(uint8_t *buffer) const;
int32_t unpackint32_t(uint8_t *buffer) const;
uint8_t packPercentage(uint8_t* buffer, double value);
uint8_t packFXP8_8(uint8_t* buffer, double value);
uint8_t packFXP16_16(uint8_t* buffer, double value);
uint8_t packint16_t(uint8_t* buffer, int16_t value);
uint8_t packint32_t(uint8_t* buffer, int32_t value);
double unpackPercentage(uint8_t* buffer) const;
double unpackFXP8_8(uint8_t* buffer) const;
double unpackFXP16_16(uint8_t* buffer) const;
int16_t unpackint16_t(uint8_t* buffer) const;
int32_t unpackint32_t(uint8_t* buffer) const;
void sendMessage(uint32_t messageID, const uint8_t *data, uint8_t dataSize,
void sendMessage(uint32_t messageID, const uint8_t* data, uint8_t dataSize,
int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
void requestMessage(uint32_t messageID,
int32_t period = CAN_SEND_PERIOD_NO_REPEAT);
bool getMessage(uint32_t messageID, uint32_t mask, uint8_t *data,
uint8_t *dataSize) const;
bool getMessage(uint32_t messageID, uint32_t mask, uint8_t* data,
uint8_t* dataSize) const;
void setupPeriodicStatus();
void updatePeriodicStatus() const;
@@ -196,7 +196,8 @@ class CANJaguar : public MotorSafety,
float m_faultTime = 0.0f;
// Which parameters have been verified since they were last set?
bool m_controlModeVerified = false; // Needs to be verified because it's set in the constructor
bool m_controlModeVerified =
false; // Needs to be verified because it's set in the constructor
bool m_speedRefVerified = true;
bool m_posRefVerified = true;
bool m_pVerified = true;

View File

@@ -22,8 +22,8 @@ class CANSpeedController : public SpeedController {
kSpeed = 2,
kPosition = 3,
kVoltage = 4,
kFollower = 5, // Not supported in Jaguar.
kMotionProfile = 6, // Not supported in Jaguar.
kFollower = 5, // Not supported in Jaguar.
kMotionProfile = 6, // Not supported in Jaguar.
};
// Helper function for the ControlMode enum
@@ -97,6 +97,6 @@ class CANSpeedController : public SpeedController {
virtual void ConfigMaxOutputVoltage(double voltage) = 0;
virtual void ConfigFaultTime(float faultTime) = 0;
// Hold off on interface until we figure out ControlMode enums.
// virtual void SetControlMode(ControlMode mode) = 0;
// virtual ControlMode GetControlMode() const = 0;
// virtual void SetControlMode(ControlMode mode) = 0;
// virtual ControlMode GetControlMode() const = 0;
};

View File

@@ -7,14 +7,14 @@
#pragma once
#include "SafePWM.h"
#include "CANSpeedController.h"
#include "HAL/CanTalonSRX.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "MotorSafetyHelper.h"
#include "PIDInterface.h"
#include "PIDOutput.h"
#include "PIDSource.h"
#include "PIDInterface.h"
#include "HAL/CanTalonSRX.h"
#include "MotorSafetyHelper.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SafePWM.h"
#include "tables/ITable.h"
#include <memory>
@@ -36,17 +36,22 @@ class CANTalon : public MotorSafety,
AnalogEncoder = 3,
EncRising = 4,
EncFalling = 5,
CtreMagEncoder_Relative = 6, //!< Cross The Road Electronics Magnetic Encoder in Absolute/PulseWidth Mode
CtreMagEncoder_Absolute = 7, //!< Cross The Road Electronics Magnetic Encoder in Relative/Quadrature Mode
CtreMagEncoder_Relative = 6, //!< Cross The Road Electronics Magnetic
//! Encoder in Absolute/PulseWidth Mode
CtreMagEncoder_Absolute = 7, //!< Cross The Road Electronics Magnetic
//! Encoder in Relative/Quadrature Mode
PulseWidth = 8,
};
/**
* Depending on the sensor type, Talon can determine if sensor is plugged in ot not.
* Depending on the sensor type, Talon can determine if sensor is plugged in
* ot not.
*/
enum FeedbackDeviceStatus {
FeedbackStatusUnknown = 0, //!< Sensor status could not be determined. Not all sensors can do this.
FeedbackStatusPresent = 1, //!< Sensor is present and working okay.
FeedbackStatusNotPresent = 2, //!< Sensor is not present, not plugged in, not powered, etc...
FeedbackStatusUnknown = 0, //!< Sensor status could not be determined. Not
//! all sensors can do this.
FeedbackStatusPresent = 1, //!< Sensor is present and working okay.
FeedbackStatusNotPresent =
2, //!< Sensor is not present, not plugged in, not powered, etc...
};
enum StatusFrameRate {
StatusFrameRateGeneral = 0,
@@ -59,27 +64,28 @@ class CANTalon : public MotorSafety,
* Enumerated types for Motion Control Set Values.
* When in Motion Profile control mode, these constants are paseed
* into set() to manipulate the motion profile executer.
* When changing modes, be sure to read the value back using getMotionProfileStatus()
* to ensure changes in output take effect before performing buffering actions.
* When changing modes, be sure to read the value back using
* getMotionProfileStatus() to ensure changes in output take effect before
* performing buffering actions.
* Disable will signal Talon to put motor output into neutral drive.
* Talon will stop processing motion profile points. This means the buffer is
* effectively disconnected from the executer, allowing the robot to gracefully
* clear and push new traj points. isUnderrun will get cleared.
* Talon will stop processing motion profile points. This means the buffer
* is effectively disconnected from the executer, allowing the robot to
* gracefully clear and push new traj points. isUnderrun will get cleared.
* The active trajectory is also cleared.
* Enable will signal Talon to pop a trajectory point from it's buffer and process it.
* If the active trajectory is empty, Talon will shift in the next point.
* If the active traj is empty, and so is the buffer, the motor drive is neutral and
* isUnderrun is set. When active traj times out, and buffer has at least one point,
* Talon shifts in next one, and isUnderrun is cleared. When active traj times out,
* and buffer is empty, Talon keeps processing active traj and sets IsUnderrun.
* Enable will signal Talon to pop a trajectory point from it's buffer and
* process it. If the active trajectory is empty, Talon will shift in the
* next point. If the active traj is empty, and so is the buffer, the motor
* drive is neutral and isUnderrun is set. When active traj times out, and
* buffer has at least one point, Talon shifts in next one, and isUnderrun
* is cleared. When active traj times out, and buffer is empty, Talon
* keeps processing active traj and sets IsUnderrun.
* Hold will signal Talon keep processing the active trajectory indefinitely.
* If the active traj is cleared, Talon will neutral motor drive. Otherwise
* Talon will keep processing the active traj but it will not shift in
* points from the buffer. This means the buffer is effectively disconnected
* from the executer, allowing the robot to gracefully clear and push
* new traj points.
* isUnderrun is set if active traj is empty, otherwise it is cleared.
* isLast signal is also cleared.
* Talon will keep processing the active traj but it will not shift in
* points from the buffer. This means the buffer is effectively
* disconnected from the executer, allowing the robot to gracefully clear
* and push new traj points. isUnderrun is set if active traj is empty,
* otherwise it is cleared. isLast signal is also cleared.
*
* Typical workflow:
* set(Disable),
@@ -87,8 +93,10 @@ class CANTalon : public MotorSafety,
* clear buffer and push buffer points,
* set(Enable) when enough points have been pushed to ensure no underruns,
* wait for MP to finish or decide abort,
* If MP finished gracefully set(Hold) to hold position servo and disconnect buffer,
* If MP is being aborted set(Disable) to neutral the motor and disconnect buffer,
* If MP finished gracefully set(Hold) to hold position servo and disconnect
* buffer,
* If MP is being aborted set(Disable) to neutral the motor and disconnect
* buffer,
* Confirm mode takes effect,
* clear buffer and push buffer points, and rinse-repeat.
*/
@@ -102,8 +110,8 @@ class CANTalon : public MotorSafety,
* This is simply a data transer object.
*/
struct TrajectoryPoint {
double position; //!< The position to servo to.
double velocity; //!< The velocity to feed-forward.
double position; //!< The position to servo to.
double velocity; //!< The velocity to feed-forward.
/**
* Time in milliseconds to process this point.
* Value should be between 1ms and 255ms. If value is zero
@@ -122,12 +130,15 @@ class CANTalon : public MotorSafety,
* Set to true to only perform the velocity feed-forward and not perform
* position servo. This is useful when learning how the position servo
* changes the motor response. The same could be accomplish by clearing the
* PID gains, however this is synchronous the streaming, and doesn't require restoing
* PID gains, however this is synchronous the streaming, and doesn't require
* restoing
* gains when finished.
*
* Additionaly setting this basically gives you direct control of the motor output
* Additionaly setting this basically gives you direct control of the motor
* output
* since motor output = targetVelocity X Kv, where Kv is our Fgain.
* This means you can also scheduling straight-throttle curves without relying on
* This means you can also scheduling straight-throttle curves without
* relying on
* a sensor.
*/
bool velocityOnly;
@@ -135,17 +146,22 @@ class CANTalon : public MotorSafety,
* Set to true to signal Talon that this is the final point, so do not
* attempt to pop another trajectory point from out of the Talon buffer.
* Instead continue processing this way point. Typically the velocity
* member variable should be zero so that the motor doesn't spin indefinitely.
* member variable should be zero so that the motor doesn't spin
* indefinitely.
*/
bool isLastPoint;
/**
/**
* Set to true to signal Talon to zero the selected sensor.
* When generating MPs, one simple method is to make the first target position zero,
* and the final target position the target distance from the current position.
* When generating MPs, one simple method is to make the first target
* position zero,
* and the final target position the target distance from the current
* position.
* Then when you fire the MP, the current position gets set to zero.
* If this is the intent, you can set zeroPos on the first trajectory point.
* If this is the intent, you can set zeroPos on the first trajectory
* point.
*
* Otherwise you can leave this false for all points, and offset the positions
* Otherwise you can leave this false for all points, and offset the
* positions
* of all trajectory points so they are correct.
*/
bool zeroPos;
@@ -158,9 +174,10 @@ class CANTalon : public MotorSafety,
/**
* The available empty slots in the trajectory buffer.
*
* The robot API holds a "top buffer" of trajectory points, so your applicaion
* can dump several points at once. The API will then stream them into the Talon's
* low-level buffer, allowing the Talon to act on them.
* The robot API holds a "top buffer" of trajectory points, so your
* applicaion can dump several points at once. The API will then stream
* them into the Talon's low-level buffer, allowing the Talon to act on
* them.
*/
unsigned int topBufferRem;
/**
@@ -180,8 +197,8 @@ class CANTalon : public MotorSafety,
bool hasUnderrun;
/**
* This is set if Talon needs to shift a point from its buffer into
* the active trajectory point however the buffer is empty. This gets cleared
* automatically when is resolved.
* the active trajectory point however the buffer is empty. This gets
* cleared automatically when is resolved.
*/
bool isUnderrun;
/**
@@ -194,9 +211,11 @@ class CANTalon : public MotorSafety,
*/
TrajectoryPoint activePoint;
/**
* The current output mode of the motion profile executer (disabled, enabled, or hold).
* When changing the set() value in MP mode, it's important to check this signal to
* confirm the change takes effect before interacting with the top buffer.
* The current output mode of the motion profile executer (disabled,
* enabled, or hold).
* When changing the set() value in MP mode, it's important to check this
* signal to confirm the change takes effect before interacting with the
* top buffer.
*/
SetValueMotionProfile outputEnable;
};
@@ -268,7 +287,8 @@ class CANTalon : public MotorSafety,
virtual int GetPulseWidthVelocity() const;
virtual int GetPulseWidthRiseToFallUs() const;
virtual int GetPulseWidthRiseToRiseUs() const;
virtual FeedbackDeviceStatus IsSensorPresent(FeedbackDevice feedbackDevice)const;
virtual FeedbackDeviceStatus IsSensorPresent(
FeedbackDevice feedbackDevice) const;
virtual bool GetForwardLimitOK() const override;
virtual bool GetReverseLimitOK() const override;
virtual uint16_t GetFaults() const override;
@@ -286,7 +306,8 @@ class CANTalon : public MotorSafety,
virtual void ConfigLimitMode(LimitMode mode) override;
virtual void ConfigForwardLimit(double forwardLimitPosition) override;
virtual void ConfigReverseLimit(double reverseLimitPosition) override;
void ConfigLimitSwitchOverrides(bool bForwardLimitSwitchEn, bool bReverseLimitSwitchEn);
void ConfigLimitSwitchOverrides(bool bForwardLimitSwitchEn,
bool bReverseLimitSwitchEn);
void ConfigForwardSoftLimitEnable(bool bForwardSoftLimitEn);
void ConfigReverseSoftLimitEnable(bool bReverseSoftLimitEn);
/**
@@ -312,18 +333,20 @@ class CANTalon : public MotorSafety,
*/
void ConfigRevLimitSwitchNormallyOpen(bool normallyOpen);
virtual void ConfigMaxOutputVoltage(double voltage) override;
void ConfigPeakOutputVoltage(double forwardVoltage,double reverseVoltage);
void ConfigNominalOutputVoltage(double forwardVoltage,double reverseVoltage);
void ConfigPeakOutputVoltage(double forwardVoltage, double reverseVoltage);
void ConfigNominalOutputVoltage(double forwardVoltage, double reverseVoltage);
/**
* Enables Talon SRX to automatically zero the Sensor Position whenever an
* edge is detected on the index signal.
* @param enable boolean input, pass true to enable feature or false to disable.
* @param risingEdge boolean input, pass true to clear the position on rising edge,
* pass false to clear the position on falling edge.
*
* @param enable boolean input, pass true to enable feature or false to
* disable.
* @param risingEdge boolean input, pass true to clear the position on rising
* edge, pass false to clear the position on falling edge.
*/
void EnableZeroSensorPositionOnIndex(bool enable, bool risingEdge);
void ConfigSetParameter(uint32_t paramEnum, double value);
bool GetParameter(uint32_t paramEnum, double & dvalue) const;
bool GetParameter(uint32_t paramEnum, double& dvalue) const;
virtual void ConfigFaultTime(float faultTime) override;
virtual void SetControlMode(ControlMode mode);
@@ -343,37 +366,39 @@ class CANTalon : public MotorSafety,
bool IsEnabled() const override;
double GetSetpoint() const override;
/**
* Calling application can opt to speed up the handshaking between the robot API and the Talon to increase the
* download rate of the Talon's Motion Profile. Ideally the period should be no more than half the period
* of a trajectory point.
* Calling application can opt to speed up the handshaking between the robot
* API and the Talon to increase the download rate of the Talon's Motion
* Profile. Ideally the period should be no more than half the period of a
* trajectory point.
*/
void ChangeMotionControlFramePeriod(int periodMs);
/**
* Clear the buffered motion profile in both Talon RAM (bottom), and in the API (top).
* Be sure to check GetMotionProfileStatus() to know when the buffer is actually cleared.
* Clear the buffered motion profile in both Talon RAM (bottom), and in the
* API (top). Be sure to check GetMotionProfileStatus() to know when the
* buffer is actually cleared.
*/
void ClearMotionProfileTrajectories();
/**
* Retrieve just the buffer count for the api-level (top) buffer.
* This routine performs no CAN or data structure lookups, so its fast and ideal
* if caller needs to quickly poll the progress of trajectory points being emptied
* into Talon's RAM. Otherwise just use GetMotionProfileStatus.
* This routine performs no CAN or data structure lookups, so its fast and
* ideal if caller needs to quickly poll the progress of trajectory points
* being emptied into Talon's RAM. Otherwise just use GetMotionProfileStatus.
* @return number of trajectory points in the top buffer.
*/
int GetMotionProfileTopLevelBufferCount();
/**
* Push another trajectory point into the top level buffer (which is emptied into
* the Talon's bottom buffer as room allows).
* Push another trajectory point into the top level buffer (which is emptied
* into the Talon's bottom buffer as room allows).
*
* @param trajPt the trajectory point to insert into buffer.
* @return true if trajectory point push ok. CTR_BufferFull if buffer is full
* due to kMotionProfileTopBufferCapacity.
* @return true if trajectory point push ok. CTR_BufferFull if buffer is full
* due to kMotionProfileTopBufferCapacity.
*/
bool PushMotionProfileTrajectory(const TrajectoryPoint & trajPt);
bool PushMotionProfileTrajectory(const TrajectoryPoint& trajPt);
/**
* @return true if api-level (top) buffer is full.
@@ -381,28 +406,34 @@ class CANTalon : public MotorSafety,
bool IsMotionProfileTopLevelBufferFull();
/**
* This must be called periodically to funnel the trajectory points from the API's top level buffer to
* the Talon's bottom level buffer. Recommendation is to call this twice as fast as the executation rate of the motion profile.
* So if MP is running with 20ms trajectory points, try calling this routine every 10ms. All motion profile functions are thread-safe
* through the use of a mutex, so there is no harm in having the caller utilize threading.
* This must be called periodically to funnel the trajectory points from the
* API's top level buffer to the Talon's bottom level buffer. Recommendation
* is to call this twice as fast as the executation rate of the motion
* profile. So if MP is running with 20ms trajectory points, try calling this
* routine every 10ms. All motion profile functions are thread-safe through
* the use of a mutex, so there is no harm in having the caller utilize
* threading.
*/
void ProcessMotionProfileBuffer();
/**
* Retrieve all status information.
* Since this all comes from one CAN frame, its ideal to have one routine to retrieve the frame once and decode everything.
* @param [out] motionProfileStatus contains all progress information on the currently running MP.
* Since this all comes from one CAN frame, its ideal to have one routine to
* retrieve the frame once and decode everything.
* @param [out] motionProfileStatus contains all progress information on the
* currently running MP.
*/
void GetMotionProfileStatus(MotionProfileStatus & motionProfileStatus);
void GetMotionProfileStatus(MotionProfileStatus& motionProfileStatus);
/**
* Clear the hasUnderrun flag in Talon's Motion Profile Executer when MPE is ready for another point,
* but the low level buffer is empty.
* Clear the hasUnderrun flag in Talon's Motion Profile Executer when MPE is
* ready for another point, but the low level buffer is empty.
*
* Once the Motion Profile Executer sets the hasUnderrun flag, it stays set until
* Robot Application clears it with this routine, which ensures Robot Application
* gets a chance to instrument or react. Caller could also check the isUnderrun flag
* which automatically clears when fault condition is removed.
* Once the Motion Profile Executer sets the hasUnderrun flag, it stays set
* until Robot Application clears it with this routine, which ensures Robot
* Application gets a chance to instrument or react. Caller could also check
* the isUnderrun flag which automatically clears when fault condition is
* removed.
*/
void ClearMotionProfileHasUnderrun();
@@ -437,7 +468,7 @@ class CANTalon : public MotorSafety,
std::unique_ptr<CanTalonSRX> m_impl;
std::unique_ptr<MotorSafetyHelper> m_safetyHelper;
int m_profile = 0; // Profile from CANTalon to use. Set to zero until we can
// actually test this.
// actually test this.
bool m_controlEnabled = true;
bool m_stopped = false;
@@ -447,37 +478,38 @@ class CANTalon : public MotorSafety,
double m_setPoint = 0;
/**
* Encoder CPR, counts per rotations, also called codes per revoluion.
* Default value of zero means the API behaves as it did during the 2015 season, each position
* unit is a single pulse and there are four pulses per count (4X).
* Caller can use ConfigEncoderCodesPerRev to set the quadrature encoder CPR.
* Default value of zero means the API behaves as it did during the 2015
* season, each position unit is a single pulse and there are four pulses per
* count (4X). Caller can use ConfigEncoderCodesPerRev to set the quadrature
* encoder CPR.
*/
uint32_t m_codesPerRev = 0;
/**
* Number of turns per rotation. For example, a 10-turn pot spins ten full rotations from
* a wiper voltage of zero to 3.3 volts. Therefore knowing the
* number of turns a full voltage sweep represents is necessary for calculating rotations
* and velocity.
* A default value of zero means the API behaves as it did during the 2015 season, there are 1024
* position units from zero to 3.3V.
* Number of turns per rotation. For example, a 10-turn pot spins ten full
* rotations from a wiper voltage of zero to 3.3 volts. Therefore knowing
* the number of turns a full voltage sweep represents is necessary for
* calculating rotations and velocity. A default value of zero means the API
* behaves as it did during the 2015 season, there are 1024 position units
* from zero to 3.3V.
*/
uint32_t m_numPotTurns = 0;
/**
* Although the Talon handles feedback selection, caching the feedback selection is helpful at the API level
* for scaling into rotations and RPM.
* Although the Talon handles feedback selection, caching the feedback
* selection is helpful at the API level for scaling into rotations and RPM.
*/
FeedbackDevice m_feedbackDevice = QuadEncoder;
static const unsigned int kDelayForSolicitedSignalsUs = 4000;
/**
* @param devToLookup FeedbackDevice to lookup the scalar for. Because Talon
* allows multiple sensors to be attached simultaneously, caller must
* specify which sensor to lookup.
* @return The number of native Talon units per rotation of the selected sensor.
* Zero if the necessary sensor information is not available.
* allows multiple sensors to be attached simultaneously,
* caller must specify which sensor to lookup.
* @return The number of native Talon units per rotation of the selected
* sensor. Zero if the necessary sensor information is not available.
* @see ConfigEncoderCodesPerRev
* @see ConfigPotentiometerTurns
*/
double GetNativeUnitsPerRotationScalar(FeedbackDevice devToLookup)const;
double GetNativeUnitsPerRotationScalar(FeedbackDevice devToLookup) const;
/**
* Fixup the sendMode so Set() serializes the correct demand value.
* Also fills the modeSelecet in the control frame to disabled.
@@ -486,43 +518,58 @@ class CANTalon : public MotorSafety,
*/
void ApplyControlMode(CANSpeedController::ControlMode mode);
/**
* @param fullRotations double precision value representing number of rotations of selected feedback sensor.
* If user has never called the config routine for the selected sensor, then the caller
* is likely passing rotations in engineering units already, in which case it is returned
* as is.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* @return fullRotations in native engineering units of the Talon SRX firmware.
* @param fullRotations double precision value representing number of
* rotations of selected feedback sensor. If user has
* never called the config routine for the selected
* sensor, then the caller is likely passing rotations
* in engineering units already, in which case it is
* returned as is.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* @return fullRotations in native engineering units of the Talon SRX
* firmware.
*/
int32_t ScaleRotationsToNativeUnits(FeedbackDevice devToLookup, double fullRotations) const;
int32_t ScaleRotationsToNativeUnits(FeedbackDevice devToLookup,
double fullRotations) const;
/**
* @param rpm double precision value representing number of rotations per minute of selected feedback sensor.
* If user has never called the config routine for the selected sensor, then the caller
* is likely passing rotations in engineering units already, in which case it is returned
* as is.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* @return sensor velocity in native engineering units of the Talon SRX firmware.
* @param rpm double precision value representing number of rotations per
* minute of selected feedback sensor. If user has never called
* the config routine for the selected sensor, then the caller is
* likely passing rotations in engineering units already, in which
* case it is returned as is.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* @return sensor velocity in native engineering units of the Talon SRX
* firmware.
*/
int32_t ScaleVelocityToNativeUnits(FeedbackDevice devToLookup, double rpm) const;
int32_t ScaleVelocityToNativeUnits(FeedbackDevice devToLookup,
double rpm) const;
/**
* @param nativePos integral position of the feedback sensor in native Talon SRX units.
* If user has never called the config routine for the selected sensor, then the return
* will be in TALON SRX units as well to match the behavior in the 2015 season.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* @return double precision number of rotations, unless config was never performed.
* @param nativePos integral position of the feedback sensor in native
* Talon SRX units. If user has never called the config
* routine for the selected sensor, then the return will be
* in TALON SRX units as well to match the behavior in the
* 2015 season.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* @return double precision number of rotations, unless config was never
* performed.
*/
double ScaleNativeUnitsToRotations(FeedbackDevice devToLookup, int32_t nativePos) const;
double ScaleNativeUnitsToRotations(FeedbackDevice devToLookup,
int32_t nativePos) const;
/**
* @param nativeVel integral velocity of the feedback sensor in native Talon SRX units.
* If user has never called the config routine for the selected sensor, then the return
* will be in TALON SRX units as well to match the behavior in the 2015 season.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* @return double precision of sensor velocity in RPM, unless config was never performed.
* @param nativeVel integral velocity of the feedback sensor in native
* Talon SRX units. If user has never called the config
* routine for the selected sensor, then the return will be
* in TALON SRX units as well to match the behavior in the
* 2015 season.
* @see ConfigPotentiometerTurns
* @see ConfigEncoderCodesPerRev
* @return double precision of sensor velocity in RPM, unless config was never
* performed.
*/
double ScaleNativeUnitsToRpm(FeedbackDevice devToLookup, int32_t nativeVel) const;
double ScaleNativeUnitsToRpm(FeedbackDevice devToLookup,
int32_t nativeVel) const;
// LiveWindow stuff.
std::shared_ptr<ITable> m_table;

View File

@@ -7,17 +7,17 @@
#pragma once
#include "USBCamera.h"
#include "ErrorBase.h"
#include "nivision.h"
#include "NIIMAQdx.h"
#include "USBCamera.h"
#include "nivision.h"
#include "HAL/cpp/priority_mutex.h"
#include <thread>
#include <memory>
#include <condition_variable>
#include <memory>
#include <thread>
#include <tuple>
#include <vector>
#include "HAL/cpp/priority_mutex.h"
class CameraServer : public ErrorBase {
private:

View File

@@ -9,9 +9,9 @@
#define Compressor_H_
#include "HAL/HAL.hpp"
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "tables/ITableListener.h"
#include "LiveWindow/LiveWindowSendable.h"
#include <memory>
@@ -55,7 +55,7 @@ class Compressor : public SensorBase,
std::shared_ptr<nt::Value> value, bool isNew) override;
protected:
void *m_pcm_pointer;
void* m_pcm_pointer;
private:
void SetCompressor(bool on);

View File

@@ -7,11 +7,11 @@
#pragma once
#include "HAL/HAL.hpp"
#include "AnalogTriggerOutput.h"
#include "CounterBase.h"
#include "SensorBase.h"
#include "HAL/HAL.hpp"
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include <memory>
@@ -20,10 +20,8 @@ class DigitalGlitchFilter;
/**
* Class for counting the number of ticks on a digital input channel.
* This is a general purpose class for counting repetitive events. It can return
* the number
* of counts, the period of the most recent cycle, and detect when the signal
* being counted
* has stopped by supplying a maximum cycle time.
* the number of counts, the period of the most recent cycle, and detect when
* the signal being counted has stopped by supplying a maximum cycle time.
*
* All counters will immediately start counting - Reset() them if you need them
* to be zeroed before use.
@@ -34,35 +32,35 @@ class Counter : public SensorBase,
public:
explicit Counter(Mode mode = kTwoPulse);
explicit Counter(int32_t channel);
explicit Counter(DigitalSource *source);
explicit Counter(DigitalSource* source);
explicit Counter(std::shared_ptr<DigitalSource> source);
DEPRECATED("Use pass-by-reference instead.")
explicit Counter(AnalogTrigger *trigger);
explicit Counter(const AnalogTrigger &trigger);
Counter(EncodingType encodingType, DigitalSource *upSource,
DigitalSource *downSource, bool inverted);
explicit Counter(AnalogTrigger* trigger);
explicit Counter(const AnalogTrigger& trigger);
Counter(EncodingType encodingType, DigitalSource* upSource,
DigitalSource* downSource, bool inverted);
Counter(EncodingType encodingType, std::shared_ptr<DigitalSource> upSource,
std::shared_ptr<DigitalSource> downSource, bool inverted);
virtual ~Counter();
void SetUpSource(int32_t channel);
void SetUpSource(AnalogTrigger *analogTrigger, AnalogTriggerType triggerType);
void SetUpSource(AnalogTrigger* analogTrigger, AnalogTriggerType triggerType);
void SetUpSource(std::shared_ptr<AnalogTrigger> analogTrigger,
AnalogTriggerType triggerType);
void SetUpSource(DigitalSource *source);
void SetUpSource(DigitalSource* source);
void SetUpSource(std::shared_ptr<DigitalSource> source);
void SetUpSource(DigitalSource &source);
void SetUpSource(DigitalSource& source);
void SetUpSourceEdge(bool risingEdge, bool fallingEdge);
void ClearUpSource();
void SetDownSource(int32_t channel);
void SetDownSource(AnalogTrigger *analogTrigger,
void SetDownSource(AnalogTrigger* analogTrigger,
AnalogTriggerType triggerType);
void SetDownSource(std::shared_ptr<AnalogTrigger> analogTrigger,
AnalogTriggerType triggerType);
void SetDownSource(DigitalSource *source);
void SetDownSource(DigitalSource* source);
void SetDownSource(std::shared_ptr<DigitalSource> source);
void SetDownSource(DigitalSource &source);
void SetDownSource(DigitalSource& source);
void SetDownSourceEdge(bool risingEdge, bool fallingEdge);
void ClearDownSource();
@@ -99,9 +97,9 @@ class Counter : public SensorBase,
// Makes the counter count down.
std::shared_ptr<DigitalSource> m_downSource;
// The FPGA counter object
void *m_counter = nullptr; ///< The FPGA counter object.
void* m_counter = nullptr; ///< The FPGA counter object.
private:
uint32_t m_index = 0; ///< The index of this counter.
uint32_t m_index = 0; ///< The index of this counter.
std::shared_ptr<ITable> m_table;
friend class DigitalGlitchFilter;

View File

@@ -9,8 +9,8 @@
#include <array>
#include "HAL/cpp/priority_mutex.h"
#include "DigitalSource.h"
#include "HAL/cpp/priority_mutex.h"
class Encoder;
class Counter;
@@ -26,13 +26,13 @@ class DigitalGlitchFilter : public SensorBase {
DigitalGlitchFilter();
~DigitalGlitchFilter();
void Add(DigitalSource *input);
void Add(Encoder *input);
void Add(Counter *input);
void Add(DigitalSource* input);
void Add(Encoder* input);
void Add(Counter* input);
void Remove(DigitalSource *input);
void Remove(Encoder *input);
void Remove(Counter *input);
void Remove(DigitalSource* input);
void Remove(Encoder* input);
void Remove(Counter* input);
void SetPeriodCycles(uint32_t fpga_cycles);
void SetPeriodNanoSeconds(uint64_t nanoseconds);
@@ -44,7 +44,7 @@ class DigitalGlitchFilter : public SensorBase {
// Sets the filter for the input to be the requested index. A value of 0
// disables the filter, and the filter value must be between 1 and 3,
// inclusive.
void DoAdd(DigitalSource *input, int requested_index);
void DoAdd(DigitalSource* input, int requested_index);
int m_channelIndex = -1;
static priority_mutex m_mutex;

View File

@@ -10,20 +10,18 @@
#include "DigitalSource.h"
#include "LiveWindow/LiveWindowSendable.h"
#include <memory>
#include <cstdint>
#include <memory>
class DigitalGlitchFilter;
/**
* Class to read a digital input.
* This class will read digital inputs and return the current value on the
* channel. Other devices
* such as encoders, gear tooth sensors, etc. that are implemented elsewhere
* will automatically
* allocate digital inputs and outputs as required. This class is only for
* devices like switches
* etc. that aren't implemented anywhere else.
* channel. Other devices such as encoders, gear tooth sensors, etc. that are
* implemented elsewhere will automatically allocate digital inputs and outputs
* as required. This class is only for devices like switches etc. that aren't
* implemented anywhere else.
*/
class DigitalInput : public DigitalSource, public LiveWindowSendable {
public:

View File

@@ -16,8 +16,8 @@
/**
* Class to write to digital outputs.
* Write values to the digital output channels. Other devices implemented
* elsewhere will allocate
* channels automatically so for those devices it shouldn't be done here.
* elsewhere will allocate channels automatically so for those devices it
* shouldn't be done here.
*/
class DigitalOutput : public DigitalSource,
public ITableListener,
@@ -50,7 +50,7 @@ class DigitalOutput : public DigitalSource,
private:
uint32_t m_channel;
void *m_pwmGenerator;
void* m_pwmGenerator;
std::shared_ptr<ITable> m_table;
};

View File

@@ -7,8 +7,8 @@
#pragma once
#include "SolenoidBase.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SolenoidBase.h"
#include "tables/ITableListener.h"
#include <memory>

View File

@@ -7,15 +7,15 @@
#pragma once
#include "SensorBase.h"
#include "RobotState.h"
#include "Task.h"
#include <atomic>
#include <condition_variable>
#include "HAL/HAL.hpp"
#include "HAL/cpp/Semaphore.hpp"
#include "HAL/cpp/priority_mutex.h"
#include "HAL/cpp/priority_condition_variable.h"
#include <condition_variable>
#include <atomic>
#include "HAL/cpp/priority_mutex.h"
#include "RobotState.h"
#include "SensorBase.h"
#include "Task.h"
struct HALControlWord;
class AnalogInput;
@@ -29,7 +29,7 @@ class DriverStation : public SensorBase, public RobotStateInterface {
enum Alliance { kRed, kBlue, kInvalid };
virtual ~DriverStation();
static DriverStation &GetInstance();
static DriverStation& GetInstance();
static void ReportError(std::string error);
static void ReportWarning(std::string error);
static void ReportError(bool is_error, int32_t code, const std::string& error,
@@ -70,26 +70,22 @@ class DriverStation : public SensorBase, public RobotStateInterface {
float GetBatteryVoltage() const;
/** Only to be used to tell the Driver Station what code you claim to be
* executing
* for diagnostic purposes only
* executing for diagnostic purposes only
* @param entering If true, starting disabled code; if false, leaving disabled
* code */
void InDisabled(bool entering) { m_userInDisabled = entering; }
/** Only to be used to tell the Driver Station what code you claim to be
* executing
* for diagnostic purposes only
* executing for diagnostic purposes only
* @param entering If true, starting autonomous code; if false, leaving
* autonomous code */
void InAutonomous(bool entering) { m_userInAutonomous = entering; }
/** Only to be used to tell the Driver Station what code you claim to be
* executing
* for diagnostic purposes only
* executing for diagnostic purposes only
* @param entering If true, starting teleop code; if false, leaving teleop
* code */
void InOperatorControl(bool entering) { m_userInTeleop = entering; }
/** Only to be used to tell the Driver Station what code you claim to be
* executing
* for diagnostic purposes only
* executing for diagnostic purposes only
* @param entering If true, starting test code; if false, leaving test code */
void InTest(bool entering) { m_userInTest = entering; }
@@ -99,7 +95,7 @@ class DriverStation : public SensorBase, public RobotStateInterface {
void GetData();
private:
static DriverStation *m_instance;
static DriverStation* m_instance;
void ReportJoystickUnpluggedError(std::string message);
void ReportJoystickUnpluggedWarning(std::string message);
void Run();

View File

@@ -7,12 +7,12 @@
#pragma once
#include "HAL/HAL.hpp"
#include "CounterBase.h"
#include "SensorBase.h"
#include "Counter.h"
#include "PIDSource.h"
#include "CounterBase.h"
#include "HAL/HAL.hpp"
#include "LiveWindow/LiveWindowSendable.h"
#include "PIDSource.h"
#include "SensorBase.h"
#include <memory>
@@ -22,17 +22,13 @@ class DigitalGlitchFilter;
/**
* Class to read quad encoders.
* Quadrature encoders are devices that count shaft rotation and can sense
* direction. The output of
* the QuadEncoder class is an integer that can count either up or down, and can
* go negative for
* reverse direction counting. When creating QuadEncoders, a direction is
* supplied that changes the
* sense of the output to make code more readable if the encoder is mounted such
* that forward movement
* generates negative values. Quadrature encoders have two digital outputs, an A
* Channel and a B Channel
* that are out of phase with each other to allow the FPGA to do direction
* sensing.
* direction. The output of the QuadEncoder class is an integer that can count
* either up or down, and can go negative for reverse direction counting. When
* creating QuadEncoders, a direction is supplied that changes the sense of the
* output to make code more readable if the encoder is mounted such that forward
* movement generates negative values. Quadrature encoders have two digital
* outputs, an A Channel and a B Channel that are out of phase with each other
* to allow the FPGA to do direction sensing.
*
* All encoders will immediately start counting - Reset() them if you need them
* to be zeroed before use.
@@ -52,11 +48,11 @@ class Encoder : public SensorBase,
Encoder(uint32_t aChannel, uint32_t bChannel, bool reverseDirection = false,
EncodingType encodingType = k4X);
Encoder(std::shared_ptr<DigitalSource> aSource,
std::shared_ptr<DigitalSource> bSource,
std::shared_ptr<DigitalSource> bSource, bool reverseDirection = false,
EncodingType encodingType = k4X);
Encoder(DigitalSource* aSource, DigitalSource* bSource,
bool reverseDirection = false, EncodingType encodingType = k4X);
Encoder(DigitalSource *aSource, DigitalSource *bSource,
bool reverseDirection = false, EncodingType encodingType = k4X);
Encoder(DigitalSource &aSource, DigitalSource &bSource,
Encoder(DigitalSource& aSource, DigitalSource& bSource,
bool reverseDirection = false, EncodingType encodingType = k4X);
virtual ~Encoder();
@@ -81,9 +77,9 @@ class Encoder : public SensorBase,
void SetIndexSource(uint32_t channel, IndexingType type = kResetOnRisingEdge);
DEPRECATED("Use pass-by-reference instead.")
void SetIndexSource(DigitalSource *source,
void SetIndexSource(DigitalSource* source,
IndexingType type = kResetOnRisingEdge);
void SetIndexSource(const DigitalSource &source,
void SetIndexSource(const DigitalSource& source,
IndexingType type = kResetOnRisingEdge);
void UpdateTable() override;
@@ -99,15 +95,15 @@ class Encoder : public SensorBase,
void InitEncoder(bool _reverseDirection, EncodingType encodingType);
double DecodingScaleFactor() const;
std::shared_ptr<DigitalSource> m_aSource; // the A phase of the quad encoder
std::shared_ptr<DigitalSource> m_bSource; // the B phase of the quad encoder
void *m_encoder = nullptr;
int32_t m_index = 0; // The encoder's FPGA index.
double m_distancePerPulse = 1.0; // distance of travel for each encoder tick
std::shared_ptr<DigitalSource> m_aSource; // the A phase of the quad encoder
std::shared_ptr<DigitalSource> m_bSource; // the B phase of the quad encoder
void* m_encoder = nullptr;
int32_t m_index = 0; // The encoder's FPGA index.
double m_distancePerPulse = 1.0; // distance of travel for each encoder tick
std::unique_ptr<Counter> m_counter =
nullptr; // Counter object for 1x and 2x encoding
EncodingType m_encodingType; // Encoding type
int32_t m_encodingScale; // 1x, 2x, or 4x, per the encodingType
nullptr; // Counter object for 1x and 2x encoding
EncodingType m_encodingType; // Encoding type
int32_t m_encodingScale; // 1x, 2x, or 4x, per the encodingType
std::shared_ptr<ITable> m_table;
friend class DigitalGlitchFilter;

View File

@@ -7,23 +7,21 @@
#pragma once
#include "Counter.h"
#include <memory>
#include "Counter.h"
/**
* Alias for counter class.
* Implement the gear tooth sensor supplied by FIRST. Currently there is no
* reverse sensing on
* the gear tooth sensor, but in future versions we might implement the
* necessary timing in the
* FPGA to sense direction.
* reverse sensing on the gear tooth sensor, but in future versions we might
* implement the necessary timing in the FPGA to sense direction.
*/
class GearTooth : public Counter {
public:
/// 55 uSec for threshold
static constexpr double kGearToothThreshold = 55e-6;
GearTooth(uint32_t channel, bool directionSensitive = false);
GearTooth(DigitalSource *source, bool directionSensitive = false);
GearTooth(DigitalSource* source, bool directionSensitive = false);
GearTooth(std::shared_ptr<DigitalSource> source,
bool directionSensitive = false);
virtual ~GearTooth() = default;

View File

@@ -26,16 +26,16 @@ class I2C : SensorBase {
I2C(const I2C&) = delete;
I2C& operator=(const I2C&) = delete;
bool Transaction(uint8_t *dataToSend, uint8_t sendSize, uint8_t *dataReceived,
bool Transaction(uint8_t* dataToSend, uint8_t sendSize, uint8_t* dataReceived,
uint8_t receiveSize);
bool AddressOnly();
bool Write(uint8_t registerAddress, uint8_t data);
bool WriteBulk(uint8_t *data, uint8_t count);
bool Read(uint8_t registerAddress, uint8_t count, uint8_t *data);
bool ReadOnly(uint8_t count, uint8_t *buffer);
bool WriteBulk(uint8_t* data, uint8_t count);
bool Read(uint8_t registerAddress, uint8_t count, uint8_t* data);
bool ReadOnly(uint8_t count, uint8_t* buffer);
void Broadcast(uint8_t registerAddress, uint8_t data);
bool VerifySensor(uint8_t registerAddress, uint8_t count,
const uint8_t *expected);
const uint8_t* expected);
private:
Port m_port;

View File

@@ -8,8 +8,8 @@
#pragma once
#include "HAL/HAL.hpp"
#include "SensorBase.h"
#include "Resource.h"
#include "SensorBase.h"
#include <memory>
@@ -29,23 +29,24 @@ class InterruptableSensorBase : public SensorBase {
virtual bool GetAnalogTriggerForRouting() const = 0;
virtual void RequestInterrupts(
InterruptHandlerFunction handler,
void *param); ///< Asynchronus handler version.
void* param); ///< Asynchronus handler version.
virtual void RequestInterrupts(); ///< Synchronus Wait version.
virtual void
CancelInterrupts(); ///< Free up the underlying chipobject functions.
virtual WaitResult WaitForInterrupt(
float timeout, bool ignorePrevious = true); ///< Synchronus version.
float timeout,
bool ignorePrevious = true); ///< Synchronus version.
virtual void
EnableInterrupts(); ///< Enable interrupts - after finishing setup.
virtual void DisableInterrupts(); ///< Disable, but don't deallocate.
virtual double ReadRisingTimestamp(); ///< Return the timestamp for the
///rising interrupt that occurred.
/// rising interrupt that occurred.
virtual double ReadFallingTimestamp(); ///< Return the timestamp for the
///falling interrupt that occurred.
/// falling interrupt that occurred.
virtual void SetUpSourceEdge(bool risingEdge, bool fallingEdge);
protected:
void *m_interrupt = nullptr;
void* m_interrupt = nullptr;
uint32_t m_interruptIndex = std::numeric_limits<uint32_t>::max();
void AllocateInterrupts(bool watcher);

View File

@@ -7,8 +7,8 @@
#pragma once
#include "Timer.h"
#include "RobotBase.h"
#include "Timer.h"
/**
* IterativeRobot implements a specific type of Robot Program framework,
@@ -18,8 +18,7 @@
* robot program.
*
* This class is intended to implement the "old style" default code, by
* providing
* the following functions which are called by the main loop,
* providing the following functions which are called by the main loop,
* StartCompetition(), at the appropriate times:
*
* RobotInit() -- provide for initialization at robot power-on
@@ -28,19 +27,17 @@
* appropriate mode is entered:
* - DisabledInit() -- called only when first disabled
* - AutonomousInit() -- called each and every time autonomous is entered from
* another mode
* another mode
* - TeleopInit() -- called each and every time teleop is entered from
* another mode
* another mode
* - TestInit() -- called each and every time test is entered from
* another mode
* another mode
*
* Periodic() functions -- each of these functions is called iteratively at the
* appropriate periodic rate (aka the "slow loop"). The
* default period of
* the iterative robot is synced to the driver station
* control packets,
* giving a periodic frequency of about 50Hz (50 times
* per second).
* default period of the iterative robot is synced to
* the driver station control packets, giving a periodic
* frequency of about 50Hz (50 times per second).
* - DisabledPeriodic()
* - AutonomousPeriodic()
* - TeleopPeriodic()

View File

@@ -11,18 +11,17 @@
#include <cstdint>
#include <memory>
#include <vector>
#include "GenericHID.h"
#include "ErrorBase.h"
#include "GenericHID.h"
class DriverStation;
/**
* Handle input from standard Joysticks connected to the Driver Station.
* This class handles standard input that comes from the Driver Station. Each
* time a value is requested
* the most recent value is returned. There is a single class instance for each
* joystick and the mapping
* of ports to hardware buttons depends on the code in the driver station.
* time a value is requested the most recent value is returned. There is a
* single class instance for each joystick and the mapping of ports to hardware
* buttons depends on the code in the driver station.
*/
class Joystick : public GenericHID, public ErrorBase {
public:
@@ -86,7 +85,7 @@ class Joystick : public GenericHID, public ErrorBase {
virtual bool GetRawButton(uint32_t button) const override;
virtual int GetPOV(uint32_t pov = 0) const override;
bool GetButton(ButtonType button) const;
static Joystick *GetStickForPort(uint32_t port);
static Joystick* GetStickForPort(uint32_t port);
virtual float GetMagnitude() const;
virtual float GetDirectionRadians() const;
@@ -106,7 +105,7 @@ class Joystick : public GenericHID, public ErrorBase {
void SetOutputs(uint32_t value);
private:
DriverStation &m_ds;
DriverStation& m_ds;
uint32_t m_port;
std::vector<uint32_t> m_axes;
std::vector<uint32_t> m_buttons;

View File

@@ -16,7 +16,7 @@ class MotorSafety;
class MotorSafetyHelper : public ErrorBase {
public:
MotorSafetyHelper(MotorSafety *safeObject);
MotorSafetyHelper(MotorSafety* safeObject);
~MotorSafetyHelper();
void Feed();
void SetExpiration(float expirationTime);
@@ -28,14 +28,18 @@ class MotorSafetyHelper : public ErrorBase {
static void CheckMotors();
private:
double m_expiration; // the expiration time for this object
bool m_enabled; // true if motor safety is enabled for this motor
double m_stopTime; // the FPGA clock value when this motor has expired
mutable priority_recursive_mutex
m_syncMutex; // protect accesses to the state for this object
MotorSafety *m_safeObject; // the object that is using the helper
// the expiration time for this object
double m_expiration;
// true if motor safety is enabled for this motor
bool m_enabled;
// the FPGA clock value when this motor has expired
double m_stopTime;
// protect accesses to the state for this object
mutable priority_recursive_mutex m_syncMutex;
// the object that is using the helper
MotorSafety* m_safeObject;
// List of all existing MotorSafetyHelper objects.
static std::set<MotorSafetyHelper*> m_helperList;
static priority_recursive_mutex
m_listMutex; // protect accesses to the list of helpers
// protect accesses to the list of helpers
static priority_recursive_mutex m_listMutex;
};

View File

@@ -20,8 +20,7 @@ class Notifier : public ErrorBase {
template <typename Callable, typename Arg, typename... Args>
Notifier(Callable&& f, Arg&& arg, Args&&... args)
: Notifier(std::bind(std::forward<Callable>(f),
std::forward<Arg>(arg),
: Notifier(std::bind(std::forward<Callable>(f), std::forward<Arg>(arg),
std::forward<Args>(args)...)) {}
virtual ~Notifier();
@@ -37,12 +36,12 @@ class Notifier : public ErrorBase {
// update the HAL alarm
void UpdateAlarm();
// HAL callback
static void Notify(uint64_t currentTimeInt, void *param);
static void Notify(uint64_t currentTimeInt, void* param);
// held while updating process information
priority_mutex m_processMutex;
// HAL handle
void *m_notifier;
void* m_notifier;
// address of the handler
TimerEventHandler m_handler;
// the absolute expiration time

View File

@@ -7,8 +7,8 @@
#pragma once
#include "SensorBase.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "tables/ITableListener.h"
#include <memory>
@@ -17,10 +17,9 @@
* Class implements the PWM generation in the FPGA.
*
* The values supplied as arguments for PWM outputs range from -1.0 to 1.0. They
* are mapped
* to the hardware dependent values, in this case 0-2000 for the FPGA.
* Changes are immediately sent to the FPGA, and the update occurs at the next
* FPGA cycle. There is no delay.
* are mapped to the hardware dependent values, in this case 0-2000 for the
* FPGA. Changes are immediately sent to the FPGA, and the update occurs at the
* next FPGA cycle. There is no delay.
*
* As of revision 0.1.10 of the FPGA, the FPGA interprets the 0-2000 values as
* follows:
@@ -59,23 +58,19 @@ class PWM : public SensorBase,
* kDefaultPwmPeriod is in ms
*
* - 20ms periods (50 Hz) are the "safest" setting in that this works for all
* devices
* devices
* - 20ms periods seem to be desirable for Vex Motors
* - 20ms periods are the specified period for HS-322HD servos, but work
* reliably down
* to 10.0 ms; starting at about 8.5ms, the servo sometimes hums and get
*hot;
* by 5.0ms the hum is nearly continuous
* reliably down to 10.0 ms; starting at about 8.5ms, the servo sometimes
* hums and get hot; by 5.0ms the hum is nearly continuous
* - 10ms periods work well for Victor 884
* - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
* controllers.
* Due to the shipping firmware on the Jaguar, we can't run the update
* period less
* than 5.05 ms.
* controllers. Due to the shipping firmware on the Jaguar, we can't run the
* update period less than 5.05 ms.
*
* kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period
* scaling is implemented as an
* output squelch to get longer periods for old devices.
* scaling is implemented as an output squelch to get longer periods for old
* devices.
*/
static constexpr float kDefaultPwmPeriod = 5.05;
/**

View File

@@ -25,8 +25,10 @@ class PWMSpeedController : public SafePWM, public SpeedController {
virtual void SetInverted(bool isInverted) override;
virtual bool GetInverted() const override;
protected:
explicit PWMSpeedController(uint32_t channel);
private:
bool m_isInverted = false;
};

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