Use normalized pixels in cPNP problem formulation (#1816)

## Description

instead of using camera calibration, the CasADi problem formulation now
expect the caller to provide "normalized pixel coordinates". This
reduces the number of floating point operations we need to perform (and
reduces total LOC by 6%). `casadi_wrapper.cpp` now converts from (u, v)
coordinates to normalized (x'', y'') coordinates with:

x'' = (u - c_x) / f_x
y'' = (u - c_y) / f_y

Which is the inverse of this (from [opencv
docs](https://docs.opencv.org/4.x/d9/d0c/group__calib3d.html), and
assuming no distortion):

![image](https://github.com/user-attachments/assets/41ca657d-af42-4cdf-9c25-6a4f04d20940)

In my testing, this is ~16% faster on my x86 laptop. Would love some rio
benchmarks.

## Meta

Merge checklist:
- [x] Pull Request title is [short, imperative
summary](https://cbea.ms/git-commit/) of proposed changes
- [x] The description documents the _what_ and _why_
- [~] If this PR changes behavior or adds a feature, user documentation
is updated
- [~] If this PR touches photon-serde, all messages have been
regenerated and hashes have not changed unexpectedly
- [~] If this PR touches configuration, this is backwards compatible
with settings back to v2024.3.1
- [~] If this PR addresses a bug, a regression test for it is added
This commit is contained in:
Matt Morley
2025-03-18 21:34:56 -07:00
committed by GitHub
parent 8d4024b8c8
commit abbf3f2820
43 changed files with 257912 additions and 270947 deletions

View File

@@ -162,7 +162,7 @@ void print_cost(casadi_real robot_x, casadi_real robot_y,
Eigen::Vector3d x_guess;
x_guess << robot_x, robot_y, robot_theta;
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 200; i++) {
auto start = wpi::Now();
auto x_out = constrained_solvepnp::do_optimization(
true, TAG_COUNT,
@@ -170,13 +170,18 @@ void print_cost(casadi_real robot_x, casadi_real robot_y,
x_guess, field2points, point_observations, 0, 0);
auto end = wpi::Now();
std::cout << "iter "
<< i
// << "\nGuess:\n" << x_guess << "\n Optimized ->\n"
// << std::endl <<
// x_out.value_or(constrained_solvepnp::RobotStateMat::Zero())
<< "\nSucceeded? " << static_cast<bool>(x_out) << "\nIn "
<< (end - start) << "uS" << std::endl;
std::cout << i << "," << static_cast<bool>(x_out) << "," << end - start
<< std::endl;
std::cout << "Solution:"
<< x_out.value_or(constrained_solvepnp::RobotStateMat::Identity())
<< std::endl;
// std::cout << "iter "
// << i
// // << "\nGuess:\n" << x_guess << "\n Optimized ->\n"
// // << std::endl <<
// // x_out.value_or(constrained_solvepnp::RobotStateMat::Zero())
// << " - Succeeded? " << static_cast<bool>(x_out) << " - In "
// << (end - start) << "uS" << std::endl;
}
}