Skip to content

Conversation

@StringsVR
Copy link
Contributor

No description provided.

Copy link
Collaborator

@BeepBot99 BeepBot99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall good, some changes requested. In addition to the requested changes, could you link to the WPILib flywheel tuning page somewhere on each of the added pages? Maybe on the guide page it could go in the "make sure to tune your controller" callout.

Also, flywheel.md will not show up in the sidebar. You need to edit the configuration files. You should clone the repo and run npm install and npm run dev (or use the package manager of your choice) to preview the docs locally.

If you're using a command-based framework like NextFTC,
you can create commands that spin the flywheel up or shut it down.

An example of a Flywheel subsystem using NextControl can be found
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example on this page should be without NextFTC, as NextControl does not depend on NextFTC. See the slides page.

```kotlin
controlSystem {
velPid(0.005, 0.0, 0.0)
basicFF(0.01, 0.02, 0.03)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know these are the numbers used in NextFTC/Examples, but in this case, kA in basicFF is actually unused, so it should be replaced with 0.

here will learn how to program your own flywheel subsystem.

> [!TIP]
> This subsystem can be generalized to any subsystem with a motor.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be "to any subsystem with a motor whose velocity needs to be controlled," or something along those lines.

@@ -0,0 +1,231 @@
# Flywheel Subsystem

A subsystem that is found in almost all FTC robots in most seasons is a flywheel,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most seasons is not true. (Although it is true of every season you've competed in.)

> [!TIP]
> This subsystem can be generalized to any subsystem with a motor.

## Step 1: Create your subsystem
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize "subsystem."

Comment on lines +1 to +231
# Flywheel Subsystem

A subsystem that is found in almost all FTC robots in most seasons is a flywheel,
here will learn how to program your own flywheel subsystem.

> [!TIP]
> This subsystem can be generalized to any subsystem with a motor.

## Step 1: Create your subsystem

The first step to creating your subsystem is setting up the structure for it.
There should only be one instance of each
subsystem. To do this, we will make our subsystem
a [singleton](https://www.geeksforgeeks.org/singleton-design-pattern/).

:::tabs key:codes

== Kotlin

Creating our subsystem with the `object` keyword makes it a singleton:

```kotlin
object Flywheel : Subsystem {

}
```

== Java
In Java, there are a couple lines of boilerplate you will need to add to the top
of every subsystem you create to
make it a singleton:

```java
public class Flywheel implements Subsystem {
public static final Flywheel INSTANCE = new Flywheel();
private Flywheel() { }

}
```

:::

## Step 2: Create your motor

Next, we need to set up a motor to power our flywheel. Let's start by creating a
variable to store our motor. It should be
of type `MotorEx`.

:::tabs key:code

== Kotlin

```kotlin
private val motor = MotorEx("flywheel_motor")
```

== Java

```java
private MotorEx motor = new MotorEx("flywheel_motor");
```

:::

We also need a `ControlSystem`, since we want to move our motor. We'll be
using [NextControl](/control), NextFTC's
solution to control in FTC. NextControl makes it very easy to create more
complex controllers if you ever need them.
Let's use a PID controller with a basic feedforward.

:::tabs key:code
== Kotlin

```kotlin
private val controller = controlSystem {
velPid(0.005, 0.0, 0.0)
basicFF(0.0, 0.0, 0.0)
}
```

== Java

```java
private ControlSystem controlSystem = ControlSystem.builder()
.velPid(0.005, 0.0, 0.0)
.basicFF(0.0, 0.0, 0.0)
.build();
```

:::

> [!IMPORTANT]
> Don't forget to tune your controller!

Now, we must set our motor power to the `ControlSystem`'s output every loop. We
can run code every loop by overriding the `periodic()` function.

The reason we set the motor power in `periodic()` instead of in our commands is
that the `ControlSystem` needs to be updated every loop to work properly. If we
only set the motor power in our commands, the motor power would only be updated
when a command is running, meaning once a command finishes, the motor power
would stop being updated and thus remain at whatever it was last set to,
pushing it past its target velocity.

:::tabs key:code

== Kotlin

```kotlin
override fun periodic() {
motor.power = controlSystem.calculate(motor.state)
}
```

== Java

```java
@Override
public void periodic() {
motor.setPower(controlSystem.calculate(motor.getState()));
}
```

:::

That's all you need to do to create a motor in NextFTC.

We're not quite done, though. We still need to create our commands!

## Step 3: Create commands

The last step when you create a Subsystem is to create the commands you'll be
using. This process varies with each
subsystem. Here, we'll create two commands.

To control our motor's velocity , we will be using the `RunToVelocity` command.

Let's create our first `RunToVelocity` command.

:::tabs key:code
== Kotlin

```kotlin
val on: Command = RunToVelocity(controller, 500.0).named("FlywheelOn")
```

== Java

```java
public final Command on = new RunToVelocity(controller, 500.0)
.requires(this)
.named("FlywheelOn");
```

:::

Pretty easy, right? Let's duplicate it and update our variable name and target
velocity to create our off command:

:::tabs key:code
== Kotlin

```kotlin
val off: Command = RunToVelocity(controller, 0.0).named("FlywheelOff")
```

== Java

```java
public final Command off = new RunToVelocity(controller, 0.0)
.requires(this)
.named("FlywheelOff");
```

:::

## Final result

That's it! You've created your first subsystem! Here is the final result:

:::tabs key:code
== Kotlin

```kotlin
object Flywheel : Subsystem {
private val motor = MotorEx("flywheel_motor")

private val controller: ControlSystem = controlSystem {
velPid(0.005, 0.0, 0.0)
basicFF(0.01, 0.02, 0.03)
}

val off: Command = RunToVelocity(controller, 0.0).named("FlywheelOff")
val on: Command = RunToVelocity(controller, 500.0).named("FlywheelOn")

override fun periodic() {
motor.power = controller.calculate(motor.state)
}
}
```

== Java

```java
public class Flywheel implements Subsystem {
public static final Flywheel INSTANCE = new Flywheel();
private Flywheel() { }

private final MotorEx motor = new MotorEx("flywheel_motor");

private final ControlSystem controller = ControlSystem.builder()
.velPid(0.005, 0, 0)
.basicFF(0.01, 0.02, 0.03)
.build();

public final Command off = new RunToVelocity(controller, 0.0)
.requires(this)
.named("FlywheelOff");

public final Command on = new RunToVelocity(controller, 500.0)
.requires(this)
.named("FlywheelOn");

@Override
public void periodic() {
motor.setPower(controller.calculate(motor.getState()));
}
}
```

:::
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general on this page, it seems to be copy-pasted from the lift page. Since users should have already read that page, it is mostly duplicate information. Instead, in places say "as we did in the lift," or something similar (or at least don't make it the exact same text verbatim, that's boring.)

@zachwaffle4 zachwaffle4 requested review from zachwaffle4 and removed request for zachwaffle4 November 20, 2025 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants