Skip to content

Rig support is broken: each shot in a riginstance overwrites the previous shot #1118

@dkogan

Description

@dkogan

Hello. I'm trying to run a solve with a fixed-geometry rig; this doesn't work, and I'm wondering if it has ever worked.

I'm on Debian GNU/Linux. I'm buliding the bleeding-edge git tree from source: 6322e7c

I run reconstruct --algorithm triangulation. Without rig definitions in the data directory (rig_cameras.json, rig_assignments.json) this runs ok. With those definitions present I see this:

2026-03-31 18:44:58,678 INFO: Starting triangulation reconstruction
2026-03-31 18:45:05,584 INFO: Triangulation SfM. Outer iteration 0, triangulated 17628 points.
2026-03-31 18:45:05,584 INFO: Triangulation SfM. Inner iteration 0, running bundle ...
2026-03-31 18:45:05,585 INFO: Shots and/or GCPs are well-conditioned. Using naive 3D-3D alignment.
Traceback (most recent call last):
  File ".../OpenSfM/bin/opensfm_main.py", line 34, in <module>
    main()  # pragma: no cover
    ~~~~^^
  File ".../OpenSfM/bin/opensfm_main.py", line 26, in main
    commands.command_runner(
    ~~~~~~~~~~~~~~~~~~~~~~~^
        commands.opensfm_commands,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
        create_default_dataset_context,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        dataset_choices=["opensfm"],
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File ".../OpenSfM/opensfm/commands/command_runner.py", line 46, in command_runner
    command.run(data, args)
    ~~~~~~~~~~~^^^^^^^^^^^^
  File ".../OpenSfM/opensfm/commands/command.py", line 16, in run
    self.run_impl(data, args)
    ~~~~~~~~~~~~~^^^^^^^^^^^^
  File ".../OpenSfM/opensfm/commands/reconstruct.py", line 16, in run_impl
    reconstruct.run_dataset(dataset, args.algorithm)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../OpenSfM/opensfm/actions/reconstruct.py", line 18, in run_dataset
    report, reconstructions = reconstruction.triangulation_reconstruction(
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        data, tracks_manager
        ^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File ".../OpenSfM/opensfm/reconstruction.py", line 1596, in triangulation_reconstruction
    b1rep = bundle(
        reconstruction, camera_priors, rig_camera_priors, None, config_override
    )
  File ".../OpenSfM/opensfm/reconstruction.py", line 77, in bundle
    report = pysfm.BAHelpers.bundle(
        reconstruction.map,
    ...<3 lines>...
        config,
    )
IndexError: map::at

Would be great to make this error message more friendly. In any case this happens because the

ba.AddPointProjectionObservation(shot.id_, lm_obs.first->id_, obs.point,
call tries to find a shot in the list:
o.shot = &shots_.at(shot);
and this shot isn't there.

It isn't there because when we loop through all our images, and add them to the relevant rig:

reconstruction.add_rig_instance(pymap.RigInstance(rig_instance_id))
we actually overwrite the existing images in the rig instance with each image that comes in:
return self.map.update_rig_instance(rig_instance)
. Note that we call create_rig_instance() and then unconditionally call update_rig_instance() to overwrite the rig instance we currently have with the brand-new empty one.

If I remove this update_rig_instance() then I get complete rig instances. There's another error here:

rotation = rotation_from_shot_metadata(shot)
because the shot.pose is immutable or something. If I make those errors soft, the reconstruction run completes. The rig constraint isn't obviously enforced (the reconstruction geometry doesn't do what I asked), but I'm no longer convinced that this has ever worked, so I don't want to continue to debug before hearing from yall first.

I don't want to send you my reproducing data (it is big!) but I suspect that defining any kind of rig with the included sample data would tickle this bug just fine. Let me know if that's useful.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions