ReduxLib C++ 2026.1.2
Loading...
Searching...
No Matches
redux::sensors::canandmag::Canandmag Class Reference

#include <Canandmag.h>

Inheritance diagram for redux::sensors::canandmag::Canandmag:
Collaboration diagram for redux::sensors::canandmag::Canandmag:

Public Member Functions

 Canandmag (int canID, std::string bus="halcan")
 
units::turn_t GetPosition ()
 
units::turn_t GetAbsPosition ()
 
bool SetPosition (units::turn_t newPosition, units::second_t timeout=20_ms)
 
bool SetAbsPosition (units::turn_t newPosition, units::second_t timeout=20_ms, bool ephemeral=false)
 
bool ZeroAll (units::second_t timeout=20_ms)
 
units::turns_per_second_t GetVelocity ()
 
bool MagnetInRange ()
 
CanandmagFaults GetStickyFaults ()
 
CanandmagFaults GetActiveFaults ()
 
units::celsius_t GetTemperature ()
 
CanandmagStatus GetStatus ()
 
void ClearStickyFaults ()
 
void SetPartyMode (uint8_t level)
 
CanandmagSettings GetSettings (units::second_t timeout=350_ms, units::second_t missingTimeout=20_ms, uint32_t attempts=3)
 
void StartFetchSettings ()
 
CanandmagSettings GetSettingsAsync ()
 
CanandmagSettings SetSettings (CanandmagSettings &settings, units::second_t timeout=20_ms, uint32_t attempts=3)
 
CanandmagSettings ResetFactoryDefaults (bool clearZero=false, units::second_t timeout=350_ms)
 
redux::canand::CanandSettingsManager< CanandmagSettings > & GetInternalSettingsManager ()
 
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< CanandmagStatus > & GetStatusFrame ()
 
void HandleMessage (redux::canand::CanandMessage &msg) override
 
redux::canand::CanandAddressGetAddress () override
 
std::string GetDeviceClassName () override
 
redux::canand::CanandFirmwareVersion GetMinimumFirmwareVersion () override
 
- Public Member Functions inherited from redux::canand::CanandDevice
bool IsConnected (units::second_t timeout=2_s)
 
std::string GetDeviceName ()
 
virtual void PreHandleMessage (CanandMessage &msg)
 
virtual void CheckReceivedFirmwareVersion ()
 
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)
 

Static Public Attributes

static constexpr double kCountsPerRotation = 16384
 
static constexpr double kCountsPerRotationPerSecond = 1024
 

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< CanandmagStatusstatus {CanandmagStatus{0, 0, false, 30_degC, false}, 0_ms}
 
redux::canand::CanandSettingsManager< CanandmagSettingsstg {*this}
 

Detailed Description

Class for the CAN interface of the Canandmag.

If you are using a Canandmag 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 20ms 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:

