Skip to content

Commit

Permalink
Merge pull request #48 from robotpy/misc
Browse files Browse the repository at this point in the history
Misc
  • Loading branch information
virtuald authored Dec 21, 2023
2 parents f9df8ef + db9db23 commit 81aea4d
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 61 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ jobs:
run: |
./rdev.sh ci run
env:
RPYBUILD_PARALLEL: "1"
RPYBUILD_STRIP_LIBPYTHON: "1"
MACOSX_DEPLOYMENT_TARGET: "12"
SCCACHE_GHA_ENABLED: "true"

- uses: actions/upload-artifact@v3
Expand Down Expand Up @@ -215,7 +213,6 @@ jobs:
run: |
/build/venv/bin/cross-python -m devtools ci run --no-test
env:
RPYBUILD_PARALLEL: "1"
RPYBUILD_STRIP_LIBPYTHON: "1"

- uses: actions/upload-artifact@v3
Expand Down
24 changes: 24 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Copyright (c) 2009-2023 FIRST and other WPILib contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of FIRST, WPILib, nor the names of other WPILib
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY FIRST AND OTHER WPILIB CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 changes: 46 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,47 @@
mostrobotpy
===========
===========

This repository contains core python libraries that wrap the C++ artifacts of
[allwpilib](https://github.com/wpilibsuite/allwpilib). These libraries are
officially supported for use in the FIRST Robotics Competition.

API Documentation
=================

API documentation is at https://robotpy.readthedocs.io/projects/robotpy/en/latest/

Building RobotPy
================

> [!WARNING]
> It is not recommended for users to build their own copy of RobotPy.
> Instead you should use our prebuilt packages that we publish on PyPI and
> on the WPILib artifactory site. See TODO for details
mostrobotpy consists of many interdependent python packages, which can be
found in the `subprojects` directory. Each subproject can be built like
any other python project, but it is recommended that you use our `rdev.sh`
tool instead.

You must have a working C++ build system and python development headers
installed for your system.

Next install dependencies using pip:

pip install -r rdev_requirements.txt
pip install numpy

Then run this command to build all the wheels.

./rdev.sh ci run

All the resulting wheels are in `dist`, which can be installed using `pip`.

Cross Compilation
-----------------

We only support cross-compiling for RoboRIO and raspbian via the WPILib
docker build containers. See `.github/workflows/dist.yml`'s `cross-build`
job for the name of the containers and the steps that must be run inside
the container.

14 changes: 14 additions & 0 deletions devtools/__main__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import os
import sys

import click

from .ctx import Context
from . import ci
from . import update_pyproject

#
# Environment variables for configuring the builds
#

# Always run robotpy-build in parallel
os.environ["RPYBUILD_PARALLEL"] = "1"

# MACOSX_DEPLOYMENT_TARGET is required for linking to WPILib
if sys.platform == "darwin":
os.environ["MACOSX_DEPLOYMENT_TARGET"] = "12"


@click.group()
@click.pass_context
Expand Down
50 changes: 29 additions & 21 deletions subprojects/robotpy-wpilib/wpilib/_impl/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,23 @@
import sys

from os.path import exists
from importlib.metadata import entry_points
import importlib.metadata

from .logconfig import configure_logging

if sys.version_info < (3, 10):

def entry_points(group):
eps = importlib.metadata.entry_points()
return eps.get(group)

else:
entry_points = importlib.metadata.entry_points


def _log_versions():
import wpilib
import wpilib.deployinfo
import hal

import logging

Expand All @@ -36,14 +44,14 @@ def _log_versions():

logger = logging.getLogger("wpilib")

logger.info("WPILib version %s", wpilib.__version__)
logger.info("HAL version %s", hal.__version__)
try:
import robotpy.version
except ImportError:
robotpy_version = None
else:
logger.info("RobotPy version %s", robotpy.version.__version__)

# should we just die here?
if hal.__version__.split(".")[:3] != wpilib.__version__.split(".")[:3]:
logger.warning(
"Core component versions are not identical! This is not a supported configuration, and you may run into errors!"
)
logger.info("WPILib version %s", wpilib.__version__)

if wpilib.RobotBase.isSimulation():
logger.info("Running with simulated HAL.")
Expand All @@ -55,20 +63,20 @@ def _log_versions():
"Running simulation HAL on actual roboRIO! This probably isn't what you want, and will probably cause difficult-to-debug issues!"
)

versions = {}
if logger.isEnabledFor(logging.DEBUG):
versions = {}

# Log third party versions
# -> TODO: in the future, expand 3rd party HAL support here?
for group in ("robotpylib", "robotpybuild"):
for entry_point in entry_points(group=group):
# Don't actually load the entry points -- just print the
# packages unless we need to load them
dist = entry_point.dist
versions[dist.name] = dist.version
# Log third party versions
for group in ("robotpylib", "robotpybuild"):
for entry_point in entry_points(group=group):
# Don't actually load the entry points -- just print the
# packages unless we need to load them
dist = entry_point.dist
versions[dist.name] = dist.version

for k, v in versions.items():
if k not in ("wpilib", "robotpy-hal"):
logger.info("%s version %s", k, v)
for k, v in versions.items():
if k != "wpilib":
logger.debug("%s version %s", k, v)


def _enable_faulthandler():
Expand Down
79 changes: 43 additions & 36 deletions subprojects/robotpy-wpimath/wpimath/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
# Open Source Software; you can modify and/or share it under the terms of
# the WPILib BSD license file in the root directory of this project.

from __future__ import annotations

