mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
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:
committed by
Peter Johnson
parent
68690643d2
commit
e14e45da76
90
.clang-format
Normal file
90
.clang-format
Normal 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
|
||||
...
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
|
||||
#include "HAL/cpp/priority_mutex.h"
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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" {
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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, ¶m) == 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, ¶m) == 0) {
|
||||
pthread_getschedparam(*task, &policy, ¶m) == 0) {
|
||||
*priority = param.sched_priority;
|
||||
return OK;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -1 +1 @@
|
||||
//nothing here yet!
|
||||
// nothing here yet!
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
class Switch {
|
||||
public:
|
||||
public:
|
||||
virtual ~Switch() {}
|
||||
|
||||
/// \brief Returns true when the switch is triggered.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
47
styleguide/format.py
Executable 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])
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SolenoidBase.h"
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
#include "SolenoidBase.h"
|
||||
#include "tables/ITableListener.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
/**
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user