sign in
Start typing to search across all 16 weeks…
home / summer / week 4
Summer · Week 4 of 8

Arrays & Methods

storing lists of data and writing reusable blocks of code. methods are your best friend :)

Arrays

ok so before last week you learned loops, and you were probably thinking "ok cool, i can repeat stuff." but repeat stuff on WHAT? loops are way more useful when you have a collection of data to work through. that's where arrays come in. an array is just a fixed-size list where every slot holds the same type of thing.

once you have arrays AND loops together, you can do things like "apply this formula to all four drivetrain (the drivetrain is the system of motors and wheels that makes the robot move) motors" in four lines instead of sixteen. that combo is one of the most used patterns in all of FRC code.

arrays — the locker row mental model

imagine a row of lockers at school. each locker has a number painted on the door (0, 1, 2, 3...) and can hold exactly one thing inside. all the lockers in the row hold the same type of stuff — you can't have a locker full of text next to a locker full of numbers. the whole row is one unit — one array.

that number painted on the door is called the index. the thing inside the locker is the value. you get to the value by specifying which locker number you want: lockers[2] means "open locker number 2 and give me what's inside."

now think about real FRC code. a swerve drivetrain (swerve = drivetrain where each wheel steers independently) has four modules. each module has a motor with a CAN ID (CAN ID = the unique number that identifies each motor on the robot's wiring network). before arrays, you'd track each one with a separate variable:

java — the messy way
// tracking four motors with four separate variables — already painful
int motor1 = 1;
int motor2 = 2;
int motor3 = 3;
int motor4 = 4;

// now imagine trying to loop through them. you literally can't.
// imagine passing them all to a method. nightmare.
// imagine changing all four to a new base CAN ID. hunt and replace, four times.

with an array, you collapse all four into one thing you can loop through, pass around, and update in one place:

java — the clean way
// one variable, four values, perfectly loopable
int[] motorIDs = {1, 2, 3, 4};

that's the whole pitch for arrays. one variable, ordered list, same type throughout. let's get into the details.

two ways to declare an array

there are two common patterns for creating an array in Java, and you'll see both in real code. the first is for when you know the size but want to fill it in later. the second is for when you already have the values ready to go.

java
// Way 1: declare the size, fill it in slot by slot
// Java fills all empty slots with 0 for int/double, false for boolean, null for objects
int[] arr = new int[4]; // creates 4 slots, all set to 0 right now
arr[0] = 10;           // assign slot 0
arr[1] = 11;           // assign slot 1
arr[2] = 12;           // assign slot 2
arr[3] = 13;           // assign slot 3

// Way 2: declare and fill in one shot — size is inferred from the list
int[]    motorIDs     = {10, 11, 12, 13};           // 4 ints
double[] moduleAngles = {0.0, 90.0, 180.0, 270.0}; // 4 doubles
boolean[] sensorStates = {false, false, true, false}; // 4 booleans

the syntax int[] means "an array of ints." the square brackets after the type are the signal to Java that this is an array, not a single value. you can also write int arr[] with the brackets after the name, but everyone writes the brackets after the type. go with that style.

use Way 1 when your values come from somewhere else at runtime (like reading from sensors). use Way 2 when you know your values at compile time (like constants for CAN IDs or module offsets).

zero indexing — read this twice

this is the single most common beginner mistake. please read carefully because this trips up almost everyone the first few times.

in Java, arrays start counting at zero, not one. if you have a 4-element array, the valid indices are 0, 1, 2, 3. there is no index 4. the first element is always at index 0, the last is always at index array.length - 1. this is called zero-based indexing and it is universal across nearly every programming language.

java — zero indexing
String[] modules = {"FL", "FR", "BL", "BR"};
//                    [0]    [1]    [2]    [3]
//               ↑ first                last ↑
//              (NOT 1!)           (NOT 4!)

System.out.println(modules[0]); // "FL" — index 0, the first element
System.out.println(modules[1]); // "FR" — index 1
System.out.println(modules[2]); // "BL" — index 2
System.out.println(modules[3]); // "BR" — index 3, the last element

// changing a value is the same syntax as reading, just with = on the right
modules[2] = "BackLeft"; // slot 2 now holds "BackLeft"

quick trick you'll use constantly: the last valid index is always arr.length - 1. if there are 4 elements, last index is 3. if there are 10 elements, last index is 9. whenever you need the last element, write arr[arr.length - 1] and you'll never be wrong.

the .length property

every array has a built-in property called .length that tells you exactly how many slots it has. notice: no parentheses. it's a property, not a method call. arr.length, not arr.length(). (this trips people up because String has a .length() method with parentheses. arrays are different.)

java
double[] speeds = {0.5, 0.75, 1.0, -0.5};

System.out.println(speeds.length); // 4 — counts total slots, not last index
// NOTE: last valid INDEX is 3, but LENGTH is 4. classic confusion point.

// .length in a for loop — this pattern is everywhere in FRC code
for (int i = 0; i < speeds.length; i++) {
    System.out.println("Speed at index " + i + ": " + speeds[i]);
}
// prints:
// Speed at index 0: 0.5
// Speed at index 1: 0.75
// Speed at index 2: 1.0
// Speed at index 3: -0.5

using arr.length in your loop condition instead of a hardcoded number is the right habit to build. if you ever resize the array, the loop automatically adjusts — you don't have to hunt down every place you hardcoded the size.

ArrayIndexOutOfBoundsException — the crash you will definitely see

story time. you have a 4-element array. you're confident the last index is 4, because there are 4 elements. you write arr[4]. the compiler says nothing. you run the program. it immediately crashes with this error:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4

this is one of the most common runtime errors in Java. the compiler cannot catch it because the index might not be known until the program actually runs. Java has to wait and see — and when it sees an invalid index, it crashes.

java — the classic crash
int[] motorIDs = {10, 11, 12, 13};
// valid indices: 0, 1, 2, 3

System.out.println(motorIDs[4]);  // CRASH — index 4 doesn't exist
System.out.println(motorIDs[-1]); // CRASH — negative indices are also invalid

// BAD loop that crashes — uses <= instead of <
for (int i = 0; i <= motorIDs.length; i++) { // on last loop: i=4, CRASH
    System.out.println(motorIDs[i]);
}

// GOOD loop — uses strictly less than (<)
for (int i = 0; i < motorIDs.length; i++) { // stops at i=3, perfectly safe
    System.out.println(motorIDs[i]);
}

// safely getting the last element
System.out.println(motorIDs[motorIDs.length - 1]); // 13 — always safe

ArrayIndexOutOfBoundsException: the two most common causes are (1) using <= instead of < in your loop condition, and (2) using arr.length as an index directly instead of arr.length - 1. both stem from forgetting that indices start at 0 and end at length minus 1, not length.

looping through arrays — tying it all together

arrays and for loops are a combo you'll use constantly. the pattern is always the same: loop from 0 to arr.length - 1 (using i < arr.length), and access each element with arr[i]. here's a real FRC example: you have two parallel arrays, one for CAN IDs and one for module offset angles. you want to print info for every module:

java — FRC: loop through module CAN IDs
final int[]    kModuleCANIDs    = {10, 11, 12, 13};
final double[] kModuleAngles_deg = {0.0, 90.0, 180.0, 270.0};

// both arrays have .length == 4, so this loop runs exactly 4 times (i = 0,1,2,3)
for (int i = 0; i < kModuleCANIDs.length; i++) {
    System.out.println(
        "Module " + i +
        ": CAN ID = " + kModuleCANIDs[i] +  // same index, different array
        ", offset angle = " + kModuleAngles_deg[i] + "°"
    );
}
// Module 0: CAN ID = 10, offset angle = 0.0°
// Module 1: CAN ID = 11, offset angle = 90.0°
// Module 2: CAN ID = 12, offset angle = 180.0°
// Module 3: CAN ID = 13, offset angle = 270.0°

this "parallel arrays" pattern — two arrays with matching indices where arr1[i] and arr2[i] describe the same thing — shows up a lot in FRC. once you get to OOP next week, you'll learn how to bundle those two together into one object. but arrays first.

Declaration
int[] arr = new int[4]
Declare an array of 4 ints. All slots start at 0 until you assign them explicitly.
Initialization
int[] arr = {1, 2, 3, 4}
Declare and fill in one shot. The size is inferred from how many values you give it.
Access
arr[0] arr[1]
Get or set a value by its index. Zero-indexed — first element is always [0], last is [length-1].
Length
arr.length
How many slots the array has. NOT a method — no parentheses. Last valid index is arr.length - 1.

Topic 1 — Coding Prompt

Module Sensor Buffer
Declare and loop through parallel arrays

Declare these two arrays:
double[] motorTemps = {42.1, 38.5, 51.0, 44.8};
String[] moduleNames = {"FL", "FR", "BL", "BR"};

Write a for loop that prints each module on one line like: "FL: 42.1°C"

Use the same index variable to access both arrays at once. After the loop, print the total number of modules using .length.

Topic 1 — Quick Check


Methods

ok so now you can write code that loops, stores lists, and makes decisions. but there's a big problem you'll hit almost immediately: copy-paste. you end up writing the same formula or logic in three different places in your file. then you find a bug in it, and now you have to fix it in three places. miss one and your robot does math wrong at a competition.

methods solve this completely. a method is a named block of code that you write once and can call as many times as you want from anywhere. fix it in the method, fixed everywhere.

the anatomy of a method

think of a method like a recipe. you write the pancake recipe once in a cookbook. then whenever you want pancakes, you just say "make pancakes." you don't re-write the whole recipe every time you want breakfast. the recipe is the method. "make pancakes" is calling it.

here's the non-pancake version. say you need to calculate wheel RPM from motor RPM at three different places in your code. without methods, that's three copies of the same formula:

java — no methods, very bad
// Place 1: in driveForward()
double wheelRPM1 = motorRPM1 / 8.46;

// Place 2: in driveRotate()
double wheelRPM2 = motorRPM2 / 8.46;

// Place 3: in getTelemetry()
double wheelRPM3 = motorRPM3 / 8.46;

// ...oops. the real gear ratio is 8.14, not 8.46.
// now you need to fix it in 3 places. miss one and your robot math is wrong.

with a method, you write the formula once. when the gear ratio changes, you fix one line and everywhere is instantly correct:

java — with a method, much better
// write the recipe once — fix gear ratio here, fixed everywhere
public static double calcWheelRPM(double motorRPM, double gearRatio) {
    return motorRPM / gearRatio;
}

// call it from anywhere, as many times as you want
double wheelRPM1 = calcWheelRPM(motorRPM1, 8.46);
double wheelRPM2 = calcWheelRPM(motorRPM2, 8.46);
double wheelRPM3 = calcWheelRPM(motorRPM3, 8.46);

method anatomy — every piece explained

you need to be able to look at any method signature and immediately know what every word means. let's go piece by piece through a real example. each number below corresponds to a label in the code:

java — method anatomy
//  [1]    [2]    [3]       [4]          [5]                    [5]
public static double calcWheelRPM(double motorRPM, double gearRatio) {
    return motorRPM / gearRatio; // [6] — the body, and return statement
} // closing brace ends the method
[1] public
Access modifier
public means any code anywhere can call this method. private limits it to only code inside the same class. start with public for now — we go deeper on this in the OOP week.
[2] static
Belongs to the class
static means this method belongs to the class itself, not to a specific object. you can call it as ClassName.calcWheelRPM(...) without creating an object first. utility methods are almost always static.
[3] double
Return type
what type of value this method hands back. use void if it does something but doesn't give you a value back. the type here must match what you return inside the body.
[4] calcWheelRPM
Method name
camelCase, starts with a lowercase verb. describes what the method DOES. on WRT, names follow patterns: setX(), getX(), or action words like spin(), stop(), extend().
[5] (double motorRPM, double gearRatio)
Parameters
the inputs to the method. each has a type and a name. the method works with its own copy of these values — changing them inside the method doesn't affect the caller's variables.
[6] return
Return statement
return ends the method immediately and sends a value back. the type of the value must match the declared return type. for void methods, you can omit return entirely or write bare return;.

void methods — doing things without returning anything

not every method hands back a value. sometimes a method just does something — sets a motor speed, prints some info to the console, runs an animation. for those, you use void as the return type. void literally means "nothing" — this method gives nothing back.

java — void vs returning
// void method — does something useful, returns nothing
public static void printSpeed(double speed) {
    System.out.println("Current speed: " + speed);
    // no return statement needed — Java auto-returns when the block ends
    // (you CAN write bare "return;" to exit early, but it's optional here)
}

// returning method — calculates something and hands the result back
public static double clampSpeed(double speed, double maxSpeed) {
    if (speed > maxSpeed)  return  maxSpeed; // early return if too high
    if (speed < -maxSpeed) return -maxSpeed; // early return if too low
    return speed;                             // already in range, return as-is
}

// calling them — notice the difference
printSpeed(0.75);                                 // called as a statement — no assignment
double safeSpeed = clampSpeed(1.5, 1.0); // safeSpeed = 1.0 (was clamped)
double alsoSafe  = clampSpeed(0.8, 1.0); // alsoSafe = 0.8 (already in range)

you cannot do double x = printSpeed(0.75); — there's nothing to assign because printSpeed returns void. the compiler will tell you "incompatible types: void cannot be converted to double." if you need to both do something AND get a value back, use a return type other than void.

parameters vs arguments — the distinction that trips everyone up

these two words get used interchangeably all the time, but they actually mean different things. here's the one-line version: a parameter is the placeholder in the method's definition. an argument is the actual value you pass in when you call it.

Parameter
In the method definition
double motorRPM and double gearRatio in the signature are parameters. they're like the blanks in a recipe: "add ___ cups of flour." the recipe doesn't know the number yet.
Argument
In the method call
5400.0 and 8.46 when you write calcWheelRPM(5400.0, 8.46) are arguments. they're the actual ingredients filling in the blanks in the recipe.

in everyday conversation, people say "parameter" to mean both. that's fine. but in an interview or a code review, knowing the technical distinction shows you actually understand what's happening under the hood.

methods calling other methods

this is where things get powerful. methods can call other methods. you break down complex behavior into small, understandable pieces, and then compose them together. in FRC you'll see this all the time — a high-level shoot() method might call spinUpFlywheels(), then wait for isAtSpeed(), then call activateIndexer().

java — methods calling methods
// step 1: a focused method that does one thing
public static double motorRPMtoWheelRPM(double motorRPM, double gearRatio) {
    return motorRPM / gearRatio;
}

// step 2: another focused method that does one thing
public static double wheelRPMtoSpeed_fps(double wheelRPM, double wheelDiam_in) {
    double circumference_ft = Math.PI * wheelDiam_in / 12.0; // convert inches to feet
    return wheelRPM * circumference_ft / 60.0;               // RPM to fps
}

// step 3: a higher-level method that calls both of the above
public static double motorRPMtoSpeed_fps(double motorRPM, double gearRatio, double wheelDiam_in) {
    double wheelRPM = motorRPMtoWheelRPM(motorRPM, gearRatio);   // call #1
    return wheelRPMtoSpeed_fps(wheelRPM, wheelDiam_in);           // call #2
    // reading this, you can understand what it does without seeing the math
}

each of those small methods is easy to test in isolation and easy to read. the composed version reads almost like English. this is the core idea behind good code structure — small, focused pieces that you build up into bigger behavior.

WRT naming patterns: in our codebase, methods fall into categories. setX() methods change state (like setSpeed(double speed)). getX() methods read state (like getPosition()). action methods describe mechanism behavior: spin(), stop(), extend(), retract(). when naming a method, pick a verb that describes exactly what it does. vague names like calc() or doThing() are not acceptable in real code review.

common method mistakes (this WILL bite you)

three mistakes that beginners hit over and over. recognize these so you can fix them in 10 seconds instead of staring at the error for 20 minutes.

java — mistakes to know cold
// MISTAKE 1: forgetting the return statement
// compiler says: missing return statement
public static double addValues(double a, double b) {
    double result = a + b;
    // oops — computed result but never returned it
    // fix: add "return result;" here
}

// MISTAKE 2: return type doesn't match what you actually return
// compiler says: incompatible types: double cannot be converted to int
public static int getSpeed() {
    return 0.75; // 0.75 is a double, but signature says int — mismatch
    // fix: either change return type to double, or return (int) 0.75
}

// MISTAKE 3: calling with wrong argument types
// compiler says: method calcWheelRPM(double,double) not applicable for arguments (String,double)
public static double calcWheelRPM(double motorRPM, double gearRatio) {
    return motorRPM / gearRatio;
}
calcWheelRPM("5400", 8.46); // "5400" is a String — wrong type, compile error
// fix: pass the number as a number: calcWheelRPM(5400.0, 8.46)

Topic 2 — Coding Prompt

Clamp and Convert
Write two utility methods and call them in sequence

Write a static method called clampSpeed(double speed, double max) that prevents speeds from going out of range:
• if speed is above max → return max
• if speed is below -max → return -max
• otherwise → return speed unchanged

In main, test it by printing these calls:
clampSpeed(1.3, 1.0) → should return 1.0
clampSpeed(-1.1, 1.0) → should return -1.0
clampSpeed(0.5, 1.0) → should return 0.5

Topic 2 — Quick Check


Javadocs & Code Documentation

story time. it's 11pm the night before a regional competition. a motor controller is behaving weird and you need to dig into the subsystem code to figure out what's wrong. you open the file and you see this:

java — the nightmare
public static double calc(double x, double y) {
    return x / y;
}

public static double conv(double a, double b, double c) {
    return a * Math.PI * b / 12.0 * c / 60.0;
}

what does calc do? what are x and y in units? what does conv return? no idea. you wrote this code two months ago and now nobody — including you — can read it. you have to dig through every call site to piece together what it does. at 11pm. at a competition. this is a real situation that happens to real teams.

good documentation is how you avoid this entirely. let's look at all three comment types and then go deep on the one that actually matters for team code.

the three comment types in Java

java — all three comment types
// 1. Single-line comment — use for quick inline explanations
// starts with // and goes to the end of the line
// compiler completely ignores everything after //
double safeSpeed = Math.min(speed, 1.0); // clamp — TalonFX faults above 1.0

/*
 * 2. Block comment — spans multiple lines
 * use when you want to explain a whole section,
 * or temporarily disable a chunk of code during debugging
 * starts with slash-asterisk, ends with asterisk-slash
 */

/**
 * 3. Javadoc comment — this is the important one for team code
 * same as a block comment but with TWO asterisks to start
 * IDEs like VS Code and IntelliJ show this as a hover tooltip
 * place one directly above every public class and every public method
 *
 * @param speed  the target speed in range -1.0 to 1.0
 * @return       true if the motor reached the target speed
 */
public boolean setSpeed(double speed) {
    // implementation here...
    return true;
}

the difference between /* ... */ and /** ... */ is literally one asterisk. but that one asterisk tells IDEs and documentation generators to treat it specially. always use /** for method documentation, not /*.

Javadoc in full — @param and @return

Javadoc is what turns your comments into actual living documentation. hover over a method call in VS Code after adding a Javadoc and you'll see a tooltip pop up with the description, parameters, and return value. your teammates don't have to scroll to the method definition to understand how to use it — the tooltip appears right there.

java — full javadoc example
/**
 * Calculates wheel RPM from a motor's RPM and the drivetrain gear ratio.
 * Use this any time you need to convert raw motor velocity to actual wheel speed.
 * The gear ratio is defined as motor turns per wheel turn (e.g. 8.46 means
 * the motor spins 8.46 times for every 1 rotation of the wheel).
 *
 * @param motorRPM  the motor's rotational speed in RPM (Falcon 500 free speed: ~6380)
 * @param gearRatio motor turns per wheel turn — higher ratio = more torque, less speed
 * @return the resulting wheel speed in RPM as a double
 */
public static double motorRPMtoWheelRPM(double motorRPM, double gearRatio) {
    return motorRPM / gearRatio;
}

/**
 * Clamps a speed value to a safe operating range.
 * TalonFX motor controllers fault if commanded above 1.0 or below -1.0.
 * Always clamp before passing values to motor.set().
 *
 * @param speed    the raw speed to clamp (can be any double)
 * @param maxSpeed the maximum allowed magnitude, usually 1.0
 * @return speed clamped to the range [-maxSpeed, maxSpeed]
 */
public static double clampSpeed(double speed, double maxSpeed) {
    if (speed >  maxSpeed) return  maxSpeed;
    if (speed < -maxSpeed) return -maxSpeed;
    return speed;
}

the tags you need to know: @param documents one input — one line per parameter, name then description. @return documents what gets handed back. there's also @throws for documenting exceptions, but @param and @return cover 90% of what you'll write. also: put the @param lines in the same order as the parameters appear in the signature.

class-level Javadoc

it's not just methods that get Javadocs — public classes do too. a class-level Javadoc sits above the class declaration and describes what the class represents, what it's responsible for, and any important notes about how to use it.

java — class-level javadoc
/**
 * Utility class for swerve drivetrain calculations.
 * Contains static methods for converting between encoder ticks, RPM, and
 * real-world speeds and distances. All methods are stateless (no instance needed).
 *
 * Used by: DriveSubsystem, autonomous routines, telemetry dashboards (telemetry = real-time data from the robot displayed on the driver's dashboard).
 */
public class DriveCalculator {

    /**
     * Converts encoder ticks to wheel revolutions.
     * @param ticks       raw encoder tick count from TalonFX
     * @param ticksPerRev encoder ticks per full motor revolution (TalonFX = 2048)
     * @return total revolutions as a double
     */
    public static double ticksToRevolutions(int ticks, int ticksPerRev) {
        return (double) ticks / ticksPerRev; // cast to avoid integer division
    }
}

good comments vs bad comments

here's the thing — writing useless comments is almost as bad as writing no comments at all. a bad comment just restates what the code obviously already says. a good comment explains WHY something is done, or gives context that isn't obvious from reading the code itself.

java — bad vs good comments
// BAD: tells me what I can already see. zero extra information.
double clamped = Math.min(speed, 1.0); // set clamped to min of speed and 1.0

// GOOD: tells me WHY — and includes the specific thing to watch out for
double clamped = Math.min(speed, 1.0); // clamp — TalonFX faults above 1.0


// BAD: the number 8.46 is magic — where did it come from? when does it change?
double wheelRPM = motorRPM / 8.46;

// GOOD: the constant is named and the comment explains the physical meaning
final double kGearRatio = 8.46; // L2 SDS MK4i gear ratio (motor turns per wheel turn)
double wheelRPM = motorRPM / kGearRatio;


// BAD: vague javadoc that adds nothing — you could have just read the signature
/**
 * calculates rpm
 * @param a the a
 * @param b the b
 * @return something
 */

// GOOD: specific enough that a teammate understands without reading the body
/**
 * Converts motor RPM to actual wheel surface speed in feet per second.
 * Uses wheel circumference (pi * diameter / 12 for inches to feet) and
 * divides by 60 to convert from per-minute to per-second.
 *
 * @param wheelRPM     wheel rotational speed in RPM (after gear reduction)
 * @param wheelDiam_in wheel outer diameter in inches (e.g. 4.0 for 4" wheels)
 * @return surface speed in feet per second
 */

WRT rule: every public method gets a Javadoc. every tricky calculation or non-obvious logic gets an inline comment explaining WHY. if you submit code for the real robot codebase, undocumented public methods will be flagged in code review and sent back. this is not optional.

Topic 3 — Coding Prompt

Document Your Utility Class
Add proper Javadoc to a DriveCalculator class

The starter code has three methods but zero documentation. Your job:
1. Add a Javadoc comment above the class explaining what DriveCalculator does
2. Add a Javadoc above each method with @param for each input and @return describing the output
3. Add one inline comment inside each method explaining WHY that math works, not just what it does
4. Rename the constant to follow WRT convention: k prefix + a units suffix (e.g. kTicksPerRev)

Topic 3 — Quick Check


Fill in the Blanks

// Method that returns nothing, takes a double speed param
public static setSpeed(double speed) { }
// Return the sum of a and b
public static int add(int a, int b) { }
// Access the 3rd element (index 2) of array arr
int val = arr[];

Knowledge Check

Coding Challenge

Wheel Speed Calculator
Write reusable methods for real FRC drivetrain math

Write two static methods for drivetrain math:
1. motorToWheelRPM(double motorRPM, double gearRatio) — returns motorRPM / gearRatio
2. wheelRPMtoSpeed(double wheelRPM, double wheelDiam_in) — returns wheel surface speed in ft/s using: Math.PI * wheelDiam_in / 12.0 * wheelRPM / 60.0

In main, call both with: motorRPM = 5400, gearRatio = 8.46, wheelDiam_in = 4.0. Print the wheel RPM and the speed in ft/s.

Add a @param and @return Javadoc comment to each method.

Project Task — Week 4
DriveCalculator.java

Create DriveCalculator.java in your minibot-project folder. This utility class handles all the math your drivetrain needs — converting between encoder ticks (raw sensor counts), RPMs, and real-world distances.

  • static double ticksToRevolutions(int ticks, int ticksPerRev) — divide ticks by ticksPerRev, return as double
  • static double revolutionsToInches(double revolutions, double wheelDiameterInches) — multiply by Math.PI * diameter
  • static double motorRPMtoWheelRPM(double motorRPM, double gearRatio) — divide motorRPM by gearRatio
  • static double[] processModuleSpeeds(double[] rawSpeeds, double maxSpeed) — loop through and clamp each speed to [-maxSpeed, maxSpeed], return cleaned array
  • Add full Javadoc to every method including @param and @return
  • In main: test with a TalonFX (2048 ticks/rev), gear ratio 8.46, wheel diameter 4 inches
these calculations will be used inside your DriveSubsystem in week 5!

Weekly Test

covers everything from week 4. score gets sent to the leads :) try without looking back first!!

week 4 test
arrays, methods, javadoc · 8 questions!!