41 #include <Calibration/Calibration.h>
42 #include <Color/ColorParameterSet.h>
43 #include <Image/ImageProcessor.h>
46 #include <Locators/VisualTargetLocator.h>
60 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
61 tcpNameLeft = getProperty<std::string>(
"TCPNameLeft").getValue();
62 tcpNameRight = getProperty<std::string>(
"TCPNameRight").getValue();
63 markerNameLeft = getProperty<std::string>(
"MarkerNameLeft").getValue();
64 markerNameRight = getProperty<std::string>(
"MarkerNameRight").getValue();
65 useVision = getProperty<bool>(
"UseVision").getValue();
71 robotStateComponent = getProxy<armarx::RobotStateComponentInterfacePrx>(
72 getProperty<std::string>(
"RobotStateComponentName").getValue());
81 std::string colorParameterFilename =
82 getProperty<std::string>(
"ColorParameterFile").getValue();
85 colorParameterFilename))
87 ARMARX_ERROR <<
"Could not find color parameter file in ArmarXDataPath: "
88 << colorParameterFilename;
92 ARMARX_VERBOSE <<
"Color parameter file name: " << colorParameterFilename;
94 visualTargetLocator =
new CVisualTargetLocator();
101 colorParameterSet =
new CColorParameterSet();
102 colorParameterSet->LoadFromFile(colorParameterFilename.c_str());
105 showSegmentedResultImages = getProperty<bool>(
"ShowSegmentedResultImages").getValue();
107 if (!showSegmentedResultImages)
119 ARMARX_VERBOSE <<
"Adding object class " << objectClassEntity->getName();
122 objectClassEntity->addWrapper(
124 markerColors[objectClassEntity->getName()] = recognitionWrapper->getObjectColor();
129 memoryx::ObjectLocalizationResultList
131 CByteImage** cameraImages,
132 armarx::MetaInfoSizeBasePtr imageMetaInfo,
133 CByteImage** resultImages)
139 const float recognitionCertainty = 0.8f;
140 const float uncertaintyWhenReturningKinematicPosition = 10000;
141 const float maxDistToFwdKinPose =
142 getProperty<float>(
"MaximalAcceptedDistanceFromForwardKinematics").getValue();
144 localRobot, robotStateComponent,
timestamp))
147 <<
"Failed to synchronize local robot - results are probably wrong";
149 const auto agentName = localRobot->getName();
150 std::string firstObjectName = objectClassNames.at(0);
151 bool firstEntryIsLeft = firstObjectName.find(
"left") != std::string::npos ||
152 firstObjectName.find(
"Left") != std::string::npos;
154 Eigen::Matrix4f leftHandPose = localRobot->getRobotNode(tcpNameLeft)->getPoseInRootFrame();
156 localRobot->getRobotNode(tcpNameRight)->getPoseInRootFrame();
158 localRobot->getRobotNode(markerNameLeft)->getPoseInRootFrame();
160 localRobot->getRobotNode(markerNameRight)->getPoseInRootFrame();
163 leftHandPose, localRobot->getRootNode()->getName(), agentName);
165 rightHandPose, localRobot->getRootNode()->getName(), agentName);
172 leftHandPose = cameraPoseInv * leftHandPose;
173 rightHandPose = cameraPoseInv * rightHandPose;
174 leftMarkerPose = cameraPoseInv * leftMarkerPose;
175 rightMarkerPose = cameraPoseInv * rightMarkerPose;
177 Eigen::Vector3f markerOffsetToTCPLeft =
178 leftHandPose.block<3, 1>(0, 3) - leftMarkerPose.block<3, 1>(0, 3);
179 Eigen::Vector3f markerOffsetToTCPRight =
180 rightHandPose.block<3, 1>(0, 3) - rightMarkerPose.block<3, 1>(0, 3);
183 memoryx::ObjectLocalizationResultList resultList;
188 Vec3d handMarkerPositionLeft, handMarkerPositionRight;
189 int numFoundMarkers = 0;
194 visualTargetLocator->LocateOneOrTwoTargets(
cameraImages,
196 handMarkerPositionLeft,
197 handMarkerPositionRight,
200 markerColors[firstObjectName]);
207 visualTargetLocator->LocateOneOrTwoTargets(
cameraImages,
209 handMarkerPositionLeft,
210 handMarkerPositionRight,
213 markerColors[firstObjectName]);
216 ARMARX_VERBOSE <<
"Found " << numFoundMarkers <<
" hand markers.";
218 if (numFoundMarkers == 0)
220 ARMARX_INFO <<
"Marker not found, color: " << markerColors[firstObjectName];
224 if (numFoundMarkers > 0)
227 memoryx::ObjectLocalizationResult result;
228 result.recognitionCertainty = recognitionCertainty;
230 Eigen::Vector3f position;
232 if (numFoundMarkers == 1)
234 if (objectClassNames.size() == 1)
236 result.objectClassName = objectClassNames.at(0);
237 position << handMarkerPositionLeft.x, handMarkerPositionLeft.y,
238 handMarkerPositionLeft.z;
240 float distToFwdKinPos;
241 if (firstEntryIsLeft)
243 distToFwdKinPos = (leftMarkerPose.block<3, 1>(0, 3) - position).norm();
244 position = position + markerOffsetToTCPLeft;
245 result.orientation = orientationLeftHand;
249 distToFwdKinPos = (rightMarkerPose.block<3, 1>(0, 3) - position).norm();
250 position = position + markerOffsetToTCPRight;
251 result.orientation = orientationRightHand;
260 armarx::FramedPositionPtr::dynamicCast(result.position);
261 if (firstEntryIsLeft)
264 << pos->toRootFrame(localRobot)->output();
269 << pos->toRootFrame(localRobot)->output();
272 <<
"Distance to position from forward kinematics: " << distToFwdKinPos
273 <<
"(max: " << maxDistToFwdKinPose <<
")";
275 if (distToFwdKinPos < maxDistToFwdKinPose)
277 resultList.push_back(result);
288 ARMARX_VERBOSE <<
"Refusing found marker because it is too far from "
289 "the position from the kinematic model ("
290 << distToFwdKinPos <<
", max: " << maxDistToFwdKinPose
294 else if (objectClassNames.size() == 2)
297 <<
"Found only 1 hand marker, but 2 were searched for. Returning the "
298 "localized marker position as a localization result for the closer "
299 "hand from forward kinematics.";
301 position << handMarkerPositionLeft.x, handMarkerPositionLeft.y,
302 handMarkerPositionLeft.z;
303 float distToFwdKinPosLeft =
304 (leftMarkerPose.block<3, 1>(0, 3) - position).norm();
305 float distToFwdKinPosRight =
306 (rightMarkerPose.block<3, 1>(0, 3) - position).norm();
308 std::string nameLeft, nameRight;
310 if (firstEntryIsLeft)
312 nameLeft = objectClassNames.at(0);
313 nameRight = objectClassNames.at(1);
317 nameLeft = objectClassNames.at(1);
318 nameRight = objectClassNames.at(0);
321 ARMARX_VERBOSE <<
"Distance to position from forward kinematics for "
322 << nameLeft <<
": " << distToFwdKinPosLeft
323 <<
"(max: " << maxDistToFwdKinPose <<
")";
324 ARMARX_VERBOSE <<
"Distance to position from forward kinematics for "
325 << nameRight <<
": " << distToFwdKinPosRight
326 <<
"(max: " << maxDistToFwdKinPose <<
")";
329 if (distToFwdKinPosLeft < maxDistToFwdKinPose &&
330 distToFwdKinPosLeft < distToFwdKinPosRight)
332 result.objectClassName = nameLeft;
333 position = position + markerOffsetToTCPLeft;
337 result.orientation = orientationLeftHand;
338 resultList.push_back(result);
341 if (distToFwdKinPosRight < maxDistToFwdKinPose &&
342 distToFwdKinPosRight < distToFwdKinPosLeft)
344 result.objectClassName = nameRight;
345 position = position + markerOffsetToTCPRight;
349 result.orientation = orientationRightHand;
350 resultList.push_back(result);
354 else if (numFoundMarkers == 2)
356 if (objectClassNames.size() == 1)
360 result.objectClassName = objectClassNames.at(0);
362 position << handMarkerPositionLeft.x, handMarkerPositionLeft.y,
363 handMarkerPositionLeft.z;
365 float distToFwdKinPosLeft =
366 (leftMarkerPose.block<3, 1>(0, 3) - position).norm();
367 float distToFwdKinPosRight =
368 (rightMarkerPose.block<3, 1>(0, 3) - position).norm();
370 if (firstEntryIsLeft)
372 ARMARX_VERBOSE <<
"Distance to position from forward kinematics: "
373 << distToFwdKinPosLeft <<
"(max: " << maxDistToFwdKinPose
376 position = position + markerOffsetToTCPLeft;
380 result.orientation = orientationLeftHand;
382 if (distToFwdKinPosLeft < maxDistToFwdKinPose &&
383 distToFwdKinPosLeft < distToFwdKinPosRight)
385 resultList.push_back(result);
390 ARMARX_VERBOSE <<
"Distance to position from forward kinematics: "
391 << distToFwdKinPosRight
392 <<
"(max: " << maxDistToFwdKinPose <<
")";
394 position = position + markerOffsetToTCPRight;
398 result.orientation = orientationRightHand;
400 if (distToFwdKinPosRight < maxDistToFwdKinPose &&
401 distToFwdKinPosRight < distToFwdKinPosLeft)
403 resultList.push_back(result);
408 position << handMarkerPositionRight.x, handMarkerPositionRight.y,
409 handMarkerPositionRight.z;
411 distToFwdKinPosLeft = (leftMarkerPose.block<3, 1>(0, 3) - position).norm();
412 distToFwdKinPosRight =
413 (rightMarkerPose.block<3, 1>(0, 3) - position).norm();
415 if (firstEntryIsLeft)
417 ARMARX_VERBOSE <<
"Distance to position from forward kinematics: "
418 << distToFwdKinPosLeft <<
"(max: " << maxDistToFwdKinPose
421 position = position + markerOffsetToTCPLeft;
425 result.orientation = orientationLeftHand;
427 if (distToFwdKinPosLeft < maxDistToFwdKinPose &&
428 distToFwdKinPosLeft < distToFwdKinPosRight)
430 resultList.push_back(result);
435 ARMARX_VERBOSE <<
"Distance to position from forward kinematics: "
436 << distToFwdKinPosRight
437 <<
"(max: " << maxDistToFwdKinPose <<
")";
439 position = position + markerOffsetToTCPRight;
443 result.orientation = orientationRightHand;
445 if (distToFwdKinPosRight < maxDistToFwdKinPose &&
446 distToFwdKinPosRight < distToFwdKinPosLeft)
448 resultList.push_back(result);
452 else if (objectClassNames.size() == 2)
454 std::string nameLeft, nameRight;
456 if (firstEntryIsLeft)
458 nameLeft = objectClassNames.at(0);
459 nameRight = objectClassNames.at(1);
463 nameLeft = objectClassNames.at(1);
464 nameRight = objectClassNames.at(0);
467 result.objectClassName = nameLeft;
468 position << handMarkerPositionLeft.x, handMarkerPositionLeft.y,
469 handMarkerPositionLeft.z;
470 position = position + markerOffsetToTCPLeft;
471 float distToFwdKinPosLeft =
472 (leftMarkerPose.block<3, 1>(0, 3) - position).norm();
473 float distToFwdKinPosRight =
474 (rightMarkerPose.block<3, 1>(0, 3) - position).norm();
477 result.orientation = orientationLeftHand;
479 ARMARX_VERBOSE <<
"Distance to position from forward kinematics (left): "
480 << distToFwdKinPosLeft <<
"(max: " << maxDistToFwdKinPose
483 if (distToFwdKinPosLeft < maxDistToFwdKinPose &&
484 distToFwdKinPosLeft < distToFwdKinPosRight)
486 resultList.push_back(result);
489 result.objectClassName = nameRight;
490 position << handMarkerPositionRight.x, handMarkerPositionRight.y,
491 handMarkerPositionRight.z;
492 position = position + markerOffsetToTCPRight;
493 distToFwdKinPosLeft = (leftMarkerPose.block<3, 1>(0, 3) - position).norm();
494 distToFwdKinPosRight =
495 (rightMarkerPose.block<3, 1>(0, 3) - position).norm();
498 result.orientation = orientationRightHand;
500 ARMARX_VERBOSE <<
"Distance to position from forward kinematics (right): "
501 << distToFwdKinPosRight <<
"(max: " << maxDistToFwdKinPose
504 if (distToFwdKinPosRight < maxDistToFwdKinPose &&
505 distToFwdKinPosRight < distToFwdKinPosLeft)
507 resultList.push_back(result);
514 if (showSegmentedResultImages)
516 CByteImage* pSegmentedImage =
new CByteImage(
520 markerColors[firstObjectName],
523 ::ImageProcessor::ConvertImage(pSegmentedImage,
resultImages[2]);
524 delete pSegmentedImage;
529 if (resultList.size() < objectClassNames.size())
532 memoryx::ObjectLocalizationResult result;
533 result.recognitionCertainty = recognitionCertainty;
536 localRobot->getRobotNode(tcpNameLeft)->getPoseInRootFrame(),
537 localRobot->getRootNode()->getName(),
540 localRobot->getRobotNode(tcpNameRight)->getPoseInRootFrame(),
541 localRobot->getRootNode()->getName(),
544 float var = uncertaintyWhenReturningKinematicPosition *
545 uncertaintyWhenReturningKinematicPosition;
546 variances << var, 0, 0, 0, var, 0, 0, 0, var;
548 if (objectClassNames.size() == 1)
550 ARMARX_INFO <<
"Returning hand pose from forward kinematics for one hand: "
551 << objectClassNames.at(0);
553 result.objectClassName = objectClassNames.at(0);
555 if (firstEntryIsLeft)
557 ARMARX_INFO <<
"left hand position: " << positionLeftHand->output();
558 result.position = positionLeftHand;
559 result.orientation = orientationLeftHand;
560 Eigen::Vector3f
mean = positionLeftHand->toEigen();
561 result.positionNoise =
566 ARMARX_INFO <<
"right hand position: " << positionRightHand->output();
567 result.position = positionRightHand;
568 result.orientation = orientationRightHand;
569 Eigen::Vector3f
mean = positionRightHand->toEigen();
570 result.positionNoise =
574 resultList.push_back(result);
576 else if (objectClassNames.size() == 2)
578 std::string leftName =
579 firstEntryIsLeft ? objectClassNames.at(0) : objectClassNames.at(1);
580 std::string rightName =
581 firstEntryIsLeft ? objectClassNames.at(1) : objectClassNames.at(0);
583 if (resultList.size() == 0)
585 ARMARX_INFO <<
"Returning hand pose from forward kinematics for two hands: "
586 << objectClassNames.at(0) <<
", " << objectClassNames.at(1);
588 result.objectClassName = leftName;
589 result.position = positionLeftHand;
590 result.orientation = orientationLeftHand;
591 Eigen::Vector3f
mean = positionLeftHand->toEigen();
592 result.positionNoise =
594 resultList.push_back(result);
596 result.objectClassName = rightName;
597 result.position = positionRightHand;
598 result.orientation = orientationRightHand;
599 mean = positionRightHand->toEigen();
600 result.positionNoise =
602 resultList.push_back(result);
606 if (resultList.at(0).objectClassName == leftName)
608 ARMARX_INFO <<
"Returning hand pose from recognition for " << leftName
609 <<
" and from forward kinematics for " << rightName;
610 result.objectClassName = rightName;
611 result.position = positionRightHand;
612 result.orientation = orientationRightHand;
613 Eigen::Vector3f
mean = positionRightHand->toEigen();
614 result.positionNoise =
616 resultList.push_back(result);
620 ARMARX_INFO <<
"Returning hand pose from recognition for " << rightName
621 <<
" and from forward kinematics for " << leftName;
622 result.objectClassName = leftName;
623 result.position = positionLeftHand;
624 result.orientation = orientationLeftHand;
625 Eigen::Vector3f
mean = positionLeftHand->toEigen();
626 result.positionNoise =
628 resultList.push_back(result);
634 ARMARX_WARNING <<
"More than 2 hands requested - this case is not handled here";
637 for (
auto& result : resultList)
648 HandMarkerLocalization::drawCrossInImage(CByteImage* image,
649 Eigen::Vector3f point,
652 Vec3d positionIVT = {point(0), point(1), point(2)};
653 Vec2d projectedPoint;
668 if (size < projectedPoint.x && size < projectedPoint.y &&
669 projectedPoint.x < image->width - size - 1 &&
670 projectedPoint.y < image->height - size - 3)
672 for (
int i = -size; i <= size; i++)
674 int indexHorizontalLine =
675 3 * ((int)projectedPoint.y * image->width + (
int)projectedPoint.x + i);
676 int indexVerticalLine =
677 3 * (((int)projectedPoint.y + i) * image->width + (int)projectedPoint.x);
678 image->pixels[indexHorizontalLine] = 255;
679 image->pixels[indexHorizontalLine + 1] = 255;
680 image->pixels[indexHorizontalLine + 2] = 255;
681 image->pixels[indexVerticalLine] = 255;
682 image->pixels[indexVerticalLine + 1] = 255;
683 image->pixels[indexVerticalLine + 2] = 255;