mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-02 02:51:42 +00:00
Reverted accidental commits
Change-Id: Ieee3600da11df698f1025c85972acd979e486aa0
This commit is contained in:
26
hal/include/HAL/CAN.hpp
Normal file
26
hal/include/HAL/CAN.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "NetworkCommunication/CANSessionMux.h"
|
||||
|
||||
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 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);
|
||||
|
||||
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);
|
||||
|
||||
bool canRxReceive(uint32_t arbID);
|
||||
|
||||
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);
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "Accelerometer.hpp"
|
||||
#include "Analog.hpp"
|
||||
#include "CAN.hpp"
|
||||
#include "Compressor.hpp"
|
||||
#include "Digital.hpp"
|
||||
#include "Solenoid.hpp"
|
||||
|
||||
232
hal/lib/Athena/CAN.cpp
Normal file
232
hal/lib/Athena/CAN.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
#include "HAL/CAN.hpp"
|
||||
#include <map>
|
||||
|
||||
struct CANMessage
|
||||
{
|
||||
uint8_t data[8];
|
||||
};
|
||||
|
||||
static std::map<uint32_t, CANMessage> outgoingMessages;
|
||||
static std::map<uint32_t, CANMessage> incomingMessages;
|
||||
|
||||
static const uint32_t kFullMessageIDMask = 0x1fffffff;
|
||||
|
||||
/**
|
||||
* Gets the data from the outgoing hashmap and calls
|
||||
* CANSessionMux...sendMessage.
|
||||
*/
|
||||
void canTxSend(uint32_t arbID, uint8_t length, int32_t period)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
int32_t status;
|
||||
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage(
|
||||
arbID, message.data, length, period, &status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time an single byte field changes in a message.data,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackInt8(uint32_t arbID, uint8_t offset, uint8_t value)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
message.data[offset] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time a short integer field changes in a message.data,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackInt16(uint32_t arbID, uint8_t offset, uint16_t value)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
*(uint16_t *)(message.data + offset) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time a long integer field changes in a message.data,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackInt32(uint32_t arbID, uint8_t offset, uint32_t value)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
*(uint32_t *)(message.data + offset) = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time an 8.8 fixed point field changes in a message,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackFXP16(uint32_t arbID, uint8_t offset, double value)
|
||||
{
|
||||
int16_t raw = value * 255.0;
|
||||
|
||||
canTxPackInt16(arbID, offset, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a field in the outgoing hashmap.
|
||||
*
|
||||
* This is called every time a 16.16 fixed point field changes in a message,
|
||||
* such as when a setter on a CAN device is called.
|
||||
*/
|
||||
void canTxPackFXP32(uint32_t arbID, uint8_t offset, double value)
|
||||
{
|
||||
int32_t raw = value * 65535.0;
|
||||
|
||||
canTxPackInt32(arbID, offset, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
uint8_t canTxUnpackInt8(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
return message.data[offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
uint16_t canTxUnpackInt16(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
return *reinterpret_cast<uint16_t *>(message.data + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
uint32_t canTxUnpackInt32(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = outgoingMessages[arbID];
|
||||
|
||||
return *reinterpret_cast<uint32_t *>(message.data + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
double canTxUnpackFXP16(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
int16_t raw = canTxUnpackInt16(arbID, offset);
|
||||
|
||||
return raw / 255.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the outgoing hashmap.
|
||||
*
|
||||
* This is called in getters for configuration data.
|
||||
*/
|
||||
double canTxUnpackFXP32(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
int32_t raw = canTxUnpackInt32(arbID, offset);
|
||||
|
||||
return raw / 65535.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data from CANSessionMux (if it's available) and put it in the incoming
|
||||
* hashmap.
|
||||
*
|
||||
* @return true if there's new data. Otherwise, the last received value should
|
||||
* still be in the hashmap.
|
||||
*/
|
||||
bool canRxReceive(uint32_t arbID)
|
||||
{
|
||||
CANMessage &message = incomingMessages[arbID];
|
||||
|
||||
uint8_t length;
|
||||
uint32_t timestamp;
|
||||
int32_t status;
|
||||
|
||||
FRC_NetworkCommunication_CANSessionMux_receiveMessage(
|
||||
&arbID, kFullMessageIDMask, message.data, &length, ×tamp, &status);
|
||||
|
||||
return status != ERR_CANSessionMux_MessageNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
uint8_t canRxUnpackInt8(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = incomingMessages[arbID];
|
||||
|
||||
return message.data[offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
uint16_t canRxUnpackInt16(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = incomingMessages[arbID];
|
||||
|
||||
return *reinterpret_cast<uint16_t *>(message.data + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
uint32_t canRxUnpackInt32(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
CANMessage &message = incomingMessages[arbID];
|
||||
|
||||
return *reinterpret_cast<uint32_t *>(message.data + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
double canRxUnpackFXP16(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
int16_t raw = canRxUnpackInt16(arbID, offset);
|
||||
|
||||
return raw / 255.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a field from the incoming hashmap.
|
||||
*
|
||||
* This is called in getters for status data.
|
||||
*/
|
||||
double canRxUnpackFXP32(uint32_t arbID, uint8_t offset)
|
||||
{
|
||||
int32_t raw = canRxUnpackInt32(arbID, offset);
|
||||
|
||||
return raw / 65535.0;
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "NetworkCommunication/FRCComm.h"
|
||||
#include "NetworkCommunication/UsageReporting.h"
|
||||
#include "NetworkCommunication/LoadOut.h"
|
||||
#include "NetworkCommunication/CANSessionMux.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -1,608 +0,0 @@
|
||||
/**
|
||||
* auto generated using spreadsheet and WpiClassGen.csproj
|
||||
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
|
||||
*/
|
||||
#include "CanTalonSRX.h"
|
||||
#include "NetworkCommunication/CANSessionMux.h" //CAN Comm
|
||||
#include <string.h> // memset
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
#define STATUS_1 0x02041400
|
||||
#define STATUS_2 0x02041440
|
||||
#define STATUS_3 0x02041480
|
||||
#define STATUS_4 0x020414C0
|
||||
#define STATUS_5 0x02041500
|
||||
#define STATUS_6 0x02041540
|
||||
#define STATUS_7 0x02041580
|
||||
|
||||
#define CONTROL_1 0x02040000
|
||||
|
||||
#define EXPECTED_RESPONSE_TIMEOUT_MS (200)
|
||||
#define GET_STATUS1() CtreCanNode::recMsg<TALON_Status_1_General_10ms_t > rx = GetRx<TALON_Status_1_General_10ms_t>(STATUS_1 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS2() CtreCanNode::recMsg<TALON_Status_2_Feedback_20ms_t > rx = GetRx<TALON_Status_2_Feedback_20ms_t>(STATUS_2 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS3() CtreCanNode::recMsg<TALON_Status_3_Enc_100ms_t > rx = GetRx<TALON_Status_3_Enc_100ms_t>(STATUS_3 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS4() CtreCanNode::recMsg<TALON_Status_4_AinTempVbat_100ms_t> rx = GetRx<TALON_Status_4_AinTempVbat_100ms_t>(STATUS_4 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS5() CtreCanNode::recMsg<TALON_Status_5_Startup_OneShot_t > rx = GetRx<TALON_Status_5_Startup_OneShot_t>(STATUS_5 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS6() CtreCanNode::recMsg<TALON_Status_6_Eol_t > rx = GetRx<TALON_Status_6_Eol_t>(STATUS_6 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
#define GET_STATUS7() CtreCanNode::recMsg<TALON_Status_7_Debug_200ms_t > rx = GetRx<TALON_Status_7_Debug_200ms_t>(STATUS_7 | GetDeviceNumber(), EXPECTED_RESPONSE_TIMEOUT_MS)
|
||||
|
||||
/* encoder/decoders */
|
||||
/** control */
|
||||
typedef struct _TALON_Control_1_General_10ms_t {
|
||||
unsigned TokenH:8;
|
||||
unsigned TokenL:8;
|
||||
unsigned Demand24H:8;
|
||||
unsigned Demand24M:8;
|
||||
unsigned Demand24L:8;
|
||||
unsigned CloseLoopCellSelect:1;
|
||||
unsigned SelectlFeedbackDevice:4;
|
||||
unsigned LimitSwitchEn:3;
|
||||
unsigned RevEncoderPosAndVel:1;
|
||||
unsigned RevMotDuringCloseLoopEn:1;
|
||||
unsigned BrakeType:2;
|
||||
unsigned ModeSelect:4;
|
||||
unsigned RampThrottle:8;
|
||||
} TALON_Control_1_General_10ms_t ;
|
||||
typedef struct _TALON_Control_2_Rates_OneShot_t {
|
||||
unsigned Status1Ms:8;
|
||||
unsigned Status2Ms:8;
|
||||
unsigned Status3Ms:8;
|
||||
unsigned Status4Ms:8;
|
||||
} TALON_Control_2_Rates_OneShot_t ;
|
||||
typedef struct _TALON_Control_3_ClearFlags_OneShot_t {
|
||||
unsigned ZeroFeedbackSensor:1;
|
||||
unsigned ClearStickyFaults:1;
|
||||
} TALON_Control_3_ClearFlags_OneShot_t ;
|
||||
|
||||
/** status */
|
||||
typedef struct _TALON_Status_1_General_10ms_t {
|
||||
unsigned CloseLoopErrH:8;
|
||||
unsigned CloseLoopErrM:8;
|
||||
unsigned CloseLoopErrL:8;
|
||||
unsigned Throttle_h3:3;
|
||||
unsigned Fault_RevSoftLim:1;
|
||||
unsigned Fault_ForSoftLim:1;
|
||||
unsigned TokLocked:1;
|
||||
unsigned LimitSwitchClosedRev:1;
|
||||
unsigned LimitSwitchClosedFor:1;
|
||||
unsigned Throttle_l8:8;
|
||||
unsigned ModeSelect_h1:1;
|
||||
unsigned SelectlFeedbackDevice:4;
|
||||
unsigned LimitSwitchEn:3;
|
||||
unsigned Fault_HardwareFailure:1;
|
||||
unsigned Fault_RevLim:1;
|
||||
unsigned Fault_ForLim:1;
|
||||
unsigned Fault_UnderVoltage:1;
|
||||
unsigned Fault_OverTemp:1;
|
||||
unsigned ModeSelect_b3:3;
|
||||
unsigned TokenSeed:8;
|
||||
} TALON_Status_1_General_10ms_t ;
|
||||
typedef struct _TALON_Status_2_Feedback_20ms_t {
|
||||
unsigned SensorPositionH:8;
|
||||
unsigned SensorPositionM:8;
|
||||
unsigned SensorPositionL:8;
|
||||
unsigned SensorVelocityH:8;
|
||||
unsigned SensorVelocityL:8;
|
||||
unsigned Current_h8:8;
|
||||
unsigned StckyFault_RevSoftLim:1;
|
||||
unsigned StckyFault_ForSoftLim:1;
|
||||
unsigned StckyFault_RevLim:1;
|
||||
unsigned StckyFault_ForLim:1;
|
||||
unsigned StckyFault_UnderVoltage:1;
|
||||
unsigned StckyFault_OverTemp:1;
|
||||
unsigned Current_l2:2;
|
||||
unsigned reserved:6;
|
||||
unsigned CloseLoopCellSelect:1;
|
||||
unsigned BrakeIsEnabled:1;
|
||||
} TALON_Status_2_Feedback_20ms_t ;
|
||||
typedef struct _TALON_Status_3_Enc_100ms_t {
|
||||
unsigned EncPositionH:8;
|
||||
unsigned EncPositionM:8;
|
||||
unsigned EncPositionL:8;
|
||||
unsigned EncVelH:8;
|
||||
unsigned EncVelL:8;
|
||||
unsigned EncIndexRiseEventsH:8;
|
||||
unsigned EncIndexRiseEventsL:8;
|
||||
unsigned reserved:5;
|
||||
unsigned QuadIdxpin:1;
|
||||
unsigned QuadBpin:1;
|
||||
unsigned QuadApin:1;
|
||||
} TALON_Status_3_Enc_100ms_t ;
|
||||
typedef struct _TALON_Status_4_AinTempVbat_100ms_t {
|
||||
unsigned AnalogInWithOvH:8;
|
||||
unsigned AnalogInWithOvM:8;
|
||||
unsigned AnalogInWithOvL:8;
|
||||
unsigned AnalogInVelH:8;
|
||||
unsigned AnalogInVelL:8;
|
||||
unsigned Temp:8;
|
||||
unsigned BatteryV:8;
|
||||
unsigned reserved:8;
|
||||
} TALON_Status_4_AinTempVbat_100ms_t ;
|
||||
typedef struct _TALON_Status_5_Startup_OneShot_t {
|
||||
unsigned ResetCountH:8;
|
||||
unsigned ResetCountL:8;
|
||||
unsigned ResetFlagsH:8;
|
||||
unsigned ResetFlagsL:8;
|
||||
unsigned FirmVersH:8;
|
||||
unsigned FirmVersL:8;
|
||||
} TALON_Status_5_Startup_OneShot_t ;
|
||||
typedef struct _TALON_Status_6_Eol_t {
|
||||
unsigned currentAdcUncal_h2:2;
|
||||
unsigned reserved1:5;
|
||||
unsigned SpiCsPin_GadgeteerPin6:1;
|
||||
unsigned currentAdcUncal_l8:8;
|
||||
unsigned tempAdcUncal_h2:2;
|
||||
unsigned reserved2:6;
|
||||
unsigned tempAdcUncal_l8:8;
|
||||
unsigned vbatAdcUncal_h2:2;
|
||||
unsigned reserved3:6;
|
||||
unsigned vbatAdcUncal_l8:8;
|
||||
unsigned analogAdcUncal_h2:2;
|
||||
unsigned reserved4:6;
|
||||
unsigned analogAdcUncal_l8:8;
|
||||
} TALON_Status_6_Eol_t ;
|
||||
typedef struct _TALON_Status_7_Debug_200ms_t {
|
||||
unsigned TokenizationFails_h8:8;
|
||||
unsigned TokenizationFails_l8:8;
|
||||
unsigned LastFailedToken_h8:8;
|
||||
unsigned LastFailedToken_l8:8;
|
||||
unsigned TokenizationSucceses_h8:8;
|
||||
unsigned TokenizationSucceses_l8:8;
|
||||
} TALON_Status_7_Debug_200ms_t ;
|
||||
typedef struct _TALON_Config_SetGains0_1_t {
|
||||
unsigned PH:8;
|
||||
unsigned PM:8;
|
||||
unsigned PL:8;
|
||||
unsigned IH:8;
|
||||
unsigned IM:8;
|
||||
unsigned IL:8;
|
||||
unsigned IZoneH:8;
|
||||
unsigned IZoneL:8;
|
||||
} TALON_Config_SetGains0_1_t ;
|
||||
typedef struct _TALON_Config_SetGains0_2_t {
|
||||
unsigned DH:8;
|
||||
unsigned DM:8;
|
||||
unsigned DL:8;
|
||||
unsigned FH:8;
|
||||
unsigned FM:8;
|
||||
unsigned FL:8;
|
||||
unsigned RampRateH:8;
|
||||
unsigned RampRateL:8;
|
||||
} TALON_Config_SetGains0_2_t ;
|
||||
typedef struct _TALON_Config_SetGains1_1_t {
|
||||
unsigned PH:8;
|
||||
unsigned PM:8;
|
||||
unsigned PL:8;
|
||||
unsigned IH:8;
|
||||
unsigned IM:8;
|
||||
unsigned IL:8;
|
||||
unsigned IZoneH:8;
|
||||
unsigned IZoneL:8;
|
||||
} TALON_Config_SetGains1_1_t ;
|
||||
typedef struct _TALON_Config_SetGains1_2_t {
|
||||
unsigned DH:8;
|
||||
unsigned DM:8;
|
||||
unsigned DL:8;
|
||||
unsigned FH:8;
|
||||
unsigned FM:8;
|
||||
unsigned FL:8;
|
||||
unsigned RampRateH:8;
|
||||
unsigned RampRateL:8;
|
||||
} TALON_Config_SetGains1_2_t ;
|
||||
typedef struct _TALON_Config_SetSoftLimits_t {
|
||||
unsigned LimitFH:8;
|
||||
unsigned LimitFMH:8;
|
||||
unsigned LimitFML:8;
|
||||
unsigned LimitFL:8;
|
||||
unsigned LimitRH:8;
|
||||
unsigned LimitRMH:8;
|
||||
unsigned LimitRML:8;
|
||||
unsigned LimitRL:8;
|
||||
} TALON_Config_SetSoftLimits_t ;
|
||||
typedef struct _TALON_Param_Request_t {
|
||||
unsigned ParamEnum:8;
|
||||
} TALON_Param_Request_t ;
|
||||
typedef struct _TALON_Param_Response_t {
|
||||
unsigned ParamEnum:8;
|
||||
unsigned ParamValueH:8;
|
||||
unsigned ParamValueMH:8;
|
||||
unsigned ParamValueML:8;
|
||||
unsigned ParamValueL:8;
|
||||
} TALON_Param_Response_t ;
|
||||
|
||||
|
||||
CanTalonSRX::CanTalonSRX(UINT8 deviceNumber): CtreCanNode(deviceNumber)
|
||||
{
|
||||
RegisterRx(STATUS_1 | deviceNumber );
|
||||
RegisterRx(STATUS_2 | deviceNumber );
|
||||
RegisterRx(STATUS_3 | deviceNumber );
|
||||
RegisterRx(STATUS_4 | deviceNumber );
|
||||
RegisterRx(STATUS_5 | deviceNumber );
|
||||
RegisterRx(STATUS_6 | deviceNumber );
|
||||
RegisterRx(STATUS_7 | deviceNumber );
|
||||
RegisterTx(CONTROL_1 | deviceNumber, 10);
|
||||
}
|
||||
/* CanTalonSRX D'tor
|
||||
*/
|
||||
CanTalonSRX::~CanTalonSRX()
|
||||
{
|
||||
}
|
||||
void CanTalonSRX::Set(double value)
|
||||
{
|
||||
if(value > 1)
|
||||
value = 1;
|
||||
else if(value < -1)
|
||||
value = -1;
|
||||
value *= 1023;
|
||||
SetDemand24(value); /* must be within [-1023,1023] */
|
||||
}
|
||||
/*------------------------ auto generated ----------------------*/
|
||||
|
||||
CTR_Code CanTalonSRX::GetFault_OverTemp(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_OverTemp;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_UnderVoltage(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_UnderVoltage;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_ForLim(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_ForLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_RevLim(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_RevLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_HardwareFailure(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_HardwareFailure;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_ForSoftLim(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_ForSoftLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFault_RevSoftLim(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->Fault_RevSoftLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_OverTemp(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_OverTemp;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_UnderVoltage(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_UnderVoltage;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_ForLim(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_ForLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_RevLim(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_RevLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_ForSoftLim(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_ForSoftLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetStckyFault_RevSoftLim(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->StckyFault_RevSoftLim;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetAppliedThrottle11(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->Throttle_h3;
|
||||
raw <<= 8;
|
||||
raw |= rx->Throttle_l8;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetCloseLoopErr(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->CloseLoopErrH;
|
||||
raw <<= 16;
|
||||
raw |= rx->CloseLoopErrM;
|
||||
raw <<= 8;
|
||||
raw |= rx->CloseLoopErrL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetSelectlFeedbackDevice(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->SelectlFeedbackDevice;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetModeSelect(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->ModeSelect_h1;
|
||||
raw <<= 3;
|
||||
raw |= rx->ModeSelect_b3;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetLimitSwitchEn(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->LimitSwitchEn;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetLimitSwitchClosedFor(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->LimitSwitchClosedFor;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetLimitSwitchClosedRev(int ¶m)
|
||||
{
|
||||
GET_STATUS1();
|
||||
param = rx->LimitSwitchClosedRev;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetCloseLoopCellSelect(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->CloseLoopCellSelect;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetSensorPosition(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->SensorPositionH;
|
||||
raw <<= 16;
|
||||
raw |= rx->SensorPositionM;
|
||||
raw <<= 8;
|
||||
raw |= rx->SensorPositionL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetSensorVelocity(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->SensorVelocityH;
|
||||
raw <<= 8;
|
||||
raw |= rx->SensorVelocityL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetCurrent(double ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->Current_h8;
|
||||
raw <<= 2;
|
||||
raw |= rx->Current_l2;
|
||||
param = (double)raw * 0.125 + 0;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetBrakeIsEnabled(int ¶m)
|
||||
{
|
||||
GET_STATUS2();
|
||||
param = rx->BrakeIsEnabled;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetEncPosition(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->EncPositionH;
|
||||
raw <<= 16;
|
||||
raw |= rx->EncPositionM;
|
||||
raw <<= 8;
|
||||
raw |= rx->EncPositionL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetEncVel(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->EncVelH;
|
||||
raw <<= 8;
|
||||
raw |= rx->EncVelL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetEncIndexRiseEvents(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->EncIndexRiseEventsH;
|
||||
raw <<= 8;
|
||||
raw |= rx->EncIndexRiseEventsL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetQuadApin(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
param = rx->QuadApin;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetQuadBpin(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
param = rx->QuadBpin;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetQuadIdxpin(int ¶m)
|
||||
{
|
||||
GET_STATUS3();
|
||||
param = rx->QuadIdxpin;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetAnalogInWithOv(int ¶m)
|
||||
{
|
||||
GET_STATUS4();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->AnalogInWithOvH;
|
||||
raw <<= 16;
|
||||
raw |= rx->AnalogInWithOvM;
|
||||
raw <<= 8;
|
||||
raw |= rx->AnalogInWithOvL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetAnalogInVel(int ¶m)
|
||||
{
|
||||
GET_STATUS4();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->AnalogInVelH;
|
||||
raw <<= 8;
|
||||
raw |= rx->AnalogInVelL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetTemp(double ¶m)
|
||||
{
|
||||
GET_STATUS4();
|
||||
uint32_t raw = rx->Temp;
|
||||
param = (double)raw * 0.6451612903 + -50;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetBatteryV(double ¶m)
|
||||
{
|
||||
GET_STATUS4();
|
||||
uint32_t raw = rx->BatteryV;
|
||||
param = (double)raw * 0.05 + 4;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetResetCount(int ¶m)
|
||||
{
|
||||
GET_STATUS5();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->ResetCountH;
|
||||
raw <<= 8;
|
||||
raw |= rx->ResetCountL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetResetFlags(int ¶m)
|
||||
{
|
||||
GET_STATUS5();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->ResetFlagsH;
|
||||
raw <<= 8;
|
||||
raw |= rx->ResetFlagsL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::GetFirmVers(int ¶m)
|
||||
{
|
||||
GET_STATUS5();
|
||||
uint32_t raw = 0;
|
||||
raw |= rx->FirmVersH;
|
||||
raw <<= 8;
|
||||
raw |= rx->FirmVersL;
|
||||
param = (int)raw;
|
||||
return rx.err;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetDemand24(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->Demand24H = param>>16;
|
||||
toFill->Demand24M = param>>8;
|
||||
toFill->Demand24L = param>>0;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetLimitSwitchEn(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->LimitSwitchEn = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetSelectlFeedbackDevice(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->SelectlFeedbackDevice = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetRevMotDuringCloseLoopEn(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->RevMotDuringCloseLoopEn = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetBrakeType(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->BrakeType = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetModeSelect(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->ModeSelect = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetCloseLoopCellSelect(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->CloseLoopCellSelect = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetRampThrottle(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->RampThrottle = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
CTR_Code CanTalonSRX::SetRevEncoderPosAndVel(int param)
|
||||
{
|
||||
CtreCanNode::txTask<TALON_Control_1_General_10ms_t> toFill = GetTx<TALON_Control_1_General_10ms_t>(CONTROL_1 | GetDeviceNumber());
|
||||
if (toFill.IsEmpty()) return CTR_UnexpectedArbId;
|
||||
toFill->RevEncoderPosAndVel = param;
|
||||
FlushTx(toFill);
|
||||
return CTR_OKAY;
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* auto generated using spreadsheet and WpiClassGen.csproj
|
||||
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
|
||||
*/
|
||||
#ifndef CanTalonSRX_H_
|
||||
#define CanTalonSRX_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include "CtreCanNode.h"
|
||||
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
class CanTalonSRX : public CtreCanNode
|
||||
{
|
||||
public:
|
||||
CanTalonSRX(UINT8 deviceNumber=0);
|
||||
~CanTalonSRX();
|
||||
void Set(double value);
|
||||
|
||||
/*------------------------ auto generated ----------------------*/
|
||||
CTR_Code GetFault_OverTemp(int ¶m);
|
||||
CTR_Code GetFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetFault_ForLim(int ¶m);
|
||||
CTR_Code GetFault_RevLim(int ¶m);
|
||||
CTR_Code GetFault_HardwareFailure(int ¶m);
|
||||
CTR_Code GetFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_OverTemp(int ¶m);
|
||||
CTR_Code GetStckyFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetStckyFault_ForLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevLim(int ¶m);
|
||||
CTR_Code GetStckyFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetAppliedThrottle11(int ¶m);
|
||||
CTR_Code GetCloseLoopErr(int ¶m);
|
||||
CTR_Code GetSelectlFeedbackDevice(int ¶m);
|
||||
CTR_Code GetModeSelect(int ¶m);
|
||||
CTR_Code GetLimitSwitchEn(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedFor(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedRev(int ¶m);
|
||||
CTR_Code GetCloseLoopCellSelect(int ¶m);
|
||||
CTR_Code GetSensorPosition(int ¶m);
|
||||
CTR_Code GetSensorVelocity(int ¶m);
|
||||
CTR_Code GetCurrent(double ¶m);
|
||||
CTR_Code GetBrakeIsEnabled(int ¶m);
|
||||
CTR_Code GetEncPosition(int ¶m);
|
||||
CTR_Code GetEncVel(int ¶m);
|
||||
CTR_Code GetEncIndexRiseEvents(int ¶m);
|
||||
CTR_Code GetQuadApin(int ¶m);
|
||||
CTR_Code GetQuadBpin(int ¶m);
|
||||
CTR_Code GetQuadIdxpin(int ¶m);
|
||||
CTR_Code GetAnalogInWithOv(int ¶m);
|
||||
CTR_Code GetAnalogInVel(int ¶m);
|
||||
CTR_Code GetTemp(double ¶m);
|
||||
CTR_Code GetBatteryV(double ¶m);
|
||||
CTR_Code GetResetCount(int ¶m);
|
||||
CTR_Code GetResetFlags(int ¶m);
|
||||
CTR_Code GetFirmVers(int ¶m);
|
||||
CTR_Code SetDemand24(int param);
|
||||
CTR_Code SetLimitSwitchEn(int param);
|
||||
CTR_Code SetSelectlFeedbackDevice(int param);
|
||||
CTR_Code SetRevMotDuringCloseLoopEn(int param);
|
||||
CTR_Code SetBrakeType(int param);
|
||||
CTR_Code SetModeSelect(int param);
|
||||
CTR_Code SetCloseLoopCellSelect(int param);
|
||||
CTR_Code SetRampThrottle(int param);
|
||||
CTR_Code SetRevEncoderPosAndVel(int param);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,101 +1,98 @@
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
|
||||
#include "CtreCanNode.h"
|
||||
#include "NetworkCommunication/CANSessionMux.h"
|
||||
#include <string.h> // memset
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
static const UINT32 kFullMessageIDMask = 0x1fffffff;
|
||||
|
||||
CtreCanNode::CtreCanNode(UINT8 deviceNumber)
|
||||
{
|
||||
_deviceNumber = deviceNumber;
|
||||
}
|
||||
CtreCanNode::~CtreCanNode()
|
||||
{
|
||||
}
|
||||
void CtreCanNode::RegisterRx(uint32_t arbId)
|
||||
{
|
||||
/* no need to do anything, we just use new API to poll last received message */
|
||||
}
|
||||
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
txJob_t job = {0};
|
||||
job.arbId = arbId;
|
||||
job.periodMs = periodMs;
|
||||
_txJobs[arbId] = job;
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
|
||||
job.toSend,
|
||||
8,
|
||||
job.periodMs,
|
||||
&status);
|
||||
}
|
||||
timespec diff(const timespec & start, const timespec & end)
|
||||
{
|
||||
timespec temp;
|
||||
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||
} else {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
|
||||
{
|
||||
CTR_Code retval = CTR_OKAY;
|
||||
int32_t status = 0;
|
||||
uint8_t len = 0;
|
||||
uint32_t timeStamp;
|
||||
/* cap timeout at 999ms */
|
||||
if(timeoutMs > 999)
|
||||
timeoutMs = 999;
|
||||
FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
|
||||
if(status == 0){
|
||||
/* fresh update */
|
||||
rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
|
||||
clock_gettime(2,&r.time); /* fill in time */
|
||||
memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
|
||||
}else{
|
||||
/* did not get the message */
|
||||
rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
|
||||
if(i == _rxRxEvents.end()){
|
||||
/* we've never gotten this mesage */
|
||||
retval = CTR_RxTimeout;
|
||||
/* fill caller's buffer with zeros */
|
||||
memset(dataBytes,0,8);
|
||||
}else{
|
||||
/* we've gotten this message before but not recently */
|
||||
memcpy(dataBytes,i->second.bytes,8);
|
||||
/* get the time now */
|
||||
struct timespec temp;
|
||||
clock_gettime(2,&temp); /* get now */
|
||||
/* how long has it been? */
|
||||
temp = diff(i->second.time,temp); /* temp = now - last */
|
||||
if(temp.tv_sec > 0){
|
||||
retval = CTR_RxTimeout;
|
||||
}else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){
|
||||
retval = CTR_RxTimeout;
|
||||
}else {
|
||||
/* our last update was recent enough */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void CtreCanNode::FlushTx(uint32_t arbId)
|
||||
{
|
||||
int32_t status = 0;
|
||||
txJobs_t::iterator iter = _txJobs.find(arbId);
|
||||
if(iter != _txJobs.end())
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
|
||||
iter->second.toSend,
|
||||
8,
|
||||
iter->second.periodMs,
|
||||
&status);
|
||||
}
|
||||
|
||||
#include "CtreCanNode.h"
|
||||
#include "NetworkCommunication/CANSessionMux.h"
|
||||
#include <string.h> // memset
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
static const UINT32 kFullMessageIDMask = 0x1fffffff;
|
||||
|
||||
CtreCanNode::CtreCanNode(UINT8 deviceNumber)
|
||||
{
|
||||
_deviceNumber = deviceNumber;
|
||||
}
|
||||
CtreCanNode::~CtreCanNode()
|
||||
{
|
||||
}
|
||||
void CtreCanNode::RegisterRx(uint32_t arbId)
|
||||
{
|
||||
/* no need to do anything, we just use new API to poll last received message */
|
||||
}
|
||||
void CtreCanNode::RegisterTx(uint32_t arbId, uint32_t periodMs)
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
txJob_t job;
|
||||
job.arbId = arbId;
|
||||
job.periodMs = periodMs;
|
||||
_txJobs[arbId] = job;
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( job.arbId,
|
||||
job.toSend,
|
||||
8,
|
||||
job.periodMs,
|
||||
&status);
|
||||
}
|
||||
timespec diff(const timespec & start, const timespec & end)
|
||||
{
|
||||
timespec temp;
|
||||
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||
} else {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
CTR_Code CtreCanNode::GetRx(uint32_t arbId,uint8_t * dataBytes, uint32_t timeoutMs)
|
||||
{
|
||||
CTR_Code retval = CTR_OKAY;
|
||||
int32_t status = 0;
|
||||
uint8_t len = 0;
|
||||
uint32_t timeStamp;
|
||||
/* cap timeout at 999ms */
|
||||
if(timeoutMs > 999)
|
||||
timeoutMs = 999;
|
||||
FRC_NetworkCommunication_CANSessionMux_receiveMessage(&arbId,kFullMessageIDMask,dataBytes,&len,&timeStamp,&status);
|
||||
if(status == 0){
|
||||
/* fresh update */
|
||||
rxEvent_t & r = _rxRxEvents[arbId]; /* lookup entry or make a default new one with all zeroes */
|
||||
clock_gettime(2,&r.time); /* fill in time */
|
||||
memcpy(r.bytes, dataBytes, 8); /* fill in databytes */
|
||||
}else{
|
||||
/* did not get the message */
|
||||
rxRxEvents_t::iterator i = _rxRxEvents.find(arbId);
|
||||
if(i == _rxRxEvents.end()){
|
||||
/* we've never gotten this mesage */
|
||||
retval = CTR_RxTimeout;
|
||||
/* fill caller's buffer with zeros */
|
||||
memset(dataBytes,0,8);
|
||||
}else{
|
||||
/* we've gotten this message before but not recently */
|
||||
memcpy(dataBytes,i->second.bytes,8);
|
||||
/* get the time now */
|
||||
struct timespec temp;
|
||||
clock_gettime(2,&temp); /* get now */
|
||||
/* how long has it been? */
|
||||
temp = diff(i->second.time,temp); /* temp = now - last */
|
||||
if(temp.tv_sec > 0){
|
||||
retval = CTR_RxTimeout;
|
||||
}else if(temp.tv_nsec > ((int32_t)timeoutMs*1000*1000)){
|
||||
retval = CTR_RxTimeout;
|
||||
}else {
|
||||
/* our last update was recent enough */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
void CtreCanNode::FlushTx(uint32_t arbId)
|
||||
{
|
||||
int32_t status = 0;
|
||||
txJobs_t::iterator iter = _txJobs.find(arbId);
|
||||
if(iter != _txJobs.end())
|
||||
FRC_NetworkCommunication_CANSessionMux_sendMessage( iter->second.arbId,
|
||||
iter->second.toSend,
|
||||
8,
|
||||
iter->second.periodMs,
|
||||
&status);
|
||||
}
|
||||
|
||||
@@ -1,116 +1,121 @@
|
||||
#ifndef CtreCanNode_H_
|
||||
#define CtreCanNode_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <string.h> // memcpy
|
||||
#include <sys/time.h>
|
||||
class CtreCanNode
|
||||
{
|
||||
public:
|
||||
CtreCanNode(UINT8 deviceNumber);
|
||||
~CtreCanNode();
|
||||
|
||||
UINT8 GetDeviceNumber()
|
||||
{
|
||||
return _deviceNumber;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
template <typename T> class txTask{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
T * toSend;
|
||||
T * operator -> ()
|
||||
{
|
||||
return toSend;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *toSend;
|
||||
}
|
||||
bool IsEmpty()
|
||||
{
|
||||
if(toSend == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template <typename T> class recMsg{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t bytes[8];
|
||||
CTR_Code err;
|
||||
T * operator -> ()
|
||||
{
|
||||
return (T *)bytes;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *(T *)bytes;
|
||||
}
|
||||
};
|
||||
UINT8 _deviceNumber;
|
||||
void RegisterRx(uint32_t arbId);
|
||||
void RegisterTx(uint32_t arbId, uint32_t periodMs);
|
||||
|
||||
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
|
||||
void FlushTx(uint32_t arbId);
|
||||
|
||||
template<typename T> txTask<T> GetTx(uint32_t arbId)
|
||||
{
|
||||
txTask<T> retval = {0, nullptr};
|
||||
txJobs_t::iterator i = _txJobs.find(arbId);
|
||||
if(i != _txJobs.end()){
|
||||
retval.arbId = i->second.arbId;
|
||||
retval.toSend = (T*)i->second.toSend;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
template<class T> void FlushTx(T & par)
|
||||
{
|
||||
FlushTx(par.arbId);
|
||||
}
|
||||
|
||||
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
|
||||
{
|
||||
recMsg<T> retval;
|
||||
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class txJob_t {
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t toSend[8];
|
||||
uint32_t periodMs;
|
||||
};
|
||||
|
||||
class rxEvent_t{
|
||||
public:
|
||||
uint8_t bytes[8];
|
||||
struct timespec time;
|
||||
rxEvent_t()
|
||||
{
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
bytes[4] = 0;
|
||||
bytes[5] = 0;
|
||||
bytes[6] = 0;
|
||||
bytes[7] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint32_t,txJob_t> txJobs_t;
|
||||
txJobs_t _txJobs;
|
||||
|
||||
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
|
||||
rxRxEvents_t _rxRxEvents;
|
||||
};
|
||||
#endif
|
||||
#ifndef CtreCanNode_H_
|
||||
#define CtreCanNode_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include "NetworkCommunication/CANSessionMux.h" //CAN Comm
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <string.h> // memcpy
|
||||
#include <sys/time.h>
|
||||
class CtreCanNode
|
||||
{
|
||||
public:
|
||||
CtreCanNode(UINT8 deviceNumber);
|
||||
~CtreCanNode();
|
||||
|
||||
UINT8 GetDeviceNumber()
|
||||
{
|
||||
return _deviceNumber;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
template <typename T> class txTask{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
T * toSend;
|
||||
T * operator -> ()
|
||||
{
|
||||
return toSend;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *toSend;
|
||||
}
|
||||
bool IsEmpty()
|
||||
{
|
||||
if(toSend == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template <typename T> class recMsg{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t bytes[8];
|
||||
CTR_Code err;
|
||||
T * operator -> ()
|
||||
{
|
||||
return (T *)bytes;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *(T *)bytes;
|
||||
}
|
||||
};
|
||||
UINT8 _deviceNumber;
|
||||
void RegisterRx(uint32_t arbId);
|
||||
void RegisterTx(uint32_t arbId, uint32_t periodMs);
|
||||
|
||||
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
|
||||
void FlushTx(uint32_t arbId);
|
||||
|
||||
template<typename T> txTask<T> GetTx(uint32_t arbId)
|
||||
{
|
||||
txTask<T> retval = {0};
|
||||
txJobs_t::iterator i = _txJobs.find(arbId);
|
||||
if(i != _txJobs.end()){
|
||||
retval.arbId = i->second.arbId;
|
||||
retval.toSend = (T*)i->second.toSend;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
template<class T> void FlushTx(T & par)
|
||||
{
|
||||
FlushTx(par.arbId);
|
||||
}
|
||||
|
||||
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
|
||||
{
|
||||
recMsg<T> retval;
|
||||
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class txJob_t {
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t toSend[8];
|
||||
uint32_t periodMs;
|
||||
txJob_t() : arbId(0),periodMs(0)
|
||||
{
|
||||
for(unsigned i=0;i<sizeof(toSend);++i)
|
||||
toSend[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class rxEvent_t{
|
||||
public:
|
||||
uint8_t bytes[8];
|
||||
struct timespec time;
|
||||
rxEvent_t()
|
||||
{
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
bytes[4] = 0;
|
||||
bytes[5] = 0;
|
||||
bytes[6] = 0;
|
||||
bytes[7] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint32_t,txJob_t> txJobs_t;
|
||||
txJobs_t _txJobs;
|
||||
|
||||
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
|
||||
rxRxEvents_t _rxRxEvents;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@ DEFAULT_DESTINATION_TEST_RESULTS_DIR=${DEFAULT_DESTINATION_DIR}/testResults
|
||||
# C++ test variables
|
||||
DEFAULT_CPP_TEST_NAME=FRCUserProgram
|
||||
DEFAULT_CPP_TEST_ARGS="--gtest_color=yes"
|
||||
DEFAULT_LOCAL_CPP_TEST_FILE=../build/wpilibc/wpilibC++IntegrationTests/FRCUserProgram
|
||||
DEFAULT_LOCAL_CPP_TEST_FILE=../cmake/target/cmake/wpilibc/wpilibC++IntegrationTests/FRCUserProgram
|
||||
CPP_REPORT=cppreport.xml
|
||||
DEFAULT_LOCAL_CPP_TEST_RESULT=${DEFAULT_LOCAL_TEST_RESULTS_DIR}/${CPP_REPORT}
|
||||
DEFAULT_DESTINATION_CPP_TEST_RESULTS=${DEFAULT_DESTINATION_TEST_RESULTS_DIR}/${CPP_REPORT}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "Resource.h"
|
||||
#include "MotorSafetyHelper.h"
|
||||
#include "PIDOutput.h"
|
||||
#include "CANSpeedController.h"
|
||||
#include "SpeedController.h"
|
||||
#include "HAL/Semaphore.hpp"
|
||||
#include "HAL/HAL.hpp"
|
||||
#include "LiveWindow/LiveWindowSendable.h"
|
||||
@@ -23,7 +23,7 @@
|
||||
* Luminary Micro Jaguar Speed Control
|
||||
*/
|
||||
class CANJaguar : public MotorSafety,
|
||||
public CANSpeedController,
|
||||
public SpeedController,
|
||||
public ErrorBase,
|
||||
public LiveWindowSendable,
|
||||
public ITableListener
|
||||
@@ -41,11 +41,40 @@ public:
|
||||
/** Sets a potentiometer as the position reference only. <br> Passed as the "tag" when setting the control mode. */
|
||||
static const struct PotentiometerStruct {} Potentiometer;
|
||||
|
||||
typedef enum {kPercentVbus, kCurrent, kSpeed, kPosition, kVoltage} ControlMode;
|
||||
typedef enum {kCurrentFault = 1, kTemperatureFault = 2, kBusVoltageFault = 4, kGateDriverFault = 8} Faults;
|
||||
typedef enum {kForwardLimit = 1, kReverseLimit = 2} Limits;
|
||||
typedef enum {
|
||||
kNeutralMode_Jumper = 0, /** Use the NeutralMode that is set by the jumper wire on the CAN device */
|
||||
kNeutralMode_Brake = 1, /** Stop the motor's rotation by applying a force. */
|
||||
kNeutralMode_Coast = 2 /** Do not attempt to stop the motor. Instead allow it to coast to a stop without applying resistance. */
|
||||
} NeutralMode;
|
||||
typedef enum {
|
||||
/**
|
||||
* Disables the soft position limits and only uses the limit switches to limit rotation.
|
||||
* @see CANJaguar#GetForwardLimitOK()
|
||||
* @see CANJaguar#GetReverseLimitOK()
|
||||
*
|
||||
*/
|
||||
kLimitMode_SwitchInputsOnly = 0,
|
||||
/**
|
||||
* Enables the soft position limits on the Jaguar.
|
||||
* These will be used in addition to the limit switches. This does not disable the behavior
|
||||
* of the limit switch input.
|
||||
* @see CANJaguar#ConfigSoftPositionLimits(double, double)
|
||||
*/
|
||||
kLimitMode_SoftPositionLimits = 1
|
||||
} LimitMode;
|
||||
|
||||
explicit CANJaguar(uint8_t deviceNumber);
|
||||
virtual ~CANJaguar();
|
||||
|
||||
uint8_t getDeviceNumber() const;
|
||||
uint8_t GetHardwareVersion();
|
||||
|
||||
// SpeedController interface
|
||||
virtual float Get();
|
||||
virtual void Set(float value, uint8_t syncGroup=0);
|
||||
virtual void Disable();
|
||||
|
||||
// PIDOutput interface
|
||||
virtual void PIDWrite(float output);
|
||||
@@ -75,42 +104,39 @@ public:
|
||||
void SetVoltageMode(QuadEncoderStruct, uint16_t codesPerRev);
|
||||
void SetVoltageMode(PotentiometerStruct);
|
||||
|
||||
// CANSpeedController interface
|
||||
virtual float Get() override;
|
||||
virtual void Set(float value, uint8_t syncGroup=0) override;
|
||||
virtual void Disable() override;
|
||||
virtual void SetP(double p) override;
|
||||
virtual void SetI(double i) override;
|
||||
virtual void SetD(double d) override;
|
||||
virtual void SetPID(double p, double i, double d) override;
|
||||
virtual double GetP() override;
|
||||
virtual double GetI() override;
|
||||
virtual double GetD() override;
|
||||
virtual float GetBusVoltage() override;
|
||||
virtual float GetOutputVoltage() override;
|
||||
virtual float GetOutputCurrent() override;
|
||||
virtual float GetTemperature() override;
|
||||
virtual double GetPosition() override;
|
||||
virtual double GetSpeed() override;
|
||||
virtual bool GetForwardLimitOK() override;
|
||||
virtual bool GetReverseLimitOK() override;
|
||||
virtual uint16_t GetFaults() override;
|
||||
virtual void SetVoltageRampRate(double rampRate) override;
|
||||
virtual uint32_t GetFirmwareVersion() override;
|
||||
virtual void ConfigNeutralMode(NeutralMode mode) override;
|
||||
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) override;
|
||||
virtual void ConfigPotentiometerTurns(uint16_t turns) override;
|
||||
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) override;
|
||||
virtual void DisableSoftPositionLimits() override;
|
||||
virtual void ConfigLimitMode(LimitMode mode) override;
|
||||
virtual void ConfigForwardLimit(double forwardLimitPosition) override;
|
||||
virtual void ConfigReverseLimit(double reverseLimitPosition) override;
|
||||
virtual void ConfigMaxOutputVoltage(double voltage) override;
|
||||
virtual void ConfigFaultTime(float faultTime) override;
|
||||
virtual void SetControlMode(ControlMode mode) override;
|
||||
virtual ControlMode GetControlMode() override;
|
||||
// Other Accessors
|
||||
void SetP(double p);
|
||||
void SetI(double i);
|
||||
void SetD(double d);
|
||||
void SetPID(double p, double i, double d);
|
||||
double GetP();
|
||||
double GetI();
|
||||
double GetD();
|
||||
float GetBusVoltage();
|
||||
float GetOutputVoltage();
|
||||
float GetOutputCurrent();
|
||||
float GetTemperature();
|
||||
double GetPosition();
|
||||
double GetSpeed();
|
||||
bool GetForwardLimitOK();
|
||||
bool GetReverseLimitOK();
|
||||
uint16_t GetFaults();
|
||||
void SetVoltageRampRate(double rampRate);
|
||||
virtual uint32_t GetFirmwareVersion();
|
||||
uint8_t GetHardwareVersion();
|
||||
void ConfigNeutralMode(NeutralMode mode);
|
||||
void ConfigEncoderCodesPerRev(uint16_t codesPerRev);
|
||||
void ConfigPotentiometerTurns(uint16_t turns);
|
||||
void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition);
|
||||
void DisableSoftPositionLimits();
|
||||
void ConfigLimitMode(LimitMode mode);
|
||||
void ConfigForwardLimit(double forwardLimitPosition);
|
||||
void ConfigReverseLimit(double reverseLimitPosition);
|
||||
void ConfigMaxOutputVoltage(double voltage);
|
||||
void ConfigFaultTime(float faultTime);
|
||||
ControlMode GetControlMode();
|
||||
|
||||
static void UpdateSyncGroup(uint8_t syncGroup);
|
||||
static void UpdateSyncGroup(uint8_t syncGroup);
|
||||
|
||||
void SetExpiration(float timeout);
|
||||
float GetExpiration();
|
||||
@@ -123,6 +149,9 @@ public:
|
||||
|
||||
protected:
|
||||
// Control mode helpers
|
||||
|
||||
void ChangeControlMode(ControlMode controlMode);
|
||||
|
||||
void SetSpeedReference(uint8_t reference);
|
||||
uint8_t GetSpeedReference();
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2014. 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 "SpeedController.h"
|
||||
|
||||
/**
|
||||
* Interface for "smart" CAN-based speed controllers.
|
||||
* @see CANJaguar
|
||||
* @see CANTalon
|
||||
*/
|
||||
class CANSpeedController : public SpeedController
|
||||
{
|
||||
public:
|
||||
enum ControlMode {
|
||||
kPercentVbus=0,
|
||||
// TODO(james): Handle kFollower in CANJaguar.
|
||||
kFollower=1, // Only supported on Talon SRX.
|
||||
kVoltage=2,
|
||||
kPosition=3,
|
||||
kSpeed=4,
|
||||
kCurrent=5,
|
||||
kDisabled=15
|
||||
};
|
||||
|
||||
enum Faults {
|
||||
kCurrentFault = 1,
|
||||
kTemperatureFault = 2,
|
||||
kBusVoltageFault = 4,
|
||||
kGateDriverFault = 8
|
||||
};
|
||||
|
||||
enum Limits {
|
||||
kForwardLimit = 1,
|
||||
kReverseLimit = 2
|
||||
};
|
||||
|
||||
enum NeutralMode {
|
||||
/** Use the NeutralMode that is set by the jumper wire on the CAN device */
|
||||
kNeutralMode_Jumper = 0,
|
||||
/** Stop the motor's rotation by applying a force. */
|
||||
kNeutralMode_Brake = 1,
|
||||
/** Do not attempt to stop the motor. Instead allow it to coast to a stop without applying resistance. */
|
||||
kNeutralMode_Coast = 2
|
||||
};
|
||||
|
||||
enum LimitMode {
|
||||
/** Only use switches for limits */
|
||||
kLimitMode_SwitchInputsOnly = 0,
|
||||
/** Use both switches and soft limits */
|
||||
kLimitMode_SoftPositionLimits = 1
|
||||
};
|
||||
|
||||
virtual float Get() = 0;
|
||||
virtual void Set(float value, uint8_t syncGroup=0) = 0;
|
||||
virtual void Disable() = 0;
|
||||
virtual void SetP(double p) = 0;
|
||||
virtual void SetI(double i) = 0;
|
||||
virtual void SetD(double d) = 0;
|
||||
virtual void SetPID(double p, double i, double d) = 0;
|
||||
virtual double GetP() = 0;
|
||||
virtual double GetI() = 0;
|
||||
virtual double GetD() = 0;
|
||||
virtual float GetBusVoltage() = 0;
|
||||
virtual float GetOutputVoltage() = 0;
|
||||
virtual float GetOutputCurrent() = 0;
|
||||
virtual float GetTemperature() = 0;
|
||||
virtual double GetPosition() = 0;
|
||||
virtual double GetSpeed() = 0;
|
||||
virtual bool GetForwardLimitOK() = 0;
|
||||
virtual bool GetReverseLimitOK() = 0;
|
||||
virtual uint16_t GetFaults() = 0;
|
||||
virtual void SetVoltageRampRate(double rampRate) = 0;
|
||||
virtual uint32_t GetFirmwareVersion() = 0;
|
||||
virtual void ConfigNeutralMode(NeutralMode mode) = 0;
|
||||
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) = 0;
|
||||
virtual void ConfigPotentiometerTurns(uint16_t turns) = 0;
|
||||
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) = 0;
|
||||
virtual void DisableSoftPositionLimits() = 0;
|
||||
virtual void ConfigLimitMode(LimitMode mode) = 0;
|
||||
virtual void ConfigForwardLimit(double forwardLimitPosition) = 0;
|
||||
virtual void ConfigReverseLimit(double reverseLimitPosition) = 0;
|
||||
virtual void ConfigMaxOutputVoltage(double voltage) = 0;
|
||||
virtual void ConfigFaultTime(float faultTime) = 0;
|
||||
virtual void SetControlMode(ControlMode mode) = 0;
|
||||
virtual ControlMode GetControlMode() = 0;
|
||||
};
|
||||
@@ -1,81 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2014. 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 "SafePWM.h"
|
||||
#include "CANSpeedController.h"
|
||||
#include "PIDOutput.h"
|
||||
#include "MotorSafetyHelper.h"
|
||||
|
||||
class CanTalonSRX;
|
||||
|
||||
/**
|
||||
* CTRE Talon SRX Speed Controller
|
||||
*/
|
||||
class CANTalon : public MotorSafety,
|
||||
public CANSpeedController,
|
||||
public ErrorBase
|
||||
{
|
||||
public:
|
||||
explicit CANTalon(uint8_t deviceNumber);
|
||||
virtual ~CANTalon();
|
||||
|
||||
// PIDController interface
|
||||
virtual void PIDWrite(float output) override;
|
||||
|
||||
// MotorSafety interface
|
||||
virtual void SetExpiration(float timeout) override;
|
||||
virtual float GetExpiration() override;
|
||||
virtual bool IsAlive() override;
|
||||
virtual void StopMotor() override;
|
||||
virtual void SetSafetyEnabled(bool enabled) override;
|
||||
virtual bool IsSafetyEnabled() override;
|
||||
virtual void GetDescription(char *desc) override;
|
||||
|
||||
// CANSpeedController interface
|
||||
virtual float Get() override;
|
||||
virtual void Set(float value, uint8_t syncGroup=0) override;
|
||||
virtual void Disable() override;
|
||||
virtual void EnableControl();
|
||||
virtual void SetP(double p) override;
|
||||
virtual void SetI(double i) override;
|
||||
virtual void SetD(double d) override;
|
||||
virtual void SetPID(double p, double i, double d) override;
|
||||
virtual double GetP() override;
|
||||
virtual double GetI() override;
|
||||
virtual double GetD() override;
|
||||
virtual float GetBusVoltage() override;
|
||||
virtual float GetOutputVoltage() override;
|
||||
virtual float GetOutputCurrent() override;
|
||||
virtual float GetTemperature() override;
|
||||
virtual double GetPosition() override;
|
||||
virtual double GetSpeed() override;
|
||||
virtual bool GetForwardLimitOK() override;
|
||||
virtual bool GetReverseLimitOK() override;
|
||||
virtual uint16_t GetFaults() override;
|
||||
virtual void SetVoltageRampRate(double rampRate) override;
|
||||
virtual uint32_t GetFirmwareVersion() override;
|
||||
virtual void ConfigNeutralMode(NeutralMode mode) override;
|
||||
virtual void ConfigEncoderCodesPerRev(uint16_t codesPerRev) override;
|
||||
virtual void ConfigPotentiometerTurns(uint16_t turns) override;
|
||||
virtual void ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition) override;
|
||||
virtual void DisableSoftPositionLimits() override;
|
||||
virtual void ConfigLimitMode(LimitMode mode) override;
|
||||
virtual void ConfigForwardLimit(double forwardLimitPosition) override;
|
||||
virtual void ConfigReverseLimit(double reverseLimitPosition) override;
|
||||
virtual void ConfigMaxOutputVoltage(double voltage) override;
|
||||
virtual void ConfigFaultTime(float faultTime) override;
|
||||
virtual void SetControlMode(ControlMode mode) override;
|
||||
virtual ControlMode GetControlMode() override;
|
||||
|
||||
private:
|
||||
uint8_t m_deviceNumber;
|
||||
CanTalonSRX *m_impl;
|
||||
MotorSafetyHelper *m_safetyHelper;
|
||||
|
||||
bool m_controlEnabled;
|
||||
ControlMode m_controlMode;
|
||||
};
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "Buttons/JoystickButton.h"
|
||||
#include "Buttons/NetworkButton.h"
|
||||
#include "CANJaguar.h"
|
||||
#include "CANTalon.h"
|
||||
#include "Commands/Command.h"
|
||||
#include "Commands/CommandGroup.h"
|
||||
#include "Commands/PIDCommand.h"
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* auto generated using spreadsheet and WpiClassGen.csproj
|
||||
* @link https://docs.google.com/spreadsheets/d/1OU_ZV7fZLGYUQ-Uhc8sVAmUmWTlT8XBFYK8lfjg_tac/edit#gid=1766046967
|
||||
*/
|
||||
#ifndef CanTalonSRX_H_
|
||||
#define CanTalonSRX_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include "CtreCanNode.h"
|
||||
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
class CanTalonSRX : public CtreCanNode
|
||||
{
|
||||
public:
|
||||
CanTalonSRX(UINT8 deviceNumber=0);
|
||||
~CanTalonSRX();
|
||||
void Set(double value);
|
||||
|
||||
/*------------------------ auto generated ----------------------*/
|
||||
CTR_Code GetFault_OverTemp(int ¶m);
|
||||
CTR_Code GetFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetFault_ForLim(int ¶m);
|
||||
CTR_Code GetFault_RevLim(int ¶m);
|
||||
CTR_Code GetFault_HardwareFailure(int ¶m);
|
||||
CTR_Code GetFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_OverTemp(int ¶m);
|
||||
CTR_Code GetStckyFault_UnderVoltage(int ¶m);
|
||||
CTR_Code GetStckyFault_ForLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevLim(int ¶m);
|
||||
CTR_Code GetStckyFault_ForSoftLim(int ¶m);
|
||||
CTR_Code GetStckyFault_RevSoftLim(int ¶m);
|
||||
CTR_Code GetAppliedThrottle11(int ¶m);
|
||||
CTR_Code GetCloseLoopErr(int ¶m);
|
||||
CTR_Code GetSelectlFeedbackDevice(int ¶m);
|
||||
CTR_Code GetModeSelect(int ¶m);
|
||||
CTR_Code GetLimitSwitchEn(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedFor(int ¶m);
|
||||
CTR_Code GetLimitSwitchClosedRev(int ¶m);
|
||||
CTR_Code GetCloseLoopCellSelect(int ¶m);
|
||||
CTR_Code GetSensorPosition(int ¶m);
|
||||
CTR_Code GetSensorVelocity(int ¶m);
|
||||
CTR_Code GetCurrent(double ¶m);
|
||||
CTR_Code GetBrakeIsEnabled(int ¶m);
|
||||
CTR_Code GetEncPosition(int ¶m);
|
||||
CTR_Code GetEncVel(int ¶m);
|
||||
CTR_Code GetEncIndexRiseEvents(int ¶m);
|
||||
CTR_Code GetQuadApin(int ¶m);
|
||||
CTR_Code GetQuadBpin(int ¶m);
|
||||
CTR_Code GetQuadIdxpin(int ¶m);
|
||||
CTR_Code GetAnalogInWithOv(int ¶m);
|
||||
CTR_Code GetAnalogInVel(int ¶m);
|
||||
CTR_Code GetTemp(double ¶m);
|
||||
CTR_Code GetBatteryV(double ¶m);
|
||||
CTR_Code GetResetCount(int ¶m);
|
||||
CTR_Code GetResetFlags(int ¶m);
|
||||
CTR_Code GetFirmVers(int ¶m);
|
||||
CTR_Code SetDemand24(int param);
|
||||
CTR_Code SetLimitSwitchEn(int param);
|
||||
CTR_Code SetSelectlFeedbackDevice(int param);
|
||||
CTR_Code SetRevMotDuringCloseLoopEn(int param);
|
||||
CTR_Code SetBrakeType(int param);
|
||||
CTR_Code SetModeSelect(int param);
|
||||
CTR_Code SetCloseLoopCellSelect(int param);
|
||||
CTR_Code SetRampThrottle(int param);
|
||||
CTR_Code SetRevEncoderPosAndVel(int param);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
#ifndef CtreCanNode_H_
|
||||
#define CtreCanNode_H_
|
||||
#include "ctre.h" //BIT Defines + Typedefs
|
||||
#include <NetworkCommunication/CANSessionMux.h> //CAN Comm
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
#include <string.h> // memcpy
|
||||
#include <sys/time.h>
|
||||
class CtreCanNode
|
||||
{
|
||||
public:
|
||||
CtreCanNode(UINT8 deviceNumber);
|
||||
~CtreCanNode();
|
||||
|
||||
UINT8 GetDeviceNumber()
|
||||
{
|
||||
return _deviceNumber;
|
||||
}
|
||||
protected:
|
||||
|
||||
|
||||
template <typename T> class txTask{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
T * toSend;
|
||||
T * operator -> ()
|
||||
{
|
||||
return toSend;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *toSend;
|
||||
}
|
||||
bool IsEmpty()
|
||||
{
|
||||
if(toSend == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
template <typename T> class recMsg{
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t bytes[8];
|
||||
CTR_Code err;
|
||||
T * operator -> ()
|
||||
{
|
||||
return (T *)bytes;
|
||||
}
|
||||
T & operator*()
|
||||
{
|
||||
return *(T *)bytes;
|
||||
}
|
||||
};
|
||||
UINT8 _deviceNumber;
|
||||
void RegisterRx(uint32_t arbId);
|
||||
void RegisterTx(uint32_t arbId, uint32_t periodMs);
|
||||
|
||||
CTR_Code GetRx(uint32_t arbId,uint8_t * dataBytes,uint32_t timeoutMs);
|
||||
void FlushTx(uint32_t arbId);
|
||||
|
||||
template<typename T> txTask<T> GetTx(uint32_t arbId)
|
||||
{
|
||||
txTask<T> retval = {0};
|
||||
txJobs_t::iterator i = _txJobs.find(arbId);
|
||||
if(i != _txJobs.end()){
|
||||
retval.arbId = i->second.arbId;
|
||||
retval.toSend = (T*)i->second.toSend;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
template<class T> void FlushTx(T & par)
|
||||
{
|
||||
FlushTx(par.arbId);
|
||||
}
|
||||
|
||||
template<class T> recMsg<T> GetRx(uint32_t arbId, uint32_t timeoutMs)
|
||||
{
|
||||
recMsg<T> retval;
|
||||
retval.err = GetRx(arbId,retval.bytes, timeoutMs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class txJob_t {
|
||||
public:
|
||||
uint32_t arbId;
|
||||
uint8_t toSend[8];
|
||||
uint32_t periodMs;
|
||||
};
|
||||
|
||||
class rxEvent_t{
|
||||
public:
|
||||
uint8_t bytes[8];
|
||||
struct timespec time;
|
||||
rxEvent_t()
|
||||
{
|
||||
bytes[0] = 0;
|
||||
bytes[1] = 0;
|
||||
bytes[2] = 0;
|
||||
bytes[3] = 0;
|
||||
bytes[4] = 0;
|
||||
bytes[5] = 0;
|
||||
bytes[6] = 0;
|
||||
bytes[7] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<uint32_t,txJob_t> txJobs_t;
|
||||
txJobs_t _txJobs;
|
||||
|
||||
typedef std::map<uint32_t,rxEvent_t> rxRxEvents_t;
|
||||
rxRxEvents_t _rxRxEvents;
|
||||
};
|
||||
#endif
|
||||
@@ -1,60 +0,0 @@
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
//Bit Defines
|
||||
#define BIT0 0x01
|
||||
#define BIT1 0x02
|
||||
#define BIT2 0x04
|
||||
#define BIT3 0x08
|
||||
#define BIT4 0x10
|
||||
#define BIT5 0x20
|
||||
#define BIT6 0x40
|
||||
#define BIT7 0x80
|
||||
#define BIT8 0x0100
|
||||
#define BIT9 0x0200
|
||||
#define BIT10 0x0400
|
||||
#define BIT11 0x0800
|
||||
#define BIT12 0x1000
|
||||
#define BIT13 0x2000
|
||||
#define BIT14 0x4000
|
||||
#define BIT15 0x8000
|
||||
|
||||
//Signed
|
||||
typedef signed char INT8;
|
||||
typedef signed short INT16;
|
||||
typedef signed int INT32;
|
||||
typedef signed long long INT64;
|
||||
|
||||
//Unsigned
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned int UINT32;
|
||||
typedef unsigned long long UINT64;
|
||||
|
||||
//Other
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned long ULONG;
|
||||
|
||||
typedef enum {
|
||||
CTR_OKAY, //No Error - Function executed as expected
|
||||
CTR_RxTimeout, /*
|
||||
* Receive Timeout
|
||||
*
|
||||
* No module-specific CAN frames have been received in
|
||||
* the last 50ms. Function returns the latest received data
|
||||
* but may be STALE DATA.
|
||||
*/
|
||||
CTR_TxTimeout, /*
|
||||
* Transmission Timeout
|
||||
*
|
||||
* No module-specific CAN frames were transmitted in
|
||||
* the last 50ms. Parameters passed in by the user are loaded
|
||||
* for next transmission but have not sent.
|
||||
*/
|
||||
CTR_InvalidParamValue,
|
||||
CTR_UnexpectedArbId,
|
||||
}CTR_Code;
|
||||
|
||||
#endif
|
||||
@@ -343,7 +343,6 @@ void CANJaguar::Set(float outputValue, uint8_t syncGroup)
|
||||
}
|
||||
break;
|
||||
default:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "The Jaguar only supports Current, Voltage, Position, Speed, and Percent (throttle) modes.");
|
||||
return;
|
||||
}
|
||||
if (syncGroup != 0)
|
||||
@@ -1159,9 +1158,6 @@ void CANJaguar::SetP(double p)
|
||||
dataSize = packFXP16_16(dataBuffer, p);
|
||||
sendMessage(LM_API_ICTRL_PC, dataBuffer, dataSize);
|
||||
break;
|
||||
default:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
|
||||
break;
|
||||
}
|
||||
|
||||
m_p = p;
|
||||
@@ -1196,9 +1192,6 @@ void CANJaguar::SetI(double i)
|
||||
dataSize = packFXP16_16(dataBuffer, i);
|
||||
sendMessage(LM_API_ICTRL_IC, dataBuffer, dataSize);
|
||||
break;
|
||||
default:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
|
||||
break;
|
||||
}
|
||||
|
||||
m_i = i;
|
||||
@@ -1233,9 +1226,6 @@ void CANJaguar::SetD(double d)
|
||||
dataSize = packFXP16_16(dataBuffer, d);
|
||||
sendMessage(LM_API_ICTRL_DC, dataBuffer, dataSize);
|
||||
break;
|
||||
default:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
|
||||
return;
|
||||
}
|
||||
|
||||
m_d = d;
|
||||
@@ -1323,9 +1313,6 @@ void CANJaguar::EnableControl(double encoderInitialPosition)
|
||||
case kVoltage:
|
||||
sendMessage(LM_API_VCOMP_T_EN, dataBuffer, dataSize);
|
||||
break;
|
||||
default:
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "The Jaguar only supports Current, Voltage, Position, Speed, and Percent (throttle) modes.");
|
||||
break;
|
||||
}
|
||||
|
||||
m_controlEnabled = true;
|
||||
@@ -1366,7 +1353,7 @@ void CANJaguar::DisableControl()
|
||||
*/
|
||||
void CANJaguar::SetPercentMode()
|
||||
{
|
||||
SetControlMode(kPercentVbus);
|
||||
ChangeControlMode(kPercentVbus);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
}
|
||||
@@ -1381,7 +1368,7 @@ void CANJaguar::SetPercentMode()
|
||||
*/
|
||||
void CANJaguar::SetPercentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
|
||||
{
|
||||
SetControlMode(kPercentVbus);
|
||||
ChangeControlMode(kPercentVbus);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1397,7 +1384,7 @@ void CANJaguar::SetPercentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
|
||||
*/
|
||||
void CANJaguar::SetPercentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev)
|
||||
{
|
||||
SetControlMode(kPercentVbus);
|
||||
ChangeControlMode(kPercentVbus);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
SetSpeedReference(LM_REF_QUAD_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1412,7 +1399,7 @@ void CANJaguar::SetPercentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
|
||||
*/
|
||||
void CANJaguar::SetPercentMode(CANJaguar::PotentiometerStruct)
|
||||
{
|
||||
SetControlMode(kPercentVbus);
|
||||
ChangeControlMode(kPercentVbus);
|
||||
SetPositionReference(LM_REF_POT);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
ConfigPotentiometerTurns(1);
|
||||
@@ -1428,7 +1415,7 @@ void CANJaguar::SetPercentMode(CANJaguar::PotentiometerStruct)
|
||||
*/
|
||||
void CANJaguar::SetCurrentMode(double p, double i, double d)
|
||||
{
|
||||
SetControlMode(kCurrent);
|
||||
ChangeControlMode(kCurrent);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
SetPID(p, i, d);
|
||||
@@ -1446,7 +1433,7 @@ void CANJaguar::SetCurrentMode(double p, double i, double d)
|
||||
*/
|
||||
void CANJaguar::SetCurrentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
SetControlMode(kCurrent);
|
||||
ChangeControlMode(kCurrent);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1465,7 +1452,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, d
|
||||
*/
|
||||
void CANJaguar::SetCurrentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
SetControlMode(kCurrent);
|
||||
ChangeControlMode(kCurrent);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
SetSpeedReference(LM_REF_QUAD_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1484,7 +1471,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
|
||||
*/
|
||||
void CANJaguar::SetCurrentMode(CANJaguar::PotentiometerStruct, double p, double i, double d)
|
||||
{
|
||||
SetControlMode(kCurrent);
|
||||
ChangeControlMode(kCurrent);
|
||||
SetPositionReference(LM_REF_POT);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
ConfigPotentiometerTurns(1);
|
||||
@@ -1504,7 +1491,7 @@ void CANJaguar::SetCurrentMode(CANJaguar::PotentiometerStruct, double p, double
|
||||
*/
|
||||
void CANJaguar::SetSpeedMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
SetControlMode(kSpeed);
|
||||
ChangeControlMode(kSpeed);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1523,7 +1510,7 @@ void CANJaguar::SetSpeedMode(CANJaguar::EncoderStruct, uint16_t codesPerRev, dou
|
||||
*/
|
||||
void CANJaguar::SetSpeedMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
SetControlMode(kSpeed);
|
||||
ChangeControlMode(kSpeed);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
SetSpeedReference(LM_REF_QUAD_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1543,7 +1530,7 @@ void CANJaguar::SetSpeedMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev,
|
||||
*/
|
||||
void CANJaguar::SetPositionMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev, double p, double i, double d)
|
||||
{
|
||||
SetControlMode(kPosition);
|
||||
ChangeControlMode(kPosition);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
SetPID(p, i, d);
|
||||
@@ -1558,7 +1545,7 @@ void CANJaguar::SetPositionMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerR
|
||||
*/
|
||||
void CANJaguar::SetPositionMode(CANJaguar::PotentiometerStruct, double p, double i, double d)
|
||||
{
|
||||
SetControlMode(kPosition);
|
||||
ChangeControlMode(kPosition);
|
||||
SetPositionReference(LM_REF_POT);
|
||||
ConfigPotentiometerTurns(1);
|
||||
SetPID(p, i, d);
|
||||
@@ -1570,7 +1557,7 @@ void CANJaguar::SetPositionMode(CANJaguar::PotentiometerStruct, double p, double
|
||||
*/
|
||||
void CANJaguar::SetVoltageMode()
|
||||
{
|
||||
SetControlMode(kVoltage);
|
||||
ChangeControlMode(kVoltage);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
}
|
||||
@@ -1585,7 +1572,7 @@ void CANJaguar::SetVoltageMode()
|
||||
*/
|
||||
void CANJaguar::SetVoltageMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
|
||||
{
|
||||
SetControlMode(kVoltage);
|
||||
ChangeControlMode(kVoltage);
|
||||
SetPositionReference(LM_REF_NONE);
|
||||
SetSpeedReference(LM_REF_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1601,7 +1588,7 @@ void CANJaguar::SetVoltageMode(CANJaguar::EncoderStruct, uint16_t codesPerRev)
|
||||
*/
|
||||
void CANJaguar::SetVoltageMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRev)
|
||||
{
|
||||
SetControlMode(kVoltage);
|
||||
ChangeControlMode(kVoltage);
|
||||
SetPositionReference(LM_REF_ENCODER);
|
||||
SetSpeedReference(LM_REF_QUAD_ENCODER);
|
||||
ConfigEncoderCodesPerRev(codesPerRev);
|
||||
@@ -1616,7 +1603,7 @@ void CANJaguar::SetVoltageMode(CANJaguar::QuadEncoderStruct, uint16_t codesPerRe
|
||||
*/
|
||||
void CANJaguar::SetVoltageMode(CANJaguar::PotentiometerStruct)
|
||||
{
|
||||
SetControlMode(kVoltage);
|
||||
ChangeControlMode(kVoltage);
|
||||
SetPositionReference(LM_REF_POT);
|
||||
SetSpeedReference(LM_REF_NONE);
|
||||
ConfigPotentiometerTurns(1);
|
||||
@@ -1631,7 +1618,7 @@ void CANJaguar::SetVoltageMode(CANJaguar::PotentiometerStruct)
|
||||
*
|
||||
* @param controlMode The new mode.
|
||||
*/
|
||||
void CANJaguar::SetControlMode(ControlMode controlMode)
|
||||
void CANJaguar::ChangeControlMode(ControlMode controlMode)
|
||||
{
|
||||
// Disable the previous mode
|
||||
DisableControl();
|
||||
|
||||
@@ -1,462 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2014. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "CANTalon.h"
|
||||
#include "WPIErrors.h"
|
||||
#include "ctre/CanTalonSRX.h"
|
||||
|
||||
/**
|
||||
* The CANTalon object is currently incomplete. As of Nov 14 2014, we only know
|
||||
* for sure that sending a throttle and checking basic values (eg current,
|
||||
* temperature) work.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructor for the CANTalon device.
|
||||
* @param deviceNumber The CAN ID of the Talon SRX
|
||||
*/
|
||||
CANTalon::CANTalon(uint8_t deviceNumber)
|
||||
: m_deviceNumber(deviceNumber)
|
||||
, m_impl(new CanTalonSRX(deviceNumber))
|
||||
, m_safetyHelper(new MotorSafetyHelper(this))
|
||||
, m_controlEnabled(false)
|
||||
, m_controlMode(kPercentVbus)
|
||||
{
|
||||
}
|
||||
|
||||
CANTalon::~CANTalon() {
|
||||
delete m_impl;
|
||||
delete m_safetyHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the PID value as seen in the PIDOutput base object.
|
||||
*
|
||||
* @deprecated Call Set instead.
|
||||
*
|
||||
* @param output Write out the PercentVbus value as was computed by the PIDController
|
||||
*/
|
||||
void CANTalon::PIDWrite(float output)
|
||||
{
|
||||
if (GetControlMode() == kPercentVbus)
|
||||
{
|
||||
Set(output);
|
||||
}
|
||||
else
|
||||
{
|
||||
wpi_setWPIErrorWithContext(IncompatibleMode, "PID only supported in PercentVbus mode");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
float CANTalon::Get()
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the output set-point value.
|
||||
*/
|
||||
void CANTalon::Set(float value, uint8_t syncGroup)
|
||||
{
|
||||
if(m_controlEnabled) {
|
||||
CTR_Code status;
|
||||
switch(GetControlMode()) {
|
||||
case kPercentVbus:
|
||||
{
|
||||
m_impl->Set(value);
|
||||
status = CTR_OKAY;
|
||||
}
|
||||
break;
|
||||
case kFollower:
|
||||
{
|
||||
status = m_impl->SetDemand24((int)value);
|
||||
}
|
||||
break;
|
||||
case kVoltage:
|
||||
{
|
||||
// Voltage is an 8.8 fixed point number.
|
||||
int volts = int(value * 256);
|
||||
status = m_impl->SetDemand24(volts);
|
||||
}
|
||||
default:
|
||||
// TODO: Add support for other modes. Need to figure out what format
|
||||
// SetDemand24 needs.
|
||||
break;
|
||||
}
|
||||
if (status != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::Disable()
|
||||
{
|
||||
// Until Modes other than throttle work, just disable by setting throttle to 0.0.
|
||||
m_impl->Set(0.0); // TODO when firmware is updated, remove this.
|
||||
//m_impl->SetModeSelect(kDisabled); // TODO when firmware is updated, uncomment this.
|
||||
m_controlEnabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::EnableControl() {
|
||||
SetControlMode(m_controlMode);
|
||||
m_controlEnabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::SetP(double p)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::SetI(double i)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::SetD(double d)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::SetPID(double p, double i, double d)
|
||||
{
|
||||
SetP(p);
|
||||
SetI(i);
|
||||
SetD(d);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
double CANTalon::GetP()
|
||||
{
|
||||
// TODO
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
double CANTalon::GetI()
|
||||
{
|
||||
// TODO
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
double CANTalon::GetD()
|
||||
{
|
||||
// TODO
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the voltage coming in from the battery.
|
||||
*
|
||||
* @return The input voltage in vols.
|
||||
*/
|
||||
float CANTalon::GetBusVoltage()
|
||||
{
|
||||
double voltage;
|
||||
CTR_Code status = m_impl->GetBatteryV(voltage);
|
||||
if(status != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
return voltage;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
float CANTalon::GetOutputVoltage()
|
||||
{
|
||||
int throttle11;
|
||||
CTR_Code status = m_impl->GetAppliedThrottle11(throttle11);
|
||||
float voltage = GetBusVoltage() * float(throttle11) / 1023.0;
|
||||
if(status != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
return voltage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
float CANTalon::GetOutputCurrent()
|
||||
{
|
||||
double current;
|
||||
|
||||
CTR_Code status = m_impl->GetCurrent(current);
|
||||
if(status != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
float CANTalon::GetTemperature()
|
||||
{
|
||||
double temp;
|
||||
|
||||
CTR_Code status = m_impl->GetTemp(temp);
|
||||
if(temp != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*
|
||||
* @return The position of the sensor currently providing feedback.
|
||||
*/
|
||||
double CANTalon::GetPosition()
|
||||
{
|
||||
int postition;
|
||||
// TODO convert from int to appropriate units (or at least document it).
|
||||
|
||||
CTR_Code status = m_impl->GetSensorPosition(postition);
|
||||
if(status != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
return (double)postition;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*
|
||||
* @returns The speed of the sensor currently providing feedback.
|
||||
*/
|
||||
double CANTalon::GetSpeed()
|
||||
{
|
||||
int speed;
|
||||
// TODO convert from int to appropriate units (or at least document it).
|
||||
|
||||
CTR_Code status = m_impl->GetSensorVelocity(speed);
|
||||
if(status != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
return (double)speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
bool CANTalon::GetForwardLimitOK()
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
bool CANTalon::GetReverseLimitOK()
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
uint16_t CANTalon::GetFaults()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::SetVoltageRampRate(double rampRate)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The version of the firmware running on the Talon
|
||||
*/
|
||||
uint32_t CANTalon::GetFirmwareVersion()
|
||||
{
|
||||
int firmwareVersion;
|
||||
|
||||
CTR_Code status = m_impl->GetFirmVers(firmwareVersion);
|
||||
if(status != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
|
||||
return firmwareVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::ConfigNeutralMode(NeutralMode mode)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::ConfigEncoderCodesPerRev(uint16_t codesPerRev)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::ConfigPotentiometerTurns(uint16_t turns)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::DisableSoftPositionLimits()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::ConfigLimitMode(LimitMode mode)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::ConfigForwardLimit(double forwardLimitPosition)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::ConfigReverseLimit(double reverseLimitPosition)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
* Does this exist on the Talon?
|
||||
*/
|
||||
void CANTalon::ConfigMaxOutputVoltage(double voltage)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
* Does this exist on the Talon?
|
||||
*/
|
||||
void CANTalon::ConfigFaultTime(float faultTime)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
void CANTalon::SetControlMode(CANSpeedController::ControlMode mode)
|
||||
{
|
||||
m_controlMode = mode;
|
||||
CTR_Code status = m_impl->SetModeSelect((int)mode);
|
||||
if(status != CTR_OKAY) {
|
||||
wpi_setErrorWithContext(status, getHALErrorMessage(status));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO documentation (see CANJaguar.cpp)
|
||||
*/
|
||||
CANSpeedController::ControlMode CANTalon::GetControlMode()
|
||||
{
|
||||
return m_controlMode;
|
||||
}
|
||||
|
||||
void CANTalon::SetExpiration(float timeout)
|
||||
{
|
||||
m_safetyHelper->SetExpiration(timeout);
|
||||
}
|
||||
|
||||
float CANTalon::GetExpiration()
|
||||
{
|
||||
return m_safetyHelper->GetExpiration();
|
||||
}
|
||||
|
||||
bool CANTalon::IsAlive()
|
||||
{
|
||||
return m_safetyHelper->IsAlive();
|
||||
}
|
||||
|
||||
bool CANTalon::IsSafetyEnabled()
|
||||
{
|
||||
return m_safetyHelper->IsSafetyEnabled();
|
||||
}
|
||||
|
||||
void CANTalon::SetSafetyEnabled(bool enabled)
|
||||
{
|
||||
m_safetyHelper->SetSafetyEnabled(enabled);
|
||||
}
|
||||
|
||||
void CANTalon::GetDescription(char *desc)
|
||||
{
|
||||
sprintf(desc, "CANTalon ID %d", m_deviceNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Common interface for stopping the motor
|
||||
* Part of the MotorSafety interface
|
||||
*
|
||||
* @deprecated Call Disable instead.
|
||||
*/
|
||||
void CANTalon::StopMotor()
|
||||
{
|
||||
Disable();
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2014. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WPILib.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "TestBench.h"
|
||||
|
||||
TEST(CANTalonTest, QuickTest) {
|
||||
CANTalon talon(0);
|
||||
talon.SetControlMode(CANTalon::kPercentVbus);
|
||||
talon.EnableControl();
|
||||
talon.Set(1.0);
|
||||
Wait(0.25);
|
||||
EXPECT_GT(talon.GetOutputCurrent(), 4.0);
|
||||
|
||||
talon.Set(0.0);
|
||||
talon.Disable();
|
||||
}
|
||||
Reference in New Issue
Block a user