Canandmag canandmag{0}; // instantiates with encoder id 0
// Reading the Canandmag
canandmag.GetPosition(); // returns a multi-turn relative position, in rotations (turns)
canandmag.GetAbsPosition(); // returns an absolute position bounded from [0..1) over one rotation
canandmag.GetVelocity(); // returns measured velocity in rotations per second
// Updating position
canandmag.SetPosition(-3.5_tr); // sets the relative position to -3.5 turns (does not persist on reboot)
canandmag.SetAbsPosition(330_deg, 0_s); // sets the absolute position to 330 degrees without blocking for confirmation (persists on reboot)
canandmag.ZeroAll(); // sets both the relative and absolute position to zero
// Changing configuration
settings.SetVelocityFilterWidth(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
canandmag.SetSettings(settings, 20_ms); // apply the new settings to the device, with maximum 20 ms timeout per settings operation
// Faults
canandmag.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.
CanandmagFaults faults = canandmag.GetStickyFaults(); // fetches faults
fmt::print("Encoder rebooted: {}\n", faults.powerCycle);
// Timestamped data
redux::frames::FrameData<units::turn_t> posFrameData = canandmag.GetPositionFrame().GetFrameData(); // gets current position + timestamp together
posFrameData.GetValue(); // fetched position in rotations
posFrameData.GetTimestamp(); // timestamp of the previous position
Definition Frame.h:52
Definition CanandmagFaults.h:13
bool powerCycle
Definition CanandmagFaults.h:34
Definition CanandmagSettings.h:54
void SetVelocityFilterWidth(units::millisecond_t widthMs)
Definition Canandmag.h:92

Constructor & Destructor Documentation

◆ Canandmag()

redux::sensors::canandmag::Canandmag::Canandmag ( int  canID,
std::string  bus = "halcan" 
)

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.

Parameters
canIDthe device id to use
busthe message bus to use. Defaults to "halcan"

Member Function Documentation

◆ ClearStickyFaults()

void redux::sensors::canandmag::Canandmag::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::canandmag::Canandmag::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.

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

◆ GetAbsPositionFrame()

redux::frames::Frame< units::turn_t > & redux::sensors::canandmag::Canandmag::GetAbsPositionFrame ( )
inline

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

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

◆ GetActiveFaults()

CanandmagFaults redux::sensors::canandmag::Canandmag::GetActiveFaults ( )

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

Returns
CanandmagFaults of the active faults

◆ GetAddress()

redux::canand::CanandAddress & redux::sensors::canandmag::Canandmag::GetAddress ( )
overridevirtual

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.

Returns
a reference to the CanandAddress for the device.

Implements redux::canand::CanandDevice.

◆ GetDeviceClassName()

std::string redux::sensors::canandmag::Canandmag::GetDeviceClassName ( )
inlineoverridevirtual

Returns a canonical class-wide device name.

Returns
std::string of a device type name

Reimplemented from redux::canand::CanandDevice.

◆ GetInternalSettingsManager()

redux::canand::CanandSettingsManager< CanandmagSettings > & redux::sensors::canandmag::Canandmag::GetInternalSettingsManager ( )
inline

Returns the CanandSettingsManager associated with this device.

The CanandSettingsManager is an internal helper object. Teams are typically not expected to use it except for advanced cases (e.g. custom settings wrappers)

Returns
internal settings manager handle

◆ GetMinimumFirmwareVersion()

redux::canand::CanandFirmwareVersion redux::sensors::canandmag::Canandmag::GetMinimumFirmwareVersion ( )
inlineoverridevirtual

Returns the minimum firmware version this vendordep requires.

Returns
minimum firmware version

Reimplemented from redux::canand::CanandDevice.

◆ GetPosition()

units::turn_t redux::sensors::canandmag::Canandmag::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.

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

◆ GetPositionFrame()

redux::frames::Frame< units::turn_t > & redux::sensors::canandmag::Canandmag::GetPositionFrame ( )
inline

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

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

◆ GetSettings()

CanandmagSettings redux::sensors::canandmag::Canandmag::GetSettings ( units::second_t  timeout = 350_ms,
units::second_t  missingTimeout = 20_ms,
uint32_t  attempts = 3 
)
inline

Fetches the Canandmag'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 an init function, rather than the main loop.

Note that unlike v2023, this function will always return a settings object, but they may be incomplete settings!

You will need to do something like this to unwrap/verify the result:

// device declaration
Canandmag canandmag{0};
// in your init/other sequence
CanandmagSettings stg = canandmag.GetSettings();
if (stg.AllSettingsReceived()) {
// do your thing here
} else {
// handle missing settings
}
redux::canand::CanandSettingsManager< CanandmagSettings > stg
Definition Canandmag.h:434

Advanced users can use this function to retry settings missed from StartFetchSettings:

// device declaration
Canandmag canandmag{0};
enc.StartFetchSettings(); // send a "fetch settings command"
// wait some amount of time
CanandmagSettings stg = enc.GetSettingsAsync();
stg.AllSettingsReceived(); // may or may not be true
stg = enc.GetSettings(0_ms, 20_ms, 3); // Retry getitng the missing settings.
stg.AllSettingsReceived(); // far more likely to be true
bool AllSettingsReceived() const
Definition CanandSettings.h:56
void StartFetchSettings()
Definition Canandmag.h:270
Parameters
timeoutmaximum number of seconds to wait for a settings operation before timing out (default 350_ms)
missingTimeoutmaximum number of seconds to wait for each settings retry before giving up
attemptsnumber of attempts to try and fetch values missing from the first pass
Returns
Received set of CanandmagSettings of device configuration.

◆ GetSettingsAsync()

CanandmagSettings redux::sensors::canandmag::Canandmag::GetSettingsAsync ( )
inline

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

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

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

// device declaration
Canandmag enc{0};
// somewhere in an init function
// ...
// somewhere in a loop function
CanandmagSettings stg = enc.GetSettingsAsync();
if (stg.AllSettingsReceived()) {
// do something with the returned settings
fmt::print("Encoder velocity frame period: {}\n", *stg.GetVelocityFramePeriod());
}

If this is called after Canandmag::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:

// device declaration
Canandmag enc{0};
// somewhere in a loop
stg_set.SetVelocityFramePeriod(100_ms);
enc.SetSettings(stg_set);
CanandmagSettings stg_get = enc.GetSettingsAsync();
// will likely return std::nullopt, as the device likely hasn't already responded to the settings set request
// after up to 100 ms...
stg_get = enc.GetSettingsAsync();
// will likely be a value equivalent to 100_ms, may still be std::nullopt if the device is disconnected, so be careful of blind dereferences
void SetVelocityFramePeriod(units::second_t period)
std::optional< units::second_t > GetVelocityFramePeriod()
Returns
CanandmagSettings of currently known settings

◆ GetStatus()

CanandmagStatus redux::sensors::canandmag::Canandmag::GetStatus ( )
inline

Get the contents of the previous status packet, which includes active faults, sticky faults, and temperature.

Returns
device status as a status struct

◆ GetStatusFrame()

redux::frames::Frame< CanandmagStatus > & redux::sensors::canandmag::Canandmag::GetStatusFrame ( )
inline

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

Returns
the current status frame, as a CanandmagStatus record.

◆ GetStickyFaults()

CanandmagFaults redux::sensors::canandmag::Canandmag::GetStickyFaults ( )

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

Returns
CanandmagFaults of the sticky faults

◆ GetTemperature()

units::celsius_t redux::sensors::canandmag::Canandmag::GetTemperature ( )

Get onboard encoder temperature readings in degrees Celsius.

Returns
temperature in degrees Celsius

◆ GetVelocity()

units::turns_per_second_t redux::sensors::canandmag::Canandmag::GetVelocity ( )

Returns the measured velocity in rotations per second.

Returns
velocity, in rotations (turns) per second

◆ GetVelocityFrame()

redux::frames::Frame< units::turns_per_second_t > & redux::sensors::canandmag::Canandmag::GetVelocityFrame ( )
inline

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

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

◆ HandleMessage()

void redux::sensors::canandmag::Canandmag::HandleMessage ( redux::canand::CanandMessage msg)
overridevirtual

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().

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

Implements redux::canand::CanandDevice.

◆ MagnetInRange()

bool redux::sensors::canandmag::Canandmag::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.

Returns
whether the output shaft magnet is in range.

◆ ResetFactoryDefaults()

CanandmagSettings redux::sensors::canandmag::Canandmag::ResetFactoryDefaults ( bool  clearZero = false,
units::second_t  timeout = 350_ms 
)
inline

Resets the encoder to factory defaults, and then wait for all settings to be broadcasted back.

Parameters
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 in seconds (suggested at least 0.35 seconds)
Returns
CanandmagSettings object of received settings. Use CanandmagSettings.AllSettingsReceived() to verify success.

◆ SetAbsPosition()

bool redux::sensors::canandmag::Canandmag::SetAbsPosition ( units::turn_t  newPosition,
units::second_t  timeout = 20_ms,
bool  ephemeral = false 
)

Sets the new absolute position value for the encoder which will (by default) persist across reboots.

Parameters
newPositionnew absolute position in fraction of a rotation (acceptable range [0..1))
timeoutmaximum time to wait for the operation to be confirmed (default 0.020 seconds). Set to 0 to not check (and not block).
ephemeralif true, set the setting ephemerally – the new zero offset will not persist on power cycle.
Returns
true on success, false on timeout

◆ SetPartyMode()

void redux::sensors::canandmag::Canandmag::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.

Parameters
levelthe party level value to set.

◆ SetPosition()

bool redux::sensors::canandmag::Canandmag::SetPosition ( units::turn_t  newPosition,
units::second_t  timeout = 20_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 Canandmag::SetAbsPosition

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

◆ SetSettings()

CanandmagSettings redux::sensors::canandmag::Canandmag::SetSettings ( CanandmagSettings settings,
units::second_t  timeout = 20_ms,
uint32_t  attempts = 3 
)
inline

Applies the settings from a CanandmagSettings object to the Canandmag. For more information, see the CanandmagSettings class documentation.

Example:

Canandmag enc{0};
// After configuring the settings object...
CanandmagSettings failed = enc.SetSettings(stg);
if (failed.IsEmpty()) {
// success
} else {
// handle failed settings
}
bool IsEmpty() const
Definition CanandSettings.h:85
Parameters
settingsthe CanandmagSettings to update the encoder with
timeoutmaximum time in seconds to wait for each setting to be confirmed. (default 0.020s, set to 0 to not check and not block).
attemptsthe maxinum number of attempts to write each individual settings
Returns
CanandmagSettings object of unsuccessfully set settings.

◆ StartFetchSettings()

void redux::sensors::canandmag::Canandmag::StartFetchSettings ( )
inline

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

◆ ZeroAll()

bool redux::sensors::canandmag::Canandmag::ZeroAll ( units::second_t  timeout = 20_ms)

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

Parameters
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).
Returns
true on success, false on timeout

Member Data Documentation

◆ absPosition

redux::frames::Frame<units::turn_t> redux::sensors::canandmag::Canandmag::absPosition {0.0_tr, 0_ms}
protected

internal Frame variable holding current absolute position state

◆ kCountsPerRotation

constexpr double redux::sensors::canandmag::Canandmag::kCountsPerRotation = 16384
staticconstexpr

number of encoder ticks per rotation

◆ kCountsPerRotationPerSecond

constexpr double redux::sensors::canandmag::Canandmag::kCountsPerRotationPerSecond = 1024
staticconstexpr

number of velocity ticks per rotation per second

◆ position

redux::frames::Frame<units::turn_t> redux::sensors::canandmag::Canandmag::position {0.0_tr, 0_ms}
protected

internal Frame variable holding current relative position state

◆ status

redux::frames::Frame<CanandmagStatus> redux::sensors::canandmag::Canandmag::status {CanandmagStatus{0, 0, false, 30_degC, false}, 0_ms}
protected

internal Frame variable holding current status value state

◆ stg

redux::canand::CanandSettingsManager<CanandmagSettings> redux::sensors::canandmag::Canandmag::stg {*this}
protected

internal settings manager

◆ velocity

redux::frames::Frame<units::turns_per_second_t> redux::sensors::canandmag::Canandmag::velocity {0_tps, 0_ms}
protected

internal Frame variable holding current velocity state


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