> For the complete documentation index, see [llms.txt](https://docs.seattlesolvers.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.seattlesolvers.com/features/util.md).

# Utility Functions

SolversLib comes with many different Utility Functions:

* [Look Up Tables](https://docs.seattlesolvers.com/features/util#what-is-a-look-up-table)
* [Timing Functions](https://docs.seattlesolvers.com/features/util#timing-functions)
* [Math Utilities](https://docs.seattlesolvers.com/features/util#math-utilities)
* [Directional Enums](https://docs.seattlesolvers.com/features/util#directional-enums)

## What is a Look Up Table?

A look up table or LUT for short is used to store values and be able to quickly recall them.

The SolversLib provides 2 different variations of look up tables. In this year's game they can be used to store different set and tested velocities or angles. You can either retrieve the closest reference or you can interpolate through them.

## LUT (Look Up Table)

Provides a way to store values in a table to quickly retrieve them. For example, this might be used to store different speeds or angles based on certain distances. This class allows you to find the closest entry to the input.

For example if you enter:

| Input | Output |
| :---: | :----: |
|   0   |    0   |
|   1   |    1   |
|   2   |    1   |

When you request 1.1, it will return 1.

### Example Usage:

```java
import com.seattlesolvers.solverslib.util.LUT;

LUT<Double, Double> speeds = new LUT<Double, Double>()
{{
    add(5.0, 1.0);
    add(4.0, 0.9);
    add(3.0, 0.75);
    add(2.0, 0.5);
    add(1.0, 0.2);
}};

double distance = odometry.getPose().getTranslation().getDistance(new Translation2d(5, 10));
shooter.set(speeds.getClosest(distance));
```

## InterpLUT (Interpolated Look Up Table)

Provides a way to fill in the gaps in the data. Similarly to the LUT above, this allows you to add data points and retrieve a data point given an output. The difference between a normal LUT and InterpLUT is that the interpolated LUT uses math to fill in all the gaps. Effectively generating filler data based on the data around it.

### Example Usage:

```java
import com.seattlesolvers.solverslib.util.InterpLUT;

//Init the Look up table
InterpLUT lut = new InterpLUT();

//Adding each val with a key
lut.add(1.1, 0.2);
lut.add(2.7, .5);
lut.add(3.6, 0.75);
lut.add(4.1, 0.9);
lut.add(5, 1);
//generating final equation
lut.createLUT();

double distance = odometry.getPose().getTranslation().getDistance(new Translation2d(5, 10));
shooter.set(lut.get(distance));

//getting the velo required and passing it to the shooter.
```

## Timing Functions

SolversLib provides its timing utilities through the nested classes of the [Timing](https://github.com/FTC-23511/SolversLib/blob/master/core/src/main/java/com/seattlesolvers/solverslib/util/Timing.java) class: a `Stopwatch` for measuring elapsed and loop times, a `Timer` for counting down a fixed duration, and a `Rate` for limiting how often fast code paths run. They are lightweight alternatives to the SDK's `ElapsedTime` for quick uses.

{% hint style="warning" %}
A new `Stopwatch` or `Timer` is created **paused** at 0 — call `.start()` to begin timing.
{% endhint %}

### Stopwatch

A `Stopwatch` measures elapsed time. It can be created with a `TimeUnit`, or defaults to seconds:

```java
import com.seattlesolvers.solverslib.util.Timing;
import java.util.concurrent.TimeUnit;

Timing.Stopwatch stopwatch = new Timing.Stopwatch();                          // seconds
Timing.Stopwatch preciseStopwatch = new Timing.Stopwatch(TimeUnit.MILLISECONDS);
```

| Function                  | Return Type | Description                                                          |
| ------------------------- | ----------- | -------------------------------------------------------------------- |
| `stopwatch.start()`       | void        | Starts (or restarts) the stopwatch                                   |
| `stopwatch.start(paused)` | void        | Restarts the stopwatch, optionally leaving it paused                 |
| `stopwatch.pause()`       | void        | Pauses the stopwatch, freezing `elapsedTime()`                       |
| `stopwatch.resume()`      | void        | Resumes a paused stopwatch                                           |
| `stopwatch.elapsedTime()` | long        | Returns the elapsed (unpaused) time, in the constructor's `TimeUnit` |
| `stopwatch.deltaTime()`   | long        | Returns the time since `start()` or the last `deltaTime()` call      |
| `stopwatch.isTimerOn()`   | boolean     | Returns whether the stopwatch is running (started and not paused)    |

`deltaTime()` makes measuring loop times easy:

```java
Timing.Stopwatch loopTimer = new Timing.Stopwatch(TimeUnit.MILLISECONDS);
loopTimer.start();

while (opModeIsActive()) {
    // robot code...

    telemetry.addData("loop time (ms)", loopTimer.deltaTime());
    telemetry.update();
}
```

### Timer

A `Timer` extends `Stopwatch` to count down a fixed length, so every `Stopwatch` method above works on a `Timer` too. It is created with a length, or a length and a `TimeUnit` (defaulting to seconds):

```java
Timing.Timer timer = new Timing.Timer(30);                              // 30 seconds
Timing.Timer preciseTimer = new Timing.Timer(500, TimeUnit.MILLISECONDS);
```

On top of the `Stopwatch` methods, it adds:

| Function                | Return Type | Description                                                                |
| ----------------------- | ----------- | -------------------------------------------------------------------------- |
| `timer.remainingTime()` | long        | Returns the time left until the timer is done                              |
| `timer.done()`          | boolean     | Returns whether at least the timer's length of (unpaused) time has elapsed |

```java
Timing.Timer timer = new Timing.Timer(500, TimeUnit.MILLISECONDS);
timer.start();

while (!timer.done()) {
    // e.g. wait for a servo to physically reach its position
}
```

### Rate (Refresh Rate Timer)

A `Rate` limits how often something runs — for example, capping hardware reads/writes or telemetry updates. It only works in milliseconds and starts counting when created.

`Rate` is a non-static inner class of `Timing`, so it is constructed through a `Timing` instance:

```java
Timing.Rate rate = new Timing().new Rate(100); // 100 ms interval

// in your loop
if (rate.atTime()) {
    // runs only when at least 100 ms have passed since the last check
}
```

* `atTime()`: returns whether at least the rate's interval has passed since the last `atTime()` (or `reset()`) call, and restarts the clock either way.
* `reset()`: restarts the interval.

{% hint style="warning" %}
`atTime()` restarts its clock on **every** call, even when it returns `false`. If you poll it much faster than its interval, it will never return `true` — call it only once per loop, and keep the interval close to (or below) your loop time.
{% endhint %}

## Math Utilities

SolversLib provides its math utilities through the [MathUtils](https://github.com/FTC-23511/SolversLib/blob/master/core/src/main/java/com/seattlesolvers/solverslib/util/MathUtils.java) class. Every method is `static`, so you never create a `MathUtils` object — just import the class and call the methods on it directly:

```java
import com.seattlesolvers.solverslib.util.MathUtils;
```

### Clamp

`clamp` lets you restrict a value to a certain max and min and is usable in double and int.

**Example Usage:**

Double Method:

```java
import com.seattlesolvers.solverslib.util.MathUtils;

double ValueToClamp;
double LowestPossibleValue;
double HighestPossibleValue;

double OutputVal = MathUtils.clamp(ValueToClamp,
                         LowestPossibleValue,
                         HighestPossibleValue);
```

Int Method:

```java
import com.seattlesolvers.solverslib.util.MathUtils;

int ValueToClamp;
int LowestPossibleValue;
int HighestPossibleValue;

int OutputVal = MathUtils.clamp(ValueToClamp,
                         LowestPossibleValue,
                         HighestPossibleValue);
```

### Round

`round(double number, int places)` rounds a number to the given amount of decimal places (rounding half up), which is handy for cleaning up telemetry values.

```java
double rounded = MathUtils.round(3.14159, 2); // 3.14
```

### Angle Normalization

These methods wrap an angle back into a standard range, which is useful for heading math — for example, making sure your turn-to-angle code always takes the shortest way around. The boolean parameter picks the output range: `true` gives 0 to 360° (or 0 to 2π), while `false` gives -180° to 180° (or -π to π).

| Method                                                                 | Description                                                                                 |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `normalizeAngle(double angle, boolean zeroToMax, AngleUnit angleUnit)` | Normalizes an angle in the unit given by the FTC SDK's `AngleUnit` (`DEGREES` or `RADIANS`) |
| `normalizeDegrees(double angle, boolean zeroToFull)`                   | Shortcut for `normalizeAngle` with `AngleUnit.DEGREES`                                      |
| `normalizeRadians(double angle, boolean zeroToFull)`                   | Shortcut for `normalizeAngle` with `AngleUnit.RADIANS`                                      |
| `returnMaxForAngleUnit(AngleUnit angleUnit)`                           | Returns the full-circle value for the unit (360 for degrees, 2π for radians)                |

```java
double heading = MathUtils.normalizeDegrees(450, true);  // 90.0
double error = MathUtils.normalizeDegrees(190, false);   // -170.0
```

### Signed Square Root

`sqrtWithSig(double val)` returns the square root of the absolute value while keeping the original sign — useful for shaping joystick inputs without losing direction.

```java
double shaped = MathUtils.sqrtWithSig(-0.25); // -0.5
```

## Directional Enums

SolversLib comes with multiple directional enums for all your directional needs! You can use these for any autonomous or TeleOP States or anything you want!

| Direction | Index |
| --------- | ----- |
| LEFT      | 0     |
| RIGHT     | 1     |
| UP        | 2     |
| DOWN      | 3     |
| FORWARD   | 4     |
| BACKWARDS | 5     |

You can find some examples in the [sample folder](https://github.com/FTC-23511/SolversLib/tree/master/examples/src/main/java/org/firstinspires/ftc/teamcode).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.seattlesolvers.com/features/util.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
