119 #include <yarp/os/Network.h>
120 #include <yarp/os/RFModule.h>
121 #include <yarp/os/PeriodicThread.h>
122 #include <yarp/os/Bottle.h>
123 #include <yarp/os/BufferedPort.h>
124 #include <yarp/os/Time.h>
125 #include <yarp/sig/Vector.h>
126 #include <yarp/math/Math.h>
128 #include <yarp/dev/Drivers.h>
129 #include <yarp/dev/CartesianControl.h>
130 #include <yarp/dev/PolyDriver.h>
134 #define MAX_TORSO_PITCH 30.0
135 #define EXECTIME_THRESDIST 0.3
136 #define PRINT_STATUS_PER 1.0
139 using namespace yarp::os;
141 using namespace yarp::sig;
142 using namespace yarp::math;
171 string _remote,
string _local) :
172 PeriodicThread((double)_period / 1000.0), rf(_rf),
173 remote(_remote), local(_local) { }
178 ctrlCompletePose = !rf.check(
"onlyXYZ");
179 reinstateContext = rf.check(
"reinstate_context");
182 Property option(
"(device cartesiancontrollerclient)");
183 option.put(
"remote", remote);
184 option.put(
"local", local);
185 if (!driver.open(option))
192 iarm->storeContext(&startup_context_id);
195 defaultExecTime = rf.check(
"T", Value(2.0)).asFloat64();
200 printf(
"Detected arm kinematics version %s\n", hwver.
get_version().c_str());
202 map<string, int> torsoJointsRemap{{
"pitch", 0 }, {
"roll", 1 }, {
"yaw", 2 }};
204 torsoJointsRemap[
"roll"] = 0;
205 torsoJointsRemap[
"pitch"] = 1;
209 Vector newDof, curDof;
210 iarm->getDOF(curDof);
213 if (curDof.length() > 7) {
214 if (rf.check(
"DOF10")) {
216 newDof[torsoJointsRemap[
"pitch"]] = 1;
217 newDof[torsoJointsRemap[
"roll"]] = 1;
218 newDof[torsoJointsRemap[
"yaw"]] = 1;
220 limitTorsoPitch(torsoJointsRemap[
"pitch"]);
221 }
else if (rf.check(
"DOF9")) {
223 newDof[torsoJointsRemap[
"pitch"]] = 1;
224 newDof[torsoJointsRemap[
"roll"]] = 0;
225 newDof[torsoJointsRemap[
"yaw"]] = 1;
227 limitTorsoPitch(torsoJointsRemap[
"pitch"]);
228 }
else if (rf.check(
"DOF8")) {
230 newDof[torsoJointsRemap[
"pitch"]] = 0;
231 newDof[torsoJointsRemap[
"roll"]] = 0;
232 newDof[torsoJointsRemap[
"yaw"]] = 1;
235 newDof[torsoJointsRemap[
"pitch"]] = 0;
236 newDof[torsoJointsRemap[
"roll"]] = 0;
237 newDof[torsoJointsRemap[
"yaw"]] = 0;
241 iarm->setDOF(newDof, curDof);
244 iarm->setTrackingMode(
false);
248 iarm->setInTargetTol(rf.find(
"tol").asFloat64());
251 iarm->storeContext(&task_context_id);
255 if (iarm->getPose(xd, od))
262 port_xd.open(local +
"/xd:i");
270 printf(
"Thread started successfully\n");
272 printf(
"Thread did not start\n");
279 if (Bottle* b = port_xd.read(
false)) {
280 if (b->size() >= 3) {
281 for (
int i = 0; i < 3; i++)
282 xd[i] = b->get(i).asFloat64();
284 if (ctrlCompletePose && (b->size() >= 7)) {
285 for (
int i = 0; i < 4; i++)
286 od[i] = b->get(3 + i).asFloat64();
289 if (reinstateContext)
290 iarm->restoreContext(task_context_id);
292 const double execTime = calcExecTime(xd);
293 if (ctrlCompletePose)
294 iarm->goToPose(xd, od, execTime);
296 iarm->goToPosition(xd, execTime);
306 iarm->restoreContext(startup_context_id);
316 iarm->getLimits(axis, &
min, &
max);
326 return defaultExecTime;
328 return 1.5 * defaultExecTime;
333 double t = Time::now();
336 Vector
x, o, xdot, odot;
337 Vector xdhat, odhat, qdhat;
340 iarm->getTaskVelocities(xdot, odot);
341 iarm->getDesired(xdhat, odhat, qdhat);
342 double e_x =
norm(xdhat -
x);
344 printf(
"xd [m] = %s\n", xd.toString().c_str());
345 printf(
"xdhat [m] = %s\n", xdhat.toString().c_str());
346 printf(
"x [m] = %s\n",
x.toString().c_str());
347 printf(
"xdot [m/s] = %s\n", xdot.toString().c_str());
348 printf(
"norm(e_x) [m] = %g\n", e_x);
350 if (ctrlCompletePose) {
351 Vector e_o = dcm2axis(axis2dcm(odhat) * axis2dcm(o).transposed());
355 printf(
"od [rad] = %s\n", od.toString().c_str());
356 printf(
"odhat [rad] = %s\n", odhat.toString().c_str());
357 printf(
"o [rad] = %s\n", o.toString().c_str());
358 printf(
"odot [rad/s] = %s\n", odot.toString().c_str());
359 printf(
"norm(e_o) [rad] = %g\n",
norm(e_o));
387 name = rf.check(
"name", Value(
"armCtrl")).asString();
388 robot = rf.check(
"robot", Value(
"icub")).asString();
389 part = rf.check(
"part", Value(
"right_arm")).asString();
391 remote = slash + robot +
"/cartesianController/" + part;
392 local = slash + name + slash + part;
400 rpcPort.open(local +
"/rpc");
434 rf.configure(
argc, argv);
436 if (rf.check(
"help")) {
437 printf(
"Options:\n");
438 printf(
"\t--name name : controller name (default armCtrl)\n");
439 printf(
"\t--robot name : robot name to connect to (default: icub)\n");
440 printf(
"\t--part type : robot arm type, left_arm or right_arm (default: right_arm)\n");
441 printf(
"\t--T time : specify the task execution time in seconds (default: 2.0)\n");
442 printf(
"\t--tol tolerance: specify the cartesian tolerance in meters\n");
443 printf(
"\t--DOF10 : control the torso yaw/roll/pitch as well\n");
444 printf(
"\t--DOF9 : control the torso yaw/pitch as well\n");
445 printf(
"\t--DOF8 : control the torso yaw as well\n");
446 printf(
"\t--onlyXYZ : disable orientation control\n");
447 printf(
"\t--reinstate_context : reinstate controller context upon target reception\n");
453 if (!
yarp.checkNetwork()) {
454 printf(
"YARP server not available!\n");
459 return mod.runModule(rf);
bool configure(ResourceFinder &rf)
CtrlThread(unsigned int _period, ResourceFinder &_rf, string _remote, string _local)
BufferedPort< Bottle > port_xd
void limitTorsoPitch(const int axis)
double calcExecTime(const Vector &xd)
A class for defining the versions of the iCub limbs.
std::string get_version() const
Return the version string.
double norm(const yarp::sig::Matrix &M, int col)
Returns the norm of the vector given in the form: matrix(:,col).
int main(int argc, char *argv[])
#define EXECTIME_THRESDIST
Copyright (C) 2008 RobotCub Consortium.