Code Monkey home page Code Monkey logo

crowddynamics's Introduction

Crowd Dynamics

Crowd dynamics is a simulation environment written in Python package for simulation movement of crowds. The project was created in summer 2016 for Systems Analysis Laboratory at Aalto University in Finland. The documentation has more detail about the project.

Installation

Crowd dynamics is tested on Ubuntu 16.04 using Python 3.6. First, install the Conda package manager. Miniconda distribution is the easiest to install. Then, clone the crowddynamics repository.

git clone https://github.com/jaantollander/crowddynamics.git

Inside the crowddynamics directory, install the Conda environment, activate it, and install crowddynamics as an editable.

conda env create -f environment.yml
conda activate crowd36
pip install --editable .

Graphical User Interface

We can use a graphical user interface (GUI) for visualizing the crowd simulations and display data interactively, which can be very useful for designing new simulations and debugging. We have implemented the GUI for crowddynamics using Qt via pyqt and pyqtgraph. It is maintained separately from the crowddynamics repository due to its dependencies on Qt.

We start by cloning the repository.

git clone https://github.com/jaantollander/crowddynamics-qtgui.git

Inside crowddynamics-qtgui directory, install the requirements and install crowddynamics-qtgui as editable. We must install pyqt version 4 using Conda from the conda-force channel for it to work correctly. Be sure that you activate the environment where you installed crowddynamics.

conda activate crowd36
conda install pyqt=4 -c conda-forge
pip install -r requirements.txt
pip install --editable .

Usage

Inside the crowddynamics/examples directory, we can find example simulations.

from crowddynamics.examples.simulations import Hallway
from crowddynamics.simulation.agents import Circular
from crowddynamics.logging import setup_logging

if __name__ == '__main__':
    setup_logging()
    iterations = 1000
    simulation = Hallway(agent_type=Circular)
    for i in range(iterations):
        simulation.update()

Tests

Tests are implemented using Pytest and Hypothesis.

Install test dependencies.

pip install -r requirements-tests.txt

In the project's root directory, run pystest test suite.

pytest

Documentation

Documentation is created using Sphinx.

Install documentation dependencies

pip install -r requirement-docs.txt

In docs directory.

make html

Versioning

Versioneer is used for versioning.

crowddynamics's People

Contributors

jaantollander avatar pyup-bot 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crowddynamics's Issues

The change of Taset per second should be set in the GUI

The linear change of T ASET per second is denoted by Δ T ASET . For simplicity, we assume that all agents have the same value for Δ T ASET .

So, basically, Δ T ASET = -1 , accounts for a normally progressing evacuation. If Δ T ASET > -1 , the agents evacuation situation is improving with time, e.g., fire fighters are extinguishing the fire. If Δ T ASET < -1 , the situation gets worse with time, e.g., the fire is spreading rapidly.

Δ T ASET should be part of the settings in the GUI.

Crowd Quantities

  • crowd density
  • crowd pressure
  • velocity

Crowd Density Algorithm

Implement algorithms for computing crowd densities using Voronoi diagrams.

Steffen, B., & Seyfried, A. (2010). Methods for measuring pedestrian density, flow, speed and direction with minimal scatter. Physica A: Statistical Mechanics and Its Applications, 389(9), 1902–1910. https://doi.org/10.1016/j.physa.2009.12.015

https://stackoverflow.com/questions/20515554/colorize-voronoi-diagram?noredirect=1&lq=1
https://gist.github.com/pv/8036995
https://www.toptal.com/python/computational-geometry-in-python-from-theory-to-implementation

Improvements for Obstacles

Better array format

Change obstacles array format from point pair to array of points where the the points belonging to different geometries (Point, LineString, Polygon.interior, Polygon.exterior) are separated by row where first element is np.nan and second element if flag indicating the geometry.

Todo

  • BaseGeometry to numpy.array converter
  • Overlapping testing between agents and obstacles
  • Interactions between agents and obstacles

Something wrong with best-response strategy update

Even though TASET =0, some of the agents appear to update to the strategy Patient (marked with color blue). However, this should not be possible, if the best-response strategy update is coded correctly.

equilibrium gone wrong

