ROSEndEffector
ROS End-Effector package: provides a ROS-based set of standard interfaces to command robotics end-effectors in an agnostic fashion.
ActionPinchTight.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  ActionPinchGeneric ("pinchTight", 2, 3, ActionPrimitive::Type::PinchTight) { }
23 
24 ROSEE::ActionPinchTight::ActionPinchTight(unsigned int jointStateSetMaxSize) :
25  ActionPinchGeneric ("pinchTight", 2, jointStateSetMaxSize, ActionPrimitive::Type::PinchTight) { }
26 
27 ROSEE::ActionPinchTight::ActionPinchTight (std::pair <std::string, std::string> fingerNamesPair,
28  JointPos jp, collision_detection::Contact cont) :
29  ActionPinchGeneric ("pinchTight", 2, 3, ActionPrimitive::Type::PinchTight ) {
30 
31  //different from insertState, here we are sure the set is empty (we are in costructor)
32  fingersInvolved.insert(fingerNamesPair.first);
33  fingersInvolved.insert(fingerNamesPair.second);
34  actionStates.insert (std::make_pair (jp, cont) );
35 }
36 
37 ROSEE::ActionPinchTight::ActionPinchTight (std::string finger1, std::string finger2,
38  JointPos jp, collision_detection::Contact cont) :
39  ActionPinchGeneric ("pinchTight", 2, 3, ActionPrimitive::Type::PinchTight ) {
40 
41  //different from insertState, here we are sure the set is empty (we are in costructor)
42  fingersInvolved.insert(finger1);
43  fingersInvolved.insert(finger2);
44  actionStates.insert (std::make_pair (jp, cont) );
45 }
46 
48  return (actionStates.begin()->first);
49 }
50 
52  auto it = actionStates.begin();
53  unsigned int i = 1;
54  while (i < index ) {
55  ++ it;
56  }
57  return (it->first);
58 }
59 
60 std::vector < ROSEE::JointPos > ROSEE::ActionPinchTight::getAllJointPos() const{
61 
62  std::vector < JointPos > retVect;
63  retVect.reserve ( actionStates.size() );
64 
65  for (auto it : actionStates ) {
66  retVect.push_back(it.first);
67  }
68 
69  return retVect;
70 }
71 
72 
73 std::vector < ROSEE::ActionPinchTight::StateWithContact > ROSEE::ActionPinchTight::getActionStates () const {
74 
75  std::vector < ROSEE::ActionPinchTight::StateWithContact > retVect;
76  retVect.reserve ( actionStates.size() );
77 
78  for (auto it : actionStates ) {
79  retVect.push_back(it);
80  }
81 
82  return retVect;
83 
84 }
85 
86 bool ROSEE::ActionPinchTight::insertActionState (ROSEE::JointPos jp, collision_detection::Contact cont) {
87 
88  auto pairRet = actionStates.insert ( std::make_pair (jp, cont) ) ;
89 
90  if (! pairRet.second ) {
91  //TODO print error no insertion because depth is equal... very improbable
92  return false;
93  }
94 
95  if (actionStates.size() > maxStoredActionStates) {
96  //max capacity reached, we have to delete the last one
97  auto it = pairRet.first;
98 
99  if ( (++it) == actionStates.end() ){
100  // the new inserted is the last one and has to be erased
101  actionStates.erase(pairRet.first);
102  return false;
103  }
104 
105  // the new inserted is not the last one that has to be erased
106  auto lastElem = actionStates.end();
107  --lastElem;
108  actionStates.erase(lastElem);
109  }
110 
111  return true;
112 }
113 
114 
116 
117  std::stringstream output;
118  output << "ActionName: " << name << std::endl;
119 
120  output << "FingersInvolved: [";
121  for (auto fingName : fingersInvolved){
122  output << fingName << ", " ;
123  }
124  output.seekp (-2, output.cur); //to remove the last comma (and space)
125  output << "]" << std::endl;
126 
127  output << "JointsInvolvedCount: " << std::endl;;
128  output << jointsInvolvedCount << std::endl;
129 
130  unsigned int nActState = 1;
131  for (auto itemSet : actionStates) { //the element in the set
132  output << "Action_State_" << nActState << " :" << std::endl;
133 
134  output << "\t" << "JointStates:" << std::endl;
135  output << itemSet.first;
136  output << "\t" << "MoveitContact:" << std::endl;
137  output << "\t\tbody_name_1: " << itemSet.second.body_name_1 << std::endl;
138  output << "\t\tbody_name_2: " << itemSet.second.body_name_2 << std::endl;
139  output << "\t\tbody_type_1: " << itemSet.second.body_type_1 << std::endl;
140  output << "\t\tbody_type_2: " << itemSet.second.body_type_2 << std::endl;
141  output << "\t\tdepth: " << itemSet.second.depth << std::endl;
142  output << "\t\tnormal: " << "["<< itemSet.second.normal.x() << ", "
143  << itemSet.second.normal.y() << ", " << itemSet.second.normal.z() << "]" << std::endl;
144  output << "\t\tpos: " << "["<< itemSet.second.pos.x() << ", "
145  << itemSet.second.pos.y() << ", " << itemSet.second.pos.z() << "]" << std::endl;
146 
147  nActState++;
148  }
149  output << std::endl;
150 
151  std::cout << output.str();
152 
153 }
154 
155 
156 void ROSEE::ActionPinchTight::emitYaml ( YAML::Emitter& out ) const {
157 
158  out << YAML::Key << YAML::Flow << fingersInvolved;
159 
160  unsigned int nCont = 1;
161  out << YAML::Value << YAML::BeginMap;
162  out << YAML::Key << "PrimitiveType" << YAML::Value << primitiveType;
163  out << YAML::Key << "ActionName" << YAML::Value << name;
164  out << YAML::Key << "JointsInvolvedCount" << YAML::Value << YAML::BeginMap;
165  for (const auto &jointCount : jointsInvolvedCount ) {
166  out << YAML::Key << jointCount.first;
167  out << YAML::Value << jointCount.second;
168  }
169  out << YAML::EndMap;
170 
171  for (const auto & actionState : actionStates) { //.second is the set of ActionState
172 
173  std::string contSeq = "ActionState_" + std::to_string(nCont);
174  out << YAML::Key << contSeq;
175 
176  out << YAML::Value << YAML::BeginMap;
177  //actionState.first, the jointstates map
178  out << YAML::Key << "JointPos" << YAML::Value << YAML::BeginMap;
179  for (const auto &joint : actionState.first) {
180  out << YAML::Key << joint.first;
181  out << YAML::Value << YAML::Flow << joint.second; //vector of double is emitted like Seq
182  }
183  out << YAML::EndMap;
184 
185  //actionState.second, the optional
186  out << YAML::Key << "Optional" << YAML::Value;
187  emitYamlForContact ( actionState.second, out );
188 
189  out << YAML::EndMap;
190  nCont++;
191  }
192  out << YAML::EndMap;
193 
194 }
195 
196 
197 bool ROSEE::ActionPinchTight::fillFromYaml ( YAML::const_iterator yamlIt ) {
198 
199  std::vector <std::string> fingInvolvedVect = yamlIt->first.as <std::vector < std::string >> ();
200  for (const auto &it : fingInvolvedVect) {
201  fingersInvolved.insert(it);
202  }
203 
204  for ( YAML::const_iterator keyValue = yamlIt->second.begin(); keyValue != yamlIt->second.end(); ++keyValue) {
205 
206  std::string key = keyValue->first.as<std::string>();
207  if (key.compare("JointsInvolvedCount") == 0) {
208  jointsInvolvedCount = keyValue->second.as < JointsInvolvedCount > ();
209 
210  } else if (key.compare ("ActionName") == 0 ) {
211  name = keyValue->second.as <std::string> ();
212 
213  } else if (key.compare ("PrimitiveType") == 0) {
215  keyValue->second.as <unsigned int>() );
216  if (parsedType != primitiveType ) {
217  std::cerr << "[ERROR ActionPinchTight::" << __func__ << " parsed a type " << parsedType <<
218  " but this object has primitive type " << primitiveType << std::endl;
219  return false;
220  }
221 
222  } else if (key.compare(0, 12, "ActionState_") == 0) { //compare 12 caracters from index 0 of key
223 
224  JointPos jointPos;
225  collision_detection::Contact contact;
226  for(YAML::const_iterator asEl = keyValue->second.begin(); asEl != keyValue->second.end(); ++asEl) {
227 
228  //asEl can be the map JointPos or the map Optional
229  if (asEl->first.as<std::string>().compare ("JointPos") == 0 ) {
230  jointPos = asEl->second.as < JointPos >();
231  } else if (asEl->first.as<std::string>().compare ("Optional") == 0 ) {
232 
233  YAML::Node cont = asEl->second["MoveItContact"];
234  contact.body_name_1 = cont["body_name_1"].as < std::string >();
235  contact.body_name_2 = cont["body_name_2"].as < std::string >();
236  switch (cont["body_type_1"].as < int >())
237  {
238  case 0:
239  contact.body_type_1 = collision_detection::BodyType::ROBOT_LINK;
240  break;
241  case 1:
242  contact.body_type_1 = collision_detection::BodyType::ROBOT_ATTACHED;
243  break;
244  case 2:
245  contact.body_type_1 = collision_detection::BodyType::WORLD_OBJECT;
246  break;
247  default:
248  std::cout << "some error, body_type_1" << cont["body_type_1"].as < int >()
249  << "unknown" << std::endl;
250  contact.body_type_1 = collision_detection::BodyType::WORLD_OBJECT;
251  }
252  switch (cont["body_type_2"].as < int >())
253  {
254  case 0:
255  contact.body_type_2 = collision_detection::BodyType::ROBOT_LINK;
256  break;
257  case 1:
258  contact.body_type_2 = collision_detection::BodyType::ROBOT_ATTACHED;
259  break;
260  case 2:
261  contact.body_type_2 = collision_detection::BodyType::WORLD_OBJECT;
262  break;
263  default:
264  std::cout << "some error, body_type_2" << cont["body_type_2"].as < int >()
265  << "unknown" << std::endl;
266  contact.body_type_2 = collision_detection::BodyType::WORLD_OBJECT;
267  }
268  contact.depth = cont["depth"].as<double>();
269  std::vector < double > normVect = cont["normal"].as < std::vector <double> >();
270  std::vector < double > posVect = cont["pos"].as < std::vector <double> >();
271  contact.normal = Eigen::Vector3d (normVect.data() );
272  contact.pos = Eigen::Vector3d (posVect.data() );
273 
274  } else {
275  //ERRROr, only joinstates and optional at this level
276  std::cerr << "[ERROR ActionPinchTight::" << __func__ << "not know key "
277  << asEl->first.as<std::string>() <<
278  " found in the yaml file at this level" << std::endl;
279  return false;
280  }
281  }
282  actionStates.insert ( std::make_pair (jointPos, contact));
283 
284  } else {
285  std::cerr << "[ERROR ActionPinchTight::" << __func__ << "not know key " << key <<
286  " found in the yaml file" << std::endl;
287  return false;
288  }
289  }
290 
291  return true;
292 }
293 
294 bool ROSEE::ActionPinchTight::emitYamlForContact (collision_detection::Contact moveitContact, YAML::Emitter& out) const {
295 
296  out << YAML::BeginMap;
297  out << YAML::Key << "MoveItContact" << YAML::Value << YAML::BeginMap;
298  out << YAML::Key << "body_name_1";
299  out << YAML::Value << moveitContact.body_name_1;
300  out << YAML::Key << "body_name_2";
301  out << YAML::Value << moveitContact.body_name_2;
302  out << YAML::Key << "body_type_1";
303  out << YAML::Value << moveitContact.body_type_1;
304  out << YAML::Key << "body_type_2";
305  out << YAML::Value << moveitContact.body_type_2;
306  out << YAML::Key << "depth";
307  out << YAML::Value << moveitContact.depth;
308  out << YAML::Key << "normal";
309  std::vector < double > normal ( moveitContact.normal.data(), moveitContact.normal.data() + moveitContact.normal.rows());
310  out << YAML::Value << YAML::Flow << normal;
311  out << YAML::Key << "pos";
312  std::vector < double > pos ( moveitContact.pos.data(), moveitContact.pos.data() + moveitContact.pos.rows());
313  out << YAML::Value << YAML::Flow << pos;
314  out << YAML::EndMap;
315  out << YAML::EndMap;
316 
317  return true;
318 }
Type
Enum useful to discriminate each action when, for example, we want to parse a file if you change thi...
Definition: Action.h:82
Virtual class, Base of all the primitive actions.
std::vector< ROSEE::ActionPinchTight::StateWithContact > getActionStates() const
Specific get for the ActionPinchTight to return the state with contact info.
void emitYaml(YAML::Emitter &) const override
Function to fill the argument passed with info about the action.
std::string name
Definition: Action.h:146
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
A base virtual class for the PinchTight and PinchLoose classes.
void print() const override
For the pinch, we override these function to print, emit and parse the optional info Contact...
Type
Enum useful to discriminate each primitive action when, for example, we want to parse a file if you ...
std::vector< ROSEE::JointPos > getAllJointPos() const override
Return all the joint position stored.
JointsInvolvedCount jointsInvolvedCount
Definition: Action.h:149
bool emitYamlForContact(collision_detection::Contact, YAML::Emitter &) const
private function to be called by the emitYaml
bool fillFromYaml(YAML::const_iterator yamlIt) override
function to fill members of the Action with infos taken from yaml files
const unsigned int maxStoredActionStates
std::set< StateWithContact, depthComp > actionStates
For each pair, we want a set of action because we want to store (in general) more possible way to do ...
JointPos getJointPos() const override
Get the position related to this action.
std::set< std::string > fingersInvolved
Definition: Action.h:148
bool insertActionState(JointPos, collision_detection::Contact)
function to insert a single action in the actionStates set of possible action.