Skip to content

Commit

Permalink
Added Akit Subsystems
Browse files Browse the repository at this point in the history
  • Loading branch information
falOn-Dev committed Jun 13, 2024
1 parent 4e5c1f5 commit 80180b5
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 3 deletions.
3 changes: 2 additions & 1 deletion book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
- [Robot Programming](robot/robot.md)
- [Intro to WPILIB](robot/intro-to-wpilib.md)
- [Device I/O](robot/device-io.md)
- [IO Layers](robot/io-layers.md)
- [IO Layers](robot/advantagekit/io-layers.md)
- [Robot Code Structure](robot/robot-code-structure.md)
- [AdvantageKit Subsystems](robot/advantagekit/akit-subsystems.md)
- [Open-Loop Control](robot/open-loop-control.md)
- [Closed-Loop Control](robot/closed-loop-control.md)
- [Development Practices](development-practices/intro.md)
Expand Down
70 changes: 70 additions & 0 deletions book/src/robot/advantagekit/akit-subsystems.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Subsystems With AdvantageKit

Building off of both the previous section, and the section on IO Layers, we can now create a subsystem that uses an IO
layer to interact with hardware. This allows us to easily swap out the implementation of the hardware without changing
the
code that uses it, and makes it easy to test the subsystem in isolation with a mock implementation of the IO layer.

## Creating a Subsystem

The structure of a subsystem using AdvantageKit is very similar to that of a subsystem using barebones WPILib. The main
difference is that instead of directly interacting with the hardware, you interact with an IO layer that abstracts away
the
hardware. This makes it easy to swap out the implementation of the hardware without changing the code that uses it, and
makes
it easy to test the subsystem in isolation with a mock implementation of the IO layer.

A subsystem in AdvantageKit typically won't contain any methods for interacting with the hardware, instead, it will
contain
a public instance of an IO layer for raw hardware interaction from outside the subsystem, and command factory methods
that
create commands that interact with the hardware.

A subsystem in AdvantageKit also typically won't contain any properties for the sensor values, instead, it will contain
a public instance of an Inputs object that is updated by the IO layer, and can be read from outside the subsystem.

Here's an example of a subsystem that controls a drivetrain using an IO layer:

```kotlin
/*
Assume we have a DrivetrainIO interface that has methods for controlling the drivetrain, and an Inputs object that
contains the sensor values for the drivetrain
*/

class DriveSubsystem : SubsystemBase {
val io: DrivetrainIO
val inputs = DrivetrainIO.DrivetrainIOInputs()

constructor(io: DrivetrainIO) {
this.io = io
}

fun getDriveCommand(speed: Double, rotation: Double): Command {
return this.run {
io.drive(speed, rotation)
}
}

fun driveDistance(distance: Double): Command {
return this.run {
io.drive(0.5, 0.0)
}.until { inputs.leftWheelDistance >= distance }
}

override fun periodic() {
io.updateInputs(inputs)
Logger.processInputs(inputs)
}
}
```

In this example, the `DriveSubsystem` class contains an instance of a `DrivetrainIO` interface, and an instance of a
`DrivetrainIOInputs` object that contains the sensor values for the drivetrain. The `DriveSubsystem` class also contains
methods for creating commands that interact with the hardware, and a `periodic` method that updates the sensor values
from the IO layer and logs them with the `processInputs` method of the `Logger` class.

As you can also see, when creating the subsystem you'll need to pass in an instance of the IO layer that the subsystem
will use. This allows you to easily swap out the implementation of the hardware without changing the code that uses it,
and makes it easy to test the subsystem in isolation with a simulated implementation of the IO layer.

## Conclusion
File renamed without changes.
4 changes: 2 additions & 2 deletions book/src/robot/robot-code-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ Here's an example of a simple subsystem that controls a drivetrain
import java.util.function.DoubleSupplier

class Drivetrain : Subsystem() {
private val leftMotor = Talon(0)
private val rightMotor = Talon(1)
private val leftMotor = CANSparkMax(0, MotorType.kBrushless)
private val rightMotor = CANSparkMax(1, MotorType.kBrushless)

fun drive(speed: Double, rotation: Double) {
leftMotor.set(speed + rotation)
Expand Down

0 comments on commit 80180b5

Please sign in to comment.