The problem should be located in game.py in the following line of code:

@numba.jit(nopython=True)
def best_response_strategy(agent, players, door, radius_max, strategy,
                           strategies, t_aset, interval, dt):
    """Best response strategy. Minimizes loss."""
    x = agent.position[players]
    t_evac = agent_closer_to_exit(door, x) / exit_capacity(door, radius_max)

    loss = np.zeros(2)  # values: loss, indices: strategy
    np.random.shuffle(players)
    for i in players:
        if poisson_clock(interval, dt):
            for j in agent.neighbors[i]:
                if j < 0:
                    continue
                for s_our in strategies:
                    loss[s_our] += payoff(s_our, strategy[j], t_aset, t_evac[i],
                                          t_evac[j])
            strategy[i] = np.argmin(loss)  # Update strategy
            loss[:] = 0  # Reset loss array

What exactly the enviroment is?

What python version should used?
I tried from python 3.5.2, 3.5.4 and 3.7.3 on windows but none of them worked.

These two librarise can't meet requriment.txt:
numpy must upgrade to 1.3.3+ to meet the pandas requirement.
And Shapely could't find version shapely==1.5.17.post1 but 1.6.4.

In agent.py "from collections import Callable, Collection, Generator" there is no class named Collection in collections.abc under version of python 3.6 ,but I see the ductment used python3.5.

When I soved that.

The newest error seems to be a numba error:

PS C:\Users\Administrator> crowddynamics Traceback (most recent call last):
File "C:\Python35\lib\site-packages\numba\pythonapi.py", line 1297, in serialize_object
gv = self.module.__serialized[obj]
KeyError: (<class 'RuntimeError'>, ('numba jitted function aborted due to unresolved symbol',))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Python35\Scripts\crowddynamics-script.py", line 9, in
load_entry_point('crowddynamics==0+unknown', 'console_scripts', 'crowddynamics')()
File "C:\Python35\lib\site-packages\pkg_resources_init_.py", line 565, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "C:\Python35\lib\site-packages\pkg_resources_init_.py", line 2631, in load_entry_point
return ep.load()
File "C:\Python35\lib\site-packages\pkg_resources_init_.py", line 2291, in load
return self.resolve()
File "C:\Python35\lib\site-packages\pkg_resources_init_.py", line 2297, in resolve
module = import(self.module_name, fromlist=['name'], level=0)
File "C:\Python35\lib\site-packages\crowddynamics-0+unknown-py3.5.egg\crowddynamics\cli.py", line 11, in
from crowddynamics.simulation.multiagent import MultiAgentSimulation
File "C:\Python35\lib\site-packages\crowddynamics-0+unknown-py3.5.egg\crowddynamics\simulation\multiagent.py", line 10, in
from crowddynamics.simulation.agents import Agents
File "C:\Python35\lib\site-packages\crowddynamics-0+unknown-py3.5.egg\crowddynamics\simulation\agents.py", line 15, in
from crowddynamics.core.distance import distance_circles,
File "C:\Python35\lib\site-packages\crowddynamics-0+unknown-py3.5.egg\crowddynamics\core\distance.py", line 13, in
from crowddynamics.core.vector2D import length, rotate90, dot
File "C:\Python35\lib\site-packages\crowddynamics-0+unknown-py3.5.egg\crowddynamics\core\vector2D.py", line 8, in
@numba.vectorize([f8(f8)], cache=True)
File "C:\Python35\lib\site-packages\numba\npyufunc\decorators.py", line 118, in wrap
vec = Vectorize(func, **kws)
File "C:\Python35\lib\site-packages\numba\npyufunc\decorators.py", line 38, in new
return imp(func, identity=identity, cache=cache, targetoptions=kws)
File "C:\Python35\lib\site-packages\numba\npyufunc\dufunc.py", line 89, in init
self._install_cg()
File "C:\Python35\lib\site-packages\numba\npyufunc\dufunc.py", line 275, in _install_cg
targetctx = self._dispatcher.targetdescr.target_context
File "C:\Python35\lib\site-packages\numba\npyufunc\ufuncbuilder.py", line 40, in target_context
return cpu_target.target_context
File "C:\Python35\lib\site-packages\numba\targets\registry.py", line 54, in target_context
return self._toplevel_target_context
File "C:\Python35\lib\site-packages\numba\utils.py", line 283, in get
res = instance.dict[self.name] = self.func(instance)
File "C:\Python35\lib\site-packages\numba\targets\registry.py", line 38, in _toplevel_target_context
return cpu.CPUContext(self.typing_context)
File "C:\Python35\lib\site-packages\numba\targets\base.py", line 240, in init
self.init()
File "C:\Python35\lib\site-packages\numba\targets\cpu.py", line 48, in init
rtsys.initialize(self)
File "C:\Python35\lib\site-packages\numba\runtime\nrt.py", line 35, in initialize
self._library = nrtdynmod.compile_nrt_functions(ctx)
File "C:\Python35\lib\site-packages\numba\runtime\nrtdynmod.py", line 199, in compile_nrt_functions
ir_mod, library = create_nrt_module(ctx)
File "C:\Python35\lib\site-packages\numba\runtime\nrtdynmod.py", line 189, in create_nrt_module
_define_nrt_unresolved_abort(ctx, ir_mod)
File "C:\Python35\lib\site-packages\numba\runtime\nrtdynmod.py", line 166, in _define_nrt_unresolved_abort
ctx.call_conv.return_user_exc(builder, RuntimeError, (msg,))
File "C:\Python35\lib\site-packages\numba\targets\callconv.py", line 344, in return_user_exc
struct_gv = pyapi.serialize_object(exc)
File "C:\Python35\lib\site-packages\numba\pythonapi.py", line 1299, in serialize_object
struct = self.serialize_uncached(obj)
File "C:\Python35\lib\site-packages\numba\pythonapi.py", line 1282, in serialize_uncached
arr = self.context.insert_unique_const(self.module, name, bdata)
File "C:\Python35\lib\site-packages\numba\targets\base.py", line 401, in insert_unique_const
gv = mod.get_global(name)
File "C:\Python35\lib\site-packages\llvmlite\ir\module.py", line 138, in get_global
return self.globals[name]
KeyError: '.const.pickledata.2479669597384'