import math
import typing

kInchesPerFoot = 12.0
kMetersPerInch = 0.0254
Expand All @@ -11,81 +14,81 @@
kKilogramsPerLb = 0.453592


def metersToFeet(meters: float) -> float:
def metersToFeet(m: meters) -> feet:
"""Converts given meters to feet.
:param meters: The meters to convert to feet.
:param m: The meters to convert to feet.
:returns: Feet converted from meters.
"""
return metersToInches(meters) / kInchesPerFoot
return metersToInches(m) / kInchesPerFoot


def feetToMeters(feet: float) -> float:
def feetToMeters(ft: feet) -> meters:
"""Converts given feet to meters.
:param feet: The feet to convert to meters.
:param ft: The feet to convert to meters.
:returns: Meters converted from feet.
"""
return inchesToMeters(feet * kInchesPerFoot)
return inchesToMeters(ft * kInchesPerFoot)


def metersToInches(meters: float) -> float:
def metersToInches(m: meters) -> inches:
"""Converts given meters to inches.
:param meters: The meters to convert to inches.
:param m: The meters to convert to inches.
:returns: Inches converted from meters.
"""
return meters / kMetersPerInch
return m / kMetersPerInch


def inchesToMeters(inches: float) -> float:
def inchesToMeters(i: inches) -> meters:
"""Converts given inches to meters.
:param inches: The inches to convert to meters.
:param i: The inches to convert to meters.
:returns: Meters converted from inches.
"""
return inches * kMetersPerInch
return i * kMetersPerInch


# Converts given degrees to radians.
degreesToRadians = math.radians
degreesToRadians: typing.Callable[[degrees], radians] = math.radians

# Converts given radians to degrees.
radiansToDegrees = math.degrees
radiansToDegrees: typing.Callable[[radians], degrees] = math.degrees


def radiansToRotations(radians: float) -> float:
def radiansToRotations(rad: radians) -> float:
"""Converts given radians to rotations.
:param radians: The radians to convert.
:param rad: The radians to convert.
:returns: rotations Converted from radians.
"""
return radians / math.tau
return rad / math.tau


def degreesToRotations(degrees: float) -> float:
def degreesToRotations(deg: degrees) -> float:
"""Converts given degrees to rotations.
:param degrees: The degrees to convert.
:param deg: The degrees to convert.
:returns: rotations Converted from degrees.
"""
return degrees / 360
return deg / 360.0


def rotationsToDegrees(rotations: float) -> float:
def rotationsToDegrees(rotations: float) -> degrees:
"""Converts given rotations to degrees.
:param rotations: The rotations to convert.
:returns: degrees Converted from rotations.
"""
return rotations * 360
return rotations * 360.0


def rotationsToRadians(rotations: float) -> float:
Expand All @@ -98,7 +101,9 @@ def rotationsToRadians(rotations: float) -> float:
return rotations * math.tau


def rotationsPerMinuteToRadiansPerSecond(rpm: float) -> float:
def rotationsPerMinuteToRadiansPerSecond(
rpm: revolutions_per_minute,
) -> radians_per_second:
"""Converts rotations per minute to radians per second.
:param rpm: The rotations per minute to convert to radians per second.
Expand All @@ -108,47 +113,49 @@ def rotationsPerMinuteToRadiansPerSecond(rpm: float) -> float:
return (rpm / kSecondsPerMinute) * math.tau


def radiansPerSecondToRotationsPerMinute(radiansPerSecond: float) -> float:
def radiansPerSecondToRotationsPerMinute(
rps: radians_per_second,
) -> revolutions_per_minute:
"""Converts radians per second to rotations per minute.
:param radiansPerSecond: The radians per second to convert to from rotations per minute.
:param rps: The radians per second to convert to from rotations per minute.
:returns: Rotations per minute converted from radians per second.
"""
return (radiansPerSecond * kSecondsPerMinute) / math.tau
return (rps * kSecondsPerMinute) / math.tau


def millisecondsToSeconds(milliseconds: float) -> float:
def millisecondsToSeconds(ms: milliseconds) -> seconds:
"""Converts given milliseconds to seconds.
:param milliseconds: The milliseconds to convert to seconds.
:param ms: The milliseconds to convert to seconds.
:returns: Seconds converted from milliseconds.
"""
return milliseconds / kMillisecondsPerSecond
return ms / kMillisecondsPerSecond


def secondsToMilliseconds(seconds: float) -> float:
def secondsToMilliseconds(s: seconds) -> milliseconds:
"""Converts given seconds to milliseconds.
:param seconds: The seconds to convert to milliseconds.
:param s: The seconds to convert to milliseconds.
:returns: Milliseconds converted from seconds.
"""
return seconds * kMillisecondsPerSecond
return s * kMillisecondsPerSecond


def kilogramsToLbs(kilograms: float) -> float:
def kilogramsToLbs(kg: kilograms) -> pounds:
"""Converts kilograms into lbs (pound-mass).
:param kilograms: The kilograms to convert to lbs (pound-mass).
:param kg: The kilograms to convert to lbs (pound-mass).
:returns: Lbs (pound-mass) converted from kilograms.
"""
return kilograms / kKilogramsPerLb
return kg / kKilogramsPerLb


def lbsToKilograms(lbs: float) -> float:
def lbsToKilograms(lbs: pounds) -> kilograms:
"""Converts lbs (pound-mass) into kilograms.
:param lbs: The lbs (pound-mass) to convert to kilograms.
Expand Down

0 comments on commit 81aea4d

Please sign in to comment.