Logging is how we keep track of the robot’s, or it’s mechanism’s, states, variables, and other stuff. All of our logging is based off AdvantageKit, and specifically the LoggedRobot class, which our Robot class inherits from.

https://github.com/team4099/Offseason-2025/blob/fef4fd0e6bc73e1355973ba8d574f73f9c3136e3/src/main/kotlin/com/team4099/robot2025/Robot.kt#L44

Logging with LoggableInputs

All of our subsystems are logged in the AdvantageKit style of logging. I’m sure you’ve seen by now that our subsystems have at least 3 files. For this example, I’ll use 2025 offseason elevator.

The ElevatorIO.kt file is the file that deals with logging our inputs from the motor. The class that represents this is named, not surprisingly, LoggableInputs. We override the LoggableInputs interface with our own inputs method. Here, we define all the variables that we want to save from the motor, including the current motor’s position, voltage, temperature, and current.

https://github.com/team4099/Offseason-2025/blob/de4234512ea9f216ae43720ed6c430ed59b6a198/src/main/kotlin/com/team4099/robot2025/subsystems/elevator/ElevatorIO.kt#L27-L90

The functions toLog and fromLog both are overriden and take parameter of type LogTable. In the toLog, you put all the data that we have into the logs (populate the logs). In the fromLog , we update the fields with the data received from the logs (populate the fields).

<aside> 🤔

You may be wondering, why the FIRST would we take data from the logs and put that into our fields, if we know our fields are the ones in the data anyways? Well, the real reason is to REPLAY a match based off of a LogTable . The robot code will read the values from the LogTable and update the fields to that.

</aside>

Then, the implementation files for ElevatorIO (our hardware and software files) inherit this ElevatorIO interface, as you’re likely familiar with. The reason we do this is to take the updateInputs method, which takes in parameter of type [SubsystemIO].[Subsystem]Inputs. This function is used to update all of the fields that you defined in your [Subsytem]Inputs class.

For example, this is what it looks like in our Offseason-2025 ElevatorIOTalonFX.kt

https://github.com/team4099/Offseason-2025/blob/e4435b5577b36cb4f76aee9a850f48615ddad043/src/main/kotlin/com/team4099/robot2025/subsystems/elevator/ElevatorIOTalon.kt#L188-L216