Hoping to get your help

Conda packaging

CrowdDynamics should be made installable through Conda package manager.

Multithreading Interactions

Todo

  •  Split workloads equally by splitting agents by the amount of interactions
  • Test against non multithreaded version of the algorithm

Generate random numbers from complementary CDF of Gamma distribution using Numba

For estimating the number of strategy update times for an agent during the time interval dt, we would need to use the complementary CDF of Erlang or Gamma distribution. As these are only available in the scipy.stats library, which is not numba-compatible, I wasn't able to use them in the issue #2 . But I set the number of strategy updates times to be fixed to 10, which should be sufficient for all values of dt used.

If one would like to code a random number generator from complementary CDF of Gamma distribution, here are two resources https://www.continuum.io/blog/developer-blog/calling-c-libraries-numba-using-cffi and https://en.wikipedia.org/wiki/Gamma_distribution.

Agent's strategies don't alter their movement

Currently, whether an agent is patient or impatient doesn't affect its parameters in the social force model (or velocity dependent model, if that is used).

According to Heliövaara et al., 2013:

  1. Impatient agents do not avoid contacts with other agents as much. This is reflected by a smaller magnitude of the social force fijsoc for the impatient agents.
  2. Impatient agents accelerate faster to their target velocity. This is implemented by decreasing the individual relaxation time τ i for the impatient agents.
  3. Impatient agents move more nervously. This is implemented by increasing the individual random fluctuation force ξ i (t) for the impatient agents.

This should be implemented somewhere in the code. For the velocity dependent model similar rules should be created.

Herding Behavior and Exit Selection


layout: "post"
title: "FDS+Evac: Herding Behavior and Exit Selection"
date: "2017-05-23 09:40"

Korhonen, T., & Heliövaara, S. (2011). FDS+Evac: Herding Behavior and Exit Selection, (August), 1373–1385. https://doi.org/10.3801/IAF

Exit Selection Model

