ROSEndEffector
ROS End-Effector package: provides a ROS-based set of standard interfaces to command robotics end-effectors in an agnostic fashion.
ActionTimed.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 <copyright holder> <email>
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
20  type = Action::Type::Timed;
21 }
22 
24 
25 }
26 
28  return jointPosFinal;
29 }
30 
31 std::vector<ROSEE::JointPos> ROSEE::ActionTimed::getAllJointPos() const {
32 
33  std::vector<ROSEE::JointPos> jpVect;
34  jpVect.reserve (actionsNamesOrdered.size());
35  for (auto actName : actionsNamesOrdered) {
36  jpVect.push_back( actionsJointPosMap.at (actName) );
37  }
38  return jpVect;
39 }
40 
41 std::vector<ROSEE::JointsInvolvedCount> ROSEE::ActionTimed::getAllJointCountAction() const {
42 
43  std::vector<ROSEE::JointsInvolvedCount> jcVect;
44  jcVect.reserve (actionsNamesOrdered.size());
45  for (auto actName : actionsNamesOrdered) {
46  jcVect.push_back( actionsJointCountMap.at (actName) );
47  }
48  return jcVect;
49 }
50 
51 std::vector<std::pair<double, double> > ROSEE::ActionTimed::getAllActionMargins() const {
52 
53  std::vector <std::pair <double,double> > timeVect;
54  timeVect.reserve (actionsNamesOrdered.size());
55  for (auto actName : actionsNamesOrdered) {
56  timeVect.push_back( actionsTimeMarginsMap.at (actName) );
57  }
58  return timeVect;
59 }
60 
62 
63  auto it = actionsJointPosMap.find(actionName);
64 
65  if ( it != actionsJointPosMap.end() ) {
66  return (it->second);
67 
68  } else {
69  std::cerr << "[ACTIONTIMED:: " << __func__ << "] ERROR: action " << actionName << " not present in this composed timed action" << std::endl;
70  return ROSEE::JointPos();
71  }
72 }
73 
75 
76  auto it = actionsJointCountMap.find(actionName);
77 
78  if ( it != actionsJointCountMap.end() ) {
79  return (it->second);
80 
81  } else {
82  std::cerr << "[ACTIONTIMED:: " << __func__ << "] ERROR: action " << actionName << " not present in this composed timed action" << std::endl;
84  }
85 }
86 
87 
88 std::pair <double, double> ROSEE::ActionTimed::getActionMargins ( std::string actionName ) const {
89 
90  auto it = actionsTimeMarginsMap.find(actionName);
91 
92  if ( it != actionsTimeMarginsMap.end() ) {
93  return ( it->second );
94 
95  } else {
96  std::cerr << "[ACTIONTIMED:: " << __func__ << "] ERROR: action " << actionName << " not present in this composed timed action" << std::endl;
97  return std::make_pair(-1, -1);
98  }
99 }
100 
101 std::vector<std::string> ROSEE::ActionTimed::getInnerActionsNames() const {
102  return actionsNamesOrdered;
103 }
104 
105 
107 
108  std::stringstream output;
109 
110  output << "Timed Action '" << name << "'" << std::endl;
111 
112  output << "\tNice TimeLine:" << std::endl << "\t\t";
113  for ( auto it : actionsNamesOrdered ) {
114  output << actionsTimeMarginsMap.at(it).first << " -----> " << it << " -----> " << actionsTimeMarginsMap.at(it).second << " + ";
115  }
116  output.seekp (-3, output.cur); //to remove the last --+--
117  output << std::endl;
118 
119  output << "\tJointPos of each actions, in order of execution:\n";
120  for ( auto actionName : actionsNamesOrdered ) {
121  output << "\t" << actionName << std::endl;
122  output << actionsJointPosMap.at(actionName) << std::endl;
123  }
124 
125  output << "\tJointPos final, the sum of all joint pos of each inner action:\n";
126  output << jointPosFinal << std::endl;
127 
128  output << "\tFingers involved: [" ;
129  for (auto it : fingersInvolved) {
130  output << it << ", ";
131  }
132  output.seekp (-2, output.cur); //to remove the last comma (and space)
133  output << "]" << std::endl;
134 
135  output << "\tEach joint influenced by x inner action:" << std::endl;
136  output << jointsInvolvedCount << std::endl;
137 
138  std::cout << output.str();
139 
140 }
141 
142 void ROSEE::ActionTimed::emitYaml(YAML::Emitter& out) const {
143 
144  out << YAML::BeginMap << YAML::Key << name << YAML::Value << YAML::BeginMap ;
145  std::string timeline;
146  for ( auto it : actionsNamesOrdered ) {
147  timeline += (std::to_string(actionsTimeMarginsMap.at(it).first) + " -----> " +
148  it + " -----> " + std::to_string(actionsTimeMarginsMap.at(it).second) + " + ");
149  }
150  if (! timeline.empty() ) {
151  timeline.pop_back(); timeline.pop_back(); timeline.pop_back(); //to delete last " + "
152  }
153 
154  out << YAML::Comment(timeline);
155  out << YAML::Key << "Type" << YAML::Value << type;
156  out << YAML::Key << "FingersInvolved" << YAML::Value << YAML::Flow << fingersInvolved;
157 
158  out << YAML::Key << "JointsInvolvedCount" << YAML::Value << YAML::BeginMap;
159  for (const auto &jointCount : jointsInvolvedCount ) {
160  out << YAML::Key << jointCount.first;
161  out << YAML::Value << jointCount.second;
162  }
163  out << YAML::EndMap;
164 
165  out << YAML::Key << "ActionsJointPosFinal" << YAML::Value << YAML::BeginMap;
166  for ( const auto joint : jointPosFinal ) {
167  out << YAML::Key << joint.first;
168  out << YAML::Value << YAML::Flow << joint.second; //vector of double is emitted like Seq
169  }
170  out << YAML::EndMap;
171 
172  out << YAML::Key << "ActionsNamesOrdered" << YAML::Value << YAML::Flow << actionsNamesOrdered;
173 
174  out << YAML::Key << "ActionsTimeMargins" << YAML::Value << YAML::BeginMap;
175  for (const std::string action : actionsNamesOrdered ){
176 
177  out << YAML::Key << action << YAML::Value << YAML::BeginMap;
178 
179  out << YAML::Key << "marginBefore" <<
180  YAML::Value << actionsTimeMarginsMap.at(action).first;
181 
182  out << YAML::Key << "marginAfter" <<
183  YAML::Value << actionsTimeMarginsMap.at(action).second;
184  out << YAML::EndMap;
185  }
186  out << YAML::EndMap;
187 
188  out << YAML::Key << "ActionsJointPos" << YAML::Value << YAML::BeginMap;
189  for (const std::string action : actionsNamesOrdered ){
190 
191  out << YAML::Key << action << YAML::Value << YAML::BeginMap;
192 
193  for ( const auto joint : actionsJointPosMap.at(action) ) {
194  out << YAML::Key << joint.first;
195  out << YAML::Value << YAML::Flow << joint.second; //vector of double is emitted like Seq
196  }
197  out << YAML::EndMap;
198  }
199  out << YAML::EndMap;
200 
201 
202  out << YAML::Key << "ActionsJointCount" << YAML::Value << YAML::BeginMap;
203  for (const std::string action : actionsNamesOrdered ){
204 
205  out << YAML::Key << action << YAML::Value << YAML::BeginMap;
206 
207  for ( const auto joint : actionsJointCountMap.at(action) ) {
208  out << YAML::Key << joint.first;
209  out << YAML::Value << YAML::Flow << joint.second; //vector of double is emitted like Seq
210  }
211  out << YAML::EndMap;
212  }
213  out << YAML::EndMap;
214 
215 
216 
217 
218  out << YAML::EndMap; // map began at the beginning of the function
219  out << YAML::EndMap;// map began at the beginning of the function
220 }
221 
222 bool ROSEE::ActionTimed::fillFromYaml(YAML::const_iterator yamlIt){
223 
224  name = yamlIt->first.as<std::string>();
225  type = Action::Type::Timed;
226 
227  for (auto keyValue = yamlIt->second.begin(); keyValue != yamlIt->second.end(); ++keyValue ) {
228 
229  std::string key = keyValue->first.as<std::string>();
230 
231  if ( key.compare ("FingersInvolved") == 0 ) {
232  auto tempVect = keyValue->second.as <std::vector <std::string> > ();
233  fingersInvolved.insert ( tempVect.begin(), tempVect.end() );
234 
235  } else if ( key.compare ("Type") == 0 ) {
236  if (ROSEE::Action::Type::Timed != static_cast<ROSEE::Action::Type> ( keyValue->second.as <unsigned int>() )) {
237  std::cout << "[Timed ACTION::" << __func__ << "] Error, found type " << keyValue->second.as <unsigned int>()
238  << "instead of Timed type (" << ROSEE::Action::Type::Timed << ")" << std::endl;
239  return false;
240  }
241  type = ROSEE::Action::Type::Timed;
242 
243  } else if ( key.compare ("ActionsNamesOrdered") == 0 ) {
244  actionsNamesOrdered = keyValue->second.as < std::vector <std::string> > ();
245 
246  } else if ( key.compare ("JointsInvolvedCount") == 0 ) {
247  jointsInvolvedCount = keyValue->second.as < JointsInvolvedCount >();
248 
249  } else if ( key.compare("ActionsTimeMargins") == 0 ) {
250 
251  for (auto tMargins = keyValue->second.begin(); tMargins != keyValue->second.end(); ++tMargins ) {
252 
253  std::string actNAme = tMargins->first.as<std::string>();
254  double before = tMargins->second["marginBefore"].as<double>();
255  double after = tMargins->second["marginAfter"].as<double>();
256  actionsTimeMarginsMap.insert (std::make_pair (actNAme, std::make_pair(before, after) ) ) ;
257  }
258 
259  } else if ( key.compare("ActionsJointPos") == 0) {
260 
261  for (auto jPos = keyValue->second.begin(); jPos != keyValue->second.end(); ++jPos ) {
262 
263  std::string actName = jPos->first.as<std::string>();
264  JointPos jp = jPos->second.as<ROSEE::JointPos>();
265  actionsJointPosMap.insert (std::make_pair (actName, jp) );
266  }
267 
268  } else if ( key.compare("ActionsJointCount") == 0) {
269 
270  for (auto jCount = keyValue->second.begin(); jCount != keyValue->second.end(); ++jCount ) {
271 
272  std::string actName = jCount->first.as<std::string>();
273  JointsInvolvedCount jc = jCount->second.as<ROSEE::JointsInvolvedCount>();
274  actionsJointCountMap.insert (std::make_pair (actName, jc) );
275  }
276 
277 
278  } else if ( key.compare("ActionsJointPosFinal") == 0) {
279 
280  jointPosFinal = keyValue->second.as < JointPos >();
281 
282  } else {
283  std::cerr << "[TIMEDACTION::" << __func__ << "] Error, not known key " << key << std::endl;
284  return false;
285  }
286  }
287 
288  return true;
289 }
290 
291 bool ROSEE::ActionTimed::insertAction(ROSEE::Action::Ptr action, double marginBefore, double marginAfter,
292  unsigned int jointPosIndex, double percentJointPos, std::string newActionName) {
293 
294  std::string usedName = (newActionName.empty()) ? action->getName() : newActionName;
295 
296  unsigned int count = actionsJointPosMap.count( usedName );
297 
298  if (count > 0) {
299  std::cerr << "[ACTIONTIMED:: " << __func__ << "] ERROR: " << usedName << " already present. Failed Insertion" << std::endl;
300  return false;
301  }
302 
303  if (marginAfter < 0 || marginBefore < 0) {
304  std::cerr << "[ACTIONTIMED:: " << __func__ << "] ERROR: Please pass positive time margins" << std::endl;
305  return false;
306  }
307 
308  if ( jointPosIndex > action->getAllJointPos().size()-1 ) {
309  std::cerr << "[ACTIONTIMED:: " << __func__ << "] ERROR: you pass index "<< jointPosIndex <<
310  " but there are only " << action->getAllJointPos().size() << " JointPos in the action passed as argument" << std::endl;
311  return false;
312  }
313 
314  if (percentJointPos < 0 || percentJointPos > 1) {
315  std::cerr << "[ACTIONTIMED:: " << __func__ << "] Please insert percentage for jointpos between 0 and 1. Passed: "
316  << percentJointPos << std::endl;
317  return false;
318  }
319 
320  if ( actionsNamesOrdered.size() > 0 &&
321  (! ROSEE::Utils::keys_equal(action->getAllJointPos().at(jointPosIndex), actionsJointPosMap.begin()->second)) ) {
322  //we need only to compare the first jointPos (.begin())
323  std::cerr << "[ACTIONTIMED:: " << __func__ << "] The action passed as argument has different keys in jointPosmap"
324  << " respect to the others inserted in this timed action " << std::endl;
325  return false;
326  }
327 
328  ROSEE::JointPos insertingJP = (percentJointPos)*(action->getAllJointPos().at( jointPosIndex )) ;
329  actionsJointPosMap.insert (std::make_pair ( usedName, insertingJP) );
330  actionsTimeMarginsMap.insert ( std::make_pair( usedName, std::make_pair(marginBefore, marginAfter)));
331  actionsNamesOrdered.push_back ( usedName );
332  actionsJointCountMap.insert (std::make_pair (usedName, action->getJointsInvolvedCount()));
333 
334  //father member
335  for ( auto it: action->getFingersInvolved() ) {
336  fingersInvolved.insert ( it );
337  }
338 
339  if (actionsNamesOrdered.size() == 1 ) { //We are inserting first action, we have to init the JointsInvolvedCount map
340 
341  jointsInvolvedCount = action->getJointsInvolvedCount();
342  jointPosFinal = insertingJP;
343 
344  } else {
345  // add the action.jointInvolvedCount to the timed jointCount
346  // and update jointPosFinal
347  for (auto jic : action->getJointsInvolvedCount() ) {
348  jointsInvolvedCount.at(jic.first) += jic.second;
349 
350  if (jic.second > 0) {
351  //if so, we must overwrite the pos of this joint in jointPosFina
352  jointPosFinal.at(jic.first) = insertingJP.at(jic.first);
353  }
354  }
355  }
356 
357  return true;
358 }
359 
360 
Type
Enum useful to discriminate each action when, for example, we want to parse a file if you change thi...
Definition: Action.h:82
ActionTimed()
Default constructor, used when parsing action from yaml file.
Definition: ActionTimed.cpp:19
std::string name
Definition: Action.h:146
bool insertAction(ROSEE::Action::Ptr action, double marginBefore=0.0, double marginAfter=0.0, unsigned int jointPosIndex=0, double percentJointPos=1, std::string newActionName="")
Insert an action as last one in the time line.
std::map< std::string, std::vector< double > > JointPos
The map to describe the position of all actuated joints.
Definition: Action.h:40
std::vector< ROSEE::JointPos > getAllJointPos() const override
Override function from father Action.
Definition: ActionTimed.cpp:31
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
std::pair< double, double > getActionMargins(std::string actionName) const
get for time margins
Definition: ActionTimed.cpp:88
The pure virtual class representing an Action.
Definition: Action.h:71
ROSEE::JointPos jointPosFinal
Here is contained the wanted final position of the timed action.
Definition: ActionTimed.h:162
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
void emitYaml(YAML::Emitter &out) const override
Emit info in a file with yaml format.
std::map< std::string, ROSEE::JointPos > actionsJointPosMap
Definition: ActionTimed.h:155
bool fillFromYaml(YAML::const_iterator yamlIt) override
Fill the internal data with infos taken from yaml file.
std::map< std::string, std::pair< double, double > > actionsTimeMarginsMap
Definition: ActionTimed.h:154
ROSEE::JointPos getJointPosAction(std::string actionName) const
get for joint positions
Definition: ActionTimed.cpp:61
Action::Type type
Definition: Action.h:147
std::vector< std::string > getInnerActionsNames() const
getter for action that composed this one
std::vector< ROSEE::JointsInvolvedCount > getAllJointCountAction() const
Get the JointsInvolvedCount maps of all the inner actions, in order.
Definition: ActionTimed.cpp:41
JointsInvolvedCount jointsInvolvedCount
Definition: Action.h:149
std::shared_ptr< Action > Ptr
Definition: Action.h:75
std::vector< std::string > actionsNamesOrdered
This vector is used to take count of the order of the actions inserted.
Definition: ActionTimed.h:167
void print() const override
Print info about this action.
std::map< std::string, ROSEE::JointsInvolvedCount > actionsJointCountMap
Definition: ActionTimed.h:156
ROSEE::JointsInvolvedCount getJointCountAction(std::string actionName) const
get for JointsInvolvedCount of the inner actions
Definition: ActionTimed.cpp:74
std::set< std::string > fingersInvolved
Definition: Action.h:148
JointPos getJointPos() const override
Override this function is necessary because it is pure virtual in father class Action.
Definition: ActionTimed.cpp:27
std::vector< std::pair< double, double > > getAllActionMargins() const
get all the time margins of all inner action
Definition: ActionTimed.cpp:51