Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added python notes and examples to kinematics intro #2417

Merged
merged 5 commits into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions source/_static/css/frc-rtd.css
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,8 @@ summary {
font-weight: bold;
margin: -.5em -.5em 0;
padding: .5em;
}

code.py-class {
all: unset!important;
}
13 changes: 13 additions & 0 deletions source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"sphinx.ext.mathjax",
"sphinx.ext.todo",
"sphinx.ext.autosectionlabel",
"sphinx.ext.intersphinx",
"sphinxcontrib.rsvgconverter",
"sphinxext.delta",
"sphinxext.opengraph",
Expand Down Expand Up @@ -323,3 +324,15 @@ def new_send(self, data):


http.client.HTTPConnection.send = new_send

intersphinx_mapping = {
"robotpy": ("https://robotpy.readthedocs.io/projects/robotpy/en/latest/", None),
}

# We recommend adding the following config value.
# Sphinx defaults to automatically resolve *unresolved* labels using all your Intersphinx mappings.
# This behavior has unintended side-effects, namely that documentations local references can
# suddenly resolve to an external location.
# See also:
# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#confval-intersphinx_disabled_reftypes
intersphinx_disabled_reftypes = ["*"]
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
Introduction to Kinematics and The Chassis Speeds Class
==================================================================
Introduction to Kinematics and The ChassisSpeeds Class
======================================================

What is kinematics?
-------------------
The brand new kinematics suite contains classes for differential drive, swerve drive, and mecanum drive kinematics and odometry. The kinematics classes help convert between a universal ``ChassisSpeeds`` object, containing linear and angular velocities for a robot to usable speeds for each individual type of drivetrain i.e. left and right wheel speeds for a differential drive, four wheel speeds for a mecanum drive, or individual module states (speed and angle) for a swerve drive.
The kinematics suite contains classes for differential drive, swerve drive, and mecanum drive kinematics and odometry. The kinematics classes help convert between a universal ``ChassisSpeeds`` (`Java <https://github.wpilib.org/allwpilib/docs/release/java/edu/wpi/first/math/kinematics/ChassisSpeeds.html>`__, `C++ <https://github.wpilib.org/allwpilib/docs/release/cpp/structfrc_1_1_chassis_speeds.html>`__, :external:py:class:`Python <wpimath.kinematics.ChassisSpeeds>`)object, containing linear and angular velocities for a robot to usable speeds for each individual type of drivetrain i.e. left and right wheel speeds for a differential drive, four wheel speeds for a mecanum drive, or individual module states (speed and angle) for a swerve drive.

What is odometry?
-----------------
Odometry involves using sensors on the robot to create an estimate of the position of the robot on the field. In FRC, these sensors are typically several encoders (the exact number depends on the drive type) and a gyroscope to measure robot angle. The odometry classes utilize the kinematics classes along with periodic user inputs about speeds (and angles in the case of swerve) to create an estimate of the robot's location on the field.

The Chassis Speeds Class
------------------------
The ChassisSpeeds Class
-----------------------
The ``ChassisSpeeds`` object is essential to the new WPILib kinematics and odometry suite. The ``ChassisSpeeds`` object represents the speeds of a robot chassis. This struct has three components:

* ``vx``: The velocity of the robot in the x (forward) direction.
Expand All @@ -21,7 +21,7 @@ The ``ChassisSpeeds`` object is essential to the new WPILib kinematics and odome

Constructing a ChassisSpeeds object
-----------------------------------
The constructor for the ``ChassisSpeeds`` object is very straightforward, accepting three arguments for ``vx``, ``vy``, and ``omega``. In Java, ``vx`` and ``vy`` must be in meters per second. In C++, the units library may be used to provide a linear velocity using any linear velocity unit.
The constructor for the ``ChassisSpeeds`` object is very straightforward, accepting three arguments for ``vx``, ``vy``, and ``omega``. In Java and Python, ``vx`` and ``vy`` must be in meters per second. In C++, the units library may be used to provide a linear velocity using any linear velocity unit.

.. tab-set-code::

Expand All @@ -40,12 +40,22 @@ The constructor for the ``ChassisSpeeds`` object is very straightforward, accept
frc::ChassisSpeeds speeds{3.0_mps, -2.0_mps,
units::radians_per_second_t(std::numbers::pi)};

.. code-block:: python

import math
from wpimath.kinematics import ChassisSpeeds

# The robot is moving at 3 meters per second forward, 2 meters
# per second to the right, and rotating at half a rotation per
# second counterclockwise.
speeds = ChassisSpeeds(3.0, -2.0, math.pi)


Creating a ChassisSpeeds Object from Field-Relative Speeds
----------------------------------------------------------
A ``ChassisSpeeds`` object can also be created from a set of field-relative speeds when the robot angle is given. This converts a set of desired velocities relative to the field (for example, toward the opposite alliance station and toward the right field boundary) to a ``ChassisSpeeds`` object which represents speeds that are relative to the robot frame. This is useful for implementing field-oriented controls for a swerve or mecanum drive robot.

The static ``ChassisSpeeds.fromFieldRelativeSpeeds`` (Java) / ``ChassisSpeeds::FromFieldRelativeSpeeds`` (C++) method can be used to generate the ``ChassisSpeeds`` object from field-relative speeds. This method accepts the ``vx`` (relative to the field), ``vy`` (relative to the field), ``omega``, and the robot angle.
The static ``ChassisSpeeds.fromFieldRelativeSpeeds`` (Java / Python) / ``ChassisSpeeds::FromFieldRelativeSpeeds`` (C++) method can be used to generate the ``ChassisSpeeds`` object from field-relative speeds. This method accepts the ``vx`` (relative to the field), ``vy`` (relative to the field), ``omega``, and the robot angle.

.. tab-set-code::

Expand All @@ -69,4 +79,18 @@ The static ``ChassisSpeeds.fromFieldRelativeSpeeds`` (Java) / ``ChassisSpeeds::F
frc::ChassisSpeeds speeds = frc::ChassisSpeeds::FromFieldRelativeSpeeds(
2_mps, 2_mps, units::radians_per_second_t(std::numbers::pi / 2.0), Rotation2d(45_deg));

.. code-block:: python

import math
from wpimath.kinematics import ChassisSpeeds
from wpimath.geometry import Rotation2d

# The desired field relative speed here is 2 meters per second
# toward the opponent's alliance station wall, and 2 meters per
# second toward the left field boundary. The desired rotation
# is a quarter of a rotation per second counterclockwise. The current
# robot angle is 45 degrees.
speeds = ChassisSpeeds.fromFieldRelativeSpeeds(
2.0, 2.0, math.pi / 2.0, Rotation2d.fromDegrees(45.0))

.. note:: The angular velocity is not explicitly stated to be "relative to the field" because the angular velocity is the same as measured from a field perspective or a robot perspective.