| 1 |  |  | // Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse, | 
    
    | 2 |  |  | // JRL, CNRS/AIST. | 
    
    | 3 |  |  |  | 
    
    | 4 |  |  | #include <dynamic-graph/command-bind.h> | 
    
    | 5 |  |  | #include <dynamic-graph/factory.h> | 
    
    | 6 |  |  | #include <dynamic-graph/pool.h> | 
    
    | 7 |  |  |  | 
    
    | 8 |  |  | #include <boost/assign/list_of.hpp> | 
    
    | 9 |  |  | #include <boost/numeric/conversion/cast.hpp> | 
    
    | 10 |  |  | #include <sot/core/feature-posture.hh> | 
    
    | 11 |  |  | #include <string> | 
    
    | 12 |  |  | namespace dg = ::dynamicgraph; | 
    
    | 13 |  |  |  | 
    
    | 14 |  |  | using dynamicgraph::sot::FeatureAbstract; | 
    
    | 15 |  |  |  | 
    
    | 16 |  |  | namespace dynamicgraph { | 
    
    | 17 |  |  | namespace sot { | 
    
    | 18 |  |  | using command::Command; | 
    
    | 19 |  |  | using command::Value; | 
    
    | 20 |  |  |  | 
    
    | 21 |  |  | class FeaturePosture::SelectDof : public Command { | 
    
    | 22 |  |  |  public: | 
    
    | 23 |  |  |   virtual ~SelectDof() {} | 
    
    | 24 |  |  |   SelectDof(FeaturePosture &entity, const std::string &docstring) | 
    
    | 25 |  |  |       : Command(entity, boost::assign::list_of(Value::UNSIGNED)(Value::BOOL), | 
    
    | 26 |  |  |                 docstring) {} | 
    
    | 27 |  |  |   virtual Value doExecute() { | 
    
    | 28 |  |  |     FeaturePosture &feature = static_cast<FeaturePosture &>(owner()); | 
    
    | 29 |  |  |     std::vector<Value> values = getParameterValues(); | 
    
    | 30 |  |  |     unsigned int dofId = values[0].value(); | 
    
    | 31 |  |  |     bool control = values[1].value(); | 
    
    | 32 |  |  |     feature.selectDof(dofId, control); | 
    
    | 33 |  |  |     return Value(); | 
    
    | 34 |  |  |   } | 
    
    | 35 |  |  | };  // class SelectDof | 
    
    | 36 |  |  |  | 
    
    | 37 |  |  | FeaturePosture::FeaturePosture(const std::string &name) | 
    
    | 38 |  |  |     : FeatureAbstract(name), | 
    
    | 39 |  |  |       state_(NULL, "FeaturePosture(" + name + ")::input(Vector)::state"), | 
    
    | 40 |  |  |       posture_(0, "FeaturePosture(" + name + ")::input(Vector)::posture"), | 
    
    | 41 |  |  |       postureDot_(0, "FeaturePosture(" + name + ")::input(Vector)::postureDot"), | 
    
    | 42 |  |  |       activeDofs_(), | 
    
    | 43 |  |  |       nbActiveDofs_(0) { | 
    
    | 44 |  |  |   signalRegistration(state_ << posture_ << postureDot_); | 
    
    | 45 |  |  |  | 
    
    | 46 |  |  |   errorSOUT.addDependency(state_); | 
    
    | 47 |  |  |   jacobianSOUT.setConstant(Matrix()); | 
    
    | 48 |  |  |  | 
    
    | 49 |  |  |   std::string docstring; | 
    
    | 50 |  |  |   docstring = | 
    
    | 51 |  |  |       "    \n" | 
    
    | 52 |  |  |       "    Select degree of freedom to control\n" | 
    
    | 53 |  |  |       "    \n" | 
    
    | 54 |  |  |       "      input:\n" | 
    
    | 55 |  |  |       "        - positive integer: rank of degree of freedom,\n" | 
    
    | 56 |  |  |       "        - boolean: whether to control the selected degree of " | 
    
    | 57 |  |  |       "freedom.\n" | 
    
    | 58 |  |  |       "    \n" | 
    
    | 59 |  |  |       "      Note: rank should be more than 5 since posture is " | 
    
    | 60 |  |  |       "independent\n" | 
    
    | 61 |  |  |       "        from freeflyer position.\n" | 
    
    | 62 |  |  |       "    \n"; | 
    
    | 63 |  |  |   addCommand("selectDof", new SelectDof(*this, docstring)); | 
    
    | 64 |  |  | } | 
    
    | 65 |  |  |  | 
    
    | 66 |  |  | FeaturePosture::~FeaturePosture() {} | 
    
    | 67 |  |  |  | 
    
    | 68 |  |  | unsigned int &FeaturePosture::getDimension(unsigned int &res, int) { | 
    
    | 69 |  |  |   res = static_cast<unsigned int>(nbActiveDofs_); | 
    
    | 70 |  |  |   return res; | 
    
    | 71 |  |  | } | 
    
    | 72 |  |  |  | 
    
    | 73 |  |  | dg::Vector &FeaturePosture::computeError(dg::Vector &res, int t) { | 
    
    | 74 |  |  |   const dg::Vector &state = state_.access(t); | 
    
    | 75 |  |  |   const dg::Vector &posture = posture_.access(t); | 
    
    | 76 |  |  |  | 
    
    | 77 |  |  |   res.resize(nbActiveDofs_); | 
    
    | 78 |  |  |   std::size_t index = 0; | 
    
    | 79 |  |  |   for (std::size_t i = 0; i < activeDofs_.size(); ++i) { | 
    
    | 80 |  |  |     if (activeDofs_[i]) { | 
    
    | 81 |  |  |       res(index) = state(i) - posture(i); | 
    
    | 82 |  |  |       index++; | 
    
    | 83 |  |  |     } | 
    
    | 84 |  |  |   } | 
    
    | 85 |  |  |   return res; | 
    
    | 86 |  |  | } | 
    
    | 87 |  |  |  | 
    
    | 88 |  |  | dg::Matrix &FeaturePosture::computeJacobian(dg::Matrix &, int) { | 
    
    | 89 |  |  |   throw std::runtime_error( | 
    
    | 90 |  |  |       "jacobian signal should be constant." | 
    
    | 91 |  |  |       " This function should never be called"); | 
    
    | 92 |  |  | } | 
    
    | 93 |  |  |  | 
    
    | 94 |  |  | dg::Vector &FeaturePosture::computeErrorDot(dg::Vector &res, int t) { | 
    
    | 95 |  |  |   const Vector &postureDot = postureDot_.access(t); | 
    
    | 96 |  |  |  | 
    
    | 97 |  |  |   res.resize(nbActiveDofs_); | 
    
    | 98 |  |  |   std::size_t index = 0; | 
    
    | 99 |  |  |   for (std::size_t i = 0; i < activeDofs_.size(); ++i) { | 
    
    | 100 |  |  |     if (activeDofs_[i]) res(index++) = -postureDot(i); | 
    
    | 101 |  |  |   } | 
    
    | 102 |  |  |   return res; | 
    
    | 103 |  |  | } | 
    
    | 104 |  |  |  | 
    
    | 105 |  |  | void FeaturePosture::selectDof(unsigned dofId, bool control) { | 
    
    | 106 |  |  |   const Vector &state = state_.accessCopy(); | 
    
    | 107 |  |  |   const Vector &posture = posture_.accessCopy(); | 
    
    | 108 |  |  |   std::size_t dim(state.size()); | 
    
    | 109 |  |  |  | 
    
    | 110 |  |  |   if (dim != (std::size_t)posture.size()) { | 
    
    | 111 |  |  |     throw std::runtime_error("Posture and State should have same dimension."); | 
    
    | 112 |  |  |   } | 
    
    | 113 |  |  |   // If activeDof_ vector not initialized, initialize it | 
    
    | 114 |  |  |   if (activeDofs_.size() != dim) { | 
    
    | 115 |  |  |     activeDofs_ = std::vector<bool>(dim, false); | 
    
    | 116 |  |  |     nbActiveDofs_ = 0; | 
    
    | 117 |  |  |   } | 
    
    | 118 |  |  |  | 
    
    | 119 |  |  |   // Check that selected dof id is valid | 
    
    | 120 |  |  |   if (dofId >= dim) { | 
    
    | 121 |  |  |     std::ostringstream oss; | 
    
    | 122 |  |  |     oss << "dof id should less than state dimension: " << dim << ". Received " | 
    
    | 123 |  |  |         << dofId << "."; | 
    
    | 124 |  |  |     throw ExceptionAbstract(ExceptionAbstract::TOOLS, oss.str()); | 
    
    | 125 |  |  |   } | 
    
    | 126 |  |  |  | 
    
    | 127 |  |  |   if (control) { | 
    
    | 128 |  |  |     if (!activeDofs_[dofId]) { | 
    
    | 129 |  |  |       activeDofs_[dofId] = true; | 
    
    | 130 |  |  |       nbActiveDofs_++; | 
    
    | 131 |  |  |     } | 
    
    | 132 |  |  |   } else {  // control = false | 
    
    | 133 |  |  |     if (activeDofs_[dofId]) { | 
    
    | 134 |  |  |       activeDofs_[dofId] = false; | 
    
    | 135 |  |  |       nbActiveDofs_--; | 
    
    | 136 |  |  |     } | 
    
    | 137 |  |  |   } | 
    
    | 138 |  |  |   // recompute jacobian | 
    
    | 139 |  |  |   Matrix J(Matrix::Zero(nbActiveDofs_, dim)); | 
    
    | 140 |  |  |  | 
    
    | 141 |  |  |   std::size_t index = 0; | 
    
    | 142 |  |  |   for (std::size_t i = 0; i < activeDofs_.size(); ++i) { | 
    
    | 143 |  |  |     if (activeDofs_[i]) { | 
    
    | 144 |  |  |       J(index, i) = 1; | 
    
    | 145 |  |  |       index++; | 
    
    | 146 |  |  |     } | 
    
    | 147 |  |  |   } | 
    
    | 148 |  |  |  | 
    
    | 149 |  |  |   jacobianSOUT.setConstant(J); | 
    
    | 150 |  |  | } | 
    
    | 151 |  |  |  | 
    
    | 152 |  |  | DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(FeaturePosture, "FeaturePosture"); | 
    
    | 153 |  |  | }  // namespace sot | 
    
    | 154 |  |  | }  // namespace dynamicgraph |