Open-source project
baijiuyang/collision-avoidance2 avatar
baijiuyang/collision-avoidance2

Fitting a pedestrian avoidance model is a command line, and the data is not in the repo

This repo is created to serve simulaion and analysis on the data collected in Jiuyang Bai's dissertation research.

1,521 stars119 forksJupyter NotebookLicense varies

At a glance

What is it?
Bai movObst2 is a computational modelling package for pedestrian moving-obstacle avoidance, built around ODE simulation and parameter fitting with SciPy optimizers. It is a dissertation reproduction repository: the code, the notebooks and the fitting script are here, while the experiment data has to be supplied by you.
Who is it for?
Adopt this package if you want to reproduce or extend the Bai movObst2 pedestrian avoidance analysis and you have the raw experiment data, since the model definitions, the fitting script and the notebooks are all present. Skip it if you need a general pedestrian simulation library or a turnkey dataset, because the pickles are produced locally from data you provide.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 128 days ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • baijiuyang/collision-avoidance21,521 ★ · -11
Star history
Repository2026-10-162026-11-07
baijiuyang/collision-avoidance21.5k1.5k

-11 Stars in the last 22 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

This is a dissertation package, not a general simulator

The repository description is direct: it was created to serve simulation and analysis on data collected in Jiuyang Bai's dissertation research. That framing explains the whole structure.

It is a computational modelling framework for pedestrian moving-obstacle avoidance behaviour in the Bai movObst2 experiment, described as based on dynamical systems approaches, specifically Fajen-style steering and Cohen-style avoidance. Those are two named theoretical traditions, and the code is organised around them rather than around a general-purpose pedestrian model.

The scope is narrow on purpose. The README says the repository implements modelling and analysis specifically for the movObst2 experiments, movObst2a and movObst2b. You are not getting a library for crowd simulation in general, and nothing in the design suggests the models transfer to a different experimental paradigm without rewriting them.

The repository root makes the history visible: there is a `Bai_movObst1/` directory alongside `Bai_movObst2/`, an `Untitled.ipynb` at the top level, and a `requirements.txt`. The README documents the movObst2 directory in detail and says nothing about movObst1, so a reader arriving now gets detailed documentation for one half of the repository and a directory listing for the other.

Everything is Python and Jupyter. The primary language is recorded as Jupyter Notebook, which fits a project where the notebooks are the interface rather than a side artifact.

Approach and avoidance are separate, swappable models

The model inventory is the core design decision, and it splits the dynamics into two halves that are fitted separately and then combined.

The approach models describe goal-directed steering, the motion a pedestrian would make with nothing in the way. Four are listed: `fajen_approach`, `fajen_approach2`, `acceleration_approach` and `jerk_approach`. The progression is from a positional formulation to acceleration and then jerk, which is a common way of making a steering model differentiable enough to fit.

The avoidance models describe obstacle evasion, and there are more of them: `cohen_avoid`, `cohen_avoid2`, `cohen_avoid3`, `cohen_avoid4`, `perpendicular_avoid`, `cohen_avoid_heading` and `cohen_avoid4_heading`. The numbered Cohen variants are successive revisions of the same formulation, and the two heading variants apply an additional constraint to the avoidant's heading.

Separating them has a practical payoff visible in the fitting interface. There is a `--approach_experiment` argument, distinct from `--experiment_name`, which selects the experiment whose data supplies the approach model parameters. A researcher can fit approach behaviour from one condition and avoidance behaviour from another, then combine them.

The ODE simulation sits on top of both: it integrates the combined approach plus avoidance dynamics to produce trajectories, driven by `packages/ode_simulator.py` with the model definitions in `packages/models.py`.

Installation ends with an empty data directory

Setup is conventional Python, and it is worth doing in order because the last step has no equivalent step to copy.

Python 3.8 or newer is required, with NumPy, SciPy, scikit-learn and Matplotlib as the dependency set. The requirements file gives the floors: numpy>=1.19.0, scipy>=1.5.0, scikit-learn>=0.23.0 and matplotlib>=3.3.0.

A virtual environment is recommended, and the README gives both activation forms:

bash
python -m venv venv
# Linux/macOS
source venv/bin/activate

On Windows the same command is followed by `venv\Scripts\activate` instead.

Then the dependencies:

bash
pip install -r requirements.txt

Or installed by hand with `pip install numpy scipy scikit-learn matplotlib`, which is the same set.

Step four is the one with no instructions attached, and it is where a new user stalls. Raw experiment data has to be placed under `Raw_Data/` relative to the project, and the notebooks and scripts expect pickle files with specific names, such as `Bai_movObst2_data_30Hz.pickle` and `Cohen_movObst2_data.pickle`.

Those pickles are not in the repository. They are produced by the import notebooks, which convert raw CSV or experiment output into `Data` objects and save them. So the order is: obtain the raw data, run an import notebook, then run the fitting or simulation notebooks.

The fitting script exposes its whole interface on the command line

`Bai_movObst2/fitting.py` is the tool you will actually run, and its arguments are documented in a table.

A full fit invocation reads like a specification of the analysis:

bash
python Bai_movObst2/fitting.py --experiment_name Bai_movObst2 \
  --approach_experiment Bai_movObst2 \
  --subject all \
  --t_start obst_onset \
  --t_end obst_out \
  --ps trial \
  --method differential_evolution \
  --approach_model fajen_approach2 \
  --avoid_model cohen_avoid4 \
  --training_model cohen_avoid4

