Changelog¶
Version 2.1.0¶
API-breaking changes
FlyGym 2.1.0 drops the dm-control PyMJCF backend in favour of MuJoCo's native MjSpec API
(#282, #285).
Model elements (cameras, materials, bodies, joints, …) are now mujoco._specs.Mjs* objects rather than dm_control.mjcf wrappers. The following changes may require updates:
-
element.full_identifier→element.name: PyMJCF exposedfull_identifierto return the fully-scoped compiled name (e.g."fly/trackcam"). MjSpec mutates.namein place when a child spec is attached with a prefix, so.namealready returns the prefixed name afterworld.add_fly(). Replace every occurrence of.full_identifierwith.name.Migration: If you stored references to spec elements (e.g. the
MjsCamerareturned byfly.add_tracking_camera()) and later usedelement.full_identifieras a dict key or to look up the compiled ID, replace it withelement.name:# Before (PyMJCF) cam = fly.add_tracking_camera(name="body_cam") world.add_fly(fly, ...) frames = renderer.frames[cam.full_identifier] # AttributeError under MjSpec # After (MjSpec) cam = fly.add_tracking_camera(name="body_cam") world.add_fly(fly, ...) frames = renderer.frames[cam.name] # "fly_name/body_cam" after attachmentNo other change is needed:
cam.namealready returns the same prefixed string thatcam.full_identifierused to return, because MjSpec mutates held element references in place when the child spec is attached. -
spec.asset.find_all("material")→spec.materials: The PyMJCF tree-traversal helper is gone. MjSpec exposes typed collection properties (spec.materials,spec.bodies,spec.joints, etc.) directly on theMjSpecobject. -
add_tracking_cameraplacement is now relative to the fly's root segment:Fly.add_tracking_camera()now adds the camera inside the fly's root segment (thorax) body so that MuJoCo'strackmode actually follows the fly as it moves. As a result,pos_offset(androtation) are interpreted in the root segment's body frame rather than in world coordinates as before, and the defaultpos_offsetchanged from(0, -7.5, 6)to(-0.5, -7.5, 5). The samepos_offsetnow yields the same camera position relative to the fly in every context (FlatGroundWorld,TetheredWorld, or a fly compiled on its own forpreview_model).Migration: Any hard-coded
pos_offsetvalues must be re-tuned. A value that previously positioned the camera in the world frame now positions it relative to the root segment, which in the neutral pose sits roughly(0.5, 0, 1.3)mm from the fly's attachment point plus the spawn height. The camera will therefore appear higher and shifted toward the head unless you adjust the offset (to reproduce the old framing, subtract the root segment's rest position from your previous world-frame offset). -
World.world_dof_neutral_statesis now aset, not adict: Under MjSpec, the neutral pose of world-level DoFs (e.g. the free joints by which flies are attached) is read from the compiled model'sqpos0rest configuration. The explicit per-DoF state values thatWorld.world_dof_neutral_statesused to map to are therefore no longer needed, so the attribute is now aset[str]of DoF (joint) names rather than adict[str, list[float]]. Relatedly,World._attach_fly_mjcfnow returns aset[str]of the DoF names it created instead of a name → state mapping.Migration: If you read this attribute, iterate it as a set of names (iterating a
dictalready yielded its keys, so plainfor name in world.world_dof_neutral_statesis unaffected); subscripting it (world.world_dof_neutral_states[name]) no longer works. If you implement a customWorldsubclass, return aset[str]from_attach_fly_mjcf.
Additions¶
- [Experimental feature] Integrated FlyMimic (Özdil et al., 2026): an imitation-learning task and a muscle-actuated musculoskeletal fly model (#270). A tutorial is also added.
- [Experimental feature] Integrated the FlyBody model (#272). Two tutorials are also added.
- Added an in-browser interactive viewer using WebAssembly (#273).
- Moved the NeuroMechFly Live game into FlyGym and reimplemented it to run in-browser using WebAssembly (#277, #278).
- Added standalone kinematic-replay scripts for end-to-end testing and profiling (#283). A tutorial on profiling is also added.
- Added Docker installation instructions.
- Tutorial are now runnable in Google Colab (#284).
- Bumped MuJoCo and MuJoCo Warp versions to 3.9 (#281, #291).
- FlyGym now supports Python 3.12 – 3.14.
- Moved large asset files to an S3 bucket and made FlyGym download them lazily (#280, #292).
- Added unit tests that execute the tutorial notebooks and check for errors (#286).
Bug fixes¶
- Fixed geom fitting that forced claw (tarsus5) geoms to capsules even when
UNMODIFIED(#274). - Fixed packaging so the
flygympackage's bundled assets (simplified meshes, poses, configs, and the musculoskeletal MJCF) are reliably shipped in the built wheel/sdist. They are now declared explicitly under[tool.setuptools.package-data]rather than relying oninclude-package-data, which silently included nothing on a clean build (no MANIFEST.in / setuptools-scm).
Housekeeping¶
- Switch from MkDocs to ProperDocs, a fork of MkDocs 1.x.x that will continue to support for plugins like Material for MkDocs (see this note).
- Added packaging tests (
tests/core/test_packaging.py) that build a wheel and assert every bundled asset is shipped (large lazily-downloaded meshes excluded), withflygym_demoassets checked separately.
Version 2.0.2¶
API-breaking changes
- Adhesion control range:
Fly.add_leg_adhesion()andSimulation.set_leg_adhesion_states()now use a normalised[0, 1]control range (0 = fully released, 1 = full gain) instead of the previous[1, 100]range. Boolean0/1adhesion commands that previously fell outside the valid range will now work as expected. get_ground_contact_info()first return value: renamed fromcontact_activetocontact_foundand now returns the raw MuJoCo contact-sensorfoundchannel (a floating-point value) rather than a booleanized flag. Code that comparedcontact_active == 1should now checkcontact_found > 0.ContactParams.get_solimp_tuple(): now returns a 5-element tuple (was 4). The previously missingsolver_impedance_min2max_widthfield is now included as the third element ([dmin, dmax, width, midpoint, power]), matching MuJoCo'ssolimpspecification. Any code that destructured or indexed the old 4-tuple needs to be updated.
Bug fixes¶
ContactParams.get_solimp_tuple()previously returned a 4-element tuple, causing MuJoCo to silently use a default value for the transition-width parameter. It now returns the correct 5-element tuple.
Additions¶
- Added vision to CPU-based simulation. Addition of vision to GPU-based simulation will be deferred for now.
- Added
GappedTerrainWorld,BlocksTerrainWorld, andMixedTerrainWorldtoflygym.compose. - Added
Simulation.get_bodysegment_contact_forces()for querying ground-contact forces on arbitrary body segments. - Added locomotion controller examples (
CPGController,RuleBasedController,HybridController,HybridTurningController) inflygym_demo.complex_terrain. Added tutorials accordingly.
Housekeeping¶
- Switched formatter from Black to Ruff
Version 2.0.1 (2026–04–16)¶
Bug fixes¶
- Include sample Spotlight data in shipped
flygym_demobuild (#259). - Fix dimension check for 3D rotations specified in
axisangleformat. - Fix bugs with creating
AnatomicalJointandJointDOFobjects from strings.
Additions¶
- New API to add sites to fly model and read out their positions
- Additional tutorial: 1bis. Advanced model composition
Housekeeping¶
- Add changelog and correct info in LICENSE
Contributors¶
@sibocw, @djsamseng
Version 2.0.0 (2026–04–02)¶
Full rewrite — not backward-compatible
This version is a full rewrite of the codebase and it is not backward-compatible. See this page for more info.
Version 1.2.1¶
- Improve vision readout computing time by avoiding redundant memory copies
- Bump NumPy version to 2.* and end official support for macOS 13
Version 1.2.0¶
API-breaking changes
- Enhance camera logic. See the Camera API reference for details.
- Use the FlyVis package as published on PyPI. Users should now use
flyvisinstead offlyvisionas module name.
Other changes¶
- Add NeuroMechFly game for outreach (used at EPFL Scientastic! Days, etc.).
- Transition from
setup.pytopyproject.toml, specifically using Poetry as the build backend. Users can now install FlyGym with the exact versions of dependencies used by the developers by runningpoetry installfrom the root directory. This will create a virtual environment with the correct dependencies as specified in the includedpoetry.lockfile, which is version-tracked as a part of the FlyGym Github repository. - Add VS Code devcontainer support.
- Remove support for Python 3.9.
Version 1.1.0¶
- Added cardinal direction sensing (vectors describing +x, +y, +z of the fly) to the observation space.
- Removed legacy spawn orientation preprocessing: Previously, pi/2 was subtracted from the user-specified spawn orientation on the x-y plane. This was to make the behavior consistent with a legacy version of NeuroMechFly. This behavior is no longer desired; from this version onwards, the spawn orientation is used as is.
- Strictly fixed the required MuJoCo version to 3.2.3, and dm_control version to 1.0.23. This is to prevent API-breaking changes in future versions of these libraries from affecting FlyGym. FlyGym maintainers will periodically check for compatibility with newer versions of these libraries.
- Changed flip detection method: Previously, flips are reported when all legs reliably lose contact with the ground. Now, we simply check if the z component of the "up" cardinal vector is negative. Additionally, the
detect_flipparameter ofFlyis now deprecated; flips are always detect and reported. - Allowed different sets of DoFs to be monitored vs. actuated. Previously, the two sets are always the same.
- From this version onwards, we will use EffVer as the versioning policy. The version number will communicate how much effort we expect a user will need to spend to adopt the new version. While we previously tried to adhere to the stricter SemVer, we found that it was not effective because many core dependencies of FlyGym (e.g., MuJoCo, NumPy, and Python itself) do not use SemVer.
Version 1.0.1¶
Fixed minor bugs related to the set of DoFs in the predefined poses, and to rendering at extremely high frequencies. Fixed outdated class names and links in the docs. In addition, contact sensor placements used by the hybrid turning controller are now added to the preprogrammed module.
Version 1.0.0¶
In spring 2024, NeuroMechFly was used, for the second time, in a course titled Controlling behavior in animals and robots at EPFL. At the same time, we revised the NeuroMechFly v2 manuscript. In these processes, we significantly improved the FlyGym package, added new functionalities, and incorporated changes as we received feedback from the students. These enhancements are released as FlyGym version 1.0.0. This release is not backward compatible; please refer to the tutorials and API references for more information. The main changes are:
Major API changes
- The
NeuroMechFlyclass is split intoFly, a class that represents the fly, andSimulation, a class that represents the simulation, which can potentially contain multiple flies. - The
Parametersclass is deprecated. Parameters related to the fly (such as joint parameters, actuated DoFs, etc.) should be set directly on theFlyobject. Parameters related to the simulation (such as the time step, the render cameras, etc.) should be set directly on theSimulationobject. - A new
Cameraclass is introduced. A simulation can contain multiple cameras.
New examples¶
See examples:
- Path integration based on ascending mechanosensory feedback.
- Head stabilization based on ascending mechanosensory feedback.
- Navigating a complex plume, simulated separately in a fluid mechanics simulator.
- Following another fly using a realistic, connectome-constrained neural network that processes visual inputs.
Version 0.2.5¶
Modify model file to make it compatible with MuJoCo 3.1.1. Disable Python 3.7 support accordingly.
Version 0.2.4¶
Set MuJoCo version to 2.3.7. Documentation updates.
Version 0.2.3¶
Various bug fixes. Improved placement of the spherical treadmill in the tethered environment.
Version 0.2.2¶
Changed default joint kp and adhesion forces to those used in the controller comparison task. Various minor bug fixes. Documentation updates.
Version 0.2.1¶
Simplified class names: NeuroMechFlyMuJoCo → NeuroMechFly, MuJoCoParameters → Parameters. Minor documentation updates.
Version 0.2.0¶
The current base version — major API change from 0.1.x.
Version 0.1.x¶
Versions used during the initial development of NeuroMechFly v2.
Unversioned¶
Versions used for the Spring 2023 offering of BIOENG-456 Controlling Behavior in Animals and Robots course at EPFL.