# HandEyeCalib `HandEyeCalib` 提供手眼标定、TCP 标定,以及基于标定结果的点位/姿态转换能力。 当前模块由两部分组成: - `IHandEyeCalib` 面向应用和工具的标定算法接口。 - `Utils/CoordinateTransform` 面向业务侧的坐标变换工具函数。 ## 当前保留的公开能力 ### IHandEyeCalib ```cpp virtual int CalculateRT( const std::vector& eyePoints, const std::vector& robotPoints, HECCalibResult& result) = 0; virtual int CalculateRT( const std::vector& pointPairs, HECCalibResult& result) = 0; virtual void TransformPoint( const HECRotationMatrix& R, const HECTranslationVector& T, const HECPoint3D& srcPoint, HECPoint3D& dstPoint) = 0; virtual void RotatePoint( const HECRotationMatrix& R, const HECPoint3D& srcPoint, HECPoint3D& dstPoint) = 0; virtual void RotationMatrixToEuler( const HECRotationMatrix& R, HECEulerOrder order, HECEulerAngles& angles) = 0; virtual void EulerToRotationMatrix( const HECEulerAngles& angles, HECEulerOrder order, HECRotationMatrix& R) = 0; virtual bool TransformPose( const HECCalibResult& calibResult, const HECPoint3D& eyeCenter, const HECPoint3D& longAxisDir, const HECPoint3D& normalDir, int dirVectorInvert, HECEulerOrder eulerOrder, HECLongAxisDir longAxisMapping, HECPoseResult& poseResult) = 0; virtual double CalculateError( const std::vector& eyePoints, const std::vector& robotPoints, const HECCalibResult& calibResult) = 0; virtual int CalculateEyeInHand( const std::vector& calibData, HECCalibResult& result) = 0; virtual HECTCPCalibResult CalculateTCP( const HECTCPCalibData& data) = 0; virtual int CalculateEyeToHandWithPose( const std::vector& calibData, HECCalibResult& result) = 0; ``` ### CoordinateTransform 主要保留两类场景: - `threeAxis*` 三轴设备坐标转换 - `sixAxis*` 六轴设备坐标转换 其中六轴眼在手上转换的核心接口为: ```cpp CTHomogeneousMatrix sixAxisEyeInHandBuildTransform( const CTRobotPose& robotPose, CTEulerOrder eulerOrder, const CTHomogeneousMatrix& handEyeMatrix); ``` **约定**:`robotPose.rx / ry / rz` 必须已经是真实绕 X/Y/Z 轴的角(弧度)。 若机器人报文的字段排列不是 `RX, RY, RZ`(例如配天 `A=RZ, B=RY, C=RX`),调用方需要先把字段按真实轴含义装进 `CTRobotPose`,再调用本函数。 ## 已移除的旧接口 以下接口已经从公开 API 中移除,不建议继续使用: - `TransformPointWithCenter` - `RotationMatrixToEulerZYX` - `EulerZYXToRotationMatrix` - 旧版 `TransformPose(calibResult, eyePoint, eyeDirVectors, invertYZ, ...)` - `CalculateEyeInHandWithTarget` 原因: - 仓库内已无实际调用 - 与现有接口功能重复 - 增加维护成本,容易让业务层误选旧接口 ## 使用示例 ### 1. 创建与销毁实例 ```cpp #include "IHandEyeCalib.h" IHandEyeCalib* calib = CreateHandEyeCalibInstance(); // ... DestroyHandEyeCalibInstance(calib); ``` ### 2. 对应点刚体变换标定 ```cpp std::vector eyePoints; std::vector robotPoints; HECCalibResult result; int ret = calib->CalculateRT(eyePoints, robotPoints, result); ``` ### 3. Eye-In-Hand 标定 ```cpp std::vector calibData; HECCalibResult result; int ret = calib->CalculateEyeInHand(calibData, result); ``` ### 4. 欧拉角与旋转矩阵互转 ```cpp HECEulerAngles srcAngles; srcAngles.roll = 0.1; srcAngles.pitch = 0.2; srcAngles.yaw = 0.3; HECRotationMatrix rotation; calib->EulerToRotationMatrix(srcAngles, HECEulerOrder::ZYX, rotation); HECEulerAngles dstAngles; calib->RotationMatrixToEuler(rotation, HECEulerOrder::ZYX, dstAngles); ``` ### 5. 由中心点和方向种子生成机器人姿态 ```cpp HECPoseResult poseResult; bool ok = calib->TransformPose( calibResult, HECPoint3D(100.0, 50.0, 200.0), // eyeCenter HECPoint3D(1.0, 0.0, 0.0), // longAxisDir HECPoint3D(0.0, 0.0, 1.0), // normalDir 0, // dirVectorInvert HECEulerOrder::ZYX, HECLongAxisDir::AxisX, poseResult); ``` ### 6. 业务侧直接做六轴眼在手上转换 ```cpp #include "CoordinateTransform.h" // 若机器人协议字段是 (A, B, C) 对应 (RZ, RY, RX), // 调用前需按真实轴含义把 C 放 rx、B 放 ry、A 放 rz。 CTRobotPose robotPose = CTRobotPose::fromDegrees( x, y, z, c, b, a); CTHomogeneousMatrix total = CCoordinateTransform::sixAxisEyeInHandBuildTransform( robotPose, CTEulerOrder::ZYX, handEyeMatrix); CTVec3D ptRobot = total.transformPoint(CTVec3D(camX, camY, camZ)); ``` ## 整理原则 - 算法能力放在 `IHandEyeCalib` - 通用坐标变换放在 `CoordinateTransform` - 业务层只负责选择配置和调用 - 同一能力只保留一套主入口,避免重复接口长期并存