/* * Software License Agreement (BSD License) * * Copyright (c) 2011-2014, Willow Garage, Inc. * Copyright (c) 2014-2016, Open Source Robotics Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of Open Source Robotics Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /** \author Dalibor Matura, Jia Pan */ #ifndef FCL_ARTICULATED_MODEL_JOINT_H #define FCL_ARTICULATED_MODEL_JOINT_H #include "fcl/common/data_types.h" #include #include #include #include #include namespace fcl { class JointConfig; class Link; enum JointType {JT_UNKNOWN, JT_PRISMATIC, JT_REVOLUTE, JT_BALLEULER}; /// @brief Base Joint template class Joint { public: Joint(const std::shared_ptr& link_parent, const std::shared_ptr& link_child, const Transform3& transform_to_parent, const std::string& name); Joint(const std::string& name); virtual ~Joint() {} const std::string& getName() const; void setName(const std::string& name); virtual Transform3 getLocalTransform() const = 0; virtual std::size_t getNumDofs() const = 0; std::shared_ptr getJointConfig() const; void setJointConfig(const std::shared_ptr& joint_cfg); std::shared_ptr getParentLink() const; std::shared_ptr getChildLink() const; void setParentLink(const std::shared_ptr& link); void setChildLink(const std::shared_ptr& link); JointType getJointType() const; const Transform3& getTransformToParent() const; void setTransformToParent(const Transform3& t); protected: /// links to parent and child are only for connection, so weak_ptr to avoid cyclic dependency std::weak_ptr link_parent_, link_child_; JointType type_; std::string name_; std::shared_ptr joint_cfg_; Transform3 transform_to_parent_; public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW }; template class PrismaticJoint : public Joint { public: PrismaticJoint(const std::shared_ptr& link_parent, const std::shared_ptr& link_child, const Transform3& transform_to_parent, const std::string& name, const Vector3& axis); virtual ~PrismaticJoint() {} Transform3 getLocalTransform() const; std::size_t getNumDofs() const; const Vector3& getAxis() const; protected: Vector3 axis_; }; template class RevoluteJoint : public Joint { public: RevoluteJoint(const std::shared_ptr& link_parent, const std::shared_ptr& link_child, const Transform3& transform_to_parent, const std::string& name, const Vector3& axis); virtual ~RevoluteJoint() {} Transform3 getLocalTransform() const; std::size_t getNumDofs() const; const Vector3& getAxis() const; protected: Vector3 axis_; }; template class BallEulerJoint : public Joint { public: BallEulerJoint(const std::shared_ptr& link_parent, const std::shared_ptr& link_child, const Transform3& transform_to_parent, const std::string& name); virtual ~BallEulerJoint() {} std::size_t getNumDofs() const; Transform3 getLocalTransform() const; }; //============================================================================// // // // Implementations // // // //============================================================================// //============================================================================== template Joint::Joint(const std::shared_ptr& link_parent, const std::shared_ptr& link_child, const Transform3& transform_to_parent, const std::string& name) : link_parent_(link_parent), link_child_(link_child), name_(name), transform_to_parent_(transform_to_parent) {} //============================================================================== template Joint::Joint(const std::string& name) : name_(name) { } //============================================================================== template const std::string& Joint::getName() const { return name_; } //============================================================================== template void Joint::setName(const std::string& name) { name_ = name; } //============================================================================== template std::shared_ptr Joint::getJointConfig() const { return joint_cfg_; } //============================================================================== template void Joint::setJointConfig(const std::shared_ptr& joint_cfg) { joint_cfg_ = joint_cfg; } //============================================================================== template std::shared_ptr Joint::getParentLink() const { return link_parent_.lock(); } //============================================================================== template std::shared_ptr Joint::getChildLink() const { return link_child_.lock(); } //============================================================================== template void Joint::setParentLink(const std::shared_ptr& link) { link_parent_ = link; } //============================================================================== template void Joint::setChildLink(const std::shared_ptr& link) { link_child_ = link; } //============================================================================== template JointType Joint::getJointType() const { return type_; } //============================================================================== template const Transform3& Joint::getTransformToParent() const { return transform_to_parent_; } //============================================================================== template void Joint::setTransformToParent(const Transform3& t) { transform_to_parent_ = t; } //============================================================================== template PrismaticJoint::PrismaticJoint(const std::shared_ptr& link_parent, const std::shared_ptr& link_child, const Transform3& transform_to_parent, const std::string& name, const Vector3& axis) : Joint(link_parent, link_child, transform_to_parent, name), axis_(axis) { type_ = JT_PRISMATIC; } //============================================================================== template const Vector3& PrismaticJoint::getAxis() const { return axis_; } //============================================================================== template std::size_t PrismaticJoint::getNumDofs() const { return 1; } //============================================================================== template Transform3 PrismaticJoint::getLocalTransform() const { const Quaternion quat(transform_to_parent_.linear()); const Vector3& transl = transform_to_parent_.translation(); Transform3 tf = Transform3::Identity(); tf.linear() = quat.toRotationMatrix(); tf.translation() = quat * (axis_ * (*joint_cfg_)[0]) + transl; return tf; } //============================================================================== template RevoluteJoint::RevoluteJoint(const std::shared_ptr& link_parent, const std::shared_ptr& link_child, const Transform3& transform_to_parent, const std::string& name, const Vector3& axis) : Joint(link_parent, link_child, transform_to_parent, name), axis_(axis) { type_ = JT_REVOLUTE; } //============================================================================== template const Vector3& RevoluteJoint::getAxis() const { return axis_; } //============================================================================== template std::size_t RevoluteJoint::getNumDofs() const { return 1; } //============================================================================== template Transform3 RevoluteJoint::getLocalTransform() const { Transform3 tf = Transform3::Identity(); tf.linear() = transform_to_parent_.linear() * AngleAxis((*joint_cfg_)[0], axis_); tf.translation() = transform_to_parent_.translation(); return tf; } //============================================================================== template BallEulerJoint::BallEulerJoint(const std::shared_ptr& link_parent, const std::shared_ptr& link_child, const Transform3& transform_to_parent, const std::string& name) : Joint(link_parent, link_child, transform_to_parent, name) {} //============================================================================== template std::size_t BallEulerJoint::getNumDofs() const { return 3; } //============================================================================== template Transform3 BallEulerJoint::getLocalTransform() const { Matrix3 rot( AngleAxis((*joint_cfg_)[0], Eigen::Vector3::UnitX()) * AngleAxis((*joint_cfg_)[1], Eigen::Vector3::UnitY()) * AngleAxis((*joint_cfg_)[2], Eigen::Vector3::UnitZ())); Transform3 tf = Transform3::Identity(); tf.linear() = rot; return transform_to_parent_ * tf; } } // namespace fcl #endif