/* * Copyright 2010, * Florent Lamiraux * * CNRS * */ #ifndef SOT_DEVICE_HH #define SOT_DEVICE_HH /* --------------------------------------------------------------------- */ /* --- INCLUDE --------------------------------------------------------- */ /* --------------------------------------------------------------------- */ #include <pinocchio/fwd.hpp> /* -- MaaL --- */ #include <dynamic-graph/linear-algebra.h> /* SOT */ #include <dynamic-graph/all-signals.h> #include <dynamic-graph/entity.h> #include <sot/core/matrix-geometry.hh> #include "sot/core/api.hh" #include "sot/core/periodic-call.hh" namespace dynamicgraph { namespace sot { /// Define the type of input expected by the robot enum ControlInput { CONTROL_INPUT_NO_INTEGRATION = 0, CONTROL_INPUT_ONE_INTEGRATION = 1, CONTROL_INPUT_TWO_INTEGRATION = 2, CONTROL_INPUT_SIZE = 3 }; const std::string ControlInput_s[] = {"noInteg", "oneInteg", "twoInteg"}; /* --------------------------------------------------------------------- */ /* --- CLASS ----------------------------------------------------------- */ /* --------------------------------------------------------------------- */ class SOT_CORE_EXPORT Device : public Entity { public: static const std::string CLASS_NAME; virtual const std::string &getClassName(void) const { return CLASS_NAME; } enum ForceSignalSource { FORCE_SIGNAL_RLEG, FORCE_SIGNAL_LLEG, FORCE_SIGNAL_RARM, FORCE_SIGNAL_LARM }; protected: dynamicgraph::Vector state_; dynamicgraph::Vector velocity_; bool sanityCheck_; dynamicgraph::Vector vel_control_; ControlInput controlInputType_; bool withForceSignals[4]; PeriodicCall periodicCallBefore_; PeriodicCall periodicCallAfter_; double timestep_; /// \name Robot bounds used for sanity checks /// \{ Vector upperPosition_; Vector upperVelocity_; Vector upperTorque_; Vector lowerPosition_; Vector lowerVelocity_; Vector lowerTorque_; /// \} public: /* --- CONSTRUCTION --- */ Device(const std::string &name); /* --- DESTRUCTION --- */ virtual ~Device(); virtual void setStateSize(const unsigned int &size); virtual void setState(const dynamicgraph::Vector &st); void setVelocitySize(const unsigned int &size); virtual void setVelocity(const dynamicgraph::Vector &vel); virtual void setSecondOrderIntegration(); virtual void setNoIntegration(); virtual void setControlInputType(const std::string &cit); virtual void increment(const double &dt = 5e-2); /// \name Sanity check parameterization /// \{ void setSanityCheck(const bool &enableCheck); void setPositionBounds(const Vector &lower, const Vector &upper); void setVelocityBounds(const Vector &lower, const Vector &upper); void setTorqueBounds(const Vector &lower, const Vector &upper); /// \} PeriodicCall &periodicCallBefore() { return periodicCallBefore_; } PeriodicCall &periodicCallAfter() { return periodicCallAfter_; } public: /* --- DISPLAY --- */ virtual void display(std::ostream &os) const; virtual void cmdDisplay(); SOT_CORE_EXPORT friend std::ostream &operator<<(std::ostream &os, const Device &r) { r.display(os); return os; } public: /* --- SIGNALS --- */ dynamicgraph::SignalPtr<dynamicgraph::Vector, int> controlSIN; dynamicgraph::SignalPtr<dynamicgraph::Vector, int> attitudeSIN; dynamicgraph::SignalPtr<dynamicgraph::Vector, int> zmpSIN; /// \name Device current state. /// \{ dynamicgraph::Signal<dynamicgraph::Vector, int> stateSOUT; dynamicgraph::Signal<dynamicgraph::Vector, int> velocitySOUT; dynamicgraph::Signal<MatrixRotation, int> attitudeSOUT; /*! \brief The current state of the robot from the command viewpoint. */ dynamicgraph::Signal<dynamicgraph::Vector, int> motorcontrolSOUT; dynamicgraph::Signal<dynamicgraph::Vector, int> previousControlSOUT; /*! \brief The ZMP reference send by the previous controller. */ dynamicgraph::Signal<dynamicgraph::Vector, int> ZMPPreviousControllerSOUT; /// \} /// \name Real robot current state /// This corresponds to the real encoders values and take into /// account the stabilization step. Therefore, this usually /// does *not* match the state control input signal. /// \{ /// Motor positions dynamicgraph::Signal<dynamicgraph::Vector, int> robotState_; /// Motor velocities dynamicgraph::Signal<dynamicgraph::Vector, int> robotVelocity_; /// The force torque sensors dynamicgraph::Signal<dynamicgraph::Vector, int> *forcesSOUT[4]; /// Motor torques /// \todo why pseudo ? dynamicgraph::Signal<dynamicgraph::Vector, int> pseudoTorqueSOUT; /// \} protected: /// Compute roll pitch yaw angles of freeflyer joint. void integrateRollPitchYaw(dynamicgraph::Vector &state, const dynamicgraph::Vector &control, double dt); /// Store Position of free flyer joint MatrixHomogeneous ffPose_; /// Compute the new position, from the current control. /// /// When sanity checks are enabled, this checks that the control is within /// bounds. There are three cases, depending on what the control is: /// - position: checks that the position is within bounds, /// - velocity: checks that the velocity and the future position are /// within bounds, /// - acceleration: checks that the acceleration, the future velocity and /// position are within bounds. /// \todo in order to check the acceleration, we need /// pinocchio and the contact forces in order to estimate /// the joint torques for the given acceleration. virtual void integrate(const double &dt); protected: /// Get freeflyer pose const MatrixHomogeneous &freeFlyerPose() const; public: virtual void setRoot(const dynamicgraph::Matrix &root); virtual void setRoot(const MatrixHomogeneous &worldMwaist); private: // Intermediate variable to avoid dynamic allocation dynamicgraph::Vector forceZero6; }; } // namespace sot } // namespace dynamicgraph #endif /* #ifndef SOT_DEVICE_HH */