iCub-main
main.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 RobotCub Consortium, European Commission FP6 Project IST-004370
3  * Author: Ugo Pattacini
4  * email: ugo.pattacini@iit.it
5  * website: www.robotcub.org
6  * Permission is granted to copy, distribute, and/or modify this program
7  * under the terms of the GNU General Public License, version 2 or any
8  * later version published by the Free Software Foundation.
9  *
10  * A copy of the license can be found at
11  * http://www.robotcub.org/icub/license/gpl.txt
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details
17 */
18 
134 #include <cstdlib>
135 #include <memory>
136 #include <iostream>
137 #include <iomanip>
138 #include <string>
139 #include <sstream>
140 
141 #include <yarp/os/LogStream.h>
142 #include <yarp/os/Searchable.h>
143 #include <yarp/os/Property.h>
144 #include <yarp/os/Value.h>
145 #include <yarp/os/Bottle.h>
146 #include <yarp/os/Network.h>
147 #include <yarp/os/ResourceFinder.h>
148 #include <yarp/os/RFModule.h>
149 #include <yarp/sig/Vector.h>
150 #include <yarp/sig/Matrix.h>
151 #include <yarp/math/Math.h>
152 
153 #include <iCub/iKin/iKinSlv.h>
154 
155 using namespace std;
156 using namespace yarp::os;
157 using namespace yarp::sig;
158 using namespace yarp::math;
159 using namespace iCub::iKin;
160 
161 static string pathToCustomKinFile;
162 
163 
164 /************************************************************************/
166  protected:
167  bool configured{false};
168  iKinChain* chain{nullptr};
169  Matrix C_orig;
170  Vector lB_orig;
171  Vector uB_orig;
172 
173  /************************************************************************/
174  void clone(const iKinLinIneqConstr* obj)override {
175  iKinLinIneqConstr::clone(obj);
176 
177  const auto* ptr = static_cast<const GenericLinIneqConstr*>(obj);
178  configured = ptr->configured;
179  chain = ptr->chain;
180  C_orig = ptr->C_orig;
181  lB_orig = ptr->lB_orig;
182  uB_orig = ptr->uB_orig;
183  }
184 
185  public:
186  /************************************************************************/
187  GenericLinIneqConstr(iKinChain* chain_, Searchable& options) :
188  chain(chain_), C_orig(0, chain_->getN()), iKinLinIneqConstr() {
189  if (options.check("LIC_num")) {
190  auto LIC_num = options.find("LIC_num").asInt32();
191  if (LIC_num > 0) {
192  for (auto i = 0; i < LIC_num; i++) {
193  ostringstream tag;
194  tag << "LIC_" << i;
195  Bottle& group = options.findGroup(tag.str());
196  if (group.isNull()) {
197  yError() << "Unable to find group \"" << tag.str() << "\"";
198  return;
199  }
200  Bottle* row = group.find("C").asList();
201  if (row == nullptr) {
202  yError() << "Unable to find option \"C\" for group \"" << tag.str() << "\"";
203  return;
204  }
205  if (row->size() != chain->getN()) {
206  yError() << "Option \"C\" of group \"" << tag.str() << "\" has wrong size";
207  return;
208  }
209  C_orig = pile(C_orig, zeros(chain->getN()));
210  for (auto i = 0; i < row->size(); i++) {
211  C_orig(C_orig.rows() - 1, i) = row->get(i).asFloat64();
212  }
213  lB_orig = cat(lB_orig, group.check("lB", Value(lowerBoundInf)).asFloat64());
214  uB_orig = cat(uB_orig, group.check("uB", Value(upperBoundInf)).asFloat64());
215  }
216 
217  yInfo() << "Detected generic linear inequalities constraints";
218  configured = true;
219  update(nullptr);
220  }
221  }
222  }
223 
224  /************************************************************************/
225  void update(void*)override {
226  setActive(false);
227  if (configured) {
228  getC().resize(C_orig.rows(), 0);
229  getlB() = lB_orig;
230  getuB() = uB_orig;
231  for (auto i = 0U; i < chain->getN(); i++) {
232  if (chain->isLinkBlocked(i)) {
233  auto v = chain->getAng(i) * C_orig.getCol(i);
234  getlB() -= v;
235  getuB() -= v;
236  } else {
237  getC() = cat(getC(), C_orig.getCol(i));
238  }
239  }
240  setActive(true);
241  }
242  }
243 };
244 
245 
246 /************************************************************************/
248  shared_ptr<iKinLimb> limb{nullptr};
249  shared_ptr<GenericLinIneqConstr> cns{nullptr};
250  shared_ptr<PartDescriptor> desc{nullptr};
251 
252  protected:
253  /************************************************************************/
254  PartDescriptor* getPartDesc(Searchable& options) {
255  if (!options.check("robot")) {
256  yError() << "\"robot\" option is missing!";
257  return nullptr;
258  }
259 
260  if (!options.check("NumberOfDrivers")) {
261  yError() << "\"NumberOfDrivers\" option is missing!";
262  return nullptr;
263  }
264 
265  string robot = options.find("robot").asString();
266  yInfo() << "Configuring solver for " << robot << " ...";
267 
268  Property linksOptions;
269  linksOptions.fromConfigFile(pathToCustomKinFile);
270  limb = shared_ptr<iKinLimb>(new iKinLimb(linksOptions));
271  if (!limb->isValid()) {
272  yError() << "invalid links parameters!";
273  return nullptr;
274  }
275 
276  cns = shared_ptr<GenericLinIneqConstr>(new GenericLinIneqConstr(limb->asChain(), options));
277  desc = shared_ptr<PartDescriptor>(new PartDescriptor);
278  desc->lmb = limb.get();
279  desc->chn = limb->asChain();
280  desc->cns = cns.get();
281 
282  bool failure = false;
283  desc->num = options.find("NumberOfDrivers").asInt32();
284  for (int cnt = 0; cnt < desc->num; cnt++) {
285  ostringstream str;
286  str << "driver_" << cnt;
287  Bottle& driver = options.findGroup(str.str());
288  if (driver.isNull()) {
289  yError() << "\"" << str.str() << "\" option is missing!";
290  failure = true;
291  break;
292  }
293 
294  if (!driver.check("Key")) {
295  yError() << "\"Key\" option is missing!";
296  failure = true;
297  break;
298  }
299 
300  if (!driver.check("JointsOrder")) {
301  yError() << "\"JointsOrder\" option is missing!";
302  failure = true;
303  break;
304  }
305 
306  string part = driver.find("Key").asString();
307  bool directOrder = (driver.find("JointsOrder").asString() == "direct");
308 
309  Property optPart;
310  optPart.put("device", "remote_controlboard");
311  optPart.put("remote", "/" + robot + "/" + part);
312  optPart.put("local", "/" + slvName + "/" + part);
313  optPart.put("robot", robot);
314  optPart.put("part", part);
315  desc->prp.push_back(optPart);
316  desc->rvs.push_back(!directOrder);
317  }
318 
319  return (failure ? nullptr : desc.get());
320  }
321 
322  public:
323  /************************************************************************/
324  CustomCartesianSolver(const string& name) : CartesianSolver(name) { }
325 };
326 
327 
328 
329 /************************************************************************/
330 class SolverModule : public RFModule {
331  protected:
332  shared_ptr<CartesianSolver> slv{nullptr};
333 
334  public:
335  /************************************************************************/
336  bool configure(ResourceFinder& rf) {
337  string part, slvName;
338  if (rf.check("part")) {
339  part = rf.find("part").asString();
340  } else {
341  yError() << "part option is not specified";
342  return false;
343  }
344 
345  Bottle& group = rf.findGroup(part);
346  if (group.isNull()) {
347  yError() << "unable to locate " << part << " definition";
348  return false;
349  }
350 
351  if (group.check("name")) {
352  slvName = group.find("name").asString();
353  } else {
354  yError() << "name option is missing";
355  return false;
356  }
357 
358  if (group.check("CustomKinFile")) {
359  yInfo() << "Custom Cartesian Solver detected!";
360 
361  ResourceFinder rf_kin;
362  rf_kin.setDefaultContext(rf.getContext());
363  rf_kin.configure(0, nullptr);
364  pathToCustomKinFile = rf_kin.findFileByName(group.find("CustomKinFile").asString());
365 
366  slv = shared_ptr<CartesianSolver>(new CustomCartesianSolver(slvName));
367  } else if ((part == "left_arm") || (part == "right_arm")) {
368  slv = shared_ptr<CartesianSolver>(new iCubArmCartesianSolver(slvName));
369  } else if ((part == "left_leg") || (part == "right_leg")) {
370  slv = shared_ptr<CartesianSolver>(new iCubLegCartesianSolver(slvName));
371  } else {
372  yError() << part << " is invalid";
373  return false;
374  }
375 
376  return slv->open(group);
377  }
378 
379  /************************************************************************/
381  if (slv) {
382  slv->interrupt();
383  }
384 
385  return true;
386  }
387 
388  /************************************************************************/
389  double getPeriod() {
390  return 1.0;
391  }
392 
393  /************************************************************************/
394  bool updateModule() {
395  if (slv->isClosed()) {
396  return false;
397  }
398 
399  if (slv->getTimeoutFlag()) {
400  slv->getTimeoutFlag() = false;
401  slv->suspend();
402  }
403 
404  return true;
405  }
406 };
407 
408 
409 /************************************************************************/
410 int main(int argc, char* argv[]) {
411  Network yarp;
412  if (!yarp.checkNetwork()) {
413  yError() << "YARP server not available!";
414  return EXIT_FAILURE;
415  }
416 
417  ResourceFinder rf;
418  rf.setDefaultContext("cartesianSolver");
419  rf.setDefaultConfigFile("cartesianSolver.ini");
420  rf.configure(argc, argv);
421 
422  SolverModule mod;
423  return mod.runModule(rf);
424 }
425 
426 
427 
PartDescriptor * getPartDesc(Searchable &options)
Definition: main.cpp:254
CustomCartesianSolver(const string &name)
Definition: main.cpp:324
void clone(const iKinLinIneqConstr *obj) override
Definition: main.cpp:174
void update(void *) override
Updates internal state.
Definition: main.cpp:225
GenericLinIneqConstr(iKinChain *chain_, Searchable &options)
Definition: main.cpp:187
bool configure(ResourceFinder &rf)
Definition: main.cpp:336
bool updateModule()
Definition: main.cpp:394
double getPeriod()
Definition: main.cpp:389
bool interruptModule()
Definition: main.cpp:380
Abstract class defining the core of on-line solvers.
Definition: iKinSlv.h:345
Derived class which implements the on-line solver for the chain torso+arm.
Definition: iKinSlv.h:584
Derived class which implements the on-line solver for the leg chain.
Definition: iKinSlv.h:610
A Base class for defining a Serial Link Chain.
Definition: iKinFwd.h:354
A class for defining generic Limb.
Definition: iKinFwd.h:873
Class for defining Linear Inequality Constraints of the form lB <= C*q <= uB for the nonlinear proble...
Definition: iKinIpOpt.h:69
zeros(2, 2) eye(2
int main(int argc, char *argv[])
Definition: main.cpp:31
static string pathToCustomKinFile
Definition: main.cpp:161
Copyright (C) 2008 RobotCub Consortium.