## ILQGames.jl

Rapidly designing and solving differential games in Julia.
Author lassepe
Popularity
25 Stars
Updated Last
1 Year Ago
Started In
August 2019

# iLQGames.jl

iLQGames.jl is a framework for rapidly designing and solving nonlinear general-sum differential games, built around iterative linear-quadratic game approximations.

A brief introduction to this framework and benchmarks against a C++ implementation can be found in this short workshop manuscript. Finally, this paper demonstrates the flexibility and performance of iLQGames.jl by combining it with a particle-filter scheme to reason about uncertainty in differential games in real-time.

## Installation

Within the Julia REPL run:

```using Pkg

## Example

Here is an example of two players controlling a single 4D-unicycle. Player-1 controls the steering, Player-2 controls the acceleration.

#### 1. Describe Dynamics

We define a Unicycle as a subtype of our `ControlSystem` type and implement the differential equation by overloading `dx` for our type.

```using iLQGames
import iLQGames: dx

# parameters: number of states, number of inputs, sampling time, horizon
nx, nu, ΔT, game_horizon = 4, 2, 0.1, 200

# setup the dynamics
struct Unicycle <: ControlSystem{ΔT,nx,nu} end
# the differential equation of a uncycle with state: (px, py, phi, v)
dx(cs::Unicycle, x, u, t) = SVector(x[4]cos(x[3]), x[4]sin(x[3]), u[1], u[2])
dynamics = Unicycle()
```

#### 2. Setup Costs

To setup the costs encoding each players objectives, we can derive a custom subtype from `PlayerCost`, or, as done here, simply hand the cost function as a lambda function to the `FunctionPlayerCost`.

```# player-1 wants the unicycle to stay close to the origin,
# player-2 wants to keep close to 1 m/s
costs = (FunctionPlayerCost((g, x, u, t) -> (x[1]^2 + x[2]^2 + u[1]^2)),
FunctionPlayerCost((g, x, u, t) -> ((x[4] - 1)^2 + u[2]^2)))
# indices of inputs that each player controls
player_inputs = (SVector(1), SVector(2))```

#### 3. Solve the Game

With this information we can construct the game...

`g = GeneralGame(game_horizon, player_inputs, dynamics, costs)`

...and solve it for some initial conditions `x0`. Automatic differentiation will save us from having to specify how to compute LQ approximations of the system.

```# get a solver, choose initial conditions and solve (in about 9 ms with automatic differentiation)
solver = iLQSolver(g)
x0 = SVector(1, 1, 0, 0.5)
converged, trajectory, strategies = solve(g, solver, x0)```

Finally, we can visualize the path of the unicycle as follows (x- and y-position):

```# for visualization we need to state which state indices correspond to px and py
position_indices = tuple(SVector(1,2))
# Note: you can use the `plot_traj` call without @animated to get a non-animated plot instead.
@animated(plot_traj(trajectory, g, [:red, :green], player_inputs),
1:game_horizon, "minimal_example.gif")```

At the equilibrium solution, Player-2 accelerates to reach the desired speed. Player-1 steers the unicycle in a figure-8 to stay close to the origin.: