Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0f37cf8
motors done
Powerlax Sep 1, 2025
4eb1209
read the docs skeleton
Powerlax Sep 1, 2025
9ee8895
docs structure
Powerlax Sep 3, 2025
6775b57
gyro done
Powerlax Sep 3, 2025
55226ac
added different strategies for stdev
Powerlax Sep 3, 2025
f1e9aa7
added camera configs
Powerlax Sep 3, 2025
260b845
added photon vision camera
Powerlax Sep 3, 2025
3a58ddc
created the detected object contiainer
Powerlax Sep 3, 2025
cdfbfb2
changed how configs work
Powerlax Sep 4, 2025
b705b5a
limelight config
Powerlax Sep 4, 2025
1244a51
hi
Powerlax Sep 4, 2025
b25956b
added registry for can
Powerlax Sep 4, 2025
8634f57
changed how errors work
Powerlax Sep 4, 2025
281a6df
added absolute encoders
Powerlax Sep 4, 2025
4865886
fixed absolute encoders
Powerlax Sep 4, 2025
54a5b93
asdf
Powerlax Sep 4, 2025
b5cd760
did all of the controller work
Powerlax Sep 4, 2025
646a950
base layer done
Powerlax Sep 4, 2025
bc5d396
base layer actually done
Powerlax Sep 4, 2025
4eb150d
base layer fully done
Powerlax Sep 5, 2025
fe7c85e
added motor docs
Powerlax Sep 6, 2025
7512cc0
added pid docs
Powerlax Sep 6, 2025
ceaef27
made poplib base easier to use
Powerlax Sep 6, 2025
c2bb03b
gyro docs done
Powerlax Sep 6, 2025
827b448
absolute encoder docs done
Powerlax Sep 6, 2025
ad6105e
docs + follower changes
Powerlax Sep 9, 2025
13c02d1
base layer docs done
Powerlax Sep 10, 2025
3e92363
smol update
Powerlax Sep 10, 2025
0f45ec6
hi heres a bunch of swerve code bye
Powerlax Sep 11, 2025
0afdb5f
hi
Aditya9246 Sep 11, 2025
71c3b8f
swerve done
Powerlax Sep 13, 2025
3a6ef6f
swerve acc done, and now working on elevator
Powerlax Sep 14, 2025
f8d6a45
elevator done
Powerlax Sep 18, 2025
fdfe01e
hi
SeonmokJ Sep 23, 2025
6c78fe9
pre test
Powerlax Oct 23, 2025
f851f9f
Merge branch 'poplibv2' of https://github.com/packofparts/poplib into…
Powerlax Oct 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: "2"

build:
os: "ubuntu-22.04"
tools:
python: "3.10"

python:
install:
- requirements: docs/requirements.txt

sphinx:
configuration: docs/source/conf.py
20 changes: 20 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
35 changes: 35 additions & 0 deletions docs/make.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@ECHO OFF

pushd %~dp0

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build

if "%1" == "" goto help

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

:end
popd
2 changes: 2 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sphinx==7.1.2
sphinx-rtd-theme==1.3.0rc1
7 changes: 7 additions & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
POPLib API Documentation
========================

.. toctree::

base
application
10 changes: 10 additions & 0 deletions docs/source/application.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Application Layer POPLib Documentation
======================================

.. toctree::

application/swerve
application/elevator
application/pivot
application/pnuematics
application/flywheel
2 changes: 2 additions & 0 deletions docs/source/application/elevator.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Elevator
========
2 changes: 2 additions & 0 deletions docs/source/application/flywheel.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Flywheel
========
2 changes: 2 additions & 0 deletions docs/source/application/pivot.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Pivot
=====
2 changes: 2 additions & 0 deletions docs/source/application/pnuematics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Pnuematics
==========
2 changes: 2 additions & 0 deletions docs/source/application/swerve.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Swerve
======
14 changes: 14 additions & 0 deletions docs/source/base.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Base POPLib Documentation
=========================

.. toctree::

base/motors
base/pid
base/gyro
base/absolute encoders
base/camera
base/limelight
base/io
base/beambreak
base/tunable numbers
40 changes: 40 additions & 0 deletions docs/source/base/absolute encoders.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Absolute Encoders
=================

There are many use cases for absolute encoders, typically as a QOL feature for Swerve.
Because of this, we provide an easy-to-use API for absolute encoders. Our team only uses
one type of absolute encoder: a CANCoder. To create a new CANCoder, you first need to create a
CANCoderConfig:

