Class CanandUtils

java.lang.Object
com.reduxrobotics.canand.CanandUtils

public class CanandUtils extends Object
Series of utility functions for CAN messaging and bit manipulation. For more information, see https://docs.wpilib.org/en/stable/docs/software/can-devices/can-addressing.html
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    static long
    Shorthand for BitSet.toLongArray()[0], except zero length bitsets return 0.
    static long
    bytesToLong(byte[] data)
    Convert bytes to long without allocating new bytebuffers.
    static int
    constructMessageId(int deviceType, int devId, int pageId, int msgId)
    Construct a CAN message id to send to a Redux device.
    static float
    extractFloat(byte[] v, int bstart)
    Extracts a float from a byte array.
    static float
    Convert a 24-bit float in a long field to a 32-bit float.
    static long
    extractLong(byte[] v, int start, int end, boolean signed)
    More scope-limited long-extracting helper that only works on up to 8-length byte arrays.
    static long
    extractLong(BitSet v, int start, int end, boolean signed)
    Extracts a long from a BitSet, optionally sign-extending the output.
    static long
    Converts a 32-bit float to a 24-bit representation with the least significant eight bits of mantissa removed.
    static long
    floatToShiftedLong(float v, int bitstart)
    Writes a float to a long.
    static int
    getApiIndex(int fullId)
    Extracts the 8-bit API index from a full message id.
    static int
    getApiPage(int fullId)
    Extracts 2-bit product id/API class from a full message id Instead of doing a 6bit/4bit split for api class/api index, we use an even 5 bit split.
    static int
    getDeviceId(int fullId)
    Extracts 6-bit device id from a full message id This is the "CAN id" that end users will see and care about.
    static int
    getDeviceType(int fullId)
    Extracts 5-bit device type code from a full message id
    static double
    Always returns the hardware FPGA timestamp.
    static boolean
    idMatches(int idToCompare, int deviceType, int devId)
    Checks if a full CAN id will match against device type and device id We use this to determine if a message is intended for a specific device.
    static BitSet
    signExtend(BitSet v, int s)
    Sign extends a BitSet to 64 bits by copying the bit from index s-1 to [s..64).
    static void
    writeFloatToBytes(float v, byte[] dest, int bstart)
    Writes a float to a byte array.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • CanandUtils

      public CanandUtils()
  • Method Details

    • getDeviceType

      public static int getDeviceType(int fullId)
      Extracts 5-bit device type code from a full message id
      Parameters:
      fullId - the full 29-bit message id
      Returns:
      the device type code
    • getApiPage

      public static int getApiPage(int fullId)
      Extracts 2-bit product id/API class from a full message id Instead of doing a 6bit/4bit split for api class/api index, we use an even 5 bit split.
      Parameters:
      fullId - the full 29-bit message id
      Returns:
      the product id code
    • getApiIndex

      public static int getApiIndex(int fullId)
      Extracts the 8-bit API index from a full message id. Instead of doing a 6bit/4bit split for api class/api index, we use an even 5 bit split.
      Parameters:
      fullId - the full 29-bit message id
      Returns:
      the product id code
    • getDeviceId

      public static int getDeviceId(int fullId)
      Extracts 6-bit device id from a full message id This is the "CAN id" that end users will see and care about.
      Parameters:
      fullId - the full 29-bit message id
      Returns:
      the device CAN id
    • idMatches

      public static boolean idMatches(int idToCompare, int deviceType, int devId)
      Checks if a full CAN id will match against device type and device id We use this to determine if a message is intended for a specific device.
      Parameters:
      idToCompare - full 29-bit id
      deviceType - device id code
      devId - device id
      Returns:
      whether the parameters matches the message id
    • constructMessageId

      public static int constructMessageId(int deviceType, int devId, int pageId, int msgId)
      Construct a CAN message id to send to a Redux device.
      Parameters:
      deviceType - the device id code
      devId - CAN device id
      pageId - API page id
      msgId - API message id
      Returns:
      a 29-bit full CAN message id
    • bytesToLong

      public static long bytesToLong(byte[] data)
      Convert bytes to long without allocating new bytebuffers.
      Parameters:
      data - byte array
      Returns:
      long made of the first 8 bytes
    • signExtend

      public static BitSet signExtend(BitSet v, int s)
      Sign extends a BitSet to 64 bits by copying the bit from index s-1 to [s..64).
      Parameters:
      v - the BitSet to sign extend.
      s - the index of the first bit to apply sign extension to. Bit s-1 will be sampled to determine the sign value.
      Returns:
      v, the input BitSet
    • bsToLong

      public static long bsToLong(BitSet v)
      Shorthand for BitSet.toLongArray()[0], except zero length bitsets return 0.
      Parameters:
      v - the input BitSet
      Returns:
      v interpreted as a long
    • extractLong

      public static long extractLong(BitSet v, int start, int end, boolean signed)
      Extracts a long from a BitSet, optionally sign-extending the output.
      Parameters:
      v - input BitSet to extract from
      start - index of the first bit to extract
      end - index after the last bit to extract
      signed - whether the long is signed
      Returns:
      an extracted long
    • extractLong

      public static long extractLong(byte[] v, int start, int end, boolean signed)
      More scope-limited long-extracting helper that only works on up to 8-length byte arrays. Use the BitSet version for values that are across 9 or more bytes.
      Parameters:
      v - byte array that is 0-8 bytes long
      start - index of the first bit to extract
      end - index after the last bit to extract
      signed - whether to sign extend the result
      Returns:
      an extracted long
    • extractFloat

      public static float extractFloat(byte[] v, int bstart)
      Extracts a float from a byte array.
      Parameters:
      v - byte array, length should be >= 4
      bstart - byte index to start reading from where bstart + 4 < v.length
      Returns:
      float value
    • writeFloatToBytes

      public static void writeFloatToBytes(float v, byte[] dest, int bstart)
      Writes a float to a byte array.
      Parameters:
      v - the value to write
      dest - the byte array to write into
      bstart - index to start writing at
    • floatToShiftedLong

      public static long floatToShiftedLong(float v, int bitstart)
      Writes a float to a long.
      Parameters:
      v - the value to write
      bitstart - bitindex to start writing at
      Returns:
      shifted long
    • floatToGuineaFloat24

      public static long floatToGuineaFloat24(float v)
      Converts a 32-bit float to a 24-bit representation with the least significant eight bits of mantissa removed. This properly conserves NaN/inf values as Float.floatToIntBits(float) always coerces to the canonical represntations for NaNs.
      Parameters:
      v - float value
      Returns:
      24-bit value as long
    • extractFloatFromGuineaFloat24

      public static float extractFloatFromGuineaFloat24(long v)
      Convert a 24-bit float in a long field to a 32-bit float.
      Parameters:
      v - 24-bit float value
      Returns:
      java float value
    • getFPGATimestamp

      public static double getFPGATimestamp()
      Always returns the hardware FPGA timestamp.

      Certain popular libraries think it is really funny to replace Timer.getFPGATimestamp() with a version that only updates every 20 milliseconds.

      Unfortunately for us, this makes ReduxLib internals not function correctly, so this calls the JNI function directly to sidestep that shim.

      Returns:
      the current time in seconds according to the FPGA