text: // Copyright  (C)  2007  Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
  
  // Version: 1.0
  // Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
  // Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
  // URL: http://www.orocos.org/kdl
  
  // This library is free software; you can redistribute it and/or
  // modify it under the terms of the GNU Lesser General Public
  // License as published by the Free Software Foundation; either
  // version 2.1 of the License, or (at your option) any later version.
  
  // This library is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  // Lesser General Public License for more details.
  
  // You should have received a copy of the GNU Lesser General Public
  // License along with this library; if not, write to the Free Software
  // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  
  
  #ifndef KDL_SEGMENT_HPP
  #define KDL_SEGMENT_HPP
  
  #include "frames.hpp"
  #include "rigidbodyinertia.hpp"
  #include "joint.hpp"
  #include <vector>
  
  namespace KDL {
  
      /**
  	  * \brief This class encapsulates a simple segment, that is a "rigid
  	  * body" (i.e., a frame and a rigid body inertia) with a joint and with
  	  * "handles", root and tip to connect to other segments.
       *
       * A simple segment is described by the following properties :
       *      - Joint
       *      - Rigid Body Inertia: of the rigid body part of the Segment
       *      - Offset from the end of the joint to the tip of the segment:
       *        the joint is located at the root of the segment.
       *
       * @ingroup KinematicFamily
       */
      class Segment {
          friend class Chain;
      private:
          std::string name;
          Joint joint;
          RigidBodyInertia I;
          Frame f_tip;
  
      public:
          /**
           * Constructor of the segment
           *
           * @param name name of the segment
           * @param joint joint of the segment, default:
           * Joint(Joint::None)
           * @param f_tip frame from the end of the joint to the tip of
           * the segment, default: Frame::Identity()
           * @param M rigid body inertia of the segment, default: Inertia::Zero()
           */
          explicit Segment(const std::string& name, const Joint& joint=Joint(Joint::None), const Frame& f_tip=Frame::Identity(),const RigidBodyInertia& I = RigidBodyInertia::Zero());
          /**
           * Constructor of the segment
           *
           * @param joint joint of the segment, default:
           * Joint(Joint::None)
           * @param f_tip frame from the end of the joint to the tip of
           * the segment, default: Frame::Identity()
           * @param M rigid body inertia of the segment, default: Inertia::Zero()
           */
          explicit Segment(const Joint& joint=Joint(Joint::None), const Frame& f_tip=Frame::Identity(),const RigidBodyInertia& I = RigidBodyInertia::Zero());
          Segment(const Segment& in);
          Segment& operator=(const Segment& arg);
  
          virtual ~Segment();
  
          /**
           * Request the pose of the segment, given the joint position q.
           *
           * @param q 1D position of the joint
           *
           * @return pose from the root to the tip of the segment
           */
          Frame pose(const double& q)const;
          /**
           * Request the 6D-velocity of the tip of the segment, given
           * the joint position q and the joint velocity qdot.
           *
           * @param q 1D position of the joint
           * @param qdot 1D velocity of the joint
           *
           * @return 6D-velocity of the tip of the segment, expressed
           *in the base-frame of the segment(root) and with the tip of
           *the segment as reference point.
           */
          Twist twist(const double& q,const double& qdot)const;
  
          /**
           * Request the name of the segment
           *
           *
           * @return const reference to the name of the segment
           */
          const std::string& getName()const
          {
              return name;
          }
          /**
           * Request the joint of the segment
           *
           *
           * @return const reference to the joint of the segment
           */
          const Joint& getJoint()const
          {
              return joint;
          }
          /**
           * Request the inertia of the segment
           *
           *
           * @return const reference to the inertia of the segment
           */
          const RigidBodyInertia& getInertia()const
          {
              return I;
          }
          /**
           * Request the inertia of the segment
           *
           *
           * @return const reference to the inertia of the segment
           */
          void setInertia(const RigidBodyInertia& Iin)
          {
              this->I=Iin;
          }
  
          /**
           * Request the pose from the joint end to the tip of the
           *segment.
           *
           * @return the original parent end - segment end pose.
           */
          Frame getFrameToTip()const
          {
              
              return joint.pose(0)*f_tip;
          }
  
          /**
           * Set the pose from the joint end to the tip of the
           * segment.
           *
           * @param f_tip_new pose from the joint end to the tip of the segment
           */
          void setFrameToTip(const Frame& f_tip_new);
      };
  }//end of namespace KDL
  
  #endif
  