.. code-block:: java

CANCoderConfig canCoderConfig = new CANCoderConfig(CAN_ID, CAN_BUS_NAME, OFFSET, INVERTED);

We first require you to give the CAN ID of the CANCoder. Then, we ask you the CAN Bus name
that the CANCoder is on. We then ask you the offset that should be applied to this CANCoders.
CANCoders are absolute encoders, which means that they will remember this offset and can be used
to move a motor back to the same place every time, even when the robot has just started up. This
differs from normal encoders as those need to be zeroed out at the start of every match to be usable,
and can't "remember" anything. Finally, we ask if the CANCoder is inverted. We can now use this config
to create a CANCoder:

.. code-block:: java

CANCoder encoder = new CANCoder(Constants.canCoderConfig);

.. note::

Whenever a CAN device (like a CANCoder) is created in POPLib, it is registered in the internal
CAN ID Registry. If a duplicate CAN ID is found, an error message will be printed out to
DriverStation (instead of actually crashing the robot program). Please take POPLib DriverStation
error messages seriously. Duplicate CAN IDs make it difficult to debug a robot during competition
and can lead to unexcepted errors.

There is only one use of the CANCoder: moving your motors to thier "zero" position at the start of a match.
Lets say that we already have created a Motor variable (named motor) that is configured with PID. If we
want to move it to the zero position, we would do something like this:

.. code-block:: java

motor.setTargetPosition(encoder.getPosition().getRotations());

38 changes: 38 additions & 0 deletions docs/source/base/beambreak.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
BeamBreak
=========

In FRC, it is very useful to know if an object is in a mechanism on your robot. To do
that, a beambreak sensor is typically used, so POPLib provides a helpful BeamBreak API
to help you query your beambreak. We start by creating a object like so:

.. code-block:: java

BeamBreak beambreakSensor = new BeamBreak(Constants.BEAMBREAK_PORT_ID);

To create a BeamBreak object, all you need is the port id that the beambreak is on.

.. note::

The "Port Id" is NOT a CAN ID as the beambreak is not on the CAN Loop. It instead
directly connects to the roborio's digitial input ports. We are asking what digital
input port your beambreak is on. If you dont know, consult your local electrical subteam.

Lets talk about how to use the BeamBreak API. If you want to see if the beambreak sensor is
blocked, do something like this:

.. code-block:: java

boolean isObjectBlockingSensor = beambreakSensor.isBlocked();

Another cool thing you can do with the BeamBreak API is command chaining. Say you have a Command
(we are representing our example command as a variable named "command") and you want to run this
command until the beambreak is blocked. This would be helpful, say, if you have a beambreak on your
intake and you want to stop your intake motors once the beambreak detects that a gamepiece is in the
intake:

.. code-block:: java

command.until(beambreakSensor.getBlockedSupplier()).andThen(...);

And thats all you really need to know about the BeamBreak API. If you want to know more, read the java
docs.
66 changes: 66 additions & 0 deletions docs/source/base/camera.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
Photonvision Cameras
====================

Here at Pack of Parts, we use our PhotonVision Camera to detect April Tags and
do vision-based pose estimation, and we use our limelight cameras to detect objects
on the ground (such as gamepieces). This page will be dedicated to covering the
Camera API, which represents PHOTONVISION Cameras.

To create a new Camera, we of course have to create a new CameraConfig. Lets take a
look at the constructor:

.. code-block:: java

public CameraConfig(String cameraName,
Transform3d cameraToRobot,
double poseAmbiguityThreshold,
double poseDistanceThreshold,
StdDevStategy stdDevStategy,
AprilTagFields thisYearsField)

The first parameter is the name of the Camera. Note that this is the name of the
CAMERA as in the PhotonVision settings and NOT the name of the computer that is
running PhotonVision. The second parameter is the position of the camera's focal
lens relative to the center of the robot, represented as a Transform3d and in
WPILIB's Robot Coordinate System. Next we ask you for the maximum allowed ambiguity
and distance that an April Tag detection can have for it to still be considered valid.
The higher these numbers, more "accurate" your April Tag detections will be but you
will detect less AprilTags. Finally, we ask for the April Tag map that tell us where
each April Tag is on the field. This is given to you by WPILIB.

We can now use the Config to create a new PhotonVision Camera:

.. code-block:: java

