From cb55cd3cb61357fc0c9b37f68e744b8fac10570c Mon Sep 17 00:00:00 2001 From: Rainer Kartmann <rainer.kartmann@kit.edu> Date: Tue, 1 Aug 2023 12:08:00 +0200 Subject: [PATCH] Fix using cloned nodes instead of original nodes to get the correct local trafo, refactoring --- VirtualRobot/RobotFactory.cpp | 191 +++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 84 deletions(-) diff --git a/VirtualRobot/RobotFactory.cpp b/VirtualRobot/RobotFactory.cpp index 1b1ec5265..dbb79067f 100644 --- a/VirtualRobot/RobotFactory.cpp +++ b/VirtualRobot/RobotFactory.cpp @@ -1254,146 +1254,169 @@ namespace VirtualRobot } VirtualRobot::RobotPtr - RobotFactory::createFlattenedModel(Robot &robot) + RobotFactory::createFlattenedModel(Robot& robot) { const Eigen::Matrix4f globalPose = robot.getGlobalPose(); robot.setGlobalPose(Eigen::Matrix4f::Identity()); - RobotPtr flattenedModel = std::make_shared<LocalRobot>("Flattened_" + robot.getName(), robot.getType()); + RobotPtr flattenedRobot = + std::make_shared<LocalRobot>("Flattened_" + robot.getName(), robot.getType()); struct NodeToClone { - RobotNodePtr original; - RobotNodePtr parent; + RobotNodePtr nodeInOriginalRobot; + RobotNodePtr parentInFlattenedRobot; }; - std::queue<NodeToClone> nodes({{robot.getRootNode(), nullptr}}); - - while (!nodes.empty()) - { - NodeToClone current = nodes.front(); - nodes.pop(); + auto isBody = [](RobotNodePtr const& node) -> bool + { return node->getVisualization() != nullptr and node->getChildren<RobotNode>().empty(); }; - RobotNodePtr cloned = current.original->clone(flattenedModel, false, current.parent); + auto isLink = [](RobotNodePtr const& node) -> bool { + return node->getVisualization() == nullptr and + not node->getChildren<RobotNode>().empty(); + }; - if (current.parent == nullptr) + auto pushAllChildren = [](RobotNodePtr const& original, + RobotNodePtr const& cloned, + std::queue<NodeToClone>& nodes) + { + for (const auto& child : original->getChildren()) { - flattenedModel->setRootNode(cloned); + auto const& childNode = std::dynamic_pointer_cast<RobotNode>(child); + if (childNode == nullptr) + { + continue; + } + + nodes.push({childNode, cloned}); } + }; - auto isBody = [](RobotNodePtr const& node) -> bool - { - return node->getVisualization() != nullptr and node->getChildren<RobotNode>().empty(); - }; + struct BodyAndLink + { + RobotNodePtr body; + RobotNodePtr link; + std::vector<RobotNodePtr> others; + }; - auto isLink = [](RobotNodePtr const& node) -> bool - { - return node->getVisualization() == nullptr and not node->getChildren().empty(); - }; + auto findBodyAndLink = [isBody, + isLink](RobotNodePtr const& jointNode) -> std::optional<BodyAndLink> + { + std::optional<RobotNodePtr> body; + std::optional<RobotNodePtr> link; + std::vector<RobotNodePtr> others; - auto pushAllChildren = [&nodes](RobotNodePtr const& original, RobotNodePtr const& cloned) + for (const auto& child : jointNode->getChildren()) { - for (auto const& child : original->getChildren()) + auto const& childNode = std::dynamic_pointer_cast<RobotNode>(child); + if (childNode == nullptr) { - auto const& childNode = std::dynamic_pointer_cast<RobotNode>(child); - if (childNode == nullptr) - { - continue; - } - - nodes.push({childNode, cloned}); + continue; } - }; - - auto findSpecialChildren = [isBody, isLink](RobotNodePtr const& node) -> std::optional<std::tuple<RobotNodePtr, RobotNodePtr, std::vector<RobotNodePtr>>> - { - std::optional<RobotNodePtr> body; - std::optional<RobotNodePtr> link; - std::vector<RobotNodePtr> others; - for (auto const& child : node->getChildren()) + if (isBody(childNode)) { - auto const& childNode = std::dynamic_pointer_cast<RobotNode>(child); - if (childNode == nullptr) + if (body.has_value()) { - continue; + return std::nullopt; } - if (isBody(childNode)) + body = childNode; + } + else if (isLink(childNode)) + { + if (link.has_value()) { - if (body.has_value()) - { - return std::nullopt; - } - - body = childNode; + return std::nullopt; } - else if (isLink(childNode)) - { - if (link.has_value()) - { - return std::nullopt; - } - link = childNode; - } - else - { - others.emplace_back(childNode); - } + link = childNode; } - - if (body.has_value() and link.has_value()) + else { - return std::make_tuple(body.value(), link.value(), others); + others.emplace_back(childNode); } + } - return std::nullopt; - }; - - auto performFlattenedAttach = [&flattenedModel, pushAllChildren](RobotNodePtr const& clonedJoint, RobotNodePtr const& originalBody, RobotNodePtr const& originalLink) + if (body.has_value() and link.has_value()) { - RobotNodePtr clonedBody = originalBody->clone(flattenedModel, false, clonedJoint); - RobotNodePtr clonedLink = originalLink->clone(flattenedModel, false, clonedBody); + return BodyAndLink{.body = body.value(), .link = link.value(), .others = others}; + } + + return std::nullopt; + }; + + auto performFlattenedAttach = + [&flattenedRobot, pushAllChildren](RobotNodePtr const& clonedJoint, + RobotNodePtr const& originalBody, + RobotNodePtr const& originalLink, + std::queue<NodeToClone>& nodesToClone) + { + const bool cloneChildren = false; + RobotNodePtr clonedBody = + originalBody->clone(flattenedRobot, cloneChildren, clonedJoint); + RobotNodePtr clonedLink = + originalLink->clone(flattenedRobot, cloneChildren, clonedBody); + + Eigen::Matrix4f global_T_body = clonedBody->getGlobalPose(); + Eigen::Matrix4f global_T_link = clonedLink->getGlobalPose(); + + Eigen::Matrix4f body_T_link = simox::math::inverted_pose(global_T_body) * global_T_link; + + clonedLink->setLocalTransformation(body_T_link); + clonedLink->updateTransformationMatrices(); + + pushAllChildren(originalLink, clonedLink, nodesToClone); + }; + + std::queue<NodeToClone> nodes({{robot.getRootNode(), nullptr}}); + while (not nodes.empty()) + { + NodeToClone current = nodes.front(); + nodes.pop(); - Eigen::Matrix4f localLinkTransform = simox::math::inverted_pose(clonedBody->getGlobalPose()) * clonedLink->getGlobalPose(); - clonedLink->setLocalTransformation(localLinkTransform); - clonedLink->updateTransformationMatrices(); + const bool cloneChildren = false; + RobotNodePtr cloned = current.nodeInOriginalRobot->clone( + flattenedRobot, cloneChildren, current.parentInFlattenedRobot); - pushAllChildren(originalLink, clonedLink); - }; + if (current.parentInFlattenedRobot == nullptr) + { + flattenedRobot->setRootNode(cloned); + } - if (current.original->isJoint()) + if (current.nodeInOriginalRobot->isJoint()) { - auto specials = findSpecialChildren(current.original); - if (specials.has_value()) + std::optional<BodyAndLink> bodyAndLink = + findBodyAndLink(current.nodeInOriginalRobot); + if (bodyAndLink.has_value()) { - auto [body, link, others] = specials.value(); + auto [body, link, others] = bodyAndLink.value(); - performFlattenedAttach(cloned, body, link); + performFlattenedAttach(cloned, body, link, nodes); - for (auto const& other : others) + for (const auto& other : others) { nodes.push({other, cloned}); } } else { - pushAllChildren(current.original, cloned); + pushAllChildren(current.nodeInOriginalRobot, cloned, nodes); } } else { - pushAllChildren(current.original, cloned); + pushAllChildren(current.nodeInOriginalRobot, cloned, nodes); } } robot.setGlobalPose(globalPose); - flattenedModel->setGlobalPose(globalPose); + flattenedRobot->setGlobalPose(globalPose); - return flattenedModel; + return flattenedRobot; } + void RobotFactory::cloneRecursiveUnite(RobotPtr robot, RobotNodePtr currentNode, RobotNodePtr currentNodeClone, std::vector<std::string> uniteWithAllChildren) { std::vector<SceneObjectPtr> c = currentNode->getChildren(); -- GitLab