All agents use three criteria to determine preference number $P_i(k)$ for each exit $k ∈ ℰ$ which depends on the agent type. Criteria (boolean variables true or false) are

  • Visible, variable
  • Familiar, constant
  • No-smoke, variable

Preference numbers for herding and conservative agents

 P  Visible  Familiar  No-smoke
 1  true  true  true
 2  false  true  false
 3  true  false  true
 4  true  true / false  false
 5  false  true  false

Preference numbers for active agents

 P  Visible  Familiar  No-smoke
 1  true  true/false  true
 1  true/false  true  true
 2  true  true/false  false
 2  true/false  true  false

Agents select the exit with smallest preference number. If two of more exits share the same preference, the decisicion between the exits is made by minimizing estimated egress time.

Agent types and Preference numbers

  • Herding: Herding agents use only familiar exits. If they have no familiar exits they follow other agents. Herding agents follow the movement of 5 closest agents that are withing the radius of 5 m. Only nearest neighbour that are heading away from the agent are considered ($cos(φ) &lt; -0.2$, $φ$ is angle between agents directions).

  • Conservative: Preferes familiar routes that are visible. Can get lost meaning agent does not have any visible or familiar exits. In this case they behave like herding agents until one or more exits become visible again.

  • Active: Active agents prefer all visible exists familiar or not in order to find fastest exit route. Can be though as the leaders for herding agents.

Exit selection algorithm for selecting exit $k$ is formulated using a penalty function

$$ \arg\min_{k ∈ ℰ} (T_i(k) + P_i(k) M) $$

where $T_i(k)$ is the estimated evacuation time for agent $i$ through exit $k$ and $M &gt; 0$ is sufficiently large constant. Estimated evacuation time consist of the time to walk to the door and estimated egress time of the crowd mass in front of the door.

Conclusions

Presence of active agents decreaces average egress time even in precense of large number of herding agents.

Core Performance Enhancements

Some performance enhancement proposals

  • Rewrite Agent class with custom numpy.dtype
  • Implement Walls using custom numpy.dtype
  • Use numba.CC to precompile core functions
  • Use multithreading to enhance the speed of computing interactions
  • Python Intel Distribution and Intel Math Kernel Library
  • Evaluate potential GPU acceleration and CUDA use
  • Pytest pytest-benchmark plugin for benchmarking code
  • psutil
  • Coverage of Numba jitted functions
  • float32 vs float64

