29#include <SimoxUtility/json.h>
30#include <SimoxUtility/math/pose/invert.h>
31#include <SimoxUtility/math/pose/pose.h>
32#include <VirtualRobot/XML/RobotIO.h>
48 defs->component(localizer);
49 defs->defineOptionalProperty<std::string>(
"cmp.PointCloudToArViz",
51 "Name of the PointCloudToArViz component.");
53 defs->optional(localizerMarkerID,
"loc.MarkerID",
"The marker ID to use (-1 for any ID).");
55 defs->optional(robotArMarkerFileName,
56 "robot.ArMarkerRobotFileName",
57 "File name of robot model with ArMarker marker.");
58 defs->optional(robotBaseNodeName,
"robot.BaseNodeName",
"Name of the base robot node.");
59 defs->optional(robotArMarkerMarkerNodeName,
60 "robot.ArMarkerMarkerNodeName",
61 "Name of the ArMarker marker robot node.");
63 defs->optional(calibrationFilePath,
"calibrationFilePath",
"Path to the calibration file.");
77 return "ArMarkerExternalCameraCalibration";
83 namespace fs = std::filesystem;
87 ARMARX_INFO <<
"Loading robot with ArMarker marker from: " << robotArMarkerFileName;
88 robotArMarker = VirtualRobot::RobotIO::loadRobot(
89 robotArMarkerFileName, VirtualRobot::RobotIO::RobotDescription::eStructure);
93 fs::path path = calibrationFilePath;
95 this->calibrationFilePath = parent_path / path.filename();
96 ARMARX_INFO <<
"Calibration file: " << calibrationFilePath;
104 if (vis.pointCloudToArViz)
113 vis.layerCamera =
arviz.layer(
"In Camera");
114 vis.layerCamera.add(
viz::Pose(
"Origin"));
115 vis.layerCamera.add(vis.markerPoseInCamera);
117 vis.layerRobotBase =
arviz.layer(
"In RobotBase");
118 vis.layerRobotBase.add(vis.markerPoseInRobotBase);
119 vis.layerRobotBase.add(vis.markerModelInRobotBase);
120 vis.layerRobotBase.add(vis.cameraPoseInRobotBase);
147 ArMarkerExternalCameraCalibration::run()
157 visionx::ArMarkerLocalizationResultList localizationResults;
160 localizationResults = localizer->GetLatestLocalizationResult();
162 catch (
const Ice::ConnectionRefusedException&)
167 ARMARX_VERBOSE <<
"Got " << localizationResults.size() <<
" localization results.";
169 std::optional<visionx::ArMarkerLocalizationResult> result;
170 if (localizationResults.size() > 0)
172 if (localizerMarkerID < 0)
174 result = localizationResults.front();
178 for (
const auto& r : localizationResults)
180 if (r.id == localizerMarkerID)
192 FramedPosePtr framedPose = FramedPosePtr::dynamicCast(result->pose);
193 Eigen::Matrix4f pose = framedPose->toEigen();
195 onLocalizationResult(pose);
199 vis.markerPoseInCamera.scale(0.5);
202 arviz.commit({vis.layerCamera, vis.layerRobotBase});
204 cycle.waitForCycleDuration();
209 ArMarkerExternalCameraCalibration::onLocalizationResult(
210 const Eigen::Matrix4f& markerPoseInCamera)
214 Eigen::Matrix4f cameraPoseMarker = simox::math::inverted_pose(markerPoseInCamera);
216 VirtualRobot::RobotNodePtr arMarkerNode =
217 robotArMarker->getRobotNode(robotArMarkerMarkerNodeName);
218 VirtualRobot::RobotNodePtr baseNode = robotArMarker->getRobotNode(robotBaseNodeName);
221 cameraPoseMarker, arMarkerNode->getName(), robotArMarker->getName());
222 framedCameraPose.changeFrame(robotArMarker, baseNode->getName());
224 Eigen::Matrix4f cameraPoseInRobotBase = framedCameraPose.toEigen();
225 Eigen::Matrix4f markerInRobotBase = cameraPoseInRobotBase * markerPoseInCamera;
227 vis.markerPoseInCamera.pose(markerPoseInCamera).scale(1.0);
228 vis.markerPoseInRobotBase.pose(baseNode->getPoseInRootFrame() * markerInRobotBase);
229 vis.cameraPoseInRobotBase.pose(baseNode->getPoseInRootFrame() * cameraPoseInRobotBase);
232 Eigen::Matrix4f::Identity(), arMarkerNode->getName(), robotArMarker->getName());
233 framedMarkerModelPose.changeFrame(robotArMarker, baseNode->getName());
234 vis.markerModelInRobotBase.pose(baseNode->getPoseInRootFrame() *
235 framedMarkerModelPose.toEigen());
239 std::scoped_lock lock(markerPoseMutex);
240 this->markerPoseInCamera = markerPoseInCamera;
241 this->cameraPoseInRobotBase = cameraPoseInRobotBase;
243 if (vis.pointCloudToArViz)
245 vis.pointCloudToArViz->setCustomTransform(
246 new Pose(baseNode->getPoseInRootFrame() * cameraPoseInRobotBase));
251 ArMarkerExternalCameraCalibration::storeCalibration()
253 ExternalCameraCalibration calibration;
255 std::scoped_lock lock(markerPoseMutex);
256 calibration.cameraPose = cameraPoseInRobotBase;
257 calibration.cameraPoseFrame = robotBaseNodeName;
261 const nlohmann::json j = calibration;
264 << calibrationFilePath <<
"\n\n"
266 nlohmann::write_json(calibrationFilePath, j, 2);
274 tab.storeButton.setLabel(
"Store calibration");
283 if (tab.storeButton.wasClicked())
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Brief description of class ArMarkerExternalCameraCalibration.
void onInitComponent() override
void onDisconnectComponent() override
void RemoteGui_update() override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectComponent() override
static std::string GetDefaultName()
void onExitComponent() override
void createRemoteGuiTab()
std::string getDefaultName() const override
armarx::viz::Client arviz
static std::string resolvePath(const std::string &path, bool verbose=true)
Resolves environment variables and home paths and tries to make path absolute.
Default component property definition container.
ProxyType getProxyFromProperty(const std::string &propertyName, bool addToDependencies=false, const std::string &endpoints="", bool throwOnProxyError=true)
Get a proxy whose name is specified by the given property.
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
This util class helps with keeping a cycle time during a control cycle.
std::string getName() const
Retrieve name of object.
bool synchronizeLocalClone(const VirtualRobot::RobotPtr &robot) const
bool isStopped()
Retrieve whether stop() has been called.
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_VERBOSE
The logging level for verbose information.
const VariantTypeId FramedPose
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
IceInternal::Handle< FramedPose > FramedPosePtr
SimpleRunningTask(Ts...) -> SimpleRunningTask< std::function< void(void)> >
void RemoteGui_startRunningTask()
void RemoteGui_createTab(std::string const &name, RemoteGui::Client::Widget const &rootWidget, RemoteGui::Client::Tab *tab)