Camera camera = new Camera(Constants.CAMERA_CONFIG);

We can now use this camera in various ways. One of the most popular ways of using a
PhotonVision Camera is like so. Let us assume you have created a variable of the type
SwerveDrivePoseEstimator (which is a WPILIB class, so go read those docs for more info).
Let us call this variable "poseEstimator". You can then do something like this in your
drivebase's periodic loop (note that this is done for you if you are using POPLib Swerve):

.. code-block:: java

Optional<EstimatedRobotPose> estPose = camera.getEstimatedPose(this.getOdomPose());
if (estPose.isPresent()) {
this.odom.addVisionMeasurement(estPose.get().estimatedPose.toPose2d(),
estPose.get().timestampSeconds,
camera.getVisionStdDevs());
}

This is how you do vision-based pose estimation with variable standard deviations. That's
it, if you use the magic of POPLib.

Now, the second way to use the Camera API is to retieve the distance from the that the
camera is from the April Tag, which is helpful for vision-based alignment. Do something
like this:

.. code-block:: java

Pose2d tagToCameraDifference;
Optional<Pose2d> possiblePose = camera.relativeDistanceFromCameraToAprilTag();
if (possiblePose.isPresent()) {
tagToCameraDifference = possiblePose.get();
}

72 changes: 72 additions & 0 deletions docs/source/base/gyro.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
Gyro
====

It is incredibly easy to create a new Gyro object using POPLib. It is first important to
note that the Gyro class is an abstract class, meaning that you will actally want to create
a new Pigeon object instead of a new Gryo object (where the Pigeon is a specific type of gyro
our team uses).

To create a new Pigeon object simply do this:

.. code-block:: java

PigeonConfig config = new PigeonConfig(Constants.GYRO_CAN_ID, Constants.GYRO_INVERTED, Constants.CAN_BUS_NAME)
Pigeon gyro = new Pigeon(config);

The constructor is rather simple: it requires the CAN ID of the Pigeon, whether or not the Pigeon
is inverted (the front of your Pigeon should always be pointing to the front of your robot, and your
Pigeon should always be at the EXACT center of your robot. If the front of the Pigeon is facing the
back of your robot, then set this Pigeon as being inverted). Finally, we ask for the name of the CAN
Bus Loop where this device is located.

.. note::

Whenever a CAN device (like a Pigeon) is created in POPLib, it is registered in the internal
CAN ID Registry. If a duplicate CAN ID is found, an error message will be printed out to
DriverStation (instead of actually crashing the robot program). Please take POPLib DriverStation
error messages seriously. Duplicate CAN IDs make it difficult to debug a robot during competition
and can lead to unexcepted errors.

Now lets move on to how to use the gyro. During the start of your match you will likely want to zero out
your gyro, which can be done like so:

.. code-block:: java

gyro.zeroGyro(); // both of these do the same thing
gyro.setAngle(new Rotation2d(0)); // both of these do the same thing

One of the main uses for a gyro is to get the yaw angle of your robot, normalized (fit from 0 to 360). This
may be done like so:

.. code-block:: java

Angle rotationOfRobotAsAngle = gyro.getNormalizedAngle();
Rotation2d rotationOfRobotAsRot2d = gyro.getNormalizedRotation2dAngle();

Again, both of these do the exact same thing, just in different formats. Now, sometimes, you may want to be
really fancy, and you want to know the angle of the robot with the latency already compensated (because
technically when you call gyro.getNormalizedAngle(), the value it returns is a few milliseconds old due to
fact that the electrical signal has to travel from the gyro to the robot brain). If you want to know the
exact angle of the robot at that exact moment in time use:

.. code-block:: java

Angle rotationOfRobotWithLatComp = gyro.getLatencyCompensatedAngle();

However, note that this is truly unnessesary and very over the top. Something that may be more helpful is
knowing the AngluarVelocity of your robot. To get this from your gyro, simply do:

.. code-block:: java

AngluarVelocity gyroRotVelo = gyro.getAngularVelo();

Finally, there may be cases where you need to access the raw values of the pitch, yaw, and roll of the robot.
These values will be NOT BE INVERTED and will NOT BE NORMALIZED. They can be accessed like so:

.. code-block:: java

Angle gyroYaw = gyro.getYaw();
Angle gyroPitch = gyro.getPitch();
Angle gyroRoll = gyro.getRoll();


Loading
Loading