Case Study: Migrating the Drivetrain to a CANivore CAN FD Bus
Offload high-traffic devices to a second CAN FD bus to cut utilization and unlock higher update rates.
Sign in to track progress, earn XP, and save lessons.
When you pack a swerve drivetrain plus sensors onto the roboRIO's single CAN bus, utilization can climb toward saturation and you start dropping packets. The CANivore solves this by adding a second, faster CAN FD bus over USB.
The problem, quantified: CTRE documents a test of 35 devices that would require roughly 120% utilization on the standard roboRIO CAN bus, which is impossible, so you lose packets and devices flicker. The general guidance is to keep utilization comfortably below saturation; past it you get lost frames and errors. A full swerve stack plus mechanisms can push a single bus toward that edge.
The fix: the CANivore is a USB-to-CAN FD adapter that gives the roboRIO a second, higher-bandwidth bus. In the same CTRE test, the device set that needed ~120% on a standard bus ran at roughly 51% utilization on CANivore CAN FD (status frame rates unchanged), because CAN FD carries more data per frame, faster.
Migration steps:
- Mount the CANivore and connect it to a roboRIO USB port. Give it a name in Phoenix Tuner X.
- Move the drivetrain devices (the 8 Talon FX, 4 CANcoders, Pigeon 2) onto the CANivore bus, leaving lower-priority devices on the roboRIO 'rio' bus.
- In code, construct devices with the bus name. The CAN bus identifier is
"rio"for the native bus,"*"for the first available CANivore, or the CANivore's name/serial:
import com.ctre.phoenix6.hardware.TalonFX;
import com.ctre.phoenix6.CANBus;
CANBus canivore = new CANBus("drivetrain"); // your CANivore's name
TalonFX frontLeftDrive = new TalonFX(1, canivore);
TalonFX frontLeftSteer = new TalonFX(2, canivore);
// ... remaining drivetrain devices on the same bus
- Verify utilization with
canivore.getStatus(), which returns bus utilization and error counters. Confirm you are comfortably below saturation.
Layer on signal optimization. Even on CAN FD, only request the data you need. Phoenix 6 uses an opt-in model: call setUpdateFrequency() on the signals you use, then optimizeBusUtilization() (or ParentDevice.optimizeBusUtilizationForAll(...)) to slow or disable everything else:
frontLeftDrive.getPosition().setUpdateFrequency(100); // Hz
frontLeftDrive.getVelocity().setUpdateFrequency(100);
frontLeftDrive.optimizeBusUtilization();
Important caution from CTRE: optimizeBusUtilization() slows or disables any signal you did not explicitly set a frequency for, so you must keep required signals enabled. When using followers, the leader must keep its DutyCycle, MotorVoltage, and TorqueCurrent signals; remote sensors (such as a CANcoder feeding a steering motor) must keep their Position and Velocity signals enabled. Always re-verify your sensors still report after optimizing.
Payoff: lower utilization means no dropped packets, and the extra headroom lets you run odometry signals at higher, time-synced rates, which improves swerve pose estimation. This is a high-leverage upgrade for any robot pushing 20+ CAN devices.
Key takeaways
- A full swerve stack can push CAN toward saturation; CTRE's documented test shows ~120% load on a standard bus drops to ~51% on CANivore CAN FD.
- Construct devices with a CANBus name to place them on the CANivore; verify with canivore.getStatus().
- Use Phoenix 6's opt-in signals: setUpdateFrequency() on needed signals then optimizeBusUtilization(), and keep required follower/remote-sensor signals enabled or they will be disabled.
Go deeper
Lesson quiz
RequiredAnswer all 3 questions correctly to complete this lesson.
1.What is the main bandwidth advantage of a CTRE CANivore CAN FD bus over the standard roboRIO CAN 2.0 bus?
2.After migrating supported devices to a CANivore, what typically happens to the reported CAN bus utilization?
3.Besides bandwidth, what does putting CTRE devices on a CANivore CAN FD bus enable for supported hardware?
Answer every question to submit.