Giter VIP home page Giter VIP logo

robotpy-wpilib's Introduction

RobotPy WPILib

This repository contain a python implementation of wrappers for WPILib, the library used to interface with hardware for the FIRST Robotics Competition. Teams can use this library to write their robot code in Python, a powerful dynamic programming language.

Note: RobotPy is a community project and is not officially supported by FIRST. Please see the FAQ for more information.

Documentation

All RobotPy documentation can be found at https://robotpy.readthedocs.io

Installation

Installation instructions can be found in the RobotPy documentation

License

See LICENSE.txt

Contributors

RobotPy is a community project, and many people have contributed over the years to make it what it is today. RobotPy's history can be found on our documentation site.

robotpy-wpilib's People

Contributors

amorygalili avatar archduketim avatar arilotter avatar ariovistus avatar arthurallshire avatar auscompgeek avatar auxiliary-character avatar codetheweb avatar computer-whisperer avatar erikboesen avatar etiennebeaulac avatar evanjbs avatar ewpratten avatar james-ward avatar jcaselman avatar jduskey avatar m1stershad0w avatar peterjohnson avatar ryannazaretian avatar sarosenb avatar stmobo avatar thetriplev avatar tophercantrell avatar vanjac avatar virtuald avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

robotpy-wpilib's Issues

Convert unit tests to use the simulated HAL

I think this is the right thing to do -- it allows us to write tests for the simulated HAL and WPILib at the same time.

Still need to actually do it for a module to determine whether it's truly the right thing to do. There might be some facilities that aren't testable using this method, in which case MagicMock is the preferred way to go.

Utility library

I've got a bunch of utility classes that I've been meaning to make easy to install on the Robot. Now might be a good time to collect these sorts of things and make it easy.

RuntimeError: cannot wait on un-acquired lock

Any use of RobotBase currently results in the following error getting thrown from the FRCDriverStation thread.

Exception in thread FRCDriverStation:
Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 921, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.4/threading.py", line 869, in run
    self._target(*self._args, **self._kwargs)
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/driverstation.py", line 92, in task
    self.packetDataAvailableMutex, 0)
  File "<string>", line 5, in takeMultiWait
  File "/home/christian/PycharmProjects/robotpy-2015-fork/hal-sim/hal_impl/functions.py", line 108, in takeMultiWait
    sem.cond.wait() # timeout is ignored in C++ HAL
  File "/usr/lib/python3.4/threading.py", line 282, in wait
    raise RuntimeError("cannot wait on un-acquired lock")
RuntimeError: cannot wait on un-acquired lock

Implement startup via setuptools entry_points mechanism

There's a bunch of things that one might want to do with robot code. Some include:

  • pyfrc: simulation, unit tests, full robot testing, upload code, etc
  • gazebo: simulation
  • on the actual robot: just launch robotbase.main
  • Other uses: ??

I'm convinced that it is highly convenient to be able to 'just run robot.py', and have wpilib figure out the correct thing to do, without needing to modify robot code. To this end, I'm proposing that the robot code looks something like this:

import wpilib

... 

if __name__ == '__main__':
    wpilib.run(MyRobot)

wpilib.run would reside in the _impl module, which would use setuptools entry points to load various hook points, which would do whatever they need to do to setup the robot code. These entry points would be passed argparse objects so that command line options could be added to run the robot code in various ways. This means:

  • the roborio hal would have an entrypoint defined that would just cause the robot code to run without additional setup.
  • pyfrc would have an entrypoint defined that would allow running simulation, unit tests, whatever else
  • the gazebo connector would have an entrypoint defined that would allow running simulation, etc
  • And so on..

TODO: Stick these thoughts in the documentation.

@sarosenb: this is important for adapting pyfrc for 2015

hal.HALControlWord correct arguments

When running the example robot script under examples/test.py, with the workarounds described in #28 , I encounter the following error:

Traceback (most recent call last):
  File "/home/christian/PycharmProjects/modded-command/robot.py", line 24, in <module>
    wpilib.RobotBase.main(MyRobot)
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/robotbase.py", line 129, in main
    RobotBase.initializeHardwareConfiguration()
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/robotbase.py", line 124, in initializeHardwareConfiguration
    RobotState.impl = DriverStation.getInstance()
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/driverstation.py", line 41, in getInstance
    DriverStation.instance = DriverStation()
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/driverstation.py", line 56, in __init__
    self.controlWord = hal.HALControlWord()
