ROSEndEffector
ROS End-Effector package: provides a ROS-based set of standard interfaces to command robotics end-effectors in an agnostic fashion.
ActionComposed.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 IIT-HHCM
3  * Author: Davide Torielli
4  * email: davide.torielli@iit.it
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
20 
22  independent = true;
23  nInnerActions = 0;
24  type = Action::Type::Composed;
25 }
26 
28  independent = true;
29  nInnerActions = 0;
30  type = Action::Type::Composed;
31 }
32 
34  this->independent = independent;
35  nInnerActions = 0;
36  type = Action::Type::Composed;
37 }
38 
40  return nInnerActions;
41 }
42 
44  return independent;
45 }
46 
47 std::vector<std::string> ROSEE::ActionComposed::getInnerActionsNames() const {
48  return innerActionsNames;
49 }
50 
52  return (nInnerActions == 0);
53 }
54 
55 
56 bool ROSEE::ActionComposed::sumAction ( ROSEE::Action::Ptr action, double jointPosScaleFactor, unsigned int jointPosIndex )
57 {
58 
59  if ( ! checkIndependency(action) ) {
60  return false; //cant add this primitive
61  }
62 
63  if ( jointPosIndex > action->getAllJointPos().size()-1 ) {
64  std::cerr << "[ACTIONCOMPOSED:: " << __func__ << "] The given jointPosindex " << jointPosIndex
65  << " exceed the number " << action->getAllJointPos().size() << " of jointpos of passed action" << std::endl;
66  return false;
67  }
68 
69  if ( nInnerActions > 0 &&
70  (! ROSEE::Utils::keys_equal(action->getAllJointPos().at(jointPosIndex), jointPos)) ) {
71  std::cerr << "[ACTIONCOMPOSED:: " << __func__ << "] The action passed as argument has different keys in jointPosmap"
72  << " respect to the others inserted in this composed action " << std::endl;
73  return false;
74  }
75 
76  if (jointPosScaleFactor < 0) {
77  std::cerr << "[ACTIONCOMPOSED:: " << __func__ << "] You can not scale the joint position of the action to be inserted by a "
78  << "value less than 0; jointPosScaleFactor passed is: " << jointPosScaleFactor << std::endl;
79  return false;
80  }
81 
82  if (jointPosScaleFactor > 1) {
83  std::wcerr << "[ACTIONCOMPOSED:: " << __func__ << "] WARNING, You are scaling with a value greater than 1 "
84  << " this could cause to command position over the joint limits; jointPosScaleFactor passed is: " << jointPosScaleFactor << std::endl;
85  }
86 
87  JointPos actionJP = action->getAllJointPos().at(jointPosIndex) * jointPosScaleFactor;
88  JointsInvolvedCount actionJIC = action->getJointsInvolvedCount();
89 
90  if (nInnerActions == 0) { //first primitive inserted
91 
92  for (auto joint : actionJP ){
93  jointsInvolvedCount.insert ( std::make_pair (joint.first, actionJIC.at(joint.first) ) );
94  jointPos.insert ( std::make_pair (joint.first, joint.second) );
95  }
96 
97  } else {
98 
99  if (independent) {
100 
101  //if here, action is independent, we can add the joints states
102  for ( auto joint : actionJP ){
103 
104  if ( actionJIC.at (joint.first ) > 0 ) {
105 
106  jointPos.at(joint.first) = joint.second;
107  jointsInvolvedCount.at(joint.first) += actionJIC.at (joint.first );
108  //+= or = is the same for the checks done before
109  }
110  }
111 
112  } else {
113  // for each joint, add the state's value to the mean
114  // (number of element in the previous mean is given by jointsInvolvedCount.at(x))
115 
116  for ( auto joint : actionJP ) {
117  if ( actionJIC.at( joint.first ) == 0 ) {
118  continue; //if the action that is being added has this joint not setted, not consider it
119  }
120 
121  //update the count
122  jointsInvolvedCount.at(joint.first) += actionJIC.at (joint.first );
123 
124  //iterate all dofs of jointPos
125  for (unsigned int dof = 0; dof < joint.second.size(); dof++ ) {
126 
127  double mean = jointPos.at( joint.first ).at(dof) +
128  ( (joint.second.at(dof) - jointPos.at(joint.first).at(dof)) /
129  jointsInvolvedCount.at(joint.first) );
130 
131  jointPos.at(joint.first).at(dof) = mean;
132  }
133  }
134  }
135  }
136 
137  innerActionsNames.push_back ( action->getName() );
138  for ( auto it: action->getFingersInvolved() ) {
139  fingersInvolved.insert ( it );
140  }
141 
142  nInnerActions ++;
143 
144  return true;
145 }
146 
148 
149  if (!independent) {
150 
151  } else if (nInnerActions == 0 ) {
152 
153  for ( auto jic : action->getJointsInvolvedCount() ){
154  if ( jic.second > 1 ) {
155  // if action is dependent we check that all its joints are setted only once
156  // so we can teoretically add a "dipendent" action if all its joints are setted once
157  return false; //cant add this primitive
158  }
159  }
160 
161  } else {
162 
163  for ( auto jic : action->getJointsInvolvedCount() ){
164  if ( jic.second + jointsInvolvedCount.at(jic.first) > 1 ) {
165  // we use the sum so also if action is dependent we check that all its joints are setted once
166  // so we can teoretically add a "dipendent" action if all its joints are setted once
167  return false; //cant add this primitive
168  }
169  }
170  }
171 
172  return true;
173 }
174 
175 
177 
178  std::stringstream output;
179 
180  output << "Composed Action '" << name;
181  independent ? output << "' (independent):" : output << "' (not independent):" ;
182  output << std::endl;
183 
184  output << "Composed by " << nInnerActions << " inner action: [" ;
185  for (auto it : innerActionsNames) {
186  output << it << ", ";
187  }
188  output.seekp (-2, output.cur); //to remove the last comma (and space)
189  output << "]" << std::endl;
190 
191  output << "Fingers involved: [" ;
192  for (auto it : fingersInvolved) {
193  output << it << ", ";
194  }
195  output.seekp (-2, output.cur); //to remove the last comma (and space)
196  output << "]" << std::endl;
197 
198  output << "Each joint influenced by x inner action:" << std::endl;
199  output << jointsInvolvedCount;
200 
201  output << "JointPos:" << std::endl;
202  output << jointPos << std::endl;
203 
204  std::cout << output.str();
205 }
206 
207 
208 void ROSEE::ActionComposed::emitYaml ( YAML::Emitter& out) const {
209 
210  out << YAML::BeginMap << YAML::Key << name << YAML::Value << YAML::BeginMap ;
211  out << YAML::Key << "Type" << YAML::Value << type;
212  out << YAML::Key << "Independent" << YAML::Value << independent;
213  out << YAML::Key << "NInnerActions" << YAML::Value << nInnerActions;
214  out << YAML::Key << "InnerActionsNames" << YAML::Value << YAML::Flow << innerActionsNames;
215  out << YAML::Key << "FingersInvolved" << YAML::Value << YAML::Flow << fingersInvolved;
216  out << YAML::Key << "JointsInvolvedCount" << YAML::Value << YAML::BeginMap;
217  for (const auto &jointCount : jointsInvolvedCount ) {
218  out << YAML::Key << jointCount.first;
219  out << YAML::Value << jointCount.second;
220  }
221  out << YAML::EndMap;
222 
223  out << YAML::Key << "JointPos" << YAML::Value << YAML::BeginMap;
224  for (const auto &joint : jointPos) {
225  out << YAML::Key << joint.first;
226  out << YAML::Value << YAML::Flow << joint.second; //vector of double is emitted like Seq
227  }
228  out << YAML::EndMap;
229  out << YAML::EndMap;
230  out << YAML::EndMap;
231 }
232 
233 // if parsed, we dont have the link with the primitives... so primitiveObjects is empty
234 bool ROSEE::ActionComposed::fillFromYaml ( YAML::const_iterator yamlIt ) {
235 
236  name = yamlIt->first.as<std::string>();
237 
238  for (auto keyValue = yamlIt->second.begin(); keyValue != yamlIt->second.end(); ++keyValue ) {
239 
240  std::string key = keyValue->first.as<std::string>();
241 
242  if ( key.compare ("Independent") == 0 ) {
243  independent = keyValue->second.as<bool>();
244 
245  } else if ( key.compare ("NInnerActions") == 0 ) {
246  nInnerActions = keyValue->second.as <unsigned int>();
247 
248  } else if ( key.compare ("Type") == 0 ) {
249  if (ROSEE::Action::Type::Composed != static_cast<ROSEE::Action::Type> ( keyValue->second.as <unsigned int>() )) {
250  std::cout << "[COMPOSED ACTION::" << __func__ << "] Error, found type " << keyValue->second.as <unsigned int>()
251  << "instead of Composed type (" << ROSEE::Action::Type::Composed << ")" << std::endl;
252  return false;
253  }
254  type = ROSEE::Action::Type::Composed;
255 
256  } else if ( key.compare ("InnerActionsNames") == 0 ) {
257  innerActionsNames = keyValue->second.as <std::vector <std::string> >();
258 
259  } else if ( key.compare ("FingersInvolved") == 0 ) {
260  auto tempVect = keyValue->second.as <std::vector <std::string> > ();
261  fingersInvolved.insert ( tempVect.begin(), tempVect.end() );
262 
263  } else if ( key.compare ("JointsInvolvedCount") == 0 ) {
264  jointsInvolvedCount = keyValue->second.as < JointsInvolvedCount >();
265 
266  } else if ( key.compare ("JointPos") == 0 ) {
267  jointPos = keyValue->second.as < JointPos >();
268 
269  } else {
270  std::cout << "[COMPOSED ACTION PARSER] Error, not known key " << key << std::endl;
271  return false;
272  }
273  }
274  return true;
275 }
276 
277 
278 
std::string name
Definition: Action.h:146
std::vector< std::string > innerActionsNames
std::map< std::string, std::vector< double > > JointPos
The map to describe the position of all actuated joints.
Definition: Action.h:40
std::map< std::string, unsigned int > JointsInvolvedCount
The map to describe, how many times a joint is set by the action.
Definition: Action.h:63
bool empty()
Check if the action composed is empty.
bool keys_equal(std::map< keyType, valueType1 > const &lhs, std::map< keyType, valueType2 > const &rhs)
Return false if two maps have different keys.
Definition: Utils.h:182
unsigned int nInnerActions
virtual void print() const override
Print info about this action (name, jointpos, inner actions names, and other)
Class to handle a generic, simple action.
Definition: ActionGeneric.h:32
std::vector< std::string > getInnerActionsNames() const
bool checkIndependency(ROSEE::Action::Ptr action)
unsigned int numberOfInnerActions() const
bool isIndependent() const
Action::Type type
Definition: Action.h:147
virtual bool sumAction(ROSEE::Action::Ptr action, double jointPosScaleFactor=1.0, unsigned int jointPosIndex=0)
Function to add another action to this one.
JointsInvolvedCount jointsInvolvedCount
Definition: Action.h:149
std::shared_ptr< Action > Ptr
Definition: Action.h:75
virtual bool fillFromYaml(YAML::const_iterator yamlIt) override
Fill the internal data with infos taken from yaml file.
virtual void emitYaml(YAML::Emitter &out) const override
Emit info in a file with yaml format.
std::set< std::string > fingersInvolved
Definition: Action.h:148