diff --git a/filterpy/kalman/EKF.py b/filterpy/kalman/EKF.py index 5e83aec0..d5492473 100644 --- a/filterpy/kalman/EKF.py +++ b/filterpy/kalman/EKF.py @@ -212,7 +212,7 @@ def predict_update(self, z, HJacobian, Hx, args=(), hx_args=(), u=0): if np.isscalar(z) and self.dim_z == 1: z = np.asarray([z], float) - F = self.F + F = self.FJacobian() B = self.B P = self.P Q = self.Q @@ -341,6 +341,12 @@ def update(self, z, HJacobian, Hx, R=None, args=(), hx_args=(), self.x_post = self.x.copy() self.P_post = self.P.copy() + def FJacobian(self, u=0): + """ + Calculates the Jacobian of the transition matrix. Override if F is not sufficient. + """ + return self.F + def predict_x(self, u=0): """ Predicts the next state of X. If you need to @@ -348,7 +354,8 @@ def predict_x(self, u=0): need to do this, for example, if the usual Taylor expansion to generate F is not providing accurate results for you. """ - self.x = dot(self.F, self.x) + dot(self.B, u) + F = self.FJacobian() + self.x = dot(F, self.x) + dot(self.B, u) def predict(self, u=0): """ @@ -364,7 +371,8 @@ def predict(self, u=0): """ self.predict_x(u) - self.P = dot(self.F, self.P).dot(self.F.T) + self.Q + F = self.FJacobian() + self.P = dot(F, self.P).dot(F.T) + self.Q # save prior self.x_prior = np.copy(self.x) @@ -416,7 +424,7 @@ def __repr__(self): pretty_str('P', self.P), pretty_str('x_prior', self.x_prior), pretty_str('P_prior', self.P_prior), - pretty_str('F', self.F), + pretty_str('F', self.FJacobian()), pretty_str('Q', self.Q), pretty_str('R', self.R), pretty_str('K', self.K), diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..8e7fe380 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,83 @@ +[build-system] + +# requires is a list of packages that are needed to build your package. +# You don’t need to install them; +# build frontends like pip will install them automatically in a temporary, +# isolated virtual environment for use during the build process +requires = ["setuptools", "setuptools-scm", "wheel"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages.find] +where = ["filterpy"] + +[tool.setuptools.package-data] +"filterpy" = ["README.rst", "filterpy/changelog.txt", "LICENSE", "filterpy/kalman/tests/*.py"] + +[tool.flake8] +max-line-length = 120 +extend-ignore = ["E265"] +# Ignore block comment should start with '# ' because it causes issues with environment definition for scripts + +[tool.autopep8] +max_line_length = 120 +in-place = 1 +aggressive = 1 +ignore = "" + +# this is the [project] table +[project] +# add the distribution name of the package, the tar ball and python wheel use this name, this name goes the /home/$USER/.local/lib/python3.8/site-packages/ +name = "filterpy" + +dynamic = ["dependencies", "optional-dependencies"] + +# version is the package version. See the version specifier specification +# for more details on versions. Some build backends allow it to be +# specified another way, such as from a file or a git tag. +version = "0.2.0" +authors = [ + { name="Roger Labbe", email="rlabbejr@gmail.com" } +] +description = "Kalman filtering and optimal estimation library" +readme = "README.rst" +license = { file="LICENSE" } + +# installers like pip use this to check for matching python versions +requires-python = ">=3.7" +classifiers = [ + # How mature is this project? Common values are + # 3 - Alpha + # 4 - Beta + # 5 - Production/Stable + "Development Status :: 5 - Production/Stable", + + # Indicate who your project is intended for + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Mathematics", + "Topic :: Scientific/Engineering :: Physics", + "Topic :: Utilities", + + + # Pick your license as you wish (should match "license" above) + "License :: OSI Approved :: MIT License", + + # Specify the Python versions you support here. In particular, ensure + # that you indicate whether you support Python 2, Python 3 or both. + "Programming Language :: Python :: 3.7", + + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Operating System :: Unix", + "Operating System :: MacOS" +] + +[tool.setuptools.dynamic] +dependencies = {file = ["requirements.txt"]} +optional-dependencies.readthedocs = {file = ["requirements.readthedocs.txt"]} + +[project.urls] +"Homepage" = "http://github.com/rlabbe/filterpy" +"Bug Tracker" = "http://github.com/rlabbe/filterpy/issues/" diff --git a/requirements.txt b/requirements.txt index 6bad1038..f23634b2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ numpy scipy +matplotlib diff --git a/setup.py b/setup.py deleted file mode 100644 index eb706477..00000000 --- a/setup.py +++ /dev/null @@ -1,103 +0,0 @@ -from setuptools import setup, find_packages # Always prefer setuptools over distutils -from codecs import open # To use a consistent encoding -from os import path -import filterpy - -here = path.abspath(path.dirname(__file__)) - -# Get the long description from the relevant file -with open(path.join(here, 'README.rst'), encoding='utf-8') as f: - long_description = f.read() - -setup( - name='filterpy', - - # Versions should comply with PEP440. For a discussion on single-sourcing - # the version across setup.py and the project code, see - # http://packaging.python.org/en/latest/tutorial.html#version - version=filterpy.__version__, - - description='Kalman filtering and optimal estimation library', - long_description=long_description, - - # The project's main homepage. - url='https://github.com/rlabbe/filterpy', - - # Author details - author='Roger Labbe', - author_email='rlabbejr@gmail.com', - - # Choose your license - license='MIT', - - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers - classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - 'Development Status :: 5 - Production/Stable', - - # Indicate who your project is intended for - 'Intended Audience :: Developers', - 'Intended Audience :: Education', - 'Intended Audience :: Science/Research', - 'Topic :: Scientific/Engineering', - 'Topic :: Scientific/Engineering :: Mathematics', - 'Topic :: Scientific/Engineering :: Physics', - 'Topic :: Utilities', - - - # Pick your license as you wish (should match "license" above) - 'License :: OSI Approved :: MIT License', - - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Operating System :: Unix', - 'Operating System :: MacOS' - ], - - # What does your project relate to? - keywords='Kalman filters filtering optimal estimation tracking', - - # You can just specify the packages manually here if your project is - # simple. Or you can use find_packages(). - packages=find_packages(exclude=['contrib']), - - # List run-time dependencies here. These will be installed by pip when your - # project is installed. For an analysis of "install_requires" vs pip's - # requirements files see: - # https://packaging.python.org/en/latest/technical.html#install-requires-vs-requirements-files - install_requires=['numpy', 'scipy', 'matplotlib'], - - # If there are data files included in your packages that need to be - # installed, specify them here. If using Python 2.6 or less, then these - # have to be included in MANIFEST.in as well. - package_data={ - 'filterpy': ['README.rst', 'filterpy/changelog.txt', 'LICENSE', 'filterpy/kalman/tests/*.py'], - }, - - # Although 'package_data' is the preferred approach, in some case you may - # need to place data files outside of your packages. - # see http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files - # In this case, 'data_file' will be installed into '/my_data' - #data_files=[('my_data', ['data/data_file'])], - - # To provide executable scripts, use entry points in preference to the - # "scripts" keyword. Entry points provide cross-platform support and allow - # pip to create the appropriate form of executable for the target platform. - #entry_points={ - # 'console_scripts': [ - # 'sample=sample:main', - # ], - #}, -)