TypeError: __init__() missing 1 required positional argument: 'd'

I can't tell what hal.HALControlWord() is supposed to require on hal-roborio, but the implementation in hal-sim appears to require the argument d, and seems to pull data from it, as if it were a dictionary.

I can resolve the issue by replacing hal.HALControlWord() with hal.GetHALControlWord() in wpilib/wpilib/driverstation.py, but I don't know how this fix affects hal-roborio

By default, configure python logging at startup

This might fall into the utility library category, but I think it would be nice for us to provide a good default implementation of python logging configuration so when bugs occur, users can easily retrieve error information.

This is related to deployment, I think. #2

Counter argumuent input

When initializing a Counter object, it seems to be unable to accept just one channel for an argument. Attempting to do so results in a ValueError:

  File "/home/christian/PycharmProjects/modded-command/example.py", line 26, in <module>
    wpilib.RobotBase.main(MyRobot)
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/robotbase.py", line 144, in main
    robot.startCompetition()
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/iterativerobot.py", line 65, in startCompetition
    self.robotInit()
  File "/home/christian/PycharmProjects/modded-command/example.py", line 15, in robotInit
    self.counter = wpilib.Counter(1)
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/counter.py", line 158, in __init__
    raise ValueError("didn't specify down source")
ValueError: didn't specify down source

Is this behavior intentional? If so, it seems odd for you to be unable to use the counter on a single port.

HALError: Could not initialize HAL

Whenever I try to use wpilib in a robot.py script, the following error occurs upon loading the library:

Traceback (most recent call last):
  File "/home/christian/PycharmProjects/modded-command/robot.py", line 16, in <module>
    wpilib.RobotBase.main(MyRobot)
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/robotbase.py", line 129, in main
    RobotBase.initializeHardwareConfiguration()
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/wpilib/robotbase.py", line 119, in initializeHardwareConfiguration
    hal.HALInitialize()
  File "/home/christian/robotpy-2015/lib/python3.4/site-packages/hal/functions.py", line 108, in HALInitialize
    raise HALError("Could not initialize HAL")
hal.exceptions.HALError: Could not initialize HAL

This was run from a virtualenv, with wpilib, hal-base, and hal-sim installed via the workaround in #27.

A temporary fix suggested by virtuald is to have, in hal-sim/hal_impl/functions.py, set HALInitialize to return True And it seems solve the issue.

I would fork and pull request the fix, but my team's request for a github account has not been returned yet, so I wouldn't be able to keep the fork as a private repository.

NetworkTables should be compatible with python 2?

Not sure if it's not, but something to think about. This would make it a useful library for anyone using it from the driver station who couldn't use python3 (for example, if you wrote your UI using PyGTK 2).

Script to validate HAL interface

We have something that compares the Java code to our python implementations, and ensures that they are correct. Now we need something that compares the C HAL headers to our python wrappers and ensures that they are correct. This is arguably more important -- and probably trickier to get right.

Theoretically, once a parser is working, we could autogen the HAL interface. However, I don't think that's necessarily a good idea, since we have some special cases where we need some hand-written stuff.

A script that goes through the wpilib source tree and checks for disparities

There are already python frameworks for parsing java, so this should be a pretty straightforward thing to do. It would be useful

At some point, we might diverge from the original implementation, so the script will need to be able to have a list of things that don't count, or things we won't implement, etc.

Get HAL version

What do you think about putting a little utility function somewhere in wpilib that gets version info for the HAL implementation? I know that would reduce the "abstraction" element of it, but it would make it a bit easier to have the robot code differentiate between physical robot and simulator.

Allowance for repeated wpilib reference initialization

This is a potential enhancement on the way wpilib initializes sensor references:

If I read the code correctly, in a style of robot programming where a device reference is wanted in multiple places (the command framework, in particular), the following might happen:

#In one place:
cannon_switch = wpilib.DigitalInput(4)

#In another place, time, or context where the first reference is unavailable:
cannon_switch = wpilib.DigitalInput(4)
#IndexError: Resource at index 4 is already allocated

While the scenario is often avoidable, it adds another element of complexity to the code by necessarily sharing the created reference. Some code-base designs may lend themselves easily to managing device references, while others less so.

I would like to suggest adding a mechanism to sensorbase and other base device classes where:

If a new object is being created which requires a certain resource, and the resource is already taken by another object, that wpilib attempt to identify if the type of the existing object matches the type of the new object. If this is identified to be so, then still create the object, but with some modifications:

A reference to the existing object would be stored in the new object, and a getattribute overload would forward any attribute requests to the already existing object.

What do you think? If you like the idea, I would be willing to try and implement it.

Mechanism to reset HAL/static resources

Going to need this if we're going to run unit tests that run the robot in different ways (ala pyfrc).

HAL already supports this via the reset_data function, but there are other things that might not support such a thing.

Add gazebo connector

WPILib uses a separate implementation of itself to do this, but I'm not convinced yet that this is the right solution. I'd much rather do it from the HAL -- but already I'm seeing why they didn't do it this way. Will decide on this later.

Unit tests for WPILib

Ideally, we should be able to get a really high rate of coverage on all of WPILib, so that we are assured that bugs that could crash the robot won't find their way in. Once this is all said and done, we can setup a travis-ci job to check all new pushes and pull requests.

Also, the existing magicmock unit tests should be converted to use the simulated hal.. maybe. See #9.

There are already unit tests for some things, we can use the coverage tool to find things that haven't been tested yet.

As you start working on tests, add a note here.

Deployment directions for RobotPy 2015

This is mostly a placeholder to collect thoughts on how it should be done. I don't have a RoboRIO yet so it's hard to know what will work best here.

My current thought is that it would be nice if pyfrc (or similar) was the primary supported mechanism, and it uploaded your code/etc. Presuming we have SSH access to the bot or similar, it could make sure the robot has the latest version of wpilib/hal/etc installed also?

Alternatively, we could develop an eclipse plugin -- though I'd rather have a deployment mechanism that I could just write a script to run.

NotifyDict register function, should it be able setdefault for keys that are not in the main dict

Question on NotifyDict do you think you should be able to add a value to the dict when doing register, I think a better option is for register to return a success or failure or true and false, you shouldn't be able to add with register. Particularly it maybe important NOT to add stuff with register because of possible typos which can lead to hard to find errors. I think we should instead do something like the following:

def register(self, k, v):
    if k in self:
        self.cbs.setdefault(k, []).append(cb)
        return true
    returm false

PIDController does not have deterministic timing

As currently written, PIDController doesn't repeat at deterministic intervals because it uses a timed sleep instead of being started periodically. For example, if the PID get or set functions take variable amounts of time to run, the loop timing changes, which is undesirable for controller time-dependent I and D gain settings.

Logging interpreter-crashing exceptions

I was wondering if we should set something up to log exceptions that bubble up to interpreter-level without being caught? Perhaps save them to something like "death_message.log"?

Identify SSH client for deployment

