ReduxLib C++ 2023.1.0
No Matches
redux::sensors::canandcoder::CANandcoder Class Reference

#include <CANandcoder.h>

Inheritance diagram for redux::sensors::canandcoder::CANandcoder:

Public Member Functions

 CANandcoder (int id)
units::turn_t GetPosition ()
units::turn_t GetAbsPosition ()
bool SetPosition (units::turn_t newPosition, units::second_t timeout=50_ms)
bool SetAbsPosition (units::turn_t newPosition, units::second_t timeout=50_ms)
bool ZeroAll (units::second_t timeout=50_ms)
units::turns_per_second_t GetVelocity ()
bool MagnetInRange ()
CANandcoderFaults GetStickyFaults ()
CANandcoderFaults GetActiveFaults ()
units::celsius_t GetTemperature ()
void ClearStickyFaults ()
void SetPartyMode (uint8_t level)
std::optional< CANandcoderSettingsGetSettings (units::second_t timeout=350_ms)
void StartFetchSettings ()
CANandcoderSettings GetSettingsAsync ()
bool SetSettings (const CANandcoderSettings &settings, units::second_t timeout=50_ms)
bool ResetFactoryDefaults (bool clearZero=false, units::second_t timeout=350_ms)
bool IsPresent (units::second_t timeout=2000_ms)
redux::frames::Frame< units::turn_t > & GetPositionFrame ()
redux::frames::Frame< units::turn_t > & GetAbsPositionFrame ()
redux::frames::Frame< units::turns_per_second_t > & GetVelocityFrame ()
redux::frames::Frame< CANandcoderStatus > & GetStatusFrame ()
void HandleMessage (redux::canand::CANandMessage &msg) override
redux::canand::CANandAddressGetAddress () override
virtual void HandleMessage (CANandMessage &msg)=0
virtual CANandAddressGetAddress ()=0

Protected Attributes

redux::frames::Frame< units::turn_t > position {0.0_tr, 0_ms}
redux::frames::Frame< units::turn_t > absPosition {0.0_tr, 0_ms}
redux::frames::Frame< units::turns_per_second_t > velocity {0_tps, 0_ms}
redux::frames::Frame< CANandcoderStatusstatus {CANandcoderStatus{0, 0, false, 30_degC, false}, 0_ms}

Static Protected Attributes

static constexpr double COUNTS_PER_ROTATION = 16384
static constexpr double VEL_TICK_PER_RPS = 1024

Additional Inherited Members

- Protected Member Functions inherited from redux::canand::CANandDevice
void SetSettingById (uint8_t settingId, uint8_t *value, uint8_t length)
void HandleSettingRecv (uint8_t settingId, uint64_t settingValue)
std::optional< uint64_t > ConfirmSetSetting (uint8_t settingIdx, uint8_t *payload, uint8_t length, units::second_t timeout)
bool SendCANMessage (uint8_t apiIndex, uint8_t *data, uint8_t length)
template<std::size_t len>
requires (len < 8U)
void SendCANMessage (uint8_t msgId, std::span< std::byte, len > data)

Detailed Description

Class for the CAN interface of the CANandcoder.

If you are using a CANandcoder with Spark Max or Talon with the PWM output, see our Spark Max docs or our Talon SRX docs for information on how to use the encoder with the Rev and CTRE APIs.

The C++ vendordep uses the units library for all dimensioned values, including settings.

Operations that receive data from the device (position, velocity, faults, temperature) generally do not block. The object receives data asynchronously from the CAN packet receive thread and reads thus return the last data received.

Operations that set settings or change offsets will generally wait for up to 50ms by default as they will usually wait for a confirmation packet to be received in response – unless the blocking timeout is set to zero, in which case the operation swill not block.

Example code:

CANandcoder canandcoder{0}; // instantiates with encoder id 0 

// Reading the CANandcoder
canandcoder.GetPosition(); // returns a multi-turn relative position, in rotations (turns)
canandcoder.GetAbsPosition(); // returns an absolute position bounded from [0..1) over one rotation
canandcoder.GetVelocity(); // returns measured velocity in rotations per second

