Skip to content

Commit

Permalink
Merge pull request #52 from cwrowley/conda-build
Browse files Browse the repository at this point in the history
Add conda build recipe and improve version numbering
  • Loading branch information
cwrowley committed Apr 6, 2015
2 parents 9671fe3 + 5ff196c commit 15fd5c1
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 295 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Expand Up @@ -3,7 +3,9 @@ build/
dist/
.ropeproject/
MANIFEST
control/version.py
control/_version.py
__conda_*.txt
record.txt
build.log
*.egg-info/
.coverage
Expand Down
9 changes: 5 additions & 4 deletions .travis.yml
Expand Up @@ -8,8 +8,6 @@ python:
before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- sudo apt-get update --fix-missing -qq
- sudo apt-get install gfortran liblapack-dev
# use miniconda to install numpy/scipy, to avoid lengthy build from source
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
wget http://repo.continuum.io/miniconda/Miniconda-3.4.2-Linux-x86_64.sh -O miniconda.sh;
Expand All @@ -21,13 +19,16 @@ before_install:
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
- conda install --yes python=$TRAVIS_PYTHON_VERSION conda-build pip coverage
- conda config --add channels http://conda.binstar.org/cwrowley
- conda info -a

# Install packages
install:
- conda install --yes python=$TRAVIS_PYTHON_VERSION coverage nose numpy scipy matplotlib pip
- conda build conda-recipe
- conda install control --use-local
- conda install slycot
- pip install coveralls
- pip install slycot

# command to run tests
script:
Expand Down
111 changes: 71 additions & 40 deletions README.rst
@@ -1,65 +1,96 @@
Python Control System Library
=============================

.. image:: https://travis-ci.org/python-control/python-control.svg?branch=master
:target: https://travis-ci.org/python-control/python-control
:target: https://travis-ci.org/python-control/python-control
.. image:: https://coveralls.io/repos/python-control/python-control/badge.png
:target: https://coveralls.io/r/python-control/python-control
:target: https://coveralls.io/r/python-control/python-control

Python Control Systems Library
==============================

The Python Control Systems Library is a Python module that implements basic
operations for analysis and design of feedback control systems.

Features
--------

- Linear input/output systems in state-space and frequency domain
- Block diagram algebra: serial, parallel, and feedback interconnections
- Time response: initial, step, impulse
- Frequency response: Bode and Nyquist plots
- Control analysis: stability, reachability, observability, stability margins
- Control design: eigenvalue placement, linear quadratic regulator
- Estimator design: linear quadratic estimator (Kalman filter)


Links
=====

- Project home page: http://python-control.sourceforge.net
- Source code repository: https://github.com/python-control/python-control
- Documentation: http://python-control.readthedocs.org/
- Issue tracker: https://github.com/python-control/python-control/issues
- Mailing list: http://sourceforge.net/p/python-control/mailman/


Dependencies
============

RMM, 23 May 09
The package requires numpy, scipy, and matplotlib. In addition, some routines
use a module called slycot, that is a Python wrapper around some FORTRAN
routines. Many parts of python-control will work without slycot, but some
functionality is limited or absent, and installation of slycot is recommended
(see below). Note that in order to install slycot, you will need a FORTRAN
compiler on your machine. The Slycot wrapper can be found at:

This directory contains the source code for the Python Control Systems
Library (python-control). This package provides a library of standard
control system algorithms in the python programming environment.
https://github.com/jgoppert/Slycot

Installation
------------
============

The package may be installed using pip or distutils.

Pip
---

To install using pip::

Using pip
~~~~~~~~~~~
pip install slycot # optional
pip install control

Pip is a python packaging system. It can be installed on debian based
linux distros with the command::
Distutils
---------

sudo apt-get install pip
To install in your home directory, use::

Pip can then be used to install python-control::
python setup.py install --user

sudo pip install control
To install for all users (on Linux or Mac OS)::

python setup.py build
sudo python setup.py install

From Source
~~~~~~~~~~~

Standard python package installation::
Development
===========

python setup.py install
Code
----

