pydiffgame
PyDiffGame is a Python implementation of a Nash Equilibrium solution to Differential Games, based on a reduction of Game Hamilton-Bellman-Jacobi (GHJB) equations to Game Algebraic and Differential Riccati equations, associated with Multi-Objective Dynamical Control Systems
Science Score: 54.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
✓CITATION.cff file
Found CITATION.cff file -
✓codemeta.json file
Found codemeta.json file -
○.zenodo.json file
-
✓DOI references
Found 1 DOI reference(s) in README -
✓Academic publication links
Links to: researchgate.net, ieee.org -
○Committers with academic emails
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (11.8%) to scientific vocabulary
Keywords
Repository
PyDiffGame is a Python implementation of a Nash Equilibrium solution to Differential Games, based on a reduction of Game Hamilton-Bellman-Jacobi (GHJB) equations to Game Algebraic and Differential Riccati equations, associated with Multi-Objective Dynamical Control Systems
Basic Info
- Host: GitHub
- Owner: krichelj
- License: mit
- Language: Python
- Default Branch: master
- Homepage: https://krichelj.github.io/PyDiffGame/
- Size: 7.41 MB
Statistics
- Stars: 53
- Watchers: 6
- Forks: 10
- Open Issues: 0
- Releases: 3
Topics
Metadata Files
README.md
What is this?
PyDiffGame is a Python implementation of a Nash Equilibrium solution to Differential Games, based on a reduction of Game Hamilton-Bellman-Jacobi (GHJB) equations to Game Algebraic and Differential Riccati equations, associated with Multi-Objective Dynamical Control Systems\
The method relies on the formulation given in:
The thesis work "Differential Games for Compositional Handling of Competing Control Tasks" (Research Gate)
The conference article "Composition of Dynamic Control Objectives Based on Differential Games" (IEEE | Research Gate)
The package was tested for Python >= 3.10.
Installation
To install this package run this from the command prompt:
pip install PyDiffGame
The package was tested for Python >= 3.10, along with the listed packages versions in requirments.txt
Input Parameters
The package defines an abstract class PyDiffGame.py. An object of this class represents an instance of differential game.
The input parameters to instantiate a PyDiffGame object are:
A:np.arrayof shape $(n,n)$ >System dynamics matrixB:np.arrayof shape $(n, m1 + ... + mN)$, optional >Input matrix for all virtual control objectivesBs:Sequenceofnp.arrayobjects of len $(N)$, each array $Bi$ of shape $(n,mi)$, optional >Input matrices for each virtual control objectiveQs:Sequenceofnp.arrayobjects of len $(N)$, each array $Q_i$ of shape $(n,n)$, optional >State weight matrices for each virtual control objectiveRs:Sequenceofnp.arrayobjects of len $(N)$, each array $Ri$ of shape $(mi,m_i)$, optional >Input weight matrices for each virtual control objectiveMs:Sequenceofnp.arrayobjects of len $(N)$, each array $Mi$ of shape $(mi,m)$, optional >Decomposition matrices for each virtual control objectiveobjectives:SequenceofObjectiveobjects of len $(N)$, each $Oi$ specifying $Qi, Ri$ and $Mi$, optional >Desired objectives for the gamex_0:np.arrayof len $(n)$, optional >Initial state vectorx_T:np.arrayof len $(n)$, optional >Final state vector, in case of signal trackingT_f: positivefloat, optional >System dynamics horizon. Should be given in the case of finite horizonP_f:listofnp.arrayobjects of len $(N)$, each array $P{fi}$ of shape $(n,n)$, optional, default = uncoupled solution ofscipy's solve_are> >Final condition for the Riccati equation array. Should be given in the case of finite horizonstate_variables_names:Sequenceofstrobjects of len $(N)$, optional >The state variables' names to display when plottingshow_legend:boolean, optional >Indicates whether to display a legend in the plotsstate_variables_names:Sequenceofstrobjects of len $(n)$, optional >The state variables' names to displayepsilon_x:floatin the interval $(0,1)$, optional >Numerical convergence threshold for the state vector of the systemepsilon_P:floatin the interval $(0,1)$, optional >Numerical convergence threshold for the matrices P_iL: positiveint, optional >Number of data pointseta: positiveint, optional >The number of last matrix norms to consider for convergencedebug:boolean, optional >Indicates whether to display debug information
Tutorial
To demonstrate the use of the package, we provide a few running examples. Consider the following system of masses and springs:
The performance of the system under the use of the suggested method is compared with that of a Linear Quadratic Regulator (LQR). For that purpose, class named PyDiffGameLQRComparison is defined. A comparison of a system should subclass this class.
As an example, for the masses and springs system, consider the following instantiation of an MassesWithSpringsComparison object:
```python import numpy as np from PyDiffGame.examples.MassesWithSpringsComparison import MassesWithSpringsComparison
N = 2 k = 10 m = 50 r = 1 epsilonx = 10e-8 epsilonP = 10e-8 q = [[500, 2000], [500, 250]]
x0 = np.array([10 * i for i in range(1, N + 1)] + [0] * N) xT = x0 * 10 if N == 2 else np.array([(10 * i) ** 3 for i in range(1, N + 1)] + [0] * N) Tf = 25
masseswithsprings = MassesWithSpringsComparison(N=N, m=m, k=k, q=q, r=r, x0=x0, xT=xT, Tf=Tf, epsilonx=epsilonx, epsilonP=epsilonP) ```
Consider the constructor of the class MassesWithSpringsComparison:
```python import numpy as np from typing import Sequence, Optional
from PyDiffGame.PyDiffGame import PyDiffGame from PyDiffGame.PyDiffGameLQRComparison import PyDiffGameLQRComparison from PyDiffGame.Objective import GameObjective, LQRObjective
class MassesWithSpringsComparison(PyDiffGameLQRComparison): def init(self, N: int, m: float, k: float, q: float | Sequence[float] | Sequence[Sequence[float]], r: float, Ms: Optional[Sequence[np.array]] = None, x0: Optional[np.array] = None, xT: Optional[np.array] = None, Tf: Optional[float] = None, epsilonx: Optional[float] = PyDiffGame.epsilonxdefault, epsilonP: Optional[float] = PyDiffGame.epsilonPdefault, L: Optional[int] = PyDiffGame.Ldefault, eta: Optional[int] = PyDiffGame.etadefault): IN = np.eye(N) Z_N = np.zeros((N, N))
M_masses = m * I_N
K = k * (2 * I_N - np.array([[int(abs(i - j) == 1) for j in range(N)] for i in range(N)]))
M_masses_inv = np.linalg.inv(M_masses)
M_inv_K = M_masses_inv @ K
if Ms is None:
eigenvectors = np.linalg.eig(M_inv_K)[1]
Ms = [eigenvector.reshape(1, N) for eigenvector in eigenvectors]
A = np.block([[Z_N, I_N],
[-M_inv_K, Z_N]])
B = np.block([[Z_N],
[M_masses_inv]])
Qs = [np.diag([0.0] * i + [q] + [0.0] * (N - 1) + [q] + [0.0] * (N - i - 1))
if isinstance(q, (int, float)) else
np.diag([0.0] * i + [q[i]] + [0.0] * (N - 1) + [q[i]] + [0.0] * (N - i - 1)) for i in range(N)]
M = np.concatenate(Ms,
axis=0)
assert np.all(np.abs(np.linalg.inv(M) - M.T) < 10e-12)
Q_mat = np.kron(a=np.eye(2),
b=M)
Qs = [Q_mat.T @ Q @ Q_mat for Q in Qs]
Rs = [np.array([r])] * N
R_lqr = 1 / 4 * r * I_N
Q_lqr = q * np.eye(2 * N) if isinstance(q, (int, float)) else np.diag(2 * q)
state_variables_names = ['x_{' + str(i) + '}' for i in range(1, N + 1)] + \
['\\dot{x}_{' + str(i) + '}' for i in range(1, N + 1)]
args = {'A': A,
'B': B,
'x_0': x_0,
'x_T': x_T,
'T_f': T_f,
'state_variables_names': state_variables_names,
'epsilon_x': epsilon_x,
'epsilon_P': epsilon_P,
'L': L,
'eta': eta}
lqr_objective = [LQRObjective(Q=Q_lqr,
R_ii=R_lqr)]
game_objectives = [GameObjective(Q=Q,
R_ii=R,
M_i=M_i) for Q, R, M_i in zip(Qs, Rs, Ms)]
games_objectives = [lqr_objective,
game_objectives]
super().__init__(args=args,
M=M,
games_objectives=games_objectives,
continuous=True)
```
Finally, consider calling the masses_with_springs object as follows:
```python outputvariablesnames = ['$\frac{x1 + x2}{\sqrt{2}}$', '$\frac{x2 - x1}{\sqrt{2}}$', '$\frac{\dot{x}1 + \dot{x}2}{\sqrt{2}}$', '$\frac{\dot{x}2 - \dot{x}1}{\sqrt{2}}$']
masseswithsprings(plotstatespaces=True, plotMx=True, outputvariablesnames=outputvariablesnames, savefigure=True) ```
This will result in the following plot that compares the two systems performance for a differential game vs an LQR:
And when tweaking the weights by setting
python
qs = [[500, 5000]]
we have:
Authors
If you use this work, please cite our paper:
@inproceedings{pydiffgame_paper,
author={Kricheli, Joshua Shay and Sadon, Aviran and Arogeti, Shai and Regev, Shimon and Weiss, Gera},
booktitle={29th Mediterranean Conference on Control and Automation (MED 2021)},
title={{Composition of Dynamic Control Objectives Based on Differential Games}},
year={2021},
volume={},
number={},
pages={298-304},
doi={10.1109/MED51440.2021.9480269}}
Further details can be found in the citation document.
Acknowledgments
This research was supported in part by the Leona M. and Harry B. Helmsley Charitable Trust through the 'Agricultural, Biological and Cognitive Robotics Initiative' ('ABC') and by the Marcus Endowment Fund both at Ben-Gurion University of the Negev, Israel. This research was also supported by The 'Israeli Smart Transportation Research Center' ('ISTRC') by The Technion and Bar-Ilan Universities, Israel.
Owner
- Name: Joshua Shay Kricheli
- Login: krichelj
- Kind: user
- Location: Tel Aviv, Israel
- Company: Ben Gurion University of the Negev
- Website: shaykricheli.com
- Repositories: 6
- Profile: https://github.com/krichelj
AI/ML Researcher, Vice President Data Science, M.Sc. in Computer Science, B.Sc. in Mechanical Engineering
Citation (CITATIONS.bib)
@software{pydiffgame_package,
author = {Kricheli, Joshua Shay and Sadon, Aviran},
title = {{PyDiffGame}},
howpublished = {\url{https://krichelj.github.io/PyDiffGame/}},
year = {2021},
}
@inproceedings{pydiffgame_paper,
author={Kricheli, Joshua Shay and Sadon, Aviran and Arogeti, Shai and Regev, Shimon and Weiss, Gera},
booktitle={29th Mediterranean Conference on Control and Automation (MED 2021)},
title={{Composition of Dynamic Control Objectives Based on Differential Games}},
year={2021},
volume={},
number={},
pages={298-304},
doi={10.1109/MED51440.2021.9480269}}
@mastersthesis{kricheli2022differential,
title={{Differential Games for Compositional Handling of Competing Control Tasks}},
author={Kricheli, Joshua Shay},
year={2022},
school={Ben-Gurion University of the Negev}
}
GitHub Events
Total
- Create event: 3
- Release event: 4
- Issues event: 4
- Watch event: 5
- Delete event: 4
- Issue comment event: 4
- Push event: 14
- Fork event: 2
Last Year
- Create event: 3
- Release event: 4
- Issues event: 4
- Watch event: 5
- Delete event: 4
- Issue comment event: 4
- Push event: 14
- Fork event: 2
Committers
Last synced: 7 months ago
Top Committers
| Name | Commits | |
|---|---|---|
| shaykrichelifrenn | s****2@g****m | 298 |
| shaykrichelifrenn | s****y@f****o | 21 |
| Gera Weiss | g****s@g****m | 3 |
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: 7 months ago
All Time
- Total issues: 15
- Total pull requests: 0
- Average time to close issues: 3 months
- Average time to close pull requests: N/A
- Total issue authors: 4
- Total pull request authors: 0
- Average comments per issue: 0.87
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 2
- Pull requests: 0
- Average time to close issues: 2 days
- Average time to close pull requests: N/A
- Issue authors: 1
- Pull request authors: 0
- Average comments per issue: 1.5
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
- krichelj (11)
- txw226 (2)
- Comp1exBoyan (1)
- zhang261007 (1)
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels
Packages
- Total packages: 1
-
Total downloads:
- pypi 21 last-month
- Total dependent packages: 0
- Total dependent repositories: 0
- Total versions: 4
- Total maintainers: 1
pypi.org: pydiffgame
PyDiffGame is a Python implementation of a Nash Equilibrium solution to Differential Games, based on a reduction of Game Hamilton-Bellman-Jacobi (GHJB) equations to Game Algebraic and Differential Riccati equations, associated with Multi-Objective Dynamical Control Systems
- Homepage: https://krichelj.github.io/PyDiffGame/
- Documentation: https://pydiffgame.readthedocs.io/
- License: MIT License
-
Latest release: 1.0.0
published 10 months ago
Rankings
Maintainers (1)
Dependencies
- matplotlib >=3.5.1
- numpy >=1.22.3
- quadpy >=0.16.10
- scipy >=1.8.0
- setuptools >=60.9.3
- tqdm >=4.63.0