The Camera class defines how images should be rendered from a camera in the world model. Note that the Camera class does not by itself add a camera to the MuJoCo model — the camera must have already existed and can be referenced by its name. The camera can be added in two ways:

  1. By adding a camera to the MuJoCo model file. Refer to the section on camera in the MuJoCo XML reference for more information. As an example, the following XML code adds a tracking camera to the MuJoCo model:

    <!-- ... other things ... -->
    <camera name="camera_top" class="nmf" mode="track" ipd="0.068" pos="0 0 8" euler="0 0 0"/>
  1. By calling .worldbody.add() on the root element of the MuJoCo model programmatically in Python. Practically, this can be done by extending an existing FlyGym Arena class and adding the camera in the __init__ method. For example, the following code adds a stationary bird’s eye camera to the MuJoCo model:

from flygym.arena import BaseArena

class MyArena(BaseArena):
    def __init__(self):
        self.birdeye_cam = self.root_element.worldbody.add(
            pos=(20, 0, 20),
            euler=(0, 0, 0),
        # ... other things ...

Once the camera is added to the MuJoCo model, it can be referenced by its name to initialize the Camera object with additional parameters assigned to it. These can include: rendering rate in frames-per-second (FPS), window size, play speed, etc. Furthermore, the Camera class has useful methods such as .save_video, .reset, etc. Logics such as rotating the camera in tilted terrain are also implemented in the Camera class. The .render method is the main point of entry for fetching images from the camera.

The full API reference of the Camera class is as follows:

class Fly, camera_id: str = 'Animat/camera_left', window_size: Tuple[int, int] = (640, 480), play_speed: float = 0.2, fps: int = 30, timestamp_text: bool = False, play_speed_text: bool = True, draw_contacts: bool = False, decompose_contacts: bool = True, force_arrow_scaling: float = float('nan'), tip_length: float = 10.0, contact_threshold: float = 0.1, draw_gravity: bool = False, gravity_arrow_scaling: float = 1e-4, align_camera_with_gravity: bool = False, camera_follows_fly_orientation: bool = False, decompose_colors: Tuple[Tuple[int, int, int], Tuple[int, int, int], Tuple[int, int, int]] = ((255, 0, 0), (0, 255, 0), (0, 0, 255)), output_path: str | Path | None = None, perspective_arrow_length=False)

Bases: object

Camera associated with a fly.


The fly to which the camera is associated.

window_sizeTuple[int, int]

Size of the rendered images in pixels.


Play speed of the rendered video.

fps: int

FPS of the rendered video when played at play_speed.


If True, text indicating the current simulation time will be added to the rendered video.


If True, text indicating the play speed will be added to the rendered video.


The dm_control camera instance associated with the camera. Only available after calling initialize_dm_camera(physics). Useful for mapping the rendered location to the physical location in the simulation.


If True, arrows will be drawn to indicate contact forces between the legs and the ground.


If True, the arrows visualizing contact forces will be decomposed into x-y-z components.


Scaling factor determining the length of arrows visualizing contact forces.


Size of the arrows indicating the contact forces in pixels.


The threshold for contact detection in mN (forces below this magnitude will be ignored).


If True, an arrow will be drawn indicating the direction of gravity. This is useful during climbing simulations.


Scaling factor determining the size of the arrow indicating gravity.


If True, the camera will be rotated such that gravity points down. This is useful during climbing simulations.


If True, the camera will be rotated so that it aligns with the fly’s orientation.


Colors for the x, y, and z components of the contact force arrows.

output_pathOptional[Union[str, Path]]

Path to which the rendered video should be saved. If None, the video will not be saved.

dm_camera: dm_control.mujoco.Camera
initialize_dm_camera(physics: dm_control.mjcf.Physics)

dm_control comes with its own camera class that contains a number of useful utilities, including in particular tools for mapping the rendered location (row-column coordinate on the rendered image) to the physical location in the simulation. Given the physics instance of the simulation, this method initializes a “shadow” dm_control camera instance.


Physics instance of the simulation.

render(physics: dm_control.mjcf.Physics, floor_height: float, curr_time: float) ndarray | None

Call the render method to update the renderer. It should be called every iteration; the method will decide by itself whether action is required.


The rendered image is one is rendered.

save_video(path: str | Path, stabilization_time=0.02)

Save rendered video since the beginning or the last reset(), whichever is the latest. Only useful if render_mode is ‘saved’.

pathstr or Path

Path to which the video should be saved.

stabilization_timefloat, optional

Time (in seconds) to wait before starting to render the video. This might be wanted because it takes a few frames for the position controller to move the joints to the specified angles from the default, all-stretched position. By default 0.02s

set_gravity(gravity: ndarray, rot_mat: ndarray = None) None

Set the gravity of the environment. Changing the gravity vector might be useful during climbing simulations. The change in the camera point of view has been extensively tested for the simple cameras (left right top bottom front back) but not for the composed ones.


The gravity vector.

rot_matnp.ndarray, optional
The rotation matrix to align the camera with the gravity vector

by default None.