// Updating position
canandcoder.SetPosition(-3.5_tr); // sets the relative position to -3.5 turns (does not persist on reboot)
canandcoder.SetAbsPosition(330_deg, 0); // sets the absolute position to 330 degrees without blocking for confirmation (persists on reboot)
canandcoder.ZeroAll(); // sets both the relative and absolute position to zero

// Changing configuration
CANandcoderSettings settings;
settings.SetVelocityFilterPeriod(25_ms); // sets the velocity filter averaging period to 25 ms
settings.SetInvertDirection(true); // make positive be clockwise instead of ccw opposite the sensor face
canandcoder.SetSettings(settings, 50_ms); // apply the new settings to the device, with maximum 50 ms timeout per settings operation

// Faults
canandcoder.ClearStickyFaults(); // clears all sticky faults (including the power cycle flag). This call does not block.

// this flag will always be true on boot until the sticky faults have been cleared, 
// so if this prints true the encoder has rebooted sometime between ClearStickyFaults and now.
CANandcoderFaults faults = canandcoder.GetStickyFaults(); // fetches faults
fmt::print("Encoder rebooted: {}\n", faults.powerCycle);

// Timestamped data
FrameData<double> posFrame = canandcoder.GetPositionFrame(); // gets current position + timestamp together
posFrame.GetValue(); // fetched position in rotations
posFrame.GetTimestamp(); // timestamp of the previous position

Constructor & Destructor Documentation

◆ CANandcoder()

redux::sensors::canandcoder::CANandcoder::CANandcoder ( int  id)

Constructor with the device's id. This object will be constant with respect to whatever CAN id assigned to it, so if a device changes id it may change which device this object reads from.

idthe device id to use

Member Function Documentation

◆ ClearStickyFaults()

void redux::sensors::canandcoder::CANandcoder::ClearStickyFaults ( )

Clears sticky faults.

It is recommended to clear this during initialization, so one can check if the encoder loses power during operation later.

This call does not block, so it may take up to the next status frame (default every 1000 ms) for the sticky faults to be updated.

◆ GetAbsPosition()

units::turn_t redux::sensors::canandcoder::CANandcoder::GetAbsPosition ( )

Gets the current absolute position of the encoder, in a scaled value from 0 inclusive to 1 exclusive. By default, higher values are in the counter-clockwise direction from the sensor face.

This value will persist across encoder power cycles making it appropriate for swerves/arms/etc.

absolute position in fraction of a rotation [0..1)

◆ GetAbsPositionFrame()

redux::frames::Frame< units::turn_t > & redux::sensors::canandcoder::CANandcoder::GetAbsPositionFrame ( )

Returns the current absolute position frame, which includes CAN timestamp data.

the current position frame, which will hold the current position in the same units as CANandcoder::getAbsPosition()

◆ GetActiveFaults()

CANandcoderFaults redux::sensors::canandcoder::CANandcoder::GetActiveFaults ( )

Fetches active faults. Active faults are only active for as long as the error state exists.

CANandcoderFaults of the active faults

◆ GetAddress()

redux::canand::CANandAddress & redux::sensors::canandcoder::CANandcoder::GetAddress ( )

Returns the reference to the CANandAddress representing the combination of CAN bus and CAN device ID that this CANandDevice refers to.

Implementing device subclasses should likely construct a new CANandAddress in their constructor and return it here.

a reference to the CANandAddress for the device.

Implements redux::canand::CANandDevice.

◆ GetPosition()

units::turn_t redux::sensors::canandcoder::CANandcoder::GetPosition ( )

Gets the current integrated position in rotations.

This value does not wrap around, so turning a sensed axle multiple rotations will return multiple sensed rotations of position. By default, positive is in the counter-clockwise direction from the sensor face.

On encoder power-on, unlike the absolute value, this value will always initialize to zero.

signed relative position in rotations (range [-131072.0..131071.999938396484])

◆ GetPositionFrame()

redux::frames::Frame< units::turn_t > & redux::sensors::canandcoder::CANandcoder::GetPositionFrame ( )

Returns the current relative position frame, which includes CAN timestamp data. redux::canand::FrameData objects are immutable.

the current position frame, which will hold the current position in the same units as CANandcoder::GetPosition()

◆ GetSettings()

std::optional< CANandcoderSettings > redux::sensors::canandcoder::CANandcoder::GetSettings ( units::second_t  timeout = 350_ms)

