For the complete documentation index, see llms.txt. This page is also available as Markdown.

Access raw hardware devices

Get the actual vendor motor controller/encoder/gyro objects SwerveParser built, for configuration that isn't exposed through SmartMotorController.

Most robot code never needs this page. SwerveDrive, SwerveModule, and YAMS's SmartMotorController cover driving, telemetry, and the vast majority of per-motor configuration. Reach for createSwerveDriveDevices when you need to call a vendor-specific method (a CTRE TalonFXConfigurator option, a REV SparkMax signal, a CANcoder-specific setting) that SmartMotorController doesn't expose, or when you need real hardware, not a wrapper, for something like MegaTag2 vision fusion (see the example below).

SwerveParser.createSwerveDrive(config) hands you back a fully-built SwerveDrive. Everything underneath it (drive/azimuth motor controllers, absolute encoders, the gyro) is wrapped and effectively private. SwerveParser.createSwerveDriveDevices(config) builds the exact same hardware, but also gives you the raw vendor objects it created along the way, alongside the SwerveDrive itself.

1. Call createSwerveDriveDevices instead of createSwerveDrive

import swervelib.parser.SwerveParser;
import swervelib.parser.SwerveParser.SwerveDriveDevices;

SwerveParser.parse(new File(Filesystem.getDeployDirectory(), "swerve/base"));
SwerveDriveDevices devices = SwerveParser.createSwerveDriveDevices(cfg);

drive = devices.swerveDrive();

2. Read the devices back out

SwerveDriveDevices is a record with three components:

Component
Type
Notes

swerveDrive

SwerveDrive

The same object createSwerveDrive(...) would have returned. Use it exactly as normal.

gyro

Object

The raw gyro device (e.g. a CTRE Pigeon2), or null if gyro.type is "custom". See below.

modules

SwerveModuleDevices[]

One entry per module, in the same order as the modules array in swervedrive.json.

Each SwerveModuleDevices is in turn:

Component
Type
Notes

drive

Object

Raw drive motor controller (e.g. a REV SparkMax/SparkFlex, or a CTRE TalonFX/TalonFXS).

azimuth

Object

Raw azimuth/angle motor controller.

absoluteEncoder

Object

Raw absolute encoder device: a separate device (e.g. CANcoder, AnalogEncoder, DutyCycleEncoder), or the same object as azimuth if the encoder is attached to the azimuth controller.

Cast each Object to whatever vendor type you know it to be from your swervedrive.json/module JSON type strings (see Device Type Strings):

3. Example: full 3-axis gyro data for MegaTag2

SwerveDrive.getGyroAngle() only ever gives you yaw, which is genuinely all MegaTag2 requires (see How to use a custom gyro for the same point applied to skew correction). But if your gyro is a full IMU and you'd like to feed a vision coprocessor real roll and pitch too, you need the raw device, not the wrapped one:

Then hand that to your vision coprocessor's orientation input the same way you would the yaw-only version, for example YALL's LimelightSettings.withRobotOrientation(...). Whether the extra roll/pitch actually improves your pose estimate depends on your camera mount and how noisy that IMU data is; it isn't automatically better than yaw-only, just more complete.

This pattern is vendor-specific: getRotation3d() and per-axis StatusSignals are CTRE Pigeon2 methods. A different gyro's raw device exposes full orientation and angular velocity differently, or not at all, in which case yaw-only (from SwerveDrive.getGyroAngle()) is what you have, and that's fine, it's all MegaTag2 needs anyway.

4. Handle a custom gyro

If swervedrive.json's gyro.type is "custom", the parser never builds a gyro device at all, see How to use a custom gyro, so devices.gyro() is null. Your own gyro object (the one you constructed to call SwerveDriveConfig.withGyro(...)) is already in scope wherever you built it; there's nothing to retrieve here.

Why Object?

SwerveModuleDevices/SwerveDriveDevices are deliberately vendor-agnostic. YAGSL supports mixing CTRE, REV, ThriftyBot, AndyMark, and Redux hardware across modules (see Supported Hardware), so there's no single common supertype to return instead of Object. The cast is the price of that flexibility.

Last updated

Was this helpful?