Ideally, I think the RobotPy/wpilib deployment script (#2) should run from the user's computer, and that they don't need to have to figure out how to ssh/scp files to the RoboRIO -- which, while easy, isn't always the most intuitive thing.

Another requirement for the installer is that we shouldn't require Windows users to have a compiler installed, in order for them to run the installer successfully. Having a compiler requirement on Windows will limit our user base.

OSX/Linux users will already have SSH installed, so there we could just interact with those via the command line.

Paramiko/fabric are great tools to use for SSH in native python, but require compilation + dependencies. One possible workaround is using pyinstaller to create a binary package for Windows, but it only has experimental python3 support.

Alternatively, we could write the installer in a different language and distribute a binary that way.

Solving this problem will be necessary for pyfrc to continue to be a useful mechanism to upload code to the robot.

Commands framework

Should we implement this? Not sure if anyone is using it in python land. Perhaps this is a question for people on ChiefDelphi.

Timer.getFPGATimestamp() returns 1/10th of what it should.

If the Timer.getFPGATimestamp() method is supposed to return the value in seconds, it seems to be living in Narnia. After one second of run time, it currently returns .1, rather than 1.

I suppose that this is due to a missing zero either in hal-sim or wpilib, but I don't know what the value of hal.getFPGATime is supposed to be.

Philosophy question: initialized variables

Traceback (most recent call last):
  File "./test.py", line 16, in <module>
    print(foo.setPosition(0.4))
  File "wpilib/wpilib/pwm.py", line 164, in setPosition
    rawValue = int(pos * self.getFullRangeScaleFactor() + self.getMinNegativePwm())
  File "wpilib/wpilib/pwm.py", line 320, in getFullRangeScaleFactor
    return self.getMaxPositivePwm() - self.getMinNegativePwm()
  File "wpilib/wpilib/pwm.py", line 290, in getMaxPositivePwm
    return self.maxPwm
AttributeError: 'PWM' object has no attribute 'maxPwm'

In the Java wpilib, the maxPwm (and other vars) are not initialized, so it appears that in the python impl you chose to not include them, which causes this traceback if one forgot to call the correct initialization function.

As a user, when I see a traceback like that, I immediately assume an error in the underlying library, and not necessarily in my own code.

In general, I think we should add a check for these sorts of things (particularly if we're going to omit the variables), so the user gets a better error message. We could either throw an exception or assert an error -- my preference is to assert an error, and include a descriptive message of why the user is getting the error. Then the checks can be turned off when using optimized mode.

Frameworks taking advantage of python's capabilities as an interpreted language

Several months ago, I started building a framework that attempted to take advantage of the flexible nature of python, and recently got it to a point where it works pretty well in those areas. You can find it here: https://github.com/Team4819/4819-2014-Offseason-RobotPy . I showed it to virtuald, recently, and he pointed out several key issues with the design concept, as well as the fact that it works strikingly similar to the command framework, which I was unaware existed for python.

Faulty implementation aside, I still was able to do a few neat things with it:

Module reloading: In my framework, I grouped all of the code relevant to a subsystem of the robot into a single python file, which I call a module. These modules are dynamically imported into the framework in such a way that they can, later, be unloaded entirely, and then re-loaded, again. This allowed me to live-edit the individual modules and, with a button press, see results immediately on the robot, without even leaving teleoperated mode!

Error recovery: I used a config file to specify, for each module, a "fallback list" of alternative modules with the same basic abilities. Then, mid-run, if the loaded module threw an exception, it would be immediately unloaded and replaced by the next module on the fallback list, which could be a more basic and robust version.

I think that python as a FRC language as so much more potential than it is currently getting used for. If there were an official framework designed with python in mind, and it's abilities as an interpreted language, I think robotpy could become much more than just an alternative programming language for robots.

Add type information to docstrings

I showed the new documentation to some students this afternoon, and they found it difficult to determine what type to pass in to the solenoid. Those of us familiar with wpilib already know this stuff, but it would be nice to add type information in to places as we come across it.

I added solenoid documentation to the hal-testing branch already.

Library installation via pip fails

When I tried to install wpilib into a virtualenv with pip, I received a lovely error:

Unpacking /home/christian/PycharmProjects/robotpy-2015/wpilib
  Running setup.py egg_info for package from file:///home/christian/PycharmProjects/robotpy-2015/wpilib
    Traceback (most recent call last):
      File "<string>", line 16, in <module>
      File "/tmp/pip-s6fqxp45-build/setup.py", line 25, in <module>
        with open(join(setup_dir, base_package, 'version.py'), 'r') as fp:
    FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-s6fqxp45-build/wpilib/version.py'
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):

  File "<string>", line 16, in <module>

  File "/tmp/pip-s6fqxp45-build/setup.py", line 25, in <module>

    with open(join(setup_dir, base_package, 'version.py'), 'r') as fp:

FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-s6fqxp45-build/wpilib/version.py'

From what I can tell, it was due to setup not finding the version.py file, which wasn't created due to there being no .git in that directory.

I was able to bypass the error by commenting out that code, and replacing "__version__" with a random version number.

This issue seems to be present on the following files:
wpilib/setup.py
networktables/setup.py
hal-sim/setup.py
hal-base/setup.py

Documentation for WPILib needs to be validated in sphinx

There's a lot of warnings when generating the documentation, which means there's probably a lot of formatting problems. Let's make sure cross-linking between types works too.

Once this all goes public, we can publish it on readthedocs.org.

Idea: repurpose WPI's eclipse plugins for a set of python plugins

Since @bradamiller and team have already went through the trouble to create FRC related plugins for Eclipse, why not adjust them a little bit to do python-related tasks instead? I use eclipse for python development, and so do my students. This could be a useful thing to do if someone wanted to tackle it.

The one problem I see is finding somewhere to host the eclipse plugins, as github isn't a good place to host an eclipse update site.

Disable networktables when not installed

Currently you cannot use robotbase without networktables installed, or it throws an error when it tries to initialize it. Perhaps it should detect this and avoid using it if it is missing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.