27 #include <SimoxUtility/json.h>
28 #include <SimoxUtility/math/pose/pose.h>
29 #include <SimoxUtility/math/pose/invert.h>
31 #include <VirtualRobot/XML/RobotIO.h>
45 defs->component(localizer);
46 defs->defineOptionalProperty<std::string>(
"cmp.PointCloudToArViz",
"PointCloudToArViz",
"Name of the PointCloudToArViz component.");
48 defs->optional(localizerMarkerID,
"loc.MarkerID",
"The marker ID to use (-1 for any ID).");
50 defs->optional(robotArMarkerFileName,
"robot.ArMarkerRobotFileName",
"File name of robot model with ArMarker marker.");
51 defs->optional(robotBaseNodeName,
"robot.BaseNodeName",
"Name of the base robot node.");
52 defs->optional(robotArMarkerMarkerNodeName,
"robot.ArMarkerMarkerNodeName",
"Name of the ArMarker marker robot node.");
54 defs->optional(calibrationFilePath,
"calibrationFilePath",
"Path to the calibration file.");
61 return "ArMarkerExternalCameraCalibration";
67 namespace fs = std::filesystem;
71 ARMARX_INFO <<
"Loading robot with ArMarker marker from: " << robotArMarkerFileName;
72 robotArMarker = VirtualRobot::RobotIO::loadRobot(robotArMarkerFileName, VirtualRobot::RobotIO::RobotDescription::eStructure);
76 fs::path path = calibrationFilePath;
78 this->calibrationFilePath = parent_path / path.filename();
79 ARMARX_INFO <<
"Calibration file: " << calibrationFilePath;
87 if (vis.pointCloudToArViz)
98 vis.layerCamera.add(vis.markerPoseInCamera);
100 vis.layerRobotBase =
arviz.
layer(
"In RobotBase");
101 vis.layerRobotBase.add(vis.markerPoseInRobotBase);
102 vis.layerRobotBase.add(vis.markerModelInRobotBase);
103 vis.layerRobotBase.add(vis.cameraPoseInRobotBase);
133 void ArMarkerExternalCameraCalibration::run()
136 while (!task->isStopped())
143 visionx::ArMarkerLocalizationResultList localizationResults;
146 localizationResults = localizer->GetLatestLocalizationResult();
148 catch (
const Ice::ConnectionRefusedException&)
153 ARMARX_VERBOSE <<
"Got " << localizationResults.size() <<
" localization results.";
155 std::optional<visionx::ArMarkerLocalizationResult> result;
156 if (localizationResults.size() > 0)
158 if (localizerMarkerID < 0)
160 result = localizationResults.front();
164 for (
const auto& r : localizationResults)
166 if (r.id == localizerMarkerID)
178 FramedPosePtr framedPose = FramedPosePtr::dynamicCast(result->pose);
181 onLocalizationResult(pose);
185 vis.markerPoseInCamera.scale(0.5);
188 arviz.
commit({vis.layerCamera, vis.layerRobotBase});
190 cycle.waitForCycleDuration();
194 void ArMarkerExternalCameraCalibration::onLocalizationResult(
const Eigen::Matrix4f& markerPoseInCamera)
198 Eigen::Matrix4f cameraPoseMarker = simox::math::inverted_pose(markerPoseInCamera);
200 VirtualRobot::RobotNodePtr arMarkerNode = robotArMarker->getRobotNode(robotArMarkerMarkerNodeName);
201 VirtualRobot::RobotNodePtr baseNode = robotArMarker->getRobotNode(robotBaseNodeName);
203 FramedPose framedCameraPose(cameraPoseMarker, arMarkerNode->getName(), robotArMarker->getName());
204 framedCameraPose.changeFrame(robotArMarker, baseNode->getName());
207 Eigen::Matrix4f markerInRobotBase = cameraPoseInRobotBase * markerPoseInCamera;
209 vis.markerPoseInCamera.pose(markerPoseInCamera).scale(1.0);
210 vis.markerPoseInRobotBase.pose(baseNode->getPoseInRootFrame() * markerInRobotBase);
211 vis.cameraPoseInRobotBase.pose(baseNode->getPoseInRootFrame() * cameraPoseInRobotBase);
214 framedMarkerModelPose.changeFrame(robotArMarker, baseNode->getName());
215 vis.markerModelInRobotBase.pose(baseNode->getPoseInRootFrame() * framedMarkerModelPose.toEigen());
219 std::scoped_lock lock(markerPoseMutex);
220 this->markerPoseInCamera = markerPoseInCamera;
221 this->cameraPoseInRobotBase = cameraPoseInRobotBase;
223 if (vis.pointCloudToArViz)
225 vis.pointCloudToArViz->setCustomTransform(
new Pose(baseNode->getPoseInRootFrame() * cameraPoseInRobotBase));
230 void ArMarkerExternalCameraCalibration::storeCalibration()
232 ExternalCameraCalibration calibration;
234 std::scoped_lock lock(markerPoseMutex);
235 calibration.cameraPose = cameraPoseInRobotBase;
236 calibration.cameraPoseFrame = robotBaseNodeName;
240 const nlohmann::json j = calibration;
242 ARMARX_IMPORTANT <<
"Writing calibration to \n" << calibrationFilePath <<
"\n\n" << j.dump(2);
243 nlohmann::write_json(calibrationFilePath, j, 2);
252 tab.storeButton.setLabel(
"Store calibration");
260 if (tab.storeButton.wasClicked())