ModuleNotFoundError: No module named 'numba.typing'`

Hi,
I have the following error when I try to run one example of crowddynamics.

Traceback (most recent call last): File "test_simm.py", line 1, in <module> from crowddynamics.examples.simulations import Hallway File "/home/josue/_crowdsim/crowddynamics/crowddynamics/examples/simulations.py", line 9, in <module> from crowddynamics.simulation.logic import Reset, Integrator, Fluctuation, \ File "/home/josue/_crowdsim/crowddynamics/crowddynamics/simulation/logic.py", line 11, in <module> from crowddynamics.core.evacuation import exit_detection File "/home/josue/_crowdsim/crowddynamics/crowddynamics/core/evacuation.py", line 4, in <module> from numba.typing.typeof import typeof ModuleNotFoundError: No module named 'numba.typing'

I'm on numba 0.53.1
And i tried to go on numba 0.47.0 but then I have this issue :
TypeError: create_target_machine() got an unexpected keyword argument 'jitdebug'

I don't know what to do... :=)
Thanks !

List of Enhancements

General Enhancements

Command line client and Graphical user interface

  • Progress bar

    • Fix tqdm progress bar to work with pytest
  • Commands

    • startproject
    • list
    • run
    • new
      • Template / cookiecutter
  • Command Arguments

    • debug
    • profile
    • loglevel
    • seed for random state
  • help text for mkoption

  • Launch multiple simulation in parallel

  • Scheduler

  • Read simulation configs from file

  • load and restart old simulations

  • chaining command to run different simulation types at chained, should
    also work in parallel

  • token normalization

References:

Visualization

Structures

  • Rewrite Agent class with custom numpy.dtype
  • Implement Walls using custom numpy.dtype
  • Linear obstacles -> linestrings concatenated with np.nan
    • Save information if linestring is closed (linear ring)
  • Agents should have active / inactive state

Performance and Algorithms

  • Navigation algorithm
    • Fix artifacts when merging direction maps
    • Optimize fill missing values by interpolation nearest values.
    • Nearest interpolation should take mean value when multiple points are at same length
  • Social forces should not effect through obstacles
  • Replace social force between agent and obstacles with navigation + adjusting force
  • Herding / Leader Follower effect
  • Fix three_circle model
  • Control and save random state / seed used for generating the simulation
  • Fix truncnorm to control the standard deviation
  • Test performance of KDTree for partitioning

Performance

MultiAgentSimulation

  • Properties -> Descriptors
    • domain
    • obstacles
    • targets
    • agents
    • tasks
  • Validation
    • Types
    • Values

Task Nodes

  • Factory for generating nodes
  • Nodes using generators / coroutines
  • Changing agent state

IO

  • Simulation Time
  • json/ yaml metadata files
  • Simulation initial configurations
  • Serializing simulation geometries: GeoJSON-like dicts

References

Testing

  • Fix coverage of Numba jitted functions

    Code coverage does not recognize Numba jitted functions (@numba.jit()). Can possibly be fixed with llvm-cov.

  • Benchmarks

Documentation

Packaging and distributing

  • Conda recipe, conda-forge feedstock

Poisson clock not coded correctly

The Poisson clock is not coded correctly in game.py. Below is described how it should be coded. This should be implemented to the game.py file.

In the game model, the number of times an agent updates its strategy in a time interval interval should follow a Poisson distribution with parameter λ (λ denotes the average number of occurrences in time interval interval ).

On the other hand, this means that the time interval between an agent's strategy updates should follow the exponential distribution with parameter 1/λ .

Now, in the code, we update the game in discrete time steps dt . Thus, it's possible that an agent updates its strategy more than once during the time step dt . Each of the N agents might update its strategy 0,1,2,3,... times. The intuitive way to calculate how many times an agent updates its strategies during the time step dt , and what are those times, would be to loop through the agents and for each agent generate update times from the exponential distribution until the cumulative sum of these update times exceeds dt .

However, this is rather inefficient. A more efficient way is to make use of the Erlang distribution (https://en.wikipedia.org/wiki/Erlang_distribution). The sum of k independent exponentially distributed variables with parameter 1/λ follows the Erlang distribution with shape parameter k and scale parameter 1/λ . Using the Erlang distribution we can ask the question, with 100% probability, what is the maximum amount of times an agent could update its strategies during the time dt ?

We do this by calculating what is the lowest value for the shape parameter k for which it holds P(X > dt) = 1.00, or using the cumulative distribution function 1 - F(dt;k;1/λ) = 1.00 , i.e., F(dt;k;1/λ)=0 . Note that X denotes here the random variable for the sum of k exponentially distributed variables. With Python this can be done with the following code:

from scipy import stats

sf = 0
shape = 1
while (sf < 1):
   sf = scipy.stats.erlang.sf(dt, shape, loc=0, scale=scaleparam)
   shape = shape + 1

After we have calculated the shape parameter, we know how many update times to generate for all the agents. In the code below, the update times are generated, and based on them the order in which the agents update their strategies.

import numpy as np
# generate k exponentially distributed update times for each agent
upd_times = scipy.stats.expon.rvs(loc=0, scale=scaleparam, size=(n_a,shape), random_state=None)
# calculate the cumulative sum of the update times for each agent
a = np.cumsum(upd_times, axis=1)
# choose all the elements which satisfy <= dt
b = np.where(a<=dt)
c = a[b]
# sort the elements
d = np.argsort(c)
# loop through the agents in correct chronological order,
# and set the agents to update to their best-response strategy.
# The best-response update is not specified here
for i in d:
   strategy[b[0][i]] = ...

Agents should be able to have different Taset

Since T ASET denotes the agent's perceived available safe egress time, i.e., the time to evacuate safely, it is a subjective measure. Thus, different agents could have different T ASET . This should be implemented somewhere in the code.

Agents Sensory Region

Some example senses agents could have

  • Field of vision. For example interactions should not affect through non-opaque obstacles.

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.