Add pose_test tool and harden solvePose; expose camera controls

- pose_test: verify the geometry chain (4 corners -> distance/yaw/pitch)
  before any detector exists; modes: camera + mouse clicks, --image,
  --corners (headless), --selftest (synthetic round-trip, no camera needed)
- solvePose: undistort corners first, then solvePnPGeneric(IPPE) and pick
  the best candidate; reject solutions behind the camera (z<=0) or with
  reprojection error > 8px
  - fixes IPPE + distortion + in-plane rotation returning garbage
  - 4 coplanar points: cyclic/mirrored orderings give the same quad and
    the same pose (harmless); crossing orderings blow up reprojection
    and are rejected
- camera_set: implement setAeState/setExposureTime/setAnalogGain(+-Times)/
  setWbMode/setFrameSpeed; configs/camera_runtime.yaml drives them
- selftest passes all 6 synthetic cases; verified on 6 real photos
  (chessboard outer rect 180x120mm): distance 0.44-0.69m, reproj <2.5px
This commit is contained in:
2026-09-16 21:08:03 +08:00
parent c50be9a48d
commit 19ac43da6f
8 changed files with 724 additions and 30 deletions
+5 -3
View File
@@ -72,10 +72,12 @@ public:
/**
* 四个角点 → 装甲板位姿
* @param corners 图像坐标,顺序必须是:左下、左上、右上、右下
* (与 jlu_vision 的 ArmorPoints.hpp 3D 点顺序一致)
* 内部流程:solvePnPGeneric(IPPE) 取回全部候选解 →
* 依次筛掉「z<=0(相机后方)」「重投影超差」→ 取重投影最小者。
* 注:角点在解算前先做去畸变(IPPE+畸变+板内旋转组合有数值坑)。
* @param corners 图像坐标(原图,含畸变),顺序:左下、左上、右上、右下
* @param size 装甲板物理尺寸
* @return 成功返回位姿;无解或重投影误差过大返回 std::nullopt
* @return 成功返回位姿;全部候选被筛掉时返回 std::nullopt
*/
std::optional<ArmorPose> solvePose(const std::array<cv::Point2f, 4> &corners,
const ArmorSize &size) const;