Class Canandgyro

java.lang.Object
com.reduxrobotics.canand.CanandDevice
com.reduxrobotics.sensors.canandgyro.Canandgyro
All Implemented Interfaces:
AutoCloseable

public class Canandgyro extends CanandDevice
Class for the CAN interface of the Canandgyro.

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 (heading, 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:
 Canandgyro canandgyro = new Canandgyro(0); // gyro id 0 
 
 // Reading angular position
 canandgyro.getYaw(); // gets the yaw (Z-axis) value in rotations [-0.5 inclusive..0.5 exclusive)
                      // This is probably what you want to use for robot heading.
 canandgyro.getMultiturnYaw(); // also gets yaw, except without a wraparound
 canandgyro.getPitch(); // pitch (Y-axis) value
 canandgyro.getRoll(); // roll (X-axis) value
 canandgyro.getRotation2d(); // Z-axis Rotation2d object
 canandgyro.getRotation3d(); // Full 3d rotation object
 canandgyro.getQuaternion(); // Raw rotation quaternion object
                             // getQuaternion{X, Y, Z, W}() methods also exist to avoid allocation.
 
 
 // Reading angular velocity (all in rotations per second)
 canandgyro.getAngularVelocityYaw();
 canandgyro.getAngularVelocityPitch();
 canandgyro.getAngularVelocityRoll();
 
 // Linear acceleration (gravitational units)
 canandgyro.getAccelerationX();
 canandgyro.getAccelerationY();
 canandgyro.getAccelerationZ();
 
 // Updating pose:
 canandgyro.setYaw(0.25); // set yaw to 0.25 rotations positive
 canandgyro.setPose(0.0, 0.1, 0.25, 0.02); // set roll, pitch, yaw as 0.0, 0.1, and 0.25 rotations
                                           // with 20 ms timeout
 
 // Manually calibrating:
 // The Canandgyro automatically calibrates on boot, but you may want to force a calibration.
 // Calibration takes several seconds!!!
 
 canandgyro.startCalibration(); // begin calibration
 canandgyro.isCalibrating(); // check if the gyro is still calibrating
 canandgyro.waitForCalibrationToFinish(5.0); // wait up to 5 seconds for calibration to finish.
 
 
 // Changing configuration and adjusting frame periods
 CanandgyroSettings settings = new CanandgyroSettings();
 settings.setYawFramePeriod(20); // sets the yaw frame period to one packet every 20 ms
 settings.setAngularPositionFramePeriod(10); // sets the angular position frame period to once 
                                             // every 10 ms (may be useful for balancing)
 settings.setAccelerationFramePeriod(0); // disable accel frame periods (default quite low anyway)
 canandgyro.setSettings(settings, 0.020); // apply the new settings to the device, with maximum 
                                          // 20 ms timeout per settings operation
 
 // Faults
 canandgyro.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 gyro has rebooted sometime between clearStickyFaults and now.
 CanandgyroFaults faults = canandgyro.getStickyFaults(); // fetches faults
 System.out.printf("Device rebooted: %d\n", faults.powerCycle());
 
 // Timestamped data
 // gets current angular position + timestamp together
 var quatFrameData = canandgyro.getAngularPositionFrame();
 quatFrameData.getValue(); // fetched quaternion object
 quatFrameData.getW(); // fetched quaternion W component
 quatFrameData.getTimestamp(); // timestamp of the quaternion data
 
  • Field Details

    • singleYaw

      protected final DoubleFrame<Double> singleYaw
      Yaw frame (units: rotations)
    • multiYaw

      protected final DoubleFrame<Double> multiYaw
      Yaw frame (units: rotations)
    • quat

      protected final QuaternionFrame quat
      Quaternion frame
    • vel

      protected final Vec3Frame vel
      Angular velocity frame (rotations/second)
    • accel

      protected final Vec3Frame accel
      Linear acceleration frame (gravitational unit Gs)
    • status

      protected final ByteArrayFrame<CanandgyroStatus> status
      Status frame
    • calibrating

      protected final AtomicBoolean calibrating
      Calibrating state
  • Constructor Details

    • Canandgyro

      public Canandgyro(int canID)
      Instantiates a new Canandgyro.
      Parameters:
      canID - the device id assigned to it.
  • Method Details

    • getQuaternion

      public Quaternion getQuaternion()
      Gets a quaternion object of the gyro's 3d rotation from the zero point -- Warning: this allocates objects! Limit the number of calls you make to this per robot loop!
      Returns:
      a Quaternion of the current Canandgyro pose
    • getRotation3d

      public Rotation3d getRotation3d()
      Gets a Rotation3d object of the gyro's 3d rotation from the zero point -- Warning: this allocates objects! Limit the number of calls you make to this per robot loop! If you just want Z-axis rotation as a double, it's more performant to use getYaw().
      Returns:
      a Rotation3d of the current Canandgyro pose
    • getRotation2d

      public Rotation2d getRotation2d()
      Gets a Rotation2d object representing the rotation around the yaw axis from the zero point -- Warning: this allocates objects! Limit the number of calls you make to this per robot loop! If you just want Z-axis rotation as a double, it's more performant to use getYaw().
      Returns:
      a Rotation2d of the current Canandgyro yaw
    • getQuaternionW

      public double getQuaternionW()
      Gets the W term of the current Canandgyro rotation quaternion, normalized from [-1.0..1.0] inclusive.
      Returns:
      quaternion term value
    • getQuaternionX

      public double getQuaternionX()
      Gets the X term of the current Canandgyro rotation quaternion, normalized from [-1.0..1.0] inclusive.
      Returns:
      quaternion term value
    • getQuaternionY

      public double getQuaternionY()
      Gets the Y term of the current Canandgyro rotation quaternion, normalized from [-1.0..1.0] inclusive.
      Returns:
      quaternion term value
    • getQuaternionZ

      public double getQuaternionZ()
      Gets the Z term of the current Canandgyro rotation quaternion, normalized from [-1.0..1.0] inclusive.
      Returns:
      quaternion term value
    • useDedicatedYawAngleFrame

      public void useDedicatedYawAngleFrame(boolean use)
      Sets whether this object should use the dedicated yaw message for yaw angle instead of deriving it from the pose quaternion frame. By default this is true, as the yaw angle frame is more precise and by default more frequent.
      Parameters:
      use - use the yaw angle
    • getYaw

      public double getYaw()
      Gets the yaw (Z-axis) rotation from [-0.5 inclusive..0.5 exclusive). This is probably the function you want to use for applications like field-centric control, although some libraries may want the value from getRotation2d() instead.

      Multiplying by (2 * Math.PI) will give you radians, while multiplying by 360 will give you degrees.

      If you want a multi-turn yaw that does not wrap around, consider getMultiturnYaw()

      Returns:
      yaw in rotations.
    • getMultiturnYaw

      public double getMultiturnYaw()
      Gets a multi-turn yaw (Z-axis) rotation that tracks to multiple continuous rotations. Note that this relies on the dedicated multi-turn yaw packet so if it is disabled via CanandgyroSettings.setYawFramePeriod(double) it will not return fresh data.
      Returns:
      multi-turn yaw in rotations.
    • getPitch

      public double getPitch()
      Gets the pitch (Y-axis) rotation from [-0.5 inclusive..0.5 exclusive).
      Returns:
      pitch in rotations.
    • getRoll

      public double getRoll()
      Gets the roll (Z-axis) rotation from [-0.5 inclusive..0.5 exclusive).
      Returns:
      roll in rotations.
    • getAngularVelocityRoll

      public double getAngularVelocityRoll()
      Gets the angular velocity along the roll (X) axis in rotations per second.
      Returns:
      angular velocity in rot/s
    • getAngularVelocityPitch

      public double getAngularVelocityPitch()
      Gets the angular velocity along the pitch (Y) axis in rotations per second.
      Returns:
      angular velocity in rot/s
    • getAngularVelocityYaw

      public double getAngularVelocityYaw()
      Gets the angular velocity along the yaw (Z) axis in rotations per second.
      Returns:
      angular velocity in rot/s
    • getAccelerationX

      public double getAccelerationX()
      Gets the linear acceleration along the X axis in gravitational units.
      Returns:
      linear acceleration in Gs
    • getAccelerationY

      public double getAccelerationY()
      Gets the linear acceleration along the Y axis in gravitational units.
      Returns:
      linear acceleration in Gs
    • getAccelerationZ

      public double getAccelerationZ()
      Gets the linear acceleration along the Z axis in gravitational units.
      Returns:
      linear acceleration in Gs
    • getYawFrame

      public DoubleFrame<Double> getYawFrame()
      Gets the dedicated single-turn yaw Frame object.
      Returns:
      yaw frame
    • getMultiturnYawFrame

      public DoubleFrame<Double> getMultiturnYawFrame()
      Gets the dedicated multi-turn yaw Frame object.
      Returns:
      yaw frame
    • getAngularPositionFrame

      public QuaternionFrame getAngularPositionFrame()
      Gets the angular position Frame object.
      Returns:
      angular position quaternion frame
    • getAngularVelocityFrame

      public Vec3Frame getAngularVelocityFrame()
      Gets the angular velocity Frame object. getValue() returns a Vec<N3> in roll/pitch/yaw order in rotations per second.
      Returns:
      angular velocity frame
    • getAccelerationFrame

      public Vec3Frame getAccelerationFrame()
      Gets the linear acceleration Frame object. getValue() returns a Vec<N3> in x/y/z order in gravitational units.
      Returns:
      acceleration frame
    • getStatusFrame

      public Frame<CanandgyroStatus> getStatusFrame()
      Returns the current status frame which includes CAN timestamp data.
      Returns:
      the current status frame as a CanandgyroStatus record.
    • startCalibration

      public void startCalibration()
      Tell the Canandgyro to begin its calibration routine. This calibration routine is performed automatically on power-on and takes several seconds. The LED on the Canandgyro will stay at a solid yellow during the calibration process. As this method returns immidiately, it is up to the user code to determine if the device is done calibrating (e.g. through isCalibrating()).
    • isCalibrating

      public boolean isCalibrating()
      Returns if the Canandgyro is known to be currently calibrating.
      Returns:
      if the Canandgyro is calibrating
    • waitForCalibrationToFinish

      public boolean waitForCalibrationToFinish(double timeout)
      Blocks the current thread until the Canandgyro has finished calibrating or until a timeout is reached.
      Parameters:
      timeout - the timeout in seconds to wait for a calibration confirmation.
      Returns:
      true if the calibration has finished within the timeout, false if not.
    • setPose

      public boolean setPose(double newRoll, double newPitch, double newYaw, double timeout)
      Sets a new angular position pose without recalibrating with a given roll/pitch/yaw. If you just want to set yaw, use setYaw(double, double)
      Parameters:
      newRoll - new roll (x) pose in rotations
      newPitch - new pitch (y) pose in rotations
      newYaw - new yaw (z) pose in rotations
      timeout - the timeout in seconds to wait for a pose set confirmation. Set to 0 to not check (always return true.)
      Returns:
      true if a pose set confirmation was received (or if timeout is zero)
    • setPose

      public boolean setPose(Rotation3d newPose, double timeout)
      Sets a new angular position without recalibrating with a Rotation3d.
      Parameters:
      newPose - new rotation3d pose
      timeout - the timeout in seconds to wait for a pose set confirmation. Set to 0 to not check (always return true.)
      Returns:
      true if a pose set confirmation was received (or if timeout is zero)
    • setPose

      public boolean setPose(Quaternion newPose, double timeout)
      Sets a new pose without recalibrating with a Quaternion.
      Parameters:
      newPose - new quaternion pose
      timeout - the timeout in seconds to wait for a pose set confirmation. Set to 0 to not check (always return true.)
      Returns:
      true if a pose set confirmation was received (or if timeout is zero)
    • setYaw

      public boolean setYaw(double yaw)
      Sets a new yaw without recalibrating the Canandgyro. Blocks for up to 20 milliseconds to confirm the transaction.
      Parameters:
      yaw - new yaw angle in rotations
      Returns:
      true if a confirmation was received
    • setYaw

      public boolean setYaw(double yaw, double timeout)
      Sets a new yaw without recalibrating the Canandgyro.
      Parameters:
      yaw - new yaw angle in rotations
      timeout - the timeout in seconds to block to confirm the transaction (set 0 to not block)
      Returns:
      true if a confirmation was received or the timeout is zero
    • getStickyFaults

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

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

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

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

      public void clearStickyFaults()
      Clears sticky faults.

      It is recommended to clear this during initialization, so one can check if the device 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 CanandgyroFaults.faultsValid() for faults returned by getStickyFaults()

    • setPartyMode

      public void setPartyMode(int level)
      Controls "party mode" -- an device identification tool that blinks the onboard LED various colors if level != 0. This function does not block.
      Parameters:
      level - the party level value to set.
    • getSettings

      public CanandgyroSettings 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.

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

      Note that 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:
      CanandgyroSettings representing the device's configuration
    • getSettings

      public CanandgyroSettings 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 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:
      CanandgyroSettings representing the device's configuration
    • getSettings

      public CanandgyroSettings getSettings()
      Fetches the device's current configuration in a blocking manner. This function will block for up to 0.350 seconds waiting for the device to reply, so it is best to put this in an init function rather than the main loop.

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

      Returns:
      CanandgyroSettings representing the device's configuration
    • startFetchSettings

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

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

      Most users will probably want to use getSettings() 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
       Canandgyro canandgyro = new Canandgyro(0); 
       canandgyro.startFetchSettings();
       
       // ...
       // somewhere in a loop function
       
       if (canandgyro.getSettingsAsync().allSettingsReceived()) {
         // do something with the settings object
         System.out.printf("Canandgyro yaw frame period: %d\n",
            canandgyro.getSettingsAsync().getYawFramePeriod());
       }
       
      If this is called after setSettings(Canandgyro.CanandgyroSettings), this method will return a settings object where only the fields where the device has echoed the new values back will be populated. To illustrate this, consider the following:
       
       // somewhere in initialization (just as a definition):
       Canandgyro canandgyro = new Canandgyro(0); 
       
       // somewhere in a loop 
       canandgyro.setSettings(new CanandgyroSettings().setStatusFramePeriod(0.100));
       
       // will likely return Empty, as the device hasn't confirmed the previous transaction
       canandgyro.getSettingsAsync().getStatusFramePeriod(); 
       
       // after up to ~300 ms...
       canandgyro.getSettingsAsync().getStatusFramePeriod(); // will likely return 100 ms
       
      Returns:
      CanandgyroSettings object of known settings
      See Also:
    • setSettings

      public CanandgyroSettings setSettings(CanandgyroSettings settings, double timeout, int attempts)
      Applies the settings from a CanandgyroSettings 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 CanandgyroSettings object of settings that were not able to be successfully applied.
      Parameters:
      settings - the CanandgyroSettings 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 CanandgyroSettings object of unsuccessfully set settings.
      See Also:
    • setSettings

      public boolean setSettings(CanandgyroSettings settings, double timeout)
      Applies the settings from a CanandgyroSettings object to the device. For more information, see the CanandgyroSettings class documentation.
      Parameters:
      settings - the CanandgyroSettings to update the device 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 timed out
      See Also:
    • setSettings

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

      public CanandgyroSettings resetFactoryDefaults(double timeout)
      Resets the device to factory defaults.
      Parameters:
      timeout - how long to wait for the new settings to be confirmed by the device in seconds (suggested at least 0.35 seconds)
      Returns:
      CanandgyroSettings object of received settings. Use CanandSettings.allSettingsReceived() to verify success.
    • getInternalSettingsManager

      public CanandSettingsManager<CanandgyroSettings> 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.