To see if things are working, you can run the script
examples/secord-matlab.py (using ipython -pylab). It should generate a step
response, Bode plot and Nyquist plot for a simple second order linear
system.
You can check out the latest version of the source code with the command::

git clone https://github.com/python-control/python-control.git

Testing
-------

You can also run a set of unit tests to make sure that everything is working
You can run a set of unit tests to make sure that everything is working
correctly. After installation, run::

python runtests.py

Slycot
------

Routines from the Slycot wrapper are used for providing the
functionality of several routines for state-space, transfer functions
and robust control. Many parts of python-control will still work
without slycot, but some functionality is limited or absent, and
installation of Slycot is definitely recommended. The Slycot wrapper
can be found at:
python setup.py test

https://github.com/jgoppert/Slycot
Contributing
------------

and can be installed with::
Your contributions are welcome! Simply fork the GitHub repository and send a
`pull request`_.

sudo pip install slycot
.. _pull request: https://github.com/python-control/python-control/pulls
3 changes: 3 additions & 0 deletions conda-recipe/bld.bat
@@ -0,0 +1,3 @@
cd %RECIPE_DIR%\..
%PYTHON% make_version.py
%PYTHON% setup.py install --single-version-externally-managed --record=record.txt
32 changes: 32 additions & 0 deletions conda-recipe/meta.yaml
@@ -0,0 +1,32 @@
package:
name: control

build:
script:
- cd $RECIPE_DIR/..
- $PYTHON make_version.py
- $PYTHON setup.py install --single-version-externally-managed --record=record.txt

requirements:
build:
- python
- nose

run:
- python
- numpy
- scipy
- matplotlib

test:
imports:
- control

about:
home: http://python-control.sourceforge.net
license: BSD License
summary: 'Python control systems library'

# See
# http://docs.continuum.io/conda/build.html for
# more information about meta.yaml
103 changes: 47 additions & 56 deletions control/__init__.py
Expand Up @@ -56,65 +56,56 @@
lqe linear quadratic estimator
"""

try:
__CONTROL_SETUP__
except NameError:
__CONTROL_SETUP__ = False

if __CONTROL_SETUP__:
import sys as _sys
_sys.stderr.write('Running from control source directory.\n')
del _sys
else:
# Import functions from within the control system library
# Should probably only import the exact functions we use...
from .bdalg import series, parallel, negate, feedback
from .delay import pade
from .dtime import sample_system
from .freqplot import bode_plot, nyquist_plot, gangof4_plot
from .freqplot import bode, nyquist, gangof4
from .lti import issiso, timebase, timebaseEqual, isdtime, isctime
from .margins import stability_margins, phase_crossover_frequencies
from .mateqn import lyap, dlyap, care, dare
from .modelsimp import hsvd, modred, balred, era, markov
from .nichols import nichols_plot, nichols
from .phaseplot import phase_plot, box_grid
from .rlocus import root_locus
from .statefbk import place, lqr, ctrb, obsv, gram, acker
from .statesp import StateSpace
from .timeresp import forced_response, initial_response, step_response, \
impulse_response
from .xferfcn import TransferFunction
from .ctrlutil import unwrap, issys
from .frdata import FRD
from .canonical import canonical_form, reachable_form

# Import functions from within the control system library
# Should probably only import the exact functions we use...
from .bdalg import series, parallel, negate, feedback
from .delay import pade
from .dtime import sample_system
from .freqplot import bode_plot, nyquist_plot, gangof4_plot
from .freqplot import bode, nyquist, gangof4
from .lti import issiso, timebase, timebaseEqual, isdtime, isctime
from .margins import stability_margins, phase_crossover_frequencies
from .mateqn import lyap, dlyap, care, dare
from .modelsimp import hsvd, modred, balred, era, markov
from .nichols import nichols_plot, nichols
from .phaseplot import phase_plot, box_grid
from .rlocus import root_locus
from .statefbk import place, lqr, ctrb, obsv, gram, acker
from .statesp import StateSpace
from .timeresp import forced_response, initial_response, step_response, \
impulse_response
from .xferfcn import TransferFunction
from .ctrlutil import unwrap, issys
from .frdata import FRD
from .canonical import canonical_form, reachable_form
# Exceptions
from .exception import *

# Exceptions
from .exception import *

# Version information
from control.version import full_version as __version__
from control.version import git_revision as __git_revision__
# Version information
try:
from ._version import __version__, __commit__
except ImportError:
__version__ = "dev"

# Import some of the more common (and benign) MATLAB shortcuts
# By default, don't import conflicting commands here
#! TODO (RMM, 4 Nov 2012): remove MATLAB dependencies from __init__.py
#!
#! Eventually, all functionality should be in modules *other* than matlab.
#! This will allow inclusion of the matlab module to set up a different set
#! of defaults from the main package. At that point, the matlab module will
#! allow provide compatibility with MATLAB but no package functionality.
#!
from .matlab import ss, tf, ss2tf, tf2ss, drss
from .matlab import pole, zero, evalfr, freqresp, dcgain
from .matlab import nichols, rlocus, margin
# bode and nyquist come directly from freqplot.py
from .matlab import step, impulse, initial, lsim
from .matlab import ssdata, tfdata
# Import some of the more common (and benign) MATLAB shortcuts
# By default, don't import conflicting commands here
#! TODO (RMM, 4 Nov 2012): remove MATLAB dependencies from __init__.py
#!
#! Eventually, all functionality should be in modules *other* than matlab.
#! This will allow inclusion of the matlab module to set up a different set
#! of defaults from the main package. At that point, the matlab module will
#! allow provide compatibility with MATLAB but no package functionality.
#!
from .matlab import ss, tf, ss2tf, tf2ss, drss
from .matlab import pole, zero, evalfr, freqresp, dcgain
from .matlab import nichols, rlocus, margin
# bode and nyquist come directly from freqplot.py
from .matlab import step, impulse, initial, lsim
from .matlab import ssdata, tfdata

# The following is to use Numpy's testing framework
# Tests go under directory tests/, benchmarks under directory benchmarks/
from numpy.testing import Tester
test = Tester().test
bench = Tester().bench
from numpy.testing import Tester
test = Tester().test
bench = Tester().bench
2 changes: 1 addition & 1 deletion control/tests/freqresp.py
Expand Up @@ -40,7 +40,7 @@
systf = tf(sys)
tfMIMO = tf(sysMIMO)

print systf.pole()
print(systf.pole())
#print tfMIMO.pole() # - should throw not implemented exception
#print tfMIMO.zero() # - should throw not implemented exception

Expand Down
40 changes: 40 additions & 0 deletions make_version.py
@@ -0,0 +1,40 @@
from subprocess import check_output
import os

def main():
cmd = 'git describe --always --long'
output = check_output(cmd.split()).decode('utf-8').strip().split('-')
if len(output) == 3:
version, build, commit = output
else:
raise Exception("Could not git describe, (got %s)" % output)

print("Version: %s" % version)
print("Build: %s" % build)
print("Commit: %s\n" % commit)

filename = "control/_version.py"
print("Writing %s" % filename)
with open(filename, 'w') as fd:
if build == '0':
fd.write('__version__ = "%s"\n' % (version))
else:
fd.write('__version__ = "%s.post%s"\n' % (version, build))
fd.write('__commit__ = "%s"\n' % (commit))

# Write files for conda version number
SRC_DIR = os.environ.get('SRC_DIR', '.')
conda_version_path = os.path.join(SRC_DIR, '__conda_version__.txt')
print("Writing %s" % conda_version_path)
with open(conda_version_path, 'w') as conda_version:
conda_version.write(version)

conda_buildnum_path = os.path.join(SRC_DIR, '__conda_buildnum__.txt')
print("Writing %s" % conda_buildnum_path)

with open(conda_buildnum_path, 'w') as conda_buildnum:
conda_buildnum.write(build)


if __name__ == '__main__':
main()

0 comments on commit 15fd5c1

Please sign in to comment.