diff --git a/VirtualRobot/IK/DifferentialIK.cpp b/VirtualRobot/IK/DifferentialIK.cpp index b70bba190863d7a20eb606f6fe7ec7daef499774..23f6b730846254277032f61eafcb1307ce698aee 100644 --- a/VirtualRobot/IK/DifferentialIK.cpp +++ b/VirtualRobot/IK/DifferentialIK.cpp @@ -390,11 +390,12 @@ namespace VirtualRobot // Calculus for rotational joints is different as for prismatic joints. if (dof->isRotationalJoint()) { - // get axis + // todo: find a better way of handling different joint types std::shared_ptr<RobotNodeRevolute> revolute = std::dynamic_pointer_cast<RobotNodeRevolute>(dof); THROW_VR_EXCEPTION_IF(!revolute, "Internal error: expecting revolute joint"); - // todo: find a better way of handling different joint types + + // get axis axis = revolute->getJointRotationAxis(coordSystem); // if necessary calculate the position part of the Jacobian @@ -452,18 +453,31 @@ namespace VirtualRobot RobotNodeHemispherePtr hemisphere = std::dynamic_pointer_cast<RobotNodeHemisphere>(dof); - VR_ASSERT(hemisphere->first.has_value() xor hemisphere->second.has_value()); - if (hemisphere->isSecondHemisphereJointNode()) { // Set Jacobian for both DoFs. RobotNodeHemisphere::SecondData& second = hemisphere->getSecondData(); const hemisphere::Maths::Jacobian jacobian = second.getJacobian(); - tmpUpdateJacobianPosition.block<3, 2>(0, i - 1) - = jacobian.block<3, 2>(0, 0).cast<float>(); - tmpUpdateJacobianOrientation.block<3, 2>(0, i - 1) - = jacobian.block<3, 2>(3, 0).cast<float>(); + using Matrix3x2f = Eigen::Matrix<float, 3, 2>; + + const Matrix3x2f velocities = jacobian.block<3, 2>(0, 0).cast<float>(); + const Matrix3x2f rotAxes = jacobian.block<3, 2>(3, 0).cast<float>(); + + const Eigen::Matrix3f globalOri = second.firstNode->getGlobalOrientation(); + + Matrix3x2f velocitiesCoord = globalOri * velocities; + Matrix3x2f rotAxesCoord = globalOri * rotAxes; + if (coordSystem) + { + auto coordSystemInverseGlobalRot = coordSystem->getGlobalOrientation().transpose(); + + velocitiesCoord = coordSystemInverseGlobalRot * velocitiesCoord; + rotAxesCoord = coordSystemInverseGlobalRot * rotAxesCoord; + } + + tmpUpdateJacobianPosition.block<3, 2>(0, i - 1) = velocitiesCoord; + tmpUpdateJacobianOrientation.block<3, 2>(0, i - 1) = rotAxesCoord; } else { diff --git a/VirtualRobot/Nodes/RobotNodeFourBar.cpp b/VirtualRobot/Nodes/RobotNodeFourBar.cpp index a70581dd9fec393485ec191d9d01234d0a67c417..615a468dc5f35b6d85178b368cf350a4cab1f5d4 100644 --- a/VirtualRobot/Nodes/RobotNodeFourBar.cpp +++ b/VirtualRobot/Nodes/RobotNodeFourBar.cpp @@ -176,7 +176,7 @@ namespace VirtualRobot { this->xmlInfo = info; - VR_ASSERT(second.has_value()); + VR_ASSERT(active.has_value()); switch (info.role) { case Role::PASSIVE: @@ -199,16 +199,16 @@ namespace VirtualRobot bool RobotNodeFourBar::initialize(SceneObjectPtr parent, const std::vector<SceneObjectPtr>& children) { - VR_ASSERT_MESSAGE(first.has_value() xor second.has_value(), - std::stringstream() << first.has_value() << " / " << second.has_value()); + VR_ASSERT_MESSAGE(first.has_value() xor active.has_value(), + std::stringstream() << first.has_value() << " / " << active.has_value()); - // The second node needs to store a reference to the first node. + // The active node needs to store a reference to the first node. // Whenever the joint value has changed, the passive joint will be updated. if (active) { std::cout << "Initializing active four bar joint" << std::endl; - VR_ASSERT_MESSAGE(not second->first, "Second must not be initialized yet."); + VR_ASSERT_MESSAGE(not active->passive, "Second must not be initialized yet."); VirtualRobot::SceneObjectPtr currentParent = parent; @@ -281,8 +281,8 @@ namespace VirtualRobot void RobotNodeFourBar::updateTransformationMatrices(const Eigen::Matrix4f& parentPose) { - VR_ASSERT_MESSAGE(first.has_value() xor second.has_value(), - std::stringstream() << first.has_value() << " / " << second.has_value()); + VR_ASSERT_MESSAGE(first.has_value() xor active.has_value(), + std::stringstream() << first.has_value() << " / " << active.has_value()); std::cout << "Updating RobotNodeFourBar::updateTransformationMatrices" << std::endl; @@ -316,7 +316,7 @@ namespace VirtualRobot // } // else if (active) // { - // VR_ASSERT_MESSAGE(second->first, "First node must be known to second node."); + // VR_ASSERT_MESSAGE(active->first, "First node must be known to active node."); // JointMath& math = active->math(); // Eigen::Vector2f actuators(active->passive->getJointValue(), this->getJointValue()); @@ -333,7 +333,7 @@ namespace VirtualRobot // Eigen::IOFormat iof(5, 0, " ", "\n", " [", "]"); // std::cout - // << __FUNCTION__ << "() of second actuator with " + // << __FUNCTION__ << "() of active actuator with " // << "\n lever = " << math.joint.lever << "\n theta0 = " << math.joint.theta0 // << "\n radius = " << math.joint.radius << "\n joint value = " << jointValue // << "\n actuator (angle) = \n" @@ -351,8 +351,8 @@ namespace VirtualRobot RobotNodeFourBar::print(bool printChildren, bool printDecoration) const { ReadLockPtr lock = getRobot()->getReadLock(); - VR_ASSERT_MESSAGE(first.has_value() xor second.has_value(), - std::stringstream() << first.has_value() << " / " << second.has_value()); + VR_ASSERT_MESSAGE(first.has_value() xor active.has_value(), + std::stringstream() << first.has_value() << " / " << active.has_value()); if (printDecoration) { @@ -367,7 +367,7 @@ namespace VirtualRobot } else if (active) { - std::cout << "* four_bar joint second node"; + std::cout << "* four_bar joint active node"; // std::cout << "* Transform: \n" // << active->math.joint.getEndEffectorTransform() << std::endl; } @@ -519,8 +519,8 @@ namespace VirtualRobot std::string RobotNodeFourBar::_toXML(const std::string& /*modelPath*/) { - VR_ASSERT_MESSAGE(first.has_value() xor second.has_value(), - std::stringstream() << first.has_value() << " / " << second.has_value()); + VR_ASSERT_MESSAGE(first.has_value() xor active.has_value(), + std::stringstream() << first.has_value() << " / " << active.has_value()); if (first) { diff --git a/VirtualRobot/Nodes/RobotNodeHemisphere.cpp b/VirtualRobot/Nodes/RobotNodeHemisphere.cpp index a2d999867affb1b8adf6f5d79ffc12675ef5607b..d472654467060a64d9de011afd00050be2575c48 100644 --- a/VirtualRobot/Nodes/RobotNodeHemisphere.cpp +++ b/VirtualRobot/Nodes/RobotNodeHemisphere.cpp @@ -127,7 +127,7 @@ namespace VirtualRobot // The second node needs to store a reference to the first node. if (secondData) { - VR_ASSERT_MESSAGE(not secondData->first, "Second must not be initialized yet."); + VR_ASSERT_MESSAGE(not secondData->firstNode, "Second must not be initialized yet."); RobotNodeHemisphere* firstNode = dynamic_cast<RobotNodeHemisphere*>(parent.get()); RobotNodeHemisphere* secondNode = this; @@ -171,7 +171,7 @@ namespace VirtualRobot } else if (secondData) { - VR_ASSERT_MESSAGE(secondData->first, "First node must be known to second node."); + VR_ASSERT_MESSAGE(secondData->firstNode, "First node must be known to second node."); hemisphere::CachedMaths& maths = secondData->maths(); Eigen::Vector2f actuators(secondData->firstNode->getJointValue(), this->getJointValue());