`--experiment_name` names the dataset, `--approach_experiment` picks the experiment supplying approach parameters, and `--subject` takes a subject ID, the literal `all`, or a negative index. `--t_start` and `--t_end` define the analysis window using event names rather than seconds, with `obst_onset` and `obst_out` named as examples and `dtheta*dpsi_onset` showing that derived event markers are also valid. `--ps` is a parallelisation key, with `trial` given as the example.

The negative subject index is the detail worth understanding. Negative indices exclude a subject, so `--subject -0` leaves subject 0 out, which is how leave-one-subject-out cross-validation is expressed on the command line without a separate mode. The batch file `start_fitting_cross_validation.bat` runs multiple subjects in parallel, and `start_fitting_individual.bat` is the per-subject counterpart.

`--training_model` says which model is being fitted and accepts either an approach or an avoidance model, which is what lets the same script fit either half of the dynamics.

Five optimizers, and cross-validation is a batch file

The `--method` argument accepts five choices from SciPy's global optimisation and local optimisation families: `differential_evolution`, `dual_annealing`, `nelder-mead`, `shgo` and `basinhopping`.

That list maps onto different problems. Differential evolution and dual annealing are global methods, suitable when the parameter landscape has multiple basins, which is the normal situation when fitting behaviour models to noisy human trajectories. Nelder-Mead is a local simplex method, faster per evaluation and appropriate once parameters are near a known optimum. SHGO is a simplicial homology-based global method, and basin hopping combines local search with random perturbation.

The README's own example uses `differential_evolution`, which tells you what the author reaches for by default.

Fitted values and their bounds live in `parameters.py`, described as trained model parameters and bounds. That separation is sensible for this kind of work, since it means the same parameter set is reused by the simulation notebook rather than being refitted every time a trajectory is plotted.

The remaining pieces complete the loop. `helper.py` handles geometry, plotting and utilities. `data_container.py` holds the `Data` class that manages trial metadata, trajectories and derived quantities. The simulation notebook loads data with `load_data('Bai_movObst2_data')`, runs simulations with `ODESimulator` and fitted models from `parameters.py`, and visualises with `sim.play()`. The analysis notebook runs statistics, model comparisons, MDS and plots.

The VR scripts depend on commercial software

Two files in the directory are not analysis code at all, and they carry the project's hardest dependency.

`movObst2a.py` and `movObst2b.py` are the virtual reality experiment scripts used for data collection, and the README states they require WorldViz Vizard. These scripts therefore require WorldViz Vizard to be available.

`vizconnect_config.py` holds the Vizard connection configuration, which is the file where you would point the scripts at your own Vizard instance. `movObst2_inputGenerator.py` sits alongside them for generating experiment input.

The practical consequence is that the data collection path and the analysis path have completely different requirements. You can clone this repository on a laptop, install four Python packages and reproduce the analysis from pickles without ever touching Vizard. You cannot collect new data on that laptop.

The contributing section acknowledges the split as a separate area, listing VR experiments as fixes or extensions for `movObst2a` and `movObst2b` and marking them Vizard-specific. That is the one place in the documentation where an external commercial dependency is named, and it is worth remembering before planning to extend the experiment rather than the model.

No licence, no releases, no data

Three absences are worth stating plainly, because each affects what you can do with this.

There is no licence. The README badge points at a LICENSE file in the repository root, and the repository listing does not show one at the top level alongside README.md and requirements.txt. The recorded licence for the project is unknown. If you want to reuse the model code in your own work, that is a question to ask the author rather than one you can answer from the repository.

There are no GitHub releases. The branch you clone is the state of the work.

And there is no data. The pickles the scripts expect are produced locally from raw experiment output, and the raw output itself is not distributed here. Anyone reproducing this analysis needs the original experiment data from the dissertation work.

Activity is modest. The last push was on 2026-07-03.

What the repository does offer is unusually clear documentation for a research codebase: a project structure tree with a one-line comment per file, an argument table, named event markers for the time window, and a contribution guide that names specific files for each kind of contribution. For a package built to be read as much as run, that is the right trade.

Editorial conclusion

Adopt this package if you want to reproduce or extend the Bai movObst2 pedestrian avoidance analysis and you have the raw experiment data, since the model definitions, the fitting script and the notebooks are all present. Skip it if you need a general pedestrian simulation library or a turnkey dataset, because the pickles are produced locally from data you provide. Verify first that your raw files sit under `Raw_Data/` and that `python Bai_movObst2/fitting.py` runs on your platform before planning a fit, and note the repository records no licence.

Frequently asked questions

How do I install and run this pedestrian avoidance modeling package?

Use Python 3.8 or newer, create a virtual environment, and run `pip install -r requirements.txt`, which installs NumPy, SciPy, scikit-learn and Matplotlib. Then place your raw experiment data under `Raw_Data/` and run an import notebook to produce the pickle files the analysis expects.

How do I run leave-one-subject-out cross-validation?

Use negative subject indices to exclude them, for example `--subject -0` excludes subject 0. The batch file `start_fitting_cross_validation.bat` runs multiple subjects in parallel, while `start_fitting_individual.bat` handles a single subject.

Which optimization methods can I use when fitting the models?

The `--method` argument accepts `differential_evolution`, `dual_annealing`, `nelder-mead`, `shgo` and `basinhopping`. The README's own example uses differential evolution.

Official sources

  1. baijiuyang/collision-avoidance2 on GitHub
  2. Issues
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/baijiuyang-collision-avoidance2.svg)](https://hysenlabs.com/projects/baijiuyang-collision-avoidance2)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/baijiuyang-collision-avoidance2.svg)](https://hysenlabs.com/projects/baijiuyang-collision-avoidance2)

Was this useful?