79 #include <yarp/os/BufferedPort.h>
80 #include <yarp/os/Time.h>
81 #include <yarp/os/Network.h>
82 #include <yarp/os/PeriodicThread.h>
83 #include <yarp/os/Thread.h>
84 #include <yarp/os/Property.h>
85 #include <yarp/os/Vocab.h>
86 #include <yarp/os/Log.h>
87 #include <yarp/os/LogStream.h>
88 #include <yarp/os/Terminator.h>
89 #include <yarp/dev/ControlBoardInterfaces.h>
90 #include <yarp/dev/PolyDriver.h>
91 #include <yarp/sig/Vector.h>
92 #include <yarp/os/ResourceFinder.h>
95 using namespace yarp::dev;
96 using namespace yarp::os;
97 using namespace yarp::sig;
99 const int FIXED_TIME_MOVE=5;
100 const int SAMPLER_RATE=100;
103 struct LimbInterfaces
106 IPositionControl *ipos;
113 LimbInterfaces() : dd(0), ipos(0), ienc(0), md(0)
133 typedef std::list<Vector> PositionList;
134 typedef PositionList::iterator PositionListIterator;
135 typedef std::vector<PositionList> RobotSequence;
136 typedef std::vector<LimbInterfaces> RobotInterfaces;
137 typedef RobotInterfaces::iterator RobotInterfacesIterator;
153 std::vector<std::string> tags;
154 RobotSequence sequences;
156 DemoSequences(
const std::vector<std::string> &t)
159 sequences.resize(LIMBS);
162 bool fromFile(
const char *filename)
165 config.fromConfigFile(filename);
168 for (
int k=0; k<LIMBS; k++)
170 Bottle seqFile=config.findGroup(tags[k].c_str());
171 int length=(seqFile.findGroup(
"DIMENSIONS").find(
"numberOfPoses")).asInt32();
172 int nj=seqFile.findGroup(
"DIMENSIONS").find(
"numberOfJoints").asInt32();
173 for (
int ii=0; ii<length; ii++)
176 if (seqFile.findGroup(
"REORDER").isNull())
177 sprintf(tmp,
"POSITION%d",ii);
179 sprintf(tmp,
"POSITION%d",seqFile.findGroup(
"REORDER").findGroup(
"order").get(ii+1).asInt32());
180 Bottle &xtmp=seqFile.findGroup(tmp).findGroup(
"jointPositions");
183 if (nj!=xtmp.size()-1)
184 yWarning(
"**** WARNING: mismatch of sizes in the input file! nj=%d, xtmp=%d \n",nj,xtmp.size());
185 for (
int l=0; l<xtmp.size()-1; l++)
186 vect[l]=xtmp.get(l+1).asFloat64();
187 sequences[k].push_back(vect);
196 for (
int l=0; l<LIMBS; l++)
198 yInfo(
"Sequence for %s:",tags[l].c_str());
200 int s=sequences[l].size();
201 PositionListIterator it=sequences[l].begin();
202 while (it!=sequences[l].end())
205 yInfo(
"%s",v.toString().c_str());
218 std::vector<std::string> tags;
219 std::vector<Property> options;
220 RobotInterfaces interfaces;
225 options.resize(LIMBS);
226 interfaces.resize(LIMBS);
231 RobotInterfacesIterator it;
232 for (it=interfaces.begin(); it!=interfaces.end(); it++)
245 for (
int k=0; k<LIMBS; k++)
248 tmp.dd=
new PolyDriver;
249 tmp.dd->open(options[k]);
250 if (!tmp.dd->isValid())
252 yError(
"Error opening %s",tags[k].c_str());
257 ret=ret && tmp.dd->view(tmp.ipos);
258 ret=ret && tmp.dd->view(tmp.ienc);
261 success=success && ret;
267 class RobotMover :
public PeriodicThread
270 RobotSequence sequences;
282 PositionListIterator *its;
283 PositionListIterator *itends;
287 RobotMover(Robot *r,
int rate) : PeriodicThread((double)rate/1000.0)
292 its=
new PositionListIterator[LIMBS];
293 itends=
new PositionListIterator[LIMBS];
294 motionTime=FIXED_TIME_MOVE;
304 void setVerbose(
bool f)
307 void waitMotion(
double dT,
bool checkDone=
false)
317 for (
int k=0; k<LIMBS; k++)
320 bool *tmp=robot->interfaces[k].md;
321 for (
int j=0; j<robot->interfaces[k].nj; j++)
339 for (
int k=0; k<LIMBS; k++)
342 yInfo(
"%s dumping MotionDone:",robot->tags[k].c_str());
343 for (
int j=0; j<robot->interfaces[k].nj; j++)
344 yInfo(
"%s",robot->interfaces[k].md[j]?
"true":
"false");
349 void computeSpeed(
double dT)
354 for (
int l=0; l<LIMBS; l++)
356 int nj=robot->interfaces[l].nj;
357 Vector &encs=robot->interfaces[l].encoders;
358 Vector &sp=robot->interfaces[l].speed;
359 Vector &cmd=robot->interfaces[l].cmd;
361 for (
int j=0; j<nj; j++)
363 double dp=fabs(encs[j]-cmd[j]);
375 for (
int l=0; l<LIMBS; l++)
377 its[l]=sequences[l].begin();
378 itends[l]=sequences[l].end();
384 yInfo(
"Starting controller...");
387 yError(
"sequences not set, returning false");
392 for (
int l=0; l<LIMBS; l++)
395 robot->interfaces[l].ipos->getAxes(&nj);
396 robot->interfaces[l].resize(nj);
397 robot->interfaces[l].speed=0;
398 robot->interfaces[l].encoders=0;
399 robot->interfaces[l].cmd=0;
412 for (
int l=0; l<LIMBS; l++)
415 while (!robot->interfaces[l].ienc->getEncoders(robot->interfaces[l].encoders.data()))
419 yDebug(
"Waiting for encoders!\n");
424 robot->interfaces[l].cmd=p;
428 computeSpeed(motionTime);
430 for (
int l=0; l<LIMBS; l++)
432 robot->interfaces[l].ipos->setRefSpeeds(robot->interfaces[l].speed.data());
433 robot->interfaces[l].ipos->positionMove(robot->interfaces[l].cmd.data());
437 yInfo(
"%s",robot->tags[l].c_str());
438 yInfo(
"going to: %s ",robot->interfaces[l].cmd.toString().c_str());
439 yInfo(
"speed: %s ",robot->interfaces[l].speed.toString().c_str());
445 waitMotion(motionTime);
448 if (its[0]==itends[0])
452 yInfo(
"Sequence %d completed",count);
458 void setTime(
double dT)
481 yInfo(
"Stopping controller...");
484 void setSequences(
const RobotSequence &seq)
492 int main(
int argc,
char *argv[])
502 ResourceFinder finder;
503 bool no_legs{
false };
504 finder.setDefaultContext(
"demoYoga");
505 finder.configure(argc,argv);
506 finder.setDefault(
"positions",
"yoga.ini");
507 finder.setDefault(
"robot",
"icub");
508 std::string inifile=finder.findFile(
"positions").c_str();
509 std::string robotName=finder.find(
"robot").asString().c_str();
511 bool verbose=finder.check(
"verbose");
512 bool diagnostic=finder.check(
"diagnostic");
513 no_legs = finder.check(
"no_legs");
519 yError(
"No position file specified");
524 yInfo(
"Reading positions file from %s",inifile.c_str());
527 std::string prefix=string(
"/")+robotName+
"/";
531 icub.options[0].put(
"device",
"remote_controlboard");
532 icub.options[0].put(
"local",(prefix+
"demoYoga/right_arm/client").c_str());
533 icub.options[0].put(
"remote",(prefix+
"right_arm").c_str());
534 icub.tags[0]=
"RIGHTARM";
536 icub.options[1].put(
"device",
"remote_controlboard");
537 icub.options[1].put(
"local",(prefix+
"demoYoga/left_arm/client").c_str());
538 icub.options[1].put(
"remote",(prefix+
"left_arm").c_str());
539 icub.tags[1]=
"LEFTARM";
541 icub.options[2].put(
"device",
"remote_controlboard");
542 icub.options[2].put(
"local",(prefix+
"demoYoga/head/client").c_str());
543 icub.options[2].put(
"remote",(prefix+
"head").c_str());
546 icub.options[3].put(
"device",
"remote_controlboard");
547 icub.options[3].put(
"local",(prefix+
"demoYoga/torso/client").c_str());
548 icub.options[3].put(
"remote",(prefix+
"torso").c_str());
549 icub.tags[3]=
"TORSO";
552 icub.options[4].put(
"device",
"remote_controlboard");
553 icub.options[4].put(
"local", (prefix +
"demoYoga/right_leg/client").c_str());
554 icub.options[4].put(
"remote", (prefix +
"right_leg").c_str());
555 icub.tags[4] =
"RIGHTLEG";
557 icub.options[5].put(
"device",
"remote_controlboard");
558 icub.options[5].put(
"local", (prefix +
"demoYoga/left_leg/client").c_str());
559 icub.options[5].put(
"remote", (prefix +
"left_leg").c_str());
560 icub.tags[5] =
"LEFTLEG";
565 for (
int k=0; k<LIMBS; k++)
566 icub.options[k].put(
"diagnostic",
"");
569 DemoSequences *sequences=
new DemoSequences(icub.tags);
571 sequences->fromFile(inifile.c_str());
576 op.fromConfigFile(inifile.c_str());
578 if (op.check(
"time"))
579 dT=op.find(
"time").asFloat64();
581 if (!icub.createDevices())
583 yError(
"Error creating devices, check parameters");
587 RobotMover *robot_mover=
new RobotMover(&icub,SAMPLER_RATE);
588 robot_mover->setVerbose(verbose);
589 robot_mover->setSequences(sequences->sequences);
592 yInfo(
"Setting time to %g",dT);
593 robot_mover->setTime(dT);
596 robot_mover->start();
599 while (reply!=
"quit")
604 yInfo(
"Received a quit message");