I’m dealing with some annoying warning messages from the CANLight class, telling me the device is not present every time the code tries to set the light color (I know it’s not present, since we don’t have a CANLight on our test bot)
The warning is totally expected, and not an issue, but the console print is built into the CANLight class, so I want to try to deter
My original goal was to determine if a CANLight device is present in code, so I can stop sending it commands if I know it doesn’t exist, but as I think about it, a more generalized version of this challenge could be helpful as well in many different ways, making a map of all CAN devices on a robot or detecting if a particular device loses connection during a match.
I have no experience with the WPILib CAN API, and I have been unable to find any in-depth documentation, so here are some specific questions I have about it:
How can I efficiently check which CAN ports are taken?
How can I determine what kind of device is connected to a particular CAN port? (I assume this will depend on the device)
Is there a way to check if a particular CAN ID is being shared by two devices? - this is a very annoying bug to deal with and comes up a lot when working with new Talons. Can we use the WPILib CAN API to avoid it?
My team uses a class we call RobotMap, which serves as a list of all ports (motor controller ports, joystick ports, DIO’s etc.). In the case of motor controllers, when you declare a motor controller in a subsystem it’s port. Here’s some code that can serve as an example
In your subsystem:
climberMotor = new CANTalon(RobotMap.CLIMBER_MOTOR_PORT);
Then in RobotMap:
//drive motor ports
public static final int FRONT_RIGHT_MOTOR_PORT = 0;
public static final int FRONT_LEFT_MOTOR_PORT = 1;
public static final int REAR_RIGHT_MOTOR_PORT = 2;
public static final int REAR_LEFT_MOTOR_PORT = 3;
//climber motor port
public static final int CLIMBER_MOTOR_PORT = 4;
RobotMap is just a useful way to organize various different ports into a central location so 2 motors won’t have the same port for example
We took a different approach to this. We created a “flag” (really a couple of resistors) attached to a DIO port on our test bot’s rio. This allows us to deploy the same code to our test bot and our main bot and have it behave slightly differently on the test bot.
For example, we were getting constant error messages when initializing our cameras (our test rio has damaged USB ports) so we added this:
if (pdp.isTony()) {
try {
UsbCamera camera0 = CameraServer.getInstance().startAutomaticCapture(0);
camera0.setResolution(160, 120);
camera0.setFPS(15);
} catch (Exception e) {
DriverStation.reportError(e.getMessage(), true);
}
try {
UsbCamera camera1 = CameraServer.getInstance().startAutomaticCapture(1);
camera1.setResolution(160, 120);
camera1.setFPS(15);
} catch (Exception e) {
DriverStation.reportError(e.getMessage(), true);
}
}
isTony() is a helper function that simply looks for the state of that DIO port. 1 means this is the test bot, 0 means this is “Tony,” our competition bot.
Applied to the OP’s situation, this would allow you to skip initializing the CANLight device on your test bot. Of course, the rest of your code would have to cleanly handle that uninitialized variable! In my example that’s easy because we never have to touch camera0 and camera1 once they’re initialized.