Class Canandmag

java.lang.Object
com.reduxrobotics.canand.CanandDevice
com.reduxrobotics.sensors.canandmag.Canandmag
All Implemented Interfaces:
AutoCloseable

public class Canandmag extends CanandDevice
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.

In general, the Java API will use SI units (seconds, meters, deg Celsius), with the exception of rotation being expressed in turns (+1 rotation == 1.0)

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 by default 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 = new Canandmag(0); // 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 inclusive to 1 
                               // exclusive over one rotation
 canandmag.getVelocity(); // returns measured velocity in rotations per second
 
 // Updating position
 canandmag.setPosition(-3.5); // sets the relative position to -3.5 turns with default 
                                // confirmation timeout of 20 ms (does not persist on reboot)
 canandmag.setAbsPosition(0.330, 0); // sets the absolute position to 0.5 turns without blocking
                                       // for confirmation (persists on reboot)
 canandmag.zeroAll(); // sets both the relative and absolute position to zero
 
 // Changing configuration
 Canandmag.Settings settings = new Canandmag.Settings();
 settings.setVelocityFilterWidth(25); // sets the velocity filter averaging period to 25 ms
 settings.setInvertDirection(true); // make positive be clockwise instead of ccw opposite the 
                                    // sensor face
 settings.setPositionFramePeriod(0.010); // set the position frame period to be sent every 10 ms
 canandmag.setSettings(settings, 0.020); // 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 is true the encoder has rebooted sometime between clearStickyFaults and now.
 Canandmag.Faults faults = canandmag.getStickyFaults(); // fetches faults
 System.out.printf("Encoder rebooted: %d\n", faults.powerCycle());
 
 // Timestamped data
 // gets current position + timestamp together
 FrameData<Double> posFrameData = canandmag.getPositionFrame().getFrameData(); 
 posFrameData.getValue(); // fetched position in rotations
 posFrameData.getTimestamp(); // timestamp of the previous position
 
  • Field Details

    • position

      protected DoubleFrame<Double> position
      internal Frame variable holding current relative position state
    • absPosition

      protected DoubleFrame<Double> absPosition
      internal Frame variable holding current absolute position state
    • velocity

      protected DoubleFrame<Double> velocity
      internal Frame variable holding current velocity state
    • status

      protected ByteArrayFrame<Canandmag.Status> status
      internal Frame variable holding current status value state
    • kCountsPerRotationPerSecond

      public static final double kCountsPerRotationPerSecond
      Conversion factor from velocity packet ticks per second to rotations per second.
      See Also:
    • kCountsPerRotation

      public static final double kCountsPerRotation
      Conversion factor for number of position packet ticks per rotation.
      See Also:
  • Constructor Details

    • Canandmag

      public Canandmag(int canID)
      Instantiates a new Canandmag object. 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:
      canID - the device id to use [0..63]
  • Method Details

    • getPosition

      public double getPosition()
      Gets the current integrated relative 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, and also counter-clockwise looking at the LED side of the throughbore.

      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])
    • getAbsPosition

      public double getAbsPosition()
      Gets the current absolute position of the encoder, scaled from 0 inclusive to 1 exclusive.

      By default, higher values are in the counter-clockwise direction from the sensor face, and also counter-clockwise looking at the LED side of the throughbore.

      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)
    • setPosition

      public boolean setPosition(double newPosition, double timeout)
      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 setAbsPosition(double, double, boolean)

      Parameters:
      newPosition - new relative position in rotations (acceptable range [-131072.0..131071.99993896484])
      timeout - maximum time in seconds to wait for a setting to be confirmed. Set to 0 to not check (and not block).
      Returns:
      true on success, false on setting failure
    • setPosition

      public boolean setPosition(double newPosition)
      Sets the new relative (multi-turn) position of the encoder to the given value, with a confirmation timeout of 20 ms.

      Note that this does not update the absolute position, and this value is lost on power cycle. To update the absolute position, use setAbsPosition(double, double, boolean)

      Parameters:
      newPosition - new relative position in rotations (acceptable range [-131072.0..131071.99993896484])
      Returns:
      true on success, false on setting failure
    • setAbsPosition

      public boolean setAbsPosition(double newPosition, double timeout, boolean ephemeral)
      Sets the new absolute position value for the encoder which will (by default) persist across reboots.
      Parameters:
      newPosition - new absolute position in fraction of a rotation (acceptable range [0..1))
      timeout - maximum time in seconds to wait for the operation to be confirmed. Set to 0 to not check (and not block).
      ephemeral - if true, set the setting ephemerally
      Returns:
      true on success, false on setting failure
    • setAbsPosition

      public boolean setAbsPosition(double newPosition, double timeout)
      Sets the new absolute position value for the encoder which will persist across reboots with a specified timeout.
      Parameters:
      newPosition - new absolute position in fraction of a rotation (acceptable range [0..1))
      timeout - maximum time in seconds to wait for the operation to be confirmed. Set to 0 to not check (and not block).
      Returns:
      true on success, false on timeout
    • setAbsPosition

      public boolean setAbsPosition(double newPosition)
      Sets the new absolute position value for the encoder which will persist across reboots with default timeout of 20 ms.
      Parameters:
      newPosition - new absolute position in fraction of a rotation (acceptable range [0..1))
      Returns:
      true on success, false on timeout
    • zeroAll

      public boolean zeroAll(double timeout)
      Sets both the current absolute and relative encoder position to 0 -- generally equivalent to pressing the physical zeroing button on the encoder.
      Parameters:
      timeout - maximum time in seconds to wait for each operation (zeroing absolute and relative position) to be confirmed. Set to 0 to not check (and not block).
      Returns:
      true on success, false on timeout
    • zeroAll

      public boolean zeroAll()
      Sets both the current absolute and relative encoder position to 0 -- generally equivalent to pressing the physical zeroing button on the encoder.

      This will wait up to 20 ms to each of the absolute and relative positions, so up to 100 ms total (realistically less)

      Returns:
      true on success, false on timeout
    • getVelocity

      public double getVelocity()
      Returns the measured velocity in rotations per second.
      Returns:
      velocity, in rotations (turns) per second
    • magnetInRange

      public boolean 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.
    • getStickyFaults

      public Canandmag.Faults getStickyFaults()
      Returns sticky faults. Sticky faults are the active faults, except once set they do not become unset until clearStickyFaults() is called.
      Returns:
      Canandmag.Faults of the sticky faults.
      See Also:
    • getActiveFaults

      public Canandmag.Faults getActiveFaults()
      Returns an object representing currently active faults. Active faults are only active for as long as the error state exists.
      Returns:
      Canandmag.Faults of the active faults
      See Also:
    • getTemperature

      public double getTemperature()
      Get onboard encoder temperature readings in degrees Celsius.
      Returns:
      temperature in degrees Celsius
    • getStatus

      public Canandmag.Status getStatus()
      Get the contents of the previous status packet, which includes active faults, sticky faults, and temperature.
      Returns:
      device status as a Canandmag.Status record
    • clearStickyFaults

      public void 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. To check for validity, use Canandmag.Faults.faultsValid() for faults returned by getStickyFaults()

    • setPartyMode

      public void setPartyMode(int 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:
      level - the party level value to set.
    • getSettings

      public Canandmag.Settings getSettings(double timeout, double missingTimeout, int attempts)
      Fetches the device's current configuration in a blocking manner, with control over failure handling.

      This method works by requesting the device first send back all settings, and then waiting for up to a specified timeout for all settings to be received by the robot controller. If the timeout is zero, this step is skipped.

      If there are settings that were not received by the timeout, then this function will attempt to individually fetched each setting for up to a specified number of attempts. If the fresh argument is true and the timeout argument is 0, then only this latter step runs, which can be used to only fetch settings that are missing from the known settings cache returned by getSettingsAsync().

      The resulting set of known (received) settings is then returned, complete or not.

      This function blocks, so it is best to put this in init routines rather than a main loop.

       Canandmag enc = new Canandmag(0); 
       
       // Typical usage
       // fetch all settings with a timeout of 320 ms, and retry missing values 3 times
       Canandmag.Settings stg = enc.getSettings(0.350, 0.02, 3);
       
       // Advanced usage
       enc.startFetchSettings(); // send a "fetch settings command"
       
       // wait some amount of time
       stg = enc.getSettingsAsync();
       stg.allSettingsReceived(); // may or may not be true
       
       stg = enc.getSettings(0, 0.02, 3); // only fetch the missing settings, with 20ms timeout on each
       stg.allSettingsReceived(); // far more likely to be true
       

      Note that unlike v2023, this function may return incomplete settings! Use CanandSettings.allSettingsReceived() to verify all settings were received.

      Parameters:
      timeout - maximum number of seconds to wait for settings before giving up.
      missingTimeout - maximum number of seconds to wait for each settings retry before giving up.
      attempts - number of attempts to try and fetch values missing from the first pass
      Returns:
      Canandmag.Settings representing the device's configuration
    • getSettings

      public Canandmag.Settings getSettings(double timeout)
      Fetches the device's current configuration in a blocking manner. This function will block for up to the specified number of seconds waiting for the device to reply, so it is best to put this in a teleop or autonomous init function, rather than the main loop.

      If settings time out, it will retry each missing setting once with a 20ms timeout, and if they still fail, a partial Settings will still be returned.

      Note that unlike v2023, this function may return incomplete settings! Use CanandSettings.allSettingsReceived() to verify all settings were received.

      Parameters:
      timeout - maximum number of seconds to wait for settings before giving up
      Returns:
      Canandmag.Settings representing the device's configuration
    • getSettings

      public Canandmag.Settings getSettings()
      Fetches the Canandmag's current configuration in a blocking manner.

      This function will block for up to 0.350 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.

      Note that unlike v2023, this function may return incomplete settings! Use CanandSettings.allSettingsReceived() to verify all settings were received.

      Returns:
      Canandmag.Settings representing the device's configuration
    • startFetchSettings

      public void startFetchSettings()
      Tells the device to begin transmitting its settings. Once they are all transmitted (after ~200-300ms), the values can be retrieved from getSettingsAsync()
    • getSettingsAsync

      public Canandmag.Settings getSettingsAsync()
      Non-blockingly returns a Canandmag.Settings object of the most recent known settings values received from the encoder.

      Most users will probably want to use getSettings(double, double, int) instead. One can call this after a startFetchSettings() call, and use CanandSettings.allSettingsReceived() to check if/when all values have been seen. As an example:

       
       // somewhere in an init function
       Canandmag enc = new Canandmag(0); 
       enc.startFetchSettings();
       
       // ...
       // somewhere in a loop function
       
       if (enc.getSettingsAsync().allSettingsReceived()) {
         // do something with the settings object
         System.out.printf("Encoder velocity frame period: %d\n", 
             enc.getSettingsAsync().getVelocityFramePeriod());
       }
       
      If this is called after setSettings(Canandmag.Settings), 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 an init function
       Canandmag enc = new Canandmag(0); 
       
       // somewhere in a loop 
       enc.setSettings(new Canandmag.Settings().setVelocityFramePeriod(0.100));
       
       // This will likely return empty, as the encoder hasn't confirmed the previous transaction
       enc.getSettingsAsync().getVelocityFramePeriod(); 
       
       // after up to 100 ms...
       enc.getSettingsAsync().getVelocityFramePeriod(); // will likely return 100
       
      Returns:
      Canandmag.Settings object of known settings
      See Also:
    • setSettings

      public Canandmag.Settings setSettings(Canandmag.Settings settings, double timeout, int attempts)
      Applies the settings from a Canandmag.Settings object to the device, with fine grained control over failure-handling. This overload allows specifiyng the number of retries per setting as well as the confirmation timeout. Additionally, it returns a Canandmag.Settings object of settings that were not able to be successfully applied.
      Parameters:
      settings - the Canandmag.Settings to update the encoder with
      timeout - maximum time in seconds to wait for each setting to be confirmed. Set to 0 to not check (and not block).
      attempts - the maximum number of attempts to write each individual setting
      Returns:
      a Canandmag.Settings object of unsuccessfully set settings.
      See Also:
    • setSettings

      public boolean setSettings(Canandmag.Settings settings, double timeout)
      Applies the settings from a Canandmag.Settings object to the Canandmag. For more information, see the Canandmag.Settings class documentation.
      Parameters:
      settings - the Canandmag.Settings to update the encoder with
      timeout - maximum time in seconds to wait for each setting to be confirmed. Set to 0 to not check (and not block).
      Returns:
      true if successful, false if a setting operation failed
      See Also:
    • setSettings

      public boolean setSettings(Canandmag.Settings settings)
      Applies the settings from a Canandmag.Settings object to the Canandmag. For more information, see the Canandmag.Settings class documentation.
      Parameters:
      settings - the Canandmag.Settings to update the encoder with
      Returns:
      true if successful, false if a setting operation timed out
      See Also:
    • resetFactoryDefaults

      public Canandmag.Settings resetFactoryDefaults(boolean clearZero, double timeout)
      Resets the encoder to factory defaults, and then wait for all settings to be broadcasted back.
      Parameters:
      clearZero - whether to clear the zero offset from the encoder's memory as well
      timeout - how long to wait for the new settings to be confirmed by the encoder in seconds (suggested at least 0.35 seconds)
      Returns:
      Canandmag.Settings object of received settings. Use CanandSettings.allSettingsReceived() to verify success.
    • resetFactoryDefaults

      public Canandmag.Settings resetFactoryDefaults(boolean clearZero)
      Resets the encoder to factory defaults, waiting up to 500 ms to confirm the settings changes.
      Parameters:
      clearZero - whether to clear the zero offset from the encoder's memory as well
      Returns:
      Canandmag.Settings object of received settings. Use CanandSettings.allSettingsReceived() to verify success.
    • getPositionFrame

      public Frame<Double> getPositionFrame()
      Returns the current relative position frame.
      Returns:
      the current position frame, which will hold the current position in the same units as getPosition()
    • getAbsPositionFrame

      public Frame<Double> getAbsPositionFrame()
      Returns the current absolute position frame.
      Returns:
      the current position frame, which will hold the current position in the same units as getAbsPosition()
    • getVelocityFrame

      public Frame<Double> getVelocityFrame()
      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 getVelocity()
    • getStatusFrame

      public Frame<Canandmag.Status> getStatusFrame()
      Returns the current status frame, which includes CAN timestamp data. FrameData objects are immutable.
      Returns:
      the current status frame, as a Canandmag.Status record.
    • getInternalSettingsManager

      public CanandSettingsManager<Canandmag.Settings> getInternalSettingsManager()
      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
    • handleMessage

      public void handleMessage(CanandMessage msg)
      Description copied from class: CanandDevice
      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().

      Specified by:
      handleMessage in class CanandDevice
      Parameters:
      msg - a CanandMessage representing the received message.
    • getAddress

      public CanandAddress getAddress()
      Description copied from class: CanandDevice
      Returns 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.

      Specified by:
      getAddress in class CanandDevice
      Returns:
      the CanandAddress for the device.
    • getMinimumFirmwareVersion

      public CanandFirmwareVersion getMinimumFirmwareVersion()
      Description copied from class: CanandDevice
      Returns the minimum firmware version this vendordep requires for this device. User-implmenting classes can return null to disable firmware checks.
      Overrides:
      getMinimumFirmwareVersion in class CanandDevice
      Returns:
      minimum firmware version