Fetches the CANandcoder's current configuration in a blocking manner. This function will need to block for at least 0.2-0.3 seconds waiting for the encoder to reply, so it is best to put this in a teleop or autonomous init function, rather than the main loop.

timeoutmaximum number of seconds to wait for settings before giving up (default 0.350s)
std::optional with CANandcoderSettings if received or std::nullopt on timeout

◆ GetSettingsAsync()

CANandcoderSettings redux::sensors::canandcoder::CANandcoder::GetSettingsAsync ( )

Non-blockingly returns a CANandcoderSettings object of the most recent known settings values received from the encoder.

Most users will probably want to use CANandcoder::GetSettings() instead.

One can call this after a CANandcoder::StartFetchSettings() call, and use CANandcoderSettings::AllSettingsReceived() to check if/when all values have been seen. As an example:

// somewhere in an init function
CANandcoder enc = CANandcoder(0); 

// ...
// somewhere in a loop function

CANandcoderSettings stg = enc.GetSettingsAsync(stg);
if (stg.AllSettingsReceived()) {
  // do something with the returned settings
  fmt::print("Encoder velocity frame period: {}\n", *stg.GetVelocityFramePeriod());

If this is called after CANandcoder::SetSettings(), this method will return a settings object where only the fields where the encoder has echoed the new values back will be populated. To illustrate this, consider the following:

// somewhere in a loop 
CANandcoderSettings stg_set;
CANandcoderSettings stg_get = enc.GetSettingsAsync();

// will likely return std::nullopt, as the encoder hasn't confirmed the previous transaction

// after up to 100 ms...
stg_get = enc.GetSettingsAsync();
*stg_get.getVelocityFramePeriod(); // will likely return 100
CANandcoderSettings of currently known settings

◆ GetStatusFrame()

redux::frames::Frame< CANandcoderStatus > & redux::sensors::canandcoder::CANandcoder::GetStatusFrame ( )

Returns a handle to the current status frame, which includes CAN timestamp data.

the current status frame, as a CANandcoderStatus record.

◆ GetStickyFaults()

CANandcoderFaults redux::sensors::canandcoder::CANandcoder::GetStickyFaults ( )

Fetches sticky faults. Sticky faults are the active faults, except once set they do not become unset until ClearStickyFaults() is called.

CANandcoderFaults of the sticky faults

◆ GetTemperature()

units::celsius_t redux::sensors::canandcoder::CANandcoder::GetTemperature ( )

Get onboard encoder temperature readings in degrees Celsius.

temperature in degrees Celsius

◆ GetVelocity()

units::turns_per_second_t redux::sensors::canandcoder::CANandcoder::GetVelocity ( )

Returns the measured velocity in rotations per second.

velocity, in rotations (turns) per second

◆ GetVelocityFrame()

redux::frames::Frame< units::turns_per_second_t > & redux::sensors::canandcoder::CANandcoder::GetVelocityFrame ( )

Returns the current velocity frame, which includes CAN timestamp data.

the current velocity frame, which will hold the current velocity in the same units as CANandcoder::getVelocity()

◆ HandleMessage()

void redux::sensors::canandcoder::CANandcoder::HandleMessage ( redux::canand::CANandMessage msg)

A callback called when a Redux CAN message is received and should be parsed. Subclasses of CANandDevice should override this to update their internal state accordingly.

HandleMessage will be called on all Redux CAN packets received by the vendordep that match the CANandAddress returned by CANandDevice::GetAddress().

msga reference to a CANandMessage representing the received message. The message may not have lifetime outside the function call.

Implements redux::canand::CANandDevice.

◆ IsPresent()

bool redux::sensors::canandcoder::CANandcoder::IsPresent ( units::second_t  timeout = 2000_ms)

Checks whether or not the CANandcoder has sent a message within the last timeout seconds.

timeoutwindow to check for message updates (default 2.0 seconds)
true if there has been a message within the last timeout seconds, false if not

◆ MagnetInRange()

bool redux::sensors::canandcoder::CANandcoder::MagnetInRange ( )

Returns whether the encoder magnet is in range of the sensor or not. This can be seen visually on the sensor – a green LED is in range, whereas a red LED is out of range.

whether the output shaft magnet is in range.

◆ ResetFactoryDefaults()

bool redux::sensors::canandcoder::CANandcoder::ResetFactoryDefaults ( bool  clearZero = false,
units::second_t  timeout = 350_ms 

Resets the encoder to factory defaults.

clearZerowhether to clear the zero offset from the encoder's memory as well
timeouthow long to wait for the new settings to be confirmed by the encoder (default 0.35s, set to 0 to not block)
true if successful, false if a setting operation timed out or if timeout is 0

◆ SetAbsPosition()

bool redux::sensors::canandcoder::CANandcoder::SetAbsPosition ( units::turn_t  newPosition,
units::second_t  timeout = 50_ms 

Sets the new absolute position value for the encoder which will persist across reboots

newPositionnew absolute position in fraction of a rotation (acceptable range [0..1))
timeoutmaximum time to wait for the operation to be confirmed (default 0.050 seconds). Set to 0 to not check (and not block).
true on success, false on timeout

◆ SetPartyMode()

void redux::sensors::canandcoder::CANandcoder::SetPartyMode ( uint8_t  level)

Controls "party mode" – an encoder identification tool that blinks the onboard LED various colors at a user-specified strobe period. The strobe period of the LED will be (50 milliseconds * level). Setting this to 0 disables party mode.

This function does not block.

levelthe party level value to set.

◆ SetPosition()

bool redux::sensors::canandcoder::CANandcoder::SetPosition ( units::turn_t  newPosition,
units::second_t  timeout = 50_ms 

Sets the new relative (multi-turn) position of the encoder to the given value.

Note that this does not update the absolute position, and this value is lost on a power cycle. To update the absolute position, use CANandcoder::SetAbsPosition

newPositionnew position in rotations
timeoutmaximum time to wait for the operation to be confirmed (default 0.050 seconds). Set to 0 to not check (and not block).
true on success, false on timeout

◆ SetSettings()

bool redux::sensors::canandcoder::CANandcoder::SetSettings ( const CANandcoderSettings settings,
units::second_t  timeout = 50_ms 

Applies the settings from a CANandcoderSettings object to the CANandcoder. For more information, see the CANandcoderSettings class documentation.

settingsthe CANandcoderSettings to update the encoder with
timeoutmaximum time in seconds to wait for each setting to be confirmed. (default 0.050s, set to 0 to not check and not block).
true if successful, false if a setting operation timed out

◆ StartFetchSettings()

void redux::sensors::canandcoder::CANandcoder::StartFetchSettings ( )

Tells the CANandcoder to begin transmitting its settings; once they are all transmitted (after ~200-300ms), the values can be retrieved through the CANandcoder::GetSettingsAsync() function call

◆ ZeroAll()

bool redux::sensors::canandcoder::CANandcoder::ZeroAll ( units::second_t  timeout = 50_ms)

Sets both the current absolute and relative encoder position to 0 – generally equivalent to pressing the physical zeroing button on the encoder.

timeoutmaximum time in seconds to wait for each operation to be confirmed (there are 2 ops for zeroing both absolute and relative positions, so the wait is up to 2x timouet). Set to 0 to not check (and not block).
true on success, false on timeout

Member Data Documentation

◆ absPosition

redux::frames::Frame<units::turn_t> redux::sensors::canandcoder::CANandcoder::absPosition {0.0_tr, 0_ms}

internal Frame variable holding current absolute position state


constexpr double redux::sensors::canandcoder::CANandcoder::COUNTS_PER_ROTATION = 16384

number of encoder ticks per rotation

◆ position

redux::frames::Frame<units::turn_t> redux::sensors::canandcoder::CANandcoder::position {0.0_tr, 0_ms}

internal Frame variable holding current relative position state

◆ status

redux::frames::Frame<CANandcoderStatus> redux::sensors::canandcoder::CANandcoder::status {CANandcoderStatus{0, 0, false, 30_degC, false}, 0_ms}

internal Frame variable holding current status value state


constexpr double redux::sensors::canandcoder::CANandcoder::VEL_TICK_PER_RPS = 1024

number of velocity ticks per rotation per second

◆ velocity

redux::frames::Frame<units::turns_per_second_t> redux::sensors::canandcoder::CANandcoder::velocity {0_tps, 0_ms}

internal Frame variable holding current velocity state

The documentation for this class was generated from the following file: