//*************************************************************************
TEST (EssentialMatrixFactor3, extraTest) {

    // The "true E" in the body frame is
    EssentialMatrix bodyE = cRb.inverse() * trueE;

    for (size_t i = 0; i < 5; i++) {
        EssentialMatrixFactor3 factor(100, i, pA(i), pB(i), cRb, model2, K);

        // Check evaluation
        Point3 P1 = data.tracks[i].p;
        const Point2 pi = camera2.project(P1);
        Point2 reprojectionError(pi - pB(i));
        Vector expected = reprojectionError.vector();

        Matrix Hactual1, Hactual2;
        double d(baseline / P1.z());
        Vector actual = factor.evaluateError(bodyE, d, Hactual1, Hactual2);
        EXPECT(assert_equal(expected, actual, 1e-7));

        // Use numerical derivatives to calculate the expected Jacobian
        Matrix Hexpected1, Hexpected2;
        boost::function<Vector(const EssentialMatrix&, double)> f = boost::bind(
                    &EssentialMatrixFactor3::evaluateError, &factor, _1, _2, boost::none,
                    boost::none);
        Hexpected1 = numericalDerivative21<Vector2, EssentialMatrix, double>(f, bodyE, d);
        Hexpected2 = numericalDerivative22<Vector2, EssentialMatrix, double>(f, bodyE, d);

        // Verify the Jacobian is correct
        EXPECT(assert_equal(Hexpected1, Hactual1, 1e-6));
        EXPECT(assert_equal(Hexpected2, Hactual2, 1e-8));
    }
}
//*************************************************************************
TEST (EssentialMatrixFactor2, factor) {
    for (size_t i = 0; i < 5; i++) {
        EssentialMatrixFactor2 factor(100, i, pA(i), pB(i), model2);

        // Check evaluation
        Point3 P1 = data.tracks[i].p, P2 = data.cameras[1].pose().transform_to(P1);
        const Point2 pi = PinholeBase::Project(P2);
        Point2 reprojectionError(pi - pB(i));
        Vector expected = reprojectionError.vector();

        Matrix Hactual1, Hactual2;
        double d(baseline / P1.z());
        Vector actual = factor.evaluateError(trueE, d, Hactual1, Hactual2);
        EXPECT(assert_equal(expected, actual, 1e-7));

        // Use numerical derivatives to calculate the expected Jacobian
        Matrix Hexpected1, Hexpected2;
        boost::function<Vector(const EssentialMatrix&, double)> f = boost::bind(
                    &EssentialMatrixFactor2::evaluateError, &factor, _1, _2, boost::none,
                    boost::none);
        Hexpected1 = numericalDerivative21<Vector2, EssentialMatrix, double>(f, trueE, d);
        Hexpected2 = numericalDerivative22<Vector2, EssentialMatrix, double>(f, trueE, d);

        // Verify the Jacobian is correct
        EXPECT(assert_equal(Hexpected1, Hactual1, 1e-8));
        EXPECT(assert_equal(Hexpected2, Hactual2, 1e-8));
    }
}
Пример #3
0
::ceres::ResidualBlockId Estimator::addObservation(uint64_t landmarkId,
                                                   uint64_t poseId,
                                                   size_t camIdx,
                                                   size_t keypointIdx) {
  OKVIS_ASSERT_TRUE_DBG(Exception, isLandmarkAdded(landmarkId),
                        "landmark not added");

  // avoid double observations
  okvis::KeypointIdentifier kid(poseId, camIdx, keypointIdx);
  if (landmarksMap_.at(landmarkId).observations.find(kid)
      != landmarksMap_.at(landmarkId).observations.end()) {
    return NULL;
  }

  // get the keypoint measurement
  okvis::MultiFramePtr multiFramePtr = multiFramePtrMap_.at(poseId);
  Eigen::Vector2d measurement;
  multiFramePtr->getKeypoint(camIdx, keypointIdx, measurement);
  Eigen::Matrix2d information = Eigen::Matrix2d::Identity();
  double size = 1.0;
  multiFramePtr->getKeypointSize(camIdx, keypointIdx, size);
  information *= 64.0 / (size * size);

  // create error term
  std::shared_ptr < ceres::ReprojectionError
      < GEOMETRY_TYPE
          >> reprojectionError(
              new ceres::ReprojectionError<GEOMETRY_TYPE>(
                  multiFramePtr->template geometryAs<GEOMETRY_TYPE>(camIdx),
                  camIdx, measurement, information));

  ::ceres::ResidualBlockId retVal = mapPtr_->addResidualBlock(
      reprojectionError,
      cauchyLossFunctionPtr_ ? cauchyLossFunctionPtr_.get() : NULL,
      mapPtr_->parameterBlockPtr(poseId),
      mapPtr_->parameterBlockPtr(landmarkId),
      mapPtr_->parameterBlockPtr(
          statesMap_.at(poseId).sensors.at(SensorStates::Camera).at(camIdx).at(
              CameraSensorStates::T_SCi).id));

  // remember
  landmarksMap_.at(landmarkId).observations.insert(
      std::pair<okvis::KeypointIdentifier, uint64_t>(
          kid, reinterpret_cast<uint64_t>(retVal)));

  return retVal;
}