     addBetweenFactor: @escaping (
       _ variables1: FrameVariables.Indices, _ variables2: FrameVariables.Indices,
       _ graph: inout FactorGraph
-    ) -> ()
+    ) -> (),
+    addFixedBetweenFactor: ((
+      _ values: FrameVariables, _ variables: FrameVariables.Indices,
+      _ graph: inout FactorGraph
+    ) -> ())? = nil
   ) {
+    precondition(
+      addFixedBetweenFactor != nil,
+      "I added a runtime check for this argument so that I would not have to change all " +
+        "callers before compiling. It is actually required."
+    )
+
     self.frames = frames
     self.variableTemplate = variableTemplate
     self.frameVariableIDs = frameVariableIDs
     self.addPriorFactor = addPriorFactor
     self.addTrackingFactor = addTrackingFactor
     self.addBetweenFactor = addBetweenFactor
+    self.addFixedBetweenFactor = addFixedBetweenFactor!
 
     self.optimizer.precision = 1e-1
     self.optimizer.max_iteration = 100

      // Set the initial guess of the `i+1`-th variable to the value of the previous variable.
      x[frameVariableIDs[i + 1]] = x[frameVariableIDs[i], as: FrameVariables.self]

      // Create a tracking factor graph on just the `i`-tha dn `i+1`-th variables
      var g = graph(on: i..<(i + 2))

      // The `i`-th variable is already initialized well, so add a prior factor that it stays
      // near its current position.
      addPriorFactor(frameVariableIDs[i], x[frameVariableIDs[i]], &g)

      let currentVarID = (frameVariableIDs[i + 1] as! Tuple1<TypedID<Pose2>>).head
      let initialPose = x[currentVarID]
      var bestPose = x[currentVarID]
      var bestError = g.error(at: x)
      for _ in 0..<1000 {
        let noise = Tensor<Double>(randomNormal: [3]).scalars
        let candidatePose = initialPose.retract(Vector3(
          0.3 * noise[0],
          8 * noise[1],
          4.6 * noise[2]))
        x[currentVarID] = candidatePose
        let candidateError = g.error(at: x)
        if candidateError < bestError {
          bestError = candidateError
          bestPose = candidatePose
        }
      }
      x[currentVarID] = bestPose

      // Optimize the factor graph.
      try? optimizer.optimize(graph: g, initial: &x)
    }

    // We could also do a final optimization on all the variables jointly here.

  /// Adds to `graph` between factor(s) between the variables at `variables1` and the variables at `variables2`.
  public let addBetweenFactor: (
    _ variables1: FrameVariables.Indices, _ variables2: FrameVariables.Indices,
    _ graph: inout FactorGraph
  ) -> ()

  /// Adds to `graph` "between factor(s)" between `constantVariables` and `variables` that treat
  /// the `constantVariables` as fixed.
  ///
  /// This is used during frame-by-frame initialization to constrain frame `i + 1` by a between
  /// factor on the value from frame `i` without optimizing the value of frame `i`.
  public let addFixedBetweenFactor: (
    _ values: FrameVariables, _ variables: FrameVariables.Indices,
    _ graph: inout FactorGraph
  ) -> ()

