code: def update(self, z, R2=None):
          
  
          if z is None:
              self.z = np.array([[None]*self.dim_z]).T
              self.x_post = self.x.copy()
              self._P1_2_post = np.copy(self._P1_2)
              return
  
          if R2 is None:
              R2 = self._R1_2
          elif np.isscalar(R2):
              R2 = eye(self.dim_z) * R2
  
          # rename for convienance
          dim_z = self.dim_z
          M = self.M
  
          M[0:dim_z, 0:dim_z] = R2.T
          M[dim_z:, 0:dim_z] = dot(self.H, self._P1_2).T
          M[dim_z:, dim_z:] = self._P1_2.T
  
          _, self.S = qr(M)
          self.K = self.S[0:dim_z, dim_z:].T
          N = self.S[0:dim_z, 0:dim_z].T
  
          # y = z - Hx
          # error (residual) between measurement and prediction
          self.y = z - dot(self.H, self.x)
  
          # x = x + Ky
          # predict new x with residual scaled by the kalman gain
          self.x += dot(self.K, pinv(N)).dot(self.y)
          self._P1_2 = self.S[dim_z:, dim_z:].T
  
          self.z = deepcopy(z)
          self.x_post = self.x.copy()
          self._P1_2_post = np.copy(self._P1_2)
docs: Add a new measurement (z) to the kalman filter. If z is None, nothing
          is changed.
  
          Parameters
          ----------
  
          z : np.array
              measurement for this update.
  
          R2 : np.array, scalar, or None
              Sqrt of meaaurement noize. Optionally provide to override the
              measurement noise for this one call, otherwise  self.R2 will
              be used.